Настало время для работы над курсом по самому сложному из мейнстримных языков — C++. Обсудим, почему индустрия нуждается в проработанном курсе по C++ прямо сейчас, и как именно он может выглядеть.
Что было в прошлой серии
Пол года назад мы анонсировали нашу площадку с курсами на Хабре. У нас был готов курс по питону и несколько глав курса по расту. С тех пор мы добавили:
- Курс по Haskell. С разрешения основателя русскоязычного хаскель-сообщества Дениса Шевченко мы превратили его книгу «О Haskell по-человечески» в интерактивный курс. В нем 24 главы и 70+ задач.
- Плэйграунд для запуска кода на C++, Python, Golang, Rust и Haskell.
- Авторизацию через 3rd-party.
- Несколько новых глав в курсе по Rust. Аналитики подсчитали, что такими темпами курс будет завершен к 2043 году.
- Шесть глав курса по Go. Жаль, но курс заморожен: автор не смог уделять достаточно времени проекту. Мы уже ищем нового автора.
За пол года курсами воспользовалось больше 5к разработчиков. Конечно, пользователи задают нам вопросы про эти языки. А вот чего мы не ожидали, так это обилия вопросов о C++. Причем за каждым вторым тянется шлейф декадентства и печали.
Разумно ли учить C++, раз его опять хоронят? Стоит ли браться за такой сложный язык, если жизнь ограничена скоротечным человеческим веком? Если я выучу C++, означает ли это, что меня увезет санитайзер? C++ — это про античность и легаси?
Маленькая, но гордая команда нашего проекта сплошь состоит из плюсовиков. Услышав сомнения наших студентов, мы буквально не смогли сидеть, сложа руки!
И мы видим две основные причины, по которым вселенной не хватает интерактивного опенсорс курса по C++.
Распространение современного C++ буксует
У C++ масса достоинств. Как-никак это язык №1 для разработки производительного обобщенного кода. Но помимо достоинств C++ обладает 40-летней историей и пунктиком на обратную совместимость. Мир полнится проектами на старом и весьма специфичном C++. Это наследие времен, когда лучшие практики еще не выработались, а в языке не было инструментов для написания безопасного, надежного и читабельного кода.
Типичный проект на C++, отметивший двадцатилетие.
В те времена отсутствовали или находились в зачаточном состоянии вещи, без которых тяжело представить современную разработку. Код-ревью, статические анализаторы кода, линтеры, запуск тестов в CI/CD, даже системы контроля версий. В таких условиях зарождалось огромное количество до сих пор живых проектов. В этих проектах принятые давным-давно решения продолжают влиять на текущую кодовую базу и на принятие новых решений. И когда разработчик погружается в этот удивительный код, он говорит: С++ кошмарен.
Проблемы старых проектов проецируются на современный C++.
Что хуже, во многих книгах, курсах и лекциях обучение C++ напоминает раскопки наслоений стандартов. И начинаются они конечно же с адресной арифметики. Многие из студентов опускают руки, потому что «C++ слишком сложный». А многие — подсаживаются на сырые указатели.
Материалов для эффективного изучения современного C++ мало. Особенно интерактивных, с практикой. И тем более бесплатных.
Настало время это исправить. Иначе новые поколения плюсовиков так и будут шалить с C-style cast. А современному C++ до скончания веков будут приписывать грехи легаси.
У С++ недостаточно популяризации
Итак, проблема, которая нас подталкивает к написанию курса — это нехватка обучающих материалов по современному C++. Но есть и вторая не менее важная проблема. Чтобы проникнуться ею, проведем эксперимент. Представьте, что вы — разработчик, захотевший погрузиться в определенный язык. Вы пошли гуглить. По запросам Rust, Golang, Python, Kotlin для вас за пару кликов откроется целая развлекательная программа:
- учебник для плавного погружения,
- коллекция примеров кода,
- online IDE,
- подборка аудио/видео-контента...
От начала гугления до чтения мануала: 1 клик.
А теперь загуглите C++. На первой странице поиска вы не найдете ни-че-го, что приблизило бы к контакту с современным C++ и не просило бы за это денег.
От начала гугления до первого «может, ну его».
Конечно, вы не сдаетесь и выясняете, что C++ описан в некоем Стандарте. Как ни странно, платном. Зато вы находите его бесплатный черновик. С первых страниц приходит осознание, что он не предназначен для знакомства с языком. Ну, только если вы не привыкли начинать знакомство с разработки компилятора.
Вы снова не сдаетесь и спрашиваете более конкретно: как выучить C++? Вас ждут напутствия:
- Сначала учи сишечку. И ассемблер бы неплохо.
- Читай эту, эту и вот эту книги Страуструпа. Заполируй списком вот из этих книг. Для азов должно хватить.
- Пройди наш курс и станешь гуру. Персональный промокод. Рассрочка.
СкрипачC++ не нужен. Учи %ХАЙПОВЫЙ_ЯЗЫК%.
В докладе «Delivering safe C++» Страуструп затронул проблемы имиджа и распространения C++.
От современного языка ожидается, что к знакомству с ним открыт короткий и понятный путь. У C++ такого пути нет. В отличие от его конкурентов.
Да, лет 5-8 назад мало какой язык мог похвастаться продуманной онлайн-обучалкой. Но за это время индустрия преобразилась. Для изучения языка программирования все реже заходят в книжный и все чаще на интерактивные площадки. Потому что язык можно выучить только одним способом: начав программировать на нем. И курс с задачами, проектами и юнит-тестами помогает это сделать эффективнее всего.
Итак, мы озвучили две причины, сподвигшие нас начать работу над курсом по C++:
- нехватку обучающих материалов по лучшим практикам Modern C++,
- отсутствие простой и эффективной точки входа в C++.
Осталось ответить на вопрос: а не высосаны ли из пальца озвученные проблемы? Кому надо – сам въедет в C++. А язык только выиграет от того, что на пороге отсеиваются все не готовые. Ведь так?
А есть ли проблемы?
C++ сдает позиции. Python и Go заменяют его на бэкенде, а Rust — там, где нужна высокая производительность. C++ вытесняется из ниш, в которых раньше процветал. Почему?
Для программиста C++ — не самый простой и удобный язык. С точки зрения бизнеса — не самый выгодный выбор. Но только ли в этом дело?
В конкурентной борьбе выигрывают языки с наиболее активным комьюнити. Именно сообщество вокруг языка формирует мнение о нем у широкой аудитории. Реклама в собственной компании, публикация интересных статей, развитие образовательных ресурсов — все это работает на рост популярности языка. Если же язык популярен, на нем не боятся начинать новые проекты, а рынок вакансий не схлопывался до узких ниш и легаси.
Уже сейчас очевидно, что комьюнити C++ менее активное и пробивное, чем, например, комьюнити раста. И это особенно опасно в долгосрочной перспективе.
У этой проблемы есть следствие: если мнение о языке не формирует комьюнити, его сформирует кто-нибудь другой. За примером далеко ходить не надо. Прямо сейчас развивается история «C++ опасен, его нужно отменить».
В ноябре 2022 г. Агентство национальной безопасности США (АНБ) выпускает отчет о безопасной работе с памятью. По данным АНБ, 70% дыр в безопасности программ — из-за переполнения буфера и неправильного выделения/освобождения памяти. Цифры взяты от Microsoft и Google. Обе корпорации — счастливые обладательницы легаси на антикварном и крайне своеобразном C++. Сей факт не смущает сотрудников АНБ. Они дают рекомендацию отказаться от мифического языка C/C++ в пользу Python, Java, C#, Go, Delphi/Object Pascal, Swift, Ruby, Rust и Ada.
В декабре 2022 г. Страуструп отвечает открытым письмом, в котором напоминает о Modern C++, Core Guidelines и о том, что безопасность не заканчивается на одном только управлении памятью. А также о том, что во многих случаях безопасность не стоит во главе угла.
В октябре 2023 г. Страуструп выступает с докладом «Delivering Safe C++» на CppCon.
В октябре 2024 г. происходит сразу два события:
- Гугл в своем блоге анонсирует выпиливание из кодовой базы небезопасных языков.
- А на следующий день ФБР и CISA (Агентство по кибербезопасности и защите инфраструктуры США) заявляют, что производители критически важного ПО обязаны к 2026 году предоставить роадмап по миграции с небезопасных языков. Совпадение?
План Гугла по выпилу C и C++.
С трудом верится, чтобы на полном серьезе обсуждались набросы того же порядка, но, напримр, про питон или го. А вы можете представить, чтобы корпорации хвастались роадмапом отказа от питона, потому что у него неявная типизация и нет ключевого слова const
? Думается, питон-комьюнити бы доходчиво объяснило, что это неудачная затея. Будь сообщество C++ бодрее, история про «небезопасность» заглохла бы на старте. И мы возвращаемся к вопросу популяризации.
Правильным шагом в этом направлении будет годный опенсорсный курс. Почему опенсорсный? История знает прекрасные и некогда общедоступные курсы, которые пришли к монетизации и стали закрытыми. Опенсорс, у которого любой желающий может сделать форк, этого риска лишен. А почему для популяризации важна бесплатность, надеюсь, и так понятно.
Опенсорс курс по C++: первое приближение
На четверых участников проекта Senior Junior у нас почти пол века опыта коммерческой C++ разработки. Проекты самые разные: от распределенных систем на C++98 до микросервисов и библиотек на C++20. Навигационные и поисковые движки, мобильные sdk, IDE, видео-стриминг, AdTech, ИБ, ПО для спутников и нефтянки. Мы представляем, какого подмножества C++ достаточно, чтобы чувствовать себя уверенно при решении рабочих задач. И какие идиомы языка встречаются чаще остальных.
Наша цель – чтобы после прохождения курса разработчик мог:
- решать задачи из реальной жизни на современном C++,
- понимать код на старом C++,
- проводить код-ревью,
- собеседоваться,
- представлять, как строится интероп между C++ и другими языками,
- владеть инструментарием для отладки, поиска бутылочных горлышек, профилирования, устранения утечек памяти.
Целевая аудитория курса — программисты. От студентов до синьоров с десятками лет опыта в других языках. Для них не придется раздувать текст объяснениями, что такое функции, массивы, переменные. К тому же, если вы никогда не программировали, начинать с C++ не стоит.
На наш взгляд, эффективный курс по C++ для обозначенной аудитории должен обладать несколькими качествами:
- мотивированностью подачи,
- механизмами для поддержания мотивации продолжать обучение,
- упором на практику.
Мотивированность подачи
Как сказал преподаватель и автор видео-лекций по C++ Илья Мещерин, главный критерий хороших образовательных курсов — мотивированность. Прежде чем подталкивать к использованию очередной фичи языка, нужно подготовить почву для осознания ее необходимости. В чем суть фичи? Зачем она существует? Как бы выглядел код без нее? В каких случаях она полезна, а в каких — нет? Есть ли альтернативы?
Слишком много учебников начинают рассказ про корутины с того, что они делятся на stackful и stackless, что есть ключевые слова co_await
и co_yield
. А вот в чем суть корутин и какие задачи они решают мире конкурентности — не раскрывается. Какую боль снимают модули? А зачем потребовалось вводить в язык рейнджи, жили же без них?
Тема, сильнее прочих пострадавшая от отсутствия мотивированности при объяснении – семантика перемещения. Хотя, казалось бы, вот уж где простор для обсуждения предпосылок!
Худшее, что можно сделать для объяснения семантики перемещения – показать эту схему.
Мотивация разработчика
Никто в этой вселенной не знает C++ полностью. Как при таком раскладе не испугаться и взяться его учить? Как не забить через месяц? Предлагаем сочетать прагматичную приоритизацию тем и дробление длинного пути обучения на короткие дистанции.
Самые широкоупотребимые и важные концепции нужно разбирать в первую очередь. Редкие (пусть даже и увлекательные) нюансы, теряющие актуальность конструкции и наоборот еще не успевшие прижиться фичи — по остаточному принципу. C++ — язык, богатый возможностями. Не нужно знать их все, чтобы писать качественный код.
Многие учебники сходу кидают читателя в мир сырых указателей. Однако современный C++ не поощряет их использование без крайней необходимости. А чем раньше студент сможет приступить к решению реальных задач на C++, тем лучше. Напрашивается вывод, что знакомство с контейнерами и алгоритмами STL должно состояться до погружения в магию адресной арифметики.
Отсортировав таким образом темы, мы получим путь по изучению C++. Длинный путь. Так давайте же разметим его майлстоунами и превратим в набор коротких путешествий.
Каждый майлстоун — маленькая победа, дающая чувство удовлетворения и новый комплект скилов. Первый же майлстоун — это возможность решать задачи на Hackerrank и LeetCode. Путь к нему короток: достаточно запомнить базовый синтаксис C++, научиться пользоваться основными контейнерами и алгоритмами STL.
Разноплановая практика
На нашей площадке мы придерживаемся правила:
Просто читать про язык = тратить время.
Учить язык = писать код.
У нас есть аж три вида практики:
- Решение задач, идущих прямо по тексту глав.
- Выполнение проектов. Проект – это что-то вроде небольшой лабораторной или домашки на пару вечеров.
- Эксперименты в плэйграунде. Большинство примеров кода из глав открываются в плэйграунде в один клик.
Для всех задач и проектов можно посмотреть подсказки и полные решения.
Задачи в главах самые разноплановые: написать решение с нуля, дополнить или исправить уже существующее, прочитать код и понять, что он выведет. Мы стараемся продумывать задачи так, чтобы они покрывали всю теорию.
Глава курса по хаскелю.
Раз в несколько глав пользователи выполняют проект. Примеры проектов из курса по питону: калькулятор алгебраических выражений, утилита tree, простейший поисковый движок.
К каждому проекту прилагается описание и online IDE, в котором можно переключаться между файлами. Среди файлов обязательно присутствуют юнит-тесты.
Проект из курса по питону.
Задачи и проекты важны для нарабатывания практики. Они несут и дополнительную пользу:
- Смена вида деятельности. Если постоянно переключаться между теорией и практикой, материал запоминается более надежно.
- Снижение риска самообмана «мне все понятно, я все запомнил».
- Демонстрация прогресса. Студент видит, что может справляться со все более сложными проектами. А это лучшая мотивация.
Нашим студентам такое чередование практики с теорией понравилось, и мы планируем использовать его в грядущем курсе по C++.
Присоединяйтесь к работе над курсом по C++
Приглашаем всех желающих приложить руку к созданию курса:
- Подключайтесь к обсуждению оглавления. От него зависит, насколько целостным и последовательным получится курс.
- Участвуйте в ревью глав. Для этого подписывайтесь на наш гитхаб и следите за анонсами в телеграм-группе.
- Пробная глава про сборку проекта уже в мастере. Если найдете в ней недочеты, то сообщайте об этом через Issue.
- Присылайте интересные примеры кода и задачи в нашу телеграм-группу и на гитхаб.
Заключение
C++ — для сильных духом. Его невозможно выучить полностью. И тем не менее, его учат. Мы считаем, что опенсорс курс по современному C++ — отличный вклад в будущее любимого языка. И приглашаем всех желающих поучаствовать в работе над курсом!
Автор: Serine