Поговорили о перспективах С++, его особенностях и востребованности на рынке с Андреем Никитиным, ведущим инженером-разработчиком направления системного программирования Нижегородского подразделения компании «Криптонит».
С++ уже более сорока лет. В чём причина его популярности?
В плане семантики — это универсальный язык, но чаще С++ используется как объектно-ориентированный — с наследованием, интерфейсами и так далее. С++ позволяет строить что угодно — универсальные абстракции, иерархии любой сложности, логические слои, стеки протоколов... Обычно среди сильных сторон упоминают кроссплатформенность, но её нет «по умолчанию». Это не Java, программы на которой транслируются в байт-код и запускаются в виртуальной машине. В C++ нужно сразу писать код под все планируемые архитектуры и операционные системы, учитывать зависимые библиотеки. Всё это требует значительных усилий. Кроссплатформенность в С++ не данность, а отдельное требование, которое нужно учитывать на этапе разработки.
Почему С++ используют в «Криптоните» сейчас, когда есть более современные языки?
У нас в компании есть разные проекты. Некоторые из них начинались много лет назад, когда ещё не были популярны Rust, Golang и другие новомодные языки. При этом нам были важны требования производительности и «близости к железу». С++ был у всех на слуху. Он как раз обеспечивал сочетание высокоуровневого языка и возможность использования низкоуровневых функций. Сейчас мы продолжаем его использовать, потому что нет смысла портировать эти многолетние проекты на другие языки. Всё уже выверено и оптимизировано.
Уже не первый год говорят, что C++ — это «мёртвый язык». Насколько вы согласны с такой оценкой?
Его популярность сохраняется на высоком уровне даже на фоне появления более простых в освоении языков. В ближайшие годы от С++ точно не откажутся. В мире существует огромное наследие кода на C++ и тысячи масштабных проектов, которые нужно поддерживать. Сам язык продолжает использоваться и развиваться. Этим занимается комитет по стандартизации, который раз в 3 года выкатывает обновления стандарта и дополнительный функционал. Сейчас мы используем в разработке продуктов C++ стандарта 2020 года и с интересом следим за нововведениями в готовящийся стандарт C++23.
Насколько значительны изменения между разными стандартами С++?
Довольно существенные. Например, в С++20 появился ещё один подход к параллельному программированию — так называемые «корутины», которые несут меньше накладных расходов, чем создание и остановка обычных потоков.
В каких областях чаще всего используется С++?
На С++ пишут всё, что устроено сложно, а должно работать быстро:
игровые движки, включая Unreal Engine и Unity;
Microsoft Office, продукты Adobe (Photoshop, Premiere, Lightroom, After Effects, Illustrator);
браузерный движок Chromium — основа большинства современных интернет-браузеров. Кстати, в одном из проектов «Криптонита» также используется ядро Chromium;
LLVM — низкоуровневая виртуальная машина для написания компиляторов и оптимизации кода;
прошивки, особенно для встраиваемых (embedded) устройств;
различные серверные бэкенды.
Где применяют С++ в «Криптоните»?
Мы как раз используем С++ в бэкендах систем хранения данных, которые получают поток входящего траффика и каким-то образом сохраняют его в различные БД или файловую систему, либо вообще на другой хост. Для этого у нас в «Криптоните» есть модульный event-driven фреймворк, который позволяет эффективно распараллеливать нагрузку и делать дополнительную пре- и пост-обработку входящих данных.
Расскажешь подробнее?
Он построен по классической схеме «звезда», где различные модули обмениваются сообщениями. Такая архитектура позволяет нам очень гибко масштабироваться горизонтально за счёт количества и набора модулей, а также за счёт встроенных в каждый модуль механизмов распараллеливания входящей нагрузки.
Из-за чего C++ теряет массовую привлекательность?
Появляются языки с более низким порогом вхождения. Например, чтобы начать писать телеграм-ботов на Python, достаточно взять гайд из интернета и кодить по нему. В С++ не уедешь далеко без понимания того, как устроена память, логика указателей, как компилируется программа и так далее. По сравнению с более молодыми языками, C++ требовательнее к программисту и не допускает вольностей. Например, в нём нет «динамической типизации». Это статически типизированный язык. Даже когда вы пишете что-то вроде «auto var = 5», переменная var сразу имеет не «какой-то неизвестный», а совершенно точно определённый тип, в данном случае — int. В С++ нет сборщика мусора, поэтому за памятью нужно следить самостоятельно. Это тоже дисциплинирует, заставляет тщательнее продумывать алгоритм. Количество обучающих материалов и документации по С++ просто невообразимое. Кто-то радуется такому обилию, а кого-то отпугивает объём литературы. Например, черновик C++23 занимает более 2000 страниц.
Лично для тебя какие минусы сохранились в С++?
«Минусы» в «плюсах» — забавно! Пожалуй, главный минус — скудная стандартная библиотека. Например, в std даже нет библиотеки для работы c JSON. Это, конечно, боль. Всегда разработчики на C++ были вынуждены сами писать различные вспомогательные утилиты и библиотеки. Из-за этого же когда-то появился boost — набор библиотек классов. С каждым стандартом полезные вещи потихонечку перетекают из буста в стандартную библиотеку, но не так быстро, как хотелось бы.
Почему к С++ настолько разное отношение среди программистов? Одни только его считают «настоящим», а другие ненавидят и всячески критикуют?
Традиционно философией С++ было дать программисту полную свободу действий, чтобы он мог использовать только самое необходимое и не платить потерей производительности за остальное. К сожалению, не всегда программисты пользуются этой свободой правильно. С++ вам не нянька! Делайте, что хотите, но виноваты будете сами! Например, если выделяете память, то не оставляйте её без присмотра. Синхронизация доступа к разделяемым ресурсам — тоже на вашей совести. Вам решать, будет ли это эксклюзивный доступ, или синхронизация через транспорт, или одновременное неблокирующее чтение, либо что-то ещё.
То есть, в С++ компилятор «не думает за программиста»?
С каждым стандартом компилятор становится «умнее», но некоторые негативные эффекты всё ещё могут быть не видны на этапе компиляции. Любая ошибка времени выполнения чревата cегфолтами — ошибками сегментации, то есть — обращению к участкам памяти, недоступным для записи. Чтобы избежать этого и других проявлений «Undefined Behaviour», нужно быть внимательным, пользоваться санитайзерами, статическими анализаторами и тестами.
Наверное, отсюда и возникает основная критика языка?
Да. Чрезмерную свободу называют главным недостатком C++, из-за которого слишком легко «отстрелить себе обе ноги». Просто надо знать инструмент, с которым работаешь. При достаточном уровне понимания он даёт огромную мощь. Когда производительность менее важна, можно писать высокоуровневый абстрактный ООП код, а когда надо максимально ускориться — то обратиться к низкоуровневым возможностям языка и оптимизировать код под конкретную архитектуру. Освоение C++ позволяет не просто изучить программирование, но и лучше понять взаимосвязи между кодом и железом. Зная С++, гораздо легче изучать другие языки.
В новых стандартах С++ появились какие-то «предохранители», которые не дают так просто «выстрелить себе в ногу»?
В современном С++ многое стало проще. Например, идиома RAII (получение ресурса = инициализация, а освобождение ресурса = уничтожение объекта) и умные указатели решают проблемы, связанные с временем жизни объектов и необходимостью вручную следить за памятью. Сейчас на С++ проще писать относительно безопасный и эффективный код, который даже может быть похож на «plain english», а не на караван знаков препинания.
Насколько просто изучать С++ самостоятельно?
Зависит от человека. В современных реалиях изучать С++ с нуля полностью самостоятельно, на мой взгляд, довольно сложно. Особенно в качестве первого языка. Такое подойдёт только упорным, если не сказать дотошным, людям. С другой стороны, многие выбирают путь самостоятельного изучения, опять же — из-за обилия обучающих материалов и очень развитого сообщества разработчиков. Наверное, С++ имеет одно из самых обширных комьюнити по всему миру.
Считаю, что среди обучающих курсов довольно много инфоцыганщины, ведь реальные разработчики заняты в реальных проектах, а кто и чему там учит — это дискуссионный вопрос. При этом есть бесплатные образовательные проекты. Как правило, их ведут идейные люди. Например, взгляните на блог гика многопоточного программирования Дмитрия Вьюкова. Также в качестве практики можно решать задачки на leetcode. На мой взгляд, оптимально получить некоторую базу, а потом заниматься практикой и самостоятельным развитием.
Традиционной площадкой для поиска ответов на вопросы разработчиков является Stack Overflow. Перед тем, как задать там вопрос, стоит внимательно поискать. C большой вероятностью, его уже задавали раньше. Обратите внимание на cppreference.com. Его можно использовать в качестве документации к стандартной библиотеке. Есть и русскоязычные ресурсы. Много полезной информации по С++ можно найти на том же Хабре.
Каким был твой путь освоения C++?
Я начал изучение С++ в университете (ННГУ им. Лобачевского, факультет ВМК). Потом работал долгое время на С89, а сейчас уже больше 6 лет пишу на С++. У меня обучение растянулось на долгий период и ещё продолжается, в том числе потому, что в каждом стандарте вводятся новые конструкции.
Как ты оцениваешь востребованность С++ на рынке труда?
Примерно с 2016 года в опросах Rust лидирует как «самый любимый» язык. Однако рынок труда все ещё на стороне С++. Если посмотреть вакансии на hh.ru, то можно с удивлением обнаружить, что по запросу «rust developer» находится гораздо меньше вакансий, чем по запросу «С++ developer». Так что, С++ всё ещё очень востребован.
На собеседованиях часто просят показать свои наработки: код на GitLab, разные pet-проекты. С чего посоветуешь начать?
Можно написать внешне простую игрушку с хорошей внутренней логикой, например, шахматы с графикой на Qt. Ещё популярный вариант — программировать микроконтроллеры и электронные конструкторы типа Arduino, писать код по автоматизации для умных устройств. Это весьма перспективное направление. А для нашей команды, например, актуален бэкенд. Было бы интересно увидеть у соискателя код, реализующий что-нибудь многопоточное, с конкуренцией за ресурсы и обработкой данных из разных источников.
Если программист захочет перейти на другой язык, то какой легче освоить после С++?
Наверное, самым близким к С++ можно считать Rust. Его старались сделать проще, компактнее, безопаснее, уйти от известных недостатков С++. Однако не спешите очаровываться им. Пока спрос на Rust-программистов гораздо ниже, да и перейти будет легко только в одну сторону: с C++ на Rust, но не наоборот. Всё дело в понимании «внутренней кухни», которую даёт С++. Ещё хочу обратить внимание, что Rust не столько заменяет, сколько дополняет C++. У нас есть один проект, в котором код пишут на этих двух языках, а потом компилируют его в один бинарный файл через сишное API.
Когда вы набираете новых людей в команду, как вы их оцениваете?
Скажу, чего мы не делаем: мы не смотрим на «корочки» и сертификаты о прохождении курсов. Беседуем предметно, и по ответам довольно быстро становится понятен реальный уровень знаний претендента.
Кстати, прямо сейчас у нас есть вакансия Senior developer C++ в команду Нижнего Новгорода! Переходите по ссылке, чтобы узнать подробности, и откликайтесь прямо на сайте.
Эта статья завершает наш цикл про языки программирования. Ранее наши разработчики делали обзоры Rust, Scala, JavaScript, Spark, Golang и Python.
Комментарии (13)
ManGegenMann
17.06.2024 08:42+1Нужно признать что нам нужен С++ 2.0. Язык который твёрдо и чётко полностью выкинет обратную совместимость с С и старыми версиями С++.
В текущем виде С++ это уродливый гомункул с кучей говняка который так любят ковырять фанаты. Похожая ситуация у С# где 1 действие можно сделать 5 способами которые компилируются в один IL.
Octabun
17.06.2024 08:42Только что, считай случайно, прикоснулся к С++. Оказывается, ни g++ ни clang+ не поддерживают std::format. Это как вообще? А так - язык отдельно, компиляторы отдельно, библиотеки отдельно, все сидят по болотам и берут пример с куликов.
В Rust, на мой личный вкус, очень много закономерно неправильных, ибо преследующих ложные цели, решений, но только того, что rustup и cargo существуют в единственном экземпляре, на тот же вкус достаточно чтобы оправдать найденное в Сети мнение
На Rust пишут для того чтобы не писать на С++.
потому что не враги самим себе.
KanuTaH
17.06.2024 08:42+2Только что, считай случайно, прикоснулся к С++. Оказывается, ни g++ ни clang+ не поддерживают std::format. Это как вообще?
Ну как же не поддерживают-то? Какие-то более старые версии, может, и не поддерживают, что неудивительно: развитие - это постепенный процесс, все сразу мгновенно ниоткуда не появляется.
MiyuHogosha
17.06.2024 08:42стаая версия. Или не вставил стандарт. Мжно восползоваться реализацией {fmt}
Octabun
17.06.2024 08:42Или не вставил стандарт.
Конечно ничего не вставлял, я же прикоснулся, а std::stringstream есть. Но что пишет clang по этому поводу?
-std=<value> Language standard to compile for
И что прикажете писать, списка вариантов то нет... И самое главное - КАКОГО ЧЁРТА ТУТ ЕСТЬ ВАРИАНТЫ КРОМЕ СУПЕР ЗАПАСНЫХ НА СЛУЧАЙ НЕ ПОСЛЕДНЕГО СТАНДАРТА, ВЫБЕСИЛО УЖЕ.
И g++ не лкчше
-std=<standard> Assume that the input sources are for <standard>.
Писука хотя бы самосогласована, так что лучше, но совсем чуть-чуть.
Но я не столько об этом, сколько о попытках отрицать очевидное но неприятное, которые в итоге защищаемому объекту медвежья услуга. Это особо опасно именно сейчас, но это моё личное мнение.
И немножко про то что именно этим путём приходим, например, к тому, что копипаста на Хабр даёт не вполне то что в цитатах выше, а
-std= Assume that the input sources are for .
MiyuHogosha
17.06.2024 08:42+3Это международный стандарт, поэтому и есть варианты. Требование стандарта является необходимость соответствовать документации на стандарт.
Ни один из компиляторов сейчас не поддерживает 20-й и 23-й стандарт полностью. Поэтому оно не по умолчанию. А на маке "шланг" вообще еще в 98м году живет, потому что это их корпоративный стандарт.
стандарты идут в формате с++XX и gnu++XX для Си++. Список поддерживаемых указан в документе в справке на эту опцию в случае g++. А спрашивать надо g++, не gcc, gcc - это точка входа разных компиляторов и других средств сборки.
Библиотека {fmt} является канонической реализацией std::format, ей и отдельно можно пользоваться.
Octabun
17.06.2024 08:42+1Ни один из компиляторов сейчас не поддерживает 20-й и 23-й стандарт полностью. Поэтому оно не по умолчанию
Справка gcc полагает иначе - потому, что поддержка всё ещё экспериментальная.
В остальном то, что Вы пишете, только подтверждает то, что я написал, спасибо.
KanuTaH
17.06.2024 08:42Но я не столько об этом, сколько о попытках отрицать очевидное но неприятное, которые в итоге защищаемому объекту медвежья услуга. Это особо опасно именно сейчас, но это моё личное мнение.
Опасно критиковать то, в чем совершенно не разбираешься, и не именно сейчас, а всегда. Впрочем, опасно это главным образом для самого "критикана".
yokotoka
17.06.2024 08:42Было бы интересно увидеть у соискателя код, реализующий что-нибудь многопоточное, с конкуренцией за ресурсы и обработкой данных из разных источников
<sarcasm> То есть пишущего на Go?
kekoz
17.06.2024 08:42+2В ближайшие годы от С++ точно не откажутся.
Что-то мне так чувствуется, что “ближайшие годы” — это лет так 15-20 минимум. Больше того, я практически уверен, что в эти “ближайшие годы” и C никуда не умрёт.
cat-chi
Я очень люблю C++. Этот язык можно изучать бесконечно! В нём бесконечное количество способов решить задачу. Я бы даже сказал, что количество способов решения задачи в C++ равно количеству разработчиков, которые пишут на C++.
Словом, чертовски интересный язык.
Но для задач, где требуется быстро получить результат, я предпочту любой другой язык – с богатой стандартной библиотекой, удобным тулчейном, адекватной системой сборки и т.д.
Конечно, сейчас для C++ не всё так страшно. Тот же Conan немного спасает ситуацию. Интересных библиотек и фреймворков добавилось, особенно когда Yandex начал выкладывать свои разработки в open source.
Но всё-таки нет.