java_iibrary | Unsorted

Telegram-канал java_iibrary - Java Portal | Программирование

12073

Присоединяйтесь к нашему каналу и погрузитесь в мир для Java-разработчика Связь: @devmangx РКН: https://clck.ru/3H4WUg

Subscribe to a channel

Java Portal | Программирование

Spring Boot: для отправки писем можно использовать spring-boot-starter-mail.

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

Добавь зависимость:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>


Настрой почтовые параметры в application.properties (или application.yml):

spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=my_email@gmail.com
spring.mail.password=my_password
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true


Используй JavaMailSender в коде:

@Autowired
private JavaMailSender mailSender;

public void sendEmail(String to, String subject, String text) {
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(to);
message.setSubject(subject);
message.setText(text);
message.setFrom("your_email@gmail.com");

mailSender.send(message);
}


👉 Java Portal

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

Java Portal | Программирование

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

❌В HashMap, пока сама мапа существует, ключи и связанные с ними значения не будут удалены сборщиком мусора.

✅В WeakHashMap ключи хранятся через weak-ссылки. Если на ключ больше нет strong-ссылок в других местах программы, GC может его собрать, и он будет автоматически удалён из мапы.

Пример:

Map<User, String> map = new WeakHashMap<>();

User u1 = new User("Mick");
map.put(u1, "Cached data");
...
u1 = null;

// С этого момента ключ u1 может быть удалён сборщиком мусора.


👉 Java Portal

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

Java Portal | Программирование

Spring Boot: аккуратно задавайте границы @ComponentScan, чтобы случайно не сканировать целые пакеты целиком.

👉 Java Portal

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

Java Portal | Программирование

Java-совет: начиная с Java 11, лучше использовать String.strip() вместо trim(), потому что он корректно обрабатывает Unicode-пробелы.

❌Поскольку trim() не обрабатывает некоторые типы пробельных символов, определённых в Unicode, он может оставлять неожиданные символы.

✅String.strip() использует Character.isWhitespace(int codePoint) для определения пробелов. Этот метод следует полному стандарту Unicode для пробельных символов, а не только ASCII, и удаляет все виды пробелов.

Пример:

String text = "\u2003Hello World\u2003";
System.out.println("trim(): [" + text.trim() + "]");
System.out.println("strip(): [" + text.strip() + "]");


Смысл сохранён полностью: trim() ограничен ASCII, strip() работает по Unicode-правилам и ведёт себя ожидаемо.

👉 Java Portal

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

Java Portal | Программирование

Spring Boot: ты можешь валидировать входные DTO через @Valid плюс аннотации вроде @NotBlank, @Email и т.д.

public class RegistrationRequest {

@Email(message = "Please provide a valid email address")
@NotBlank(message = "Email is required")
private String email;

@Size(min = 8, max = 16, message = "Password must be 8–16 characters long")
private String password;

@Pattern(
regexp = "^[0-9]{10,15}$",
message = "Phone number must be 10–15 digits"
)
private String phone;

// getters & setters
}


By Default, if the validation fails Spring automatically returns a 400 Bad Request with a detailed error body like:


{
"timestamp": "2025-01-01T12:00:00Z",
"status": 400,
"errors": [
"Email is required",
"Age must be at least 18"
]
}


You can customize the response by implementing a global exception handler


👉 Java Portal

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

Java Portal | Программирование

Совет по Java: начиная с Java 12, можно использовать String.indent(n), чтобы форматировать многострочные строки, добавляя отступ.

n > 0: добавляет n пробелов в начале каждой строки.

n < 0: убирает до n ведущих пробелов (пробелов в начале) из каждой строки.

Добавление пробелов:

String text = "Text\ncontent";
System.out.println(text.indent(0));
System.out.println(text.indent(4));
System.out.println(text.indent(0));

Удаление пробелов:

String text = " Text\n content";
System.out.println(text.indent(-4));


👉 Java Portal

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

Java Portal | Программирование

Java-совет: начиная с Java 8 можно использовать ChronoUnit.between(start, end), чтобы посчитать интервал времени в конкретной единице (дни, часы, минуты) без ручных вычислений.

👉 Java Portal

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

Java Portal | Программирование

Совет по Java: используйте List.copyOf(list), чтобы сделать безопасную, неизменяемую копию и избежать случайных изменений.

// До Java 10, чтобы получить независимую неизменяемую копию, приходилось писать так:
List<String> copy = Collections.unmodifiableList(new ArrayList<>(originalList));

// Начиная с Java 10 это можно сделать короче:
List<String> copy = List.copyOf(originalList);

// Любая попытка добавить/удалить элемент выбросит UnsupportedOperationException:
List<String> original = new ArrayList<>();
original.add("A");
original.add("B");
List<String> copy = List.copyOf(original);
copy.add("C"); // UnsupportedOperationException


👉 Java Portal

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

Java Portal | Программирование

Java: с CompletableFuture.allOf(...) можно дождаться завершения сразу нескольких асинхронных задач, без ручной возни с join() по каждой.

👉 Java Portal

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

Java Portal | Программирование

Java tip: для точных расчетов времени используй Duration и Instant.

✅Instant представляет конкретный момент времени в UTC с точностью до наносекунд. Получить можно так: Instant.now().

✅Duration показывает временной интервал между двумя Instant (в секундах, миллисекундах, наносекундах).

Вот пример:

Instant start = Instant.now();
...
Instant end = Instant.now();

Duration elapsed = Duration.between(start, end);


👉 Java Portal

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

Java Portal | Программирование

Spring Boot: не используй FetchType.EAGER, если реально нет необходимости.

✗ Помечая связь как EAGER, ты говоришь ORM подгружать её каждый раз вместе с сущностью, даже если ты вообще не обращаешься к этой связи (не вызываешь геттер/метод отношения).

✗ В этом примере каждый раз, когда ты загружаешь Order, ORM автоматически подтянет и Customer:

@Entity
class Order {
@ManyToOne(fetch = FetchType.EAGER)
private Customer customer;
}


✗ И ещё: если не делать явный fetch, получаешь классический эффект N+1:

1. Один запрос на все Orders
2. По одному запросу на каждый Order для Customers

👉 Java Portal

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

Java Portal | Программирование

Rate limiting в системном дизайне: один пользователь или сервис не должен слишком часто дергать API и завалить его.

В Spring Boot для этого можно использовать библиотеку Bucket4j и сделать Rate Limit Filter.

Она умеет:

▪️защищать от примитивных DDoS-атак
▪️отсеивать кривых клиентов, которые шлют запросы в цикле
▪️ограничивать число запросов за единицу времени
▪️делать доступ чуть более честным: понемногу всем, а не все одному

Очень просто, быстро и потокобезопасно.

▪️На каждый запрос проверяет, есть ли в кэше ключ клиента (например IP). Если нет, создает для него bucket с токенами.
▪️Каждый раз пытается забрать из bucket один токен, то есть право выполнить запрос.
▪️Если токен в bucket есть, проходишь. Если токены закончились, получаешь HTTP 429 и ждешь пополнения.

Заметки:
-> request.getRemoteAddr() ищет корректный способ получить IP клиента, возможно через request.getHeader("X-Forwarded-For")
-> new ConcurrentHashMap<>() сам по себе не чистится, продумай, как долго хранить данные и как их вычищать, если запросов много
-> лимит задается одинаковый для всех эндпоинтов. Часто у разных API разная нагрузка, поэтому логично ставить разные лимиты (по URL, HTTP-методу или типу операции)
-> refillGreedy() это всего лишь один из вариантов пополнения токенов. Есть и другие стратегии (плавное пополнение, фиксированные интервалы), которые дают более точный контроль нагрузки
-> вынеси все настройки в application.yaml, чтобы менять лимиты без правок кода

Простая реализация, чтобы понять, как работает библиотека, приложена

👉 Java Portal

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

Java Portal | Программирование

Spring Boot: держи контроллеры тонкими, логику выноси в сервисы.

Главная задача контроллера, по сути, только разрулить HTTP-часть.

Плохой пример: бизнес-правила запихнуты в контроллер, типа проверки остатков и лимита заказа:

@RestController
@RequestMapping("/api/orders")
public class OrderController {

@Autowired
private OrderRepository orderRepository;

@Autowired
private ProductRepository productRepository;

@PostMapping
public ResponseEntity<?> createOrder(@RequestBody CreateOrderRequest request) {

// Validation logic
if (request.getProductId() == null || request.getQuantity() <= 0) {
return ResponseEntity
.badRequest()
.body("Invalid request");
}

// Business logic
Product product = productRepository.findById(request.getProductId())
.orElse(null);

if (product == null) {
return ResponseEntity
.status(HttpStatus.NOT_FOUND)
.body("Product not found");
}

if (product.getStock() < request.getQuantity()) {
return ResponseEntity
.badRequest()
.body("Not enough stock");
}

BigDecimal totalPrice = product.getPrice()
.multiply(BigDecimal.valueOf(request.getQuantity()));

if (totalPrice.compareTo(new BigDecimal("10000")) > 0) {
return ResponseEntity
.badRequest()
.body("Order limit exceeded");
}

// Persistence + transaction logic
product.setStock(product.getStock() - request.getQuantity());
productRepository.save(product);

Order order = new Order();
order.setProduct(product);
order.setQuantity(request.getQuantity());
order.setTotalPrice(totalPrice);
order.setCreatedAt(LocalDateTime.now());

orderRepository.save(order);

return ResponseEntity
.status(HttpStatus.CREATED)
.body(order.getId());
}
}


👉 Java Portal

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

Java Portal | Программирование

Java.hasChosen(you) 


🥶😟

Почему Java всё ещё №1 в автотестах?

Стас Васенков, основатель школы автотестировщиков @qa_guru, расскажет про свой мэтч с Java. Чем его зацепил этот язык и куда привёл. И куда Java может привести вас.

Приходите на открытый эфир ➡ 27 января ➡ 13:00 (МСК)

Что будет:
— неочевидные карьерные сценарии
— внутрянка: какой стек ждут, когда ищут автоматизатора
— кому Java уже не поможет 🐹

Не откладываем в TODO ➡ webinar.join();

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

Java Portal | Программирование

Spring Boot: лучше не использовать wildcard-исключения для транзитивных зависимостей в POM-файлах, потому что они могут прятать проблемы.

Wildcard-исключения просто убирают симптом и маскируют реальную причину: несовпадение версий.

<!-- Так лучше НЕ делать: wildcard-исключение (фактически “вырубаем всё”) -->
<exclusions>
<exclusion>
<!-- * = любой groupId -->
<groupId>*</groupId>
<!-- * = любой artifactId -->
<artifactId>*</artifactId>
</exclusion>
</exclusions>

<!-- Лучше: исключать конкретную транзитивную зависимость явно -->
<exclusion>
<!-- точный groupId зависимости, которую исключаем -->
<groupId>org.apache.tomcat.embed</groupId>
<!-- точный artifactId зависимости, которую исключаем -->
<artifactId>tomcat-embed-websocket</artifactId>
</exclusion>


👉 Java Portal

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

Java Portal | Программирование

От базовых до продвинутых программ на Java

39 программ на Java, каждая из которых решает отдельную задачу, включая разворот строки, проверку на палиндром, генерацию чисел Фибоначчи, вычисление факториала, проверку простого числа, сортировку массива, удаление дубликатов, поиск наибольшего элемента, и многое другое

👉 Java Portal

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

Java Portal | Программирование

Следуешь DDD и подходу model-first в Spring Data JDBC? Писать миграции Flyway или Liquibase руками и держать в голове синтаксис каждой конкретной БД — утомительно и легко накосячить.

IntelliJ IDEA позволяет генерировать миграции напрямую из ваших сущностей.

Подробнее: https://jb.gg/b8o1hq

👉 Java Portal

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

Java Portal | Программирование

Недавно открыл для себя learn.java — официальный сайт от Oracle для изучения Java. Здесь всё чётко и по делу 😈

> Установка JDK и настройка IDE
> Пошаговые уроки по основам Java
> Практические задания в онлайн-редакторе
> Мини-проекты для закрепления знаний
> Дополнительные ресурсы для углубленного обучения

Плюс — есть Java Playground, где можно писать и запускать код прямо в браузере, без лишних установок

👉 Java Portal

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

Java Portal | Программирование

Аннотации Spring Boot, которые нужно знать

👉 Java Portal

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

Java Portal | Программирование

Как и зачем писать свой DatabaseDialect для Kafka JDBC Sink

Я активно использую на проекте Kafka Connect Framework и в частности Kafka JDBC Sink Connector для быстрого сохранения данных из Kafka Topic в БД PostgresSQL. Для большинства задач достаточно написать простую JSON-конфигурацию и все стабильно и быстро работает из коробки. Нет необходимости в написании собственного кода. Однако в нетиповых ситуациях расширяемость Kafka Connect тоже помогает - можно переопределить и написать один из компонентов.

В конфигурации JDBC Sink Connector Task существует настройка dialect.name, которая отвечает за выбор диалекта для работы с конкретной БД. Как правило, в 99% случаев используется один из уже реализованных для популярных БД диалектов, как например в моем случае PostgresSqlDatabaseDialect для PostgreSQL.

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


В данной статье автор хочет показать идеи того, как реализация своего DatabaseDialect может помочь при имплементации нестандартных сценариев для вполне себе популярной БД Postgres, для которой существует PostgresSqlDatabaseDialect.

👉 Java Portal

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

Java Portal | Программирование

Хороший блог/ресурс по структуре данных Graph

Вчера, когда я снова разбирал задачи на графы, я наткнулся на этот блог в разделе Discussions на LeetCode.

Ссылка: гугл док

👉 Java Portal

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

Java Portal | Программирование

В Spring Boot лучше заменять @Value на @ConfigurationProperties, если хочешь больше контроля и нормальную тестируемость.

▪️Когда ты используешь @Value для кучи параметров, конфиг расползается по проекту: настройки оказываются разбросаны по разным классам, их сложнее поддерживать и тестировать.
▪️@ConfigurationProperties собирает связанные параметры в один класс, позволяет навесить валидацию и делает структуру кода аккуратнее.

Разница по сути такая:

▪️С @Value это строковая инъекция свойств без валидации.
▪️С @ConfigurationProperties это type-safe конфиг с возможностью валидации.

Плюсы:

▪️автокомплит в IDE
▪️валидация
▪️проще тестировать
▪️чище структура кода

В тестах можно просто замокать объект с настройками, вместо того чтобы возиться с отдельными @Value аннотациями на каждом поле.

👉 Java Portal

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

Java Portal | Программирование

Осознанная стоимость абстракций: Autoboxing в современной Java

Мы живём во времена, когда на оперативной памяти для heap Java-приложений почти не экономят, а архитектурные решения, которые ещё недавно можно было назвать расточительными, всё чаще воспринимаются как best practices.

Но не все коту масленица. Благодаря AI-буму, облачным вычислениям и микросервисной архитектуре с сотнями одновременно работающих инстансов, мы можем воочию наблюдать неукротимый рост стоимости оперативной памяти, что обязывает вернуться к рассмотрению принципов её экономии.

В этих условиях привычные абстракции требуют переоценки.

Сегодня я хочу напомнить об одной из самых распространенных в Java — autoboxing — механизме автоматической упаковки примитивных типов в соответствующие объекты-обертки.

Приглашаю вас посмотреть на знакомый Java-код не глазами разработчика, а глазами JVM, сборщика мусора и процессора, и разобраться, как незаметные на уровне синтаксиса решения превращаются в аллокации, давление на GC и раздувание heap.


👉 Java Portal

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

Java Portal | Программирование

Изучение Spring Boot у новичков часто вызывает перегруз 😵‍💫

Поэтому автор сделал Spring Boot Self Learning Guide: короткий гайд с упором на примеры, который покрывает самые часто используемые фичи Spring Boot.

👉 Java Portal

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

Java Portal | Программирование

HTTP/2 через TCP против HTTP/3 через QUIC

▪️HTTP/2

Мультиплексирование на уровне HTTP, сериализация на уровне TCP
Общий порядок доставки и контроль перегрузки (TCP)

Одна TCP-сессия

HTTP/2 фреймы (мультиплексированные)

* HEADERS (поток 1)
* HEADERS (поток 3)
* HEADERS (поток 2)
* DATA (поток 1)
* DATA (поток 3)
* DATA (поток 2)

TCP-пакеты: P1, P2, P3, P4, P5

TCP-пакеты смешивают данные из разных потоков
HoL-блокировка в TCP (Head-of-Line): потеря одного пакета блокирует все потоки

Клиент -> Сервер


▪️HTTP/3

Мультиплексирование на транспортном уровне (QUIC)

* Независимые потоки
* Независимый порядок доставки и восстановление

QUIC-соединение (поверх UDP)
QUIC Stream 1: QUIC Packet, QUIC Packet, QUIC Packet
QUIC Stream 2: QUIC Packet, QUIC Packet
QUIC Stream 3: QUIC Packet, QUIC Packet

Нет HoL-блокировки: потеря пакета влияет только на один поток

Клиент -> Сервер


👉 Java Portal

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

Java Portal | Программирование

Совет для IntelliJ: Alt+Enter можно использовать, чтобы быстро чинить ошибки и предупреждения, но список вариантов там довольно ограничен.

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

👉 Java Portal

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

Java Portal | Программирование

Как снизить хвостовые задержки в Java с помощью ZGC: читать

Он заметно снижает хвостовые задержки (p999/p9999) по сравнению с G1 за счет микропауз, но платит за это повышенным CPU и при нехватке процессора может упираться в allocation stalls, поэтому включать его стоит только после замеров на своей нагрузке.

👉 Java Portal

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

Java Portal | Программирование

Защищаю своё Spring Boot Java-приложение, которое использует 64 ГБ оперативной памяти, чтобы вернуть { "status": "ok" }

👉 Java Portal

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

Java Portal | Программирование

Project Panama: как Java научилась говорить на C! (Часть 1)

Как безопасно и эффективно вызывать C-функции из Java? Благодаря Project Panama — новому API из OpenJDK — это стало возможно без использования JNI.

👉 Java Portal

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

Java Portal | Программирование

Batch Processing vs Stream Processing: в чем разница?

Batch processing (пакетная обработка)

▪️Обрабатывает данные большими порциями (батчами) по расписанию.
▪️Отлично подходит для исторических данных, хранилищ (DWH) и аналитики.
▪️Примеры: расчёт зарплаты, периодические отчёты, ETL/ELT джобы.

Плюсы: эффективно на больших объёмах, дешевле по ресурсам, хорошо оптимизируется под throughput
Минусы: высокая задержка (latency), не подходит для задач, где нужно “прямо сейчас”

⚙️Инструменты: Apache Hadoop, Apache Spark, AWS Glue

Stream processing (потоковая обработка)

▪️Обрабатывает данные непрерывно, по мере поступления.
▪️Используется для real-time аналитики, антифрода, мониторинга “вживую”.
▪️Примеры: мониторинг биржи, рекомендации в реальном времени, IoT-датчики.

Плюсы: низкая задержка, инсайты в реальном времени, реактивные системы
Минусы: сложнее в реализации и поддержке, требует высокой доступности и масштабируемости

⚙️Инструменты: Apache Kafka, Apache Flink, Apache Storm, Spark Streaming

Во многих современных системах делают гибрид: batch для хранения и аналитики, stream для реакций и real-time сигналов.

👉 Java Portal

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