golang

Реальные задачи с собеседований в Яндекс, VK, Ozon и Сбер — Go, Java, Python, React

  • пятница, 13 февраля 2026 г. в 00:00:08
https://habr.com/ru/articles/995600/

В первой части я рассказал, что выяснилось после анализа 9 247 технических интервью через ии помощник для собеседований: кто собеседуется, куда, какие вопросы задают. Статистика, графики, цифры. Всё чинно благородно.

Эта часть про задачи. Те самые, которые звучат на live-coding секции, и из-за которых у кандидатов потеют ладони и сжимается пятая точка, а интервьюеры делают покерфейс, когда видят hashCode() { return 1; }.

Честно, собрать этот материал оказалось в разы сложнее, чем аналитику из первой части. Там - агрегация, группировка, графики. Здесь целая детективная работа. Enigma AI не сохраняет скриншоты экрана кандидата (приватность, вот это всё). Зато сохраняет описание задачи, извлечённое vision-моделью из того, что видит кандидат на экране. Получается что-то вроде "на экране код на Go, функция принимает слайс, есть цикл с горутинами, переменная i...". По этим слепкам и транскрипциям разговоров я восстанавливал условия задач, кластеризовал похожие формулировки, определял компании. Было потрачено прорва времени. Но это было увлекательно, как собирать пазл из 2 000 фрагментов, где половина кусочков одного цвета. Но надеюсь результат того стоил и вам это будет интересно, а главное полезно.

Общая картина: что дают и кому

Паттерн чёткий. Go-интервью про конкурентность: каналы, горутины, мьютексы, race conditions. Java - контракты языка и проектирование. Python - data pipelines и работа с данными. JS/React - всё сразу, от typeof null до полноценных компонентов с API. C# - ООП-паттерны и LINQ.

Есть и общее: каждый стек тестирует edge cases. Не "можешь ли ты решить", а "помнишь ли ты про пустой массив, nil, переполнение, отмену контекста". Аккуратность важнее алгоритмической гениальности.

Go: а где у тебя мьютекс?

Go собеседования составляют порядка 34% live-coding сессий в моей выборке. Пять из шести задач, которые я разобрал про конкурентность. Это вряд ли совпадение. Go - это модно, стильно, молодежно. Компании нанимают Go-разработчиков для высоконагруженных сервисов, и хотят убедиться, что кандидат не напишет data race в первый же день.

Client-Side Load Balancer - Яндекс, Middle / Senior

Интерфейс Backend дан. Экземпляры ненадёжны, падают, зависают, перегружены. Нужен Balancer, который балансирует запросы между ними.

Минимум - round-robin. Хорошо - retry с переходом на следующий бэкенд + ctx.Done(). Отлично - health-check, circuit breaker, thundering herd.

Типичная яндексоидная задача: интерфейс дан, реализуй. Звучит просто, пока не начнёшь писать. 70% кандидатов забывают про atomic на счётчике round-robin. Ещё 20% добавляют мьютекс, но не проверяют контекст между ретраями. Оставшиеся доходят до health-check и их приглашают на следующий раунд. Ну или не приглашают, это же Яндекс.

// Решение Middle уровня. То, что от вас ждут
func (b *Balancer) Invoke(ctx context.Context, req Request) (Response, error) {
    n := len(b.backends)
    start := int(atomic.AddUint64(&b.next, 1) - 1) % n

    var lastErr error
    for i := 0; i < n; i++ {
        select {
        case <-ctx.Done():
            return nil, ctx.Err()
        default:
        }
        idx := (start + i) % n
        resp, err := b.backends[idx].Invoke(ctx, req)
        if err == nil {
            return resp, nil
        }
        lastErr = err
    }
    return nil, fmt.Errorf("all %d backends failed: %w", n, lastErr)
}

Найди баги: гонки и замыкания - Wildberries, Middle

Имеем два сломанных фрагмента. Первый - цикл с горутинами ищет максимальное чётное число. Второй - параллельный поиск документов через каналы. Найди все баги.

В Wildberries чаще встречается этот формат. Не напиши с нуля, а вот код, он написан твоим предшественником в пятницу вечером, объясни почему всё плохо. Этакое небольшое ревью, но с подвохом.

for i := 1000; i > 0; i-- {
    go func() {
        if i%2 == 0 && i > max { 
            max = i
        }
    }()
}
fmt.Printf("Maximum is %d", max)  

Три проблемы в шести строках. Замыкание по переменной цикла (до Go 1.22 гарантированный баг, после зависит от версии и если кандидат это знает, ему плюс). Гонка на max без синхронизации. И мой любимый: fmt.Printf вызывается до того, как горутины успевают что-то сделать.

Система бэкапов: стриминг, сжатие, пайплайн

Бэкап до 1 терабайта. Сжатие 1.5-3x. Хранилище с лимитом 100 мегабайт на файл. Спроектировать и написать пайплайн: чтение → сжатие → запись. Всё в память не влезает.

Стык System Design и кода. Яндекс дает скелет с интерфейсами и просит написать рабочий пайплайн с воркерами. Самый частый вопрос на обсуждении: "а что если коэффициент сжатия окажется меньше 1.5 и фрагмент не влезет в 100 мегабайт?" Те, кто сразу думает про edge cases проходят. Те, кто говорит "ну, мы возьмём фрагмент поменьше" без конкретики - досвидос.

Места в кинотеатре – VK, Junior / Middle

Массив из 0 и 1, зритель садится максимально далеко от остальных. Три случая: начало ряда, между зрителями, конец ряд

Классический LeetCode 849, в ВК почему-то очень ее любят, встречается аж 9 раз слово в слово для разных сессий соискателей.

ВК в целом дает задачи проще, чем Яндекс, но чаще проверяет внимательность. Здесь ловушка на краях: когда свободные места прилегают к стенке зала, расстояние считается иначе, чем в середине. Половина кандидатов пишет только обработку промежутков между зрителями и получает неправильный ответ на [0,0,0,1]. Обидно, когда ошибся из-за волнения.

Едем далее.

Монотонный слайс + степень двойки - Ozon, Junior / Middle

Две задачи за 20 минут. Первая - проверить монотонность слайса (два флага за один проход). Вторая - степень двойки (ожидается x & (x-1) == 0).

Ozon любит формат пулемёта: решил получи следующую. Монотонный слайс- разминка. Степень двойки - фильтр. Цикл с делением "пойдет". Битовый трюк с объяснением "хорошо". Битовый трюк + рассуждение про math.MinInt и отрицательные числа - пятерка в зачетку.

Worker Pool с graceful shutdown - Авито, Middle / Senior

Реализовать пул воркеров. Пул принимает задачи через канал, обрабатывает N горутинами, корректно завершается по context.Done(). Могут попросить добавить rate limiting.

Авито часто даёт инфраструктурные задачи. Не алгоритмы, а паттерны Go: fan-out, fan-in, graceful shutdown. Тут ключевое - не забыть корректно закрыть каналы и дождаться завершения всех горутин. Типичная ошибка: горутина читает из закрытого канала и молча получает zero value. Кандидат думает, что всё работает, а на самом деле половина задач теряется. Классика.


Java: найди восемь отличий

Java-собеседования устроены немного иначе. Меньше про алгоритмы, больше "а ты понимаешь, как это работает под капотом?" Сбер, Яндекс и Альфа особенно любят давать код с неочевидными багами. Компилируется, запускается, тесты зелёные. А потом в проде данные тихо перепутываются.

Code Review класса Person

Класс с SerializableExternalizableclone(), JAXB-аннотациями. Восемь багов. Найди все.

Супер-хит Сбера. Я видел эту задачу (или её вариации) в транскрипциях десятки раз. Восемь багов.

Нет no-arg конструктора - Externalizable упадёт при десериализации. Перепутан порядок полей в writeExternal/readExternal - phone и address поменяются местами. Тихо. Без исключений. В проде. clone() без Cloneable - всегда CloneNotSupportedException, обёрнутый в ErrorhashCode() возвращает 1 - HashMap превращается в LinkedList. И так далее до JAXB-аннотаций.

Самый коварный баг порядок полей. Например writeExternal пишет name → surname → phone → address, а readExternal читает name → surname → address → phone. Всё компилируется, тесты проходят (если в тестах phone == address == null). А в проде у Иванова из Москвы телефон вдруг становится "ул. Тверская, 1". Сбер обожает именно такие баги, потому что в банковском софте они стоят денег.

Сжатие массива в диапазоны – VK, Junior / Middle

[1, 4, 5, 2, 3, 9, 8, 11, 0] → "0-5,8-9,11". Сортировка + линейный проход.

Задача из категории "просто, но мучительно". Алгоритм тривиальный, а ошибок четыре штуки с гарантией. Забыли отсортировать (удивительно часто). Потеряли последний диапазон после цикла. Лишняя запятая. ArrayIndexOutOfBoundsException на пустом массиве. ВК оценивает не алгоритм, а аккуратность. Кандидат, который с первого раза написал чистое решение без багов за 12 минут в приоритете. Кандидат, который написал в целом правильно, но с тремя багфиксами под вопросом.

Система фильтрации уведомлений – Яндекс, Middle / Senior

Дано уведомление: id, тип (EMAIL/SMS/PUSH), получатель, текст. У получателя разрешённые каналы и заблокированные отправители. Фильтрация + дедупликация за 24 часа. Хранение реализовывать не нужно, только контракты и логику.

Тут Яндекс проверяет не умение кодить, а умение проектировать. Кандидат должен сам определить интерфейсы для получения настроек и истории, продумать pipeline фильтров. Типичная ошибка - провести 20 минут на моделях данных и не успеть дойти до фильтрации. Яндексу не нужны идеальные DTO. Им нужен рабочий NotificationFilter с тремя проверками внутри.

Concurrent HashMap с сегментами – Альфа-Банк, Senior

Реализовать потокобезопасную HashMap с сегментной блокировкой. Не ConcurrentHashMap из JDK, а свою упрощённую, но с пониманием принципов.

Альфа даёт тяжёлые задачи для сеньоров. Про понимание того, как устроена ConcurrentHashMap: почему сегменты, почему не один мьютекс, как определить сегмент по хешу. Многие из кандидатов начинают с "обернём обычную HashMap в synchronized" и потом не могут объяснить, зачем нужны сегменты. Учитесь на чужих ошибках.


Python: а теперь напиши генератор

Python-задач в live-coding меньше, чем Go и Java, но они стабильно появляются в Ozon, Яндексе и Kaspersky. Фокус на генераторах, декораторах и data processing.

Rate Limiter через декоратор – Kaspersky, Middle

Написать декоратор @rate_limit(max_calls=5, period=60), который ограничивает количество вызовов функции. Потокобезопасность, как возможное доп. требования.

Касперский проверяет понимание замыканий и декораторов. Базовую версию пишут почти все. Потокобезопасную с threading.Lock не все. Версию со скользящим окном вместо фиксированного единицы.

Потоковая обработка лог-файла – Ozon, Middle

Имеем файл логов 10 GB. Посчитать топ-10 URL по количеству запросов. В память не влезает. Ожидается решение через генераторы и collections.Counter.

Ozon любит data processing. Кандидат, который делает file.readlines() провалил задачу ещё до того, как начал считать. Правильный ответ: генератор, построчное чтение, Counter с most_common(10). Могут задать вопрос: "а если URL миллионы уникальных и Counter не влезает в память?"

Яндекс в большинстве случаев предлагает написать бизнес код: работа банкомата, бронирование такси и т.д. Смотрит на чистоту кода, обработку ошибок и рассуждения кандидата.

C#: объясни, зачем нужен IDisposable

C# задач немного, около 6% от всего live-coding. Но они стабильно появляются в МТС и Positive Technologies. Поэтому только одна самая распространенная задача.

Observer с weak references – Positive Technologies, Middle / Senior

Реализовать EventBus с подписками. Но подписчики не должны удерживаться от GC, используй WeakReference. А что с потокобезопасностью?

Проверяют глубину знания .NET. Базовый Observer пишут все. Weak references добавляют те, кто реально работал с долгоживущими приложениями и сталкивался с утечками памяти через подписки. Самая частая ошибка: забывают проверить, жив ли подписчик, перед вызовом.

JS/React: от typeof null до SWAPI за 45 минут

Фронтенд-собеседования самые разнообразные и самые плотные. Одно интервью может включать квиз, задачу на паттерн, react-компонент с API и вопрос про ререндеры. Всё за 45 минут. Дышать необязательно. Вообще разброс вариативности задач по фронту самая впечатляющая, очень тяжело было хоть как-то систематизировать.

JS Quiz – МТС, Junior / Middle

Семь console.logвопросов подряд. Быстрый фильтр: знаешь язык или нет.

Самый коварный вопрос, ну или нет:

const a = {}, b = {}, c = {}
a[b] = '1'
a[c] = '2'
console.log(a)  // { '[object Object]': '2' }

Объекты при использовании как ключи приводятся к [object Object]. Оба. Второе присваивание перезаписывает первое. Проваливают 50% кандидатов. Знание typeof null === 'object' при этом не помогает.

Event Loop + this + EventEmitter – Т-Банк, Middle

Порядок вывода Promise/setTimeout. Потеря контекста в .filter(). Реализация EventEmitter с chaining. Три задачи подряд.

Т-Банк (бывш. Тинькофф) структурирует фронтенд интервью как серию мини-задач нарастающей сложности. Event loop на разогрев: 1, 4, 6, 3, 2, 5. Потеря this в колбэке .filter() очевидная ловушка: обычная функция теряет контекст, стрелочная нет. EventEmitter единственное место, где нужно писать с нуля.

EventEmitter - самая частая задача на фронтенд-собесах в моей выборке. Я видел её в транскрипциях Т-Банка, МТС, VK, Авито и Lamoda. Видимо, она идеально тестирует набор: замыкания, объекты, chaining. И писать её ровно 5 минут, если знаешь паттерн. И 25, если нет.

React: ререндеры + SWAPI - Т-Банк, Middle / Senior

Объяснить, какие компоненты ререндерятся при клике. Написать поиск персонажей Star Wars с debounce, AbortController и индикатором загрузки.

Задача про ререндеры это не про код, а про понимание React. "При клике на Render что произойдёт?" Правильный ответ: ререндерятся все, потому что React.memo нигде не используется. "А при вводе текста?" - Parent и Child, но не App. Ключевой момент: handleChange создаётся заново при каждом рендере, и Child получает новую ссылку. Те, кто знает про useCallback, объясняют это за минуту. Остальные мучаются.

SWAPI-задача наш финальный босс. За 20 минут написать поиск с debounce и отменой запросов. По транскрипциям, AbortController добавляют 30–40%. Остальные получают race condition: ввёл "sky", запрос ушёл, стёр, ввёл "luke", пришёл ответ на "sky", отобразились Скайуокеры вместо Люка. Кек.

Чек-боксы с логированием - МТС, Junior / Middle

Отрисовать чек-боксы по двум массивам, запоминать выбранные, логировать двойной клик. Заготовка с ошибками в атрибутах (disable вместо disabledfor вместо htmlFor).

МТС даёт джунам заготовку с намеренными ошибками в JSX и смотрит, заметит ли кандидат. disable вместо disabledfor вместо htmlFor.,useEffect без массива зависимостей, подписка на dblclick добавляется при каждом рендере. Задача проверяет не креативность, а внимательность к деталям и знание отличий HTML от JSX.


Паттерны по компаниям

Компания

Стек

Формат

Фокус

Яндекс

Go, Java

1 задача, 30–45 мин

Проектирование + код. Интерфейсы даны

Сбер

Java

Code review, 20 мин

Контракты языка, внимательность к деталям

VK

Go, Java

1–2 задачи, 15–20 мин

Алгоритмы, граничные случаи

Ozon

Go, Python

2–3 задачи, «пулемёт»

Скорость, битовые операции, data processing

Wildberries

Go

Код с багами

Конкурентность, каналы, race conditions

Т-Банк

JS/React

3–5 мини-задач

Всё: quiz + паттерны + React + API

МТС

JS/React

Quiz + компонент

Знание JS, JSX-ошибки

Авито

Go

1 задача, 30 мин

Инфраструктурные паттерны: пулы, пайплайны

Альфа-Банк

Java

1 задача, 40 мин

Глубина: concurrency, внутренности JDK

Kaspersky

Python, Go

1–2 задачи

Декораторы, генераторы, системщина

Что из этого следует

Я перелопатил сотни задач, и вот к чему пришёл.

Компании не ищут людей, которые решают LeetCode Hard за 15 минут. Ни одна задача в моей выборке не требовала знания сложных алгоритмов. Ни деревьев отрезков, ни динамического программирования на графах, ни суффиксных массивов. Зато все до единой требовали аккуратности. Пустой массив, nil, отменённый контекст, перепутанный порядок полей вот за что снижают оценку.

Go-разработчикам: тренируйте конкурентность. Не теорию каналов, а практику: балансировщик, воркер-пул, pipeline с graceful shutdown. Пять из семи Go-задач в моей выборке требовали sync.Mutexatomic или WaitGroup.

Java-разработчикам: перечитайте Effective Java, главы про equals/hashCode и сериализацию. Серьёзно. Сбер и Яндекс спрашивают это постоянно. Особенно любят код, где всё компилируется и тесты проходят, но данные перепутываются.

Python-разработчикам: генераторы и декораторы - ваш хлеб. Если не можете написать декоратор с параметрами за 5 минут потренируйтесь. Это ваш аналог битовых операций для Go.

Фронтендерам: готовьтесь к марафону. 45 минут, пять задач. Debounce + AbortController наизусть. EventEmitter наизусть. useCallback и React.memo понимать, а не просто использовать. И да, typeof null === 'object' спрашивают до сих пор.


Первая часть с общей аналитикой по 9 247 интервью – здесь. Если хотите попробовать Энигму -enigmai.ru.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Какой формат live-coding вы считаете самым адекватным?
28.38%Одна задача на 30–45 минут с обсуждением21
16.22%2–3 короткие задачи «пулемётом»12
39.19%Code review чужого кода29
33.78%Код с багами – найди ошибку25
14.86%Мини-проект, приближённый к реальной работе11
33.78%Любой формат неадекватен, live-coding не нужен25
Проголосовали 74 пользователя. Воздержались 12 пользователей.