Библиотека Java разработчика
10.3K subscribers
1.05K photos
595 videos
58 files
1.43K links
📚 Лайфхаки, приёмы и лучшие практики для Java-разработчиков. Всё, что ускорит код и прокачает навыки. Java, Spring, Maven, Hibernate.


По всем вопросам @evgenycarter

РКН clck.ru/3KoGeP
Download Telegram
Вы знаете названия шаблонов проектирования, но сможете ли выбрать архитектуру, которая выдержит реальную нагрузку? CQRS, Event Sourcing, Saga Pattern звучат убедительно. Но каждый из этих подходов решает конкретные задачи — и добавляет сложности. Ошибка в выборе архитектуры часто обходится дороже, чем ошибка в коде.

На открытом уроке «Основные шаблоны проектирования в системном дизайне»:

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

Ведущий Роман Грицуляк — разработчик, консультант по проектированию ИТ-систем.

Открытый урок проходит в преддверии старта курса «Проектирование систем».

Регистрируйтесь сейчас - напомним перед вебинаром: регистрация

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
👍1
🕸️ Service Mesh: Инфраструктура, невидимая для кода

Проблема: "Толстые" микросервисы
Если вы используете Spring Cloud (Netflix OSS), ваша бизнес-логика перемешана с сетевой логикой.
Вам нужно добавлять в код Java аннотации для ретраев (повторных запросов), настраивать Circuit Breaker (Предохранитель), писать логику для распределенной трассировки.

А теперь представьте, что в компанию пришла команда, которая пишет на Go или Node.js. Им придется искать аналоги всех этих библиотек для своих языков! Разве сеть это проблема программиста? Нет, это проблема инфраструктуры.

🦸‍♂️ Решение: Service Mesh и паттерн Sidecar
Service Mesh (Сервисная сетка) - это выделенный инфраструктурный слой для безопасного, быстрого и надежного общения микросервисов друг с другом. Самый популярный инструмент на рынке - Istio.

Вся магия строится на паттерне Sidecar (Коляска мотоцикла).


Рядом с вашим контейнером Java в том же поде (Pod) Kubernetes незаметно запускается второй маленький контейнер - Proxy-сервер (обычно это Envoy).

Теперь ваше Java-приложение вообще ничего не знает о внешнем мире.
1. Оно хочет отправить запрос в PaymentService? Оно просто шлет HTTP-запрос на localhost.

2. Sidecar-прокси перехватывает этот запрос.

3. Sidecar сам находит нужный сервис, сам шифрует трафик, сам делает ретраи, если сеть моргнула, и отправляет запрос другому Sidecar-у на стороне PaymentService.

🎛️ Как устроен Istio: Data Plane и Control Plane

Data Plane (Плоскость данных): Это армия тех самых Sidecar-прокси (Envoy), которые стоят рядом с каждым сервисом и перекидывают байты.

Control Plane (Плоскость управления): Это мозг (Istiod). Он раздает команды всем прокси-серверам: "Так, с сегодняшнего дня все запросы шифруем", "А теперь 5% трафика направь на новую версию сервиса".

Суперспособности Service Mesh

Зачем терпеть усложнение архитектуры? Ради этих фич:

1. Управление трафиком (Traffic Routing)
Вам больше не нужно деплоить новую версию на всех сразу и молиться, чтобы она не упала.
Вы можете сказать Istio: "Пусти 99% пользователей на версию v1, и только 1% пользователей с iPhone - на версию v2 (Канареечный релиз)". Если v2 работает стабильно, плавно увеличиваем процент.

2. Нулевое доверие (Zero-Trust Security & mTLS)
Если хакер проникнет во внутреннюю сеть дата-центра, он сможет "слушать" трафик между вашими сервисами (там могут лететь пароли и токены в открытом виде).
Istio из коробки включает mTLS (Mutual TLS). Трафик между ВСЕМИ микросервисами автоматически шифруется. При этом разработчикам не нужно возиться с сертификатами в Java-коде.

3. Наблюдаемость (Observability) без кода
Помните Jaeger, Zipkin и Prometheus из прошлого сезона? Чтобы они работали, мы добавляли библиотеки в pom.xml.
С Service Mesh это не нужно! Так как все запросы проходят через Sidecar-прокси, он сам собирает метрики (сколько времени занял запрос, какие были ошибки) и сам рисует красивые графы зависимостей в Grafana и Jaeger.

4. Устойчивость к сбоям (Resilience)
Если PaymentService "лежит", Sidecar может автоматически сделать 3 повторные попытки (Retry) с интервалом в секунду. Если сервис всё равно не отвечает, Sidecar включит Circuit Breaker (разорвет цепь) и будет сразу возвращать ошибку, чтобы не перегружать зависший сервис.

⚔️ Service Mesh vs API Gateway
Часто спрашивают: "Зачем мне Istio, если у меня уже есть Spring Cloud Gateway?"
API Gateway: Управляет трафиком Север-Юг (Снаружи вовнутрь). Он стоит на границе интернета и вашей системы, принимает запросы от пользователей, проверяет JWT-токены и пускает внутрь.

Service Mesh: Управляет трафиком Восток-Запад (Внутри системы). Он следит за тем, как микросервисы общаются между собой за закрытыми дверями.

🔥 Итог
Service Mesh (Istio) - это инструмент для крупных и сложных систем.
Если у вас 5 микросервисов - это оверкилл, используйте Spring Cloud.
Если у вас 100 микросервисов на разных языках программирования, строгие требования к безопасности (банки) и частые релизы без Service Mesh вы сойдете с ума.

#SystemDesign #ServiceMesh #Istio #Microservices #DevOps

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥43👍2💩1
🚀 Подборка полезных IT каналов в Max


Системное администрирование, DevOps 📌

https://max.ru/i_odmin Все для системного администратора
https://max.ru/bash_srv Bash Советы
https://max.ru/sysadminof Книги для админов, полезные материалы
https://max.ru/i_odmin_book Библиотека Системного Администратора
https://max.ru/i_devops DevOps: Пишем о Docker, Kubernetes и др.

1C разработка 📌
https://max.ru/odin1c_rus Cтатьи, курсы, советы, шаблоны кода 1С

Программирование C++📌

https://max.ru/cpp_lib Библиотека C/C++ разработчика

Программирование Python 📌
https://max.ru/python_of Python академия.
https://max.ru/BookPython Библиотека Python разработчика

Java разработка 📌
https://max.ru/bookjava Библиотека Java разработчика

GitHub Сообщество 📌
https://max.ru/githublib Интересное из GitHub

Базы данных (Data Base) 📌
https://max.ru/database_info Все про базы данных

Фронтенд разработка 📌
https://max.ru/frontend_1 Подборки для frontend разработчиков

Библиотеки 📌
https://max.ru/programmist_of Книги по программированию
https://max.ru/proglb Библиотека программиста
https://max.ru/bfbook Книги для программистов

Программирование 📌
https://max.ru/bookflow Лекции, видеоуроки, доклады с IT конференций
https://max.ru/itmozg Программисты, дизайнеры, новости из мира IT
https://max.ru/php_lib Библиотека PHP программиста 👨🏼‍💻👩‍💻

Шутки программистов 📌
https://max.ru/itumor Шутки программистов

Защита, взлом, безопасность 📌
https://max.ru/thehaking Канал о кибербезопасности
https://max.ru/xakkep_1 Хакер Free

Книги, статьи для дизайнеров 📌

https://max.ru/odesigners Статьи, книги для дизайнеров

Математика 📌
https://max.ru/Pomatematike Канал по математике
https://max.ru/phismat_1 Обучающие видео, книги по Физике и Математике

Вакансии 📌
https://max.ru/progjob Вакансии в IT

Мир технологий 📌
https://max.ru/mir_teh Канал для любознательных


Бонус 📌
https://max.ru/piterspb_78 Свежие новости Санкт-Петербурга
https://max.ru/mockva_life Свежие новости Москвы
🖕4
🔌 Проектирование API: REST, GraphQL или gRPC?


🧱 1. REST (Классика и Стандарт)

REST (Representational State Transfer) - это де-факто стандарт интернета. Большинство публичных API (GitHub, Stripe, Telegram) построены на нем.

Суть: В центре всего находится Ресурс (Существительное). А действия над ним выполняются через стандартные HTTP-методы (Глаголы).
GET /users/123 - Дай мне пользователя 123.
POST /users - Создай пользователя.
DELETE /users/123 - Удали пользователя.

Плюсы:

Простота: Понятен всем, легко тестировать через Postman или браузер.

Кэширование: Идеально работает с CDN (о которых мы говорили раньше), так как использует стандартные механизмы HTTP.

Минусы:

Over-fetching (Избыточность): Мобильному приложению нужно только имя пользователя, но метод GET /users/1 возвращает огромный JSON на 50 полей (с адресами, датами и т.д.). Вы тратите трафик впустую.

Under-fetching (Недостаточность) и проблема N+1: Чтобы показать профиль пользователя и его 10 последних постов, фронтенду придется сделать 1 запрос к /users/1 и еще 10 запросов к /posts?userId=1. Это медленно.


🕸️ 2. GraphQL (Мечта Фронтендера)

Разработан в Facebook для решения проблем REST при слабом мобильном интернете.

Суть: У вас есть всего один Endpoint (обычно POST /graphql). Клиент сам пишет запрос-схему, где указывает, какие конкретно поля ему нужны.

Запрос клиента:

query {
user(id: "123") {
name
email
posts(last: 10) {
title
}
}
}

Ответ сервера: Вернется JSON строго с именем, email и 10 заголовками постов. Ни одним байтом больше!

Плюсы:

• Решает проблемы Over-fetching и Under-fetching. Один запрос = ровно те данные, что нужны для отрисовки экрана.

• Быстрая итерация фронтенда: UI-команде больше не нужно просить бэкендеров написать новый endpoint /users-with-posts-and-comments.


Минусы:

Сложность кэширования: Так как всё идет через один URL POST /graphql, вы не можете просто закэшировать это на уровне CDN (Cloudflare).

Угроза для Базы Данных: Если клиент напишет слишком глубокий вложенный запрос (Пользователь -> Посты -> Комментарии -> Авторы комментариев -> Их посты), ваша БД просто "ляжет".


🚀 3. gRPC (Спидраннер для Микросервисов)

Разработан в Google. Если REST и GraphQL общаются с помощью удобочитаемого текста (JSON) поверх старого HTTP/1.1, то gRPC ломает эти правила.

Суть: Вы вызываете функцию на другом сервере так, будто она лежит в вашем собственном коде.
Он использует HTTP/2 (поддерживает стриминг) и Protobuf (Protocol Buffers).
Protobuf - это бинарный формат. Вместо того чтобы передавать ключи "name": "Alex", он передает просто байты по заранее оговоренной жесткой схеме (.proto файл).



Плюсы:

Невероятная скорость: Бинарный формат весит в разы меньше JSON и парсится процессором мгновенно. gRPC работает до 10 раз быстрее REST.

Строгая типизация: Вы описываете контракты в .proto файле, и из него автоматически генерируется код и для Java-бэкенда, и для Python-клиента. Никаких ошибок "ожидал строку, пришло число".

Стриминг: Можно открыть соединение и непрерывно лить данные в обе стороны.


Минусы:

Не читается человеком: Вы не можете просто открыть консоль браузера и посмотреть payload, там будут непонятные бинарные символы.

Плохая поддержка браузерами: Напрямую из JavaScript в браузере gRPC вызвать сложно (нужен прокси grpc-web), поэтому для публичного фронтенда его почти не используют.


В идеальной современной архитектуре:
Мобилка общается с API Gateway по GraphQL —> Gateway общается с внутренними микросервисами по gRPC.

#SystemDesign #API #REST #GraphQL #gRPC #Java

📲 Мы в MAX

👉@BookJava
8👍6
Scala создан на базе Java, но при этом остаётся более лаконичным и выразительным языком. При этом они отлично сочетаются: вы можете использовать Java-код внутри Scala. На Scala разрабатывают микросервисы, системы аналитики, решения для машинного обучения и обработки данных, а также высоконагруженные сервисы.
Приглашаем на серию открытых уроков перед стартом курса «Scala-разработчик»:

📆1 апреля в 20:00
Разберём функциональную валидацию данных с помощью Cats Validated. Поговорим, почему Either неудобен для таких задач, научимся собирать все ошибки сразу и реализуем валидацию формы регистрации. Вы поймёте, когда использовать Validated, а когда Either, и сможете применять это в реальном коде.

📆14 апреля в 20:00
Изучим ключевые возможности Scala через case classes и pattern matching. На практике разберём, как создавать безопасные модели данных, работать с событиями и писать чистый, понятный код, который используется в production.

📆20 апреля в 20:00
Погрузимся в тему эффектов в Scala. Разберём, что такое эффекты и как они помогают писать предсказуемый и масштабируемый код. Рассмотрим Option, Either, Future, а также Cats Effect и ZIO, и покажем, как применять их в реальных задачах.

💥Присоединяйтесь, чтобы прокачать навыки Scala и функционального программирования на практике. Подробности об уроках и регистрация: https://vk.cc/cVMvN3

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Совет по Java 💡

Чтобы сделать большие и сложные цепочки компараторов более читаемыми, мне нравится присваивать компараторы переменным, имена которых начинаются с "by". Таким образом, вызов sorted() становится меньше и читается почти как естественный язык. Кроме того, вы можете использовать статический импорт.

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥2
🖥️ Java: передача по значению или по ссылке? 🤔

В Java передача данных происходит ТОЛЬКО по значению (pass-by-value). Однако работа с объектами может ввести в заблуждение и создать впечатление, что передача идет по ссылке.

🔹 Как работает передача в Java?
Примитивные типы (int, double, char): передается копия значения. Изменения внутри метода не влияют на оригинальную переменную.

Объекты (экземпляры классов): передается копия ссылки на объект, а не сам объект. Внутри метода можно изменить состояние объекта, но нельзя изменить саму ссылку на него.

📌 Примеры
🔹 Передача примитивов (значение не изменяется)

public class Test {
public static void modifyPrimitive(int num) {
num = 10; // Это изменение локальное
}

public static void main(String[] args) {
int x = 5;
modifyPrimitive(x);
System.out.println(x); // Выведет: 5 (не изменилось)
}
}


🔹 Передача объекта (изменение состояния объекта сохраняется)

class Person {
String name;
}

public class Test {
public static void modifyObject(Person p) {
p.name = "Alice"; // Изменяет состояние объекта
}

public static void main(String[] args) {
Person person = new Person();
person.name = "Bob";
modifyObject(person);
System.out.println(person.name); // Выведет: Alice
}
}


🔹 Переназначение ссылки (не изменяет оригинальный объект)

class Person {
String name;
}

public class Test {
public static void reassignReference(Person p) {
p = new Person(); // Переназначение ссылки (локально)
p.name = "Charlie";
}

public static void main(String[] args) {
Person person = new Person();
person.name = "Bob";
reassignReference(person);
System.out.println(person.name); // Выведет: Bob (не изменилось)
}
}


🔥 Итог
🔹 Java всегда передает данные по значению!
🔹 Примитивы передаются как копии значений.
🔹 Объекты передаются как копии ссылок, но изменения внутри объекта сохраняются.
🔹 Если внутри метода изменить саму ссылку, это не повлияет на оригинальный объект.

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍92
👩‍💻 Открытый урок «Spring Boot Actuator: основы мониторинга и управления приложением»

🗓 30 марта в 20:00 МСК

🆓 Бесплатно. Урок в рамках старта курса «Разработчик на Spring Framework» от Otus.

Узнайте, как эффективно реализовать интернационализацию и локализацию в Spring-приложениях.

На вебинаре разберем:

Знакомимся с базовыми возможностями Spring Boot Actuator — важным инструментом для контроля приложений.

О чём поговорим:
✔️ Зачем нужен Spring Boot Actuator.
✔️ Какие задачи решает при работе с приложениями.
✔️ Базовая настройка Actuator.
✔️ Просмотр метрик и их значение.


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

🔗 Ссылка на регистрацию: https://vk.cc/cVR0CO

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
👍1
Совет по Java 💡☕️

Чтобы получить все дни месяца, вы можете начать с объекта YearMonth, получить его первый день, а затем использовать функцию datesUntil(), которая возвращает Stream всех дней до указанной даты.

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4👎1
🚀 Совет по Java API 🚀

При использовании Integer.valueOf(int) помните, что значения в диапазоне от -128 до 127 кэшируются для повышения производительности. За пределами этого диапазона создаются новые объекты.

Размер кэша можно контролировать с помощью опции -XX:AutoBoxCacheMax=<размер>. 🔥

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
В чем разница между Checked и Unchecked исключениями во время выполнения?

Да, в Java есть существенные различия между checked (проверяемыми) и unchecked (непроверяемыми) исключениями во время выполнения.

1. Проверка на этапе компиляции
- Checked исключения: Проверяются на этапе компиляции. Компилятор требует, чтобы вы либо обработали исключение (с помощью try-catch), либо объявили его в сигнатуре метода (с помощью throws). Если этого не сделать, код не скомпилируется.
- Unchecked исключения: Не проверяются на этапе компиляции. Компилятор не требует их обработки или объявления. Обычно они возникают из-за логических ошибок в коде (например, NullPointerException, ArrayIndexOutOfBoundsException).

2. Поведение во время выполнения
- Checked исключения: Эти исключения обычно связаны с внешними факторами (например, проблемы с файловым вводом-выводом, сетевыми соединениями) и могут возникать в ходе нормального выполнения программы. Если такое исключение выбрасывается и не обрабатывается, оно будет передаваться вверх по стеку вызовов, пока не будет перехвачено или программа не завершится.
- Unchecked исключения: Эти исключения часто вызваны ошибками в коде (например, деление на ноль, обращение к null). Если такое исключение выбрасывается и не перехватывается, оно также будет передаваться вверх по стеку вызовов, но, поскольку их не требуется объявлять или обрабатывать, это может привести к неожиданному завершению программы.

3. Наследование
- Checked исключения: Все исключения, которые наследуют Exception (но не RuntimeException), являются проверяемыми.
- Unchecked исключения: Все исключения, которые наследуют RuntimeException или Error, являются непроверяемыми.

4. Примеры
- Checked исключения: IOException, SQLException, ClassNotFoundException.
- Unchecked исключения: NullPointerException, ArrayIndexOutOfBoundsException, ArithmeticException.

5. Обработка во время выполнения
- Checked исключения: Поскольку они проверяются на этапе компиляции, вы обязаны явно их обрабатывать. Это делает код более устойчивым, но может увеличить его объем.
- Unchecked исключения: Поскольку они не проверяются на этапе компиляции, их сложнее отлаживать и обрабатывать, так как они могут быть неочевидными в коде.

6. Производительность
- Нет значительной разницы в производительности между checked и unchecked исключениями во время выполнения. Стоимость выбрасывания и перехвата исключений одинакова для обоих типов.

Итог
- Checked исключения: Контролируются компилятором, должны быть обработаны или объявлены, обычно используются для recoverable (восстанавливаемых) ситуаций.
- Unchecked исключения: Не контролируются компилятором, часто возникают из-за ошибок в коде и могут привести к аварийному завершению программы, если не обработаны.

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

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍51👎1
🚀Разбираем принцип работы ConcurrentHashMap

Сегодня разберёмся, почему ConcurrentHashMap лучше подходит для многопоточной работы, чем HashMap, и как он работает внутри.

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

📌 Основные особенности:
- Делит данные на сегменты (до JDK 8 или использует synchronized и CAS операции (начиная с JDK 8).
- Чтение (get()) не требует блокировки.
- Запись (put()) использует минимально возможные блокировки.
- Нет null ключей и значений (в отличие от HashMap).

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


import java.util.concurrent.ConcurrentHashMap;

public class Main {
public static void main(String[] args) {
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();

map.put("Java", 1);
map.put("Python", 2);
map.put("C++", 3);

System.out.println(map.get("Java")); // 1
}
}


📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍31
🔴 Завтра тестовое собеседование с Java-разработчиком

1 апреля(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.

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

Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.

Переходи в нашего бота, чтобы получить ссылку на эфир →
@shortcut_sh_bot

Реклама.
О рекламодателе.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🚀Как правильно использовать Optional в Java

Optional<T> в Java — это мощный инструмент для работы с возможными null значениями, но часто его используют неправильно. Давайте разберём основные ошибки и лучшие практики.

Плохие примеры:

1️⃣ Использование Optional как поля в классе

class User {
Optional<String> name; // Плохая практика
}

Лучше просто использовать String, а если нужно, то оборачивать значение в Optional при возврате.

2️⃣ Использование isPresent() вместо ifPresent()

if (optionalValue.isPresent()) {
process(optionalValue.get()); // Неоптимально
}

Лучше так:

optionalValue.ifPresent(this::process); // Правильный подход


📌 Хороший пример использования:

public Optional<User> findUserById(int id) {
return Optional.ofNullable(userRepository.get(id));
}


💡 Правильное использование Optional помогает избежать NullPointerException и делает код чище.

🔥 А как вы используете Optional? Пишите в комментариях! 🚀

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🔥 Разбираем CompletableFuture: Асинхронность в Java без боли

Привет, коллеги! Сегодня поговорим о CompletableFuture, который помогает писать асинхронный код в Java без коллбэков и потерь в читабельности.

📌 1. Почему CompletableFuture?
В Java давно есть Future, но он неудобен:
Нельзя комбинировать несколько задач.
Блокирует поток при вызове .get().
Нет удобных методов для обработки результатов.

👉 CompletableFuture решает все эти проблемы, позволяя комбинировать задачи, обрабатывать ошибки и не блокировать потоки.



📌 2. Базовый пример использования

import java.util.concurrent.CompletableFuture;

public class AsyncExample {
public static void main(String[] args) {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
sleep(2000);
return "Привет, мир!";
});

future.thenAccept(result -> System.out.println("Результат: " + result));

System.out.println("Этот текст выведется раньше результата!");
sleep(3000); // Чтобы программа не завершилась раньше времени
}

private static void sleep(int ms) {
try { Thread.sleep(ms); } catch (InterruptedException ignored) {}
}
}

🔹 Здесь supplyAsync() выполняет задачу в другом потоке, а thenAccept() позволяет асинхронно обработать результат.



📌 3. Комбинирование нескольких задач

CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "World");

CompletableFuture<String> result = future1.thenCombine(future2, (s1, s2) -> s1 + " " + s2);

System.out.println(result.join()); // Hello World

thenCombine() объединяет результаты двух асинхронных задач.



📌 4. Обработка ошибок (exceptionally)

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
if (Math.random() > 0.5) {
throw new RuntimeException("Что-то пошло не так!");
}
return "Все хорошо!";
}).exceptionally(ex -> "Ошибка: " + ex.getMessage());

System.out.println(future.join());

Если в supplyAsync() произошла ошибка, она обработается в exceptionally(), и программа не упадёт.



📌 5. Запуск нескольких задач параллельно

CompletableFuture<Void> allTasks = CompletableFuture.allOf(
CompletableFuture.runAsync(() -> sleepAndPrint("Задача 1", 1000)),
CompletableFuture.runAsync(() -> sleepAndPrint("Задача 2", 2000)),
CompletableFuture.runAsync(() -> sleepAndPrint("Задача 3", 1500))
);

allTasks.join(); // Дождёмся завершения всех задач

private static void sleepAndPrint(String msg, int ms) {
try { Thread.sleep(ms); } catch (InterruptedException ignored) {}
System.out.println(msg);
}

allOf() позволяет запустить несколько задач параллельно и дождаться их завершения.



📌 Итог
🔹 CompletableFuture – это мощный инструмент для работы с асинхронностью в Java.
🔹 Позволяет избежать блокировок, обрабатывать ошибки, комбинировать задачи.
🔹 Улучшает читаемость кода по сравнению с Future и ExecutorService.


📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
1️⃣ Чем record лучше class в Java?

В Java 14 появился record – новый тип классов, предназначенный для удобного хранения данных. Чем он лучше обычного class? Давайте разберёмся!

🔹 Запись против класса
Обычный класс:

class Person {
private final String name;
private final int age;

public Person(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() { return name; }
public int getAge() { return age; }

@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + "}";
}
}

Много бойлерплейта…

Теперь то же самое с record:

record Person(String name, int age) {}

Меньше кода
Автоматически генерируются toString(), equals(), hashCode()
Иммутабельность по умолчанию

⚠️ Когда НЕ стоит использовать record?
- Если нужен изменяемый объект
- Если требуется сложная бизнес-логика внутри класса

Вы уже используете record в своих проектах? Делитесь опытом! 🚀

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
🚀 Подборка полезных IT каналов в Max


Системное администрирование, DevOps 📌

https://max.ru/i_odmin Все для системного администратора
https://max.ru/bash_srv Bash Советы
https://max.ru/sysadminof Книги для админов, полезные материалы
https://max.ru/i_odmin_book Библиотека Системного Администратора
https://max.ru/i_devops DevOps: Пишем о Docker, Kubernetes и др.

1C разработка 📌
https://max.ru/odin1c_rus Cтатьи, курсы, советы, шаблоны кода 1С

Программирование C++📌

https://max.ru/cpp_lib Библиотека C/C++ разработчика

Программирование Go📌
https://max.ru/golang_lib Библиотека Go (Golang) разработчика

Программирование React📌
https://max.ru/react_lib React

Программирование Python 📌
https://max.ru/python_of Python академия.
https://max.ru/BookPython Библиотека Python разработчика

Java разработка 📌
https://max.ru/bookjava Библиотека Java разработчика

GitHub Сообщество 📌
https://max.ru/githublib Интересное из GitHub

Базы данных (Data Base) 📌
https://max.ru/database_info Все про базы данных

Фронтенд разработка 📌
https://max.ru/frontend_1 Подборки для frontend разработчиков

Библиотеки 📌
https://max.ru/programmist_of Книги по программированию
https://max.ru/proglb Библиотека программиста
https://max.ru/bfbook Книги для программистов

Программирование 📌
https://max.ru/bookflow Лекции, видеоуроки, доклады с IT конференций
https://max.ru/itmozg Программисты, дизайнеры, новости из мира IT
https://max.ru/php_lib Библиотека PHP программиста 👨🏼‍💻👩‍💻

Шутки программистов 📌
https://max.ru/itumor Шутки программистов

Защита, взлом, безопасность 📌
https://max.ru/thehaking Канал о кибербезопасности
https://max.ru/xakkep_1 Хакер Free

Книги, статьи для дизайнеров 📌

https://max.ru/odesigners Статьи, книги для дизайнеров

Математика 📌
https://max.ru/Pomatematike Канал по математике
https://max.ru/phismat_1 Обучающие видео, книги по Физике и Математике

Вакансии 📌
https://max.ru/progjob Вакансии в IT

Мир технологий 📌
https://max.ru/mir_teh Канал для любознательных


Бонус 📌
https://max.ru/piterspb_78 Свежие новости Санкт-Петербурга
https://max.ru/mockva_life Свежие новости Москвы
🖕81👍1
🔥 5 паттернов проектирования, которые должен знать каждый Java-разработчик

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


1️⃣ Singleton
Ограничивает создание объекта одним экземпляром. Полезен для логирования, работы с базами данных, кэшей.

🔹 Пример кода (Lazy Initialization, thread-safe):

public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}

Используется в Spring Bean, Hibernate SessionFactory.



2️⃣ Factory Method
Позволяет создавать объекты без привязки к конкретному классу. Отлично подходит, если у вас много типов объектов с общей логикой.

🔹 Пример:

interface Product {
void create();
}

class ConcreteProductA implements Product {
public void create() { System.out.println("Создан продукт A"); }
}

class ProductFactory {
public static Product createProduct(String type) {
if ("A".equals(type)) return new ConcreteProductA();
throw new IllegalArgumentException("Неизвестный тип продукта");
}
}

Используется в JDBC (DriverManager.getConnection).



3️⃣ Builder
Позволяет создавать сложные объекты пошагово. Альтернатива длинным конструкторам с кучей параметров.

🔹 Пример (Lombok @Builder делает его проще!):

@Builder
public class Car {
private String model;
private int year;
private String engine;
}

Car car = Car.builder().model("Tesla").year(2024).engine("Electric").build();

Используется в StringBuilder, HttpRequest в Java 11+.



4️⃣ Observer
Позволяет подписаться на события и реагировать на них. Часто используется в GUI, event-driven системах.

🔹 Пример (наблюдатель за событиями):

interface Observer {
void update(String message);
}

class User implements Observer {
private String name;
public User(String name) { this.name = name; }
public void update(String message) {
System.out.println(name + " получил уведомление: " + message);
}
}

class Channel {
private List<Observer> observers = new ArrayList<>();
public void subscribe(Observer o) { observers.add(o); }
public void notifyAll(String message) {
for (Observer o : observers) { o.update(message); }
}
}

Используется в Spring Events, RxJava.



5️⃣ Decorator
Добавляет функциональность объекту без изменения его структуры. Часто применяется в логгировании, кешировании, потоках IO.

🔹 Пример (логирование обертки над OutputStream):

class LoggingOutputStream extends OutputStream {
private OutputStream wrapped;
public LoggingOutputStream(OutputStream wrapped) { this.wrapped = wrapped; }
@Override
public void write(int b) throws IOException {
System.out.println("Записываем байт: " + b);
wrapped.write(b);
}
}

Используется в BufferedReader, Logger, Spring Security Filters.


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

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
5👍5
🚀 Stream API в Java: 5 мощных трюков, которые ты мог не знать

Stream API – одна из самых крутых фич в Java, но многие используют только map(), filter() и collect(). Давай разберем 5 полезных трюков, которые сделают код элегантнее и эффективнее!

🔹 1. Группировка элементов (Collectors.groupingBy)
Разбиваем список строк на группы по длине:


List<String> words = List.of("apple", "banana", "cat", "dog", "elephant");
Map<Integer, List<String>> grouped = words.stream()
.collect(Collectors.groupingBy(String::length));

System.out.println(grouped);
// {3=[cat, dog], 5=[apple], 6=[banana], 8=[elephant]}


🔹 2. Уникальные элементы (distinct())
Фильтруем дубликаты в потоке:


List<Integer> numbers = List.of(1, 2, 2, 3, 4, 4, 5);
List<Integer> unique = numbers.stream()
.distinct()
.collect(Collectors.toList());

System.out.println(unique); // [1, 2, 3, 4, 5]


🔹 3. Пропуск N элементов (skip(n))
Хотим пропустить первые 3 элемента и взять только оставшиеся:


List<String> names = List.of("Alice", "Bob", "Charlie", "David", "Eve");
List<String> skipped = names.stream()
.skip(3)
.collect(Collectors.toList());

System.out.println(skipped); // [David, Eve]


🔹 4. Найти максимальное значение (max())
Допустим, у нас есть список чисел, найдем максимальное:


List<Integer> nums = List.of(10, 20, 30, 5, 15);
Optional<Integer> maxNum = nums.stream().max(Integer::compareTo);

maxNum.ifPresent(System.out::println); // 30


🔹 5. Проверить, содержит ли список нужное значение (anyMatch())
Допустим, нам нужно проверить, есть ли в списке число больше 100:


List<Integer> nums = List.of(10, 50, 200, 30);
boolean hasLargeNumber = nums.stream().anyMatch(n -> n > 100);

System.out.println(hasLargeNumber); // true


🔥 Stream API – это мощный инструмент для работы с коллекциями. Используйте его, и ваш код станет чище, короче и быстрее!

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
📌 Java Record: Почему Это Круто?

Сегодня расскажу вам о record в Java – мощном инструменте, который упростит вашу жизнь при работе с неизменяемыми объектами.

🔹 Что такое record?
Введённый в Java 14, record – это специальный тип класса, предназначенный для хранения данных. Он автоматически генерирует:
Конструктор
Геттеры (но без get в названии)
equals(), hashCode(), toString()

🔹 Пример использования

public record User(String name, int age) {}

Этот код эквивалентен написанию полноценного класса с полями, конструктором, геттерами и методами equals/hashCode/toString, но занимает всего одну строку!

🔹 Преимущества record
🚀 Меньше кода – никаких бойлерплейтов
🚀 Иммутабельность – данные не изменяются после создания
🚀 Читаемость – сразу видно, что это объект только для хранения данных

🔹 Ограничения:
Поля record всегда final
Наследование от record запрещено

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍42🔥2