Как устроен поиск под капотом
Что проверяют
Прежде всего, умеете ли вы уточнить вопрос: «поиск» может означать поиск по структуре данных в памяти или полнотекстовый поиск в продукте. Сильный ответ коротко закрывает первое и подробно разбирает второе. Следом обычно спрашивают, почему LIKE '%слово%' не годится на больших таблицах.
Как отвечать
В памяти процесса на Go:
- map: хэш-таблица, поиск в среднем O(1). С Go 1.24 встроенная map реализована на Swiss Tables, порядок обхода по-прежнему не гарантирован;
- бинарный поиск:
slices.BinarySearchилиsort.Searchна отсортированном срезе, O(log n) без лишней памяти.
Полнотекстовый поиск строится на обратном индексе:
- анализ текста: токенизация, нижний регистр, стоп-слова, стемминг или лемматизация. Без морфологии запрос «вакансии» не найдёт «вакансия»;
- обратный индекс: словарь термов, у каждого список документов (posting list) с позициями. Запрос из нескольких слов превращается в пересечение списков;
- ранжирование: BM25 учитывает частоту слова в документе и его редкость в корпусе, поверх добавляют свежесть и бизнес-сигналы;
- движок: Elasticsearch или OpenSearch поверх Lucene, в PostgreSQL связка
tsvectorи GIN-индекса, в самом Go библиотека Bleve.
Сервис на Go обычно не пишет индекс сам, а держит API: принимает запрос, строит запрос к движку, собирает фасеты, кэширует популярные выдачи. Индекс обновляется асинхронно, из основной базы через очередь или CDC. Отдельно упомяните семантический поиск: эмбеддинги и приближённый поиск ближайших соседей по HNSW, часто в гибриде с BM25.
Где спотыкаются
Отвечают только про map и бинарный поиск, не уточнив, о чём вопрос. Если интервьюер имел в виду поиск в продукте, ответ мимо.
Предлагают LIKE '%слово%'. Ведущий % не даёт использовать B-tree, база читает таблицу целиком, а морфологии и ранжирования нет вовсе.
Забывают о задержке индексации. Elasticsearch делает документ видимым после refresh, по умолчанию раз в секунду, а конвейер через очередь добавляет своё. Пользователь создал запись и не нашёл её сразу: это нужно заранее объяснить продукту.