All streams
Search
Write a publication
Pull to refresh
362
0.3
Alex Efros @powerman

Software Architect, Team Lead, Lead Go Developer

Send message

Ну, они сначала пытаются без мамонтов…

О, писал про важное, и забыл про деньги. :)

Рынок выравнивается. Это нормально

Нет, простите, но тут Вы сильно ошибаетесь. То, что сейчас творится в РФ с зарплатами IT - это не "рынок выравнивается". Это совершенно другое: пропала конкуренция с западными компаниями за разработчиков плюс пошло вливание бюджетного бабла. Это - не рынок. И для рыночной экономики это - не нормально. Да, с этим приходится жить - другой экономики и другого рынка нам не дали. Но совершенно не обязательно при этом заниматься самообманом, рассказывая себе (и другим) что всё хорошо.

Мне стало интересно: почему у некоторых разработчиков возникает синдром бога?

Изначально (для меня это было в 90-е) эту тему не раз уже поднимали, как бы не в ФИДО ещё. На тот момент ответ был очевиден: программирование это творчество. А творя - все мы становимся ближе к Богу. Этот ответ сильно выпадает из контекста оригинальной статьи про 400к, но я считаю что правда всё ещё где-то здесь, а не там, в зарплатах и карьерах.

Это работа, а не искусство.

Это и так и не так. Всё зависит от конкретного человека. Для меня это всю жизнь было именно искусством. Я пишу код с 1989. И все эти годы умудрялся найти такую работу, на которой был комфортный мне баланс между временем на рабочую рутину (то, что делать нужно) и творчество (то, что я сам хотел делать) - не в пользу рутины. Так что кто хочет заниматься искусством - обеспечит себе такую возможность.

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

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

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

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

Посмотрите лучше Cursor, с моделью Sonnet 3.5 (она доступна на триале). Что-то достаточно адекватное сейчас выдают в основном Sonnet 3.5/3.7/4, Gemini 2.5 Pro и, возможно o3 (мало тестил, не уверен) - но лучше для первого впечатления взять Sonnet, чтобы понять уровень, на который надо ориентироваться работая с другими моделями.

Copilot в free варианте даёт только 50 запросов, которые испаряются быстрее, чем успеваешь понять что и как делать, если нет опыта. В этом плане Cursor намного адекватнее - там и функционала больше, и доки, и запросов на триале. Так что для задачи "посмотреть что оно может" Cursor сегодня подходит намного лучше. А дальше можно примерно то же самое настроить себе и на (платном) Copilot, если нужен именно Copilot.

В целом, Sonnet выдаёт отличный код - в полном соответствии с требованиями, когда эти требования станут ясны модели (либо из существующего кода, либо заданные вручную в правилах текущего проекта, либо из уточнений в чате). И сам пишет к этому коду и тесты, и доку обновляет. Единственный момент - чтобы получить хороший код нужно его себе сначала представлять, т.е. это не "vibe coding". И получив недостаточно хороший - объяснить модели что именно не так (ровно так же, как объясняли бы новому сотруднику на проекте). А повторяющиеся объяснения один раз внести в правила проекта.

Как уменьшение с 29% до 25% превратилось в "сократилось почти на 32%"?

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

CSAM - собираются вводить именно в ЕС.

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

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

Передавать в юзкейсы структуру или поля по отдельности?

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

Должно ли хранилище, в виде БД например, иметь валидацию данных? Операции по крону? Дефолтные значения полей?

  • БД обычно уже имеет валидацию, не зависимо от нашего желания. Да, не всегда, точнее в зависимости от выбранной БД. Но суть в том, что это не наш архитектурный выбор - валидация обычно есть, нужна она или нет. Более корректная постановка вопроса: нужно ли нам делать валидацию на уровне БД? На мой взгляд, это нужно делать исключительно в том объёме, который необходим для обеспечения целостности данных на уровне самой БД. Т.е. в полях БД не должно храниться неизвестных значений enum, указывающих на несуществующие записи в других таблицах id, etc. Обычно всю эту валидацию можно реализовать встроенными средствами самой БД и в нашем коде про это может не быть ни строчки (не считая обработки соответствующих типов ошибок).

  • Необходимость в операциях про крону обычно определяется либо бизнесом либо это какая-то техническая поддержка данных в самой БД. Иными словами - это не вопрос архитектуры, если они нужны то они нужны.

  • Дефолтные значения полей могут, на первый взгляд, выглядеть вопросом связанным с архитектурой, но по факту это вопрос стиля написания SQL-запросов, не более того. Если в запросах создающих записи лень явно указывать каждое поле, то можно эту часть запроса вынести в схему БД в виде дефолтных значений. Архитектурным вопросом тут скорее является "а почему бизнес-логика в репо при создании записи передаёт не все поля?" - и это правильный вопрос, который обычно полностью снимает вопросы стиля SQL-запросов и дефолтов в схеме БД.

Когда и где вводить versioning: в HTTP‑уровне, в домене (разные агрегаты) или в репозиториях (Multi‑tenant)?

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

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

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

Хороший пример того, как можно 15 лет активно развиваться оставаясь на первой версии API - сам язык Go и его стандартная библиотека.

Из этих соображений на своих проектах я стараюсь в принципе не провоцировать мышление в сторону "если что - сделаем новую версию API", используя для этого в т.ч. психологические приёмы вроде отсутствия номера версии в "первой" версии API. Т.е. я не использую /v1/ в URL, и не использую поле version в форматах данных. Понятно, что при необходимости это не помешает их добавить во второй версии не создав никаких конфликтов, но само их отсутствие заставляет в первую очередь думать как внести изменения совместимым образом а не как можно сделать быстро-грязно несовместимое изменение и тупо увеличить номер версии.

Должны ли доменные ошибки возвращать rich‑error (с кодом/контекстом) или достаточно обычных error с текстом?

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

они хоть вообще инет зарежут, ничего им не будет (сейчас)

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

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

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

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

Транзакции: где их начинать/заканчивать?

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

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

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

Если перейти от абстрактных идей к конкретике, то, по моим наблюдениям, для большинства небольших проектов (вроде микросервисов) оптимальным подходом часто является комбинация из:

  • Чистой/гексагональной архитектуры (отделение работающих с внешним миром адаптеров от бизнес-логики). В практическом смысле это даёт нам:

    • Возможность легко тестировать бизнес-логику.

    • Значительное ускорение полного набора тестов проекта.

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

    • Возможность переиспользовать одну и ту же бизнес-логику с разными адаптерами внешнего мира (напр. вызывать её через HTTP, gRPC или CLI, или использовать разные БД).

  • Service-Oriented Repository (он же Transaction Script) - один большой интерфейс для репо, содержащий близкие к задачам бизнес-логики операции (вроде Deposit или BlockUser), полностью инкапсулирующие в себе транзакции. В практическом смысле это даёт нам:

    • Эффективность работы с БД (во всех смыслах - от возможности использовать всю мощь SQL до отсутствия медленных транзакций).

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

    • Необходимость применять Transactional Outbox паттерн если нужно отправлять события связанные с изменениями в нашей БД (это не минус как таковой, но немного лишней суматохи - нужно как-то хранить события в БД и как-то доставлять их получателям).

    • … не только плюсы, но ещё и минус: перемещение небольшой части бизнес-логики в слой репозитория и/или непосредственно в схему БД.

  • Eventual consistency и/или саги и/или распределённые транзакции для бизнес-операций требующих транзакционности для данных, распределённых между несколькими микросервисами. Сложность этой части полностью определяется тем, насколько адекватно была спроектирована микросервисная архитектура (в терминах DDD - стратегическая часть дизайна). В идеальном варианте удаётся обойтись вообще без саг или незначительным количеством саг (условно, до 5) на весь проект, используя для всего остального eventual consistency. В худшем варианте саги будут использоваться вообще для всех операций в которых участвует больше одного микросервиса.

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

Но, например, в проектах, где уже для всего используются саги, или для микросервиса где находится очень много очень сложной бизнес-логики, более адекватным выбором скорее всего будет чистый DDD с его Repository per Aggregate (он же Thin Repository + Service Layer).

А для очень небольшого проекта или быстрого прототипа даже чистая/гексагональная архитектура может оказаться избыточным усложнением.

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

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

А чем Вы занимаетесь вне работы на предприятии, когда никаких обязанностей нет?

Музыкой и кино Вы не интересуетесь, судя по всему. Доступ в инет сильного энтузиазма явно тоже не вызывает. Неужели бумажные книги? Сомнительно, этот интерес редко идёт в настолько полном отрыве от музыки и фильмов. Огород-рыбалка-готовка-сделай сам? Так это всё в наши дни изучается по видео с ютуба. Большая часть приходящих в голову других способов интересно провести время почему-то либо незаконны либо вредны для здоровья… Я явно упускаю что-то очевидное.

Зависит от того, на чём смотреть картинку. Напр. у меня монитор с разрешением между 720p и 1080p - 1680x1050. И на нём 480p выглядит достаточно отвратительно, чтобы это было заметно. А вот между 720p и 1080p разницу заметить очень сложно, между 1080p и 4K - невозможно. А если у кого-то большой экран, то ему вполне может быть очень даже заметна разница между 4K и 1080p.

Ровно та же история со звуком, кстати. Чтобы достаточно чётко слышать разницу между mp3 320kbps и flac нужны определённого уровня ЦАП, усилок и колонки/наушники.

А Вы злой… хотите избавиться от редакторов хабра, однако!

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

И в любой стране ЕС, например, подобные идеи сдохнут не родившись.

Так выглядело лет 10 назад. А сегодня ситуация сильно изменилась. Вот, например, свежий обзор реального положения дел: https://forklog.com/exclusive/razorvannaya-pautina - в EC таких законов напринимали, что просто ой.

В 2025 ещё кто-то верит, что можно решить политические проблемы техническими средствами? Это может сработать исключительно в краткосрочной перспективе, но никак не "Для окончательного решения проблемы".

Information

Rating
2,401-st
Location
Харьков, Харьковская обл., Украина
Date of birth
Registered
Activity

Specialization

Backend Developer, Software Architect
Lead
From 10,000 $
Designing application architecture
Golang
Linux
Docker
Network security
Modular testing
Mentoring
Development of tech specifications
Software development
High-loaded systems