Node.js
Экспресс-шпаргалка 20/20
- Event Loop проходит фазы
timers -> pending callbacks -> poll -> check -> close, аmicrotasks(Promise,nextTick) выполняются между фазами. - Streams выбирают для больших payload и непрерывных данных, чтобы не держать все в памяти и использовать backpressure.
Bufferнужен для бинарных данных: файлы, сокеты, криптография, кодировки.nextTickвыполняется раньше всего,setImmediateвcheck,setTimeoutвtimersпосле минимальной задержки.worker_threadsдля CPU-bound задач,clusterдля масштабирования HTTP-процесса по ядрам.- CommonJS (
require) проще для legacy, ESM (import) стандартнее и лучше для современного tooling. - Централизованный error handling: единый error schema, middleware/filters, correlation id и разделение 4xx/5xx.
- Graceful shutdown: stop accepting new requests -> drain active -> close DB/broker -> forced exit by timeout.
- От перегрузки защищают rate limit, очереди, таймауты, circuit breaker и ограничение параллелизма.
- Логи должны быть структурными (JSON), с
traceId/requestId, уровнями и метриками latency/error-rate. - Конфиг:
12-factor, fail-fast валидация env при старте, секреты только через secret manager. - Большие файлы обрабатывают stream/pipeline с лимитами размера, type-check и защитой от медленных клиентов.
healthпоказывает жив ли процесс,readinessготов ли сервис принимать трафик с учетом зависимостей.- JWT безопасен только с проверкой
alg, подписи,exp/aud/iss, ротацией ключей и коротким TTL access-токена. - Кэш ставят на read-heavy пути с TTL, стратегией инвалидации и защитой от cache stampede.
- WebSocket требует heartbeat/ping-pong, лимитов соединений, backpressure и стратегии reconnect.
- Утечки памяти ищут через heap snapshots, allocation profiling и сравнение роста heap во времени.
- ORM ускоряет CRUD, query builder/raw SQL нужен для сложных и критичных по perf запросов.
- N+1 лечат batching, joins/eager loading и измерением количества запросов на один API call.
- Backward compatibility достигают additive changes, versioning, deprecation window и контрактными тестами.
1. Как устроен Event Loop в Node.js и его фазы?
Теги: nodejs, backend, event-loop, async
Сложность: Middle/Senior
Короткий ответ
Node Event Loop обрабатывает callback-очереди по фазам: timers -> pending callbacks -> poll -> check -> close callbacks, а microtasks выполняются между фазами.
Что сказать на интервью (30-60 секунд)
- Где это применяется: Критично для API-сервисов, фоновых обработчиков, BFF и интеграций с внешними системами.
- Главный риск: CPU-bound операции в request path блокируют Event Loop и увеличивают latency для всех пользователей.
- Как проверяете решение: Проверяю сценарий под пиковым трафиком: latency, saturation и поведение при деградации зависимости.
Мини-пример
console.log('A');
setTimeout(() => console.log('timer'), 0);
setImmediate(() => console.log('immediate'));
process.nextTick(() => console.log('nextTick'));
Углубление (2-3 минуты)
- Свяжите тему "Как устроен Event Loop в Node.js и его фазы?" с одним production-сценарием и объясните, почему она влияет на результат.
- Покажите, какие сигналы observability подтверждают устойчивость решения.
- Сформулируйте ключевой trade-off и объясните, как решение масштабируется на уровне системы.
Типичные ошибки
- Держат тяжелую обработку в синхронном request path.
- Запускают изменения без наблюдаемости и runbook.
- Путают соседние концепции и не обозначают границы применимости выбранного подхода.
Follow-up вопросы
- Что вынесете в фон, чтобы не блокировать critical path?
- Какие метрики покажут деградацию раньше инцидента?
- Какой trade-off на уровне архитектуры здесь самый критичный?
Что повторить
- Runbook деградации внешней зависимости.
- Health/readiness и корреляцию логов/метрик.
- Пройдите 2-3 связных вопроса в Банке вопросов и проверьте устойчивость ответа.
Связанные модули и карта
2. Когда использовать Streams вместо чтения файла целиком?
Теги: nodejs, backend, streams
Сложность: Middle/Senior
Короткий ответ
Streams применяют для больших или непрерывных данных, чтобы читать/писать чанками и не держать весь payload в памяти.
Что сказать на интервью (30-60 секунд)
- Где это применяется: Критично для API-сервисов, фоновых обработчиков, BFF и интеграций с внешними системами.
- Главный риск: Неправильная обработка backpressure приводит к росту памяти и нестабильности процесса.
- Как проверяете решение: Прогоняю нагрузочный кейс, фиксирую лимиты (timeout/concurrency/retry) и проверяю стабильность сервиса.
Мини-пример
import { createReadStream } from 'node:fs';
createReadStream('./big.log').pipe(process.stdout);
Углубление (2-3 минуты)
- Свяжите тему "Когда использовать Streams вместо чтения файла целиком?" с одним production-сценарием и объясните, почему она влияет на результат.
- Покажите, какие сигналы observability подтверждают устойчивость решения.
- Сформулируйте ключевой trade-off и объясните, как решение масштабируется на уровне системы.
Типичные ошибки
- Запускают изменения без наблюдаемости и runbook.
- Не ограничивают ресурсы (конкурентность, очередь, таймауты).
- Путают соседние концепции и не обозначают границы применимости выбранного подхода.
Follow-up вопросы
- Что вынесете в фон, чтобы не блокировать critical path?
- Как поведение изменится под пиковым трафиком?
- Какой trade-off на уровне архитектуры здесь самый критичный?
Что повторить
- Runbook деградации внешней зависимости.
- Health/readiness и корреляцию логов/метрик.
- Пройдите 2-3 связных вопроса в Банке вопросов и проверьте устойчивость ответа.
Связанные модули и карта
3. Что такое Buffer и где он нужен?
Теги: nodejs, backend, buffer
Сложность: Middle/Senior
Короткий ответ
Buffer - бинарный контейнер памяти в Node для работы с байтами, сетевыми пакетами и файлами.
Что сказать на интервью (30-60 секунд)
- Где это применяется: Критично для API-сервисов, фоновых обработчиков, BFF и интеграций с внешними системами.
- Главный риск: Отсутствие лимитов, таймаутов и наблюдаемости в Node-сервисе ведет к каскадным инцидентам под нагрузкой.
- Как проверяете решение: Сверяю поведение по runbook: детектирование, mitigation и проверка восстановления после сбоя.
Мини-пример
const payload = Buffer.from('hello', 'utf8');
console.log(payload.toString('hex'));
Углубление (2-3 минуты)
- Свяжите тему "Что такое Buffer и где он нужен?" с одним production-сценарием и объясните, почему она влияет на результат.
- Покажите, какие сигналы observability подтверждают устойчивость решения.
- Сформулируйте ключевой trade-off и объясните, как решение масштабируется на уровне системы.