Организованное программирование | Кирилл Мокевнин – Telegram
Организованное программирование | Кирилл Мокевнин
12.6K subscribers
73 photos
304 links
Как из джуниора дойти до мидла, а потом и до синьора
Ютуб https://youtube.com/@mokevnin
Связь для предложений: @kirillpublic
Download Telegram
Выпуск про Хаскель (с лайвкодингом) выйдет завтра, а сегодня я хочу поделиться соообщением Ростислава (подписчика), которое он вчера написал. Именно ради такого эффекта я делаю то что делаю. Безумно рад таким кейсам:

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

Особенно спасибо за выпуски про VictoriaMetrics и Злых Марсиан. Спустя десяток подкастов именно они до меня достучались и я осознал, что можно прийти в open source

Я лет 5 пытаюсь построить свои SaaS'ы. В мае решил попробовать свои навыки для open source'а и в июне я выпустил https://postgresus.com (GitHub) для резервного копирования PostgreSQL

За полгода проект вырос до ~3к звёзд, ~45к Docker pull'ов и оказался востребованным (очень много фидбека). Теперь хочу сделать Postgresus лучшей бекапилкой PostgreSQL в мире 🦦

Несколько дней назад как раз выложил статью на Хабр про версию 2.0 - https://habr.com/ru/articles/974492/

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

Тем более у меня немного маркетинговое искажение: я стараюсь делать удобно с точки зрения UX и DevEx - а это непаханное поле в open source'e

В общем, спасибо вам большое, что стараетесь для таких, как я! Если бы не вы, этого проекта бы не было

p.s. Если у вас происходят подобные сдвиги, обязательно пишите! Можно прямо тут в комментах

Ссылки: Телеграм | Youtube | VK
5🔥142👍4326🤡2🤔1
Хаскель! Ура, долгожданный выпуск 🙂

В гостях у меня снова Александр Вершилов. Мы час говорили про хаскель, фп и влияние на разработку, а потом, решили попробовать лайвкодинг, чтобы наглядно показать, в чем его прелесть и почему им стоит заняться хотя бы для общего развития. https://www.youtube.com/watch?v=AHpmdGVYSZo&lc=Ugw1wWGR7A6q3tyUc9t4AaABAg Максимально рекомендуется всем, кто хочет стать более крутым инженером

Альтернативные ссылки: Аудио | vk
👏40🔥29👍7🥰75👎1🤔1🤡1
Async Jobs (Background Jobs)

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

Буквально в каждом не тривиальном приложении, уже на старте, появляется задача выполнять какие-то задачи асинхронно. Самое простое - отправка писем после регистрации. Почему этого нельзя делать там же где делается регистрация? Отправка письма это почти наверняка взаимодействие с внешним сервисом по api или smtp. А это сеть со всеми вытекающими от задержек до ошибок. Ваши пользователи будут регулярно получать тайматы и ошибку 500. Сразу встает вопрос транзакционности и гарантий. Что в таких ситуациях делать?

Первое, что приходит на ум, это выполнять отправку в памяти, но отдельно. Такие механизмы иногда предоставляются самим фреймворком (async в spring boot), либо это можно организовать самому (nodejs, go). Для не критичных вещей, когда нет нагрузок и особых рисков, можно и так, но этот подход быстро упирается в потолок. Что не так?

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

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

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

Короче, по середине между двумя этими подходами и затесались background jobs. Это механизм, позволяющий выполнять любые задачи асинхронно в отдельном процессе с персистентностью (а значит гарантиями) и возможностью масштабировать. То есть их можно запускать хоть на другом сервере и в любом количестве экземпляров. Чем это отличается от работы через очереди спросите вы? Отличается и вот в чем. Для начала пример в python (celery). Определение джобы:


# tasks.py
from celery import shared_task

@shared_task
def send_welcome_email(user_id, email):
send_email(email)


Использование:


# registration.py
from tasks import send_welcome_email

def register_user(email):
user = create_user(email)
send_welcome_email.delay(user.id, user.email)

return user


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

Реализации джоб есть в каждом языке. Какой либой пользуетесь вы?

Ссылки: Телеграм | Youtube | VK
1👍6519🔥10🥱3👎1🤔1
Как я потерял 5000$ на авиабилетах

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

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

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

Буквально через две недели пришли паспорта для меня и жены. Нам дали визу на 73 дня, что было точно по плану. А вот на детей не пришли. Примерно в те же дни я получил письмо (и может звонок, не помню уже), где мне сказали, что детей надо сфоткать и для их свидетельств о рождении нужны апостили (каждый стоит 120$). Я тогда слегка офигел, потому что мы заплатили деньги за помощь в оформлении, а они в итоге поставили нас в такую ситуацию. Фотки еще ладно, мы просто теряем время на поездках (туда ехать час), а вот апостиль это уже не так просто. Его надо заказывать и ждать.

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

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

Продолжение в комментах, потому что пост получился длиннее чем разрешено в телеге =>

Ссылки: Телеграм | Youtube | VK
😱54👍1514😢5🤮5👎4👏1🤣1🤪1
Если вы еще не подрубили chrome mcp (https://github.com/ChromeDevTools/chrome-devtools-mcp) к своему проекту, то самое время это сделать. С его помощью я тут же смог решить несколько задач по верстке, которые раньше мне не поддавались из-за того, что я местами плаваю в ней + требовался глубокий дебаг включающий в себя и верстку и react и конкретно компоненты Mantine. Теперь эта штука имея полный доступ ко всему творит просто чудеса. Я в шоке.

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

Ссылки: Телеграм | Youtube | VK
👍67🔥1910🤔5💩1
Что означает "порт занят"?

Я как-то совсем стороной обходил все что касается операционок, администрирования и девопса, хотя сказать есть что. Особенно в свете последних собеседований 🙂 Открою эту рубрику постом про занятые порты.

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


Error: bind() to port 5432 failed: Address already in use


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

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

Когда серверное приложение стартует, оно создаёт сокет и привязывает его к конкретному порту (и ip). Этим оно сообщает операционной системе: «все соединения, пришедшие на этот порт, передавай мне». Если в этот момент порт уже занят другим процессом, операционная система не может создать второй сокет на тот же порт и возвращает ошибку Address already in use.

С этим разобрались. Что теперь делать?

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

Если для нас это сюрприз, то для начала надо посмотреть, а что там вообще запущено? Есть много способов, самый простой и универсальный:


lsof -i :5432 # может понадобиться sudo

com.docke 1682 user 241u IPv6 0x6373ba4a2a38037e 0t0 TCP *:postgresql (LISTEN)


Видим, что порт держит процесс с PID 1682. Возникает логичный вопрос: просто убить его через kill? Это почти всегда неправильный ответ. В реальных системах серверные приложения обычно запущены не вручную, а как сервисы. Это означает, что процесс был стартован менеджером сервисов, может автоматически перезапускаться, и его нужно останавливать тем же способом, каким он был запущен.

Для начала имеет смысл посмотреть, как именно был запущен процесс. Это можно сделать через ps -fp 1682. Если в команде запуска видно что-то вроде postgres, redis, nginx и так далее, то с большой вероятностью это сервис, а не разовый процесс.

На Linux такие вещи чаще всего управляются через systemd. В этом случае имеет смысл проверить статус сервиса, например systemctl status postgresql, и остановить его корректно командой sudo systemctl stop postgresql.

На маке серверные приложения часто ставят через Homebrew. Там можно посмотреть список сервисов командой brew services list, а затем остановить нужный сервис через brew services stop postgresql.

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

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

p.s. Ребят нужен такой контент (лайкните если да)? Я знаю что для многих это довольно базовый уровень, но с другой стороны, немало и тех, кто с операционками на вы.

Ссылки: Телеграм | Youtube | VK
👍50082🔥28👎6😨4🤯3🥱2🤔1👌1
Традиционные результаты года

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

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

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

Всем чмоки, увидимся в следующем году (а завтра я уже записываю новый выпуск для подкаста)

p.s. Если у вас есть истории про то, как канал повлиял на ваши убеждения/код который вы пишите/подходы которые вы используете, то было бы классно -) Поделитесь плс
👍4224🔥18🎄7🤔1
Иификация. Чем дальше, тем больше ии интегрируется в мой процесс разработки и уже появился какой-то набор паттернов, которыми я бы хотел поделиться. В этом посте поделюсь сетапом, а в будущих уже расскажу подробнее про эффективное использование

1. chatgpt всегда остается когда надо просто поговорить. Причем сейчас он может работать в агентском режиме, к нему можно подключить репозитории и всякое другое
2. Для работы над кодом codex и copilot в терминале отдельно от редактора.
3. В редакторе автокомплит + nes (next edit suggestion). Тут есть небольшое ограничение самого nvim, которое не позволяет делать многострочные nes, но это поправят буквально в следующей версии, которую я очень жду
4. Немного экспериментирую с автоматическими пулреквестами copilot и даже парочку принял. Но чего-то серьезного там не сделать без постоянного контроля и направления, поэтому пока отложил до лучших времен

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

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

Что касается автокомплита, то к нему конечно надо привыкать и не жать его сразу, потому что часто не та логика. Но правильной логики достаточно много, чтобы не хотеть вырубать этот механизм. Особенно когда речь идет про использование каких-то библиотечных механизмов, которые надо изучать, чтобы правильно использовать. А тут тебе уже сразу дают варианты использования. Ну и собственный код тоже неплохо помогает дописывать, особенно если он типизирован. То есть чем ближе к строгости и простоте, тем лучше подсказки. Вангую что для go это вообще работает все идеально. Очень круто в джаве и ts. В Ruby хуже, но после того как мы начали активно внедрять типизацию с Sorbet, то качество подсказок резко выросло, да и работать стало сильно приятнее.

Ну и NES. Что-то подобное еще до ИИ делали IDE от JetBrains, они пытались угадать следующие изменения и предлагали их, даже если по коду прямой связи не было, например могли подсказать что надо поменять название теста. Сейчас же, все эти штуки, причем универсально, а не под конкретные кейсы, делает NES (что кстати значительно приближает редакторы к платным фичам jetbrains). Меняешь что-то, что не делается стандартным рефакторингом, а оно уже говорит тебе что может поменять все остальные варианты. Эта фича, конечно, прорыв в области работы с кодом. Есть тут свои конечно особенности с тем как она возникает и иногда мешает, но думаю доведут до ума и руки перестроятся. Без нее уже не могу работать.

Ну и непосредственно кодинг в консоли. Кодекс развивается семимильными шагами, как консольная утилита, его интерфейс и возможности на голову выше чем у стандартного copilot. Например сейчас появилась возможность запускать что-то в бекграунде, а это позволяет стартовать сервисы прямо внутри, чтобы иметь прямой доступ к логам (если они идут в stdout) и ошибкам старта. Значительный буст в качестве дало подключение devtools mcp, фронтенд просто стал щелкаться как орехи там где мне не хватало знаний верстки. Если прямо сейчас идет какая-то работа, то codex не блокирует ввод, ему можно накидать каких-то дополнений и уточнений. И такого разного ux удобного там много.

p.s. А какой у вас сетап?

Ссылки: Телеграм | Youtube | VK
1👍6117💩17🔥9🤯2🤔1
Переключение контекста в программировании. Работать только над фичами утомляет и в течение дня иногда хочется переключиться или просто голова не особо варит, а делать полезное хочется. Куда и как можно переключиться? Вот что работает в моем случае. Для начала, какие типы задач я выделяю (в моей практике):

- UX/UI. Дизайн, удобство, отзывчивость и любые фронтовые правки
- Обновление зависимостей (люблю я это дело)
- Типизация. Добавление типов (нам в ruby актуально), оптимизация типов и т.п.
- DX. Тут и скорость работы инструментов (сборка, тесты и т.п.) и CI и разворачивание проекта
- Kubernetes. Сам по себе отдельно, как инфраструктурная единица
- Инфраструктура. Сюда относятся облака, хостинги и terraform для этого добра
- Покрытие и тесты. Тесты всегда можно дописать
- Массовые тупые рефакторинги. Когда надо бы поправить весь код, но обычно не доходили руки, а тут ИИ, который может сам если его попросить
- Посидеть над беклогом и поотвечать в тикетах :)

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

А у вас какие фишки для переключения в разработке?

Ссылки: Телеграм | Youtube | VK
50👍38🔥8💩5🤔1
Популярность Tailwindcss убила бизнес ее создателя

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

На днях ему пришлось уволить 3 из 4 разработчиков работающих над проектом. Денег осталось на 6 месяцев (с учетом падающего входящего потока) и дальше он пока не придумал что делать.

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

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

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

Ссылки: Телеграм | Youtube | VK
2😭46👍40😱17136😁2🤔1🥴1😍1
Задачка про события

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

Ссылки: Телеграм | Youtube | VK
🤔14👍64👎2
История про пулреквест

Есть такая софтина https://www.dittofeed.com/ которая нужна для crm-макретинга (email рассылок и т.п.) Таких решений довольно много и честно говоря стоят они немало. Поэтому попрыгав по разным сервисам, мы в конце концов пришли к тому, что ладно, пусть будет меньше функций, но зато open source, который можно поставить к себе если что. Дитофид как раз оказался таким решением. Не единственным, но помимо подходящей функциональности я обращаю внимание на технологии и перспективы. В данном случае там юзаюется как по мне очень неплохой сетап на ноде (ts + drizzle + fastify).

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

Мы буквально сразу бахнули ишюс, с описанием проблемы и мейнтенер окнул, сказал норм идея https://github.com/dittofeed/dittofeed/issues/1718 Ну и с тех пор прошло больше трех месяцев без какого либо движения. А буквально неделю назад на выходных, я зашел посмотреть как там дела и подумал, а чо бы не попробовать copilot прямо в авторежиме на гитхабе, благо он у меня оплачен. Форкнул, запустил и через 15 минут получил готовое решение. Кода там было немного и по моим ощущениям все было сделано правильно, хотя проект я не запускал. Отправил пулреквест и через буквально несколько дней мне отписался чувак со словами, что все классно, только ошибки линтера поправь. Я еще раз попросил copilot накинуть фикса и стал ждать. И вуаля, вчера пулреквест слили, а я не написал ни строчки кода

Ссылки: Телеграм | Youtube | VK
👍115🔥32🤣22🤡1211👎5😢4🤔1😱1🤝1
по сути же получается нужно меньше разработчиков сейчас? Интересно как это выглядит с точки зрения владельца бизнеса

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

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

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

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

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

Как говорится селяви :)

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

Ссылки: Телеграм | Youtube | VK
👍9129🔥9🤔3💯2👎1
Кейс про ии, n+1 и orm

Все опытные бекендеры так или иначе знают, что sql-запросы в цикле это зло. Но даже если их явно не делать, то они все равно будут появляться при использовании ORM. Например мы извлекаем какую-то связь, а затем генерируем json по этому набору данных, попутно вызывая какие-то вложенные связи: user.companies().map((company) => company.creator()). В этом примере сами компании будут извлечены одним запросом, но обращение к creator() породит цепочку запросов, по запросу на каждую компанию. В миру эта штука называется select n + 1

Кто-то скажет что фу, orm зло, потому что там есть такая проблема. Я к этому отношусь не так, orm позволяет быстро двигаться вперед, а n+1 обычно чинится очень просто, за счет механизмов подгрузки связей в orm. Например так: user.companies.includes(:creator).map.... Несмотря на это, у нас на Хекслете действительно десятки мест где такая проблема есть. Чаще всего она не критическая, поэтому мы чиним по мере появления проблем.

Хорошая новость заключается в том, что если у вас ORM, то возможно написать инструмент, который будет находить n + 1 самостоятельно почти для всех ситуаций. Так как мы пишем на Rails, то используем гем Bullet, который добрые люди написали довольно давно как раз под эту задачу. Он не просто показывает где n+1, но конкретно говорит как его убрать:


user: kirillmokevnin
GET /programs/algorithms-extended
USE eager loading detected
Stack::Landing::LearningModule => [:project_cover_attachment]
Add to your query: .includes([:project_cover_attachment])
// тут еще стек вызовов для удобства


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

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

> Запускай тесты по очереди, исправляй исключение n+1 (bullet) по рекомендации. Если тест после этого снова не проходит, переходи к следующему

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

Ссылки: Телеграм | Youtube | VK
1👍7416🔥9🤡4🤔2
Как организовывать событийную архитектуру

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

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

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

Доменные события

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

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

```ruby
# выполнили регистрацию и делаем событие
data = { user_id: user.id }

event = UserSignedUpEvent.new(data:)
EventSender.publish_event(event)
```

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

Отправка событий

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

А вот сама отправка это интересно. Если действовать в лоб, то мы бы взяли sdk сервисов, которые нам нужны, например posthog для продуктовой аналитики, mailchimp для crm-маркетинга и т.п. Больше сервисов, больше интеграций, больше трансформаций данных под конкретные системы с их собственными принципами работы.

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

Ссылки: Телеграм | Youtube | VK

p.s. Не хватило места, последнее разберу отдельным постом
1👍2819🔥5🤮2🥱1🦄1
Откуда ии будут брать контент для обучения?

В индустрии циркулирует страх, что люди перестали обсуждать код на публичных площадках, stackoverflow почти умер, что будет дальше? Хорошая новость в том, что все это есть на reddit, но дело даже не в этом. Я сегодня наткнулся документ для llm, который описывает лучшие практики, паттерны и описание команд (по сути api) для работы с редисом redis.antirez.com

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

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

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

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

Ссылки: Телеграм | Youtube | VK
1👍45👎41🤔5🤮54💩4🔥3