Подготовка к многоэтапному отбору Middle/Senior Java-разработчика в финтех-экосистему: Java 11+, Spring Boot, Kafka, Kubernetes и высоконагруженные платёжные сервисы
Фишка: FAANG-подобный процесс с code review, алгоритмами и System Design; сильный акцент на надёжность интеграций, retry-стратегии и работу под нагрузкой в финтех-домене
| Этап | Длительность | Что проверяют |
|---|---|---|
| HR-скрининг | 30–45 мин | Мотивация, опыт, ожидания по зарплате, выбор направления (Т-Инвестиции, Т-Бизнес, Т-Страхование, платёжный процессинг), формат работы (гибрид, офис в Екатеринбурге) |
| Онлайн-тест и домашнее задание | до 1 ч | Блиц-тест по базовым темам, тестовая задача на программирование с ограничением по времени (ссылки одноразовые) |
| Техническое интервью | 60–90 мин | Code review, Java Core, Spring (скоупы бинов, прокси, жизненный цикл), транзакции и уровни изоляции, concurrency (synchronized, volatile, java.util.concurrent), диагностика проблем производительности |
| Алгоритмическая секция | 60–90 мин | 1–2 задачи в онлайн-IDE: структуры данных, два указателя, DP; важно рассуждать вслух и покрывать edge cases |
| System Design | 60–90 мин | Для Senior: проектирование распределённого сервиса (мессенджер, платёжный шлюз, уведомления); сбор требований, оценка нагрузки, выбор Kafka/БД, компромиссы |
| Мэтчинг с командой | 30–60 мин | Знакомство с командой, стек проекта, спектр задач; уточните стек до старта — от него зависит интерес к позиции |
Обязательный минимум
Плюсом будет
Какие знаешь правила переопределения hashCode и equals?
Контракт: если equals — то hashCode совпадает; симметричность, транзитивность, консистентность; используйте одни и те же поля; для mutable-ключей в HashMap — осторожно
Какие знаешь методы класса Object?
equals, hashCode, toString, clone, finalize (deprecated), getClass, wait/notify/notifyAll
В чём разница между Comparable и Comparator?
Comparable — natural order внутри класса (compareTo); Comparator — внешняя сортировка, несколько стратегий, Comparator.comparing(), thenComparing()
Что такое функциональный интерфейс?
Один абстрактный метод (@FunctionalInterface); лямбды и method reference; примеры: Predicate, Function, Supplier, Consumer
Что такое JIT и как он влияет на поведение приложения?
Just-In-Time компиляция байткода в нативный код; hotspot-оптимизации; warm-up; влияние на latency после старта
Зачем нужны маркерные интерфейсы в Java?
Пустые интерфейсы-маркеры (Serializable, Cloneable); метаданные для JVM/фреймворков; в современном Java чаще аннотации
Ловушка: Что будет при вставке в HashMap двух элементов, равных по equals, но с разным hashCode? — деградация в linked list в бакете, O(n) вместо O(1)
Совет: На code review часто дают кусок кода со строками — разберите пул интернирования, == vs equals и синхронизацию на String
В чём разница между ArrayList и LinkedList и когда их использовать?
ArrayList: O(1) random access, O(n) вставка в середину; LinkedList: O(n) доступ, O(1) вставка при известном узле; на практике ArrayList — дефолт
Какова сложность основных операций в ArrayList и LinkedList?
ArrayList: get O(1), add end O(1) amortized, add middle O(n); LinkedList: get O(n), add at iterator O(1)
В чём разница между synchronizedMap и ConcurrentHashMap?
synchronizedMap — блокировка всей map; ConcurrentHashMap — сегментная/blocking lock-free структура, лучше для read-heavy; разные гарантии итерации
В чём отличие методов map и flatMap в Java Streams?
map: T→R; flatMap: T→Stream<R> и схлопывание; flatMap для вложенных коллекций, Optional
В чём разница между SQL и NoSQL?
SQL: ACID, схема, JOIN, вертикальное масштабирование; NoSQL: гибкая схема, горизонтальное масштабирование, eventual consistency; выбор по модели данных и нагрузке
Фишка: В Т-Банке много сервисов с высокой нагрузкой — умение выбрать коллекцию и объяснить сложность важнее заучивания API
Какие типы локов существуют в Java и чем они отличаются от synchronized?
synchronized, ReentrantLock (tryLock, fairness), ReadWriteLock, StampedLock; отличие: гибкость, interruptible, условия (Condition)
Какие знаешь виды синхронизации?
Мониторы, volatile (visibility), atomic-классы, locks, semaphores, CountDownLatch, CyclicBarrier
Как избежать гонок при инкрементации счётчиков?
AtomicInteger/LongAdder, synchronized, locks; LongAdder для высокой конкуренции
Как можно реализовать безопасную многопоточную разработку?
Иммутабельность, thread-safe коллекции, правильный порядок захвата локов, минимизация shared state
Как ускорить параллельное выполнение метода с большим числом вызовов?
ExecutorService, ForkJoinPool, parallelStream (осторожно с общим состоянием), пулы потоков по профилю нагрузки
Ловушка: Зачем делать переменную атомарной, если запросы в контроллер идут в одном потоке? — Tomcat использует пул потоков, один инстанс бина обслуживает множество запросов
Совет: Готовьте пример deadlock: два потока, два лока, разный порядок захвата — и как диагностировать через thread dump
Для чего нужен Spring?
IoC/DI, управление жизненным циклом, AOP, абстракции над инфраструктурой (JDBC, JPA, Web, Security)
В чём разница между Spring Boot и Spring Framework?
Boot — автоконфигурация, embedded server, starter-зависимости, production-ready (actuator); Framework — ядро IoC/AOP
Какой жизненный цикл Bean в Spring?
Instantiation → populate → BeanNameAware → post-processors → @PostConstruct → init → ready → @PreDestroy → destroy
Зачем нужны транзакции и как работают в Spring?
ACID; @Transactional + прокси; propagation (REQUIRED, REQUIRES_NEW), isolation, rollbackFor; транзакция на уровне БД, не HTTP
Что такое оптимистичные и пессимистичные блокировки?
Пессимистичная: SELECT FOR UPDATE; оптимистичная: version column, проверка при UPDATE; выбор по конфликтности записей
Какие есть проблемы в использовании REST?
Over/under-fetching, нет стандарта ошибок, версионирование, идемпотентность, отсутствие типизации; для внутренних — gRPC
Какие есть стратегии ретраев?
Fixed/exponential backoff, jitter, max attempts, idempotency key; retry только на transient errors
Как повысить надёжность отправки запросов при недоступности стороннего сервиса?
Circuit breaker, timeout, retry с backoff, fallback, bulkhead, rate limiter, async + очередь
Фишка: Типичный кейс Т-Банка: сервис + Postgres + third-party API тормозит — проверьте latency, GC, locks в БД, circuit breaker и rate limiter
Ловушка: Будут ли проблемы при прямой передаче в @RestController модели с ManyToOne? — LazyInitializationException, циклическая сериализация JSON; используйте DTO
Что такое транзакция в базах данных?
ACID: Atomicity, Consistency, Isolation, Durability; BEGIN/COMMIT/ROLLBACK
Может ли любая операция в SQL содержаться в транзакции?
Большинство DML — да; DDL часто auto-commit; TRUNCATE, CREATE INDEX CONCURRENTLY — исключения в PostgreSQL
Что такое первичный и внешний ключ?
PK — уникальный идентификатор строки; FK — ссылка на PK другой таблицы, referential integrity
Что такое распределённая транзакция?
2PC/XA across services; сложность и хрупкость; альтернатива: Saga, outbox pattern, eventual consistency
Как проверить, что проблема в базе данных при высокой нагрузке?
Метрики: query latency, locks, connections, slow query log, EXPLAIN ANALYZE, CPU/IO, connection pool exhaustion
Совет: Для платёжного шлюза критичны идемпотентность операций и корректная обработка частичных сбоев — обсуждайте outbox и Saga
Что такое Kubernetes?
Оркестратор контейнеров: Pod, Deployment, Service, Ingress; self-healing, scaling, rolling updates
В чём разница между контейнером и виртуальной машиной?
VM: полная ОС, гипервизор; контейнер: shared kernel, изоляция через namespaces/cgroups, быстрее старт
Какие инструменты мониторинга использовал?
Prometheus + Grafana, ELK, Jaeger/Zipkin tracing, JVM metrics (heap, GC), alerting по SLO
Фишка: В вакансии указаны Docker/K8s/OpenShift — ожидают понимание деплоя Spring Boot в контейнер, health checks, ресурсных лимитов
Банкомат
Есть банкомат с купюрами разных номиналов (Map<номинал, количество>). Реализовать метод withdraw(amount), который возвращает Map<номинал, количество> выданных купюр. Метод вызывается многократно, купюры расходуются. Если сумму выдать невозможно — ошибка.
Жадный алгоритм: сортировка номиналов по убыванию, на каждом шаге берём min(нужно, доступно). Для канонического набора купюр (1,2,5,10...) работает; для произвольного — DP/backtracking.
```java
public Map<Integer, Integer> withdraw(int amount) {
Map<Integer, Integer> result = new TreeMap<>(Collections.reverseOrder());
int remaining = amount;
for (var entry : vault.entrySet().stream()
.sorted(Map.Entry.<Integer,Integer>comparingByKey().reversed())
.toList()) {
int denom = entry.getKey();
int count = Math.min(remaining / denom, entry.getValue());
if (count > 0) {
result.put(denom, count);
remaining -= denom * count;
}
}
if (remaining != 0) throw new IllegalArgumentException("Cannot withdraw");
return result;
}
```Сложность: O(d) где d — число номиналов; DP O(amount × d) для произвольных номиналов
Асинхронное обновление пользователя (code review)
Найти проблемы в UserServiceImpl: @Transactional updateUser вызывает @Async notifyAboutUpdatedUser, который снова читает и сохраняет User в другом потоке.
Проблемы: 1) @Async не сработает без @EnableAsync и отдельного executor; 2) транзакция updateUser может не закоммититься до чтения в async-потоке — race condition; 3) @Async на том же классе — self-invocation, прокси не сработает; 4) нет обработки ошибок notification; 5) два save без явной необходимости. Исправление: TransactionalEventListener(AFTER_COMMIT), отдельный сервис для async, DTO вместо повторного чтения, идемпотентность уведомлений.
Сложность: —
Атомарность: БД + HTTP-запрос
Код-ревью: @Transactional метод сохраняет данные в БД, затем отправляет HTTP POST уведомление. При ошибке HTTP — RuntimeException.
Проблема: HTTP внутри транзакции — долгий lock; при RuntimeException откатится БД, но уведомление могло уйти (нет атомарности). Решения: outbox pattern (сохранить событие в таблицу в той же транзакции, отдельный воркер отправляет); Saga; идемпотентный consumer на стороне получателя.
Сложность: —
Длина самой длинной подстроки без повторов
Дана строка s. Найти длину самой длинной подстроки без повторяющихся символов. Пример: "abcabcbb" → 3.
Sliding window + HashSet/Map позиций:
```java
public int lengthOfLongestSubstring(String s) {
Map<Character, Integer> last = new HashMap<>();
int max = 0, left = 0;
for (int right = 0; right < s.length(); right++) {
char c = s.charAt(right);
if (last.containsKey(c) && last.get(c) >= left) {
left = last.get(c) + 1;
}
last.put(c, right);
max = Math.max(max, right - left + 1);
}
return max;
}
```Сложность: O(n) по времени, O(min(n, alphabet)) по памяти
Одинаковые элементы в трёх отсортированных массивах
Найти общие элементы в трёх отсортированных массивах, используя O(1) дополнительной памяти (кроме вывода).
Три указателя: сравниваем arr1[i], arr2[j], arr3[k]; если равны — добавляем (с пропуском дубликатов); иначе сдвигаем указатель с минимальным значением. ```java // i, j, k — индексы; при равенстве — записать и ++все три // при неравенстве — ++ у минимального ```
Сложность: O(n1+n2+n3) время, O(1) память
Каркас ответа
3 дня
7 дней
14 дней
| Блок | Готов, если... |
|---|---|
| Java Core | можешь объяснить контракт equals/hashCode, разницу ArrayList/LinkedList и ответить на code review со строками |
| Многопоточность | можешь показать deadlock, объяснить volatile/synchronized и выбрать между ConcurrentHashMap и synchronizedMap |
| Spring | можешь описать жизненный цикл бина, propagation транзакций и проблемы @Async + @Transactional |
| Базы данных | можешь объяснить ACID, уровни изоляции и как диагностировать медленные запросы |
| Интеграции | можешь описать retry, circuit breaker и outbox pattern для БД+HTTP |
| Алгоритмы | решаешь за 20–30 мин задачу уровня «три указателя» или sliding window с edge cases |
| System Design | можешь за 45 мин спроектировать event-driven сервис с Kafka, БД и оценкой нагрузки |
| Поведенческие | есть 3 истории по STAR и 5 вопросов к интервьюерам о команде и продукте |
В день собеседования