Бывает так: задачу вы решили, код рабочий. А интервьюер вежливо улыбается и говорит: «Не совсем понятно, как вы к этому пришли». В этот момент разговор, по сути, закончен.
Со мной это случилось на первом техническом собеседовании. Дали маркер и задачу в две строки: найти в массиве два числа, которые в сумме дают target, и вернуть их индексы. Я застрочил кодом — пусть решение говорит само за себя. Минут через десять поднял голову. Брови интервьюера приподняты, улыбка вежливая, комментарий короткий: «Не уверен, что понимаю, как вы пришли к такому ответу».
Алгоритм у меня был нормальный. Провалилось другое — я не показал, как думаю.
Что на самом деле оценивают
Собеседование по программированию — это не экзамен с одним правильным ответом. Смотрят на процесс: как вы уточняете условия, почему выбираете ту или иную структуру данных, что делаете, когда застряли. Если процесс целиком в голове, интервьюеру приходится его реконструировать. Восстанавливать чужую мысль по готовому коду — занятие неблагодарное, и там, где ясности нет, появляется сомнение.
Отсюда простой вывод: половину оценки вы получаете или теряете ещё до того, как напишете первую строку.
Скрипт из трёх проходов
Метод, который у меня в итоге сложился, звучит почти по-детски. Перед кодом вы проговариваете вслух три вещи, всегда в одном порядке.
- Пересказ задачи и ограничений. Своими словами. Это проверка, что вы услышали именно то, что спросили, а не то, что вам показалось. Заодно интервьюер видит: границы задачи вы держите в голове.
- Подход на верхнем уровне. Называете алгоритм или структуру и объясняете, почему именно они. Скажем, словарь для хранения уже встреченных чисел — потому что проверка существования занимает O(1), а два вложенных цикла дали бы O(n²).
- Код с проговариванием каждого шага. Каждая строка — с коротким «зачем». Вы поддерживаете инвариант вслух: «в seen лежат только числа, которые я уже прошёл».
Формулировки можно менять под себя, смысл не в заученных фразах. Вот каркас, который я использую:
«Сначала перескажу задачу, чтобы убедиться, что понял правильно: нужно…»
«План такой: делаю… потому что…»
«Начинаю писать. Держу словарь, в котором храню… по ходу перебора, чтобы проверять нужное значение за O(1)».
Третий пункт — самый тяжёлый. Именно тут хочется замолчать и уйти в код, потому что проговаривание замедляет. Замедление — не побочный эффект, а суть метода.
Молча и вслух: одна и та же задача
Вернёмся к задаче про два числа. Молчаливое решение: пустой словарь, цикл по массиву, на каждом шаге считаем complement = target минус текущий элемент, проверяем, есть ли он в словаре, если есть — возвращаем пару индексов, если нет — кладём текущее число в словарь. Всё верно, работает за один проход.
Но интервьюер видит только финал. Ему остаётся догадываться, почему словарь, а не вложенные циклы, учтены ли дубликаты, что вернётся, если пары не существует. Пустота в эфире приглашает задавать неудобные вопросы.
Теперь то же решение, но с голосом. «Перескажу задачу: нужны два разных индекса, сумма элементов по которым равна target, и хочется уложиться в линейное время. План — один проход и словарь уже встреченных пар значение-индекс, чтобы искать дополнение за константу. Завожу пустой словарь seen. Иду по списку через enumerate — мне нужны и значение, и его позиция. Для каждого числа считаю complement. Если он уже в seen — пара найдена, возвращаю два индекса. Иначе кладу текущее число в seen. Инвариант: в seen лежат только элементы, которые я уже просмотрел. Если цикл закончился без пары — по договорённости верну пустой список или брошу исключение».
Код тот же. Меняется другое: теперь видна логика, и интервьюер может поймать ошибку в момент, когда она появляется, а не после.
Ошибки, которые стоят оффера
| Ошибка | Что происходит | Как исправить |
|---|---|---|
| Сразу лезть в код | Интервьюер угадывает ваши намерения и может упустить недопонимание | Всегда начинать с пересказа задачи |
| Объяснять очевидное | Теряете время и звучите заученно | Одна фраза на шаг, акцент на «почему», а не на синтаксисе |
| Молча дебажить | Непонятно, как вы ищете причину сбоя | Проговаривать: «вижу X, это намекает на Y, проверю Z» |
| Слова-заполнители | Сбивают ритм и выдают неуверенность | Заменять «эээ» на короткую паузу |
Вторая строка таблицы — та, на которую наступают чаще всего. Нас учили показывать работу, а не объяснять её, поэтому тянет комментировать, что делает каждая скобка. Интервьюеру это не нужно. Ему нужно знать, почему выбран словарь и почему цикл один.
Когда проговаривать не надо
Метод из трёх проходов — для живого интервью. Take-home задание, письменный тест или парная сессия, где партнёр ждёт от вас тишины, разберутся без него. Но и там полезно оставить вслух хотя бы пересказ задачи — если есть кому слушать.
Как натренировать
Возьмите случайную задачу среднего уровня, поставьте таймер на пятнадцать минут и решите её вслух — с другом, с диктофоном, с плюшевой игрушкой, кому что ближе. Потом послушайте запись и проверьте две вещи.
- Прозвучал ли пересказ задачи, прежде чем вы начали писать?
- Было ли обоснование подхода до первой строки?
И отдельно — получила ли каждая строка кода своё короткое «зачем». Где провал, правьте скрипт и повторяйте. Проговаривание вслух ощущается неуклюже ровно до того момента, пока не станет привычкой; дальше вы просто говорите то, что и так думаете, только вслух.
Отдача, к слову, шире интервью. Умение объяснять ход решения пригодится в ревью, в разборе чужого баг-репорта и в разговоре с коллегой, который пришёл за советом. Интервьюер тут просто первый, кто это оценил.
Комментарии (1)
Войдите, чтобы комментировать.