Для чего в программировании нужна хеш-функция (Hash)?

«Для чего в программировании нужна хеш-функция (Hash)?» — вопрос из категории Алгоритмы и структуры данных, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Хеш-функция нужна для преобразования произвольных данных (объекта, строки) в фиксированное числовое значение (хеш-код). Это основа для эффективной работы структур данных, требующих быстрого поиска и сравнения, таких как словарь (Dictionary) и множество (Set).

Основное назначение:

  1. Быстрое сравнение объектов. Сравнение двух хеш-кодов происходит мгновенно и дешевле, чем поточечное сравнение всех полей больших структур.
  2. Определение места хранения в хеш-таблицах. Хеш-код используется как индекс «корзины» (bucket) для быстрого доступа к элементу за время, близкое к O(1).

В Swift эта концепция реализована через протокол Hashable, который наследуется от Equatable.

struct User: Hashable { // Swift автоматически синтезирует реализацию, если все свойства Hashable
    let id: UUID
    let email: String
}

// Использование в качестве ключа в Dictionary
var userScores: [User: Int] = [:
let user = User(id: UUID(), email: "test@example.com")
userScores[user] = 100

// Использование в Set
var uniqueUsers: Set<User> = []
uniqueUsers.insert(user)

Критически важные требования к Hashable:

  • Детерминированность: Для одного и того же объекта хеш-код должен быть одинаковым в течение всего времени его жизни (при условии, что свойства, участвующие в hash(into:), не меняются).
  • Связь с Equatable: Если два объекта равны (a == b), то их хеш-коды обязательно должны быть равны (a.hashValue == b.hashValue). Обратное неверно: разные объекты могут иметь одинаковый хеш-код (коллизия). Хорошая хеш-функция минимизирует вероятность коллизий.
  • Производительность: Вычисление хеша должно быть быстрым.