FEDOR BORSHEV
25.4K subscribers
33 photos
1 video
4 files
647 links
Рассказываю, как руководить программистами

fborshev@pm.me / borshev.com

Реклама не продаётся
Download Telegram
Live stream started
Live stream finished (2 hours)
Вынужден с сожалением констатировать, что если вы не хотите, чтобы ваш сайт, приложение или бекенд без вашей воли начали выступать с политической позицией — прямо сейчас отключите dependabot, renovate и любую другую форму автоматического обновления пакетов.

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

Важный принцип из ГТД — нужно отделить принятие решения от его выполнения.

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

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

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

Мы избавились от mailchimp в самом важном процессе — отсылке учебных писем. На стриме (и немного потом, см. код) я сделал собственную реализацию цепочек. Идея простая — все образовательные письма мы шлём не через маркетинговые инструменты вроде mailchimp или mindbox, а через транзакционные — sendgrid, postmark, mandrill, или даже через свой SMTP. Хоть это и выглядит немного огородно, это всё равно лучший вариант для школы. Даже если бы нас не заканселил мейлчимп, я бы всё равно это сделал, вот почему:

— Доставляемость. Письма моментально доходят и не попадают в папку «промоакции» в gmail. Это снимает запросы в сапорт вида «не вижу урока\посмотрите в «промоакциях», у нас их сейчас 3–4 в день.
— Контроль. Теперь у нас прямо в постгресе есть данные о том, какому студенту ушло письмо, какому — нет. Довольно легко можем обогатить эти данные данными из трекинга, чтобы сделать интересные триггеры, к примеру реактивировать студентов, которые не открыли два подряд письма от нас.
— Надёжность. Даже если нас забанят все в мире сервисы транзакционных писем — мы за пару часов переключимся на отправку через SMTP и будем слать письма через собственные шаблоны.
— Беспарольный вход! Теперь мы в одном шаге от открытия прозрачного входа в LMS — достаточно просто добавлять индивидуальный токен в каждую ссылку каждого письма, и студенты смогут вообще не проходить аунтификацию.

Сейчас заканчиваем восстанавливать рассылки по всем текущим курсам, так что если вы вдруг что-то не получили — получите сегодня.
Work-life balance

У понятия work-life balance есть странная асимметрия — его почти всегда употребляют только в одну сторону — «что-то я многовато работаю». Никогда не слышал, чтобы люди говорили: «Что-то я маловато работаю, надо бы побольше».

Думаю, эта асимметрия вызвана тем, что есть странные люди (назовём их «упёртыми»), которые в принципе не считают какой-либо баланс необходимостью. Вместо мифического баланса упёртые люди просто определяют свои цели и идут к ним. Если эта цель — проводить по 8 качественных часов с семьёй, и на счету хватает денег на 5 лет такой жизни, зачем напрягаться на работе? Если цель — заработать 50 миллионов, зачем бездельничать?

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

Если вам не нравится ваш work-life balance, может, у вас просто цели нет?
#вопрос Я написал код на основе того, что уже был в проекте, но на ревью мне сказали, что этот код был плохой и надо улучшать. Как сразу понимать, хороший код ты пишешь или нет?

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

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

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

Это был традиционный вопрос по понедельникам. Задавайте свои на fborshev@pm.me
Асинхронная Архитектура: новый набор

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

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

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

Даже если вы джун, который пилит монолит в маленьком стартапе, курс вам поможет: мышление проектировщика позволяет писать более понятный и изолированный код. Промокод V7DD10 даёт скидку 10% до 10 апреля.

Обучение стартует 21 апреля и длится 4 недели.

Смотреть программу →

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

В 2017 году была очень популярна MongoDB — это такая база данных, которая не требует схемы, то есть не ограничивает разработчиков в формате данных, которые они в неё складывают. С тех пор много воды утекло — разработчики перестали пихать schemeless куда попало, менее маргинальные БД вроде PostgreSQL научились JSONb, а создатели MongoDB даже добавили поддержку схемы. Но многие ребята всё ещё пытаются хранить важные для бизнеса данные в JSON, и это плохо.

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

{
name: 'Как перестать переставать и начать начинать',
author: 'Роббинс, Тони',

}

Автора книги всегда можно узнать, обратившись к ключу author объекта типа book — так делают сайт, мобильное приложение, интеграция с типографией и электронная библиотека. И когда неожиданно после года работы выяснится, что автора у книги может быть два или три, и book.author становится массивом, вам приходится лезть во все приложения, которые выводят автора книги и менять код для вывода, иначе пользователи увидят что-то вроде «'Роббинс, Тони', 'Трейси, Брайан'» вместо «Тони Роббинс и Брайан Трейси».

Пример предельно упрощён, но смысл понятен — если не ограничить формат хранения данных, то рано или поздно кто-то туда положит такое дерьмо, от которого развалится всё приложение. Если не хотите, чтобы так случилось — делайте максимально жёсткую структуру данных: никогда не пользуйтесь JSON для важных данных, и добавляйте столько констрейнтов, сколько только можете придумать. Если вам не повезло работать с критичными данными, хранящимися в документоориентированных БД — пишите максимально жёсткие схемы.
#вопрос Ты часто журишь разработчиков, которые ставят сроки и продалбывают их. Но что делать, если я сам такой разработчик? Я твердо уверен, что дело не в моей лени или дисциплине. Как только дело доходит до планирования, все становится плохо. Такое случается даже в моем собственном проекте, в котором мне не перед кем отчитываться. Говорят, что не обязательно “угадывать срок”, достаточно просто вовремя корректировать его и управлять ожиданиями, но после второго переноса мне уже становится стыдно. Посоветуй, как перестать продалбываться и жить без стресса из-за сроков?

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

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

А серебряной пули, увы, я не знаю.

Это был традиционный вопрос по понедельникам. Задавайте свои на fborshev@pm.me
Кажется, ИТ-эмиграцией сейчас интересуются вообще все. Давайте поинтересуемся и мы — в четверг в 19:00 собираемся здесь с Димой @seniorsoftwarevlogger. Дима уже 8.5 лет живёт в Германии, сейчас работает в Twilio.

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

UPD: запись лежит в комментах
Live stream scheduled for
Live stream started
Live stream finished (1 hour)
Целиться в процесс, а не в результат

Сейчас будет каминг-аут: меня пугают большие амбициозные цели. К примеру, мне могу согласиться пару раз в неделю ходить в спортзал, чем поставить себе цель «подтянуть мышечный каркас». Каждый раз, когда я буду пропускать спортзал (а такое рано или поздно случится даже если я — биоробот), я начну думать: «а накачаю ли я теперь мышцы? А не потерял ли я в результате?». Это тяжело.

Имея простую нестрашную цель «ходить в зал несколько раз в неделю», я пропускаю спортзал гораздо спокойнее — никто же не умрёт, если я на этой неделе схожу не три раза, а два или даже один раз?

Так работает со всеми большими целями: я никогда не решусь похудеть на 10 килограммов, но вполне смогу большую часть недели потреблять не больше 1500 килокалорий в день. Вряд ли я когда-нибудь решился бы построить бизнес — это страшно. Зато мне вполне хватило смелости уволится с работы и пару месяцев попробовать что-нибудь поделать.

Может и вам поможет? Если часто не достигаете больших целей, попробуйте ставить маленькие цели на процесс, а не большие цели на результат, мне помогает.
#вопрос Ты как-то писал «не стоит делать асинхронный сервис для отправки СМС». Почему?

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

К сожалению, большинство сервисов отправки СМС, которые я видел в живых архитектурах, решали совсем другую задачу — что-то вроде «пусть наши приложения ходят не напрямую к провайдеру СМС, а через наш асинхронный сервис, чтобы не шарить креды/научить девопсов RabbitMQ/попробовать Elixir». Такие сервисы выглядят нестыдно ровно до момента, когда в них не протекает бизнес-логика.

К примеру, вы начинаете часть СМС слать не через GSM, а через мобильные пуши. Если делать это на уровне отдельного сервиса, то придётся рассказать ему о сущности юзера и о привязке этой сущности к идентификатору девайса — и вот уже у вас в системе появляется «агрегат сообщения», и послать сообщение становится невозможным, не зная данных юзера, или не настраивая перегон данных о пользователях в ваш сервис отправки.

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

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

Более подробно логику принятия таких решений мы рассматриваем в «Асинхронная Архитектура» в Школе Сильных Программистов. Набираем третий поток прямо сейчас.

P.S. Это был традиционный вопрос по понедельникам. Задавайте свои на fborshev@pm.me
Не давать обещаний сходу

Чтобы программисты успевали в срок, менеджеры всегда закладывают «сержантский запас»: если команда оценила проект в 5 дней, опытный менеджер заложит 2 недели: скорее всего, что-то пойдёт не так и этот запас пригодится.

Почему-то этой уловкой редко пользуются программисты. Я и сам раньше на это напарывался: видел интересную задачу на пару часов, думал: «Что я, пару часов на неделе не найду?» — и давал обещания. В итоге брал кучу лишних задач и не оставлял себе буфера — если двухчасовая задача превращалась в 4 часа или основной проект съедал времени больше запланированного, приходилось или каяться или перерабатывать.

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

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

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

На активную часть работ ушла целая неделя — я прямо садился и по два часа в день занимался yaml-программированием. В итоге получился довольно развесистый плейбук для 6 сервисов — кроме основного монолита у нас есть ещё несколько ботов, сервис веб-аналитики и Metabase.

Работа по переносу далась мне довольно тяжело в эмоциональном плане — я не делал ничего нового и необычного, а просто использовал свои мехнические навыки, чтобы сохранить статус-кво. Марьяна сказала, что тяжело было потому, что я чейнджер, а не раннер. Что бы-то ни было, перенос закончен, а у нас появился ещё один открытый репозиторий, на этот раз с инфраструктурой.
#вопрос В процессе программирования в результате всегда оказываюсь не готов упаковать свои скрипты и сниппеты в финальную программу для деплоя. То есть по частям всё работает, всё знаю, во всём разобрался. Но упаковать всё вместе никак не получается. Точнее не получается в срок. Всё время какое-то копошение в конце — то тут подправить, то там отформатировать и т.д. В результате конечно же срываются сроки. Есть ли какой-то универсальный совет на этот счёт?

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

Чаще всего работа перед запуском — скучная и тупая: нужно почитать логи, поправить «на живую» ошибки дописав тесты, поковыряться в контейнере. Увы, от этого никуда не деться. Но можно облегчить.

Во-первых, побуду кепом — постарайтесь предугадать проблемы до запуска. К примеру мы с Саматом, даже когда разрабатываем полугодовой проект, деплоим его на прод с первого месяца — так к запуску у нас уже вылечиваются все детские болезни CI\CD и окружения: за полгода каждая слабая часть среды успевает хоть раз, но отказать. Если пишете небольшой проект — его тоже лучше бы сразу докеризировать, обмазать линтерами и покрыть тестами. Если лень — заведите себе cookiecutter, как мы сделали с django: все настройки проекта разворачиваются за одну команду.

Второй совет чуть менее очевидный — поработайте над Developer Experience. Возможно ковыряться перед запуском скучно именно потому, что нужно ходить на серверы руками и читать логи через grep (даже не через ripgrep). Форматировать код скучно потому, что нет команды make fix, которая сразу подгоняет код под стандарты проекта. Разваливающийся код вполне может получаться просто потому, что вам неудобно писать тесты из-за сложного окружения, которое нужно поднимать вручную.

Главное не забывайте, что лучше говно в проде, чем не говно не в проде :-)

Это был традиционный вопрос по понедельникам. Задавайте свои на fborshev@pm.me