Вопрос 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 вращаются вокруг распределенных вычислений, уменьшения карт и т.д.,