Разговор про Java обычно ведут в прошедшем времени, а вакансии на ней публикуют в настоящем. Это расхождение стоит разобрать, потому что решение о языке принимает не мода, а тот, кто платит за содержание системы десять лет.
Тупик: судить по разговорам
Первое, что пробуют, — оценить язык по тому, сколько о нём говорят: сколько новых проектов на конференциях, сколько восторгов, сколько статей. Метрика доступная и понятная.
Она не помогает, потому что меряет не то. Разговоры отражают приток нового, а не объём работающего. Язык, на котором написана половина того, что уже крутится в банках, страховых и телекоме, будет упоминаться редко — обсуждать нечего, оно просто работает. И наоборот, язык, на котором пока написано мало, но который пробуют, будет на слуху непропорционально.
Для решения «на чём писать новый сервис» эта разница критична: вас интересует не громкость, а то, во сколько обойдётся содержание через пять лет и найдёте ли вы людей.
Вторая привычная подмена — судить по числу вопросов на публичных площадках. Здесь ловушка тоньше: поток вопросов иссяк по всем языкам сразу, и накопленный объём отражает не сегодняшнюю распространённость, а то, сколько лет язык прожил в эпоху, когда вопросы писали публично. Молодой язык проиграет по этой мере даже при бурном росте, а старый выиграет, даже угасая.
Что Java даёт из того, что редко называют
Совместимость через годы. Код, собранный давно, обычно продолжает работать на новой версии среды выполнения. Для системы, живущей десятилетие, это не удобство, а статья расходов, которой не возникает. В экосистемах, где обновление мажорной версии означает переписывание, эта статья появляется регулярно и в смету попадает поздно.
Предсказуемость под нагрузкой. Среда выполнения умеет держать высокую пропускную способность на долгих процессах и хорошо изучена: поведение под памятью, поведение сборщика мусора, поведение при разогреве описаны и воспроизводимы. Для систем, где важна не рекордная скорость, а отсутствие сюрпризов, это весомее любого бенчмарка.
Инструменты для разбора проблем. Профилировщики, снимки памяти, трассировка, анализ пауз — всё это существует давно, работает на боевых системах и не требует изобретательности. В момент, когда что-то идёт не так в три часа ночи, зрелость инструментов стоит дороже элегантности языка.
Рынок людей. Инженеров, знающих язык, много, и они распределены по всем уровням: есть кого нанять и есть кому учить. Для редкого языка верно обратное, и это отдельная строка в стоимости решения.
Понятность решений для чужого. У языка с длинной историей сложились устойчивые способы делать типовые вещи, и новый человек в проекте узнаёт их без объяснений. Это неочевидная экономия: она не видна в момент найма, но проявляется в скорости, с которой человек начинает приносить пользу.
Где она проигрывает
Честный разбор требует назвать и обратное, иначе получится реклама.
Старт процесса и потребление памяти. Там, где нужно поднимать сотни коротких процессов или укладываться в тесную квоту, характеристики среды выполнения работают против вас. Это территория, где выигрывают языки с меньшим базовым расходом.
Многословность и обрядность. Часть её снята современными версиями языка, часть осталась в накопленной культуре: фреймворки, слои, конфигурация. На небольшой задаче это заметный налог, и он платится временем разработчика, а не машины.
Скорость выхода первой версии. Для проверки гипотезы, которую, возможно, выбросят через месяц, тяжёлая экосистема — не преимущество. Здесь выигрывают языки, где от идеи до работающего прототипа короче путь.
Инерция экосистемы. Обилие готовых решений оборачивается тем, что типовой проект тянет за собой много чужого кода, а вместе с ним — обновления, уязвимости и чужие решения, принятые за вас.
Порог входа в существующий проект. Накопленная культура слоёв и конфигурации означает, что новый человек разбирается не с задачей, а с тем, как в этом конкретном проекте принято делать простые вещи. Плата за длинную историю берётся именно здесь.
Как выбирать на самом деле
Вопрос «хороший ли язык» подменяет собой вопрос, который действительно надо решить: какой у системы срок жизни и кто будет её содержать.
Для системы, которую пишут на годы, у которой много интеграций и высокая цена ошибки, аргументы про совместимость, предсказуемость и рынок людей перевешивают многословность. Для сервиса, который может быть переписан за неделю, они не значат ничего.
Отсюда практическое правило: сначала оцените срок жизни и цену отказа, потом смотрите на язык. Обратный порядок приводит к спорам о вкусах, потому что без этого контекста аргументы обеих сторон одинаково верны.
Второе соображение — про команду, а не про код. Язык, который знают двое из десяти, создаёт узкое место в дежурстве и в отпусках. Это не довод против, это довод за то, чтобы посчитать, сколько людей вы готовы обучить и за какой срок.
Третье — про то, что вокруг. Язык редко выбирают в пустоте: рядом уже есть системы, с которыми новая будет разговаривать, и команда, которая её будет содержать. Сервис на языке, которого нет больше нигде в компании, платит дважды: за отдельный конвейер сборки и за отдельный набор знаний, который придётся поддерживать вживую. Иногда это оправданно, но считать надо обе статьи, а не только удовольствие от языка.
Полезно и проверить решение на худшем сценарии. Представьте, что человек, написавший систему, ушёл, а она сломалась в выходные. Насколько быстро оставшиеся разберутся, есть ли инструменты, найдётся ли по ошибке хоть что-то осмысленное. Ответ на этот вопрос обычно сдвигает выбор сильнее, чем сравнение синтаксиса.
Позиция редакции
Мы считаем, что Java остаётся разумным выбором для систем с долгим сроком жизни и высокой ценой отказа, и что решение стоит принимать по сроку жизни и составу команды, а не по тому, о чём чаще говорят. Практический вывод: если вы затрудняетесь ответить, сколько лет проживёт система, вопрос о языке ещё не созрел — сначала ответьте на первый.
Мы неправы, если задача — быстро проверить гипотезу и отбросить её. Там стоимость содержания через пять лет не существует как величина, и все перечисленные аргументы теряют силу; выбирать надо по скорости выхода первой версии.