Ниже приведены несколько типичных сценариев с короткими ответами (TL;DR — можно сохранить для повторения перед интервью):
🔸Типы Spring-бинов и стереотипы
Сценарий: Представь, что ты проектируешь сложную e-commerce платформу. Где ты используешь интерфейс с аннотацией
@Repository, а где — с аннотацией @Service? Приведи конкретный пример, какую роль каждая из этих аннотаций играет в процессе оформления заказа пользователем.→
@Component — универсальный бин,@Service — бизнес-логика,@Repository — DAO + перевод исключений в DataAccessException,@Controller — контроллер уровня MVC.🔸Циклические зависимости
Сценарий: Коллега добавил новую фичу, и теперь твое Spring-приложение не стартует, выдавая BeanCurrentlyInCreationException из-за циклической зависимости между ServiceA и ServiceB.
Предположим, что быстро переработать бизнес-логику невозможно. Какое минимальное изменение кода ты бы предложил, чтобы приложение хотя бы запустилось, и почему это считается временным решением?
→
Spring по умолчанию может использовать проксирование и конструкторную/сеттерную инъекцию.
Лучшее решение — перепроектировать зависимости или использовать
@Lazy.🔸Распространение транзакций
Сценарий: У тебя есть OrderService с методом createOrder(), помеченным
@Transactional.Внутри он вызывает updateInventory() (тоже в OrderService и тоже с
@Transactional).Если updateInventory() выбрасывает runtime-исключение, что произойдет с транзакцией, начатой в createOrder()?
Как изменить дизайн, если нужно, чтобы оба метода выполнялись в отдельных, независимых транзакциях?
→
Транзакция не будет распространяться (прокси не сработает при внутреннем вызове).
Решение — self-injection (внедрение самого себя как зависимости) или использование AOP.
🔸Скоупы бинов
Сценарий: Нужно хранить товары пользователя в корзине и управлять временным списком поисковых фильтров, который очищается после каждого HTTP-запроса.
Какой скоуп ты выберешь для ShoppingCart и какой — для SearchFilter, и почему?
→
@SessionScope — для корзины (привязано к пользовательской сессии),@RequestScope — для поискового фильтра (новый бин на каждый HTTP-запрос).🔸Controller Advice
Сценарий: В приложении есть и традиционные веб-эндпоинты с Thymeleaf, и REST API.
Нужно централизовать обработку ошибок (например, перехват ResourceNotFoundException):
Как вернуть страницу 404 для обычных web-эндпоинтов?
Как вернуть JSON с ошибкой 404 для REST API?
→
@ControllerAdvice — используется с @Controller, возвращает view.@RestControllerAdvice — сочетает @ControllerAdvice + @ResponseBody (для REST API).🔸Автоконфигурация
Сценарий: Ты добавил в проект стороннюю библиотеку (например, кастомный логгер) и просто положил её JAR в classpath.
Без написания конфигурационных классов Spring автоматически подхватывает нужные бины.
Объясни, как Spring Boot определяет и подключает их при старте.
→
Использует SpringFactoriesLoader, который читает META-INF/spring.factories и конфигурирует бины в зависимости от содержимого classpath.
🔸Ограничение частоты запросов
Сценарий: Твой публичный API перегружен — один клиент шлет слишком много запросов, мешая остальным.
Какой практичный, независимый от технологий подход можно применить для ограничения, например, 100 запросов в минуту на клиента, и где обычно реализуется такая логика?
→
Bucket4j / Resilience4j, счетчики в Redis, лимитирование на уровне API Gateway.
🔸Распределённые транзакции
Сценарий: В микросервисной архитектуре оформление заказа включает два шага — списание товара в Inventory Service и списание денег через Payment Service.
Если списание товара прошло успешно, а оплата — нет, какой шаблон проектирования поможет откатить изменения в Inventory и обеспечить согласованность данных?
→
Шаблон Saga (хореография или оркестрация), либо двухфазный коммит (2PC, но редко используется на практике).
👉 Java Portal
