Вопросы по Node.js и бэкенд
Поймёшь, как устроен Node.js изнутри и как на нём пишут бэкенд: event loop и libuv, потоки, фреймворки, ошибки, масштабирование и безопасность. Ровно то, что спрашивают на бэкенд-секции.
Проверьте себя: тест по Node.js и бэкенд
20 вопросов, 10 минут, уровень junior, middle или senior
Event loop и libuv
Фазы event loop, микрозадачи, process.nextTick, setImmediate и пул потоков libuv.
Урок: Event loop в Node.js и libuv 7 мин- Тяжёлый цикл без блокировки event loop
- Код-ревью: что блокирует event loop
- Что блокирует event loop
- Объясни event loop в Node.js
- setImmediate и setTimeout внутри I/O
- setTimeout(0) против setImmediate на верхнем уровне
- Что такое libuv
- Рекурсивный process.nextTick
Ещё 14 вопросов и задач
- process.nextTick и setImmediate
- Event loop Node и браузера: в чём разница
- Порядок nextTick, промиса и setTimeout
- Что выведет: await, nextTick и setImmediate
- Что выведет: nextTick, промис, таймер, immediate
- Порядок фаз event loop
- Когда Node.js завершает процесс
- nextTick внутри промиса
- UV_THREADPOOL_SIZE
- Размер пула потоков libuv
- Что уходит в пул потоков libuv
- p99 вырос в 10 раз, CPU 40%: как ищешь причину
- setImmediate и setTimeout внутри I/O-колбэка
- Что на самом деле идёт в пул потоков libuv
Модули и npm
CommonJS и ES-модули, разрешение путей, require(esm) в Node 22, поле exports в package.json.
Урок: CommonJS и ES-модули в Node.js 6 мин- Порядок инициализации модулей и поиск цикла
- Разрешение поля exports в package.json
- semver: проверка ^ и ~ диапазонов
- CommonJS и ESM коротко
- Циклический require
- __dirname в ES-модуле
- Dual package hazard
- Импорт CommonJS из ESM
Ещё 11 вопросов и задач
- Чем CommonJS отличается от ES-модулей
- Поле exports в package.json
- exports = {} в CommonJS
- Живые привязки в ESM
- Префикс node:
- Как опубликовать библиотеку для ESM и CJS
- Сколько раз выполнится модуль
- require() для ES-модуля в Node 22
- Как Node понимает, что .js это ESM
- Циклический require в CommonJS
- require(esm) в Node 22
Потоки и буферы
Readable, Writable, Transform, backpressure, pipeline и Buffer.
Урок: Потоки и буферы в Node.js 7 мин- Пачки из асинхронного итератора
- Разбиение потока на строки по чанкам
- Запись с учётом backpressure
- Итоги платежей из CSV-выгрузки
- Слияние k отсортированных логов
- Топ эндпоинтов по access-логу с нормализацией маршрутов
- Сессии пользователей по потоку событий
- Код-ревью: выгрузка и загрузка больших файлов
Ещё 16 вопросов и задач
- Загрузка файлов по 5 ГБ через Node-сервис
- Чем pipeline лучше pipe
- Buffer.allocUnsafe
- Backpressure
- write() вернул false
- Как отдать большой файл по HTTP
- Что такое Buffer
- Длина строки и длина буфера
- Как импортировать CSV на 10 ГБ
- Объясни потоки и backpressure
- Виды потоков
- highWaterMark по умолчанию
- Чем pipeline лучше pipe
- subarray копирует или нет
- Какой это тип потока
- Склейка текста из чанков
Файлы и процессы
fs с промисами, пути, child_process, переменные окружения, сигналы и коды выхода.
Урок: Файлы, пути и процессы в Node.js 6 мин- spawn, exec, execFile, fork: что когда
- Загрузка .env без dotenv
- Тип значений process.env
- Инъекция команд через exec
- existsSync перед открытием
- Коды выхода процесса
- Зачем child_process.fork
- Как сделать graceful shutdown
Ещё 12 вопросов и задач
- path.join и path.resolve
- process.exit и незавершённые операции
- Относительный путь в fs
- Какой сигнал нельзя перехватить
- Graceful shutdown
- spawn и exec: в чём разница
- Разбор аргументов командной строки
- Парсер .env-файла
- Защита от path traversal при раздаче файлов
- Код-ревью: конвертация файлов через внешнюю утилиту
- exec, spawn и большой вывод
- Node как PID 1 в контейнере
HTTP-сервер, Express, NestJS
Модуль http, middleware в Express, модули и DI в NestJS, жизненный цикл запроса.
Урок: HTTP-сервер, Express и NestJS 8 мин- req.body равен undefined
- Dependency Injection
- Как устроить обработку ошибок в API
- Как Express узнаёт обработчик ошибок
- Express или NestJS: что выбрать
- Ошибки async-обработчиков в Express 5
- Почему Fastify быстрее Express
- Guard и Pipe в NestJS
Ещё 17 вопросов и задач
- ERR_HTTP_HEADERS_SENT
- Что такое middleware
- Порядок middleware в Express
- Порядок обработки запроса в NestJS
- Состояние в сервисе NestJS
- Тело запроса в node:http
- Content negotiation по заголовку Accept
- compose: цепочка middleware как в Koa
- Курсорная пагинация по (created_at, id)
- Ошибки домена в HTTP-ответ (problem+json)
- Разбор query string с повторяющимися ключами
- Роутер: сопоставление пути и параметров
- Валидация тела запроса по схеме
- Код-ревью: Express-эндпоинт заказа
- Случайные 502 за балансировщиком
- Путь запроса в NestJS
- Request-scoped провайдеры в NestJS
Асинхронные паттерны
Колбэки, промисы, async/await, ограничение параллелизма, отмена через AbortController, EventEmitter.
Урок: Асинхронные паттерны в Node.js 7 мин- AbortSignal.timeout
- AbortController
- Promise.all или Promise.allSettled
- Promise.any, когда всё упало
- Колбэки, промисы и async/await
- Ограничение параллелизма
- Как обработать 10 000 URL не больше чем по 10 за раз
- Событие error без слушателя
Ещё 21 вопрос или задача
- Error-first callback
- EventEmitter синхронный или нет
- forEach с async-колбэком
- Что выведет: await, then, nextTick и таймер
- Что выведет: микрозадачи внутри таймера
- Executor промиса выполняется сразу
- Таймаут через Promise.race
- return промиса без await внутри try
- Последовательные await и Promise.all
- Прерываемый sleep с AbortSignal
- Расписание экспоненциального backoff
- Свой EventEmitter: on, off, once, emit
- mapLimit: параллельная обработка с ограничением
- retry с backoff и фильтром ошибок
- Семафор для ограничения доступа к ресурсу
- singleFlight: склейка одинаковых запросов
- withTimeout: дедлайн для промиса
- Код-ревью: рассылка уведомлений
- AsyncLocalStorage для контекста запроса
- Отмена работы, когда клиент ушёл
- Необработанный отклонённый промис в Node 22
Ошибки и логирование
Операционные и программные ошибки, unhandledRejection, graceful shutdown, структурные логи.
Урок: Ошибки и логирование в Node.js 7 мин- Опция cause у Error
- Обработчик ошибок в Express
- Что нельзя писать в лог
- Как устроить логирование в продакшене
- Операционные и программные ошибки
- Операционная или программная ошибка
- Request id через всю цепочку
- Как ты обрабатываешь ошибки в Node-сервисе
Ещё 15 вопросов и задач
- Структурные логи
- name у наследника Error
- try/catch и ошибка в setTimeout
- Что делать в uncaughtException
- unhandledRejection
- Необработанный rejected промис в Node 22
- Статистика по access-логу: коды и p95
- Circuit breaker: closed, open, half-open
- Цепочка причин ошибки (error.cause)
- Graceful shutdown: дождаться запросов в работе
- Структурный лог с маскированием секретов
- Код-ревью: обработка ошибок в сервисе
- Что можно делать в process.on("exit")
- Почему логирование может тормозить сервис
- Сквозная трассировка запроса между сервисами
Кластер, воркеры, масштабирование
cluster, worker_threads, горизонтальное масштабирование, stateless-сервисы и балансировка.
Урок: Кластер, воркеры и масштабирование Node.js 7 мин- Консистентное хеширование с виртуальными узлами
- Балансировка least connections
- Плавный взвешенный round-robin как в nginx
- Код-ревью: сервис перед масштабированием в 4 инстанса
- Модуль cluster
- cluster внутри Kubernetes
- Память у воркеров cluster
- cluster или worker_threads
Ещё 13 вопросов и задач
- setInterval-крон при нескольких экземплярах
- Флаг --max-old-space-size
- Как Node.js использует несколько ядер
- Нагрузка выросла в 10 раз: что делаешь
- Что мешает горизонтальному масштабированию
- Stateless-сервис
- WebSocket на нескольких экземплярах
- worker_threads
- Передача данных в worker_threads
- Ускорят ли воркеры запросы к базе
- Утечка памяти в проде: план действий
- Обмен данными с worker_threads
- worker_threads или cluster для CPU-задачи
Безопасность бэкенда
Инъекции, хранение паролей, rate limiting, секреты, заголовки безопасности и зависимости.
Урок: Безопасность бэкенда на Node.js 8 мин- Безопасный INSERT: параметры и белый список колонок
- CORS: проверка Origin по белому списку
- Проверка claims JWT после подписи
- deepMerge без prototype pollution
- Rate limiter на token bucket
- Кто превысил лимит запросов: скользящее окно
- Код-ревью: регистрация, вход и сброс пароля
- Как защитить Node.js API
Ещё 16 вопросов и задач
- Mass assignment
- NoSQL-инъекция в MongoDB
- Как хранить пароли
- Path traversal
- Prototype pollution через merge
- Rate limit на нескольких экземплярах
- Rate limiting
- ReDoS
- Соль в хешировании паролей
- Секрет попал в git: что делать
- Как исправить SQL-инъекцию
- SSRF
- Сравнение секретов
- Защита от SSRF в загрузке по URL
- Безопасность зависимостей npm
- Сравнение секретов и timing attack
Кеш и очереди
Redis, стратегии кеширования и инвалидации, очереди задач, ретраи и идемпотентность.
Урок: Кеш и очереди в Node-бэкенде 8 мин- At-least-once и идемпотентность
- Как работает cache-aside
- Как ты добавишь кеш в сервис
- Dead letter queue
- Идемпотентный обработчик
- Удалить ключ или обновить при изменении
- KEYS * в проде
- Transactional outbox
Ещё 16 вопросов и задач
- Атомарный счётчик в Redis
- Redis кончилась память
- Как повторять упавшие задачи
- Cache stampede
- Jitter для TTL
- Зачем очередь и как сделать её надёжной
- Cache-aside с отрицательным кешированием
- Батчинг запросов как в DataLoader
- Идемпотентный обработчик по Idempotency-Key
- Очередь задач с ретраями и dead letter
- LRU-кеш с TTL
- Дедупликация событий из NDJSON-потока
- Код-ревью: кеш профиля в Redis
- Отложенные задачи: напоминание через 24 часа
- Exactly-once при обработке сообщений
- Лавина на популярном ключе кеша