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

«Этот манёвр будет стоить нам 51 год...»

— или 20% от вашего бюджета на самообразование. В Java-мире архитектурные паттерны и алгоритмы — это то, что отличает мидла от сеньора. Не ждите особого случая, забирайте базу прямо сейчас.

Успейте купить курсы Proglib Academy по старой цене до понедельника:

— Разработка ИИ-агентов
— Математика для разработки AI-моделей
— ML для старта в Data Science
— Математика для Data Science
— Специалист по ИИ
— Алгоритмы и структуры данных
— Программирование на Python
— Основы IT для непрограммистов
— Архитектуры и шаблоны проектирования

Взять по старой цене

⚠️ Цены вырастут 19 января

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

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

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

#DevLife

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

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

💻 Kafka транзакции в Spring Boot: от конфига до кода

Разберём практическую реализацию транзакций на конкретном примере.

1️⃣ Конфигурация продюсера

propertiesspring.kafka.producer.properties.enable.idempotence=true
spring.kafka.producer.properties.transactional.id=order-service-${random.value}-


2️⃣ Конфигурация консьюмера

propertiesspring.kafka.consumer.isolation-level=read_committed


3️⃣ Добавляем TransactionManager

@Bean
public KafkaTransactionManager<String, Object> kafkaTransactionManager(
ProducerFactory<String, Object> producerFactory
) {
return new KafkaTransactionManager<>(producerFactory);
}


4️⃣ Используем @Transactional

@Transactional
public void publishOrderResult(OrderRequest request) {
String orderId = UUID.randomUUID().toString();
OrderPlacedEvent event = new OrderPlacedEvent(
orderId,
request.email(),
request.productName()
);

kafkaTemplate.send("order-placed", orderId, event);
kafkaTemplate.send("order-audit", orderId, event);
// Обе отправки атомарны — либо обе успешны, либо обе откатятся
}


⚠️ Важно: если в приложении есть и Kafka и JPA TransactionManager:

Вариант 1 — пометить как @Primary:

@Primary
@Bean
public KafkaTransactionManager<String, Object> kafkaTransactionManager(...) {...}


Вариант 2 — явно указать:

@Transactional("kafkaTransactionManager")
public void publishOrderResult(...) {...}


⚠️ В большинстве систем дедупликация и идемпотентность — более простое и эффективное решение.

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

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

#Enterprise

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

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

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

#DevLife

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

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

Roadmap для Java-разработчика: интеграция ИИ-агентов в Enterprise

ИИ-агенты — это не только область Python. В корпоративной разработке на Java архитектура и надёжность агентов выходят на первый план.

Ваш путь внедрения ИИ:

— изучение принципов взаимодействия с LLM через API;

— интеграция агентских паттернов в существующие `JVM`-сервисы;

— создание систем с разделением ответственности между агентами;

— мониторинг и отладка автономных процессов.

Курс «Разработка ИИ-агентов» даст необходимые навыки для проектирования интеллектуальных надстроек над сложными системами.

Повысить квалификацию в ИИ

При регистрации до 19 января действует акция «3 в 1»: один курс покупаете, два получаете в подарок.

Дедлайн: 19 января.

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

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

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

#DevLife

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

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

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

#DevLife

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

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

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

#DevLife

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

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

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

#DevLife

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

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

Как бы вы оптимизировали запрос с JOIN?

Создание индексы на колонках, которые используются для соединений. Это ускорит поиск строк, особенно если соединяемые таблицы большие.

Если возможно, уменьшить размер данных, участвующих в соединении. Для этого можно использовать подзапросы или фильтровать данные до соединения.

Использование правильного типа JOIN.

EXPLAIN для анализа выполнения запроса и выявления узких мест. Это покажет, как именно СУБД обрабатывает запрос и на каких этапах происходят замедления.

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

Рассмотреть варианты изменения структуры БД (например, денормализация).

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

#core #лучшее2025

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

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

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

#DevLife

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

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

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

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

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

#Enterprise

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

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

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

#DevLife

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

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

⚙️ Как работает Garbage Collector

Механизм сборки мусора в JVM — это не просто “магия, которая чистит память”, а сложная система, работающая по поколениям, фазам и стратегиям.

Понимание его внутренней архитектуры важно, если вы хотите управлять производительностью, избегать утечек и эффективно настраивать параметры JVM.

🔹 Архитектура: как устроена куча (Heap)

Куча памяти делится на поколения:

Heap
├── Young Generation
│ ├── Eden Space
│ └── Survivor Spaces (S0, S1)
└── Old Generation (Tenured)


Eden — вновь созданные объекты.
Survivor — те, кто “выжил” после первой сборки.
Old Gen — объекты, пережившие несколько сборок, считаются “долгоживущими”.

Дополнительно есть Metaspace (с Java 8), где хранятся данные о классах.

🔹 Алгоритм работы GC: по фазам

1. Mark

GC начинает с “корневых” ссылок (стек, глобальные переменные) и помечает все достижимые объекты.

2. Sweep
Удаляются все немаркированные объекты — они считаются “мертвыми”.

3. Compact (в некоторых GC)
Уплотнение памяти: “живые” объекты перемещаются ближе друг к другу, чтобы избежать фрагментации.

🔹 Типы сборок

1. Minor GC
Запускается при заполнении Eden. Очищаются только молодые поколения. Быстро, но может происходить часто.

2. Major GC / Full GC
Включает Old Gen и Metaspace. Дорогая операция, может “заморозить” все потоки (stop-the-world pause).

🔹 Типы сборщиков и их принципы

— Serial GC: однопоточная сборка. Просто и медленно.
— Parallel GC: многопоточная сборка всех поколений. Высокая пропускная способность.
— G1 GC: делит кучу на регионы, параллельно собирает “Region Set”. Поддерживает предсказуемые паузы.
— ZGC: целиком конкурентный сборщик. Работает с огромными кучами (до терабайта), паузы <10 мс.
— Shenandoah: минимальные паузы за счёт почти полной конкуренции с пользовательскими потоками.

🔹 Как GC определяет, что объект мёртв?

GC не использует reference count. Он строит граф достижимости:
1. Начинает с “корней” (GC roots)
2. Если оттуда нельзя добраться до объекта — он считается мусором
3. Это позволяет избежать утечек при циклических ссылках

🔹 Советы по оптимизации

— Избегайте долгоживущих ссылок (static, ThreadLocal) без необходимости
— Используйте WeakReference, если хотите избежать удержания объекта GC
— Кэшируйте объекты осознанно — утечка через Map может быть незаметной
— Задавайте лимиты памяти (-Xms512m -Xmx1024m)

💬 Ловили OutOfMemoryError в проде когда-нибудь?

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

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

#CoreJava #лучшее2025

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

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

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

#DevLife

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

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

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

Backend Engineer (Java/Kotlin) — от 600 до 3 500 $ — офис (Минск)

Middle Java-разработчик — 240 000 - 260 000₽ — удалёнка

Java Developer — от 5 000 $ — удалёнка

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

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

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

🔥 Field vs Constructor Injection: зомби-объекты в production

Казалось бы, избитая тема. Но копните глубже @Autowired — и обнаружите, что ваши объекты после new существуют в состоянии "клинической смерти".

Автор разбирает не "удобство тестов" (это мелочи), а фундаментальные проблемы: нарушение контракта конструктора, проблемы с JMM, хрупкость при AOT-компиляции для GraalVM, race conditions в мультипоточке.

Рекомендую прочитать, если хотите понять почему Spring Framework 6 окончательно выбрал constructor injection, а не просто "так все делают".

🔗 Читайте подробнее

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

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

#coreJava

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

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

🔍 Просто о сложном: идемпотентность

Идемпотентность — это свойство операции, которую можно выполнить несколько раз, получая тот же результат, что и при однократном выполнении.

Простыми словами: повторный вызов не меняет состояние системы после первого успешного выполнения.
Классический пример — HTTP методы: GET, PUT, DELETE идемпотентны, POST — нет.

🔹 Ключевые моменты

▪️ Идемпотентная операция: setStatus(ACTIVE) — сколько раз ни вызови, статус будет ACTIVE.
▪️ Неидемпотентная операция: balance += 100 — каждый вызов увеличивает баланс.
▪️ Идемпотентность ≠ отсутствие побочных эффектов (это чистота функций).
▪️ Критична для распределённых систем: retry-механизмы, очереди сообщений, API.
▪️ Защищает от дублирующих запросов при сетевых сбоях.

🔹 Под капотом

В реальных системах идемпотентность достигается через:

→ Idempotency Key — клиент генерирует уникальный ключ и передаёт в запросе. Сервер проверяет: если операция с таким ключом уже выполнялась — возвращает закешированный результат.
→ Версионирование — оптимистичные блокировки через версии записей (JPA @Version).
→ Уникальные идентификаторы — вместо "создай заказ" отправляем "создай заказ с ID=xyz". Повторный запрос с тем же ID игнорируется.
→ Статус-машины — переходы между состояниями: если уже в целевом состоянии, ничего не делаем.

🔹 Подводные камни

— Idempotency key нужно хранить ограниченное время (обычно 24 часа).
— Нужна атомарность проверки и выполнения.
— Сложность при асинхронной обработке.
— Не все бизнес-операции можно сделать идемпотентными.
— Overhead на хранение и проверку ключей.

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

— REST API с критичными операциями (платежи, создание заказов).
— Kafka consumers — защита от повторной обработки при rebalance.
— Интеграция с внешними системами через retry.
— Scheduled jobs, которые могут запуститься дважды.
— Распределённые транзакции (Saga pattern).
— Webhook обработчики.
— Любые операции с денежными средствами.

Не нужно:

— Внутренние CRUD операции без side effects.
— Операции чтения (они идемпотентны по умолчанию).
— Высоконагруженные операции, где overhead критичен.
— Простые внутренние методы без внешних вызовов.

🔧 Бонус-трюк: в Spring можно создать аннотацию @Idempotent и реализовать через AOP с использованием Redis для хранения idempotency keys. Получается декларативная идемпотентность на уровне методов.

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

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

#CoreJava

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

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

🖥 Когда Kafka транзакции действительно нужны

Kafka транзакции не панацея, а узкоспециализированный инструмент.

🔹 Что гарантируют Kafka транзакции:

— Атомарную публикацию в несколько топиков (все сообщения видны или ни одно).
— Связывание read → process → write в одну операцию для консьюмеров-продюсеров.

🔹 Что НЕ гарантируют:


— Откат изменений во внешних системах (БД, API, email).
— Защиту от дубликатов, если downstream-сервисы не настроены правильно.

🔹 Два реальных сценария использования транзакций:

1️⃣ Публикация в несколько топиков без возможности дедупликации

Отправка события обработки заказа и событие в audit-топик с временной меткой. Если сервис упадёт между отправками, то при повторе время не совпадёт — история будет некорректной.

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

2️⃣ Схема read → process → write без дедупликации

Если сервис упадёт после отправки сообщений, но до коммита оффсета, downstream-сервисы увидят дубликаты.

Транзакции связывают отправку и коммит в одну атомарную операцию.

💡 Ключевой вывод: большинство систем прекрасно работают без транзакций, используя дедупликацию и идемпотентность.

Транзакции добавляют накладные расходы и подходят только для специфических кейсов.

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

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

#CoreJava

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

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

Что такое JIT-компилятор?

JIT (Just-In-Time) компилятор — это компонент JVM, который компилирует байт-код в машинный код непосредственно во время выполнения программы, а не до старта приложения. Его задача — улучшить производительность, оптимизируя код, исходя из реальных условий работы программы.

JIT компилирует только те части кода, которые реально исполняются, и может применять различные оптимизации для ускорения работы приложения. Это позволяет сочетать гибкость интерпретируемого байт-кода и производительность нативного кода.

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

#core

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

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

Как настроить production-ready логирование в Spring Boot

Логи в проде — это не просто System.out.println(). Это структурированные данные, correlation ID, асинхронная запись и ротация. Разбираем настройку от А до Я.

1️⃣ Выбираем стек: Logback + SLF4J

Spring Boot из коробки использует Logback. Добавляем зависимости:

<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>7.4</version>
</dependency>

ИЛИ

gradleimplementation 'net.logstash.logback:logstash-logback-encoder:7.4'


Это даст JSON-формат логов для удобного парсинга в ELK/Grafana.

2️⃣ Создаём logback-spring.xml

Кладём в src/main/resources:

<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<includeContext>false</includeContext>
<includeMdc>true</includeMdc>
</encoder>
</appender>

<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/application.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>logs/application-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>10GB</totalSizeCap>
</rollingPolicy>
<encoder class="net.logstash.logback.encoder.LogstashEncoder"/>
</appender>

<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
</configuration>


Логи ротируются по размеру и времени, старые архивируются в gzip.

3️⃣ Добавляем Correlation ID

Создаём фильтр для трекинга запросов:

@Component
public class CorrelationIdFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain chain) throws ServletException, IOException {
String correlationId = request.getHeader("X-Correlation-ID");
if (correlationId == null) {
correlationId = UUID.randomUUID().toString();
}
MDC.put("correlationId", correlationId);
response.setHeader("X-Correlation-ID", correlationId);
try {
chain.doFilter(request, response);
} finally {
MDC.clear();
}
}
}


Теперь каждый лог привязан к конкретному запросу. В JSON-логе будет поле correlationId.

4️⃣ Настраиваем уровни логирования в application.yml

logging:
level:
root: INFO
com.yourcompany: DEBUG
org.springframework.web: WARN
org.hibernate.SQL: DEBUG
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss} - %msg%n"


Для прода root: INFO, для дебага поднимаем до DEBUG только нужные пакеты.

5️⃣ Асинхронная запись логов

Добавляем в logback-spring.xml:

<appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="FILE"/>
<queueSize>512</queueSize>
<discardingThreshold>0</discardingThreshold>
</appender>

<root level="INFO">
<appender-ref ref="ASYNC_FILE"/>
</root>


Логи пишутся в отдельном потоке и не блокируют бизнес-логику.

6️⃣ Интеграция с мониторингом

Для отправки в Logstash/Fluentd добавляем TCP-аппендер:

<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>logstash.example.com:5000</destination>
<encoder class="net.logstash.logback.encoder.LogstashEncoder"/>
</appender>


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

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

#Enterprise

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

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

👑 Магия IntelliJ IDEA: покрытие тестами

Запускаешь тесты, они зелёные, и ты думаешь всё ок? А потом баг на проде в ветке, которую никто не проверил. IDEA умеет показывать, что реально покрыто тестами.

🔹 Что это

Run with Coverage — запуск тестов с визуализацией покрытия кода. Видишь прямо в редакторе, какие строки покрыты тестами, а какие нет.

🔹 Как запустить

— Ctrl+Shift+F10 → выбрать "Run with Coverage".
— Или правой кнопкой на тест/класс → "More Run/Debug" → "Run with Coverage".
— Или через иконку щита рядом с кнопкой Run.

🔹 Что показывает

→ Зелёная полоска слева от кода — строка выполнилась.
→ Красная полоска — строка не покрыта тестами.
→ Жёлтая полоска — ветка покрыта частично (if выполнился, else — нет).
→ Окно Coverage — статистика по классам, пакетам, методам.

🔹 Фишки

→ Кликни на класс в Coverage window → увидишь его code coverage.
→ Кликни на жёлтую полоску → IDEA покажет, какая именно ветка не покрыта.
→ Сортируй классы по проценту покрытия — найдёшь слабые места.
→ Экспортируй отчёт (HTML) через кнопку в Coverage панели.

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


— Находишь непокрытые edge cases.
— Видишь, что тест не проверяет все ветки if/else.
— Не гадаешь, а точно знаешь, что покрыто.
— Быстро понимаешь, где добавить тесты.

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

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

#Enterprise

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

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

⚡️ Параллельные стримы: ускорение или нет?

Java предоставляет мощный инструмент для обработки данных — параллельные стримы. Они позволяют автоматически распределять вычисления по нескольким потокам, но их эффективность зависит от множества факторов.

Добавление parallelStream() бездумно — это не "оптимизация", а лотерея с шансом на баги и падение.

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

— При небольшом наборе данных (<10 000 элементов) затраты на управление потоками могут превышать прирост скорости.
— Операции sorted(), distinct() или limit() требуют полного знания данных, что снижает эффективность параллельного выполнения.
— Вложенные parallelStream() в CompletableFuture или ExecutorService могут привести к конкуренции за ресурсы и неожиданному падению производительности.

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

— Обработка больших объёмов данных (100 000+ элементов).
— Операции независимы и ресурсоёмки, например, сложные вычисления, парсинг файлов, загрузка данных из сети.

🔍 Важная особенность

parallelStream() использует ForkJoinPool.commonPool(). Если есть другие задачи, использующие этот же пул, они могут начать конкурировать за потоки, замедляя всё приложение.

💬 Делитесь в комментах интересными кейсами

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

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

#CoreJava #лучшее2025

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

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

📈 Как «ленивая разработка» захватывает IT-рынок

Пока мы выстраиваем архитектуру, пишем тесты и спорим о лучших практиках, рынок всё активнее обживают те, кто вообще не пишет код. Low-code и no-code решения не просто живы — они становятся нормой для бизнеса.

Порог входа минимальный, скорость разработки — бешеная, а заказчику всё равно, написано ли это на Java или накликано в визуальном редакторе. Вопрос: как долго останется актуальной классическая разработка?

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

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

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

#CoreJava #лучшее2025

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

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

Enterprise AI 2026: время автономных Java-агентов

В мире Spring и Hibernate наступает новая эра — эпоха мультиагентных систем. В 2026-м ИИ-агенты становятся частью бизнес-логики крупных корпораций.

Освойте передовой стек на нашем курсе:

— паттерн ReAct: внедрение автономности в сложные системы;
— интеграция с n8n для бесшовной автоматизации процессов;
— протокол MCP: стандарт взаимодействия агентов в Enterprise;
— продвинутый RAG: работа с огромными объёмами корпоративных данных.

Сделайте шаг в сторону ИИ, пока другие только присматриваются.

❄️ До 12 января акция «3 в 1»: курс по ИИ-агентам + 2 курса в подарок.

Изучить программу

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

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

💼⌛️ ТОП-5 причин, почему программист не может долго найти работу

Почему некоторые разработчики остаются "между работами" месяцы?

Не всегда дело в нехватке вакансий или «рынок просел». Часто дело в подходе к поиску проекта. Вроде бы есть опыт, стек, даже pet-проекты, но офферов всё нет.

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

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

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

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

#CoreJava #лучшее2025

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

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

👑 Магия IntelliJ IDEA: Ctrl+E

Переключаешься между файлами через Project View? Теряешь время на поиск нужной вкладки среди десятка открытых? Есть способ быстрее.

🔹 Что это

Ctrl+E (Recent Files) — показывает список недавно открытых файлов. Быстрый доступ к тому, с чем ты работал последние 5-10 минут.

🔹 Что умеет

— Показать последние открытые файлы.
— Переключиться на файл по первым буквам названия.
— Видеть структуру директорий для контекста.
— Отметить часто используемые файлы звёздочкой.
— Фильтровать список прямо в окне поиска.

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


— Не нужно искать файл в дереве проекта.
— Быстрее, чем кликать по вкладкам.
— Видишь историю своей работы.
— Меньше отвлекаешься от кода.

🎯 Бонус


— Нажми Ctrl+E дважды — увидишь только недавно редактированные файлы.
— Начни печатать — список отфильтруется автоматически.
— Стрелками вверх/вниз быстро переключаешься между последними 2-3 файлами.

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

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

#Enterprise

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

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

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

Java Developer — офис (Москва)

Java Developer (Middle) — 100 000 – 200 000 ₽ — офис (Тольятти)

Java-разработчик — 300 000 —‍ 490 000 ₽ — офис/Гибрид (Москва)

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

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

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

Java в мире AI-агентов: Enterprise-подход к автономности

Пока другие балуются с промптами, мы учимся строить надёжные мультиагентные системы. В 2026 году автономные агенты — это стандарт для автоматизации сложных бизнес-процессов.

На курсе от Proglib Academy ты освоишь:

— паттерн ReAct: как заставить агента рассуждать и действовать;
— интеграцию с n8n для управления рабочими процессами;
— протокол MCP от Anthropic для бесшовного обмена данными;
— продвинутый RAG для мгновенного поиска по корпоративным знаниям.

Результат — дипломный проект в виде автономной группы агентов для анализа данных или техподдержки.

❄️ До 12 января забирай курс по ИИ-агентам по акции «3 в 1» (получи ещё два курса бесплатно).

Прокачать скиллы

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

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

📈 Big-O ≠ производительность

Часто выбор коллекции ограничивается только таблицей сложностей и на этом всё.

Но реальный кейс сложнее: средняя сложность ≠ реальная скорость в продакшне. JVM, кэш процессора, GC и паттерны доступа могут радикально поменять картину.

🔑 Главная мысль

Выбирайте коллекцию под сценарий использования, а не “по самой быстрой ячейке в таблице”.

1️⃣ ArrayList — быстр в чтение, но не во вставке

ArrayList хранит элементы в массиве → локальность памяти + CPU кэш → итерации летят.
Вставка в середину за O(n), но при небольших списках разница с LinkedList исчезающе мала.

🔧 Паттерн использования:

— 90% чтение, редкие вставки → идеально.
— Если заранее известно примерное кол-во элементов → задайте initialCapacity, иначе ArrayList будет несколько раз пересоздавать массив (copy O(n) на каждом росте).

📌 Факт:

В бенчмарках JMH даже при вставке в середину ArrayList часто быстрее LinkedList просто потому, что LinkedList платит за “pointer chasing” (скачки по памяти, cache-miss).

2️⃣ LinkedList — звучит круто, но редко нужен

Да, вставка/удаление в начало или конец за O(1).
Но get(i) = O(n), и каждый шаг = новый объект, новая ссылка → нагрузка на GC.

🔧 Паттерн использования:

— Когда нужна двусторонняя очередь с частыми удалениями/добавлениями в начало и конец.
— Во всех остальных случаях лучше ArrayDeque, он без лишних объектов и быстрее почти всегда.

📌 Факт:

LinkedList ест больше памяти: на каждый элемент два указателя + объект-узел.

3️⃣ HashMap / HashSet — быстрые, пока не наступил resize

HashMap даёт O(1) доступ при хорошем hashCode().

Но:
— Если хэши “плохие” → коллизии → O(log n)
— При достижении load factor 0.75 → resize → перераспределение всех бакетов (дорогая операция).

🔧 Паттерн использования:

— Когда нужен быстрый поиск по ключу без сохранения порядка или когда важно хранить уникальные элементы или строить словари/кэши по ключу.
— Если знаете примерное кол-во элементов → сразу задайте кол-во элементов в конструкторе new HashMap<>(N).

📌 Факт:

Начиная с Java 8 при коллизии, когда LinkedList становится длинным (по умолчанию ≥ 8 элементов) → список превращается в красно-чёрное дерево.

4️⃣ TreeMap / TreeSet — порядок стоит денег

Дают O(log n) доступ и всегда хранят ключи отсортированными.
Но если сортировка нужна редко, дешевле собрать HashMap и вызвать sorted() на стриме.

🔧 Паттерн использования:

— Когда важно поддерживать сортировку на каждой операции (напр. Top-N задач в приоритетной очереди).
— Не храните mutable-ключи, т.к. можно “потерять” элемент при изменении поля, участвующего в compareTo.

📌 Факт:

TreeMap хранит узлы с балансировкой (красно-чёрное дерево) → накладные расходы на память + сравнения ключей.

5️⃣ LinkedHashMap — скрытый герой для кэшей

LinkedHashMap поддерживает порядок вставки или порядок доступа (accessOrder=true).
Можно сделать LRU-кэш, переопределив removeEldestEntry.

🔧 Паттерн использования:

— Когда важен порядок, но сортировка не нужна.
— Когда нужно легко реализовать ограниченный кэш.

📌 Факт:

Каждый get() в режиме accessOrder вызывает перестановку в двусвязном списке → небольшие накладные расходы.

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

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

#CoreJava #лучшее2025

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