На собеседовании Java-разработчика спрашивают, как работает программа: где она хранит данные, как обрабатывает ошибки и что происходит, когда несколько задач выполняются одновременно. Список названий — Core, JVM, Spring, JPA — поначалу мало помогает. Чтобы начать подготовку, сначала разберём, какая задача стоит за каждой темой.
Этот обзор рассчитан на начинающего. Здесь можно выбрать, что изучать дальше, даже если вы ещё не работали с перечисленными технологиями. В девяти подробных статьях пригодится базовое знакомство с Java: что такое переменная, условие и вызов метода. Метод — именованная часть программы, которую вызывают, чтобы выполнить действие или получить результат. Более сложные понятия объясняются по мере появления.
В каждом блоке ниже есть ссылка на подробный разбор с учебными примерами. В конце собраны все девять ссылок и предложен порядок подготовки. Из любой статьи серии можно вернуться сюда по ссылке в начале.
Подготовка к собеседованию Java-разработчика: с чего начать
Откройте вакансию и выпишите, что в ней требуется. Например, Java 21 — версия языка и средств его запуска, PostgreSQL — база данных, Spring Boot — набор средств для создания приложения. Библиотекой называют готовый код, который подключают к своей программе, чтобы не писать всё с нуля. Если название незнакомо, пока достаточно понять, для какой задачи оно нужно.
Уточните и формат встречи. Вас могут попросить устно объяснить правило, прочитать короткий код, написать решение или обсудить устройство приложения. Для первой встречи на начинающую позицию и для собеседования опытного разработчика нужны разные уровни подробности. Наши девять блоков — карта подготовки, а не обязательный список требований любой компании.
Основные примеры серии относятся к Java 17 и 21. Для Spring выбраны Framework 6.x и Boot 3.x, для работы с объектами базы данных — Jakarta Persistence и Hibernate 6.x, для тестов — JUnit 5 и Mockito 5. Что делают эти инструменты, разберём ниже. Версии указаны потому, что поведение и настройки могут меняться: сверяйте их с вакансией, а отличия в примерах читайте отдельно.
Работодатель может добавить алгоритмы, сеть, безопасность или обмен сообщениями между программами. Не пытайтесь сначала выучить все технологии из длинного списка. Начните с основ языка, затем переходите к тем задачам, которые предстоит решать на работе.
Java: вопросы к собеседованию по девяти блокам
Представим учебное приложение магазина. Ему нужно хранить товары, считать сумму заказа, принимать запросы покупателей и сохранять покупки. Каждая тема ниже объясняет часть этой работы. Пример магазина помогает связать названия с понятными действиями; это условная ситуация, а не описание устройства Hintsage.
1. Java Core и объектно-ориентированное программирование
Java Core — основы самого языка. Здесь учатся различать числа, строки и объекты, вызывать методы и понимать, какое значение получит переменная. Объект объединяет связанные данные и действия: например, у товара есть название и цена, а у корзины — список покупок и действие «посчитать сумму». Класс описывает, как устроены такие объекты.
Такой способ организации программы называется объектно-ориентированным программированием, сокращённо ООП. На собеседовании могут предложить два товара с одинаковыми данными и спросить: это один объект или два разных? Из этого вырастают вопросы о сравнении, копировании и изменении данных. Начать полезно с разницы между самим объектом и ссылкой — значением, через которое программа к нему обращается.
- Что получает метод: сам объект или копию ссылки на него?
- Как проверить, что это тот же объект, и как сравнить его данные?
- Как Java выбирает, какой метод вызвать, если названия совпадают?
- Как запретить замену значения переменной и как запретить изменение самого объекта?
Подробный разбор: вопросы по Java Core и ООП с объяснениями и примерами кода.
2. Коллекции и Generics
Коллекции нужны, когда данных много. Один товар можно хранить в одной переменной, а для всех товаров корзины удобен список — List. Если нужны только разные значения, например уникальные категории товаров, используют множество — Set. Для поиска товара по его коду подходит Map: она хранит пары «ключ — значение», в нашем случае «код товара — сведения о товаре».
Generics позволяют указать, какие значения допустимы. Запись List<String> означает список строк: компилятор, который проверяет и переводит исходный Java-код, не даст обычным способом добавить в него число. На интервью важно объяснить и выбор хранилища, и правила работы с его элементами.
- Как
HashMapбыстро ищет значение по ключу и как различает похожие ключи? - Что произойдёт, если изменить поле ключа после добавления в карту?
- Получили мы отдельную копию списка или другой способ обращаться к прежним данным?
- Почему список целых чисел нельзя просто объявить списком любых чисел?
Подробный разбор: вопросы о коллекциях и Generics с примерами работы структур данных.
3. Лямбда-выражения, Stream API и Optional
Допустим, из всех заказов нужно выбрать оплаченные и сложить их суммы. Stream API позволяет записать такую обработку цепочкой: взять данные, оставить нужные, преобразовать и получить результат. API здесь означает набор готовых методов, которыми пользуется наш код. Сам Stream описывает обработку элементов, а не хранит ещё одну копию списка.
Лямбда-выражение — короткая запись действия, которое передают другому коду: например, правило «оставить только оплаченный заказ». Optional — объект, который явно показывает: результат есть или он отсутствует. Это полезно, если поиск товара может ничего не найти. В подробном разборе посмотрим, когда действия цепочки действительно выполняются и как обращаться с отсутствующим результатом.
- Когда Java начнёт отбирать и преобразовывать элементы цепочки?
- Как из нескольких списков получить одну последовательность элементов?
- Что делать с одинаковыми ключами при сборке результата в карту?
- Как подготовить запасной результат только тогда, когда основной не найден?
Подробный разбор: вопросы по Stream API, лямбда-выражениям и Optional с разбором результатов.
4. Многопоточность и модель памяти Java
Поток выполнения — отдельная последовательность действий программы. Магазин может одновременно принимать заказы и отправлять письма покупателям. Несколько потоков помогают выполнять такие задачи с перекрытием по времени. При этом они могут обращаться к одним данным: например, два заказа пытаются купить последний товар.
Поэтому важно согласовать действия: кто меняет остаток и когда другие увидят новое значение. Модель памяти Java, или JMM, задаёт правила видимости изменений и порядка действий между потоками. Блокировка позволяет по очереди выполнять защищённый участок кода, а атомарная операция выглядит для других потоков как одно неделимое действие. В разборе сначала увидим проблему на простом счётчике, затем сравним способы её решения.
- Почему два увеличения общего счётчика могут потерять одно из изменений?
- Как сделать так, чтобы один поток увидел данные, подготовленные другим?
- Как дождаться результата задачи и корректно попросить её остановиться?
- Для каких задач полезны виртуальные потоки — потоки, которыми управляет Java?
Подробный разбор: вопросы по многопоточности Java и модели памяти с учебным кодом.
5. JVM, память, сборка мусора и диагностика
JVM — программа, которая выполняет подготовленный Java-код. Её называют виртуальной машиной Java. До запуска исходный код переводят в байткод — набор инструкций для JVM. Во время работы приложению нужна память для объектов и выполнения методов.
Память для объектов может освобождаться автоматически. Этим занимается сборщик мусора, или GC. Он выясняет, до каких объектов программа ещё может добраться по ссылкам; память недоступных объектов можно использовать снова. Если приложение продолжает хранить ссылки на ненужные данные, сборщик не сможет определить, что разработчик хотел от них избавиться. Поэтому даже в Java бывают утечки памяти. В этом блоке разбираем, как они возникают и какие сведения помогают найти причину.
- Для чего нужны разные области памяти: стек, куча и память со сведениями о классах?
- Почему утечка памяти возможна при автоматической сборке мусора?
- Почему ошибки «не хватает памяти» и «слишком глубока цепочка вызовов» требуют разного разбора?
- Как узнать, на что приложение тратит память и почему останавливается на паузы?
Подробный разбор: вопросы об устройстве JVM, памяти, сборке мусора и диагностике.
6. Исключения, ввод-вывод и ресурсы
Исключение сообщает, что действие не удалось завершить обычным способом. Например, программа пытается открыть файл с товарами, а файла нет. Вместо ожидаемых данных она получает сведения об ошибке. Нужно решить, где её обработать и что сообщить остальному коду.
Ввод-вывод — чтение и запись данных, например в файле или сетевом соединении. Открытый файл использует ресурсы операционной системы, поэтому после работы его нужно закрыть. Ошибка может возникнуть как при чтении, так и при закрытии. Подробная статья показывает, как не потерять сведения об ошибке и как освободить ресурс даже при неудачном чтении.
- Какие ошибки компилятор требует обработать или явно передать вызывающему коду?
- Что выполнится перед выходом из метода, если при работе произошла ошибка?
- Как
try-with-resourcesавтоматически закрывает открытые ресурсы? - Почему при чтении файла программа иногда получает меньше данных, чем запросила?
Подробный разбор: вопросы об исключениях, вводе-выводе и закрытии ресурсов в Java.
7. Spring Framework и Spring Boot
Spring помогает организовать приложение из связанных частей. Например, часть программы принимает заказ, другая считает цену, третья сохраняет результат. Если для расчёта нужен справочник скидок, это зависимость: один объект использует другой для своей работы. Spring может создавать такие объекты и передавать их друг другу.
Spring Boot помогает подготовить настройки и запустить приложение с выбранными библиотеками. На сервере программа обычно получает HTTP-запрос: сообщение от браузера или другой программы с указанием нужного действия. Например, покупатель нажал «Оформить заказ», и сервер должен проверить данные, сохранить покупку и вернуть ответ. В этом блоке проследим этот путь и разберём роль Spring на каждом шаге.
- Откуда объект, который обрабатывает заказ, получает объект для сохранения данных?
- Можно ли безопасно использовать один объект для запросов нескольких покупателей?
- Какие настройки Spring Boot готовит сам и когда использует настройки разработчика?
- Как сделать так, чтобы связанные изменения данных сохранились вместе или были отменены?
Подробный разбор: вопросы по Spring и Spring Boot с примерами зависимостей и транзакций.
8. SQL, JDBC, JPA и Hibernate
База данных хранит сведения между запусками приложения. В реляционной базе данные организованы в таблицы: например, каждая строка таблицы товаров содержит код, название и цену. SQL — язык, на котором запрашивают и изменяют такие данные. JDBC позволяет отправлять SQL-запросы из Java-программы.
JPA задаёт правила, по которым Java-объекты связывают с записями базы. Hibernate — один из инструментов, который выполняет эти правила: например, превращает сохранение объекта заказа в SQL-запросы. Важно различать объект в памяти программы и запись в базе — изменение первого не означает, что второе уже окончательно сохранено.
Транзакция объединяет действия с базой в одну группу: их можно подтвердить вместе или отменить при ошибке. Например, создание заказа и уменьшение остатка товара должны согласовываться. На интервью проверяют, понимаете ли вы, когда меняются данные и что произойдёт, если другой покупатель делает то же самое.
- Как передать в SQL-запрос введённое пользователем значение безопасным способом?
- Чем отправка SQL-изменений в базу отличается от их окончательного подтверждения?
- Как возникает N+1 — один исходный запрос и дополнительные запросы для связанных данных?
- Как обнаружить, что другая транзакция уже изменила ту же запись?
Подробный разбор: вопросы по SQL, JDBC, JPA и Hibernate с объяснением работы с данными. Для практики запросов также пригодится разбор JOIN, группировок и оконных функций.
9. Тестирование: JUnit, Mockito и интеграционные проверки
Автоматический тест — код, который проверяет другой код. Например, мы заранее знаем: два товара по 100 рублей должны дать сумму 200 рублей. Тест передаёт такие данные в расчёт и сравнивает полученный ответ с ожидаемым. JUnit помогает запускать проверки и сообщать, какие из них не прошли.
Для проверки цены не всегда нужен настоящий сервис отправки писем. Mockito позволяет поставить вместо него управляемую подмену — mock, задать её ответы и проверить обращения к ней. Если же нужно узнать, правильно ли Java-программа сохраняет заказ в базе, понадобится проверить их совместную работу. Такая проверка называется интеграционной. В статье разберём, что можно проверить каждым способом и какие ошибки он способен пропустить.
- Как проверить итоговую сумму и как проверить, что программа попросила отправить письмо?
- Когда нужна подмена другого объекта, а когда проще использовать настоящий?
- Как проверить исключение и разные наборы входных данных?
- Почему успешный тест с одной базой не доказывает работу с другой?
Подробный разбор: вопросы по тестированию Java, JUnit и Mockito с примерами проверок.
Как понять, что вы умеете объяснить механизм
Начните с маленькой задачи, а не с определения наизусть. Например, List — список с позициями элементов. Есть список из трёх кодов: 1, 7, 1. Мы просим удалить элемент с позиции 1; позиции в Java считаются с нуля. Удалится второй элемент — 7, а останется 1, 1. Теперь можно объяснить правило: удаление по позиции отличается от удаления по значению.
Следующий шаг — изменить условие. Если нужно удалить именно число 1, следует выбрать способ удаления по значению. Так проверяется, поняли ли вы действие программы. В подробной статье о коллекциях этот пример разобран с кодом и объяснением выбора метода.
- Что нужно сделать
Назовите исходные данные и действие: например, удалить элемент списка.
- Что делает программа
Проследите действия по порядку и объясните, откуда взялся результат.
- Что изменится
Поменяйте одно условие: элемент, число задач или наличие ошибки.
- Где это пригодится
Придумайте похожую рабочую задачу и выберите подходящий способ решения.
Если не получается предсказать результат, вернитесь к объяснению нужного шага. Если пример понятен, попробуйте придумать свой: для корзины магазина, очереди писем или поиска товара. Постепенно добавляйте условия, например необходимость обслуживать сразу нескольких покупателей. Вам станет легче объяснять, почему решение подходит именно этой задаче.
В каком порядке повторять темы
Если вы начинаете с небольшим опытом, сначала разберите правила языка и хранение данных. Затем переходите к обработке ошибок и работе приложения. Таблица предлагает один последовательный маршрут; его можно изменить под требования вакансии и уже знакомые темы.
| Шаг | Блоки | Что проверить перед переходом |
|---|---|---|
| 1. Основа | Core и ООП; коллекции и Generics. | Можете объяснить разницу между объектами и выбрать, где хранить список товаров. |
| 2. Обработка данных и ошибок | Stream/Optional; исключения и ввод-вывод. | Можете проследить отбор заказов и объяснить, что делать, если файл не удалось прочитать. |
| 3. Работа программы | Многопоточность; JVM и GC. | Понимаете, что может произойти с общими данными и почему приложение расходует память. |
| 4. Сервер и база данных | Spring Boot; SQL/JDBC/JPA/Hibernate. | Можете рассказать, как запрос покупателя доходит до записи заказа в базе. |
| 5. Проверка решений | JUnit, Mockito и интеграционные тесты. | Умеете задать входные данные, ожидаемый результат и проверку нужной ошибки. |
Проверять примеры полезно с самого начала, даже если до статьи о тестах вы ещё не дошли. Сначала запишите, что программа должна вывести. Затем запустите её и объясните каждую строку результата. Если задач несколько, один успешный запуск ещё не доказывает, что ошибка невозможна: в другой раз они могут выполниться в другом порядке.
Перед интервью попробуйте ответить вслух на несколько вопросов без конспекта. Вместо общей оценки «я плохо знаю Java» запишите конкретное затруднение: «не понимаю, почему изменился список» или «не могу объяснить, когда данные сохраняются в базу». Откройте нужный разбор, проследите пример по шагам и снова ответьте своими словами.
