{"id":14268,"url":"\/distributions\/14268\/click?bit=1&hash=1e3309842e8b07895e75261917827295839cd5d4d57d48f0ca524f3f535a7946","title":"\u0420\u0430\u0437\u0440\u0435\u0448\u0430\u0442\u044c \u0441\u043e\u0442\u0440\u0443\u0434\u043d\u0438\u043a\u0430\u043c \u0438\u0433\u0440\u0430\u0442\u044c \u043d\u0430 \u0440\u0430\u0431\u043e\u0447\u0435\u043c \u043c\u0435\u0441\u0442\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e?","buttonText":"\u0423\u0437\u043d\u0430\u0442\u044c","imageUuid":"f71e1caf-7964-5525-98be-104bb436cb54"}

Как нанимать и управлять программистами уровня 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. Нормальный программист

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

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

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

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

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

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

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

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

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

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

Вот так

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

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

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

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

Цели правил

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

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

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

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

  • Поставить промышленную 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 минут, если мыслей никаких.
  • Кидаем ошибку и значимую часть трейса в рамках одного скриншота.
  • Кидаем скриншот кода, который вызвал ошибку, с номерами строк и названием класса, чтобы можно было быстро понять контекст и найти по тексту.

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

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

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

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

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

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

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

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

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

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

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

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

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

Итого

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

0
62 комментария
Написать комментарий...
Аккаунт удален

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

Ответить
Развернуть ветку
Alexey Laptev
Автор

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

Ответить
Развернуть ветку
Аккаунт удален

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

Ответить
Развернуть ветку
Alexey Laptev
Автор

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

Все эти оптимизации процесса экономят время и уменьшают срок разработки.

Разумеется если ваш продакшн это винда или ios, там другие требования, например наличие макбука для разработки на ios.

Ответить
Развернуть ветку
Аккаунт удален

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

Ответить
Развернуть ветку
Alexey Laptev
Автор

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

Ответить
Развернуть ветку
59 комментариев
Раскрывать всегда