Про техническое интервью
Прочитал замечательный пост Саши Маринича о оправдании задачек на интервью в Grammarly. Я безумно люблю эту компанию, но по тексту скорее несогласен.
И начать хочу с того, что инженеры часто недооценивают важность гуманитарных штук (говорю это как инженер, который недооценивал). И хайринг одна из таких вещей. К тому же всегда есть множество мифов и мало кто умеет готовить правильно. Но я отвлекся.
Нет ничего плохого в том чтобы спрашивать о алгоритмах и структурах данных. Есть разница в подходах. Например, для позиции инфраструктурного инженера знание каких-то определенных вещей намного естественнее, чем знание алгоритмов которые обязан знать фронтендер.
К примеру, любой инфраструктурный инженер поймёт что такое хэш таблица, как с ней обращаться и что из неё вытащить. Но задачку на связанный список вероятнее всего провалит. И провалит не потому что он плохой инженер, а потому что он с таким типом данных не сталкивается в реальной жизни и, вероятнее всего, не столкнется в рутинной работе. А если он запомнит его для того чтобы пройти интервью (потому что все спрашивают), то через пол года всё равно забудет от неиспользованная.
Также подобные тесты могут давать разные результаты для кандидатов с разным уровнем подготовки. Например, если спросить инфраструктурного инженера о стоимости операции, то он в первую очередь будет считать стоимость операции суммируя и умножая накладные расходы на запись в память, диск, память цпу и так далее, в то время как любой математик-алгоритмист остановится на вычислении Θ().
Стоит обратить внимание, что задачки типа “переверни список” (то есть сильно синтетические без привязки к реальному миру) пройдет любой третьекурсник прочитавший cracking the coding interview.
И получается, что если смотреть с определенного угла, то подобные вопросы могут дать разные ответы просто для разных групп инженеров и могут быть сфабрикованы.
Естественно, невозможно защититься на 100% от плохого (ну относительно) найма, но есть способы которые помогают уменьшить вероятность.
Обычно почти любую задачу подобного типа можно разбить на несколько шагов:
1. Что мы хотим в итоге? (сформулировать требования)
2. Как мы можем проверить удовлетворение требованием и придумать вопросы? (сформулировать гипотезу)
3. Хорошие инженеры могут ответить на вопросы? (проверить гипотезу на положительный результат)
4. Плохие инженеры не могут ответить на вопросы? (проверить гипотезу на отрицательный результат)
5. Нарабатывать и улучшать (строим обратную связь для корректикровки и меняем вопросы в зависимости от того работают они или нет)
В случае с собеседованиями мы хотим нанять человека который будет хорошо справляться с работой с которой уже справляются наши инженеры (Ну мы много чего хотим, я беру только одну штуку. Если вы хотите нанять несуществующую у вас экспертизу, то это отдельный разговор). Для этого можно попробовать вместо теоретизирования на тему “что должен знать хороший инженер” собрать данные о реальных задачах которые текущие инженеры решают ежедневно.
Миф о том что “хороший инженер должен знать” достаточно старый и принёс много странного в наш мир. Но судить о знаниях человека по каким-то отстраненным вещам так же глупо, как и судить о механике по тому может ли он вслепую собрать двигатель. Или о хирурге, по его теоретическим знаниям каких-то экстремальных операционных методик. Если мы будем спрашивать по теории, то мы в редких случаях будем заваливать проверку на положительный результат (когда кандидат хороший практик, но что-то не знает) и будем супер уязвимы в негативному результату (зубрилка зазубрил).
Реальные задачи дают нам такой бонус — мы проверяем применение теории в практике, отсекаем зубрилок, которые не могут применить теорию на практике и бонусом даём инженерам которые применяют теорию на практике привычный контекст, в котором они намного быстрее сориентируются. Я понимаю, что таким образом мы ставим реальных инженеров в выигрышную позицию перед зубрилками и “хороший инженер как раз может применить теорию к практике и найти новый способ решения задачи и спроецировать знания из ежедневного опыта на синтетическую задачку”. Но в обычном случае как раз “зубрилки” получали преимущество над “практиками”. Не уверен что вы хотели бы создать такую ситуацию намеренно.
После того как вы собрали список реальных задач, можно подумать о том как можно минимальным количеством вопросов за ограниченное время оценить возможность того что человек будет аналогичные задачи решать.
Лучше всего взять реальную задачу и попросить кандидата её сделать в каком-то урезанном варианте. Этот способ лучше других, потому что так мы сможем увидеть человека в реальном деле, которым мы сейчас занимались. Ясное дело, что вряд ли кто-то из кандидатов сделает за час так же хорошо как сделали вы за месяц, но если вы помните какие идеи вы с командой бреймштормили или у вас есть система контролей версий, то вы сможете оценить идеи и реализации кандидата. Также с прицелом на вопросы на интервью можно специально запомнить кто из коллег какие идеи предлагал на обсуждении. Так нам будет легче оценивать возможность кандидата работать с нами.
Впрочем я не буду отрицать что какие-то конкретные штуки могут быть общими. Допустим мы выяснили что наша команда часто использует хэш таблицы в абсолютно разных сценариях. В таком случае стоит подумать как приблизить кандидата к условиям в которых он сможет показать себя с лучше стороны.
Пример:
У нас есть метрики (много уникальных ключей) которые мы собираем с наших серверов. Нам надо сделать так чтобы каждая метрика попадала на один и тот же сервер. Как нам это сделать? Что делать если сервера в автоскейлинг группе?
Или аналогичный вопрос:
Представьте что вы разрабатываете сайт который может открываться на разных домашних девайсах. Мы хотим сделать так, чтобы если клиент уже авторизовался у нас с своего мобильного устройства и запустил наш клиент, то при авторизации с своего компьютера, телевизора или домашней приставки он не вводил пароль, а получал нотификацию на телефон которая предлагала бы ему авторизовать дополнительное устройство. (Подсказка: мы можем допустить что у всех устройств будет один и тот же ip адрес, хотя уточняющие вопросы тоже могу многое сказать о способе мышления)
Очень хорошо заходят задачи на реальное написание кода. Например:
Допустим у нас есть сервер, который принимает от группы клиентов вопросы, обсчитывает их и отдает обратно. В какой-то момент мы поняли что мы часто делаем одну и ту же работу. Как вы бы решили эту проблему?
««Предлагает Кеш»»
Мы внедрили Redis, но так как данные очень маленькие и нагрузка очень большая, то мы тратим очень много времени на открытие сетевого соединения и/или системные вызовы
««Предлагает in-mem хэш таблицу или папу»»
Напишите пример
««Пишет»»
Если нам необходимо вытеснение, напишите пример
««Пишет»»
Мы решили что на многопроцессорной системе мы хотим иметь несколько тредов (для простоты каждый тред привязан к процессу) как бы вы это реализовали?
««Пишет»»
Ну или придумать задачку на то что например у нас есть много тредов и каждый работает только с своим кусочком памяти и нам надо сделать хэш таблицу чтобы каждая запись попадала в свой тред.
Вопросы в стиле историй и привязанные к реальности всегда лучше, потому что так устроен наш мозг. Мы всегда легче воспринимаем истории и аналогии. Даже Фейнман писал что его главная сила в том что он может найти подходящий пример. И если мы потратив немного сил вместо совсем уж синтетики будем давать задачки которые помогут отличить кандидатов с опытом от кандидатов без опыта, но заученными знаниями, не отсеивая первых, то это того стоит. Иначе мы будем нанимать только кандидатов и с опытом (допустим это мы проверяем другими тестами) и заточенных на собеседования. И получится эдакий карго культ, в котором разработчики считают что они хорошие девелоперы только потому что прошли интервью в нашу компанию и будут точно так же “штормить духов” которые хотят устроиться в компанию, теряя связь с реальностью и нанимая олимпиадников и выпускников в первую очередь только потому что они как и наши нанятые инженеры будут заточены на гиперсинтетические задачи из универа.
Как бонус — кандидаты будут вам благодарны и будут хвалить ваши интервью и вашу компанию и не потому что “о боже мой какая там илитка сидит”, а потому что вы не требовали от них ничего, чего бы они не делали бы на работе.
После того как список вопросов будет разработан, то можно дать его инженерам из вашей команды или из других команд (можно дернуть кого-то толкового из сообщества, кто работает на аналогичной позиции) и проверить какие вопросы и как они решают.
С последним пунктом бывают сложности, потому что вокруг некоторых вещей уже сложились целые карго культы и люди слепо исповедуют что знание вещей которые они даже не используют — необходимо.
Вопросы на которые не ответили практикующие инженеры однозначно плохие. Их стоит убрать.
После того как список вопросов будет утвержден, то следует проверить его на “плохой” выборке. Это сложная тема, в принципе подойдут люди у которых нет или недостаточно опыта: выпускники вузов, известные одиозные личности или преподаватели курсов по программированию, возможно преподаватели в ВУЗах. Если у вас в команде или в команде ваших знакомых есть инженер который не справляется с своей работой, то стоит дать эти вопросы ему и посмотреть зафелится он или нет.
После этого уже стоит проверять вопросы в бою, но вносить в них корректировки в зависимости от результатов и отзывов. И будет у вас хороший хайринг, а не пол человека в год.