Мал, да удал: почему пять строк рефакторинга могут сказать о разработчике больше, чем весь его GitHub

Страницы:  1

Ответить
 

Professor Seleznov


Привет, Хабр! Жизнь не стоит на месте, как и мое исследование, так что пришла пора пересмотреть то, как я оцениваю код.
Изначально я опиралась на анализ целых репозиториев — мы вычисляли семантическую плотность и классические метрики кода. Результаты были многообещающими, но на практике я столкнулась с «шумом», который невозможно игнорировать:
  • Проблема «Чужого кода»: в реальных проектах личный почерк автора размыт правками лидов, автогенерацией и legacy-кодом. Да и кто хранит корпоративный код на GitHub?
  • Отсутствие эталона: сравнивать код банковского API и шейдеров для Unity — это как сравнивать соленое с длинным. Модели нужна точка отсчета.
  • Нейрогенерация и «заброшки»: на GitHub часто лежат либо старые учебные проекты, либо быстрые эксперименты, которые не отражают реальный уровень инженера «здесь и сейчас».
Теперь я предлагаю пойти от большего к меньшему: вместо того чтобы изучать весь «организм» (репозиторий), мы возьмем его крошечный образец.
Честно подсмотренная идея
Я решила адаптировать метод, который используют коллеги на собеседованиях: мы даем респонденту заведомо неверный, но рабочий кусок кода. Там есть всё: нарушение SOLID, раздутое наследование, отсутствие DI и «лапша» из данных. Задача инженера — «полечить» его.
Чем больше «архитектурных правок» сделает человек, тем выше его насмотренность и больше опыт. Но как оценить результат объективно и быстро?
Код – это буквально литературное произведение, поэтому будет не зазорно обратить внимание на лингвистически термины. Для оцифровки качества рефакторинга адаптируем два лингвистических параметра, вычисляемых с помощью модели GraphCodeBERT:
  • Плотность решений: Отношение количества архитектурных маркеров (интерфейсы, инъекции, паттерны) к общему числу токенов. Такая метрика позволит оценить уровень «зашумленности» реализации.
  • Семантическая плотность: Концентрация информационной нагрузки в одном блоке кода. Высокий показатель будет свидетельствовать об эффективном использовании архитектурных приемов вместо «воды».
Теоретическая апробация: Зонд против Репозитория
Перейдем к эксперименту: проверим, может ли компактный архитектурный «зонд» объемом всего в 30 строк оказаться репрезентативнее целого репозитория. Этот фрагмент — результат моей совместной работы с нейросетью, синтезированный специально для данного эксперимента.
public interface INotifier
{
string Target { get; }
void Send(string msg);
}
public class EmailNotifier : INotifier
{
public string Target { get; set; }
public void Send(string msg) => Console.WriteLine($"To {Target}: {msg}");
}
public class OrderProcessor
{
private readonly IEnumerable _admins;
public OrderProcessor(IEnumerable admins)
{
_admins = admins;
}
public void ConfirmOrder(int id)
{
var validAdmins = _admins.Where(a => !string.IsNullOrWhiteSpace(a.Target));
foreach (var admin in validAdmins)
{
admin.Send($"Order {id} confirmed");
}
}
}
Теперь рассчитаем и сравним заявленные выше метрики для 9 репозиториев из выборки в статье о GrafCodeBert и для данного "идеального" кода.
Результаты в таблице говорят сами за себя.
Источник Плотность решений (DD, %) Семантическая плотность (SL)
Репозиторий №0 1.94 0.029
Репозиторий №1 1.34 0.063
Репозиторий №2 2.85 0.040
Репозиторий №3 6.11 0.025
Репозиторий №4 2.40 0.034
Репозиторий №5 4.81 0.031
Репозиторий №6 3.79 0.034
Репозиторий №7 1.63 0.041
Репозиторий №8 0.74 0.034
Среднее по репозиториям 2.84 0.037
Архитектурный зонд 1.47 0.108

В среднем, при высокой плотности решений в репозиториях, видна низкая семантическая плотность, особенно в сравнении с зондом.
pic
Сравнение метрик для средних значений по репозиториям и для зонда
Что же, математически мы доказали, что зонд лучше. Пришло время понять, как его использовать для оценки грейда.
Путь до идеала и дальше
Чтобы оценить решение кандидата, нам нужно проверить, насколько близко он подошел к задуманному архитектурному эталону. В процессе исследования, пришлось отказаться от расчета линейного расстояния между векторами в пользу векторной проекции.
pic
Визуальное объяснение расчета показателя K (спасибо gemini за иллюстрацию)
Таким образом мы измеряем «длину пути», пройденного от сломанного кода к "идеалу", выраженного в переменной K. Если K выше единицы — значит, человек предложил решение даже более эффективное, чем выбранный эталон.
Апробация на реальности
Апробировать методику было решено на реальных людях. Респонденты делились своим опытом, грейдом, навыками в теории и правили "сломанный" зонд. Опрос все еще активен, он занимает не больше 10 минут.
Полученные ответы я использовала для расчета TSI (подробнее вот в этой статье) и K-score – то, насколько близко к идеалу респондент поправил код в промежутке от сломанного до идеального.
Логика вычисления результирующего грейда была следующей:
pic
Дерево решений, визуализированное gemini
Результаты и пояснения уже были разосланы тем, кто прошел опрос и захотел их узнать. (Очень надеюсь, что они никого не разочаровали ^_^) А теперь пришла пора посмотреть на общие обезличенные результаты.
pic
Сравнение самооценки и высчитанного грейда
pic
Визуализация близости решений к "идеалу"
Анализ реальных кейсов подтвердил применимость моих идей. Сводные данные подтверждают: даже на малой выборке предложенный семантический зонд позволяет идентифицировать грейд специалиста с точностью, сопоставимой с многочасовыми скринингами.
Выводы
Разрабатываемый подход — это не замена собеседованию, но мощный инструмент «доказательного грейдирования». Он более гибкий, чем стандартные системы, и позволяет за считанные минуты получить объективный инженерный паспорт, минимизируя человеческий фактор и предвзятость. И самое вдохновляющее здесь — это результаты K > 1, когда человек находит решение изящнее и эффективнее выбранного эталона.
Буду рада вашим комментариям и предложениям. Чем больше вы делитесь собственным опытом и указываете на "проблемные" места, тем значимее будет итоговый результат😉.-Источник
 
Loading...
Error