В этом году случилось уникальное событие — для большинства школьников России школьный этап всероссийской олимпиады школьников по информатике проводился по едиными правилам, общим комплектам задач (всего было 4 варианта заданий на всю страну), с использованием тестирующей системы.
Организация
Организационной стороной занимался образовательный центр "Сириус", который проводил школьный этап всероссийской олимпиады по шести предметам — математике, информатике, физике, химии, биологии, астрономии. В прошлом году уже была апробация для шести регионов. В этом году принять участие было предложено всем регионам. Предпосылка в том, что формально по порядку проведения ВсОШ за проведения школьного этапа отвечают муниципалитеты, поэтому уровень организации школьного этапа зачастую оставляет желать лучшего, а местами он и вообще не проводится.
Согласились почти все — проще перечислить регионы, которые не участвовали и решили проводить школьный этап самостоятельно (по убыванию численности населения): Московская область, Красноярский край, Вологодская область, Алтайский край, Омская область, Республика Крым, Пермский край, Пензенская область, Тверская область, Забайкальский край, Амурская область, Республика Марий Эл, Республика Карелия, Новгородская область, Республика Хакасия, Республика Ингушетия, Республика Алтай, Чукотский автономный округ, Ненецкий автономный округ. Я не включил в этот список Москву — хотя она и не участвовала в школьном этапе, проводимом Сириусом, но всё равно школьный этап по информатике для Москвы проводился по тем же заданиями и тем же правилам. На самом деле наоборот — правила и принципы составления задания были взяты московские, и московский формат проведения школьного этапа олимпиады был распротранён на всю страну.
Всего вместе с Москвой участвовало свыше 80% регионов России (если считать по численности населения).
Все регионы были разбиты на четыре группы, примерно равной по численности населения, расположенные примерно в одних часовых поясах. Первая и вторая группы — это московский часовой пояс, третья группа — это MSK+1 и MSK+2, четвёртая группа — от MSK+4 до MSK+9. Тут я (и многие коллеги) впервые узнали, что в зоне MSK+3 находится всего лишь один регион — Омская область, которая не участвовала в проекте. Для каждой группы был установлен свой день проведения — с 26 по 29 октября.
Авторы заданий
Задания разрабатывал большой коллектив авторов в четырёх рабочих группах. Огромная благодарность всем авторам за то, что они сделали четыре хороших комплекта заданий. Также отдельное спасибо MikeMirzayanov за систему полигон, которая использовалась для подготовки всех заданий, и помощь в решении технических вопросов,
Логины для участия в олимпиаде распространялись по школам через ФИС ОКО (федеральная информационная система оценки качества образования), доступ к которой есть у всех школ. Школам выдавались логины по числу учащихся +10% запаса. Регламент проведения олимпиады предусматривал возможность участия с 8 до 20 часов по местному времени, реально же возможность участия была от 8 утра в самом раннем регионе до 20 часов в самом позднем.
Содержание заданий
Олимпиада проводилась для 5-11 классов по формату заданий, принятому в Москве в последние годы.
Для 9-11 классов предлагалось 5 задач по программированию на двухчасовой тур. Примерный план варианта — формула (целочисленная арифметика), задача на использование if, задача на цикл, задача на массив, идейная задача. Система оценивания — потестовая, все тесты независимые, хотя в условия и выделяются подзадачи по ограничениям или частным случаям, но групп тестов и зависимостей между тестами нет. Тестирование производилось сразу после сдачи на всех тестах. Задачи доступны в тренировках: первая группа, вторая группа, третья группа, четвёртая группа.
Для 7-8 классов предлагается смешанный вариант. Статистика показывает, что лишь небольшая часть школьников 7-8 классов, участвующих в олимпиаде умеет программировать (например, статистика этого школьного этапа — около 10% участников сдавало задачи по программированию), поэтому участникам предлагается 4 задачи с вводом ответа и 3 задачи по программированию. Задачи с вводом ответа — это по сути output-only задачи, которые, скорее всего, можно решить без использования компьютера (но не запрещается и использование компьютера). Ответ на них нужно записать в поле ввода. Это похоже на формат олимпиад по математике в дистанционной форме, но благодаря чекеру можно выставлять произвольные баллы за решения, например, оценивать алгоритм для исполнителя по числу использованных команд. Об этом формате проведения олимпиады было опубликовано несколько статей. При этом считается, что 7 задач много для тура, а школьники могут выбирать понравившиеся задачи, поэтому оцениваются только 5 задач из 7 с наилучшим результатом. Продолжительность тура — 2 часа.
При этом сильные программирующие школьники 7-8 классов могли писать олимпиаду за 9 класс.
Для 5-6 классов предлагался вариант без программирования, только из 5 output-only задач. Продолжительность тура — 45 минут.
Условия задач, решения, архивы и видеоразборы опубликованы: группа 1, группа 2, группа 3, группа 4.
Тестирующая система
Тестирующая система должна удовлетворять ряду требований: держать несколько десятков тысяч пользователей одновременно, справляться с проверкой задач по программированию (тут в пиковые моменты нужно было порядка 40 инвокеров, благо при составлении задач было требование не делать большое число тестов), поддерживать output-only задачи со сдачей ответа в поле ввода. И выполнить все эти требования одновременно вместе оказалось довольно сложно.
Для проведения дистанционных олимпиад по другим предметам Сириус использует собственную тестируюущую систему. Она специально была разработана для проведения подобных мероприятий, поэтому там довольно просто реализован механизм входа и регистрации (вместо пары логин-пароль используется один "ключ", затем нужно ввести фамилию-имя и можно переходить к олимпиаде) и умеет держать нужную нагрузку. В ней уже есть поддержка задач по программированию и проведены соревнования на несколько сотен участников, однако, на соревнованиях по программированию на тысячах участников система ещё не использовалась. Кроме того, поддержка output-only задач в настоящий момент не достигла нужного нам уровня, например, нет возможности выставлять в качестве оценки за решение произвольное число от 0 до 100. Поэтому от использования системы Сириуса пришлось отказаться, но я надеюсь, что в дальнейшем мы будем использовать её.
Codeforces хоть и умеет держать нужное количество пользователей (если считать число участников Div.3 раундов, которое превышает 20.000, что примерно нам и нужно), но совсем не поддерживает output-only задачи.
Яндекс-контест мы пробовали использовать в прошлом году в ходе пилотного проведения школьного этапа для нескольких регионов, с его помощью можно добиться желаемого формата проведения олимпиады, однако, это весьма неудобно делать. Например, ввод фамилии-имени участника при регистрации осуществлялся при помощи добавления в контест "нулевой" задачи, без сдачи которой нельзя перейти к следующим задачам, а это усложняет подведение результатов (нужно отдельно выгружать архив сабмитов, считывать его программно и сливать с таблицей результатов). Задачи вида output-only приходится проверять повторно после окончания тура с заменой чекера. Все массовые операции вида "создать пользователей", "выгрузить архив решений", "провести перетестирование" требуют привлечения поддержки и занимают очень много времени. Наконец, у Яндекс-контеста при переходе его на новый уровень нагрузки могут возникнуть проблемы в неизвестных ранее местах, так, например, год назад 20 тысяч одновременно пытавшихся открыть страницу Яндекс.контеста пользователей, полностью положили его. Допустить что-то подобное на мероприятии такого уровня не хотелось бы.
Поэтому использовался ejudge, который много лет использовался для проведения олимпиад в Москве. Отдельная благодарность автору ejudge Александру Чернову за систему и регулярные консультации.
ejudge, разумеется, имеет большое число недостатков, связанных прежде всего с тем, что система разрабатывается более 20 лет и её архитектура соответствует взглядам 20-летней давности. При разработке ejudge просто не закладывалась идея, что в контесте могут быть десятки тысяч одновременных пользователей и сотни тысяч пользователей всего. Все пользовательские запросы, например, обрабатываются процессом ej-contests, который работает в один поток и никак не распараллеливается. Поэтому, кажется, предел возможностей ejudge — это около 4000 одновременных пользователей на мощном компьютере, при большем числе пользователей ej-contests уже не успевает обрабатывать запросы пользователей.
В ejudge плохо организована работа с базой пользователей, например, запуск контеста (и выполнение действия reload config files) влечёт считывание всей базы пользователей в память, что занимает ощутимое время и требует оперативной памяти для хранения ненужной базы пользователей.
Год назад в результате возникших проблем с добавлением пользователей в коде ejudge мною были найдены вшитые ограничения:
#define EJ_MAX_USER_ID 999999
#define MAX_USER_ID_32DIGITS 4
Последняя строчка ограничивает размер поля для хранения USER_ID 20 битами. При этом для проведения школьного этапа в этом году было сгенерировано порядка 10 миллионов логинов в систему.
Зато система ejudge проверена и предсказуема. Известно, что один сервер ejudge может держать 3000 одновременных пользователей, и распределить нагрузку можно созданием отдельных серверов так, чтобы на каждый из них приходилось не более 3.000 одновременных пользователей (и около 15.000 пользователей за день проведения тура).
Поэтому для проведения олимпиады использовалось несколько независимых серверов так, чтобы ожидаемое максимальное число пользователей составляло порядка 2000 на одном сервере. Каждая из четырёх групп регионов разбивалась на подгруппы по ожидаемому числу участников: первая и третья группы были разбиты на две подгруппы, вторая группы — на три подгруппы, четвёртую восточную группу разбивать не пришлось. Итого получилось 8 подгрупп и 24 сервера (для групп классов также использовались отдельные сервера), плюс 3 сервера для Москвы. Но для проведения туров одновременно использовались только сервера одной группы, то есть при проведении школьного этапа для второй группы + Москвы было задействовано 12 одновременно работающих фронтенд-серверов.
Все сервера находятся в облаке AWS, благодаря чему процесс клонирования серверов довольно прост.
Таким образом, для участия в олимпиаде школьник должен иметь помимо логина и пароля ещё и ссылку на вход в тестирующую систему, которая разная для разных серверов. Для этого мы в последние годы используем сервис сокращения ссылок to.click, которому мы благодарны за поддержку и всяческую помощь.
Проблемы
К сожалению, провести олимпиаду "идеально" не получилось, хотя итог оказался лучше "пессимистичного" сценария. Трудностей с тестирующей системой не было, но, к сожалению, отбиться от DDOS-атак без потерь не удалось.
Проблемы с серьёзными DDOS-атаками в последние годы возникали у организаторов школьного этапа в Московской области, я же некоторое время считал, что лучший способ защиты от DDOS-атак — это просто хранить в секрете адреса серверов, не публикуя ссылки на вход в тестирующую систему в открытом доступе. Но при увеличении масштаба мероприятия этот метод перестал работать. Впервые c DDOS-атакой при проведении школьного этапа мы столкнулись год назад, тогда без видимых причин выросла нагрузка на CPU и сеть на одном из серверов и происходило ощутимое замедление отклика сервера (это было год назад на московском сервере для олимпиады 9-11 классов), но точно идентифицировать атаку по логам не удалось.
Поэтому (по примеру Московской области) все сервера находятся за Cloudflare. Но оказалось, что недостаточно просто завести сервера за Cloudflare, нужно ещё и с настройками разобраться.
На этот раз первая DDOS-атака началась 27 октября в 20:00. В это время заканчивался тур для Москвы, поскольку для регионов проведение тура по регламенту до 20:00. Атака заключалась в загрузке страницы входа в систему, в минуту число запросов доходило до 2 миллионов. При этом Cloudflare распознал атаку и успешно блокировал запросы, т.е. тестирующая система продолжала работать. Но часть участников (по-видимому, те участники, у которых массово совпадали IP-адреса) также были "распознаны" Cloudflare, как атака, и им тоже был заблокирован доступ в тестирующую систему.
Вторая DDOS-атака случилась 28 октября в 13:13 по московскому времени (если "автор" этой атаки читает этот пост, то да, мы "оценили" его шутку). Она была гораздо более длительной и продолжалась свыше 5 часов. Мне кажется, что вторая атака не связана с первой — первая была направлена на московский сервер, здесь атака шла на сервер для регионов. Но сценарий оказался точно таким же — Cloudflare начал блокировать атаку и часть участников. По моим оценкам, трудности доступа к тестирующей системе из-за блокировки Cloufflare возникли у 30% участников олимпиады, для остальных же тур продолжался, т.к. с самой тестирующей системой проблем не было.
Примерно через 1 час 10 минут после начала атаки удалось разобраться с настройками Cloudflare, и вместо блокировки атакующих была включена капча, т.е. все заблокированные участники могли добраться до тестирующей системы при помощи ввода капчи. После этого атака продолжалась ещё более 4 часов, но никаких затруднений (помимо ввода капчи) у участников уже не было. Для компенсации трудностей тур был продлён до ночи, а участникам, которые не смогли сдать решения, предлагалось сделать это повторно под новым логином.
Списывания
К сожалению, при таком формате проведения олимпиады задания сливаются в интернет в течение первого часа, а вскоре появляются и их решения. Главный вред от этого в том, что большое число копи-пастеров вытесняют из верхней части таблицы результатов честных участников и не дают им возможности пройти на муниципальный этап, поскольку число участников муниципального этапа ограничено. Возникает необходимость очистить результаты от "мусорных" участников. Но стандартные алгоритмы, которые используются на подобных соревнованиях, предполагающие попарное сравнение подозрительных решений членом жюри, здесь не сработают, потому что решений и списываний очень много, сравнивать попарно решения нет никакой возможности. Да и сценарий списываний тут другой — есть некоторое количество решений, которые были слиты в интернет, и участники сдавали эти решения, как правило, без каких либо модификаций. Хотя несущественные модицификации возникают, например, при копи-пасте решений часто появляются лишние пустые строки. Или есть другой интересный эффект: при копировании решений с одного популярного сайта участники зачастую копирую и номера строк, которые записаны в первом столбце таблицы вёрстки кода, получается такая программа:
1
2
3
4
5
6
7
N = int(input())
K = int(input())
if 1 <= N <= 10 ** 4:
if (1 <= K <= N) and ((N % K) == 0):
print(2 * N * (N // K - 1))
else:
print(0)
Но этот код с точки зрения языка Python является корректным и набирает столько же баллов!
Поэтому проверка на списывание проводится по другой методике, цель которой — выкинуть решения, явно скопированные из интернета. Проверка весьма поверхностная, не ловит какие-либо существенные модификации кода, но в этом и нет нужды, потому что большинство списывальщиков просто делают копи-паст найденного решения, и очистка таблицы от этого мусора уже даст результат. Например, в одном из регионов после проведения такой очистки число участников, набравших балл, примерно соответствующий прохождению на муниципальный этап, сократилось в 4 раза.
Печальная статистика заключается в том, что в целом по стране среди участников 9-11 классов, которые набрали больше 0 баллов, минимум 58% использовало чужие решения (это только то, что удалось найти поверностной проверкой). Доля "списывальщиков" разнится от региона к региону, в отдельных регионах доходя до 90% участников.
В целом есть два довольно банальных наблюдения: в тех регионах, где участники писали в школах (а не из дома), доля списывания ниже. В тех регионах, где число участников выше среднего, т.е. было искусственное повышение числа участников, доля списывания выше (если пригнать на олимпиаду не желающих в ней участвовать школьников, то они либо ничего не сдадут, либо спишут).
Статистика
Публикую два файла со статистикой.
Число участников по регионам в каждой группе. Здесь удалены найденные списанные решения и в 9-11 классах посчитано число участников, имеющих ненулевые баллы после этого.
Статистика по используемым языкам программирования. Учитывается только 9-11 класс, после проверки на списывание. Считается, что участник использовал язык программирования, если набрал больше 0 баллов, сдавая решения на этом языке.