Организованное программирование | Кирилл Мокевнин
11.3K subscribers
63 photos
238 links
Как из джуниора дойти до мидла, а потом и до синьора
Ютуб https://youtube.com/@mokevnin
Связь для предложений: @kirillpublic
Download Telegram
Гибкость добавляет сложность или убирает ее?
Когда я слышу что кто, то говорит “у нас очень гибкая система и код”, то меня это скорее пугает. Дело в том что любая гибкость увеличивает сложность. Чем гибче чем сложнее. Почему так получается?

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

Из недавнего опыта. Я искал для проектов Хекслета фронтенд систему, которая позволяет генерировать интерфейсы из готовых элементов в коде, чтобы не тратить время на ручное их написание там, где нам это не нужно. Например нам такое нужно во всех проектах, где делается бекенд, а фронтенд предоставляем мы сами. После изучения вопроса стало понятно что есть два основных решения: https://refine.dev/ и https://marmelab.com/react-admin/ Если посмотреть их документацию, то видно что первое решение более гибкое и например позволяет менять внешний вид так как работает с разными css-фреймворками. Но если посмотреть на код, эта гибкость дается дорого, количество кода, которое надо писать в refine, значительно больше чем в react-admin, где из коробки material который не поменяешь, но зато весь css скрыт на 100%. В итоге я выбрал react-admin, а реализация того что нам нужно составила около 100 строк кода (несколько крудов, аутентификация, связь с бекендом).

Все тоже самое проявляется и на более низком уровне:

⁃ Отсутствие внедрения зависимостей VS внедрение зависимостей (усложняет систему очень сильно)
⁃ Работа с конфигами из файлов VS универсальная штука загрузки конфигов
⁃ Модель с фиксированными полями VS модель с динамическим набором полей
⁃ Active Records VS Data Mapper
⁃ Работа с одной базой данных VS Поддержка любых баз данных (особенно если NoSQL смешивается с SQL)

Все это не значит что гибкость не нужна, но нужно правильно оценивать эту гибкость. Часто она дается настолько дорого, что лучше все же не обобщать. Хорошим примером может служить Java и Spring Boot где все сильно обобщено, есть множество интерфейсов на все случаи жизни, которые все реализуют. Огромная куча абстракций, которую не так то просто выучить. Зато все можно подменить и в теории это работает. С другой стороны находятся фреймворки динамических языков типа Django, Ruby On Rails, Laravel, где шли другим путем, давали готовые решения, которые не такие гибкие, но зато очень простые, легкие в изучении и использовании.

p.s. Какая концепция вам ближе? Spring Boot или Django/Rails/Laravel?
👍29🤔135💯5🐳1
Как нас шантажирует человек, пересмотревший пацанов
> это слито с вашего дырявого сайта...Во шухер будет...удачи чушпаны!!!)))

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

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

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

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

Мы принимаем разные меры (но я не расскажу какие потому что он скорее всего меня читает lol), чтобы разрулить эту ситуацию правильно. Но при этом хочется сказать несколько важных вещей. 2fa штука важная, будем внедрять. Надо во все курсы встраивать урок про безопасность паролей)
110😁45👍37🔥13❤‍🔥5🥰3👨‍💻3🤡1
Как мы реализовали подписку на Хекслете

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

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

Концепция была в следующем, что с точки зрения платформы, должно быть не важно каким образом у человека появился доступ. Это может быть купон, страйп, доступ для друга, подарок, оплата через компанию и еще тысяча разных способов. Внутри платформы все это сводится к единому признаку “имеет доступ?”. Для этого мы придумали систему с днями доступа. Специальная таблица, в которую заносится любой доступ в виде дней. Например купил подписку на месяц (снялись деньги), получил 30 дней доступа (в зависимости от месяца). Дали купон на 10 дней, после активации туда заносится эта информация. С другой стороны, каждый день запускается скрипт, который списывает эти дни по одному. Фактически у нас получился аналог книги доходов/расходов в бухгалтерии.

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

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

Как-то раз я общался с Андреем Ребровым, который является СТО компании scentbird.com мы обсуждали с ним биллинг. Оказалось что они реализовали такую же схему, только у них были не дни, а недели или месяцы, сейчас уже не помню.

p.s. В ваших проектах есть подписки? Как они реализованы?
👍61🔥236🤔1💘1
Почему плохой код? Потому что мы стартап

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

Если мы говорим про создание типовых веб-проектов, то у нас все достаточно просто. Современные фреймворки и их экосистема, позволяют без особых затрат и сложностей реализовывать проекты достаточно приличных размеров. Что для этого нужно? Модели, контроллеры и вьюхи/фронтенд, по большому счету все. Какой-то серьезной архитектуры тут еще нет, все сводится к тому что надо тратить немного времени на продумывании сущностей и их связей, это главная задача. А дальше как-то мы все это обрабатываем в контроллерах, выводим во вьюхах или отдаем по api. То насколько код здесь чистый не принципиально, а принципиальны две вещи:

⁃ Сущности и их связи. Фактически тут мы говорим о перекладывании модели предметной области на код. Здесь нужно немного думать вперед.
⁃ Структура API. Важно не облажаться с форматом, чтобы потом не пришлось переделывать. Менять публичное апи это еще та попаболь.
⁃ Идеально еще интеграционное тестирование, которое полезно даже в стартапах, так как не сильно зависит от внутренностей (об этом были свои посты)

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

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

⁃ Сразу включаем микросервисы. Хаха, мое любимое. Будет отдельный пост
⁃ Забиваем на возможности фреймворков и пилим все сами. Вплоть до игнорирования ORM
⁃ Плохое знание экосистемы. Как ни странно даже среди вроде бы синьоров такое встречается. Пилят то, что уже напилено в виде библиотек. А иногда это “у нас не должно быть зависимостей” и дальше пилим все сами
⁃ Непонимание концепции автоматов и моделирования процессов на их базе. Бывает такое что интуитивно делают правильно, но часто делают не правильно
⁃ Использование необкатанных и не популярных инструментов, где еще как не в стартапе воткнуть светл?
⁃ Какие-то установки типа: 100% покрытие, на любой чих юнит-тест, вся логика в моделях, юзаем graphql, вводим три слоя абстракций, используем ddd, без паттернов жизнь не жизнь, внедряем event source и так далее.

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

p.s. По каким причинам в ваших проектах плохой код?)
👍31🤣10🫡6👏43🤔1
Ни единой идеи как так получилось
😁62🤣22🤔63👍1
Итоги 2023 года
В этом году встречаемся последний раз, поэтому можно немного подвести итогов. За шесть месяцев я нафигачил 68 постов (ничо си) и вас, мои дорогие, стало 3500 человек. Учитывая что все это происходит в свободное время без каких-то вложений, то результат достаточно хороший, но пока еще никто не пришел с предложением продавать рекламу. Делать я этого не буду, но все равно обидно :D

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

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

Всем спасибо за доверие! С наступающим! Я не планирую уходить на выходные, буду писать и дальше. Уже есть план на два десятка статей. Накидывайте своих тем, я буду их добавлять в список.

p.s. Если у вас есть свой канал на любой площадке, сбросьте ссылку на него в комментах с описанием. Давайте посмотрим кто у нас тут собрался)
79🔥24🎄15👍12🤔1
Если бы я делал веб-проект с нуля

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

Базовым стеком я бы назвал:

Ruby On Rails, React, React Native

Дальше по приоритетам:

⁃ Система будет очень сложной с большим количеством программистов сразу? Spring Boot
⁃ Нужно много бекендовой тяжелой обработки? Go или Java
⁃ Нет экспертизы в руби? Берем Laravel или Django
⁃ Нужны нативные мобильные приложения? Тут все понятно: Swift и Kotlin
⁃ Нужен реалтайм на фронте (а значит асинхронный бекенд)? Node.js, Go
⁃ Нужно e2e тестирование? Playwright

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

p.s. На чем бы вы сделали проект с нуля?
👍705🤔3😁2🔥1👏1
Хранение деревьев в базе: Материализованный путь

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

Однако, есть решение лучше. Кое-кто слышал про nested set и это действительно решение, но очень громоздкое, тяжелое в реализации и понимании. Поэтому тут мы его даже не будем рассматривать, так как есть по настоящему элегантное решение, которое называется materialized path.

Идея в Materialized path заключается в том, что каждый узел (каждая запись в базе) хранит полный путь до корня. То есть вместо parent_id, мы добавляем path, который выглядит, например, так: 1/2/5/8/99/3. / - часто используется как разделитель, но можно выбрать и другой. 1 - в примере это корень под который попадает текущая запись, 3 это прямой родитель. Все что между это промежуточные родительские записи.

Этим подходом мы сразу решили проблему выборку всей нужной ветки. Все что нам надо будет сделать это в коде разделить 1/2/5/8/99/3 на идентификаторы, и сделать один in запрос IN (1, 2, 5, 8, 99, 3)

При такой структуре, для выборки всех потомков понадобится такой запрос:


SELECT * FROM <name> WHERE path LIKE '1/2/%';


Для выборки детей:


SELECT * FROM <name> WHERE path LIKE '1/2';


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

habr.com/en/articles/46659/
👍92🔥363🤔1🐳1👾1
Как мы экономим на фронтенде используя виджеты

Хекслет фронтенда реализован в виде виджетов. Что это значит? Изначально сам проект представляет собой классический MVC (model2), в котором View это обычные серверные шаблоны, в нашем случае на haml.


.table-responsive
%table.table.table-striped
%thead
%tr
%th= sort_link(@search, :id)
%th= sort_link(@search, :email)
%tbody
- @users.each do |user|
%tr
%td= user.id
%td= user.email


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

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


- append_javascript_packs 'community'
- append_stylesheet_packs 'community'


Эти файлы готовит webpack на базе entrypoints. Каждый entrypoint это свой виджет. Внутри уже идет подключение реакта, стилей и всего что там нужно (с точки зрения перфоманса вебпак выделяет общие чанки, которые подключаются один раз для всех).


import app from '../community/index.jsx';

import './community.scss';

const communityBoxId = 'community-box';

app.init(communityBoxId, /* параметры */);


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

Такой подход позволяет оставаться в рамках классической серверной шаблонизации и при этом по необходимости внедрят интерактивные элементы на нужных страницах или на сквозь (как нотификации).
👍49🐳13🔥1232❤‍🔥2🤔2
Заблуждения программистов относительно времени

Кто работал со временем в коде, тот в цирке не смеется. Вот вам подборка заблуждений насчет времени, которые гуляют среди программистов:

1. В месяцах бывает 28, 29, 30 или 31 день.
2. В одно и то же время используется только одна календарная система.
3. Переход на летнее время происходит в одно и то же время каждый год.
4. Переход на летнее время происходит в одно и то же время в каждом часовом поясе.
5. Переход на летнее время всегда корректируется на час.
6. В одном и том же месяце везде одинаковое количество дней!
7. Время Unix - это количество секунд, прошедших с 1 января 1970 года.
8. День перед субботой всегда пятница.
9. Если создать два объекта даты рядом друг с другом, они будут представлять одно и то же время. (фантастический генератор Heisenbug)
10. Недели начинаются в понедельник.
11. Дни начинаются утром.
12. Выходные состоят из субботы и воскресенья.
13. В каждой минуте 60 секунд.
14. GMT и UTC - это один и тот же часовой пояс.
15. Время всегда идет вперед.
16. 24:12:34 - недействительное время.
17. Часовые пояса всегда отличаются на целый час
18. Двузначные годы должны быть где-то в диапазоне 1900-2099
19. Существует только 24 часовых пояса
20. Часовые пояса всегда на целые часы удалены от UTC
21. В году 365 или 366 дней.
22. Високосные годы случаются каждые 4 года.

p.s. оригинал поста https://infiniteundo.com/post/25509354022/more-falsehoods-programmers-believe-about-time Там 79 пунктов
👍3514🔥7😁7🤯5🤔4🤷‍♂2🤓1
Синхронные VS Асинхронные дейли

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

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

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

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

В итоге перешли и остались довольны. Пример того как это работает можно посмотреть тут https://geekbot.com/

p.s. Какой дейли у вас в компании? Это эффективно иль нет?
👍57🔥112❤‍🔥1🤔1
В ближайшие месяцы хотим провести экскурсии в it компании для студентов нашего колледжа https://hexly.ru/ Это Москва, Питер и Новосиб. Ребят если вы можете это организовать или есть кому/кого посоветовать, то напишите плс. Лайк шер алишер.
👏16😁3🤔1
Ревью кода, которые не тормозят

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

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

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

По каким критериям можно разбивать задачу?

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

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

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

p.s. Вы страдаете от процесса проверки пулреквестов у вас в компании?
👍41💯74🤔3😭2🤡1
Парный кодинг для всех

Про парное программирование слышали наверное все, но все ли его практикуют?

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

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

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

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

Научные исследования https://tuple.app/pair-programming-guide/scientific-research-into-pair-programming
Отличный доклад на тему https://www.youtube.com/watch?v=Vu5ujdZDS6E

p.s. Практикуете ли вы парное программирование у себя в компании?
👍4525🔥3🤔2
simple git hook для всех
Вы знаете что можно удобно управлять хуками в git с помощью либы simple-git-hook?

Два действия:

1. Ставится эта либа через npm
2. Прописывается нужная команда на нужный хук в package.json
3. Запускается команда npx simple-git-hooks, которая все сама апдейтит



{
"simple-git-hooks": {
"pre-commit": "npx lint-staged",
"pre-push": "cd ../../ && npm run format",

// All unused hooks will be removed automatically by default
// but you can use the `preserveUnused` option like following to prevent this behavior

// if you'd prefer preserve all unused hooks
"preserveUnused": true,

// if you'd prefer preserve specific unused hooks
"preserveUnused": ["commit-msg"]
}
}


Шикарная вещь, ставим во все наши опенсорсы и внутренние проекты.

p.s. Какие подобные улучшалки вы еще знаете?
👏15👍8🥴7🔥21🤔1
Делать ли livecoding на собесе

Тут в твиттере разгорелось после того как Козуля написал о лайвкодинге, который не проходят люди подделавшие резюме. Твит раз https://twitter.com/vladkozulya/status/1754986992570450283 твит два https://twitter.com/vladkozulya/status/1755209744057299174

Как обычно все поделились на две группы, среди которых та что считает лайвкодинг злом. Хочу на эту тему кое что сказать.

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

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

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

p.s. Вы делаете лайвкодинг? Проходите его сами и завалили?
p.s.s. Задачка на разминку: Какой угол между часовой и минутной стрелкой когда на часах 15:15? 🙂
👍34🔥8👎2🤔1🤮1
Переписывание редактора Хекслета на TS

Давно я не махал шашками серьезно, а тут полез поправить одну штуку в редактор, ну и как-то затянуло и в итоге уже третью неделю я переписываю его с JS на TS. Заодно так сказать вливаюсь в современные тренды. Я еще не закончил, но история уже получается прикольная, что я даже пытаюсь податься с докладом на holyjs, чтобы там про это рассказать.

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

Первое что я сделал это заменил бек fastify на nextjs. Я люблю fastify, но мне хотелось снизить уровень конфигурирования до минимума. Это получилось, что-что, а вот тут next работает из коробки очень хорошо. Иногда все же приходится рестартовать, когда почему-то стейт не обновляется на беке, но в целом оно как-то само там магически работает и достаточно легко поддается легкой кастомизации если надо.

Что удивило, это поддержка бека. Правда вебсокеты подрубаются как костыль и команда разработки не очень спешит заниматься этим вопросом, так как для их платформы Vercel это не вещь, которая принесет деньги. Из-за этого получилось что я одновременно для части апи использую старый роутинг pages, а для части новый в app. Это рекомендация во всех issues.

Из странного, некст не показывает access логи к апи. Если что-то не так, ты вообще не понимаешь что не так. Опций никаких нет, в ишьюсе тихо. Понятно что api не приоритет.

Их хорошего, за счет того что у неста все же есть бек и мне он подходит, то получилось что не надо стартовать два отдельных приложения и менеджерить их. А это всегда требует доп усилий, в таких случаях, надо поставить что-то типа foreman (pm2) или docker compose.

В целом у редактора бекенд очень небольшой, буквально вебсокеты с rpc на 15 действий поверх него и пара rest эндпоинтов. Некст такое обрабатывает легко. Но если бы у меня был по настоящему большой и развесистый бекенд, то я бы брал fastify.
👍38🔥2🤔1
Кладбище забытых проектов

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

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

Кое что все таки оставил, одна часть это опенсорс, который может и не стал невероятно популярным, но все же я понаделал разного добра: отправил кучу пулреквестов (недавно у меня приняли пулреквест из php либы, который я года три-четыре назад сделал), создал немного относительно популярных библиотек, собрал большой список тестовых заданий, который наверное стал самым популярным из того что я начинал (но это не код хаха) https://github.com/Hexlet/ru-test-assignments.

Вторая это Хекслет, которым я занимаюсь уже 11 лет. Есть чем городиться, это довольно крутая техническая штука, которая даже легла в основу книги https://painlessrails.com/book/ Несмотря на размер (а Хекслет довольно большой) и возраст, он в отличном состоянии и поддерживается очень небольшой профессиональной командой. Но так как он свой, почему-то нет ощущения, что я сделал что-то как программист, с чужими это как-то по другому работает)

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

p.s. Что самого крутого сделали вы?
👍50🔥269❤‍🔥1🤔1
Шаблоны проектирования

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

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

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

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

• Убирает ифы из кода. Да вот так вот просто.
• Позволяет управлять кодом через конфигурацию, когда мы не очередной иф вставляем или правим сам код где используется объект, а мы в конфигурации приложения меняем реализацию. В основном это делается в библиотеках, которые мы можем конфигурировать. На уровне приложений такое применяется там где есть контейнеры зависимостей, например, активно в php и java фреймворках. Редко в js, go, python, ruby.

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

p.s. Часто ли вы используете паттерны?
p.s.s. Домашнее задание: Какой паттерн используется в ситуации, когда вы хотите иметь возможность подменить базу данных, в течении жизни приложения (например переехать с одной на другую) без изменения кода (в теории)
👍37🔥198🤔1