×Закрыть

Тыкая пальцем в небо, или эволюция одной метрики

Это заметка выросла из ненаписанного комментария к колонке Сергея Малярова «Простой путь» — поделюсь, какими способами мы пользуемся, чтобы снизить неопределенность оценок в разработке и запрошу идей по усовершенствованию.


«Миссионер средневековья рассказывает, что нашёл точку, где небо касается Земли»
Гравюра Камиля Фламмариона, раскрашенная Хуго Хайкенвельдером;

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

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

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

  Подзадача *  Первоначальная оценка (ч) *  Уточненная оценка (ч) *  Фактическая трудоемкость (ч) *  Осталось (ч)
 

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

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

Вот рядом 2 графика распределения плотности вероятностей — Гаусса, с 20%-ной дисперсией, которое привычно нашему интуитивному представлению о вероятности, и Пуассона. Что мы видим:

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

Итого — во второй версии таблички сбора метрики у нас каждая строчка имеет вид:

  Подзадача *  Первоначальная оценка (ч) - min  *  Первоначальная оценка - max *  Уточненная оценка (ч) *  Фактическая трудоемкость (ч) *  Осталось (ч)
 

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

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

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

Итого, следующая инкарнация нашей таблички имеет вид:

  Подзадача *  Первоначальная оценка (ч) - min  *  Первоначальная оценка - max *  Уточненная оценка (ч) *  Фактическая трудоемкость (ч) *  Осталось (ч) * Технический долг *  Ошибки
 

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

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

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

Можно ли как-то выделить способы разработки, дружественные планированию? Да, если стараться, чтобы:

  • объем планирования был как можно меньше (инкрементальные релизы)
  • взаимосвязи между пунктами оценки были как можно меньше (исследовательские задачи делать в отдельной итерации и не смешивать с обычными)
  • объем программы был как-можно меньше (высокоуровневые языки, библиотеки)
  • связность модулей была как можно ниже (фреймворки и изменения базовой арзхитектуры делать в отдельной итерации и не смешивать с функциональными)

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

  • Этот множитель получается большим и неинтуитивным, который предлагается просто принять как данное и смириться.
  • Предлагается оценивать время в часах на реализацию, включая все остальные активности (документация, митинги, и т.д.) в этот большой коэффициент переноса. Получается, мы измеряем вещи уровнем ниже, чем сам процесс разработки. С другой стороны стоит отметить, что прогноз именно в продуктивных часах играет и позитивную роль, это по сути аналог «к-ства точек функциональности, длиной в один чаc», и именно фокусировка в часах делает эту оценку более или менее однозначной, просто она имеет другой физический смысл, чем время работы.

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

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

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

LinkedIn

12 комментариев

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

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

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

Неохваченные риски у нас — типа кто-то ушел/ заболел/ пришел новый человек и его надо вводить в курс дела итд. Хмм, мы в таких случаях перепланируем. А как еще можно ?

Руслан, все зависит от того, кто несет ответственность за риски. В time & material модели, когда заказчик платит фактически не за предоставляемый вами scope, а за ресурсы (людей, оборудование...), он берет на себя часть рисков. В этом случае перепланирование — совершенно нормальная практика. Однако, в модели fixed price, когда заказчик платит за поставку набора фич к определенной дате, все риски связанные с персоналом, технологиями, организацией (ну, например в здании отключили электричество на сутки, упал интернет, слетел сервер, посольство не выдало вовремя визу для бизнес-поездки и т.д.) несет на себе поставщик, т.е. вы. Не успели к дате релиза — не получаете денег.
Поэтому необходимый буфер необходимо закладывать в максимальную (а при использовании модели PERT — также в наиболее вероятную) оценку. Суть моего комментария была в том, что для одних задач риски превратятся в проблемы (и вы их затянете), а для других — даже не наступят (и вы их сделаете быстрее), и в целом вы имеете хорошие шансы успеть к конечной дате (повторюсь — задач должно быть как можно больше, т..е. декомпозиция должна быть как можно более детальной).

Ага. Ну риски изменений в команде или отключния электричества вобще от задачи не зависят. Тут максимум — отдельный задача в плане на компенсацию. А про риски зависимые от задачи — да, в принципе справедливо. С другой стороны есть определенный предел возможности декомпозиции без реализации. Ага, и теперь понятно почему я об этом не написал — потому что мы и так около этого предела плаваем. А если у кого-то планирование крупноблочное — то да, надо спускаться до разумного предела. Если доведу до guidelines — надо будет добавить. Спасибо.

Считаю что статья совершенно бесполезная, никакой пользы ее чтение не несёт а скореей запутывает читателя.

Питання по останньому варіанту таблиці

Технический долг * Ошибки

Ти ці дві категорії задач відносиш до кожного рядка?

Тобто ти проводиш аналіз причин кожного ТД та кожної помилки?

Чи я не так тебе зрозумів?

1. Технічний борг. Виникає одразу після закінчення модулю. Зміст — виникає задача з краткий опис рефакторінгу, яка ставиться (або не ставиться) в план наступної ітерації.

Відношу до кожного рядка, але нулі там стоять досить часто

2. Помилки. Тут маються на увазі ті помилки, що проявилися після сдачі. Ми проводимо не повноцінний аналіз причин, а просто классифікація — до якого модулю помилка відноситься. Проводить її та людина, що її виправляє. Навіщо це потрібно — щоб знати скільки коштують гарантійні зобов’язання.

Також відноситься до кожного рядка і також є нулі.

Руслан, спасибо за статью.

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

1. Скажите, а зачем вы собираете данные о минимальной и максимальной первоначальной оценке, только для того, чтобы понимать когда работы будут окончены в лучшем и.или худшем случае, или есть еще какая-то задача? Вы как-то анализируете эти данные (или собираетесь анализировать) в сравнении с уточненной и фактической оценкой? Есть ли у вас предположения, что эти данные должны показать?
2. Что у вас пишут в колонке о состоянии процесса?

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

1. В первую очередь что-бы самим понимать. Еще психологически — человеку обычно намного легче указать диапазон чем одну цифру. Ну и проверки — уточненная оценка, x: такое что мат-ожидание не превысит х, и фактическая оценка на должна находится между минимальной и максимальной. (ага — забыл написать за очевидностью: уточненная оценка переуточняется раз в отчетный период). Разность между минимальной и максимальной цифрой также говорит нам о степени отфорнарности оценок.
2. Состояние workflow: не начато, в процессе, ожидание, замороженно, сделано — на тестировании, сдано

3 Подсчитывает сначала потенциальный исполнитель, потом я корректирую (обычно спрашиваю — почему) — и так итерационно. С системой подсчета сложно — на глазок + смотрим на статистику. Единица планирования которая пишется — час, понимаемый как 1/8 рабочего дня. Подозреваю что часто реальная единица в которой думается — 4 часа (то есть полдня). Письменный Guidelines отсуствуют, но это связанно с тем что организация маленькая. Зависимости оценок от размеров пунктов — тут у нас поля для экспериментов не было, тем более цифры то характеризуют еще проект и команду. Кстати, вот сейчас пробуем степень детализации поднять в одном проекте и посмотреть что получится. С другой стороны есть общие вещи которые очевидны — например однородность разбиения (отношение оценки объемов минимальной и максимальной подзадач должно быть не больше 5). Вещи, которые так вылезают стараемся перенести в следующую итерацию.

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

Понравилась идея про «количество точек функциональности длиной в один час». Это же применимо и для Scrum с оценкой в «попугаях». Т.е. оценивая задачу на planning poker’e, мы фактически оцениваем количество точек функциональности, только за единицу измерения берём идеальную user story.

Подписаться на комментарии