|
|
|
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 |
В среднем, при высокой плотности решений в репозиториях, видна низкая семантическая плотность, особенно в сравнении с зондом.

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

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

Дерево решений, визуализированное gemini Результаты и пояснения уже были разосланы тем, кто прошел опрос и захотел их узнать. (Очень надеюсь, что они никого не разочаровали ^_^) А теперь пришла пора посмотреть на общие обезличенные результаты.

Сравнение самооценки и высчитанного грейда

Визуализация близости решений к "идеалу" Анализ реальных кейсов подтвердил применимость моих идей. Сводные данные подтверждают: даже на малой выборке предложенный семантический зонд позволяет идентифицировать грейд специалиста с точностью, сопоставимой с многочасовыми скринингами. Выводы Разрабатываемый подход — это не замена собеседованию, но мощный инструмент «доказательного грейдирования». Он более гибкий, чем стандартные системы, и позволяет за считанные минуты получить объективный инженерный паспорт, минимизируя человеческий фактор и предвзятость. И самое вдохновляющее здесь — это результаты K > 1, когда человек находит решение изящнее и эффективнее выбранного эталона. Буду рада вашим комментариям и предложениям. Чем больше вы делитесь собственным опытом и указываете на "проблемные" места, тем значимее будет итоговый результат😉.-Источник
|
|
|
|