В IT тема спортивного (соревновательного, олимпиадного) программирования очень спорная. Я это замечал и здесь на Хабре, и в работе. Не раз я слышал о том, что навыки, полученные на соревнованиях или при подготовке, никак не помогают в работе, а в худшем случае, даже мешают и создают проблемы другим.

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

Что это такое

Давайте немного напомню, как выглядят соревнования (контесты) по программированию. В самом классическом виде вы участвуете командой из 3-х человек за одним компьютером без интернета. Вам даётся 5 часов времени и 10-12 алгоритмических задач. Да-да, тех самых, что так любят спрашивать на собеседованиях или LeetCode. Решения проверяются автоматически на основе набора тестов, которые участникам неизвестны. Кто больше задач решил, тот и победил. А при равенстве учитывается количество попыток решения.

Есть и индивидуальные форматы, которые меньше по времени. Есть различные варианты оценки результатов, онлайн форматы. Но суть всегда примерно одинакова — есть задачи, участник пишет код, система автоматически проверяет решение и выдаёт вердикт.

Пример такой задачи
Пример такой задачи

Как я туда попал

На первом курсе университета (СибГУТИ) у нас организовали олимпиаду по программированию и я решил поучаствовать. До этого я никогда не сталкивался с этим, даже не знал, как это происходит. Но нам обещали какие-то плюшки, что было очень значимо в то время, поэтому я решил поучаствовать.

За 5 часов я умудрился решить 2 задачи. Одна из них — утешительная. Такая всегда есть в наборе, чтобы никто не ушёл с нулём. А вот вторая — была вполне себе нормальная. И я без знаний каких-то алгоритмов, попытки с 20-й смог её решить. Счастливый случай, который сильно изменил мою жизнь.

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

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

Программирование — это спорт

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

Почему-то в IT эта логика немного ломается. Опыт в спортивном программировании зачастую является даже минусом, приходится доказывать, что ты «нормальный» программист. Отчасти это основано на том, что решения бывших «олимпиадников» одноразовые, не поддерживаемые. Это следствие специфики соревнований — тебе не нужно писать качественный код, который будут читать через 5-10 лет другие люди, тебе нужно решить задачу здесь и сейчас.

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

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

  • Умение сформулировать проблему. Соревновательная задача обычно описана естественным языком, из которого тебе еще нужно понять суть, составить математическую модель, доказать её, проверить.

  • Качественный результат. Твоё решение должно решать поставленную задачу, желательно с первого раза. Поэтому, ты проверяешь и перепроверяешь его. Отрабатываешь граничные кейсы, сам придумываешь тесты и сам тестируешь.

  • Умение работать в условиях ограничений, давления. 5 часов на 10-12 задач — это очень мало, на самом деле. Часто приходится выбирать, в какие задачи вкладывать усилия в первую очередь, а какие отбросить.

Это же ровно те качества, которые нужны нам в работе. Я на себе ощущал, насколько проще мне справляться с некоторыми задачами. А навык написания кода можно подтянуть. Тем более, что от команды к команде они отличаются.

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

Спорт и работа

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

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

Часть моей презентации для руководства компании
Часть моей презентации для руководства компании

Делаю своё

Для проведения внутренних контестов нужна была площадка. Какой-то аналог LeetCode или Codeforces, но попроще, чтобы можно было легко развернуть локально и не тратить дни на настройку. Я перепробовал, наверное, десяток вариантов, включая классические PCMS2 и Ejudge, а также ряд безымянных опенсорсных решений. Но всё было не то: часть поставлялась без исходного кода и возможности развития, а часть была слишком сложной и громоздкой в администрировании для моих локальных задач. Идеалом на тот момент была система нашего университета — на ней я тоже проводил пару соревнований. Она была достаточно простой и надёжной, но, увы, тоже без исходников.

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

Я взял привычные для себя на тот момент (2015-2016 года) технологии: .net 4.5, MSSQL, EF,  ASP.NET Web Forms, jQuery. Сердце системы, компонент, который должен запускать решения участников, ограничивать их по времени и памяти, мне долгое время не давался — не хватало знаний по WinAPI. Поэтому я взял готовое приложение, которое запускает другие приложения с нужными мне опциями. Но этого было достаточно, система работала.

Со временем проект переехал на современные технологии (.NET 8, React TypeScript), но привязка к Windows осталась. Думаю, для небольшого проекта это допустимо.

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

Создание собственной платформы не было самоцелью или попыткой сделать убийцу TopCoders. Мне просто хотелось иметь удобный локальный инструмент, чтобы проводить внутренние соревнования для коллег и студентов. Для меня это был способ развивать инженерную культуру вокруг себя, объединять людей со схожими интересами и показывать им, что программирование — это не только закрытие тикетов в Jira, но азарт, соревнование.

Соревнование или развлечение

Можно точно утверждать, что если вы ни разу не решали «олимпиадные» задачи, то типичные соревнования вам не понравятся — порог входа всё-таки высоковат. Высок шанс решить всего 1-2 задачи, расстроиться и больше никогда к этому не притрагиваться. Это можно также сравнить со спортом — есть профессионалы, а есть те, кто просто хочет иногда поиграть с коллегами в волейбол после работы. Интересно играть, когда все примерно одного уровня.

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

Так, например, родился формат, в котором нужно проявить свою «мультиязычность» — один язык программирования можно использовать только для одной задачи, поэтому не получится использовать только привычные инструменты, придется вспомнить что-то экзотическое — perl или даже 1С.

Но самый мой любимый формат — это первоапрельские соревнования, идею которых я подсмотрел у тех же CodeForces. Суть таких соревнований в том, что знания программирования, алгоритмов здесь вообще не важны. Потребуется наблюдательность, нестандартное мышление и немного удачи. В задаче вообще может отсутствовать условие, оно может быть зашифровано в каком-то изображении или спрятано на секретной странице, ссылку на которую ещё надо найти. А помимо стандартных ограничений по времени и памяти ваше решение вдруг должно стать «вежливым»:

Здесь полный контроль над системой так же даёт преимущество — всегда можно немного подхачить и сделать контест ещё интереснее.

Когда я пришёл работать в Контур, то продолжил создавать контесты уже для новых коллег

Кстати, о Контуре я узнал когда-то из-за олимпиад — он был спонсором. Уже тогда у меня сложилось какое-то положительное впечатление о компании и инженерной культуре.

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

Немного про Контур и спортивное программирование

Контур всегда в том или ином виде организовывал тренировки для олимпиадников: для этого использовались площади компании, а тренерами были сами контуровцы. Например, уже в июне 1996 прошёл первый чемпионат УрГУ, а организатором и тренером был один из сотрудников.

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

Зачем вам спортивное программирование

Давайте вернёмся к началу. Спортивное программирование — это не универсальная таблетка и не обязательное условие для успешной карьеры. Вы вполне можете стать отличным сеньором, ни разу не открыв LeetCode.

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

Немного статистики по соревнованиям, которые я уже провёл (не только в Контуре, а суммарно):

- Больше всего успешных решений сделали на C# 9.0 (.net 4.8) — 442 решения.

- Самый редкий язык — это Rust 1.72.0. Всего 22 успешных решения.


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