воскресенье, 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 > 40) throw 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". Отличный пример того как упороться новой фичей и еще один способ превратить код в головоломку.

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

[prog.flame] Может ли аккуратно написанный код выглядеть и пахнуть как говнокод?

Таки да!

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

Во-первых, количество аргументов метода search. Тут как в старой программерской мудрости: если ваша функция получает 10 аргументов, то вы наверняка забыли передать туда еще что-то :) Кроме того, есть подряд идущие аргументы одного типа (например, три аргумента типа dim_t, затем три аргумента типа bool). Мой опыт показывает, что это прямой путь к тому, что рано или поздно какое-то из значений будет перепутано.

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

Вот, скажем, мой взгляд зацепился за объявление переменной biased_decoder типа std::unique_ptr<BiasedDecoder>. Она инициализируется реальным значением только при выполнении некоторых условий, в остальных случаях там будет nullptr. Используется же потом этот biased_decoder всего лишь один раз, довольно далеко от того места, в котором он был создан. Где гарантии, что никто к biased_decoder не обратится еще раз, не проверив предварительно bias_towards_prefix?

Или вот этот вот keep_batches, который так же unique_ptr, но который объявляется вне ветки if-а, в которой он затем создается и используется. Нафига, спрашивается? Там же вообще, насколько я понимаю, можно было обойтись без unique_ptr и объявить keep_batches как обычную переменную на стеке прямо в том месте, где она потребовалась...

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

Для тех, кому лень переходить по ссылке на github, под катом весь фрагмент, к которому я докопался.

ЗЫ. На этот проект вышел через здесь, захотелось посмотреть, что там в других местах с качеством C++ного кода.

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

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

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

Фильмы

Быть Сальвадором Дали (Daliland, 2022). Я посмотрел с большим удовольствием. Но у меня Дали вообще, наверное, любимый современный художник, так что здесь я изначально сильно предвзят.

Рай земной (Paradise, 2023). На удивление неплохо для фильма от Netflix.

(Не)идеальные роботы (Robots, 2023). Простенько и немного предсказуемо, но прикольно. Посмотрел с удовольствием.

Бекки (Becky, 2020) и Бекки в ярости (The Wrath of Becky, 2023). Кино для любителей жанра "кишки, кровь, рас3.14дорасило", правда в немного лайт-версии. При этом первый фильм, как будто снимали на серьезных щах и, тем самым, немного подпортили впечатление. А вот во втором фильме создатели как будто специально говорят "мы не просто снимаем треш и угар, но и угараем с этого, поугарайте вместе с нами". Так что второй мне, как любителю жанра, понравился даже больше.

Не буди во мне киллера (Les complices, 2023). Вполне сойдет для ситуации, когда смотреть больше нечего.

Мальдивы подождут (2022). Если не ждать многого, то вполне смотрибельно для российского фильма. Но не шедевр, конечно же.

Гангстердам (Gangsterdam, 2017). Посредственная молодежная комедия с шутками про пердеж (в прямом смысле). Но местами смешная.

Сердце Стоун (Heart of Stone, 2023). Красиво снятая мура.

Сериалы

Город шпионов (Spy City, первый сезон, 2020). Смотреть интересно, интригу в первых сериях закручивают хорошо, а вот развязка разочаровывает, как будто творческий порыв авторов внезапно выдохся.

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

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

Библиотекарь (первый сезон, 2023). Как по мне, так это сериал для любителей фэнтези. Если вы спокойно погружаетесь с фэнтезийный мир с его выдуманными законами, то можно и посмотреть. Если к фэнтези равнодушны, то можно и пройти мимо.

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

среда, 23 августа 2023 г.

[prog.c++] Пример того, как NRVO(RVO) оптимизация может к вам в код UB подсадить

В процессе одного из споров на RSDN-е родился пример того, как компилятор, применив NRVO, приводит к неожиданному поведению.

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

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

Фокус с entity в том, что есть еще и entity_registry, т.е. реестр объектов entity. Если в конструктор entity передать ссылку на entity_registry, то entity себя в реестре зарегистрирует. А в деструкторе -- вычеркнет.

Пока объект находится в реестре, его можно изменить через реестр: вызываем метод entity_registry::update и реестр вызывает update для всех зарегистрированных в нем объектов.

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

void check() {
   entity_registry registry;
   entity e1{registry};

   entity e2; // Не в реестре.

   entity e3{e1}; // Не в реестре.

   registry.update(25);

   std::cout << e1.value() << ", " << e2.value() << ", " << e3.value() << std::endl;
}

Мы получим вполне ожидаемое:

add to registry: 0x7ffd7b567c18
25, 0, 0
removed from registry: 0x7ffd7b567c18

Т.е. объект e1 добавил себя в реестр, потом мы получили три предсказуемых значения (два нулевых, т.к. никто не менял e2 и e3), затем e1 изъял себя из реестра.

А теперь внимание, вопрос: что будет во в таком случае?

entity make_entity(entity_registry & registry) {
   entity ent{registry};
   ent.update(42);
   return ent;
}

void demo() {
   entity_registry registry;
   const entity ent = make_entity(registry);

   registry.update(100);

   std::cout << ent.value() << std::endl;
}

Можем ли мы изменть значение константного ent внутри функции demo через вызов update у реестра?