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

вопросы на собеседовании Java разработчика

Собеседование Java-разработчика охватывает семантику языка, коллекции, многопоточность, Spring и умение рассуждать о JVM. Ниже — вопросы, которые задают чаще всего, каждый с эталонным ответом.

Junior · без опыта / до 1 годаMiddle · 2–4 года опытаSenior · 5+ лет опыта

Что спрашивают

Core Java и ООП
Collections Framework
Многопоточность
Spring Boot и Spring Data
JVM, GC и память
SQL и Hibernate

12 реальных вопросов с ответами

К каждому вопросу — эталонный ответ, с которым можно сравнить свой.

1

Как устроен HashMap внутри и чем от него отличается ConcurrentHashMap?

Ответ

HashMap хранит записи в массиве бакетов, индекс берётся из хеша ключа; коллизии складываются в связный список, который после восьми узлов превращается в красно-чёрное дерево. Он не потокобезопасен — одновременный ресайз может испортить структуру. ConcurrentHashMap достигает потокобезопасности блокировкой только той корзины, в которую пишут (CAS плюс synchronized на узле), а не всей мапы, поэтому чтения идут без блокировок, а записи конкурируют только в пределах одной корзины.

2

Объясните контракт equals() и hashCode(). Что ломается при его нарушении?

Ответ

Если два объекта равны по equals(), они обязаны возвращать одинаковый hashCode; неравные объекты могут совпадать по хешу, но в идеале не совпадают. Нарушение ломает все хеш-коллекции: объект попадает в один бакет, а последующий поиск считает другой хеш, идёт в другой бакет и сообщает, что записи нет. Классический баг — изменить поле, участвующее в hashCode, уже после добавления объекта в множество.

3

Что такое garbage collection и какие сборщики есть в JVM?

Ответ

GC освобождает память кучи для объектов, до которых больше нельзя добраться от GC roots. Куча поколенческая — большинство объектов умирают молодыми, поэтому минорные сборки в young generation дёшевы. Из сборщиков есть Serial и Parallel для пропускной способности, G1 как современный дефолт с балансом паузы и throughput, а также ZGC и Shenandoah для очень больших куч с паузами меньше миллисекунды.

4

В чём разница между checked и unchecked исключениями?

Ответ

Checked наследуются от Exception и обязаны быть объявлены или обработаны — они описывают восстановимые ситуации, к которым вызывающий код должен готовиться, например IOException. Unchecked наследуются от RuntimeException и сигналят об ошибках программиста: NullPointerException, IllegalArgumentException. На практике совет такой: unchecked для багов, checked умеренно, потому что принуждение обрабатывать исключение в каждом вызове чаще всего рождает пустые catch-блоки.

5

Что такое Dependency Injection в Spring и какие есть типы инъекции?

Ответ

DI означает, что объект получает зависимости от контейнера, а не создаёт их сам, — это развязывает классы и делает их тестируемыми. Spring поддерживает инъекцию через конструктор, сеттер и поле. Предпочтительна конструкторная: зависимости становятся final, объект никогда не существует в недостроенном виде, и класс не может скрыть разрастающийся список зависимостей так, как это позволяет инъекция в поле.

6

В чём разница между @Component, @Service, @Repository и @Controller?

Ответ

Все четыре регистрируют класс как бин Spring и технически взаимозаменяемы для сканирования. Различаются намерением и тем, что Spring к ним добавляет: @Repository транслирует исключения персистентности в иерархию DataAccessException, @Controller и @RestController участвуют в маппинге запросов, а @Service — семантическая пометка бизнес-логики. Использование конкретной аннотации документирует слой и включает нужное поведение.

7

Что такое транзакция? Объясните уровни изоляции.

Ответ

Транзакция — это единица работы, удовлетворяющая ACID: она либо целиком коммитится, либо откатывается. Уровни изоляции меняют консистентность на параллелизм: Read Uncommitted допускает грязные чтения, Read Committed их исключает, Repeatable Read дополнительно исключает неповторяющиеся чтения, Serializable убирает и фантомы ценой пропускной способности. Большинство систем работают на Read Committed и закрывают остаточные аномалии оптимистичными блокировками.

8

В чём разница между ArrayList и LinkedList? Когда выбрать каждый?

Ответ

ArrayList опирается на расширяемый массив: доступ по индексу O(1), но вставка и удаление в середине сдвигают элементы. LinkedList — двусвязный список: вставка и удаление у известного узла O(1), зато доступ по индексу O(n), и каждый элемент несёт накладные расходы узла. На практике ArrayList выигрывает почти всегда, потому что локальность кеша процессора важнее теоретической сложности; LinkedList полезен в основном как Deque.

9

Что такое volatile и synchronized? Когда использовать каждый?

Ответ

volatile гарантирует видимость — запись сразу видна другим потокам, а чтения не кешируются — но не даёт атомарности, поэтому volatile-счётчик всё равно теряет инкременты. synchronized даёт и видимость, и взаимное исключение, так что блок в каждый момент выполняет только один поток. volatile берут для простого флага, который читают многие потоки; synchronized или Atomic — когда операция это чтение-изменение-запись.

10

Объясните N+1 problem в Hibernate и как её избежать.

Ответ

N+1 возникает, когда вы одним запросом достаёте N родительских сущностей, а затем лениво обращаетесь к коллекции у каждой, порождая N дополнительных запросов. Обычно это выглядит как страница, которая летает на трёх записях в тестах и намертво встаёт на трёх тысячах. Лечится JOIN FETCH в JPQL, entity graph, батчингом через @BatchSize или проекцией, которая выбирает ровно те поля, что нужны представлению.

11

В чём разница между String, StringBuilder и StringBuffer?

Ответ

String неизменяем, поэтому каждая конкатенация создаёт новый объект — сборка строки в цикле через + квадратична по времени. StringBuilder это изменяемый буфер и правильный инструмент для такого цикла. StringBuffer то же самое, но с synchronized-методами; по сути это легаси, потому что делить изменяемый буфер между потоками приходится редко, и обычно всё равно нужна более крупная блокировка.

12

Что такое Stream API и когда его не стоит применять?

Ответ

Stream описывает операции над коллекциями декларативно — как конвейер ленивых промежуточных операций и терминальной, которая запускает вычисление. Он хорош для фильтрации, преобразования и агрегации, потому что намерение остаётся читаемым. Не стоит применять в горячих циклах, где абстракция стоит измеримого времени, в логике с побочными эффектами и там, где обычный for читался бы яснее.

🦎

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

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

Пройти интервью Java Backend →
Бесплатно · 3 интервью в месяц

Другие специализации

🔍QA Manual🤖QA Automation🐍Python Backend🐘PHP Backend🦫Go Backend🟢Node.js Backend⚛️React Frontend💚Vue Frontend🅰️Angular FrontendNext.js📈Business Analyst🎯Product Manager📋Project Manager🎨UI/UX Designer📣Marketing