Поговорим про собеседования: взгляд бэкендера

в 8:36, , рубрики: алгоритмы и структуры данных, Блог компании Яндекс, интервью с разработчиками, собеседование в IT, собеседования
Меня зовут Максим Бабенко, и, может быть, вы знаете меня как преподавателя ШАДа (или как автора рассказа про технологию YT на Хабре).

Мне кажется, почти каждый читатель Хабра либо знаком с теми, кто побывал на собеседовании в Яндекс, либо сам его проходил. Несмотря на это, процесс интервью не всегда очевиден для людей извне, по-прежнему вызывает множество вопросов и окружён мифами. Некоторые из них близки к правде, другие — наоборот.

В Яндексе я работаю уже больше 12 лет и повидал все наши изменения процесса собеседования. Сегодня я расскажу о наших интервью, попробую разобрать самые популярные мифы и объяснить, чем они обусловлены.

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


В мире IT довольно много спорных вопросов: С++ против Java, табы против пробелов и т. д. В обсуждениях, как именно должны быть организованы интервью разработчиков, тоже сломано немало копий. Сейчас у большинства крупных IT-компаний похожие процессы интервью, но не потому, что проще копировать друг друга, а потому что мы работаем в похожих условиях и наши процессы эволюционировали схожим образом.

Лет десять назад в Яндексе не было единого стандарта собеседований, каждая команда могла проводить их по-своему. Где-то устраивали не ограниченную по времени и формату серию интервью. В других местах уже на первой встрече могли дать ноутбук, попросить написать на нём код, и, если код работал, сразу нанять человека. Кажется, абсолютным рекордом был случай, когда разработчика наняли уже через 40 минут после начала встречи. Но были и антирекорды. Например, один из наших коллег решал в офисе одну задачу 8 часов подряд!

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

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

Каждая секция — это независимое мини-интервью на заданную тему в формате один на один и длительностью обычно в 1 час. По его результатам интервьюер описывает в специальном тикете, что он спросил, что ответил кандидат, как всё прошло, и ставит свою оценку —на какой примерно уровень нанимать этого кандидата или не нанимать совсем. Общаться друг с другом интервьюеры могут только тогда, когда они завершили секцию, иначе секции не будут независимыми. Когда последний интервьюер опишет свою секцию, «карты вскрываются» — все интервьюеры получают email с результатами всех участников процесса. Чтобы получить оффер от Яндекса, кандидату не обязательно пройти все секции: одну или несколько можно и провалить. Независимость секций позволяет нам увидеть человека в разных условиях и с точек зрения разных людей. Иначе велик шанс, что «самый громкий» из тех, кто видел или знает кандидата, переспорит коллег. В случае, когда кандидат показывает противоречивые результаты, мы можем добавить секции, чтобы выяснить, является ли это закономерностью или невезением. В ряде случаев это помогает получить оффер тем, кто в прежних условиях получил бы отказ.

Если кандидат успешно справляется с основной частью секций, то дальше нужно определиться с командой. Этим Яндекс и отличается от небольших компаний: у нас для разработчика может найтись сразу несколько подходящих мест. К этому моменту уже понятно, на какой уровень мы готовы сделать человеку предложение. Если кандидатом заинтересовалась только одна команда, то всё просто. Но за хороших кандидатов возникают целые внутренние баталии, таким кандидатам хотят предложить себя сразу много команд. Мы назначаем кандидату финальные секции с заинтересовавшимися командами, чтобы он мог выбрать те задачи, которые ему более интересны. Суть финалов ровно в этом — показать спектр задач и дать возможность выбрать то место, где кандидату будет интереснее всего. Понятно, что человеку со стороны порой трудно определиться с командой после устного разговора, поэтому мы развиваем и альтернативный формат — Буткемп. Это возможность поработать сразу в нескольких командах, попробовать разные задачи на практике, а затем уже определиться. На наших текущих масштабах в десятки тысяч (!) собеседований в год и наших задачах этот процесс работает эффективнее, чем тот, что был раньше.

Снаружи это не заметно, но внутри вокруг каждого изменения процесса идут жаркие споры. Например, недавно для бэкенд-разработчиков мы начали сокращать количество технических интервью с проверкой кода. Сделали это не умозрительно, а на основе собранной статистики по тысячам пройденных собеседований. Логика такая: если очередная встреча в среднем мало влияет на оценку кандидата, то такая встреча не особо нужна, это время лучше посвятить рассказу о задачах и проектах команды.

Мы стремимся объяснять кандидатам, почему нужна та или иная секция. Например, показываем статьи на Хабре про алгоритмическую секцию, на которые я ещё буду ссылаться ниже. Оценить, хорошо ли мы справляемся именно с этим информированием, здорово помогают отзывы кандидатов, мы запрашиваем их после собеседований. Не игнорируйте их, пожалуйста.

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

Миф 1: Яндекс игнорирует предыдущий опыт кандидатов

Я разработчик с многолетним опытом использования технологии X и указал ее в своем резюме. Но прошло уже два собеседования, а про X меня ничего не спросили. Получается, весь мой предыдущий опыт работы не имеет никакой ценности? Опытные разработчики оказываются в одних рядах с недавними выпускниками, которые ничего серьезного еще и сделать не успели?

Короткий ответ: это не так, но есть нюансы. Часть подобных знаний может оказаться востребованной в Яндексе напрямую. Скажем, если в выбранной области специализации существует небольшое количество де-факто стандартных библиотек или фреймворков, которые хорошо масштабируются и находят свое применение в Яндексе, то высока вероятность, что в выбранной команде вы встретите знакомые вам инструменты и, более того, — их знание окажется ожидаемым.

С бэкенд-разработкой всё сложнее и интереснее. Существенная часть бэкенда Яндекса написана и пишется на C++, в первую очередь, в тех проектах, которые предполагают низкоуровневую работу с данными. Для понимания масштаба: объемы хранимых Яндексом данных превышают Eb, а их обработка выполняется с использованием миллионов CPU-ядер одномоментно.

На таких масштабах даже экономия в 1% является значительной. Как и многие другие крупнейшие компании, Яндекс инвестирует значительные ресурсы разработки в построение эффективной собственной инфраструктуры, и здесь выбор C++ по-прежнему остается оптимальным. При этом из готовых и популярных фреймворков на ум приходит разве что стандартная библиотека языка. Ее мы активно используем, но если примитивы, предлагаемые стандартной библиотекой, для наших задач оказываются субоптимальны − создаем свои и не спрашиваем на собеседовании про другие. Таким образом, у C++-разработчиков могло сложиться впечатление, будто их опыт нам не интересен, — и именно поэтому я начал разбирать этот миф с языка С++.

В случае с Java или, например, с Go ситуация чуть иная: эти платформы обычно используются уже на более высоких уровнях инфраструктурного стека, и для них существует множество хорошо зарекомендовавших себя надежных фреймворков, способных держать высокие нагрузки и масштабироваться при необходимости. Некоторые из подобных фреймворков активно используются в Яндексе, и в случае прохождения финалов руководители и члены команды наверняка не откажутся обсудить специфику задач и выбранный технологический стек.

Одновременно важно отметить, что, скажем, от бэкенд-разработчика на С++ или Java мы ожидаем высокой степени гибкости: для него архитектурные вопросы (высоконагруженные системы, масштабирование, отказоустойчивость и т. д.), как правило, оказываются намного важнее и труднее, чем специфика использования конкретных языков и библиотек.

В частности, хороший специалист по бэкенду без труда сможет принять участие как в проекте, где используется C++, так и в том, где основной язык — Java (Scala, Kotlin и т. д.). Более того, не редки случаи, когда в одном проекте сочетаются сразу нативные и управляемые среды, что тем более подталкивает к идее абстрагироваться от языка при найме кандидатов.

Поэтому если вам кажется, что мы не спрашиваем у вас про ваши самые сильные стороны (а мы и правда не всегда на них концентрируемся) — скорее всего, мы просто сразу стараемся оценить, как эти сильные стороны будут вам помогать именно в контексте Яндекса (а вот на это мы смотрим постоянно).

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

Миф 2: В обычной работе знание алгоритмов не нужно

Все готовые примитивы уже давным-давно написаны и оптимизированы: достаточно позвать нужные функции в нужном порядке, и задача решена.

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

Действительно, бывают оптимизации, влияние которых на работу сервиса слишком мизерное, или они внедрены преждевременно. Казалось бы, нет смысла глубоко понимать алгоритмы, благодаря которым такие оптимизации возможны. Но даже противники подобных малополезных оптимизаций признают: чтобы отличать их от эффективных решений, тоже нужны базовые знания алгоритмов и структур данных. Бороться с избыточным применением алгоритмов можно — зная алгоритмы.

Конечно, понимать специфику предметной области (может ли параметр N вырасти в 100 раз за ближайший год?) тоже необходимо. НоИ если последнее лучше всего получить, непосредственно работая в проекте, наблюдая его текущее состояние и стратегические планы развития, то знания об алгоритмах и их сложности абсолютно универсальны, а потому подобные навыки у кандидата разумно ожидать уже на входе.

Рекомендую прочитать пост Алексея Шаграева ashagraev, в котором он на реальных продуктах показал необходимость знания алгоритмов.

Миф 3: Мы напрасно проверяем не то, чем предстоит заниматься

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

Хороший, сложный вопрос, ответ на который полезно явно проговорить. Яндекс − большая и разнородная компания. Тем не менее, от меня и моих коллег ожидается достаточная степень умственной и проектной мобильности. Иными словами, мы практически не нанимаем «специалистов по фреймворку X» исключительно за то, что они знают этот фреймворк. Время идет, фреймворки меняются, отчасти как дань моде, отчасти потому что появляются новые, более совершенные.

Мы делаем ставку на то, что наш новый коллега проработает с нами долго. С прицелом на это строится наша система внутренней ротации, а также схема вознаграждений, стимулирующая оставаться в компании, принося пользу в самых разных ее частях и переключаясь по мере развития с проекта на проект. Если вам захочется перейти в другую команду, попробовать новое или даже сменить предметную область, мы должны максимально облегчить вам этот путь.

Поэтому нам важно держать общую и достаточно высокую планку, которая бы позволила упростить для разработчика формальности переходов внутри Яндекса.

Миф 4: На интервью условия совершенно не похожи на рабочие

Набирать код на секциях в простом текстовом редакторе без автодополнения неудобно, кроме того я не помню наизусть имена функций и классов стандартной библиотеки. Зачем просить разработчика выполнять задания в условиях, совершенно не похожих на реальные?

Признаюсь, это не миф, это правда. Сейчас я попробую раскрыть нашу логику. Уверен, с ней согласятся не все. Это нормально: подобные споры ведутся не только снаружи, но и внутри. В любом случае, диалог — это хорошо.

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

Возвращаясь в более знакомую плоскость, мне кажется очевидным, что любой разработчик должен уметь писать код, находящий максимум чисел в массиве линейным поиском. С закрытыми глазами и не обращаясь при этом к помощи stackoverflow. Одновременно странно ожидать от кандидатов умения безошибочно и, что называется, на автомате писать код быстрого преобразования Фурье (хотя, конечно, многие бывшие олимпиадники снисходительно улыбнутся, услышав это, поскольку не посчитают алгоритм FFT сколь-нибудь сложным). Иными словами, существует некоторый минимальный порог практических навыков написания кода, и спор на самом деле идёт о том, где в точности этот порог должен проходить.

Важно: в Яндексе подобная секция никак не привязана к конкретному языку или к его библиотекам. Фактически решения задач с этой секции выглядит примерно одинаково на любом распространенном языке и занимает 10-20 строк кода. На секции мы всегда предлагаем кандидату самостоятельно выбрать тот язык, на котором у него больше всего опыта. При этом мы действительно ожидаем, что в выбранном языке у кандидата достаточная «беглость» (fluency), чтобы писать на нем простейшие конструкции, не задумываясь.

Но даже если вы, скажем, забыли, как именно называется метод, добавляющий элементы в очередь (push, enqueue или, может, add), то это не сыграет большой роли — интервьюер либо подскажет вам, либо просто предложит назвать метод так, как вам будет понятнее, ведь суть решения от этого не меняется.

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

Подобная языковая нейтральность и базовый характер задач — это факторы, которые, по нашему мнению, добавляют объективности и универсальности секции. Вместо того, чтобы искать для каждого кандидата со знаниями в области X равного ему по силам специалиста в этой области, чтобы тот смог дать состоятельную оценку, мы поступаем иначе. С моей точки зрения, алгоритмы − это фактически lingua franca современной IT-индустрии. Решение алгоритмических задач под силу абсолютно любому разработчику, а оценка качества их решения достаточна проста, чтобы из секций можно было извлечь ясный и однозначный сигнал.

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

Примеры и более полное описание алгоритмических секций вы можете найти в отдельном посте на Хабре.

Миф 5: Вам, похоже, нужны только программисты-олимпиадники

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

Собеседования в Яндекс, конечно, не ограничиваются секциями подобного вида. Еще при первой встрече мы стараемся выяснить у потенциального кандидата, с какими задачами он сталкивался в своих предыдущих проектах, что его интересует, как он видит дальнейшее свое развитие в профессиональном плане.

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

Для опытных кандидатов также проводятся специализированные секции (по архитектуре, распределенным системам, базам данных, машинному обучению, сетевым технологиям и т. п.).

Наконец, после прохождения технических секций кандидату ставят несколько «финалов», где присутствуют руководители, непосредственно ищущие к себе в команду новых сотрудников. Сами финалы не предполагают решение базовых алгоритмических задач, ведь руководитель команды уже уверен в способностях кандидата. Для кандидата финал − это возможность познакомиться непосредственно с потенциальной командой, узнать о методологии работы, используемых инструментах, смежных командах, да и в целом о решаемых задачах из первых рук. Но финал − это всегда диалог. Для того, чтобы сделать правильный выбор среди кандидатов, потенциальный будущий руководитель наверняка захочет узнать подробнее о кандидате, включая его высокоуровневые навыки. Например, на подобной секции вам могут описать одну из типичных (реальных, жизненных!) задач или проблем, с которой в этой команде уже сталкивались.

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

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

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


В этой статье я описал то, как в общих чертах выглядит процесс собеседования в Яндекс и почему он эволюционировал именно в такую форму.

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

Автор: Максим Бабенко

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js