Ozon go school: Как не нужно проводить отбор

    Go School


    Как вы знаете, в середине мая Ozon объявил о запуске школы программирования на языке Go. Обещали следующее:

    • бесплатное обучение
    • возможность получить знания по реальной разработке на Go от Ozon
    • возможность получить работу в Ozon

    Чтобы попасть в школу, нужно было:

    • иметь опыт промышленного программирования
    • пройти тестовые задания по программированию на платформе Яндекс.Контест
    • пройти skype-собеседования

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

    Тогда же было озвучено число студентов, которое готовы принять в Школу — около 40 человек.

    Так понемногу условия поступления прирастали новыми пунктами, среди добавленных также значилось:

    • желательно проживать в Москве
    • быть гражданином РФ
    • возраст старше 18 лет

    Но все это выяснилось уже позже, а пока предложение Ozon привлекло многих разработчиков. Пора было приступать к первому этапу: прохождению теста.

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




    Сперва надо было решить пять задач по программированию на платформе Яндекс.Контест. Первые четыре задания были типичными алгоритмическими задачками, которые обожают давать на собеседованиях. Эти задания можно было решить на любом языке из предложенного списка. Последнее — пятое — требовалось решать на Go.

    Задание E


    Описание
    Необходимо написать функцию func Merge2Channels(f func(int) int, in1 <-chan int, in2 <-chan int, out chan <-int, n int) в package main.
    Описание ее работы:
    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

    Как работают тесты для задания 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 тоже не проходят тесты на Яндекс.Контест. А ведь уже несколько недель у компании был сделанный нами детальный анализ проблемы. Он так и остался без внимания, найдя свой покой где-то в бездонных корпоративных инбоксах.

    Ошибки случаются. Лучше их своевременно признать, чем тянуть до последнего, рассчитывая, что никто не заметит. А когда вас тычут носом в ваш провал, то упрямиться и поручать пиарщикам замять вопрос вовсе бессмысленно. И если данный разбор заставит хотя бы одну компанию тщательнее подходить к организации таких контестов, то этот текст написан не зря.

    Ссылки



    Спасибо за помощь в написании статьи участникам группы Gozone

    UPDATE: OZON исправил работу чекера, теперь все работает как надо (прошел 1 месяц)
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 107

      +19
      Как то весьма ожидаемо от Озона. Они и не такое совершали и «сидели с покер-фейсом».
        +5
        Чего только стоит ситуация с хранением паролей в открытом виде
        2012 год — РРраз habr.com/ru/sandbox/45548
        2016 год — Двввааа interface31.ru/forum/index.php?topic=79.0
        2019 год — Трррри! habr.com/ru/news/t/459600
        Как минимум 7 лет их поливали критикой, указывая на очевидный косяк и даже этого не хватило, чтобы они признали и исправили свою ошибку.
        А ведь неизвестно сколько пользователей пострадало. Представьте себе среднестатистического пользователя, который весьма бережно хранит свои данные, но по незнанию использует одинаковые пароли на различных сервисах и почте. И вот 7 лет не хватило, чтобы озон заделали дырищу, из-за которой такой пользователь оказался под серьезной угрозой.
        0
        В памяти всплыл собственный горький опыт прохождения контестов лет 15 назад. Хочеться сказать, тогда это не было мейнстримом и воспринималось организмом как новая зубная пломба и когда от нее что-то отпадало то доктор ставивший пломбу переживал за качество ;)
          +2
          Не жалею что потратил несколько дней пытаясь решить задание E, приобрел хороший опыт. Хотя такое отношение организаторов немного расстраивает, не ужели чтобы собрать резюме не достаточно открыть вакансии на хх.
            +9
            Жаль потраченного времени. Весь опыт прохождения этого отбора сводится к тому, что не стоит учавствовать в подобных мероприятиях.
              +2
              Сама по себе задача Е была достаточно интересна, поэтому желание проверить варианты решений вдохновило одного из участников группы сделать сайт для проверки, где можно проверить свое решение и посмотреть код других правильных решений. Варианты правильных решений достаточно разнообразны. Более того, эта задача перекочевала и в бесплатный курс по Go на Stepike.
                +1
                Ну она была одна из самых простых заданий и затрат по времени меньше чем в остальных. Не считая невозможности прохождения.
                  0
                  Ну не знаю, все кроме Е мне показались не сложными — уровня первых двух на районных олимпиадах или кодфорсе, а над Е пришлось немного задуматься, почитать про каналы чтоб написать свое правильное решение, а потом пойти искать тех самых недобросовестных людей про которых писали организаторы.
              0
              Согласен. Тех, кто не остановился перед трудностями, эта ситуация заставила проработать самые сложные и не очевидные варианты, и в конечном итоге докопаться до сути. И заодно они поделились опытом с другими.
              Некоторые ВУЗы используют в своей программе задачи у которых нет решения. Это позволяет искать новые знания и придумывать новые подходы. Правда у Озона это вышло не намеренно.
              Будем надеяться, что первые блины дадут Озону хорошую почву развития и успеха.
                +3
                В нормально настроенном тестовом отборе, не должно быть возможности его взломать, чтобы посмотреть как работает проверка решения, и подставить ложное решение, которое вдобавок организаторами будет засчитано, потому что они на самом деле не проверяют код.
                +5
                И ведь могли бы взять себе действительно классных специалистов, кто докопался до сути и стоял до конца.
                  +3
                  я думаю что так и получилось, они набрали лучших. Только лучших в их понимании: возраст, пол, навыки, зарплатные ожидания(а их легко можно выявить косвенно по резюме). И тут все честно, лично мне просто для себя хотелось бы получить фидбек о своем техническом уровне по отношению к другим участникам контеста, а получил типовую отписку. Но опять же никто фидбеков не обещал, как говорится ваши ожидания — ваши проблемы )
                    0

                    проверка задания в конце не рабочее, в итоге много людей просто в заблуждении были

                      0
                      Да я как бы сам из тех кто несколько дней убил на это задание, думая что делаю что — то не так и все такие есть решение, еще 1 попытка, еще 1 рефакторинг, еще 1 подход к решению, еще 1 раз перепишу все заново и так по кругу )))) Хорошо что хоть из дома не выгнали.
                    +1
                    Видимо задача взять лучших именно в школу не стояла. Лучшим наверное сразу работу предложили.
                  +2
                  Самое обидное, что Ozon четко не сказали, что в задании/тестовой системе/конфигурации баг и в результате нельзя получить 'OK'. Все их ответы еще больше вводили в заблуждение. Эти мифические 32 человека, которые сумели выполнить задание Е, размытые формулировки, о том, что тест был составлен слишком широко — всё это только наталкивало на мысль, что ты заблудился в 3х соснах. Печалька.
                    0
                    Вот тоже самое хотел написать, потраченное время жалко.
                    +12

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

                      +2

                      Почему "плохо замаскированный"? Наоборот — громко объявленный на главной странице проекта :)


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


                      image

                        0

                        На лэндинге было написано "по итогам обучения", но скорее всего несколько офферов были сделаны по итогам отборочного конкурса. Так-то устроить качественную школу и похантить оттуда топовых выпускников — идея достойная, Яндекс это делает давно.

                      +3

                      Товарищи ex-Lazada не позорьте, а!


                      Надо было сразу заявлять об отборе на full time работу и, видимо, onsite. Нехорошо сделали.

                        –32
                        Привет!

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

                        Принять участие в школе может любой специалист, но поскольку для нас важно пригласить разработчиков на работу по окончании курса, было ограничение по возрасту 18+ — возможно, стоило написать об этом более явно. А вот жить в Москве и области не обязательно — в школу пригласили участников и из Санкт-Петербурга, Перми, Краснодара, Пензы, Челябинска, Екатеринбурга, Уфы, Брянска. При этом, учитывая конкурс в 55 человек на место, делать решение задач единственным фактором отбора не получится, просто потому что 4 из 5 задач решили многие — по той же причине скрыли лидерборд.

                        И о задаче Е — в ее условиях и алгоритме проверки мы допустили сразу несколько ошибок, и чтобы наши недоработки не повлияли на результат, не учитывали решение при прохождении отбора. Возможно, стоило убрать ее раньше – но тогда оставался риск потерять полученные решения, а значит, кто-то из участников мог лишиться своих 4 из 5.

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

                          Если вы действительно представитель Озона — как насчёт прокомментировать предметно то, что освещено в статье, в т.ч. "Я не я и хата не моя"? Пока что ваш ответ выглядит как жалкая попытка оправдаться и сгладить явные косяки.

                            +2
                            А зачем им что-то комментировать?
                            Задание было где?
                            пройти тестовые задания по программированию на платформе Яндекс.Контест

                            Виноват яндекс.
                              +3

                              Вы о чём? Ему PR отдел не разрешит дать прямой ответ. Вот я работаю на галере <большая_company_name> — любые публичные заявление при которых я говорю что-то от имени <большая_company_name> или даже просто заявляю, что я там работаю и моё мнение такое-то — я обязан согласовать с PR отделом (не суть важно, как именно отдел наазывается). Ну а публичное признание ошибок — это то, что ни одна сколько-нибудь большая компания не допустит. Исключения из этого правила — в основном небольшие компании, либо уж ну просто очень серьёзный факап, который зарегистрирован чуть ли не гос. органами.

                              +14
                              Одно дело совершить ошибку в задаче, это случается. Другое дело нагло врать о том, что «все нормально, 32 участника уже решили»
                                –9
                                Мы на самом деле получили 32 ответа с вердиктом «ок», и не вычитывали их до момента, пока не начали получать сообщения об ошибках. Но когда количество ответов с итогом Wrong Answer стало массовым, в попытке помочь участникам изменили настройку чекера — и в итоге задача, вместо того чтобы стать проще, перестала решаться вовсе. Действительно мы заметили это не сразу, но как только стало понятно, что ошибка на нашей стороне, сообщили всем участникам, что не будем засчитывать задание Е.
                                  +1
                                  что собственно Вам мешало не юлить, а просто обратить внимание на массовые репорты, а позже и на детальный разбор Вашей ошибки, или хотя бы попробовать самим отправить верное решение на тесты в контест и убедиться самим. Как и было написано в статье — решение задачи E которое было предложено Ozon, так же не проходило тесты.

                                  Нельзя ничего чинить, потому-что-
                                  Доработать это в режиме реального времени у нас нет возможности: есть риск потерять уже существующие решения.
                                  Серьезно? 32 участника которых никто не видел, но их решение каким-то не совсем ясным образом прошло сломанные тесты. Отсюда вопрос — почему эти результаты вообще важны и должны считаться легитимными если тесты сломаны, какой вообще тогда смысл прикрываться 32-мя решениями?
                                  Собственно что мешало исправить тесты тоже не понятно, написать что-то вроде — «да, мы тут нашли баг, наш косяк, уже исправили», аннулировать все результаты по задаче E, и попросить всех участников заново отправить свои решения на тест?
                                  Времени было достаточно.
                                    0
                                    Если Вам будет легче, я один из тех 32-х, у кого система приняла решение.
                                      0
                                      Роман, а можно посмотреть на Ваш код, который приняла система?
                                        +1
                                        Да, конечно
                                        package main
                                        
                                        import (
                                        	"fmt"
                                        	"time"
                                        )
                                        
                                        func main() {
                                        
                                        	n := 10
                                        
                                        	in1 := make(chan int)
                                        	in2 := make(chan int)
                                        	out := make(chan int)
                                        
                                        	go func(in1 chan<- int, n int) {
                                        		for i := 0; i < n; i++ {
                                        			fmt.Println("Write to in1: ", i)
                                        			in1 <- i
                                        		}
                                        	}(in1, n)
                                        
                                        	go func(in2 chan<- int, n int) {
                                        		for i := 0; i < n; i++ {
                                        			fmt.Println("Write to in2: ", i)
                                        			in2 <- i * 10
                                        		}
                                        	}(in2, n)
                                        
                                        	go func(out <-chan int) {
                                        		for i := range out {
                                        			fmt.Println("Read from Out: ", i)
                                        		}
                                        	}(out)
                                        
                                        	Merge2Channels(func(x int) int {
                                        		time.Sleep(time.Duration(x%3) * time.Second)
                                        		return x * x
                                        	}, in1, in2, out, n)
                                        
                                        	fmt.Println("Done")
                                        	fmt.Scanln()
                                        }
                                        
                                        type orderedNumer struct {
                                        	pos int
                                        	num int
                                        }
                                        
                                        //Merge2Channels merges 2 channels
                                        func Merge2Channels(f func(int) int, in1 <-chan int, in2 <-chan int, out chan<- int, n int) {
                                        
                                        	fin1 := make(chan orderedNumer)
                                        	fin2 := make(chan orderedNumer)
                                        
                                        	go funcNum(f, in1, fin1, n)
                                        	go funcNum(f, in2, fin2, n)
                                        
                                        	go mergeFNums(fin1, fin2, out, n)
                                        }
                                        
                                        func funcNum(f func(int) int, in <-chan int, fin chan<- orderedNumer, n int) {
                                        	pos := 0
                                        	for i := 0; i < n; i++ {
                                        		num := <-in
                                        		// fmt.Println("Read from in: ", num)
                                        		onum := orderedNumer{pos, num}
                                        		pos++
                                        		go func(f func(int) int, onum orderedNumer, fin chan<- orderedNumer) {
                                        			onum.num = f(onum.num)
                                        			// fmt.Println("Write to fin: ", onum)
                                        			fin <- onum
                                        		}(f, onum, fin)
                                        	}
                                        }
                                        
                                        func mergeFNums(fin1 <-chan orderedNumer, fin2 <-chan orderedNumer, out chan<- int, n int) {
                                        	nums1 := make(map[int]int, n)
                                        	nums2 := make(map[int]int, n)
                                        
                                        	sendPos := 0
                                        	for i := 0; i < n*2; i++ {
                                        		select {
                                        		case onum1 := <-fin1:
                                        			nums1[onum1.pos] = onum1.num
                                        		case onum2 := <-fin2:
                                        			nums2[onum2.pos] = onum2.num
                                        		}
                                        
                                        		// fmt.Println("Check ", sendPos)
                                        		sendNum1, ok1 := nums1[sendPos]
                                        		sendNum2, ok2 := nums2[sendPos]
                                        
                                        		if ok1 && ok2 {
                                        			out <- sendNum1 + sendNum2
                                        			sendPos++
                                        		}
                                        	}
                                        
                                        	for i := sendPos; i < n; i++ {
                                        		sendNum1 := nums1[i]
                                        		sendNum2 := nums2[i]
                                        		out <- sendNum1 + sendNum2
                                        	}
                                        }
                                        



                                        решение было принято 13-го мая
                                        0
                                        Система не была поломана на старте, это случилось позже, когда перенастроили «для улучшения вывода ошибок». По крайней мере так оно выглядит. Ниже есть тред с техническим описание того, что случилось. До фикса даже референсные решения из соседней статьи от озона не работали.
                                  +3
                                  Видимо было еще и возрастное ограничение сверху, но об этом нам не скажут. А можете озвучить максимальный возраст ученика взятого в школу по результатам отбора?
                                    +1
                                    Если озвучат, их какой-нибудь надзор вздернет.
                                      0
                                      да, что-то упустил этот момент — сейчас вроде даже в институты ограничений по возрасту нет, а в союзе до 35 лет только брали.
                                      0

                                      Это да… пытался тут мидл программистом андроида удаленно устроится — не берут )


                                      Возраст 40+. Опыт программирования на многих языках. В мега-супер проектах не участвовал, но есть приложения на маркете, которые живут со времен андроида 2. Есть опыт программирования на жаве со времен 1.4.

                                        0
                                        Уверены что дело в этом? Просто учитывая дефицит специалистов как то тяжело поверить в такое, хотя не исключаю что может быть правдой.
                                        Может стоит хайповые темы и знание модных библиотек еще подтянуть? Всякие там корутины, архитектуры и архитектурные принципы, и прочее что обычно в вакансиях болтается? На гитхаб чего нибудь выложить и попросить кого нибудь проверенного отревьюить. Я конечно молодой, что мне скидку делает в глазах работодателей, но в андроид и вовсе из 1с перепрыгнуть умудрился.
                                          0

                                          Я использую rxjava и room в последних приложениях, делаю верстку экранов не на horizontal/vertical/border layout с клеем, а на ConstraintLayout, и вместо SimpleCursorAdapter использую RecyclerView.


                                          Мне в лучшем случае присылают ответ: "вы нам не подходите". Вполне возможно hr специалисты отсекают мое резюме по ключевым словам, хотя скорей всего по возрасту. Сеньору 25 лет страшно работать с дяденькой, который программировал на ассемблере z80, когда он еще не родился.


                                          И, да, 1с я тоже программирую. Нормальный программист выбирает язык под задачу — так меня учили в школе )

                                            0
                                            А с архитектурой у вас как? MVP, MVVM, MVI, редакс какой нибудь или что нибудь более экзотическое? С тестами? На гитхабе есть что нибудь?
                                            Эйджизм конечно существует, но насколько мне известно чтобы его преодолеть достаточно приложить усилий не немногим больше чем молодежи. По крайней мере если человек уже программист, а не из маркетинга, например, приходит.
                                              0

                                              Еще раз: меня просто не зовут на собеседования программиста андроид.


                                              Программистом 1с позвали с первой рассылки (резюме другое).

                                                0
                                                Ну так я и рекомендую что подтянуть и сделать чтобы позвали. Это в 1с требования очень низкие, лишь бы код писать умел. На другие стеки, тем более в возрасте, подтверждения и знания серьезнее нужны.
                                      0
                                      Покайтесь! И исправьте наконец чекер на контесте :)
                                        0
                                        А почему сразу то не признали ошибку? Без этих вот ивиливаний.
                                        +3

                                        Я совершенно не понял ваше описание проблем с задачей E в посте, хотя сам готовил много "классических" задач под разные системы (в том числе Я.Контест). Впрочем, пост в Telegram кое-то прояснил, процитирую:


                                        и дальше наша теория того, что произошло:
                                        1) они настроили задачу по умолчанию, stdout был включен, они прогнали свой тест — все ок, соответственно в run.sh они не добавляли перенаправление
                                        2) они пошли смотреть как выглядит страничка для участников, увидели что там "стандартный вывод" в поле "Вывод" под названием задачи и сделали "рефакторинг" — отключили его, установили имя файла как "см формат вывода", не проверили авторское решение (там есть кнопка "пересудить" для него)
                                        (есть еще вариант что они по какой-то другой причине отключили stdout не сразу, а через пару дней, но это на суть не влияет)

                                        Вот это уже звучит реалистично. Вполне разумная схема для впихивания нетривиальных задач в олимпиадную систему: компилируем участника вместе со своими юнит-тестами, запускаем, упало — Runtime Error, не упало — всё прошло. Чекер тривиален и ничего не проверяет.


                                        Правда, совершенно непонятно, как тут можно разумно получить Wrong Answer, если уж чекер тривиален.


                                        Для контекста: практически все системы для олимпиад работают по одной и той же схеме, сомневаюсь, что Я.Контест сильно отличается:


                                        1. Предполагается, что решение задачи — отдельная программа, читает некоторые данные, выводит некоторые данные, всё за ограниченное время. Решение помещается в один файл. Это позволяет поддерживать сразу кучу языков, только бы компилятор был.
                                        2. При создании задачи выставляется "имя входного файла", "имя выходного файла", а также список пар (входные данные, "ответ жюри" на тест) плюс специальный "чекер".
                                        3. Каждое решение система "компилирует" в один файл. В очень творческом смысле — например, действительно, скопировав исходники в архив.
                                        4. Далее на каждом тесте система независимо "запускает" решение, подсунув входной файл. Выходной файл решение должно создать самостоятельно. Файл с "ответом жюри" в этот момент в песочнице отсутствует, чтобы участник не скатать.
                                        5. Если решение упало (ненулевой код возврата) или заняло много времени, то оно убивается. Получаем либо Runtime Error, либо Time Limit Exceeded (много процессорного времени в каком-то из смыслов), либо Idleness Limit Exceeded (процессорного мало, но много wall clock, например, решение заблокировалось на чтении). Иногда дополнительно после этого проверяется наличие созданного выходного файла (увы, не помню, как в Я.Контесте).
                                        6. Если решение не упало и прошло по времени, то в песочницу копируется файл с ответом жюри и запускается чекер. На обычных контестах обычно пишется на testlib и принимает три аргумента командной строки: входной файл, выходной файл (который должен был создать запуск участника), только что скопированный файл с ответом жюри. В целом "файл с ответом" может быть творческий и содержать не ответ, а какую-то подсказку для чекера, но это не очень хорошо.
                                        7. Если чекер вернул 0 — ответ засчитан. Иначе — Wrong Answer, Presentation Error, Jury Error ("всё сломалось, зовите жюри разбираться"), в зависимости от настроек.
                                          0
                                          Правда, совершенно непонятно, как тут можно разумно получить Wrong Answer, если уж чекер тривиален.


                                          А все просто — чекеру не приходили данные.

                                          Процитирую первую часть сообщения:
                                          чтобы чекер работал надо чтобы был включен stdout или run.sh писал в файл (у них как мы видели не пишет)
                                          дальше чекер может хитро проверять вывод, в их случае мог бы проверять время тестов или как-то по другому парсить вывод go test — но как мы видели, даже если записать пробел в файл то чекер говорит ок, соответственно никакой пользовательской логики в нем нету. если чекер возвращает 0 — платформа пишет ok (https://admin.contest.yandex.ru/docs/advanced-usage-examples/default-tests-for-language.html)
                                            0

                                            Если чекер тривиален, он не проверяет данные никак и пустой вход его тоже устроит. Если чекер нетривиален, то он не будет съедать абсолютно любой ввод. Чекер, которые проверяет, что вход непуст — это что-то очень странное.


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

                                              +2
                                              Выходной файл, как ни странно, создается системой автоматически (как мы видели).
                                              Presentation error мы ни разу не видели.

                                              Что конкретно проверяет их чекер мы не видели, это недоступная информация.
                                              Мы создали свой контест и использовали простейший пример чекера из статьи.

                                              Я могу лишь предположить, что их чекер искал в файле слово FAIL (вывод go test) и проверял что файл не пуст (так как файл создается автоматически всегда).

                                              Кстати, любой желающий может создать свой контест и посмотреть как он работает. Какие-то нюансы мы могли и пропустить.
                                                +2
                                                Кстати пару часов назад они кликнули нужную галку (включили stdout) и теперь задача работает. А всего-то надо было это сделать месяц назад :-D
                                                  0
                                                  И вправду
                                                  image
                                          +1
                                          Отличная статья!!! Тот разбор задачи и ситуации, который ждали от Озона. Первые подозрения о качестве организации закрались, когда Озон опубликовал статью о преподавателях, которые будут обучать. Основная масса лекторов с опытом разработки на go меньше года. При этом в вебинаре Озоновцы сказали, что у них 200 go программистов. Получается, что на организацию школы и обучение смогли выделить только джунов.
                                            +5

                                            После того, как я из задания E достал Makefile, shell-скрипты и их код на go, и указал им на их ошибку по почте, мне вообще больше не ответили ни да, ни нет, просто молчание.

                                              +5

                                              а нас таких в группе было 170 человек, и каждый думал, что проблема у нас

                                              +10
                                              А я благодарен озону, сделал два вывода из этой истории: 1) Go не быстрее Python, но сложнее в написании.(меньше ест памяти) 2) Крупные it компании России далеки от того места где хотелось бы работать. (лицемерие и обман не прибавляют доверия).
                                                0
                                                ну и да, было приятно коллегам в понедельник рассказывать решение задачи о поиске двух слогающих числа target и смотреть на их удивление от простоты решения
                                                  +3
                                                  Go быстрее Python и не сложнее.
                                                    –1
                                                    Да и не понятно, зачем было С++ переименовывать в первые две буквы гугла ))) и выдавать за новый ЯП.
                                                      0
                                                      C++ и Go одинаковы?
                                                        0
                                                        Абсолютно разные языке же.
                                                      +1

                                                      Я программировал на обоих. Мое сугубое имхо: Go быстрее, дает более компактные докер образы, и не сложнее. Есть своя специфика — он более явный, ты больше пишешь, явно обрабатываешь ошибки, явно запускаешь горутины, вместо всей машинерии с async/await/task. Питон более лаконичный: те же comprehensions, with, и прочее, что позволяет в несколько строк написать много действий.
                                                      Не хочу скатываться в холивар — у каждого инструмента свое применение, в котором он хорош.

                                                        –2
                                                        Согласен, не может компилируемый язык быть медленнее интерпретируемого, но именно это случилось на мероприятии, о котором идет речь(что удивительно и о чем я написал выше). И да ЯП это только инструмент, главное кто и как им пользуется.
                                                          0
                                                          Если алгоритм сильно упирается в I/O или какие другие блокирующие вызовы, то языки по производительности мало будут отличаться друг от друга. Ничего удивительного нет.
                                                            0
                                                            Так они в итоге сильно отличаются. В задаче 3, написал на 3 языках. Go с TL на 7 уровне застрял, Python дошел до 9 уровня с 201мс (но сьел 86мб), C++ прошел 9 уровень с 189 мс и съел 42мб.
                                                              +1
                                                              Тут ещё смотря как код написан. В C++ легко выстрелить себе в ногу и получить много лишних копирований при передаче значений из функции в функцию, а в Питоне, например, получим просто передачу указателя.
                                                                0
                                                                из функции в функцию? А мы точно об одном и том же говорим? Там несколько ветвлений и итераций
                                                                0
                                                                У меня в этой задаче на Питоне получалось либо большое потребление памяти (86.25Mb при 299ms на 9 тесте), либо по времени не укладывался (1.586s при 3.98Mb на 8 тесте). Золотую середину найти так и не удалось. Интересно, реально ли вообще её решить на Питоне с поставленными ограничениями?
                                                                  0
                                                                  Пробовал сборщик мусора и типизацию всего, становилось хуже. Думаю реально, но надо больше времени
                                                                    0
                                                                    Думаю реально, но надо больше времени
                                                                    Реально (но уже с новым ограничением в 1.5 секунды.) :)
                                                                    (Если прочитать всю входную строку с сделать split() — не хватает памяти
                                                                    («9: memory-limit-exceeded 189ms / 74.14Mb»).
                                                                    Срабатывает, если, например, вручную по прочитанной строке пройти, находя числа по одному. (Читать сразу из входа по 1 символу было слишком долго).
                                                                    Регулярные выражения не пробовал.)
                                                                    Python 2.7
                                                                    № Вердикт Ресурсы Баллы
                                                                    1 ok 32ms / 2.38Mb -
                                                                    2 ok 32ms / 2.38Mb -
                                                                    3 ok 33ms / 2.38Mb -
                                                                    4 ok 32ms / 2.38Mb -
                                                                    5 ok 34ms / 2.38Mb -
                                                                    6 ok 367ms / 3.29Mb -
                                                                    7 ok 246ms / 4.86Mb -
                                                                    8 ok 1.438s / 4.86Mb -
                                                                    9 ok 333ms / 26.05Mb -


                                                                    # -*- coding: utf-8 -*-
                                                                    IN_FILE = 'input.txt'
                                                                    OUT_FILE = 'output.txt'
                                                                    
                                                                    seen = set()  # Было
                                                                    result = 0  # ничего не нашли
                                                                    
                                                                    def get_number(st, start):
                                                                        result = ''
                                                                        i = start
                                                                        l = len(st)
                                                                        while st[i].isdigit() and i < l - 1:
                                                                            result += st[i]
                                                                            i += 1
                                                                        # forward to next number if any
                                                                        while not st[i].isdigit() and i < l - 1:
                                                                            i += 1
                                                                    
                                                                        if len(result):
                                                                            return int(result), i
                                                                        else:
                                                                            return None, None
                                                                    
                                                                    
                                                                    with open(IN_FILE) as f:
                                                                        target = int(f.readline())
                                                                        # for number in [int(x) for x in f.readline().split()]: # Out-of-memory
                                                                        next = 0
                                                                        numbers = f.readline()
                                                                        while(True):
                                                                            number, next = get_number(numbers, next)
                                                                            if number is None:
                                                                                break
                                                                            complement = target - number
                                                                            if complement > 0 and complement in seen:
                                                                                result = 1
                                                                                break
                                                                            seen.add(number)
                                                                    
                                                                    # print(target, result)
                                                                    
                                                                    with open(OUT_FILE, "w") as f:
                                                                        f.write(str(result))
                                                                    


                                                                    Во время конкурса решилось на С++ (после попыток на других языках).
                                                                      0
                                                                      Теперь покажу как O(n) -> O(n)⁄4.
                                                                      На последнюю задачу много времени потратил, после стало не интересно пробовать и некогда.
                                                                      import sys
                                                                      data = open('input.txt', 'r')
                                                                      target, sequence = data.read().splitlines()
                                                                      target = int(target)
                                                                      digits: List[int] = [map(int, sequence.split()))
                                                                      file_out = open('output.txt', 'w')
                                                                      x = target//2
                                                                      y = target -x
                                                                      if(x==y):
                                                                          y+=1
                                                                      z = tuple(filter(lambda u: u<=x, digits))
                                                                      w = tuple(filter(lambda u: u>=y, digits))
                                                                      for i in z:
                                                                          for j in w:
                                                                              if i+j==target:
                                                                                  file_out.write('1')
                                                                                  sys.exit()
                                                                      file_out.write('0')
                                                                    0
                                                                    Видимо вы что-то не то делаете, 3 задача (F) решается с помощью порционного чтения, где надо бросто выбрать размер буфера. У меня вышло на питоне 357ms 3.97Mb
                                                                      0
                                                                      А можно увидеть ваш код, как вами было это реализовано?
                                                                        0
                                                                        Конечно
                                                                        from itertools import chain
                                                                        result = "0"
                                                                        trash = set()
                                                                        with open("input.txt", "r") as in_file:
                                                                            target = int(in_file.readline())
                                                                            prev = ""
                                                                            while True:
                                                                                chars = in_file.read(1000)
                                                                                if chars:
                                                                                    numbers_str = chars.split(" ")
                                                                                    first = numbers_str[0]
                                                                                    last = numbers_str[-1]
                                                                                    numbers = map(lambda x: int(x), numbers_str[1:-1])
                                                                                    if prev == "":
                                                                                        first = int(first)
                                                                                    elif first == "":
                                                                                        first = int(prev)
                                                                                    else:
                                                                                        first = int(prev + first)
                                                                                    prev = last
                                                                                    for number in chain([first], numbers):
                                                                                        if number < target:
                                                                                            if number in trash:
                                                                                                result = "1"
                                                                                                break
                                                                                            trash.add(target - number)
                                                                                    if result == "1":
                                                                                        break
                                                                                else:
                                                                                    break
                                                                        
                                                                        with open("output.txt", "w") as out_file:
                                                                            out_file.write(result)
                                                                        


                                                                        Не идеальное решение, но имеет место быть
                                                                      0
                                                                      Я решил. Все задачи кроме последней на питоне (и SQL).
                                                                      Но пришлось очень аккуратно подгонять размер кусков считывания входного файла. =)
                                                                        0
                                                                        16 май 2020, 00:24:50 33060438 F Python 3.7.3 OK — 0.931s. 3.95Mb
                                                                        def f_sum_of_two():
                                                                            has_sum = 0
                                                                            diffs = set()
                                                                            digits = ""
                                                                            with open("input.txt") as f:
                                                                                target = int(f.readline().rstrip())
                                                                                while True:
                                                                                    char = f.read(1)
                                                                                    if not char:
                                                                                        break
                                                                                    if not char.isdigit():
                                                                                        number = int(digits)
                                                                                        digits = ""
                                                                                        if number > target:
                                                                                            continue
                                                                                        if number in diffs:
                                                                                            has_sum = 1
                                                                                            break
                                                                                        diff = target - number
                                                                                        diffs.add(diff)
                                                                                    else:
                                                                                        digits += char
                                                                        
                                                                            with open("output.txt", "w") as f:
                                                                                f.write(str(has_sum))
                                                                    +1
                                                                    В Go очень медленный стандартный ввод (через fmt.Scan() ) — нужно читать ввод через bufio. С++ в этом плане гораздо быстрее считывает данные стандартными средствами cin, отчасти поэтому всех начинающих олимпиадников на него с питона пересаживают (можно посмотреть код решения подобных задач на разных языках на кодфорсе)
                                                                      0
                                                                      Может в этом проблема, я с Go знаком поверхностно. Мне ввод и вывод коллега писал.
                                                                       file, err := os.Open("input.txt")
                                                                       if err != nil {
                                                                        panic(err)
                                                                       }
                                                                       defer file.Close()
                                                                       data := make([]byte, 64)
                                                                       for {
                                                                        n, err := file.Read(data)
                                                                        if err == io.EOF {
                                                                         break
                                                                        }
                                                                        str += string(data[:n])
                                                                       }
                                                                        0
                                                                        Чтение маленькими блоками, я бы блоками меньше 4к не читал никогда, ибо размер страницы памяти. А еще с маленькими блоками больше перевыделений памяти при сложении.
                                                                          0
                                                                          Спасибо, передам коллеге завтра.
                                                                          +1

                                                                          Строки в Go иммутабельны, при выполнении конкатенации каждый раз создаётся новая строка.


                                                                          Go не быстрее Python, но сложнее в написании.

                                                                          Странно делать такой вывод, если знакомство хотя бы с одним из языков — поверхностное

                                                                            0
                                                                            У Вас более странный вывод относительно моего вывода. Видимо, это следствие поверхностнных знаний относительно понятия Вывод. Вывод (лат. conclusio) в логике — процесс рассуждения, в ходе которого осуществляется переход от некоторых исходных суждений (предпосылок) к новым суждениям — заключениям. Вывод может проводиться в несколько этапов—умозаключений.
                                                                  0
                                                                  тоже переписал решение задачи е раз 5 )
                                                                  побаловался с go
                                                                  нашел душевный чатик и поучаствовал в ковыряниях палочкой в этом всем ))
                                                                  в целом неплохо провел время.
                                                                  главное, имхо, как и в любом деле, вовремя соскочить )
                                                                    +2
                                                                    Идея школы была интересна многим в её изначальном представлении — чисто онлайн (особенно учитывая текущие обстоятельства) школа про go. Уже потом мы заметили, что FAQ на сайте стал меняться и появились новые условия :-)

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

                                                                    Весь сыр бор из-за Е начался именно из-за того, что задача выглядела простой, но не работала. Многие потратили бОльшее время на решение, чем ожидали. Я потратил 2 ночи на задание: 1ую — пытаясь переписать задание по-разному, потом написал свои тесты с нереальными угловыми случаями и в итоге так перестарался с решением, что потратил вторую ночь ловя дедлоки. И даже это задание не прошло.
                                                                    Надо, конечно, было бы раньше полезть в систему и посмотреть почему так, тут сам виноват :-)
                                                                    И вот когда мы нашли косяки в системе, тогда то нас и пробило на «добиться правды».

                                                                    Тем, кто не участвовал, наверно все это кажется дичью, и оно, от части, так и есть :-)
                                                                    В общем то, эта статья — это просто наша попытка привнести правду в случившееся и показать, что признавать ошибки — это правильно, а юлить — не очень :-)
                                                                      +1

                                                                      Получил моральное удовлетворение от вашей публикации. Вы описали весь мой путь от и до. За исключением того:


                                                                      • через панику и ошибки последний тест я продебажил самостоятельно за 63 подхода.
                                                                      • на мои два письма о проблемах контеста мне никто не ответил

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

                                                                        0
                                                                        А мой комментарий к Озоновской статье
                                                                        habr.com/ru/company/ozontech/blog/507932
                                                                        так и ожидает модерации.
                                                                        И почему я не удивлен :)
                                                                          +2
                                                                          Мой коммент тоже на модерации (писал в ответ на то что отписки получили те кто решил 3 и менее задач). Решил 4 задачи (и по задаче Е прислал решение), но получил такую же отписку: «Побольше практики: участвуйте в проектах, чемпионатах, олимпиадах.». Причем мое решение такое же как описано в той статье. Возможно, все из-за того, что не завершал тестирование до последнего, ожидая какого-либо прояснения информации по задаче Е.
                                                                            0
                                                                            Мой коммент тоже на модерации (писал в ответ на то что отписки получили те кто решил 3 и менее задач). Решил 4 задачи (и по задаче Е прислал решение), но получил такую же отписку: «Побольше практики: участвуйте в проектах, чемпионатах, олимпиадах.».
                                                                            Мне прислали такое же письмо (тоже решил 4 и Е (сейчас то же самое (плюс коммент, чтобы формально отличалось) решение, что давало «WA», даёт «OK» (говорят, недавно (уже после подведения результатов) тестирование починили)).

                                                                            Причем мое решение такое же как описано в той статье. Возможно, все из-за того, что не завершал тестирование до последнего, ожидая какого-либо прояснения информации по задаче Е.
                                                                            Вероятно, лучше не искать закономерностей там, где их нет (и держаться подальше от болот).
                                                                          +4
                                                                          Участвовал в данном тестировании.
                                                                          Я один из требований и описания тестирования/школы понял, что для прохождения тестов необходимо знание какого то ЯП и не обязательно GO?

                                                                          Прошёл все тесты на Питоне и был сильно удивлён заданию на Go. В школу Go. Которое не работает. =)
                                                                            +1

                                                                            Да, прикольно получилось )
                                                                            Задание на Go шло как дополнительное, если уже имеешь где-то посмотрел go, прошел go tour, то можешь показать знания.
                                                                            Но в итоге так и вышло — задание необязательное :)

                                                                              0
                                                                              А у вас случайно не осталось решения задачи «F. Сумма двух» на Питоне, которое прошло тесты Яндекс Контеста? Очень хотелось бы на него взглянуть.
                                                                                0
                                                                                конечно осталось. =)
                                                                                За 80 истраченых попыток я успел:
                                                                                — Вычитать все сходные параметры.
                                                                                — Составить карту верных ответов (если за 95 попыток не получится).
                                                                                — Попробовать несколько вариантов оптимизации в плане обработки и хранения данных.
                                                                                — Побиться головой о стену )

                                                                                Прошу не судить строго, я его только начал пробовать)
                                                                                input_file = open("input.txt")
                                                                                
                                                                                target = input_file.readline()
                                                                                target = int(target)
                                                                                
                                                                                numbers_trg = []
                                                                                chunk_len_def = 2200000
                                                                                chunk_len = chunk_len_def
                                                                                tail = ""
                                                                                is_exit = 0
                                                                                is_double = 0
                                                                                
                                                                                while chunk_len > 0:
                                                                                    chunk = input_file.read(chunk_len_def)
                                                                                    chunk_len = len(chunk)
                                                                                
                                                                                    if chunk_len == 0:
                                                                                        break
                                                                                
                                                                                    split_chunk = [int(i) for i in chunk.split()]
                                                                                
                                                                                    if chunk[0].isdigit() and tail != "":
                                                                                        split_chunk[0] = int(str(tail) + str(split_chunk[0]))
                                                                                
                                                                                    if chunk[-1].isdigit() and chunk_len == chunk_len_def:
                                                                                        tail = split_chunk[-1]
                                                                                        split_chunk.pop(-1)
                                                                                    else:
                                                                                        tail = ""
                                                                                    if len(split_chunk) == 0:
                                                                                        break
                                                                                
                                                                                    if target % 2 == 0:
                                                                                        is_double += split_chunk.count(target / 2)
                                                                                        if is_double > 1:
                                                                                            is_exit = 1
                                                                                            break
                                                                                    if len(list(filter(lambda x: target - x in numbers_trg, set(split_chunk)))) > 0:
                                                                                        is_exit = 1
                                                                                        break
                                                                                
                                                                                    numbers_trg.extend(list(filter(lambda x: x < target and not x in numbers_trg, set(split_chunk))))
                                                                                    split_chunk.clear()
                                                                                    chunk = ""
                                                                                    #print(numbers_trg)
                                                                                    #print(split_chunk)
                                                                                    #print(is_exit)
                                                                                
                                                                                imin = 1
                                                                                imax = target - 1
                                                                                
                                                                                while imin < imax and is_exit != 1:
                                                                                    if imin in numbers_trg and imax in numbers_trg:
                                                                                        is_exit = 1
                                                                                
                                                                                    if is_exit == 1:
                                                                                        break
                                                                                
                                                                                
                                                                                    imin += 1
                                                                                    imax -= 1
                                                                                
                                                                                
                                                                                input_file.close()
                                                                                
                                                                                output_file = open("output.txt", "w")
                                                                                
                                                                                #print(f"{imin},{imax},{is_exit},{is_double},{numbers_trg}")
                                                                                
                                                                                if is_exit == 1:
                                                                                    output_file.write("1")
                                                                                else:
                                                                                    output_file.write("0")
                                                                                




                                                                              0
                                                                              удалено
                                                                                +1
                                                                                В ВК была компания рекламная, мелькала в ленте. «По словам организаторов, заявки подали более 4000 человек, что стало неожиданностью для них.» — слабо верю в эту неожиданность.
                                                                                  +3
                                                                                  возможно, морально готовят к реальной работе. когда постановка задачи корявая, обратная связь не работает, а в отделе тестирования сплошь норкоманы. в общем, всё правильно сделали.
                                                                                    +5

                                                                                    Именно реакция на такие ситуации и формирует репутацию технологической компании.


                                                                                    OZON: WA

                                                                                      +18

                                                                                      Ozon объявляет о наборе нубов в школу Go, "нубы" прут с такой силой, что хакают платформу проведения тестов Яндекса, запускают playground правильной проверки задания, объясняют Озону как надо делать сборку, попутно х##сося его на Хабре.


                                                                                      Шел 5 месяц самоизоляции :)

                                                                                        +2
                                                                                        вот- вот, может, все- таки хакнувшие платформу попали в какой- то особый лист и их сразу утащат на работу в отдел кибербезопасности, например?
                                                                                          +1
                                                                                          мечты…
                                                                                        +6
                                                                                        В очередной раз PR отдел крупной российской компании показал свою недееспособность. Как-то уже в порядке вещей.
                                                                                          +4
                                                                                          До начальства ваш пост скорее всего не дойдёт, а менеджер за это отвечающий очень не хочет выглядеть идиотом и прилюдно обделаться. К сожалению, в менеджеры часто набирают кого попало.
                                                                                            +1
                                                                                            Предположу, что это было так:

                                                                                            Приходит hr к одному из лидов со словами: «Нам для pr нужно то-то.» Лид отрывает пару человек от задач и говорит: «С вас задачи на конкурс». За небольшое время появляется контест и рабочие руки возвращаются к таскам в спринте. Далее происходит то, что происходит.
                                                                                              0

                                                                                              Хотел принять участие, но решил, что опыта маловато. Как оказалось — не зря, убил бы время и нервы. Кстати, школа-то вообще работает? Или это просто был замаскированный набор сотрудников?

                                                                                                0
                                                                                                Видимо у меня одного были проблемы с формулировкой задач
                                                                                                  0
                                                                                                  Сложности связаны также с тем, что Go — новый язык для платформы

                                                                                                  Не понятно, зачем вообще было связываться с Яндексом. На том же CodeForces в списке поддерживаемых Go уже довольно давно.

                                                                                                    +1
                                                                                                    Да достаточно знать, что они состоят в АКИТ, чтобы игнорировать все их проявления жизнедеятельности.
                                                                                                      +1
                                                                                                      Что-бы вы понимали, у OZONа не только тут косяки. Весь OZON в той, или иной мере косячен с ног до головы, начиная с работы с партнерами, которые поставляют товары и месяцами ждут ответ саппорта на внезапные блокировки и т.д., заканчивая переносами некоторых доставок неделями и последующей отменой некоторых позиций.

                                                                                                      Там в целом набрали команду не пойми кого, которые работают не пойми как. )
                                                                                                        0
                                                                                                        Сколько я не взаимодействовал с озоном как клиент, у меня всегда остается ощущение, что это компания застрявшая в начале нулевых. Какими они были тогда, такими они и остались.
                                                                                                        0

                                                                                                        Да, жаль только потраченного времени. Ну может заменят криворуких программистов теперь.

                                                                                                          0
                                                                                                          Заменят это вряд ли — разве что повысят.

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

                                                                                                        Самое читаемое