Итог интервью · Node.js · Middle
Нормально, 64 из 100

Деметра: Node.js ты знаешь уверенно: event loop и кеш объяснил на примерах. Проседают данные — индексы и повторная доставка сообщений. Подтяни их, и следующее интервью пройдёт ровнее
Что подтянуть
- Как не обработать сообщение дважды: ключ идемпотентности и таблица обработанных
- Какой индекс ставить под запрос: B-tree, GIN, частичный
Что повторить
- Транзакционный outbox
- Уровни изоляции в PostgreSQL
Что получилось
- Event loop разобрал по фазам и сам привёл пример с промисом
- В кеше Redis назвал TTL, прогрев и что делать при промахе
По каждому вопросу
В каком порядке выполнятся setTimeout, setImmediate, process.nextTick и Promise.then?78 из 100
- Хорошо
- Назвал фазы event loop и объяснил, почему nextTick и промисы идут раньше таймеров
- Упущено
- Не сказал, что порядок setTimeout(0) и setImmediate в главном модуле не гарантирован
Как ответить
Сначала nextTick, потом микрозадачи промисов, дальше фазы цикла. Внутри колбэка ввода-вывода setImmediate всегда раньше setTimeout(0), а в главном модуле порядок зависит от того, успел ли истечь таймер
Запрос по таблице заказов тормозит. Какой индекс поставишь и как проверишь?52 из 100
- Хорошо
- Начал с EXPLAIN ANALYZE и посмотрел, есть ли Seq Scan
- Упущено
- Не выбрал тип индекса под условие и не вспомнил про составной индекс
Как ответить
Смотрю план и условие WHERE. Под равенство и диапазон — B-tree, порядок колонок по селективности. Под поиск по массиву или JSONB — GIN. Под фильтр по одному статусу — частичный индекс. После — снова EXPLAIN ANALYZE
Как сделать, чтобы заказ из Kafka не списал деньги дважды?46 из 100
- Хорошо
- Понял, что Kafka может доставить сообщение повторно
- Упущено
- Не сказал, где хранить отметку об обработке и как не потерять её при падении
Как ответить
Даю обработчику ключ идемпотентности, например id заказа. Списание и запись ключа в таблицу обработанных делаю в одной транзакции. Пришёл повтор — ключ уже есть, сообщение пропускаю
Когда кешировать в Redis и как не отдать устаревшие данные?70 из 100
- Хорошо
- Назвал TTL и сброс ключа при записи, привёл пример с карточкой товара
- Упущено
- Не упомянул, что при массовом промахе база получит всю нагрузку разом
Как ответить
Кеширую то, что читают чаще, чем меняют. Ключ сбрасываю при записи и ставлю TTL на случай пропуска. От лавины промахов — разброс TTL и блокировка на пересчёт одного ключа
Что будет, если в Express-обработчике бросить ошибку внутри async-функции?74 из 100
- Хорошо
- Знает, что Express 4 не ловит отклонённый промис сам
- Упущено
- Не сказал про unhandledRejection и что процесс в новых версиях Node.js упадёт
Как ответить
Express 4 не ловит отклонённый промис: нужна обёртка с next(err) или Express 5. Иначе сработает unhandledRejection, а в Node.js 15 и новее процесс упадёт
Две транзакции одновременно меняют остаток товара. Что может пойти не так?64 из 100
- Хорошо
- Описал потерянное обновление на примере двух покупок
- Упущено
- Не назвал SELECT FOR UPDATE и уровни изоляции
Как ответить
На READ COMMITTED обе прочитают один остаток и одна запись перетрёт другую. Лечится атомарным UPDATE с условием, SELECT FOR UPDATE или уровнем SERIALIZABLE с повтором транзакции
