Вопросы на собеседовании: Бэкенд-разработчик
100 реальных вопросов с образцовыми ответами и пояснениями для уровня Middle.
Смотреть пример резюме: Бэкенд-разработчик →Вопросы
Держите URL мелкими и подгружайте глубокие связи отдельно.
- Вкладывайте только на один уровень, например /orders/{id}/items, избегая /users/{id}/orders/{id}/items.
- Для более глубоких связей возвращайте идентификаторы связанных ресурсов и давайте клиенту грузить их отдельно.
- Или предложите параметр ?include=, инициирующий JOIN на стороне сервера.
- Определите соглашения по именованию, методам и структуре ошибок до первого эндпоинта.
Зачем это спрашивают: Интервьюер проверяет, понимает ли кандидат ограничения REST и умеет ли балансировать между удобством навигации и практичностью использования, а не просто знает слово REST.
Проблема N+1: один запрос на N записей плюс ещё по запросу на каждую запись.
- В итоге выходит N+1 запросов вместо одного.
- В ORM решается жадной загрузкой через JOIN-включения или пакетный загрузчик вроде DataLoader.
- В сыром SQL перепишите как один запрос с JOIN или IN, а затем соберите результат в коде.
Зачем это спрашивают: Это лакмусовая бумажка реального опыта работы с ORM и умения рассуждать о связи между кодом приложения и количеством обращений к базе данных.
Различие в том, блокируете ли вы строку заранее.
- Оптимистическая считает конфликты редкими: читает с версией, проверяет её при обновлении, откатывает если изменилась.
- Пессимистическая блокирует строку при чтении, не давая другим писателям до коммита.
- Используйте оптимистическую для записей с низкой конкуренцией, например обновления профиля.
- Используйте пессимистическую для операций с высокой конкуренцией, например резервирования ограниченных мест.
Зачем это спрашивают: Интервьюер хочет убедиться, что кандидат знает конкурентные последствия каждого подхода и может подобрать механизм под реальную частоту конфликтов.
Выбирайте документоориентированную базу, когда данные естественно иерархичны или полиморфны.
- Хорошо подходит для вложенных или полиморфных структур, требующих в SQL множества JOIN-таблиц.
- Также когда схема быстро меняется и добавление столбцов в общую таблицу было бы разрушительным.
- Реляционная выигрывает для многострочных ACID-транзакций, сложных произвольных запросов и строгой ссылочной целостности.
- Решение зависит от паттернов доступа, а не только от формы данных.
Зачем это спрашивают: Интервьюер проверяет, избегает ли кандидат слепого копирования чужих решений и умеет ли формулировать конкретные компромиссы вместо ссылок на популярность.
Используйте присланный клиентом Idempotency-Key для дедупликации запросов.
- Клиент генерирует уникальный ключ, обычно UUID, и отправляет его с запросом.
- Сервер сохраняет ключ и ответ в кратковременном кеше вроде Redis перед обработкой.
- При повторном ключе возвращает кешированный ответ, не выполняя побочный эффект.
- Установите TTL, обычно 24 часа, и задокументируйте окно повторных попыток клиента.
Зачем это спрашивают: Идемпотентность критична для эндпоинтов оплаты и заказов; интервьюер проверяет, сталкивался ли кандидат с реальными сценариями повторных попыток и понимает ли серверную механику.
Пул соединений переиспользует открытые соединения с базой между запросами.
- Это избегает нового TCP-соединения и TLS-рукопожатия на каждый запрос.
- Без него сервис под нагрузкой может исчерпать лимиты соединений и добавить сотни мс на запрос.
- Настраивайте минимальный и максимальный размер пула по конкурентности, max_connections базы и среднему времени запроса.
Зачем это спрашивают: Вопрос выявляет, понимает ли кандидат операционную границу между кодом приложения и базой данных и умеет ли рассуждать об исчерпании ресурсов под нагрузкой.
Подтвердите утечку, затем снимайте хип, чтобы найти удерживаемое.
- Подтвердите по метрике использования хипа, которая растёт вместо возврата к базовому уровню после GC.
- Делайте снимки хипа во времени через --inspect и Chrome DevTools или clinic.js, затем сравнивайте их.
- Ищите неудалённые слушатели событий, замыкания с большими буферами и неограниченные кеши на уровне модуля.
Зачем это спрашивают: Интервьюер хочет убедиться, что кандидат движется от симптома к причине систематически, а не угадывает и перезапускает процесс.
Circuit breaker отслеживает частоту ошибок зависимости и быстро падает при их всплеске.
- Он считает ошибки за скользящее окно.
- Когда частота ошибок превышает порог, он открывается и вызовы падают сразу без обращения к зависимости.
- После таймаута переходит в полуоткрытое состояние, пропуская один пробный запрос; успех закрывает его снова.
- Применяйте к синхронным внешним вызовам, где медленные отказы истощили бы пулы потоков или очереди.
Зачем это спрашивают: Вопрос проверяет, понимает ли кандидат режимы каскадных отказов в распределённых системах и знает ли конкретный механизм для ограничения радиуса поражения.
B-tree индекс даёт поиск за O(log n), но добавляет стоимость записи.
- Он хранит отсортированные ключи в сбалансированном дереве, находя строки за O(log n) вместо полного сканирования.
- Он ускоряет чтение, но замедляет каждый INSERT, UPDATE и DELETE, так как обновляется и дерево.
- Добавляйте, когда планы показывают последовательное сканирование больших таблиц с избирательными фильтрами.
- Проверяйте неиспользуемые индексы через pg_stat_user_indexes и удаляйте лишние.
Зачем это спрашивают: Это позволяет оценить, понимает ли кандидат, что индексы не бесплатны, и умеет ли рассуждать о компромиссе чтение/запись вместо рефлекторного добавления индекса на каждый столбец.
CAP утверждает, что распределённое хранилище гарантирует не более двух из трёх: согласованность, доступность и устойчивость к разделению.
- Разделения неизбежны, поэтому реальный выбор между CP и AP.
- Пример CP: PostgreSQL с синхронной репликацией.
- Пример AP: Cassandra или DynamoDB.
- Используйте это, чтобы решить, терпит ли сервис устаревшие чтения или нуждается в линеаризуемых.
Зачем это спрашивают: Интервьюер проверяет, умеет ли кандидат переводить теоретическое ограничение в конкретное дизайн-решение, а не просто рассказывать теорему.
Используйте паттерн expand-contract для изменений схемы без простоя.
- Сначала деплойте миграцию, добавляющую новые столбцы или таблицы без удаления старых.
- Деплойте код, который пишет и в старую, и в новую структуру.
- Заполните существующие данные, затем деплойте финальную миграцию, удаляющую старую структуру.
- Избегайте блокирующего DDL, используя concurrent index builds в PostgreSQL.
Зачем это спрашивают: Это выявляет, владел ли кандидат схемой в продакшне и понимает ли, что наивный ALTER TABLE может заблокировать таблицу на минуты и вызвать даунтайм.
Вертикальное добавляет ресурсы одной машине; горизонтальное добавляет экземпляры.
- Вертикальное добавляет CPU или RAM одной машине: просто, но ограниченно и создаёт единую точку отказа.
- Горизонтальное добавляет экземпляры за балансировщиком, требуя stateless-приложений или вынесенного состояния.
- По умолчанию выбирайте горизонтальное для stateless API-сервисов.
- Принимайте вертикальное для управляемых баз, пока не нужны read replicas или шардирование.
Зачем это спрашивают: Интервьюер хочет убедиться, что кандидат понимает предпосылку statelessness для горизонтального масштабирования и умеет рассуждать об операционной сложности каждого варианта.
Event sourcing хранит состояние как упорядоченный лог неизменяемых событий.
- Текущее состояние получается воспроизведением событий с начала или со снимка.
- Подходит, когда нужен полный аудит, воспроизведение истории или несколько read-моделей.
- Стоимость: сложные read-пути, итоговая согласованность между проекциями и больше хранилища.
Зачем это спрашивают: Вопрос оценивает, понимает ли кандидат, когда добавленная сложность оправдана, а не применяет ли паттерн там, где это было бы избыточным усложнением CRUD-сервиса.
Используйте token bucket или скользящее окно в Redis с ключом по клиенту.
- Ключ по API-ключу или IP-адресу.
- На каждый запрос атомарно уменьшайте счётчик и проверяйте лимит, возвращая 429 с Retry-After при превышении.
- Настраивайте лимиты на ключ для разных уровней клиентов и отдавайте X-RateLimit-Remaining.
- Рассмотрите вынос логики на уровень шлюза, чтобы код сервиса оставался чистым.
Зачем это спрашивают: Это проверяет практические знания управления распределённым состоянием для распространённого механизма защиты API и думает ли кандидат об опыте клиента, а не только о защите сервера.
Найдите конфликтующие блокировки, затем обеспечьте согласованный порядок их захвата.
- Запросите pg_locks и pg_stat_activity или лог ошибок, чтобы увидеть, кто держит и ждёт что.
- Дедлоки обычно возникают из-за захвата блокировок в разном порядке.
- Исправьте, захватывая блокировки в согласованном порядке, часто сортируя идентификаторы ресурсов заранее.
- Установите разумный lock_timeout, чтобы зависшая транзакция быстро падала.
Зачем это спрашивают: Интервьюер проверяет, действительно ли кандидат отлаживал дедлок и знает конкретные инструменты и первопричину, а не просто теоретическое определение.
Держите транзакции локальными и используйте саги между сервисами.
- Проектируйте вокруг ограниченных контекстов, чтобы каждая транзакция была локальной для одного сервиса.
- Для межсервисных операций используйте паттерн саги через события-хореографию или оркестратор.
- Принимайте итоговую согласованность на границах сервисов как практическую реальность.
- Проектируйте под неё UX, например состояние ожидания пока завершается асинхронная операция.
Зачем это спрашивают: Это проверяет, понимает ли кандидат, что two-phase commit обычно непрактичен в микросервисах, и знает ли реальные альтернативы с их компромиссами.
Очередь доставляет сообщение одному потребителю; pub-sub рассылает всем подписчикам.
- Очередь: один потребитель забирает сообщение, и оно удаляется, хорошо для распределения работы.
- Pub-sub: каждый текущий подписчик получает сообщение, хорошо для широковещания событий.
- Kafka размывает границу: группы потребителей ведут себя как очереди, независимые группы воспроизводят тот же лог.
- Выбирайте по тому, обрабатывается ли сообщение один раз или многими независимыми системами.
Зачем это спрашивают: Интервьюер ищет кандидата, умеющего различать конкурирующие паттерны сообщений и подбирать правильный под реальный сценарий использования.
Используйте stateless JWT для аутентификации и проверки в middleware для авторизации.
- Выдавайте короткий access-токен и долгий refresh-токен при входе; передавайте access-токен в Authorization.
- Храните роли или детальные разрешения в базе и проверяйте их в middleware до обработчика.
- Держите логику auth отдельно от бизнес-логики.
- Ротируйте ключи подписи, ставьте строгий срок действия и используйте HTTPS, чтобы предотвратить кражу токенов.
Зачем это спрашивают: Это позволяет оценить, знает ли кандидат полный жизненный цикл аутентификации, а не только как декодировать JWT, и понимает ли последствия истечения срока действия и отзыва токенов для безопасности.
Денормализация хранит избыточные данные, чтобы избежать дорогих JOIN.
- Пример: копировать отображаемое имя пользователя в таблицу заказов.
- Помогает, когда read-heavy эндпоинт делает один и тот же JOIN миллионы раз.
- Компромисс: обновления нужно распространять на копии, добавляя сложность записи и риск устаревания.
- Вводите только после того, как профилирование подтвердит, что JOIN реально узкое место.
Зачем это спрашивают: Вопрос проверяет, рассматривает ли кандидат денормализацию как обдуманный, взвешенный компромисс, а не выбор стиля по умолчанию.
Кешируйте данные, которые дороги, меняются редко и читаются куда чаще, чем пишутся.
- Кешируйте на слое, ближайшем к потребителю.
- Для разделяемых между экземплярами данных используйте Redis с явным TTL и инвалидацией при записи.
- Защищайтесь от cache stampede вероятностным досрочным истечением или мьютексом при холодном кеше.
- Делайте ключи узкими и для простых случаев предпочитайте TTL-истечение событийной инвалидации.
Зачем это спрашивают: Это проверяет, понимает ли кандидат классические компромиссы кеширования и сталкивался ли с реальными проблемами инвалидации, а не воспринимает Redis как магию.
Закрытые вопросы
- 21
Каковы практические различия между HTTP/1.1 и HTTP/2 для бэкенд-сервисов?
http - 22
Что такое паттерн саги и как он управляет распределёнными транзакциями?
sagadistributedtransactions - 23
Как обрабатывать долгоживущие фоновые задания в веб-приложении?
soft-skillsjobs - 24
Каковы компромиссы между синхронным и асинхронным проектированием API?
designapiasync - 25
Как реализовать эффективную пагинацию для больших наборов данных?
pagination - 26
Что такое фильтр Блума и для каких бэкенд-задач он подходит?
bloom-filter - 27
Как писать интеграционные тесты для сервиса, вызывающего внешние API?
integrationapi - 28
Что такое gRPC и когда вы предпочтёте его REST?
restgrpc - 29
Как профилировать медленный API-эндпоинт в продакшне?
endpoints - 30
Что такое итоговая согласованность и каковы практические последствия построения систем с ней?
system-designconsistency - 31
Как проектировать схему базы данных для мультитенантного приложения?
databaseschemadesign - 32
Что такое CQRS и когда имеет смысл его применять?
cqrs - 33
Как реализовать распределённую блокировку?
lockingdistributed - 34
Какие стратегии вы используете для снижения P99 задержки в высоконагруженном сервисе?
latency - 35
Как валидировать и санировать пользовательский ввод в бэкенд-сервисе?
validation - 36
Как структурировать бэкенд-код, чтобы он был тестируемым?
- 37
Что такое шардирование базы данных и какие трудности оно вносит?
databasesharding - 38
Как управлять секретами и конфигурацией в развёрнутом приложении?
deploymentconfigsecrets - 39
В чём разница между жёстким и мягким удалением и как выбрать между ними?
soft-delete - 40
Как вы подходите к код-ревью как middle-разработчик?
code-review - 41
Что такое наблюдаемость и как её реализовать в бэкенд-сервисе?
observability - 42
Как управлять версионированием API?
versioningsoft-skills - 43
Что такое backpressure в потоковой системе и как с ним работать?
system-designstreamingbackpressure - 44
Что такое JWT и каковы его основные соображения безопасности?
jwt - 45
Как спроектировать эффективную систему планирования заданий для периодических задач?
system-designdesignjobs - 46
В чём разница между OLTP и OLAP нагрузками и как это влияет на выбор базы данных?
database - 47
Как реализовать логику повторных попыток с экспоненциальной задержкой?
resilience - 48
Что такое подготовленный запрос и как он предотвращает SQL-инъекцию?
sqlinjection - 49
В каких ситуациях можно намеренно отказаться от использования ограничения внешнего ключа?
foreign-keys - 50
Как вы реагируете, когда сервис, за который вы отвечаете, падает в продакшне?
incidents - 51
Что такое обратный прокси и зачем ставить его перед бэкенд-сервисом?
proxy - 52
Как измерять и улучшать пропускную способность пайплайна обработки данных?
throughputconcurrency - 53
Как безопасно обрабатывать параллельные записи в одну строку базы данных?
soft-skillsdatabaseconcurrency - 54
В чём разница между сканированием индекса и последовательным сканированием в PostgreSQL и когда каждое из них происходит?
indexespostgres - 55
Как решить, когда вводить очередь сообщений в архитектуру?
queues - 56
Как надёжно реализовать систему доставки вебхуков?
system-designwebhooks - 57
Как тестировать бизнес-логику, тесно связанную с вызовами базы данных?
database - 58
Что такое service mesh и когда он становится полезным?
service-mesh - 59
Как управлять настройками пула соединений базы данных при высокой конкурентности?
databasepoolingconcurrency - 60
Каковы свойства ACID транзакции базы данных и что каждое означает на практике?
databasetransactionsacid - 61
В чём разница между структурированным и неструктурированным логированием и что предпочтительнее для продакшн-сервисов?
logging - 62
Как реализовать полнотекстовый поиск в бэкенд-сервисе?
search - 63
Как обрабатывать частичные сбои в распределённой системе?
system-designdistributedsoft-skills - 64
Что такое паттерн strangler fig и когда он полезен?
migration - 65
Как обеспечить обратную совместимость при внесении изменений в API?
api - 66
Что такое read replica и как использовать её в архитектуре?
replicationarchitecture - 67
Каков ваш процесс написания постмортема после продакшн-инцидента?
incidentsconcurrency - 68
В чём разница между жадной и ленивой загрузкой в ORM?
ormlazy-loading - 69
Как реализовать health check и readiness probe для бэкенд-сервиса?
health-checks - 70
Как поддерживать зависимости сервиса в актуальном состоянии, не ломая приложение?
dependencies - 71
Как проектировать API-контракт между двумя командами?
designapi - 72
Где должна происходить терминация SSL/TLS в вашей инфраструктуре и почему?
tls - 73
Как реализовать флаги функций в бэкенд-сервисе?
feature-flags - 74
Как приоритизировать исправление технического долга наряду с разработкой новых функций?
prioritizationtech-debt - 75
Что такое журнал предзаписи в базе данных и как он используется?
database - 76
Как обрабатывать сложность часовых поясов в бэкенд-приложении?
soft-skillsalgorithms - 77
Как CDN взаимодействует с бэкенд API-сервисом?
api - 78
Как выбрать между использованием ORM и написанием сырого SQL?
sqlorm - 79
Что такое план выполнения запроса в базе данных и как использовать его для оптимизации запросов?
databasequeriesoptimization - 80
Как реализовать идемпотентных потребителей сообщений для очереди?
idempotency - 81
Как оркестрация контейнеров влияет на то, как вы пишете бэкенд-сервисы?
containers - 82
Как подходить к нагрузочному тестированию перед крупным релизом?
testing - 83
Каковы компромиссы между UUID и автоинкрементным целым числом в качестве первичного ключа?
primary-keys - 84
Как реализовать многофакторную аутентификацию в бэкенд-сервисе?
auth - 85
Как диагностировать и исправлять медленные запросы к базе данных в продакшн-системе?
databasequeriessystem-design - 86
В чём разница между сбором метрик на основе push и pull?
monitoring - 87
Как выбрать формат сериализации данных для межсервисной коммуникации?
serialization - 88
Что такое проблема fan-out в социальных лентах и как вы её решаете?
fan-out - 89
Как реализовать graceful shutdown для бэкенд-сервиса?
lifecycle - 90
Что такое API-шлюз и какие функции он обычно берёт на себя?
gatewayapi - 91
Как обрабатывать каскадные сбои между сервисами?
soft-skills - 92
Что такое материализованное представление и когда его использовать?
materialized-views - 93
Как обеспечить, что ваш сервис справится с внезапным 10-кратным всплеском объёма запросов?
- 94
Что такое задача двух генералов и как она связана с распределёнными системами?
system-designdistributed - 95
Что такое вертикальное партиционирование и чем оно отличается от горизонтального?
partitioningscaling - 96
Как наставлять младшего разработчика в вашей команде?
mentoring - 97
Как вы оцениваете трудозатраты для технической задачи?
estimation - 98
Как вы оцениваете и принимаете новую технологию в свой стек?
decision-making - 99
Как управлять изменениями схемы базы данных, затрагивающими разделяемую библиотеку, используемую несколькими сервисами?
databaseschemasoft-skills - 100
Что вы делаете, когда не согласны с техническим решением, принятым более старшим инженером?
conflict