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

О блоге

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

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

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

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

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

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

пятница, 17 апреля 2026 г.

[prog.c++] Просмотрел чужой доклад о SObjectizer

Марко Арена сделал доклад о SObjectizer и этот доклад публично доступен на YouTube: [Milan Meetup] Concorrenza multiparadigma con SObjectizer (Marco Arena)

Выступление на итальянском языке, но с помощью Yandex Browser можно послушать в переводе.

Дополнительные материалы (слайды на английском и репозиторий с кодом) доступны здесь: https://lao.bz/mcs

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

Про себя могу сказать так: с трудом верится, что все это происходит. Выкладывая SObjectizer в открытый доступ мы, конечно же, надеялись, что инструмент окажется кому-то полезным. Но вот чтобы доклады о SO-5 читал кто-то не из моей команды... Это всегда воспринималось как фантастика.

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

среда, 15 апреля 2026 г.

[prog.sadness] Вскрик души в процессе копания в чужом коде

Краткая выжимка впечатлений после нескольких дней археологических раскопок в чужом самодокументирующемся (т.е. без комментариев от слова совсем) коде.

PascalCase -- отстой.

PascalCase в совокупности с длинными строками и экономией на пробелах и пустых строках -- отстой вдвойне.

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

Удачно выбранные имена классов рулят. Неинформативные имена или имена, отличающиеся всего одной буквой (например, resource_handler и resources_handler) доставляют (в худшем смысле этого слова) неимоверно.

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

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

Но главное впечатление, еще более субъективное, личное и неутешительное для меня самого: очень сложно работать с кодом, написанным по принципу "сейчас кое как слепим, а потом переделаем по нормальному". Пытаясь разобраться с результатом главная мысль в голове -- "Господь, жги, тут уж ничем не помочь". А жечь то как раз и нельзя 😡

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

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

пятница, 3 апреля 2026 г.

[prog.c++] Эх, давно я не брал в руки SObjectizer...

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

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

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

Передачу memory_pool-а в дочернюю нить сделал через переменные, защищенные mutex-ом. А чтобы эффективно ждать появление значений в этих переменных -- std::condition_variable. Чтобы получить уведомление от дочерней нити о том, что memory_pool перестал использоваться, задействуется std::promise и std::future. Как-то многовато для того, чтобы прокинуть одну команду из родительской нити в дочернюю, а затем один сигнал обратно 🙁

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

И вот после того, как все это было сделано, стала терзать мысль о том, что на SObjectizer-е с mchain-ами должно же было бы получиться проще. Терзала она меня, терзала, и в конце-концов заставила потратить немного времени, чтобы сделать вариант на SO-5.

Ну и что хочу сказать? 😉

На SO-5 и компактнее, и проще, и понятнее. На мой сугубо субъективный взгляд.

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

Получается тривиальное взаимодействие: в родительской нити сперва send, затем receive, а в дочерней нити сперва receive из которого уже делается send в обратном направлении.


Отдельный вопрос по поводу надежности каждого из решений. В общем, она там везде никакая, т.к. изначально все рассчитано только на happy path.

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

  • автоматическое завершение дочерней нити в SObjectizer-варианте как раз уже обеспечивается за счет использования auto_joiner-ов и auto_closer-ов;
  • контроль тайм-аутов ожидания в случае с so_5::receive добавляется элементарно. В случае с примитивами из C++ной библиотеки, в принципе, тоже не сложно, но телодвижений, имхо, все-таки чуть-чуть побольше потребуется.

Я специально не стал вставлять фрагменты кода в пост, а дал ссылки на github. Прежде всего ради экономии собственного времени на написание этого текста. Но если такой вариант неудобен и читателям хотелось бы видеть куски кода прямо здесь, то дайте знать в комментариях, пожалуйста.

четверг, 2 апреля 2026 г.

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

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

Фильмы

Аватар: Огонь и пепел (Avatar: Fire and Ash, 2025). Лично мне понравился гораздо больше, чем вторая часть. Ничем не удивил, но это образец отлично сделанного аттракциона, после которого не жалко потраченного времени.

Ограбление в Лос-Анджелесе (Crime 101, 2026). В принципе, норм. Но мне не хватило экшена и показалось, что фильм излишне затянут.

Военная машина (War Machine, 2026). Красочно, динамично, прямолинейно, тупо и пафосно. При желании можно посмотреть, а можно и проигнорировать данное "кино".

Ночной замес (Wake Up, 2023). Хороший пример недорогого молодежного слешера. Любители жанра могут спокойно смотреть, здесь нет ничего лишнего, мне даже понравилось как сыграл главный злодей.

На помощь! (Send Help, 2026). Не понял что это было: для серьезного триллера слишком много дурацкого юмора и откровенного треша, для чернушной треш-комедии слишком мало дурацкого юмора и откровенного треша. Как сюда занесло Рейчел МакАдамс просто загадка.

Крик 7 (Scream 7, 2026). Динамично, кроваво. Но тупость большинства персонажей множит все хорошее на ноль.

Адское пламя (Hellfire, 2026). Мог бы быть душевный боевичок в стиле 1980-х с сильно постаревшими, но крутыми в прошлом актерами, если бы не нарисованная на компьютере стрельба. Такая откровенная дешевизна убивает все хорошее, что в фильме могло бы быть. Можно смело пройти мимо и не тратить свое время.

Тропа гнева (2025). Откровенная халтура, лучше не смотреть.

Иерархия (Hierarchy, 2025). Дешевая поделка. Не стоит тратить на это время.

Сериалы

Подслушано в Рыбинске (первый сезон, 2024). Отличное кино, посмотрел с удовольствием.

Ограбление (Steal, первый сезон, 2025). Нормально. Есть пара моментов, к которым мне бы хотелось придраться, но в целом можно смотреть.

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

Захваченный рейс (Hijack, второй сезон, 2026). К сожалению, можно лишь повторить то, что писал про первый сезон: "Отлично снято и к игре актеров нет претензий. Пожалуй, это все хорошее, что можно сказать про этот сериал. Остальное, как по мне, одни недостатки." Если кому-то понравился первый сезон, то можно глянуть и второй. А вот если не понравился или не смотрели, то лучше бы пройти мимо.

Незнакомка (The Stranger, 2020). Смотреть интересно, но когда сезон заканчивается и начинаешь анализировать итоги, то складывается ощущение, что "нам втирали какую-то дичь".

понедельник, 30 марта 2026 г.

[prog.c++] Говорят, что основная работа над C++26 завершена

Например, об этом написал Герб Саттер. Типа в C++ теперь есть и рефлексия, и контракты, и даже уменьшено число UB. Уж теперь-то точно заживем.

У меня, однако, отношение к данному событию весьма равнодушное.

Ну вот не отношусь к счастливчикам, которые пилят один проект для одной платформы на одном компиляторе. Посему не могу сидеть на самом свежем GCC (или clang-е, или MSVC) под самой-самой свежей ОС и наслаждаться плюшками самого свежего C++. До меня эти нововведения доходят спустя годы. Так что если смогу задействовать C++26 в продакшене году эдак в 2029-ом, то и хорошо.

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

Например, синтаксис для рефлексии. Повторял, повторю и буду повторять, что сочетания [: и :] -- это, наверное, худшее из того, что можно было придумать. Настолько плохо это различимо в коде, что просто караул.

Ну или взять контракты. В Eiffel-е -- это одна из самых классных фич языка, можно сказать киллер-фича. Тогда как в C++26 я что-то не вижу возможности использования old в постусловиях. Такое ощущение, что в C++ных контрактах мне не получится написать что-то вроде:

void push_back(T v) post(this->size() == old this->size() + 1)
{...}

Если я ошибаюсь, то буду признателен за подсказку о том, как такой фокус в C++ных контрактах осуществить.

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