Организованное программирование | Кирилл Мокевнин
12.9K subscribers
76 photos
317 links
Как из джуниора дойти до мидла, а потом и до синьора
Ютуб https://youtube.com/@mokevnin
Связь для предложений: @kirillpublic
Download Telegram
Forwarded from Хекслет
Пока все спали мы переехали с intel машин на amd. Скорость загрузки сайта выросла от 30 до 50 процентов. На подавляющем большинстве страниц скорость загрузки с выключенным кешом меньше 500мс (было до секунды)!

Вы заметили ускорение?

Telegram | YouTube | Сообщество
🔥82👍20🤔9👏53🤮3👎2🏆1
Как я разлюбил динамическую типизацию. В профессиональную разработку я вкатился через PHP 4 версии, который не просто был динамическим языком программирования, он даже языком то мог назвать себя с натяжкой, формально да, но это был такой продвинутый шаблонизатор. Потом был php 5, который вобрал в себя ООП модель Java, что сделало программирование очень похожим по стилю и способу организации программ.

На тот момент, да и десяток лет до этого, динамические языки полностью захватили веб. Началось все с Perl, потом PHP и наконец Ruby с Python. Даже сейчас подавляющее большинство сайтов реализовано на PHP. Дешевый хостинг, огромное количество CMS и конечно же фреймворков. Тогда фурор произвели Rails, на котором не только начинались все стартапы, но и он стал прототипом для большинства фреймворков на других языках.

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

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

Где-то там же активно рост jquery и javascript превращался из языка для снежинок, в инструмент добавления интерактивности. Кто не помнит, gmail с его прорывной на тот момент концепцией не перезагружать страницы (это было реализовано через фреймы), очень сильно бустанул все это направление.

Время шло, размеры проектов становились все больше и разработчики стали задумываться о том, что неплохо было бы иметь все тоже самое, но в типизированном окружении или на типизированном языке. Когда в проекте миллионы строк и тысячи программистов, все эти хуякхуяк на js и php становились очень проблематичными. Например фейсбук реализовал язык Hack, типизированное надмножество PHP, который отличался конечно, но им было значительно проще перейти на него, чем переписывать проект. Аналогичный путь выбрал vk, развивая собственные инструменты статического анализа и ограничения поверх PHP. В корпоративном сегменте Java окончательно закрепилась через Spring MVC и позже Spring Boot. В Microsoft-стеке аналогичную роль играл ASP.NET MVC, который активно противопоставлялся скриптовым подходам PHP и Ruby.

Я как и масса разработчиков по всему миру смотрел на это довольно скептически. Мы видели какими монструозными были эти решения, насколько типизация заставляла писать больше шаблонного кода и когда простые задачи превращались во что-то невообразимо сложное. В самих языках не было ни вывода типов, ни алгебраических типов данных (мы про популярные языки) ни других ништяков. В эти годы были популярны батлы и срачи на тему статика vs динамика. Масла в огонь подливали Erlang и Clojure vs Haskell. Хотя писали на них не часто, но зато срались знатно.

Конечно одна из причин, была в том, что далеко не все работали в гигантских проектах. Проекты в которых работал я, ну сотни тысяч строк кода, но не миллионы. До сих пор, многие кто работают с таким объемом не признают статику.

А потом появился TypeScript, который сначала медленно, а потом все быстрее начал захватывать разработку. Для меня это стало переломным моментом, хотя далеко и не сразу. Первый раз для веба, я увидел, что типизация может быть удобной. Сначала мы переписали на TS весь наш JS, потом мы перешли (и щас в процессе) на типизированный Ruby. Теперь динамика в моей жизни осталась только на lua в конфигах вима 🙂

Telegram | YouTube | Сообщество
1👍7118🔥11👎7🤔2🎄21
Наставил скилов для реакта и web performance и гоняю теперь. Я подофигел когда он lighthouse из терминала начал запускать. Никогда еще оптимизация под веб (performance, seo, accessibility, core vitals) не была таким увлекательным занятием

Кому интересно, вот они: https://github.com/vercel-labs/agent-skills и https://github.com/addyosmani/web-quality-skills

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

p.s. Какие скилы вы юзаете и они вам сильно помогают?

Telegram | YouTube | Сообщество
👍52🔥2816🤮9🥱5🤯2👀1
Как я поставил на поток генерацию SDK

Значит к делу. У нас в Хекслете немало разных интеграций внутри кода, начиная от управления docker на других машинах (для практик), до создания заявок в AmoCRM. И для многих из них нам приходится писать небольшие (а иногда большие) обертки над их апишкой, потому что sdk для их сервисов либо нет, либо они устарели. А иногда sdk есть, но только для одного-двух языков. Короче беда, особенно этим страдают русскоязычные сервисы, где даже дока по api какой-то колхоз где все примеры на php. Я понимаю почему так было изначально, когда весь рунет был на пыхе, но елки палки, с тех пор десяток лет прошел.

На выходных психанул и решил покончить с этим. План был прост, закидываем доку в codex и просим на его основе составить typespec, который потом генерирует openapi спеку, которую я потом закидываю в какой-нибудь генератор sdk. Быстрое гугление показало, что есть опенсорсный генератор с поддержкой ruby, но он не делал типизацию (в ruby Sorbet) поэтому продолжил поиски и нашел сервис stainless, с которым забегая вперед все получилось.

Почему не сразу openapi? Typespec это продукт майкрософта. Он позволяет описывать openapi спеку на языке похожем на ts, с линтерами, компилятором и вот этим всем. Затем все это добро можно превратить не только в openapi спеку, но и сразу из него сделать готовые библиотеки. К сожалению ruby пока там нет, поэтому вместо простого typespec => sdk, получилась схема typespec => openapi => stainless.

Начал я с AmoCRM, в котором размер апи мама не горюй. Причем дока местами неточная, поэтому я добавил туда единственную официальную sdk на PHP. Закинул это все в codex и попросил собрать typespec. Суммарно весь процесс занял около часа и на выходе я получил тысячи строк (выходной openapi spec >8 000 строк). Все это лежит в отдельной репе, через которую генерируются sdk.

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


require "bundler/setup"
require "amocrm"

amocrm = Amocrm::Client.new(
token: ENV["AMOCRM_AUTH_TOKEN"], # This is the default and can be omitted
subdomain: "My-Subdomain"
)

response = amocrm.unsorted_leads.create_forms(
body: [{metadata: {}, source_name: "source_name", source_uid: "source_uid"}]
)

puts(response)


Весь процесс шел гладко примерно до этого момента, но когда я уже начал использовать библиотеку, выяснилось, что там есть баг. Для части запросов AmoCRM возвращал application+hal/json чем ломал логику сгенерированной sdk. Агент раскопал, что там был неправильный регексп и сразу его пофиксил пулреквестом в sdk. Ну и чо бы не сказать ребятам о проблеме подумал я и прямо из интерфейса stainless отправил им багрепорт. Какого же было мое удивление, когда на следующий день их бот прислал пулреквест в мою sdk с эти исправлением, но уже официально.

В общем мне это так понравилось, что я решил повторить этот трюк с кучкой других сервисов. И теперь у меня есть openapi схема и sdk для cloudpayments, docker, yoomoney.

Все это открыто и лежит на гитхабе. Можно брать не только готовые sdk, но и спеки.

либа https://github.com/Hexlet/amocrm-ruby
спека https://github.com/Hexlet/amocrm-api

p.s. Если кто знает ребята из этих сервисов, киньте им, пусть заберут себе и выложат на сайте чтоли :)

Telegram | YouTube | Сообщество
🔥68👍2916👎3🙉3🤔1
События, бизнес и CDP

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

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

При этом у каждого такого сервиса свой формат событий, свои обязательные поля, свои ограничения и свои способы интеграции. Один хочет userId, другой работает только с email, третий требует отдельные “e-commerce события”, четвертый не умеет принимать серверные события и живёт только в браузере.

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

CDP (Customer Data Platform) решает эту проблему архитектурно: вы перестаёте интегрировать приложение с каждым сервисом напрямую и вместо этого делаете один стабильный канал событий. Приложение отправляет события в CDP, а уже CDP маршрутизирует их в нужные инструменты: аналитику, CRM, рассылки, рекламные кабинеты, data warehouse, и так далее.

Но дело не только в этом. CDP это не просто медиатор. CDP формирует связку между пользователями и всеми действиями, которые мы отслеживаем. Все это хранится в каком-то warehouse. В нашем случае rudderstack подключен к clickhouse. К которому в свою очередь подключены, например, аналитики, через yandex datalens.

Кто-то мог бы сказать, а чем это лучше какого-нибудь n8n? В отличие от универсальных коннекторов различных сервисов, CDP заточен конкретно под продуктово-маркетинговые задачи. Он встраивается на сайт как универсальная аналитика на фронтенд, бекенд и самостоятельно занимается трекингом, установкой visitor_id связью с user_id. А дальше все это отправляется во внешние системы по заранее сформированному маппингу (с возможностью кастомизации). То есть вы не просто сами настраиваете пересылку, а она уже спроектирована под конкретные связки. Поэтому в большинстве случаев достаточно просто добавить нужный сервис и дальше все работает автоматически.

Пример. Существует спека Ecomerce Events (https://www.rudderstack.com/docs/event-spec/ecommerce-events-spec/) описывающая события, которые понимает примерно одинаково большинство систем. Если отправлять эти события так как описано внутрь CDP, то она сама распознает их и сделает правильный маппинг во внешние системы (https://www.rudderstack.com/docs/destinations/streaming-destinations/yandex-metrica/)

p.s. А как в ваших проектах решается эта задача?

Telegram | YouTube | Сообщество
👍2010🔥4🤮2🤷1
Как я разлюбил динамическую типизацию 2

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

Тайпскрипт в этом смысле изменил многое. Когда стало понятно что он с нами надолго и уже было понаписано немало типов, я в своих проектах стал подключать комментарий @ts-check который дал бесплатную типизацию в js проектах, самого js и либ, где эти типы были прописаны. И все это бесплатно, код не нужно было никак менять.

Затем мне пришлось разбираться с ts по долгу службы, так как запрос вырос и на Хекслете не было соответствующих курсов. Я потратил месяцы на эксперименты и написание разных небольших либ плюс поработал с ts в реакте. Здесь я прочувствовал удобство структурной типизации, возрадовался алгебраическим типам данных и литеральным типам и конечно же выводу типов, без которого меня всегда отталкивали языки типа Java. Сейчас, кстати, уже, хвала богам, все стало прилично.

Где-то там же, стало понятно, что надо весь фронт Хекслета переводить на react (раньше был только кусками), потому что бекендовая шаблонизация начала умирать. Тут удачно появилась inertia.js, которая позволила это делать максимально комфортно. Этот процесс мы стартанули чуть больше года назад и вот вот закончим (в начале марта). Чем больше я работал с этим кодом, тем больше мне становилось некомфортно возвращаться в Rails и особенно шаблоны, где возможности навигации и рефакторинга достаточно ограничены. Да этого сильно больше в больших идехах, но это все заслуга их разработчиков, а не самой экосистемы. Короче не очень надежно и перспективно.

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

В итоге сошлась кучка факторов: упало значение многих фишек rails, потому что шаблонизация уехала в react целиком, разработка стала вестись через агенты, а им нужны типы, ts сильно повысил планку к возможностям которые дает хорошая система типов вкупе с тем насколько это может быть компактным. Последним и решающим фактором стало то, что агенты отлично пишут типы. Первое время с ts я нехило так мучился, когда надо было дописывать сложные типы самому (всякие хитрые дженерики). Как же это упростилось, когда подключилась генерация агентами.

Закончилось это тем, что я подключил к Хекслету Sorbet это статическая система типов, которую очень необычно (в других языках ваще не так сделано) интегрировали в Ruby. А благодаря агентам и ии автокомплиту мы буквально за неделю описали все типами и весь новый код стали писать только с ними. По пути пришлось менять привычки и подходы, за что наверное на меня рубисты посмотрят косо, но местами код стал напоминать java стиль, с явным созданием dto и отказу от dsl там где это можно сделать безболезненно. Метапрограммирования в общем стало меньше (кому интересно, гляньте гем tapioca, который очень помогает)

За это время я полностью трансформировался. Новые проекты я точно буду начинать только на статически типизированных языках. Мой личный топ для типовых веб проектов kotlin, ts, go (только там где по все остальное не подходит). На уровне фреймворков я буду брать spring boot + react. Про это точно будет отдельный пост. Вот такой вот поворот

Telegram | YouTube | Сообщество
👍4022🔥10🫡8💩5😢2
Расходы в штатах. Сколько стоит жить в майами?

Для контекста, мы переехали сюда в 19 году и за это время цены местами выросли в полтора два раза. Когда переехали нас было четыре человека, здесь родили еще одного (первый американец в семье) и теперь нас пятеро. Детям 12, 9 и 2.

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

2000$ - Ипотека (включает в себя налог на недвижку и страховки). И мне повезло, что я ее взял под 2.5% годовых за 230 000$ (127 квадратов) практически на берегу в ковид. Щас цены ваще другие.
900$ - HOA (это комуналка + интернет + обслуживание комплекса, включая бассейн)

Помимо этого в кондо каждый год что-то происходит и собирают деньги на фиксы, недавно качалку восстанавливали после того как ее сожгли, сейчас бассейн ремонтируют, скоро гараж (на тысячи машин) обновляют. Тут доп расходы в год от 1000$ до 5000$ и раз в 10-15 лет могут попросить 20 000$ на капиталку.

250$ - Электричество. Тут даже если уехать не платить нельзя, потому что с выклченным кондеем сразу заведется какая-нибудь плесень и квартире хана. Он работает даже если мы уезжаем.

230$ - Связь. Цена в месяц на одного человека за линию 40, плюс немного устройств

1200$ - Машина в лизинг в месяц. Тут можно было дешевле, долларов на 500$, но очень хотелось поездить на bmw 🙂

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

1300$ - мед страховка на меня с женой. Правда надо понимать что американская страховка на медицину это не 100% покрытие, еще каждый месяц доплачиваем за посещения/лекарства/процедуры сотни долларов (в зависимости от того как часто ходим). Детям с прошлого года стали выдавать medicaid (его в основном дают малообеспеченным, но во флориде иногда включают для всех детей). Иначе еще 1000$ за детей бы добавилось.

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

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

Поехали дальше, переменные расходы

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

1500$ - амазон. Тут все от бытовухи до памперсов и игрушек.

900$ - гимнастика для сына (не каждый день). Забирают прямо из школы (это называется after school, в штатах очень популярно). Еда не входит, кладем ему сами либо можно доплачивать 15$ за прием. Старшая тусует с друзьями, тут экономия 🙂

500$ - кредиты в месяц. В основном техника, обновления телефонов, планшетов и лаптопов

150$ - бензин. Я езжу мало, у нас пешеходный город

100$ - качалка в месяц для жены. Качалка в кондо тоже есть, но она такая, для очень не искушенных

x - женские дела (процедурки как мы любим говорить). Тут не знаю, жена сама решает сколько тратит и когда 🙂

1000$ - просто улетает на всякое, где то ребенок попросил, где-то штраф (один штраф это 150-250), где-то в мол съездили, где-то чайник новый заказали или xbox в ремонт. Услуги в штатах тоже очень дорогие

Опциональные

250$ - любой выезд на выходных куда-нибудь. Как правило на мою семью вход это 100$ на всех плюс прием пищи и перекусы.

Слетать в мексику (как турция для рф) или покататься на круизе (порт прямо тут) выходит где-то 6000$ на неделю.

Ко всему этому прибавляем ежегодные расходы на бухгалтера и налоги (как раз сейчас идет период), которые гуляют от 30% до 40%

Стоит ли оно того? Стоит (но очень нервно)

Telegram | YouTube | Сообщество
😱13437👍29🥴14🤯8🙈7👀6🎉3
Ребят важный вопрос. Если телегу действительно заблочат, то какой план чтобы не потерять друг друга?
😁83🗿65🌚4👻3🔥2👀2💩1🥱1
Отношение к задачам по бизнес ценности

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

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

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

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

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

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

Telegram | YouTube | Сообщество
1👍7316🔥7💯5