Привет, Хабр! Жизнь не стоит на месте, как и мое исследование, так что пришла пора пересмотреть то, как я оцениваю код.

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

  • Проблема «Чужого кода»: в реальных проектах личный почерк автора размыт правками лидов, автогенерацией и legacy-кодом. Да и кто хранит корпоративный код на GitHub?

  • Отсутствие эталона: сравнивать код банковского API и шейдеров для Unity — это как сравнивать соленое с длинным. Модели нужна точка отсчета.

  • Нейрогенерация и «заброшки»: на GitHub часто лежат либо старые учебные проекты, либо быстрые эксперименты, которые не отражают реальный уровень инженера «здесь и сейчас».

Теперь я предлагаю пойти от большего к меньшему: вместо того чтобы изучать весь «организм» (репозиторий), мы возьмем его крошечный образец.

Честно подсмотренная идея

Я решила адаптировать метод, который используют коллеги на собеседованиях: мы даем респонденту заведомо неверный, но рабочий кусок кода. Там есть всё: нарушение SOLID, раздутое наследование, отсутствие DI и «лапша» из данных. Задача инженера — «полечить» его.

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

Код – это буквально литературное произведение, поэтому будет не зазорно обратить внимание на лингвистически термины. Для оцифровки качества рефакторинга адаптируем два лингвистических параметра, вычисляемых с помощью модели GraphCodeBERT:

  1. Плотность решений: Отношение количества архитектурных маркеров (интерфейсы, инъекции, паттерны) к общему числу токенов. Такая метрика позволит оценить уровень «зашумленности» реализации.

  2. Семантическая плотность: Концентрация информационной нагрузки в одном блоке кода. Высокий показатель будет свидетельствовать об эффективном использовании архитектурных приемов вместо «воды».

Теоретическая апробация: Зонд против Репозитория

Перейдем к эксперименту: проверим, может ли компактный архитектурный «зонд» объемом всего в 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<INotifier> _admins;

    public OrderProcessor(IEnumerable<INotifier> 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 (спасибо gemini за иллюстрацию)

Таким образом мы измеряем «длину пути», пройденного от сломанного кода к "идеалу", выраженного в переменной K. Если K выше единицы — значит, человек предложил решение даже более эффективное, чем выбранный эталон.

Апробация на реальности

Апробировать методику было решено на реальных людях. Респонденты делились своим опытом, грейдом, навыками в теории и правили "сломанный" зонд. Опрос все еще активен, он занимает не больше 10 минут.

Полученные ответы я использовала для расчета TSI (подробнее вот в этой статье) и K-score – то, насколько близко к идеалу респондент поправил код в промежутке от сломанного до идеального.

Логика вычисления результирующего грейда была следующей:

Дерево решений, визуализированное gemini
Дерево решений, визуализированное gemini

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

Сравнение самооценки и высчитанного грейда
Сравнение самооценки и высчитанного грейда
Визуализация близости решений к "идеалу"
Визуализация близости решений к "идеалу"

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

Выводы

Разрабатываемый подход — это не замена собеседованию, но мощный инструмент «доказательного грейдирования». Он более гибкий, чем стандартные системы, и позволяет за считанные минуты получить объективный инженерный паспорт, минимизируя человеческий фактор и предвзятость. И самое вдохновляющее здесь — это результаты K > 1, когда человек находит решение изящнее и эффективнее выбранного эталона.

Буду рада вашим комментариям и предложениям. Чем больше вы делитесь собственным опытом и указываете на "проблемные" места, тем значимее будет итоговый результат😉.