Привет, меня зовут Ислам, я тимлид в ФОДЖИН. За последние четыре года мне удалось поработать над несколькими аутсорс-проектами, и также у меня за плечами достаточно опыта работы в аутстафе. Я руководил командами, менторил начинающих разработчиков и помогал им с решением различных задач на проектах. 

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

Кому будет полезен мой рассказ: 

  • начинающим тимлидам/техлидам, за которыми закрепили команду разработчиков, но которые не совсем знают, какие проблемы их могут поджидать;

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

Быть хорошим программистом – что это значит?

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

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

Много лет назад, в попытках впервые устроиться на работу, я на собесе в одной компании по хардам разнес просто всё, что можно было. Но по софтам я был объективно ужасен ???? Затем мой одногруппник (назовем его Иван) собеседовался на ту же самую позицию, в той же самой компании. Он не ответил ни на один технический вопрос, но зато смешно шутил. В итоге выбрали его. А спустя лет шесть мне рассказали, что в итоге Иван стал QA, потому что, по его словам, «можно ничего не делать и много зарабатывать».

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

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

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

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

Как стать хорошим специалистом: накопить опыт решения различных задач

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

Менее болезненный способ — это работа над пет-проектами. Важное уточнение: они должны быть не на уровне туду листов: «кнопочку нажал и работает». Я рекомендую придумывать более интересные задачи, особенно вовлекающие те технологии, с которыми вы раньше не работали. Например, встройте карту в свое приложение через MapBox и попробуйте кластеризовать маркеры на этой карте. Или попробуйте отрендерить 3D объекты на экране с возможностью их вращения, зума. Так или иначе, вы потрогаете библиотеки, с которыми раньше не работали. 

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

Как стать хорошим специалистом: развивать софт скиллы

Новичкам в программировании обычно советуют читать «Чистый код», «Чистую архитектуру», «Программист-прагматик» и прочую классику. А я всем рекомендую книгу «Идеальный программист» (автор Роберт Мартин). В ней объясняется не то, как писать код — а то, как быть хорошим специалистом. 

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

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

Полезный навык — доброжелательность и профессиональное общение

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

Однажды, будучи специалистом на аутстафе, я работал на проекте с менеджерами из Лондона. В первый день я просто залетел в общий чат и написал что-то типа: hello everyone, I’m going to help you with this, and that, and if you need anything, just let me know about it… — в общем, дружелюбно показал всем, что я супер отзывчивый и доброжелательный человек.

После этого они меня просто полюбили, хотя в тот момент я еще ничего не сделал, не написал ни строчки кода, не приступил ни к одной таске. Работы там было всего на две недели, и когда я закончил, они оставили отзыв в духе «11 из 10», настолько им всё понравилось.

На этом примере видно, что софт скиллы напрямую влияют на отношение клиента к вам.

Но в то же время важно помнить и о правилах рабочей коммуникации. Приведу пример того, как делать не стоит. Когда я уже стал наставником, у меня в команде был разработчик, который прямо при мне писал клиенту (именно CTO, а не менеджеру или другому разработчику) что-то типа: hey, my man, what’s up… — и дальше в таком духе. Я ему вежливо объяснил, что так обращаться к клиенту нельзя, потому что это переходит рамки профессионального общения.

Другой, не менее полезный навык — умение решать проблемы

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

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

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

Дело было примерно так. Я как опытный специалист проэстимировал задачи и дал их команде. Но мои разработчики — это не я, и они не совсем укладываются в эти эстимейты. Допустим, у нас есть 5 задач, на которые мы утвердили следующее количество часов:

n1=2

n2=2

n3=5

n4=3

n5=5

Решены уже первые 3 задачи, но по факту вместо 9 часов было затрекано 12. Нашему клиенту, конечно же, не хочется оплачивать часы, которые не были согласованы.

Варианты развития ситуации:

1) выгодный нам — договориться об оплате дополнительных часов; 

2) невыгодный нам — работать бесплатно; 

3) компромиссный вариант, выгодный и нам, и заказчику — оптимизировать время разработки.

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

В итоге у моей команды вместо, например, 20 затреканных часов, получится, скажем, 18 часов из согласованных 17. Для заказчика это звучит приятнее: меньше часов для переплаты. Потенциальный конфликт сглаживается, и доверие не страдает.

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

Проактивность — это тоже качество хорошего специалиста

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

Однажды я работал на проекте, связанном с логистикой, и мне довольно-таки часто удавалось предложить полезные изменения/дополнения для задач. Например: UX’ные предложения, изменение цветов текста на некоторых экранах для улучшения читабельности, оптимизация веса приложения, переключение на более быстро работающий движок и т.д. 

Зачем проявлять заинтересованность? Чтобы о вас складывалось положительное мнение. Разработчик активно участвует в жизни продукта → клиент замечает это и воспринимает разработчика как мотивированного члена команды, а не просто сотрудника.

Мой опыт: управление командой, эстимация задач и решение различных проблем

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

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

Ситуация №1: Разработчик ничего не понимает и молчит

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

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

Если вы заметили подобное, я советую чуть больше уделять внимание этому разработчику. Допустим, уточнить понимание задачи в самом начале и пообещать вашу помощь в случае проблем. Дальше можно действовать по ситуации: объяснить задачу подробнее, натолкнуть на решение, помочь решить… Ну, или просто уволить (нет).

Ситуация №2: Разработчик неправильно эстимирует задачи

При этом тимлид может услышать от разработчика что-то вроде: «Ща, еще 2 часа и будет готово» → Через 6 часов: «Думаю, еще часов 5 осталось и потом всё». Это не самый страшный случай, потому что разработчик способен решить задачу, хоть и с опозданием. 

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

На всякий случай еще скажу: если задача действительно решается за 2 часа, а разработчик возится с ней 2 недели, то вряд ли он эту задачу когда-нибудь решит, дайте вы ему хоть еще 2 недели, хоть 2 месяца, хоть 2 года.

Ситуация №3: Разработчик отдает заведомо нерабочий функционал

Например, разработчик сделал новую фичу, тестит ее, и приложение крашится. И он такой: «Да нормально» ???? И кидает задачу в ПР. Тимлид, допустим, доверяет разработчику, быстро пробегается по ПРу и мержит его в мастер/мейн. QA-специалист тестирует новый функционал, ничего не работает, пишут об этом разработчику. А разработчик такой: «А, не работает? Ну давайте, я починю». 

Что может сделать тимлид: дать по голове разработчику.

Разработчик, будучи неопытным, пытается выиграть больше времени: якобы задачу он сделал, у него всё типо работало, а потом QA нашел там баг, и, вот, надо еще пару часов накинуть на «баг фиксинг». Откуда я знаю про такую схему? Когда-то, давным-давно, я и сам так делал. Но мне хватило 1-2 раз, чтобы понять, что это суперплохая тактика, которая сильно подводит команду.

Ситуация №4: Разработчики забыли, что время нужно не только на кодинг

Например, разработчик написал новый функционал, после чего тимлид проверил этот код и оставил 300 комментариев в ПРе, и теперь разработчику нужно еще 10 часов, чтобы пофиксить все проблемные места.

Еще одна стандартная ситуация: команде мобильных разработчиков на каком-нибудь React Native нужно затестить разработанную фичу в нескольких местах. Например, на смартфонах iOS и Android, на планшетах iOS и Android, а также (в идеале) на разных размерах экранов. В итоге разработчики сделали задачку, например, за два часа, а тестирование на всех устройствах займет еще где-то час.

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

Лайфхак: как оценивать задачи

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

Обычно я поступаю так:

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

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

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

Скорость, качество, результат: как мы с командой искали баланс (и нашли)

Бывает так, что создание новой фичи занимает больше часов, чем изначально планировалось, потому что QA-специалисты нашли серьезные баги, а разработчики не вложили это в эстимейт. Но тут немного спорный момент. Объясню на примере из личного опыта.

Рабочая история: тестирование и критерии приемки

Разрабатывая один E-commerce проект, мы поначалу совершали следующую ошибку: пытались сделать всё «идеально». Например, мы сделали фичу, отправили тестировщику, а он находит редкий баг, что-то вроде: «Открой приложение, сверни на 3 секунды, открой обратно на 5 секунд, посмотри на потолок, и будет такой-то баг». Скорее всего, такие проблемы никогда не воспроизведутся у пользователя.

Попадались и некритичные баги, не совсем имеющие отношения к текущей задаче или никак не влияющие на работоспособность соответствующей фичи. Но мы думали: «Нет, надо довести всё до совершенства». 

Такое вот стремление к «идеальности» очень тормозило нашу  разработку. В итоге мы пересмотрели процесс и выделили четкие критерии приемки (acceptance criteria): 

  • если разработчики сделали что-то, и оно поставленную задачу выполняет, то результат можно принимать;

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

Опытные QA-специалисты знают, что не актуальные в данный момент проблемы можно вынести в отдельный тикет. Если есть необходимость всё пофиксить, то после согласования с заказчиком команде выделяется на это отдельное время. 

Что такое качество?

Понятие «качество» можно рассматривать в двух смыслах: качество кода и качество конечного результата. Частая ошибка начинающего разработчика — это уделять много внимания первому и мало думать про второе. 

В чем разница? Качество кода — это (из названия понятно) то, как он написан. Но я по опыту могу сказать: клиенту всё равно, как разработчик пишет свой код. Красиво, некрасиво, с паттернами, без паттернов… Для клиента главное, чтобы продукт отлично работал и выполнял заложенные функции — это и есть качество конечного результата.

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

Какие короткие пути есть? Как ими пользоваться (спойлер: осторожно) 

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

Разберем на примере: вот вы видите, что у вас в коде есть фрагменты, которые повторяются. Тут вы можете начать думать: «Ох, сейчас я как возьму, как вынесу всё это в отдельный модуль, как адаптирую я этот код, чтобы он мог работать во всех этих местах, а потом как протестирую, чтобы убедиться, что оно всё будет работать…» Однако не факт, что некоторые из этих фрагментов кода настолько похожи, что их можно вынести в отдельную функцию/модуль/куда-то еще. В итоге вы потратите ценное время на то, что может даже и не работать. 

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

Мое мнение: не стоит бояться дупликации кода, ведь иногда намного быстрее и лучше просто сделать Ctrl-C+Ctrl-V. В итоге всё быстро сделано, круто работает, и клиент доволен. Но при этом важно понимать, что короткие пути не должны превращать кодовую базу во что-то неподдерживаемое. 

Если техдолг неконтролируемый, он может в будущем критично замедлить работу или вообще уничтожить проект. В этом случае разработчики объясняют ситуацию проджект-менеджеру: «Приложение не будет работать через полгода, надо бы техдолгом заняться». И дальше задача ПМа убедить клиента, что сейчас действительно стоит выделить время на исправление проблем, которые были допущены для ускорения разработки.

Баланс и приоритеты

При создании MVP команде разработки нужно уметь расставлять приоритеты. В конечном итоге важно не то, насколько код красивый, а то, что он работает в 100% случаев и не создает проблем на будущее. 

Оптимально, если разработчики стараются сочетать три фактора:

  1. Возможность быстро разрабатывать и укладываться в эстимейт;

  2. Отличное качество конечного результата, чтобы клиенту всё нравилось;

  3. Более-менее нормальный вид кода, чтобы в будущем не получился «накопительный эффект», который усложнит работу с проектом. Если код нормально написан, специалисту нетрудно будет разобраться с ним и сделать лучше.

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

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

Комментарии (0)