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

fborshev@pm.me / borshev.com

Реклама не продаётся
Download Telegram
Прекрасная статья про стартап в одно лицо.

Фаундер, он же CTO, он же CFO и вообще единственный сотрудник, рассказывает про набор весьма скучных инструментов, которые позволили ему одному сделать вполне технологичный бизнес — поисковый движок для подкастов listennotes.com.

Никаких дорогущих юристов — для фандрейзинга подходит Clerky. Прекрасный Stripe и Stripe Atlas вместо бухгалтерии и интеграций с банками. Никакого Kubernetes — только AWS и Ansible.

Основная мысль — если не переусложнять вещи и обдуманно делегировать, то современный мир уже позволяет уместить все знания, нужные для запуска компании, в одной голове. Пусть и не в России (Страйпа у нас наверное не будет никогда), но за 8 часов в день.

Кстати, у него там Django на бекенде:-)
Вопрос: как посоветуешь делать оценку заказной разработки, когда клиент просит жесткий бюджет, скоуп и сроки?

За все 10 лет в заказной разработке, я ни разу не видел проекта, который на финише соответствовал бы оценке, данной в начале.

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

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

Почитайте другие ответы по тегу #вопрос. Рубрику вопросов можно поддержать — либо задать свой вопрос на @fedor_borshev или просто задонатить.
Якорь спокойствия

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

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

Это не так уж и плохо: надо бы только найти менее деструктивный якорь, к примеру что-нибудь из обширного мира потребления. Не могу осилить новую технологию? Ничего, зато у меня айфон новый, и вообще езжу я на БМВ. Всего-то 9 лет платить осталось!

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

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

Посмотрите, к чему вы чаще обращаетесь во внутреннем диалоге, когда вокруг полный пиздец? К якорям спокойствия в настоящем или к большим целям в будущем?
VPN без рекламы от Cloudflare, всем и бесплатно

Cloudflare запустили VPN в своём приложении 1.1.1.1. Говорят, что быстрый и не сажает батарею.

Обещают, что анонимность (We don't write user-identifiable log data to disk), и что нашу историю не продадут добрым корпорациям. Это конечно не no-log policy у NordVPN, но вполне достаточно для того, чтобы быть спокойным за свои данные.

Варианта использования два: просто бесплатный и чуть более быстрый WARP-плюс за 130 рублей в месяц.

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

Скачивайте для iOS или Android, если ещё не.
Качество кода и счастье

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

Вот, к примеру, качество кодовой базы. По-идее, можно очень долго жить с горами говнокода в продакшене — просто нанимаешь в 2–3 раза больше программистов, игнорируешь высокий churn, пытаясь загасить проблему корпоративами/тимбилдингами/мотивацией, и привычно умножаешь все сроки на 3.

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

Ключевой элемент счастливой команды — качество кодовой базы: архитектура, стандарты кодирования, тесты и автоматизация рутины.

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

Боль браузерного тестирования стара так же, как сами браузеры. Представьте ситуацию: вы написали тест, который открывает браузер, нажимает на кнопку «купить» и проверяет, что товар добавился в корзину. В 5 случаях тест работает нормально, а на шестой раз — падает. И у вас нет никакого способа понять в чем проблема — это у вас приложение в иногда не показывает кнопку «Купить», или просто страница медленно грузится? Только делать скриншот страницы во время ошибки и смотреть. А какое это автоматизированное тестирование, если оно не работает без человека?

Недавно узнал, что человечество сделало громадный шаг в сторону нестыдного браузерного тестирования — Puppeteer. Puppetteer — это обёртка над хромом (да, работает только в одном браузере). При этом хром — headless: не нужна графика и куча библиотек. Контейнер с таким счастьем на базе Alpine Linux весит всего 160Мб.

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

У нас в ГдеМатериале есть хорошая практика — мы периодически проверяем актуальность зависимостей. Я говорю не о мелких обновлениях и не о фиксах безопасности (они давно автоматизированы), а об обновлении мажорных версий библиотек, скажем Django с 1.11 до 2.0.

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

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

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

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

Вот прилетает к нам задача, скажем «Жму на кнопку — не работает». Обычно мы чиним такие баги весьма тупо — поднимаем фронт и бек, придумываем гипотезу, и начинаем дебажить: вносим исправление и жмём на кнопку. Если заработало — отлично, если нет — просто перебираем дальше гипотезу за гипотезой. Иногда мы перебираем гипотезы настолько беспорядочно, что даже не убираем следы предыдущих попыток.

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

Правильный процесс выглядит так: открываем контроллер в API, куда ходит кнопка, а дальше ставим под сомнение каждый нижележащий метод, проговаривая про себя гипотезы, к примеру: «я сомневаюсь, что метод get_users() не возвращает неактивных пользователей». Если сразу не находим теста, который доказывает обратное — пишем свой. Если тест падает — отлично, у вас уже есть тест, и остаётся только написать код. Если написанный тест не падает — git checkout --, и ставим под сомнение следующий метод.

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

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

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

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

Будьте подробными: рассказывайте о том, почему пришли к тем или иным решениям. Не «давай перенесём кнопку наверх», а «Эта кнопка — ключевой call-to-action на странице, а я боюсь, что новые пользователи сразу её не увидят» Так вы не только уменьшите количество переписки в трекере, но ещё и опытом с коллегами поделитесь.
Главный карьерный принцип

Когда-то давно услышал полезный совет: зайдя в новую комнату, всегда ищи самого умного человека, и говори с ним. Если самый умный человек в комнате это ты — ищи другую комнату.

То же самое и в карьере — ищи место, где в твоей работе будут находить недостатки. Если недостатки в своей работе можешь найти только ты — ищи другое место.
Вопрос: какие меры вы применяете для провинившегося сотрудника?

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

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

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

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

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

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

Время стоит беречь не только в проектах, но и в личной жизни. Всё так же — если уже 20:00, а вы ещё не ходили в спортзал, то вы никак не можете сделать так, чтобы сейчас стало 18:00 — вы можете только не пойти в спортзал. Если вы приехали на работу в метро, а по дороге слушали музыку или изучали новинки в Arcades — вы просто приехали на работу на метро. А эти же 40 минут можно было потратить на чтение книги или спокойно поспать.

Берегите время.
Качество кода: какие метрики снимать

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

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

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

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

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

Существует куча способов бороться с такой прокрастинацией, но все они относятся к всего к двум группам: робото-само-дисциплина и умение договариваться с собой. Лично у меня подход с дисциплиной не работает — через пару недель насилия над собой в голове не остаётся ничего, кроме желания заснуть часов на 20.

Мой любимый способ, чтобы победить текстовую прокрастинацию — это хорошее окружение: тихая кофейня с вкусным кофе и приятные приложения для текста: IA Writer, Bear и Day One. Подробнее о том, как они помогают больше писать — рассказал в блоге.
​​Писать так, чтобы не переспрашивали

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

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

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

Ну а чтобы прокачать навык написания тестов — приходите на мой мастер-класс в субботу :-)
Технические долги

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

Представь что ты увидел в магазине новый iMac pro. Можно пойти и накопить 400 тысяч (долго и муторно), а можно достать кредитку и купить прямо сейчас.

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

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

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

В командах у технического долга появляется ещё одно вредное свойство — по долгам одного нерадивого участника приходится платить другим. Относись к такому долгу, как к деньгам: представь, что ты в баре, и нашёл в кармане кредитку коллеги. Ты же не станешь угощать весь бар 18-летним Макаланом, правда?

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

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

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

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

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

Почитайте другие ответы по тегу #вопрос или задайте свой вопрос на почту fedor@borshev.com
Будь подробнее

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

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

Или: «Привет! Мы приняли задачу. К сожалению, мы не сможем гарантировать, что сделаем задачу до конца спринта — дело в том, что она ушла стажёру. Конечно, у стажёра стоит дедлайн, но даже несмотря на то, что его сопровождает опытный программист, стажёр — всё-таки новый человек в нашей команде, поэтому результат мы гарантировать не сможем».

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

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

P.S. Как вы заметили, на канале стало гораздо меньше рекламы. Я решил совсем от неё отказаться, но у меня пока остались обязательства, поэтому в ближайшее время выйдет ещё 3–4 поста. Потом с рекламой будет долгое затишье.
Два способа отказать в задаче

У продакта есть два способа отказать представителю бизнеса, пришедшему с бесполезной задачей — классический и жёсткий.

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

Жёсткий — это честно объяснить: «к сожалению, Странное Говно — вообще задача не про деньги потому-то и потому-то. Давай подумаем, как мы могли бы её изменить, чтобы она стала про деньги?».

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

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