Выпуск 23. Январь 2015
← Tapper — система тестирования ПО полного цикла | Содержание | Использование TLS в Perl →Как нанять Perl-программиста
Про один удачный эксперимент по найму программистов
Если вы один из тех, кто когда-либо собеседовал человека на работу, вам наверняка приходилось сталкиваться с проблемой подбора хороших кадров. В статье я постараюсь опубликовать максимум всех материалов, которые были задействованы во время постановки эксперимента.
Но прежде чем начать — позвольте представиться.
Об авторе
Меня зовут Алексей Варяник, друзья зовут меня cono (как, в принципе, и многие коллеги).
Занимаюсь Perl-разработкой начиная с 4-го курса университета (2004 год). В стенах comScore.com подрос до TeamLead. После того, как проект отдали на поддержку в Кювейт, перешёл работать в компанию Provectus на проект livenation.com (поддержка сайта ticketmaster.com). В скором времени на этом проекте вырос до Software Engineering Manager, а как вам всем наверняка известно, одной из обязанностей software manager является подбор и собеседование «кадров» :)
Собеседования
По началу набирать программистов не составляло особого труда. HR-отдел находил «бесценных» Perl-разработчиков, мы их собеседовали, ну и, если уж совсем понравился, брали на работу. Команды состояли из back-end- (BE, perl), front-end- (FE, js) и QA-инженеров. Именно в такой последовательности и хотели нанимать. Но к сожалению, всё выходило с точностью до наоборот. Cначала появлялись QA, после чего FE, и только лишь после гигантских усилий BE. Постепенно проблема подбора BE становилась всё сложнее и сложнее. То ли разработчики «заканчивались», то ли люди становились более избалованные, и Чёрное море больше никого не привлекало :)
Слышу звон, не знаю где он
Кололись, плакали, но продолжали есть кактусы. Одним из первых «спасательных» решений было — нанимать людей из других областей (язык, технологии). И вот тут началось самое интересное. Наконец-то пошли люди и довольно много, но в то же время достаточно интересные «кадры».
— Опишите пожалуйста процесс передачи GET параметров? — Они появлюятся в переменной
$_GET
.
Бывали и очень серьёзные ребята, которые пишут на «плюсах» под кастомную архитектуру:
— Объясните пожалуйста, что такое Template в C++? — Шаблон! — Хорошо, а для чего они используются? — Эээ…
Бывали и просто хорошие программисты:
— Напишите пожалуйста функцию, которая принимает целое число и возвращает 0, если число чётное и 1 в противном случае. — Я, наверное, вам не подойду.
Нагромоздив некое количество костылей (предварительное тестовое задание, технические вопросы от HR, …), нам удалось снизить поток шарлатанов и бездарей. В целом, мы смогли нанять ещё парочку смышлёных ребят.
И вот тут-то звоночек и зазвонил. Решили рассматривать другие варианты найма.
Предыстория
В году эдак 2008-м, когда я был программистом на banner.kiev.ua, соседи по офису набирали Perl-разработчиков на проект mail.ua (уже mail.ru), и встретили те же самые проблемы, что и мы сейчас. Тогда было принято решение: набирать смышлённых мальчуганов и девчонок и обучать их великому делу! (программировать на Perl).
В тот раз этот эксперимент закончился очень удачно, мы набрали замечательных ребят (и девочку, привет Янка!). Некоторые из них, даже открыли собственную компанию: WebbyLab.
Набор
Тогда я участвовал как преподаватель, но в этот раз пришлось поучаствовать и в организации процесса. Списался с одним из организаторов прошлых курсов (Олег Савчук aka oSa), попросил перечень тем, по которым вели прошлые курсы:
- Обзор курсов. Обзор возможностей Perl. Настройка среды.
- Введение в Perl. Скалярные данные. Основные операции с числами.
- Массивы и хеши. Цикл foreach. Специальные переменные (
$_
). Операторыnext
,last
,redo
. - Операции над строками. Регулярные выражения.
- Процедуры и функции. Пакеты и модули.
- Ссылки и объекты.
- CGI.
- DBI.
Темы равномерно распределили между разработчиками, уже работающими у нас. Попросил каждого подготовить доклад по теме (не более чем на полтора часа) и тестовые задания (о них более детально расскажу чуть позже).
Далее вступили в бой наши HR и PR. Отдельное спасибо хочется сказать Оле Ковальской, она провела титанический труд по общению с кандидатами, а их было уж очень много.
Было сформировано следующее объявление о наборе:
Время учить Perl
Perl устарел? Нет, не слышали… Perl не просто жив и процветает, он еще и достаточно востребован!
Provectus IT объявляет набор на курсы Perl с возможностью последующего трудоустройства.
Обучение будет включать в себя лекционные и практически занятия с акцентом на самостоятельное обучение. Такой подход предоставит учащимся возможность в дальнейшем быстрее вникнуть в проект, справляться со сложными задачами, оперативно принимать решения.
Курс рассчитан на 3 недели (по 2 занятия в неделю). Всех желающих ждет строгий отбор ведущих Perl-истов команды Live Nation/Ticketmaster.
Требования:
- Предпочтительно образование в области компьютерных наук или математики.
- Логическое и аналитическое мышление.
- Способность быстро обучаться.
- Наличие опыта работы с любым объектным языком программирования.
- Базовое знание Perl будет плюсом.
- Английский язык (письменный и устный).
- Опыт работы с MySQL (предпочтительно) либо с другими СУБД.
- Знания алгоритмов и прикладной математики.
Обучение будет проходить на бесплатной основе!
На выходе мы получили огромное количество резюме (более сотни). И люди попадались абсолютно разные: студенты, бывалые программисты, моряки дальнего плавания и даже преподаватель :)
Из всего списка мы отобрали 54 человека и разослали им пригласительное письмо. Надеясь хоть как-то отсеять народ, мы придумали три тестовых задания, которые нужно было выполнить, чтобы прийти на собеседование. Но до собеседования дошли все 54 человека. Было принято решение вести собеседование по проделанным тестовым заданиям и не более 20 минут (такой вариант конечно даёт очень много false-negative-результатов, но пришлось чем-то жертвовать).
Пригласительное письмо
Привет!
В ответ на Ваше резюме на позицию trainee Perl, спешим пригласить Вас на собеседование, которое состоится в день_недели, дата июля в время в виде группового отбора.
В прикреплённом файле Вы найдёте тестовое задание. Мы рассчитываем на Ваше выполнение этого задания на любом понятном нам языке программирования (BASIC, C, C++, Java, Pascal, Perl, Python, PHP) или просто в виде алгоритма. Собеседование будет включать Ваше устное описание выполненного задания и ответы на наши вопросы. Выполненное тестовое задание просим подготовить по возможности в виде распечатки (если с этим возникнут сложности — приносите в электронном виде, и мы поможем распечатать).
Как будет проходить собеседование? Мы попросим Вас заполнить анкету, а затем побеседовать с нашими Software Engineers на тему выполненного задания. Даже если Вы затрудняетесь выполнить часть задания — это не беда: нам будет интересно пообщатсья с Вами о ходе мысли и в целом на программистские темы. Так как мы работаем на международную компанию, то просим Вас подготовиться рассказать о себе на английском языке.
Как будет проходить обучение? Курс рассчитан на 7 тем, по каждой планируется 1-2 лекции и практические задания. Лекции будут происходить в первой половине дня (ориентировочно с 10:00) дважды в неделю в нашем офисе. Там же Вы регулярно сможете пообщаться с опытными разработчиками и задать им интересующие вопросы. Курс продлится около 5 недель. По окончании курса все успешные студенты будут допущены к собеседованию, по результатам которого происходит трудоустройство. Мы хотим взять на работу всех. Нет, честно.
Как мы сообщали ранее, курсы бесплатные, а значит — мы оставляем за собой право выбора учеников. Благодарим за понимание.
Тестовые задания
Про тестовые задания хотелось поговорить более детально и упомянуть, на что обращали внимание, какие вопросы задавали. Итак, первое задание:
В цикле от 1 до 71 вывести
c*10
для каждогос
, кратного 3, иc*100
для каждогоc
, кратного 7. Еслиc
не кратно 3 иc
не кратно 7 – не выводить ничего. Посчитать и вывести две суммы выведенных чисел.
Первое задание очень простое, больше для мотивации, чем для проверки каких-либо знаний, чтобы дать человеку понимание что он может выполнить эти задания.
Вопросы задавали по code-flow и оптимизации:
- а что случится если переставить эти строки местами;
- как модифицировать программу так, чтобы выводить
c
в случае некратности 3 и 7 (числа не просто так были выбраны простыми, дабы увидеть вариант:c % 21
); - как прооптимизировать программу (хотели добиться ухода от перебора 1 .. 71 и приходу к простому суммированию).
Второе задание немного сложнее:
Написать функцию, которая сгенерирует пагинацию (список номеров страниц с указанием текущей страницы).
Входные параметры:
a: общее количество записей b: количество записей на странице c: стартовая страница
Пагинация имеет вид:
< 1 2 [3] 4 5 … >
Всегда отображается 5 страниц и троеточие в стороне, в которой есть неотображённые страницы. Если текущая страница приближается к первой или последней — всё равно выводим 5 номеров страниц, приближая пагинатор к нужной стороне.
< … 6 7 8 [9] 10>
Эта задача для определения крайних случаев (edge-case’ов):
- общее количество записей 0;
- стартовая страница вне диапазона;
- страниц меньше 5 (многоточие должно было исчезнуть с обеих сторон).
Если какой-либо критерий не был выполнен, спрашивали, как нужно модифицировать программу чтобы добиться нужного эффекта.
И последняя задача (две в одной):
На входе – бинарный файл. Представив его как последовательность символов в кодировке ASCII, подсчитать количество символов z и Y в этом файле. Вывести оба числа в системах счисления от 2 до 16.
В этом задании преследовалось две цели, но во время проверки нарисовалась и третья:
- capacity testing (нагрузочное тестирование — прим. ред.) — понимает ли кандидат, как нужно изменить программу, если на вход подаётся файл размером в несколько террабайт;
- проверка математических знаний (системы счисления);
- соответствие техническим требованиям, почему-то именно эта задача вызвала большие сложности с пониманием технического задания (Y & y — это разные буквы, от 2 до 16, это и 3, и 4, и 5, …).
Начало
В итоге мучительных интервью-сессий были отобраны 20 человек (планировалось 10, очень не хотелось прощаться с некоторыми). И одного попросили добавить по блату (мы же в Украине живём, куда ж без этого :)
ИТОГО: 21
Первая лекция была вводной, мы просто собрались вместе, познакомились. Ученики увидели своих будущих учителей, учителя — учеников. Одним из важных на мой взгляд моментов было расстановка всех точек над И. А именно:
- Это бесплатные курсы.
- Лекции будут читать простые программисты (и далеко не все из них с даром преподавателя).
Т.е. на первом же этапе мы определили простые правила приличия: относиться с уважением друг к другу, ведь никто никому ничего не должен. Любые несогласные могли покинуть данные курсы в любой момент. Ребята оказались все взрослые, и курсы проходили «без сучка и задоринки».
С технической стороны всем были выданы виртуальные машинки для VirtualBox (дабы снизить риск ошибок environment и архитектуры). Базовые инструкции: как установить виртуальную машину, как зайти, как писать код, как тестировать, проблемы с сетью и т.д., и т.п.
Домашнее задание
Старт дан, и на этом этапе мы начали задумываться о контроле успеваемости и о том, как узнать результаты в конце эксперимента. Материал хотелось закрепить практическими задачами. Поэтому каждый из восьми преподавателей взял на себя обязанность придумать (подсмотреть) 1-3 задания по своей теме.
- Написать программу нахождения корней квадратного уровнения:
ax2+bx+c=0
. - Перевод числа из десятичной системы счисления в другую и обратно.
- Подсчитать частоты возникновения слова в тексте.
- Нахождение циклов в циклической структуре данных.
- Замены подстрок в строке (хеш соответствий).
- Написать простейший shell.
- Произведение двух матриц.
- Аналог
Data::Dumper
. - Написать классы Date & Calendar.
- SQL-executor.
- CGI-приложение.
Более детальное описание заданий вы можете найти в этом документе.
К каждому тестовому заданию был написан некий набор тестов, о которых мы поговорим далее.
Проблема №1: Проверка
Дальнейший процесс развивался спонтанно, эволюционно и по мере возникновения проблем. И первой такой проблемой явилась проверка выполненных заданий.
Т.к. environment был задекларирован ещё на первой встрече, среда тестирования уже была определена. VirtualBox обладает замечательным механизмом snapshot-ов. При каждом тестировании востанавливаем виртуальную машину к исходному (не испорченому) состоянию и запускаем тесты.
Запускать 21 программу * N тестов вручную было очень накладно, поэтому на коленке были написаны shell-скрипты для тестирования.
На первых заданиях делались всяческие поблажки: вывод подправить, shebang исправить, и т.д. Не все были готовы к олимпиадному подходу (строгие входные данные, строгие выходные данные), но после первых результатов всё быстро стало на круги своя.
Вариант приёма исходников тоже по-началу был не идеален (кто в скайп, кто в почту: — А можно я исправленную версию пришлю?). На коленке была написан небольшой скрипт загрузки результатов, через которую можно было отправить решение хоть миллион раз до определённого времени. После этого времени — только один раз.
Все результаты складывались в git (на тот момент не публичный). В этом же репозитории находились и номинальные решения от «преподавателей».
Тестируемому скрипту передавалось имя файла с входными данными (тестовые данные определены в model/*/dat
).
Проблема №2: Статистика
Статистики хотелось получить как можно больше — а значит и объективнее. В погоне за статистикой первыми были получены результаты прогона тестов, они имели следующий вид:
+/- означают прошёл тест или нет, и «T» — прерван по таймауту (если алгоритм зацикливался).
Этой статистики показалось мало, а так как результаты загружались через Web, можно было подсчитать среднее время, затраченное на решение (планировалось использовать эту статистику, если кто-то будет с одинаковыми оценками, но так и не пригодилась :)
Результирующая таблица получилась следующей:
Статистика выкладывалась постепенно и соревновательный дух не прекращался ни на секунду.
Проблема №3: Апелляция
Как бы не приноравливались наши «ученики» к оллимпиадному режиму, всё равно допускалось много ошибок, связанных с выводом (и даже ошибки в номинальных решениях). Ввиду этого было принято решение соблюсти все каноны Олимпиадного режима и добавить этап апелляции. Как говорилось ранее, исходники складывались в git, поэтому с точки зрения реализации решили использовать github + merge request. Патчи принимались только те, которые не изменяли логику работы программы, а только ошибки вывода.
В итоге наши студенты ещё и научились простейшим операциям с git (commit, push, merge-request, …)
Английский
В конце курса обучения было обещано собеседование с присутствием заказчика (американец), поэтому одно из изначальных требований было умение объясниться технически на английском. У нас в компании проводятся разговорные встречи клуба английского языка (бесплатные), поэтому всем участникам эксперимента было предложено бесплатное посещение занятий в течение всего курса обучения.
Собеседование
Собеседование решили проводить от высшей оценки к низшей. Статистически вышло так, что мы прособеседовали только тех, у кого бал был выше пяти.
На собеседованиях ребята очень волновались, хотя на английском их сильно и не спрашивали, но присутствие иностранного заказчика наводило некий ужас :)
В результате собеседований мы наняли пять человек на ставку Junior BE и ещё двух человек без зарплаты на позицию trainee. К сожалению, с нами на текущий момент остались только лишь четверо.
Выводы
Во всём есть свои «+» и «-», именно их и хотелось бы опубликовать как выводы.
Достоинства
- Мы получили четырех SUPER-Junior разработчиков. Которые в течение месяца смогли показать отличную обучаемость. Как и в течение дальнейшего периода работы на компанию.
- Интересный опыт для «преподавателей».
- Последующее отношение «преподавателей» к своим успешным «ученикам» — очень тёплое и способствует хорошему командному духу (все заинтересованы в дальнейшем их успехе).
- Вхождение в проект этих разработчиков в разы быстрее, чем просто нанятых посредством интервью (опять же ввиду скорости обучаемости).
- Есть маленький шанс получить на выходе сразу Middle-разработчиков (если входные данные были опытными программистами :)
- Имидж компании.
- Новые люди в Perl-сообществе.
Недостатки
- Таким образом практически невозможно набрать Senior-разработчиков (но при должном подходе junior очень быстро могут стать senior-разработчиками).
- Затраченное время (хотя вы получите целеустремлённых разработчиков, которые в разы лучше «зажравшихся» професионалов).
- Затраченное время. И всё же, как бы я не убеждал вас в успешности эксперимента, четыре раза подумайте о затраченном времени на него. Есть ли в этом смысл конкретно для вас. Не стоит относиться ко всему как к панацее, переложите изложеный опыт на свои реалии.
← Tapper — система тестирования ПО полного цикла | Содержание | Использование TLS в Perl →