Больше года я занимаю должность технического лидера в своей компании, и хочется поделиться наработками по теме. Имеет смысл уточнить: я веду отдел iOS-разработки из 10 человек в компании-аутсорсере. В моём случае должность подразумевает оптимизацию работы отдела, распределение задач между разработчиками и активности, связанные с программированием. Расскажу немного о своём опыте, наработках и умозаключениях. Статья может быть полезна прежде всего новичкам на аналогичной должности, либо тем, кто на неё метит. Какие-то практики и принципы могут быть переносимы на обычную разработку, на другие платформы или даже другие специальности.
Обязанности
Чтобы понять, чем конкретно мне приходится заниматься, имеет смысл начать со списка обязанностей. В них входят:
- Обязанности разработчика:
- Написание кода, рефакторинг
- Ревью кода
- Консультирование специалистов других отделов по технической части
- Оценка трудоёмкости проектов и отдельных задач
- Участие в найме
- Оптимизация работы отдела:
- Повышение технического навыка разработчиков
- Определение порядка выполнения стандартных активностей
- Наработка готовых решений
- Введение новых сотрудников в отдел
- Утилизация времени простоя разработчиков
- Распределение задач:
- Задачи на проектах, требующих временного вмешательства
- Задачи внутри отдела
- Оценки проектов для продажи
- Консультирование менеджмента по части распределения разработчиков между проектами
Здесь приведены основные обязанности; часть активностей, специфичных для нашей компании, опущена. Большинство разработчиков выполняет стандартный набор активностей и имеет хорошее представление о них, поэтому упор хочется сделать именно на ведении отдела.
Оптимизация работы отдела
В чём она в принципе может заключаться? Очевидно, в улучшении скорости и качества выполнения стандартных задач. Казалось бы, обычно бывает либо одно, либо другое, но здесь важно наращивание опыта — компания реализует большое количество проектов, в процессе работы решаются одни и те же задачи, и со временем можно выделить наиболее удачные и логичные решения и научить отдел ими пользоваться. В этом заключается глобальная идея оптимизации.
Пройдёмся по средствам, которые позволяют это в определённой мере реализовать.
Документирование
Стандартные активности можно и нужно документировать. Записанная информация лучше запомненной по многим причинам:
- Она представляется в одном и том же виде для всех
- Её представление всегда будет полным и корректным, без «испорченного телефона»
- Её изучение тратит время только изучающего
- Она не теряется ни из-за плохой памяти, ни при недоступности отдельных людей
- Её всегда можно освежить
- Она не рассинхронизируется при изменении
- В процессе фиксации и доработки детально продумываются все важные аспекты
- Действия в рамках инструкций могут подлежать автоматизации
- … можно продолжать
Имеет смысл документировать всё, что выполняется многократно. Это могут быть гайдлайны для кода, порядок выполнения оценок или проведения собеседований, правила работы с репозиториями или баг-трекером — что угодно, что нужно делать постоянно и чему приходится обучать новых людей снова и снова.
Самая сложная задача — приучить людей использовать документацию. Прежде всего, нужно донести до всех, что информация имеется. Нужно на неё ссылаться на вместо того, чтобы пересказывать самостоятельно.
Крайне важно держать документацию в актуальном состоянии, так как иначе работа над ней будет просто тратой времени. Это не принесёт пользы, так как доверия к неактуальным источникам информации не будет, ими опять же не будут пользоваться, а время будет потрачено. В идеальном мире участвовать в развитии общей документации должен весь отдел — тогда все будут понимать, какая именно документация имеется, где её искать, как ей поделиться, а сама информация будет актуальной.
Не призываю разводить бюрократию и покрывать инструкциями каждое мелкое движение, так как это неэффективно. Но самые основные вещи имеет смысл определить, зафиксировать и начать доносить до людей.
Переносимый код
В случае мобильной аутсорс-разработки мы имеем относительно небольшие по размеру и сроку жизни проекты, на которых большая часть функционала схожа, либо вообще повторяется. В этом случае можно создать базу кода, переносимого между проектами. Это могут быть стандартные утилитарные функции, какие-то контролы, отдельные слои или что-то ещё.
Если отдел имеет свою историю, там в любом случае уже есть какие-то наработки, которые переносятся между проектами просто как отдельные файлы. Такой вариант проще, но код дорабатывается под нужды одного проекта, а в случае переиспользования его доработки могут разниться. Выделение переносимого функционала в отдельные репозитории даёт возможность продуктивнее развивать и стабилизировать решения. Использование менеджеров зависимостей дополнительно сокращает время на переиспользование, хотя и увеличивает время на поддержку и вносит свои ограничения.
Если изначально базы кода нет, разработчикам может быть непривычно и неудобно выносить решения в отдельные репозитории, потому что «зачем мне напрягаться, если и так работает»? Возможно, кому-то придётся объяснять, что стратегически с точки зрения работы компании так будет лучше. Со временем процесс входит в привычку, не создаёт проблем и не вызывает непонимания, потому что воспринимается, как должное.
Автоматизация
Некоторые стандартные активности поддаются автоматизации. Это упрощает рутинные действия, ускоряет работу, снижает человеческий фактор и иногда привносит возможности, которые в ручном режиме практически не реализуемы.
Стандартный пример: автоматизация процесса сборки позволяет сильно (иногда почти до нуля) снизить затраты на подготовку билдов и внедрить в процесс статический анализ или тестирование в обязательном порядке (имею в виду, что можно запретить сборку без успешного статического анализа).
Другой пример: вспомнив о специфике отдела, можно говорить, что автоматизации поддаётся процедура старта проекта. В нашем отделе применяется шаблон, который может сгенерировать начальное содержимое репозитория со структурой проекта, настроенной под все гайдлайны, а также с настроенными git и continuous integration. Его применение значительно упрощает и ускоряет старты новых проектов.
В целом, простейшим случаем автоматизации можно считать создание различных шаблонов для документов, кода или чего бы то ни было ещё.
Единообразие
При разработке время зачастую теряется на погружение в проекты, так как те могут быть по-разному устроены, а одни и те же задачи могут из раза в раз решаться по-новому без видимых на то причин. Заступая на новый проект, где всё в очередной раз сделано по-своему, разработчик потратит определённое время на изучение инструментария. Если у него за плечами больше десятка проектов, разницы не будет — он будет уже примерно представлять, как могут решаться стандартные задачи. Если же обширного опыта нет, время будет тратиться. Здесь можно сэкономить, приведя разработку к единому виду.
Для достижения единообразия проектов применимо всё, что уже перечислено: общие правила, база решений типовых задач, автоматизация. Используя их, можно сделать проекты в определённой степени похожими и понятными для новых разработчиков.
Не стоит при этом излишне усердствовать — проекты не обязательно должны быть похожи, как две капли воды. Эксперименты с инструментами и архитектурой важны как для веселья нарабатывания опыта, так и для исследования потенциальных нововведений. Имеет смысл системно экспериментировать, отталкиваясь от единой базы.
Эффективность решений
В идеальной картине мира нужно следить за тем, оправдает ли себя то или иное решение. Перевалив за определённый порог, затраты на его поддержку могут превысить выгоду. Наилучшим и единственным объективным показателем здесь является время. Если есть возможность хотя бы иногда отсмотреть срезы затрат на поддержку всего используемого набора, например, по месяцам, это может помочь лучше сориентироваться. У меня, к сожалению, времени не хватает, и приходится всё определять на глаз. К тому же, некоторые потенциально неэффективные решения иногда становится реально содержать, благодаря внезапно освободившимся разработчикам. Реальная разработка в этом плане может отличаться от логичной теоретической.
Увеличение количества используемых инструментов и объёмов документации может сделать слишком сложной поддержку всех наработок или даже их применение. Например, забыть об одном правиле из 50ти куда проще, чем об одном из 5ти. Нахождение баланса между функциональностью и сложностью с этой точки зрения — не самая тривиальная задача. Не могу сказать, что смог найти этот баланс и обеспечить использование наработок в полной мере.
Обучение
Большое количество времени я потратил на создание системы обучения разработчиков. Построив качественную систему обучения, можно решить сразу несколько задач:
- Повышение технического навыка разработчиков
- Донесение информации о наличии инструкций и готовых решений
- Обеспечение допусков к типовым активностям
- Направление роста разработчиков в правильную сторону
- Рациональное использование времени простоя
На данный момент система имеет вид:
- Больше десятка ступеней, от самых азов до хардкора
- Общий объём информации приблизительно на пару лет изучения
- Ступени включают тестовые задания, инструкции и теоретическую часть
- Принятие ступени осуществляется в два этапа:
- Выполнение тестовых заданий, с ревью кода
- Интервью по инструкциям и теоретической части
- Принятие ступеней осуществляется практически непрерывно, минимальный интервал между интервью — одна неделя
- К системе привязаны допуски до активностей
Таким образом, разработчики непрерывно находятся в процессе роста, причём система построена так, чтобы сначала закрыть потенциальные дыры в знаниях, а затем обучить решать типовые задачи, то есть строится исключительно на материале, применяемом постоянно.
Ступени включают инструкции для выполнения тех или иных активностей (написание кода, старты проектов, оценка), и по мере закрытия ступеней разработчики получают соответствующие допуски.
Начинается обучение с вводной ступени, которая содержит гадлайны кода, инструкции по работе с системой контроля версий и баг-трекером, а также самые азы программирования. Придя в компанию, разработчики допускаются на проекты, уже отчитавшись о знании того, как мы работаем, и минимальном наборе навыков, а также выполнив тестовый проект и пройдя в процессе соответствующее ревью, то есть, имея полное представление о процессе работы.
Обучение разработчиков — длительный процесс даже в рамках отдельно взятой системы, поэтому на проработку материала и формы его принятия необходимо большое количество времени. Дело осложняется тем, что изучение информации длится неделями и месяцами, поэтому быстро сформировать и протестировать разбиение материала на этапы невозможно. Принятие ступеней также происходит относительно редко, что требует максимального внимания — поначалу необходимо использовать каждую процедуру сдачи для получения информации об удобстве системы.
Распределение задач
Структура нашей компании реализована так, что технический лидер не управляет распределением разработчиков. Участие в формировании команд имеет консультативный вид: кого с кем лучше ставить, потянет ли та или иная команда проект и т.д.
В мои обязанности входит только обеспечение выполнения задач, которые не относятся к активным проектам. Если есть относительно свободные люди, им можно передавать оценку трудоёмкости приложений для продажи или, например, неотложные задачи на формально приостановленных проектах, где совсем некому их выполнить, либо внутренние активности отдела или что-то ещё. Если свободных ресурсов нет, нужно выполнять всё самому.
Передача задач и проста, и сложна — нужно проверять, кто свободен на данный момент, лично обращаясь к разработчикам и менеджерам проектов. Мне пока не удалось придумать ничего эффективнее обычного диалога, хоть чутьё и подсказывает, что должна быть какая-то возможность сделать это проще и прозрачнее. Единственное, что удалось придумать для упрощения коммуникации — общий чатик для разработчиков. Иногда, написав туда, можно узнать, что кто-либо внезапно свободен и может выполнить необходимую работу.
Сам процесс делегирования задач и контроля выполнения — не самая простая область, и мне удалось освоить только самые его азы, поэтому здесь каких-то откровений не будет. У всех задач есть степень передаваемости — насколько эффективной и безопасной может быть её делегирование. Всегда можно отдать какую-то простую задачу, которую будет сложно сделать так, чтобы она сильно что-то испортила. Всегда лучше быть готовым к худшим сценариям, хотя всё зависит от уровня исполнителя. Если уровень разработчика высокий и есть доверие, можно передавать большие и сложные задачи или даже формирование общего видения по тому или иному вопросу. Требования к выполнению передаваемой задачи всегда нужно обозначать максимально точно, чтобы исключить элементарные ошибки и снизить возможность некорректной трактовки. Также нельзя забывать о проверке результатов.
Ясно, что по мере роста отдела нужно разворачивать структуру, в которой обязанности будут дополнительно распределяться на постоянной основе, либо разбивать один целый отдел на несколько меньших по размеру но в моей практике до такого не доходило.
Как всё это осилить
Если окинуть взглядом перечисленное и представить, какое количество времени нужно на каждую из этих активностей, станет понятно, что должность подразумевает действительно много задач. Это не будни разработчика, когда у тебя в обычный день одна-две, максимум пять активностей одинакового типа. Мой стандартный день включает 5-10, а иногда и 15 задач, и их тип может сильно различаться.
Так как от природы мой
Хуже всего в моём случае справляется память, поэтому часть практик направлена на замену памяти
Делегирование. О нём уже немного сказал. При нехватке времени нужно стараться по максимуму передавать работу другим.
Привлечение разработчиков на уровне культуры. Если сформировать у отдела хорошие привычки, часть активностей может выполняться даже без ведома технического лидера. К примеру, ошибки в переносимом коде могут исправляться разработчиками в рамках обычного выполнения задач на проектах.
Чеклисты. Чтобы не забывать о порядке действий, можно составить их списки: на обычный рабочий день, на выполнение той или иной активности, на отдельную задачу или на случай определённого события (например, обновления какого-либо инструмента). Со временем необходимость в чеклистах отпадает, так их соблюдение входит в привычку, но поначалу они могут быть весьма полезны.
Напоминания. Когда я выполняю задачу, то стараюсь оставить себе напоминания по каждой мелочи на случай, если вдруг отвлекусь или забуду что-то в ходе работы. Это могут быть “TODO” в коде, записки в отдельном документе или на листочке бумаги. Нужно по максимуму страховаться от того, что в процессе работы что-то будет забыто и не доделано.
Дисциплина. Выполнять задачи нужно в полном объёме, чтобы не нужно было больше о них вспоминать. Статусы в системе управления проектами нужно выставлять своевременно, списывать время нужно сразу же по окончании работы над задачей, потому что, выполнив десяток различных задач и исчерпав ресурсы
Отказ в коммуникациях. Множество обязанностей подразумевает множество коммуникаций. Ответить на письма и сообщения в мессенджерах можно, закончив текущую активность. Самая сильная коммуникация — личная, и она тяжелее всего поддаётся постановке в очередь. Когда ко мне во время выполнения задачи подходят люди, частенько приходится говорить им, что я занят и не могу разговаривать. В противном случае контекст мыслей будет постоянно теряться, и после разговора придётся всё вспоминать заново. При определённом количестве коммуникаций, если в них не отказывать, производительность при выполнении сложных и объёмных задач будет проседать, иногда почти до нуля. Развернуть человека, который подошёл к тебе лично, может быть непросто, но при большом количестве задач это необходимо.
Список задач
На мой взгляд, самый важный инструмент, достойный отдельного пункта. Если вы не можете удерживать в голове все свои задачи, нужно вести их учёт. Здесь необходимо нечто более свободное, чем баг-трекер. Я использую простой текстовый документ.
Когда поступает новая задача, она просто добавляется в список так, чтобы примерно сохранялась очерёдность, в зависимости от приоритетов. Когда активная задача заканчивается, я возвращаюсь к списку, выбираю наиболее приоритетный пункт и берусь за него. Так время не тратится на поиски задач.
При необходимости можно оценить, сколько времени потребуется на каждую активность в списке и обозначить сроки их выполнения. Такие оценки, правда, не всегда корректны, поскольку задачи поступают в случайном порядке, и заранее неизвестно, когда и сколько их ещё появится. Впрочем, с этим тоже можно бороться, заложив определённое время в день на внезапную занятость и давая пессимистические оценки.
В отдельную секцию списка у меня выделены пункты, касающиеся проверки выполнения переданных активностей. Если задачу выполняет другой человек, необходимо периодически проверять статус, иначе она может просто затеряться, так как мало кто из разработчиков заботится о том, чтобы ничего не забывать.
Для кого-то ведение простого списка задач может выглядеть, как «велосипед», но это простая и реально рабочая практика, которая помогает сохранить время и не забыть о задачах. По крайней мере, радикально снизить количество забытых.
Ощущения
Вроде бы, описал, чем я занимаюсь и как со всем этим справляюсь. Можно добавить немного лирики о собственных ощущениях от работы. Возможно, кому-то это поможет принять решение о том, стоит ли этим заниматься.
Результат не осязаем. Если я делаю проекты, то это больше относится к старту, и в итоге его делают другие люди. Обучение разработчиков напрямую отследить невозможно. Чтобы понять, работает ли то или иное решение, нужно выполнить одни и те же задачи с ним и без него, снять статистику затрат на его разработку и поддержку, и сделать выводы. На такой аудит в наших условиях времени нет и не может быть. В итоге, отследить, насколько верны или неверны мои действия, невозможно. Предъявить результаты моей работы в чистом виде, соответственно, тоже нельзя. Это не добавляет морали.
Проекты обезличились. Когда разработчик делает хотя бы один полноценный релиз приложения, он начинает хорошо ориентироваться в его поведении. Когда речь идёт только о старте приложения, ревью или фиксе нескольких сложных багов, запомнить проекты не получается. Даже технологии кажутся везде одинаковыми.
Простые задачи достаются разработчикам. Браться за простые вещи доводится крайне редко. Мне очень нравится заниматься простой вёрсткой стандартных экранов и подгонять пиксели и цвета, воевать с проблемами UIKit, но в последнее время большая часть задач имеет отношение к построению архитектуры приложений.
Короткая память ухудшилась. Переваривание больших объёмов информации поначалу перегружало
Смена контекста работы стала проще. Как выяснилось, этот момент поддаётся тренировке.
Незнакомые проекты/технологии/подходы даются проще. Занимаясь отдельными проектами, разработчик ими ограничен. Когда видишь одни и те же вещи, воплощённые во множестве разных форм на разных проектах, становится гораздо проще абстрагироваться от деталей и понять общие принципы.
Видно, как работает компания. Имея отношение к нескольким проектам и ко всем разработчикам сразу, можно понять, как работает весь отдел и смежные отделы. Это видение иногда позволяет дать правильные ответы на нестандартные вопросы о том, какой порядок действий будет самым простым для всех в сумме, к чьему ведению относится то или иное решение и т.д.
Нужно самому ставить задачи. Когда выполняешь проект, будучи разработчиком, то выполняешь набор заданий, подготовленный кем-то другим. При ведении отдела нет никакого ТЗ или скоупа работ. Отдел — это сам по себе некий проект, и я в нём и разработчик, и менеджер проекта, и владелец продукта. Решения о том, какие задачи нужно выполнить — на мне.
Нужно учить людей. Часто одному и тому же. Иногда по нескольку раз. Роль технического лидера, собственно, для этого и нужна. Если в компании есть разработчики, у которых сможет поучиться он сам (у нас такие, к счастью, есть), это очень здорово, и к ним имеет смысл относиться с большим вниманием.
Переданные задачи редко выполнены до конца. Где-то это обусловлено ошибками, спешкой, невнимательностью, где-то непониманием общего видения, где-то вкусовщиной. Большей частью приходится давать дополнительные указания и отправлять задачи на доработку, а в условиях горящих сроков и вовсе дорабатывать самостоятельно. Стараюсь следить, чтобы это не становилось «узким местом» процесса.
Итоги
Статья получилась объёмной. Надеюсь, кому-нибудь она что-то прояснит. Возможно, кто-то привнесёт в свою практику что-либо из этих наработок или извлечёт для себя что-то ещё. Естественно, в каждой компании и каждом отделе роль технического лидера будет выглядеть по-своему, но я осветил те аспекты, которые на данный момент видятся наиболее значительными в моих условиях. Спасибо.
Автор: e-Legion Ltd.