Выпуск 67 · подкаст «Тысяча фичей»

#67: Java и Spring в 2026

2:25:26

Александр Пахомов и Миша Поливаха — практикующий Java-разработчик, стоявший у истоков сообщества Spring.io, — разбирают, на чём держится Java в 2026-м. Почему энтерпрайз не переписывает и не апгрейдит (патчинг CVE для Java 6 как живой бизнес), как Spring выиграл у Java EE на скорости эволюции и правильных продуктовых решениях Рода Джонсона и команды Spring Boot, чем занят Project Leyden и почему AppCDS отбирает у Quarkus его главное преимущество. Вторая половина — спор двух подходов: для гостя тулинг это IDE, стартеры и dev mode, для ведущего, который код руками не пишет, — quality gates, которыми обкладывают агента; отсюда претензии к Java-экосистеме на фоне `clippy --fix`, история отказа OpenJDK принимать сгенерированные PR и финальное расхождение о том, можно ли нарастить экспертизу, не написав код руками.

Главное

  • Java держится в энтерпрайзе не техническим превосходством, а консолидацией экосистемы: одна проблема — один канонический способ решения, единый «паровоз» (виртуальные потоки Spring поддержал сразу) и взаимозаменяемость инженеров между командами.
  • Java EE проиграла Spring на скорости: спецификации согласовывались годами (многострадальный JSR-305 в итоге отозвали, а JSpecify появился уже силами консорциума — Google, JetBrains), и Oracle в конце концов отдал javax в Eclipse Foundation.
  • Ключевых решений у Spring два: Spring Boot признал, что 80% конфигурации никто не переопределяет, и дал дефолты; и Spring не поворачивался спиной к экосистеме — в отличие от Quarkus, который заперся в Jakarta EE и остался «чёрным лебедем» со своими реализациями всего.
  • Project Leyden и AppCDS съедают главное преимущество Quarkus — быстрый старт. Команды Oracle и Spring работают настолько плотно, что Spring PetClinic фигурирует в официальных JEP'ах как референсная имплементация.
  • У собеседников разное понимание тулинга: для Поливахи это то, что помогает писать код (IDE, стартеры, Docker Compose Starter, dev mode), для Пахомова, который код руками не пишет, — quality gates, которыми обкладывают агента, чтобы проще брать на себя ответственность за его код.
  • Претензия к Java: в Rust `clippy --fix` и `rustfmt` идут батарейкой вместе с языком и снимают сам спор о стиле, а в Java форматтеры и статические анализаторы собираются плагинами — и обсуждения code style живы до сих пор. Контраргумент гостя: это вопрос инженерной культуры и экспрессивности языка, а не тулинга.
  • Долгий Java-билд — это почти всегда тесты (подъём Spring-контекстов, Testcontainers), а не компиляция: монорепа Axelix с полутора тысячами тестов собирается за две-три минуты.
  • OpenJDK отказался принимать сгенерированные pull request'ы, потому что у них боттлнек не в написании кода, а в дизайне и согласовании совместимости. Пахомов видит в этом риск остаться за бортом, Поливаха — разумную выжидательную позицию, как у Линуса Торвальдса: «несите ответственность за свой код».

В выпуске

  • Миша ПоливахаПрактикующий Java-разработчик, стоял у истоков сообщества Spring.io. Разрабатывает в опенсорсе Axelix — мониторинговое решение для Spring Boot-приложений. Выступает на конференциях (JPoint, Spring.io, Devoxx).
Расшифровка

[00:00] Александр: Всем привет! Это подкаст «Тысяча фичей». У меня в гостях Миша Поливаха — практикующий Java-разработчик, человек, который стоял у истоков (я это подчёркиваю — у истоков) создания сообщества Spring.io. Миша выступает на конференциях — на JPoint, на Spring.io и на Devoxx. Сегодня в подкасте мы будем разгонять про Java, Spring, Quarkus, Claude Code, современное программирование на JVM-стеке. Будет интересно, так что заваривайте чаёк, кофеёк, надевайте наушники поплотнее — можно даже, например, пойти погулять в парк и послушать, потому что разговор будет интересный. Миша, привет!

[00:35] Миша: Привет, Саша, привет!

[00:51] Александр: Мы хотели начать с такого, знаешь, обзорного разговора: а что сейчас у нас вообще в Java-стеке, в JVM-мире происходит, какие технологии на слуху, какие используются, какие вообще стоят нашего внимания. Давай с этого ракурса зайдём в мир Java.

[01:05] Миша: Ты знаешь, Java — во многом интересный язык с точки зрения того, что у него есть уже установленная и проверенная временем ниша, в которой его как язык и как платформу довольно сложно сместить, потеснить и так далее. В основном это enterprise: серверная мощность, обслуживание каких-то бэкенд-систем, процессинг внутри банковской сферы, брокерский процессинг, страховые компании, авиалинии и так далее. Всё, что мы сейчас из крупных бизнесов возьмём, — там на бэкенде чаще всего Java. И что интересно: со временем это не сильно менялось, даже с учётом появления Go, с учётом появления C#. Java в ряде случаев позиции этим языкам отдала — то есть эти языки действительно часть ниш заняли, это объективно так, — но в целом она остаётся именно таким backbone, я бы выразился, основным хребтом enterprise. И одна из отличительных особенностей, которую большинство людей, всю жизнь программировавших в рамках экосистемы Java и не выходивших за рамки JVM, наверное, не замечают: что в других языках на каждый чих есть своя библиотека. То есть они решают все проблемы таким образом: у меня есть библиотека, которая даёт мне возможность форматировать даты, например. А в Java у тебя есть непосредственно отдельный модуль, который этим занимается: вот java.time, есть DateTimeFormatter — и ты можешь ему сказать форматировать дату так, как тебе душе угодно; там есть потокобезопасные инструменты в рамках Java, которые позволяют это делать. Но даже дело не в этом, а в том, что у Java очень зрелая и стабильная JDK — сам Development Kit долгое время полировался. А в ряде других языков сам по себе SDK и вообще то, что даёт язык, — довольно скудное пространство. Вот в JavaScript это так, и поэтому очень много библиотек просто на все-все случаи жизни. Есть даже шутки: грубо говоря, у нас есть крупное решение, и весь наш стек работает на библиотеке, которую написал тинейджер из Небраски, который её забросил, когда поступил в колледж.

[04:05] Александр: А эта шутка — доля шутки в ней действительно есть?

[04:08] Миша: Конечно, доля шутки — потому что это всё мы знаем. Есть даже, знаешь, такой веб-сайт с мемами про программистов, и там вся экосистема, вся эта архитектура современного софта представляет собой такую пирамиду — и эта пирамида стоит на маленькой-маленькой тоненькой палочке, а у палочки рядышком есть приписка, что это какая-нибудь библиотека. В Java, например, это в своё время был cglib, на котором Spring сидит и так далее. Ну, он до сих пор на cglib сидит — можем обсудить, почему. Эта палочка — какая-то небольшая библиотека, которая решает очень конкретную проблему, а на ней сидит вообще весь стек. Вот, проксирование объектов просто.

[04:50] Александр: Слушай, интересно. Ты сейчас такую тему затронул: что Java — это огромный стек именно с точки зрения того, где он используется, по объёму. То есть это большое количество бэкендов и систем, написанных сейчас на этом языке, и эта ниша устоявшаяся — в том плане, что просто так это всё взять и переписать на что-то более модное, современное не получится. Даже с самым мощным AI, который существует, эта задача, во-первых, безумно сложная, а во-вторых — с точки зрения затраченных ресурсов, а зачем? И ты говоришь, что очень консолидированный вот этот большой объём — и он внутри себя с точки зрения стека консолидированный. И что это за стек? Мы сейчас сказали, что есть неплохая, скажем так, библиотека, встроенная прямо в стандартную библиотеку Java, — java.time. Я вот помню, ты начал про это говорить: ещё была Joda-Time до восьмой Java, по-моему, — она была прародителем API и того, как вообще было бы удобно работать с датами в Java; и потом, по сути, то же самое перетекло в стандартную библиотеку с точки зрения UX, developer experience — того, как ты работаешь с библиотекой. Я помню, я эту библиотеку прямо учил на экзамен: что-то Oracle Certificate получал, была какая-то сертификация.

[06:14] Миша: OCA, да.

[06:16] Александр: OCA, да, вот я её сдавал, будучи джуном. И вот это вот с датами — у меня просто вьетнамские флешбеки: надо было в голове понять, какой будет результат работы этой библиотеки.

[06:26] Миша: Да, такие времена были, и не так уж давно это было. Oracle вообще, на самом деле, известны тем, что их OCA-шные сертификации заставляли джависта быть, по сути дела, компилятором. То есть они буквально спрашивали тебя: вот смотри, у тебя есть такой отрезок кода на Java — что тут будет, что произойдёт? Или: какой метод есть вот у этого объекта, у этого класса, что он делает и как конкретно он работает. Ну, я не скажу, что это продуктивный способ сертифицировать разработчиков, но такой, какой был. И сертификация в целом — будем честны, для Oracle, и для Amazon в том числе, она, наверное, даже не особо имеет смысл научить разработчика. Хотя такая цель в том числе есть, но она не основная, на мой взгляд: основная цель там всё-таки маркетинг — всякие скидки, которые предоставляются компаниям за наличие n-ного количества сертифицированных разработчиков и так далее. Это отдельная целая маркетинговая история с этими сертификациями, непростая.

[07:31] Александр: Да, ну вот флешбеки случились. Давай пройдёмся как раз по поводу консолидации: а что ещё в Java есть такого устойчивого, что уже база — с точки зрения, как это, моветона в Java?

[07:43] Миша: Да-да, я сейчас, наверное, уйду в глубокий монолог. Смотри: я сказал в самом начале, что Java довольно хорошо себя укоренила в энтерпрайзе. И переписывать это дело не просто долго — на самом деле часто нет смысла. Потому что в большинстве своём (и мы к этому дойдём чуть позже, когда будем разговаривать про искусственный интеллект и так далее) крупным энтерпрайзам не так важна скорость в моменте — им важна стабильность. Это как финансовые рынки, фондовые: если мы говорим про крупные рынки капитала — вот представь себе BlackRock, у него там десять триллионов долларов инвестиций, они могут купить эту NVIDIA дважды сейчас, даже на всём её пике хайпа, где она стоит каких-то баснословных денег. И дело в том, что они рассматривают — если послушать финансовых топов, которые входят в советы директоров, senior management, — они больше смотрят на то, насколько рынок стабильный, на верховенство закона и так далее. И для большинства энтерпрайзов — вот если взять какой-нибудь Citibank, если взять Boeing, что-нибудь такого разряда — им в большинстве своём важно, чтобы деливерились стабильные изменения и чтобы платформа их не подводила. Вот это очень важно. То есть они должны понимать, что есть какой-то фреймворк, на который мы сможем насадить абсолютно всех. Вот у нас есть, грубо говоря, софт, который обслуживает наш банкинг. Софта много, много. Он плюс-минус не то чтобы одинаковый, но похожий — паттерны используются. И было бы неприятно, если бы у нас было, грубо говоря, не то чтобы как в JavaScript или Go, где у нас один сервис — и там проблему решают совершенно одним способом, второй сервис — а там эту проблему решают другим способом, третий — третьим способом. Всё почему? Потому что именно в JavaScript, в Go и так далее одну и ту же проблему можно решить ста пятнадцатью разными способами. В Java, конечно, тоже — но в Java за счёт того, что экосистема очень консолидирована, этой свободы меньше. Вот, например, когда человек выбирает, на чём писать любой бэкенд для веба, он в большинстве своём выбирает Spring Boot. У этого есть причины — есть причины, почему Spring победил, мы про них поговорим потом. Но важно, что именно поэтому Java у энтерпрайзов осталась и остаётся, и этот тренд до сих пор такой. Представляешь, даже несмотря на то, что Java постоянно ругали. Ты зайдёшь в твиттер — и там лид дата-платформы Netflix каждый год перед тем, как выступать на JavaOne, говорит: вот у нас дата-платформа написана на Java, у нас три с лишним тысячи микросервисов на Java работают, которые питают Netflix. И он там описывает и так далее. И ему в твиттере, конечно, каждый раз наваливают: что? У меня отец на ней писал, дедушка на ней писал; а не пробовали переписать на Rust? Ну, мы все знаем, как твиттер выглядит, — вот прямо в ту сторону. И они на это смотрят и понимают: да зачем? И вот этот человек, который выступает, — тоже staff-инженер в Netflix, — очень хорошую вещь сказал: представьте себе, что у нас есть огромная экосистема, дата-платформа, и мы просто хотим развивать свой internal tooling, писать свой собственный софт, решать свои проблемы — и чтобы язык, платформа и экосистема вокруг неё не были препятствиями для нас.

[11:21] Миша: То есть не должно быть такого, что мы решаем свою проблему — и вдруг натыкаемся на то, что вот этот тинейджер из Небраски (вот эта JavaScript-история) поступил в колледж и теперь просто не поддерживает эту библиотеку, и там нет какой-то важной интеграции, и что теперь делать? То есть фактически экосистема вас не то что бросила — там нет экосистемы как таковой, именно консолидированной. В Java такого нет. Вводится фича «виртуальные потоки» — Spring говорит: мы её поддержим без проблем. Хочешь виртуальные потоки в embedded Tomcat — они у тебя будут, не переживай. То есть тебе не надо думать над тем, что эта экосистема — понимаешь, она единым паровозом едет. Это очень важно. И в этом случае enterprise говорит: да на кой нам все эти ваши короткие языки, или вот тот факт, что люди кричат про какой-то boilerplate и так далее. Всё хорошо, стабильно, спокойно работает, экосистема нас особо не подводит — да зачем переписывать? Американский и европейский enterprise довольно сильно отличаются от российского, знаешь чем? Тем, что они крайне сильно не любят переписывать и апгрейдить софт. В России, если ты возьмёшь какую-нибудь технологическую компанию, они на самом деле очень близки к вот этому твиттерному пониманию: нам надо было решить проблему, мы посмотрели, что Spring в новой версии её уже решает, — и мы решили обновить нашу экосистему на такую-то версию Spring и так далее. А американцы в enterprise будут сильно кичиться за свои деньги: так, любыми способами — можем мы сейчас не тратить деньги на обновление версии Spring? Можем мы сейчас этого не делать? Вот есть компания, называется BellSoft, которая довольно много оперирует на американском и европейском рынке: она продаёт свой собственный дистрибутив Liberica JDK, продаёт так называемые Zero CVE образы для рантайма OpenJDK и так далее. Они уже несколько раз говорили о том, что на западе и на американском рынке продаётся именно поддержка, патчинг CVE для условной Java 6. Мы сейчас говорим про то, что вышла Java 26 — а там есть просто бэкенд в каких-нибудь ситибанках на Java 6. Причём — я действительно с человеком разговаривал, — он говорит: к нам приходят и говорят, у нас Java 4, можете дать нам ваш патч? Они говорят: минимум, что мы поддерживаем, это 6, сможете обновиться на 6? Почесали репу такие: ну наверное сможем. И обновились — и получили пропатченный рантайм. Ну вот представляешь? То есть они не будут смотреть на это с точки зрения того, что нам нужно идти в ногу со временем, со стеком, — вообще не колышет. Важно, что этот софт нас не трогает, он стабильно работает — вот это Java и так далее, и всё с ним хорошо.

[14:07] Александр: Работает — не трожь.

[14:08] Миша: Да, это нормальное отношение именно к этому. Но ещё ведь очень важно что? Важно, что люди в энтерпрайзе — это взаимозаменяемые юниты. Ну, если смотреть именно с точки зрения руководства. То есть они смотрят на вас и понимают: вот человек из этой команды, он писал бэкенд с учётом, грубо говоря, Spring Framework, Hibernate и так далее — это такой универсальный солдат, если так можно выразиться. И сейчас мы его пересадим в другую команду: она имеет немножко другой бизнес-домен, она решает другие проблемы, но он встретится ровно с тем же самым технологическим стеком. Он всё это видел, он всё это знает — в силу своих компетенций, может быть, не так глубоко, но тем не менее у него не будет какого-то сильного когнитивного диссонанса.

[14:50] Александр: Так, окей, мне в целом нравится заход. Мы сейчас говорим про Java как про язык программирования, про JVM, JRE как про платформу — вот этот паровоз и набор стандартных, именно в Java включённых, библиотек и подходов. Системы сборки мы, наверное, особо трогать не будем: это чаще всего Maven, Gradle, другого вроде в индустрии не используется. Ant — хотя, наверное, те чуваки, которые на четвёртой Java, возможно, и Ant’ом собирают тот сервис, но это уже эзотерика. В том плане, что билд-системы у нас тоже устоявшиеся. Дальше что? Дальше у нас есть какие-то фреймворки, с помощью которых мы строим веб-сервисы — чаще всего на бэкенде — и вообще выстраиваем архитектуру нашего приложения. Вот тут какова у нас консолидация?

[15:40] Миша: Ну вот тут, на самом деле, кроме Spring, я бы так сказал — чисто моя позиция, — кроме Spring ничего нет. Одна из вещей, в которую я довольно сильно верю, заключается в том, что в ближайшее время, прямо в ближайшие годы, я не вижу вообще никаких альтернатив Spring Framework ни в какой обозримой перспективе. Вообще.

[16:01] Александр: Ага. Так, давай сейчас остановимся немного и горящие передачи немножко подостудим — потому что давай сначала про терминологию. Вот мы говорим про Spring в целом как про базовый Spring — то есть даже не Spring Boot, не для того, чтобы веб-сервисы, а вот этот контейнер, inversion of control, dependency injection, построение архитектуры приложения, — мы сейчас про это говорим? Или мы говорим вообще про Spring как про всю экосистему со всеми стартерами и так далее?

[16:33] Миша: Обязательно про всю экосистему, обязательно. Spring в своё время, когда начинался, когда Род Джонсон — это человек, который основал компанию SpringSource (она до этого называлась Interface21) — начал разработку Spring Framework, они пытались решать конкретные боли; она прямо была описана в книжке — разработка enterprise Java-приложений с использованием EJB и так далее, — конкретные боли Java EE. Конечно, можно было бы сказать — и, наверное, правильно сказать, — что Spring Framework просто уловил на тот момент ветер времени: потому что большое количество людей тогда чувствовали, что с Java EE что-то не так. Потому что странно, что мы настолько сильно усложняем спеку, настолько сильно усложняем решение проблем.

[17:18] Александр: Да, мы сейчас говорим про Java EE — давай немножечко подсветим, что это такое. Потому что меня слушают не только Java-разработчики или молодые Java-разработчики, которым даже «Java EE» — и такие: а что это такое?

[17:28] Миша: Хорошо, без проблем. Смотрите, ребят: Java как язык программирования изначально разрабатывалась компанией Sun Microsystems. Sun Microsystems — это такая компания, которая в какое-то даже далёкое бородатое время имела некоторые разработческие офисы в России и даже пыталась Java как-то приносить в университеты; прямо действительно такое время было — до того, как Sun Microsystems в 2007–2008 году закончилась: путём того, что Oracle с ними — не то что там слияние, но, грубо говоря, он уже стал владельцем непосредственно языка программирования Java и ряда других технологий, которые Sun разрабатывал: например, операционной системы Solaris и так далее — вот то, что вместе с Sun шло. И хочется сказать, что Java как язык зарождался в Sun Microsystems — и зарождался с идеей того, что были проблемы, связанные с тем, что системным разработчикам приходилось довольно глубоко интегрироваться с железом, на котором они работают. Опять же, если люди не знают: когда ты пишешь программы на языках вроде C, C++ — вообще на языках, где ты пытаешься интеропиться с хардваром, — ты очень часто беспокоишься о том, на каком железе ты бежишь. Тебе это важно. А в Java ты вообще об этом не думаешь: у тебя совершенно ноль когнитивных ресурсов на это уходит. Если мы говорим про C — уходит много: тебе нужно думать над тем, где ты, грубо говоря, исполняешься; какой у тебя int на платформе. Конечно, там есть всякие стандартные типы и так далее, но тебе важно это понимать, потому что в ряде случаев компилятор себя по-разному ведёт: всякие #ifdef, препроцессорные утилиты и так далее. И это настолько сильно в какой-то момент задолбало людей, что была написана Java. И Sun, когда они начали разрабатывать этот продукт, поняли, что эта боль не только для них: эта боль существует в индустрии в довольно массовом масштабе, и эта боль есть у энтерпрайзов. И Sun начали по-своему пытаться коммерциализировать Java — сделать какую-то платформу поверх Java, на которой можно будет зарабатывать деньги. И их платформа называлась Jakarta EE — прошу прощения, Java EE: была так называемая J2EE, Java 2 Enterprise Edition, вот это, грубо говоря, Java для бизнесов. Они пытались выстраивать линию, что есть Java, у неё есть стандартная библиотека, она позволяет решать какие-то базовые задачи. А вот если вы бизнес — то наверняка вам нужен веб-сервер, наверняка вам нужно уметь работать с базой данных, наверняка вам нужна возможность не просто обрабатывать HTTP-запросы, а как-то проверять, что они аутентифицированы, что они авторизованы выполнять эту операцию — у нас есть свои стандарты для этого; а ещё наверняка вам нужно как-то с XML работать. То есть существовал такой нарратив: есть стандартный Java SE, Standard Edition, — а вот Enterprise Edition, это, грубо говоря, ряд спецификаций, которые выпускал тогда ещё Sun, а потом Oracle.

[20:52] Миша: …и непосредственно были вендоры, которые предоставляли реализацию для этих спецификаций. Это были спецификации как раз EJB, Enterprise Java Beans; всякие сервлеты, javax.servlet — спецификация для веб-серверов, для сервлетов. И этих спецификаций было как у дурака фантиков: они потом наращивались и наращивались в рамках проекта Java Enterprise Edition. Ну и, конечно, одним из основных вендоров в своё время был Oracle — который, ещё раз говорю, Sun по сути поглотил. Помимо Oracle были и другие вендоры, но они сейчас уже тоже из этого бизнеса ушли. Кстати, ушли почему? Потому что они поняли, что все просто повально проиграли Spring. Это стало настолько очевидно году к 2016–2017-му, что тогда все эти спецификации — javax и так далее — Oracle затрансферил в Eclipse Foundation. А Eclipse Foundation — это, если можно так выразиться (я, может быть, ещё раз кому-то подогрею попу), свалка мёртвых проектов. Фактически такой чердак истории: то есть у нас сейчас нет желания и денег это поддерживать, поэтому мы это в Eclipse Foundation задонатили — ну, скинули. Это так выглядит на самом деле. И, конечно, они пытались на этой enterprise-платформе как-то коммерциализировать Java. Но основная проблема была в том, что она была очень сложная. То есть они шли по пути: не-не-не, ты не можешь просто так к базе данных подключиться. — Ну ведь я хочу просто select. — Нет, нельзя, у тебя будет двадцать пять типов строк и так далее. И ты смотришь на это и думаешь: да не может быть настолько всё сложно. Какие-то дескрипторы, какие-то пятнадцать типов XML-ов, всякие web.xml для сервлетов — что вообще происходит? Я пытаюсь решить простую задачу, я пытаюсь обработать HTTP-запрос: почему я должен описывать двадцать пять XML-файлов, конфигурировать это разными способами и так далее? И это действительно у людей откликалось. Если вы сейчас посмотрите, например, на экосистему Go — насколько просто там запустить веб-сервер; или, например, запустить веб-сервер на JavaScript с помощью Express; или с помощью Django — просто даже думать не надо, там всё настолько тривиально. Если бы вы каким-то образом сейчас оказались в году так 2008–2010, когда Java EE реально была a thing — когда она реально ещё конкурировала со Spring, — и попытались бы это сделать, вы бы просто штаны наделали, увидев, насколько много вещей вам приходится сделать, чтобы засетапить примерно то же самое, что дают современные языки. Это откликалось совершенно у всех — и у springовой команды тоже.

[23:45] Александр: То есть точка, в которой мы сейчас находимся, — это когда Java EE предложила набор спецификаций и реализации этих спецификаций для enterprise-веб-разработки: со всеми этими серверами, коннекциями, бинами, XML-ями. По сути, они-то хотели решить общую проблему: они видели, что люди пишут такой софт в энтерпрайзе, много пишут руками, много делают всё по-разному, ничего не специфицировано, — давайте мы им сейчас специфицируем, сделаем. И вот проиграли-то они в чём? Просто сделали херню? Или не додумали? Или это был первый блин комом? Вот почему получилось так плохо — мне интересно.

[24:29] Миша: Потому что Oracle. Ну вот как тебе сказать: есть компании, которые… Знаешь, нельзя двигаться вперёд без того, чтобы обдумать спецификацию с пятнадцати разных сторон, согласовывать её два года. Хороший пример — nullability-аннотации. Казалось бы: Java — язык программирования, который позволяет тебе… Вот у тебя есть ссылка, и она может быть либо того типа, которым она объявлена — например, String, то есть строкой, которую ты себе представляешь, — либо null. И логично предположить, что у разработчика будет желание каким-то образом изъявить свою волю, сказать, что эта строка не может быть null. Или может быть null. То есть он захочет скоммуницировать дальнейшим разработчикам тот факт, что в этот API нельзя передавать null-строку — нельзя, мы ожидаем, что она здесь будет. Иными словами, это вещь, которая действительно была полезна — потому что в языке есть поддержка того, что ссылка может быть null. Java с такой богатой экосистемой, с богатой стандартной библиотекой — пыталась ли она как-то внедрить эти аннотации в Java? Да много раз. Был JSR-305, многострадальный, который годами находился в обсуждении. Годами. И в конце концов Java Community Process его вообще отозвал — сказал, что его не будет по ряду причин. И появился JSpecify как стандарт, который за энное количество лет это стандартизировал. Причём стандартизировал JSpecify не просто какие-то ребята из Oracle внутри себя, а консорциум компаний — Google, JetBrains и так далее. То есть это было гораздо сложнее — между компаниями договориться, чем внутри Oracle. Но у Oracle, конечно, есть стейкхолдеры: понятное дело, что есть другие компании, которые в том числе влияют на Java Community Process. Это понятно. Но сама суть в том, что вот эта медлительность внесения изменений, медлительность эволюции в своё время Java практически почти похоронила, на самом деле. Если бы они году в 2017–2018-м или где-то в этом районе не одумались и не перешли бы на шестимесячный релизный цикл, не сделали бы обновление Java как языка и как платформы динамичным, то, я думаю, они бы во многом могли оказаться вообще не там, где сейчас находятся. Но Java, конечно, во многом ещё помог тулинг. В Java самый лучший тулинг с точки зрения именно инструментов для разработки. Например, IntelliJ IDEA и вообще IDE от JetBrains — это просто небо и земля. Ребята, которые фактически программируют в VS Code, фронтендеры и так далее, — это сейчас будет неуместное сравнение, но тем не менее: это как будто один человек ездит на Porsche, а другой просто сидит на улице у разведённого костра. Вот это примерно уровень того, насколько разные уровни поддержки тулинга в VS Code, например, и в IDE от JetBrains. Я регулярно видел, как люди, начиная знакомиться с тем, что вообще может IntelliJ, насколько она крутая, — приходят потом в VS Code и говорят: господи, я что, JavaDoc даже в IDE посмотреть не могу? Мне в интернет, что ли, идти и смотреть документацию этой функции? Или: блин, декомпилировать байт-код я прямо здесь, что ли, не могу? Такие мелкие вещи очень сильно всплывают тоже. Но в общем — возвращаясь к Java EE, — здесь можно очень просто сказать: проиграли потому, что Oracle; потому, что слишком медленные; и потому, что действительно просто плохо отвечали вызовам времени. Вот и всё. Потому что скорость решает.

[28:17] Александр: Да, то есть людишки долго договаривались — и договорились о херне, ну и получилось плохо. Люди виноваты, в общем-то. Мне было интересно понять суть. И получается, что получилось не очень — и мы переходим к Spring. Получается, Spring посмотрел на это всё — или его создатели сказали: не, это фигня, мы сейчас сделаем нормально, правильно?

[28:42] Миша: Ну, я не уверен, что прямо «это всё фигня, мы сделаем нормально». Именно когда начинали Spring Framework — и Род Джонсон об этом тоже говорил, и Юрген Хёллер, это вот прямо люди, которые стояли у истоков, — они, когда на это смотрели, больше думали над тем, чтобы решать сначала какие-то локальные боли. Просто какие-то локальные боли: ну, инверсию контроля сделать; потом, условно говоря, возможность как-то меньше кода писать для работы с сервлетами. И потом уже мы доросли до embedded Tomcat-сервера, а потом уже до того, что у нас появляется какой-то слой работы с базой данных — Spring Data и так далее. Это всё происходило с течением времени, то есть это такой эволюционный процесс. Мне кажется, основная причина, почему у них всё получилось и почему всё было хорошо, — это то, что они развивались просто гораздо быстрее, чем Java EE. Это с одной стороны. А с другой — у них прямо ключевые решения были приняты правильно. Есть вещи, которые мне в Spring не нравятся тоже, не поймите меня неправильно, — но ключевые решения, например создание Spring Boot, были приняты правильно. Spring Boot — это то, что, мне кажется, просто поставило крышку гроба Java EE в своё время: очень хороший гвоздь в крышку гроба воткнуло. Потому что Spring Boot по сути дела позволил тебе создать полноценное веб-приложение за десять минут — без какой-то конфигурации, без всего просто.

[30:15] Александр: Без EE.

[30:17] Миша: Ну да. И это был просто фурор.

[30:22] Миша: Потому что раньше Spring — ну да, его любили, он решал проблемы и так далее, но нужно было пятнадцать раз присесть: всякие LocalSessionFactoryBean для работы с базой данных, всякие WebMvcConfigurer для того, чтобы свой веб-слой сконфигурировать. И вот это волевое решение — что на самом деле большинство разработчиков пишет одни и те же конфигурации и большинству на самом деле дефолты будут нужны. И это так и оказалось: при наличии сотен и сотен пропертей, если взглянуть на то, что люди переопределяют, — они переопределяют, дай бог, несколько десятков. То есть они реально 80% конфигурации вообще не трогают. Нет смысла заставлять их это определять самих. И это было просто фантастикой. У меня есть вещи, которые мне в Spring не очень нравятся, но ключевые решения они принимали, на мой взгляд, верные — и принимали их тогда, когда надо было. Вот если ты посмотришь: мало реальных крупных решений, которые переживали вызовы времени прямо на протяжении двадцати с лишним лет. Что у тебя двадцать плюс лет существует технология — и она, знаешь, не сбавляет темпы, не умирает потихоньку. А Spring прямо действительно в таком состоянии — я имею в виду состояние Spring на данный момент. Ещё раз: я не голословно это говорю. Я сейчас разрабатываю в опенсорсе с командой продукт Axelix — это мониторинговое решение для Spring Boot-приложений. И я не просто так выбрал именно мониторинг Spring Boot: я искренне верю в то, что у Spring нет конкурента вообще. Могу поговорить про Quarkus и рассказать, почему я так считаю, — это отдельный вопрос; или про Helidon и Micronaut тоже можем пообщаться. Но важно, что они не просто устояли, выжили на протяжении всего этого времени, — они остаются именно флагманским решением, флагманом, который не сдаёт долю рынка. Даже с React так не получилось. Вот React, казалось бы, — даже не старая библиотека, она моложе, чем Spring, если что. Но это библиотека, вокруг которой построена тоже своя экосистема: у тебя есть React Router, всякий React Internationalization, всякий React Redux и так далее — state management; то есть вся экосистема React тоже обвешана, очень много библиотек поверх, кастомных хуков написано. И даже они со временем — по ряду причин, потому что где-то не так удобно работать с пропсами, где-то не так удобно с хуками, — и появляются всякие вещи вроде Vue, которые прямо агрессивно начинают отъедать долю рынка у React. Не часто бывает, когда у тебя настолько крупная экосистема, которая просто всех затмевает. Это не часто. И, на мой взгляд, у Spring могли бы быть нормальные конкуренты. Могли бы быть — но нет, никто нормальных не сделал. Вот у Quarkus основная проблема, которой они себя просто обрекли, — это тот факт, что они решили строить своё решение на Jakarta EE-спеках. В момент, когда это решение было принято, можно было сказать: выносим вперёд ногами. Потому что когда они принимали это решение, они думали, что мы строим cloud native, всякие микросервисы — грубо говоря, фреймворк для Java-микросервисов для облака. Это же их основной лозунг был: что мы идём в GraalVM, в native, очень efficient с точки зрения ресурсов, быстрее запускаемся, чем Spring, и так далее. Но как только они приняли решение, что мы будем строиться поверх Jakarta EE-спецификации, поверх их аннотаций, будем следовать Jakarta EE-спекам в этом, — это не очень просто, если честно. Да, они их упрощали, они говорят: ну да, нужен дескриптор, но мы специально написали плагин, который его за вас сгенерирует, пожалуйста, включите. Они сами прекрасно понимают, насколько эта спека их тормозит. Но они её выбрали тогда, когда люди от неё плевались: людям она не нравилась, Oracle это признал, они её просто сбагрили в Eclipse Foundation, потому что не хотят это дерьмо поддерживать. А они решили на ней строить свою платформу. Так мало того, что решили, — проблема-то, знаешь, в чём? В том, что из-за того, что они решили строить на этом свою платформу, и из-за отсутствия коллабораций они остались таким чёрным лебедем, который просто в озере плавает — и он один. Вот если ты посмотришь на решения в рамках Quarkus… Смотри: весь опенсорс — вот, допустим, ты хочешь отправить HTTP-запрос. Вот есть компания Netflix, она написала Feign-клиентов; потом она забросила его поддержку, и появился OpenFeign — вот эта история, и действительно бизнесы работают. А Spring — какая у него философия? Я говорю ещё раз: ряд ключевых решений они приняли правильно. И помимо Spring Boot важное ключевое решение, которое они приняли правильно, — они не вставали жопой к экосистеме. Слишком часто они этого не делали; иногда поворачивались, если так можно выразиться, иногда такое было — но в ключевые моменты этого не было. Что это означает? Вот, например, есть Feign — мы привыкли общаться через Feign. Вот когда Netflix OSS-стек был ещё на коне — помнишь, там Zuul, Ribbon и так далее, это, наверное, лет шесть-семь назад было, — Feign тогда был очень популярен. И они просто берут поверх, Spring Cloud, и пишут поддержку с меньшим количеством конфигураций, чтобы разработчик писал как можно меньше кода, как можно более прозрачно для существующих решений. А Quarkus говорит: нет, у нас всё своё. Всё своё. У нас абсолютно своя система логирования, своя ORM, мы по-своему работаем — мы под Jakarta Data работаем; у нас не Feign-клиент, у нас своя реализация, спецификация и так далее. То есть, попадая в их мир, ты фактически попадаешь в какой-то отдельный опенсорс, который существует отдельно от всего остального мира — при этом работая в мире Jakarta EE. И теперь: единственное важное преимущество, которое действительно в своё время заставило Spring пересмотреть свои приоритеты, — у них было что? Это более быстрый запуск и меньшее потребление ресурсов. Правда. Потому что Quarkus действительно имеет такую тенденцию: он в целом быстрее запускается и потребляет меньше ресурсов. Но вот беда. Во-первых, проект Leyden. Проект Leyden — если использовать AppCDS… И почему Spring очень много на это уповал, очень много акцентов на это делал в рамках последних конференций Spring.io — наверное, трёх последних конференций Spring.io? Потому что они понимали, что с приходом AppCDS и с приходом Project Leyden как такового разницы в запусках по времени с Quarkus у них практически не будет, на самом деле. То есть если сейчас люди узнают про то, как можно нормально интегрировать Application CDS-архивы в запуск Java-приложений, то они очень быстро придут к пониманию: блин, приложение на Spring запускается вот так вот, очень быстро, оказывается. Так можно, что ли, было? Да, конечно.

[37:35] Александр: А давай подробнее про это — а как это должно работать? Потому что ты говоришь «Leyden», а кто-то, может быть, даже первый раз слышит это слово.

[37:44] Миша: Да, конечно. Смотрите, ребят… Саш, я, к сожалению, просто аудиторию не сильно знаю: я привык к тому, что когда мы в Spring.io на подкастах обсуждаем такие вещи, мы обсуждаем их очень глубоко технически для джавистов — мы предполагаем, что наша аудитория понимает, о чём мы говорим. Здесь я, наверное, отступлю в сторону — Саша, наверное, хочет, чтобы я это аудитории рассказал. Смотрите, ребят: есть такая вещь в Java-мире, называется OpenJDK. OpenJDK — это такой проект, можно сказать, референсная имплементация Java Development Kit. То есть у нас есть некоторые спецификации: виртуальной машины, спецификация языка и так далее. Есть референсная реализация, называется OpenJDK, она лежит на гитхабе, и её поддерживает — ну, фактически можно сказать, что консорциум компаний, но на деле фактически Oracle и так далее. Этот OpenJDK — живой организм: это действительно референсная имплементация, и сам язык, и платформа эволюционируют. Туда добавляются какие-то новые фичи в язык — например, вещи, связанные с деструктуризацией рекордов, с паттерн-матчингом на примитивных типах, что угодно. Какие-то новые фичи в язык попадают. И важно, что платформа и сам OpenJDK должны на это реагировать — и не просто реагировать, а выносить какие-то изменения. И в рамках OpenJDK есть набор так называемых проектов. Проекты — это инициативы по внедрению определённых функциональностей в язык и в платформу. Есть проект Leyden. Его задача очень простая — ускорить запуск Java-приложений. На самом деле у них есть ещё одна цель — ускорить так называемый ramp-up. Ramp-up с английского можно перевести как «время до пикового перформанса». То есть любая виртуальная машина работает таким образом, что она сначала — чаще всего, да, как это выглядит — интерпретирует некоторые инструкции, потом пытается понять общие эвристики запуска: как у тебя непосредственно исполняется байт-код и так далее, — и потом пытается каким-то образом это оптимизировать, скомпилировать в более оптимизированный вид, и потом уже выполнять эти скомпилированные инструкции вместо того, чтобы интерпретировать их на лету. Похожим образом работает V8 — это рантайм для JavaScript, написанный Томасом Вюртингером и его командой в своё время в Google, по-моему. Так же работает HotSpot — это виртуальная машина Java от Oracle и так далее. Это нормальный паттерн. И вот это как раз суть Project Leyden: фактически ускорение запуска приложений и ускорение выхода к пиковому перформансу, уменьшение периода ramp-up. Ramp-up включает в себя запуск непосредственно — подъём приложения, вот этот bootstrap, когда мы просто пишем java -jar, передаём jar, нажимаем enter: вот с этого момента много чего происходит. Я думаю, мы сейчас не будем прямо разбираться, как там class loading работает и всё такое, — но в итоге потом получается, что приложение начинает быть работоспособным: то есть Java Runtime интерпретирует байт-код, и мы можем с ним работать — можем послать, например, если это веб-сервер, веб-запрос, и этот байт-код проинтерпретируется.

[40:54] Миша: Это первая часть ramp-up, скажем так, половинка его, — но всё ещё это интерпретация. А пиковый перформанс — это уже от точки, где мы интерпретируем, до точки так называемого прогретого состояния: когда большинство инструкций, которые чаще всего исполняются, прогрелись, сджитились, возможно, пару раз, — и теперь на каждый наш запрос выполняется огромное количество кода, скомпилированного под платформу, на которой это всё бежит, и это действительно быстро. И вот от точки, когда я нажал Enter, и до момента, когда начал получать пиковый перформанс, — это всё называется ramp-up.

[41:30] Александр: И, собственно, насколько я понял, цель проекта Leyden — максимально оптимизировать вот это время целиком: то есть не только время старта, но и время прогрева.

[41:39] Миша: Так и есть. Есть и другие проекты в рамках OpenJDK — например, Project Babylon: его задача, если так можно выразиться, сделать Java более приятной для работы с какими-то внешними языками, платформами, грубо говоря — с хардваром. Вот, например, у тебя есть необходимость: есть какая-то сишная библиотека, которая делает то, что нужно, но вот беда — как её вызвать, как с ней интеропиться? Есть JNI — ну, у JNI есть свои проблемы, он не слишком дружелюбный, я бы сказал, очень недружелюбный. Иногда есть желание часть процессинга на Java — например, в мире нейросетей это очень актуально — просто офлоадить на GPU: чтобы у тебя это выполнялось не на центральном процессоре, а офлоадилось на GPU и выполнялось там. В общем, Project Babylon смотрит в эту сторону: он пытается улучшить interoperability в целом. Если говорить про другие проекты — есть Project Amber, например, который занимается тем, что пытается улучшить dev experience: то есть сделать так, чтобы разработчикам было просто приятнее писать Java-код. Например, деструктуризация рекордов. Большинство фич языка, когда люди спрашивают «а какие фичи тебе в языке больше всего нравятся?», — чаще всего это как раз то, что вносит Project Amber: вот теперь можно глубоко деструктуризировать рекорды — в Java 26 и так далее. Или, например, сейчас можно вызывать суперконструктор, но перед вызовом суперконструктора ты можешь написать стейтменты и тому подобное. То есть это ещё один проект. И их много — это прямо целые инициативы, которые вносят свои изменения в язык. Мы начинали с чего? С того, почему Spring очень активно это популяризировал. Они же прекрасно понимают: если сейчас AppCDS их поддержит — а они их поддержат… Команда Oracle очень плотно общается с командой Spring, я бы сказал, крайне плотно. Чтобы было понимание, насколько плотно: когда выходят JEP’ы…

[43:41] Александр: JEP — это Java Enhancement Proposal, на всякий случай. Поясню, потому что не факт, что аудитория глубоко в Java погружена: то есть когда выходит предложение о том, какую фичу в Java внести, какую доработку сделать. В Kotlin есть так называемый KEEP — Kotlin Evolution and Enhancement Process. Вот аналог в Java — это JEP.

[44:01] Миша: И когда выходит JEP, например по AppCDS, когда они говорят, что вот эта конкретная фича предположительно улучшит те или иные эвристики в рамках джавовых приложений, — они за референсную имплементацию иногда используют Spring PetClinic. То есть типовое springовое приложение — это прямо в официальных JEP’ах происходит, понимаешь? То есть они очень плотно друг с другом общаются. Именно команда Oracle, которая разрабатывает OpenJDK, команда, которая разрабатывает Spring Framework, HeroDevs — это прямо целый такой трейн, некоторая просто вершина нашей индустрии: JetBrains, HeroDevs, Oracle и, конечно же, Spring Framework. Если они вот это сейчас сделают и у них будет лучше время до пикового перформанса, лучше время запуска, — то у Quarkus просто не останется преимущества, к сожалению. Quarkus, ещё раз говорю, мог бы стать хорошим конкурентом, они могли бы это сделать. Команда, которая его пишет, — очень талантливые парни. Но, на мой взгляд, просто менеджерское решение, которое было принято неправильно в самом начале, — вот это «мы будем придерживаться этой Java EE-шной спецификации до конца», — оно просто похоронило в своё время Quarkus. Я не знаю, зачем… Давай так: я предполагаю, зачем они так сделали. Потому что Red Hat — это основная компания, которая поддерживает эти спецификации, и это компания, которая разрабатывает Quarkus. То есть они, наверное, посмотрели на это так: надо есть свой собственный испечённый хлеб. Мы же не просто так эти спецификации поддерживаем — наверное, давайте на них и будем строить своё решение, свою платформу, свой энтерпрайз. Но, блин, я думаю, что нет — так, наверное, поступать не стоило. Вот для примера возьмём JetBrains, кстати. JetBrains разрабатывают язык программирования Kotlin. И Kotlin — во многом прекрасный язык, очень приятный, я на нём тоже много пишу; конечно, не без изъянов, есть вещи, которые мне не очень нравятся. Но тем не менее команда Kotlin и JetBrains в целом объявляли в прошлом году стратегическое партнёрство со Spring. Причём обратите внимание: когда мы говорим про мир Kotlin и про микросервисы, написанные на Kotlin на бэкенде, — Kotlin на бэкенде это же было изначальное желание, изначальная основа. Kotlin в Android — это так просто получилось. Так получилось. То есть фактически основой всегда был Kotlin на бэкенде: задачи, которые решались в первых версиях Kotlin, — это был бэкенд, предполагалось вот что. И теперь смотрите: предполагается, что люди на бэкенде на Kotlin будут писать свои веб-приложения с помощью чего? С помощью Ktor. У JetBrains есть специальный, я бы сказал так, фреймворк, который называется Ktor: это прямо такой модульный фреймворк, который предлагает тебе возможность поднять веб-сервер, подключить к нему нужный модуль — допустим, модуль для CORS, cross-site request, вот эти вот с origins; дальше даёт тебе модуль для работы с аутентификацией, авторизацией; даёт модуль для работы с тем-то и тем-то. Ты фактически можешь прямо так своё веб-приложение построить. И этот Ktor-фреймворк очень популярен в мире котлинистов. В этом году был опрос State of Java у JUG Ru — кстати, по-моему, ты тоже на JPoint был. Они проводили опрос, и оказалось, что если мы говорим про людей, которые используют Kotlin, то они в половине случаев пишут свой бэкенд на Ktor, а в другой половине случаев — на Spring Framework и Spring Boot. Но ещё раз: JetBrains не заняли такую позицию, какую занял, например, Red Hat. Они сказали, что надо просто это признать: Spring победил, надо это признать. И они заключают с ним стратегическое партнёрство в мире Kotlin — а не поворачиваются к ним попой со словами «у нас свой Ktor, мы будем его развивать, а со Spring Framework мы ничего делать не будем». Это была бы полная глупость. Я вам даже больше того скажу: я знаю лично людей, которые лоббировали в JetBrains решение об этом партнёрстве. Я готов аплодировать этим людям стоя — они молодцы, это умные ребята, реально. Потому что нет смысла с этим бороться, нельзя бороться. Нету сейчас нормальных конкурентов — так у нас получилось. И не то чтобы это плохо: Spring Framework сейчас водят очень хорошие и умные люди, на самом деле.

[48:24] Александр: Так, слушай, неплохо мы прошлись по конкурентам и вообще поговорили про экосистему. Мне нравится, как ты это всё рассказываешь: тебя можно слушать — только иногда, знаешь, вопросики задавать уточняющие. Потому что, честно, даже сам — я на Java уже десять лет пишу, и восемь лет я прямо писал код. И раньше, года два назад, чуть больше чем два, я такой: так, мне надо досконально знать, как работает Spring, потому что это state of the art в backend Java. То есть я должен написать свои Spring Boot-стартеры. Я участвовал в опенсорсе — Spring Boot Starter Testcontainers Oracle: если вы используете его на проекте, я этот модуль добавил. То есть я прямо туда включался. И действительно, когда ты начал говорить про Spring Boot, я улетел в своих мыслях: а, вот когда я первый раз увидел, что такое Spring Boot — что можно просто аннотацию @SpringBootApplication над классом main поставить, дальше рядом положить конфигурацию с аннотацией @Bean и вернуть оттуда, например, какую-нибудь конфигурацию для базы данных, конфигурацию для Kafka, обработчик для Kafka — и всё, она уже даже заработает. То есть ты просто пишешь такой glue-код — круг компонентов, которые твоё приложение использует. И самый прикол в том, что до Spring Boot этот код действительно приходилось писать самому: то есть ты много писал инфраструктурного кода, и это одинаковый код. Вот когда я понял, что я теперь не пишу одинаковый код, а пишу логику, — у меня этот «вау» случился, лет семь назад, и я такой: да, всё, Spring Boot — это отлично. За счёт чего это у них получилось? Знаешь, мне как инженеру интересно понять устройство, майндсет того человека или тех людей, которые в нужный момент принимают нужные решения. И вот инженерное решение Spring Boot — как они мыслили? Они такие: нам надо вот это, а не вот это. Это интересно.

[50:25] Миша: Золотой вопрос, Саш, молодец. Это, на самом деле, вопрос даже не с точки зрения инженерии — это вопрос с точки зрения менеджмента проекта и понимания того, что мы делаем и нужно ли людям то, что мы делаем.

[50:38] Александр: Такой продуктовый вижен.

[50:41] Миша: Да, это больше продуктовый view — в целом продакт-дизайн уже, вот в эту сторону.

[50:45] Миша: И я скажу так: на мой взгляд, здесь много ответов на этот вопрос. Первый заключается в том, что Род Джонсон — довольно хороший именно продакт-дизайнер. Род Джонсон, чтобы, ребят, было понимание, — это основоположник Spring Framework, и это человек, который на самом деле уже не совсем даже программист, а бизнесмен. Это человек, который сейчас разрабатывает продукт под названием Embabel — такое корпоративное решение для написания Java-агентов: фактически агентов поверх Spring Boot, агентов на Java. Он в своё время основал компанию — она называлась SpringSource, — и он думал над тем, как конкретно эта компания будет делать деньги. Потом уже SpringSource купила компания Pivotal Software, потом Pivotal Software как департамент вошёл в VMware Tanzu, и так далее — там целая серия была вот этих mergers & acquisitions сделок.

[51:43] Александр: Санта-Барбара.

[51:45] Миша: Да. Но Род Джонсон был человеком, который не просто был разработчиком, а думал над тем, как конкретно продавать вещи, связанные с этим продуктом, как это сделать правильно. И вот именно в этом моменте важно понимать, что не всегда разработчик — условный Юрген Хёллер и так далее — понимает, нужно ли то, что они делают, вообще рынку. К сожалению, не всегда. А у Рода Джонсона в этом плане действительно был большой талант: он очень хорошо и тонко чувствовал, что то, что они делают, реально закрывает боли. В своё время, по-моему, он даже входил в совет директоров такой базы, как Neo4j, — то есть он даже там успел немножко поконсультировать ребят. Но я это к тому, насколько важна — ну, не личность в истории, но важно, кто у тебя стоит у истоков этого продукта и как вообще он смотрит на развитие продукта: то есть это инженер — или это инженер-продакт, такая смесь. То есть это фаундер именно. Где-то в этом районе: он частично техник, он писал на Java, на плюсах, но частично занимается продажами — он понимает, как это работает. Это именно майндсет технического фаундера, если так можно выразиться. Вот это Род Джонсон — но ещё раз говорю, сейчас он уже бизнесмен: у него там ещё один свой стартап и так далее. Потом, что мне кажется важным моментом с точки зрения правильно выбранных людей… На самом деле все причины, которые я сейчас буду называть, будут сводиться к следующему: потому что в нужный момент были выбраны ключевые люди. То есть правильные люди стояли на нужных местах, на нужных постах. С одной стороны, это был Род Джонсон. А с другой стороны — если мы говорим именно про Spring Boot, про создание Spring Boot, — это уже история, когда Рода у руля не было: Spring уже был более продвинутой технологией, когда создавался Spring Boot. Тогда у руля, когда этот проект пытались создавать, были ребята по типу Дэйва Сайера, по типу Фила Уэбба и так далее. И это парни, которые уже такие дяди в возрасте — они много писали энтерпрайза, прямо много писали энтерпрайза. Вот Дэйв Сайер, он, по-моему, прямо какое-то гигантское количество кода в своё время написал, он давно в индустрии. И он прямо описывал те проблемы, которые видел непосредственно при написании Spring-приложений. И когда он пришёл вместе с командой, которая находилась на тот момент в Америке — тот же Фил Уэбб, он сейчас тоже в Штатах, — они просто поняли, какая ключевая проблема существует, и начали разрабатывать свой проект Spring Boot для решения этих конкретных болей. Нам важно понимать, что Spring Boot — немножечко другой проект: он разрабатывается совсем другой командой по сравнению с той, которая разрабатывает Spring Framework. Это совершенно разные люди. Но важно, что те ребята, которые начинали писать Spring Boot, — это люди, которые до этого много писали на Spring Framework и знали его. Например, есть такой человек, который приложил очень много усилий — я бы сказал, с точки зрения именно разработческих усилий, это человек, который заслуживает очень большого уважения: он очень много в Spring Boot сделал и написал. Это Стефан Николь, чувак, который живёт в Бельгии. Он на самом деле очень скромный парень, малообщительный. Он тоже в своё время писал огромное количество кода на Spring, он тоже об этом говорил и прекрасно понимал эти боли. И он был одним из тех разработчиков, которые стояли у истоков Spring Boot. То есть фактически им в этом плане повезло, что люди, которые в своё время были, если так можно выразиться, в окопах, — они оказались у руля Spring Boot. И это им в том числе помогло, потому что они знали, какие боли решают, и это оказалось полезно.

[55:47] Александр: Да, получается, смотри: я два ключевых момента здесь для себя выявил. Во-первых, люди, которые создавали Spring Boot, понимали, как ты говоришь, боли — можно переформулировать: это максимальные из возможных эксперты в той доменной области, для которой предназначен продукт. Они не стали делать продукт для, не знаю, iOS-разработчиков — потому что они не разрабатывали на iOS, они не пошли свой Swift делать: они бы сделали его плохо. То есть те руки, которыми ты всё это строишь, должны быть максимально погружены в доменную область. И в этом плане, мне кажется, это очень важно с точки зрения такой жизненной, инженерной мудрости: если ты что-то строишь, то команда, которая это строит, должна максимально понимать, что она делает, и быть консьюмерами этого продукта по-хорошему. Они для себя его должны писать. Догфудинг работает, потому что люди, которые делают продукт под себя, делают его хорошо: у них есть глубинное понимание того, что они делают. И вот это ключевое, что я для себя выявляю. А второе ключевое — что этого недостаточно. Большое количество разработчиков делают тулинг для себя; я думаю, люди, которые писали Quarkus, тоже так или иначе разбираются в доменной области, спора нет. Но должна быть фигура или ряд ключевых фигур, которые принимают продуктовые решения по продукту, по вижену, по направлению, по вектору. Вот те самые решения — они не только те самые инженеры, они всё ещё должны быть ими, но у них есть ещё что-то стратегическое, вижен, бизнесовое — и смелость принять эти решения: то есть не колебаться, не думать, не разговаривать с каждым, не устраивать совет на каждое решение. Нужен такой правильный лидер, который сделает ключевые решения, — и с помощью команды, хорошо понимающей, что делать, тогда получается продукт вот такой, как Spring Boot. Мне кажется, эти два ключевых момента можно масштабировать на любую вещь, которую мы делаем в жизни вообще, даже не в технологиях. И это инсайт — мы здесь в подкасте иногда майним инсайты, вот это один из них. Слушай, мне было бы интересно, знаешь, в какую сторону идти. Мы очень много поговорили про всё, что сейчас… На мой субъективный взгляд — как энтузиаста, как человека, который закрыл IntelliJ IDEA год назад и открывал её только на воркшопах в офисе JetBrains, один раз открыл, чтобы код показать, — я фултайм программирую в Claude Code. И на Java, и на Rust, и на Go, и на TypeScript — на всём, на чём нужно программировать, я это делаю в Claude Code. Если мне нужно посмотреть код, я открываю Vim. Вот это мой workflow, вот так он устроен. И я всё ещё не перестал быть Java-разработчиком, о боже. И это просто мой тулинг. Я бы хотел начать говорить про те изменения, которые происходят, — но прежде я бы закрыл тему тулинга. Потому что ты его затронул довольно вскользь, быстренько сказал, что у Java как у экосистемы есть тулинг, который превосходит остальные в разы, — и с этим спорить сложно. За это Java я и полюбил. И вообще говоря, положа руку на сердце: когда я был джуном и принимал для себя решение, в какую технологию пойти, — я судил о технологии по тому тулингу, с которым ты с этой технологией работаешь. Это, может быть, глупо с точки зрения матёрого инженера, который сейчас в Vim пишет, — но когда я был джуном, я именно так принимал для себя карьерное решение: какую книжку открыть? По Spring Boot, по Swift, по Python или по JavaScript? И я выбирал Spring Boot — потому что Spring Boot-приложение я бы писал в IDEA. И вот это интересно. Давай поговорим с точки зрения тулинга: про IDEA мы любим, разговариваем много, IntelliJ — отличная штука. Давай немножечко опишем, какое у нас есть сейчас понимание тулинга и в какую сторону, наверное, хотелось бы, чтобы он трансформировался. Потому что у меня есть ряд претензий к Java-тулингу, на самом деле, — я их выскажу после того, как мы опишем вообще, что у нас есть. Потому что некоторые люди, например, пишут на Go фултайм, на Rust — и вообще не знают, а в чём прикол IntelliJ.

[1:00:09] Миша: Мне кажется, что суть IntelliJ в том, что она очень хорошо покрывает — я бы сказал, 80% потребностей большинства разработчиков. На самом деле в IntelliJ фичей настолько много, что…

[1:00:21] Миша: …из них, дай бог, процентов пять-десять вы используете. Пять-десять — я прямо положу руку на сердце и это скажу.

[1:00:31] Александр: Давай я сейчас скажу — вернусь на два-три года назад, когда я ещё не понимал, что будет с моей карьерой, — какие фичи я использовал. Особо ничего не поменялось за три года, факт. В тулинге я имею в виду, в IntelliJ. В общем, что я использую, за что я такой: не, ну Java это на голову выше. Первое — это дебаггер. Дебаг Java-приложения — это самый лучший debug experience ever, нет ничего лучше. Это респект инженерам IntelliJ, которые сделали и UI для этого дебаггера, и в целом как продукт его оформили и встроили в IntelliJ. Второе — это декомпиляция байт-кода. Потому что библиотека, которую я себе притянул, там вообще-то байт-код — вот, если кто не знал; и чтобы посмотреть, что там происходит, иногда хочется вникнуть, байт-код нужно декомпилировать в исходный Java-файл. Ну, там не совсем всегда так, но даже…

[1:01:21] Миша: Да, там можно скачать исходники, я согласен. Но иногда кода просто нет в открытом доступе.

[1:01:31] Александр: Иногда кода нет, да. И что ты будешь тогда делать? А байт-код есть — и ты читаешь, это круто. И ещё одна на самом деле киллер-фича, но это уже из моего раннего-раннего, когда я ещё с CLI и с терминалом нормально не работал, — это коннектор к базе данных. В IntelliJ Ultimate она, по-моему, только есть. То есть ты JDBC-строку подключаешь, и у тебя сбоку всегда есть коннекция к базе данных — к локальной, а может быть, если есть доступ на dev, можно порты прокинуть. В общем, коннекцию к базе данных настраивать круто, и это классная вьюшка для работы с базой данных. Она как DBeaver — вообще в разы: то есть таб, встроенный в IntelliJ IDEA для работы с базами данных, удобнее, чем продукт, который создан для работы с базами данных, как DBeaver. Мне было удобнее всегда в IntelliJ работать, у меня какие-то конфигурации под это были настроены. Ну и, наверное, ещё одна моя топовая фича — это рефакторинги и в целом экшены, которые в IDEA есть как в платформе: потому что IntelliJ IDEA — это платформа, она предоставляет огромное количество экшенов, и эти экшены можно использовать. Типа рефакторинг, форматирование — кстати, форматирование в IntelliJ классное. Переход от интерфейса к имплементации или посмотреть все имплементации этого интерфейса. Со Spring Boot удобно было работать — то есть такая общая поддержка тоже круто. Я вот назвал свои топовые фичи; не знаю, может быть, у тебя есть какие-то ещё, которые ты можешь накинуть.

[1:02:59] Миша: Смотри, всё, что ты сказал, абсолютно всё у меня откликается, я со всем этим согласен, прямо со всем — это база, не могу быть больше согласен, чем есть. Я, может быть, добавил бы немножко другие вещи, но они более прикладные. То, что ты говоришь, — это вещи, связанные больше в общем случае с работой с Java-кодом. А мне кажется, то, что в IntelliJ сделано и что действительно сделало тулинг от IntelliJ особенным, — это поддержка фреймворков и сборщиков. Глубокая интеграция с Maven, с Gradle. Возможность слинковать проект — когда IntelliJ понимает, что у тебя есть вот этот модуль и что ты его подключаешь здесь вот так, как project в Gradle, например, и что у тебя автоматически появляется этот класс доступным в classpath компиляции и в рантайме. Когда IntelliJ прекрасно понимает, что ты тут добавляешь новый source set для тестов — интеграционных, конкурентных, перформанс-бенчмарков, — она это понимает, автоматически это маркирует, и тебе не нужно самому его как-то включать. Это поддержка тулинга вокруг. Я понимаю, что это очень общие слова, но, грубо говоря, поддержка именно сборщиков, поддержка фреймворков. Ты можешь посмотреть и понять, что у тебя, предположим, используется Spring Framework — что, скорее всего, ты там написал вещи, связанные с работой с базой данных, с веб-слоем, с чем угодно. Конечно, большая часть этого — в Ultimate: вот именно поддержка Spring Framework как технологии — это Ultimate.

[1:04:49] Александр: Ты имеешь в виду IntelliJ Ultimate? Или она Enterprise называется — сейчас я просто уже давно не смотрел.

[1:04:54] Миша: Сейчас у IntelliJ единый дистрибутив: они поставляют одну IDE, ты её ставишь, — и чтобы получить доступ к Ultimate-фичам (условно, сейчас неважно, как мы это называем), ты просто вводишь ключ лицензии, и все эти фичи у тебя открываются. Вот и всё. Это сейчас сделано таким образом — тоже парни довольно большие молодцы, что так поступили, на мой взгляд. Тем не менее, что сейчас хочется сказать: вот эта поддержка фреймворка, возможность навигации по springовым пропертям, навигации по бинам, возможность посмотреть, какой у тебя будет сгенерирован SQL в рамках этого метода Spring Data-репозитория, — это всё очень важно, крайне полезно. Если бы этого не было, это была бы совсем другая история. Поддержка Spring Boot-тестов, поддержка JUnit — вот что я имею в виду под поддержкой фреймворков и тулинга. Всё, что ты сказал, тоже, конечно, откликается — всё правильно. Я понимаю, что у тебя, наверное, сейчас претензии в разряде того, что сейчас AI — и, возможно, разработчик сам код и сам эти Spring Boot-тесты особо уже не пишет, он всё это делегирует. И, возможно, вот эта навигация и вот этот dev experience уже не так сильно важны. Может быть, в этом у тебя основная претензия, я предполагаю.

[1:06:23] Александр: Ну смотри, давай к претензиям чуть-чуть позже придём. Мне бы хотелось ещё: а что ещё у нас в Java-мире с точки зрения тулинга есть? И вообще экосистема в большом смысле. Мы поговорили про язык, поговорили про Spring Boot, поговорили про IntelliJ IDEA — эти штуки все вместе работают. Но есть что-то ещё в software development lifecycle: от, условно, «взял тикет в работу» или «начал работать над фичей, над сервисом» до того, как ты его задеплоил. Что ещё в этом процессе у нас существует и в каком состоянии это находится?

[1:07:01] Миша: Ещё раз: тулинг — это любой инструментарий поверх Java как языка и так далее. По крайней мере, любой DevTool, который ты возьмёшь: Axelix, который мы пишем, допустим; AmpliCode; IntelliJ Ultimate — это всё в копилку. Лично у меня то, что мне удобно, что нравится и что я постоянно использую, — это вещи, связанные, например, просто с банальным менеджментом дистрибутивов Java: какой-нибудь SDKMAN. Но он есть в том или ином виде как аналог в любой экосистеме — то есть у тебя есть какой-нибудь Node Version Manager в TypeScript, JavaScript, когда ты можешь разные версии ноды поставить. Я думаю, что основа под тем, что мы называем exceptional tooling, — то есть тем, что мы называем таким особенным dev experience, — это вещи, связанные либо со стартерами, которые Spring Boot предоставляет. Например, Docker Compose Starter для Spring Boot: когда Spring Boot способен сам обнаружить, что у тебя есть некоторый Docker Compose, который должен подняться при локальном дебаге, — сам его запустит, сам прокинет нужные порты, сам подцепится к этой базе данных; а когда Spring Boot-приложение умрёт, он сам отцепится и погасит все эти контейнеры. То есть есть некоторый тулинг, который даёт Spring Boot со своими плагинами, допустим, для сборки. Вот у тебя есть какой-нибудь Spring Boot Maven- или Gradle-плагин, который просто берёт — и ты даже не думаешь, что там и как у тебя происходит: он тебе просто даёт в конце executable jar. Просто запускай, не думай больше ни о чём — просто запусти java -jar. Ещё раз говорю: это либо тулинг вокруг экосистемы, либо из IDE. А с точки зрения именно какого-то CLI — вот здесь я бы не сказал, что какие-то особенности есть у Java. То есть есть какие-то инструменты, но они в том числе есть и в других языках тоже.

[1:08:42] Александр: Да, я имею в виду — давай про них поговорим, чтобы полную картину нарисовать, в рамках которой потом, возможно, какую-то претензию высказать. Я к тому, что мы же, вообще говоря, софт разрабатываем чаще всего — особенно если мы говорим про enterprise — не в одиночку. Мы редко бываем индивидуальными контрибьюторами в серьёзные системы: как минимум люди хотят нас заменить, если что, другими людьми. Ну просто это база: чёрный ящик не любят, за чёрный ящик платить, наверное, не будут — если только ты не какой-то гений и талант. А мы разрабатываем код вместе, в команде. У нас есть где-то репозиторий, где этот код лежит: GitHub, GitLab — вообще без разницы, где он лежит. И есть некоторая система, которая является CI, continuous integration: то есть то, как код попадает в транк, какие процессы вокруг этого стоят, какой пайплайн. Когда много людей пишут разный код, здесь у нас возникают новые челленджи — например, какая-то стандартизация форматтеров, или статические проверки, тесты. То есть вот вокруг этого что у нас есть?

[1:09:54] Миша: Да, но это всё-таки инструменты. Давай так: мне кажется, у нас с тобой просто разное понимание тулинга. В моём понимании тулинг — это то, что помогает разработчику в повседневной разработке. Это возможность открыть проект в IDE, пронавигироваться. Это возможность сразу же понять, какая тут версия Java нужна. Это возможность сразу же, без погружения в детали, что-то собрать — вот просто в jar, я даже не думаю ни о чём таком. Или возможность запустить, как я сказал, Docker-контейнер и сразу же его погасить. Или возможность при изменении property сразу же перезапустить приложение — есть такой проект, называется Spring Boot DevTools. Ещё раз говорю: у Spring Boot есть прямо огромное количество вот таких мелких DevTools-инструментов, этих стартеров, которые помогают в разработке. Как у Quarkus есть dev mode — это известная история, что у крупных экосистемных фреймворков это есть. А вот если мы говорим про форматтеры, про всякие вещи, связанные со статическим анализом, всякие PMD, SpotBugs, — то это всё-таки, в моём понимании, инструменты quality control. То есть инструменты общего quality gate: контроля над тем, как у тебя код попадает непосредственно в мастер, в транк. Есть, конечно, некоторый процесс: во-первых, у тебя это должно скомпилироваться; во-вторых, тесты должны пройти; в-третьих, у тебя должно пройти автоматическое форматирование со Spotless, например, или, не дай бог, Checkstyle; должны пройти какие-то статические чеки от Error Prone, должна пройти проверка от NullAway — о том, что ты никуда, где null не ожидается, не передаёшь null; должны пройти всякие SpotBugs и PMD. Прошли — отлично. Дальше у тебя начинаются SAST, DAST — статические анализы на уязвимости, динамические анализы на уязвимости. Прошли — отлично. SonarQube, который всё это бандлит вместе, JaCoCo-репорт, — то есть это всё часть одного большого пайплайна качества. Ну и финально какой-нибудь код-ревью, и в мерж — и всё, отлично. Ну и, может быть, на каких-то окружениях проверили — у кого есть, замечательно. То есть это, на мой взгляд, не совсем просто DevTools — это, в моём понимании, инструменты, которые улучшают именно качество софта. Но в Java это просто принято: в Java принято иметь такой довольно строгий процесс quality gate. В большинстве экосистем он менее строгий, чем в Java. Если посмотреть на традиционные энтерпрайзы — почему они так к этому относятся? Потому что, извините меня, там деньги: и если будет downtime в каком-нибудь крупном банке, в России например, я вас уверяю, что если с командой сопровождения или с SRE-инженерами не разберутся, они вас вызвонят ночью — и вполне себе нормально у них всё будет.

[1:12:33] Александр: Вот я как раз — да, ты сказал, что у нас как будто немного разное понимание тулинга, и я понял, что да. Для меня тулинг как для разработчика в современном мире — это как раз quality gates и всё, что вокруг них связано. Потому что я-то код руками не пишу. Соответственно, мой тулинг теперь — это не то, что мне помогает код писать руками, навигироваться по нему или даже запускать автоматически. Ну давай, положа руку на сердце: мне вообще насрать, как Клод запустит моё приложение. Я знаю, что нормально: он напишет нормальный compose, напишет вокруг него пару адекватных шелл-скриптов, и это всё будет работать на сто процентов. Это не будет какой-то откровенной ерундой. И ещё это будет работать на CI. И потом разработчик, который себе стянет через git pull, запустит этот же скрипт — и у него заработает. А мне больше ничего и не надо, положа руку на сердце. То есть в этом плане тулинг меня даже не интересует. Меня интересует, например: а что, когда агент сгенерировал код, — что дальше? Вот если он сгенерировал фигню, я хочу теперь как разработчик, как инженер, эти quality gates к себе как-то притянуть поближе, чтобы они были максимально удобные, чтобы я своего агента контролировал этими quality gates. То есть у разработчиков появляется новая потребность: мы теперь хотим обложить наших агентов максимальными форматтерами, чекстайлами, PMD и так далее, чтобы он меньше косячил и чтобы нам было проще принимать на себя ответственность за его код. И в этом плане у меня есть ряд огромных вопросов, которые вызывают искреннее удивление. Потому что Java действительно очень огромная экосистема, и много людей, которые пишут на Java. И мне интересно: а как так вышло, что, например, в Rust есть Clippy — это, по сути, PMD/Checkstyle в Java, — который ты запускаешь, и он тебе: у тебя вот здесь бага, или здесь в новой версии надо писать вот так, здесь у тебя будет возможный race, а тут лучше тебе Mutex вместо этого использовать. То есть это такой анализатор — что-то гибридное. И в чём там суть? В том, что, во-первых, я могу всё это настроить на уровне Cargo-тулинга: то есть это батареечка, которая есть, я просто установил Cargo — и это у меня есть как экосистема прямо языка. Мне не надо даже никакие мавеновские, градловые плагины тянуть, версии проверять — оно вот здесь, батарейка вместе с языком мне поставлена. И там есть просто восхитительный флаг --fix: когда я пишу clippy --fix, он автоматически фиксит то, что очевидно можно пофиксить. То есть я как разработчик — или я как агент — даже не генерирую код, который он просит: он сам знает. Потому что если ты знаешь, что здесь null-check надо заменить на, не знаю, assertNotNull, потому что это быстрее на каких-нибудь платформах, — так возьми и замени, ну tool, ты же это можешь сделать. И tool в Rust это делает. То же самое про rustfmt: просто штука, которую запускаешь, она просто работает — и у тебя код всегда отформатирован. То есть в таких экосистемах, как Rust и Go, нет дискурса о форматтерах. А я в Java-комьюнити, в Java-разработке всё ещё иногда наблюдаю, что люди вокруг стиля кода разводят обсуждения. Какой у вас Checkstyle? А, Google. А вот здесь кастомные rules, а вот тут вот так, а давайте обсудим, давайте создадим митинг, где мы решим, как мы обрабатываем — не знаю — или как мы лямбды пишем, или пишем мы for each, или for each в лямбде… Да кого вообще это сейчас интересует? Вот я каждый раз себе это задаю, и у меня глаза реально по пять копеек, когда я это вижу: типа, люди всерьёз это делают. А вот в Rust и в Go — за счёт как раз этого тулинга, в моём понимании тулинга, — этого просто нет как проблемы. Так вот, я вижу ряд проблем у нас в Java-экосистеме, которые появляются в этом новом мире, где мы являемся операторами агентов, — и я пока не вижу решений. Вот, наверное, это основной мой вопросик к Java.

[1:16:29] Миша: Мне кажется, ты миксуешь разные понятия. Во-первых, в Java есть Spotless, который умеет автоматически фиксить, — это код-форматтер, автоматически фиксить умеет. Во-вторых, люди, которые спорят по поводу код-стайла — типа, давайте соберём митинг и так далее, — это вопрос именно инженерной культуры, а не тулинга. Потому что форматтеры кода для этого и нужны: вот у тебя проходит форматирование кода — это означает, что мы приняли решение, что код будет написан так. Если ты считаешь, что форматтер настроен неправильно, то ты можешь — как в Go, в Rust, в Java — прийти, написать тикет, оставить на GitHub, где угодно в вашей системе, сказать: ребят, мне кажется, что наш форматтер, наш rule поступает неправильно, мне кажется, что нужно по-другому форматировать этот код. Без проблем. Но обсуждать в общем случае, что мы совершенно что-то делаем не так, спорить об этом — у тебя для этого есть форматтер. То есть основная задача форматтера — сделать так, чтобы был унифицированный способ форматирования, как повторяющиеся выражения выражать в коде, и чтобы никто об этом не спорил, не тратил на это время. Если люди начинают тратить на это время, то это просто вопрос к процессам, на самом деле, на мой взгляд.

[1:17:45] Александр: Да, я понимаю. Но понимаешь — в Go такого дискурса нет. Он сейчас с тобой возник, и да, ты очень правильную вещь говоришь: это вопрос инженерной культуры в компании. Но я, когда создаю компанию и выбираю основной технологический стек, не хочу свои когнитивные ресурсы тратить на то, что у нас вообще про это у кого-то голова болит. Ну просто реально: в Go этого нет как явления. Люди просто gofmt — и вперёд. Все приняли это. А в Java как будто бы этого нет — в плане, что есть и IDE-форматтер, например: IntelliJ IDEA форматирует код иногда по-разному.

[1:18:27] Миша: Потому что Go гораздо проще, чем Java, с точки зрения синтаксиса. Это, во-первых. Вот смотри, возьми Kotlin, например: там форматтеров — diktat, ktfmt, — этих форматтеров полно, которые могут Kotlin форматировать. В Kotlin компилятор настолько на стероидах, что он просто может творить невероятную дичь: то есть ты посмотришь на эту сигнатуру функции и будешь такой — капец, я не верю, что это компилируется в байт-код. И там очень много может быть вопросов к форматированию. Это же вопрос экспрессивности языка. В Go язык настолько минималистичный, что там, скажем так, форматировать особо и нечего, если честно.

[1:19:19] Миша: Это как, знаешь, в Terraform: в Terraform есть тоже автоматический автоформаттер для HashiCorp Configuration Language. Но извините, там форматировать не так чтобы много — это простой HCL, спорить вокруг этого сложно. А Java — да, она не такая экспрессивная, как Kotlin, принято. Но с точки зрения синтаксических конструкций — с учётом того, что в Java вводятся, ещё раз вспоминай, всякие switch expressions, глубокие деструктуризации, всякий pattern matching, новые синтаксисы постоянно вводятся, украшения, шорткаты, — это всё надо форматировать. Go вообще не такой язык, он об этом не думает. Понимаешь, в чём дело? Обсуждается то, когда есть что обсуждать. А если нечего обсуждать, то буквально нет просто потребности. Вот ты Go приводишь в пример — хорошо, я тебе другой пример приведу. Go — язык, который во многом отказался от ORM. Ну, пытался отказаться от ORM: они как-то открещивались от этого и говорили, что это неправильно так жить, это не по-христиански, в общем. Потом появляются проекты типа GORM и так далее. И на Reddit спрашивают: а как так? То есть настолько залайканная, со звёздочками библиотека, которая позволяет решать проблемы. И всё-таки начинают спорить о том, нужен GORM или не нужен GORM: ORM — это не по нашей философии. — Да нет, вы не понимаете, есть продуктивное приложение, которое… Понимаешь, в чём дело? Это же вопрос не свойства языка — это свойство того, есть ли топик для обсуждения. Потому что если его нет, то и смысла об этом говорить нет.

[1:21:10] Александр: Так, ну окей, ладно. Смотри, давай дальше пойдём — с точки зрения именно современного подхода и вызовов. У меня к Java есть вопрос по поводу как раз того самого времени запуска сложных, тяжёлых приложений. Мне хочется запускать ралли, а-ля лупы агентов, чтобы они в этом своём закрытом уроборосе — я это так называю: я систему саму на себя замыкаю, изолирую и говорю: вот пока не решишь и не оптимизируешь до конца — не приходи. И я в целом заинтересован, чтобы вот этот цикл обратной связи для агента был побыстрее. Потому что сейчас это сильно важно: во-первых, с точки зрения конечной стоимости для меня — и токенов, и скорости решения задач — это решает. Если раньше я мог, например, при долгом запуске Java: ну, кофейку хлебну, в Jira схожу, — и это для меня как для человека соответствовало моему темпу производства кода и его дебаггинга, вот этот цикл обратной связи с Java меня не напрягал; особенно если что-то закэшировалось — в целом норм, перезапускаешь. Но бывают — я думаю, все в enterprise сталкивались — сервисы, у которых тесты прогоняются просто чёрт знает сколько, а локально, скорее всего, всё ещё и не прогонишь, и ты там специальный springboot’овый профиль используешь, чтобы локально прогонять; ну, в общем, как ты ни изгаляешься, этот луп работает. Для агента-то теперь всё по-другому, потому что я хочу быстрее. И в этом плане для меня Java всё ещё медленная с точки зрения именно developer experience: потому что если мы берём springboot’овое приложение, оно может долго стартовать. И это может быть проблемой в современном мире — именно такая, знаешь, новая проблема, с которой мы сталкиваемся. Если раньше можно было сказать: ну какая тебе разница, пять секунд, десять? — то вот, типа, нормальное приложение, веб-сервер, стартует за пятьсот миллисекунд.

[1:23:02] Миша: Да, давай так: я понимаю проблему, но мне кажется, здесь нужно сделать немножечко шаг назад. Java сама по себе, ещё раз, — это язык энтерпрайзов в современном мире. И в большинстве своём — я понимаю, что есть люди, которые не пишут никаких тестов, а если пишут, то юнит-тесты, и вообще на моках, — но если мы говорим про компании, где есть инженерная культура, где люди относятся к своему пайплайну проверки качества кода более ответственно, то вот именно в Java запуск springboot’ового приложения… Смотри: если ты пытаешься решить какую-то проблему — как ты говоришь, в цикле дать агенту, — то агент что делает? Он пытается исправить какой-то баг и пытается запустить тесты, чтобы проверить, что в его понимании всё в порядке. Он пытается запустить тесты в проекте, чтобы убедиться, что проблема решена. А тесты на Spring и на Spring Boot могут быть довольно медленные за счёт того, что поднимается определённый контекст. Но ещё раз: зачем это делается? Для того, чтобы повысить качество тестирования. Если мы говорим про springboot’овые приложения, которые пишутся в enterprise, про качественные springboot’овые тесты, то тебе нужно будет поднимать контекст — ты это захочешь делать. Если ты захочешь добавить в тесты Testcontainers — а ты захочешь это сделать, иначе как бы ты проверял тот факт, что ты корректно работаешь с базой данных, — контейнеры будут подниматься, и они будут подниматься тоже, может быть, даже не очень быстро. Особенно если предположить, что ты не используешь reusable-контейнеры — а ты, скорее всего, не используешь. И на деле здесь, конечно, существуют некоторые трейд-оффы: что джавовый билд в целом — билд самой Java с тестами и так далее — может быть долгий. Я тебе привожу контрпример. У нас в Axelix большая монорепа на GitHub — большая монорепа прямо, можешь на GitHub открыть. И у нас суммарно сейчас, я прямо смотрел по тестам — у нас агрегированный репорт строится по всем тестам, которые бежали в системе, в стартерах и так далее, — у нас там полторы тысячи с лишним тестов. И вся монорепа билдится — если я сейчас прямо начну её билдить с Gradle, уберу build cache, configuration cache и так далее — буквально за две-три минуты. Вся монорепа. Я понимаю, что Go компилируется быстро — Go компилируется быстро, действительно: что там компилировать? Это не Kotlin-компилятор, которому приходится пыхтеть постоянно, чтобы понять вообще, куда это и как должно скомпилироваться. Но ещё раз, вопрос же в том, что в сборке больше всего доминирует время тестов. И дальше возникает вопрос: а насколько качественные ты хочешь свои тесты? Java — язык энтерпрайзов. И энтерпрайз готов Jenkins или там где-то побольше пособирать: да, пускай у нас разработчики не семи пядей во лбу, они не будут оптимизировать Spring Boot-контекст в тестах профайлером, тест-профайлером, — чем, кстати, мы занимаемся в Axelix: мы там просто пипец как это оптимизируем. У нас есть чувак из опенсорса, который, наверное, на Joker выступит в этом году с докладом — я надеюсь, он там уже заявку подал, — где он рассказывает про то, как он это у нас оптимизировал: он прямо pull request’ами забрасывал. И да, действительно — это просто то, за что ты платишь. Это качество тестов. Если мы будем предполагать, что именно компиляция не является камнем преткновения — а она на самом деле не является чем-то очень долгим именно в мире Java, — то долго в билде всегда именно тесты. Любой Java-билд: время занимают интеграционные тесты. Но я тебя уверяю: если мы сейчас на Go будем писать тесты такого же уровня качества, с Testcontainers и так далее, то разница во времени будет вообще небольшая. Я бы не сказал, что здесь есть какая-то проблема именно с платформой. Это просто вопрос того, что в Java очень принято иметь большие сервисы. Вот в Go, например, — если уж такая пьянка пошла, — вообще не принято иметь прямо очень большие микросервисы: у них сервис очень маленький, миниатюрненький. А в Java нормальная история — иметь микросервис на пятьдесят, семьдесят, восемьдесят тысяч строк кода. Прямо кода, действительно, без учёта хедеров, лицензий и так далее, может быть, без JavaDoc. Это нормально, такое происходит. А в Go просто не так. Проблема ли это Java? Да я бы не сказал. Просто ещё раз: место Java — это enterprise, это прямо действительно enterprise. Go тоже там находится, но… Мы сейчас можем за это тоже похоливарить, конечно. Но ещё раз: если мы сейчас возьмём и предположим, что мы на Java напишем такой же сервис, с таким же уровнем качества тестов, тестового покрытия, как в Go, — разница, наверное, будет, но небольшая просто. Я к этому. Конечно, если мы говорим про традиционный enterprise: ты зашёл в банк, и у тебя там есть сервис процессинга торговых поручений от биржи, и ты открываешь сто — сто пятьдесят тысяч строк кода. Микросервис наш такой, стандартный, семьдесят таблиц в базе данных. И там интеграционные тесты и так далее, которые, конечно, никто никогда не оптимизировал; все эти инкрементальные сборки — никто про них никогда не слышал. Понятное дело, что это будет медленно. Но это просто специфика того, где Java находится, — а не языка, я думаю, что нет. Так просто сложились обстоятельства, если коротко говорить. Мне кажется, это не проблема платформы — так сложились обстоятельства просто.

[1:28:40] Александр: Ну вот про тесты, наверное, последнее, что мне хотелось бы добавить. Ты неплохо сказал, что большую часть времени сборки занимает тестирование, — и это абсолютная правда. Сейчас, если бы у меня был код, когда я писал на Spring Boot, я бы взял все тесты, запустил под async-profiler много раз, поставил бы десяток экспериментов, поставил бы задачу Клоду: найди мне самую долгую горячую точку в тестах на flame graph, — и он бы мне показал. И я думаю, что где-то там был бы билд Spring Boot-контекста. Потому что большинство тестов хотят изоляции, а вот этот share, как правило, приводит к каким-то странным вещам. Я всегда писал изолированный, свежий Spring Boot-контекст и свежие Testcontainers запускал — потому что если я хочу в параллель, например, запускать, что мне делать? Ну, короче, там много разных шуток; я такой: ладно, я лучше изолирую, буду на safe space. И загрузка Spring Boot-контекста в хорошем таком Java-приложении, где у тебя несколько стартеров и всякие конфигурации, — это время, реально.

[1:29:46] Миша: Но они кэшируются. Ты, конечно, можешь это отключить, если запаришься. Но я к тому, что кэшировать их безопасно. Это нормально. Если ты захочешь — тебе нужно будет специально сказать @DirtiesContext, есть такая аннотация, или что-то подобное; там можно через lifecycle listener это сделать. Тебе нужно будет явно сказать: чувак, очень важно, я сейчас буду делать грязь — или кто-то до меня делал грязь, я не знаю, — пожалуйста, прямо сейчас для этого теста сделай новый контекст. Я прямо тебя прошу, пожалуйста. Ты, конечно, можешь ему это сказать, но это не дефолтное поведение, потому что Spring это понимает. И я тебе больше того скажу: там ключ кэширования контекстов… Вот, кстати, у нас чувак, который писал ядро Axelix, выступал с хорошим докладом по поводу того, как работает кэширование контекстов в Spring Boot, на JPoint в этом году — доклад тоже выйдет. И он там пояснял, насколько сложным образом устроен этот ключ, именно чтобы проверить кэш-хит. То есть если Spring будет где-то подозревать, что какая-то проперть откуда-то попала — незаконная какая-то, нехристианская, — то он: не-не-не, ни в коем случае не будем брать из кэша, строим новый. Он очень консервативный в этом плане. Есть проблемы — мы, кстати, скоро напишем по этому поводу блогпост, — когда у нас кэширование контекстов выстрелило нам в ногу. Но это буквально один раз за год. У нас так получалось: у нас есть такой компонент, называется Axelix Master, и в тестах в ряде случаев — мы поддерживаем разные базы данных, у нас есть Testcontainers для Postgres, для MySQL и для SQLite. И для большинства тестов мы прогоняем их со SQLite — есть и те, которые с Postgres, с MySQL. И SQLite мы прогоняем в таком режиме, в котором для каждого коннекшена, который открывается к одному и тому же датасорсу, шарится in-memory база данных. И так получается, что если у тебя контекст уходит в сон — то есть он снимается, — и запускается другой тест с другим построенным контекстом, то есть не идёт попадание в кэш, — то старые соединения, которые были в старом Hikari-пуле, нормально не закрывались и, соответственно, оставляли закрытой SQLite-базу данных. И у нас фактически что с тестами происходило — у нас были флаки-тесты. Но это такой узкий кейс, который мы сейчас, я не знаю, в статье опишем: что из-за закэшированного контекста оставался незакрытый ресурс на коннекшене, там была открытая SQLite-база данных — из-за динамики того, как… ну, то есть много вещей должно совпасть. Конечно, иногда это выстрелит тебе в ногу: понятно, что тесты желательно должны быть изолированы настолько, насколько возможно. Это база, я с тобой согласен на сто процентов, — но просто это часто дорого. Если прямо всё поднимать — это очень дорого. Будет ли иногда это стрелять? Я вот говорю: раз в год это выстрелит — возможно, на статью выстрелит. Не в плане на уголовную — на Хабр.

[1:32:51] Александр: Да, я вот сейчас всё это слушаю — и реально ты хорошо подметил, что Java это язык для энтерпрайза. Потому что во всех других случаях я, реально, не понимаю, зачем сейчас используют Java. Окей, я согласен, что в энтерпрайзе есть огромное количество штук, которые за счёт использования Spring и всей этой экосистемы решаются. Есть штуки, которые вносят дополнительные проблемы с этими решениями: то есть надо понимать, что когда мы строим что-то, что решает одни проблемы, мы приносим другие. И более того, мы увеличиваем энтропию системы, которую разрабатываем. Это мне как инженеру немного странно: когда я разрабатываю какой-то сервис, я такой — так, а я же этот код не написал, и он мне не подконтролен; всё, что у меня есть, это конфигурации и аннотации, по сути, и какие-то методы жизненного цикла, которые я могу переопределить, — вот как я могу влиять на систему, которую строю. Ну, потому что я во фреймворке нахожусь. Это просто трейд-офф использования фреймворка, от этого ты никуда не денешься: ты получаешь вместе с этим огромное количество уже протестированного нормального кода, который ты сам не пишешь. Это понятно. В энтерпрайзе оно того, скорее всего, стоит — здесь я согласен. Потому что ты в энтерпрайзе, во-первых, людей меняешь одних на других постоянно; во-вторых, их много; и в-третьих, не всегда квалификация всех людей, которые работают, настолько высока, что люди отчётливо воспринимают систему. Ну, потому что это реальность, в которой мы живём: люди хакают собесы и, вообще говоря, делают работу не очень честно. Это просто жизнь. То есть мы не живём в иллюзии, где все инженеры, где все прочитали Spring Boot in Action, прочитали документацию Spring Boot, следят за тем, что там работает, и вообще могут @DirtiesContext включить с ответственностью — да, я сейчас это на себя беру. Да нет, они просто хлопнут Enter, им Клод предложит — и они зашипают. Вот что будет в реальной жизни. Поэтому здесь — ну, жизнь. Ладно, здесь окей. А если мы отсекаем энтерпрайз и берём просто всю разработку, кроме энтерпрайзной? Во-первых, что такое энтерпрайз — тоже большой вопрос: каждый стартап, если успешный, потом, наверное, частью становится энтерпрайзом рано или поздно. Но вот я сейчас, например, выбирая стек для себя как инженер, который разрабатывает с AI, — я Java не рассматриваю в принципе. И здесь у меня вопрос: останется ли Java на этом рынке, будет ли его расширять, — или она его захватила и будет максимально долго на нём сидеть, и, собственно, новых приложений на Java мы будем видеть всё меньше? Вот такой вопрос.

[1:35:20] Миша: Вопрос не в бровь, а в глаз, на самом деле. Вопрос очень хороший. Вот именно в твоих словах — в том, что «я для своего нового проекта Java не выберу», — мне с тобой поспорить здесь тяжело. Потому что Java объективно, знаешь, как принято говорить, late to the party: она в этом плане всегда была где-то в хвостике, отстающей. Когда в Java говорили про то, что… Ещё раз: я этот язык люблю, я на нём пишу, и даже опенсорс-решение, которое мы разрабатываем, тоже на Java написано — у нас, кстати, Axelix Master это Spring Boot-приложение. Ну да, почему нет. И когда в Java появились виртуальные потоки, это преподносили так, будто это какое-то действительно очень важное нововведение в языке. В принципе, это правда — это важно для языка. Но если мы будем смотреть на это не в отрыве, а в контексте всей программной инженерии, всей экосистемы, языков программирования в целом, — то мы очень быстро поймём, что async/await, всякие вещи, связанные с горутинами, — вообще возможность написания неблокирующего кода в рамках языка, — эта идея далеко не новая. Большинство других языков в том или ином виде это предлагали. Да, в Java реализация очень хорошая, но всё равно надо признать, что она просто поздно пришла. Ну чего говорить, если в Java до сих пор нет string templates — то есть нет шаблонизированных строк. Они просто есть везде, это нормально, — а вот в Java до сих пор нет, представляешь. Это немножко обидно. Но ещё раз: ответ на этот вопрос, на мой взгляд, очень тяжёлый. Потому что я не знаю, что будет с искусственным интеллектом; я не знаю, что нам завтра ребята из какого-нибудь Сан-Франциско придут и скажут: вот у нас есть такая-то модель 2.0, и всё, нам всем теперь точно gg, так что готовьтесь, ребята. Я же не знаю, как это получится. Но в общем случае мне кажется, что пока что у энтерпрайзов нет желания — и это видно по статистике использования Java, кстати, — у энтерпрайзов нет желания переходить на другие стеки пока что. Мне кажется, что новые проекты, возможно, будут начинаться на других языках. Но если мы говорим про поддержку существующих систем, про доработки существующих систем, — то там спокойно будут выбирать Java: опять же, если есть желание написать новый сервис, люди будут спокойно выбирать Java в тех местах.

[1:38:17] Миша: Что имеется в виду под энтерпрайзом? Конкретно, например, в банкинге у них есть чёткий процесс выдачи ипотечных кредитов, автокредитов, кредитов наличными и так далее. То есть есть чёткий бизнес-процесс, который уже функционирует, и есть много софта, который надо написать. И желательно сделать так, чтобы в массе своей этот софт не сильно друг от друга отличался, чтобы у нас была какая-то унификация написанных решений. И в этом плане Java не позволяет тебе выстрелить себе в ногу почти никогда — прямо откровенно, например, как в C и так далее, — и предоставляет хорошую экосистему. И ещё раз говорю: нет пока у них резона переезжать, и это тоже видно по статистике — например, JetBrains каждый год проводят массовый опрос.

[1:39:04] Александр: Stack Overflow проводит опрос, я знаю.

[1:39:06] Миша: Ну Stack Overflow — ладно, помянем: там уже всё понятно, они уже, к сожалению, как ресурс, скорее всего, закончились.

[1:39:14] Александр: Кстати, вот представь себе — никогда бы не думал, что до этого доживу. Это обалдеть просто. Мы пережили Stack Overflow.

[1:39:21] Миша: Да, ты понимаешь, ушла эпоха — это же обалдеть. Я сам помню: у меня на Stack Overflow, не знаю, ответов под сотню дано, может быть, даже больше — то есть я тоже там когда-то что-то отвечал. Но важно-то что? JetBrains каждый год проводят такие опросы, в которых делают срез индустрии — прямо срез того, как она видит и что она делает. Почему? Потому что у JetBrains, понятное дело, экосистема немножко в сторону Java всё равно повёрнута, потому что у них IntelliJ — это всё-таки…

[1:39:51] Александр: Немножко — ты, конечно, мягко сказал. Ну IntelliJ, я бы не сказал, что это не их флагманский продукт.

[1:40:01] Миша: Ну давай так: она у них повёрнута в сторону Java? Да. Повёрнута в сторону Kotlin и так далее. Но всё-таки будем честны: они далеко не только в Java живут. У них есть WebStorm — он не прямо настолько доминирует на рынке, он имеет какое-то признание в мире JavaScript-разработчиков, но там большое количество людей сидят на VS Code, на форках VS Code, на Cursor и так далее. PhpStorm много людей используют в мире — хотя PHP уже такой язык, понятное дело; ну, всё равно его достаточно, тем не менее. И CLion, Rider — то есть у них есть экспертиза в других языках. Просто в Java у них так получилось, что они растоптали рынок, а в других местах они участник рынка — не являются прямо лидером. Но это тоже неплохо. И они проводят опросы каждый год, в которых — ещё раз, можно дать скидку на тот факт, что они находятся в таком пуле, где их окружают люди, часто связанные с Java, — но использование Java вообще не падает. По-моему, оно держится на стабильных уровнях. Можно всегда сказать, что да, конечно, будут люди выбирать другие языки. Я думаю, что да, будут, конечно, выбирать другие языки. Я не пытаюсь быть каким-то апологетом Java как платформы: понятное дело, что мы все программисты, мы все в первую очередь инженеры — мы пытаемся решить проблемы. Просто, на мой взгляд, как это выглядит: нет сейчас объективных причин с неё, например с enterprise, переезжать. Нет такого, что платформа прямо умирает — она не умирает, она сейчас очень активно развивается. Нет причин переходить и потому, что экосистема заброшенная, полумёртвая, — тоже такого нет: будем честны, там самая сильная экосистема, наверное, в мире. Поэтому мне кажется, что она поживёт ещё очень долго. Если ты посмотришь на количество кода, который написан, — именно долгоживущего кода, не как JavaScript, у которого цикл жизни, допустим, год или даже меньше, он переписывается очень регулярно, постоянно дописывается. А вот если говорить про сервисы, которые очень долго находятся в эксплуатации, — а где они долго находятся? В энтерпрайзе. То там пока никто особо не смог их подвинуть в Java. Наверное, время пройдёт, наверное, это когда-то поменяется — когда либо появятся прямо действительно хорошие альтернативы, либо с Java как с экосистемой, с языком, с платформой будет что-то прямо плохо, либо мы уже перестанем код писать совсем. Тогда уже будет вообще неважно.

[1:42:38] Александр: Так, окей. Слушай, мне запомнилась ещё такая мысль — точнее, не мысль, а тот факт, которым ты поделился. Я в именах — у меня просто память отвратительная… Тот человек, который создавал Spring, вот ты его имя называл…

[1:42:52] Миша: Род Джонсон, да.

[1:42:52] Александр: Он сейчас делает что-то новое. И он делает что? Он делает фреймворк для написания AI-агентов на Java. А теперь смотри: учитывая тот факт, что мы подошли к этому человеку с той позиции, что а какой у него был майндсет, какие ключевые решения, что за vision у этого человека был, что получилось сделать Spring Boot хорошим, — и мы с тобой оба тут признаём, что, наверное, чувак-то умный, даже более чем. И вот этот более чем умный чувак сейчас занимается вот этим. То есть можем ли мы с тобой через призму того, чем он занимается, посмотреть на то, что это его vision — и он действительно талантливый, — то это то, чем стоит заниматься подобным людям и куда они двигают этот рынок? То, что он на это обратил внимание, это же многое значит.

[1:43:43] Миша: На фреймворк для написания AI-агентов? Ну, мне кажется, что да, можно на это с такой точки зрения смотреть. Но просто видишь, в чём дело: я думаю, что тут решение больше обусловлено тем, что рынок AI слишком большой. Он растёт очень быстро, какими-то космическими темпами. И из-за этого — даже понимая тот факт, что тулинга и стартапов вокруг AI будет очень много, — за счёт просто масштаба рынка, скорее всего, у него что-то получится. Просто за счёт того, что он далеко не хер с горы, извините за выражение. Это человек, который был в советах директоров разных стартапов, в борде фактически, если так выражаться английскими терминами. То есть это человек, которого довольно хорошо знает Java-индустрия, и он в Java-индустрии же выбирает пилить такой стартап. Он просто, мне кажется, понимает, что написание AI-агентов на Java — ну, скажем честно, это специфика прямо. Я даже думаю, что нечасто это будет происходить. Но тем не менее такое будет, наверняка будет. И с его именем и с его возможностями он наверняка сможет какую-то долю рынка занять. Это нормально. Мне кажется, вот так человек мыслит — я не залезу в голову, конечно, я могу у него спросить, но…

[1:45:06] Александр: Почему меня эта мысль как-то привлекла? Потому что я всё-таки верю, что подобные люди фигнёй заниматься не будут. Он реально верит в то, что это хорошо. То, что просто рынок большой, — это да, но я думаю, там не только это. Потому что я просто этим занимаюсь: я для себя абсолютно такое же решение принял — на что потратить мой талант, время и энергию? Я такой: не, ну надо делать крутых агентов, экосистему, чтобы люди с агентами взаимодействовали. И это то, чем я занимаюсь, потому что я понимаю, что это будущее: это вектор, в который мы как индустрия направляемся и бежим семимильными шагами, даже не учитывая тот факт, что это просто огромный рынок. И в этом плане я, знаешь, могу немножко подумать за другого. И я думаю: вообще говоря, проблема AI-агентов сейчас в том — ну, например, какой-нибудь OpenClaw, — что его просто обновлять невозможно. Он ломается каждый раз при обновлении, потому что это поделка, написанная на TypeScript, и людьми, у которых в целом нет вот этого чувства backward compatibility, знаешь? Вот этого энтерпрайзного вкуса — того, что софт вообще не должен ломаться с апдейтами, — этого просто не существует там. Сломать что-то, перефигачить — всё, плагин не работает, переделать всё на самом деле. То есть ты сидишь — и реально обновление OpenClaw, если у вас там довольно много плагинов и вы с ним работаете, это задача на полдня. Вот я вам реально говорю, это ужас, с которым никто не хочет сталкиваться. На полдня — это ещё ладно. Если вы включились в жизненный цикл — то есть переопределили жизненный цикл условного а-ля бина, только там это плагинная система, и, например, что-то на старте агента делаете, например регистрируете себя в каком-то реестре, — то после апдейта у вас просто он не будет регистрироваться, всё. И это будет после каждого апдейта: потому что плагины ломаются, нормальной статической компиляции нет, всё в рантайме — и ты такой: ну, приехали. И в этом плане — вот почему я, может быть, даже верю в проект. Плагины Spring довольно легко включались в существующие большие реальные приложения, и ничего не ломалось, и это потом можно было апдейтить, и это у людей получалось. Я думаю, что в целом нормальный агент, построенный под такой философией — что у нас есть батарейки в виде тулинга, интеграций, memory и всего такого, всего, что нужно сейчас агентам, — вот эта философия Spring Boot может сыграть такую штуку, что у нас появится просто способ писать стабильные агенты. Но это я так, просто мысли вслух. Не знаю, есть ли тебе что сказать на эту тему.

[1:47:40] Миша: Может быть, может быть. Но если честно, исходя из моего опыта общения с людьми — с Родом и так далее, — они мыслят немножко другими категориями. Знаешь, есть такое выражение в английском языке — down to earth, то есть приземлённое. Они больше смотрят на размер рынка, на конкретную проблему, которую ты будешь решать, на то, как ты будешь встраиваться в экосистему. А тот факт, что у этого инструмента так часто ломаются вещи и вообще заедем ли мы в будущее, — ну, это не то, как они мыслят, мой опыт такой. То есть это как бы важно, да: ты должен понимать, что делаешь софт, который через три года не улетит в помойку. Важно. Но они больше смотрят на то, как конкретно, с кем ты это будешь разрабатывать, кто будет твоим пользователем, почему они будут тебе платить. То есть вопросы у них очень прикладные — больше с точки зрения того, как этот процесс вообще будет выстроен, какое место в экосистеме мы займём, что мы будем делать. В этом плане, кстати, похоже на то, что ты говоришь: тот факт, что мы займём такое место в экосистеме, что вот на Java мы будем беспокоиться за своих пользователей, мы не будем их ломать.

[1:48:59] Александр: Да-да-да, стабильный агент. Дайте мне его поделать.

[1:49:02] Миша: Да-да, конечно. Но просто вместе с этим очень важно — на самом деле Род в том числе такой человек тоже: он очень осторожный.

[1:49:09] Миша: Он очень осторожный, думающий. Я думаю, что он в этом плане хорошо взвешивающий, понимающий свою позицию, своё место на рынке — и то, где конкретно он находится и что он может сделать.

[1:49:27] Александр: Вообще адекватно оценивать и понимать своё место — это крайне важный навык.

[1:49:32] Миша: Да, конечно. Очень важный.

[1:49:37] Александр: Слушай, раз мы тут про AI, про Spring и всё такое. Что в Spring происходит с точки зрения именно тулинга — какие новые батарейки предоставляются? Я, честно, два года уже туда вообще не смотрел, поэтому мне самому прямо интересно от тебя узнать: что по поводу AI? Потому что есть проект Spring AI, я, честно, ничего не смотрел. Если ты что-то знаешь — и, может быть, знаешь что-то ещё про другие проекты, — можешь про это рассказать?

[1:49:56] Миша: Да, конечно, Саш. Здесь, наверное, этот вопрос на две части. Во-первых, что делается в рамках интеграции с AI — чтобы люди, которые пишут софт на Spring, могли каким-то образом интегрироваться с AI. И вторая часть вопроса — как сам Spring делает так, чтобы людям, которые пишут на Spring, было удобно писать на Spring с использованием AI-агентов. Давай так: ответ на первый вопрос — то есть как они делают так, чтобы людям было просто интегрироваться с какой-то языковой моделью, какой угодно, в облаке и так далее, — это Spring AI и вообще все продукты вокруг него. Spring AI — это такой зонтик проектов, которые, с одной стороны, позволяют вам работать с языковыми моделями, а с другой — позволяют делать всё вот это: эмбеддинги, RAG, то есть retrieval augmented generation, все возможности сохранения памяти в чате и так далее. То есть всё, что тебе необходимо для поддержания контекстного окна, — всё это тебе даёт ряд проектов в рамках Spring AI. С другой стороны, у тебя есть тулинг, который позволяет тебе писать интеграцию с AI, например в виде MCP-серверов. Вот хороший пример, кстати, — извини, что я снова в эту сторону ухожу, — но у нас в рамках Axelix просто есть MCP-сервер, он написан на Spring AI; у нас очень много своего собственного тулинга вокруг него тоже, но неважно. Важно то, что этот проект очень разнообразный: он во многом просто имеет целью любой аспект интеграции с искусственным интеллектом — как с чат-моделью, как с моделью, которая способна распознавать изображения, то есть разные медиатипы фактически потреблять или производить; как возможность написания MCP-серверов; как возможность каким-то образом наполнять контекст. Это всё — про Spring AI. Ну и, само собой, там огромное количество модулей, которые интегрируются с разными моделями: с амазоновскими, с антропиковскими, с гугловскими, с OpenAI и так далее. Это ответ на первый вопрос — что они делают, чтобы люди могли интегрироваться с AI. А есть второй вопрос, и мне кажется, он ещё более интересный. Потому что, если быть честным, не так много людей будут писать код, который будет интегрироваться с языковой моделью. Такое, наверное, будет распространяться в ближайшее время, но большая часть софта — будем всё-таки приближены к земле — пока будет плюс-минус детерминированной: экономическая диффузия, это реальный термин, реально имеет место быть. Что в итоге будет? Да, конечно, люди будут писать софт, который интегрируется с AI, но не так много. Что действительно важно — так это то, чтобы у разработчиков, которые пишут на Spring Framework, была возможность писать с помощью AI-агентов качественный код на Spring Framework: условно говоря, какие-нибудь качественные Spring Data-запросы с его помощью делать. Такой вопрос в своё время задал Сергей Чернов — довольно хороший, талантливый инженер. Я просто помню, что у нас была брифинг-сессия с командой Spring — это, кстати, было в Барселоне в этом году, буквально месяц назад. И он просто берёт и задаёт такой вопрос: а вы не думали написать свои собственные, условно говоря, скиллы — чтобы люди могли просто как-то склонировать их из опенсорса, подключить (ну, либо с помощью какого-то agent package manager, майкрософтовского, любого менеджера этих скиллов) к себе, к своему проекту?

[1:53:58] Александр: Хороший вопрос.

[1:53:59] Миша: Да — чтобы люди могли просто взять, от создателей Spring, чтобы были прямо скиллы для написания, условно говоря, springовых бинов правильно: чтобы вы их правильно объявляли, а так, как не надо, — не делали. И я просто помню, что Себастьян с Кристианом переглянулись, и Кристиан сказал: мы подумаем, идея очень крутая. Кристиан Цолов — это сейчас лид Spring AI. А Себастьян — это человек, который фактически стоит у руля Spring AI сейчас; скажем так, это как раз тот чувак, который отвечает за новые фичи в Spring AI и вообще в целом в Spring AI.

[1:54:38] Александр: У меня тут есть мысль. Если этого ещё не произошло — потому что идея для AI-инженеров лежит прямо на поверхности, уже в начале декабря хотелось бы эти скиллы иметь, когда Opus выстрелил и всё стало понятно, — то, что этого не появилось, значит только одно: что инженеры, которые разрабатывают Spring, не делают это с агентами. Если бы они делали это фултайм с агентами, они бы такие: господи, это же надо срочно делать, чтобы люди тоже делали. И в этом как раз проблема того самого догфудинга, о котором мы в начале говорили: если они сами не догфудят AI-driven development, то скиллы получатся плохие, это сто процентов. И тут мы просто попадём в ситуацию: ну да, от создателей — но если они их сами не используют каждый день, то ничего хорошего не выйдет. И возможно, стоит нам как комьюнити об этом подумать и сделать что-то действительно классное, просто не знаю.

[1:55:28] Миша: Слушай, возможно. Возможно, стоит — мне кажется, мысль-то хорошая. Просто видишь, в чём дело: я не уверен, что есть какие-то однозначные вещи, которые мы сможем прямо сделать лучше, если дать агенту какой-то скилл, чтобы он не допускал вот эту частую ошибку. Хотя, если честно, такие вещи есть — мне сейчас в голову приходит пара моментов. Нет, всё-таки есть, да, всё-таки есть. Странно предположить, что о них команда Spring не знает: я думаю, что о них команда Spring довольно хорошо знает, — но возникает вопрос, а будут ли они это писать. Потому что большинство проблем, которые мне сразу приходят в голову, — это проблемы, например, на уровне работы с данными или проблемы с security breach’ами. А люди, которые работают с данными, — эта команда Spring, она такая маленькая; вот Марк Палух — он такой человек, который не то чтобы очень рад искусственному интеллекту: я думаю, просто зная этого человека, он такой — отстаньте от меня, у меня более важная задача.

[1:56:34] Александр: Вот-вот. Я именно про это и говорю: раз этого не появилось — значит, они просто аккуратно к этому относятся.

[1:56:41] Миша: Ну да, они на самом деле — если поспрашивать команду Spring — очень аккуратно к этому относятся: они в лучшем случае сдержаны. То есть нет такого, знаешь, что у нас там в каждом проекте уже AGENTS.md, .cursor, сабагенты, скиллы, у нас всё уже настроено пятнадцать раз, подключен менеджер для этих агентов, у нас мультиагентные системы уже давно — нет, там вообще нет такого уровня. Но что сказать? Это, возможно, правда, кстати, что они просто чуть-чуть в этом плане отстают от того, что происходит. В целом в этом ничего такого плохого нет: не надо бежать впереди паровоза — можно просто сесть в нужный вагон и поехать с тем же самым паровозом, не делая ошибок и не подставляясь. Это тоже хорошая стратегия — неплохая, умеренно консервативная. Но здесь для меня лично важно то, что я сейчас наблюдаю: некоторое разделение на тех, кто… Вот в OpenJDK, по-моему, недавно сказали, что они не принимают сгенерированные pull request’ы, — и вот это меня настораживает. Прямо настораживает то, что они как будто хотят оградиться и жёстко выставить: нет, мы такие не принимаем. Хотя проблема понятная — история… я не знаю, в курсе ли ты прямо глубоко этой истории.

[1:58:13] Александр: Я знаю, знаю.

[1:58:15] Миша: Проблема в том, что они просто сгенерированные pull request’ы не хотят ревьюить: потому что там много багов, они сложные, и люди нагрузку не вывозят. Понятная проблема. Простого решения у этой проблемы нет — это тоже факт, это реально новая проблема, с которой мы как индустрия сталкиваемся. Много опенсорс-проектов сталкиваются с огромным количеством pull request’ов, про которые сложно понять: это осознанный нормальный запрос, человек за него печать поставил — и сейчас я его поревьюю и залью…

[1:58:45] Александр: У меня просто такое было: я просил своего агента — поправь, — он пошёл и поправил в апстриме, pull request сделал. Я такой: блин, что? Закрывай. То есть я заглянул — а кто-то не закрывает, и это остаётся. И вот что с этим делать? Что мейнтейнерам с этим делать? Я прекрасно это понимаю. Но вот этот радикализм — «нет, мы не будем», — для меня это значит, что мы отказываемся от нового ресурса в виде AI, который генерирует код, и остаёмся на человеческом коде. И я такой: ну блин, ребята же просто сами себя тормозят. И вот эти тормоза… Я не знаю, как к этому относиться, интересно твоё мнение услышать.

[1:59:29] Миша: Я не думаю, что они себя этим тормозят. Смотри: ядро OpenJDK — давай так, если взять даже HotSpot, — он в несколько раз меньше, чем Hibernate, понимаешь? Я просто к тому, что там очень часто не нужно… Понимаешь, в чём дело: агент будет продюсить код с большой скоростью, скорость продакшена кода увеличивается. А вот на эту тему очень хорошо — я могу сейчас ошибаться, конечно, — это, наверное, даже не Брайан сказал, он, возможно, это сказал… Какой-то из архитекторов Java это сказал, человек, который во многом отвечал за Project Loom и так далее, — на сессии общения с архитекторами Java. В Сан-Франциско проходит конференция, называется JavaOne, и в ней одна из ключевых секций — это возможность в течение часа пообщаться с Java-архитекторами: там прямо такая BOF-сессия, она записывается и потом выкладывается. И там вот этот товарищ — я ещё раз говорю, извиняюсь, фамилию не помню, — сказал, что им этот вопрос тоже задавали. Причём это понятная история, что это во многом исключительный проект. Например, Spring тоже получал AI-слоп — но они лишь сказали «а-та-та, не делайте так», ни в коем случае не стали от сообщества отходить: просто Себастьян уже несколько раз постучал рукой по столу и сказал — не делайте так, пожалуйста, иначе мы будем по рукам бить, мы вас просто запомним. Такого радикального решения не было. И вот когда их спросили, они сказали, знаешь, какую вещь? Что написание кода вообще в целом — в ряде их кейсов — это вообще не bottleneck. Если посмотреть на процесс разработки, то часть, связанная с написанием кода, с созданием прототипа, с написанием рабочего решения, — этот процесс очень быстро ускоряется. Но у них большая часть времени уходит, знаешь, на что? На обсуждение в мейл-листах; на то, как не сломать backward compatibility; на то, как сделать так, чтобы потом поддерживать forward compatibility. Изменение, которое мы делаем, должно соотноситься с другими проектами в рамках OpenJDK: мы же работаем в разных проектах, но должны понимать, что в итоге создаём один продукт. И эта фича создаётся не в вакууме — она создаётся вместе с вот этой фичой, которая в том проекте, и надо понимать, как они будут взаимодействовать. У них очень много времени уходит на дизайн, а код, как правило, вообще не bottleneck. И в этом плане они просто понимают, что есть некоторый сет доверенных контрибьюторов, с которыми они общаются, — и это окей. А если они сейчас будут генерировать код искусственным интеллектом — даже сами; ряд архитекторов говорил, что они что-то подобное пробовали, — понятное дело, что это… Это такие ребята уже в возрасте, тот же Брайан, — но они с агентами тоже как-то работали. И на практике они просто понимают, что это не даст никакого значимого результата в работе: скорее всего, это никак особо сильно не ускорит процесс разработки. Знаешь, что очень важно? Мне, кстати, об этом в своё время Володя Ситников сказал, причём пару лет назад, — и я только со временем понял, насколько это важно, насколько это реально правда. Володя Ситников, для тех, кто не знает, — это человек, который сейчас в основном поддерживает PostgreSQL JDBC-драйвер; это просто база, то есть то, на чём работает современный бизнес, энтерпрайз — база данных PostgreSQL. Он сказал, что чаще всего проблема не в написании кода, а в качественном ревью: сделать так, чтобы понять, посмотреть и сказать, что это действительно то, куда мы хотим идти, что это правильно. И PostgreSQL-драйвер — вот как часто ты слышишь о каких-то взрывных фичах в PostgreSQL-драйвере? «Невероятный прорыв совершили» и так далее — я ни разу в жизни не слышал.

[2:03:50] Александр: Я думал, ты скажешь: а он существует? Нет, я знаю, но это же JDBC-драйвер, это часть… Скажи, что там делать-то вообще? Что там делать? Протокол имплементируешь, мапишь…

[2:04:02] Миша: На самом деле там, в драйвере, много всего можно оптимизировать, и много всего в PostgreSQL просто закручено до невозможности. Просто нет необходимости там настолько быстро бежать, нет необходимости дорабатывать это с такой скоростью. Давай так: конечно, хотелось бы, чтобы фичи деливерились быстрее. Но ещё раз: боттлнек в доставке фич, например в команде OpenJDK, выражается не в написании кода, а в дизайне — в продакт-дизайне, в дизайне того, как это будет работать, встраиваться в существующую экосистему. Поэтому мне кажется, что это решение всё равно радикальное, конечно, но, мне кажется, они его в какой-то момент ослабят — а сейчас просто принимают такое решение. Знаешь почему? Потому что когда у тебя есть проблема, что мейнтейнеры тратят своё очень ценное время на ревью pull request’ов, которые рискуют сломать API, рискуют быть непроизводительными, — вместо того, чтобы тратить время на вещи, которые реально двигают и продвигают язык вперёд, — это проблема для них. То есть к ним пришли и сказали: мы вам можем сейчас генерировать код быстрее. А они говорят: а у нас такой проблемы никогда не было, у нас это никогда не было боттлнеком. То есть к ним пришли и создали для них проблему. И фактически первая их реакция — сделать так: наверное, эта технология перспективная, но давайте пока не будем этой ерундой заниматься, у нас пока это не болит.

[2:05:37] Александр: Есть всегда риск того, что можно остаться за бортом, — прямо вполне реальный риск, я думаю, что он есть, база. Потому что может потом оказаться, что реально выйдет какая-нибудь новая модель, ещё какая-нибудь от OpenAI прямо завтра выйдет — и все поймут: вот оно, это оно. Уже в пятнадцатый раз «оно», — и всё, теперь уже точно можно ему довериться больше, чем архитектору Java, например. Он просто сделает, найдёт лучше и решит те проблемы, о которых даже не подумал условный Рон Преслер.

[2:06:15] Миша: Ну, может быть, да. Но просто ещё раз: в моём понимании они просто занимают выжидающую позицию. Знаешь, как ещё, кстати, об этом в своё время сказал Линус Торвальдс? У них же тоже была проблема — я думаю, наша аудитория, может, в курсе, может, не в курсе, — была история, связанная с тем, что был патч, сгенерированный искусственным интеллектом, который тоже, кстати, прошёл ревью, который приняли, смержили — и который сломал перформанс полностью, просто сломал перформанс, сломал API. Это была проблема, по-моему, когда очередное ядро выходило. Линус к этому так отнёсся: он говорит, что в целом какие-то кусочки генерировать и так далее нужно, но вы остаётесь теми, кто ответственен за ваш код. Так и есть: вы ответственны за этот код, который был сгенерирован. У него такая позиция: давайте немножко подождём и посмотрим, во что это выльется. Потому что сейчас такое турбулентное время, когда технология — я думаю, будет справедливо сказать — до сих пор формируется. Вспомни двадцать третий год, Саш: нас всех учили — zero-shot, one-shot, few-shot examples, chain of thought, всякие паттерны промптирования, prompt engineering, — нас всему этому учили. Потом такие: не-не-не, всё это не нужно. Потом нас учили как-то тюнить контекст, RAG. Не-не-не, нам всё это не нужно — у нас есть скиллы. Понимаешь, она настолько турбулентная, вся эта история, что за пару лет всё переворачивается с ног на голову, потом снова с ног на голову. И совершенно непонятно, в каком мире мы окажемся через год — не говоря уже про три года. И Линус в этом плане говорит: смотрите, ребят, давайте так — у нас есть процесс, он не без проблем работает; я осознаю проблемы с искусственным интеллектом, осознаю, что могут быть нюансы, проблемы с процессами, — просто несите ответственность за свой код, пожалуйста, и давайте сейчас в этом плане слишком агрессивно не вайбкодить, а займём выжидательную позицию: будем смотреть и думать над тем, что получится. Мне, кстати, эта позиция даже больше близка.

[2:08:19] Миша: Просто, знаешь, это как «тише едешь — дальше будешь»: здесь, конечно, нельзя ехать слишком тихо, потому что индустрия может умчаться. Но я думаю, что от таких проектов, как OpenJDK, как у Линуса, никто никогда не умчится: извините меня, это просто база, это опыт, построенный десятилетиями. И там не будет такого, знаешь: всё, мы написали свою собственную референсную имплементацию OpenJDK или свой форк Linux, работает в десять раз быстрее — ребята, все онборд. Не будет энтерпрайз на тебя смотреть: да-да, конечно, мы прямо сейчас на тебя пересядем. Не будут.

[2:08:56] Александр: Да, в общем-то, мне тут важно — просто интересно даже понаблюдать за тем, насколько долго это всё продлится и когда деды очухаются и скажут: ладно, окей, запрещать не надо. Потому что я как чел, который всё пишет с Клодом и несёт ответственность за то, что он делает, — мозги у меня на месте, — я это воспринимаю так: а вот я захочу найти security-багу с новой моделью в OpenJDK, сделать доброе дело. Естественно, я заряжу сабагентов на этой нейронке, сделаю сто экспериментов, поизучаю, сделаю починку — и принесу. И мне это сделать сейчас запрещают, потому что я это сгенерировал. Да, я это сделал качественно, основательно, сжёг кучу времени, несу ответственность — но принести это я не смогу, потому что код сгенерированный, я нарушаю договорённости. Я это даже, знаешь, немножко на личный счёт воспринимаю. Хотя тут тоже надо понимать: допустим, я бы не сильно туда хотел что-то заносить, — но хочется послабления этих гайдов, потому что возможности что-то законтрибьютить хотелось бы иметь. И, наверное, заканчивая эту тему — вообще про всё в современном мире Spring Boot: Java-разработчикам, которые, может быть, подумывают на рынок выйти, посмотреть на российский, или на европейский, или американский, — вот что сейчас с точки зрения этого турбулентного мира? Турбулентность высокая: кто-то всё ещё сидит в IntelliJ IDEA, программирует, руками перезапускает, дебажит и полностью несёт ответственность за код — руками всё, хендмейд, что называется. Кто-то Copilot только познал. Кто-то такой: ну, Junie пробую, что-то она делает, пару десятков долларов могу себе позволить, у меня лимит в компании. Кто-то уже Клода подсоединяет, кто-то закрыл IDEA, фигачит с Клодом и деливерит X10. Все разные, все по-разному — турбулентность реально. Как ты считаешь, с твоей позиции: что важно знать, что важно изучать, куда направить свой поток развития как профессионала сегодня?

[2:11:16] Миша: Экспертизу развивать. Важно понимать, что в искусственном интеллекте, мне кажется, вот что очень важно. Ребята, которые сейчас приходят в индустрию, — во-первых, они приходят в индустрию, в которой выходит Дарио на подкаст и говорит: ну, ваша песенка спета, сейчас выйдет AGI, и никто из вас не нужен будет; извините, но так получилось. Выходит какой-нибудь CEO из OpenAI, из Anthropic — и они вот с таким нарративом. В индустрию идёт меньше людей — объективно; это видно, кстати, по американским вузам: просто меньше людей идёт. Теперь смотрите, что важно. С учётом того, что люди начинают такими вещами заниматься — постоянно используют AI-агентов и так далее, — они некоторые свои навыки просто потихоньку атрофируют. В ряде случаев это нормально: люди когда-то охотились на мамонтов вживую, и сейчас этот скилл у них атрофировался, он им не нужен. Это нормально.

[2:12:23] Александр: Нормальное сравнение, я возьму на вооружение.

[2:12:25] Миша: Ну я, конечно, специально возвёл это в абсолют, взял слишком далеко: понятное дело, что мы сейчас не в таком сравнении находимся, — но чтобы сравнение было очень очевидным, контрастным. Понятное дело, что скиллы имеют свойство отмирать: они могут просто не пригодиться в будущем, и это нормально. Поэтому я не к тому, что это хорошо или плохо. Но, к сожалению, одна из вещей, которая происходит — и это уже признаётся, и я думаю, что большинство людей, кто активно использует искусственный интеллект, с этим согласны, — они перестают довольно глубоко самостоятельно интерпретировать и понимать, что вообще происходит в софте. Они перестают иметь глубокую экспертизу в тех или иных предметах — она просто теряется, потому что нет необходимости. А опыт и экспертиза, знаете, когда наращиваются? Тогда, когда ты сам лично писал код, понял, что это плохо, знаешь боль того, как поддерживать такие системы; сам лично знаешь, насколько плохо потом это дебажить, трейсить; сам лично знаешь, что вот это будет работать, а потом вот так вот оно будет стрелять. Вот это опыт — ты его наработал, ты его выстрадал. Выстрадал — это важно. Этот опыт позволяет тебе потом использовать и агентов, и принимать более оптимальные решения. Конечно, если ты написал десяток типовых микросервисов на Spring Boot и пишешь одиннадцатый — то да, Claude Code, Opus: вот тебе лошадь, короче, езжай на ней, вперёд. В принципе, так и надо делать. Но на мой взгляд, в ситуации, когда ты изучаешь новую тему или пытаешься развить свою собственную экспертизу, — вот прямо, ребят, развивайте её: убираем агентов и пишем сами, наращиваем боль сами. Потому что если мы этого делать не будем, то понимания того, всё ли агент сделал правильно, у вас просто не будет — вы не сможете принять оптимально правильное решение. Возникает вопрос: нужно ли оно будет вам в будущем? Может быть, будет настолько сильный искусственный интеллект, что вам даже не нужно будет думать над тем, насколько правильно он себя здесь ведёт, не ерунду ли он делает; может быть, можно будет просто положиться на него. Я не знаю, может быть, так будет. Но если так будет — то тогда, ещё раз говорю, это будет совсем другой мир, и тогда ваша экспертиза не будет иметь значения. Это как ящик Пандоры: когда мы его откроем, непонятно, что будет. Но давайте предположим… Вот недавно выходила статья у автора curl, где он написал, что ему дали возможность промониторить его проект с Mythos. И Mythos особо ничего сверхъестественного для проекта не сделал: нашёл одну low security vulnerability — по сравнению с тем, что делал до этого Opus. То есть давайте просто представим себе на секундочку, что инженерная экспертиза до сих пор будет нужна. Так тогда наращивайте её. И наращивать её нужно именно таким образом: типовые задачи, которые вы решали много раз, где вы уже высосали весь опыт, который могли, — вот отдавайте их Клоду, или Cursor, кому угодно, вашему AI-агенту: пожалуйста, пускай он там под капотом пыхтит и работает. Но если вы сейчас решаете какую-то конкретную проблему и отдаёте это Клоду, потому что не хотите этого делать, просто не хотите в этом разбираться, — тут, конечно, ваше дело, вы можете поступать так, как желаете. Но на мой взгляд, если вам ценна экспертиза, то ни в коем случае не надо в таком случае использовать агентов. Агент, ещё раз, — это ваш спидап, это должно вас ускорить в моментах. Но есть, к сожалению, такой побочный эффект — и это, мне кажется, не только моё наблюдение, это наблюдение и других людей: когда люди начинают использовать агентов массово, они в какой-то момент просто не могут без них жить совсем. У них не возникает мысли — они перестают думать, перестают воспринимать проблему так: а что здесь может быть не так? А что может пойти не так? В чём тут может быть проблема? Он такой: я в душе не чаю, в чём тут может быть проблема. Клод! И больше не думает. Вот это плохо. Потому что запускать Клода и делать вот эти стандартные springboot’овые микросервисы за тебя сможет большое количество людей — порог вхождения сильно снизится, — а ценность экспертизы, именно ценность экспертизы, того, чтобы гайдить, куда мы пойдём, будет расти. А экспертиза нарабатывается только тогда, когда ты сам написал код, сам сломал продакшн, сам обосрался и сам починил. Вот тогда ты нарастишь экспертизу. Но для этого тебе нужно отпускать агента туда, куда можно — где ты уверен, что ты уже всё понимаешь, — а там, где ключевым для тебя является наращивание своей экспертизы, — туда не подпускать его даже близко.

[2:17:37] Александр: «Не подпускать даже близко» — у меня, конечно, формулировка немного настораживает. То есть ты имеешь в виду, что какие-то части, например новые для себя, где я никогда не писал… Ну давай так: я никогда не писал виртуальную машину, но я хотел бы это сделать, создать её. То есть я сейчас должен взять виртуальную машину и начать писать руками — то есть не подпускать агента, значит не давать ему генерировать код той системы, которую ты разрабатываешь, правильно?

[2:18:09] Миша: Мне кажется… Давай так: ответ да, но проблема в постановке вопроса. Ты говоришь: я никогда не писал виртуальную машину. Но здесь всегда возникает вопрос: а нужно ли оно тебе? Вот нужно ли оно тебе? Я не знаю. Например, давай так скажем: я в своей жизни никогда на Lua не писал никакие моды к каким-нибудь играм, к Minecraft и так далее. Оно мне нужно или нет? Да нет. Понимаешь, в чём дело: возникает вопрос, нужен тебе этот скилл или нет, нужен тебе этот навык или нет. Это уже вопрос к тебе — к тому, как ты себя воспринимаешь и как ты себя видишь.

[2:18:47] Александр: Конечно, нужен — раз я про него сказал. Я базу данных свою пишу каждый месяц, я люблю такие штуки. Именно в этом я свою экспертизу и вижу.

[2:18:57] Миша: Нет, если так, то, конечно, без проблем.

[2:18:59] Миша: Ну то есть пытайся, делай, конечно. Да, нужно.

[2:19:01] Александр: И вот вопрос. Мы говорим, что да, это нужно — то есть не то чтобы я занимаюсь какой-то фигнёй, типа это надо. И я просто как пример чего-то нового, где у меня нет экспертизы: я вот не знаю, как интерпретировать байт-код, мне бы хотелось это узнать — интерпретатор написать свой. Вот это я должен, типа, писать руками? Но вот тут у нас позиция расходится: потому что я всё равно, естественно, это буду генерировать — но я просто буду вникать в то, что происходит, на более детальном уровне, чтобы в голове представить, как это работает, и уметь эти кубики двигать. То есть вникать и углублять экспертизу — да; но код писать руками в двадцать шестом году для меня звучит как… ну вот действительно: давай на мамонта поохотимся.

[2:19:40] Миша: Нет, на мой взгляд, это так не звучит. С тобой нейрофизиология вообще не согласится: человек учится тогда, когда делает ручками. Ещё раз: мы должны чётко себе ответить на вопрос, что мы делаем. Мы клепаем типовое решение, которое ты клепал уже пятнадцать раз, — или ты учишься? Если ты учишься, то ты не можешь просто читать чужой код. Окей, за тебя написал Claude Code, за тебя написал разработчик Spring Framework или HotSpot — да без проблем: иди на GitHub, читай, как написан HotSpot; поймёшь, как он написан, разберёшься, поймёшь, почему они там какие-то вещи сделали так или иначе. Нет, Саш, нет. У человека просто так устроен мозг, что он воспринимает информацию очень плохо. Очень плохо: когда читает — плохо, на слух — очень плохо; когда видит — получше; а ещё лучше — когда ручками сам делает. То есть тогда восемьдесят процентов информации остаётся в голове. Ты можешь, конечно, прочитать то, что написал Claude Code, и подумать, что я запомнил. Но смотрите, ребят, проведём мыслительный эксперимент: сколько технических статей вы прочитали за свою жизнь? Я вам реально говорю: если вы сейчас попытаетесь вспомнить какие-то реально отличительные технические статьи — вы их вспомните; но даже если вспомните, из них вы вспомните процентов двадцать по материалу. Это так, так работает наш мозг. Это неплохо — это просто вопрос того, насколько оно тебе надо. Если ты говоришь, что мне достаточно этих двадцати процентов от написания базы данных, что ты готов понимать это на таком уровне, — то флаг в руки, без проблем. Но если ты говоришь: я хочу в этом детально разобраться, чтобы, например, потом пойти и разрабатывать Cassandra, Neo4j, CockroachDB, — вот ты пойдёшь потом, устроишься в американский стартап, в CockroachDB, допустим, будешь разрабатывать аналог вот этого Bigtable, которое в Google, Google Spanner и так далее, — вот если тебе на таком уровне надо это понимать, то тут, извини меня, читать просто не подойдёт, так это не работает. Я тебе за себя могу сказать: людей, которые открывают исходники Spring, — я читаю, их много. Знаешь, откуда у меня формировалась экспертиза по Spring? Вот это contribution называется. Без Claude Code и так далее. Я не говорю, что так надо или что так плохо или хорошо, — я просто констатирую факт: экспертиза наращивается тогда, когда ты сам открыл, сам попытался решить проблему, понял, в чём дело. А почему у них другой модуль для сборки? А, так вот почему. А почему они здесь именно паттерн Visitor используют? А вот почему — так можно расширять API. Это всё наращивается именно путём того, что ты сам решаешь проблему. Сам решаешь проблему ручками. Это требует времени.

[2:22:33] Александр: Я тебя прекрасно понимаю, позиция устойчивая. Я думаю, что есть интерес оставить этот дискурс открытым и сделать такой open ending. Если у слушателей подкаста, кто дослушал, есть что сказать, есть чем поделиться — например, у вас есть своё мнение, вы думаете: слушайте, я считаю, что вот так и так; или «Саша генерирует код, он неправ и теряет экспертизу, а Миша её приобретает», — пишите это. Прямо в YouTube, где вы там слушаете. Claude Code пишите… Да нет, комментарии Claude Code писать не надо: потому что если от вашего аккаунта он может писать, то что-то в этом мире уже не так. Пишите от себя — хочется видеть ваши настоящие комментарии. И поддерживайте лайком; не знаю, дизлайком, если вам не нравится тема подкаста, — тоже вполне норм. В общем-то, я бы на этом заканчивал. Миш, есть ли у тебя что-нибудь, что ты хотел бы как напутствие пожелать? Два-три предложения.

[2:23:34] Миша: Я, наверное, просто подтвержу свой поинт — постараюсь подтвердить. Мне, по крайней мере, всегда так казалось и так кажется: старайтесь развивать глубину своей экспертизы. При этом, конечно, нужно идти в ногу со временем — важно осознавать, что вокруг вас мир и тулинг меняются, это нормально; что языки меняются, платформы меняются и так далее, это тоже важно. Но с течением времени — если посмотреть на историю: искусственный интеллект, появление интернета, появление каких-то прорывных технологий, которые в своё время очень сильно помогли человечеству, — с течением времени в истории экспертиза становилась не дешевле, она становилась дороже. И этот разрыв между ремесленником, который клепает вот эти круды, и человеком, который действительно понимает, как оно работает, и дизайнит систему, — этот разрыв увеличивался, и ценность этой экспертизы со временем росла. Поэтому я лишь могу сказать: адаптируйтесь к миру, в котором вы находитесь, и просто старайтесь поддерживать именно свою настоящую экспертизу. Это важно — это действительно то, что в таком турбулентном мире, где мы не понимаем, что завтра произойдёт, на мой взгляд, просто важно. И без этого мы вперёд особо никуда не уедем. Ну, а на этом всё.

[2:25:03] Александр: Я бы сказал: пока. И спасибо тебе, Миш, большое, что пришёл. Было интересно.

[2:25:07] Миша: Спасибо, Саш.