Запись реального технического этапа на позицию Senior Java-разработчика в HeadHunter. После самопрезентации и обсуждения команды кандидат отвечает на вопросы по Java, Spring Boot, Hibernate, Kafka, Docker и Kubernetes; затем разбираются асинхронное взаимодействие, Outbox Pattern, многопоточность и live-coding-задача по реализации MyOptional.
Техническое интервью начинается с рассказа кандидата о Java-бэкенде для инвестиционной платформы, ролях в команде и взаимодействии с аналитиками. Интервьюеры уточняют работу с Kafka — партиционирование, ключи сообщений и нагрузку, — Docker и Kubernetes, выбор синхронного или асинхронного взаимодействия, Outbox и обработку дубликатов. Во второй части обсуждаются функциональные интерфейсы, CompletableFuture, Stream API, параллельные стримы, ForkJoinPool, ThreadPool и Java Memory Model; в live coding кандидат реализует упрощённый MyOptional с методами map и filter.
Выбирайте синхронный вызов, когда ответ нужен в текущем бизнес-потоке; для допустимой eventual consistency подходит асинхронный обмен событиями.
Outbox сохраняет бизнес-изменение и запись события в одной транзакции, но обычно даёт доставку at-least-once: потребитель должен быть идемпотентным, например по стабильному ID события и уникальному ограничению.
Ключ Kafka выбирают по сущности, для которой нужен порядок событий, например по ID поручения. Число партиций определяют по нагрузке, числу потребителей и требованиям к порядку, а не по универсальному правилу.
При работе с CompletableFuture заранее задавайте способ объединения результатов и обработки ошибок через handle, whenComplete или exceptionally; при нескольких запросах важно сохранить сведения о каждом сбое.
Параллельные Stream API используют общий ForkJoinPool и подходят для независимых CPU-bound операций, но не для блокирующего I/O и общего изменяемого состояния без синхронизации.
volatile обеспечивает видимость изменений и гарантии порядка операций в Java Memory Model, но не делает составные операции атомарными.
В задаче на реализацию аналога Optional важно заранее определить контракт пустого значения, generic-сигнатуры и поведение map и filter.