Введение: почему Java не прощает халтуры
Вы отправили резюме, прошли HR-скрининг, и вот — приглашение на техническое собеседование. Если вы читаете эту статью на pythonlib.ru, значит, вы либо переключаетесь с Python на Java, либо просто собираете «базу знаний». В любом случае — вы на правильном пути.
Java — это не тот язык, где можно «проскочить» на харизме. Энтерпрайз-экосистема требует чёткого понимания: от JMM (Java Memory Model) до того, как работает Garbage Collector. Собеседование по Java — это не экзамен, это диалог. Но диалог, в котором вас будут проверять на прочность.
В этой статье я собрал реальный чек-лист: что учить, как отвечать и — самое главное — как не опозориться на live-coding. Без воды, только практика.
1. Java Core: фундамент, который нужно выучить наизусть
Начнём с базы. Без Java Core вас просто не будут слушать. Вот список тем, которые обязан знать каждый кандидат:
1.1. OOP (Объектно-ориентированное программирование)
Вы должны уметь объяснить полиморфизм, наследование, инкапсуляцию и абстракцию на пальцах. Причём с примерами.
Вопрос-ловушка: «Чем отличается абстрактный класс от интерфейса?»
Правильный ответ: в Java 8+ в интерфейсах появились default-методы, но абстрактный класс может содержать состояние (поля), а интерфейс — нет.
// Пример: абстрактный класс
abstract class Animal {
protected String name;
abstract void makeSound();
}
// Интерфейс с default-методом
interface Movable {
default void move() {
System.out.println("Moving...");
}
}
1.2. Коллекции (Java Collections Framework)
Это must-have. Знать HashMap, ArrayList, HashSet, TreeMap — мало. Нужно понимать:
- Как работает HashMap (массив + связный список + красно-чёрное дерево с Java 8)
- Разница между fail-fast и fail-safe итераторами
- Когда использовать LinkedList вместо ArrayList (спойлер: почти никогда)
Совет: На собеседовании вас могут попросить написать свою реализацию HashMap. Потренируйтесь заранее.
1.3. Исключения (Exceptions)
Checked vs Unchecked — классика. Помните: RuntimeException и его наследники — unchecked, всё остальное — checked. И никогда, слышите, никогда не используйте catch (Exception e) {} — это антипаттерн.
2. Многопоточность: тема, где проваливаются 80% кандидатов
Java — один из немногих языков, где многопоточность встроена на уровне языка. На собеседовании вас обязательно спросят про synchronized, volatile, AtomicInteger, Lock, Semaphore.
2.1. Ключевое слово volatile
Главный вопрос: «Гарантирует ли volatile атомарность?» Ответ: нет. Он гарантирует только видимость изменений между потоками.
public class VolatileExample {
private volatile boolean flag = true;
public void stop() {
flag = false; // Другой поток увидит это изменение сразу
}
}
2.2. Deadlock и как его избежать
Вас могут попросить написать код, который приводит к deadlock'у, а потом — исправить его.
// Классический deadlock
public class DeadlockExample {
private final Object lock1 = new Object();
private final Object lock2 = new Object();
public void method1() {
synchronized (lock1) {
synchronized (lock2) { /* ... */ }
}
}
public void method2() {
synchronized (lock2) {
synchronized (lock1) { /* ... */ }
}
}
}
Решение: всегда захватывать блокировки в одном и том же порядке, либо использовать tryLock() из пакета java.util.concurrent.locks.
3. Spring Framework: энтерпрайз без него не работает
Если вы идёте на позицию Java-разработчика, знание Spring — это не плюс, а обязательное условие. Вот что нужно повторить:
- IoC и DI — объяснить, чем отличается внедрение через конструктор от внедрения через поле
- Spring Boot — автоконфигурация, starter'ы, application.yml
- Spring Data JPA — как работают репозитории, что такое N+1 проблема
- Spring Security — JWT, OAuth2, цепочка фильтров
Типовой вопрос: «Как в Spring управлять транзакциями?»
Ответ: через аннотацию @Transactional. Но нужно понимать propagation (REQUIRED, REQUIRES_NEW, MANDATORY) и isolation levels.
@Service
public class UserService {
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
public void createUser(User user) {
// логика сохранения
}
}
4. Алгоритмы и структуры данных: live-coding без паники
Даже если вы идёте в «чистый энтерпрайз», алгоритмы вас догонят. На live-coding по Java чаще всего дают задачи на:
- Разворот связного списка
- Поиск дубликатов в массиве
- Скобочные последовательности (валидация)
- Двоичный поиск
Важно: не молчите. Проговаривайте вслух, что вы делаете. «Я хочу использовать HashMap, потому что нам нужен O(1) на lookup». Работодатель оценивает не только код, но и ход мыслей.
Пример задачи: валидация скобок
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
for (char c : s.toCharArray()) {
if (c == '(') stack.push(')');
else if (c == '{') stack.push('}');
else if (c == '[') stack.push(']');
else if (stack.isEmpty() || stack.pop() != c) {
return false;
}
}
return stack.isEmpty();
}
Коротко, элегантно, работает за O(n). Именно такой код ждут на собеседовании.
5. Паттерны проектирования: 3 must-know
Не нужно учить все 23 паттерна GoF. Достаточно трёх, которые реально спрашивают:
- Singleton — потокобезопасная реализация через enum или double-checked locking
- Factory Method — как альтернатива
new - Builder — для объектов с множеством параметров
// Потокобезопасный Singleton через enum
public enum Singleton {
INSTANCE;
public void doSomething() {