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

fborshev@pm.me / borshev.com

Реклама не продаётся
Download Telegram
Вопрос: расскажи, какими должны быть должностные обязанности менеджера?

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

Такие формальные обязанности нужны слабым менеджерам, которые умеют только копать, где сказали.

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

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

Это был традиционный вопрос по понедельникам. Другие ответы доступны по тегу #вопрос. Чтобы задать свой — напишите на @fedor_borshev.
Почему я предпочитаю удалённую работу

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

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

За процесс, наоборот, спрашивать легко: опоздал программист на работу на 5 минут — значит виноват. Тупил во вконтосик в рабочее время — значит плохо работает.

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

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

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

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

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

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

Что думаешь об ХХХ (технологии\подходе\и т.д.):
- Что думаешь про монорепозитории?
- Как лучше учиться — вширь или глубь?
- Что думаешь о node.js в вебе?

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

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


Почитайте все ответы по хештегу #вопрос, а лучше — поддержите рубрику: деньгами или новыми вопросами на @fedor_borshev.
FEDOR BORSHEV pinned Deleted message
FEDOR BORSHEV pinned «Каждый понедельник я публично отвечаю на вопросы, которые задают мне в личку. В этом посте я собрал самые интересные ответы: Что думаешь об ХХХ (технологии\подходе\и т.д.): - Что думаешь про монорепозитории? - Как лучше учиться — вширь или глубь? - Что думаешь…»
Переговоры: возможность принять финальное решение

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

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

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

Посмотрите, может быть у вас так же?
stale: бот для гитхаба, который борется с незавершёнкой

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

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

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

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

Бот формирует в голове тупое правило: забиваешь на свою работу — значит её выкидывают. Такое правило здорово помогает всем отвечать друг-другу вовремя.

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

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

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

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

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

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

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

Когда хочется продемонстрировать баг, нужно показать результат работы по задаче, показать как работает интерфейс — лучше говорить, чем писать. Чтобы передать мысль быстро, а не ждать назначенной встречи, мы прибегаем к «лумам» — коротким видео, записанным при помощи https://useloom.com.

Чтобы лум сэкономил время тебе и коллегам — соблюдай простые правила:

— Не молчи. Хороший лум — это не урок из скучного курса, а живой рассказ живого человека. Когда ты молча возишь мышкой по экрану — это понятно только тебе.
— Включи камеру. С живым человеком гораздо приятнее общаться, чем с его экраном. И пофиг, что на фоне любимая рюмочная — живое общение всё компенсирует.
— Не тяни время. Если твое видео можно уместить в минуту — не записывай пятиминутный сериал. Цени время коллег.
— У готового видео обязательно укажи заголовок. Когда твоя проблема называется «HTTP://LOCALHOST:3000», её не очень хочется решать. Клёво — когда тема понятна сразу: «Не отправляется заказ с дробной ценой», «тормозит загрузка картинок» и т.д.
Прекрасная статья про стартап в одно лицо.

Фаундер, он же 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 на странице, а я боюсь, что новые пользователи сразу её не увидят» Так вы не только уменьшите количество переписки в трекере, но ещё и опытом с коллегами поделитесь.
Главный карьерный принцип

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

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

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

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