Java
Самая актуальная информация по Java По всем вопросам- @haarrp @itchannels_telegram - 🔥лучшие каналы @pythonl - 🐍 @ai_machinelearning_big_data- ml @ArtificialIntelligencedl - AI @datascienceiot - ds @pythonlbooks 📚 РКН: clck.ru/3FmwKr #VRHSZ
إظهار المزيد📈 نظرة تحليلية على قناة تيليجرام Java
تُعد قناة Java (@javatg) في القطاع اللغوي الروسية لاعباً نشطاً. يضم المجتمع حالياً 16 803 مشتركاً، محتلاً المرتبة 7 655 في فئة التكنولوجيات والتطبيقات والمرتبة 39 290 في منطقة روسيا.
📊 مؤشرات الجمهور والحراك
منذ تأسيسه في невідомо، حقق المشروع نمواً سريعاً وجمع 16 803 مشتركاً.
بحسب آخر البيانات بتاريخ 28 يوليو, 2026، تحافظ القناة على نشاط مستقر. خلال آخر 30 يوماً تغيّر عدد الأعضاء بمقدار -2، وفي آخر 24 ساعة بمقدار -4، مع بقاء الوصول العام مرتفعاً.
- حالة التحقق: غير موثّقة
- معدل التفاعل (ER): يبلغ متوسط تفاعل الجمهور 14.37%. وخلال أول 24 ساعة من النشر يحصد المحتوى عادةً 5.86% من ردود الفعل نسبةً إلى إجمالي المشتركين.
- وصول المنشورات: يحصل كل منشور على متوسط 2 414 مشاهدة. وخلال اليوم الأول يجمع عادةً 985 مشاهدة.
- التفاعلات والاستجابة: يتفاعل الجمهور بانتظام؛ متوسط التفاعلات لكل منشور يبلغ 10.
- الاهتمامات الموضوعية: يركز المحتوى على مواضيع رئيسية مثل github, void, api, kotlin, static.
📝 الوصف وسياسة المحتوى
يصف المؤلف القناة بأنها مساحة للتعبير عن الآراء الذاتية:
“Самая актуальная информация по Java
По всем вопросам- @haarrp
@itchannels_telegram - 🔥лучшие каналы
@pythonl - 🐍
@ai_machinelearning_big_data- ml
@ArtificialIntelligencedl - AI
@datascienceiot - ds
@pythonlbooks 📚
РКН: clck.ru/3FmwKr
#VR...”
بفضل وتيرة التحديث المرتفعة (أحدث البيانات بتاريخ 29 يوليو, 2026) تحافظ القناة على حداثتها ومستوى وصول مرتفع. وتُظهر التحليلات تفاعلاً نشطاً من الجمهور، ما يجعلها نقطة تأثير مهمة ضمن فئة التكنولوجيات والتطبيقات.
equals() опасен, если объект слева может быть null:
String a = null;
String b = "hi";
boolean result = a.equals(b); // NullPointerException
Безопаснее использовать Objects.equals():
boolean result = Objects.equals(a, b); // false
Метод корректно обрабатывает все случаи:
Objects.equals(null, null); // true
Objects.equals("hi", "hi"); // true
Objects.equals("hi", null); // false
Это особенно полезно внутри equals() у собственных классов:
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof User user)) return false;
return Objects.equals(id, user.id)
&& Objects.equals(email, user.email);
}
Правило простое: когда хотя бы одна сторона сравнения потенциально может быть null, используйте Objects.equals(a, b).
#Java #JavaTips #Programming
private static final Map<Class<?>, Metadata> CACHE =
new ConcurrentHashMap<>();
static Metadata metadata(Class<?> type) {
return CACHE.computeIfAbsent(type, Metadata::inspect);
}
Проблема: статическая Map хранит сильные ссылки на Class. В приложениях с плагинами, hot reload или несколькими ClassLoader такой кэш может мешать выгрузке старых классов.
Для данных, привязанных к конкретному классу, в Java есть ClassValue:
private static final ClassValue<Metadata> METADATA =
new ClassValue<Metadata>() {
@Override
protected Metadata computeValue(Class<?> type) {
return Metadata.inspect(type);
}
};
static Metadata metadata(Class<?> type) {
return METADATA.get(type);
}
Что это даёт:
- ленивое вычисление значения;
- потокобезопасную установку результата;
- отсутствие глобальной карты с Class в качестве сильных ключей;
- возможность сбросить значение через METADATA.remove(type).
Важный нюанс: computeValue() может выполниться несколько раз при гонке потоков, хотя сохранено будет одно значение. Поэтому внутри не должно быть необратимых побочных эффектов.
ClassValue особенно полезен для кэширования reflection-метаданных, MethodHandle, сериализаторов и обработчиков аннотаций.
#java #jvm #performanceFiles.copy():
Path src = Path.of("data.csv");
Path backup = Path.of("data.csv.bak");
Files.copy(src, backup, StandardCopyOption.REPLACE_EXISTING);
Что здесь важно:
* Path работает нормально на разных ОС
* REPLACE_EXISTING перезапишет файл, если backup уже есть
* удобно для бэкапов, экспорта и временных копий перед обработкой данных
Пример:
data.csv → data.csv.bak
Одна строка вместо ручного чтения и записи байтов.
#Java #Files-Xmx вроде выставлен нормально.
Проблема в том, что JVM живёт не только heap’ом.
Память уходит ещё на:
* Metaspace
* thread stacks
* direct buffers
* JIT/code cache
* native memory
* библиотеки и агентские инструменты
Kubernetes смотрит на весь процесс внутри контейнера. Если общий расход памяти пробивает container limit, pod получает OOMKilled, а не красивый Java OutOfMemoryError.
Что делать:
* не ставить Xmx вплотную к memory limit
* оставлять запас под non-heap
* использовать MaxRAMPercentage
* проверять requests/limits
* включать JVM memory metrics и GC logs
Для Java в Kubernetes важно считать не только heap, а весь memory footprint процесса.
https://dzone.com/articles/java-pod-oomkill-kubernetes null может внезапно дать NullPointerException
✅ пустая коллекция может сломать логику агрегации
✅ один элемент часто ведёт себя иначе, чем список из 10 значений
Один тест на List.of(1, 2, 3) проверяет только красивый сценарий.
Добавьте проверки на null, empty и boundary values — и код сразу станет заметно надёжнее.
#Java #Testing #JUnitStack до сих пор встречается в старом коде, но для новых проектов лучше брать Deque, чаще всего через ArrayDeque.
Stack - legacy-класс. Он наследуется от Vector, а значит, тащит за собой старую модель и синхронизацию почти на каждом вызове.
Для обычного стека это обычно лишнее.
Вместо этого:
Deque<String> undo = new ArrayDeque<>();
undo.push("typed hello");
undo.push("added space");
undo.pop(); // removes "added space"
API остаётся привычным:
push()
pop()
peek()
Но реализация современнее и обычно быстрее.
Правило простое: нужен LIFO-стек в Java - используйте Deque, а не Stack.MethodHandle
* работаешь с нативной памятью через MemorySegment и Arena
Это сильно упрощает Java-native interop по сравнению с JNI.
Где полезно:
* высоконагруженные вычисления
* криптография
* ML inference
* игровые движки
* интеграция с системными библиотеками
Project Panama делает Java ближе к системному уровню: меньше boilerplate, меньше JNI-магии, больше контроля над памятью и нативными вызовами.
Java уже давно не только про backend. VarHandle можно использовать как лёгкий механизм publish/subscribe между потоками без volatile.
Идея простая:
- Writer записывает данные в обычные поля.
- Затем вызывает setRelease(...) на флаге.
- Reader ждёт флаг через getAcquire(...).
- После этого безопасно читает опубликованные данные.
setRelease() гарантирует публикацию всех предыдущих записей.
getAcquire() гарантирует, что после чтения флага поток увидит все опубликованные данные.
Такой подход позволяет организовать корректную передачу данных между потоками с меньшими накладными расходами, чем при использовании volatile.
`switch expression убирает старую боль со случайно забытым break.
В старом switch легко получить тихий баг: пропустил break, и выполнение провалилось в следующий case.
В новом варианте каждый case возвращает значение через ->, а break не нужен:
String label = switch (status) {
case NEW -> "queued";
case RUNNING -> "in progress";
case DONE -> "finished";
};
Плюс компилятор следит за полнотой. Добавили новый enum-статус, но не обработали его в switch? Получите compile error, а не странный баг в рантайме.
Мелочь, которая делает код короче и безопаснее.
@Entity
public class Account {
@Id
private Long id;
private BigDecimal balance;
@Version
private Long version;
}
Как это работает:
Когда Entity читается из базы, Hibernate забирает текущую версию записи. Например, version = 2.
При обновлении он делает update с проверкой этой версии. Если за это время другая транзакция уже изменила запись, версия в базе стала другой.
Тогда update не затронет ни одной строки, и Hibernate выбросит OptimisticLockException.
Подходит, когда чтений много, записей меньше, а конфликты случаются редко.
Плохо подходит, если несколько потоков постоянно меняют одну и ту же запись или нужна строгая сериализация операций. Там уже лучше смотреть в сторону pessimistic locking, очередей или переработки модели записи.
@Version особенно полезен для аккаунтов, заказов, настроек, профилей и любых сущностей, где нельзя молча перетереть чужое изменение.
User user = userRepository.findByEmail(email);
if (user != null) {
Address address = user.getAddress();
if (address != null) {
return address.getCity();
}
}
return "unknown";
Проблема не только в количестве строк.
В таких вложенных if легко забыть один уровень проверки и получить NPE в самом неожиданном месте.
С Optional это можно записать короче и безопаснее:
return userRepository.findByEmail(email)
.map(User::getAddress)
.map(Address::getCity)
.orElse("unknown");
Каждый map() выполняется только если предыдущее значение существует.
Если пользователя нет, адреса нет или город не задан - цепочка спокойно дойдёт до orElse().
Для таких случаев Optional хорошо работает как способ явно показать:
значение может отсутствовать, и это нормальная часть логики.
Главное не превращать Optional в новую религию.
Он особенно полезен на границах методов и в цепочках, где каждый следующий шаг может вернуть null.