P
prepair.app
Пройти інтерв'ю →
EnglishУкраїнськаРусскийDeutsch

Middle Java BackendПитання на співбесіді Java розробника

Middle · 2–4 роки досвіду

Співбесіда Java-розробника охоплює семантику мови, колекції, багатопотоковість, Spring та вміння міркувати про JVM. Нижче — питання, які ставлять найчастіше, кожне з еталонною відповіддю. Middle: глибше розуміння, оптимізацію та реальні робочі ситуації.

Спробувати — без реєстрації
Готуємо питання…

Теми для підготовки

Core Java та ООП
Collections Framework
Багатопотоковість
Spring Boot і Spring Data
JVM, GC та памʼять
SQL і Hibernate

9 питань рівня Middle з відповідями

1

Як влаштований HashMap усередині і що змінилося в Java 8?

Відповідь

Записи лежать у масиві бакетів, індекс береться з функції хешу ключа; колізії складаються у звʼязний список усередині бакета. У Java 8 зʼявилася treeification: щойно в бакеті більше восьми записів, він перетворюється на червоно-чорне дерево, і найгірший випадок пошуку став O(log n) замість O(n). Плюс хеш розмішується через h ^ (h >>> 16), щоб старші біти впливали на молодший індекс.

2

Що гарантує volatile, а що ні?

Відповідь

Гарантує видимість і впорядкування: запис одразу публікується іншим потокам, а читання не кешуються в регістрі. Не гарантує атомарність, тому volatile-лічильник усе одно втрачає інкременти — ++ це читання-зміна-запис, і два потоки можуть прочитати одне значення. volatile беруть для прапорця, який читають багато, а AtomicInteger чи synchronized — коли операція поєднує читання й запис.

3

Поясніть propagation у @Transactional. Коли потрібен REQUIRES_NEW?

Відповідь

Propagation вирішує, що відбувається при виклику транзакційного методу зсередини іншої транзакції. REQUIRED за замовчуванням приєднується до наявної, тому відкат у будь-якому місці відкочує все. REQUIRES_NEW призупиняє зовнішню і відкриває свою — це потрібно для аудит-логу або сповіщення, яке має пережити падіння викликаючого коду. Класична помилка — очікувати від REQUIRED ізоляції збою, якої в нього немає.

4

В ендпоінті на Hibernate видно проблему N+1. Як знайти й полагодити?

Відповідь

Знаходиться увімкненням логування SQL і підрахунком запитів на один виклик — ознака один select і слідом сотні майже однакових. Виникає, коли завантажили батьків і звертаєтеся до лінивої колекції в кожного. Лікується JOIN FETCH у JPQL, entity graph, @BatchSize для завантаження пачками або проєкцією, що вибирає лише потрібні відповіді поля. Переведення в EAGER це не лікування, а перенесення проблеми.

5

Чим Stream відрізняється від циклу for і коли цикл кращий?

Відповідь

Stream описує конвеєр лінивих операцій, запущений термінальною, і тримає фільтрацію з перетворенням читабельними. Цикл кращий у гарячій ділянці, де абстракція коштує вимірного часу, у логіці з побічними ефектами і там, де break посередині виразніший за takeWhile. Справжня пастка — паралельні стріми: вони допомагають лише на великому обсязі обчислювальної роботи і зазвичай шкодять в інших випадках.

6

Сервіс гальмує, а CPU низький. Куди дивитися?

Відповідь

Низький CPU за поганої пропускної здатності означає очікування, а не обчислення: блокуючий ввід-вивід, вичерпаний пул зʼєднань, конкуренція за блокування або зовнішній виклик без таймауту. Зніміть thread dump і подивіться, на чому реально стоять потоки. Найчастіше винен вичерпаний пул зʼєднань, і зазвичай це наслідок транзакції, відкритої на час мережевого виклику.

7

Чим автоконфігурація Spring Boot відрізняється від звичайного @Configuration?

Відповідь

Автоконфігурація — це умовна конфігурація, яку постачає стартер: класи з @ConditionalOnClass або @ConditionalOnMissingBean, що застосовуються лише якщо залежність є в classpath і ви самі бін не оголосили. Останнє й робить її водночас чарівною та передбачуваною: ваш бін завжди перемагає, і саме так перевизначається будь-який дефолт.

8

Чим різняться `wait()`, `sleep()` і `join()`?

Відповідь

sleep призупиняє поточний потік і утримує захоплене блокування — так і отримують дедлок із невинним на вигляд кодом. wait звільняє монітор і паркує потік до notify, і саме тому викликати його можна лише всередині synchronized. join чекає завершення іншого потоку. wait і notify належать Object, а не Thread, бо блокування належить обʼєкту.

9

Що робить `transient` і де кусається серіалізація?

Відповідь

transient виключає поле із серіалізації, тому при десеріалізації воно повертається значенням за замовчуванням. Позначають ним усе обчислюване, усе велике і все таємне: паролю чи живому зʼєднанню в потоці байтів робити нічого. Ширша пастка в тому, що серіалізація заморожує форму класу у формат: змініть поля — і старі дані не прочитаються, якщо не продумали serialVersionUID і сумісність, тому більшість команд беруть JSON або protobuf.

🦎

Прочитати відповіді недостатньо

На співбесіді ти говориш вголос під тиском. Кем поставить ті самі питання, оцінить кожну відповідь і покаже, що саме підтягнути.

Пройти інтерв'ю Middle Java Backend →
Безкоштовно · 3 інтерв'ю на місяць

Інші рівні — Java Backend

Junior Java BackendSenior Java BackendУсі питання Java Backend

Інші спеціалізації

🔍Middle QA Manual🤖Middle QA Automation🐍Middle Python Backend🐘Middle PHP Backend🦫Middle Go Backend🟢Middle Node.js Backend💎Middle Ruby on Rails🟣Middle .NET Backend Developer🔷Middle C++🟨Middle JavaScript