Вопросы для собеседования Java-разработчика
Готовый набор для интервьюера: 36 вопросов с тезисами эталонного ответа, задача, рубрика и план встречи.
На собеседовании Java-разработчика хорошо работает схема на 60 минут: 3-4 устных вопроса по стеку, одна задача на live coding, проектирование для middle и выше и вопросы кандидата. Ниже вопросы по грейдам из базы Техпрогона: у каждого тезисы, которые должен назвать сильный кандидат.
Всего в базе по этой роли 277 устных вопросов с чек-листом ответа.
Как построить техсобес на 60 минут
0-5 мин
Знакомство
Кто вы, формат встречи, кандидат коротко о себе и последнем проекте.
5-20 мин
Вопросы по стеку
3-4 устных вопроса из набора ниже. Сверяйте ответ с тезисами.
20-45 мин
Live coding
Одна задача. Смотрите на процесс по рубрике, а не только на ответ.
45-55 мин
Проектирование
Для middle и выше: система или решение целиком. Для junior: ещё вопросы.
55-60 мин
Вопросы кандидата
Что спросил кандидат, тоже сигнал: интерес к задачам и команде.
Junior: 12 вопросов
Основы: как устроено и зачем. Хватит 3-4 вопросов на встречу.
Чем int отличается от Integer и когда что использовать?
Что хотим услышать
- int примитив: хранит значение, не может быть null, дешёвый
- Integer объект-обёртка: может быть null, нужен в коллекциях и дженериках
- Автоупаковка через Integer.valueOf и кеш -128..127
- Сравнение Integer через equals, а не ==
- NPE при распаковке null
- В горячем коде упаковка даёт лишние объекты и нагрузку на GC
Если ответил, копните глубже
Integer a = 1000, b = 1000; a == b даёт false?List<int> нельзя хранить примитивы?Зачем нужен DI и Spring-контейнер? Объясните на примере сервиса заказов.
Что хотим услышать
- Класс объявляет зависимости, а не создаёт их
- Слабая связанность: зависимость от интерфейса
- Простые юнит-тесты: мок через конструктор
- Контейнер управляет жизненным циклом и скоупом
- Контейнер добавляет сквозную функциональность через прокси: транзакции, кеш
Если ответил, копните глубже
Расскажи, чем Kotlin отличается от Java и почему его выбирают для Android и бэкенда.
Что хотим услышать
- Null-safety в системе типов: NPE ловится при компиляции
- Меньше шаблонного кода: data class, свойства, вывод типов, именованные и дефолтные аргументы
- Функции расширения, лямбды и удобная stdlib для коллекций
- Корутины для асинхронного кода без колбэков
- Полная совместимость с Java: можно смешивать в одном проекте
- Выражения вместо операторов: if, when, try возвращают значения
Если ответил, копните глубже
Чем отличается WHERE от HAVING? Приведи пример, где нужны оба.
Что хотим услышать
- WHERE фильтрует строки до группировки, HAVING фильтрует группы после
- В WHERE нельзя агрегаты, в HAVING можно
- Порядок: FROM, WHERE, GROUP BY, HAVING, SELECT
- Условия без агрегатов лучше писать в WHERE: меньше строк до группировки
- Пример: WHERE status = 'paid' и HAVING SUM(total) > 10000
Если ответил, копните глубже
Объясни, что такое CORS и как он работает.
Что хотим услышать
- Same-origin policy: скрипт не может читать ответы другого origin (схема, хост, порт)
- CORS: сервер заголовками
Access-Control-Allow-*разрешает конкретным origin читать ответы - Проверяет браузер, сервер отвечает всегда; вне браузера CORS не действует
- Простые запросы уходят сразу, остальные после preflight OPTIONS
- С куками нужен
credentials: 'include',Allow-Credentials: trueи точный origin вместо*
Если ответил, копните глубже
Объясните разницу между вертикальным и горизонтальным масштабированием и когда что выбирать.
Что хотим услышать
- Вертикальное: мощнее машина, код не меняется, есть предел и единая точка отказа
- Горизонтальное: больше узлов, нужен stateless или распределённое состояние
- Stateless-сервисы приложения масштабируют горизонтально в первую очередь
- БД часто сначала масштабируют вертикально и репликами, шардирование позже
- Горизонтальное даёт отказоустойчивость, но добавляет сложность
Если ответил, копните глубже
Объясни, как ты оцениваешь временную и пространственную сложность своего решения на собесе.
Что хотим услышать
- Называет, что такое n (и m, если входов несколько)
- Считает циклы: вложенные перемножаются, последовательные складываются
- Помнит скрытые циклы: includes, indexOf, slice, sort, spread
- Отдельно оценивает память, включая стек рекурсии
- Сравнивает с ограничениями: при n до 10⁵ O(n²) уже не годится
Если ответил, копните глубже
arr.slice() внутри цикла?Объясни, зачем фронтенд-проекту сборщик и что происходит с кодом от исходников до файлов в dist.
Что хотим услышать
- граф зависимостей от точки входа
- трансформация: TS, JSX, современный синтаксис, CSS
- резолв пакетов из node_modules
- склейка в чанки, минификация, tree shaking
- хеши в именах для долгого кеша
- dev-сервер с HMR и source maps
Если ответил, копните глубже
Объясни разницу между жёсткой и символьной ссылкой. Когда какую использовать?
Что хотим услышать
- Жёсткая ссылка: ещё одно имя того же inode, равноправное с оригиналом
- Данные живут, пока счётчик ссылок больше нуля и файл никто не держит открытым
- Жёсткую нельзя на каталог и между разными ФС
- Символьная: отдельный файл, внутри которого путь к цели
- Символьная ломается при удалении или переносе цели, зато работает с каталогами и через ФС
- Пример: symlink на текущий релиз
current -> releases/42для атомарного переключения
Если ответил, копните глубже
ls -l во второй колонке?Назовите ваши сильные стороны.
Что хотим услышать
- Две-три стороны, а не список из десяти
- Каждая подкреплена примером
- Стороны связаны с вакансией
- Нет пустых слов вроде «стрессоустойчивый, коммуникабельный» без доказательств
- Уверенно, без хвастовства
Если ответил, копните глубже
Java передаёт аргументы по ссылке или по значению? Объясни на примере.
Что хотим услышать
- Всегда по значению
- Для объектов копируется ссылка, а не объект
- Метод может менять состояние объекта через копию ссылки
- Присваивание параметру новой ссылки не видно снаружи
- Пример со swap двух объектов, который не работает
Если ответил, копните глубже
s += "x"?Объясните, как устроена Kafka: топики, партиции, offset, группы потребителей.
Что хотим услышать
- Топик делится на партиции, партиция это упорядоченный лог
- Offset это позиция сообщения, потребитель хранит свой offset
- Сообщения не удаляются после чтения, хранятся по retention
- Consumer group: партиция на одного потребителя группы
- Ключ определяет партицию и порядок
- Репликация: лидер и реплики
Если ответил, копните глубже
Middle: 12 вопросов
Практика: почему так, какие компромиссы, что ломается.
Расскажите, как работает HashMap: что происходит при put и get, как решаются коллизии и что будет при росте.
Что хотим услышать
- Массив корзин, индекс (n-1) & hash, hash с подмешанными старшими битами
- Коллизии: цепочка, внутри сравнение hash и equals
- Treeify при 8 узлах и таблице от 64, обратно при 6
- Load factor 0.75, удвоение таблицы и перераскладка узлов
- Требования к ключу: корректные equals/hashCode, неизменяемость
- Не потокобезопасен, для потоков ConcurrentHashMap
Если ответил, копните глубже
Объясните, как Spring реализует @Transactional и почему вызов из того же класса не открывает транзакцию.
Что хотим услышать
- BeanPostProcessor заменяет бин прокси
- CGLIB-подкласс или JDK-прокси по интерфейсу
- Прокси открывает транзакцию, вызывает target, коммитит или откатывает
- Внутри target вызов через this это прямой вызов, прокси его не видит
- Решения: отдельный бин, внедрение себя, TransactionTemplate, AspectJ
- Те же правила для @Async, @Cacheable, @PreAuthorize
Если ответил, копните глубже
Расскажи, как работает by lazy, какие у него режимы и где его стоит и не стоит использовать.
Что хотим услышать
- Значение вычисляется при первом обращении и кешируется
- Только для
val - SYNCHRONIZED по умолчанию, PUBLICATION, NONE
- При исключении значение не запоминается
- Нельзя для объектов, зависящих от жизненного цикла view
Если ответил, копните глубже
lazy отличается от lateinit?NONE?lazy внутри?Спроектируй схему базы для заказов интернет-магазина: клиенты, товары, заказы, оплаты. Какие таблицы, ключи и ограничения?
Что хотим услышать
- Таблицы customers, products, orders, order_items, payments и их связи
- order_items как связь заказа и товара с qty и ценой на момент покупки
- Ограничения: FK, NOT NULL, CHECK (qty > 0), UNIQUE там, где нужно
- Типы: numeric или копейки для денег, timestamptz для времени, статус через CHECK или enum
- Индексы на FK и под частые запросы (заказы клиента по дате)
- Платежи отдельной таблицей с идемпотентным внешним id от платёжки
Если ответил, копните глубже
Чем отличаются сессии на куках и JWT? Что бы ты выбрал для обычного веб-приложения?
Что хотим услышать
- Сессия: id в куке, состояние на сервере (Redis/БД), отзыв мгновенный
- JWT: состояние в самом токене, проверка подписью без базы, сложно отозвать
- Для JWT нужна пара короткий access + отзываемый refresh
- Хранение: HttpOnly кука защищает от XSS, но нужна защита от CSRF (SameSite)
- Выбор по контексту: одно веб-приложение проще на сессиях, много сервисов и мобильные клиенты удобнее на токенах
Если ответил, копните глубже
Расскажите, по какому плану вы будете вести секцию system design на 60 минут.
Что хотим услышать
- Начинаю с уточнения функциональных требований и явно фиксирую, что не делаем
- Уточняю нефункциональные требования: масштаб, задержка, доступность, консистентность
- Делаю грубую оценку RPS и объёмов и использую её в решениях
- Описываю API и модель данных, выбираю хранилище под паттерн доступа
- Рисую высокоуровневую схему и прохожу по ней путь запроса
- Оставляю время на узкие места, отказы, масштабирование и мониторинг
Если ответил, копните глубже
Объясни решение задачи «минимальное число монет для суммы» и его сложность. Почему тут не подходит жадность?
Что хотим услышать
- Показывает контрпример для жадности
- Формулирует состояние: dp[s] минимум монет для суммы s
- Переход: dp[s] = min(dp[s - c] + 1) по монетам
- База dp[0] = 0, остальные Infinity, недостижимо → -1
- O(S · k) времени, O(S) памяти
Если ответил, копните глубже
Как бы ты построил CI/CD для веб-приложения с нуля?
Что хотим услышать
- На каждый PR: npm ci, линтер, типы, unit-тесты, сборка
- Быстрые проверки первыми, независимые джобы параллельно, кеш зависимостей
- Защита ветки main: мерж только с зелёным CI и ревью
- Сборка один раз, артефакт (образ) с версией продвигается по стендам
- Деплой на стенд автоматически, на прод с подтверждением или автоматически при хорошем покрытии
- План отката и миграции, совместимые с предыдущей версией
Если ответил, копните глубже
Мониторинг сообщает: корневой раздел заполнен на 100%, сервис падает. Что делаешь по шагам?
Что хотим услышать
- Оценить:
df -hиdf -i, место или inode - Найти крупное:
du -xh / --max-depth=1 | sort -h, затем вглубь; обычно логи, кеши, дампы, docker - Проверить удалённые, но открытые файлы:
lsof +L1 - Быстро освободить безопасно: обнулить лог через
: > fileилиtruncate, а неrmоткрытого файла;journalctl --vacuum-size,docker system pruneс пониманием - Устранить причину: logrotate, лимиты журнала, алерт на 80%
- Если нужно место надолго: расширить диск или том LVM онлайн
Если ответил, копните глубже
rm лога может не помочь?Почему вы ищете новую работу?
Что хотим услышать
- Причина через цель, а не через бегство
- Ни слова негатива о текущем работодателе
- Показано, что на текущем месте был рост и результаты
- Связка с этой вакансией
- Коротко: до минуты
Если ответил, копните глубже
Чем synchronized отличается от volatile? Когда что использовать?
Что хотим услышать
- synchronized: взаимное исключение плюс видимость
- volatile: только видимость и порядок, без атомарности составных операций
- volatile для флагов и однократной публикации
- synchronized для инвариантов из нескольких полей и read-modify-write
- Атомики как средний вариант (CAS)
- Цена: блокировка и конкуренция против дешёвого чтения
Если ответил, копните глубже
Расскажите жизненный цикл бина в Spring. На каком этапе появляются прокси и почему это важно?
Что хотим услышать
- BeanDefinition и BeanFactoryPostProcessor до создания
- Конструктор, внедрение, Aware
- BeanPostProcessor before, @PostConstruct, afterPropertiesSet, initMethod
- BeanPostProcessor after: создание AOP-прокси
- В конструкторе и @PostConstruct ещё нет прокси, вызовы через this
- Уничтожение: @PreDestroy, DisposableBean, кроме prototype
Если ответил, копните глубже
Senior: 12 вопросов
Глубина и опыт: границы подходов, решения в продакшене.
Расскажите, как работают виртуальные потоки и стоит ли переводить на них сервис на Spring Boot.
Что хотим услышать
- Платформенный поток = поток ОС, дорогой; виртуальный управляется JVM
- Continuation: при блокировке стек сохраняется в куче, носитель освобождается
- Выигрыш в пропускной способности для I/O, не для CPU
- Pinning в synchronized в Java 21-23, исправлен в 24
- Не пулить, ограничивать семафорами; осторожно с ThreadLocal
- Spring Boot 3.2+: spring.threads.virtual.enabled, проверить пул соединений БД
Если ответил, копните глубже
Как вы делаете пагинацию списка из десятков миллионов записей в Spring Data?
Что хотим услышать
- Page делает count, Slice нет
- OFFSET линейно дорожает с глубиной
- Keyset (seek) пагинация по индексированному ключу, ScrollPosition и Window
- Стабильная сортировка с уникальным ключом
- Нельзя join fetch коллекций с пагинацией
- Проекции вместо сущностей
Если ответил, копните глубже
Как в Kotlin работает делегирование реализации интерфейса через by и когда ты его используешь?
Что хотим услышать
- Компилятор генерирует методы интерфейса, переадресующие делегату
- Переопределяются только нужные методы
- Композиция вместо наследования, работает с final-классами
- Делегат фиксируется при создании
- Делегат не видит переопределений обёртки: нет полиморфизма через this
Если ответил, копните глубже
Расскажите, как в PostgreSQL устроен MVCC, откуда берутся мёртвые строки и зачем нужен VACUUM.
Что хотим услышать
UPDATEсоздаёт новую версию строки, старая остаётся сxmax;DELETEтолько помечает версию- Каждая транзакция видит версии по своему снимку, поэтому чтение не блокирует запись и наоборот
- VACUUM удаляет версии, которые уже никому не видны, обновляет visibility map и замораживает старые строки
- Долгие транзакции и забытые слоты репликации мешают очистке и раздувают таблицы
- Autovacuum настраивают по таблицам:
autovacuum_vacuum_scale_factor, лимиты стоимости; мониторинг черезpg_stat_user_tables - HOT-обновления и
fillfactorуменьшают нагрузку на индексы
Если ответил, копните глубже
VACUUM FULL отличается от обычного?Как бы ты сделал надёжный клиент WebSocket для чата, который переживает обрывы сети?
Что хотим услышать
- Реконнект с экспоненциальной задержкой и джиттером, сброс задержки после успеха
- Heartbeat: ping/pong с таймаутом, при пропуске закрыть и переподключиться
- Нумерация сообщений: после реконнекта клиент сообщает последний id, сервер досылает пропущенное
- Очередь исходящих сообщений с клиентскими id, идемпотентность на сервере против дублей
- Реакция на
online/offlineи видимость вкладки, повторная авторизация при истёкшем токене
Если ответил, копните глубже
Спроектируйте мессенджер с личными и групповыми чатами, доставкой в реальном времени и историей.
Что хотим услышать
- Требования: личные и групповые чаты до 1 000 участников, доставка онлайн и офлайн (push), история, статусы «доставлено» и «прочитано»; порядок сообщений в чате; медиа и сквозное шифрование вне рамок
- Оценка нагрузки: 50 млн DAU по 40 сообщений ≈ 2 млрд в сутки ≈ 20 000 RPS записи, в пике ~60 000; 10 млн одновременных соединений, ~100 000 на gateway → ~100 gateway; 2 млрд × 200 байт ≈ 400 ГБ в сутки, ~150 ТБ в год без реплик
- API: WebSocket: send {chat_id, client_msg_id, text}, ack {msg_id}, события new_message, read; HTTP: GET /chats/{id}/messages?before=...
- Данные: чаты и участники в PostgreSQL, сообщения в Cassandra/ScyllaDB с ключом партиции chat_id и сортировкой по msg_id, реестр user_id → gateway в Redis с TTL
- Компоненты: gateway-серверы с соединениями, сервис сообщений (сохранить, присвоить id, разослать), сервис присутствия, push-сервис для офлайн, очередь для фан-аута в группах
- Узкие места: большие группы (фан-аут через очередь), дубли при переотправке (client_msg_id для идемпотентности), переподключения и догрузка пропущенного, горячие чаты, падение gateway
Если ответил, копните глубже
Ты приходишь в проект без тестов. Как выстроишь стратегию тестирования?
Что хотим услышать
- начать с самого рискованного и ценного для бизнеса: оплата, вход, ключевые сценарии
- несколько e2e smoke-тестов на критичные пути
- unit-тесты на чистую логику: расчёты, форматирование, утилиты
- интеграционные тесты компонентов и API на новых и изменяемых местах
- тесты в CI как обязательная проверка PR
- регрессионный тест на каждый найденный баг, борьба с флаки
Если ответил, копните глубже
Пользователи жалуются, что https://api.example.com не открывается. Как будешь искать причину?
Что хотим услышать
- Воспроизвести и уточнить симптом: таймаут, refused, ошибка TLS, 5xx
- DNS:
dig +short, правильный ли IP, не истёк ли домен - Сеть и порт снаружи:
curl -v,nc -zv host 443; refused или timeout - На сервере: слушает ли процесс и на каком адресе (
ss -tlnp), отвечает ли локально - Фаервол на хосте и в облаке, балансировщик и его health checks
- Логи прокси и приложения, сертификат и его срок
Если ответил, копните глубже
Вы претендуете на senior. Расскажите о себе.
Что хотим услышать
- Назван масштаб: команда, нагрузка, пользователи или деньги
- Есть решения, которые повлияли дальше своего кода
- Есть метрики результата
- Упомянуто влияние на команду: менторинг, процессы, ревью
- Уложился в 2 минуты, не утонул в деталях
Если ответил, копните глубже
Как бы вы спроектировали сигнатуру метода addAll(коллекция, элементы) и метода max(коллекция, компаратор), чтобы они были максимально гибкими?
Что хотим услышать
- Инвариантность дженериков и зачем нужны wildcard
- addAll: Collection<? super T> приёмник, элементы как producer
- max: Collection<? extends T> и Comparator<? super T>
- PECS как правило выбора
- Wildcard только в параметрах, не в возвращаемых типах
Если ответил, копните глубже
Collections.max граница T extends Object & Comparable<? super T>?Как вы обеспечиваете согласованность данных между микросервисами без распределённых транзакций?
Что хотим услышать
- База на сервис, нет 2PC
- Саги: локальные транзакции и компенсации, хореография или оркестрация
- Outbox для надёжной публикации событий
- At-least-once доставка и идемпотентные потребители
- Eventual consistency и как её показывать пользователю
- Мониторинг зависших саг и ручной разбор
Если ответил, копните глубже
Опиши, как на Flow сделать поиск по мере ввода: какие операторы и почему.
Что хотим услышать
- Источник: MutableStateFlow с текстом запроса
- debounce, чтобы не слать запрос на каждую букву
- filter по длине и distinctUntilChanged
- flatMapLatest отменяет устаревший запрос
- catch для ошибок, flowOn или main-safe репозиторий
- stateIn в ViewModel с WhileSubscribed
Если ответил, копните глубже
Задача для live coding
Кратчайший путь в лабиринте
Лабиринт задан сеткой: . свободная клетка, # стена, S старт, T цель. За шаг можно перейти в соседнюю по стороне свободную клетку. Найдите минимальное число шагов от S до T.
Ввод: в первой строке n и m (1 ≤ n, m ≤ 1000), далее n строк по m символов. S и T встречаются ровно по одному разу.
Вывод: число шагов или -1, если дойти нельзя.
Пример
3 4
S..#
.#..
...T
5
BFS по сетке.
- Подсказка, если застрял: Все рёбра одинакового веса: нужен BFS.
- Подсказка, если застрял: Помечайте клетку при добавлении в очередь.
Эталон, тесты и таймер открываются интервьюеру в живом моке
Рубрика оценки: 1-4 балла
Те же критерии процесса, что в живом моке Техпрогона. Ставьте балл по каждому пункту, сумма показывает картину лучше, чем «понравился или нет».
Уточнил условие
Ограничения, формат входа, что вернуть при пустом вводе
Привёл примеры до кода
Обычный случай и хотя бы один краевой
Проговорил алгоритм словами
До того как писать код
Назвал сложность
По времени и по памяти
Написал рабочий код
Тесты прошли
Сам проверил краевые случаи
Прогнал в голове пустой ввод, один элемент, дубликаты
Нашёл и исправил ошибку сам
Или ошибок не было с первого раза
Мок-собес без регистрации для интервьюера
Хотите проверить кандидата на задаче с эталоном и рубрикой? Так работает живой мок в Техпрогоне.
Кандидат готовится в Техпрогоне и на задаче открывает ступень «Живой мок».
Он присылает вам ссылку. Вы открываете её без регистрации.
У вас условие, эталон, рубрика, уточняющие вопросы и таймер.
Вы ставите оценки и вердикт, кандидат сразу видит результат.
Для интервьюера бесплатно. Ссылку создаёт кандидат на тарифе Рывок
Наборы для других ролей
Готовитесь к собесу сами? Подготовка к собеседованию: Backend на Java/Kotlin