image

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

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

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

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

Анти-паттерны оценки


Большинство оценок в проектах делается в начале их жизненного цикла. И это не смущает нас, пока мы не понимаем, что оценки получены раньше, чем определены требования, и соответственно раньше, чем изучена сама задача. Следовательно, оценка обычно делается не вовремя. Этот процесс правильно назвать не оценкой, а угадыванием или предсказанием, потому что каждое пятно в требованиях — это игра в угадайку. На сколько эта неопределенность влияет на финальные результаты оценки и ее качество?

Мелочь, а неприятно


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

  1. Нужно ли клиенту, чтобы введенный телефонный номер проверялся на действительность?
  2. Если клиенту система проверки телефонных номеров нужна, какую версию он предпочтет — дешевую или дорогую?
  3. Если реализовать дешевую версию проверки телефонных номеров, не захочет ли клиент позднее переключиться на дорогую?
  4. Нельзя ли воспользоваться готовой системой проверки телефонных номеров или, вследствие каких-то проектных ограничений, необходимо разработать собственную?
  5. Как будет спроектирована система проверки?
  6. Сколько времени потребуется на программирование системы проверки телефонных номеров?

И это лишь несколько вопросов из списка, который возникает в голове опытного руководителя проектов… Как видно даже из этого примера, потенциальные различия в определении, проектировании и реализации одних и тех же возможностей могут накапливаться и увеличивать время реализации в сотни и более раз. А если объединить их в сотнях и тысячах функций большого проекта, мы получим колоссальную неопределенность в оценке самого проекта.
Еще один прекрасный пример «распухания» казалось-бы элементарного требования читайте в статье "Как две недели?!"

Конус неопределенности


image

Разработка ПО — да и многих других проектов — состоит из тысяч решений. Исследователи обнаружили, что оценкам проектов на разных стадиях присущи прогнозируемые уровни неопределенности. Конус неопределенности показывает, что оценки становятся более точными по ходу продвижения работы над проектом. Обратите внимание, что на этапе исходной концепции (где частенько даются оценки и берутся обязательства) ошибка может составить 400% (четыреста процентов, Карл!). Оптимально брать обязательства после завершения детального проектирования.

Мифический человеко-месяц


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

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

image
Команда проекта пытается справиться с авралами // Иван Айвазовский, 1850 г

Если 8 человек могут написать программу за 10 месяцев, смогут ли 80 человек написать ту же программу за один месяц? Неэффективность крайнего сжатия сроков становится особенно очевидной на крайних случаях — таких, как 1600 людей, которые должны написать программу за один день. Подробнее об этом читайте в одноименной книге Фредерика Брукса.

Паттерны оценки


Итак, с проблемами все ясно. Что можно сделать?

Декомпозиция


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

  1. Лучше понимаем состав работ. Чтобы декомпозировать задачу нужно прочитать требования. Сразу всплывут непонятные места. Снижается риск неверно истолковать требования.
  2. В ходе анализа более детального анализа требований автоматически запускается мыслительный процесс систематизации знаний. Таким образом снижается риск забыть какую-то составную часть работ, например рефакторинг, автоматизацию тестирования или дополнительные трудозатраты на выкладку и развертывание
  3. Результат декомпозиции можно использовать для проектного управления, при условии что для обоих процессов использовался один инструмент (более подробно этот вопрос рассмотрен ниже в тексте).
  4. Если измерить среднюю ошибку оценки каждой задачи, полученной в ходе декомпозиции и сравнить эту ошибку с ошибкой суммарной оценки, окажется, что суммарная ошибка меньше средней. Другими словами, такая оценка точнее (ближе к реальным трудозатратам). На первый взгляд это утверждение контр-интуитивно. Как финальная оценка может оказаться точнее, если мы ошиблись в оценке каждой декомпозированной задачи? Рассмотрим пример. Для того, чтобы создать новую форму нужно а) написать код на бекенде, б) сверстать макет и написать код на фронтенде, в) протестировать и выложить. Задача А была оценена на 5 часов, задачи Б и В на 3 часа каждая. Суммарная оценка составила 11 часов. В реальности бекенд сделали за 2 часа, на форму ушло 4, а на тестирование и исправление багов ушло еще 5. Суммарные трудозатраты составили 11 часов. Идеальное попадание в оценку. При этом ошибка оценки задачи А — 3 часа, задачи Б — 1 час, В — 2 часа. Средняя ошибка — 3 часа. Дело в том, что ошибки занижения и завышения оценки компенсируют друг друга. 3 часа, сэкономленные на бекенде компенсировали отставание в 1 и 2 часа на этапе фронтенда и тестирования. Реальные трудозатраты — это случайная величина, зависящая от множества факторов. Если вы заболеваете, то вам будет сложно сконцентрироваться и вместо трех часов может уйти шесть. Или всплывет какой-то неожиданный баг, который придется искать и исправлять целый день. Или, наоборот, может оказаться, что вместо написания своего компонента можно использовать существующий и т.д. Позитивные и негативные отклонения будут компенсировать друг друга. Таким образом, суммарная ошибка будет уменьшаться.

Фичи и таски



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

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

К сожалению иногда бывают большие фичи. В одиночку трудиться над таким объемом придется очень долго. А еще долго придется тестировать и осуществлять процесс сдачи-приемки. Тогда мы меняем тип задачи на эпик (Epic). Эпик — это просто очень толстая фича. Ничего больше эпика мы не заводим. Т.е. эпики могут быть просто большими, огромными или гигантскими. В любом случае в приемку эпик отправляется по частям (фичам).

Для того, чтобы оценивать точнее фичи декомпозируются на отдельные подзадачи (Task). Например, фичей может быть разработка нового CRUD-интерфейса. Структура тасков может выглядеть так: «вывести таблицу с данными», «прикрутить фильтрацию и поиск», «разработать новый компонент», «добавить новые таблицы в БД». Структура тасков обычно вообще не интересна бизнесу, но крайне важна для разработчика.

Оценка в группах, покер планирования




Программисты слишком оптимистично оценивают объемы работ. По разным данным занижение оценки чаще всего варьируется в диапазоне 20-30%. Однако в группах ошибка снижается. Это происходит из-за лучшего анализа за счет разных точек зрений и темперамента оценивающих.
Наибольшее распространение с ростом популярности Agile получила практика "покер планирования" Однако, с групповой оценкой связано две проблемы:

  1. Социальное давление
  2. Временные затраты

Социальное давление


Почти в любой группе опыт и личная эффективность участников будут разниться. Если в команде сильный тим/тех — лид / ведущий программист, другие члены могут испытывать чувство дискомфорта и намеренно занижать оценки: «Ну как, Вася то сможет, а я что, хуже? Я тоже так могу!». Причины могут быть разными: желание показаться лучше, чем есть на самом деле, соревновательность или просто конформизм. Итог — один: групповая оценка теряет все свои преимущества и становится индивидуальной. Тимлид проставляет оценки, а остальные просто поддакивают ему.
Я достаточно долго давил на команду с целью получить оценки, более соответствующие моим ожиданиям. Это неизменно приводило к снижению качества и срыву сроков. В результате, я изменил свое отношение и теперь моя оценка зачастую становится самой большой. В ходе обсуждения я указываю на потенциальные проблемы, которые приходят в голову: «тут рефакторинг бы не помешал, здесь у нас структура бд меняется, надо бы регресс-тест сделать будет».
Основных рекомендаций несколько:

  1. Большинство оценок занижены. Не можете выбрать между двумя оценками? Возьмите ту, что больше.
  2. Не уверены в оценке — выкидывайте карту "?" или большую оценку. Авось почти никогда не проносит.
  3. Всегда сравнивайте план и факт. Если знаете, что вы не укладываетесь в два раза, давайте оценку в два раза выше той, которая вам кажется. Начали завышать? Умножайте в уме на полтора. Через несколько итераций качество ваших оценок должно значительно улучшиться.

Временные затраты


Вам знакома фраза «Не хочешь работать? Собери совещание!». Мало того, что один программист вместо написания кода пытается предсказать будущее. Теперь это делает вся группа. Кроме того, выработка решения в группе — процесс значительно более длительный, чем принятие индивидуальных решений. Таким образом, групповая оценка — крайне затратный процесс. Стоит посмотреть на эти затраты с другой стороны. Во-первых в процессе оценки группа вынуждена обсуждать требования. Это значит, что придется их прочитать. Уже не плохо. Во-вторых, давайте сравним эти затраты с теми, которые понесет компания из-за недооценки проекта.
Много лет назад одним ноябрьским днем я сменил место работы на крупную компанию. Мне сразу стало понятно, что работа кипит. Половина компании трудилась над тем, чтобы выпустить продукт до конца года. Но примерно через неделю мне стало казаться, что до конца года они не успеют. С каждым следующим днем шансы на успех этого предприятия становились все более и более призрачными… Проект действительно сдали в декабре, правда уже следующего года. Об этом я узнал значительно позже, потому что летом начались проблемы с выплатой заработной платы сотрудникам и я уволился вместе с еще примерно половиной штата. Вы можете сказать «ну конечно, менеджеры — дураки, нужно было подстраховаться». Они подстраховывались. Полгода проблем с выплатой заработной платы не было. Держать запас оборотных средств на полгода финансирования — не простая задача. Думаю, если бы оценка была более точная, были бы другие управленческие решения на уровне топ-менеджмента.
Если рассматривать вложения в оценку как инвестиции в принятие верных управленческих решений, то они перестают казаться такими уж дорогостоящими. Размер групп — это другой вопрос. Конечно не обязательно заставлять всю команду оценивать весь объем работ. Гораздо разумнее разделить задачу по модулям, кхм, микро-сервисам и предоставить командам автономию. А на более высоком уровне использовать оценки, полученные каждой командой для составления проектного плана. Что плавно подводит нас к теме следующего абзаца.

Простановка зависимостей, диаграммы Ганта


image

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

  1. Таблица в бд
  2. Код на бекенде
  3. Код на фронтенде

Выполнять задачи именно в таком порядке проще всего с технической точки зрения. Однако в реальности существуют разные специализации. Фронтенд-специалист может по плану освободиться раньше. Вместо того, чтобы простаивать ему логичнее приступить к разработке UI, заменив запрос к серверу на мок или захардкоженные данные. Тогда к моменту, когда API будет готово останется только заменить код на вызов реального метода… в теории. На практике максимальный уровень параллелизма может быть достигнут следущим образом:

  1. Сначала быстро делаем swagger, чтобы согласовать спецификацию API
  2. Затем хардкодим данные на беке или на фронте, в зависимости от того, кто есть под рукой.
  3. Параллельно делаем бд, бекенд и фронтед. БД и бекенд частично блокируют друг друга, но чаще всего эти компетенции сочетаются в одном человеке и работы на самом деле идут последовательно: сначала бд, затем бекенд
  4. Собираем все и тестируем
  5. Исправляем баги и снова тестируем

Важно, чтобы пункты 1, 4 и 5 выполнялись как можно быстрее, чтобы уменьшить количество блокировок. Кроме технологических ограничений и ограничения в доступности специалистов необходимой компетенции существуют еще приоритеты бизнеса! А это значит, что через три недели уже назначена демонстрация важному клиенту и плевать он хотел на первую половину вашего проектного плана. Он хочет видеть конечный результат, который будет доступен не раньше, чем через два месяца. Что ж, значит придется подготовить отдельный план под эту демонстрацию. Добавляем в план забить необходимые данные БД, вставить новые ссылки для переходов в UI и т.д. Еще желательно, чтобы выкидывать в итоге пришлось процентов 20% кода, а не всю эту демонстрацию.

Художественная нарезка такого плана — задача непростая. Простановка зависимостей значительно упрощает процесс. Прежде чем приступать к модулю отчетов, нужно сделать модуль ввода данных. Логично? Добавляем зависимость. Повторяем для всех связанных задач. Поверьте, многие из зависимостей окажутся для вас неожиданностью.

В задачах автоматизации бизнес-процессов обычно получается несколько длинных «змеек» связанных задач С несколькими крупными узлами-блокировками. Чаще всего первоначальный план оказывается не эффективным с точки зрения утилизации ресурсов и/или слишком длинным в календарном выражении. Пересмотр оценки трудозатрат авось получится быстрее — не вариант. Оценка, итак, скорее всего оптимистична. Приходится возвращаться к декомпозиции, искать слишком длинные цепочки и добавлять дополнительные «развилки», чтобы увеличить степень параллелизма. Таким образом за счет увеличения суммарных трудозатрат (больше людей работают параллельно над одним проектом) снижается календарный срок проекта. Помните про «мифический человеко-месяц»? Сжать план больше, чем на 30% вряд ли выйдет. Чтобы бюджет и срок сошлись план может пересматриваться несколько раз. Есть несколько приемов, делающих процесс быстрее и проще.

Блокировка задач


Первую причину блокировки — зависимости — мы уже рассмотрели. Кроме этого могут быть просто не понятные / не точные требования. Необходим инструмент, позволяющий блокировать задачи и задавать вопросы. С уточнением требований можно разблокировать задачи и корректировать оценку. Этот процесс, кстати, почти всегда идет в ходе проекта, а не до него.

Критический путь, риски вперед


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



Короче говоря, если вы накосячите со структурой БД, придется переписывать бек, не расчитаете нагрузку, возможно придется вообще менять технологию. Подробно о рисках проектной работы я писал в статье "Рентабельный код". Чем раньше материализуются риски, стоящие на критическом пути, тем лучше. Ведь время еще есть и можно что-то предпринять. Еще лучше, если они вообще не материализуются, но давайте будем реалистами.

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

Критерии приемки, контрольные примеры



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

Ведение проекта


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

Учет рабочего времени aka time tracking




Учет рабочего времени давно стал уже стандартом де-факто в индустрии. Очень желательно, чтобы он производился в том же инструменте, что и оценка. Это позволяет отслеживать отклонение фактически-затраченного времени от оценочного. Хорошо, если этот инструмент использует еще и и менеджер проекта. Тогда все задержки критического пути будут заметны сразу. Вариант с разными инструментами тоже возможен, но потребует значительно больших трудозатрат на обслуживание процесса, а значит появится соблазн схалтурить. Мы уже знаем, чем это заканчивается. Мы используем YouTrack. Все о чем я писал в статье на данный момент доступно из коробки, хотя и требует небольшой настройки.

Заключение


  1. Оценка — это сложно
  2. Декомпозиция позволяет найти пробелы в требованиях и повысить качество оценки
  3. Групповые оценки точнее индивидуальных, используйте покер
  4. Блокеры, контрольные примеры и формальные критерии приемки улучшают коммуникацию, что в свою очередь, повышает шансы проекта на успех
  5. Начинать надо с самых рискованных задач на критическом пути проекта
  6. Оценка — это не одноразовая акция, а процесс, неотделимый от ведения проекта
  7. Без учета рабочего времени невозможно держать статус проекта актуальным и корректировать свои оценки

Хотите узнать больше об оценке проектов?


Прочитайте книгу Стива Макконела "Сколько стоит программный проект" и другие статьи на эту тему на Хабре:

  1. habr.com/ru/company/infopulse/blog/170777
  2. habr.com/ru/post/308494
  3. habr.com/ru/company/ruswizards/blog/151029
  4. habr.com/ru/company/mindbox/blog/321270
  5. habr.com/ru/post/307820

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


  1. vfabr
    04.03.2019 01:31

    Какая у вас фактическая медианная длина задачи? Есть ли ограничение на длительность задачи сверху? Как оценивать и вообще работать с задачами в которых ничего не понятно?


    1. powerman
      04.03.2019 04:11

      Какая у вас фактическая медианная длина задачи? Есть ли ограничение на длительность задачи сверху?

      Не знаю, как у автора, но лучше чтобы максимальная не превышала 3-4 дня, т.е. часов 20, а основная масса задач делалась за 4-8 часов.


      Как оценивать и вообще работать с задачами в которых ничего не понятно?

      Если непонятно потому, что задача ещё не была проанализирована — сначала сделать анализ и декомпозицию, а потом оценивать. Если непонятно потому, что очень много неизвестных факторов и неясно какие в принципе есть подходы к решению — тогда до оценки этой задачи необходимо выполнить дополнительную "исследовать и оценить доступные подходы к решению задачи", на которую выделяется небольшое фиксированное время (максимум 2-3 дня), после чего мы имеем и понимание (в общих чертах) как решать исходную задачу и более-менее адекватную оценку.


  1. MetaAbstract
    04.03.2019 11:07

    На практике часто используются усредненные оценки. Например

    Обычно за верстку главной страницы берут от 80-100$, а за верстку каждой внутренней от 20$