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

А если речь идёт про курс, посвящённый алгоритмам, всё усложняется: ведь алгоритмы сами по себе — это не то, чем вы будете заниматься на работе. Это скорее добавочный уровень знаний, помогающий вам понимать программирование. Если совсем упрощать.



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

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

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

Акела промахнулся


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

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

Знаете, это как в описании старого доброго DigitalOcean, “designed for developers”. Когда разработчики пошли и сделали решение для других разработчиков. Это крутой подход, потому что люди в теме делают что-то хорошее для таких же людей в теме. Зная все болевые точки, высказанные (и невысказанные) хотелки и нужные фичи.

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

Плюс мы перегрузили первоначальный курс математикой. Нам казалось, что без нее никак, когда ты учишь алгоритмам. При этом отказались от объяснения тех тем, которые сочли слишком простыми и базовыми (потому что на старте задумывали курс для мидлов, а нужен был для джуниоров). Поэтому некоторые студенты неслабо удивлялись, когда им на курсе про алгоритмы начинали увлеченно рассказывать про логарифмы. Да и нарастание сложности было неравномерным.

В общем, надо было что-то менять. И мы фактически поменяли весь курс.

Работа над ошибками: для кого же этот курс


Главное, что мы сделали, это учли весь фидбек, включая тот, что вы недавно читали на Хабре (ситуация произошла в начале осени 2020-го). Нам очень помогает тот факт, что люди, сумевшие продраться через первую версию курса, теперь активно участвуют в процессе и помогают добиться того, чтобы курс по алгоритмам не отпугивал сложностью задач и чтобы не создавалось впечатления, что наставники требуют от вас соответствия слишком высоко задранной планке.

Новая версия курса — для тех, кто уже умеет программировать на каком-то милом сердцу языке. То есть разработческие навыки у человека есть, он умеет в базовые конструкции: циклы, ветвления, базу хранения, переменные, контейнеры, функции и классы. А вот алгоритмической подготовки нет. Но хочется.
Важно: курс не про обучение программированию (для этого есть отдельные курсы), он именно про конкретные скиллы для решения алгоритмических задач по основам алгоритмов и структур данных.

Зачем людям вообще алгоритмы


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

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

Именно из-за этого про алгоритмы так часто спрашивают на собеседованиях.

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

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

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

Как мы сейчас учим людей на курсе


Итак, это базовый курс про алгоритмы и структуры данных. Мы начинаем с бесплатной части, так называемого «нулевого спринта», на котором предлагаем абитуриенту решить несколько задач, чтобы определить уровень подготовки. Если он справляется, значит, поймёт сам курс; если нет, то нужно подтянуть навыки программирования.


Справа в столбике — 5 задач из бесплатной части курса


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

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

В целом теперь курс рассчитан на тех, кто вообще не знает ничего про алгоритмы, в нём нет суперсложных задач. Мы рассказываем, как в памяти устроены такие структуры, как массив, список, очередь. Здесь же объясняем про базовые алгоритмы — бинарный поиск и сортировки; разбираем рекурсию и различные рекурсивные алгоритмы.

Затем подбираемся к более сложным штукам, говорим о хэш-таблицах и деревьях. После этого идут графы.

Под конец курса оставлено самое сложное — алгоритмы на строках и динамическое программирование.

От теории к практике


Процесс устроен так. Сначала на платформе Практикума студент изучает теоретические материалы, а затем попадает на платформу Яндекс.Контест, где мы публикуем задачи. Там студент решает задачи именно по той теме, которую изучал в теоретической части.

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

Сам курс — это восемь спринтов, в каждом из которых в среднем по 15 задач. Задачи при этом поделены на два вида, обычные и финальные. Для решения обычной задачи студенту просто надо написать код, послать его в Контест и получить в ответ ОК. В этом случае нужно именно одобрение от системы, и не столь важно, как именно написан сам код, — оценивается лишь его работоспособность, скорость и адекватные аппетиты в плане памяти.

С финальными задачами всё немного сложнее. Кроме одобрения от Яндекс.Контеста нужно отправить своё решение живому человеку, код-ревьюеру из нашей команды. Их у нас несколько, потому что код студенты пишут на разных языках (Python, C++, Java, Go, NodeJS). Сами примеры задач мы по этой причине пишем на псевдокоде.

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

Яндекс.Контест


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


Интерфейс Яндекс.Контеста

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

И тут начинается холивар, причём всеобъемлющий. Мнения разделяются как среди студентов, так и среди авторов курса.
Система не скажет вам, что именно в коде не так, если он не работает. Вы просто получите в ответ «Код не работает», но не будете знать, почему.
Некоторых студентов это дико бесит. Ну представьте: вы продолжаете закидывать систему кодом, а она вам просто: «Неправильно», «Опять неправильно». Как в школе, когда сдаёте реферат на 10 листов, а вам говорят: у тебя там одна ошибка, ищи. Поэтому возникает вполне резонный вопрос: как на обучающих курсах код-то отлаживать, если система не говорит, где косяк?

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

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

Конечно, у наставников есть доступ к тест-кейсам, и по запросу они могут открыть его для студента. Это вечная дилемма насчёт тех неудобств, которые помогают развиваться.

Смотрите, как получается. Если оставить тест-кейсы открытыми для всех и сразу, то вместо написания кода мы получим довольно рутинный процесс подгонки своего результата, чтобы просто скормить его системе и получить от неё заветный ОК. Скажем больше: именно это мы сейчас и наблюдаем на тех частях программы, где экспериментально открыли тесты. Это как в школе пойти и купить ГДЗ по алгебре.

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

Ещё одна полезная функция Контеста — это статистика. Мы можем посмотреть, за какую задачу студенты вообще не брались, а за какую брались многие, но почти никто не решил. Это помогает постоянно улучшать курс. Если за задачу не брались вообще, то есть просмотрели её условие и даже не попытались решить, значит, проблема в условии. Оно непонятно написано, и надо его переделать.

Человеческий фактор


Как всегда, многое зависит от людей. Если с Контестом человек сработается, как и с любым другим инструментом (типа браузера или любимой клавиатуры), то с ревьюерами и наставниками ситуация может быть иной. Кому-то из студентов просто не понравится наставник, а кто-то будет уверен, что предыдущий наставник объяснял всё хуже, чем новый.

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

Самостоятельное обучение


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

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

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

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

В этом и смысл нашего курса, заточенного теперь под джуниоров.

Кому курс точно не подойдёт


  • Тому, кто вообще не умеет программировать, и хочет научиться программированию сразу через алгоритмы. Базовый навык программирования тут необходим. Иначе вы просто не поймёте, что тут вообще происходит.
  • Тому, кто железно уверен, что отлично справится с обучением самостоятельно по книгам и иным ресурсам.
  • Тому, кто хочет алгоритмической жести. Мы сталкивались с обратной связью, когда человек был уверен, что курс по алгоритмам от Яндекса — это максимальный хардкор по алгоритмам вообще просто потому, что от Яндекса. Нет, тут всё не так. Мы любим алгоритмы, но сам курс у нас базовый. Только задачи уровня Easy и Medium. Без Hard. Возможно, у нас будут продвинутые курсы по алгоритмам, но точно отдельно от этого базового курса.
  • Тому, кто не готов уделять хотя бы 10 часов в неделю на изучение теоретического материала и непростые домашние задания.


Что дальше


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

У нас есть бесплатная вводная часть. Если сомневаетесь, нужен ли вам вообще курс по алгоритмам и осилите ли вы его, можно пройти её: и осмотритесь, и свой уровень знаний оцените.

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