Вопросы на собеседовании: Фулстек-разработчик
100 реальных вопросов с образцовыми ответами и пояснениями для уровня Middle.
Смотреть пример резюме: Фулстек-разработчик →Вопросы
var, let и const различаются областью видимости, hoisting и переприсвоением.
- var имеет функциональную область видимости и поднимается, поэтому утекает за пределы блока и создаёт баги
- let ограничен блоком и допускает переприсвоение
- const ограничен блоком и запрещает переприсвоение, хотя свойства объекта остаются изменяемыми
- по умолчанию используйте const, let только при необходимости переприсвоения, var избегайте
Зачем это спрашивают: Проверяет, понимает ли кандидат правила области видимости и может ли распознать распространённую ловушку с «утечкой» переменной из цикла или if-блока из-за поднятия var.
Node.js работает в одном потоке и делегирует ввод-вывод, поэтому не блокируется.
- libuv обрабатывает ввод-вывод через асинхронные API ОС или пул потоков для блокирующих задач
- завершённые операции ставят свои коллбэки в очередь цикла событий
- цикл обрабатывает очереди по фазам: таймеры, ожидающие коллбэки, poll, check, close
- это позволяет Node обслуживать тысячи одновременных соединений, не заставляя основной поток ждать
Зачем это спрашивают: Раскрывает, понимает ли кандидат причину неблокирующего поведения Node.js и может ли рассуждать о порядке выполнения коллбэков при отладке проблем с производительностью.
Замыкание - функция, сохраняющая доступ к внешней области видимости после её завершения.
- оно удерживает внешние переменные даже после завершения охватывающей функции
- пример: фабрика счётчика возвращает increment и get с общей приватной count
- вызывающий код не может обратиться к этой приватной переменной напрямую
- замыкания лежат в основе частичного применения, мемоизации и паттерна модуля
Зачем это спрашивают: Проверяет понимание лексической области видимости и способность применять замыкания в реальных паттернах, а не просто воспроизводить учебное определение.
В JavaScript объекты наследуют напрямую от других объектов через цепочку прототипов.
- обращение к свойству поднимается по цепочке, пока не найдёт его или не достигнет null
- классическое наследование в Java использует классы как шаблоны в жёсткой иерархии
- синтаксис class из ES6 - лишь сахар над прототипами
- он не меняет поведение среды выполнения
Зачем это спрашивают: Отделяет разработчиков, понимающих объектную модель JavaScript, от тех, кто пришёл из языков с классовым наследованием и применяет некорректные ментальные модели при отладке.
async/await - синтаксический сахар над Promise для линейного написания асинхронного кода.
- Promise соединяются через .then() и .catch(), но глубокие цепочки плохо читаются
- в длинных цепочках легко пропустить обработку ошибок
- async/await читается как синхронный код и использует try/catch для ошибок
- под капотом async-функция возвращает Promise, а await ждёт его разрешения
Зачем это спрашивают: Проверяет, понимает ли кандидат, что async/await и Promise - один и тот же механизм, что предотвращает путаницу при их совместном использовании или отладке отклонённых Promise.
WeakMap и WeakSet хранят слабые ссылки, поэтому их элементы могут собираться сборщиком мусора.
- сборщик может освободить объекты, даже если они ещё в коллекции
- идеальны для метаданных на DOM-узлах или объектах без блокировки очистки
- в отличие от Map и Set они не перебираемы
- их содержимое нельзя перечислить или получить списком
Зачем это спрашивают: Проверяет глубину знаний за пределами стандартных структур данных и понимание взаимодействия слабых ссылок с алгоритмом сборки мусора.
JavaScript использует mark-and-sweep, освобождая всё, что недостижимо из корней.
- он периодически помечает объекты, достижимые из глобальных переменных и стека вызовов, и освобождает остальное
- замыкания, удерживающие большие объекты слишком долго, вызывают утечки
- обработчики событий, добавленные повторно без удаления, текут
- глобальные структуры без ограничений тоже накапливают данные; диагностируйте снимками кучи или флагом --inspect
Зачем это спрашивают: Проверяет практические знания управления памятью, так как middle-разработчик должен уметь диагностировать и устранять утечки памяти в production, а не просто перезапускать сервис.
Значение this определяется тем, как вызвана функция, а не где она объявлена.
- при обычном вызове this указывает на глобальный объект или undefined в строгом режиме
- при вызове метода this указывает на объект перед точкой
- в стрелочной функции this лексически привязан к окружающей области видимости
- частая ловушка - потеря this при передаче метода как коллбэка, решается стрелочными функциями или .bind()
Зачем это спрашивают: Раскрывает, понимает ли кандидат правила call-site в JavaScript достаточно глубоко, чтобы отлаживать ошибку 'this is undefined' в коллбэках и обработчиках событий.
Каждая версия HTTP уменьшает блокировку начала очереди и задержку.
- HTTP/1.1 использует постоянные соединения, но блокирует начало очереди, поэтому браузеры открывают много параллельных соединений
- HTTP/2 добавляет мультиплексирование по одному соединению, сжатие заголовков и server push
- HTTP/3 заменяет TCP протоколом QUIC, убирая блокировку начала очереди на уровне соединения
- QUIC позволяет потокам падать независимо, снижая задержку в сетях с потерями
Зачем это спрашивают: Проверяет, понимает ли кандидат эволюцию протоколов и может ли обосновать выбор версии исходя из требований к инфраструктуре и производительности.
CORS - правило браузера, блокирующее межисточниковые запросы, если сервер их не разрешит.
- сервер разрешает источники через Access-Control-Allow-Origin и связанные заголовки
- запросы с кастомными заголовками или не-простыми методами сначала вызывают preflight OPTIONS
- браузер продолжает только при правильных заголовках Allow от сервера
- в Express используйте middleware cors с явным списком источников, а не wildcard в production
Зачем это спрашивают: Выявляет, понимает ли кандидат модель безопасности браузера, а не просто «отключает» ошибку CORS, что приводит к опасно разрешительным конфигурациям.
Аутентификация проверяет, кто вы; авторизация проверяет, что вам разрешено делать.
- аутентификация проверяет личность по учётным данным или подписанному токену
- авторизация проверяет права, например роль администратора перед доступом
- путаница между ними порождает уязвимости
- пример: токен проверяется, но не проверяется право пользователя на запрашиваемый ресурс
Зачем это спрашивают: Проверяет ясность мышления в вопросах базовой модели безопасности, что критично для middle-разработчика, создающего защищённые API.
Куки - механизм передачи; сессии и JWT - два способа хранить состояние пользователя.
- сессионная аутентификация хранит данные на сервере, часто в Redis, и выдаёт клиенту ID сессии
- сервер обращается к хранилищу при каждом запросе
- JWT кодируют подписанные claims на клиенте, сервер остаётся stateless и лишь проверяет подпись
- кука может нести любой вариант; флаги HttpOnly и Secure не дают JavaScript читать токен
Зачем это спрашивают: Проверяет, понимает ли кандидат компромиссы в масштабируемости и отзыве токенов, а не слепо предпочитает один подход другому.
Cache-Control и ETag дают кеширование по времени и по содержимому.
- Cache-Control задаёт политику: max-age - время жизни, no-cache - перепроверять, no-store - не кешировать
- ETag - отпечаток, который клиент возвращает в If-None-Match при следующем запросе
- сервер отвечает 304 Not Modified, если содержимое не изменилось
- их комбинация даёт и временное истечение, и проверку актуальности содержимого
Зачем это спрашивают: Практические знания, ожидаемые от middle-разработчика, строящего API и SPA, так как неправильная конфигурация кеширования вызывает либо устаревшие данные, либо излишнюю нагрузку на сервер.
WebSocket держит постоянное двустороннее соединение; поллинг повторяет короткие запросы.
- WebSocket переходит с HTTP на одно постоянное двустороннее TCP-соединение
- любая сторона может отправлять данные в любой момент
- long polling держит запрос открытым до появления данных, затем клиент запрашивает снова
- WebSocket выигрывает при частом двустороннем трафике вроде чата; поллинг проще для редких обновлений
Зачем это спрашивают: Проверяет, выбирает ли кандидат стратегию реального времени исходя из требований к частоте и направленности данных, а не всегда тянется к WebSocket.
Браузер превращает URL в пиксели через DOM, CSSOM, дерево рендеринга, разметку и отрисовку.
- после DNS и TCP/TLS он загружает HTML и строит DOM, выполняя CSS и JS по мере обнаружения
- CSS парсится в CSSOM и объединяется с DOM в дерево рендеринга
- браузер вычисляет разметку (reflow) и отрисовывает пиксели на экране
- блокирующие скрипты задерживают первую отрисовку, поэтому откладывайте некритический JS и встраивайте критический CSS
Зачем это спрашивают: Необходимо full-stack разработчикам для понимания, почему конкретные оптимизации производительности - defer-скрипты, inline-критический CSS - имеют измеримый эффект на Core Web Vitals.
Виртуальный DOM - копия реального DOM в памяти React, нужная для минимизации обновлений.
- при изменении состояния React отрисовывает новое виртуальное дерево
- он сравнивает новое дерево со старым через согласование
- он применяет только минимальный набор реальных изменений DOM
- это пакетирование и сравнение избавляет от дорогих прямых манипуляций DOM при каждом изменении
Зачем это спрашивают: Проверяет базовые знания React и понимание обоснования производительности за дизайном библиотеки, а не только поверхности API.
Управляемые компоненты берут значения из состояния React; неуправляемые оставляют их в DOM.
- значение управляемого поля проходит через состояние и обработчик onChange
- неуправляемое поле хранит значение в DOM, читается через ref при необходимости
- управляемые компоненты проще валидировать, сбрасывать и тестировать
- неуправляемые помогают огромным формам, где перерисовка на каждое нажатие бьёт по производительности
Зачем это спрашивают: Раскрывает, понимает ли кандидат поток данных в React и может ли выбрать подходящий паттерн исходя из сложности формы и требований производительности.
Хуки позволяют функциональным компонентам использовать состояние и жизненный цикл без классов.
- они добавляют состояние и жизненный цикл React в функциональные компоненты
- вызывайте их только на верхнем уровне компонента или кастомного хука
- никогда не вызывайте внутри условий, циклов или вложенных функций
- React полагается на порядок вызовов, чтобы сопоставить состояние хука с нужным экземпляром компонента между рендерами
Зачем это спрашивают: Проверяет, понимает ли кандидат причину правил использования хуков, что помогает отлаживать неожиданное поведение вместо механического следования запретам.
useEffect выполняется после рендера, а массив зависимостей управляет его повторными запусками.
- по умолчанию он выполняется после каждого рендера
- пропуск зависимостей создаёт устаревшие замыкания, захватывающие старые значения
- отсутствие очистки подписок или таймеров вызывает утечки памяти
- лишние зависимости запускают эффект слишком часто и могут привести к бесконечным циклам
Зачем это спрашивают: useEffect - один из наиболее неправильно используемых хуков; вопрос раскрывает, сталкивался ли кандидат с ошибками stale closure и очистки в реальных проектах.
useMemo кеширует вычисленное значение; useCallback кеширует ссылку на функцию.
- useMemo возвращает кешированный результат, пока зависимости не изменятся, избегая дорогих пересчётов
- useCallback не даёт функции пересоздаваться при каждом рендере
- оба сохраняют референциальное равенство между рендерами
- это важно при передаче значений в мемоизированные дочерние компоненты или в зависимости хуков
Зачем это спрашивают: Проверяет понимание референциального равенства в JavaScript и знание того, когда мемоизация реально помогает, а когда лишь усложняет код.
Закрытые вопросы
- 21
Как работает алгоритм согласования React и как пропс key влияет на него?
react - 22
Как диагностировать и устранить слишком частые перерисовки React-компонента?
reactcomponents - 23
Когда использовать Context API, а когда выделенную библиотеку управления состоянием?
stateapi - 24
Как работает разбиение кода с помощью React.lazy и Suspense и почему это важно?
react - 25
Каковы компромиссы между серверным рендерингом, статической генерацией сайтов и клиентским рендерингом?
ssr - 26
Для чего нужен useReducer и когда он предпочтительнее useState?
hooks - 27
Как конкурентный рендеринг React 18 меняет подход к обновлениям компонентов?
reactcomponentsconcurrency - 28
В чём разница между process.nextTick и setImmediate в Node.js?
concurrency - 29
Как обрабатывать ошибки в middleware Express и в async-обработчиках маршрутов?
middlewareasyncsoft-skills - 30
Что такое пул соединений с базой данных и как его правильно настроить?
databasepoolingconfig - 31
Как спроектировать REST API, поддерживающий версионирование?
restversioningdesign - 32
Каковы компромиссы между REST и GraphQL?
restgraphql - 33
Как работает JWT-аутентификация и каковы ключевые соображения безопасности?
authjwt - 34
Как предотвратить распространённые уязвимости безопасности в Node.js API?
vulnerabilitiesapi - 35
Что такое проблема N+1 запросов в GraphQL и как её решить?
queriesn+1graphql - 36
Как реализовать пагинацию в REST API и каковы компромиссы между offset- и cursor-пагинацией?
restpagination - 37
Как реализовать очередь фоновых задач в Node.js-приложении?
jobs - 38
Как безопасно управлять секретами и переменными окружения в разных средах?
secretsconfig - 39
В чём разница между SQL и NoSQL базами данных и как выбирать между ними?
sqlnosqldatabase - 40
Как работают индексы базы данных и каковы их компромиссы?
databaseindexes - 41
Что такое транзакция базы данных и что гарантируют свойства ACID?
databasetransactionsacid - 42
Объясните разницу между INNER JOIN, LEFT JOIN и FULL OUTER JOIN в SQL.
sqljoins - 43
Как подойти к оптимизации медленного SQL-запроса?
sqlqueriesoptimization - 44
Что такое нормализация базы данных и когда уместна денормализация?
databasenormalizationdenormalization - 45
Что такое теорема CAP и как она влияет на выбор базы данных?
databasecap - 46
Как MongoDB обрабатывает валидацию схемы и каковы компромиссы schema-less дизайна?
mongodbschemadesign - 47
Что такое миграции базы данных и как ими управлять в команде?
databasemigrations - 48
Как спроектировать схему базы данных для мультитенантного SaaS-приложения?
databaseschemadesign - 49
Что такое микрофронтенды и когда их стоит внедрять?
micro-frontends - 50
Как спроектировать стратегию кеширования для full-stack приложения?
designcaching - 51
Что такое событийно-ориентированная архитектура и когда она оправдана по сравнению с моделью запрос-ответ?
events - 52
Как подойти к декомпозиции монолита на сервисы, не создав распределённый монолит?
monolithdistributed - 53
Какую роль играет обратный прокси в production-деплое Node.js?
proxydeployment - 54
Что такое горизонтальное масштабирование и что должно измениться в приложении для его поддержки?
scaling - 55
Как обрабатывать распределённые транзакции между несколькими сервисами?
soft-skillstransactionsdistributed - 56
Что такое Docker и как контейнеризация приносит пользу full-stack команде?
dockercontainers - 57
Как структурировать CI/CD пайплайн для full-stack приложения?
ci-cd - 58
В чём разница между Docker-образом и Docker-контейнером?
dockercontainers - 59
Чем Kubernetes отличается от Docker Compose и в каком случае выбирать каждый?
dockerkubernetes - 60
Как мониторить Node.js-сервис в production?
monitoring - 61
Что такое CDN и как он улучшает производительность фронтенда?
performance - 62
Как достичь нулевого простоя при деплое?
deployment - 63
Что такое инфраструктура как код и почему это важно для middle-разработчика?
- 64
В чём разница между юнит-тестами, интеграционными тестами и end-to-end тестами?
unitintegratione2e - 65
Как тестировать API-эндпоинт Express?
endpoints - 66
Что такое мокирование в тестах и когда нужно избегать избыточного мокирования?
mocking - 67
Как диагностировать утечку памяти в Node.js-сервисе?
memory - 68
Как отлаживать production-проблему, которую невозможно воспроизвести локально?
- 69
Как обеспечить консистентность базы данных в интеграционных тестах?
integrationdatabaseconsistency - 70
Что такое разработка через тестирование (TDD) и когда её не стоит применять?
- 71
Опишите ваш подход к рефакторингу большого legacy-кода.
refactoring - 72
Как решать, когда разбираться с техническим долгом, а когда выпускать новую фичу?
tech-debt - 73
Как вы справляетесь с техническими разногласиями с коллегой?
soft-skillsconflict - 74
Как вы быстро осваиваете незнакомую кодовую базу?
onboardinglearning - 75
Как вы коммуницируете ломающее изменение API командам, потребляющим ваш сервис?
communicationapi - 76
Как вы оцениваете время разработки для фичи, которую никогда не строили?
estimation - 77
Каким должен быть хороший pull request?
code-review - 78
Опишите баг, вызванный гонкой состояний, с которым вы сталкивались или можете рассуждать о нём. Как его найти и исправить?
concurrency - 79
Как вы следите за изменениями в экосистеме JavaScript и Node.js, не отвлекаясь на каждую новую библиотеку?
learningjavascript - 80
Расскажите о случае, когда вам пришлось отстаивать техническое решение перед нетехническим стейкхолдером.
communication - 81
Что для вас означает владение фичей за рамками написания кода?
- 82
Как реализовать rate limiting в Node.js API, развёрнутом на нескольких экземплярах?
rate-limitingdeployment - 83
Как безопасно обрабатывать загрузки файлов в Node.js приложении?
soft-skills - 84
В чём разница между синхронным и асинхронным логированием и почему это важно в высоконагруженном Node.js сервисе?
loggingasync - 85
Как проектировать API для мобильных клиентов, которым нужно минимизировать передачу данных?
designapi - 86
Что такое CQRS и когда добавленная сложность оправдана?
cqrsalgorithms - 87
Как управлять конфигурацией, специфичной для среды, между разработкой, staging и production?
config - 88
Что такое полнотекстовый поиск PostgreSQL и когда лучше использовать Elasticsearch?
postgressearch - 89
Что происходит при исчерпании пула соединений с базой данных и как это предотвратить?
databasepooling - 90
Как подходить к доступности при создании React-компонентов?
reactcomponentsa11y - 91
Как async/await взаимодействует с Promise.all и когда его использовать?
asyncpromises - 92
Какова цель монорепозитория и какие инструменты помогают им управлять?
monorepo - 93
Как реализовать аутентификацию через OAuth или сторонний провайдер идентификации?
authoauth - 94
Что такое Server-Sent Events (SSE) и как они сравниваются с WebSocket для обновлений в реальном времени?
websocketssse - 95
Как реализовать оптимистичные обновления UI в React-приложении?
reactlocking - 96
Каково предназначение построителей запросов и ORM к базам данных, и когда предпочтительнее чистый SQL?
sqldatabasequeries - 97
Как обрабатывать долгие API-запросы, которые могут превысить таймаут клиента?
soft-skillsapi - 98
Что такое Content Security Policy и как её настроить для React-приложения?
reactcspconfig - 99
Как реализовать feature flag-и в full-stack приложении?
feature-flags - 100
Как подходить к профилированию производительности медленной страницы Next.js?
profilingnextjs