Библиотека собеса по Java | вопросы с собеседований
6.48K subscribers
433 photos
11 videos
712 links
Вопросы с собеседований по Java и ответы на них.

По рекламе: @proglib_adv

Учиться у нас: clc.to/3wECtA

Для обратной связи: @proglibrary_feeedback_bot
Download Telegram
Что происходит с @Async методом, если он вызывается из того же класса?

Self-invocation убивает прокси

Spring создаёт AOP-прокси вокруг бина. Когда ты вызываешь this.sendEmail(), вызов идёт напрямую к объекту, минуя прокси. @Async не срабатывает, метод выполняется синхронно в том же потоке. Никакого исключения — просто тихий фейл.

private метод — та же история.

CGLIB-прокси не может переопределить private метод. Spring либо кидает предупреждение в лог, либо молча игнорирует аннотацию.

⚠️ Ещё один подводный камень

Исключения внутри @Async метода не пробрасываются к вызывающему коду. Если метод возвращает void, исключение просто теряется (уходит в AsyncUncaughtExceptionHandler). Если Future — исключение обёрнуто и бросится только при вызове get().

📌 Как правильно

Вынести @Async метод в отдельный бин и вызов пойдёт через прокси
Настроить AsyncUncaughtExceptionHandler для обработки ошибок
Возвращать CompletableFuture если нужно отслеживать результат

🐸 Библиотека собеса по Java

#spring
Please open Telegram to view this post
VIEW IN TELEGRAM
👍83🔥2
Что такое N+1 проблема в Hibernate и чем JOIN FETCH отличается от @EntityGraph?

Загружаешь список из N сущностей, а потом для каждой Hibernate делает отдельный SELECT за связанной коллекцией. 1 запрос на список + N запросов на детали = катастрофа на проде.

// Загружаем 100 заказов — получаем 101 запрос
List<Order> orders = orderRepo.findAll();
orders.forEach(o -> o.getItems().size()); // LAZY — N запросов здесь


JOIN FETCH vs @EntityGraph

JOIN FETCH — пишешь в JPQL явно:
@Query("SELECT o FROM Order o JOIN FETCH o.items WHERE o.status = :s")
List<Order> findWithItems(@Param("s") Status s);

Гибко, но размножается: для каждой комбинации связей нужен свой метод.

@EntityGraph — декларативно, переиспользуемо:
@EntityGraph(attributePaths = {"items", "items.product"})
List<Order> findByStatus(Status status);


⚠️ Узкие места

JOIN FETCH с коллекциями если fetch двух коллекций одновременно → MultipleBagFetchException. Hibernate не умеет делать два JOIN FETCH на Bag-коллекции в одном запросе.

@EntityGraph → на больших данных легко получить декартово произведение в результирующем SQL и огромный набор дублирующихся строк. Используй DISTINCT или Set вместо List.

🐸 Библиотека собеса по Java

#spring
Please open Telegram to view this post
VIEW IN TELEGRAM
7👍4🔥2
Чем BeanFactory отличается от ApplicationContext?

BeanFactory — минималистичный IoC-контейнер. Умеет создавать бины и резолвить зависимости. Бины создаются лениво — только при первом getBean(). Используется в очень ресурсоограниченных средах (embedded-системы), в обычных Spring-приложениях практически не встречается.

ApplicationContext расширяет BeanFactory и добавляет всё, без чего реальное приложение не живёт: eager-инициализацию singleton'ов при старте, поддержку событий (ApplicationEvent), интернационализацию (MessageSource), lifecycle-коллбэки (@PostConstruct / @PreDestroy), AOP-интеграцию и работу с окружением (Environment / @Value).

⚠️ ApplicationContext создаёт все singleton-бины сразу при старте. Это значит: ошибки конфигурации (неверные зависимости, битые @Value) падают немедленно, а не при первом обращении к бину в рантайме.

🐸 Библиотека собеса по Java

#spring
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17🔥1😁1
Для чего нужен @Conditional в Spring?

@Conditional регистрирует бин только при выполнении определённого условия.

@Bean
@Conditional(WindowsCondition.class)
public Service windowsService() {
return new WindowsService();
}

class WindowsCondition implements Condition {
public boolean matches(ConditionContext context,
AnnotatedTypeMetadata metadata) {
return System.getProperty("os.name")
.contains("Windows");
}
}


Spring Boot предоставляет готовые: @ConditionalOnProperty, @ConditionalOnClass, @ConditionalOnMissingBean.

🐸 Библиотека собеса по Java

#spring
Please open Telegram to view this post
VIEW IN TELEGRAM
👍62🔥1
Опишите жизненный цикл бина в Spring

Основные этапы:

1. Создание экземпляра (вызов конструктора).
2. Внедрение зависимостей (поля/сеттеры).
3. Вызов Aware-интерфейсов (BeanNameAware, ApplicationContextAware и т. д.).
4. BeanPostProcessor.postProcessBeforeInitialization.
5. @PostConstruct.
6. afterPropertiesSet() (InitializingBean), затем кастомный init-метод.
7. BeanPostProcessor.postProcessAfterInitialization — здесь навешиваются прокси (AOP, @Transactional).
8. Бин готов к использованию.

При завершении контекста: @PreDestroy → destroy() (DisposableBean) → кастомный destroy-метод.

🐸 Библиотека собеса по Java

#spring
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥2
Почему @Transactional не срабатывает при вызове метода внутри того же класса?

Потому что @Transactional работает через прокси. Spring оборачивает бин в прокси-объект, и транзакция открывается, когда вызов проходит через этот прокси извне.

Если же метод класса вызывает другой @Transactional-метод того же класса напрямую (this.method()), вызов идёт мимо прокси — аннотация просто игнорируется, транзакция не открывается. Это называется self-invocation.

Решения:

- вынести транзакционный метод в отдельный бин;
- инжектить ссылку на самого себя (self-injection) и вызывать через неё;
- переключиться на AspectJ-режим вместо проксей.

🐸 Библиотека собеса по Java

#spring
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥1👏1
Как Spring разрешает циклические зависимости между бинами?

Для синглтонов с внедрением через поля или сеттеры через кеш ранних ссылок (трёхуровневый кеш). Spring создаёт «сырой» экземпляр бина, кладёт раннюю ссылку на него до завершения инициализации, и второй бин в цикле получает эту ссылку, не дожидаясь полной готовности первого.

А вот при внедрении через конструктор цикл разрешить нельзя: чтобы создать бин A, нужен готовый B, а чтобы создать B — готовый A. Результат — BeanCurrentlyInCreationException.

Лучшее решение — устранить цикл, так как это обычно запах архитектуры. Как костыль — @Lazy на одной из зависимостей.

🐸 Библиотека собеса по Java

#spring
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍2🔥1
В чём разница между @Component и @Bean?

Оба регистрируют бин в контейнере, но по-разному:

@Component (и специализации @Service, @Repository, @Controller) вешается на класс. Spring сам находит его при сканировании компонентов и создаёт бин. Подходит для своих классов, которые вы пишете сами.

@Bean вешается на метод внутри @Configuration-класса. Вы вручную создаёте объект и возвращаете его. Это нужно, когда:
бин из чужой библиотеки, куда нельзя добавить аннотацию;
требуется нетривиальная логика конструирования;
нужно условно собрать разные реализации.

🐸 Библиотека собеса по Java

#spring
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥3👏1
Как Spring реализует AOP и какие у проксей ограничения?

AOP выносит сквозную логику (транзакции, логирование, безопасность) в аспекты, не загрязняя бизнес-код. Spring применяет advice через прокси: JDK dynamic proxy, если бин реализует интерфейс, или CGLIB (наследование класса), если интерфейса нет.

Advice срабатывает только при вызове через прокси. Отсюда ограничения:
self-invocation не перехватывается;
CGLIB не может проксировать final-классы и методы, а также private-методы;
работает только на бинах, управляемых Spring.

🐸 Библиотека собеса по Java

#spring
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥1👏1
Чем отличаются BeanFactory и ApplicationContext?

BeanFactory — базовый IoC-контейнер с ленивой инициализацией: бины создаются при первом обращении.

ApplicationContext расширяет BeanFactory и добавляет почти всё, чем пользуются на практике:

eager-инициализацию синглтонов при старте;
интернационализацию (MessageSource);
публикацию и обработку событий;
автоматическую регистрацию BeanPostProcessor и BeanFactoryPostProcessor;
интеграцию с AOP и удобную работу с ресурсами.

В реальных приложениях используют ApplicationContext. BeanFactory — нишевый вариант для крайне ресурсно-ограниченных сред.

🐸 Библиотека собеса по Java

#spring
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥1👏1
Что такое propagation у @Transactional?

Propagation — политика того, как метод с аннотацией @Transactional будет взаимодействовать с существующей транзакцией.

Виды:

▪️ REQUIRED (по умолчанию): использует существующую транзакцию или создаёт новую, если её нет

▪️ REQUIRES_NEW: всегда создаёт новую транзакцию, при этом приостанавливая текущую

▪️ SUPPORTS: действует в рамках текущей транзакции, если есть, иначе без транзакции

▪️ MANDATORY: бросает исключение, если нет текущей транзакции

▪️ NEVER: запрещает наличие транзакции, если уже есть, бросает исключение

▪️ NESTED: создаёт «вложенную» транзакцию (savepoint внутри основной)

🐸 Библиотека собеса по Java

#spring
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍1🔥1