Я все-таки решил поделиться нашим опытом приема людей на работу, и решил я это сделать по двум причинам: нам удалось собрать всех самых сильных разработчиков нашего стека в городе, и люди, которые приходят — уходят от нас крайне редко (точнее, был лишь один случай ухода в собственный бизнес).
Все, что написано ниже, может вам подойти, а может — и нет. Я не претендую на истину в последней инстанции, я просто рассказываю, к чему пришли мы, и почему нам это нравится. Также я поделюсь примерами паттернов поведения и кода, которые практически однозначно решают за, или против, кандидата — невзирая почти ни на что остальное.
Мы — продуктовая компания, нам не нужны вахтовые работники на три месяца. Это тоже накладывает отпечаток на процесс отбора. Мы не в состоянии конкурировать по зарплатам с молодыми заинвестированными стартапами (это не значит, что мы работаем за копейки, просто перекупить талантливый мозг не получится). Зарплата выше средней по рынку, но можно найти галеры сразу тысяч на десять годовых щедрее. Нам приходится искать свой путь завлечения специалистов, и я о нем расскажу.
Подача заявки
Мы пробовали агентства (я сам пришел пять с лишним лет назад через агентство), но в результате остановились на сарафанном радио и прямых контактах. В Барселоне живет два миллиона человек, но разработчиков высокого уровня не так много, и я всех знаю если не в лицо, то по именам.
У нас есть тестовое задание среднего уровня сложности. Любой открытый репозиторий с чем-то посерьезнее helloworld — разумеется, заменяет тестовое задание. Претендующему на позицию «не начинающий» потребуется от шести часов до двух дней на его выполнение и оформление. Еще ни один профессионал не отказался его сделать — вместо белой доски, инверсии списка и вопросов по синтаксису непосредственно на собеседовании. Мы собираемся работать вместе годы — два дня тут погоды не сделают. Мы не оплачиваем тестовое задание, и я считаю это важным пунктом оценки соискателя: если человек требует рубль за каждый чих, мы вряд ли сработаемся. Когда тестовое задание только сформулировалось, я был первым, кто его решил — как для сопоставления с кодом кандидатов, так и просто, чтобы не забронзоветь.
Мы принимаем тестовые задания на любом языке, с некоторыми исключениями: в команду фронта мы просим использовать эмбер, потому что идеологически он отличается от хайпового реакта, и хочется посмотреть на умение работать именно в этой парадигме. В команду руби мы просим руби или эликсир. В команду микросервисов — все, что угодно, на ваш выбор. Обычно выбирают эликсир, или эрланг, как указано в вакансии, но были и хаскель, и скала.
По результатам тестового задания мы коллегиально принимаем решение: один из ведущих разработчиков его бегло просматриает, и если оценка выше 7/10 — еще двое просматривают его тщательно, как на код ревью. Если ответ — да (средняя оценка выше 8/10), мы запускаем процесс, и мы считаем, что это нам нужен этот человек, а не наоборот. Строго говоря, ровно с этого момента мы начинаем завлекать кандидата. Если он не явится на очное собседование пьяным и в семейных трусах — мы обязаны его уговорить работать с нами, чего бы это ни стоило.
Собеседование
Уговариваем мы не деньгами. Офис на 22 этаже Torre Mapfre — прямо над пляжем Икария — единственное материальное благо, которое мы упоминаем. Мы обязательно рассказываем, что много публикуем в OSS. Упоминаем, что один из членов команды — core committer компилятора и стандартной библиотеки основного используемого языка. Корпоративный технический блог, который регулярно попадает в еженедельные дайджесты самого интересного. Меня, в конце концов, в этом стеке на SO знают все, кто хоть как-то с ним связан.
Еще мы очень подробно рассказываем про условия работы, разнообразие и крутизну инструментария, участие в профильных конференциях, хостинг эликсир-митапов в Барселоне, парные сессии, процесс достижения консенсуса по архитектуре, плоскую систему управления, курсы, которые постоянно стихийно создаются ведущими специалистами. Если человек хочет расти — мы очень внятно показываем, почему тут — самое идеальное место. На очном собеседовании мы два часа рассказываем, почему соискатель хочет работать именно у нас, покупаем его, так сказать. Потом 15 минут его терзают эйчары, но я не припомню ни единого случая, когда мнение эйчара что-то значило против мнения трех ведущих специалистов. Если нам соискатель глянулся — мы его возьмем, даже если он асоциальный психопат с приводами в милицию.
Эта система работает для нас, и три недели назад мы переманили последнего разработчика в Барселоне, которого хотели переманить. Поэтому, собственно, я и собрался написать эту заметку.
Ну, и в конце, добавим немного технических подробностей.
Бонус. Примеры кода, которые сразу да, или сразу нет
Ruby > сразу нет
- нарушение SRP
- смешивание чистых методов и какого-нибудь IO в одной сущности
- копи-паста вместо абстракций
- встроенные типы (integer, float, double) для выражения денежных сумм
Ruby > почти сразу нет
- методы, изменяющие ресивер (
array.shuffle!
), кроме внятно обоснованных - использование
each
итератора для маппинга или редьюсинга - инстанс-переменные для передачи состояния из метода в метод
- инстансы там, где достаточно статических методов
.map{...}.map{...}.map{...}
вместо одного прохода, если размер коллекции неизвестен- методы, принесенные рельсами, там, где достаточно обычного руби
- лишние локальные переменные
Ruby > почти сразу да
each_with_object
со сложным аккумулятором вместо двойного прохода по коллекции- уместное использовние
proc
/lambda
, например, вcase
assert_raise
в тестах- тесты на неожиданный ввод
- dry-rb
- flip-flop (шучу, конечно).
Elixir > сразу нет
- отсутствие спек для диалайзера
- отсутствие документации для публичных функций,
doctest
обязателен - что угодно другое там, где можно pattern matching
- неконтролируемый краш процессов
Elixir > почти сразу нет
- код не подвергался воздействию форматтера
- неуместные пайпы
- использование
if
(кроме вырожденных случаев) Phoenix
для мини-задачи (вместоPlug
)
Elixir > почти сразу да
- использование
DynamicSupervisor
,GenStage
,Flow
- property based tests
- использование
@behaviour
для описания интерфейса - свой протокол (где уместно)
- своя имплементация
Access
- уместное использование
__using__(opts)
Ну вот, как-то так. Я понимаю, что написанное выше попахивает вкусовщиной, но это так и должно быть. Мы не хотим быть идеальными собеседователями. Мы хотим максимизировать найм людей, которые нам нужны и которым будет комфортно с нами. В одном флаконе. И нам это удается именно из-за этой предвзятости на берегу. Как показывает опыт, в сухом остатке мы имеем почти 100% конверсию: люди, которые к нам приходят — остаются надолго, и им у нас комфортно.
saag
Бинокль дадите?:-)
chapuza Автор
Ну не 220-й же. Но есть подзорная труба у окон, выходящих на город.
:)