вторник, 1 января 2030 г.

О блоге

Более двадцати лет я занимался разработкой ПО, в основном как программист и тим-лид, а в 2012-2014гг как руководитель департамента разработки и внедрения ПО в компании Интервэйл (подробнее на LinkedIn). В настоящее время занимаюсь развитием компании по разработке ПО stiffstream, в которой являюсь одним из соучредителей. Поэтому в моем блоге много заметок о работе, в частности о программировании и компьютерах, а так же об управлении.

Так же я пишу о жизни вообще и о нескольких своих увлечениях: о фотографии (включая публикацию своих фотографий, некоторые есть и на ZeissImages), о спорте, особенно о дартсе, и, совсем коротко, о кино.

понедельник, 31 декабря 2029 г.

[life.photo] Характерный портрет: вы и ваш мир моими глазами. Безвозмездно :)

Вы художник? Бармен или музыкант? Или, может быть, коллекционер? Плотник или столяр? Кузнец или слесарь? Владеете маленьким магазинчиком или управляете большим производством? Реставрируете старинные часы или просто починяете примус? Всю жизнь занимаетесь своим любимым делом и хотели бы иметь фото на память?

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

суббота, 11 мая 2024 г.

[prog.c++] Из непонятого: как же лучше погружать в современный C++ новых людей?

У меня недавно закончился небольшой контракт на проведение для молодых программистов чего-то вроде "курса молодого бойца" по C++. Что заставило в очередной раз задуматься на тему "а не стал ли C++ настольно монстрообразным, что обучить новичка практически невозможно?"

Но это сильно глобальный вопрос, я даже не знаю как к нему подойти. Радует лишь то, что сам я C++ изучаю года с 1991-го, когда это был, мягко говоря, совсем другой язык. Гораздо более простой, последовательный и логичный. И мне повезло, что на эту небольшую базу затем инкрементально ложились новые возможности: пространства имен, исключения, шаблоны, STL и т.д., и т.п. Т.е. сам я учил C++ по мере того, как в него добавлялись новые фичи. И поскольку добавлялись они раньше не в таком количестве и не с такой скоростью, то поспевать за ростом сложности C++ где-то до 17-го стандарта еще удавалось. Однако, на C++20 это уже сломалось даже для меня :(

Впрочем, это опять таки уход в сторону от того, о чем хотелось сегодня поговорить.

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

С одной стороны, я противник подхода, при котором разработчика сперва учат языку Си, а затем начинают давать ему C++ по частям. Типа сперва чистый Си, затем немного "Си с классами", затем чуть-чуть шаблонов, затем чуть-чуть STL, затем еще чуть-чуть шаблонов и т.д.

Как по мне, Си и C++ уже очень и очень давно совершенно разные языки. Да, в C++ есть изрядное подмножество чистого Си, но все-таки идеология C++ другая и к таким вещам, как ссылки, классы, деструкторы, нужно привыкать сразу. Чем меньше приемов из чистого Си, тем лучше.

Поэтому вроде как есть смысл новичков сразу учить использовать то хорошее, что есть в C++. Например, std::string для строк вместо char*, std::string_view вместо const char*, std::vector и std::array вместо Си-шных массивов, std::find_if вместо голых циклов и вот это вот все.

Но тут есть серьезная засада, особенно в случаях, когда у новичков за плечами уже есть опыт работы с языками со сборкой мусора (будь то Python или Java, не суть важно). По моим впечатлениям у тех, кто изучает C++ сейчас, есть проблемы с пониманием разницы между values и references. Грубо говоря, люди пишут:

void f(std::string param) {...}

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

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

Как следствие, та же move-семантка, без которой современный C++ был бы не нужен в принципе, не очень хорошо заходит. Научить избегать копирования -- это уже задача. А научиться избегать копирования за счет грамотного и регулярного использования move-семантики оказывается задачкой со звездочкой.

Рефлексируя на эту тему я пока придерживаюсь мнения, что виной тому как раз использование готовых "высокоуровневых" возможностей STL. Те же самые std::string и std::vector освобождают программиста от изрядного геморроя, но не дают этому самому программисту понимания того, как же это все работает "под капотом". А без такого понимания сложно программировать на C++ эффективно.

Что заставляет задуматься о том, чтобы учить людей C++у без использования готовых классов и шаблонов из STL.

Грубо говоря, если начинать обучение с того, чтобы молодой C++ник сам написал аналог string-а, vector-а и hash_map-а, сам бы почувствовал где и когда вызываются конструкторы, деструкторы, операторы копирования, где требуется выделить память, где освободить, где скопировать содержимое и столкнуться с проблемой exception safety... Вот если начинать обучение с этого, то может быть у человека будет гораздо больше понимания разницы между передачей по значению или по ссылке, между копированием и перемещением и т.д., и т.п.

Такой подход, на первый взгляд, производит впечатление более перспективного. Мол, мы сперва даем людям базу. А потом на эту базу кладем знания об уже готовых классах/алгоритмах из STL, чтобы можно было ощутить насколько жизнь может быть проще если пользоваться тем, что уже написано.

Но и здесь все не так радужно. Во-первых, такое обучение потребует гораздо больше времени. Ведь если мы научим молодого C++ника делать свой vector, то он все равно еще будет далек от того, чтобы уметь писать нормальный прикладной код.

Во-вторых, по моему субъективному мнению, написание библиотек классов (пусть даже в такой библиотеке будет всего лишь string, vector и hash_map) требует несколько иных навыков, нежели написание прикладного кода. Да, возможно это тараканы в моей голове, но я убежден, что библиотеко-писатели и прикладники -- это разные специалисты. Бывают, конечно, и те, кто одинаково хорош и в том, и в другом, но это такое же частое явление, как и хорошие программисты, вырастающие в хороших менеджеров. В общем, начиная с реализации собственных string и vector можно не получить должного эффекта, если обучаемый больше склонен к решению прикладных проблем, чем к написанию библиотек.

В-третьих, этот подход как раз таки очень близок к подходу, когда мы сперва учим людей чистому Си, а уже затем переходим к использованию высокоуровневых возможностей C++. Близок, не не тождественен. Тем не менее, если молодой разработчик привыкает писать относительно низкоуровневый код с ручными new/delete, alignof/alignas и пр. заморочками, то есть опасность, что он и продолжит в том же духе. Тут людей сразу пытаешься учить пользоваться std::unique_ptr и std::make_unique, а они все равно норовят использовать голые владеющие указатели с new/delete... Что уж говорить о тех, кого специально с самого начала ограждают от std::unique_ptr, std::optional, std::variant, std::vector и т.д.

В общем, я пока для себя ответа не нашел. Не знаю по какому пути следует двигаться, особенно если на серьезное погружение в С++ есть не месяц, а хотя бы полгода.

В завершение еще раз поделюсь своими тягостными впечатлениями о том, что C++ на мой взгляд, стал слишком уж большим и сложным для того, чтобы его мог изучить и освоить человек "со стороны". Речь не о старпёрах, вроде меня, кто за 30 лет в программизме имел возможность осваивать фичи "современного C++" по мере их появления. А о тех, кто про C++ ничего не знал, но должен изучить за относительно небольшое время. Как таким новичкам преподавать тот же С++20? Вот это вопрос.

Хотя, может быть я излишне пессимистичен. Может это лично мне тяжело осваивать C++20, т.к. я уже старый, мозги уже плесневеть начали, много там лишних и устаревших знаний скопилось, да еще и не так уж много возможностей применять C++20 на практике. Отсюда и мое собственное заблуждение о том, что изучать C++20 сложно. А когда человеку 20 лет, все вокруг неизвестно и удивительно, то может быть C++20 залетает в пустую юную голову просто "на ура"... Ведь может же быть и такое.

четверг, 2 мая 2024 г.

[prog.c++] Одно из недооцененных мной качеств C++

Есть в C++ одно качество, на которое я сам начал обращать внимание относительно недавно, года три или четыре назад. А вот поговорить об этом захотелось только сейчас, после выхода большой статьи "Leaving Rust gamedev after 3 years" (ее перевод уже начали делать и на Хабре -- вот первая часть).

Сразу скажу, что статью про Rust целиком не осилил, т.к. геймдев вообще не моя область. Да на Rust-е не программирую (может быть и зря, но это уже совсем другая история).

Тем не менее в начале "Leaving Rust..." речь идет о том, что Rust, в силу своей специфики, затрудняет быстрое прототипирование. Мол, Rust настолько пристально следит за программистом, что не позволяет писать откровенный говнокод. Даже в случаях, когда целью программиста является именно быстренько что-то наговнякать, проверить результат и выбросить все написанное.

Читая эту "претензию" к Rust-у вспомнил про то самое качество C++ о котором и пойдет сегодня речь.

Суть в том, что C++ позволяет программисту написать откровенно плохой код. Который, тем не менее, будет работать.

Да, да. Речь именно о том, что на C++ любой "недоучка" может написать работающий говнокод. Ключевое здесь "работающий", а "говнокод" -- это так, функция от времени ;)

И, что еще интереснее, даже работающий с приемлемой скоростью.

Т.е. неопытный C++ник из говна и палок может получить нужное ему решение.

Конечно, во многих случаях такой код будет падать, т.к. тестированием чего-то кроме happy path в таких условиях не занимаются. Конечно, он будет неэффективно расходовать память, делать что-то лишнее, протекать и иметь кучу потенциальных UB...

Но здесь и сейчас он будет работать.

И, что удивительно, на ранних этапах жизненного цикла нового софта это все, что требуется.

Грубо говоря, два-три человека, не сведущих в C++, берут и пишут несколько тысяч (а то и несколько десятков тысяч) строк кода на C++, в итоге получается первая версия работающего продукта, которая и позволяет продукту начать свой путь к потребителю. А это, по большому счету, и есть самое главное.

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

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

Выше я не зря взял термин "недоучка" в кавычки. Иногда это студенты, которые слишком рано, не имея практического опыта, попали "под крыло" к специалистам в какой-то узкой прикладной нише. Иногда это люди, которые уже умеют программировать и, зачастую, делают это очень хорошо. Но не на C++, а на Python-е или VisualBasic-е, к примеру. Да и вообще в своей предметной области съели не одну собаку. И, что самое важное, они знают что нужно клиентам и как это клиентам продать.

Но вот на C++ никогда толком не программировали, а когда понадобилось, то получили минимальные знания о языке и сходу наговнякали именно то, что им было нужно.

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

Так-то я привык к работе в условиях, когда качеству уделяется серьезное внимание, и думал, что подход "фигаг-фигак-и-в-продакшен" за последние 15-20 лет из C++ полностью ушел в Java, Python и Go. Просто в силу того, что ниша C++ все эти годы скукоживается и C++, к счастью, остается лишь там, где в этом еще есть смысл.

Но оказалось, что нет. Что новые проекты на C++ вполне себе начинают. Что на этих проектах есть фаза быстрого прототипирования. И что на этой фазе на C++ пишут абы как, и это (к моему удивлению) не ведет к фатальным последствиям.

Почему не ведет к фатальным последствиям для меня пока еще загадка. Могу предположить, что здесь здорово помогают современные средства разработки с крутыми отладчиками, анализаторами и санитайзерами. Ну и стандартная библиотека C++, хоть и остается куцей, но хотя бы std::vector и std::string уже есть везде, не нужно свое колхозить, как было в 1990-х.

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


Мое личное отношение к C++ за минувшие годы не поменялось. Как считал язык пригодным только для разработки небольшими командами опытных программистов, так и считаю. Если вам удалось такую команду собрать, что вы сможете получать и качественное решение, и в относительно сжатые сроки, и работать оно будет надежно.

Но если над кодовой базой должно работать несколько десятков человек с разной квалификацией, то C++ плохой выбор (жирное ИМХО).

среда, 1 мая 2024 г.

[life.cinema] Очередной кинообзор (2024/04)

Традиционный отчет о просмотренных за минувший месяц фильмах. Традиционно в начале каждого из списков то, что мне понравилось больше, а в конце то, что понравилось меньше всего или же оказалось откровенным шлаком (спойлер: в этом случае совсем уж откровенного шлака не было, даже "Манкимена" было любопытно посмотреть).

Фильмы

Дюна: часть вторая (2024). Красиво. Пожалуй, это все, что я могу сказать хорошего. Полагаю, фильм для тех, кому и сама книга-первоисточник понравилась. Но т.к. мне и книга не зашла, то и фильм оставил равнодушным. Так что если сделают и третью часть, то я ее, пожалуй, вообще смотреть не буду. Но красиво, да.

Хитмен. Последнее дело (Knox Goes Away, 2023). Отличная развязка. Но чтобы ее дождаться придется вытерпеть полтора часа скучной тягомотины.

Манкимэн (Monkey Man, 2024). Ну что тут сказать? Можно вывезти индуса в Голливуд, но вывести Болливуд из индуса невозможно. Как по мне, так даже попытки сделать экшОн в духе "Джона Уика" не помогают.

Сериалы

Золотое дно (первый сезон, 2024). Мне вот прям зашло, посмотрел с удовольствием. Да, в конце авторы не смогли поставить жирную точку и закинули удочки для второго сезона, но все-таки основные линии до развязки довели, за что отдельное спасибо. Пожалуй, лучшее из российских сериалов, что удалось посмотреть после Без правил.

Fallout (первый сезон, 2024). В игры Fallout никогда не играл и даже ничего про них не слышал, кроме того, что такие игры есть в принципе. А вот экранизацию было интересно смотреть даже несмотря на отсутствие каких-либо знаний о фантазийном мире Fallout-а. Отличный получился треш на тему выживания после глобальной ядерной войны. Но! Кино явно для любителей подобного треша.

Банда «ЗИГ ЗАГ» (первый сезон, 2023). Динамично. Нет ни грамма сериальной затянутости. Но столько клюквы развешено, что как-то не по себе местами становится.

Континенталь (первый сезон, 2023). Первая серия более-менее, хотя экшОна не хватило. Вторая серия -- откровенная нудятина. Третья как раз то, что от подобного фильма и ждут. Так что если бы хронометраж сократили часа на полтора, получилось бы отлично.

воскресенье, 28 апреля 2024 г.

[life.photo] В первые за долгое, долгое время сделал несколько кадров на полноценную камеру

Давненько не отводил душу посредством фотографии. Сегодня чуть-чуть удалось. Из более чем 80 кадров, после выбраковки осталось всего пять, увидеть их можно вот в этом альбоме.

Хочется надеятся, что возможностей и желания прогуляться с фотокамерой будет больше, чем в последние 3-4 года.

четверг, 25 апреля 2024 г.

[prog;work;wow] Марко Арена завершил свою серию статей про SObjectizer

Марко Арена сегодня завершил свою серию статей "SObjectizer Tales", начатую в октябре прошлого года. Полный список статей из этой серии я приведу ниже.

Сперва же хочется сказать слова благодарности. Результат получился впечатляющим, я такого не ожидал от слова совсем. Вышло очень и очень круто, большое спасибо, Марко!

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

Изначально я даже и не мог предположить, во что же это все выльется. Когда Марко спросил у меня как я отношусь к идее того, что он сделает серию постов про SObjectizer, и в самых смелых фантазиях невозможно было представить, что эта серия будет содержать тридцать (тридцать, Карл!) статей.

Как по мне, так Марко написал целую книгу. Что по объему, что по глубине и качеству материала.

И, что особенно радует, так это то, что написано все это не кем-то из SObjectizer Team, а пользователем SObjectizer-а. Скажи мне об этом кто-то еще года два-три назад, я бы счел подобное ненаучной фантастикой. А теперь это реальность.

Более того, я бы даже назвал выход серии "SObjectizer Tales" целой вехой в истории развития SObjectizer-а. Важной и значимой лично для меня.

Так что, да, я шокирован. В хорошем смысле этого слова.


Вот как в итоге выглядит вся серия.


PS. Что доставляет отдельно, так это слоган, который Марко выбрал для своей серии: Concurrent C++, made simple. Таки да, для этого все когда-то и затевалось. Но я бы насколько лаконично и емко выразить бы не смог.