Java Books
14.2K subscribers
234 photos
13 videos
269 files
279 links
Java Библиотека

По всем вопросам- @notxxx1

@ai_machinelearning_big_data - machine learning

@pythonl - Python

@itchannels_telegram - 🔥 best it channels

@ArtificialIntelligencedl - AI

@pythonlbooks-📚

@programming_books_it -it 📚

№ 5032728887
Download Telegram
💡 Редкий совет Java: используйте `ClassValue` для кэша, привязанного к классу

Обычно метаданные кэшируют так:

Map<Class<?>, Metadata> cache = new ConcurrentHashMap<>();

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

Для подобных случаев в Java есть ClassValue:

private static final ClassValue<Metadata> CACHE =
new ClassValue<>() {
@Override
protected Metadata computeValue(Class<?> type) {
return inspect(type);
}
};

Metadata metadata = CACHE.get(User.class);

Значение вычисляется отдельно для каждого класса и может быть очищено после его выгрузки.

ClassValue особенно полезен для reflection-кэшей, сериализаторов, ORM, прокси и плагинных архитектур.

Редкий инструмент JVM, который часто безопаснее, чем ConcurrentHashMap<Class<?>, ...>.

#Java #JVM #Backend #Performance
👍4🔥2🥰1
🖥 Java можно учить месяцами - и всё равно бояться написать собственный сервер

Курс «Java: с нуля до сетевого гуру» построен так, чтобы ты как можно быстрее перешёл от теории к рабочему коду.

Сначала разберёшь основы языка, ООП, коллекции и исключения. Затем перейдёшь к тому, ради чего многие и выбирают Java:

- многопоточность;
- TCP/IP и сокеты;
- клиент-серверные приложения;
- обработка нескольких подключений;
- собственные сетевые проекты.

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

Курс подходит новичкам. Никакой подготовки не требуется: обучение начинается с базы и шаг за шагом выводит к задачам реальной backend-разработки.

В результате ты получишь крепкую основу Java, поймёшь, как работают сетевые приложения, и перестанешь смотреть на серверный код как на магию.

Начни сейчас - и преврати Java из «когда-нибудь выучу» в навык, которым уже можно пользоваться.

Курс доступен на Stepik: https://stepik.org/a/295392/
Please open Telegram to view this post
VIEW IN TELEGRAM
2
💡 Java cj: unmodifiableList() не делает настоящую копию

Эти два варианта выглядят похоже, но работают по-разному:


List<String> source = new ArrayList<>();
source.add("Java");

List<String> view = Collections.unmodifiableList(source);
List<String> copy = List.copyOf(source);

source.add("Spring");

System.out.println(view); // [Java, Spring]
System.out.println(copy); // [Java]


Collections.unmodifiableList() создаёт только неизменяемое представление исходного списка. Если source изменится, изменения появятся и в view.

List.copyOf() создаёт отдельный неизменяемый снимок данных.

Используйте:

- unmodifiableList() — когда нужен read-only view актуального списка;
- List.copyOf() — когда нужно зафиксировать состояние и безопасно вернуть его наружу.


public List<String> getUsers() {
return List.copyOf(users);
}


Так внешний код не сможет изменить внутреннюю коллекцию, а последующие изменения users не повлияют на уже возвращённый результат.

List.copyOf() доступен начиная с Java 10.

#Java #JavaTips #Backend
👍3👏1
💡 Java совет: два пути могут указывать на один и тот же файл

Path.equals() сравнивает только представление пути:


Path a = Path.of("data.txt");
Path b = Path.of("./data.txt");

System.out.println(a.equals(b)); // false


Хотя оба пути могут вести к одному файлу.

Для проверки используйте:


boolean same = Files.isSameFile(a, b);


Files.isSameFile() обращается к файловой системе и учитывает:

- относительные пути;
- символические ссылки;
- реальное расположение файла.


Path file = Path.of("data.txt");
Path link = Path.of("data-link.txt");

Files.isSameFile(file, link); // true, если link ведёт к data.txt


Полезно при поиске дубликатов, проверке пользовательских путей и защите от повторной обработки одного файла.

Учтите: метод может обращаться к диску и выбрасывать IOException, поэтому это не просто строковое сравнение.

Доступно начиная с Java 7.

#Java #JavaTips #Files
3👍2
☕️ Java-совет: не запускайте блокирующий I/O через `CompletableFuture` без собственного пула

Такой код выглядит асинхронным:


CompletableFuture<User> future =
CompletableFuture.supplyAsync(() -> userClient.loadUser(id));


Но без явного Executor задача обычно попадёт в общий ForkJoinPool.commonPool().

Если loadUser() ждёт HTTP, базу данных или файловую систему, поток блокируется. Несколько медленных вызовов могут занять весь общий пул и затормозить совершенно несвязанные операции приложения.

Лучше выделить отдельный пул для блокирующего I/O:


private static final ExecutorService IO_POOL =
Executors.newFixedThreadPool(32);

CompletableFuture<User> future =
CompletableFuture.supplyAsync(
() -> userClient.loadUser(id),
IO_POOL
);


И не забыть корректно его закрыть:


IO_POOL.shutdown();


Для цепочки тоже важно явно выбирать executor:


future.thenApplyAsync(
user -> enrichUser(user),
IO_POOL
);


Почему это полезно:

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

CompletableFuture не делает блокирующий код неблокирующим. Он лишь переносит ожидание в другой поток.

Асинхронность без контроля executor - это просто блокировка в менее заметном месте.
5👍4🔥2
⚡️ Java-приём: не храни метаданные классов в `static Map<Class<?>, ...>` — используй `ClassValue`.

Допустим, библиотека кеширует информацию о каждом классе:


private static final Map<Class<?>, Metadata> CACHE =
new ConcurrentHashMap<>();


На первый взгляд всё нормально.

Но в приложениях с динамической загрузкой классов — plugins, application servers, hot reload — такой кеш может удерживать Class, а вместе с ним и его ClassLoader.

И получить неприятную утечку памяти.

В Java для этого есть малоизвестный ClassValue<T>:


private static final ClassValue<Metadata> CACHE =
new ClassValue<>() {
@Override
protected Metadata computeValue(Class<?> type) {
return buildMetadata(type);
}
};


Использование:


Metadata metadata = CACHE.get(MyClass.class);


Что даёт ClassValue:

- ленивое вычисление значения для каждого класса;
- thread-safe доступ;
- не нужен собственный ConcurrentHashMap;
- кеш лучше согласован с жизненным циклом загруженных классов.

Особенно полезно для reflection, serializers, ORM, DI-контейнеров и framework-кода, где постоянно кешируются данные по Class<?>.

🔥 Если видишь в библиотеке:


static ConcurrentHashMap<Class<?>, ...>


стоит хотя бы задать вопрос:

а почему здесь не `ClassValue`?

#Java #JVM #Backend #Programming
3👍2
Полезный Java-совет:

Не вызывай parallelStream() просто потому, что данных много.

Для коротких операций он легко оказывается медленнее обычного stream(), потому что платишь за разбиение задачи, синхронизацию и работу ForkJoinPool.

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

Если параллелизм реально нужен, лучше контролировать executor явно, а не прятать его внутри parallelStream().
5👍4
Java-ловушка: почему `parallelStream()` может замедлить приложение

Многие думают:

«Есть stream(), добавлю parallelStream() — станет быстрее».

Но не всегда.

parallelStream() использует общий ForkJoinPool Java:


users.parallelStream()
.map(this::callExternalApi)
.toList();


Если внутри идут HTTP-запросы, SQL или ожидание внешнего сервиса, можно получить обратный эффект:

забить общий пул потоков
увеличить задержки
замедлить другие части приложения

parallelStream() хорошо подходит для:

сложных CPU-вычислений
обработки больших коллекций
математических операций

Но плохо подходит для:

HTTP
базы данных
файлового I/O
ожидания внешних сервисов

Для таких задач лучше использовать отдельный пул:


ExecutorService executor =
Executors.newFixedThreadPool(20);


и контролировать количество параллельных операций.

Главное правило:

parallelStream() — для вычислений.
ExecutorService — для бизнес-логики и внешних вызовов.

Код может идеально работать на тестах, но в production внезапно получить проблемы из-за одного parallelStream().
2👍1
🔥 Java: subList() может неожиданно удерживать огромный список в памяти

Кажется, что:


List<Item> small = hugeList.subList(0, 10);
hugeList = null;


оставит только 10 элементов.

Но subList() обычно создаёт представление исходного списка, а не независимую копию. Пока жив small, исходный ArrayList и его внутренний массив тоже могут оставаться в памяти.

Если нужна отдельная маленькая коллекция:


List<Item> small = new ArrayList<>(hugeList.subList(0, 10));


Особенно неприятный баг в кэшах и долгоживущих объектах: сохраняешь 10 элементов — а в памяти остаются сотни тысяч.
🤔62👍1
⚡️ «Контейнеры - это просто Linux-процессы» - полезное упрощение, но не совсем правда

Обычно контейнер объясняют так:

> контейнер = обычный Linux-процесс + namespaces + cgroups

Для первого знакомства этого хватает. Но OCI Runtime Spec определяет контейнер шире: это изолированная среда для запуска процессов, а не сам процесс.

И Linux-механизмы, только один из вариантов реализации.

OCI охватывает не только Linux, но и:

- Windows
- FreeBSD
- Solaris
- z/OS
- VM-based containers

То есть контейнер не обязан быть «процессом в Linux». Важнее то, что среда соответствует контейнерной модели: изоляция, файловая система, ресурсы, lifecycle и правила запуска.

Хороший разбор того, что контейнер представляет собой на самом деле:

https://labs.iximiuz.com/tutorials/oci-containers-explained
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍3
Школа программирования Java Online Projects поздравляет с Днем Знаний!🧑‍🎓📚

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

🔥 Скидка 50% на курсы «Микросервисы, Kafka, Docker Spring Cloud, WebFlux» и «Деплой микросервисов в Kubernetis/Helm»
Бонусы: выпускные проекты Rescue Service и TopJava2
Курс TopKotlin или DocJava в подарок

Суперпредложение: скидка 55% скидка на всю линейку Микросервисов + все бонусы включены🔥

Программа на 100% покрывает продвинутый стек компетенций:

Архитектура и веб-стек — начинаем с реактивных приложений: Project Reactor, Spring WebFlux, R2DBC. Дальше переходим на Spring Boot 4 — полный MVC-стек и виртуальные потоки (Virtual Threads).

Инфраструктура Spring Cloud — отказоустойчивые системы на Spring Cloud Gateway и Config Server, паттерны Circuit Breaker, RateLimiter, Retry.

Event-Driven & Data — асинхронное взаимодействие через Kafka, сериализация в Avro и хранение схем в Schema Registry, паттерн Outbox с Kafka Connect и Debezium поверх PostgreSQL, Hibernate/JPA и миграции Flyway.

Безопасность — сквозная аутентификация и авторизация на Keycloak, OAuth 2.0, OpenID Connect и JWT, защита от CSRF, хранение сессий в Redis.

Тестирование и качество — интеграционные тесты с Testcontainers, WireMock и Awaitility, проверка под высокой нагрузкой с Gatling.

Observability — метрики, логи и распределенные трассировки через Micrometer, Prometheus, Loki, Tempo (или Zipkin) и визуализация всего этого в Grafana.

DevOps и развертывание — пайплайны в GitHub Actions, Docker и Docker Compose, оркестрация в Kubernetes, управление релизами через Helm.

🚀 Больше 30 технологий в одной линейке!

Успейте забрать курсы по суперцене до окончания акции! 💥
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
Autobase

Это инструмент, разработанный для автоматизации развёртывания и управления PostgreSQL-кластерами с использованием Ansible. Он поддерживает широкий набор функций, включая настройку репликации, автоматизацию резервного копирования с помощью инструментов, таких как pgBackRest и WAL-G, мониторинг состояния кластеров, а также настройку высокодоступной инфраструктуры (HA).

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

https://github.com/autobase-tech/autobase
1👍1🤯1
Apache Kafka 4.x - продвинутый бесплатный практический курс 2026 года

https://github.com/justxor/KAFKAFREECOURSR/tree/main
4👍2
☕️ Java получил практический MCP-сервер для медицинского AI-триажа

На JavaOne показали систему, где жалоба пациента превращается в тикет, а AI определяет его срочность. Теперь Oracle подробно разобрала MCP-сервер, который принимает текст и возвращает оценку от 0 до 10.

Сервер построен на Helidon и публикует один инструмент через @Mcp.Tool. Клиенту не нужно знать, какая модель работает внутри.

Доступны два режима:

* локальный MiniLM через DJL - 384-мерные эмбеддинги, без API и сети;
* OpenAI text-embedding-3-small - 1536-мерные эмбеддинги.

Финальную оценку в обоих случаях вычисляет локальная нейросеть DeepNetts.

Важный нюанс: для каждого типа эмбеддингов нужна отдельно обученная модель оценки. Нельзя взять модель, обученную на векторах MiniLM, и передать ей векторы OpenAI, даже если привести их к одинаковому размеру.

MCP-интерфейс при этом остаётся неизменным:


жалоба → эмбеддинг → DeepNetts → срочность 0–10


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

https://inside.java/2026/07/25/design-java-mcp-tool/
2👍1
🔥 Python + AI без игрушечных демок. Курс для тех, кто хочет собирать рабочие системы.

Stepik: «Python современный AI для разработчика и автоматизации задач»

63 урока, 382 шага, практика с кодом и автопроверкой.

Внутри: RAG, tool calling, агенты, evals, MCP, Ollama, vLLM, pgvector + HNSW, безопасный text-to-SQL, prompt injection, кэш, очереди и sandbox для агентного кода.

Плюс реальные автоматизации: почта, отчёты, боты, вебхуки и браузерные сценарии.

Для тех, кто уже знает Python и хочет перейти к production AI.

72 часа скидка 55%

https://stepik.org/a/295921
1
Java: в HashSet всего 10 элементов, а обход всё равно тормозит

Редкий нюанс: время обхода HashSet зависит от количества элементов и размера внутренней таблицы.


var ids = new HashSet<Integer>(1_000_000);

for (int i = 0; i < 10; i++) {
ids.add(i);
}

for (int id : ids) {
process(id);
}


После добавления элементов внутри выделена огромная таблица. Итератор проходит по её ячейкам, включая пустые, хотя size() возвращает всего 10.

Сложность обхода - O(size + capacity). Поэтому большая ёмкость «про запас» может замедлить регулярный перебор.

Если коллекция уже сильно разрослась, а затем почти опустела, можно пересобрать её:


ids = new HashSet<>(ids);


Новый набор подберёт ёмкость под оставшиеся элементы. Пересборка требует времени и дополнительной памяти, поэтому имеет смысл перед многократными обходами, а не внутри каждого цикла.

Документация - https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/util/HashSet.html
🔥5👍1
🖥 Java в 2026 году: 25 лучших практических примеров кода от основ до многопоточности

https://uproger.com/java-v-2026-godu-25-luchshih-prakticheskih-primerov-koda-ot-osnov-do-mnogopotochnosti/
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍1
Apache Kafka курс 2026: бесплатный курс по Kafka с нуля до профи на русском

Kafka обучение без воды: каждый модуль состоит из понятной теории, схем, команд, которые можно запустить у себя, типичных ошибок и вопросов для самопроверки. Курс подходит, чтобы выучить Kafka с нуля, подготовиться к собеседованию на backend, data engineer или DevOps-позицию и спроектировать надёжную систему на Kafka в продакшене.

https://github.com/justxor/KAFKAFREECOURSR
9👍3