Меня спросили об этом в недавнем интервью - PullRequest
4 голосов
/ 11 октября 2009

Меня попросили держаться подальше от HashMap или любого другого типа хеширования.

Вопрос пошел примерно так -

Допустим, у вас есть идентификаторы ПРОДУКТА до 20 десятичных знаков вместе с описаниями продуктов. Без использования Карт или какой-либо другой функции хеширования, каков наилучший / наиболее эффективный способ хранения / получения этих идентификаторов продуктов вместе с их описаниями?

Почему использование Карт плохая идея для такого сценария?

Какие изменения вы бы внесли, чтобы продать свое решение Amazon?

Ответы [ 14 ]

11 голосов
/ 11 октября 2009

Карта удобна для использования при чередовании операций вставки / удаления / поиска. Каждые операции амортизируются в O (log n).

В вашем примере вы выполняете только операцию поиска. Вы можете подумать, что любое обновление базы данных (вставка / удаление продукта) не будет происходить так много времени. Поэтому, вероятно, интервьюер хочет, чтобы вы получили лучшую структуру данных для операций поиска.

В этом случае я вижу только некоторые из предложенных в других ответах:

  • Сортированный массив (выполняет бинарный поиск)
  • Hasmap
  • Trie

Если у идентификаторов продуктов нет общего префикса, есть хороший шанс найти описание продукта только по первому символу префикса (или только по самым первым символам). Например, давайте возьмем этот список идентификаторов продуктов со 125 продуктами:

  • "1"
  • "2"
  • "3"
    ...
  • "123"
  • "124"
  • "1234567"

Предположим, что вы ищете идентификатор продукта с названием «1234567» в своей папке, обращаясь только к первым буквам: «1», затем «2», затем «3», а затем «4» приведет к хорошему описанию продукта. Не нужно читать оставшуюся часть идентификатора продукта, так как других возможностей нет. Учитывая длину идентификатора продукта как n, ваш поиск будет в O (n). Но, как в приведенном выше примере, это может быть еще быстрее получить описание продукта. Поскольку идентификатор продукта ограничен в размере (20 символов), высота дерева будет ограничена 20 уровнями. Это на самом деле означает, что вы можете считать, что операции поиска никогда не будут выходить за пределы постоянного времени, так как ваш поиск никогда не будет идти дальше высоты trie => O (1). В то время как любые поиски BST в лучшем случае амортизируются O (log N), N - количество элементов в вашем дереве .

Хотя хеш-карта может привести к более медленному поиску, поскольку вам потребуется вычислить индекс с помощью хеш-функции, которая, вероятно, реализована с использованием длины идентификатора продукта целом . Плюс просмотр списка в случае коллизии с другими идентификаторами продукта.

Выполнение бинарного поиска по отсортированному массиву, а производительность операций поиска будет зависеть от количества элементов в вашей базе данных.

6 голосов
/ 11 октября 2009

A B-Tree на мой взгляд. Это по-прежнему считается картой?

Главным образом потому, что вы можете загружать в память одновременно много предметов. Поиск этих предметов в памяти очень быстрый.

4 голосов
/ 11 октября 2009

Последовательные целые числа дают идеальный выбор для хэш-карты, но она имеет только одну проблему, так как не имеет многопоточного доступа по умолчанию. Также, поскольку Amazon был упомянут в вашем вопросе, я могу подумать, что вам необходимо принять во внимание проблемы параллелизма и ограничения ОЗУ.

Что вы можете сделать в ответе на такой вопрос, это объяснить, что с вам не разрешено использовать любые встроенные схемы хранения данных, все, что вы можете сделать, это «эмулировать» одну.

Итак, допустим, у вас есть M = 10 ^ 20 товаров с их номерами и описаниями. Вы можете разбить этот набор на группы из N подмножеств. Затем вы можете организовать M / N контейнеры, которые значительно сократили количество элементов. Использование этой идеи рекурсивно даст вам возможность хранить весь набор в контейнерах с таким свойством, что доступ к ним будет иметь приемлемый уровень производительности.

Чтобы проиллюстрировать эту идею, рассмотрим меньший пример только из 20 элементов. Я хотел бы, чтобы вы представили файловую систему с каталогами «1», «2», «3», «4». В каждом каталоге вы сохраняете описания продуктов в виде файлов следующим образом:

folder 1: files 1 to 5
folder 2: files 6 to 10
...
folder 4: files 16 to 20

Тогда для поиска файла потребуется всего два шага. Сначала вы ищете нужную папку, разделив 20/5 (ваш M / N). Затем вы используете указанный идентификатор, чтобы прочитать описание продукта, хранящееся в файле.

Это просто очень грубое описание, однако идея очень интуитивна. Так что, возможно, именно это хотел услышать ваш интервьюер.

Что касается меня, когда я сталкиваюсь с такими вопросами на собеседовании, даже если мне не удается правильно ответить на вопрос (что является наихудшим случаем :)), я всегда стараюсь получить правильный ответ от интервьюера.

2 голосов
/ 11 октября 2009

Лучший / эффективный для чего? Был бы мой ответ.

например. для их хранения, вероятно, самое быстрое - это два массива по 20 элементов в каждом. Один для идентификаторов, для описания. Перебирать их довольно быстро. И это эффективная память с умом.

Конечно, решение довольно бесполезно для любого реального приложения, но вопрос таков.

1 голос
/ 12 октября 2009

Интересно, хотели ли они, чтобы вы заметили, что в приложении для электронной коммерции (например, в Amazon) распространенным случаем использования является «обратный поиск»: получите идентификатор продукта, используя описание. Для этого используется инвертированный индекс , где каждое ключевое слово в описании является индексным ключом, который связан со списком соответствующих идентификаторов продукта. Двоичные деревья или списки пропусков являются хорошими способами индексации этих ключевых слов.

Относительно индекса идентификатора продукта: На практике B-деревья (которые являются не бинарными деревьями поиска) будут использоваться для большого дискового индекса из 20-значных идентификаторов. Однако они, возможно, искали игрушечное решение, которое могло бы быть реализовано в оперативной памяти. Так как «алфавит» десятичных чисел настолько мал, он очень хорошо поддается трию.

1 голос
/ 11 октября 2009

Я думаю, что он хотел, чтобы вы делали, а я не говорю, что это хорошая идея, это использовать пространство памяти компьютера.

Если вы используете 64-битный (виртуальный) адрес памяти и предполагаете, что у вас есть все адресное пространство для ваших данных (что является никогда регистром), вы можете сохранить однобайтовое значение.

Вы можете использовать ProductID в качестве адреса, приведя его к указателю, а затем получить этот байт, который может быть смещением в другой памяти для фактических данных.

Я не не сделал бы это таким образом, но, возможно, это был ответ, который они искали.

Асаф

1 голос
/ 11 октября 2009

Существует интересная альтернатива B-Tree: Radix Tree

0 голосов
/ 12 октября 2009

Я думаю, что он хотел, чтобы ты сделал, и Я не говорю, что это хорошая идея, это использовать пространство памяти компьютера.

Если вы используете 64-битную (виртуальную) память адрес, и при условии, что у вас есть все адресное пространство для ваших данных (которое никогда не бывает) вы можете хранить однобайтовое значение.

К сожалению, 2 ^ 64 = приблизительно = 1,8 * 10 ^ 19. Чуть ниже 10 ^ 20. Совпадение?

log2 (10 ^ 20) = 66,43.

Вот немного злое предложение.

ОК, 2 ^ 64 бит может поместиться в пространство памяти.

Предположим, что в описании содержится N байтов, скажем, N = 200. (кто хочет скачать Анну Каренину, когда они ищут тостеры?) Commandeer 8 * N 64-битные машины с большой оперативной памятью. Амазон может качать это.

Каждая машина загружает в свое (очень разреженное) растровое изображение один бит текста описания для всех описаний. Пусть MMU / виртуальная память обрабатывает разреженность.

Трансляция тега продукта в виде 59-битного числа и битовой маски для одного байта (59 = ceil (log2 (10 ^ 20)) - 8)

Каждая машина возвращает один бит из описания продукта. Поиски - это разыменование виртуальной памяти. Вы даже можете вставить и удалить.

Конечно, в какой-то момент пейджинг станет сучкой!

Как ни странно, он будет работать лучше всего, если идентификаторы продукта будут настолько клочковатыми и нехорошими, насколько это возможно. Хеш.

0 голосов
/ 11 октября 2009

Ваш интервьюер может искать три. Если у вас есть [маленькая] постоянная верхняя граница для вашего ключа, тогда у вас есть O (1) вставка и поиск.

0 голосов
/ 11 октября 2009

У меня есть ощущение, основанное на их ответе об идентификаторах продуктов и двухзначном ответе, который они искали, чтобы преобразовать числовые идентификаторы продуктов в другую базовую систему или упакованную форму.

Они указали, что описание продукта было с идентификаторами продукта, чтобы сообщить вам, что в текущем типе поля может использоваться более высокая базовая система.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...