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

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

Учиться у нас: https://proglib.io/w/08c603b6

Для обратной связи: @proglibrary_feeedback_bot
Download Telegram
Что такое наследование?

Наследование — это механизм ООП, позволяющий создавать новый класс на основе уже существующего. Новый класс (подкласс) получает все свойства и методы родительского класса (суперкласса), что обеспечивает повторное использование кода и упрощает поддержку.

Наследование реализуется с помощью ключевого слова extends. Подкласс может расширять или переопределять поведение суперкласса, а также добавлять новые поля и методы. Важно помнить, что в Java класс может наследоваться только от одного суперкласса.

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

#core
Please open Telegram to view this post
VIEW IN TELEGRAM
👍101🔥1
✔️ Java-тест: задача выполняется, результат теряется

Никаких ошибок в логах. Никаких алертов. Данные просто не сохраняются 👇

📦 Задание — code review

Сервис нотификаций: после оплаты заказа — отправить email и записать событие в БД. Оба действия независимы, сделали асинхронно.

@Service
@RequiredArgsConstructor
public class NotificationService {

private final EmailClient emailClient;
private final EventRepository eventRepository;
private final Executor taskExecutor;

public void notifyOrderPaid(Order order) {
CompletableFuture.runAsync(
() -> emailClient.sendOrderConfirmation(order),
taskExecutor
);

CompletableFuture.runAsync(
() -> {
Event event = Event.orderPaid(order.getId());
eventRepository.save(event);
},
taskExecutor
);
}
}


▪️ Объясни

— Почему исключения из runAsync полностью проглатываются и как это работает внутри.
— Чем отличается поведение runAsync от supplyAsync в контексте обработки ошибок.
— Как переписать код так, чтобы: (1) ошибки логировались, (2) один сбой не блокировал другую задачу, (3) вызывающий код мог знать об итоге.

Ставьте → 🔥, если нравится формат. Если нет → 🌚

💬 Решения под спойлер. Сравним, какое будет лучше.

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

#practise
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥93🤔2👍1
Какие существуют проблемы в многопоточной среде?

Основные проблемы многопоточности:

1️⃣ Race Conditionкогда результат работы зависит от порядка выполнения потоков. Например, два потока одновременно изменяют одну переменную без синхронизации.

2️⃣ Deadlockвзаимная блокировка, когда потоки ждут друг друга. Классика: поток А держит ресурс 1 и ждёт ресурс 2, а поток Б держит ресурс 2 и ждёт ресурс 1.

2️⃣ Livelockпотоки активны, но не могут продолжить работу, постоянно реагируя на действия друг друга. Например, как два человека в коридоре, которые одновременно пытаются уступить дорогу.

4️⃣ Starvationпоток никогда не получает доступ к ресурсу из-за того, что другие потоки постоянно его перехватывают.

5️⃣ Memory Visibility изменения, сделанные одним потоком, могут быть не видны другим из-за кэширования в CPU.

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

#concurrency
Please open Telegram to view this post
VIEW IN TELEGRAM
👍94🔥1
Сохраняешь Order в БД и отправляешь событие в Kafka. Как гарантировать, что событие не потеряется и не задвоится?

Outbox Pattern

Сохраняй событие в таблицу outbox в той же транзакции, что и бизнес-данные. Отдельный процесс читает таблицу и публикует в Kafka.

На стороне консьюмера — идемпотентность: проверяй event_id перед обработкой.

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

#patterns
Please open Telegram to view this post
VIEW IN TELEGRAM
👍61🔥1
Чем отличается @Transactional(propagation = REQUIRES_NEW) от NESTED?
И когда использование NESTED может неожиданно упасть?


REQUIRES_NEWполностью приостанавливает текущую транзакцию и открывает новую, независимую. Свой коннект к БД, свой коммит и роллбэк. Внешняя транзакция об этом не знает.

NESTED работает внутри той же транзакции через savepoint. Если вложенный метод откатится — откат только до savepoint'а, внешняя транзакция продолжает жить. Один коннект, один итоговый коммит.

⚠️ Когда NESTED неожиданно падает

1. JPA + Hibernate

JpaTransactionManager не поддерживает savepoints из коробки — получишь NestedTransactionNotSupportedException. Нужна явная донастройка, и то ненадёжно.

2. База не умеет savepoints

MySQL с движком MyISAM, некоторые конфигурации H2 — savepoints просто не поддерживаются на уровне драйвера.

3. Self-invocation

// proxy не задействован → NESTED полностью игнорируется
this.nestedMethod();


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

#spring
Please open Telegram to view this post
VIEW IN TELEGRAM
👍51🔥1
Что происходит с @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🔥1
Что такое 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🔥1
Можно ли изменить значение final переменной через рефлексию?

Технически можно, но это нарушает контракт final и приводит к непредсказуемому поведению.

Field field = obj.getClass().getDeclaredField("finalField");
field.setAccessible(true);
field.set(obj, newValue); // может не сработать


Проблемы

JVM может заинлайнить final значение при компиляции
изменения могут не отразиться из-за оптимизаций
нарушается thread-safety гарантия final

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

#core
Please open Telegram to view this post
VIEW IN TELEGRAM
👍51👏1
✔️ Java-тест: бин-синглтон, который не синглтон

Работает у одного, но ломается у другого. В логах каша из чужих данных 👇

📦 Задание — code review


Команда добавила контекст текущего пользователя в сервис через поле. Локально — всё ок.
На проде с несколькими потоками — пользователи видят чужие данные.

@Service
public class ReportService {

private User currentUser;
private ReportFilter activeFilter;

private final ReportRepository reportRepository;

public ReportService(ReportRepository reportRepository) {
this.reportRepository = reportRepository;
}

public void initContext(User user, ReportFilter filter) {
this.currentUser = user;
this.activeFilter = filter;
}

public List<Report> getReports() {
if (currentUser == null) {
throw new IllegalStateException("Context not initialized");
}

return reportRepository.findByUserAndFilter(
currentUser.getId(),
activeFilter
);
}

public ReportSummary getSummary() {
List<Report> reports = getReports();
return ReportSummary.calculate(reports, currentUser);
}
}


▪️ Объясни

— Какой скоуп у бина по умолчанию в Spring и почему это делает поля-состояния опасными.
— Почему synchronized над методами не является правильным решением здесь.
— Как переписать код, чтобы работало.

Ставьте → 🔥, если нравится формат. Если нет → 🌚

💬 Решения под спойлер. Сравним, какое будет лучше.

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

#practise
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥83👍2👏1
💬 Обратная связь

Ежемесячный опрос по грейдам. Сколько среди нас джедаев мидлов?
Ваш грейд:

🔥 — Senior
👍🏼 — Middle
❤️ — Junior
😁 — Ещё учусь

🐸 Библиотека собеса по Java
Please open Telegram to view this post
VIEW IN TELEGRAM
👍36🔥20😁2015
🏃‍♀️ Мы собрали бесплатный мега-гайд по ии-агентам 👇

В первой части постов навалили жесткой базы, чтобы вправить мозги на место. Во второй дали конкретные инструменты, фреймворки и пошаговые инструкции, что нужно кодить прямо сейчас.

Часть 1. Введение, юзкейсы и реальность
Разбираемся с терминами, снимаем розовые очки и смотрим, где ИИ реально приносит бабки, а где только жжет нервы:

1. «Так что вообще считается AI-агентом?»
2. «Где тут бот, а где уже AI-агент?»
3. «Не надо пихать AI-агента в каждую задачу»
4. «Что уже можно спокойно делать через AI-агентов?»
5. «А что через AI-агентов пока лучше не трогать?»

Часть 2. Изнанка, ошибки и архитектура
Как всё это устроено под капотом, чтобы не слить бюджет и не наломать дров на старте:

6. «Можно ли просто сесть вечером и собрать себе AI-агента?»
7. «С чего вообще начать, если хочется попробовать AI-агентов»
8. «Почему AI-агент может внезапно начать творить дичь»
9. «Где AI-агенты реально экономят время, а где только добавляют возни»
10. «Почему они жрут столько денег?»

Часть 3. Хардкорная практика (Что делать руками)
Хватит теории. Открываем ноут, запускаем Cursor и делаем нормальные, отказоустойчивые системы:

11. «Почему одного промпта мало?»
12. «Почему AI-агенту мало просто “дать доступ к данным”»
13. «Если не следить за AI-агентом, он быстро начинает жить своей жизнью»
14. «Собрать демку легко. Но как же сделать нормально»
15. «Как сделать, чтобы это не развалилось через неделю?»

👍 Сохраняйте пост в избранное, чтобы не потерять.

🤫 А завтра стартует наш курс по ии-агентам
Please open Telegram to view this post
VIEW IN TELEGRAM
1👏1💯1
Чем 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
👍15🔥1😁1
Что такое false sharing в многопоточности и как его избежать?

False sharing возникает, когда разные потоки обновляют разные переменные, находящиеся в одной кэш-линии CPU.
Несмотря на отсутствие логической связи, процессор вынужден постоянно инвалидировать кэш, создавая задержки.


Последствия: высокая латентность, падение пропускной способности, резкое ухудшение производительности в hot-paths.

Как избежать:

Разнести горячие поля по разным кэш-линиям → использовать @Contended (JDK 8+, требует -XX:-RestrictContended).
Заполнять структуру “паддингом” вручную.
Перепроектировать алгоритм, чтобы снизить частоту записи.

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

#concurrency
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥1😁1
Что такое Optional и когда его НЕ стоит использовать?

Optional<T> — контейнер, который явно сигнализирует об отсутствии значения вместо null.

Не стоит использовать

В полях класса (не сериализуется хорошо)
В параметрах методов (лучше перегрузка)
В Collections (List<Optional<T>> — антипаттерн)

Стоит использовать: как возвращаемый тип, когда значение действительно может отсутствовать.

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

#core
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥1👏1💯1
Как работает G1 GC?

G1 делит heap на равные регионы (~2048 штук) вместо фиксированных Young/Old/Perm зон. Каждый регион динамически назначается как Eden, Survivor или Old.

Ключевые фазы

Initial Mark — STW, помечает GC roots
Concurrent Mark — параллельно с приложением строит граф достижимости
Remark — STW, дочищает concurrent-фазу (SATB-алгоритм)
Cleanup / Evacuation — копирует живые объекты из регионов с наибольшим мусором (отсюда "Garbage First")

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

#core
Please open Telegram to view this post
VIEW IN TELEGRAM
👍41🔥1
Что такое Phantom Reference?

PhantomReference — самая слабая ссылка в Java. Отличается от WeakReference тем, что get() всегда возвращает null.

Используется для отслеживания момента, когда объект удалён из памяти. После удаления объекта PhantomReference помещается в ReferenceQueue.

В отличие от finalize(), это надёжный способ отследить удаление объекта. Используется редко, в основном во внутренних механизмах или для управления off-heap памятью.

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

#jvm
Please open Telegram to view this post
VIEW IN TELEGRAM
👍71🔥1👏1
Что такое WeakReference?

WeakReference — это слабая ссылка на объект, которая не препятствует его удалению сборщиком мусора.

Если на объект есть только weak references, GC может удалить его при нехватке памяти.

WeakReference<Data> weak = new WeakReference<>(data);
data = null;
// GC может удалить объект
Data retrieved = weak.get(); // может вернуть null


Используется в кешах (WeakHashMap), где элементы могут быть удалены при нехватке памяти, или для предотвращения memory leaks в listeners.

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

#jvm
Please open Telegram to view this post
VIEW IN TELEGRAM
👍51🔥1🤔1
🏃‍♀️ Как провести вечер вторника с пользой для карьеры?

Включайте кружок там личное приглашение от спикера. 👆

Уже завтра в прямом эфире, разбираем архитектуру контекста в мультиагентных системах.

🤫 Секретный лут:
промик на 5.000₽. Он достанется только тем, кто придет на прямой эфир.

👉 Регистрируйтесь на трансляцию
Please open Telegram to view this post
VIEW IN TELEGRAM
Что такое иммутабельный объект?

Иммутабельный объект — это объект, состояние которого невозможно изменить после его создания.  Иммутабельность способствует безопасности потоков и предотвращению ошибок, связанных с изменениями состояния объектов. Примером может служить класс String.

🤖 Осталось 4 места на курс по ИИ-агентам. Набор закрывается 30 апреля.
🔗 Успеть на обучение

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

#core
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥21