среда, 16 апреля 2025 г.

[prog.thoughts] Реплика в блог: так ли плохо иметь в C++ отдельный класс для сетевого пакета?

Поскольку я зарекся вступать в публичные споры на LOR/RSDN/Habr, а в Интернете, как водится, кто-то неправ, то попробую разместить свою ремарку здесь, в уютненьком ;)

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

Там даже кусок кода всплыл, типа образчик на который имеет смысл посмотреть.

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

Представление данных -- это всего лишь конкретный механизм сериализации. Скажем, использование принципа TLV (Tag-Length-Value), как в ASN.1 BER. Или плотная побитовая упаковка как в ASN.1 PER. Или же тегированное текстовое представление, вроде JSON или XML (должны сдохнуть в муках оба, шутка).

Кусок кода, который привели в обсуждении на RSDN, он как раз про представление данных.

Тогда как есть еще одна важная часть, когда мы говорим о каких-то протоколах обмена данными -- это из каких сообщений (PDU -- protocol data unit) состоит сам обмен.

Типа того, что есть сообщение handshake и ответное сообщение handshake_ack. Есть сообщение subscribe и есть ответы sub_ack и sub_nack. Есть сообщение publish и есть ответные pub_ack и pub_nack, а также сопутствующее delivery_report. И т.д., и т.п.

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

Но представление данных не есть удобный способ работать с самими PDU в коде.

Достаточно часто в наше время встречается ситуация, когда PDU представляется в виде JSON. Входящий пакет парсится, у нас в коде появляется что-то вроде nlohman::json или RapidJson::Value. И дальше программисты любятся с этими JSON-объектами как умеют. А умеют практически никак 😣 Например, если в PDU есть поле priority, то из JSON-объекта запрашивают это поле вручную по строковому имени. Если это поле нуждается в какой-то валидации (хоть при извлечении, хоть при сохранении), то это тоже делают вручную. Если делают.

Мне же думается, что работать с PDU в программе гораздо удобнее, когда PDU представляется в виде конкретного C++ного класса с нужными методами getter-/setter-ами. И когда в эти самые методы вставлена валидация значений. Более того, такие классы могут (и должны, когда есть возможность) проверять корректность значений при сериализации/десериализации. Например, если поле A в PDU имеет вот такое значение, то поле B не может быть пустым, а поле C, напротив, должно быть пустым.

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

Однажды в прошлом с чем-то таким столкнулся. Даже рассказывал об этом на RSDN и упоминал в блоге. То решение на Ruby оказалось удобным. Если доведется еще раз с подобной задачей, то буду смотреть в ту же сторону (не важно, Ruby будет использоваться для кодогенерации, Python или еще что-то). Хотя современный C++ в области шаблонной магии далеко ушел от C++03, но все равно не думаю, что подобная задача будет хорошо решаться в рамках C++20 или C++23.


PS. Еще раз по поводу кода, который показали на RSDN. Как раз тот случай, когда смотришь в код, внутренний голос спрашивает "а что так навороченно то, нельзя ли пропроще?", но без вдумчивого изучения ответа на этот вопрос нет. А вдумчиво изучать нет желания ;)


PPS. Мораль всего поста: не беритесь судить без глубокого погружения.

понедельник, 14 апреля 2025 г.

[prog] Похоже, у меня уже не получается писать код без комментариев

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

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

Изредка приходится делать маленькие (или не очень маленькие) программки "на выброс". Буквально на один-два проверочных запуска, после чего все написанное отправляется в корзину. Вот там, как правило, вообще никаких комментариев нет. Точнее не бывало. До недавних пор.

Как раз давеча пришлось такими маленькими программками заниматься.

И вот что удивительно: после того как объем кода превысил 150-200 строк я внезапно поймал себя на том, что больше не могу без комментариев. Руки сами отказываются дописывать новые строки без предварительный поясняющих комментариев.

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

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

Весь этот код, по сути, одноразовый. Заливал его на github только ради простоты переноса между разными компьютерами. Ну и экспериментировать с кодом, когда он под контролем версий, таки спокойнее и удобнее.

PS. Неприятным побочным эффектом от привычки писать комментарии становится все возрастающая нетерпимость к коду без комментариев.

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

PPPS. Проблема с бесполезными и тривиальными комментариями не в том, что они бесполезны. Проблема в том, что программистов не научили комментарии писать. Поэтому эти самые программисты и пишут бесполезные комментарии. Ну не умеют писать полезные и это объясняет текущее состояние дел почти на 95%.

PPPPS. Есть у меня ощущение, что в последние 15 лет программистов-то и программировать уже не учат. Что уж тут говорить про обучение написанию комментариев 🥺 ИМХО, это один из китов, на которых покоится миф о самодокументирующемся коде.

суббота, 12 апреля 2025 г.

[prog.c++] Довелось тут вспомнить свой старый PR в spdlog

В проект, которому сейчас помогаю, коллеги подключили spdlog. В частности, потребовался функционал автоматической ротации log-файлов. Но, к сожалению, не без сложностей т.к. штатный rotating_file_sink не подошел. Генерация имен новых log-файлов в нем захардкожена намертво, а требовалось добавлять в каждое имя специфическую для проекта информацию. Пришлось делать свой тип sink-а.

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

Пришлось коллегам копипастить код rotating_file_sink к себе в проект и дорабатывать его напильником в нужных местах.

Внезапно™ вспомнилось, что когда-то давно я сам засылал PR в spdlog, который даже был принят, но забылось что именно я там предлагал делать. А оказалось, что предлагал как раз решение подобной проблемы. Но только для daily_file_sink.

Суть в том, чтобы шаблон класса daily_file_sink требовал не один параметр шаблона, а два. Вторым параметром является тип, который предоставляет статический метод calc_filename. Тем самым calc_filename выносится из самого класса sink-а в параметр шаблона. И если нам нужны собственные правила генерации имен новых log-файлов, то мы всего лишь делаем простой класс с публичным статическим методом calc_filename, после чего подсовываем этот класс в параметр шаблона daily_file_sink. Что гораздо проще и надежнее, чем брать за основу код существующего sink-класса и переделывать его под себя.

Удивительно то, что хотя я заслал это изменение девять лет назад, этот подход с дополнительным параметром шаблона почему-то не применяется для rotating_file_sink. Хотя используется, например, в hourly_file_sink. Такое ощущение, что соответствующий PR никто не присылал, а автор spdlog не стал переделывать старую реализацию rotating_file_sink.


Думаю, что если бы я готовил подобный PR сейчас, то постарался бы обойти одну небольшую проблемку, которая есть в параметре FileNameCalc. Т.к. метод calc_filename у FileNameCalc должен быть статическим, то мы имеем дело со stateless-генерацией имен файлов. Что OK в большинстве случаев, но не всегда. Иногда может быть нужно, чтобы calc_filename сохранял какую-то информацию для использования в следующем вызове. Но сохранять ее негде. Поэтому сейчас бы я думал в сторону того, чтобы поддерживалась stateful-генерация имен.

В C++20 это вообще бы не представляло проблемы:

template <typename Mutex, typename FileNameCalc = daily_filename_calculator>
class daily_file_sink final : public base_sink<Mutex> {
  [[no_unique_address]]
  FileNameCalc _filеNameCalc;
  ...
public:

Если фактический тип FileNameCalc пуст, то _fileNameCalc не увеличивал бы размер daily_file_sink.

Но в более старых версиях C++ пришлось бы наследоваться от FileNameCalc дабы воспользоваться empty base optimization. Что не так очевидно и красиво.

Плюс еще нужно было бы предусматривать для sink-ов конструкторы, которые могли бы получать начальные значения для _fileNameCalc...

В общем, иногда кастомные stateful-генераторы имен могли бы быть полезными. Но вот во что бы вылилась их поддержка в коде spdlog? И стоило бы оно того? Хорошие вопросы, ответов на которые у меня нет.

четверг, 10 апреля 2025 г.

[soft.tools] FAR Manager и BOM-маркер в начале каждого нового текстового файла

Много-много лет пользуюсь FAR-ом но с таким приколом столкнулся впервые...

В конце 2024-го года обзавелся новым рабочим Windows-ноутбуком, но из-за болезни очень мало им пользовался. Теперь по мере возврата в нормальный режим сижу за ним все больше и больше. Установленным там с нуля FAR для меня основной инструмент по работе с файлами.

И вот внезапно © выяснилось, что при создании нового текстового файла по Shift-F4 в кодировке utf-8 FAR автоматически вставляет в начало файла BOM-маркер из трех байт. Которые, мягко говоря, уже давным давно никому никуда не упали (особенно когда приходится таскать файлы из Windows в Linux и обратно).

После чего облазил все диалоги с настройками в FAR-е, но не увидел способа "фичу" отключить.

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

  • в командной строке FAR-а нужно ввести far:config и нажать Enter;
  • в открывшемся списке параметров конфигурации нужно найти BOM (через CTRL+ALT+F);
  • заменить true на false.

Очень выручил этот рецепт, поэтому решил утащить его к себе в склерозник.

пятница, 4 апреля 2025 г.

[prog.c++] Нормально на C++ программируют лишь параноики?

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

Под кодом на "современном C++" понимается код, в котором активно используются шаблоны, лямбды, исключения, контейнеры, алгоритмы, перегрузка операторов и вот это вот все. Такой код может выглядеть как вполне себе высокоуровневый, почти как современная Java, C# или даже Scala.

Проблема, однако, в том, что C++ таким высокоуровневым языков не является.

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

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

Или, что часто происходит в моей практике, люди забывают (или не знают?) про exception safety. Как результат, если вылет исключения не приводит к немедленной катастрофе, то уж утечку ресурсов или нарушение инвариантов множества объектов вызывает точно. Далеко не все программисты, к сожалению, привыкли к повсеместному RAII. А обеспечение strong exception safety обходится не бесплатно в плане сроков написания кода (особенно если это дело еще и покрывать тестами).

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

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


На самом деле проблема не в "современном C++", а именно в C++ безотносительно его версии.

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

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

Тогда как код на современном C++, с какими-нибудь ranges и coroutines может производить обманчивое впечатление того, что C++ таки вошел в одну когорту с Java, C#, Scala и, может быть, даже Python с JavaScript. Что есть опасное заблуждение.

Да, на C++ можно писать высокоуровневый код, особенно при наличии хороших прикладных библиотек. Только вот возможность нечаянно отстрелить себе ногу никуда не делась. Что принципиально отличает C++, даже в самых его свежих стандартах, от Java/C#/Python/JavaScript.

А чтобы ничего себе не отстреливать приходится постоянно задумываться о том, а что будет если что-то пойдет не так? А если постоянно об этом задумываться, то не превращаешься ли ты в параноика?

PS. Нахожусь при мнении, что при программировании на чистом Си параноить приходится гораздо меньше. Потому, что там нет исключений. И нет неявно вызываемых конструкторов (например, когда из строкового литерала внезапно возникает экземпляр std::string). Поэтому в мире чистого Си при использовании идиомы goto cleanup чувствуешь себя намного спокойнее.

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

среда, 2 апреля 2025 г.

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

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

Фильмы

Контратака (Contraataque, 2025). Мне понравилось.

Компаньон (Companion, 2025). Получил удовольствие от просмотра. Редко в последние годы встречаются фильмы, которые захватывают внимание и при просмотре которых не хочется выискивать и цепляться к недостаткам. Однако, мои вкусы несколько специфичны 😀

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

Криминальный город: Возмездие (Beomjoe dosi 4, 2024). Если вам нравятся корейские фильмы с мордобоем, то смело можно смотреть.

Криминальный шеф (What You Wish For, 2023). Смотришь, смотришь, ждешь, ждешь настоящей кульминации и картсиса, а... А ничего похожего на это и не наступает. В результате складывается впечатление, что фильм не смог реализовать свой потенциал.

Месть (2023). Очень простенько сделанное кино, местами где-то на уровне художественной самодеятельности, но бодренькое. И с неожиданным для меня лично финалом, который с лихвой компенсировал все технические и художественные недостатки.

Свидание с монстром (Woman of the Hour, 2023). Хорошая картинка и достойная актерская игра. Но вот само построение сюжета с прыжками во времени туда обратно вызывает вопросы о том, а не испортило ли это все потенциально интересную историю.

Ограбление по-аризонски (The Last Stop in Yuma County, 2024). В принципе, я являюсь любителем такого рода фильмов. Но в данном случае нет в кино нерва, который бы вел бы зрителя от самых первых кадров до развязки (которая мне вполне понравилось). В итоге набор красивых картинок и более-менее удачных эпизодов, которые не складываются в целостное полотно.

Город демонов (Oni Goroshi, 2025). В принципе, любители жанра "кровавое мочилово" могут посмотреть. Но т.к. главный герой оказался настолько неубиваемым, что для меня лично все происходящее на экране быстро превратилось в цирк.

Клинер (Cleaner, 2025). Ничего не ждал от этого фильма, т.к. перед просмотром прочитал много отрицательных отзывов. На самом деле вполне себе средненькое современное кино про "сильных и независимых женщин" (tm). Лично мне не хватило динамики и экшОна, как-то все затянуто и уныло получилось.

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

Электрический штат (The Electric State, 2025). Просто удивительный пример того, как соединить просто офигенную картинку с абсолютно невнятным сюжетом и бездарной актерской игрой главных героев. Тот случай, когда в бочку меда (визуал) добавляют несколько мисок дерьма (сюжет, актерская игра).

Охотник за головами (The Getback, 2023). Редкая халтура, как по сюжету, так и по актерской игре. Но, особенно, в части т.н. экшОн сцен. Смело можно не смотреть.

Сериалы

Самбра: Анатомия преступления (Sambre, первый сезон, 2023). У этого сериала есть два достоинства -- полное отсутствие гламура, правда жизни как в позднем чернушном соцреализме, + очень хороший грим для героев, которые стареют по мере повествования, выглядит все очень достоверно. Но в целом это никакой не детектив, это что-то вроде социальной драмы в криминальном контексте. Хорошо сделанная, местами цепляющая, но драма, а не детектив.

ДерьмоКино вне категории

Бесстрашный (Tian long ba bu zhi qiao feng chuan, 2022). Какой-то Хон Гиль-дон только на технологиях XXI-го века. Не знаю кто и зачем будет смотреть это в здравом уме.

Мастер (A Working Man, 2025). Кино со Стейтемом превращается в отдельный жанр. Его герои настолько круты и неубиваемы, что даже неинтересно смотреть. И ладно бы там в самом экшОне были прорывы, как в первом Джоне Уике, так ведь нет. По итогу просто жалко потраченного на очередную туфту времени.

вторник, 1 апреля 2025 г.

[life.cinema] Вместо заключительного кинообзора

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

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

И сегодня на этот вопрос я убедительного ответа найти не смог.

В связи с этим завязываю с публикацией списков, 99% которых составляет дешевый шлак. Может быть время от времени буду делать короткие заметки о фильмах, которые действительно понравилось. Но без привязки к конкретному графику.

Грустно, конечно. Длилась вся эта история, емнип, с октября 2012-го. Но что поделать, если кинематограф с ускорением несется по наклонной плоскости куда-то под плинтус и выдает "шедевры" вроде Капитан Америка: Новый мир, Мастер и Бесстрашный. Не хочу участвовать в этой безумной гонке наперегонки со здравым смыслом.

Upd от 2-го апреля: тем, кто воспринял этот текст слишком уж всерьез стоит обратить внимание на дату публикации ;)

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

[prog.c++] Наследие темного прошлого C++, которое сейчас стало напрягать все больше и больше

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


Неявные приведения типов.

В каких-то случаях это удобно. Напишешь ты что-то вроде:

void dump_value(std::string_view value) {...}

а потом спокойно пихаешь туда строковый литерал:

dump_value("Hello, World!");

и все работает.

Хотя, чем старше становлюсь и с чем большим объемом чужого кода приходится иметь дело, тем больше склоняюсь к тому, что писать так:

dump_value("Hello, World!"sv);

или даже так:

std::string calculated_value = some_calculation();
dump_value(std::string_view{calculated_value});

тоже вполне себе OK.

Но вот что откровенно вымораживает, так это то, что язык допускает неявные преобразованиями между int-ами, long-ами, float-ами, double-ами и прочими числовыми типами. Иногда нужно включать высокие уровни предупреждений для того, чтобы компилятор хоть как-то пожаловался на выражения вида:

std::vector<item> items = collect_items();
int delta = items.size() > 3 ? 2 : 0;
std::size_t limit = (items.size() - delta) * 1.75;

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

Очень хочется, чтобы компилятор запретил все подобные неявные преобразования между числовыми типами. Чтобы ошибка выдавалась даже при попытке неявно преобразовать std::uint8_t в std::uint16_t. Не говоря уже про преобразования от std::size_t к short или от double к long.


Использование "безразмерных" типов short, int, long и пр.

Да, я помню, что Страуструп агитировал за int. И он же считал ошибкой, что std::size_t в STL сделали беззнаковым.

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

Поэтому когда я сейчас вижу в программах что-то вроде:

int l = strlen(some_string);

или

int last_element_index = vec.size() - 1;

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

Поэтому я вообще склонен запретить использовать в коде типы, размерность которых никак не зафиксирована (short, unsigned short, int, unsigned int, long, unsigned long и т.п.).

Грубо говоря, int-у место разве что в примерах в старых учебниках. Но в современном предназначенном для продакшена коде, ему не должно быть места. Следует использовать либо типы с зафиксированной размерностью (std::uint8_t, std::uint16_t, std::uint32_t и т.д.), либо типы с обещанной минимальной размерностью (std::uint_fast8_t, uint_least8_t, std::uint_fast16_t, std::uint_least16_t и т.д.).


И еще один момент, которого в C++ нет, но который, имхо, был бы полезен.

ЕМНИП, в Pascal можно было объявить перечисление из, скажем, трех элементов, а затем создать массив, для индексации которого может использоваться именно это перечисление. Что-то вроде:

type
  Dimensions = (Price, Speed, Riskiness);
  Corrections = array of [Dimensions] of Real;
var
  CurrentCorrections : Corrections;
begin
  CurrentCorrections[Price] := 1.0;
  CurrentCorrections[Speed] := 0.5;
  CurrentCorrections[Riskiness] := 1.25;
  ...

При этом вы точно знаете, что ваш объект CurrentCorrections тесно связан с Dimensions. И если со временем ваш Dimensions меняется, то это сказывается и на работе с CurrentCorrections.

Тогда как в C++ такой фичи нет. Мы можем сделать так:

enum class Dimensions { Price, Speed, Riskiness };
using Corrections = std::array<double, 3>; // А вот тут уже первая неприятность.
...
Corrections current_corrections;
current_corrections[Dimensions::Price] = 1.0;
current_corrections[Dimensions::Speed] = 0.5;
current_corrections[Dimensions::Riskiness] = 1.25;

Но надежность этого кода будет исключительно на совести и внимательности программиста.

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

Поэтому со временем кто-то может модифицировать перечисление Dimensions, например, вот так:

enum class Dimensions { Price = -2, Speed = 0, Riskiness = 3, Effectiveness = 10 };

и весь старый код, включая ставшее неправильным определение типа Corrections, все равно скомпилируется. А потом хорошо, если быстро упадет.

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

суббота, 29 марта 2025 г.

[prog.kill-them-all] И снова слова проклятия в адрес любителей длинных строк в исходном коде...

Простите за очередной крик души. Но блин, как же я устаю от чтения кода со слишком большой длиной строки. У меня уже даже складывается устойчивое впечатление, что чем чаще в коде встречаются строки длиной больше 80 символов, тем больше там обнаруживается говнокода.

Пример, переполнивший сегодня чашу терпения на скриншоте. Это полный скрин моего основного Windows-ноутбука. Именно так все выглядит на экране в обычном режиме.

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

Ну и да, привет всем тем чудикам, которые утверждают, что код читают только в IDE. Да хрен вам!

Так что вредный совет тем, кто по какой-то причине обратил внимание на этот пост: если вам начхать на удобство тех, кто будет читать и сопровождать ваш код в дальнейшем, то смело пишите строки длиной по 100, 120, 150 символов. Да и 150 не предел, зачем останавливаться?

PS. Прошу понять и простить за резкость, но за минувшую неделю пришлось слишком много проблемных фрагментов кода копипастить из исходников в email-ы, мессенджеры и GoogleDoc-документы. Где куски с длинной строки в 120+ символов превращались в совсем уж нечитаемое ХЗ что. В отличие от.

PPS. Надо бы взять на вооружение именно этот способ записи выражений noexcept в декларации методов. Выглядит лучше чем то, что пишу я.

пятница, 28 марта 2025 г.

[prog.forums] Попробую продлить вынужденный режим read-only на RSDN/LOR/Habr...

Когда начались проблемы со здоровьем, то вынужденно ушел в режим "только чтение" на таких ресурсах, как RSDN, LOR и Habr. Хотя до этого регулярно позволял себе что-то там комментировать и иногда (или постоянно?) встревал в тот или иной срач холивар.

И знаете что? Мне понравилось быть в режиме молчания.

Куча времени освободилось. Да и нервы как-то целее 😉

Поэтому хочу попробовать сохранять этот же режим и дальше. Возможно, что-то буду писать на RSDN/LOR когда представится возможность выкатить очередной релиз SObjectizer/RESTinio и нужно будет сделать анонс. Аналогично, если представится возможность написать какую-то статью для Хабра (скорее всего связанную с очередными релизами наших OpenSource продуктов), то сделаю это. Таки это площадки для PR-а, негоже от них отказываться полностью.

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


Касательно RSDN/LOR мне кажется, что оба эти ресурса стали жертвами закона "разбитых окон": и там, и там есть деструктивные персонажи, которых следовало давным давно забанить, но этого не сделали, поэтому и там, и там уровень дискуссий заметно снизился.

Плюс к тому, как мне неоднократно говорили коллеги, информационная среда изменилась, время профильных форумов прошло. Сейчас проффи где-то в других местах тусуются, вроде телеграмм-каналов. А RSDN/LOR остаются пережитками прошлого. Какие-то старые персонажи, которые живут на RSDN/LOR десятилетиями, остаются там по привычке. Но их мало. Изрядная часть из них пишет одно и то же или делает одни и те же однотипные вбросы. Поэтому все чаще и чаще возникает ощущение дежа-вю, мол, где-то я все это видел раньше, причем неоднократно.

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


Что касается моего участия в прошлых разборках на RSDN/LOR, если я кого-то своей резкостью обидел, то прошу прощения.

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

четверг, 27 марта 2025 г.

[prog.c++.vcpkg] Внезапные приключения с подключением OpenSSL к проекту посредством vcpkg

Есть проект, который собирается под Windows и под Linux. Для управления зависимостями используется vcpkg (вместе с манифестами, т.е. с файлами vcpkg-configuration.json и vcpkg.json, хотя манифесты тут вряд ли виноваты).

В зависимостях есть OpenSSL. Подключение OpenSSL в CMakeLists.txt проекта выглядит стандартным образом:

find_package(OpenSSL CONFIG REQUIRED)
...
target_link_libraries(some_executable_file OpenSSL::SSL OpenSSL::Crypto)

Так вот под Windows все это работает как часы, тогда как под Linux-ом случился нежданчик: внезапно™ выяснилось, что нет таких CMake-овских таргетов, как OpenSSL::SSL и OpenSSL::Crypto.

Вот нет и все, хотя find_package успешно отрабатывает.

Блуждания по потрохам кучи CMake-овских файлов, установленных vcpkg, привело вот к такому фрагменту в файле OpenSSLConfig.cmake, который лежит в vcpkg_installed/x64-linux/share/openssl (извиняюсь за его объем, но здесь все самое важное):

суббота, 22 марта 2025 г.

[soft.tools] В склерозник: изменение размера диска в .vhd образе в VirtualBox

Зафиксирую в склерозник простое решение проблемы, которая меня донимала в последнее время.

Суть в том, что компьютера от Apple с macOS у меня нет, но выяснилось, что если что-то не компилируется clang-ом на macOS, то с большой вероятностью оно не скомпилируется и clang-ом на FreeBSD. Поэтому на Windows-ноутбуке держу VirtualBox, в котором поднимаю свежий образ FreeBSD. Эти самые свежие образы беру прямо на официальном сайте FreeBSD (например, здесь они лежат для 14.2).

Но эти штатные образы FreeBSD очень маленькие -- размер диска в .vhd образе что-то в районе 4Gb, из которых свободных всего пара сотен мегабайт. Поэтому даже поставить через pkg тот же git не всегда получается: делаешь pkg install git и свободное пространство уходит в ноль.

Однако, внезапно (с) выяснилось, что это дело легко починить. Что в VirtualBox по Ctrl+D вызывается окно управления дисковыми образами, в котором можно увеличить размер диска до нужных размеров.

Ларчик, оказывается, просто открывался.

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


Вот что я пока так и не смог сделать, так это заставить FreeBSD использовать терминал отличный от 80x25. Если кто-то знает, то подскажите в комментариях, плз. В выхлопе dmesg несколько строк, которые относятся к видео:

При попытке изменить шрифт в консоли через vidfont выдается ошибка:

vidcontrol: PIO_VFONT: Operation not supported

Upd. Вот что мне немного помогло:

  • в настройках виртуальной машины в разделе System включена галочку для "Enable EFI (special OSes only)". После этого внутри FreeBSD заработал vidfont;
  • в /etc/rc.conf добавлена строка allscreens_flags="-f vgarom-8x16";
  • вот эта ссылка с полезной информацией и примерами: How to change vt console font size?

Правда, после включения галочки "Enable EFI" запущенная FreeBSD перестала нормально завершаться после выдачи ей через меню VirtualBox-а команды "Send the shutdown signal"... :(

пятница, 21 марта 2025 г.

[business] Пара интересных роликов с YouTube о провале первого бизнеса

За последнее время посмотрел на YouTube с десяток разных роликов о том, как люди с разной степенью неуспешности пытались начать свой собственный бизнес. ИМХО, изучение опыта успешных компаний -- это повторение "ошибки выжившего". Тогда как попытки разобраться в том, что пошло не так в случае прогоревшего бизнеса дают гораздо больше полезной информации.

Наиболее интересными оказались вот эти два ролика (прошу прощения, что даю ссылки на YouTube, с которым в РФ проблемы, но у нас в РБ с YouTube пока OK):

При просмотре первого видео я не мог отделаться от вопроса: "Как человек, который никогда не имел дела с миром фитнеса, решился открыть бизнес именно в этой области?"

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

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

вторник, 18 марта 2025 г.

[life] Пара-тройка вредных советов о том, как создать дискомфорт вашим соседям по больничной палате

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

Заранее приношу свои извинения за использование обсценной лексики, но здесь как в анекдоте про прачечную, никак не обойтись... :(

четверг, 6 марта 2025 г.

[life] Вещи, которые оказались полезными для меня в больнице

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

В моем случае потребовалось еще несколько вещей, которые оказались неочевидными, скажем так. Но которые сильно повысили комфортность пребывания в больничной палате.

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

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

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


Одна штука оказалась неудобной, хотя я на нее сильно рассчитывал: это планшет с большим экраном, но без SIM-карты. Интернет я раздавал на него по WiFi с телефона, но как раз качества такой раздачи для комфортного просмотра видео и не хватало :(

Получалось, что читать тексты вполне себе OK, а вот смотреть ролики или фильмы -- уже нет. В итоге использовал для всего телефон. Благо он у меня довольно большой, с экраном 6.8", так что ни с чтением, ни с просмотром, ни с прослушиванием музыки проблем не было.

А вот был бы планшет с собственной SIM-кой чтобы напрямую пользоваться мобильным Интернетом... Возможно, впечатления были бы другими.

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

Я до операции как раз для разбора почты ноутбук и использовал. Гораздо удобнее и телефона, и планшета. Но вот после операции почему-то не хотелось брать его в руки. Даже не знаю почему, хотя некоторые предположения есть -- как-то восстановление после хирургического вмешательства невольно заставляет смотреть на мир несколько иначе, и то, что раньше казалось важным и неотложным, затем таким уже может и не казаться :)

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

среда, 5 марта 2025 г.

[life-n-health] У меня был план: просто прожить год...

Возможно, старые читатели блога обратили внимание, что за прошедшие пару месяцев здесь было опубликовано совсем мало постов. Так же с моей стороны не было активности на RSDN, LOR, Habr, LinkedIn и т.д. Тому была серьезная причина и сейчас уже можно сказать несколько слов о том, что же случилось.

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

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

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

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

В общем, если хочешь рассмешить Господа Бога, то расскажи ему о своих планах. Я вот в предновогоднем посте написал, что планирую просто прожить 2025-й год. И как раз с "просто" и "прожить" что-то пошло не так ;)

Своим же читателям хочу пожелать крепкого здоровья. Как же хорошо, когда оно есть. А когда с ним возникнут проблемы, то любовь и забота ваших близких помогут вам с этим справиться. Но чтобы не остаться без этой самой любви и заботы, сместите, пожалуйста, свой work-life баланс в сторону life, а не work. Мне для осознания этой банальности потребовалось много времени, не будьте таким бараном, как я.


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

суббота, 1 марта 2025 г.

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

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

Фильмы

Ночной вор (La nuit se traîne, 2024). Мне понравилось, посмотрел с удовольствием.

Ущелье (The Gorge, 2025). Неплохо. Очень даже неплохо. Но лично мне финал не понравился, нужно было бы делать что-то гораздо более мрачное и трагичное.

Рейс навылет (Fight or Flight, 2024). Очень бодренько, даже не ожидал, отличная черная комедия с обилием мордобоя и даже, местами, "кишки, кровь, распидорасило". Мне зашло, но тем, кто не любит насилия на экране, лучше воздержаться от просмотра.

Киллер в отставке (Old Guy, 2024). Мне показалось, что смотреть это кино имеет смысл фанатам Кристофа Вальца -- он великолепен. В остальном ничем не примечательное проходное кинцо.

Элиас (Elyas, 2024). Еще одна попытка создать своего "боевого пенсионера", на этот раз от французов. Полагаю, хотели сделать что-то среднее между "Заложницей" и "Джоном Уиком", но получилось так себе. ЭкшОна мне лично не хватило, а имеющийся не поражает воображение. Но больше всего офигеваешь от сюжета, когда выясняется, что все эти горы трупов образовались из-за нежелания 13-летней соплячки подчинятся воле своего отца.

Особо опасный пассажир (Flight Risk, 2025). Могло бы получиться неплохо, если бы Марка Уолберга не заставили изображать из себя сумасшедшего клоуна.

Сериалы

Полиция Токио (Tokyo Vice, первый и второй сезоны, 2022-2024). Купился на высокий рейтинг сериала на Кинопоиске. По факту же очень нудно и сильно затянуто, особенно первый сезон, который нужно тупо перетерпеть.

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

Пингвин (The Penguin, первый сезон, 2024). Сделано качественно, но есть пару моментов, которые не позволяют мне оценить этот сериал по достоинству. Во-первых, хоть там супергеройской темы и нет, но комиксовая природа сквозит из всех щелей, а комиксы меня не торкают. Во-вторых, в кино нет ни одного положительного персонажа, которому бы хотелось сопереживать. Ощущение от просмотра "Господь, жги их всех, никого не жаль", поэтому происходящее на экране оставляет не то, чтобы равнодушным, а вызывает вопрос "когда же вы, уроды, друг друга перебьете?"

Говно года

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

четверг, 13 февраля 2025 г.

[prog.c++] Где брать информацию о современном C++?

Зафиксирую в склерознике несколько ссылок, которыми я сам регулярно пользуюсь и которые висят у меня в разного рода закладках. Чтобы самому проще было найти все это при необходимости.

All C++20 core language features with examples. Шпаргалка с примерами кода, иллюстрирующими нововведения в C++20 (только сам язык, без стандартной библиотеки).

Modern C++ Programming. Набор презентаций с рассказами о самых разных аспектах языках C++. Покрывает большой объем стандартов C++: от C++03 до C++26 на данный момент. Фундаментальная штука, такое ощущение, что если ознакомиться с материалом, то можно найти шпаргалки практически по всем аспектам языка.

Конечно же, cppreference. Но тут нужно знать что именно искать ;)

Working Draft Programming Languages — C++ Текущий драфт последнего C++ного стандарта. Там же можно найти и драфты конкретных стандартов, если вы знаете их идентификатор. Например, вот драфт C++20: N4861, а вот драфт C++23: N4950 (полагаю, все это описано здесь).

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

пятница, 7 февраля 2025 г.

[life] Ролики с YouTube про восхожения на Эверест и коммерческий альпинизм

В 2023-ем году узнал, что Валдис Пельш со своей командой заснял документальный фильм "Ген высоты 2", про восхождение на K2. А до этого от тех же авторов был первый "Ген высоты", про восхождение на Эверест. Естественно, про первый "Ген высоты" до того момента ничего не знал, поэтому засмотрел. А после него и еще несколько роликов на ту же самую тему.

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

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

Но это моя личная точка зрения, никому ее не навязываю. А если кому-то еще окажется интересна эта тема (вплоть до возникновения и реализации мечты "покорить" Эверест), то вот набор роликов с YouTube, которые лично мне показались наиболее интересными.

Ген высоты

Сергей Ковалёв. Как взойти на Эверест

Владимир Котляр. Взойти на Эверест. Фильм о восхождении на крышу мира

Еще у Владимира Котляра появился плейлист "Экспедиция на Эверест 2024", сам я его пока не смотрел, но ссылку на всякий случай оставлю: тыц

Алла Мишина. Старт в альпинизме после 50: личный опыт от Килиманджаро до Эвереста

Анна Шурышева. Восхождение на Эверест от и до. Акклиматизация, подготовка, рекомендации

Ну и, конечно же, "Ген высоты 2", хоть он и не про Эверест

суббота, 1 февраля 2025 г.

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

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

Фильмы

Граф Монте-Кристо (Le Comte de Monte-Cristo, 2024). Монументально и красочно. С визуальной точки зрения безупречно. Размах и масштаб почти такой, какой и ждешь от экранизации. Но мне лично показалось, что если бы в сюжете фильма было меньше отклонений от первоисточника, то часть происходящего на экране выглядела бы намного драматичнее.

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

Один день в Стамбуле (2024). Типичное кино от "Квартета И". Но, далеко не такой шедевр, как "О чем говорят мужчины". Так что смотреть можно, а вот ждать "Вау-эффекта" не стоит.

Охота на воров 2: Пантера (Den of Thieves 2: Pantera, 2025). В отличии от первой части вторая оказалась на редкость занудной и затянутой.

Похищение искусства (Art Thief, 2023). Очень простенько и бюджетненько. Но не без некоторой интриги. Можно глянуть если больше вообще ничего нет.

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

Сериалы

Мир дикого запада (Westworld, первый сезон, 2016). Осилил первый сезон, смотреть последующие не захотелось. От первого сезона впечатления неоднозначные: с одной стороны прикольная идея и сюжет захватывает, с другой же типичная сериальная затянутость плюс прыжки по времени повествования то туда, то сюда, из-за которых далеко не сразу понимаешь к какой сюжетной линии относится конкретный фрагмент плюс временами хочется воскликнуть "не верю".

Прометей (первый сезон, 2024). Очень и очень посредственно. Сюжет бредовый, нет ни одного убедительного персонажа. Работа оператора ближе к концу фильма начала откровенно раздражать, настолько я не понимал принципов компоновки кадров. Ну и плюс заметная сериальная неспешность, чтобы растянуть происходящее на экране хотя бы на 8 серий.

Черные голуби (Black Doves, первый сезон, 2024). Вот честно, лучше бы я это не смотрел. Во-первых, там гомосексуальная повестка в полный рост. Во-вторых, после развязки остается ощущение, что нам попытались втереть какую-то лютую дичь.

понедельник, 13 января 2025 г.

[prog.c++] Интересная постановка вопроса: если люди испытывают сложности с многопоточностью, то не забанить ли многопоточность совсем?

Этот вопрос всплыл на днях на r/cpp. Позволю себе процитировать значимую часть поста с reddit-а без перевода:

Hi all,

Had an interesting discussion today and would appreciate some advice.

Multithreaded code can be especially tricky for medium to junior level developers to write correctly. When a mistake is made, it can result in difficult to find bugs.

If the application you are working on needs to be very reliable (but isn't safety critical), what would you recommend for medium/low experience c++ teams?

Assume that the application will need to do 4 things at once and can't use state machines or coroutines. The various "threads" need to regularly exchange less than 10 KB of data a second.

Do you ban threads?

A few approaches come to mind.

#1 train the team to know the dangers and let them use threads with best practices. More experienced (and paranoid/diligent) developers carefully audit.

Any suggestions for books/resources for this team?

#2 and/or use a tool or technique to detect concurrency issues at compile time or during test? Thread sanitizer? cppcheck? ???

#3 ban threads and force concurrency to be implemented with multiple processes. 4 processes each with 1 thread. The processes will communicate with some form of IPC.

Т.е. смысл в том, что для разработчиков уровня middle/junior написание мультипоточного кода зачастую оказывается слишком сложным. И если приложение должно быть надежным, то возникает вопрос: как же быть? Может быть проще вообще запретить многопоточность в пользу многопроцессности? А если не запрещать, то что? Учить людей? Использовать какие-то инструменты для тестирования и анализа корректности кода?

Признаться, комментарии на reddit-е к этому посту я не читал, только просмотрел мельком и не увидел того, чего хотел 🙁

Поэтому выражу эмоции в этом блог-посте.

Хватить себя обманывать -- писать низкоуровневый многопоточный код сложно не только middle/junior-ам, но и senior-ам. Не устану повторять, что многопоточность на голых нитях, mutex-ах, condition_variable и, ниприведихоспади, atomic-ах -- это пот, боль и кровь.

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

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

Тем не менее, в моей практике как-то так оказывается, что выбор "можем обойтись без многопоточности" и "не можем обойтись без многопоточности", как правило, бывает очевидным. В основном этот выбор определяется тем, нужно ли нам в одно и то же время делать N вещей одновременно или не нужно.

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

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

Ну а раз не обойтись, что вопрос уже не в том, запрещать многопоточность или нет. Вопрос в том, как уменьшить количество головной боли при использовании многопоточности. И ответ на него достаточно простой: использовать инструменты уровнем повыше, чем голые нити и примитивы синхронизации. Акторы, сопрограммы, CSP-шные каналы, task-и и вот это вот все. Плюс идеология shared nothing во главе угла (в том смысле, что чем меньше у вас разделяемых мутабельных данных, тем меньше у вас проблем).

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

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


Выбор между многопоточностью и многопроцессностью в современных условиях, имхо, должен лежать не плоскости простоты написания многопоточного или однопоточного кода. А, прежде всего, в плоскости дополнительных факторов. Например, таких как:

  • обеспечение надежности работы в условиях ненадежности используемых программных компонент. Например, мы вынуждены полагаться на стороннюю библиотеку, которая время от времени падает и роняет весь процесс, в котором ее используют. Библиотека не наша, мы не можем "довести ее до ума", можем только минимизировать причиняемый ею ущерб;
  • обеспечение надежности работы в условиях ненадежности внешнего оборудования и/или внешних сервисов. Например, к компьютеру подключено устройство, которое может зависнуть. И единственный способ вернуть его к жизни -- это убить процесс, который общался с устройством, переинициалировать устройство и начать работать с ним заново. Аналогично и со сторонними сервисами, с которыми мы можем общаться через HTTP(S) или еще какую-то форму IPC. Бывает, что такой сервис набирает от нас N запросов и перестает подавать признаки жизни до тех пор, пока все эти N запросов не будут принудительно прекращены;
  • возможность жесткого прерывания длительных операций. Например, какой-то математический расчет, который может занимать часы и который не так-то просто прервать "изнутри". Но вот если вынести этот расчет в отдельный процесс, то этот процесс легко "прибить" в случае необходимости;
  • простота и удобство реконфигурации "на лету". Иногда работающий в режиме 24/7 сервис нужно переконфигурировать без его останова, но из-за внутренней кухни и/или особенностей использованных в нем библиотек, сделать такую переконфигурацию затруднительно.

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

  • в Unix-ах нужно избегать возникновения зомби-процессов;
  • после принудительно убитого дочернего процесса могут оставаться различные следы жизнедеятельности (в виде .tmp-файлов, которые не были вовремя удалены), которые нужно подчищать;
  • если взаимодействие идет через shared-memory, то нужно как-то определить а доверяем ли мы текущему содержимому блока разделяемой памяти или же внезапно умерший дочерний процесс оставил там какой-то мусор...

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

Но аргументы "за" такой переход точно не должны быть из категории "однопоточное программирование проще многопоточного".


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

суббота, 4 января 2025 г.

[life.books] Кратко о книге "Ковчег 47 Либра"

Когда-то давно, году в 2005-ом или 2006-ом прочитал отличный научно-фантастический роман "Стая" Франка Шетцинга. Сильно тогда впечатлился. Ощущения были как будто в детстве читаешь произведения Жюля Верна, где фантастические события базируются на научной основе.

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

Однако, несколько месяцев назад почему-то захотелось перечитать "Стаю". Ни с того, ни с сего.

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

Внезапно возникло желание прочесть еще что-нибудь из фантастики. Но что именно?

Проштудировал списки "лучшие фантастические произведения за 20xx год", выписал себе несколько названий, посмотрел аннотации, выбрал три или четыре штуки. Парочку даже осилил, но на начале третьей тупо сломался. Если первые две оказались обычным ширпотребом, коего в свое время на вокзалах в мягких обложках продавалось пучок на пятак, то третья произвела впечатление жуткого графоманского бреда. Забыл эту попытку как страшный сон, сейчас даже названий этих произведений не вспомню.

А тут как-то случайно через ролики на YouTube узнал о существовании Бориса Евгеньевича Штерна. И о том, что он пишет научную фантастику. Решил попробовать что-то из его произведений прочитать. Наугад попал в "Ковчег 47 Либра". И не смог остановиться.

Вот прям такое же ощущение, как в детстве, когда читаешь жюльверновские "20 тысяч лье под водой" или "Таинственный остров".

Мне отлично зашло. Настолько, что захотелось оставить зарубку в склерознике.

четверг, 2 января 2025 г.

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

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

Фильмы

Веном: Последний танец (Venom: The Last Dance, 2024). Третья часть мне понравилась больше, чем вторая. Хотя есть ощущение, что фильм полностью держится на юморе + еще немного на хорошей графике. Тем не менее, как аттракцион, который позволяет отвлечься от повседневных забот, фильм отличный.

Блуждающая тень (The Shadow Strays, 2024). Отличное кино для любителей жанра "кровавое мочилово". Хотя, имхо, до уровня первого "Рейда" чутка не дотянули, но очень старались.

День Шакала (The Day of the Jackal, 1973). Посмотрел его после одноименного сериала 2024-го года. Общего не так уж много, так что можно смотреть практически как самостоятельное произведение. Полагаю, что для своего времени было отличное кино, но сейчас это совсем уж ретро.

Задержанная (Detained, 2024). Средней паршивости кино. Производит впечатление телеспектакля, а не художественного фильма. Можно глянуть, если больше вообще уже нечего смотреть.

Безмолвное братство (The Order, 2024). Наглядный пример того, как потенциально интересную историю превратить в унылое говно.

Ручная кладь (Carry-On, 2024). Откровенная халтура. Причем и как по сюжету, так и по исполнению.

Сериалы

День шакала (The Day of the Jackal, первый сезон, 2024). К происходившему на экране есть несколько серьезных вопросов, но в целом понравился. Возможно, это лучший сериал из увиденных в 2024-ом году.

Чужак (The Outsider, 2020). О просмотре не жалею, но и не впечатлил. Сделано добротно. Но, имхо, можно было бы на пару серий и подсократить.

Горький 53 (первый сезон, 2024). Есть ощущение, что съемки этого сериала организовали чтобы пристроить большое количество известных еще 10-15 лет назад хороших актеров. Видеть их приятно, они стараются и мастерства у каждого на десятерых, но общее впечатление от сериала средненькое. Слишком много вопросов к сюжету, а развязка оставляет вопрос "И это все?" Может быть создатели планируют продолжение?

Боевой ангел (Machine, первый сезон, 2024). Все очень простенько, наивно, прямолинейно и предсказуемо. Но в этом есть свое очарование. Так что лично мне вполне зашел как раз потому, что можно не вдумываться в происходящее. Еще бы экшОна с мордобоем бы побольше, зашел бы еще лучше :)

Вне категории

Присяжный номер два (Juror #2, 2024). У меня просто нет цензурный слов: что бы так слить собственный фильм в унитаз Клинту Иствуду нужно было сильно постараться. Вот зачем нужно было историю главного героя раскрывать в самом начале? Это же убило всю интригу. Мне совершенно непонятно. Расскажи судьбу Джастина Кемпа в финале картины и получилось бы совсем другое кино, гораздо более интересное и с неожиданным поворотом в развязке.