Ловушка джуниора: почему компании перестали обучать новичков (и как пробиваются «Coached Operators»)
Опубликовано
Классический социальный контракт найма начинающих разработчиков в IT сломался.
Почти три десятилетия технологическая индустрия держалась на негласном экономическом компромиссе. Компании нанимали джуниоров, чья непосредственная производительность на старте была отрицательной. В обмен на выполнение рутины — написание бойлерплейта, мелкие правки интерфейса, базовые CRUD-эндпоинты и подготовку шаблонных юнит-тестов — старшие инженеры инвестировали часы менторства в код-ревью и объяснение архитектуры. Через 18–24 месяца новичок вырастал в автономного инженера уровня Mid, окупая инвестиции компании с процентами.
Между 2023 и 2026 годами этот механизм перестал работать.
Отчёт SignalFire 2026 State of Tech Talent зафиксировал беспрецедентную дивергенцию на рынке инженерных кадров. По сравнению с бенчмарками 2019 года, наём специалистов начального уровня (entry-level) упал примерно на 65% в крупных технологических корпорациях и на 76% в ранних стартапах. При этом наём инженеров в целом оказался куда устойчивее большинства нетехнических функций: спад составил лишь 11% у тех-гигантов, а в стартапах и вовсе был зафиксирован рост на 7%. Рынок не отказался от разработки ПО — он попросту перерубил нижнюю ступень карьерной лестницы.
Одновременно с этим общая среда рекрутинга испытала колоссальную перегрузку. В бенчмарк-отчёте 2026 Recruiting Benchmark Report платформа Greenhouse проанализировала более 640 миллионов откликов в 6 000+ компаниях и зафиксировала, что среднее число заявок на одну вакансию подскочило со 116 в 2022 году до 244 в 2025 году. В то же время внутренние команды рекрутинга сократились на 56%. В условиях резкого падения числа открытых позиций для новичков и стремительного роста пула кандидатов любая вакансия начального уровня сталкивается с экстремальной конкуренцией.
Искусственный интеллект — не единственная причина этого кризиса. Коррекция после масштабного перенайма 2020–2022 годов, подорожание венчурного капитала, волны сокращений и избыток опытных инженеров на открытом рынке сыграли огромную роль. Однако ИИ изменил юнит-экономику на полях: многие рутинные задачи внедрения, которые раньше оправдывали наличие джуниора в штате, опытный разработчик с ИИ-ассистентом закрывает быстрее, чем успеет ввести новичка в курс дела.
Так возникла «Ловушка джуниора» (The Junior Trap): чтобы получить первую работу, нужен реальный практический опыт; но рутинные задачи, на которых этот опыт традиционно накапливался, автоматизированы или поглощены старшими специалистами.
В результате индустрия приближается к серьезному структурному риску: системно недоинвестируя в приток молодых специалистов сегодня, компании выедают кадровый ресурс, созданный в прошлые годы, не готовя ему смену.
Для соискателей старый алгоритм действий больше не работает. Очередное пет-приложение из видеоурока или решение задач с LeetCode Easy знакомят с основами, но в реалиях 2026 года не доказывают готовность к промышленной разработке. Чтобы преодолеть барьер отбора, кандидатам необходимо перестать позиционировать себя как транскриберов синтаксиса и стать Coached Operators: инженерами, которые понимают системные инварианты, уверенно направляют генерацию кода ИИ и демонстрируют реальную зрелость инженерного мышления.
1. Экономика сломанной лестницы
Чтобы разобраться в природе ловушки, необходимо посмотреть на сухие расчеты найма, которыми руководствуются технические менеджеры.
В традиционной команде реальная цена найма джуниора никогда не ограничивалась зарплатой; она определялась альтернативной стоимостью времени сеньора:
Концептуальная модель распределения инженерных ресурсов
ТРАДИЦИОННАЯ МОДЕЛЬ НАСТАВНИЧЕСТВА (ДО 2023)
=============================================
Время старшего инженера:
├── Архитектура, системное проектирование и сложный функционал
└── Интенсивное менторство: код-ревью, передача контекста, парная отладка
Время начинающего инженера:
├── Рутинное внедрение: бойлерплейт, CRUD-эндпоинты, шаблоны тестов
└── Постепенное обучение и накопление компетенций
(Экономический баланс: отрицательный ROI первые 6–9 месяцев; окупаемость при выходе на уровень Mid)
МОДЕЛЬ СЕНЬОРА С ИИ-АССИСТЕНТОМ (2026)
======================================
Время старшего инженера:
├── Постановка спецификаций, системные инварианты и глубокая верификация
└── Управление ИИ-ассистентами: каркасы модулей, генерация тестов, бойлерплейт
Работа ИИ-ассистента:
└── Высокоскоростной синтез шаблонного кода, тест-сьютов и миграций БД
(Экономический баланс: быстрое закрытие рутины без долгой фазы онбординга начинающего специалиста)
Данные платформы Carta по рынку труда стартапов подтверждают долгосрочный переход к более компактным командам: софтверные компании на стадии Series A в 2024 году насчитывали медианно 15 сотрудников против 22 в 2022 году, а исследование компенсаций показывает уменьшение команд на всех стадиях финансирования. В условиях ограниченных бюджетов технические лидеры закономерно направляют ресурсы на найм опытных кадров, которым не требуется полугодовой ввод в проект.
Когда сеньор способен за пару минут развернуть скелет микросервиса, написать юнит-тесты и подготовить миграции с помощью ИИ-ассистента, непосредственное бизнес-обоснование найма новичка под эти задачи перестает существовать.
Парадокс обучения кадров: анализ структурных рисков
| Этап и фаза | Временной горизонт | Динамика рынка и поведение компаний | Системные последствия |
|---|---|---|---|
| Этап 1: Всплеск локальной эффективности | 2023–2025 | Организации становятся компактнее; опытные инженеры берут на себя рутину через ИИ, наём джуниоров замирает. | Затраты на обучение новичков падают почти до нуля; спринтовая скорость команд временно растёт. |
| Этап 2: Разрыв поколений (Текущий этап) | 2025–2027 | Пул соискателей на входе огромен при спаде вакансий на 65–76%. Боты авто-откликов перегружают ATS. | Планка отбора смещается со знания синтаксиса к системной архитектуре, пограничным случаям и отладке. |
| Этап 3: Сценарий: Кадровый обрыв сеньоров | 2028+ | Естественный уход и выгорание опытных инженеров. Слой зрелых мидлов для их замещения отсутствует. | Потенциальный острый дефицит архитекторов; бизнес сталкивается с неподдерживаемым ИИ-легаси. |
Если бизнес годами недоинвестирует в начинающих инженеров, сегодняшняя экономия обернется жестким кризисом преемственности. Однако соискатели не могут ждать, пока корпорации осознают этот риск. Адаптироваться к реалиям Этапа 2 необходимо прямо сейчас.
2. Обесценивание механического написания кода
На протяжении пятнадцати лет курсы, буткемпы и университетские программы готовили людей к одной понятной роли: транскрибер синтаксиса (Code Transcriber).
Задача такого специалиста сводилась к тому, чтобы взять однозначное описание задачи на естественном языке (тикет в Jira, макет в Figma, контракт API) и вручную перевести его в синтаксис языка программирования (JavaScript, Python, Go, SQL).
ОБЕСЦЕНЕННЫЙ СЛОЙ ТРАНСЛЯЦИИ
[Спецификация продукта] ──► [Транскрибер синтаксиса / Джуниор] ──► [Синтаксис кода]
▲
Автоматизировано через LLM
В 2026 году рыночная стоимость простой трансляции мысли в синтаксис стремительно падает.
Это не означает, что написание кода стало бесплатным. Сгенерированный код по-прежнему нужно встраивать в существующее легаси, стыковать с проприетарными API, тестировать на пограничных сценариях и оптимизировать под требования продакшена.
Однако формирование первого черновика синтаксиса больше не является дефицитным навыком. Если резюме кандидата строится вокруг посылов:
- «Знаю React, TypeScript, Express и PostgreSQL»
- «Умею создавать адаптивные REST API»
- «Пишу аккуратный код по шаблонам из обучающих курсов»
...оно рекламирует функцию, которую современные модели выполняют за секунды.
| Критерий | Механический транскрибер (Обесценивается) | Системный инженер (Растёт в цене) |
|---|---|---|
| Ключевой результат | Код, работающий в рамках «happy path» | Чёткие спецификации, инварианты и гарантированное поведение |
| Отношение к коду | Главный продукт и мерило продуктивности | Актив, влекущий постоянные затраты на сопровождение |
| Связка с ИИ | Слепое доверие ответам; копирование блоков | Управление моделью в строгих архитектурных рамках |
| Фокус внимания | Заставить функцию работать в штатном режиме | Анализ отказов, проблем параллелизма и ресурсных лимитов |
| Маркер в портфолио | Шаблонные CRUD-проекты (заметки, списки задач) | Диагностика, постмортемы, бенчмарки и знание глубин ОС и БД |
Чтобы занять устойчивое место на рынке, кандидат должен изменить профессиональную оптику: перестать быть человеком, который набивает код, и стать инженером, гарантирующим устойчивость системы.
3. Ловушка позиционирования: увлечение ИИ без инженерного фундамента
Реагируя на тренды, многие начинающие разработчики пытаются перестроить личный бренд вокруг темы искусственного интеллекта.
Здесь важно провести четкую грань:
- AI Engineering — сложная инженерная область, связанная с инфраструктурой инференса, методиками тестирования (evals), пайплайнами RAG, fine-tuning моделей, векторными базами данных и эффективным распределением памяти GPU.
- Поверхностный промптинг — добавление в резюме плашек вроде «AI Wizard» или «Prompt Specialist» при отсутствии базовой подготовки в Computer Science.
Попытка продать умение промптить как ключевую инженерную компетенцию вызывает у нанимающих менеджеров понятный скепсис. Это свидетельствует об инверсии навыков: кандидат умеет отправить запрос к модели, но не обладает багажом знаний, чтобы определить, насколько полученное решение безопасно, эффективно и устойчиво к сбоям.
Где правдоподобный код ломается в реальной среде
Языковые модели редко выдают очевидные синтаксические ошибки — их мгновенно перехватывают компиляторы и линтеры. Опасность кроется в скрытых архитектурных и семантических уязвимостях:
| Область | Что выдает модель на первый взгляд | Реальность под боевой нагрузкой |
|---|---|---|
| Асинхронный код | Читаемый синтаксис, проходящий простые тесты | Скрытые состояния гонки и порча данных при конкурентных запросах |
| Работа с базами данных | Корректные методы ORM и понятные связи | Отсутствие индексов на внешних ключах $\rightarrow$ full table scan на миллионах строк |
| Сетевые вызовы | Стандартные HTTP-запросы в блоке try/catch | Зависшие таймауты 504, вызывающие лавинообразное исчерпание пула соединений |
| Смена состояния | Прямое вычитание баланса в памяти приложения | Уязвимость к двойному списанию при параллельных транзакциях |
4. Концепция Coached Operator
Если компаниям больше не нужны механические наборщики синтаксиса, какой профиль становится востребованным?
В исследовании поведения продвинутых пользователей ИИ, подкрепленном данными экосистемы Octoverse 2025 (The New Identity of a Developer), команда GitHub отметила важный сдвиг: рабочий процесс разработчика разделяется на три ключевые фазы — понимание задачи, управление генерацией и верификация (understanding, directing, verifying). Среди опытных пользователей инструментов разработчики всё чаще поручают генерацию фрагментов кода ассистентам, оставляя за собой полную ответственность за системную архитектуру, тестирование, валидацию и интеграцию.
Этот подход мы называем моделью Coached Operator (Оператор-супервизор).
Аналогия лежит в эволюции пассажирской авиации. С появлением технологии fly-by-wire и развитых автопилотов авиакомпании не стали заменять пилотов операторами ввода данных. Функция пилота трансформировалась из физического управления штурвалом и механическими тягами в системный надзор: контроль параметров полета, оценка погодных коридоров, анализ навигационных приборов и принятие решений в нештатных условиях.
В современной разработке Coached Operator выполняет схожую роль:
WORKFLOW ДЛЯ COACHED OPERATOR
[Постановка проблемы и системные рамки]
│
▼
┌─────────────────────────────────────────────┐
│ 1. ПОНИМАНИЕ И ФОРМИРОВАНИЕ КОНТЕКСТА │ Схемы данных, инварианты, модели отказов,
│ (Архитектурные границы) │ контракты API и бюджеты задержек p99.
└──────────────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ 2. УПРАВЛЕНИЕ И СИНТЕЗ │ Направление генерации кода ИИ:
│ (Автоматизированная реализация) │ шаблоны, бойлерплейт, черновая логика.
└──────────────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ 3. АДВЕРСАРСКАЯ ВЕРИФИКАЦИЯ │ Аудит пограничных условий, гонок,
│ (Инженерный контроль) │ откатов транзакций и нагрузочные тесты.
└──────────────────────┬──────────────────────┘
│
▼
[Продакшен-верификация]
Coached Operator выстраивает работу по трем строгим принципам:
- Точное задание контекста: до отправки запроса к модели инженер формулирует контракты данных, граничные условия, ожидания по throughput и бюджеты отказов.
- Анализ с позиции критика: сгенерированный код не принимается слепо. Инженер ставит вопросы: Где здесь утечка ресурсов? Что произойдет при обрыве соединения? Гарантирует ли эта транзакция строгую атомарность?
- Ответственность за среду выполнения: оператор понимает, как код поведет себя в продакшене ОС — лимиты cgroups в контейнерах, пулы потоков, блокировки в СУБД, паузы сборщика мусора и распределенная телеметрия.
5. Возвращение к фундаменту: где правдоподобный код бессилен
Современные coding-агенты способны предложить сложный алгоритм, составить план миграции или собрать архитектурный скелет. Проблема не в том, что ИИ не справляется со сложными задачами.
Проблема в том, что модель ИИ не несет операционной ответственности за последствия своих незаметных ошибок.
В критических сценариях правдоподобного на вид кода недостаточно. Независимо от того, кто создал черновик — человек или ИИ, инженер обязан понимать фундаментальные свойства системы, чтобы гарантировать ее надежность.
А. Конкурентность и состояния гонки (Race Conditions)
Генеративная модель легко напишет функцию, которая безупречно пройдет однопоточные тесты, но приведет к потере обновлений (lost updates) в многопоточной среде:
// НАИВНЫЙ ШАБЛОН: Уязвим к потере данных при параллельных запросах
func (s *WalletService) DeductBalance(userID string, amount int64) error {
balance, err := s.db.GetBalance(userID)
if err != nil || balance < amount {
return ErrInsufficientFunds
}
// Переключение контекста или параллельный запрос происходит здесь!
return s.db.SetBalance(userID, balance - amount)
}
// ПРОМЫШЛЕННЫЙ ШАБЛОН 1: Пессимистичная блокировка строки в транзакции
func (s *WalletService) DeductBalanceWithLock(ctx context.Context, userID string, amount int64) error {
return s.db.WithTx(ctx, func(tx *sql.Tx) error {
var balance int64
err := tx.QueryRowContext(ctx,
"SELECT balance FROM wallets WHERE user_id = $1 FOR UPDATE", userID).Scan(&balance)
if err != nil {
return err
}
if balance < amount {
return ErrInsufficientFunds
}
_, err = tx.ExecContext(ctx,
"UPDATE wallets SET balance = balance - $1 WHERE user_id = $2", amount, userID)
return err
})
}
Инженерная зрелость заключается в понимании компромиссов между решениями:
- Хотя конструкция
SELECT ... FOR UPDATEрешает проблему перезаписи баланса, блокировки строк создают контеншен и риски взаимных блокировок (deadlocks) под высокой нагрузкой. - В сценариях с частой записью атомарный условный UPDATE (
UPDATE wallets SET balance = balance - $1 WHERE user_id = $2 AND balance >= $1с проверкой числа затронутых строк) или оптимистичная блокировка с контролем версий обеспечивают кратно более высокую пропускную способность без рисков дедлоков.
Понимание того, какой именно подход выбрать в конкретных условиях, и отличает инженера от того, кто просто компилирует синтаксис.
Б. Распределенные системы и ненадежность сети
Простые учебные примеры исходят из того, что сетевые вызовы выполняются мгновенно и без сбоев. Coached Operator проектирует решения с оглядкой на распределенную реальность:
- Ключи идемпотентности: гарантия того, что повторная отправка сетевого запроса не спишет деньги клиента дважды.
- Паттерн Circuit Breaker и таймауты: защита от каскадного исчерпания пула потоков при падении внешнего сервиса.
- Механизм Backpressure: защита сервисов-обработчиков от падения по OOM, когда очередь наполняется быстрее, чем система успевает ее разбирать.
В. Поведение СУБД и профилирование запросов
Знание базового SQL — это гигиенический минимум. Проектирование систем начинается с понимания планов выполнения (execution plans), селективности индексов и уровней изоляции транзакций:
- Почему классический индекс B-tree, как правило, не помогает ускорить поиск по маске с подстановочным символом в начале (
LIKE '%текст'). - В чем выражаются практические отличия между уровнями Read Committed, Repeatable Read и Serializable.
- Как амплификация записи (write amplification) и циклы компактизации влияют на время чтения в хранилищах на базе LSM-деревьев (например, RocksDB).
6. Как войти в профессию: тактика, основанная на фактах
Если типовой учебный пет-проект больше не позволяет выделиться среди сотен кандидатов, как доказать свою техническую готовность работодателю?
Вот проверенная практическая тактика для начинающих специалистов в 2026 году.
Шаг 1: Обратное код-ревью (Reverse Code Review)
Вместо демонстрации идеальных синтетических проектов, в которых всегда всё работает, покажите умение находить, разбирать и устранять проблемы в реальном софте.
Возьмите открытый репозиторий или опишите собственный контролируемый эксперимент. Зафиксируйте:
- Дефект: скрытую ошибку гонки, утечку памяти или деградацию запроса к БД.
- Анализ первопричины (Root Cause Analysis): профилирование, флеймграфы, дампы памяти или планы
EXPLAIN ANALYZE, наглядно вскрывающие природу бага. - Исправление и регрессионный пакет: код патча, замеры производительности до и после, а также автотесты, исключающие повторение инцидента.
Для технического руководителя способность читать, анализировать и стабилизировать существующий код служит куда более убедительным сигналом, чем очередной написанный с нуля пустой пет-проект.
Шаг 2: Описание архитектурных компромиссов вместо списков фичей
В резюме, профиле на GitHub или портфолио откажитесь от простых перечислений реализованных функций («Сделал авторизацию, темную тему и личный кабинет»).
Замените их описанием принятых инженерных компромиссов:
Было (Формулировка транскрибера кода):
«Создал сервис асинхронной обработки задач на Node.js и Redis.»
Стало (Формулировка Coached Operator — практический кейс):
«Спроектировал сервис асинхронных очередей с пропускной способностью 5 000 задач/сек. Сравнил Redis Streams и RabbitMQ по профилю потребления памяти; выбрал Redis Streams для минимального операционного следа. Реализовал алгоритм exponential backoff с джиттером и очереди dead-letter для защиты воркеров от падения при таймаутах базы данных.»
Шаг 3: Разработка от спецификации (Specification-First)
На технических собеседованиях и в проектах придерживайтесь контрактного подхода:
- Сначала сформулируйте интерфейсный контракт (схемы OpenAPI / Protobuf).
- Затем напишите граничные тесты (фаззинг, тесты на параллелизм).
- Используйте ИИ для черновой генерации реализации.
- В завершение проведите профилирование, бенчмарки и верификацию стабильности.
Получив задачу на интервью, не спешите сразу писать код. Задайте вопросы о требованиях к нагрузке, консистентности данных, сценариях отказа и ограничениях по памяти. Это сразу покажет нанимателю человека, мыслящего архитектурой, а не набором строк.
7. Структурированные доказательства опыта
Главный барьер для начинающих инженеров заключается в том, что традиционный формат резюме — плоский PDF-файл — проектировался под условия ушедшей эпохи.
Классическое резюме обезличивает опыт. Если соискатель указывает в списке навыков «Go, PostgreSQL, Docker, Redis», алгоритм скрининга видит ровно те же четыре слова и у инженера, детально изучавшего внутренности блокировок в базах данных, и у новичка, потратившего вечер на копирование шаблона.
В решении этой задачи заложена ключевая архитектурная идея VedaCarrier.
В современном найме решающее значение имеют только подтвержденные факты:
- Слой резюме: обеспечивает корректную обработку документа парсерами ATS для первичного поиска.
- Слой отклика: выстраивает адресный контекст под конкретные требования вакансии.
- Инженерный слой: формирует доказательную базу инженерной зрелости.
Вместо плоского списка ключевых слов VedaCarrier упаковывает профессиональный багаж в Career Knowledge Graph (Граф карьерных знаний), связывая заявленные компетенции с проверяемыми узлами доказательств:
[Пример узла в Графе карьерных знаний]
PostgreSQL (Навык)
└── контекст: Сервис финансового учета (Проект)
├── инвариант: Атомарное обновление балансов под параллельной нагрузкой
├── решение: Сравнение SELECT ... FOR UPDATE с условным UPDATE
├── реализация: Атомарный условный апдейт с валидацией affected rows
└── подтверждение: Бенчмарк: 0 потерянных транзакций при 50 000 конкурентных запросов
Даже не имея многолетнего опыта в корпоративных структурах, через структурированный граф доказательств соискатель может наглядно продемонстрировать инженерный подход к задачам.
Этот подход открывает возможность для Анализа дефицита доказательств (Evidence Gap Analysis). Классические карьерные сервисы проверяют лишь формальное наличие слов («Вам не хватает навыка Kubernetes»). Граф доказательств оценивает глубину владения:
[Диагностика дефицита доказательств — наглядный пример]
Компетенция: Kubernetes (Присутствует в профиле)
Глубина подтверждения: Низкая
├── Имеющееся подтверждение: Развернут учебный локальный кластер
└── Недостающие инженерные аспекты:
├── Управление ресурсами (лимиты cgroups, настройка requests/limits)
├── Отказоустойчивость (пробы liveness/readiness, обработка сбоев при rollout)
└── Наблюдаемость и сеть (экспорт метрик, сетевые политики NetworkPolicy)
Практическая рекомендация: Подготовьте тестовый сценарий с имитацией внезапного падения подов для верификации бесшовного обновления сервиса.
Вместо того чтобы гадать, какие модные термины добавить в резюме, начинающий инженер получает возможность системно выявлять слабые места в своем портфолио и целенаправленно создавать артефакты, которые подтверждают его квалификацию в глазах нанимающих менеджеров.
8. Итоги
«Ловушка джуниора» — это объективная рыночная реальность, кардинально изменившая путь входа в профессию. Спад найма новичков вызван совпадением целого ряда факторов: переходом к компактным командам, взрослением рынка, возвратом опытных разработчиков и автоматизацией рутинной реализации с помощью ИИ.
Однако закат транскриберов синтаксиса не означает заката профессии инженера.
Отказываясь от поверхностного отношения к коду, отвергая бессодержательный «prompt engineering» и последовательно развивая системное понимание фундаментальных механизмов Computer Science, вы мгновенно выделяетесь на фоне сотен однотипных откликов.
Управляйте инструментами. Верифицируйте результат. Владейте фундаментальными знаниями. Именно так преодолевается карьерный барьер и закладывается основа для долгосрочного профессионального роста.
Источники и материалы
- SignalFire (2026), State of Tech Talent Report 2026 — исследование рынка IT-талантов: падение найма начального уровня на 65% в крупных технологических компаниях и на 76% в ранних стартапах по сравнению с 2019 годом, при сохранении общего спроса на инженеров (-11% в tech majors, +7% в стартапах).
- SignalFire (2025), State of Talent Report 2025 — анализ посткризисной динамики найма: влияние подорожания капитала, реструктуризации команд и автоматизации рутины на сужение возможностей для специалистов без опыта.
- Greenhouse (2026), The Hire Standard: 2026 Recruiting Benchmark Report — исследование более 640 млн заявок в 6 000+ компаниях (2022–2025): рост среднего числа откликов на вакансию со 116 до 244 (+111%) на фоне сокращения штата рекрутеров на 56%.
- GitHub (2025/2026), Octoverse: AI and the Global Developer Landscape и The New Identity of a Developer — данные экосистемы и качественное исследование 22 продвинутых пользователей ИИ: трансформация инженерного процесса в модель «понимание $\rightarrow$ управление $\rightarrow$ верификация», а также данные о том, что ~80% новых разработчиков на платформе в 2025 году использовали Copilot в течение первой недели.
- Carta (2025/2026), State of Startup Compensation and Hiring — бенчмарки рынка труда стартапов, фиксирующие переход к меньшим командам (медианное число сотрудников в software-компаниях на этапе Series A снизилось с 22 в 2022 до 15 в 2024 году) при сохранении инженерного ядра бизнеса.
Комментарии
Рядом с комментарием будет показано ваше имя из профиля.