javaproglib | Unsorted

Telegram-канал javaproglib - Библиотека джависта | Java, Spring, Maven, Hibernate

25698

Все самое полезное для Java-разработчика в одном канале. Список наших каналов: https://t.me/proglibrary/9197 Обратная связь: @proglibrary_feedback_bot По рекламе: @proglib_adv Прайс: @proglib_advertising

Subscribe to a channel

Библиотека джависта | Java, Spring, Maven, Hibernate

🖥 Как LeetCode только проще

Сайт с интерактивными задачами → CodingBat Java

══════ Навигация ══════
ВакансииЗадачиСобесы

🐸 Библиотека джависта

#Enterprise

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

📌 False Sharing и Object Memory Layout в Java

Если производительность внезапно падает, хотя два потока работают с разными частями одного объекта, скорее всего, проблема в так называемом false sharing.

Вот как это работает: процессор не берет данные из памяти побайтово. Он работает с cache line, обычно это 64 байта. Если два ядра процессора держат одну и ту же cache line в своих кэшах первого уровня (L1) и хотя бы одно ядро в нее пишет, запускается протокол когерентности (MESI). Этот протокол делает копию cache line недействительной в другом ядре. И это происходит, даже если ядра пишут в разные поля объекта, но эти поля физически находятся в одной cache line.

🔹 Как объекты лежат в памяти

JVM (HotSpot) раскладывает объект примерно так:
[mark word — 8 байт]
[klass pointer — 4/8 байт]
[поля по убыванию размера: long/double → int/float → short/char → byte/boolean → ссылки]
[padding до выравнивания на 8 байт]


Порядок полей в исходнике не соответствует порядку в памяти. JVM перегруппировывает их для минимизации выравнивания. Проверить реальный layout можно через JOL:

javaSystem.out.println(ClassLayout.parseClass(MyClass.class).toPrintable());

Для класса с `long`, `int` и `boolean` JOL покажет что-то вроде:

OFFSET SIZE TYPE
0 4 (object header: mark)
4 4 (object header: mark)
8 4 (object header: class)
12 4 int value
16 8 long counter
24 1 boolean flag
25 7 (alignment/padding)


Итого 32 байта — меньше cache line. Два таких объекта рядом в массиве легко попадут в одну линию.

🔹 Классический сценарий

class Counters {
volatile long a;
volatile long b;
}


Поля a и b занимают по 8 байт. Заголовок объекта – примерно 12-16 байт. Вероятно, оба поля попадают в одну 64-байтную строку кэша. Если два потока независимо увеличивают a и b, они постоянно будут делать строку недействительной друг для друга. На многоядерной системе это легко может привести к падению производительности в 5-10 раз по сравнению с независимыми счетчиками.

Решение – добавление отступов (padding). До Java 8 это делали руками, добавляя фиктивные поля:

class PaddedCounter {
volatile long value;
long p1, p2, p3, p4, p5, p6, p7; // 56 байт padding
}


Уродливо и ненадёжно. Плюс JIT мог выкинуть «мёртвые» поля.

С Java 8 появилась аннотация @Contended (пакет jdk.internal.vm.annotation):

@Contended
volatile long a;
@Contended
volatile long b;


В JVM автоматически добавляется padding в 128 байт вокруг помеченного поля. Это сделано для защиты от prefetcher'а (размер двойной cache line). Чтобы это работало вне классов JDK, нужно использовать опцию -XX:-RestrictContended.

Аннотация @Contended стоит на полях внутри Thread (например, для thread-local random), ForkJoinPool и Striped64, который является базовым классом для LongAdder и LongAccumulator.

🔹 LongAdder как способ решения проблемы

LongAdder показывает, как можно решить проблему не просто добавлением отступов, а с помощью особого подхода к проектированию. Вместо одного volatile long используется массив Cell[], где у каждой ячейки стоит @Contended. Каждый поток пишет в свою ячейку, итоговое значение получается через sum(). При большой нагрузке это работает намного быстрее, чем AtomicLong.

За это приходится платить: sum() не является атомарной операцией. Если нужна полная точность в момент чтения, LongAdder не подойдет.

🔹 О массивах примитивных типов

Тут есть свои нюансы с long[]. Элементы располагаются один за другим, без каких-либо дополнительных данных между ними. Восемь элементов long занимают ровно одну cache line. Если несколько потоков одновременно пишут в соседние ячейки, false sharing практически гарантирован. Именно поэтому в Striped64 используется массив объектов Cell[], а не long[]: каждый объект с @Contended изолирован от других.

══════ Навигация ══════
ВакансииЗадачиСобесы

🐸 Библиотека джависта

#CoreJava

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

🐳 Магия Docker CLI

Забываете, сколько места занимают контейнеры, образы и тома Docker? Не хотите каждый раз лезть в df или гадать? Просто запустите docker system df, и у вас будет вся картина перед глазами.

🔹 Зачем это нужно

— Показывает сколько места занимают образы, контейнеры, тома и билд-кэш.
— Видно реальный размер и сколько можно освободить прямо сейчас.
— Незаменимо, когда диск неожиданно кончается на проде или CI/CD агенте.

🔹 Как использовать

— Краткая сводка: docker system df
— Подробный разбор по каждому объекту: docker system df -v
— Можно комбинировать с docker system prune, чтобы сразу почистить лишнее.
— Удобно добавить в cron или мониторинг, чтобы отслеживать рост потребления.

══════ Навигация ══════
ВакансииЗадачиСобесы

🐸 Библиотека джависта

#Enterprise

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

🖥 Визуализатор кода

Прямо в браузере можно посмотреть, что происходит под капотом кода: как создаются и взаимодействуют объекты, как данные перемещаются в памяти, и как работает стек вызовов. Всё это можно увидеть пошагово.

Если что-то непонятно, встроенный AI-помощник объяснит логику кода или поможет разобраться в чужом решении.

Ссылка на сервис

══════ Навигация ══════
ВакансииЗадачиСобесы

🐸 Библиотека джависта

#Enterprise

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

✔️ SQL-тест: Топ категорий Google Search

Задача из реального интервью в Google 👇

📦 Задание

Google хочет проанализировать самые популярные категории поиска для оптимизации результатов.

Таблицы на картинке. Напишите запрос для подсчета общего количества поисков в каждой категории по месяцам за 2024 год.

Ставьте → 🔥, если нравится формат. Если нет → 🤔

💬 Решения под спойлер. Сравним, какое будет лучше.

🐸 Библиотека собеса по Java

#practise

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

ИИ-агенты в Enterprise: как подружить LLM и суровый продакшн

Интегрировать нейросеть в корпоративный бэкенд на Java — это не просто дёрнуть API. Бизнес требует предсказуемости, отказоустойчивости и строгих лимитов. Агенты не должны ложиться от кривых данных или сливать бюджет на бесконечные ретраи.

Мы полностью обновили курс по разработке AI-агентов. Теперь фокус на enterprise-подходе: логирование, трассировка, изоляция доменов и предсказуемое поведение систем.

Что в инженерном фокусе нового потока:

— промышленный RAG: извлечение данных из legacy-баз, сканов и сложных таблиц;
— архитектура агентов: внедрение human-in-the-loop для аппрува критичных транзакций;
— ресурсоёмкость: жёсткий контроль кэша, токенов и переключение режимов обработки;
— интеграции: учим агентов взаимодействовать с легаси-интерфейсами и браузерами;
— комплаенс: развёртывание решений с полным соблюдением 152-ФЗ.

Используйте промокод Agent до 28 февраля, чтобы получить скидку 10 000 рублей.

Выбирайте акцию «3 курса по цене 1», чтобы забрать два дополнительных курса в подарок.

Внедрить AI в Enterprise

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

Сохраняйте шпаргалку по join'ам

Наглядная шпаргалка с примерами и визуализацией SQL JOIN.

══════ Навигация ══════
ВакансииЗадачиСобесы

🐸 Библиотека джависта

#CoreJava

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

Enterprise AI: когда MVP уже не прокатит

В корпоративном секторе требования к AI жёстче: безопасность, стабильность, работа с документами. Мы обновили курс «Разработка AI-агентов», добавив модули, критически важные для Enterprise-разработки.

Java-инженерам будет интересно:

🔹 Advanced RAG. Работа со сложной корпоративной документацией (сканы, таблицы), улучшение поиска и безопасности данных.

🔹 Legal Tech. Как внедрять агентов с соблюдением 152-ФЗ и юридических норм.

🔹 Надёжность. Внедрение Human-in-the-loop для контроля, логирование, трассировка и предотвращение регрессий.

🔹 Legacy. Управление браузером и старыми интерфейсами через агентов.

Стартуй сейчас!
Покупаешь курс — сразу получаешь материалы.

🎟 Промокод Agent — скидка 10 000 ₽ (до 28 февраля).

👉 AI для Enterprise-задач

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

🐸 Библиотека джависта

#DevLife

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

🔼 Прокачай DevOps-скиллы на практике

Платформа с реальными DevOps-задачами. Кейсы по Linux, Docker и Kubernetes — всё как в бою, но с читами:

✔️ Автопроверка решений
✔️ Подсказки
✔️ Готовые решения

🔗 Попробовать

══════ Навигация ══════
ВакансииЗадачиСобесы

🐸 Библиотека джависта

#CoreJava

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

✔️ Spring-тест: @RateLimit аннотация для методов

Напишите production-ready Spring компонент 👇

📦 Задание

Реализуйте кастомную аннотацию @RateLimit, которая ограничивает количество вызовов метода с использованием Spring AOP.

🔹 Требования

— Использовать Spring AOP
— Потокобезопасность
— Кэш лимитов
— Учитывать имя метода + параметры
— Custom exception при превышении

Ставьте → 🔥, если нравится формат. Если нет → 🤔

💬 Решения под спойлер. Сравним, какое будет лучше.

🐸 Библиотека собеса по Java

#practise

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

🤫 Spring 4.2+: события без наследования ApplicationEvent

Начиная с Spring 4.2 (2015 год!), классы событий больше не обязаны наследовать ApplicationEvent.

🔹 До Spring 4.2:

public class UserCreatedEvent extends ApplicationEvent {
private final String username;

public UserCreatedEvent(String username) {
this.username = username;
}

public String getUsername() {
return username;
}
}


🔹 Начиная с Spring 4.2+:

// Просто POJO
public class UserCreatedEvent {
private final String username;

public UserCreatedEvent(String username) {
this.username = username;
}
// getters...
}


🔹 Использование идентично:

@Service
public class UserService {

@Autowired
private ApplicationEventPublisher publisher;

public void createUser(String username) {
publisher.publishEvent(new UserCreatedEvent(username));
}
}

@EventListener
public void onUserCreated(UserCreatedEvent event) {
log.info("User created: {}", event.username());
}


Использование обычных POJO-классов в качестве событий делает код независимым от Spring Framework, что улучшает тестируемость и переносимость приложения.

══════ Навигация ══════
ВакансииЗадачиСобесы

🐸 Библиотека джависта

#Enterprise

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

⚙️ RestTemplate vs WebClient

🔹 RestTemplate

javaRestTemplate restTemplate = new RestTemplate();
ResponseEntity<User> response = restTemplate.getForEntity(
"https://api.example.com/users/{id}",
User.class,
userId
);
User user = response.getBody();


✔️ Простота, привычность, работает из коробки. Идеален для простых CRUD операций.

Блокирующий I/O — поток висит и ждет ответа. При высоких нагрузках нужен большой thread pool. С 5.0 официально в maintenance mode.

🔹 WebClient

javaWebClient webClient = WebClient.create("https://api.example.com");
Mono<User> userMono = webClient.get()
.uri("/users/{id}", userId)
.retrieve()
.bodyToMono(User.class);


✔️ Неблокирующий I/O — поток освобождается и обрабатывает другие запросы. Отлично работает с реактивными стримами. Fluent API, удобная настройка retry, timeout, circuit breaker.

Кривая обучения — нужно понимать реактивные концепции (Mono, Flux). Сложнее дебажить, требует Project Reactor в зависимостях.

🔹 Технические нюансы

— Thread model: RestTemplate использует по потоку на запрос (blocking I/O). WebClient работает на event loop с малым числом потоков (по умолчанию CPU cores * 2).

— Performance: в синхронных сценариях разница минимальна. При параллельных запросах WebClient показывает x2-x5 прирост throughput за счёт эффективного использования потоков.

— Memory footprint: 1000 параллельных REST вызовов через RestTemplate = ~1000 МБ стека потоков. WebClient с той же нагрузкой — десятки МБ.

— Timeout configuration: RestTemplate требует настройки через ClientHttpRequestFactory. WebClient имеет встроенный .timeout(Duration) в цепочке вызовов.

— Error handling: RestTemplate выбрасывает исключения синхронно. WebClient возвращает Mono с ошибкой.

— Testing: RestTemplate легко мокается через MockRestServiceServer. WebClient требует понимания StepVerifier из reactor-test.

— Compatibility: RestTemplate работает везде. WebClient требует Spring WebFlux в classpath, даже если используешь его в обычном Spring MVC приложении.

Что выбрать?

WebClient если стартуешь новый проект, делаешь микросервисы с высокой нагрузкой, уже используешь reactive stack или планируешь масштабироваться. RestTemplate если поддерживаешь legacy код без реактивности, команда не знакома с Project Reactor, делаешь простой CRUD сервис с малой нагрузкой.

Главное помни: преждевременная оптимизация — корень зла. Если RestTemplate закрывает задачу, не усложняй. Но если упираешься в потоки на проде, время учить реактивщину.

══════ Навигация ══════
ВакансииЗадачиСобесы

🐸 Библиотека джависта

#CoreJava

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

🚩 Pattern Matching в Switch

Раньше switch был ограничен примитивами и enum'ами. С Java 21 Pattern Matching стал стандартом, и это принципиально меняет подход к обработке полиморфных данных.

Что раньше:

Object obj = getObject();
String result;
if (obj instanceof String s) {
result = "String: " + s;
} else if (obj instanceof Integer i) {
result = "Int: " + i;
} else {
result = "Unknown";
}


✔️ Что теперь:

String result = switch (obj) {
case String s -> "String: " + s;
case Integer i -> "Int: " + i;
case null -> "Null!";
default -> "Unknown";
};


Но суть не в синтаксисе. Суть в гарантиях компилятора.

🔹 Охранные выражения (guarded patterns)

String classify(Object obj) {
return switch (obj) {
case String s when s.length() > 10 -> "Long string";
case String s -> "Short string";
case Integer i when i > 0 -> "Positive";
case Integer i -> "Non-positive";
case null -> "Null";
default -> "Other";
};
}


Условия when проверяются последовательно. Компилятор отслеживает полноту покрытия и недостижимый код. Поменяете порядок кейсов неправильно — получите ошибку компиляции.

🔹 Record patterns — деструктуризация на месте

record Point(int x, int y) {}

String describe(Object obj) {
return switch (obj) {
case Point(int x, int y) when x == y ->
"Diagonal point";
case Point(int x, int y) ->
"Point at (%d, %d)".formatted(x, y);
default -> "Not a point";
};
}


Распаковали record прямо в case. Никаких геттеров, никаких промежуточных переменных.

🔹 Sealed классы + pattern matching = полнота проверок

sealed interface Result permits Success, Failure {}
record Success(String data) implements Result {}
record Failure(String error) implements Result {}

String handle(Result result) {
return switch (result) {
case Success(String data) -> "Got: " + data;
case Failure(String error) -> "Error: " + error;
// default не нужен - компилятор знает все варианты
};
}


Компилятор гарантирует, что вы обработали все случаи. Добавите новый класс в sealed иерархию — код не скомпилится, пока не обработаете его.

🔼 Производительность

JIT оптимизирует pattern matching свитчи агрессивно. В бенчмарках разница с if-else цепочками от 2x до 10x в пользу switch в зависимости от количества веток.

══════ Навигация ══════
ВакансииЗадачиСобесы

🐸 Библиотека джависта

#CoreJava

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

😮 Топ-вакансий для джавистов за неделю

Java developer — 250 000 ₽ — удалёнка

Java Backend Developer — от 250 000 ₽ — офис/гибрид (Москва, Санкт-Петербург)

Руководитель разработки (Java) — 350 000 —‍ 425 000 ₽ — гибрид (Москва)

➡️ Еще больше топовых вакансий — в нашем канале Java jobs

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

🐸 Библиотека джависта

#DevLife

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

🖥 Параллельная обработка Kafka сообщений с гарантией at-least-once в условиях медленного внешнего сервиса

Если один запрос зависает, batch встаёт колом. Простое увеличение max.poll.records не решит проблему, если медленные ответы — это постоянное явление.

В статье описывается, как заменить пакетную синхронизацию на трёхэтапную модель: подготовка, обработка, постобработка – через специальный wait-топик. Коммит офсета происходит сразу, сохраняя гарантию at-least-once, и даже 8-часовая недоступность Postgres не сорвёт обработку.

В итоге получили 46 TPS против 170 TPS с теми же настройками. Код, конфиги Kafka Connect и результаты тестов прилагаются.

🔗 Подробнее в статье

══════ Навигация ══════
ВакансииЗадачиСобесы

🐸 Библиотека джависта

#Enterprise

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

🐸 Библиотека джависта

#DevLife

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

☕ AI-агенты в Enterprise: от прототипов на коленке к надёжным JVM-системам

Для Java-разработчика важна стабильность и предсказуемость. В новом курсе по AI-агентам мы учим строить системы, которые не «галлюцинируют» в продакшене, а работают по строгим инженерным метрикам и соблюдают законы РФ.

📚 В обновлённой программе:

— управляемый инжиниринг: трассировка ошибок, логирование и контроль производительности;
— правовое поле: развёртывание AI-решений с учётом 152-ФЗ и всей документации;
LangGraph промышленного уровня: интеграция human-in-the-loop в бизнес-процессы;
— продвинутый RAG: работа с корпоративными данными, таблицами и сканами.

Доступ к вводным материалам открывается сразу после покупки — начните погружение в архитектуру агентов 2026 года.

⏳ Специальные условия до 28 февраля:

— введите промокод Agent для получения скидки 10 000 рублей**;
— участвуйте в **акции «3 курса по цене 1» — выберите два любых курса в дополнение к основному.

👉 Получить доступ к курсу и подаркам

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

💥 Разрушим частый миф

Мне НЕ нужно разбираться с управлением памятью в Java, так как за меня всё делает GC


Garbage Collector (GC) действительно очищает неиспользуемые объекты, которые больше не имеют активных ссылок. Благодаря этому в Java не нужно вручную освобождать память, как в C++.

Несколько предпосылок к исходному тезису:

🔹 В других языках, где ручное управление памятью (C, C++), утечки очевидны — если забыл free(), память навсегда потеряна.
🔹 В Java GC работает автоматически, поэтому кажется, что он решает все проблемы сам.
🔹 "Ну раз GC есть, значит, про память можно не думать!" — типичная ошибка.

GC удаляет только те объекты, которые больше не имеют активных ссылок. Если же объект остаётся доступным, но фактически не используется, он будет занимать память до завершения работы приложения.

🔽 Несколько случаев утечек памяти

1️⃣ Статические коллекции (заполняем, но не чистим)

Если создать static List и постоянно добавлять в него объекты, они никогда не будут удалены GC, потому что статические поля живут весь срок жизни приложения.

public class MemoryLeak {
private static final List<byte[]> cache = new ArrayList<>();

public static void main(String[] args) {
while (true) {
cache.add(new byte[10 * 1024 * 1024]);
System.out.println("Добавили 10MB в кеш. Используемая память: " +
(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / (1024 * 1024) + "MB");
}
}
}


Через пару минут — OutOfMemoryError

2️⃣ Потоковые переменные (ThreadLocal)

Объекты, хранящиеся в ThreadLocal, привязываются к потоку, а в пуле потоков они могут жить дольше, чем нужно.

public class ThreadLocalLeak {
private static final ThreadLocal<byte[]> threadLocalData = new ThreadLocal<>();

public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);

for (int i = 0; i < 10; i++) {
executor.execute(() -> {
threadLocalData.set(new byte[10 * 1024 * 1024]); // 10MB на поток
System.out.println("Память занята потоком!");
});
}

executor.shutdown();
}
}


Поток завершится, а память останется занята, потому что ThreadLocal не очищается автоматически.

3️⃣ Внутренние классы и "утекшие" ссылки

Если анонимный класс или лямбда-ссылка ссылается на внешний объект, она может мешать GC очистить его.

public class InnerClassLeak {
private String data = "Очень важные данные";

public void createAnonymousClass() {
Runnable task = new Runnable() {
@Override
public void run() {
System.out.println("Используем: " + data);
}
};
new Thread(task).start();
}
}


task ссылается на data, даже если InnerClassLeak больше не используется → GC не очистит объект.

👎 Миф разрушен. GC не всемогущий и даже с ним придётся изучать, как работать с памятью в Java.

══════ Навигация ══════
ВакансииЗадачиСобесы

🐸 Библиотека джависта

#CoreJava

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

🐸 Библиотека джависта

#DevLife

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

😮 Топ-вакансий для джавистов за неделю

Java-разработчик — Офис (Казань)

Java-разработчик — от 230 000 до 330 000 ₽ — удалёнка/гибрид (Москва)

Senior Java Developer (Kotlin) — от 400 000 ₽ — удалёнка

➡️ Еще больше топовых вакансий — в нашем канале Java jobs

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

🧩 Просто о сложном: Saga Pattern

Когда пользователь оформляет заказ, нужно списать деньги, зарезервировать товар и уведомить склад. Всё в разных сервисах. Что делать, если один из них упал?

Обычная транзакция тут не поможет. Добро пожаловать в Saga.

Идея проста: разбиваем большую распределённую транзакцию на цепочку маленьких локальных. Каждый шаг — это своя транзакция в своём сервисе. Если что-то пошло не так, то запускаем компенсирующие транзакции в обратном порядке.

🔹 Два подхода

1. Choreography (хореография)

Сервисы общаются через события. Каждый сам знает, что делать дальше.

OrderService → [OrderCreated] → PaymentService
PaymentService → [PaymentDone] → InventoryService
InventoryService → [Reserved] → NotificationService


✔️ Просто, нет единой точки отказа
Сложно отследить весь флоу, спагетти из событий

2. Orchestration (оркестрация)


Есть дирижёр — Saga Orchestrator. Он знает весь сценарий и командует сервисами.
public class OrderSagaOrchestrator {

public void execute(Order order) {
try {
paymentService.charge(order);
inventoryService.reserve(order);
notificationService.notify(order);
} catch (PaymentException e) {
// компенсация не нужна — деньги не списаны
} catch (InventoryException e) {
paymentService.refund(order); // компенсируем
}
}
}


✔️ Флоу виден в одном месте, легко дебажить
Оркестратор может стать узким местом

⚠️ Важно понимать: компенсирующая транзакция ≠ откат БД. Это бизнес-операция. Если деньги уже списаны, то мы не откатываем строку в БД, мы делаем возврат.

В Java-экосистеме Saga используют вместе с:

→ Apache Kafka / RabbitMQ — для событий между сервисами
→ Axon Framework — встроенная поддержка Saga из коробки
→ Spring State Machine — для управления состоянием оркестратора
→ Temporal / Conductor — оркестрация workflow на уровне инфраструктуры

🔹 Когда использовать

✔️ Микросервисная архитектура
✔️ Несколько БД, нет возможности использовать 2PC
✔️ Долгоживущие бизнес-транзакции
Монолит с одной БД — просто используй @Transactional

Saga — это не серебряная пуля, это компромисс. Ты жертвуешь изоляцией ради масштабируемости. Данные могут быть временно не консистентны и это нормально, если бизнес с этим согласен.

══════ Навигация ══════
ВакансииЗадачиСобесы

🐸 Библиотека джависта

#CoreJava

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

🔬 Правильный вопрос про AI

Все исследования AI-ассистентов меряют одно: насколько быстрее ты закрываешь задачу. Метрика удобная, но она игнорирует 70–80% реальных затрат — поддержку, рефакторинг, устранение дефектов.

Исследование «Echoes of AI» (arXiv, 2025) спросило другое:

«Что будет, когда другой разработчик возьмёт AI-код и попытается его развивать?»

151 участник, 95% практикующие разработчики (не студенты). Java/Spring Boot проект, две фазы, настоящее РКИ. Одна группа пишет с AI, другая без. Потом третья группа без AI поддерживает и тот, и другой код.

Результат оказался неожиданный.

👉 Читать

══════ Навигация ══════
ВакансииЗадачиСобесы

🐸 Библиотека джависта

#CoreJava

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

👑 Магия IntelliJ IDEA: множественные курсоры

Нужно изменить одинаковый код в 10 местах? Обычно делаешь Find & Replace или правишь вручную каждую строку. Есть способ быстрее — Multiple Cursors. Редактируешь несколько мест одновременно.

🔹 Что это

Несколько курсоров в редакторе. Печатаешь один раз — изменения применяются везде сразу. Как Vim visual block mode, но удобнее.

🔹 Как использовать

— Alt+J (Win/Linux) или Ctrl+G (Mac) — выделить следующее вхождение слова под курсором
— Alt+Shift+J — убрать последний курсор
— Ctrl+Alt+Shift+J — выделить ВСЕ вхождения сразу
— Alt+Shift+Click — поставить курсор мышью
— Alt+Shift+Insert → Column Selection Mode — выделение столбцом

🔹 Зачем это нужно

— Массовое редактирование без регулярок
— Быстрее Find & Replace для простых случаев
— Видишь изменения сразу, контролируешь процесс

══════ Навигация ══════
ВакансииЗадачиСобесы

🐸 Библиотека джависта

#Enterprise

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

🐸 Библиотека джависта

#DevLife

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

Собираем фулл-хаус: 3 курса по цене 1

Хватит выбирать между «полезно», «модно» и «для души». Мы запустили механику, которая позволяет собрать кастомный стек навыков без удара по бюджету: покупаете один курс — два других забираете бесплатно.

Java-разработка немыслима без паттернов. Забирайте архитектуру и шаблоны проектирования, чтобы говорить на одном языке с сеньорами. Для прохождения фильтров в корпорации — алгоритмы и структуры данных.

Для тех, кто смотрит в сторону Data Engineering или ML — полный набор по AI: от математики и ML-старта до разработки автономных агентов.

Ну и классика: обновлённый Python как удобный инструмент для вспомогательных скриптов.

Собрать свой пак

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

🌐 Что происходит, когда вы вводите адрес сайта

Каждый раз, когда вы набираете https://example.com в браузере, за кулисами запускается целая цепочка событий.

1️⃣ Разбор адреса

Браузер делит URL на части:

▪️ https — протокол
▪️ example.com — домен
▪️ /page — путь к ресурсу

2️⃣ Поиск IP

Если IP не сохранён в кеше, браузер спрашивает DNS-сервер: «Где живёт example.com?»

3️⃣ Установление соединения

Создаётся TCP-соединение с сервером по IP и порту (80 для HTTP, 443 для HTTPS).

4️⃣ Запрос ресурса

Браузер отправляет HTTP-запрос: GET /page HTTP/1.1

5️⃣ Ответ сервера

Сервер возвращает HTML, CSS, JS и статус-код (например, 200 OK или 404 Not Found).

6️⃣ Рендеринг страницы

Браузер обрабатывает HTML, применяет стили и выполняет JavaScript.

7️⃣ Шифрование

Если сайт работает по HTTPS, соединение шифруется через SSL/TLS.

8️⃣ Кеширование

Браузер сохраняет ресурсы, чтобы при следующем визите всё грузилось быстрее.

══════ Навигация ══════
ВакансииЗадачиСобесы

🐸 Библиотека джависта

#CoreJava

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

🐸 Библиотека джависта

#DevLife

Читать полностью…

Библиотека джависта | Java, Spring, Maven, Hibernate

💬 Обратная связь

В связи с последними новостями созрел вопрос. Где бы кроме тг вы могли читать наш канал?

Пишите в комменты/лайкайте чужие ответы, какие ещё платформы с подобным контентом вы используете сейчас или были бы готовы использовать в будущем вместо тг?

🐸 Библиотека джависта

#DevLife

Читать полностью…
Subscribe to a channel