Вопрос Google Интервью
Это был один из вопросов Google Interview.
Какова возможная проблема, если Hash Table вырастет более чем на 30 Гб (игнорируйте проблемы, такие как плохая хеш-функция)
Я этого не знал. Что может быть удовлетворительным ответом?
Спасибо
Ответы
Ответ 1
Некоторые проблемы:
- Hash Collision может быть одной из основных проблем.
- Также будет неэффективно делать частые чтения дисков при хранении данных на диске в виде хеш-таблицы.
Ответ 2
Ответ частично зависит от того, говорят ли они об классической реализации хэш-таблицы (например, HashTable/HashMap в Java) или о чем-то более сложном. В конце концов, 30 ГБ памяти по-прежнему достаточно велики для одной машины /VM по сегодняшним стандартам.
Так подумайте о том, что происходит внизу:
- Он должен читать запись в произвольной позиции в каком-то массивном массиве.
- Он должен расти, если он заполняется не в какой-то мере; см. "коэффициент загрузки" в реализации Java.
- В собранном мусором языке/реализации все объекты, хранящиеся в хеш-таблице, должны быть проверены сборщиком мусора
Это приводит к следующим проблемам:
- Неясно, что даже сегодня операционные системы справляются с распределением блоков памяти в десятках GBs
- Для простоты скажем, что половина таблицы фактически использовалась самой таблицей (а не объектами ключа и значения). Таким образом, внутри есть 15-гигабайтный массив. Поэтому каждый раз, когда таблица растет, вам нужно выделить хотя бы еще 15 ГБ
- Даже если был выделен десяток GB-массивов, ОС будет отображать часть этой памяти. Поскольку мы принимаем хорошую хеш-функцию, мы будем разбивать кеширование страниц, если мы используем большую часть данных в массиве. Будет много ошибок страницы.
- Скажем, мы не используем все данные. Некоторые ключи используются часто, а другие - нет. Чтобы проиллюстрировать, скажем, что каждое значение ключа - крошечное - 128 байт. И для простоты скажем, что мы храним все в хеш-таблице в качестве значений. Таким образом, 30G/128 = ~ 250M записей. Но скажите, что 25k обычно использовали ключи. (25k/250M = 0,01%). Но с хорошей хэш-функцией они будут равномерно распределены по массивному массиву. Даже с небольшими размерами страниц - скажем, 4 кбайта, 25 КБ (записи) * 128 байтов (размер записи) = ~ 3,5 МБ обычно используемых данных стоят нам 25 КБ (записи) * 4 КБ (размер страницы) = ~ 100 Мб памяти, которая нуждается чтобы быть сохраненным в том случае, если вы достигли колоссальной эффективности 3.5%!
- В мире Java практикующие не рекомендуют размеры кучи размером больше 4 - 8 ГБ. Конечно, есть такие вещи, как Azul, но это просто доказывает суть - типичный сборщик мусора не очень хорошо масштабируется для этих размеров.
Я согласен с другими плакатами, которые Google ищет в качестве решения. Но я думаю, что в основе всего, простая хеш-таблица перестает масштабироваться за пределами точки. В приведенном выше примере
- Вам нужно будет распространять, если все записи будут доступны относительно равномерно
- Если некоторые из них доступны в большинстве случаев, использование двух карт (один для наиболее часто используемых) может купить вас много.
- В мире Java использование специализированных карт, в которых хранятся данные с кучи, также может купить вам производительность; см. Питер Лори работает, например.
- Даже простое разбиение базового массива в хэш-таблице (например, на Java ConcurrentHashMap) может значительно улучшить ваши улучшения, когда вам нужно увеличить хэш-таблицу.
Ответ 3
Я думаю, что интервьюер ожидал что-то в строках Распределенная таблица хешей, так как хэш-таблица 30 Гбайт не может храниться на одной машине ( по крайней мере, в текущем 64-битном мире); По моему личному опыту, довольно много QQ Google вращаются вокруг распределенных вычислений, уменьшения карт и т.д.,