Привет, Хабр! В прошлых статьях я описала, как через нововведенный параметр TSI теоретически можно определить грейд разработчика.

Для тех, кто пропустил первую часть: TSI (Topological Seniority Index) — это метрика, которая нивелирует мусор в вакансиях и позволяет отразить качественный скачок при переходе между грейдами. Она считается исходя из суммы взвешенной мощности стека, уровня ответственности и архитектурного признака в списке требований.

Но до этого мы говорили только про один язык – C#. Пора натянуть созданную мной сову на три других языка: Java, Python и Go.

Почему эти языки?

Выбрать язык для анализа – это не пальцем в небо ткнуть. Если C# я брала, потому что это мой основной язык, то Java и Python я знаю только по учебным работам и пет-проектам, а Go мне вообще не знаком.

Но на самом деле такой выбор очень красиво ложится в исследование: Java – бессмертная классика с большой историей, Python – модный в свое время мультитул, а Go – современный синоним Highload систем.

Сравнить картину рынка для четырех языков суммарно – значит оценить уже не локальный рынок, а вполне себе общий. Может, не везде так грустно и пора учить что-то новое? (так-то в любом случае пора, но все же)

Наш любимый EDA

Начнем с разведывательного анализа. Нас интересуют два вопроса: как ведет себя количество требований к каждому году опыта и как ведет себя уровень ответственности в зависимости от года опыта.

Начнем с нашего динозаврика - Java.

Объем требований и уровень ответственности на каждый год опыта для Java
Объем требований и уровень ответственности на каждый год опыта для Java

Что удивительно, с ростом опыта растет и количество требуемых навыков. Не график, а просто красота: тут тебе и плавный рост, и отсутствие завышенных требований к новичкам. Еще и уровень ответственности распределен между значением в 3 и 4 единицы.

У Python же все по-старому: тут и всплеск требований к новичкам, и падение количества требований к 6 году опыта, что демонстрирует близость к инструментальному плато. Только вот уровень ответственности пугает: 4 единицы на старте и этот минимум.

Объем требований и уровень ответственности на каждый год опыта для Python
Объем требований и уровень ответственности на каждый год опыта для Python

Страшнее всего смотреть на графики по Go: 12 требований на старте! И это не максимум! На 3 и 4 годах опыта – инструментальное плато, а дальше – очередной рост. Уровень ответственности так же не дает расслабиться: от 3,5 единиц в среднем и выше.

Объем требований и уровень ответственности на каждый год опыта для Go
Объем требований и уровень ответственности на каждый год опыта для Go
Скрытый текст

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

Краткий вывод: Java – мой фаворит. Последовательный, стабильный, без особых всплесков и аномалий. Python и Go же страдают все теми же проблемами, только в больших масштабах: времени на раскачку они не дают. Вызвано ли это перенасыщением рынка или чем-то другим – вопрос открытый.

Попытки кластеризации в лоб и с TSI

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

Результаты кластеризации слева направо: Go, Java, Python
Результаты кластеризации слева направо: Go, Java, Python

А теперь применяем методику TSI: помечаем, есть ли у нас архитектурные навыки, используем матрицу встречаемости навыков и удваиваем уровень ответственности. В итоге нас встречает очень такая себе представительная картина.

Результаты кластеризации слева направо, сверху вниз: Go, Java, Python
Результаты кластеризации слева направо, сверху вниз: Go, Java, Python

Не будем сейчас говорить о том, в каких плоскостях лежат грейды. Важно другое: мы получили РАЗДЕЛИМЫЕ кластеры. Мы МОЖЕМ назвать грейд по близости к центроиду.

Суровая теоретическая реальность

Теперь мы можем попытаться сравнить ненормализованные средние значения TSI грейдов для уже четырех языков.

Язык / Среднее значение

Junior

Middle

Senior

Java

81,34

88,02

151,56

Python

75,16

150,6

204,26

Go

102,56

119,52

166,84

C#

20,88

36,59

144,1

Эта таблица наглядно показывает: всегда есть предел обобщению. TSI прекрасно работает в локальном формате. Формула действительно улавливает усложнение требований и успешно фильтрует HR-шум. Но натягивать штаны C# на Go – крайне плохая идея.

Зато мы можем сделать выводы о том, как меняются требования к грейдам внутри языков:

1. C# — Низкий старт и «квантовый скачок»

У шарпа самый низкий порог входа (20.88). Переход к Middle тоже достаточно плавный (36.59). Зато громадная пропасть между Middle и Senior (со 36 до 144 баллов). Это ярчайшая демонстрация работы «архитектурного рычага». Чтобы стать сеньором в .NET, недостаточно просто выучить больше библиотек — нужно качественно изменить подход к проектированию.

2. Java — Энтерпрайзная стабильность

Стоит обратить внимание на минимальный разрыв между Junior (81.34) и Middle (88.02). В мире Java разница между джуном и мидлом семантически стирается. Скорее всего (я откуда знаю, я не джавист) они работают с похожим инструментарием (у нас все еще нет инструментального плато), просто Middle, вероятно, делает это с меньшим количеством багов. А вот чтобы стать Senior (151.56), придется серьезно нарастить архитектурную экспертизу.

3. Python — Самая крутая лестница

Python завлекает сравнительно низким порогом входа (75.16), но дальше начинается выживание. Планка Middle взлетает ровно в два раза (150.6) за счет уровня ответственности при инструментальном плато, а Senior требует космических 204 баллов (абсолютный рекорд среди всех языков). Это плата за универсальность: синтаксис прост, но для реального роста придется погрузиться в необъятный зоопарк фреймворков, MLOps, Data Science и тяжелого бэкенда.

4. Go — Суровый мир Highload

Судя по цифрам Go действительно не для новичков. Требования к Junior Go-разработчику (102.56) математически выше, чем к уверенному Middle в C# или Java. Это частично доказывает, что в Go редко приходят как в первый язык. От Junior'a здесь с порога требуют понимания микросервисов, конкурентности и системного мышления.

Итоги

Итоги на самом деле простые:

·        Оправдывает ли себя методика? Да оправдывает

Мы натянули "сову" C# на глобус других языков и увидели три абсолютно разные картины мира. Java показала себя как стабильный легаси-океан. Python продемонстрировал классический хайп с инструментальным плато, а Go оказался перегретым котлом, где от джунов хотят уровня архитекторов.

·        Можно ли усомниться в результатах? Конечно можно.

Но даже на этих данных (в среднем по 500 вакансий) TSI доказал свою математическую универсальность: алгоритм смог вычленить линейно разделимые кластеры там, где обычный K-Means захлебнулся бы в информационном шуме. Методика работает, а уж получится ли мне ее куда-то на практике применить...