Как нанимать и управлять программистами уровня junior и middle, не теряя месяцев времени

Всем привет! Я Лаптев Алексей, основатель и главный разработчик сервиса бесплатной сквозной аналитики и коллтрекинга Utmstat, а также Telegram-канала про сквозную аналитику. Сегодня расскажу, как работать с программистами на примере внутреннего регламента Utmstat.

Пасет котов
Пасет котов

Для кого статья

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

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

Проблема на рынке

Лебедь, рак и щука​
Лебедь, рак и щука​

Есть цепочка: бизнес — менеджер — программист, и она работает по принципу испорченного телефона.

Бизнес просто хочет сайт/сервис/приложение и поручает менеджеру сделать.

Менеджер по-своему понимает задачу, говорит ее программисту, при этом не может адекватно оценить решение от программиста.

Программист по-своему понимает задачу менеджера и просто пишет красивый код.

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

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

Дисклеймер

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

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

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

Как нанимать программистов

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

Что нужно спрашивать на собеседовании

1. Просим показать предыдущие проекты и оцениваем их сложность.

Если у вас интернет-магазин и там интернет-магазины — хорошо, если простенькие ленды — плохо. Опыта нет.

То есть смотрим, чтобы сложность предыдущих проектов была примерно как у вас.

2. Смотрим примеры кода.

Если все более-менее по стандартным паттернам — хорошо, если какой-то креатив и видно, что даже про MVC не слышал, — плохо.

3. Смотрим на рабочее окружение.

Если это бэкенд-программист, например PHP, то его рабочими инструментами должны быть Ubuntu/MacOS и PHPStorm. Это наиболее эффективная связка.

Если там Windows, noname-opensource-ide и удаленный сервер — это звоночек, но шанс еще есть.

4. Вспоминаем сложные моменты из проекта и просим предложить их решение.

Самое банальное — очереди. Если программист выдает решение похожее на ваше — хорошо, если ничего не выдает и понятия не имеет, как оно решается, — плохо.

Если словами сложно объяснить, можно попросить набросать схему компонентов в Google Draw. Писать код не нужно.

Чего не надо требовать

1. Писать код

У верстальщиков, конечно, можно спросить, но если программист на пальцах рассказал решение, то он и код напишет.

2. Требовать точные знания каких то команд и синтаксиса

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

3. Требовать знания алгоритмов и другой лютой теории

В 99% случаев программисту нужна арифметика на уровне (a+b)/2, поэтому если в задачи программиста явно не входит разработка логики с высшей математикой и каких-то быстрых алгоритмов повышенной надежности, то не надо спрашивать, как работает пузырковая сортировка и прочую ерунду.

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

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

Итого

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

Типы программистов на рынке

Прежде чем перейдем к правилам, надо понять, для кого и почему они написаны.

1. И так сойдет, лишь бы работало здесь и сейчас

У них нет цели сделать хорошо, разобраться. Пишут как умеют. Лишь бы платили.

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

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

2. Религиозный фанатик

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

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

Надо быть готовым к долгим холиварам в чатах на тему, как делать правильно и почему.

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

3. Нормальный программист

Моя любимая категория.

Тут нормальный баланс фанатизма и пофигизма, работа идет ровно.

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

О чем нужно рассказать в первый день

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

Поэтому на всякий случай нужно настроить на нужную волну.

Целью разработки является

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

Целью разработки не является

Написание продукта, напичканного всевозможными фичами, библиотеками, инструментами.

Вот так

Как нанимать и управлять программистами уровня junior и middle, не теряя месяцев времени

Что нужно понимать программисту, особенно новичку

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

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

Ежедневные правила работы

Цели правил

  • Ускорить процесс разработки продукта.

  • Минимизировать бесполезное общение в чатах.

  • Минимизировать бесполезные телодвижения команды в целом.
  • Минимизировать бардак в коде.
  • Дать план решения типовых задач новичкам.

Подготовка к работе

  • Поставить промышленную IDE уровня PHPStorm от IDEA (да, платная), никаких опен-сорcных и noname/online редакторов и VIM’a.
  • Синхронизировать настройки статического анализатора кода и автоформатирования
  • Поставить сервис скриншотов «Яндекс.Диск» (Windows) или CloudApp (Mac), чтобы не возиться с файлами. Это сервисы наиболее удобные. Все скриншоты пересылаются в виде ссылок, а не по схеме: скачал файл → нашел → отправил в чат. Вот как это работает — https://cl.ly/1b2ab0576ca3.

  • Поставить десктопную версию чата — Slack или Telegram.

  • Религиозных фанатиков уровня «я только за опенсорс», «я использую только %softname%», которые категорически не хотят переходить на объективно более производительные инструменты, можно сразу просить на выход, на практике толку от них мало.

Работа с GIT

  • Проект содержит две основные ветки — develop и master (продакшн) + задачи.
  • Каждый коммит содержит коммент в формате “#%номер задачи% — %что сделал%”.

  • Каждая задача в отдельной ветке.
  • По завершению, каждая задача проходит ревью кода и мержится в develop через pull request.

  • Каждый релиз в master теггируется кодом релиза, например r20191209.

Базовые принципы разработки

  • Твой красивый и каноничный код никому не нужен, «красивый» — код это следствие качественной работы, а не самоцель.

  • Твои длительные исследования никому не нужны, если не было на то явной задачи.

  • Лучший код — это его отсутствие. Постоянно задавай себе вопросы «Зачем?» и «Можно ли проще?».
  • Не надо заниматься программированием ради программирования.
  • Локальный разумный плохокод допустим, если есть ощутимая экономия времени и его можно причесать позже, без переписывания всей системы. Яркий пример — тесты.

  • Но плохоархитектура не допустима, она должна быть максимально продумана, чтобы нормально работать в условиях кривых локальных модулей и слабых разработчиков.
  • Держим статический анализатор кода зеленым.
  • Используем стандартное автоформатирование кода.
  • Каждая проблема на длинной дистанции должна решаться один раз (золотое правило).
  • В каждой проблеме нужно разбираться с точностью до строчки кода, никаких заверну в докер или переустановлю ОС/etc, авось пройдет. Пока нет ясной причины — нет и решения.
  • Каждую ошибку/проблему или значимое событие нужно логгировать в БД.

  • Важная функциональность должна быть покрыта тестами.

  • Тесты в релизной ветке должны работать.
  • Пиши стандартный код и используй возможности фреймворка на максимум, даже если это «не производительно».
  • Но при этом думай и закладывай возможность оптимизировать код под x1000 кратную нагрузку.
  • А еще думай, как твой код смотрится на фоне общего проекта — однотипно (хорошо) или жгучий креатив (плохо)?
  • Не занимайся преждевременной оптимизацией и не пиши низкоуровневый код без 100% уверенности, что это тут нужно, реальные узкие места покажет нагрузочный тест, вот тогда и будем усложнять. Если ты новичок — точно не пиши, без команды тимлида.
  • Не принимай решения, потому что кажется. Без метрик и чисел любые решения — пустая трата времени.

Что нужно иметь в виду в новом проекте

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

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

Работа с задачей

  • Должно быть 100% понимание смысла задачи.
  • В работе должна быть только одна задача или подзадача, фокусируйся, не распыляйся.
  • Делать ровно ту функциональность, что написана в задаче. Знаешь решение лучше? Сначала обсуди.
  • Все написанные модули покрывать тестами, как минимум проверкой, что модуль отвечает кодом 200 на типовые запросы и возвращает ожидаемый ответ.
  • Не заниматься рефакторингом и ненужными исследованиями в рамках задачи.
  • Не знаешь, как делать? Спроси.
  • Кривой код, хочешь рефакторить? Сначала спроси, потом исправляй.
  • Хочется глубоко исследовать тему на пару дней? Сначала спроси, потом исследуй
  • После выполнения задачи тесты должны работать.
  • После тебя сломались тесты? Немедленно исправляй.

Алгоритм поиска причины ошибки

  • Запустить код, который генерирует ошибку.
  • Посмотреть ошибку и stack-trace.

  • Посмотреть внутренние логи приложения.
  • Загуглить текст ошибки.
  • Просмотреть всю цепочку методов до ошибки и понять, чего там не хватает.
  • На все про все не более 30 минут.
  • Если ответ не найден — задаем вопрос тим-лиду.

Алгоритм исправления ошибки

  • Воспроизвести и ясно понять причины.

  • Если это Exception, вызванный работой пользователя, — покрыть тестом.

  • Написать тест, воспроизводящий ошибку.
  • Исправить ошибку.
  • Убедиться, что тест заработал при правильном сценарии.
  • Важно: исправляем причину ошибки, а не бездумно подгоняем код, чтобы ошибки не было, добавляя isset, try и так далее.

Как задавать вопросы тимлиду по логике кода

  • Сначала думаем сами, но не более 10 минут, если мыслей никаких.

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

  • Спрашиваем, что непонятно, с указанием строки кода или стрелками на скриншоте.

Как задавать вопрос тимлиду по ошибкам

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

  • Спрашиваем, что не понятно — с указанием строки кода или стрелками на скриншоте.

Какие вопросы не нужно задавать тимлиду

  • «За жизнь» в рабочее время.

  • Размытые вопросы уровня «Как делать задачу?». Начни делать и спрашивай конкретику, что не понятно.

  • Не задавать вопросы, требующие объемного ответа, но при этом не влияющие на выполнение текущих задач. Например, объяснить работу модуля, с которым ты никак не связан.

Обязанности разработчика

  • Проявлять интерес к проекту.

  • Знать базовые возможности используемых языков программирования, фреймворков и инструментов (особенно те, что написаны в резюме).

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

Обязанности тимлида/продуктовнера

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

Завершение рабочего дня

  • Проставить актуальный статус выполненных задач.
  • Отметить время.
  • Тезисно написать, что сделано внутри задач.

Итого

Возможно, кому-то правила показались жесткими, но их соблюдение привело к комфортной, быстрой работе без авралов и стабильным кодом.

2626
62 комментария

Комментарий недоступен

14
Ответить

Ну вы можете ценой своего времени и денег доказать обратное.

2
Ответить

перескажу кратко для тех кому лень читать: добро пожаловать на галеры

14
Ответить

Расплата за чрезмерное "ковыряние"( считай, растрату времени) программистами и расплатой бизнеса за это. Теперь программистов "стандартизируют", есть чёткие план действий для получения результата.  Многие сложности теперь гуглятся, а не требуют времени на поиски решения. Ценность и "вольность" снижается, вырисовываются чёткие рамки. 

1
Ответить

На галерах проще

1
Ответить

Поставить промышленную IDE уровня PHPStorm от IDEA (да, платная), никаких опен-сорcных и noname/online редакторов и VIM’a
@
Религиозных фанатиков уровня «я только за опенсорс», «я использую только %softname%», которые категорически не хотят переходить на объективно более производительные инструменты, можно сразу просить на выход, на практике толку от них мало

9
Ответить

А сможете внятно аргументировать, чем PHPStorm превосходит например Eclipse PDT ?

1
Ответить