Go School
Как вы знаете, в середине мая Ozon объявил о запуске школы программирования на языке Go. Обещали следующее:
- бесплатное обучение
- возможность получить знания по реальной разработке на Go от Ozon
- возможность получить работу в Ozon
Чтобы попасть в школу, нужно было:
- иметь опыт промышленного программирования
- пройти тестовые задания по программированию на платформе Яндекс.Контест
- пройти skype-собеседования
Уже в ходе отбора выяснилось, что онлайн школа будет только до момента, пока эпидемиологическая ситуация не наладится. Впрочем, иногородним жителям все-таки была обещана возможность проходить обучение по интернету.
Тогда же было озвучено число студентов, которое готовы принять в Школу — около 40 человек.
Так понемногу условия поступления прирастали новыми пунктами, среди добавленных также значилось:
- желательно проживать в Москве
- быть гражданином РФ
- возраст старше 18 лет
Но все это выяснилось уже позже, а пока предложение Ozon привлекло многих разработчиков. Пора было приступать к первому этапу: прохождению теста.
Вроде все выглядело неплохо, условия не такие сложные и вполне выполнимые.
Сперва надо было решить пять задач по программированию на платформе Яндекс.Контест. Первые четыре задания были типичными алгоритмическими задачками, которые обожают давать на собеседованиях. Эти задания можно было решить на любом языке из предложенного списка. Последнее — пятое — требовалось решать на Go.
Задание E
Описание ее работы:
n раз сделать следующее:
- прочитать по одному числу из каждого из двух каналов in1 и in2, назовем их x1 и x2.
- вычислить f(x1) + f(x2)
- записать полученное значение в out
Функция Merge2Channels должна быть неблокирующей, сразу возвращая управление.
Функция f может работать долгое время, ожидая чего-либо или производя вычисления.
Формат ввода
Количество итераций передается через аргумент n. Целые числа подаются через аргументы-каналы in1 и in2.
Функция для обработки чисел перед сложением передается через аргумент f.
Формат вывода
Канал для вывода результатов передается через аргумент out.
Примечания
Отправлять задачу необходимо под компилятором Make. Решения, выдающие неверный ответ, могут по техническим причинам получать вердикт Runtime Error. Медленные решения получают вердикт Idleness Limit, стоит рассматривать это как превышение времени исполнения.
Сделав все задания, кроме последнего, приступаем к заданию E. Описание задания не казалось сложным, надо было все лишь сделать неблокирующий код функции и возвращать результаты в правильном порядке, но все попытки были неудачными и платформа постоянно выдавала результат WA (Wrong Answer). Хотя на каждое задание отводилось по 100 попыток, тратить их стоило аккуратно, ведь самым бережливым было обещано преимущество при отборе. Два дня я пытался понять в чем дело, израсходовал попыток 20, но все время получал WA.
Решено было создать телеграм-группу с такими же неудачниками и провести брейншторм. Численность группы быстро увеличивалась и чем больше вариантов мы пробовали, тем чаще звучали догадки, что проблема не в решении, а в платформе или проверке.
Тут начинается расследование как работает Яндекс.Контест.
Несколько человек нашли способ смотреть содержимое файлов на платформе через вывод в stderr. Так у нас получилось достать тесты задания (main_test.go), структуру директории и makefile.
Локально тесты проходили, но платформа упорно выдавала WA.
Собранная информация и анализ работы платформы Яндекс.Контест позволили сформулировать алгоритм работы тестов и причину злосчастной ошибки.
Как работают тесты для задания E
По той информации, что нам удалось достать с платформы Яндекс.Контест
Этапы (Make):
1) Компиляция.
1.1) В нашей задаче нет никакой компиляции. Просто два раза перекладывает файл решения.
1.2) Архивация.
На данном этапе уже есть файлы «см формат ввода» и «см формат вывода». Они пустые.
2) Выполнение.
2.1) Разархивация.
2.2) go test. Тут происходит проверка решения. Если оно неверное, то выбрасывает panic. Если верное, то результат запуска go run выводится в STDOUT. Вот это САМЫЙ важный момент. Запомните это.
Файл запуска
#!/bin/bash
go test
3) Проверка чекером.
Чекер это просто любой скриптовый язык, который на вход принимает три параметра:
input (файл теста), answer (ожидаемый ответ файла теста), output (вывод пользовательского решения на этапе запуска).
Параметры input и output указываются в админке, и в нашем случае они не важны.
Но вот самое интересное — это answer. Туда в нашей задаче приходит содержимое файла «см формат вывода». НО! Туда никто ничего не пишет и он всегда пустой в нормальном состоянии.
В итоге им всего лишь нужно было перенаправить вывод результата работы go test и проверять вывод чекером.
Так как в файл “см формат вывода” ничего не записывается, все решения система считает как неверные, и мы получаем результат WA.
Зная, как система работает, удалось создать чит-скрипт. Он писал произвольный символ в файл “см формат вывода”, из-за чего чекер платформы считал задание выполненным. Фактически это был единственный (хотя и нечестный) способ пройти задание E успешно.
Итого. Если вы не готовы на небольшое мошенничество и отправляете абсолютно корректное решение, то получите только WA.
Ответы от Ozon
После этого исследования несколько человек написало на почту Ozon и представителям школы с подробным описанием багов. На это были получены ответы в духе: “У нас все работает, мы видим, что несколько людей выполнили задание”. Многие письма с просьбой проверить корректность задания вовсе оставались без ответа.
Ответ по почте:
Мы пока не проводили код-ревью решений, принятых системой с помощью нашего тестирования. Будем проводить только после окончания отбора. Сейчас успешных решений уже больше, это те решения, которые были приняты с вердиктом «ок». Мы ничего не меняли в задаче, как я и писала ранее. Как вы понимаете, до окончания отбора я не могу поделиться информацией о решении. Мы постараемся сделать разбор задач и поделиться информацией со всеми участниками отбора.
За время контеста Ozon дважды публиковал комментарии, которые могли видеть все участники. Во второй раз там был обширный кусок, посвященный заданию E. В нем сказано много и одновременно ничего:
Проанализировав ваши посылки по задаче Е, мы пришли к выводу, что тест по этой задаче составлен слишком обще и широко. В данном случае одного теста недостаточно. Некоторые пограничные ситуации принимаются как корректные. Ошибка в системе, которая выдается в ответ на решение участника, не всегда предсказуема. Доработать это в режиме реального времени у нас нет возможности: есть риск потерять уже существующие решения. Это мы будем прорабатывать уже после завершения отбора. Сложности связаны также с тем, что Go — новый язык для платформы, Make, как компилятор, был добавлен по нашей просьбе, чтобы обработать решения задачи на Go.
Вместе с тем в Ozon посчитали необходимым пожурить участников контеста, которые решили срезать углы:
До момента написания чит-скрипта нами было получено 32 корректных решения этой задачи. Отборочные соревнования не предполагали никакого пентеста системы, поэтому просим вас добросовестно отнестись к решению задач отбора.
Сотрудники компании даже были замечены на форуме, где посетители объединились для совместного решения задачи E, — грозили им пальчиком и апеллировали к их честности.
Цифры, статистика и печаль
Первого июня в группе появились сообщения о первых приглашениях на собеседования. Все затаили дыхание. Если письма с сообщениями об ошибках еще можно было игнорировать, то уж в интервью мы получим ответы на все вопросы.
Но на собеседованиях происходило странное — никаких разборов задач, никаких вопросов по контесту. Только несколько стандартных вопросов о местоположении, увлечениях и желании учиться в школе. Интервьюер ничего не знает ни о задаче Е, ни о проблемах с ней.
По словам организаторов, заявки подали более 4000 человек, что стало неожиданностью для них. В ответ на многочисленные вопросы и жалобы Ozon организовал онлайн-митинг в Zoom, чтобы ответить на все вопросы по школе. Но и там однозначного ответа на ситуацию с заданием Е получено не было. Прозвучало заявление, что задание Е в отборе учитываться не будет.
В телеграм-группе количество людей достигло 180. И ни один не смог пройти задание Е.
После анализа тест-системы многие в чате еще пару дней не могли поверить, что проверка задания Е содержит ошибку. Тяжело смириться, когда несколько дней твоей жизни потрачено впустую из-за чьей-то халатности.
После того как руководитель школы Ozon не признался, что задание Е сломано и его невозможно пройти, в группе начался “бомбеж”. Особенно мы не понимали, почему нельзя исправить тест-систему.
Добавил горечи факт того, что брали в школу не тех, кто сделал задания, а тех, кто подходил под критерии отбора. Один из участников группы рассказал, что его знакомого позвали на собеседование, хотя тот сделал лишь два задания из тех четырех, которые можно было пройти без уловок.
17 июня, как и было обещано, Ozon разослал всем письма о результатах (поздно вечером).
Провели несколько опросов, вот результаты:
Возрастной состав группы (131 проголосовавший):
32% — 25-29 лет
27% — 20-24 лет
24% — 30-34 лет
8% — 35-40 лет
5% — до 19 лет включительно
4% — 40+ лет
Вопреки ожиданиям, в основном аудитория собралась зрелая.
География участников (60 проголосовавших):
35% — Москва
20% — Приволжский регион
15% — Центральный регион
8% — Санкт-Петербург
7% — Московская область
5% — Северо-Западный
3% — Южный
2% — Украина
3% — Белорусь
2% — Казахстан
Как видно, очень много людей было не из Москвы, но, в общем, оно и понятно — Ozon обещал онлайн школу. Судя по отзывам тех, кого пригласили на собеседование, это были люди из разных регионов, более того — собеседовался и человек из Минска, что делало логику отбора совершенно непонятной.
Результаты отбора (100 проголосовавших):
80% — получили отказ
12% — получили приглашение
8% — не пришло ничего
Отказ получали как те, кого не приглашали на собеседование, так и те, кто собеседование прошел.
Каким должен быть отбор здорового человека
1. Рейтинг! Объективный и открытый, в котором указан список тех, кто сделал задания, прошел собесы, кто сколько набрал баллов.
2. Четкие критерии, как начислялись баллы. Должны быть общедоступные критерии, по которым каждый смог бы подсчитать свои баллы и свериться.
3. Почему была допущена ошибка с заданием Е и почему не признали сразу? Что за уловки и попытки уйти от признания своего косяка? Почему сразу не исправили проблему, а упорно говорили о каких-то 32 участниках? Для кого эта лапша? Что за неуважение?
4. Извиниться в случае косяка и рассказать о дальнейших действиях, а также о том, что будет предпринято для улучшения процедуры отбора.
Отписки уровня “Все работает, все норм, 32 человека решили, потом сломалось, виноват Яндекс, так как мейк у них кривой. Начни с себя, ищи ошибку у себя” и т.п. Или отбирали по “опыту выполнения тестовых заданий” — это уж совсем, извините, ни в какие рамки.
Каким получился отбор у Ozon
1. Нет рейтинга. Решение, кого звать, а кого нет, принималось совершенно неизвестным нам образом. Отбирали по красоте? По возрасту? По длине рук и других органов? Вам нужны хорошие специалисты или метросексуалы для позирования в витринах? Предположу, что решение принималось исключительно на основе резюме участников. Надеюсь hr получили премию за обработку 4000 резюме
Представьте, если бы вы отправили в ВУЗ результаты ЕГЭ на 399 баллов по четырём предметам и выполнили вступительное на 98, а вам бы в ответе прислали “Попробуй еще раз, мало у тебя опыта прохождения отборов” — вас бы устроил такой вариант? Здесь абсолютно такая же ситуация.
2. Задание не работает, и более того, организаторы до последнего не хотят признавать это, считая своих конкурсантов полными дегенератами — размахивая мифическими 32 участниками, прошедшими отбор.
В чем проблема сказать: “Да, лоханулись, ща катнем фикс, все заработает”.
3. Формальные отписки с отказом. Типа иди получай “Опыт прохождения тестовых заданий” — что, простите?
4. Задания в школу по Go, требующие знаний Go… Убила просто постановка задачи “Задание можно выполнить только на Go”.
5. Молчанка при попытке узнать, написать на почту или в личку. “Мы не ожидали 4к людей”. А сколько вы ожидали? 15 человек? Достаточно странно ожидать небольшое количество участников и при этом пиарить школу на всех доступных платформах/чатах/каналах в рунете
Заключение
Ozon запустил школу для найма программистов, но в компании не были готовы к наплыву желающих. Еще больше ситуацию усугубила ошибка в тест-системе. Но даже когда компании предоставили готовый анализ, в Ozon не признали проблему.
Надежда, что Ozon одумается, теплилась до конца. Вечером 23 июня сотрудники компании опубликовали итоги отбора в Школу Go. В посте нашлось место статистике, описанию задач и даже неуклюжему признанию неполадок с заданием E. Но те, кто следил за этой историей, ждали совсем другого признания. Ozon выбрал простой путь: щедро сыпал обвинениями, лишь бы не замараться самому. Вдвойне иронично, что предложенные Ozon решения задания E тоже не проходят тесты на Яндекс.Контест. А ведь уже несколько недель у компании был сделанный нами детальный анализ проблемы. Он так и остался без внимания, найдя свой покой где-то в бездонных корпоративных инбоксах.
Ошибки случаются. Лучше их своевременно признать, чем тянуть до последнего, рассчитывая, что никто не заметит. А когда вас тычут носом в ваш провал, то упрямиться и поручать пиарщикам замять вопрос вовсе бессмысленно. И если данный разбор заставит хотя бы одну компанию тщательнее подходить к организации таких контестов, то этот текст написан не зря.
Ссылки
- ozon.dev/goschool (Лендинг)
- tproger.ru/events/ozon-golang-school
- techfusion.ru/ozon-tech-zapustila-besplatnyj-kurs-programmirovaniya-na-g
- rb.ru/news/ozon-go
- hh.ru/vacancy/36952478 (стажер Go)
- hh.ru/vacancy/36886891 (разработчик Go
- hh.ru/vacancy/36887550 (разработчик Go)
- contest.yandex.ru/contest/17728/problems (яндекс.контест)
Спасибо за помощь в написании статьи участников группы Gozone
Автор: Gasoid