Всем привет, меня зовут Сергей, я руковожу группой серверных программистов студии Whalekit и активно занимаюсь наймом в эту группу. Сервер пишем на Java — соответственно, нанимаем мы тоже джавистов.

В 2016 году мы выдавали кандидатам тестовое задание, успешным кандидатам назначалось техническое собеседование.

В 2018 мы добавили 45-минутный «мотивирующий на выполнение тестового задания» этап, чтобы кандидаты лучше понимали, соответствует ли вакансия их ожиданиям.

В 2021 мы полностью отказались от тестовых заданий.

Но обо всем по порядку.


Получать выполненные тестовые задания здорово: можно оценить технические навыки и сформировать обширное представление об опыте кандидата, релевантном вакансии. Если, конечно, тестовое релевантно вакансии.

В студии Whalekit мы делаем мобильные игры с богатой метой (апгрейд оружия и персонажей, кланы, прокачка базы, списки лидеров, подбор оппонента по elo-рейтингу). Добрая половина работы серверных программистов — это написание новых и доработка существующих сервисов хранения. Мы храним профиль игрока в MongoDB и обновляем под распределенным локом на redis. В сервисе хранения наград используем постгрес с изоляцией транзакций repeatable read. Есть сервисы, которые просто хранят состояние в redis, а есть такие, логика которых реализована на lua для атомарного исполнения внутри redis.

Наше тестовое выглядит так:

Написать и покрыть тестами класс, считающий лайки, которые ставят игроки друг другу, и сохраняющий их количество в базу данных (интерфейс ниже). Базу данных выбрать самостоятельно с учетом того, что система должна работать под большой нагрузкой и масштабироваться горизонтально. Реализовать на Java.

interface LikeService {
  void like(String playerId);
  long getLikes(String playerId);
}

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

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

Бывает и так, что кандидат тратит много времени и сил на тестовое, но не получает преимущества. В сложной архитектуре больше шансов допустить ошибку. 

Например, простым в реализации решением будет выбор MongoDB в качестве базы данных. Горизонтальное масштабирование в MongoDB есть из коробки: достаточно использовать playerId в качестве ключа шардирования. Атомарность обновления счетчика также можно переложить на встроенный функционал базы данных — скажем, используя команду updateOne и оператор $inc. Для тестов можно выбрать любой привычный подход — модульные тесты с моками на MongoDB-драйвере, функциональные тесты на реальной MongoDB, запускаемой в Testcontainers, и т. д.

На этом можно остановиться, а идеи по дальнейшим оптимизациям оставить для обсуждения на предстоящем собеседовании. Но кандидат не хочет останавливаться — и решает добавить в свой класс in-memory батчинг лайков, а в базу данных батчи записывать отдельным потоком по таймеру. Тут-то и  возникает множество сложностей и ошибок. Потеря консистентности чтения, так как у разных экземпляров сервиса собственные батчи. Ошибки синхронизации наполняющих батч потоков и потока, записывающего данные в БД. Снижение надежности из-за возможной потери целого батча при падении сервиса или просто из-за таймаута при попытке записи в БД. Обилие такого рода проблем скорее добавляет минусов при просмотре тестового задания, чем плюсов за старания.

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

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

Это неплохо работало до 2021. После отсева кандидатов, чьи ожидания не совпали с ответами, отказов выполнять тестовое было меньше 10%. 

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

Так, двигаясь в ногу со временем, мы отказались от тестовых.

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

Вместо тестового я теперь голосом обсуждаю с кандидатом его опыт написания тестов, опыт горизонтального масштабирования сервисов и БД. Озвучиваю проблему гонки read-modify-write, если непонятно, могу показать пример кода. Спрашиваю возможные пути решения как с точки зрения практического опыта, так и с точки зрения кругозора. 

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

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

Избавьтесь от тестового, пока не поздно!

А вы готовы выполнять тестовое, и в каком случае? Как вам офферы за один день? На что вы обращаете внимание при найме в свою команду?

Комментарии (9)


  1. ruomserg
    01.04.2022 14:00
    +7

    С одной стороны, бессмысленно выдавать тестовое задание привязанное к своей системе, и ожидать что кандидат (который ни разу не видел вашу систему) сделает что-то разумное.

    С другой стороны, я видел людей, которые видимо генетически не способны программировать (точно также, как не у всех есть достаточный музыкальный слух чтобы играть на скрипке). Нужно любым способ убедиться, что кандидат вообще способен программировать! И тут есть два варианта:

    — Либо вы спрашиваете какую-то data science хрень — типа обращения двоичного дерева, написать приоритетную очередь на основе heap, и т.д. В этом случае вы получаете кандидата который гарантированно умеет программировать, но теряете кандидатов — которые уже забыли data science хрень, а могли бы принести немало пользы в проекте.

    — Либо вы придумываете какую-то задачу, которую можно в целом решить за 15-30 минут на собеседовании. Например, предлагаете вывести на однострочный экран в 20 символов сообщение длиной 50. И дальше слушаете — может ли кандидат предложить какое-то решение, и набросать его элементы на бумаге/экране.

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


    1. tmin10
      01.04.2022 20:29
      +2

      Только не data science, а computer science вероятно. DS это всякие нейронки, регрессии и геенетические алгоритмы.


      1. ruomserg
        02.04.2022 04:37

        Да, конечно CS


  1. alexey-m-ukolov
    01.04.2022 14:04
    +2

    Полностью согласен. В тестовые я никогда не верил — слишком далеки они от реальных задач и в лучшем случае показывают насколько программист умеет форматировать код. За десять лет я столько собеседований провёл, что разговора о задачах, с которыми человеку доводилось сталкиваться, вполне хватает для понимания его уровня и перспектив вписывания в команду. А часто всё понятно уже по резюме и на собеседовании фокусируемся на рассказе о себе и своих задачах, чтобы подходящий человек явно понимал куда попадёт.

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


  1. event1
    01.04.2022 15:34
    +2

    А вы готовы выполнять тестовое, и в каком случае?

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

    Как вам офферы за один день?

    Хорошо. Чем быстрее, тем лучше.

    На что вы обращаете внимание при найме в свою команду?

    На умение программировать, в первую очередь. Потом на релевантный опыт.


    1. alexey-m-ukolov
      01.04.2022 16:00
      +1

      Как можно нанимать программиста не убедившись, что он умеет программировать?

      Предполагается, что если человек уже где-то работал N месяцев, то объяснять ему что такое переменная и цикл не придётся. А понять, может ли он структурировать код, делать его понятным и поддерживаемым, по тестовому заданию, имхо, нельзя. Иначе оно будет "слишком длинным". Я для себя не вижу какого-то баланса здесь - сделать такое тестовое задание, чтобы его выполнение заняло пару часов, но при этом позволяющее судить о реально востребованных навыках ведения долгосрочных проектов. Но, возможно, этот баланс существует, конечно. Просто я не видал.


      1. event1
        01.04.2022 17:30

        Предполагается, что если человек уже где-то работал N месяцев, то объяснять ему что такое переменная и цикл не придётся

        У меня, к сожалению, другой опыт.

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

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


  1. DrMefistO
    02.04.2022 16:32

    Расскажу про тестовые задания для реверс-инженеров. Я всегда с большим нетерпением ожидаю их получение. Видел разные: были невероятно классные, решением которых я горжусь до сих пор (привет Диме Склярову и PT), а были все остальные - они же "каспер-подобные" где, как всегда, даётся очередная математическая/CTF-ная хрень, которая не юзается ни в одной малвари, и вообще ни в каких продуктах в реальности.

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

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


  1. GaDzik
    02.04.2022 18:55

    Первые 3 - 4 тестовый вообще не захотелось делать. Последнее делал без какиз либо усилий. Не могу сказать на счет нужности тестового ничего. Но те которые я не сделал говорят о том, что мне не понравлось бы там точно.