Node.js Core & Runtime
Event Loop
- Кратко: Event Loop — это однопоточный механизм Node.js, который управляет выполнением асинхронных операций, обрабатывая задачи из очередей событий и переходя между различными фазами. Он постоянно работает, пока есть задачи, или приложение активно слушает соединения; в противном случае процесс завершается.
- Почему спрашивают на собеседовании: Проверяет фундаментальное понимание архитектуры Node.js, способность объяснить, как асинхронность работает под капотом, и выявлять узкие места производительности.
- Хитрости/подводные камни:
- Блокировка Event Loop: Длительные синхронные CPU-bound операции (например, тяжелое хеширование паролей в цикле) или слишком большое количество запросов, превышающее пропускную способность, могут привести к блокировке единственного потока Event Loop, вызывая зависание приложения, деградацию производительности и даже уязвимость для DDoS-атак.
- Различия от браузера: Event Loop в Node.js имеет свои специфические фазы и взаимодействие с
libuv, что отличается от реализации в браузере. В Node.js Event Loop базируется на дескрипторах файлов, что может приводить к различиям на разных ОС. - Непредсказуемая точность: Node.js не предназначен для высокоточных временных операций (например, микросекунд), что делает его неподходящим для систем высокочастотной торговли.
- Что важно не забыть:
- V8 и
libuvкак основные компоненты. - Однопоточность Event Loop.
- Фазы Event Loop (Next Tick, Microtask, Poll, Timers, Check, Close Callbacks и т.д.) и их приоритеты.
- Механизм обработки задач (стек вызовов -> Event Loop -> очереди).
- Что происходит, если нет задач (
System Exit). - Worker Threads для тяжелых задач.
process.nextTickимеет высший приоритет, чем промисы иsetImmediate.
- V8 и
- Быстрый чек-лист ответа синьора:
- Однопоточная природа и ее последствия (блокировка).
- Различие между Micro- и Macro-тасками.
- Упоминание
libuvи ее роли (пул потоков для I/O, криптографии). - Объяснение, как блокировка Event Loop влияет на приложение.
- Важность Worker Threads для CPU-bound задач.
- Мини-пример/паттерн кода (если уместно): (не было в источниках, кроме описания логики
process.nextTickиsetTimeout) - Источники:
- Приоритет на собесе: Высокий
- Сложность: Продвинутая
- Уверенность в корректности (по материалам): 95%
Параллелизм и Worker Threads
- Кратко: Хотя Event Loop в Node.js однопоточный, платформа предоставляет механизмы для достижения параллелизма, такие как Worker Threads (официальный API) или создание дочерних процессов (
child_process,fork), которые выполняют задачи в отдельных потоках или процессах. - Почему спрашивают на собеседовании: Проверяет понимание ограничений однопоточной среды и способность эффективно использовать доступные инструменты для повышения производительности и масштабирования приложения, особенно для CPU-bound задач.
- Хитрости/подводные камни:
- Путаница с
libuv: Worker Threads, предоставляемые Node.js API, отличаются от внутреннего пула потоковlibuv, который используется для асинхронного I/O и криптографии. - Накладные расходы: Создание и управление Worker Threads имеет свои накладные расходы, поэтому их использование должно быть обоснованным для действительно тяжелых задач.
- Путаница с
- Что важно не забыть:
- Event Loop однопоточный, но Node.js может быть многопоточным или многопроцессным.
- Worker Threads используются для CPU-bound задач, чтобы не блокировать Event Loop.
- Могут быть использованы
child_process,fork,worker_threads. - Есть возможность создавать C++ аддоны для
libuvдля специфических задач.
- Быстрый чек-лист ответа синьора:
- Различие между Event Loop и Worker Threads.
- Сценарии использования Worker Threads (CPU-bound).
- Механизмы создания (API) и управления потоками.
- Связь с проблемой блокировки Event Loop.
- Мини-пример/паттерн кода (если уместно): (не было в источниках)
- Источники:
- Приоритет на собесе: Высокий
- Сложность: Продвинутая
- Уверенность в корректности (по материалам): 90%
V8
- Кратко: V8 — это высокопроизводительный движок JavaScript и WebAssembly с открытым исходным кодом, разработанный Google, который является основным компонентом Node.js, преобразуя JavaScript код в машинный код для выполнения.
- Почему спрашивают на собеседовании: Проверяет базовое понимание внутренней работы Node.js и его связь с экосистемой JavaScript.
- Хитрости/подводные камни: (не было в источниках)
- Что важно не забыть:
- Разработан Google.
- Преобразует JS в машинный код.
- Является частью Node.js.
- Быстрый чек-лист ответа синьора:
- Роль V8 в Node.js (компиляция JS).
- Основной компонент платформы.
- Мини-пример/паттерн кода (если уместно): (не было в источниках)
- Источники:
- Приоритет на собесе: Базовый
- Сложность: Базовая
- Уверенность в корректности (по материалам): 90%
Backend Architecture & Scalability
Масштабирование (горизонтальное vs вертикальное)
- Кратко: Масштабирование — это способность системы увеличивать свою производительность. Вертикальное масштабирование (scale up) — увеличение ресурсов одного сервера (CPU, RAM). Горизонтальное масштабирование (scale out) — добавление новых экземпляров (реплик) приложения для распределения нагрузки.
- Почему спрашивают на собеседовании: Проверяет архитектурное мышление, способность проектировать отказоустойчивые и высокопроизводительные системы, а также выбирать адекватные стратегии роста приложения.
- Хитрости/подводные камни:
- Ограничения вертикального масштабирования: Вертикальное масштабирование имеет физические и технические пределы (например, Node.js плохо работает с очень большими объемами RAM). Часто достигает потолка быстрее, чем горизонтальное.
- Масштабируемость vs Гибкость: Масштабируемость — это увеличение ресурсов, а гибкость — это способность системы как увеличиваться, так и уменьшаться пропорционально нагрузке.
- Ошибочная терминология: Иногда путают добавление новых инстансов (виртуальных машин) в облаке с вертикальным масштабированием, хотя это, по сути, форма горизонтального масштабирования.
- Что важно не забыть:
- Горизонтальное: добавление реплик, балансировщик нагрузки.
- Вертикальное: увеличение CPU/RAM на существующем инстансе.
- Важно для высоконагруженных систем (например, доставка еды перед праздниками).
Kubernetesиспользуется для горизонтального масштабирования.
- Быстрый чек-лист ответа синьора:
- Четкое разделение понятий.
- Примеры инструментов для каждого типа (Kubernetes, балансировщики).
- Ограничения вертикального масштабирования.
- Применимость к различным типам нагрузок (чтение/запись).
- Мини-пример/паттерн кода (если уместно): (не было в источниках)
- Источники:
- Приоритет на собесе: Высокий
- Сложность: Продвинутая
- Уверенность в корректности (по материалам): 95%
API Design (REST, GraphQL, gRPC)
- Кратко: REST (Representational State Transfer) — архитектурный стиль для распределенных систем, использующий HTTP-методы и URL для манипуляции ресурсами. GraphQL — язык запросов данных и среда выполнения, позволяющая клиенту точно определить, какие данные ему нужны. gRPC — высокопроизводительный фреймворк RPC (Remote Procedure Call) для создания распределенных служб.
- Почему спрашивают на собеседовании: Проверяет знание различных подходов к проектированию API, их преимущества и недостатки, а также способность выбирать подходящую технологию для конкретного сценария.
- Хитрости/подводные камни:
- Ограничения REST:
- Таймауты: Ограничения по времени (по умолчанию 2.5 минуты, но прокси/балансировщики могут обрезать раньше) могут быть проблемой для длительных операций или микросервисных коммуникаций.
- HTTP как транспорт: Передача смысла сообщения через HTTP-глаголы (GET, POST) на транспортном уровне может быть неоптимальной и ограничивать уникальность протокола.
- Избыточность данных (over-fetching): Клиент получает больше данных, чем ему нужно, что увеличивает сетевую нагрузку.
- Сложность GraphQL:
- Кэширование: По умолчанию GraphQL плохо кэшируется HTTP-механизмами из-за использования POST-запросов, что требует более сложных кастомных стратегий кэширования.
- Сложность поддержки: Требует более глубокого погружения команды в нюансы работы и потенциально более сложен в поддержке и доработке.
- Интеграция с React: В источниках упоминаются сложности с React State Manager при работе с GraphQL. ⚠️ Разночтения: В одном источнике упоминались сложности с интеграцией React и GraphQL, в то время как другое предположение от интервьюера гласило, что это, возможно, была неверная реализация, и React с GraphQL могут хорошо работать вместе.
- Ограничения REST:
- Что важно не забыть:
- REST: Стабилен, широко известен, подходит для веб-приложений.
- GraphQL: Уменьшает сетевую нагрузку (мобильные, IoT), клиент запрашивает только нужные данные.
- gRPC: Высокая производительность, стриминг (для RPC).
- Принципы REST: Клиент-сервер, stateless, cacheable, uniform interface, layered system, code-on-demand.
- HTTP-методы: GET, POST, PUT, PATCH, DELETE, OPTIONS (для обновлений PUT для полной замены, PATCH для частичной, но на практике есть разночтения).
- Быстрый чек-лист ответа синьора:
- Сравнение REST и GraphQL по over-fetching/under-fetching.
- Упоминание таймаутов как ограничения REST.
- Сложности кэширования GraphQL.
- Когда какой подход предпочтительнее (мобильные vs веб, микросервисы).
- Мини-пример/паттерн кода (если уместно): (не было в источниках)
- Источники:
- Приоритет на собесе: Высокий
- Сложность: Продвинутая
- Уверенность в корректности (по материалам): 90%
Базы данных (SQL vs NoSQL, выбор СУБД, ACID)
- Кратко: SQL (реляционные) базы данных (например, PostgreSQL, MySQL) используют структурированные таблицы, транзакции, индексы и язык SQL, подходящие для строгого хранения данных со связями. NoSQL (нереляционные) базы данных (например, MongoDB) предлагают более гибкую, неструктурированную модель (коллекции документов) и часто используются для больших объемов неструктурированных данных или быстрого доступа. ACID (Atomicity, Consistency, Isolation, Durability) — свойства, гарантирующие надежность транзакций.
- Почему спрашивают на собеседовании: Проверяет знание основ работы с данными, способность выбирать подходящие СУБД для конкретных задач, а также проектировать надежные и масштабируемые хранилища данных.
- Хитрости/подводные камни:
- Выбор СУБД: Выбор должен зависеть от конкретных потребностей микросервиса или приложения. Например, MongoDB для парсеров с неструктурированными данными, PostgreSQL для важных структурированных данных, ClickHouse для быстрых колоночных данных (аналитика).
- Транзакции в NoSQL: Исторически у MongoDB не было полноценных транзакций, но в последних версиях они появились.
- Проблемы с транзакциями в микросервисах: В распределенных системах (микросервисах) реализация транзакций сложна: подход Saga может привести к потере изолированности, а Two-Phase Commit создает узкое горлышко (координатор, который замедляет процесс).
- Производительность транзакций: Слишком большое количество транзакций или высокие уровни изоляции (например, Serializable) могут сильно замедлить систему.
- Что важно не забыть:
- ACID: Atomicity (все или ничего), Consistency (согласованность данных до и после транзакции), Isolation (транзакции не мешают друг другу), Durability (данные сохраняются надежно).
- SQL: Язык запросов, транзакции, индексы.
- NoSQL: Коллекции, неструктурированный подход.
- Проблемы с транзакциями в распределенных системах.
- Выбор СУБД должен обосновываться требованием к данным (структура, объем, важность).
- Быстрый чек-лист ответа синьора:
- Знание ACID и умение объяснить каждый пункт.
- Отличия SQL от NoSQL.
- Когда используется Postgres, Mongo, ClickHouse.
- Понимание сложностей транзакций в микросервисах.
- Мини-пример/паттерн кода (если уместно): (не было в источниках)
- Источники:
- Приоритет на собесе: Высокий
- Сложность: Продвинутая
- Уверенность в корректности (по материалам): 95%
Микросервисы
- Кратко: Микросервисы — это архитектурный подход, при котором приложение разбивается на набор небольших, слабо связанных сервисов, каждый из которых выполняет свою бизнес-функцию и может быть разработан, развернут и масштабирован независимо.
- Почему спрашивают на собеседовании: Проверяет понимание современной архитектуры, способности проектировать распределенные системы, управлять их сложностью и решать возникающие проблемы.
- Хитрости/подводные камни:
- Транзакции: Сложности с распределенными транзакциями (см. "Базы данных"), подходы Saga и Two-Phase Commit имеют свои недостатки.
- Сложность развертывания и управления: Требует инструментов оркестрации, таких как Kubernetes.
- Сложность мониторинга и отладки: Распределенная система усложняет трассировку запросов и поиск проблем.
- Накладные расходы на коммуникацию: Сетевые задержки, проблемы доступности других сервисов.
- Onboarding: Трудно для новых членов команды воспринимать общую картину.
- Что важно не забыть:
- Разбиение монолита на мелкие сервисы.
- Независимая разработка, развертывание и масштабирование.
- Проблемы с распределенными транзакциями.
- Необходимость оркестрации (Kubernetes) и мониторинга (Prometheus, Grafana).
- Важность паттерна репозитория для абстракции работы с базой данных.
- Быстрый чек-лист ответа синьора:
- Плюсы и минусы микросервисов.
- Методы решения проблемы транзакций (Saga, 2PC) и их недостатки.
- Инструменты для развертывания (Docker, Kubernetes).
- Важность принципов SOLID при декомпозиции.
- Мини-пример/паттерн кода (если уместно): (не было в источниках, кроме описания архитектурных решений)
- Источники:
- Приоритет на собесе: Высокий
- Сложность: Продвинутая
- Уверенность в корректности (по материалам): 90%
ORM / ODM
- Кратко: ORM (Object-Relational Mapper) или ODM (Object-Document Mapper) — это инструменты, которые позволяют разработчикам взаимодействовать с базами данных, используя привычные объекты языка программирования (например, JavaScript/TypeScript), вместо прямого написания SQL-запросов. Примеры включают TypeORM, Prisma.
- Почему спрашивают на собеседовании: Проверяет знание инструментов, повышающих продуктивность и безопасность работы с базами данных, а также понимание их преимуществ и недостатков.
- Хитрости/подводные камни:
- Безопасность: Главное преимущество ORM/ODM — защита от SQL-инъекций благодаря использованию Prepared Statements, которые экранируют параметры запросов. Прямое написание SQL в коде крайне опасно без тщательного экранирования.
- Производительность: ORM/ODM могут быть менее производительными для очень сложных или специфических запросов по сравнению с нативным SQL. Однако, для большинства случаев выигрыш в скорости разработки и безопасности перевешивает.
- Проблемы с миграциями: В источниках упоминались проблемы с TypeORM и версиями Node.js при создании миграций.
- Абстракция: Важно, чтобы сервис не знал напрямую, с какой базой данных он работает. ORM/ODM (через паттерн репозитория) помогают в этом, позволяя легко менять СУБД.
- Что важно не забыть:
- Безопасность: Защита от SQL-инъекций.
- Удобство: Работа с объектами, а не с SQL-строками.
- Миграции: Управление изменениями схемы базы данных.
- Инструменты: TypeORM, Prisma, Mongoose (не упомянут явно как ODM, но как DB).
- Паттерн репозитория: Использование ORM через репозитории для лучшей архитектуры.
- Быстрый чек-лист ответа синьора:
- ORM как решение проблемы безопасности (SQL-инъекции).
- Удобство работы с объектами.
- Упоминание Prepared Statements.
- Компромисс производительность/скорость разработки.
- Мини-пример/паттерн кода (если уместно): (не было в источниках, кроме описания использования TypeORM для схем)
- Источники:
- Приоритет на собесе: Высокий
- Сложность: Продвинутая
- Уверенность в корректности (по материалам): 95%
Кэширование
- Кратко: Кэширование — это процесс хранения копий данных в быстродоступном месте для более быстрого доступа к ним в будущем. Используется для оптимизации производительности и уменьшения нагрузки на основные источники данных. Примеры включают Redis, CDN.
- Почему спрашивают на собеседовании: Проверяет способность оптимизировать производительность системы, уменьшать задержки и повышать пропускную способность за счет эффективного использования кэша.
- Хитрости/подводные камни:
- Согласованность данных (Cache Invalidation): Главная проблема кэширования — устаревание данных. Нужно иметь стратегии для обновления кэша, чтобы клиенты получали актуальную информацию. Для очень критичных данных предпочтительнее репликация, а не кэширование.
- Кэширование на стороне браузера: Разработчик должен понимать, как браузер кэширует данные (например, локальное хранилище), поскольку это влияет на запросы к серверу.
- GraphQL и кэширование: GraphQL по умолчанию плохо кэшируется стандартными HTTP-механизмами, что требует реализации сложных кастомных политик кэширования.
- Что важно не забыть:
- Цель кэширования: ускорение доступа, снижение нагрузки.
- Инструменты: Redis (для временных данных), CDN (распределенные по регионам).
- Проблема согласованности данных.
- Стратегии кэширования (по времени жизни, по частоте использования - LRU/LFU).
- Разделение кэширования на стороне бэкенда и браузера.
- Быстрый чек-лист ответа синьора:
- Объяснение цели кэширования.
- Инструменты (Redis).
- Главная проблема кэширования — инвалидация/согласованность.
- Различия в кэшировании для REST и GraphQL.
- Мини-пример/паттерн кода (если уместно): (не было в источниках)
- Источники:
- Приоритет на собесе: Средний
- Сложность: Продвинутая
- Уверенность в корректности (по материалам): 90%
Оптимизация запросов к базе данных
- Кратко: Оптимизация запросов к БД — это процесс улучшения производительности запросов для более быстрого получения и обработки данных. Включает правильное использование индексов, разбиение больших запросов, шардирование и репликацию баз данных, а также оптимизацию типов данных.
- Почему спрашивают на собеседовании: Проверяет способность решать проблемы производительности, связанные с данными, и применять методы для обеспечения быстрой и эффективной работы приложения с БД.
- Хитрости/подводные камни:
- Отсутствие индексов: Медленный поиск по неиндексированным полям, особенно в больших таблицах (например, 4 ТБ). Добавление индекса на большую таблицу может быть дорогим и долгим.
- Фильтрация на уровне приложения: Фильтрация больших объемов данных на уровне Node.js-приложения вместо уровня БД сильно нагружает сервер и замедляет работу.
- Большие JOIN-ы: Сложные запросы со множеством JOIN-ов могут быть крайне неэффективными.
- Накладные расходы индексов: Индексы ускоряют чтение, но замедляют запись и обновление. Для систем с интенсивной записью может потребоваться разделение базы на read-only и write-only части.
- Неэффективные типы данных: Использование, например,
VARCHAR(128)вместоINTилиBOOLEANдля статусов может привести к значительному увеличению размера базы данных (сотни ГБ на миллионах записей).
- Что важно не забыть:
- Индексы: Создавать по часто используемым полям, составные индексы.
- Фильтрация на уровне БД: Использовать агрегации (MongoDB pipeline) или вложенные запросы для поэтапной фильтрации, сначала по индексированным полям.
- Репликация и шардирование: Для распределения нагрузки чтения/записи.
- Оптимизация запросов: Уменьшать количество запрашиваемых данных, упрощать JOIN-ы. Использовать
EXPLAINдля анализа запросов. - Оптимизация типов данных: Выбирать наиболее компактные и эффективные типы данных для колонок.
- DB Views: Заранее заготовленные функции/результаты запросов.
- Пул соединений: Увеличивать количество соединений к БД для обработки параллельных запросов.
- Быстрый чек-лист ответа синьора:
- Роль индексов и их влияние на запись/чтение.
- Фильтрация и агрегация на стороне БД.
- Шардирование/репликация для масштабирования.
- Оптимизация типов данных для экономии места.
- Использование
EXPLAINдля анализа запросов.
- Мини-пример/паттерн кода (если уместно): (не было в источниках, кроме описания логики агрегации MongoDB)
- Источники:
- Приоритет на собесе: Средний
- Сложность: Продвинутая
- Уверенность в корректности (по материалам): 95%
JavaScript Fundamentals (Context of Node.js)
Сборщик мусора (Garbage Collector)
- Кратко: Garbage Collector в JavaScript — это механизм автоматического управления памятью, который автоматически определяет и удаляет из памяти объекты, на которые больше нет активных ссылок, освобождая ресурсы.
- Почему спрашивают на собеседовании: Проверяет глубокое понимание работы JavaScript, включая управление памятью, и способность предотвращать утечки памяти в Node.js приложениях.
- Хитрости/подводные камни:
- Циклические ссылки: Современные сборщики мусора в JavaScript (например, V8) способны корректно обрабатывать объекты, которые ссылаются сами на себя, если на них нет ссылок из глобального контекста.
- Утечки памяти: Объекты могут оставаться в памяти, если на них сохраняются неявные ссылки (например, через замыкания, глобальные переменные, Event Listeners), даже если они больше не нужны.
- WeakMap/WeakSet: Могут быть использованы для хранения ссылок на объекты таким образом, чтобы не мешать сборщику мусора, если ключ не имеет других ссылок.
- Что важно не забыть:
- Автоматическое управление памятью.
- Удаление неиспользуемых объектов (нет ссылок).
- Способность обрабатывать циклические ссылки.
- Понятия Heap (куча).
- Быстрый чек-лист ответа синьора:
- Цель Garbage Collector.
- Как он определяет "мусор".
- Понимание работы с циклическими ссылками.
- Упоминание WeakMap/WeakSet.
- Мини-пример/паттерн кода (если уместно): (не было в источниках)
- Источники:
- Приоритет на собесе: Средний
- Сложность: Продвинутая
- Уверенность в корректности (по материалам): 90%
ООП и принципы SOLID
- Кратко: ООП (Объектно-ориентированное программирование) — это парадигма программирования, основанная на концепции "объектов". SOLID — это набор из пяти принципов (Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, Dependency Inversion), которые помогают создавать гибкие, масштабируемые и легко поддерживаемые системы.
- Почему спрашивают на собеседовании: Проверяет знание архитектурных паттернов, способность писать чистый, поддерживаемый и расширяемый код, а также применять эти принципы при проектировании модулей и сервисов.
- Хитрости/подводные камни:
- Применимость: Принципы SOLID применимы не только к ООП, но и к другим парадигмам и общей архитектуре, например, к разделению функциональности в микросервисах.
- Нарушение SRP: Создание "толстых" контроллеров или функций, которые делают слишком много вещей, нарушает принцип единой ответственности, усложняя отладку и поддержку.
- Что важно не забыть:
- SRP (Single Responsibility Principle): Один класс/модуль/сервис должен отвечать за одну функцию.
- OCP (Open/Closed Principle): Расширяем, но не изменяем существующий код.
- LSP (Liskov Substitution Principle): Дочерние классы должны быть полностью взаимозаменяемы с родительскими.
- ISP (Interface Segregation Principle): Разделять интерфейсы по доменной логике.
- DIP (Dependency Inversion Principle): Высокоуровневые модули не должны зависеть от низкоуровневых, оба должны зависеть от абстракций.
- Быстрый чек-лист ответа синьора:
- Назвать все 5 принципов SOLID.
- Привести примеры применения каждого принципа.
- Объяснить, как SOLID помогает в создании поддерживаемого кода.
- Связь DIP с инъекцией зависимостей.
- Мини-пример/паттерн кода (если уместно): (не было в источниках, кроме описания принципов)
- Источники:
- Приоритет на собесе: Средний
- Сложность: Продвинутая
- Уверенность в корректности (по материалам): 95%
Замыкания (Closures)
- Кратко: Замыкание — это функция, которая запоминает (или "захватывает") переменные из своего лексического окружения (области видимости, в которой она была создана), даже после того как внешняя функция, где эти переменные были объявлены, завершила свое выполнение.
- Почему спрашивают на собеседовании: Проверяет глубокое понимание фундаментальных концепций JavaScript, его модели выполнения и способность писать функциональный код, избегая нежелательных побочных эффектов или утечек памяти.
- Хитрости/подводные камни:
- Неожиданное поведение: Непонимание того, как замыкания захватывают переменные по ссылке, может привести к неожиданным результатам, если переменная изменяется после создания замыкания.
- Утечки памяти: Чрезмерное или неправильное использование замыканий может привести к утечкам памяти, если замкнутая функция удерживает ссылки на большие объекты, которые иначе были бы собраны сборщиком мусора.
- Что важно не забыть:
- Функция внутри функции.
- Доступ к переменным внешней функции.
- Переменные "живут" после завершения внешней функции.
- Создает свою область видимости.
- Быстрый чек-лист ответа синьора:
- Определение замыкания.
- Пример создания области видимости.
- Объяснение "захвата" лексического окружения.
- Мини-пример/паттерн кода (если уместно): (не было в источниках)
- Источники:
- Приоритет на собесе: Средний
- Сложность: Базовая
- Уверенность в корректности (по материалам): 90%
Передача аргументов (по ссылке vs по значению)
- Кратко: В JavaScript примитивные типы данных (строки, числа, булевы значения) передаются по значению, то есть создается копия значения. Сложные типы данных (объекты, массивы, функции) передаются по ссылке, то есть передается указатель на место в памяти, и изменения объекта внутри функции будут видны снаружи.
- Почему спрашивают на собеседовании: Проверяет базовое понимание работы с данными в JavaScript, его систему типов и способность избегать нежелательных побочных эффектов при работе с функциями.
- Хитрости/подводные камни:
- Неизменяемость строк: Строки в JavaScript неизменяемы. Любая операция, которая кажется изменением строки (например, конкатенация
+или+=), на самом деле создает новую строку в памяти. - Побочные эффекты: Передача объекта по ссылке может привести к неожиданным изменениям исходного объекта, если это не предусмотрено.
- Неизменяемость строк: Строки в JavaScript неизменяемы. Любая операция, которая кажется изменением строки (например, конкатенация
- Что важно не забыть:
- Примитивы: Числа, строки, булевы — по значению.
- Объекты: Массивы, объекты, Set, Map — по ссылке.
- Строки неизменяемы.
- Быстрый чек-лист ответа синьора:
- Разделение примитивов и сложных типов.
- Примеры для каждого типа передачи.
- Объяснение неизменяемости строк.
- Мини-пример/паттерн кода (если уместно): (не было в источниках)
- Источники:
- Приоритет на собесе: Низкий
- Сложность: Базовая
- Уверенность в корректности (по материалам): 90%
Алгоритмы и структуры данных
- Кратко: Алгоритмы — это набор инструкций для решения задачи, а структуры данных — это способы организации и хранения данных. Включает знание нотации Big O для оценки сложности алгоритмов (O(N), O(N^2), O(1)), а также таких структур, как стек, очередь, связанный список, дерево, граф, хеш-таблица.
- Почему спрашивают на собеседовании: Проверяет фундаментальные знания компьютерных наук, способность анализировать эффективность кода и выбирать подходящие подходы для оптимизации производительности.
- Хитрости/подводные камни:
- Big O: Важно игнорировать константы и рассматривать худший случай. N — это входящий параметр или количество элементов данных.
- Время доступа:
- Хеш-таблица: O(1) (константное время).
- Массив: O(1) для доступа по индексу, но O(N) для линейного поиска.
- Связанный список: O(1) для доступа к голове/хвосту, но O(N) для линейного поиска.
- Разночтения: В источниках было "массив у нас будет Уан и список ещё раз список Да список Ну односвязный линейный односвязный наверное тоже Уан убираем Окей". Это упрощенная трактовка, которая может быть неверной для поиска. ⚠️ Разночтения: Интервьюер и кандидат упрощенно называют O(1) для массива и связанного списка, что верно лишь для доступа к конкретным элементам (по индексу для массива, к голове/хвосту для списка) и неверно для поиска элемента (где будет O(N)).
- Что важно не забыть:
- Big O: Оценка сложности по времени и памяти (O(N), O(N^2), O(1)).
- Стек: LIFO (последний пришел, первый ушел).
- Очередь: FIFO (первый пришел, первый ушел).
- Связанные списки: Односвязные, двусвязные (ссылки на следующий/предыдущий элемент).
- Деревья: Бинарные, AVL, обходы (в ширину, в глубину).
- Графы: Ориентированные, неориентированные, взвешенные (ребра, узлы, кратчайший путь).
- Быстрый чек-лист ответа синьора:
- Объяснение Big O.
- Перечисление основных структур данных (стек, очередь, список, дерево, граф, хеш-таблица).
- Время доступа к этим структурам.
- Примеры задач для каждой структуры.
- Мини-пример/паттерн кода (если уместно): (не было в источниках)
- Источники:
- Приоритет на собесе: Низкий
- Сложность: Продвинутая
- Уверенность в корректности (по материалам): 70%
Security
Передача чувствительных данных
- Кратко: Передача чувствительных данных (например, паролей) требует строгих мер безопасности. Такие данные нельзя передавать в URL-параметрах запроса (
query), так как они легко перехватываются и видны в открытом виде (в логах, истории браузера). Рекомендуется использовать HTTP-заголовки (например,Authorization: Bearer JWT) или тело POST-запроса. - Почему спрашивают на собеседовании: Проверяет понимание основ веб-безопасности, способности защищать пользовательские данные и предотвращать распространенные атаки на уровне транспорта.
- Хитрости/подводные камни:
QueryvsBody:Queryпараметры предназначены для навигационных, открытых данных (фильтры, пагинация).BodyPOST-запроса — для персонализированных, конфиденциальных данных (формы). Без HTTPS оба одинаково уязвимы.- Хеширование на клиенте: Хеширование паролей на клиентской стороне не обеспечивает безопасность, так как алгоритм хеширования может быть легко реверсирован или воспроизведен злоумышленником.
- JWT: Важно не хранить чувствительные данные (например, пароли) в открытом виде в полезной нагрузке JWT-токена, так как она Base64-кодирована, а не зашифрована.
- HTTPS не панацея: Даже с HTTPS, если злоумышленник скомпрометировал клиентское устройство (например, через XSS) или использует поддельный сертификат (MITM), данные могут быть перехвачены после расшифровки.
- Что важно не забыть:
- Не передавать пароли в
query. - Использовать
POST-bodyдля аутентификационных данных. - Использовать HTTP-заголовки для токенов авторизации.
- Хеширование паролей должно происходить на сервере.
- HTTPS обязателен для защиты данных в пути.
- Не передавать пароли в
- Быстрый чек-лист ответа синьора:
- Объяснить, почему
queryопасен. - Разница между
queryиbodyдля чувствительных данных. - Роль HTTPS.
- Проблемы хеширования на клиенте.
- Куда помещать токены (заголовки).
- Объяснить, почему
- Мини-пример/паттерн кода (если уместно): (не было в источниках)
- Источники:
- Приоритет на собесе: Высокий
- Сложность: Продвинутая
- Уверенность в корректности (по материалам): 95%
Аутентификация и авторизация (токены)
- Кратко: Аутентификация — процесс проверки подлинности пользователя (логин/пароль), авторизация — предоставление ему доступа к ресурсам. Часто используются токены (например, JWT - JSON Web Token), которые состоят из access-токена (короткоживущего, для доступа к ресурсам) и refresh-токена (долгоживущего, для обновления access-токена).
- Почему спрашивают на собеседовании: Проверяет знание механизмов управления доступом, способность проектировать безопасные и удобные системы аутентификации и решать проблемы, связанные с жизненным циклом токенов.
- Хитрости/подводные камни:
- Хранение токенов: Cookies с флагами
Secure,HttpOnlyи разрешенными доменами более безопасны, чемlocalStorage(который доступен JavaScript и уязвим для XSS). - Инвалидация access-токенов: Поскольку access-токены короткоживущие (15-20 минут), их обычно не отзывают мгновенно. Для мгновенного отзыва (например, при блокировке пользователя или выходе из всех устройств) можно использовать "черный список" токенов, хранящийся в быстрой БД (например, Redis), который проверяется при каждом критическом запросе.
- CSRF-токены: Защищают формы от межсайтовой подделки запросов. Токен вставляется в форму и проверяется на бэкенде, чтобы убедиться, что запрос пришел с доверенного источника.
- Хранение токенов: Cookies с флагами
- Что важно не забыть:
- Access-токен и Refresh-токен.
- JWT (части: header, payload, signature).
- Хранение токенов в
HttpOnlySecureкуках. - Проблемы
localStorage. - Механизмы отзыва токенов (черный список).
- CSRF-токены для защиты форм.
- Быстрый чек-лист ответа синьора:
- Различие между Access и Refresh токенами.
- Место хранения токенов и почему.
- Механизмы отзыва токенов (черный список).
- Что такое CSRF и как защититься.
- Компоненты JWT и что в них нельзя хранить.
- Мини-пример/паттерн кода (если уместно): (не было в источниках)
- Источники:
- Приоритет на собесе: Средний
- Сложность: Продвинутая
- Уверенность в корректности (по материалам): 95%
SQL Injection
- Кратко: SQL Injection — это атака, при которой злоумышленник вводит вредоносный SQL-код через входные данные приложения, чтобы манипулировать или получать несанкционированный доступ к базе данных.
- Почему спрашивают на собеседовании: Проверяет знание одной из самых распространенных и опасных уязвимостей, а также методов ее предотвращения.
- Хитрости/подводные камни:
- Неэкранированные параметры: Основная причина инъекций — использование клиентских данных напрямую в SQL-запросах без их экранирования или санитизации.
- ORM/ODM: ORM/ODM (например, TypeORM, Prisma) предотвращают SQL-инъекции, используя Prepared Statements (параметризованные запросы), которые отделяют данные от кода запроса.
Raw SQL: Вставка "сырого" SQL-кода внутри приложения крайне опасна и требует особой осторожности и ручного экранирования, что часто приводит к ошибкам.
- Что важно не забыть:
- Причина: неэкранированные входные данные.
- Цель: манипуляция БД, несанкционированный доступ.
- Защита: ORM/ODM, Prepared Statements.
- Избегать "сырого" SQL.
- Быстрый чек-лист ответа синьора:
- Определение атаки.
- Причина уязвимости.
- Главный метод защиты (Prepared Statements).
- Роль ORM/ODM в предотвращении.
- Мини-пример/паттерн кода (если уместно): (не было в источниках)
- Источники:
- Приоритет на собесе: Средний
- Сложность: Базовая
- Уверенность в корректности (по материалам): 95%
XSS (Cross-Site Scripting)
- Кратко: XSS (Cross-Site Scripting) — это атака, при которой злоумышленник внедряет вредоносный клиентский скрипт (обычно JavaScript) в веб-страницу, просматриваемую другими пользователями. Скрипт может быть выполнен в браузере пользователя, что позволяет злоумышленнику украсть данные, управлять учетной записью или выполнять другие вредоносные действия.
- Почему спрашивают на собеседовании: Проверяет знание уязвимостей на клиентской стороне, которые могут влиять на бэкенд, и способность писать безопасный код, обрабатывающий пользовательский ввод.
- Хитрости/подводные камни:
- Типы XSS:
- Stored XSS: Вредоносный скрипт сохраняется на сервере (например, в базе данных) и затем отображается другим пользователям. Пример: инцидент с Tesla, где имя автомобиля содержало исполняемый код, который сработал только при просмотре отчета инженером Tesla. Или MySpace-атака.
- Reflected XSS: Скрипт отражается в ответе сервера после запроса пользователя.
- DOM-based XSS: Скрипт выполняется в браузере клиента из-за некорректной обработки DOM.
- Отложенная атака: XSS может быть не моментальной; скрипт может сработать через некоторое время или при определенных условиях (как в случае с Tesla).
- Типы XSS:
- Что важно не забыть:
- Причина: внедрение исполняемого кода (JavaScript) через пользовательский ввод.
- Цель: выполнение кода в браузере другого пользователя.
- Последствия: кража данных, несанкционированные действия.
- Пример: Tesla и MySpace.
- Быстрый чек-лист ответа синьора:
- Определение атаки.
- Причина уязвимости (пользовательский ввод).
- Примеры (Stored XSS).
- Методы защиты (санитизация ввода, CSP).
- Мини-пример/паттерн кода (если уместно): (не было в источниках)
- Источники:
- Приоритет на собесе: Средний
- Сложность: Базовая
- Уверенность в корректности (по материалам): 95%
HTTPS, TLS и Man-in-the-Middle (MITM)
- Кратко: HTTPS (Hypertext Transfer Protocol Secure) — это защищенная версия HTTP, использующая протокол TLS (Transport Layer Security) для шифрования связи между клиентом и сервером. Это предотвращает подслушивание и подделку данных. Man-in-the-Middle (MITM) — атака, при которой злоумышленник перехватывает и, возможно, изменяет коммуникацию между двумя сторонами, не будучи обнаруженным.
- Почему спрашивают на собеседовании: Проверяет знание фундаментальных механизмов сетевой безопасности, понимание ограничений HTTPS и способность защищать данные на транспортном уровне.
- Хитрости/подводные камни:
- HTTPS не полностью снимает проблему MITM:
- Скомпрометированный клиент: Если на стороне клиента выполняется вредоносный скрипт (например, через XSS), данные могут быть перехвачены после их расшифровки в браузере.
- Поддельные сертификаты: Злоумышленник может использовать поддельный SSL-сертификат (например, как в случае с Казахстаном), чтобы перехватывать и расшифровывать трафик. Пользователи могут видеть предупреждения в браузере, но все равно продолжить.
- SSL Pinning: (не было в источниках, но является способом борьбы с поддельными сертификатами).
- HTTPS не полностью снимает проблему MITM:
- Что важно не забыть:
- HTTPS = HTTP + TLS.
- TLS шифрует трафик между клиентом и сервером.
- Защищает от подслушивания и подделки.
- HTTPS не защищает от MITM, если клиент скомпрометирован или сертификат подделан.
- Роль IP (v4/v6) как сетевого уровня.
- Быстрый чек-лист ответа синьора:
- Роль HTTPS/TLS в шифровании.
- Определение MITM атаки.
- Причины, по которым HTTPS не является 100% защитой.
- Упоминание поддельных сертификатов.
- Мини-пример/паттерн кода (если уместно): (не было в источниках)
- Источники:
- Приоритет на собесе: Низкий
- Сложность: Базовая
- Уверенность в корректности (по материалам): 95%
Development Practices & Tools
Тестирование
- Кратко: Тестирование — это процесс проверки программного обеспечения на наличие ошибок и соответствие требованиям. Включает различные типы тестов: Unit-тесты (проверка отдельных модулей), Integration-тесты (проверка взаимодействия модулей), E2E-тесты (сквозное тестирование, имитирующее пользователя). Методологии разработки, управляемой тестами: TDD (Test-Driven Development) и BDD (Behavior-Driven Development).
- Почему спрашивают на собеседовании: Проверяет приверженность качеству кода, способность писать надежное ПО, а также знание инструментов и методологий для обеспечения стабильности и поддержки приложения.
- Хитрости/подводные камни:
- Сложность без тестов: В JavaScript без интеграционных тестов очень легко что-то сломать.
- Инъекция зависимостей в тестах: Позволяет легко мокать или подменять зависимости, делая тесты более изолированными и управляемыми.
- Что важно не забыть:
- Типы тестов: Unit, Integration, E2E.
- Методологии: TDD, BDD.
- Важность тестов для качества и стабильности кода.
- Мокирование данных.
- Инъекция зависимостей помогает в тестировании.
- Быстрый чек-лист ответа синьора:
- Перечисление основных типов тестов.
- Различия между TDD и BDD.
- Важность тестов для Node.js/JS.
- Как инъекция зависимостей помогает в тестах.
- Мини-пример/паттерн кода (если уместно): (не было в источниках)
- Источники:
- Приоритет на собесе: Высокий
- Сложность: Средняя
- Уверенность в корректности (по материалам): 90%
Мониторинг и профилирование
- Кратко: Мониторинг — это постоянное отслеживание состояния и производительности приложения, а профилирование — детальный анализ производительности для выявления узких мест. Инструменты включают Prometheus (сбор метрик) и Grafana (визуализация метрик).
- Почему спрашивают на собеседовании: Проверяет способность выявлять проблемы производительности, диагностировать узкие места и обеспечивать стабильную работу продакшн-систем.
- Хитрости/подводные камни:
- Диагностика микротасок: По умолчанию JavaScript не сообщает, кто именно поставил микротаску в очередь, что затрудняет диагностику. Async Hooks (Node.js API) могут помочь отследить происхождение и время выполнения микротасок.
- Grafana для микротасок: Grafana предназначена для высокоуровневых метрик, а не для детализированного анализа каждой микротаски. Для этого лучше подходят DevTools или Async Hooks.
- Что важно не забыть:
- Мониторинг: Отслеживание ресурсов (CPU, RAM) и метрик (RPS, время ответа).
- Профилирование: Выявление узких мест в коде.
- Инструменты: Prometheus (сбор), Grafana (визуализация).
- Node.js DevTools: Для просмотра
flame chart, стека вызовов, активности Garbage Collector, утечек памяти. - Async Hooks: Для трассировки микротасок.
- Быстрый чек-лист ответа синьора:
- Цели мониторинга и профилирования.
- Основные инструменты (Prometheus, Grafana).
- Как диагностировать блокировку Event Loop.
- Упоминание Async Hooks для микротасок.
- Мини-пример/паттерн кода (если уместно): (не было в источниках)
- Источники:
- Приоритет на собесе: Высокий
- Сложность: Продвинутая
- Уверенность в корректности (по материалам): 90%
Управление пакетами (npm, node_modules)
- Кратко: npm (Node Package Manager) — стандартный пакетный менеджер для Node.js, используемый для установки, управления и публикации пакетов JavaScript. Устанавливает зависимости в папку
node_modules. - Почему спрашивают на собеседовании: Проверяет знание экосистемы Node.js, способности управлять зависимостями и решать проблемы, возникающие при работе с пакетами.
- Хитрости/подводные камни:
- "Dependency hell": Проблемы с разрешением конфликтов версий и дублированием пакетов в
node_modules, что может привести к большому размеру папки и непредсказуемому поведению. - Изначальные проблемы Node.js: Первая версия Node.js (от Райана Даля) вообще не имела механизма разрешения пакетных зависимостей, что привело к появлению
npmкак стороннего решения. - Локальная разработка: Для внесения масштабных изменений в используемые пакеты и их локальной проверки используется
npm link. npm audit: Инструмент для проверки зависимостей на известные уязвимости. Сторонние сервисы, такие как Snyk, могут предоставить более детальные отчеты.- Кастомные пакеты: Можно поднять собственный Nexus или другой пакетный менеджер для хостинга измененных версий пакетов, но это требует осторожности (безопасность, поддержка).
- "Dependency hell": Проблемы с разрешением конфликтов версий и дублированием пакетов в
- Что важно не забыть:
node_modules– папка с зависимостями.npmкак стандартный пакетный менеджер.- Проблемы с версиями и дубликатами пакетов.
npm auditдля проверки уязвимостей.npm linkдля локальной разработки зависимостей.
- Быстрый чек-лист ответа синьора:
- Объяснение роли npm.
- Проблемы "dependency hell".
- Использование
npm audit. npm linkдля локальной разработки.
- Мини-пример/паттерн кода (если уместно): (не было в источниках)
- Источники:
- Приоритет на собесе: Средний
- Сложность: Продвинутая
- Уверенность в корректности (по материалам): 90%
Инъекция зависимостей (Dependency Injection)
- Кратко: Инъекция зависимостей (DI) — это шаблон проектирования, при котором компоненты получают свои зависимости из внешнего источника, а не создают их сами. Это способствует слабой связанности кода и облегчает тестирование и замену зависимостей.
- Почему спрашивают на собеседовании: Проверяет понимание современных архитектурных паттернов, способность писать гибкий, тестируемый и поддерживаемый код, а также умение управлять сложными зависимостями в проекте.
- Хитрости/подводные камни:
- Связь с DIP: DI является реализацией принципа Dependency Inversion (DIP) из SOLID, где модули зависят от абстракций, а не от конкретных реализаций.
- Тестирование: DI значительно упрощает тестирование, позволяя легко подменять реальные зависимости моками или тестовыми реализациями.
- Гибкость: Позволяет легко менять реализации (например, платежные шлюзы) без изменения основного кода, что очень важно для бизнеса.
- Что важно не забыть:
- Шаблон проектирования для управления зависимостями.
- Слабая связанность кода.
- Упрощает тестирование (мокирование).
- Позволяет легко подменять реализации (например, платежные системы).
- Применение в Nest.js.
- Быстрый чек-лист ответа синьора:
- Что такое инъекция зависимостей.
- Преимущества (тестируемость, гибкость).
- Связь с принципом DIP.
- Примеры использования.
- Мини-пример/паттерн кода (если уместно): (не было в источниках, кроме описания логики)
- Источники:
- Приоритет на собесе: Средний
- Сложность: Продвинутая
- Уверенность в корректности (по материалам): 90%
Обработка ошибок
- Кратко: Обработка ошибок — это процесс выявления, перехвата и реагирования на исключительные ситуации, возникающие во время выполнения программы. Включает централизованное управление ошибками, использование кастомных классов исключений и адекватное возвращение HTTP-статусов.
- Почему спрашивают на собеседовании: Проверяет способность писать надежный и отказоустойчивый код, а также проектировать удобные и информативные системы обработки ошибок.
- Хитрости/подводные камни:
- Centralized Error Handling: Создание отдельного файла или класса для ошибок (
Error,Exception) позволяет централизованно управлять их логированием, возвращать стандартизированные статусы и сообщения. - Кастомные статусы: Использование специфичных HTTP-статусов (например, 418 "I'm a teapot") для конкретных бизнес-сценариев может унифицировать обработку ошибок на фронтенде и упростить тестирование.
- Логика
try/catch: Важно использоватьtry/catchдля обработки потенциально "ломающихся" операций, таких какJSON.parseс невалидными данными. - Промисы: Для предотвращения
rejectionпромиса в случае "ошибки", которую нужно обработать как успешный сценарий, можно перехватитьrejectionи вернуть ожидаемое "успешное" значение (например, пустую строку вместо 400 статуса).
- Centralized Error Handling: Создание отдельного файла или класса для ошибок (
- Что важно не забыть:
- Централизованное управление ошибками.
- Кастомные классы исключений (например,
BadRequestException). - Обработка невалидных данных (например,
JSON.parse) с помощьюtry/catch. - Унификация HTTP-статусов для бизнеса и разработки.
- Перехват промисов для обработки "ошибок" как успешных сценариев.
- Быстрый чек-лист ответа синьора:
- Принципы централизованной обработки ошибок.
- Использование кастомных классов исключений.
- Обоснование применения специфичных HTTP-статусов.
- Как
try/catchили промисы помогают в обработке.
- Мини-пример/паттерн кода (если уместно):
// Пример перехвата rejection для позитивного сценария
fetchData().catch(error => {
if (error.status === 400) { // Например, 400 означает "нет каналов", но это ожидаемый сценарий
console.log('No channels available, treating as empty.');
return ''; // Возвращаем пустую строку вместо ошибки
}
throw error; // Пробрасываем другие ошибки
}); - Источники:
- Приоритет на собесе: Средний
- Сложность: Продвинутая
- Уверенность в корректности (по материалам): 95%
Контейнеризация и оркестрация
- Кратко: Контейнеризация (например, Docker) — это упаковка приложения и всех его зависимостей в изолированные "контейнеры" для обеспечения переносимости. Оркестрация (например, Kubernetes) — это автоматизированное управление (развертывание, масштабирование, мониторинг) контейнеризированных приложений.
- Почему спрашивают на собеседовании: Проверяет знание современных практик развертывания, способности работать с распределенными системами и обеспечивать их стабильную работу в продакшене.
- Хитрости/подводные камни:
- Docker Compose: Используется для определения и запуска многоконтейнерных Docker-приложений.
- Kubernetes: Более мощный инструмент для оркестрации, поддерживает реплики, гибкие связи и горизонтальное масштабирование.
- Minikube: Облегченная версия Kubernetes для локальной разработки.
- Что важно не забыть:
- Docker: Контейнеризация приложений.
- Docker Compose: Управление мультиконтейнерными приложениями.
- Kubernetes: Оркестрация, управление репликами, масштабирование.
- kubeadm, kubectl: Инструменты управления Kubernetes.
- Быстрый чек-лист ответа синьора:
- Различия между Docker и Kubernetes.
- Сценарии использования каждого.
- Как Kubernetes помогает в горизонтальном масштабировании.
- Название основных инструментов (Docker Compose, kubectl).
- Мини-пример/паттерн кода (если уместно): (не было в источниках)
- Источники:
- Приоритет на собесе: Низкий
- Сложность: Базовая
- Уверенность в корректности (по материалам): 90%
Frameworks (Express, Nest.js, Koa, Fastify)
- Кратко: Express — минималистичный и гибкий Node.js веб-фреймворк, основанный на модуле
http. Nest.js — прогрессивный, opinionated фреймворк для построения эффективных, масштабируемых серверных приложений, использующий TypeScript и вдохновленный Angular. Koa и Fastify — альтернативные фреймворки, предлагающие другие подходы к асинхронности и производительности. - Почему спрашивают на собеседовании: Проверяет знание популярных инструментов для бэкенд-разработки на Node.js, их особенности, преимущества и недостатки, а также способность выбирать подходящий фреймворк для проекта.
- Хитрости/подводные камни:
- Express и Callback Hell: Исторически Express использовал колбэки, что приводило к "Callback Hell". Хотя сейчас есть поддержка async/await, его ядро до сих пор основано на колбэках, что требует дополнительных библиотек или "monkey-patching" для полноценной работы с промисами.
- Koa: Появился как ответ на Callback Hell в Express, изначально использовал генераторы, затем промисы и async/await. Пропагандирует модульный подход.
- Fastify: Создан для высокой производительности, использует схемы и часто может быть интегрирован в Nest.js в качестве underlying платформы.
- Nest.js: Предоставляет структуру, использует декораторы, DI (инъекцию зависимостей) и может работать поверх Express или Fastify.
- Что важно не забыть:
- Express: Минималистичный, гибкий, на основе
http. - Nest.js: Структурированный, TypeScript, DI, вдохновлен Angular.
- Koa: Промисы, async/await, модульность.
- Fastify: Высокая производительность, схемы.
- Проблемы Callback Hell в Express.
- Express: Минималистичный, гибкий, на основе
- Быстрый чек-лист ответа синьора:
- Краткое описание каждого фреймворка.
- Ключевые отличия (структура, производительность, асинхронность).
- Проблемы Callback Hell и как они решались.
- Когда какой фреймворк выбрать.
- Мини-пример/паттерн кода (если уместно): (не было в источниках)
- Источники:
- Приоритет на собесе: Низкий
- Сложность: Продвинутая
- Уверенность в корректности (по материалам): 90%
Валидация данных
- Кратко: Валидация данных — это процесс проверки входных данных на соответствие определенным правилам и форматам. Это критично для безопасности и корректности работы приложения. Инструменты включают Joi, Zod, Class-Validator, JSON-схемы, Swagger-схемы.
- Почему спрашивают на собеседовании: Проверяет способность писать безопасный и надежный код, способный корректно обрабатывать пользовательский ввод и предотвращать ошибки.
- Хитрости/подводные камни:
- Опасность
JSON.parse: Прямое использованиеJSON.parseс невалидными данными, полученными от клиента, может привести к падению приложения. Необходимо обрабатывать такие операции вtry/catch. - Типизация TypeScript: Типизация в TypeScript сама по себе не является валидацией во время выполнения, но хорошо сочетается с валидаторами.
- Валидация в фреймворках: В Nest.js есть Class-Validator, Pipes для преобразования и валидации данных.
- Опасность
- Что важно не забыть:
- Инструменты: Joi, Zod, Class-Validator.
- Обработка невалидных данных с помощью
try/catch. - Использование типизации (TypeScript) и схем (JSON-схемы).
- Роль валидации в безопасности.
- Быстрый чек-лист ответа синьора:
- Название основных библиотек валидации.
- Обязательность валидации для клиентского ввода.
- Обработка ошибок валидации.
- Связь с безопасностью.
- Мини-пример/паттерн кода (если уместно): (не было в источниках)
- Источники:
- Приоритет на собесе: Низкий
- Сложность: Базовая
- Уверенность в корректности (по материалам): 90%
Troubleshooting & Performance
Оптимизация производительности (общее)
- Кратко: Оптимизация производительности — это процесс улучшения эффективности и скорости работы программного обеспечения. Включает выявление узких мест, устранение блокирующих операций, оптимизацию работы с базой данных, эффективное использование кэширования и масштабирование системы.
- Почему спрашивают на собеседовании: Проверяет способность системно подходить к решению проблем производительности, применять комплексные меры для ускорения работы приложения и обеспечивать высокую пропускную способность.
- Хитрости/подводные камни:
- CPU-bound vs I/O-bound:
- CPU-bound задачи (интенсивные вычисления) должны выноситься в Worker Threads, чтобы не блокировать однопоточный Event Loop.
- I/O-bound задачи (работа с сетью, БД) должны быть асинхронными и обрабатываться эффективно (пулы соединений, кэширование).
- Асинхронные операции в циклах: Множественные асинхронные операции в цикле могут привести к проблемам с производительностью и блокировке, если не используются пакетные операции (batch inserts/updates).
- Игнорирование мелких оптимизаций: Такие вещи, как правильные типы данных, могут сильно влиять на производительность и размер БД.
- CPU-bound vs I/O-bound:
- Что важно не забыть:
- Диагностика узких мест (мониторинг, профилирование).
- Устранение блокирующих операций (Worker Threads).
- Оптимизация работы с БД (индексы, шардирование, репликация, оптимизация запросов и типов данных).
- Эффективное кэширование (Redis, CDN).
- Масштабирование (горизонтальное, вертикальное).
- Быстрый чек-лист ответа синьора:
- Комплексный подход (код, БД, инфраструктура).
- Разделение CPU- и I/O-bound задач.
- Упоминание пакетных операций для БД.
- Инструменты диагностики.
- Мини-пример/паттерн кода (если уместно): (не было в источниках, кроме описания логики)
- Источники:
- Приоритет на собесе: Средний
- Сложность: Продвинутая
- Уверенность в корректности (по материалам): 95%
Пропуски и белые пятна (чего ожидалось, но не было в видео)
- Обработка потоков (Streams): Хотя стримы упоминались как способ чтения больших файлов чанками, глубокого обсуждения их преимуществ (эффективность по памяти, обработка больших объемов данных) и API (
Readable,Writable,Duplex,Transform) не было.- Обоснование важности: Стримы — фундаментальный механизм Node.js для работы с I/O, критичный для производительности и эффективной обработки больших данных.
- Обработка ошибок в асинхронном коде/Промисах: Помимо
try/catchдляJSON.parseи обработкиrejectionпромиса, не было детального обсуждения глобальных обработчиков ошибок (например,process.on('uncaughtException'),process.on('unhandledRejection')) и их правильного использования.- Обоснование важности: Критично для стабильности продакшн-приложений, чтобы необработанные исключения не приводили к падению сервера.
- Безопасность (CORS, Rate Limiting, Input Validation/Sanitization): Были XSS и SQL-инъекции, но не затронуты другие аспекты безопасности, такие как:
- CORS (Cross-Origin Resource Sharing): Разрешение запросов с других доменов.
- Rate Limiting: Ограничение количества запросов от клиента для предотвращения DDoS и brute-force.
- Input Validation/Sanitization: Хотя валидация данных упоминалась, не было глубокого обсуждения санитизации (очистки) входных данных для предотвращения атак.
- Обоснование важности: Эти темы являются базовыми для любого бэкенд-разработчика, работающего с веб-приложениями.
- Модульная система Node.js (CommonJS vs ES Modules): Были упоминания пакетов,
npm, но не обсуждались две основные модульные системы Node.js, их различия, как они работают и проблемы совместимости.- Обоснование важности: Глубокое понимание модульной системы Node.js важно для организации кода и работы с зависимостями.
- Веб-сокеты (WebSockets): Упоминание web-сокетов было мимолетным в контексте получения данных маленькими пакетами, но не было обсуждения, как они работают, когда используются (real-time приложения), их преимуществ и недостатков.
- Обоснование важности: WebSockets — ключевая технология для интерактивных real-time приложений, важная для многих Node.js-проектов.
- Таймеры (setTimeout, setInterval, setImmediate, process.nextTick): Хотя
process.nextTickиsetImmediateбыли упомянуты, не было детального сравнения всех таймеров, их приоритетов и типичных сценариев использования.- Обоснование важности: Понимание работы таймеров критично для предсказуемого выполнения асинхронного кода в Node.js.
- Конфигурация (dotenv, nconf): Не было обсуждения способов управления конфигурацией в Node.js-приложениях (например, переменные окружения,
.envфайлы, специализированные библиотеки).- Обоснование важности: Правильное управление конфигурацией — залог гибкости и безопасности приложения в разных окружениях.
- Работа с файловой системой: Мимолетное упоминание в контексте
libuvи чтения чанками, но не было детального обсуждения APIfsмодуля, его асинхронных и синхронных методов, а также рисков использования синхронных методов.- Обоснование важности: Работа с файловой системой — базовая операция для многих серверных приложений.