Как измерить программиста

[Об авторе: Руслан Дмитракович — разработчик ПО и предприниматель, в ИТ-индустрии с 1994 года. Пионер интернет-рекламы в Украине: основатель Украинской баннерной сети, рекламного агенства «Интернет-эксперт». Создатель проекта Code X-ray — повышение эффективности работы команд разработчиков на основании статического анализа кода]

Решил свой рост узнать удав!
И в этом он, конечно, прав.
Ведь это важно очень!
Возможно, он длиннее всех!
Во много раз длиннее всех!
«38 попугаев» Г. Остер


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

Иллюстрация Ульяны Морозовой

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

Отнеситесь к описанному ниже как к гипотезе, которую можно проверить на себе и своих коллегах. Я описал лишь часть того, что получил в ходе анализа. Начиная исследовать данную тему, я даже не представлял количество возможных направлений анализа и те объёмы данных, с которыми прийдётся иметь дело. Работая почти три десятка лет в индустрии разработки ПО, увидеть код в таком ракурсе было для меня неожиданностью.

Не все программисты «одинаково полезны»

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

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

В работе программиста не все так однозначно. Что является «продукцией» в данном случае? Например, программист Николай, решая задачу, будет, не вставая со стула, стучать по клавиатуре три дня и создаст множество кода.

Программист Василий, обдумывая решение, будет гулять по кухне, общаться с коллегами и бездельничать другими самыми разными способами. Однако за те же три дня выдаст решение, которое по объёму кода в несколько раз меньше, понятнее его коллегам и к тому же работает быстрее. И в том и другом случае задача решена, результат получен. Можно ли сравнить Василия и Николая? Например, чтобы выбрать, кого из них сделать руководителем группы.

Но что, если мы захотим подойти к вопросу объективно? Какие показатели будем измерять? Объем написанного кода? Количество решённых задач? Попытки применять такие метрики для оценивания работника ни к чему хорошему не приводили. Зная, какой именно показатель измеряется, специалист начинает им манипулировать: писать лишний код или разбивать задачи на более мелкие.

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

Оцениваем качество работы

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

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

Понятия «легаси» и «говнокод» прочно вошли в лексикон разработчиков ПО. Надо понимать, что говнокодом принято называть код, несущий избыточную когнитивную нагрузку. Чем меньше эта нагрузка, тем быстрее разбирается программист с кодом и тем меньше ошибается. Почему так происходит, можно почитать, например, у Даниэла Канемана в книге «Думай медленно, решай быстро» или у Дэвида Рока «Мозг. Инструкция по применению».

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

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

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

Я не предлагаю создавать некую универсальную формулу для оценки. Каждая конкретная метрика сложности должна рассматриваться отдельно. Это позволит обратить внимание на конкретный недостаток — и, как следствие, улучшить работу. Однако теперь у нас есть объективные показатели, по которым можно делать сравнение качества работы.

Пример

Наконец удав почувствовал, что его дёргают за хвост!
«Ага! — подумал удав. — Начали измерять!»


Чтобы не быть голословным и показать, как это работает, рассмотрим реальный проект примерно на полмиллиона строк кода. Возьмём трёх программистов, сделавших в проект значительный вклад.

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

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

Для построения графиков использовались цикломатическая сложность, средний размер метода (в строчках кода), композитные метрики: weighted methods per class и сопровождаемость кода (maintainability).

Как видно из графиков, синяя кривая находится выше, что означает более сложный код, написанный программистом DEV-1. Программисты DEV-2 и DEV-3 пишут код примерно одинаковой сложности. Формально все они имеют одну и ту же квалификацию, но анализ показывает, что между их кодом есть ощутимая разница. Особенно интересны эти данные, когда тебе известен опыт людей, отношение к ним в коллективе и их самооценка.

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

Измеряем производительность

А как насчёт производительности? Есть мнение, что измерить ее в масштабах всего бизнеса невозможно, и с этим я спорить и не буду. Однако если оперировать не деньгами, полученными от работы ПО, а артефактами внутри программного проекта, то кое-что измерить можно. Корреляция между объёмом кода (строк, классов, методов и т. д.), написанного программистом, и функциональностью программы есть. Однако значимость кода в проекте не одинакова.

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

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

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

Однако как определить формально, какой код имеет больший вес? В своё время похожую задачу решали создатели Google по отношению к документам в интернете. И если мы можем использовать Page Rank для определения важности документа, то почему бы не применить его к коду?

Итак, вкладом программиста в проект я буду называть объем написанного кода, умноженный на его PR. Следует понимать, что считать его также можно по-разному, и дело не в абсолютной точности, а в возможности сравнения.

Пример

И снова посмотрим, как это выглядит на примере нашего проекта.

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

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

Те же данные в виде таблицы:

РазработчикиСтрок кодаСтрок кода, %ПакетовВклад, %
DEV-150К9366.94
DEV-236К7288.37
DEV-323К4156.2

Больше всего пишет DEV-1 (50 тысяч строк, или 9% кода проекта), но его средняя ценность почти в два (!) раза меньше, чем у DEV-3. Если учесть, что этот код ещё и более сложный, то можно понять, откуда берётся легаси — чем сложнее код и чем его больше, тем тяжелее его сопровождать. В какой-то момент может оказаться, что лучше такой код вообще не трогать...

И напоследок посмотрим, как выглядит вклад разных команд (по три разработчика в каждой).

Как видим, команды более-менее сбалансированы, вклад в проект у них примерно одинаковый.

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

Ну, и любопытный вывод для команды 2. Очень похоже, что техлид в ней действует по принципу «Хочешь сделать хорошо — сделай это сам»...

Выводы

— Теперь, — воскликнул удав, — когда приедет моя бабушка и скажет:
Ну, внучок, ты, кажется, вырос!" — я ей отвечу: «Да, бабушка, я вырос».
И я скажу ей свой рост в попугаях!


Если вы посмотрите полюбившийся многим «Чистый код» Боба Мартина, вы не найдёте чёткого определения, что этот самый «чистый код» собой представляет. Это свидетельствует о том, что у большинства есть только интуитивное представление, «что такое хорошо, и что такое плохо» по отношению к коду. В ходе данной работы я попытался объяснить это показателями, которые можно измерить.

Попытаюсь резюмировать. Чистый код — это код с минимальной когнитивной нагрузкой. Когнитивная нагрузка может быть оценена при помощи метрик сложности. Хороший программист (для долгосрочного проекта) — тот, который «инвестирует» в будущее — увеличивает количество кода, который можно переиспользовать и минимизирует сложность, которая тормозит развитие.

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

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

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

Похожие статьи:
«Аеророзвідка» — волонтерська ініціатива 2014 року, яка згодом переросла у бойовий підрозділ і громадську організацію, що займаються...
Компания ZTE анонсировала новый смартфон Nubia Prague S, который является наследником вышедшего летом ZTE Nubia My Prague. Устройство оборудовано...
Твердження про те, що між університетською освітою в Україні й реальними вимогами на ринку IT існує прірва, не нове. Мовляв,...
Коли я закінчувала політехнічний інститут, зрозуміла, що настав час обирати серйозну роботу. Раніше лабораторну...
На думку керівника Держспецзвʼязку Юрія Щиголя, у поїздах Укрзалізниці супутниковий інтернет від Starlink...
Яндекс.Метрика