Вопросы по Java-вебу на собеседовании
Веб-вопросы у Java-разработчика проверяют, понимаешь ли ты, что происходит между запросом и твоим методом. Сервлеты сегодня почти никто не пишет руками, но именно через них объясняют модель обработки запроса.
Из чего состоит тема
Так тема разложена в тренажёре: движок ведёт прогресс по каждой подтеме отдельно и возвращает те, что просели.
- Аутентификация и защита17
- Микросервисы17
- Очереди и Kafka17
- HTTP и REST16
- Дизайн API12
Разборы подтем
Конспект по каждой: что это, как отвечать вслух, на чём валятся, плюс вопросы для самопроверки.
- Дизайн API в Java12 вопросов
- HTTP и REST в Java16 вопросов
- Очереди и Kafka в Java17 вопросов
- Микросервисы на Java17 вопросов
- Аутентификация и защита в Java17 вопросов
Примеры вопросов с разбором
- Зачем в публичном API вводят версионирование (/v1, /v2)?A)Менять API, не ломая существующих клиентов на старой версииB)Чтобы ускорить обработку запросов: чем выше номер версии, тем быстрее работает эндпоинт на сервереC)Чтобы шифровать разные версии API разными ключами, повышая безопасность передачи данных клиентамD)Чтобы разделить нагрузку: чётные версии обслуживает один сервер, нечётные — другой, для баланса
показать ответ и разбор
+A)Менять API, не ломая существующих клиентов на старой версии// разбор: Публичный API имеют внешние потребители, которых нельзя обновить одномоментно. Версионирование позволяет выпускать ЛОМАЮЩИЕ изменения (переименовать/удалить поле, сменить формат) в НОВОЙ версии (/v2), продолжая обслуживать старых клиентов на /v1, пока они мигрируют. Способы: в пути (/v1/), в заголовке (Accept/версии медиатипа), реже в query. Аддитивные (обратно-совместимые) изменения версии не требуют. Версионирование — это управление жизненным циклом контракта: ввести новое, дать время на переход, вывести старое из эксплуатации.
- Что значит, что HTTP-метод идемпотентен?A)Повтор запроса даёт тот же итог, что и один вызов (GET, PUT, DELETE)B)Метод возвращает один и тот же ответ всем пользователям независимо от их прав и переданных данныхC)Метод выполняется мгновенно и завершается успешно, не возвращая код ошибки клиентуD)Метод изменяет данные на сервере при каждом вызове, накапливая эффект от повторных обращений
показать ответ и разбор
+A)Повтор запроса даёт тот же итог, что и один вызов (GET, PUT, DELETE)// разбор: Идемпотентность: повторное выполнение запроса приводит к ТОМУ ЖЕ состоянию сервера, что и однократное. GET (не меняет состояние — safe), PUT (полная замена ресурса — повтор перезапишет тем же), DELETE (повторное удаление оставляет ресурс удалённым) — идемпотентны. POST (создать новый ресурс) — НЕ идемпотентен: повтор создаст дубль. Это важно для безопасных РЕТРАЕВ при сбоях сети: идемпотентный запрос можно повторить без опаски, а POST — только с ключом идемпотентности.
- Зачем использовать брокер сообщений (Kafka/RabbitMQ) вместо прямого вызова сервиса?A)Асинхронность и развязка: отправитель не ждёт получателя, устойчивость к пикам/сбоямB)Чтобы отказаться от базы данных: брокер хранит все данные приложения вместо неёC)Чтобы ускорить каждый отдельный запрос: сообщение через брокер доходит быстрее HTTP-вызоваD)Чтобы сервисы могли работать только на одном языке, ведь брокеры не поддерживают разные технологии
показать ответ и разбор
+A)Асинхронность и развязка: отправитель не ждёт получателя, устойчивость к пикам/сбоям// разбор: Брокер сообщений даёт АСИНХРОННУЮ, слабо связанную интеграцию: отправитель ПУБЛИКУЕТ сообщение и продолжает работу, не дожидаясь и не зная получателей; брокер надёжно хранит сообщение, пока получатель(и) его не обработают. Плюсы: развязка во времени (сервисы не обязаны быть живы одновременно), сглаживание всплесков нагрузки (буфер/очередь), устойчивость (сообщение переживёт падение потребителя), fan-out (одно событие — многим подписчикам), масштабирование потребителей. Минусы: усложнение (инфраструктура, порядок, дубликаты, отладка) и eventual consistency. Выбирают для событий/фоновой обработки, где не нужен немедленный ответ.
- В чём главный компромисс микросервисов по сравнению с монолитом?A)Независимость деплоя/масштабирования ценой сложности распределённой системыB)Микросервисы быстрее монолита, потому что каждый запрос обрабатывается отдельным процессомC)Микросервисы устраняют необходимость в базах данных, храня всё состояние в памяти сервисовD)Микросервисы проще в разработке и эксплуатации, поэтому их выбирают даже для маленьких приложений
показать ответ и разбор
+A)Независимость деплоя/масштабирования ценой сложности распределённой системы// разбор: Микросервисы дают АВТОНОМНОСТЬ: сервисы деплоятся, масштабируются и разрабатываются независимо разными командами, на разных технологиях, с изоляцией отказов. Но платят СЛОЖНОСТЬЮ распределённой системы: сетевые вызовы (латентность, частичные отказы), распределённые данные и слабая согласованность (eventual consistency, saga), сложная отладка/трассировка, инфраструктура (оркестрация, service discovery, мониторинг). Для маленького приложения/команды это чаще overkill — начинают с хорошо структурированного монолита и выделяют сервисы по мере необходимости. Выбор — инженерный компромисс, а не мода.
- В защите бэкенда: за что отвечает этап аутентификации, а за что — авторизации?A)Аутентификация — кто ты (проверка личности); авторизация — что тебе можно (проверка прав)B)Аутентификация проверяет права доступа к ресурсу, а авторизация устанавливает личность пользователяC)Это синонимы: оба слова означают вход пользователя в систему по логину и паролю без различийD)Аутентификация — про шифрование канала, а авторизация — про сжатие передаваемых данных для скорости
показать ответ и разбор
+A)Аутентификация — кто ты (проверка личности); авторизация — что тебе можно (проверка прав)// разбор: Аутентификация (authentication) отвечает на вопрос «КТО ты?» — проверяет личность (логин/пароль, токен, сертификат). Авторизация (authorization) — «что тебе МОЖНО?» — проверяет права на действие/ресурс уже установленной личности (роли, права, политики). Порядок: сначала authn (узнали, кто), потом authz (решили, можно ли). Отсюда и коды: 401 — не прошёл authn, 403 — прошёл authn, но не хватает прав (authz). Путать их — частая ошибка. В Spring Security это разные этапы фильтра (установить Authentication → проверить доступ).
- Зачем отделять DTO от entity в API?A)DTO работают быстрее entity, так как Hibernate специально оптимизирует их сериализацию в JSONB)Не завязывать контракт API на схему БД и не тащить наружу ленивые связи/лишние поляC)Entity не получится вернуть из контроллера — Spring запрещает сериализовать классы с @EntityD)DTO нужны только для входящих запросов, а для ответов возвращают сами сущности напрямую
показать ответ и разбор
+B)Не завязывать контракт API на схему БД и не тащить наружу ленивые связи/лишние поля// разбор: Entity моделирует ХРАНЕНИЕ (таблицы, связи, ленивая загрузка), DTO — КОНТРАКТ API (что видит клиент). Отдавать entity наружу опасно: контракт API жёстко привязывается к схеме БД (изменил таблицу — сломал клиентов), наружу утекают чувствительные/внутренние поля (пароли, флаги), сериализация дёргает ЛЕНИВЫЕ связи → LazyInitializationException или лавина запросов, возможны циклы в двунаправленных связях. DTO разрывает эту связку: он стабилен, содержит ровно нужные поля, собирается в транзакции. Маппинг делают вручную или MapStruct.
- Проектируя REST-эндпоинт обновления ресурса, когда выбрать PUT, а когда PATCH?A)PUT создаёт новый ресурс, а PATCH только читает существующий, не внося в него никаких измененийB)PUT заменяет ресурс целиком (идемпотентен); PATCH меняет часть полейC)PUT и PATCH идентичны; PATCH — просто более новое название того же метода в свежих версиях HTTPD)PATCH заменяет ресурс целиком и идемпотентен, а PUT вносит частичные изменения по полям
показать ответ и разбор
+B)PUT заменяет ресурс целиком (идемпотентен); PATCH меняет часть полей// разбор: PUT передаёт ПОЛНОЕ представление ресурса и заменяет его целиком — поэтому идемпотентен (повтор перезапишет тем же). PATCH передаёт только ИЗМЕНЕНИЯ (набор полей/патч) и обновляет ресурс частично; он не обязан быть идемпотентным (например, PATCH «увеличить на 1» — нет). Практика: полное обновление сущности — PUT, точечная правка пары полей — PATCH. Отсутствующие в PUT-теле поля по строгой семантике должны обнуляться — этим PUT и коварен для «обновить только имя».
- Что означает гарантия доставки at-least-once и что она требует от потребителя?A)Сообщение доставится не более одного раза, поэтому часть сообщений может быть потеряна безвозвратноB)Сообщение доставится минимум раз (возможны дубли) — потребитель должен быть идемпотентнымC)Сообщение доставится ровно один раз без дублей и потерь — это обеспечивает сам брокер автоматическиD)Порядок сообщений сохраняется глобально, а их содержимое дедуплицируется брокером перед доставкой
показать ответ и разбор
+B)Сообщение доставится минимум раз (возможны дубли) — потребитель должен быть идемпотентным// разбор: Три семантики: at-most-once (доставка ≤1 раза — возможна ПОТЕРЯ, дублей нет); at-least-once (доставка ≥1 раза — потерь нет, но возможны ПОВТОРЫ при ретраях/сбоях подтверждения); exactly-once (ровно один раз — идеал, но дорого и не всегда достижимо end-to-end). Большинство брокеров по умолчанию дают AT-LEAST-ONCE — самый практичный компромисс. Раз возможны ДУБЛИ, ПОТРЕБИТЕЛЬ обязан быть ИДЕМПОТЕНТНЫМ: повторная обработка того же сообщения не должна задваивать эффект (проверять идентификатор/ключ сообщения, upsert вместо insert). «Exactly-once» на практике часто = at-least-once + идемпотентность.
- Как обычно организуют данные в микросервисной архитектуре?A)Все сервисы работают с одной общей базой данных, обращаясь к её таблицам напрямую для скоростиB)У каждого сервиса своя БД; прямой доступ к чужой БД запрещён (только через API/события)C)Данные не хранят: каждый сервис при запросе пересчитывает нужное с нуля в оперативной памятиD)Один сервис владеет всеми данными, а остальные при каждом запросе копируют их себе целиком заранее
показать ответ и разбор
+B)У каждого сервиса своя БД; прямой доступ к чужой БД запрещён (только через API/события)// разбор: Паттерн database-per-service: КАЖДЫЙ сервис владеет СВОИМИ данными и своей БД, а другие сервисы НЕ лезут в неё напрямую — только через его API или подписываясь на его события. Так сохраняется автономия: сервис может менять свою схему/технологию БД, не ломая соседей. Общая БД на всех (shared database) — анти-паттерн: она жёстко связывает сервисы через схему, убивая независимость деплоя. Плата database-per-service — распределённые данные: нет джойнов через сервисы, согласованность через события/saga, дублирование части данных (по необходимости). Инкапсуляция данных — граница сервиса.
это 9 из 79
Ещё 70 вопросов по теме — в тренажёре, с движком повторения
Прочитать разбор и ответить самому — разные навыки. В Сеньорчике вопросы приходят сессиями, а подтему, на которой ты споткнулся, движок принесёт снова: завтра, через три дня, через неделю. Бесплатно, с дневным лимитом вопросов.
Частые вопросы
Зачем спрашивают сервлеты, если все пишут на Spring?
Потому что Spring MVC работает поверх сервлетной модели. Понимание жизненного цикла и фильтров помогает объяснить, откуда берётся контекст запроса и как работает пул потоков.
Что спрашивают про сессии?
Чем сессия отличается от куки, где она хранится, что происходит при нескольких инстансах приложения и как жить без липких сессий.