#python #data-structures #hashmap #hashtable
Вопрос:
Я изучал хэш-карты и их лучшие практики. Одной из вещей, на которую я наткнулся, было разрешение столкновений.
Эти методы включают в себя:
- Прямая Цепочка,
- Линейное Зондирование,
- Квадратичное Зондирование,
- Двойное Перемешивание.
До сих пор я обнаружил, что прямая цепочка была намного проще в реализации и имела наибольший смысл. Я не уверен, на чем мне следует сосредоточиться с точки зрения подготовки к техническим собеседованиям.
Комментарии:
1. Любой технический интервьюер, который просит вас сравнить методы хеширования, ищет не то, что нужно. Ни один профессиональный программист не пишет хэш-алгоритмы. Мы все слишком заняты, пытаясь закончить работу. Мы будем использовать Python
dict
или Cstd::map
, мы не будем писать свои собственные.2. Цепочка впала в немилость. Во всяком случае, это тот вариант, на котором вы можете сосредоточиться меньше всего. Кстати
std::map
, это не хэш-карта, смотритеstd::unordered_map
.3. ФУ, я не понимаю, почему вы включили тег «python». Ваш вопрос не зависит от языка. Если Python имеет отношение к делу, то ваш вопрос не имеет никакого смысла.
4. @TimRoberts: как руководитель отдела разработки SW в фирме HFT, я возражаю против ваших обобщений. Мы не только пишем хэш — таблицы и функции и выбираем подходы к управлению конфликтами, такие как перечисленные (часто, чтобы мы могли сопоставить реализацию на ПЛИС) — еще чаще нам нужно понимать такие варианты реализации, чтобы сделать обоснованный выбор из внешних предложений (robin_hood, Google absl, Facebook folly f14 и т. Д.) И настроить их использование.
Ответ №1:
Для технических интервью я бы предложил получить представление о плюсах/минусах этих подходов на высоком уровне, в частности:
- прямая цепочка медленно ухудшается по мере увеличения коэффициента загрузки, в то время как подходы к закрытому хэшированию/открытой адресации (все остальные, которые вы перечисляете) экспоненциально ухудшаются по мере увеличения коэффициента загрузки 1.0, поскольку становится все труднее и труднее найти пустое ведро
- линейное зондирование может быть удобным для кэширования ЦП с помощью небольших ключей (по сравнению с любым другим методом): если вы можете поместить несколько ключей в одну и ту же строку кэша, это означает, что ЦП, скорее всего, потратит меньше времени на поиск в памяти после столкновений (и инструкции SIMD иногда могут помочь сравнить с ключами нескольких блоков одновременно).
- линейное зондирование и хэширование идентификаторов могут привести к более низким, чем при криптографическом хэшировании, коэффициентам коллизий для ключей, которые имели хорошее распределение по сегментам, например идентификаторы, которые имеют тенденцию к увеличению, но могут иметь разрывы здесь и там
- линейное зондирование гораздо более подвержено кластерам столкновений, чем квадратичное зондирование, особенно с плохими хэш-функциями / ключами с трудными для хэширования колодцами и более высокими коэффициентами нагрузки (например, > = 0,8), поскольку столкновения в одной части таблицы (даже если случайно больше, чем ошибочное хэширование), как правило, усугубляют использование этой части таблицы в будущем
- квадратичное зондирование может иметь пару смещений в одной строке кэша, которые могут попадать в одну и ту же строку кэша, поэтому вы можете получить полезную вероятность того, что вторая и даже третья строка будут находиться в той же строке кэша, что и первая, но после нескольких сбоев вы будете прыгать с большим шагом, уменьшая проблемы с кластеризацией за счет большего количества пропусков в кэше
- двойное хеширование — это своего рода компромисс; если второй хеш выдает 1, то это эквивалентно линейному зондированию, но вы можете попробовать каждое 2-е ведро или каждое 3-е и т. Д.-До некоторого предела. Все еще есть много места для кластеризации (например, если h2(k) вернул 6 для одного ключа и 3 для другого ключа, который был привязан к ведру 3 дальше в таблице, чем первый ключ, тогда они посетят многие из тех же ведер во время своих поисков.
Я бы не рекомендовал сосредотачиваться на каком-либо из них с большой глубиной или игнорировать их, потому что контрасты усиливают ваше понимание любого из других.