Поговорили о перспективах С++, его особенностях и востребованности на рынке с Андреем Никитиным, ведущим инженером-разработчиком направления системного программирования Нижегородского подразделения компании «Криптонит».

С++ уже более сорока лет. В чём причина его популярности?

В плане семантики — это универсальный язык, но чаще С++ используется как объектно-ориентированный — с наследованием, интерфейсами и так далее. С++ позволяет строить что угодно — универсальные абстракции, иерархии любой сложности, логические слои, стеки протоколов... Обычно среди сильных сторон упоминают кроссплатформенность, но её нет «по умолчанию». Это не 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)


  1. cat-chi
    17.06.2024 08:42
    +4

    Я очень люблю C++. Этот язык можно изучать бесконечно! В нём бесконечное количество способов решить задачу. Я бы даже сказал, что количество способов решения задачи в C++ равно количеству разработчиков, которые пишут на C++.

    Словом, чертовски интересный язык.

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

    Конечно, сейчас для C++ не всё так страшно. Тот же Conan немного спасает ситуацию. Интересных библиотек и фреймворков добавилось, особенно когда Yandex начал выкладывать свои разработки в open source.

    Но всё-таки нет.


  1. ManGegenMann
    17.06.2024 08:42
    +1

    Нужно признать что нам нужен С++ 2.0. Язык который твёрдо и чётко полностью выкинет обратную совместимость с С и старыми версиями С++.

    В текущем виде С++ это уродливый гомункул с кучей говняка который так любят ковырять фанаты. Похожая ситуация у С# где 1 действие можно сделать 5 способами которые компилируются в один IL.


    1. OverThink
      17.06.2024 08:42

      Посмотрим как Carbon себя покажет))


  1. Octabun
    17.06.2024 08:42

    Только что, считай случайно, прикоснулся к С++. Оказывается, ни g++ ни clang+ не поддерживают std::format. Это как вообще? А так - язык отдельно, компиляторы отдельно, библиотеки отдельно, все сидят по болотам и берут пример с куликов.

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

    На Rust пишут для того чтобы не писать на С++.

    потому что не враги самим себе.


    1. KanuTaH
      17.06.2024 08:42
      +2

      Только что, считай случайно, прикоснулся к С++. Оказывается, ни g++ ни clang+ не поддерживают std::format. Это как вообще?

      Ну как же не поддерживают-то? Какие-то более старые версии, может, и не поддерживают, что неудивительно: развитие - это постепенный процесс, все сразу мгновенно ниоткуда не появляется.


      1. MiyuHogosha
        17.06.2024 08:42

        стаая версия. Или не вставил стандарт. Мжно восползоваться реализацией {fmt}


        1. 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 .


          1. MiyuHogosha
            17.06.2024 08:42
            +3

            Это международный стандарт, поэтому и есть варианты. Требование стандарта является необходимость соответствовать документации на стандарт.

            Ни один из компиляторов сейчас не поддерживает 20-й и 23-й стандарт полностью. Поэтому оно не по умолчанию. А на маке "шланг" вообще еще в 98м году живет, потому что это их корпоративный стандарт.

            стандарты идут в формате с++XX и gnu++XX для Си++. Список поддерживаемых указан в документе в справке на эту опцию в случае g++. А спрашивать надо g++, не gcc, gcc - это точка входа разных компиляторов и других средств сборки.

            Библиотека {fmt} является канонической реализацией std::format, ей и отдельно можно пользоваться.


            1. Octabun
              17.06.2024 08:42
              +1

              Ни один из компиляторов сейчас не поддерживает 20-й и 23-й стандарт полностью. Поэтому оно не по умолчанию

              Справка gcc полагает иначе - потому, что поддержка всё ещё экспериментальная.

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


            1. voldemar_d
              17.06.2024 08:42
              +1

              fmt и std::format всё-таки имеют отличия.


          1. KanuTaH
            17.06.2024 08:42

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

            Опасно критиковать то, в чем совершенно не разбираешься, и не именно сейчас, а всегда. Впрочем, опасно это главным образом для самого "критикана".


  1. yokotoka
    17.06.2024 08:42

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

    <sarcasm> То есть пишущего на Go?


  1. kekoz
    17.06.2024 08:42
    +2

    В ближайшие годы от С++ точно не откажутся.

    Что-то мне так чувствуется, что “ближайшие годы” — это лет так 15-20 минимум. Больше того, я практически уверен, что в эти “ближайшие годы” и C никуда не умрёт.