2,5 года назад мы запустили собственный курс по Flutter. Идея была простая: во-первых, мы много вкладываемся в развитие Flutter-сообщества в России (с — скромность), и было логично систематизировать знания и опыт в виде курса. Во-вторых, мы хотели выращивать хороших разработчиков в наш Flutter-отдел: спрос на Flutter-проекты у клиентов рос, а количество разработчиков на Flutter в России было ничтожно мало.
Курс эти задачи решал, но со временем вскрылись проблемы, которые не были очевидны для нас на старте. Например, красивые и подробные видеолекции оказалось сложно актуализировать. А материал, который казался нам очень простым, для студентов оказался слишком сложным. Правда, это не мешало им через боль и слёзы всё-таки проходить курс до конца. Особые мазохисты даже считали это главной фишкой и до сих пор вспоминают как лучшую «школу жизни».
Рассказываем о нашем первом опыте в эдтехе: как была устроена первая версия курса, что пошло не так, чем мы вдохновились при создании второй версии и как провели работу над ошибками.
Как была устроена первая версия курса
Мы решили сделать курс, но имели весьма туманное представление о том, как это делается. Поэтому взяли за основу опыт, который у нас был: мы много работали со студентами в вузах и даже проводили офлайн-курсы по разработке. Поэтому попытались «портировать» этот опыт на онлайн-площадку.
Курс построили по традиционной схеме: свод теории и практическое задание, которое закрепляет полученные знания. Казалось, что в теории нет никакого дефицита: по всему интернету лежат статьи на всевозможные темы, не говоря уже о богатой официальной документации. Поэтому мы решили оживить теорию через видеолекции: хорошая подача и наглядное изложение по задумке должны были улучшить усвоение материала.
Идея оказалась не из простых. Нам пришлось арендовать дополнительное помещение под студию, собрать фон, купить недостающее оборудование – всё это для красивой картинки. А чтобы картинка была не только красивая, но и информативная, к записи каждой лекции мы много готовились, верстали слайды, вспоминали некоторые важные детали. Не зря говорят, что лучший способ навести порядок в своих знаниях – начать кого-то учить. Это чистая правда.
Да, когда мы рассказывали о курсе на внешних площадках, в том числе здесь, на Хабре, мы сталкивались с комментариями в духе: «Спасибо, зачем мне платить деньги вам, если я уже почитал документацию бесплатно».
Действительно, информация доступна, её много, и при должной усидчивости всё можно освоить самостоятельно. Но в этом «много» и кроется проблема: отсев и фильтрация информации, поиск самых достоверных и самых близких к реальности источников — отдельная большая задача. И курс её решал: мы уже всё нашли, проверили и систематизировали. Оставалось только изучить.
Тем не менее, основная фишка курса была совсем не в теории, а в практической отработке навыков и живом взаимодействии с преподавателями — Flutter-разработчиками Surf. Под их руководством каждому студенту предстояло создавать мобильное приложение для путешествия, которое состояло из 8 экранов.
Студенты с нуля проходили весь путь разработки и таким образом учились «полному циклу» работы с приложением: от основ вёрстки и обработки событий пользовательского интерфейса до подготовки к релизу на iOS и Android.
«Разработка приложения идёт последовательно по шагам. Особенно прикольно, когда что-то сделаешь, а потом на следующем задании надо всё переделать, потому что узнал новое. Как на реальном проекте, когда опыта ещё не набрался».
Виктор, студент 1 набора, сейчас — разработчик мобильных приложений в Яндексе
На всём протяжении обучения студенты постоянно взаимодействовали с «живыми» экспертами. Менторы проводили код-ревью, групповые и личные консультации, общались в чате и отвечали на вопросы.
Именно на этапе код-ревью происходила основная «магия»: менторы давали студентам такие же советы, какие дают начинающим разработчикам внутри команды, помогали им писать код точно также, как это происходит в реальной работе. Код в учебных примерах всегда проще, прозрачнее и понятнее, чем в реальных проектах, но если не вылезать за пределы учебных проектов, никогда не узнаешь, каков мир на самом деле. Менторы помогали студентам комфортно и спокойно про это узнать.
«Основная ценность курса — взаимодействие с наставниками. Тут дело не в сухой информации, которая и так есть в прекрасной документации Flutter».
Кирилл Миронов, студент 1 потока, Flutter-разработчик
Мы постарались воссоздать условия работы, близкие к условиям в коммерческом проекте: дизайн-макеты — в Figma, серверная документация — в Swagger, описание требований — от заказчика.
Тем не менее, с методической точки зрения мы слегка промахнулись: «впихнуть» в цельное приложение все интересующие нас кейсы именно в том формате, в котором они бы раскрылись лучше всего, было сложнее. Приходилось адаптироваться под проект. В итоге получалось, что мы жертвуем важными элементами образовательного процесса в угоду тому, чтобы получился прикольный тестовый проект.
«Домашние задания сдаются пулл-реквестами. Проверяют их по-взрослому: от соответствия макету в Figma, до стиля кода. Смотрят код внимательно, замечают разные сомнительные архитектурные решения, проблемы с производительностью, подсказывают как сделать лучше.
Причем проверяют разные специалисты из команды Surf. Ещё есть формат вебинаров по разным темам и общий чат, где можно задать вопрос».
Кирилл Миронов, студент 1 потока, Flutter-разработчик
Зачем понадобилось переделывать курс
Два года назад Flutter и Dart выглядели совсем иначе. Dart 2 принёс серьезные изменения: появилась Null Safety, поэтому учить предыдущую версию языка стало бессмысленно. Сам мир Flutter серьёзно изменился и, мы уверены, будет ещё меняться в ближайшем будущем: хотя бы потому, что только что вышел Dart 3. Кроме того, у нас появились новые уже устоявшиеся подходы, пул библиотек. В конце концов, наш опыт как разработчиков серьёзно укрепился.
Когда мы захотели обновить курс, то поняли, что он совсем не готов к апдейтам и изменениям. Он построен как монолит, и, если вытащить и заменить один блок, вся конструкция разрушится.
Видеолекции так просто не поправить — надо перезаписывать видео полностью. А если внутри видео ссылаемся на уже некорректную документацию, ролик необходимо перемонтировать.
Курс построен на разработке одного приложения, в которое крайне тяжело встроить новую тему или сделать обновление программы обучения, не нарушив структуру и логику работы.
А ещё студенты жаловались на то, что курс слишком сложный: лекции не разжёвывали всё до конца. Чтобы выполнить очередное задание, приходилось гуглить, рыть носом, разбираться: словом, подключать не только мозг, но и морально-волевые качества. Не сделаешь — следующий блок не откроется.
Мы поняли, что вносить изменения в текущий курс слишком затратно и не имеет смысла: «освежить» курс будет стоить примерно столько же, сколько написать новый. А потом через 2–3 года его нужно будет снова «освежать» и снова тратить те же ресурсы. Поэтому нужно было придумать, как сделать курс модульным, чтобы поддерживать без избыточных затрат.
Как появилась идея нового курса
Отдельно от курса у нас есть стажёрские программы для студентов. И хотя цели примерно одинаковые, программы обучения и задания никак не пересекались: курс отдельно, стажёры отдельно. Дело в том, что курс — это массовая история. А стажёры глубоко интегрированы в нашу команду, у нас есть возможность работать с ними индивидуально каждый день. Это сильно влияет на методику взаимодействия и план обучения.
Изначально каждый ментор придумывал задания для стажёров с нуля. В какой-то момент мы поняли, что это нерационально: нужно создать базу заданий. Поэтому начали собирать небольшие задачи, которые регулярно встречаются в нашей практике.
Каждый стажёр, который к нам попадает, — это претендент на джуниора. А джуниор в нашем понимании должен обладать не только базовыми знаниями языка и технологии, но и уметь решать бизнес-задачи. То есть он не должен попасть из тепличных лабораторных условий в реальную жизнь, не будучи к этому никак подготовлен. В реальном приложении никогда не нужно рисовать абстрактные квадратики и кружочки, зато всегда много работы с сетью, сложными списками, пагинацией, хранилищами данных и многим другим.
Так появился пул задач, с которыми студенты вряд ли столкнутся, если занимаются разработкой в одиночку. Зато такие задачи часто встречаются в коммерческой разработке, и нагуглить или найти в документации решение вряд ли получится — его можно освоить только в рабочей атмосфере под руководством наставников. При этом, несмотря на многообразие проектов, большинство задач на самом деле весьма типовые и могут быть сведены к ограниченному набору классов задач: если стажёр их освоит, то сможет успешно выполнять рабочие задания.
Примеры практики для стажёров
Реализация пагинации в приложениях. Как устроена пагинация со стороны бэкенда и какие формы она может принимать. Как подходим к реализации, проектированию, какие разные кейсы существуют.
Парсинг JSON. Это можно найти в документации, но не все понимают, как это относится к реальной жизни. Например, в какой момент при парсинге определенного поля нужно выбрасывать ошибку, когда — не нужно.
Со стажёрами этот подход хорошо работал: за всё время через нас прошло 15 стажёров. Успешно закончили стажировку не все, но те, кто закончил, очень быстро влились в команду и начали приносить ей ощутимую пользу.
В какой-то момент нас осенило: а почему бы не попробовать адаптировать элементы «стажёрского» подхода для новой версии Flutter-курса.
Как построен новый Flutter-курс
Модульность вместо монолитности
Мы поняли, что пилить одно большое приложение на протяжении всего обучения — так себе идея.
Нас она лишает нас гибкости: сложно актуализировать курс, вносить в него изменения. А ещё приходится все учебные кейсы адаптировать под проект и иногда жертвовать важными элементами.
Студенты в реальности не получают той пользы, которую мы изначально закладывали. На старте нам казалось, что если студент сможет сделать цельный проект, это поможет ему в карьере: у него будет что положить в портфолио. Со временем мы поняли, что это не работает: при найме мы даже не открываем код учебных проектов с курсов, если видим их у кандидата. В них нет персонального опыта, реализация вымуштрована менторами. Такие проекты, как правило, ничего не говорят про самого кандидата – ни плохого, ни хорошего.
Поэтому от идеи монолитного приложения решили отказаться. Теперь студенты пишут много маленьких приложений, которые охватывают разные бизнес-кейсы.
В модульной системе мы можем менять, исправлять и добавлять задания, не перекраивая весь курс. А ещё это эффективнее с образовательной точки зрения: в прежнем «монолите» не получалось выстроить такой образовательный процесс, при котором студент будет, например, раз за разом возвращаться к базам данных. А повторение, или как его теперь модно называть, spaced repetition — мать учения :)
Тренируемся работать с бизнес-задачей
Каждая задача сформулирована как запрос от клиента — в виде имейла. Имейл привносит историю и эмоции: как будто пишет реальный заказчик и наша задача — помочь ему решить бизнес-проблемы.
Наши задачи совсем как реальные, но, разумеется, попроще. Иначе курс был бы работой, а студенты за такую «учёбу» должны были получать зарплату. Студенты получают ассеты, макеты в Figma. Дизайнеры делают красивые макеты, студент должен их реализовать. Если результат не соответствует бизнес-требованию, ментор задание не принимает.
Одна из целей обучения — выработать у студента чувство того, что нужно клиенту. Благодаря сочетанию двух форматов постановки задачи — «имейла от заказчика» и ТЗ — студент сразу понимает, что задача берётся не из воздуха. В каждой задаче мы формируем определённые проблемы бизнеса, которые решаются этим ТЗ. Даём студенту понять, как связаны холдер задачи и её формальное описание.
Также как часть задания на курсах есть вопросы вроде тех, которые тимлид в нашей команде задаёт начинающему разработчику перед тем, как тот берётся за задачу. Например: «Сколько времени на той взгляд займёт выполнение это задачи?» и «На какие подзадачи ты бы это поделил?».
Вместо видеолекций — взаимодействие с ментором
От видеолекций мы отказались совсем. Большая часть теории курса — это материалы, которые представляют из себя подводку к определённым темам и набор ссылок на документацию и верифицированные статьи. А также живые лекции от сотрудников нашей команды: разбор заданий, углубленная теория, объяснение неочевидных моментов.
Ценность курса — не в предоставлении «тайных» знаний в виде пересказа документации, а в опыте, который Surf даёт студенту. И этот опыт можно получить только через взаимодействие с менторами — реальными разработчиками, которые выступают в роли «тимлидов» для студентов.
Каждый день студент может общаться с менторами в чате: задавать вопросы, присылать варианты решения заданий, обсуждать кейсы. Самые непонятные моменты разбирают на онлайн-лекциях. Там можно задать вопрос голосом.
Поддерживающая атмосфера
Одна из больших проблем онлайн-обучения — что студенты, преисполненные лучшими стремлениями, бодро начинают учиться, но потом по разным причинам бросают на полпути.
Конечно, стопроцентного прохождения никогда не обеспечить: иногда люди ошибаются с курсом или считают, что получили достаточно вводных материалов и дальше могут двигаться сами.
Нам кажется, что, если студенты получают подробный, конструктивный фидбэк и чувствуют атмосферу обучения, это поможет им не бросать. Именно поэтому мы сделали взаимодействие с менторами в режиме лекций: людям нужен живой преподаватель, который будет общаться не только текстом в чате или через записанное видео.
Для кого этот курс
Изначально мы хотели построить новый курс для тех, кто входит в IT с нуля. Думали объяснять с самых азов, например, как работают алгоритмы, системы исчисления, мантиссы. Но закапывались всё глубже и глубже и в какой-то момент поняли, что делаем не курс по Flutter, а курс по Computer science. И это получается уже не дополнительное образование, а полноценный университетский курс.
Поэтому от «азбуки программирования» решили отказаться. Наш Flutter-курс будет полезен тем, у кого не было рабочего опыта в IT, но есть базовые представления об информатике. Например, студентам: они знают язык программирования вроде Basic, Pascal, Java, которым обычно учат в университетах, но при этом не понимают, что из себя представляет коммерческая разработка. Курс по Flutter поможет вкатиться в коммерческую разработку, научиться использовать на практике то, что до этого пробовал только на лабораторных.
Минимальные системные требования для комфортного обучения
— Иметь хотя бы школьный опыт написания кода на языках типа Basic, Pascal.
— Знать основы алгоритмизации: циклы, условные операторы, блок-схемы.
— Знать, что такое CLI-программы.
— На базовом уровне знать формальную логику и основы дискретной математики.
А вот Dart знать не обязательно: на курсе даём основы.
Перспективы после курса
Сейчас доступен уровень Elementary: общие инженерные принципы, база Dart и Flutter, работа над простыми бизнес-кейсами, которые посильно решить с помощью базовых навыков. Обучение на этом уровне длится 4 месяца.
Мы не обещаем, что после курса студент сразу станет мидлом или сеньором: это нереалистичные обещания. Полноценным разработчиком можно стать только тогда, когда попадаешь в команду и начинаешь работать над реальными задачами. Но наш курс — это трамплин, который позволит преодолеть самую высокую ступеньку и начать получать реальный опыт.
Для тех, кто окончит Elementary, будут доступны уровни Intermediate и Advanced (да-да, как в иностранных языках). Сейчас они в разработке: coming soon. Также эти уровни будут полезны не только «нулевым» разработчикам и выпускникам Elementary-уровня, но и практикующим программистам, которые засиделись на своем проекте, стагнировали в развитии, хотят быстро повысить свою квалификацию.
Новый набор обновлённого Flutter-курса стартует 5 июня.