Чем участие в олимпиадах полезно для карьеры разработчика
Большинство участников олимпиад по программированию заканчивают свою спортивную карьеру после выпуска из университета и начинают заниматься исследовательской деятельностью или промышленной разработкой. Самыми полезными для них оказываются даже не медали, а знания и знакомства, приобретённые на соревнованиях и не устаревающие спустя годы. Руководитель группы диалоговых систем Алисы и бронзовый призёр ACM ICPC 2014 года Слава Алипов рассказал о том, как начал заниматься спортивным программированием, чем отличаются олимпиадная и промышленная разработка и почему опыт спортивного программирования продолжает помогать ему в карьере.
Олимпиадный путь
Я стал участвовать в олимпиадах на первом курсе университета, что довольно поздно по меркам спортивного программирования. Обычно успешные спортивные программисты начинают еще в школе.
У меня же всё началось с олимпиады для студентов первого и второго курсов Томского политехнического университета, в котором я учился на бакалавриате. Я пришёл на соревнование и ничего на нём не решил, зато познакомился с олимпиадниками нашего вуза и начал ходить с ними на кружок по спортивному программированию.
На второй год я уже выиграл в олимпиаде первого и второго курсов, потом — в общеуниверситетской. Тогда же я начал проводить занятия на кружке по подготовке к олимпиадам по программированию и присоединился к первой команде вуза. Нашим лучшим результатом был полуфинал Международной студенческой олимпиады по программированию ICPC, но выйти в финал никак не удавалось. Я думал, что «наигрался» и на этом и закончу свою олимпиадную карьеру.
Я решил поступить в магистратуру в московский вуз и выбрал совместную программу Высшей школы экономики и Школы анализа данных. Эту же магистратуру выбрали два моих будущих сокомандника: они узнали о том, что я поступаю, и позвали дальше участвовать в олимпиадах вместе с ними. В этом составе мы потренировались год, на втором курсе магистратуры прошли на финал чемпионата мира по программированию и завоевали на нём бронзовые медали.
Тренировались всегда сами: формально у нас были тренеры, но в основном мы занимались самостоятельным решением задач и написанием контестов. Одним из самых результативных видов тренировки было участие в сборах, в первую очередь Ижевских и Петрозаводских.
Для успешного выступления на олимпиадах по программированию нужно не только отлично владеть выбранным языком программирования, но и иметь глубокие и обширные знания в области фундаментальных дисциплин: алгоритмы, динамическое программирование, теория вероятностей, комбинаторика, теория графов, геометрия, теория чисел и так далее. В олимпиадах хорошо заметен прогресс: ты можешь найти свои слабые места и пробелы в знаниях, поработать над ними и сразу применить новые навыки в решении задач, а результат увидеть за счёт растущего рейтинга на Codeforces или более высокой позиции на очередном соревновании. Олимпиады — это весело и азартно, а позиции и рейтинги — хорошая мотивация узнать и освоить что-то новое из математики и алгоритмов.
В олимпиадах меня привлекала возможность непрерывно улучшать свою фундаментальную подготовку
Фундаментальные знания не устаревают и пригодятся в любой сфере деятельности: учёбе, исследованиях и промышленной разработке. Технологии изменяются каждый день: появляются и исчезают фреймворки, языки программирования и подходы к проектированию. Знание алгоритмов и математических дисциплин всегда будет актуальным, и на их изучение не жалко тратить усилия, а благодаря олимпиадам это ещё и приятно.
Олимпиадный стиль программирования
Написание кода на соревнованиях и в промышленной разработке имеют принципиальные отличия. В первую очередь, на олимпиадах гораздо сильнее ограничено время на написание кода. За счёт этого формируется так называемый «олимпиадный стиль», который любят критиковать профессиональные разработчики: короткие имена переменных и функций, гораздо меньшая декомпозиция кода на подпрограммы.
В олимпиадной разработке почти не нужно использовать объектно-ориентированное программирование и объявлять классы. Спортивные программисты пишут в процедурном, минималистичном стиле, и их код в первую очередь направлен на то, чтобы решить поставленную задачу.
Несмотря на это при написании олимпиадного кода всё равно нужно задумываться о том, что его придется тестировать, и учитывать то, что с большой вероятностью он не заработает с первого раза. В промышленном программировании принято решать эту проблему тестами, убеждаться в том, что отдельные модули программы можно протестировать, и думать о том, как структурировать программу, чтобы фрагменты можно было редактировать по отдельности. На контестах по программированию на самом деле нужно делать то же самое — только проверять придётся не юнит-тестами, а дебаг-выводом или брейк-пойнтами. Поэтому и в промышленной разработке, и в написании олимпиад важен навык декомпозиции. За счет других правил декомпозиции олимпиадный код выглядит страшнее, чем промышленный, но это не значит, что он нечитаемый или не структурированный.
Написав тысячи программ, ты хорошо убедишься, что программы с первого раза не работают, их нужно уметь тестировать и исправлять
К тому же чем больше ты практикуешься, тем проще будет писать любой код — как олимпиадный, так и промышленный.
Опыт спортивного программирования и промышленная разработка
Я устроился на стажёрскую позицию в Яндекс.Метрике одновременно с поступлением в магистратуру. В эти два года я совмещал три вида деятельности: работу в Яндексе, занятия в ШАДе и Вышке, а также подготовку к олимпиадам по программированию.
В ходе стажировки мне пришлось узнать и освоить много нового: бесполезные на олимпиадах, но часто используемые в промышленном коде библиотеки для работы с памятью и сетью, примитивы для многопоточных вычислений. Для обработки огромных объемов данных сервисов Яндекса пригодились новые структуры данных и алгоритмы для приближенных вычислений. Появилась необходимость в утилитах для отладки и профилирования моих программ.
Плохо ли, что олимпиады к этому не готовят? Да нет: олимпиады не готовили меня и к тому, что у меня больше не будет стипендии, и к тому, что мне самому нужно будет планировать своё развитие и ставить цели.
При переходе от олимпиад к промышленной разработке ты перестраиваешься на другой режим написания кода. В большой компании программы занимают больше нескольких страниц А4, а на написание нового проекта можно потратить сильно больше получаса. Становится важным соблюдение строгих стайлгайдов и принципов организации кода проекта, принятых в команде. Начинаешь тренировать новый для себя навык — умение разбираться в больших объемах чужого кода.
Олимпиадникам придётся свыкнуться с тем, что у задач больше нет точного решения
Часто программу можно улучшать бесконечно, поэтому очень важно научиться находить баланс между красотой решения и затраченным на него временем. При этом твое чувство прекрасного может не совпадать с мнением руководителя, и стажировка — отличное время, чтобы разобраться с новыми критериями работы.
После того как выпускаешься из вуза, доступных олимпиадных активностей (соревнований и сборов) становится меньше, а большинство спортивных программистов сосредотачивается на работе или на своих научных интересах. Кто-то продолжает ездить на сборы с лекциями и составлять для них задачи, но спортивное программирование быстро развивается, и за ним сложно уследить, если не заниматься им постоянно.
Сейчас я работаю в команде Алисы — руковожу группой диалоговых систем, которая занимается созданием моделей и инструментов для ведения диалога с целью решения задачи пользователя. Для этого нужно понимать смысл отдельных запросов пользователя и всего диалога целиком, уметь запрашивать у пользователя необходимую для решения задачи информацию.
Также в нашей группе разрабатывается «болталка» — движок для разговоров на свободные темы. Для этой задачи нет устоявшихся подходов и гарантированно работающих решений, большая роль отведена исследованиям и экспериментам.
В такой молодой и бурно развивающейся области, как диалоговые системы, очень важно следить за научным прогрессом, пробовать на практике подходы из статей, придумывать новые модели и ставить новые задачи машинного обучения. В условиях, когда нужно уметь быстро понимать и придумывать много нового, эрудиция в математических дисциплинах и алгоритмах, приобретенная за годы участия в олимпиадах, оказывается очень кстати.