Почему ваш AI-ассистент пишет «вырвиглазный» код, и как это исправить грубой силой
Технически это называется «неконсистентный». А по-человечески — боль. Делюсь рабочим, хоть и неидеальным, способом её лечения.

Объектно-ориентированный язык программирования
Технически это называется «неконсистентный». А по-человечески — боль. Делюсь рабочим, хоть и неидеальным, способом её лечения.

Когда начинал разработку системы многомерного анализа данных временных рядов Dimension-UI, для внедрения зависимостей в исходном коде решил использовать Dagger 2. Практический опыт показал, что для приложений с большим количеством динамически создаваемых объектов инверсия зависимостей, реализованная в Dagger 2, не подходит.
Да, создание графа зависимостей в compile-time — это, во-первых, очень быстро, и, во-вторых, удобно: получаешь сообщения об ошибках конфигурации уже при компиляции.
Но накладные расходы на сопровождение всего этого хозяйства – прямо скажем, это боль.
Чтобы реализовать scope-зависимости, приходится писать и поддерживать много инфраструктурного кода внутри объектов, куда мы внедряем зависимости. В Dagger 2 такая реализация, во-первых, «загрязняет» код, а во-вторых, серьезно осложняет тестирование. Изолировать методы удобным способом не получается: в тестах нужно писать очень много кода, чтобы прокинуть необходимый контекст и корректно мокировать внешние зависимости. Я туда просто не полез — покрывал unit- и UI-тестами только базовую функциональность, где были Singleton-зависимости.
Даже с одними Singleton’ами приходится поднимать отдельную тестовую инфраструктуру для запуска приложения в тестовом режиме. Это не просто неудобно — это очень затратно по времени. Если сравнить усилия, которые надо потратить на реализацию тестирования подобного функционала в Spring и Dagger… Сравнение будет не в пользу Dagger. В целом я начал думать о переходе на runtime-генерацию графа зависимостей.

А что, если вам сказали бы, что класс без final — это ошибка проектирования? Что возможность наследования должна быть исключением, а не правилом? В новом переводе от команды Spring АйО автор предлагает радикальную идею: все классы должны быть final по умолчанию.
⚠️ Статья была написана ещё до появления Kotlin`а. Цель перевода данной статьи – поднять запылившийся на полке вопрос в дизайне API: "Нужно ли оставлять API открытым по-умолчанию для внешнего расширения?"

За 9 лет разработки ПО я периодически выступал в роли ментора и сталкивался с проблемой, которую недавно озвучил начинающий программист после онлайн-курсов:
«Не понимаю, как делить код на классы».
Оказалось, на курсах учили языку, но не программированию. А ведь язык — лишь инструмент, и принципы проектирования кода универсальны для разных языков программирования.
Я показал студенту несколько готовых шаблонов классов, чтобы он мог сразу применить, и хотел дать методичку по теории, но под рукой не оказалось ни заметок, ни статей, ни книг. Поиск в интернете и запросы к ИИ выдавали только материалы по ООП и принципам SOLID, которые мало касались нужной темы. Выходило так, что вся нужная для такой методички информация, лежит у меня в голове.
Так и родилась идея написать эту статью.

Код-ревью стало ключевым этапом в разработке: генерация кода с помощью LLM упростилась, а вот проверка его качества по-прежнему требует инженерной экспертизы.
В новом переводе от команды Spring АйО эксперты сообщества подробно и на собственном опыте рассказали про нюансы код-ревью.

В статье сравним REST, gRPC и GraphQL с точки зрения производительности, гибкости и архитектуры микросервисов. Покажем, как объединить GraphQL и gRPC для фронтенда и бэкенда, чтобы получить мощный API без лишнего трафика и задержек.

Началось все весьма прозаично, клиент позвонить к нам в техподдержку и спросил «а как бы мне поставить ваш софт но в другую схему БД». Собственно вопрос проще некуда — мы писали на спринге, а значит лезем в application.yml и ставим схему. Но, клиент не из тупых и уже это попробовал — не сработало.
Начинаем разбираться что сломалось и кто виноват. Первым делом ДевОпс повторяет кульбиты клиента и выдает простой вердикт: «В 151 миграции лажа». Я открываю и: «батюшки родный, да это же лосенок явное указание схемы!»

Привет! Меня зовут Анатолий, я ведущий разработчик в ITFB Group, и сегодня я хочу рассказать о том, как можно превратить скучные тесты в главного специалиста по продукту.
Знакомо: ваши JUnit-тесты проходят, CI/CD зелёный, все довольны. Но тут приходит бизнес-аналитик и спрашивает: "А этот сценарий проверяет, что будет, если клиент с рейтингом 700 запросит 10 миллионов?"
Вы начинаете лихорадочно копаться в коде, пытаясь найти тот самый @Test... А что если бы ответ на этот вопрос лежал не в глубинах Java-кода, а в красивом, читаемом файле, который понятен всем — от тимлида до заказчика?

Команда проекта Valhalla выпустила early-access сборку JDK с полной реализацией JEP 401 — value-классы и объекты теперь можно попробовать в действии! В новом переводе от команды Spring АйО — примеры использования, объяснение концепции, сравнение производительности с обычными объектами и практические советы для разработчиков.

Современные подходы к разработке программного обеспечения диктуют необходимость быстрого внедрения и изменения бизнес-сценариев прямо в продакшене. Особенно это критично для систем, где логика процессов часто корректируется — например, в финансовых, маркетинговых или рекламных платформах.
Одним из наиболее удобных инструментов для этого сегодня является оркестрация с использованием BPMN-диаграмм, где визуальное моделирование бизнес-процесса превращается в исполняемую логику.
На одном из проектов, над которым я работаю, я столкнулся с постоянно растущим временем сборки проекта на CI. Оказалось, что причина была в интеграционных тестах работы с БД в модулях с использованием Testcontainers. Каждый модуль запускал свой контейнер и в придачу применял на них миграции Liquibase.
В данной статье я хочу рассмотреть способ решения этой проблемы с помощью Gradle Build Services — механизма для разделения состояния между задачами. Цель - использовать только один контейнер PostgreSQL на всю сборку, и настроить все тестовые задачи на его использование.

В JDK 26 появилась долгожданная поддержка HTTP/3 в стандартном классе HttpClient. Хотя само API почти не изменилось, теперь можно явно указывать предпочтение использования HTTP/3 как на уровне клиента, так и на уровне запроса.
В новом переводе от команды Spring АйО подробно описывается, как работает выбор версии HTTP, что такое Http3DiscoveryMode, как принудительно использовать HTTP/3 и как HttpClient "обучается" на основе заголовков alt-svc.
Добрый день. Сегодня мы поговорим о двух мощных технологиях для асинхронного обмена данными — ActiveMQ Artemis и Apache Kafka. Мы разберемся, что они из себя представляют, как устроены под капотом, и главное — в каких ситуациях стоит выбрать одну, а в каких другую.
Наш план на сегодня довольно насыщенный. Мы начнем с того, почему вообще все пришли к асинхронному общению сервисов. Затем подробно разберем ActiveMQ Artemis — что это и какие задачи решает. Заглянем в его техническую архитектуру, чтобы понять источник его производительности. После этого мы кратко вспомним основы Apache Kafka, чтобы затем перейти к самому интересному — детальному сравнению. Мы составим четкие рекомендации, поговорим о нагрузочных характеристиках и подведем итоги.

Как работать с Kafka на практике, используя Spring Boot?
Разбираем базовые практические моменты на примере интернет-магазина.
Простым языком и с примерами кода о настройке Kafka-кластера, об основных аннотациях и методах Spring Boot для работы с Kafka.

Привет! Меня зовут oldzoomer, и я хочу рассказать, как я подключил приёмник Триколор к экосистеме Яндекса, чтобы управлять им голосом через Алису. Всё сделано на Java 21, Spring Boot и официальном Stingray TV API - без хаков и модификаций прошивки.

Привет! Меня зовут Бромбин Андрей. В этой статье разберём структурные паттерны ООП. Используя примеры на Java и простые метафоры, поймём природу шаблонов: как они работают, зачем нужны и чего требуют от нас взамен. Почему дизайн называют удачным при использовании паттернов по назначению, и почему так бывает не всегда.
Книг и статей о шаблонах проектирования, как песен о любви, потому что в разработке эта тема волнует каждого начинающего и не очень специалиста. Помните, как пели Чиж и Ко: «а не спеть ли мне песню о любви?» — давайте и я попробую.

Совместимость — фундаментальная характеристика платформы Java, обеспечивающая стабильную работу программ при эволюции JDK. Однако понятие «совместимость» многогранно: исходный код, бинарные файлы и поведение программ оцениваются по разным стандартам.
В новом переводе от команды Spring АйО разберем три ключевых категории совместимости: на уровне исходного кода, бинарную и поведенческую, а также рассмотрим нюансы сериализуемой и миграционной совместимости.

Статья является продолжением Пишем агента на Kotlin: KOSMOS, но может читаться независимо. Мотивация к написанию — сохранить читателю время на возьню с фреймворками для решения относительно простой задачи.
Автор подразумевает у читателя теоретическое понимание того, что такое агент. Иначе лучше прочесть хотя бы начало предыдущей части.
В статье хочу показать, как самостоятельно написать аналог Koog или Langchain4j. У вас не будет всех их фичей, зато будет очень простая и расширяемая система.

Мат рождается в душе. Больше всего его рождается когда сталкиваешься с чем-то похожим на <подставь свой фреймворк>. Инструмент с прекрасными целями и задачами постепенно превращается во все больший и больший кусок г.. в котором приходиться копаться. Ощущаешь себя жужжащей мухой, летающей вокруг по необходимости.
Когда трава была зеленее, когда мы сильно боролись за каждый такт процессора, тратя на это наше время, которое мы тогда не очень ценили, все было в какой-то мере проще.
Если тебе нужна была фича, ты ее делал сам.
Или ты искал уже реализованную фичу, и прикручивал к своему коду.
Больше времени уходило на поиск. Не всегда можно было найти.
Сейчас все поменялось.
Подключение новой фичи чаще всего присоединяет к твоему коду 100500 дополнительных фиговин, которые мало того, что чаще не нужны, но и которые мешают запустить твой код.
Они подключаются по дефолту сами, и ты ищешь как их отключить. Но так как библиотеки постоянно меняются, это не так просто. Сколько раз подключал <подставь свой фреймворк>, ещё не разу не было одинакового кода. Постоянно меняются названия методов, их параметры, типы.
Раньше было просто. Возьмем для примера <подставь свой фреймворк>. Ты подключал и говорил ему, что нужно делать в первом случае, что во втором, что в третьем.
Сейчас же так просто не работает. Все стало сложнее. Ты указываешь доступный всем метод по старинке, но не тут то было. Клиенты получают в ответ фигу. Ты думаешь, что поменялся синтаксис, ищешь новые незадеприкейчаные методы (которых по количеству уже меньше, чем задеприкейчаных), но все равно клиенты получают фигу. Один и тот же код разрешает пользователям работать с одними запросами, но не разрешает с другими. Уверен, что это как-то объясняется. Просто подключается ещё куча бинов по дефолту, с доп параметрами по дефолту, и т.д. Идеология упрощения.
Но то, что прямо игнорируется команда разработчика, это уже перебор.

ANR — это не просто “зависание”, а молчаливый краш, который напрямую бьёт по удержанию пользователей. В статье разбираю, как работает механизм ANR, какие ошибки его вызывают, как анализировать traces.txt, какие библиотеки помогают отслеживать блокировки (ANR-WatchDog, ANR-Spy, Firebase Crashlytics), и как построить процессы, чтобы QA-команда научилась ловить их ещё до релиза.