Привет, Хабр!

Cегодня поговорим, наверное, о самом серьезном этапе собеседования — live‑coding. На этом этапе вас просят писать код в реальном времени, под пристальным взглядом интервьюера.

На этом этапе выясняется, умеет ли кандидат решать задачи и писать код под реальными ограничениями времени и стресса.

Подготовка

Первое, что стоит сделать, узнав о предстоящем лайвкодинге, взять себя в руки и подготовить почву. Хорошая новость в том, что подготовка очень сильно снижает уровень паники.

Начнем с технической стороны.

Убедитесь, что вы уверенно чувствуете себя в выбранном языке программирования. Для Python, например, необходимо знать базовые вещи: типы данных, управляющие конструкции, функции, работу со структурами данных вроде списков и словарей, основные алгоритмы поиска и сортировки. Никаких сверхъестественных навыков от вас не требуют, достаточной прочной базы. И без этой базы можно растеряться даже в элементарном задании. Например, вас могут попросить перевернуть строку или найти второе максимальное число в списке, и желательно решить без встроенных функций вроде sorted. Если вы никогда не пробовали обходиться без готовых методов, велика вероятность зависнуть с открытым ртом. Так что повторяем основы: как реализовать цикл, как работать с массивами и словарями вручную, как писать простейшие алгоритмы.

Второй момент в подготовки в том, чтобы пробежаться по типовым задачам. Здесь на помощь приходят платформы вроде LeetCode, Codewars и им подобные. Заучивать решения задач бессмысленно. Задача в другом: набить руку в подходах к решению.

Решая разные задачи с ограничением по времени, вы учитесь разбивать проблему на шаги и кодировать их по очереди. Потренируйтесь решать задачки уровня простого и среднего — от классических физ база и поиска простых чисел до операций со строками и сортировками. Прочитали условие, задали уточняющие вопросы, прикинули решение, написал коди и протестировали. Такой цикл должен стать привычным.

Конечно, важно подготовиться и морально. Если есть возможность, попробуйте своеобразную репетицию, договоритесь с товарищем провести вам тестовое интервью с лайвкодингом. Или хотя бы запишите себя на видео во время решения задачи на время. Потом посмотрите: где запнулись, где зависли, где начинали бубнить что‑то неразборчивое. Это немного болезненно, зато предельно полезно.

Отдельно стоит сказать про рабочее окружение. Узнайте заранее, что за формат лайвкодинга вас ждет. Варианты сейчас разные, некоторые дают онлайн‑редактор или площадку вроде HackerRank, другие просят просто шарить экран в вашем IDE, а то и вовсе устраивают парное программирование через VS Code Live Share. Закройте лишние вкладки, уберите на время собеса всплывающие уведомления. Если будете кодить в своем IDE, настройте шрифт покрупнее, интервьюер тоже будет смотреть на экран, пусть ему не придется щуриться.

Не спеши писать код

Итак, день Х настал, вы подключаетесь к звонку, здороваетесь с интервьюером. Вам выдали условие задачи. Что дальше? Первое желание неопытного кандидата в том, чтобы сразу броситься кодить, лишь бы тишина в эфире не затянулась.

Возьмите паузу на обдумывание задачи.

Собеседник обычно ожидает, что вы сначала уточните требования и продемонстрируете понимание. Поэтому не стесняйтесь задать пару вопросов по условию, если там что‑то неясно или двусмысленно. Например, задача: «Найти все перестановки строки». Уточните, а надо вывести их в любом порядке или в лексикографическом? А как насчет повторяющихся символов, считать перестановки уникальными или нет? Такие вопросы покажут, что вы мыслите системно и порядочно. Часто условия нарочно оставляют чуть размытыми, чтобы проверить, будете ли вы их прояснять. Если ограничения (по времени, памяти, размеру входных данных) явно не указаны, спросите о них. От этого зависит выбор решения. Например, для массива из 100 миллионов элементов подход к решению будет другим, чем для массива из 100 элементов.

Получив ответы на вопросы, сформулируйте вслух план решения. Это может быть буквально пара предложений: для начала хочу пробежаться по массиву и посчитать частоты элементов, потом пройтись снова и найти первый уникальный элемент. Такое проговаривание подтверждает интервьюеру, ��то вы правильно поняли задачу, а еще и дает адекватный план действий. Бывает, кандидат молча думает, думает, проходит 5 минут тишины, и интервьюер начинает переживать, все ли в порядке. Не молчите! Если требуется время на обдумывание, ок, скажите вслух: я прикидываю разные варианты решения, нужно еще минутку. Это лучше, чем полная тишина.

Когда план ясен, можно переходить к самому коду. Но и тут не нужно гнать лошадей.

Начните с простого, рабочего решения, даже если оно не оптимальное. Многие задачки на собеседовании легко решаются просто в лоб. У оптимального, сверхэффективного решения часто больше шансов быть реализованным с проблемками, чем у прямолинейного. Так что сначала пишем код, который просто делает, чт�� надо, а уже если останется время можно его подчистить, улучшить, убрать дублирование, мелкие косяки. Интервьюеры обычно нормально относятся к такому подходу. Более того, они предпочитают увидеть живой процесс улучшения кода, чем когда кандидат сразу выпаливает заученное решение.

Представим, что задача сформулирована так:

«Напишите функцию, объединяющую два отсортированных списка чисел в один отсортированный список».

Казалось бы, ничего хитрого, можно взять и слить списки, а потом вызвать стандартную сортировку. Код получится буквально в пару строк:

def merge_sorted_naive(arr1, arr2):
    return sorted(arr1 + arr2)

В большинстве случаев работает. Сложность такого решения будет O((n+m) * log(n+m)) из‑за вызова сортировки. Но ведь нам явно сказали, что на вход подаются уже отсортированные списки! Скорее всего, ожидается, что мы воспользуемся этим знанием и напишем более эффективное решение. Зачем тратить O(n log n) на сортировку, если можно обойтись линейным временем? Приходит мысль о двух указателях, двигающихся по каждому списку. Реализуем слияние двумя указателями:

def merge_sorted(arr1, arr2):
    i = j = 0
    result = []
    # Пока в обоих списках есть элементы, выбираем меньший и добавляем его
    while i < len(arr1) and j < len(arr2):
        if arr1[i] < arr2[j]:
            result.append(arr1[i])
            i += 1
        else:
            result.append(arr2[j])
            j += 1
    # Один из списков закончился, добавляем остатки другого (они уже отсортированы)
    result.extend(arr1[i:])
    result.extend(arr2[j:])
    return result

# Пример использования:
print(merge_sorted([1,3,5,7], [2,2,6]))  # [1, 2, 2, 3, 5, 6, 7]

Решение потребует O(n+m) времени и памяти, что значительно лучше для больших объемов данных. Главное в том, что мы воспользовались подсказкой из условия: входные данные были отсортированы, значит, можно избежать лишней сложности.

Когда код готов, обязательно протестируйте его на паре примеров, если есть такая возможность.

После первого прогона и беглого теста настало время подумать об оптимизации и рефакторинге. Мы уже обсудили оптимизацию алгоритма, но есть и другие нюансы. Посмотрите на свой код свежим взглядом, все ли названия переменных понятны? нет ли лишних повторений? Возможно, какие‑то кусочки стоит вынести в отдельную функцию (если это не усложнит чтение). Но помните правило: рефакторинг не должен менять сложность алгоритма в худшую сторону. Если очень красивое решение внезапно стало работать медленнее, то это уже не наведение порядка, а шаг назад.

Ошибки новичков (и как их не допустить)

Ошибаться — человечески. Тем более в стрессовой обстановке собеседования. Давайте пройдемся по ряду промахов, которые чаще всего случаются на лайвкодинге у новичков, и подумаем, как их избежать.

Ошибка 1: игнорировать свойства входных данных. Мы уже привели пример с отсортированными массивами. Это частный случай общей проблемы, кандидат не использует подсказки в условии и решает задачу самым прямолинейным способом, хотя можно лучше. Бывает, задача специально сформулирована так, что в ней скрыт более простой путь. Классический пример: «дан отсортированный список, найдите…», сразу думайте о двоичном поиске или двух указателях. Или: «строка длиной N, содержащая только цифры от 0 до 1», ага, значит, можно вместо тяжеловесных структур обойтись простым счетчиком, поскольку диапазон значений ограничен. Совет: прежде чем кодить, выпишите себе на черновике свойства входных данных (отсортированы ли, уникальны ли элементы, диапазоны значений, особые случаи типа пустого ввода) и держите их в уме. Это убережет от решений, которые работают, но не используют всех возможностей задачи.

Ошибка 2: скрытая дорогостоящая операция. Вы можете быть уверены, что у вас алгоритм O(n), а на деле он тихонько превращается в квадратичный. Например, собираетесь вы пройтись циклом по списку, O(n), казалось бы. А внутри цикла вызываете метод, который сам за линейное время работает. В итоге общий порядок уже O(n^2), хоть вложенных циклов в коде и нет.

Допустим, нужно найти пересечение двух списков. Пишут: for x in list1: if x in list2: result.append(x). На маленьких массивах сработает, а на больших привет, квадратичная сложность, потому что x in list2 скрытая дорогостоящая операция.

Узнав о задаче, сразу оценивайте, какие объемы данных могут быть и какая сложность считается приемлемой. Интервьюер обычно подсказывает, сколько примерно есть времени на решение. Если, скажем, дали только 10 минут, значит, скорее всего, ожидается решение порядка O(n). Если времени полчаса или больше, возможно, задача потребует более сложного алгоритма, или состоит из нескольких этапов. Отталкивайтесь от этого. В примере с пересечением списков оптимальным был бы вариант перевести один список во множество (операция O(n)), а затем одним циклом проверять вхождение в это множество (операция O(1) в среднем). Код улучшенного решения:

def has_common_element(list1, list2):
    set2 = set(list2)
    for x in list1:
        if x in set2:
            return True
    return False

# Пример:
print(has_common_element([1, 2, 3], [5, 3, 9]))  # True

Теперь вместо O(n*m) мы получили O(n + m) за счет использования set. Будьте внимательны с встроенными функциями и операторами, думайте, что происходит под капотом. len(list) в Python O(1), а вот проверка x in list уже O(n), имейте в виду.

Ошибка 3: суета. В таком состоянии очень легко наделать глупостей, забыть элементарный синтаксис, начать метаться между двумя подходами и ни один не довести до конца, пропустить очевидный баг. Но интервьюер тоже человек. Ему гораздо приятнее видеть уверенного, пусть и медлительного разработчика, чем гениального, но дерганного. Поэтому задача номер один в том, чтобы успокоиться и сохранять ясность ума.

Вы не обязаны быть идеальным. Если уж совсем ничего не идет, скажите честно, что вы слегка заволновались. Большинство интервьюеров нормально реагируют на такое откровение, это лучше, чем молчать.

Кстати, о словах. Если чувствуете, что происходит какой‑то диалог, реагируйте. Часто интервьюеры подсказывают или направляют обсуждением.

Ошибка 4: плохое управление временем. Следите за часами, не до секунд, но чтобы понимать, когда нужно ускориться. Если видите, что застряли на каком‑то шаге, а время уходит, озвучьте это.

Ошибка 5: игнорирование крайних случаев. Допустим, вы быстро выдали решение для среднего сценария, когда входные данные более‑менее нормальные. Но стоит задать пустой массив или отрицательное число вместо положительного, всё ломается. Еще на этапе планирования полезно перечислить крайние случаи: пустой ввод, минимальные/максимальные значения параметров, повторяющиеся данные, невалидные данные.

Ошибка 6: плохой стиль кода. В первую очередь оценивают ваше мышление и умение решить задачу. Но и код читают! Если он как лапшичка, с переменными a, b, c и кучей магических чисел, осадочек останется. Конечно, на чистоту кода у вас мало времени, и красоту типичного проекта от вас не ждут. Однако следить за базовым порядком нужно, отступы, скобочки, читаемые имена переменных, никаких безумных однострочников, которые вы сами не поймете. Лучше написать явно и просто, чем выпендриться и утонуть в своей же гениальности.

Заключение

Live‑coding тот еще челлендж, спору нет. Но при правильном подходе оно перестает быть непосильным испытанием.

Не бойтесь просить обратную связь! Если вам отказали после лайвкодинга, вежливо спросите что‑же там пошло не так. Эти сведения бесценны для роста.

Удачи вам на собеседованиях!


Секция с кодом захватила Ru Big Tech

OTUS совместно с экспертами платформы algocode проведёт открытый онлайн-урок, посвящённый прохождению секцию лайвкодинг задач на собеседованиях.

Дата и время: 29 ноября в 12:00 (МСК)
Формат: онлайн
Спикер: Даниил — Team Lead в крупной технологической компании, имеет более 5 лет опыта и провёл свыше 50 технических собеседований.

В рамках этой секции необходимо показать:

- Знание языка программирования
- Понимание computer science
- Умение быстро погружаться в лайвкодинг задачу
- Написать рабочее решение у базовой версии
- Сделать усложнение (часто связано с конкурентностью)
- А еще нужно не облажаться с computer science вопросами

Темы урока:

  • В чем особенности секции у Яндекс, Авито, Т-Банк, Ламода и других

  • Какие темы стоит подтянуть

  • Разберем примеры вопросов и правильные ответы

    Но и это не все: прямо на уроке спикер разберет пошаговое решение реальных лайвкодинг задач.

Подробности доступны на странице урока.

Справочная информация:
Материалы algocode включены в программу курса OTUS «Golang Developer. Professional».

Комментарии (1)


  1. AdrianoVisoccini
    24.11.2025 14:42

    Мой лайфхак для лайвкодинга - если задачу или условия диктуют(что часто бывает) я открываю комментарий в коде и пишу задачу туда. По отзывам собеседующих для них это выглядит как большой гринфлаг, мол догадался записать и потом сверялся с задачей. 99% людей этого не делают, держат условие в голове, забывают, переспрашивают или в середине решения начинают делать не то
    Не знаю на сколько это правда влияет, но по моему идя как минимум норм