C++ в Практикуме. Как обучить студентов плюсам, не отпугивая

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

Меня зовут Антон Полднев, я уже давно пишу в Яндексе на C++ и руковожу сервисом, написанным на этом языке. Параллельно я учу других людей навыкам разработки. С 2016 года я вёл курсы на Coursera, затем мы их прокачали и сделали на их основе курс для Практикума. В этом посте я расскажу, как мы учим людей C++, а также про основные особенности этого языка. 

Языковые сложности. C++ VS Python   

Да, плюсы́ — не такой популярный язык для студентов, как тот же питон, например. Если мы говорим о человеке, который решил впервые попробовать свои силы в программировании, то он с большей вероятностью пойдёт писать именно на Python, нежели на C++. Здесь дело и в пороге входа, который у плюсов ощутимо выше, и в том, что на Python куда проще получить в результате своих трудов полноценную работающую программу. Ведь там многое доступно сразу из коробки, нет лишних скобочек и связанных с ними сложностей. Работа с файлами там тоже заметно проще — в общем, просто берёшь и работаешь. 

Сейчас даже в школах, где уделяют внимание программированию, учат способных учеников именно Python. Конечно, многие из нас с вами на уроках информатики начинали с Pascal или Visual Basic, в ряде школ наверняка они ещё остались. Но проблема Pascal в том, что обучиться-то ему можно, а вот найти применение в реальной жизни уже сложнее. А Python и простой, и дружелюбный, и проектов на нём много. 

— Погоди, пост же про плюсы, — скажет внимательный читатель. Да, всё верно, вот и они. Штука в том, что с Python хорошо начинать. А вот дальше всё зависит от задач и желаний программиста. Если вам хочется (и интересно) писать куда более производительный код, над которым у вас будет полный контроль, то для этого понадобится что-то низкоуровневое. Например, Java, C++, C#, в какой-то степени Go. 

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

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

Обузданная мощь

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

Программы на C++ быстрее благодаря более чёткой типизации
Программы на C++ быстрее благодаря более чёткой типизации

Программируя на C++, вы на самом деле чувствуете мощь — у вас куча возможностей. Как говорили в таких случаях Питеру Паркеру: «С большой силой приходит большая ответственность», что, кстати, тоже является хорошим стимулом для обучения. 

Если вам интересно создавать эффективный код и в процессе перелопачивать огромные объёмы данных, то дополнительным челленджем в C++ станет не просто написать быстрый код, но написать его так, чтобы он был понятен остальным. Люди же будут его использовать, поддерживать и масштабировать — это не вещь в себе, это инструмент. Хороший, работающий и ремонтопригодный. 

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

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

Как не надо учить людей C++

Хотя я выше и писал, что частенько в плюсы приходят из Python в поисках силы и контроля, лично я знаю не так уж и мало людей, для которых C++ стал первым языком. 

Идеальный путь мне видится примерно таким. 

  • В школе у вас было программирование, вас учили питону.

  • Затем вы аккуратно и постепенно переползли на плюсы.

  • В итоге хорошо разбираетесь в обоих языках, зная достоинства, недостатки и области применения каждого. 

Это если сильно всё упрощать.  

На самом деле для большинства ситуация выглядит примерно так.

  • В школе программируете на чём-то, что вроде бы и язык программирования, при этом совершенно бесполезный и в природе уже не встречается. Кроме учебников. Старых учебников. 

  • Затем поступили в университет, а там — сюрприз — внезапно плюсы. 

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

В общем, про метапрограммирование вы на таком курсе услышите разве что от других студентов. И то не факт. 

Так нельзя делать, и вот почему. Допустим, новичку рассказали про С, попросили сначала (на курсе по C++, да) попрограммировать именно на С. Если элемент страдания на курсе возведён в культ, то студенты будут программировать ещё и на ассемблере, просто для того, чтобы ощутить ту боль и метания, которые испытывали инженеры. 

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

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

— А как надо?

А надо просто рассказать людям, что программирование — это не страшно, что можно научиться писать полезные программы, небольшие, на 10–20 строк. Потом плавно переключиться на C++ и показывать, как там всё круто работает и какой хороший код получается. 

Этот подход мы применяли на Курсере. Он же у нас и в Практикуме: покажем человеку, какой язык классный. Классный сегодня, без попыток углубиться в историю и рассказов о его предыдущих архивных версиях. Просто покажем, как создать массив чисел. Или массив котиков, например. 

Например, вот так мы объясняем студентам цикл while через хождение к холодильнику
Например, вот так мы объясняем студентам цикл while через хождение к холодильнику

Мы сразу говорим студенту, что если хочется набор объектов — используй тип «вектор». Он сам себе выделит память, сколько ему там надо, всё будет ОК, вообще в этой ситуации не думай про управление памятью. Хочется сделать множество элементов, которое можно быстро добавлять и искать в нём — вот тебе контейнер, без проблем. 

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

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

Мы учим студентов на курсе, начиная с верхнеуровневых вещей, и потом уже раскрываем всё это подробнее, углубляясь в каждую тему. Про устройство контейнеров можно рассказывать уже через пару месяцев обучения, это тоже помогает разработчику прокачиваться. Потому что в отличие от других языков все стандартные средства, например, контейнеры C++ тоже написаны на C++. И мы даём задачки вида «Вы узнали, как на самом деле работает управление памятью. Теперь напишите свой список или вектор». 

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

Обучение углублённым темам

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

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

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

C++ в Яндексе

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

К рекламному движку, как мы его называем, предъявляются жёсткие требования по нагрузке: за секунду нужно обрабатывать сотни тысяч запросов, и делать это нужно за десятки–сотни миллисекунд. Спроектировать и поддерживать такой сервис довольно тяжело. И современный C++ нам в этом помогает.

Известный всем поиск Яндекса сталкивается с похожими проблемами. Он тоже написан на плюсах, и наши команды активно обмениваются опытом разработки и проектирования высоконагруженных сервисов. Или взять, например, браузер: он должен быть эффективным и не замедлять систему пользователю, который установит его на свой компьютер и откроет пару сотен вкладок. Тоже C++, и тоже челленджи.

Чеклист «Как надо»

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

  • Убедитесь, что вы начали рассказывать про язык, а не про историю развития этого языка. 

  • Убедитесь, что уже после первых уроков ваши студенты осилят написать рабочий код, простой и в то же время близкий к боевому. Давайте им все основные инструменты сразу. 

  • Вообще не страшно рассказать про вектор и при этом не рассказать про шаблоны классов. Детали реализации обсудить всегда успеете. 

  • А ещё не страшно рассказать про словарь и не рассказать, что такое бинарное дерево. 

  • Не усложняйте. Любая популярная идея в своём ядре понятна и проста. Если это не что-то хитрое типа метапрограммирования, то про это не надо рассказывать сложно. Пусть, например, вы рассказываете про активное использование ссылок. Ссылки в массе своей пришли на замену указателям. Поэтому расскажите про ссылки и не рассказывайте про указатели. До поры до времени.

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

  • Убедитесь, что студент понимает, зачем вы ему это рассказываете. Если вы решили рассказать про словарь просто потому, что словарь — это круто, студент может не понять. Покажите, зачем ему словарь. 

  • Рассказывайте про новое в языке. Быть современным важно. 

  • Не рассказывайте вообще всё. Это ловушка для преподавателя: когда вы давно в C++ и хорошо знаете язык, хочется рассказать про него всё. Рискуете перенасытить студентов и усложнить подачу. 

А усложнять не надо. 

Вот так мы и учим наших студентов. Если у вас есть вопросы, с радостью отвечу.  

Let’s block ads! (Why?)

Read More

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *