
434 задачи, 1450 сабмитов — мой путь к пониманию того, как на самом деле работают алгоритмические интервью
Введение
Всем привет! Меня зовут Евгений Мацюк. Сейчас я работаю в X (Twitter) на позиции Staff Software Engineer, до этого — TrustWallet, Careem, Kaspersky. Я соавтор Kaspresso, co-founder в MarathonLabs и Android Google Developer Expert с 2020 года.
За последние годы (2021-2025) я прошёл кодинг-интервью в X, Google, Careem, TrustWallet, Yandex и много других компаний. И знаете что? Я прошёл абсолютно все. При этом на интервью в Google в 2022 году я даже не до конца решил задачу — сказалось сильное волнение. Но интервьюер остался доволен, и рекрутер это подтвердила.
Как так вышло? Дело не в количестве решённых задач (хотя 434 — это немало). Дело в понимании того, что на самом деле оценивается на этих интервью и как правильно себя вести. Об этом и поговорим.
Три формата кодинг-интервью
Прежде чем погружаться в Leetcode, давайте быстро пробежимся по форматам кодинг-интервью, которые вам могут встретиться:
Leetcode-style задачки — самый распространённый формат. Классические алгоритмические задачи в shared-редакторе. Именно о нём эта статья.
Ревью кода + фича в блокноте — по моему мнению, самый адекватный формат. Вы де��аете то, что делаете каждый день: смотрите чужой код и пишете свой. Мелкие помарки прощаются, можно писать на псевдокоде.
Реальный проект в IDE — самый хардкорный вариант. Нужно написать работающее решение, которое запустится. Обычно занимает от 90 минут. Хорошая новость: часто разрешают подготовить скелет проекта заранее.
Leetcode остаётся самым популярным форматом, поэтому сфокусируемся на нём.
Мифы и реальность
Миф #1: Нужно решать hard и крутить красно-чёрное дерево во сне
Реальность: Это было правдой лет 5-7 назад. Сейчас индустрия осознала, что умение решать hard-задачки ничего не говорит о том, какой вы в повседневной работе, архитектуре и коммуникации.
Я наблюдаю демократизацию процесса: акцент смещается на easy/medium задачи и на умение кандидата коммуницировать. За все мои интервью (2021-2025) мне ни разу не попалась задача на динамическое программирование — то самое «демоническое», которым всех пугают.
Миф #2: Результат бинарный — решил или провалил
Реальность: Совсем не бинарно. У задачи почти всегда несколько решений. Brute force очевиден, и важно его озвучить. Оптимальное решение — это хорошо, но не обязательно.
На том самом интервью в Google я не дошёл до оптимального решения. Но я правильно коммуницировал, показал ход мыслей, и этого оказалось достаточно.
Миф #3: Главное — знать алгоритм
Реальность: Знание алгоритма — лишь одна часть, и я бы не сказал, что самая важная. Вы можете не знать оптимального решения в начале — это нормально. Важен процесс: как вы думаете, как общаетесь, как реагируете на подсказки.
Интервьюер почти всегда будет вам помогать. Слушайте его! Подсказки обычно достаточно жирные.
Миф #4: На разных уровнях разные требования к кодинг-интервью
Реальность: Это правда — требования разные. На junior/middle кодинг — ваша главная секция, и спрашивать будут серьёзно. На senior/staff/principal это скорее проверка, что вы ещё помните, как программировать. Там важнее system design и behavioral.
Подготовка
Ресурсы
Я перелопатил много материалов за годы подготовки. Большинство либо устарели, либо содержат много лишнего типа логических задач «сколько крышек люка в городе».
На 2026 год мой главный совет — Leetcode Premium. Да, это стоит денег, но это разумная инвестиция. Там есть:
Структурированные курсы по темам
Задачи, отсортированные по компаниям
Качественные решения с объяснениями
Начать можно с базового курса. Дальше — раздел Learn для углубления в конкретные темы и раздел Interview для подготовки к конкретным компаниям.
Для быстрого повторения алгоритмов использовал документ с обнадёживающим названием "I'll sleep when I'm dead".
Моки — ключ ко всему
А теперь самое важное: моки. Mock-интервью. Как только освоите базу — сразу приступайте к ним. Просите знакомых, находите партнёров в интернете, используйте специальные платформы.
Пока не проведёте хотя бы 10 моков — не тратьте время на настоящие интервью.
Почему это так важно? На моках вы ��олучаете реальную симуляцию: стресс, ограниченное время (15-30 минут), необходимость думать вслух. Это совсем другой опыт, чем решать задачки в одиночестве.
Ритуал решения задачи
Это, пожалуй, самая важная часть статьи. Правильный ритуал — это то, что отличает успешное прохождение от провала.
Шаг A: Выслушайте и уточните
Выслушайте интервьюера до конца, не перебивайте. Затем задайте уточняющие вопросы. Даже если вам всё кажется понятным — уточните corner cases:
Какой максимальный и минимальный размер массива?
Какие максимальные и минимальные значения элементов?
Могут ли быть отрицательные числа?
Отсортированы ли данные?
Какая максимальная длина строки?
Могут ли быть дубликаты?
Эти вопросы показывают, что вы думаете как инженер, а не просто кодер.
Шаг B: Покажите brute force
Проговорите и покажите очевидное решение. Именно покажите — не просто скажите словами.
Посчитайте сложность по времени и памяти. Спросите интервьюера: «Всё ли понятно? Согласны с решением?»
Шаг C: Обсудите оптимизацию
Для задач уровня medium и выше обычно есть более оптимальное решение. Обсудите с интервьюером — хотите ли вы искать его сейчас или сначала реализовать brute force.
Если не знаете оптимального решения — не паникуйте. Интервьюер будет подсказывать. Но даже если так и не придёте к оптимуму — можно реализовать brute force. Это лучше, чем ничего.
Шаг D: Имплементация
Спросите: «Могу приступать к коду?» Получив добро, начинайте писать.
Проговаривайте то, что делаете. Буквально: «Создаю массив для результата. Завожу переменную для суммы. Итерируюсь по входному массиву...» Что вижу — то и говорю.
Называйте переменные по-человечески. Не a, b, i, а currentSum, leftPointer, resultList.
Если где-то код получается не идеальным (а под стрессом это нормально) — оставьте комментарий: // TODO: refactor later. Это показывает, что вы понимаете, где можно улучшить.
fun calcSum(input: List<Int>): Int {
// TODO: handle empty input
var sum = 0
for (elem in input) {
sum += elem
}
return sum
}
Шаг E: Дебаггинг
Этим этапом очень любят пренебрегать. А он критически важен.
Дебаггинг — это не «пробежаться глазами по коду». Это написание комментариев с промежуточными значениями на каждом шаге.
Подробнее об этом — в разделе лайфхаков ниже.
Лайфхаки и визуализация
Как объяснять алгоритм без кода
Когда я начинал готовиться, меня ставило в тупик: как объяснить работу алгоритма, не написав код? На словах получается путано, особенно если оба не носители языка.
Решение: объясняйте письменно, прямо на структурах данных.
Работа с массивами
Используйте индексы и указатели в виде !:
[2, 4, 6, 8, -1, 3]
[0, 1, 2, 3, 4, 5]
!
Для двух указателей (sliding window):
[2, 4, 6, 8, -1, 3]
[0, 1, 2, 3, 4, 5]
!
!
При объяснении просто двигайте указатели и показывайте каждый шаг. Прописывайте переменные:
sum = 1
tempSum = 5
Работа с деревьями
Рисуйте дерево наглядно:
6
2 8
1 3 7 9
Используйте ! как указатель текущей позиции и * как пометку обработанного узла:
!6
*2 8
*1 !3 7 9
Здесь видно: начали с корня (6), пошли влево (2), ещё левее (1), обработали 1, обработали 2, сейчас в правом потомке двойки — это 3.
Визуализация рекурсии
[1, 2]
!
[4, 5, 6]
!
[7, 8, 9]
!
Каждая строка — уровень рекурсии. Указатель показывает, где находимся.
Дебаггинг в коде
Вот пример кода:
fun calcSum(input: List<Int>): Int {
var sum = 0
var threshold = 0
for (elem in input) {
if (elem >= threshold) {
sum += elem
threshold = sum / 2
}
}
return sum
}
Допустим, input = [1, 3, 5, 7, -1, 2, 9].
Дебаггинг выглядит так — для каждого шага прямо в коде пишем значения:
// input: [1, 3, 5, 7, -1, 2, 9]
// !
fun calcSum(input: List<Int>): Int {
var sum = 0 // 0
var threshold = 0 // 0
for (elem in input) { // elem = 1
if (elem >= threshold) { // 1 >= 0? true
sum += elem // sum = 1
threshold = sum / 2 // threshold = 0
}
}
return sum
}
Переходим ко второму элементу:
// input: [1, 3, 5, 7, -1, 2, 9]
// !
fun calcSum(input: List<Int>): Int {
var sum = 0 // 1
var threshold = 0 // 0
for (elem in input) { // elem = 3
if (elem >= threshold) { // 3 >= 0? true
sum += elem // sum = 4
threshold = sum / 2 // threshold = 2
}
}
return sum
}
И так далее. Это наглядно для интервьюера и помогает вам отловить ошибки.
Вспомогательные функции
Иногда решения получаются объёмными — 100-200 строк вместо 20-30. Используйте вспомогательные функции, которые реализуете потом:
fun someSolution() {
// основная логика
val diff = calculateDiff()
// продолжение логики
}
private fun calculateDiff() {
// will be implemented later
}
Это позволяет не отвлекаться от главного алгоритма и быстрее показать общую кар��ину.
Правило одной строки
Одна строчка — одно действие. Это упрощает дебаггинг и чтение кода. Не пишите:
if (a > b && c < d || e == f) return doSomething(x, y, z).also { process(it) }
Разбивайте на понятные шаги.
Corner cases в конце
Сначала реализуйте общее решение, потом добавьте обработку corner cases:
fun calcSum(input: List<Int>): Int {
// TODO: handle corner cases (empty input, single element)
// основная логика
...
}
Преимущества и недостатки Leetcode-формата
Давайте честно.
Для кандидата преимуществ почти нет. Кроме того факта, что эти задачки помогут найти работу. Знание алгоритмов редко пригождается в повседневной работе. Структуры данных и сложность операций вы и так должны знать — это база. А вот время на подготовку уходит прилично.
Для интервьюера преимуществ много:
Интервью укладывается в 30 минут
Кода немного, легко оценить
Чеклист понятный
При желании можно завалить любого кандидата hard-задачей (так никто не делает, но возможность есть)
Несмотря на спорность формата, он остаётся самым популярным. Но ситуация улучшается: акцент смещается с «решил/не решил» на коммуникацию и процесс мышления.
Заключение
Подытожим главное:
Мифы устарели. Hard-задачи и экзотические алгоритмы уже не так важны. Коммуникация важнее знания оптимального решения.
Моки обязательны. Минимум 10 штук перед реальными интервью.
Ритуал решает. Уточняющие вопросы → brute force → обсуждение → имплементация с проговариванием → дебаггинг.
Визуализируйте. Показывайте работу алгоритма на структурах данных, не объясняйте только словами.
Дебажьте в коде. Пишите промежуточные значения прямо в комментариях.
Эти правила помогли мне пройти все кодинг-интервью за последние 4 года. Надеюсь, помогут и вам.
Всем бобра и успешных собесов! 🦫
Пишите в комментариях свой опыт и вопросы. Какие мифы о Leetcode слышали вы?
Больше про интервью, мобильную разработку, стартапы и жизнь инженера за рубежом — в моём телеграм-канале: t.me/matsiuk_speak
