воскресенье, 31 декабря 2023 г.

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

Подошло время финального обзора в 2023-ем году. Традиционно, в начале каждого из списков идет то, что понравилось больше. Хотя, в данном случае, практически ничего и не понравилось, все перечисленное просто разной степени паршивости :(

Фильмы

Призраки в Венеции (A Haunting in Venice, 2023). Атмосферно. Но, пожалуй, это единственное достоинство данного фильма.

Чарли-Пуля (Fast Charlie, 2023). Очень скромно и бюджетно. Но если больше смотреть нечего, то сойдет.

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

Большая игра (The Independent, 2022). Посредственное кино на специфическую американскую тему и, как мне показалось, исключительно на внутреннюю аудиторию. Да еще и с BLM-повесточкой из-за которой положительные персонажи -- черные, а все отрицательные -- белые. Удивлен почему главную героиню не сделали одноногой лесбиянкой, ну чтобы уж совсем в трендах быть.

Девичник: Убойная ночь (Fear the Night, 2023). Убогая попытка снять кино про то, как сильная и отважная женщина дает отпор грубым и тупым мужланам. Посмотреть можно разве что если больше смотреть ну вот совсем нечего. Вот совсем-совсем нечего :)

Сериалы

Корпорация (Incorporated, первый сезон, 2016). Средненько, но смотрибельно, потраченного времени не жалко. Больше всего портит впечатление то, что законченной истории создатели не рассказали, а оставили много заделов на следующий сезон... Которого у сериала не оказалось :(

Темное дитя: Отголоски (Orphan Black: Echoes, первый сезон, 2023). В принципе, интересная история и интересные вопросы подняты. Но! Во-первых, как обычно для сериалов, слишком затянуто. Как по мне, так можно было раза в два хронометраж сократить. Во-вторых, в конце первого сезона они не стали даже жирную запятую ставить в своей истории. Тупо оборвали происходящее и типа "ждите следующего сезона". За что от меня жирный минус.

Сериал без рейтинга

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

Не удалось досмотреть

Триггер. Фильм. Первые минут 30-40 оставили впечатление, что это какая-то редкостная дрянь. Дальше осилить не смог.

Что из новинок 2023-го года я мог бы вспомнить с удовольствием?

Просто в качестве некого краткого подведения киноитогов 2023-го. Пожалуй, выделю два фильма и один сериал. И все три российского производства.

Во-первых, это очередная часть "О чем говорят мужчины". Ну вот заходит в меня то, что "Квартет И" рассказывает в этой своей серии, что уж тут поделать :)

Во-вторых, это "Вызов". Был сильно и приятно удивлен уровню, на котором все было сделано. Впечатляет.

В-третьих, это "Без правил". Просто потому, что все настолько динамично, что вообще нет ощущения, что смотришь сериал.

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

И да, у меня, как у программиста, типичные проблемы с плюс-минус единичкой ;)

вторник, 26 декабря 2023 г.

[prog.c++] Сочетание ключиков -source-charset:windows-1251 и -execution-charset:utf-8 в Visual C++

Не смотря на то, что в мире Linux-ов уже давным давно все на UTF-8, под Windows еще встречаются исходники с комментариями и не-юникодными строковыми/символьными литералами в CP1251. При этом Microsoft добавила в свой компилятор ключик -execution-charset, который указывает, в каком представлении строковые константы будут представлены в результирующем exe/dll файле. Соответственно, значение utf-8 для -execution-charset указывает, что в run-time ваши narrow string-и будут на самом деле в Unicode, в UTF-8 представлении. Как в Linux-е.

Но, если у вас narrow string литералы в исходнике в CP1251, то компилятору нужно указать это, чтобы он правильно сделал их конверсию в UTF-8. Для чего предназначен ключик -source-charset и значение windows-1251 для него.

Однако, указав VC++ компилятору и -source-charset:windows-1251, и -execution-charset:utf-8, можно сделать для себя удивительные открытия.

Вот, например, простая программа:

#include <iostream>
#include <typeinfo>

int main()
{
   const char str[]{ "Привет!" };
   std::cout << sizeof(str) << std::endl;
}

Когда мы ее компилируем только с -source-charset:windows-1251, то результат 8. Что вполне ожидаемо, т.к. в слове "Привет" шесть букв, плюс восклицательный знак, плюс финальный ноль-символ.

Но если мы добавим ключик -execution-charset:utf-8, то результатом будет уже 14.

Почему? Потому что каждый русский символ будет представлен уже двумя байтами в UTF-8, плюс восклицательный знак, плюс ноль-символ.

Но еще интереснее, если мы попытаемся задать массив char-ов посимвольно. Что-то вроде:

const char s[]{ 'П', 'р', 'и', 'в', 'е', 'т'};

Тут мы получим предупреждение компилятора об усечении значения при приведении его к типу char.

Но откуда это самое усечение возьмется?

А давайте посмотрим на это с помощью другой простенькой программы:

#include <iostream>
#include <typeinfo>

template<typename T>
char to_char(T v) noexcept
{
   using TU = std::make_unsigned_t<T>;

   std::cout << "type is: " << typeid(T).name() << ", value: 0x"
         << std::hex << static_cast<unsigned>(static_cast<TU>(v)) << std::dec << std::endl;
   return static_cast<char>(v);
}

void dump_hex(const std::string & w)
{
   std::cout << std::hex;
   for(const auto ch : w)
      std::cout << "0x" << static_cast<unsigned>(static_cast<unsigned char>(ch)) << ", ";
   std::cout << std::dec << std::endl;
}

int main()
{
   to_char( 'П' );
   dump_hex( "П" );
}

Если мы скомпилируем ее только с ключиком -source-charset:windows-1251, то получим:

type is: char, value: 0xcf
0xcf,

Т.е. вполне ожидаемо символьный литерал у нас имеет тип char.

А если добавим -execution-charset:utf-8, то:

type is: int, value: 0xd09f
0xd0, 0x9f,

Оказывается, что у символьного литерала уже тип int.

Что, в принципе, понятно. Но оказалось неожиданно :)


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

суббота, 23 декабря 2023 г.

[life.audiophilia.diy] Итоги уходящего года в сфере самодельных наушников и мои текущие предпочтения

Сразу приношу свои извинения за то, что приведенный ниже персональный ТОП динамиков для DIY-вкладышей публикую уже после того, как на Aliexpress закончились все ноябрьские и декабрьские скидки :(

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

Итак, уходящий 2023-й год для моего увлечения самодельными наушниками (даже более точно: самодельными наушниками-вкладышами) прошел, в целом, неудачно. Было приобретено несколько комплектов дорогих (для меня) динамиков, но мало что понравилось. Да еще и два самых дорогих комплекта были мной сломаны в процессе подбора корпусов. Такое бывает: приобретаешь динамики за $40, а потом раз! и они ломаются при установке в корпус или при извлечении из корпуса, в котором их звучание не понравилось. Это DIY, тут никто тебе никаких гарантий не дает, все от самого себя зависит.

Да еще и с лета 2023 на Aliexpress с покупателей из РБ стали взимать 20%НДС, так что это мое увлечение внезапно стало заметно дороже :(

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

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

пятница, 22 декабря 2023 г.

[blog] Happy birthday my blog - 15!

Как-то тихо подкрался очередной ДР блога. Ровно 15 лет назад здесь была опубликована первая заметка.

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

Оглядываясь назад могу сказать, что когда блог только начинался, даже и мысли не было, что он просуществует так долго. А теперь уже начинает казаться, что и рубеж в 20 лет вполне можно будет взять. Если, конечно, и я, и blogger.com, проживем еще пять лет :)

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

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

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

четверг, 21 декабря 2023 г.

[prog.bugs] Иногда цена ошибки может быть известна достаточно точно

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

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

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

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

ЗЫ. Все совпадения с реальными людьми и событиями случайны и непреднамеренны :)


Мораль сей басни: если вызывается какая-то функция, которая возвращает код ошибки, то код ошибки обязательно должен быть проверен. Обязательно. Должен. Быть. Проверен.

Далее, в случае возникновения ошибки, по ситуации:

  • если ошибка ожидаемая, то выполняется логика ее обработки. Например, попробовали открыть файл, не получилось, что-то сделали по этому поводу. Скажем, выдали сообщение пользователю и попросили ввести новое имя файла;
  • если ошибка не сильно ожидаемая и не предполагающая путей исправления здесь и сейчас, то либо возвращаем свой код ошибки наверх (если исключения под запретом), либо выбрасываем исключения. Например, вызвали malloc, а он взял и вернул NULL. Маловероятно, но потенциально может произойти. Проверили результат malloc-а и вернули код ошибки наверх;
  • если ошибка вообще из разряда невероятных, то либо действуем как в предыдущем пункте, либо же вообще тупо зовем abort. Например, вызываем getwd, а получаем NULL, хотя казалось бы как такое возможно?

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

  • во-первых, сразу же узнаете о проблеме и
  • во-вторых, не сможете тихо "замести ее под коврик".

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


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

четверг, 14 декабря 2023 г.

[prog.c++] Несколько не очень приятных открытий...

...ну или я просто пока не понял, как это можно "правильно приготовить" :(


Впервые довелось столкнуться с Google Test (далее gTest). Ранее пользовался либо чем-то самодельным, либо Catch2, либо Doctest. А вот теперь и до Google Test очередь дошла.

В принципе, мощная штука, но одна вещь оттуда сейчас чуть ли не show-stopper-ом выступила.

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

Но засада оказалась в том, что если в SetUpTestSuite возникает исключение (например, по какой-то причине я не смог загрузить нужные мне данные), то gTest все равно пытается выполнить входящие в test-suite test-cases. Хотя без нужных данных все эти test-cases завершаются негативно. А вот гарантировать отсутствие исключений я не могу -- иногда данные могут и не загружаться.

И я пока не понял, как поступать в этих случаях. Неужели просто дергать std::abort внутри SetUpTestSuite?


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

Вот что стало по-настоящему неприятным сюрпризом, так это то, что когда инициируешь запуск тестов из Test Explorer, то студия напрочь выбрасывает все, что печатается в stderr/stdout. Грубо говоря, есть у тебя в тесте какая-то тестовая печать в std::cout... И все, забудь! Что там было напечатано из Test Explorer не видно :(

Очень надеюсь, что это я неграмотный идиот и просто не знаю куда смотреть. Может там есть какая-то волшебная кнопка, чтобы показать stderr/stdout от тестов?


В C++20 добавили char8_t. Удобная штука, чтобы конструировать, например, std::filename::path не беспокоясь о том, как это будет воспринято. Например, под Windows такая запись:

std::filename::path my_path{u8"./Файл-С-Именем-На-Русском-Языке.你好.txt"};

теперь обрабатывается уже полностью корректно. А вот в рамках C++17, насколько я помню, будет облом в run-time.

Еще в C++20 добавили u8string_view. Это как string_view, но для char8_t.

Но, оказалось, что u8string_view в рамках C++20 нельзя передать в std::format. Цынк.

Ну и да, еще и диагностика как всегда в C++ ;)

Кстати говоря, как я понял, нельзя заставить std::format делать std::u8string. Можно либо std::string, либо std::wstring.


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

среда, 13 декабря 2023 г.

[prog.json.question] Нужна ли такая фича в библиотеке (де)сериализации JSON?

Есть у нас маленькая обертка над RapidJSON под названием json_dto. Ничего выдающегося, просто попытка применить идею из Boost.Serialization для того, чтобы с RapidJSON-ом работать было удобно.

Давеча в json_dto прилетел pull request, добавляющий специфическую функциональность.

Грубо говоря, нужно (де)сериализовать элементы tuple, которые в JSON представляются массивом с элементами разных типов. Что-то вроде:

{"x": [1, "abc"]}

Где для ключа "x" значением будет tuple<int, string> содержащий (1, "abd").

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

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

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

[prog.work.flame] Много слов на тему ролика АйТиБорода "ИИ убивает программирование, и вот как"

На прошлой неделе урывками посмотрел откровенно кликбейтный ролик "ИИ убивает программирование, и вот как" от известного в узких кругах АйТиБорода.

Урывками потому, что по мере просмотра подгорало знатно, тот самый случай, когда огнеупорная сидушка была бы кстати :)

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

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

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

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

пятница, 1 декабря 2023 г.

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

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

Фильмы

Zillion. Клуб твоих грез (Zillion, 2022). Мне зашло. И снято хорошо, и история рассказана отлично, следить за происходящим интересно. Но, как по мне, на главную женскую роль нужно было брать актрису помоложе.

Продавцы боли (Pain Hustlers, 2023). Неплохо.

Создатель (The Creator, 2023). Сказочка для детей. Но снято настолько красочно и убедительно, что все недостатки можно простить. Даже удивительно, что Голливуд смог в такую красивую фантастическую картинку.

Миссия невыполнима: Смертельная расплата. Часть первая (Mission: Impossible - Dead Reckoning Part One, 2023). Как обычно, отлично снятый красочный аттракцион. Но, гораздо, гораздо более скучный и унылый, чем любая из предыдущих частей.

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

Медовый месяц (Elizabeth Harvest, 2018). Интересно и необычно рассказанная история. Хотя, как мне кажется, весь фильм держится больше на красивой картинке и хороших актерах, нежели на истории. О просмотре не пожалел, но, боюсь, кино специфическое и зайдет не всем.

Чужак (Farang, 2023). В принципе, неплохой боевик с мордобоем. Но слишком уж много в нем драмы и соплей, сократили бы хронометраж минут на 10-15, стало бы еще лучше.

Последний наёмник (In the Land of Saints and Sinners, 2023). Простенькая и неторопливая история с минимумом экшена и откровенно халтурными спецэффектами.

Опасный соблазн (Fatale, 2020). Красиво. Но очень уж затянуто, да и развязка какая-то убогая.

Убийца (The Killer, 2023). Прикольно рассказанная история. Но после просмотра остается стойкое ощущение "вы нам втираете какую-то дичь!", что очень и очень сильно портит впечатление от кино.

Украсть Рафаеля (Criminali si diventa, 2021). Откровенная халтура, в которой половина снимавшихся даже играть толком не пыталась.

Фантом из прошлого (L'uomo sulla strada, 2022). Во-первых, это никакой не триллер, а унылая сопливая драма. Во-вторых, это такая муть, на которую лучше не тратить свое время.

Сериалы

Химера (первый сезон, 2022). Динамично, красочно. Следить за происходящим интересно. Но вот кому-то из героев сопереживать не хочется, такое ощущение, что положительных героев там практически и нет. Ну и местами все происходящее выглядит ну очень уж сказочно.

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

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

Прощай, любимая (первый сезон, 2014). У меня лично оставил впечатление откровенной халтуры, так что рекомендую просто пройти мимо.

среда, 29 ноября 2023 г.

[prog.c++.flame] Насколько эффективно реализована split_path в C++ REST SDK от Microsoft?

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

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

Но, полагаю, одна из причин -- это эффективность.

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

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

Ага, я тоже так думал.

Пока не довелось заглянуть в потроха C++ REST SDK от самого Microsoft.

понедельник, 20 ноября 2023 г.

[prog.oop] Что-то я не понял пассаж Барбары Лисков из её статьи от 1987-го года...

Сама статья "Data Abstraction and Hierarchy (OOPSLA ‘87 Addendum to the Proceedings)", раздел "6.2. Multiple Implementations" (стр.16):

It is often useful to have multiple implementations of the same type. For example, for some matrices we use a sparse representation and for others a nonsparse representation. Furthermore, it is sometimes desirable to use objects of the same type but different representations within the same program.

Object-oriented languages appear to allow users to simulate multiple implementations with inheritance. Each implementation would be a subclass of another class that implements the type. This latter class would probably be virtual; for example, there would be a virtual class implementing matrices, and subclasses implementing sparse and nonsparse matrices.

Using inheritance in this way allows us to have several implementations of the same type in use within the same program, but it interferes with type hierarchy. For example, suppose we invent a subtype of matrices called extended-matrices. We would like to implement extended-matrices with a class that inherits from matrices rather than from a particular implementation of matrices, since this would allow us to combine it with either matrix implementation. This is not possible, however. Instead, the extended-matrix class must explicitly state in its program text that it is a subclass of sparse or nonsparse matrices.

The problem arises because inheritance is being used for two different things: to implement a type and to indicate that one type is a subtype of another. These uses should be kept separate. Then we could have what we really want: two types (matrix and extended-matrix), one a subtype of the other, each having several implementations, and the ability to combine the implementations of the subtype with those of the supertype in various ways.

Что в моем вольном переводе на русском языке звучит так:

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

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

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

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

Так вот, я не понимаю почему Барбара Лисков сделала утверждение, что в рамках ООЯ мы не можем отнаследовать "расширенную матрицу" просто от класса "матрица" забив на существование подклассов "разреженная матрица" и "обычная матрицы", которые также наследуются от класса "матрица".

Очень смущает, что статья от 1987-го года, и там в списке литературы нет ни одной ссылки на описание таких языков программирования, как Eiffel (1986) и C++ (1985). Есть упоминание разве что SmallTalk, но в SmallTalk, насколько я помню, вообще не было понятия "абстрактный базовый тип" (или "интерфейс" в Java-подобных языках). Тогда как и в Eiffel, и в C++ понятие "абстрактного (базового) типа" как раз есть и в Eiffel/C++ мы запросто можем решить озвученную проблему имея просто абстрактный тип matrix и отнаследованный от него абстрактный тип extened_matrix.

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

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

суббота, 18 ноября 2023 г.

[life.work.memories] Вспомнилось про уход из "Интервэйла" и про один из факторов, толкнувших к открытию собственной компании...

На неделе увидел в LinkedIn пост ув.тов.Сергея Шуринова о том, что он находится в поисках новой работы. Сергей в "Интервэйле" прошел схожий с моим путь: от разработчика до директора департамента разработки и внедрения ПО.

Это вызвало воспоминания почти десятилетней давности о том, как я сам оказался в подобной ситуации и какие варианты выбора были у меня в тот момент.

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

Уходить в аутсорсинговую компанию, вроде ЕПАМ или БелИБА, на роль ресурсного менеджера не хотелось, хотя, наверное, такую возможность можно было реализовать.

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

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

Но переезжать куда-то не хотелось, поэтому и был выбран путь в сторону собственного "маленького свечного заводика". Не, ну правда, велосипедостроитель я или где? Раз нет здесь подходящего места работы, так почему бы не создать его самому? ;)

Кстати говоря, вспомнилась еще одна штука. Если не ошибаюсь, то большая половина всех мои коллег, составлявших костяк гомельского филиала "Интервэйла" в 2001-2004 годах (когда здесь все начиналось с абсолютного нуля), со временем попробовали открыть собственные связанные с разработкой ПО бизнесы. Ну, может быть, за исключением 2-3 человек. Результаты, понятное дело, у всех были разные, но попробовало подавляющее большинство. Включая меня.

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

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


На счет "говноменеджера". Когда-то давно запостил здесь заметку про переход из разработки в менеджмент. Спустя год использованный в ней термин "говноменеджер" акционеры мне припомнили. Шутки юмора они такие -- не всем понятные.

четверг, 16 ноября 2023 г.

[prog.work] Конкурируем на глобальном рынке ;)

Вот эта найденная на просторах Twitter-а запись заставила вспомнить об одном моменте, который произошел в моем сознании где-то в 2017-ом году.

Дело в том, что если не считать нескольких месяцев, проведенных в ЕПАМе, когда довелось чуть-чуть прикоснулся пятым винтиком в пятисотой шестеренке к разработке продукта для глобального рынка, практически всю свою профессиональную жизнь (до создания собственной фирмы) довелось работать над продуктами, ориентированными на узкий локальный рынок. Даже в компании "Интервэйл", которая одна из первых в РФ стала делать системы мобильного банкинга и держала заметную долю рынка SMS-информирования, все равно это были довольно-таки локальные истории.

А вот когда мы создали свой "СтифСтрим" для того, чтобы оказывать поддержку пользователям SObjectizer-а, да еще и следом, для диверсификации, занялись разработкой RESTinio... Вот тогда до меня вдруг дошло, что наши OpenSource продукты в прямом смысле слова конкурируют на самом что ни есть глобальном рынке. И для того, чтобы чего-то здесь добиться, нужно стремиться быть на одном уровне с лучшими. А лучшие здесь выпускаются в OpenSource, например, Microsoft-ом или Facebook-ом. И вот с ними приходится толкаться локтями.

Признаюсь, для меня, как для троечника, с трудом закончившего университет в "условном Бобруйске"*, это осознание не сказать, что сильно обрадовало 😏

Но как-то свыкся.

Просто стараюсь о таком не думать. А то груз ответственности становится тяжелее, чем следовало бы 🙂


* Касательно "условного Бобруйска". Меня уже несколько раз на русскоязычных форумах попрекали тем, что нет за плечами диплома МГУ или еще чего попрестижнее. Да самим фактом проживания не в Москве/Питере/Лондоне/Силиконовой долине так же. Посему данный термин мне нравится, не позволяет свалиться в снобизм 😎

понедельник, 13 ноября 2023 г.

[prog.c++] Несколько слов про реализацию цепочек асинхронных обработчиков в RESTinio-0.7.0

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

Текста будет много, кода и картинок не будет вообще. Кому не лень в это все погружаться, милости прошу под кат.

четверг, 2 ноября 2023 г.

[software.business] Любопытная статья "Open Source does not win by being cheaper"

Попалась на глаза статья под интригующим названием "Open Source does not win by being cheaper". Как по мне, так она обязательна к прочтению для всех, кто думает начать свой собственный софтверный бизнес. Особенно если этот бизнес будет завязан на модели Open Source.

Для меня эта статья была любопытна в первую очередь тем, что она касается Open Source, который решает проблемы бизнеса. Сам-то я больше привык иметь дело с Open Source, который решает проблемы программистов (библиотеки, компиляторы, middleware всякое и т.д, и т.п.) А тут статья, вроде бы о привычном Open Source, но о непривычном 🙂

В общем, повторюсь, если кто-то раздумывает о заработке на Open Source, то имеет смысл ознакомиться и с этой точкой зрения.

Также добавлю еще пару интересных ссылок в дополнение к теме:

Сюда же еще и Money and Open Source, но это, как мне показалось, больше про то, как отдельный разработчик может прокормить себя работой над Open Source (вкратце: все сложно).


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

Для того, чтобы Open Source продукт начал приносить вам деньги, он должен вроде как решать какую-то насущную проблему. Но не то, чтобы полностью... Что-то в этом продукте должно быть недоделано. Либо по функционалу, либо по качеству реализации этого функционала, либо по документации, либо все это вместе.

Чтобы у вас было нечто вроде CMake: вроде как проблему решает, но сам без поллитры не разберешься, а если и разберешься, то перепачкаешься с ног до головы в известной субстанции. И решишь, что проще в Kitware денег занести, чтобы они что-то под тебя напильником доработали.

А вот если делать нормально сразу, то есть риск того, что вашим продуктом будут просто пользоваться, даже спасибо не говоря 😉

Т.е. делать сразу хорошо в случае Open Source невыгодно. Нужно сделать на уровне "ну, в принципе, норм, но..." 🤣


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

среда, 1 ноября 2023 г.

[life.cinema] Очередной кинообзор

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

Фильмы

Рептилии (Reptile, 2023). Очень раздражала манера съемки и способ построения диалогов. А по итогу так и не понял кто на ком стоял (т.е. кто что, как, почему и зачем сотворил).

Таинственное убийство (La nuit du 12, 2022). Был введен в заблуждение описанием, на самом деле это оказался не триллер про расследование убийства, это драма про переживания следователей, ведущих расследование убийства. Тем же, кто хочет посмотреть детектив про поиск виновного в преступлении, лучше пройти мимо этого кино.

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

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

Сериалы

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

Побег из тюрьмы Даннемора (Escape at Dannemora, первый сезон, 2018). Очень и очень странные впечатления. Хорошие актеры, отлично играют, приличного качества картинка. Но вот следить за происходящим не интересно и скучно. Да и нет в этом сериале ни одного героя, за которого хотелось бы переживать. Глядя на происходящее на экране так и хочется сказать: "Никого не жаль, Господь, жги всех!"

Фильмы, которые не удалось досмотреть

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

пятница, 27 октября 2023 г.

[prog.flame] Наглядная иллюстрация на тему "ушел рисовать каракули на бумаге"...

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

Дабы не повторяться, процитирую себя самого:

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

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

К сожалению, мой собеседник меня не понял (так уж показалось) и в итоге выдал вот такой пассаж:

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

А вчера я столкнулся с ситуацией, которая отлично иллюстрирует момент с "рисованием ничего не значащих каракулей на бумаге". Что и подтолкнуло к написанию этого поста.

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

Суть в том, что в свое время в RESTinio был добавлен механизм объединения обработчиков запросов в цепочки. Это что-то a la middleware из Express.JS (но именно что a la, т.е. по мотивам, но не один-в-один).

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

Что неудобно, например, если какому-то обработчику нужно выполнить длительную асинхронную операцию. Скажем, сходить в БД или обратиться к стороннему компоненту дабы аутентифицировать пользователя.

Поэтому сразу встал вопрос "цепочки синхронных обработчиков -- это лучше, чем ничего, но можно ли сделать их асинхронными?"

Три года назад ресурсов на решение этого вопроса не хватило.

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

Но вот проблема: я не знаю как ее решить. На данный момент от слова совсем. Получается что есть и "заданный объем", и "заданный срок", а вот как сделать решительно непонятно.

Да, тот самый туман в голове с обрывками из отрывков разрозненных мыслей. Ну и каракули на бумаге, куда же без этого.

Есть ли у меня уверенность в том, что задача будет решена за неделю (а больше времени может и не быть)?

Нет, конечно.

Хочу ли я сделать первое, что придет в голову просто ради того, чтобы поставить галочку в списке фич RESTinio?

Нет. Лучше уж у нас фич будет меньше, но те, что есть, пусть будут сделаны хорошо. Это гораздо дешевле в средне- и долгосрочной перспективе.

И что же получается?

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

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

Но, если результат вовсе не гарантирован, то что же толкает на поиск решения?

Во-первых, "есть такое слово: надо!" 😂 Поскольку продукт жив, то он должен пополняться новыми фичами. Пусть даже какие-то из них (пока) непонятно как сделать.

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

Дабы не быть голословным по поводу изобретательства. Перечитываю сейчас куски документации по RESTinio, дабы восстановить в памяти что и как у нас уже сделано. Дошел до раздела про экспериментальный easy_parser router (на русском языке про него есть статья на Хабре). И вот перечитываю, а у самого остатки волос шевелятся от увиденного: сложно поверить, что все это мы сами придумали и сделали 😎

Особенно, почему-то доставил вот этот фрагмент из раздела про easy_parser:

// A parser for grammar:
//
// communicator = "port=" ("default" | port_params)
// port_params = '(' NUMBER ':' NUMBER ',' NUMBER ')'
//
struct port_params {
   unsigned short port_index_;
   unsigned int in_speed_;
   unsigned int out_speed_;
};

auto parser = epr::produce<port_params>(
   epr::exact("port="),
   epr::alternatives(
      epr::exact("default")
         >> epr::just(port_params{10u4096u4096u})
         >> epr::as_result(),
      epr::produce<port_params>(
         epr::symbol('('),
         epr::non_negative_decimal_number_p<unsigned short>()
            >> &port_params::port_index_,
         epr::symbol(':'),
         epr::non_negative_decimal_number_p<unsigned int>()
            >> &port_params::in_speed_,
         epr::non_negative_decimal_number_p<unsigned int>()
            >> &port_params::out_speed_,
         epr::symbol(')')
      ) >> epr::as_result()
   )
);

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

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


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

четверг, 26 октября 2023 г.

[prog.c++.sobjectizer] Several aspects of integration with foreign multithreading libraries

During discussion with Marco Arena about a new article from his series "SObjectizer Tales" I was asked:

You can see that gRPC "sync API" manages threading internally. This might be a problem. Speaking of which, I am really interested in your experience on SObjectizer living together with other threading hosts. How do you usually manage things in this situation? Imagine also that gRPC threads are not "exposed" anyhow.

It's a very interesting question, and it's hard to answer in a few words. But I'll try...

Let's imagine a case when we have to use SObjectizer and some other multithreaded library in an application. What kind of problems can we encounter and what can we do with them?

In the following text I'll use the imaginary library "MegaThreads" just for convenience.

вторник, 24 октября 2023 г.

[prog.c++] Оказывается, std::enable_shared_from_this можно применять и с неполным типом

Увидел неожиданное для себя в статье "On detecting improper use of std::enable_shared_from_this":

#include <memory>

struct D;

struct B : std::enable_shared_from_this<D>
{
};

struct D : B
{
};

int main() {
    auto p = std::make_shared<D>();
    auto q = p->shared_from_this();
}

И это спокойно компилируется.

Другими словами, std::enable_shared_from_this можно использовать и для типов, которые не были еще полностью определены.

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

понедельник, 23 октября 2023 г.

[prog.flame.c++] Ведь ни один вменяемый человек не начнет писать на C++ что-нибудь новое...

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

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

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

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

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

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

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

Во-первых, на данный момент накоплено огромное количество библиотек на Си и C++, на базе которых строятся готовые прикладные (или не очень прикладные) решения. Вроде FFMPEG или OpenCV. Использовать эти библиотеки из C++ легко и просто, без каких-либо промежуточных врапперов и дополнительных уровней абстракции.

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

Во-вторых, страшилки про то, что выбрав С++ вы автоматически попадаете на постоянные segmentation fault и бесконечные утечки памяти, как мне кажется, не актуальны уже лет 20. Ну, если и не 20, то лет 10 точно. И причина не столько в том, что C++ за это время стал лучше и безопаснее. Как раз таки не стал (подвижки есть, но они не кардинальные). Но С++ оброс инструментарием, который позволяет минимизировать усилия на борьбу с подобными явлениями: санитайзеры, статические и динамические анализаторы. Так что и падения, и утечки памяти в C++ном коде все еще встречаются. Однако и происходит это гораздо реже, и обнаруживается уже гораздо проще.

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

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

Ну и в завершение позволю себе озвучить один интересный аргумент против разработки на языке Go, который мне довелось услышать года четыре назад (надеюсь, что здесь я никакого NDA не нарушу). Смысл был в том, что Go-шники на рынке дорогие, все за ними гоняются, их ЗП улетели "в небеса", но при этом найти толкового Go-шника сложно, т.к. язык позволяет писать код даже посредственным программистам. В результате если взять на рынке случайного Си-шника или плюсовика, то больше шансов на то, что он будет понимать что делает и сможет сделать нормально, чем если взять случайного Go-шника, а стоить Си-шник или плюсовик будет дешевле.

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

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


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

пятница, 20 октября 2023 г.

[prog.memories] Вспомнил кайф от работы над библиотекой timertt

Благодаря вот этой теме на Reddit-е вспомнилась работа над библиотекой timertt, которая у нас в SObjectizer-е применяется для обслуживания таймеров.

Кстати говоря, если кому-то интересно какие есть подходы к обслуживанию таймеров, то краткую выжимку можно посмотреть вот в этом небольшом блог-посте, который ссылается вот на эту основополагающую PDF-у (ее URL, на всякий случай: http://www.cs.columbia.edu/~nahum/w6998/papers/sosp87-timing-wheels.pdf, именно http://, а не https://).

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

Так, в общем-то, библиотека timertt и появилась.

Работы над ней сопровождались парой постов-размышлизмов в блоге: раз, два. Сейчас их мне самому интересно перечитывать... И ведь было время и желание такие лонг-риды писать 🤔

Да, так вот к чему это все вспомнилось.

К тому, что хоть деталей работы над timertt я уже не помню от слова совсем, но вот ощущение удовольствия осталось до сих пор.

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

И, что совсем уж удивительно, timertt работает себе и работает. Уже девять лет.

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

Из чего-то подобного еще вспоминается разработка PEG-парсера для RESTinio в 2019-ом. Тогда тоже был кайф от проделываемой работы, хотя шло все гораздо сложнее, чем с timertt. Но кайф от работы ощущался все равно.

Эх... Были времена... Приятно вспомнить.

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

PS. Во время подготовки этого поста перечитал собственную же статью на Хабре про easy_parser из RESTinio и офигел от сложности того, что там описано. Как будто совсем другой человек и тот код писал, и ту статью. Какая-то более лучшая версия меня 🙂

четверг, 19 октября 2023 г.

[prog] В склерозник: отличное чтиво на тему бенчмарков и маркетинга...

...вот эта вот статья: "How fast is ASP.NET Core?"

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

Очень напомнило как мой коллега лет шесть назад принимал участие с RESTinio в подобных соревнованиях объявленных Mail.ru. Особенно когда выяснилось, что лучшие результаты показывают решения, использующие хардкорный busy waiting loop на системных вызовах.

[prog.c++] Послесловие к релизу SObjectizer-5.8.1

Несколько дней назад были зафиксированы версии SObjectizer-5.8.1 и so5extra-1.6.1. Сегодня были сделаны анонсы на нескольких профильных форумах и на Хабре была опубликована статья, рассказывающая о нововведениях. Так что всех интересующихся адресую к этой статье.

У меня же два главных впечатления от работы над версией 5.8.1 таковы:

  • проектирование и реализация bind_transformer заняли буквально несколько часов. А вот покрытие реализации тестами, да так, чтобы эти тесты не роняли компилятор в internal compiler error и не компилировались по 5 минут... Вот на это ушло в разы больше времени.

    Вообще, тесты для bind_transformer -- это отдельная песТня с шаблонной магией (например, раз и два). У меня было даже желание описать все эту магию отдельным постом (или статьей), но прикинув приблизительный объем как-то взгрустнул и не решился 😔

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

    Такая вот наглядная разница между "просто сделать" или "сделать хорошо".

  • Фичу с so_this_agent_disp_binder пришлось реально ждать три года. Прям как в народной мудрости "обещанного три года ждут". Правда, мы и не обещали. Просто вовремя вспомнили, что такая хотелка была 🙂

    А почему вспомнили? А потому, что записано все было "в книжечке". Т.е. в виде issue на GitHub-е.

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

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

Ну и да, SObjectizer на GitHub-е тихой сапой перебрался через рубеж в 400 звезд. Оно, конечно, на хлеб не намазывается, но таки чем больше звезд, тем больше доверие потенциальных пользователей. Так что отрадно. Того и гляди, такими темпами через 5 лет и до 1000 дойдем 😉

понедельник, 16 октября 2023 г.

[prog.c++.kill-them-all] Во что обходится это дерьмо, CMake?

Сегодня наткнулся на блог пост "The road to hell is paved with good intentions and C++ modules", создателя Meason-а. А в этом блог посте ссылку на вот эту презентацию: "A new CMake Scripting Language?". Из которой можно узнать интересные цифры. Например, перевод некого проекта Trilinos с GNU Autotools на CMake обошелся Sandia National Laboratories (SNL) более чем в миллион долларов -- около $500K составила стоимость рабочего времени сотрудников SNL и еще около $700K было потрачено на контракты с Kitware по доработкам CMake/CTest/CDash.

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

Но вот после знакомства с вышеупомянутой презентацией я вообще в шоке.

Это как же у Kitware получилось сперва выкатить откровенное дерьмо в мир, затем убедить кучу народа это жрать не просто причмокивая, а еще и доплачивая Kitware?

Снимаю шляпу.

Пару лет назад я был готов добавить в RESTinio поддержку HTTP-клиента за $3.5K (что на тот момент не превышало одной месячной ЗП C++ разработчика моего уровня, причем просто чистой ЗП, без налогов на ФОТ и прочих издержек). А тут создатели CMake не стесняются озвучивать сумму в миллион долларов для того, чтобы сделать улучшенный CMake.

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


Отдельно мне доставила фраза со слайда #11 в упомянутой презентации:

The book “Professional CMake” largely solves the CMake Documentation problem.

Вот нет! Эта книга, возможно, как-то решает вопрос получения денег с пользователей CMake. Но не решает проблему качества CMake-овской документации.


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


Говорил раньше и повторю еще раз: если собрать список причин по которым стоило бы распрощаться с C++, то CMake там был бы на одном из первых мест.

И не потому, что CMake плохой. Плохого софта не так уж и мало.

А потому, что сообщество, в котором такое дерьмо, как CMake, стало де-факто стандартом, не ждет ничего хорошего. И такое сообщество заслуживает того, чтобы скончаться в муках. Медленно и мучительно.

четверг, 5 октября 2023 г.

[prog.c++.sobjectizer] Марко Арена начал публиковать серию постов "SObjectizer Tales"

Один из пользователей SObjectizer-а, Марко Арена, начал публиковать серию статей под названием "SObjectizer Tales". Это не очередное руководство о том, как программировать с помощью SObjectizer-а. Это рассказ о том, как человек увидел SObjectizer, что полезного в нем нашел и как он решал стоящие перед ним задачи с помощью нашего инструмента.

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

Содержимое серии на текущий момент:


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

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

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

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

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

Прошу простить мне минуту самолюбования, но да, есть теплое чувство внутри.

воскресенье, 1 октября 2023 г.

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

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

Фильмы

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

Индиана Джонс и колесо судьбы (Indiana Jones and the Dial of Destiny, 2023). Вот если бы в этом кино было чуть меньше погонь, то было бы вот прям вообще здорово. Мне лично очень зашло, прям ностальгия по кино 1980-х.

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

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

Яростный волк (Lobo feroz, 2023). Это испанский ремейк израильского Очень плохие парни (Big Bad Wolves, 2013). Так что если израильский оригинал смотрели, то можно пройти мимо, в испанской версии ничего неожиданного не будет. А вот если "Очень плохие парни" не видели, то я бы рекомендовал именно испанский ремейк, т.к. он как-то более по человечески сделан, с ощущением реального трагизма происходящего.

Пекарь (The Baker, 2022). Довольно средненькая по качеству попытка снять очередное кино про "боевого пенсионера". На этот раз с неподражаемым Роном Перлманом в главной роли. Перлман, конечно, мощен и брутален для своего возраста, но временами в происходящее на экране не верится.

57 секунд (57 seconds, 2023). В принципе, идея прикольная. И, местами, смотрится происходящее здорово. Однако в целом остается ощущение халтурности. Как будто можно было бы сделать сильно круче, но не смогли.

История одного ограбления (Ostaggi, 2021). Посредственное кино. Можно глянуть если никаких других альтернатив нет вообще.

Мег 2: Бездна (Meg 2: The Trench, 2023). Редкая дрянь, смело можно не смотреть.

Сериалы

Черное солнце (Geomeun teyang, первый сезон, 2021). Первые пару серий были довольно бодренькие. К завершению все скатилось в унылую санта-барбару. Ну и нельзя советовать этот сериал тем, кто, как и я, не запоминает корейские имена героев, организаций и географические названия. Потому с непривычки что Хан Джи-ёк, что Канг Пил-хо, что Ку Хуо-ён -- все одинаково пролетает мимо ушей :(

Дублинские убийства (Dublin Murders, первый сезон, 2019). Редкостная дрянь, купился на высокий рейтинг и сильно пожалел о потраченном времени.

пятница, 29 сентября 2023 г.

[prog.c++] Список встраиваемых в C++ приложения HTTP-серверов написанных на C++ (сентябрь 2023)

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

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

Специально не даю никаких своих комментариев по поводу перечисленного, т.к. чукча не читатель (пользователь), чукча писатель (т.е. разработчик одного из перечисленных). Но к тем, кто сходу советует "бери Boost.Beast и не парься" отношусь с неодобрением ;)

И да, список отсортирован по алфавиту, так что в порядке следования названий никакого другого смысла искать не стоит. Но все должны знать, что выбирать и поддерживать следует RESTinio :))). Да, это неприкрытая реклама. Да, проплаченная мной. Да, могу себе позволить! ;)

Список не претендует на полноту, это лишь то, о чем я наслышан.

Это только чисто С++ные разработки. Инструменты, написанные на чистом Си, но которые могут использоваться и из C++ (вроде CivetWeb и Mongoose) сюда не включены намеренно.

вторник, 26 сентября 2023 г.

[prog.work.flame] Деньги платят не за язык, а за решение проблем?

Время от времени на просторах Интернета приходится сталкиваться с высказыванием, вынесенным в заголовок поста. Применительно к моей специфике оно часто формулируется так: "За C++ деньги не платят, платят за решение проблем" или "За C++ деньги не платят, платят за знания конкретной прикладной области".

Я понимаю подобные высказывания так: первичны знания человека в какой-то специфической области. Например, в обработке видео. Или в распознавании образов. Или в статистике. Или в компиляторостроении. И т.д., и т.п.

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

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

Как минимум по двум причинам.

Во-первых, любое объемное ПО -- это не только набор математических формул. Это все-таки огромное количество "сопроводительного текста" к этим самым формулам. Т.е. наукоемкое ядро будет занимать пару-тройку десятков процентов (а то и меньше) от общего объема кода. Тогда как большая часть -- это рутинная обвязка. И эту обвязку нужно написать. Желательно хорошо. А для этого нужен такой навык, как умение писать код. Что, вообще-то говоря, дано не всем. Особенно из числа математиков и физиков ;)

Ну и к умению писать код желательно бы еще и приложить владение инструментом, т.е. знание языка программирования и умение пользоваться этим самым языком (что далеко не всегда сопутствует знанию языка). Грубо говоря, если вы пишете на C++, то вы на автомате должны расставлять const и noexcept, и не создавать объекты через new там, где их можно просто разместить на стеке, ну и RAII во все поля, куда же без этого ;)

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

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

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

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


ЗЫ. Наверное, отчасти этот пост навеян легким сожалением о том, что такая штука, как "знание C++", не котируется. Столько лет насмарку, и как теперь жить? ;)))

ЗЗЫ. По большому счету к перспективе сменить основной язык программирования отношусь философски. Наверное среди используемых сейчас в индустрии языков найдется мало таких, которые я бы не смог толком освоить... Хотя вот Perl в свое время не смог ;) Жаль только, что на овладение новым языком время потребуется. Месяцев 9-10. Ну, чтобы овладеть. А не так, чтобы как курица лапой.

понедельник, 25 сентября 2023 г.

[work] Вроде бы "проект мечты", но что-то пошло не так...

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

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

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

При этом изначально предполагалось, что я буду на вторых ролях, что моя задача будет заниматься какими-то околосистемными и инфраструктурными вещами, вроде обмена BLOB-ами между процессами посредством shared memory. Ну и сперва никто не предполагал, что затянется все это не на один год.

Но что-то пошло не так :(

И с начала 2022-го года проектом занимался уже я один.

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

Временами напрягало, временами отпускало.

Вот этим летом напрягло очень уж сильно. Сдерживало же то, что мы вписались в проект, сделали большой объем работы, но до логического завершения пока еще не довели. А бросать начатое не доделав мне нравится еще меньше, чем писать GUI-приложения для конечного пользователя.

Но тут до нас долетело очередное эхо войны (войны, которую соседняя страна скрывает за эвфемизмом СВО) и Atlassian "порадовал" новостью о грядущей блокировке моего аккаунта. При том, что разработка как раз ведется на Atlassian-овском bitbucket-е.

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

Такая вот неоднозначная история получилась. Ведь вроде бы должен был быть "проект мечты", который и дает нам возможность погрузиться в новую тему, и оставляет время на развитие собственных проектов, и базируется на SObjectizer-е (RESTinio там не удалось применить из-за отсутствия в RESTinio HTTP-клиента), и мы в очередной раз оказались у самых истоков и начали с нуля, не имея багажа чужого легаси...

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

Так что, потенциально, все должно было бы быть хорошо.

Но что-то пошло не так.

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


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

воскресенье, 24 сентября 2023 г.

[life.work] Переживания по поводу "Мне уже XX лет, а я все еще пишу код"

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

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

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

Это потому, что начинал еще на осколках созданного в СССР, поэтому естественной и единственной видимой мне лестницей был рост до руководителя группы, потом до руководителя отдела, потом до руководителя управления и т.д. Уже много лет спустя узнал, что в современном мире разработчик может расти и в сторону "архитекторов" различного уровня: system architect, solution architect и т.д, и т.п.

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

И вот при таком видении "успешного успеха" рано или поздно происходит оценка того, что ты имеешь по сравнению с тем, о чем мечталось в юные годы. Не знаю, как это происходит у женщин, но у мужчин, как мне думается, подобное может проявиться в районе 33-х лет ("возраст Христа" и навязанные этим стереотипы), а так же между 37-ю и 50-ю годами, в очередной волне кризиса среднего возраста (тут у каждого индивидуально). Где-то в эти периоды в голове и возникает вопрос о том, а нормально ли то, что тебе уже XX лет, а ты все еще пишешь код.

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

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

Второй же врач так и остался врачом, 30 лет совершенствуясь в своей профессии, набравшись такого опыта и мастерства, что мало кто с ним сравнится.

А теперь, внимание, вопрос: если у вас или у ваших близких, нипривидихоспади, что-то серьезное случилось с зубами, к кому вы захотите попасть в кресло? К успешному руководителю самой лучшей клиники? Или к человеку, который лечит зубы 30 лет подряд без перерыва?

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

У каждого из них просто разные жизненные пути.

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


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

среда, 13 сентября 2023 г.

[work.business] Atlassian пообещал прекратить действие моей учетки в течении 30 дней

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

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

А вот на счет Atlassian-а есть сомнения.

Такое ощущение, что Atlassian со своим bitbucket-ом делает еще один шаг чтобы просрать все полимеры GitHub-у. Если в СНГ еще оставались те, кто держал свои репозитории на bitbucket-е, то теперь то их точно унесут куда-нибудь. А остальные задумаются, можно ли дальше иметь дело с Atlassian-ом. Однажды эта контора уже подосрала своим пользователям с прекращением поддержки Mercurial. Теперь вот еще один гвоздь в крышку гроба своей репутации.

Любопытно по прошествии времени смотреть на то, к каким последствиям приводят собственные решения, принятые несколько лет назад. В 2016-ом моя команда приняла решение уйти с SourceForge на bitbucket именно из-за Mercurial. Мы туда перенесли разработку SObjectizer-а и первые версии RESTinio разрабатывались там же. Но потом из-за Atlassian-а вынуждены были перебраться на GitHub.

Вот не прекрати Atlassian поддержку Mercurial на bitbucket-е мы бы могли до сих пор там оставаться. Сейчас бы Atlassian выставила разработчиков из РБ с bitbucket-а на мороз и поудаляла бы наши репозитории. Хорошо бы от этого не было бы ни нам, ни нашим пользователям.

На счет пользователей тут вот еще что думается. Как по мне, так публикация OpenSource проектов сейчас -- это как в свое время свободный обмен научными статьями: можно, конечно, закрыться в своих собственных национальных квартирах и пытаться двигать науку в отдельно взятой стране, но пользу это вряд ли кому-то принесет. Между тем, если Atlassian действительно будет удалять с bitbucket-а репозитории, созданные разработчиками из РБ и РФ, то это как попытка изъять из оборота научные статьи, написанные представителями неугодных национальностей.


Данное уведомление от Atlassian стало последним аргументом в пользу того, чтобы начать сворачивать сотрудничество с нашим текущим заказчиком из Западной Европы. Так что спустя некоторое время буду объявлять "свободная касса". Может быть кому-то из РФ или стран ближнего зарубежья мои услуги пригодятся.

понедельник, 11 сентября 2023 г.

[prog.c++] В склерозник: статья "What every systems programmer should know about concurrency"

Хорошая статья для тех, кто хотел бы в общих чертах понять что такое атомарные операции и с чем их едят: "What every systems programmer should know about concurrency".

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

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

суббота, 9 сентября 2023 г.

[prog.c++.idiotic] Позволю себе еще раз пнуть deducing this, который вводят в C++23

В C++23 давно добавили такую фичу, как deducing this. К которой лично я отношусь очень негативно. Как по мне, так с deducing this язык C++23 еще больше повышает планку требований к разработчикам. И сейчас С++ на должном уровне освоить могут не только лишь все, а уж хорошее знание и умение вменяемо использовать C++23 будет доступно, полагаю, только надмозгам.

На тему deducing this я уже несколько раз в разных соцсетях негативно высказывался. Более того, когда-то в Habr-е в комментариях даже набросал пример того, как часть задач deducing this можно было бы решить и "в традиционном" C++ном синтаксисе, не превращая C++ в подобие Python-а и Rust-а с явной передачей self-а в нестатические методы:

class params {
  int limit_;
  ...
public:
  // Иммутабельный геттер.
  [[nodiscard]] int limit() const &, const && noexcept {
    return limit_;
  }
  // Мутабельный сеттер. Может использоваться если params
  // применяется в стиле builder pattern.
  decltype(*this) limit(int v) &, && {
    if(v < -10 || v > 40throw std::invalid_argument{...};
    limit_ = v;
    return *this;
  }
};

А вот давеча прочитал статью от Сандора Дарго "C++23: some changes related to templates" и узнал, что к deducing this еще и новый std::forward_like прилагается. Мало нам было std::forward и std::move, теперь еще и std::forward_like в придачу :(

PS. Не могу не поделится еще на одну статью с примером применения deducing this: "User-defined class qualifiers in C++23". Отличный пример того как упороться новой фичей и еще один способ превратить код в головоломку.