Java
Самая актуальная информация по Java По всем вопросам- @haarrp @itchannels_telegram - 🔥лучшие каналы @pythonl - 🐍 @ai_machinelearning_big_data- ml @ArtificialIntelligencedl - AI @datascienceiot - ds @pythonlbooks 📚 РКН: clck.ru/3FmwKr #VRHSZ
Ko'proq ko'rsatish📈 Telegram kanali Java analitikasi
Java (@javatg) Rus til segmentidagi kanali faol ishtirokchi. Hozirda hamjamiyat 16 799 obunachidan iborat bo'lib, Texnologiyalar & Aralashmalar toifasida 7 520-o'rinni va Rossiya mintaqasida 39 077-o'rinni egallagan.
📊 Auditoriya ko‘rsatkichlari va dinamika
невідомо sanasidan buyon loyiha tez o‘sib, 16 799 obunachiga ega bo‘ldi.
31 Avgust, 2026 dagi oxirgi ma’lumotlarga ko‘ra kanal barqaror faollikka ega. Oxirgi 30 kunda obunachilar soni -30 ga, so‘nggi 24 soatda esa 17 ga o‘zgardi va umumiy qamrov yuqori darajada qolmoqda.
- Tasdiqlash holati: Tasdiqlanmagan
- Jalb etish (ER): Auditoriya o‘rtacha 11.16% darajada jalb etiladi. Nashrdan keyingi dastlabki 24 soatda kontent odatda umumiy obunachilar sonining 5.30% ini tashkil etuvchi reaksiyalarni to‘playdi.
- Post qamrovi: Har bir post o‘rtacha 1 874 marta ko‘riladi; birinchi sutkada odatda 890 ta ko‘rish yig‘iladi.
- Reaksiyalar va o‘zaro ta’sir: Auditoriya faol: har bir postga o‘rtacha 11 ta reaksiya keladi.
- Tematik yo‘nalishlar: Kontent github, void, api, kotlin, static kabi asosiy mavzularga jamlangan.
📝 Tavsif va kontent siyosati
Muallif resursni shaxsiy fikrni ifoda etish maydoni sifatida ta’riflaydi:
“Самая актуальная информация по Java
По всем вопросам- @haarrp
@itchannels_telegram - 🔥лучшие каналы
@pythonl - 🐍
@ai_machinelearning_big_data- ml
@ArtificialIntelligencedl - AI
@datascienceiot - ds
@pythonlbooks 📚
РКН: clck.ru/3FmwKr
#VR...”
Yuqori yangilanish chastotasi (oxirgi ma’lumot 01 Sentabr, 2026 da olingan) sababli kanal doimo dolzarb va katta qamrovli bo‘lib qoladi. Analitika auditoriya kontent bilan faol hamkorlik qilishini, uni Texnologiyalar & Aralashmalar toifasidagi muhim ta’sir nuqtasiga aylantirishini ko‘rsatadi.
Thread.sleep() - это просто пауза на заданное время.
Проблема в том, что ты угадываешь:
❌ поток может проснуться слишком рано
❌ или наоборот, ждать дольше, чем нужно
❌ polling через sleep() создаёт лишние задержки и проверки
Для координации потоков лучше использовать:
✅ wait() / notify()
✅ CountDownLatch
✅ другие примитивы синхронизации из java.util.concurrent
Например:
CountDownLatch done = new CountDownLatch(1);
done.await(); // ждём сигнал
done.countDown(); // работа завершена
А если задача должна выполняться периодически, вместо бесконечного цикла с sleep() лучше взять
ScheduledExecutorService exec =
Executors.newSingleThreadScheduledExecutor();
exec.scheduleAtFixedRate(
this::doWork,
0,
1,
TimeUnit.SECONDS
);
Thread.sleep() хорошо подходит для простой задержки.
Для ожидания события и периодических задач в Java есть более точные инструменты.
#Java #Concurrencyspring-boot-mongodb
- работают напрямую с MongoDB driver
- для /actuator/health достаточно spring-boot-starter-mongodb
- Spring Data подключать не обязательно
То есть если сервис работает с MongoDB напрямую через драйвер, health check всё равно можно получить без лишней зависимости.
Полезное изменение для более лёгких Spring Boot 4 сервисов.. в формате числа не всегда означает точку
В DecimalFormat шаблон вроде:
#,###.##
не гарантирует вывод 1,234.56.
Символы зависят от locale:
🇺🇸 US → 1,234.56
🇮🇹 Italy → 1.234,56
Поэтому если формат предназначен для конкретной страны, лучше задавать её явно:
DecimalFormatSymbols it =
new DecimalFormatSymbols(Locale.ITALY);
DecimalFormat format =
new DecimalFormat("#,###.##", it);
Иначе приложение может внезапно начать форматировать числа иначе просто потому, что JVM запустили с другой локалью.
Мелочь, которая особенно неприятно всплывает в деньгах, отчётах и CSV.1.234,56 ломает Double.parseDouble()
В Java число - это не всегда просто строка с точкой.
Например:
Double.parseDouble("1.234,56");
закончится NumberFormatException.
Проблема в локали: в разных странах . и , означают разное.
Для таких случаев лучше использовать:
NumberFormat format =
NumberFormat.getInstance(Locale.ITALY);
Number value = format.parse("1.234,56");
double n = value.doubleValue();
Получим:
1234.56
Главное правило: если число пришло от пользователя, из CSV или внешней системы — сначала узнай его locale.
Иначе можно получить не только ошибку, но и тихо распарсить совсем не то число.@ConfigurationPropertiesSource позволяет генерировать metadata для типов, которые находятся не в текущем модуле, а, например, в общей библиотеке или отдельном starter-модуле.
Раньше с такими внешними типами IDE-подсказки для application.yml и application.properties могли быть неполными или вообще отсутствовать.
Теперь можно явно указать источник конфигурационных свойств и получить нормальную metadata даже для внешних классов.
Особенно полезно для:
— multi-module проектов
— внутренних Spring Boot starter'ов
— shared configuration libraries
— больших платформенных команд
Мелкая фича, но для DX в крупных Spring Boot проектах очень приятная.
#SpringBoot4 #Configrecord позволяет сильно сократить код.
Вместо обычного класса с полями, конструктором, equals(), hashCode() и toString() можно написать:
public record User(String name, int age, String email) {}
Java сама создаст:
user.name();
user.age();
user.email();
user.equals(other);
user.hashCode();
user.toString();
При этом record остаётся неизменяемым по ссылкам на свои компоненты: сеттеров нет, а поля фактически final.
Можно добавить и компактный конструктор для валидации:
public record User(String name, int age, String email) {
public User {
if (age < 0) {
throw new IllegalArgumentException("Age cannot be negative");
}
}
}
Records появились как preview в Java 14 и стали полноценной частью языка в Java 16.
Удобный вариант для DTO, результатов запросов, событий, конфигурационных объектов и других небольших структур данных.clone() легко принять за полноценную копию объекта. Но super.clone() делает только shallow copy.
Сам объект будет новым, а ссылки на вложенные объекты останутся прежними.
То есть:
Main shallow = (Main) super.clone();
shallow и оригинал будут разными объектами, но dependency у них может указывать на один и тот же экземпляр.
Поэтому изменение вложенного объекта через одну копию неожиданно отразится и в другой.
Для deep copy нужно отдельно клонировать вложенные поля:
Main deep = (Main) super.clone();
deep.setDependency((Dependency) this.dependency.clone());
Теперь dependency тоже будет отдельным объектом.
Мелочь, на которой легко поймать очень неприятный баг: clone() копирует оболочку, а не весь граф объектов.JmsClient - более современная альтернатива привычному JmsTemplate.
Главное отличие - fluent API, из-за которого код отправки и получения сообщений становится заметно чище.
При этом JmsTemplate никуда не исчезает и продолжает работать без изменений.
Для старых проектов переписывать ничего не нужно, а для нового JMS-кода Spring теперь рекомендует смотреть в сторону JmsClient.
#SpringBoot4 #JMS
Map<List<Integer>, String> map = new HashMap<>();
List<Integer> key = new ArrayList<>(List.of(1, 2));
map.put(key, "Ritesh");
key.add(3);
System.out.println(map.get(key));
Многие ожидают:
Ritesh
Но результат:
```text
null
```
Почему?
HashMap ищет ключ через:
```java
hashCode()
equals()
```
Когда мы сделали:
```java
map.put(key, "Ritesh");
```
ключ был:
```text
[1, 2]
```
У него был один hashCode.
Но потом:
```java
key.add(3);
```
ключ стал:
```text
[1, 2, 3]
```
И его hashCode изменился.
HashMap уже положил объект в bucket по старому hash, а при get() ищет по новому.
Схема:
```text
put()
[1,2]
hash = X
↓
bucket X
key.add(3)
[1,2,3]
hash = Y
get()
ищем bucket Y
→ запись не найдена
```
Главное правило:
❌ Не изменяйте объект после того, как использовали его как ключ в HashMap.
Лучше использовать:
✅ String
✅ Integer
✅ record
✅ immutable-объекты
Например:
```java
Map<List<Integer>, String> map = new HashMap<>();
List<Integer> key = List.of(1, 2);
map.put(key, "value");
```
Самые опасные баги в Java - те, где объект всё ещё существует, ссылка всё та же, но структура данных уже не может его нормально найти.
#java #backend #programminginstanceof.
Старый вариант:
if (animal instanceof Dog) {
Dog d = (Dog) animal;
d.bark();
}
С pattern matching переменная объявляется прямо в проверке:
if (animal instanceof Dog d) {
d.bark();
}
d существует только там, где условие instanceof гарантированно истинно. Меньше кода, меньше лишних приведений типов и проще читать.
#Java #PatternMatchingTestRestTemplate на RestTestClient.
Почему это удобнее:
- fluent API в стиле RestClient;
- одинаковый подход для тестов через MockMvc и реальный HTTP-порт;
- проще читать цепочки request → response → assertions;
- меньше привязки к старому TestRestTemplate.
Пример:
restTestClient.get()
.uri("/api/users/42")
.exchange()
.expectStatus().isOk()
.expectBody(User.class)
.value(user -> assertThat(user.id()).isEqualTo(42));
Если автоконфигурация не подтянулась автоматически, добавляем:
@AutoConfigureRestTestClient
Если начинаете новый проект на Boot 4, TestRestTemplate уже вряд ли стоит выбирать по привычке.
#SpringBoot4 #Java #RestTestClient #Testing
private final AtomicLong requests = new AtomicLong();
requests.incrementAndGet();
Проблема: все потоки конкурируют за одну переменную.
Много потоков → больше CAS-коллизий → меньше производительность.
Для метрик лучше:
private final LongAdder requests = new LongAdder();
requests.increment();
Как работает:
AtomicLong:
Thread 1 ─┐
Thread 2 ─┼──> [100000]
Thread 3 ─┘
LongAdder:
Thread 1 → [10]
Thread 2 → [20]
Thread 3 → [15]
↓
sum()
LongAdder распределяет обновления между несколькими ячейками памяти, снижая конкуренцию.
Идеально для:
✅ Prometheus metrics
✅ счётчиков запросов
✅ статистики JVM
✅ rate limiter
Но важно:
adder.sum()
не гарантирует точный атомарный снимок.
Используйте:
- LongAdder → метрики и статистика;
- AtomicLong → когда нужно точное значение.
Одна замена класса может заметно улучшить производительность под нагрузкой.
#java #jvm #performancesynchronized и блокировки;
- проблемы с масштабированием.
Вместо того чтобы постоянно защищать изменяемое состояние, во многих случаях лучше проектировать код так, чтобы его было меньше изначально:
✅ immutable-объекты
✅ Java record
✅ concurrent-коллекции
✅ immutable snapshots через List.copyOf()
✅ минимум shared state
Например, ConcurrentLinkedQueue может убрать необходимость в грубой синхронизации для определённых сценариев, а record отлично подходит для неизменяемых доменных объектов.
Главная идея проста: чем меньше состояние можно изменить, тем меньше способов сломать многопоточный Java-код.
Но ConcurrentLinkedQueue не универсальная замена synchronized - выбор структуры данных всё равно должен исходить из требований к атомарности и консистентности.spring-boot-starter-undertow.
Если раньше было:
<artifactId>spring-boot-starter-undertow</artifactId>
теперь используйте Tomcat по умолчанию или подключайте Jetty:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
Ещё один важный момент: не разворачивайте Spring Boot 4 в старом Servlet-контейнере — требуется совместимость с Servlet 6.1.
Перед миграцией Boot 3 → 4 обязательно проверьте серверную часть приложения.
#SpringBoot4 #Java #Servlet