Вопросы по 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 работает поверх сервлетной модели. Понимание жизненного цикла и фильтров помогает объяснить, откуда берётся контекст запроса и как работает пул потоков.
Что спрашивают про сессии?
Чем сессия отличается от куки, где она хранится, что происходит при нескольких инстансах приложения и как жить без липких сессий.