java-interview

Собес в VK (группа балансеров, One-cloud) · Java Middle

Вопросы, задачи и подготовка к live-coding и техническому интервью.

Темы: Java 21 · Spring Boot 3 · Kafka · PostgreSQL · Kubernetes · gRPC · HAProxy · Docker

← Ко всем гайдам · Канал JavaJub в Telegram


1. Про VK и группу балансеров

VK — одна из крупнейших IT-компаний России (15 000+ сотрудников, 200+ продуктов, 95% аудитории рунета). Центр Технологий VK отвечает за IT-инфраструктуру всех продуктов: ВКонтакте, ОК, Дзен, Mail.ru, RuStore, VK Play. One-cloud — технологический фундамент VK: единая среда запуска приложений, хранилищ, баз данных и сервисов. Группа балансеров занимается управлением и администрированием L3- и L4- балансеров облака. Через них идёт ВЕСЬ сервисный и пользовательский трафик — это tier 1 уровень стабильности.

Чем занимается группа балансеров

Как устроен процесс найма

По отзывам кандидатов (DreamJob, Habr 879068, Habr 1006022): VK проводит единое техническое интервью для всех Java-вакансий, после которого распределяет по командам. Процесс похож на Яндекс, но обычно быстрее.

Этап Формат Длительность
HR-скрининг Zoom/Telegram, мотивация, ЗП, 20–30 мин

стек

Техническое интервью Теория + live-coding + SQL 60–90 мин
Алгоритмическая секция Live-coding, 2–3 задачи 45–60 мин
Архитектурная секция System Design, Miro + Zoom 45–60 мин
Финал с командой Знакомство с тимлидом и 30–60 мин

командой

ФИШКА. Единое интервью В VK техническое интервью общее для всех Java-вакансий. HR предлагает 2–3 команды на выбор, но тех-собес один. Это значит: готовиться нужно к общей Java-базе, а не к специфике балансеров. Специфика обсуждается на финале с командой.

ВНИМАНИЕ · Что бросается в глаза

По отзывам на Habr: VK спрашивает алгоритмы и структуры данных даже у Middle. Бинарный поиск, хэш-таблицы, деревья, очереди с приоритетом — будьте готовы. На этапе SQL всё обычно проходит хорошо, а вот алгоритмы — главный фильтр.

2. Стек по вакансии

Группа балансеров — часть One-cloud, разработка ведётся на современном стеке без устаревшего кода.

Основной стек

Будет плюсом

СОВЕТ. Про Java 21 VK использует Java 21 — это важно. Готовьтесь к вопросам про Virtual Threads (Project Loom), Records, Sealed Classes, Pattern Matching for switch. Это не «будет плюсом», а рабочий стек.

3. Java Core — что точно спросят

equals/hashCode, HashMap, Stream API, многопоточность — must-have. VK спрашивает глубже среднего: устройство JVM, GC, ссылочные типы.

Базовые вопросы

Класс — нельзя наследовать. Метод — нельзя переопределить. Поле — нельзя переприсвоить (мутабельное содержимое можно менять). effectively final — для лямбд.

Задачи «Что выведет?»

Тест 1. Integer cache

Integer a = 127, b = 127;
System.out.println(a == b); // true

Integer c = 128, d = 128;
System.out.println(c == d); // false

IntegerCache: -128..127. Для 127 — один объект. Для 128 — два разных. Мораль: для объектов — equals().

Тест 2. String Pool

String s1 = "hello";
String s2 = "hello";
String s3 = new String("hello");

System.out.println(s1 == s2);    // true (оба из пула)
System.out.println(s1 == s3);    // false (s3 — новый объект)
System.out.println(s1.equals(s3)); // true (содержимое одинаковое)

Тест 3. Stream — ленивость List.of(1,2,3,4,5).stream() .peek(x -> System.out.print(“A” + x + “ “)) .filter(x -> x % 2 == 0) .peek(x -> System.out.print(“B” + x + “ “))

  .toList();
// A1 A2 B2 A3 A4 B4 A5

Вертикальная обработка: каждый элемент проходит всю цепочку. Нечётные не проходят filter → B не печатается.

СОВЕТ. Про Java 21 VK использует Java 21. Готовьтесь к вопросам про Virtual Threads, Records, Sealed Classes, Pattern Matching for switch. Пример: «Чем Virtual Thread отличается от Platform Thread? Когда НЕ стоит использовать Virtual Threads?» — CPU-bound задачи, synchronized блоки (pinning).

4. Коллекции

HashMap — абсолютный чемпион вопросов. В VK спрашивают глубоко: treeify threshold, resize, null-ключи, ConcurrentHashMap внутренности.

5. Многопоточность и JMM

В VK многопоточность критична — балансеры обрабатывают весь трафик. volatile vs synchronized спрашивают на каждом собесе. ThreadPoolExecutor, CAS, пулы потоков — обязательно.

ЛОВУШКА · volatile counter++ volatile long counter; counter++ — НЕВЕРНО (три операции). Три корректных варианта: synchronized, AtomicLong.incrementAndGet(), LongAdder.increment(). LongAdder лучше при высоком contention.

6. Spring и Spring Boot

Spring Boot 3 — основной фреймворк VK для Java-сервисов. Спрашивают: прокси, жизненный цикл, автоконфигурация, транзакции.

7. Базы данных и SQL

PostgreSQL — основная БД в VK для Java-сервисов. SQL спрашивают отдельно: JOIN, GROUP BY, HAVING, индексы, транзакции.

SQL-задачи

Вторая по величине зарплата

SELECT DISTINCT salary FROM employees
ORDER BY salary DESC LIMIT 1 OFFSET 1;

Идемпотентное зачисление через Kafka Из собесов на Java Middle: поручения на зачисление денег приходят по Kafka. Kafka гарантирует доставку, но НЕ единственность. Как обеспечить, что деньги зачислятся ровно один раз?

– Таблица идемпотентности

CREATE TABLE processed_events (
    event_id UUID PRIMARY KEY,
    processed_at TIMESTAMP DEFAULT NOW()
)
;

-- В транзакции с бизнес-логикой:
INSERT INTO processed_events (event_id)
VALUES (:eventId)
ON CONFLICT (event_id) DO NOTHING;
-- Если вставка прошла — обработать
-- Если конфликт — skip (уже обработано)

8. Kafka и микросервисы

Kafka указана в стеке VK для Java-сервисов. Для группы балансеров это межсервисная коммуникация между инфраструктурными компонентами.

9. Сети и балансировка

Группа балансеров — это про сети. Даже если глубокие сетевые вопросы будут на финале с командой, базовое понимание L3/L4/L7 балансировки ожидается.

ФИШКА. Почему это важно Через балансеры группы идёт ВЕСЬ трафик VK — ВКонтакте, ОК, Дзен, Mail.ru. Это tier 1: любой сбой = даунтайм всех продуктов. На финале с командой точно спросят про L3/L4 разницу и как вы думаете о стабильности.

10. Docker, Kubernetes, CI/CD

One-cloud VK построен поверх Kubernetes. Docker и K8s — рабочие инструменты группы балансеров.

11. Практические задачи (live-coding)

По отзывам кандидатов в VK: задачи на алгоритмы, Stream API, многопоточность. Пишете код в онлайн-редакторе. Рассуждайте вслух!

Задача 1. Найти дубликаты

public Set<Integer> findDuplicates(List<Integer> list) {
    Set<Integer> seen = new HashSet<>();
    Set<Integer> dups = new HashSet<>();
    for (Integer n : list) {
        if (!seen.add(n)) dups.add(n);
    }
    return dups;
}

O(n) время, O(n) память. seen.add() → false если элемент уже есть.

Задача 2. Являются ли строки перестановками

Из реальных собесов: определить, являются ли две строки перестановкой символов (a..z) друг друга.

public boolean isPermutation(String a, String b) {
    if (a.length() != b.length()) return false;
    int[] counts = new int[26];
    for (char c : a.toCharArray()) counts[c - 'a']++;
    for (char c : b.toCharArray()) counts[c - 'a']--;
    for (int count : counts) {
        if (count != 0) return false;
    }
    return true;
}

O(n) через counting sort. Альтернатива: отсортировать обе строки O(n log n). Counting быстрее для маленького алфавита.

Задача 3. REST-контроллер

@RestController
@RequestMapping("/api/balancers")
public class BalancerController {

     private final BalancerService service;

     public BalancerController(BalancerService service) {
         this.service = service;
     }

     @PostMapping
     @ResponseStatus(HttpStatus.CREATED)
     public BalancerDto create(@RequestBody @Valid CreateBalancerRequest req) {
         return service.create(req);
     }

     @GetMapping("/{id}")
     public BalancerDto getById(@PathVariable Long id) {
         return service.findById(id);
     }
}

Задача 4. Потокобезопасный кэш

public class SimpleCache<K, V> {
    private final Map<K, V> cache = new ConcurrentHashMap<>();

     public V get(K key, Function<K, V> loader) {
         return cache.computeIfAbsent(key, loader);
     }
}

ConcurrentHashMap (не HashMap). computeIfAbsent (не containsKey+put — гонка). Ограничение размера: Caffeine с maxSize и TTL.

Задача 5. Code Review

public class UserCache {
    private static Map<Long, User> cache = new HashMap<>();

     public static User getUser(Long id) {
         if (cache.containsKey(id)) {
             return cache.get(id);
         }
         User user = loadFromDb(id);
         cache.put(id, user);
         return user;
     }
}

Проблемы: 1) HashMap не потокобезопасен → ConcurrentHashMap. 2) containsKey+get → computeIfAbsent. 3) Кэш бесконечный → memory leak. 4) static → тяжело тестировать. 5) null от loadFromDb.

Задача 6. SQL: идемпотентное зачисление

Из Пикабу (реальный вопрос на Java Middle): система зачисления денег через Kafka. Как гарантировать, что деньги зачислятся ровно один раз?

@Transactional
public void processPayment(PaymentEvent event) {
    try {
        processedEventRepo.save(
            new ProcessedEvent(event.getId()));
    } catch (DataIntegrityViolationException e) {
        log.info("Duplicate event: {}", event.getId());
        return; // уже обработано
    }
    accountRepo.credit(event.getAccountId(), event.getAmount());
}

INSERT + бизнес-логика в одной транзакции. PK conflict = дубль = skip. Kafka at-least-once + идемпотентность = exactly-once семантика.

12. System Design

Для Middle архитектурная секция может быть опциональной, но для Middle+ — обязательна. В контексте балансеров: ожидайте задачи про распределённые системы и высокую нагрузку.

13. План подготовки + чек-лист

За 2–3 недели

За неделю

В день собеса

ВНИМАНИЕ · Главный фильтр По отзывам кандидатов VK: алгоритмы и структуры данных — главный фильтр. Хэш-таблицы, деревья, очереди с приоритетом. Это спрашивают даже у Middle. SQL обычно проходит хорошо. Готовьтесь к алгоритмам!

Финальный чек-лист

Блок Готов, если можешь…
Java Core equals/hashCode + Integer cache + Virtual Threads

(Java 21) + Records

Коллекции HashMap: treeify, resize, ConcurrentHashMap Java 8, PriorityQueue

Многопоточность volatile vs synchronized + CAS + ThreadPoolExecutor + Virtual Threads pinning

Spring @Transactional прокси + self-call + scope prototype в singleton + Spring Boot 3

SQL JOIN + GROUP BY + составной индекс + оконные функции + EXPLAIN ANALYZE

Kafka Consumer Group + at-least-once + идемпотентность + exactly-once

Сети L3 vs L4 vs L7 балансировка + HAProxy + VRRP + health checks

Docker/K8s Dockerfile multi-stage + Pod/Deployment/Service + probes + Service types

System Design Load Balancer design + rate limiter + back-of-envelope расчёты

Live-coding 3 задачи за 1 час: перестановки строк, дубликаты, code review


Удачи на собесе!

// git push origin offer


Гайд из канала JavaJub — свежие разборы собесов выходят там первыми: @java_jub.

← Ко всем гайдам