Позовите Олега | Архитектура и разработка
962 subscribers
74 photos
4 videos
117 links
Привет. Меня зовут Олег (@mifleo) - я team lead команды разработки в бигтехе, архитектор, разработчик, ментор и консультант, а так же спикер на различных конференциях.
Тут пишу про IT, разработку, карьеру, софтскилах и о себе. Wellcome)
Download Telegram
Привет!

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

Новая AI-модель, новый агент, автопайплайны, скиллы, MCP, LSP для AI. Честно говоря, я долго не понимал, с чего вообще начать, а когда наконец решался — всё уже успевало устареть, и приходилось начинать заново. 🙃

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

И я не представляю, что индустрия развернётся на 180° (или, хотя бы 90) и всё станет как прежде. Да и мне, если честно, уже не хочется «как было».

Сейчас я успеваю поработать над пет-проектом, выпустить MVP своего продукта и ещё сделать бота для благотворительного фонда. Раньше пришлось бы выбирать что-то одно — и, скорее всего, ни одно дело не довёл бы до конца.

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

Я уже не раз говорил (тут, тут, если не читали, то почитайте): написание кода — не главное для инженера. Да, часто задачи решаются через код, но по сути наша работа — это решение бизнес-проблем.

К чему я всё это.

Мы с Данилом Щуцким (CutCode) решили сделать серию воркшопов по AI-кодингу — от базового уровня до продвинутого.

Только концентрированная практика, без растекания по древу теории об ИИ.


Если вы, как и я когда-то, теряетесь в постоянно меняющемся мире AI-инструментов или хотите освоить более продвинутые практики — вам точно стоит прийти.

➡️ Регистрируйтесь в боте и погнали. Будет офигенно!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👍76
Привет! В продолжение предыдущего поста хочется ещё сказать, что осознанное использование AI-кодинга требует хорошей базы — не только инженерной, но и понимания того, как использовать инструменты. Засунуть в LLM промпт «сделай удобную систему» уже недостаточно. На выходе получается продукт, который некачественный, небезопасный и ненадёжный.

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

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

3 марта состоится первый воркшоп — он будет посвящён базе: как разворачивать окружение, как проектировать решения под LLM, как планировать работу и как получать результат. Мы создадим лендинг по выбранному референсу, прикрутим к нему Telegram-бота с RAG и задеплоим всё это, не написав ни строчки кода вручную.

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

До 1 марта стоимость участия — 4000 ₽. Записаться и оплатить можно тут.

Это не разовая акция — в планах повышать сложность и переходить от базы к продвинутым инструментам.
👍6🔥6👏1
Привет!

Вчера состоялся первый в моём опыте воркшоп по ИИ, который я проводил. Ну что ж, это было… не так, как я себе представлял. Несмотря на всю подготовку, погоны и прочее, на самом воркшопе всё пошло не по плану.

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

Накануне мы погоняли промпты для воркшопа — всё шло как по маслу. На самом воркшопе агент выдавал совсем стрёмные результаты. Где-то приходилось перегенерировать. В итоге мы жёстко выбились из тайминга.

У меня начала отваливаться сеть, и каждые 5–10 минут происходил дисконнект.

В PhpStorm у Данила и в PyCharm у меня одновременно отвалился модуль работы с Git.

Последним шагом шёл деплой бота на сервер. До старта воркшопа мы прогоняли эту часть на временной виртуалке с временным IP-адресом, и Telegram этот IP-адрес закешировал и отказался слать запросы по указанному домену на новый сервер. Окей, мы завели новый домен… но упёрлись в рейт-лимит Let’s Encrypt. Час дебага. Шёл шестой час воркшопа…

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

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

Буду ли продолжать? Не знаю. Но если да, то однозначно нужно проводить больше подготовительной работы.

Вот такая вот ретроспектива.

Проводите ли вы ретроспективы после каких-то важных событий или этапов?
2👍21😢8😁5🔥3🙏3
Привет!

Продолжаю рассказывать про шаблоны низшего порядка.

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

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

Такая модель согласованности называется eventual consistency или «согласованность в конечном итоге». Если бы это была строгая согласованность, то результаты оба участника эксперимента увидели бы одновременно.

Зачем нам вообще эта проблема рассинхрона, если можно дождаться, когда данные будут доставлены повсюду? И откуда это вообще берётся?

Когда у нас есть конфигурация master–replica, данные, которые попадают в master, требуют времени, чтобы докатиться до реплик. Эта задержка называется задержкой репликации, или replication lag. И проблема выше возникает как раз из-за такой задержки.

Synchronous Replication Pattern

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

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

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

Pinning User to Master Pattern и Fragmented Pinning Pattern

Тут подход следующий: мы хотим согласованности записи и чтения, но не готовы жертвовать скоростью записи. Что делать?

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

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

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

Master Fallback Pattern

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

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

Server Wait Pattern

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

Push to Client Pattern

Есть ещё способ уведомить клиента по другому каналу связи, например использовать WebSocket. Такой подход называется Push to Client Pattern. То есть мы проталкиваем информацию о том, что изменения наступили и можно читать.

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

Как вы решаете проблему синхронизации записи и чтения?

П.С. немного картинок в комментаиях



Давайте оставаться на связи ☄️
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15👍4👏3
Привет!

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

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

То есть проблема обычно не в том, что «всё сломалось». Проблема в том, что система в какой-то момент нарушила главный инвариант: одно место на одно событие можно продать только один раз.

Как это обычно происходит? Очень просто. Два запроса почти одновременно читают состояние места и оба видят, что оно свободно. Дальше оба идут в оформление. Если между проверкой и фиксацией нет атомарности, система получает классическую race condition. На обычной нагрузке это может не проявляться вообще. На пике продаж — вполне.

Отдельно такие штуки любят системы, где чтение идёт из кэша или реплики, а запись — в primary. В одном месте уже продано, в другом ещё видно как свободное. Или когда hold, оплата и confirm размазаны по нескольким сервисам, а единого владельца инварианта нет.

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

Что с этим делать? Проектировать от инварианта.

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

Обычно нормальная модель выглядит так: available → held → sold.

Сначала место берётся во временный hold, потом проходит оплата, потом hold подтверждается. Но ключевой момент не в названиях состояний, а в том, что нельзя делать check-then-act в несколько шагов без жёсткой конкурентной защиты.

Чек-лист, того, что может помочь:

☑️ уникальное ограничение на продажу конкретного места;
☑️ атомарная фиксация hold/booking;
☑️ отказ от финальных решений на основе кэша и реплик;
☑️ идемпотентность покупки и confirm-операций;
☑️ явная state machine вместо набора несвязанных флагов.

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

Потому что если инвариант не защищён на уровне транзакционной границы, вопрос уже не в том, случится ли двойная продажа. Вопрос только в том, когда совпадёт нужная гонка.
1👍14🔥4👏32
Привет!

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

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

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

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

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

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

Если готовишься к собеседованиям и есть ощущение, что в system design ты пока плаваешь, это как раз то, с чем я могу помочь. На консультации можем разобрать твой текущий уровень, потренировать структуру ответа, посмотреть типичные ошибки, на которых кандидаты теряют баллы, и провести mock interview с подробным разбором. В итоге у тебя будет не просто ощущение, что «стало понятнее», а конкретное понимание своих слабых мест и план, как их закрыть.

Если хочешь действительно сильнее проходить эту секцию и прокачаться в архитектурных скиллах — приходи ко мне на консультацию.

Ещё о моих консультациях.
🔥12👍52👏1
Привет!

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

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

Допустим, мы создали индекс INDEX (created_at, status). B-Tree хранит индекс именно в таком виде, структура физически отсортирована. Значит, и в условии запроса его якобы нужно использовать так: WHERE created_at = now() AND status = 'new'. Логично? Да, логично. Но это уже давно не так. Абсолютно не важно, в каком порядке вы указываете поля в условии для применения индекса. Начиная с MySQL 5 и PostgreSQL 8.

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

В документации PostgreSQL явно написано, что порядок условий в WHERE не фиксирован, и оптимизатор сам перестраивает выражение.

В одной из своих обучалок по PostgreSQL я показываю пример. У меня есть таблица с колонками price — bigint и qr — varchar.

Создаю индекс:


create index price_qr_ind on orders(price, qr);


Далее выполняю запрос:


explain analyze
select qr, price
from orders
where qr = '2b3561d0c25d3e8bdaca5bc338057861'
and price < 50;


И вижу результат:


Index Only Scan using price_qr_ind on orders (cost=0.42..202.85 rows=1 width=41) (actual time=1.983..1.984 rows=0 loops=1)
Index Cond: ((price < 50) AND (qr = '2b3561d0c25d3e8bdaca5bc338057861'::text))
Heap Fetches: 0
Index Searches: 40
Buffers: shared hit=90 read=39
Planning:
Buffers: shared hit=10 dirtied=1
Planning Time: 1.283 ms
Execution Time: 2.120 ms


price_qr_ind говорит о том, что был использован именно тот самый составной индекс. И мало того, что он был использован для фильтрации, — Index Only Scan говорит о том, что отработал ещё и покрывающий индекс. И это несмотря на «неправильную» последовательность условий.

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

Так неужели порядок и вправду не важен? Важен. Но не так, как все думают.

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



Давайте оставаться на связи ☄️
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥49👍7👏2
Привет. Тема индексов оказалась интересной. По этому продолжаю.

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

Вот пример из моей лекции по PostgreSQL для простых разработчиков 🖼

Допустим, есть табличка


events (
id bigint,
tenant_id bigint,
source_type text,
severity text,
status text,
created_at timestamp,
assignee_id bigint
)


Типичный запрос в системе


SELECT id, source_type, severity, status, created_at
FROM events
WHERE tenant_id = 42
AND status = 'open'
AND severity IN ('high', 'critical')
ORDER BY created_at DESC
LIMIT 50;


Интуитивно, можно предложить сделать индекс вида (tenant_id, status, severity, created_at).
Причины очевидны:
- все поля из WHERE
- сначала equality
- потом остальное

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

Разберём запрос выше.

1️⃣ tenant_id = 42
- почти всегда присутствует
- режет огромный объём данных
- естественная сегментация
Почти гарантированно должен быть первым.

2️⃣status = 'open'
- equality
- уточняет выборку
- хорош в начале, но уже после tenant_id

3️⃣ severity IN (...)
- тоже фильтр, но не идеальный (не одиночное значение)
- менее “чистый” для индекса

4️⃣ORDER BY created_at DESC LIMIT 50
Вот здесь начинается интересное. Этот кусок важен, он открывает сценарий "быстро найти первые 50".

В следующей заметке расскажу про 2 подхода к решению этой задачки. 🙃



Давайте оставаться на связи ☄️
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥16👍95👏1
PHPeople — 3 месяца

Помните, я писал про PHPeople — сообществе php разработчиков? Так вот, мы работаем уже 3 месяца. За это время собрали 10 авторов, запустили 40+ постов в месяц и выстроили живое сообщество. Но главная цель — стать точкой сбора для всех PHP-разработчиков — пока не достигнута.
Поэтому принято решение: основной чат теперь бесплатный.
Внутри — анонсы и превью от всех авторов, общие обсуждения. Темы закрывают всё: от асинхронного PHP и типизации до рефакторинга legacy, Laravel, IDE-инструментов и AI в разработке.
Авторские чаты с полным контентом и прямым общением остаются платными — 150₽/автор или все 10 за 1 200₽.
Если ты пишешь на PHP — заходи: @phpeople_community
👍8🔥7👏5
Приет. Продолжаю тут посты про молодых лидов.

Итак, допустим, ты новый лид в команде. Или лид в новой команде. Или просто лид, который начал смотреть на процессы чуть шире своей личной зоны ответственности.

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

Это почти всегда плохая идея.

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

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

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

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

И здесь есть ещё одна важная ловушка, о которую часто бьются уже сами лиды.

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

У лида всё иначе.

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

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

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

Поэтому вывод простой.

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

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



Давайте оставаться на связи ☄️
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥9👏31
Когда говорят про cache miss rate, его часто подают как отдельную метрику: вот есть hit rate, вот miss rate, следите 🙄. Но сама по себе эта цифра не так интересна, пока ты не связываешь её с задержкой системы.

Гораздо полезнее смотреть на miss rate через такую модель:


AverageTime = CacheAccessTime + DbAccessTime * CacheMissRate


Это не идеальная формула на все случаи жизни, но она очень хорошо объясняет, почему даже небольшой рост miss rate может довольно больно ударить по latency.

Что тут означает каждая часть:
- CacheAccessTime — сколько стоит попытка прочитать данные из кэша
- DbAccessTime — сколько стоит сходить в базу, если в кэше данных нет
- CacheMissRate — доля запросов, которые не нашли данные в кэше
- AverageTime — ожидаемое среднее время доступа к данным

Идея такая: каждый запрос почти всегда сначала идёт в кэш. Значит цену доступа к кэшу мы платим всегда. А вот цену похода в базу мы платим только на той доле запросов, где произошёл miss.

Например:

- CacheAccessTime = 2 ms
- DbAccessTime = 50 ms
- CacheMissRate = 0.1

Тогда:
AverageTime = 2 + 50 * 0.1 = 7 ms

На первый взгляд всё выглядит неплохо. Среднее время доступа — всего 7 мс. Но теперь увеличим miss rate всего лишь в два раза:
- CacheMissRate = 0.2

Получаем:
AverageTime = 2 + 50 * 0.2 = 12 ms

Miss rate вырос на 10 процентных пунктов, а среднее время выросло с 7 до 12 мс. То есть почти в 1.7 раза.

И вот в этом главный смысл метрики.

Если путь после miss дешёвый, система переживёт это спокойно.

Если после miss начинается тяжёлый SQL, сетевой поход в другой сервис, агрегация или чтение большого объёма данных, даже небольшой miss rate становится очень неприятным.

Почему это вредно в проде?

Во-первых, растёт latency.
Чем больше miss rate, тем больше доля запросов уходит в более дорогую ветку. Среднее время ответа начинает расти даже тогда, когда сам кэш работает быстро.

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

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

То есть miss rate вполне может быть триггером полноценной аварии.

Как его посчитать?

CacheAccessTime и DbAccessTime мы можем легко узнать просто засекая время, AverageTime нужно смотреть в метриках вашего latency. А дальше чистая математика.

Тут мы уже можем посчитать сколько раз мы не попали в кеш в абсолютных числах:


CacheMissRate = misses / (hits + misses)


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

Важно вот ещё что: сам по себе miss rate без контекста почти бесполезен.

Одно дело 10% miss rate при дешёвом запросе по индексу.

Совсем другое — 10% miss rate, когда один промах запускает тяжёлый join на большую таблицу.

Поэтому смотреть на miss rate нужно не в отрыве, а тольк вместе с ценой промаха.

Допустим:
- CacheAccessTime = 1 ms
- DbAccessTime = 200 ms

Тогда:
- при miss rate = 1% среднее время будет 1 + 200 * 0.01 = 3 ms
- при miss rate = 5% уже 1 + 200 * 0.05 = 11 ms
- при miss rate = 10% уже 1 + 200 * 0.1 = 21 ms

Из-за чего miss rate обычно растёт?

Частые причины такие:

- слишком маленький TTL
- агрессивная инвалидация
- плохая схема ключей
- eviction из-за нехватки памяти
- cold start после рестарта
- cache stampede, когда много запросов одновременно пробивают один и тот же протухший ключ

Что с этим делать?
Не нужно поднимать hit rate любой ценой.

Хороший порядок такой:

1. Измерить CacheMissRate.
2. Измерить CacheAccessTime.
3. Измерить реальную цену fallback-пути, то есть DbAccessTime или шире — backend access time.
4. Посчитать ожидаемый вклад miss в latency.
5. Найти самые дорогие ключи, use case или endpoint’ы.
6. Уже потом решать: менять TTL, схему инвалидции, модель ключей, прогрев, защиту от stampede или вообще стратегию кэширования.
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍16🔥95
Привет. Я тут снова про ИИ. 📱

А вам всё ещё кажется, что модели недостаточно умны? Или что модели недотягивают чтобы делать твои задачи?

Я так не думаю. У современных моделей очень обширные возможности. В реальности, большинство ограничений лежит в навыках конкретного разработчика планировать и ставить задачу под LLM.

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

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

Данил Щуцкий, например, для подобных целей сделал Ai Factory — инструмент для построения воркфлоу для разработки. Я же собрал свой ворклфоу самостоятельно и дорабатываю его от задачи к задаче, делая его надёжнее и лучше.

В общем, это заход на наш второй AI workshop. Скажу прямо, воркшоп не для новичков. На нём мы расскажем и покажем как построить свой workflow, как работать с оркестрацией, субагентами, как работать с MCP и создавать собстенные.

👉 За подробностями заходите сюда!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11👍4👏2
Приветик!

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

Проблема:
У нас есть некоторая доменная сущность Order, она же заказ. Со временем она неизбежно обрастёт разными "последствиями": обновить скидку клиенту, когда заказ выполнен, отправить сообщение, когда заказ передан в доставку, переслать заказ в CRM и т.д. Знакомо? Уверен, что да.

Пока завязок не так много, всё идёт хорошо. Потом простыня из этих последствий разрастается. Кто-то ещё умудряется и всякие условия выносить. Типа

if ($orders->isPaid())
{
$this->emailService->sendNotification();
}


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

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

В коде обычно это выглядит так:


$event = new OrderPaidEvent($orderId);
$this-eventDispatcher->dispatch($event);

....

final class OrderPaidHandler implements EventHandler
{
public function handle(DomainEvent $event): void
{
}
}


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

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

Возвращаясь в начало, в чем же был предмет нашего спора? В том, где должны располагаться "последствия" события, которые работают в слое приложения. Стригерило меня предложение доменную логику ловить в хандлере, а логику пиложения (типа отправки имейла) оставлять рядом с самим триггером. Я вижу в этом проблему: код расползается, часть логики оформлена одним образом, часть другим. Это делает поддержку дороже, вход в приложение нового разработчка — сложнее.
Да и для ИИ это тоже проблема. Нужны какие-то понятные критерии, чтобы объяснить своему ИИ джуну, что нужно ложить рядом, а что в хандлер заворачивать. Короче, наш путь это единообразие.



Давайте оставаться на связи ☄️
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍4👏2
Всем привет!

Я несколько раз выступал на Podlodka PHP Crew (записи публиковал в канале), но в этот раз хочу просто рассказать о том, что совсем скоро будет очередной сезон.
Каюсь, я давно уже не пишу код на php, но всегда слежу за стеком и обновлениями. Я думаю, что все уже заметили насколько сильно изменился стек современного php разработчика. И вот, ребятки из Podlodka PHP Crew собрали онлайн-конференцию «Современный стек PHP-разработки», чтобы разобраться, как всё устроено сегодня.

🗓С 20 по 24 апреля участники:

• изучат, как сегодня запускают PHP-приложения
(worker mode, новые рантаймы, FrankenPHP),

• посмотрят, как изменилась инфраструктура и что пора выкинуть из Docker-стека,

• обсудят, как реально применять AI-агентов
в разработке (не только писать код, но и расследовать баги и планировать изменения),

• разберут практические кейсы (например, в онлайн-режиме будут запускать мультиплеерную игру на PHP с Temporal и RoadRunner),

• и в целом поймут, какие инструменты и подходы действительно стоит внедрять в 2026.

Формат — пять дней живых Zoom-сессий по утрам и вечерам, закрытое комьюнити в Telegram и общение со спикерами.

Если хотите обновить свой стек и лучше понимать, куда движется разработка на PHP — обязательно присоединяйтесь👇

🎟
Подробности и билеты
По промокоду php_crew_8_7PT0Qe получите сикду🎁


⚠️По традиции, я разыграю один белетик среди подписчиков. Думал как и придумал (но не сделал). По этому разыграю среди тех, кто прокомментирует эту публикацию и, конечно, будет подписан на канал. Итоги подведу 18.04 т.е. в субботу 💚
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥32👏2
Привет.

Хочу снова коротко рассказать про подготовку к system design interview.

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

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

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

После этого я собрал себе небольшую шпаргалку в Obsidian и какое-то время реально на неё опирался.

Потом появилась мысль дособрать её в более цельный материал. В итоге из личной заметки вырос гайд по подготовке к system design interview: с опорой на структуру ответа, набор типовых компонентов, паттерны, контрольные вопросы и ориентиры, которые помогают не рассыпаться по дороге.

Сейчас я его ещё докручиваю и обкатываю.

Если у вас впереди system design interview или просто хочется привести знания в более собранный вид, пишите в личку, буду рад помочь!
👍13🔥10👏4
Всем привет!

В прошлом году, я давал интервью про себя и рассказывал про то, как попал в IT и вообще. Делился с вами, что не умею и не люблю давтаь интервью и говорить о себе. Мне проще поумничать о чём-то.
А не так давно, меня позвали на подксат @psyvit тоже порассказывать про себя. И мне понравилось. Было душевно и лего. Обсудили культ "сильного лида", боязнь ошибок, важность быть честным и открытым с командой и, конечно же, как выжить молодому лиду.
Послушать можно тут.
🔥6👍3👏2
Как я не запустил свой стартап, но прокачался в AI-кодинге

Периодически вижу ролики в духе: «человек без технического бэкграунда за вечер собрал стартап с помощью AI».

Выглядит эффектно, но я таким историям не очень верю.

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

В какой-то момент я тоже решил попробовать сделать небольшой продукт.

У меня давно была идея сервиса для ЖКХ-квитанций. Я не люблю вручную разбирать платежки, сравнивать показания, искать, почему сумма выросла, и вспоминать, что было месяц назад.

Хотелось сделать простой сценарий:

сфоткал квитанцию → прогнал через OCR → получил JSON → увидел графики, изменения и короткое объяснение.

Под это я даже написал и выложил в open source библиотеку для работы с Yandex OCR.

Дальше всё пошло ожидаемо криво.

У квитанций нет нормального единого формата. В одном файле таблица читается нормально, в другом съезжает разметка, в третьем OCR путает поля, в четвёртом одинаковые на вид строки означают разные вещи.

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

Зато сам проект оказался хорошей площадкой для экспериментов с AI-кодингом.

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

Сначала я просто сохранял удачные промпты. Потом начал оформлять их как скилы. Потом стало понятно, что один скилл не должен пытаться делать всё сразу.

Так постепенно появился набор:

— скилл для архитектурного решения по задаче;
— скилл для проектирования API и генерации OpenAPI-спеки;
— скилл для выделения доменной модели;
— скилл для декомпозиции большой задачи;
— скилл для проверки результата через quality gates;
— скилл для поиска нарушения границ и архитектурных расхождений.
— и другие.

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

Самое интересное началось, когда я дошёл до тестирования скилов.

Например, тестовый сценарий может выглядеть так:

{
"skill": "review-architecture-boundaries",
"mode": "should_trigger",
"query": "Review this diff against the architecture baseline for boundary violations and DTO leakage.",
"expected_reason": "Boundary review against an existing baseline."
}


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

Получается почти TDD для AI-скилов.

В итоге сервис для квитанций я не запустил.

Но за время разработки собрал нормальный практический опыт по AI-кодингу: скилы, декомпозиция, оркестрация, quality gates, тестирование и работа с агентом на проекте, где есть архитектура, API, доменная модель и код.

Этим и хочу поделиться на воркшопе.

Разберём:

— как проектировать скилы под реальные задачи разработки;
— как дробить большую задачу для агента;
— как собирать workflow из нескольких скилов;
— как уменьшать галлюцинации и несостыковки;
— как проверять результат через quality gates;
— как тестировать поведение скилов;
— как встроить всё это в обычную разработку.

Если тема близка — регистрируйся.

Скоро стартуем 🔥
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8👍5👏3
Приветик!

В блоге у Мартина Фаулера вышла статейка про ИИ кодинг, подход называется Structured-Prompt-Driven Development.

SPDD — это подход к разработке с AI-ассистентами, где промпт перестаёт быть одноразовым сообщением в чат.

Промпт становится полноценным артефактом разработки:

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

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

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

SPDD как раз про этот разрыв.

В статье предлагается REASONS Canvas — структура для подготовки промпта:

Requirements — требования и Definition of Done;
Entities — доменные сущности и связи;
Approach — выбранный способ решения;
Structure — место изменения в системе;
Operations — конкретные шаги реализации;
Norms — инженерные правила;
Safeguards — ограничения, которые нельзя нарушать.

Перед генерацией кода мы явно собираем контекст, в котором модель должна работать.

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

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

У меня это оформлено не как REASONS Canvas, а как набор скилов и оркестратор:

— скилл для анализа задачи;
— скилл для архитектурного решения;
— скилл для проектирования API и OpenAPI-спеки;
— скилл для выделения доменной модели;
— скилл для декомпозиции задачи;
— скилл для проверки quality gates;
— скилл для поиска DTO leakage, нарушения границ и архитектурных расхождений.

Плюс тесты для самих скилов.

У Фаулера это описано как structured prompts, REASONS Canvas, version control, review, safeguards и quality gates.

В моём workflow — скилы, архитектурный baseline, оркестратор, проверки границ и тестовые сценарии.

Разные реализации, но идея одна: AI-кодинг нужно вытаскивать из режима «поболтал с моделью и получил diff» в нормальный инженерный процесс.

Именно про это будет наш воркшоп.

Кстати, продажи уже открыты, сам воршоп пройдёт 5️⃣ мая! 🔥

Если хочешь разобраться в AI-кодинге на уровне инженерного процесса, а не набора удачных промптов — регистрируйся в боте. 🎟
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8👍5👏3
Last Call 📞

Привет. Ребята, сегодня в 19-00 стартуем наш воркшоп по АИ кодингу!

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

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

Вот тут программа воркшопа и все подробности. Увидимся!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8