ThreadLocal может привести к утечкам памяти?ThreadLocal – удобный способ хранения данных в потоке, но может привести к утечкам памяти.• Потоки из ThreadPool не удаляются сразу после завершения работы.• Если ThreadLocal не очищается вручную, объект остаётся в памяти, даже если он больше не нужен.remove()ThreadLocal<MyClass> threadLocal = ThreadLocal.withInitial(MyClass::new);
try {
MyClass obj = threadLocal.get();
// Логика
} finally {
threadLocal.remove(); // Очищаем объект
}
ThreadLocal осторожно, особенно в серверах с ThreadPool, чтобы избежать утечек памяти.#java #threadlocal #memoryleak
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15❤2
Parallel Stream?Использование
parallelStream() может замедлить программу, если не учитывать его особенности.forEach().int[] sum = {0};
list.parallelStream().forEach(i -> sum[0] += i); // Потенциальная ошибка!reduce()int sum = list.parallelStream().reduce(0, Integer::sum);
parallelStream() эффективен, если объём данных большой и нет конкурентного доступа.#java #parallelstream #performance
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13❤1
Closeable и AutoCloseableИнтерфейсы
Closeable и AutoCloseable предназначены для управления ресурсами, которые нужно явно закрывать после использования, например, потоки ввода-вывода, соединения с базами данных и т. д. Однако у них есть некоторые различия.1️⃣
AutoCloseable появился в Java 7 в связи с введением try-with-resources, это базовый интерфейс для всех ресурсов, которые могут быть автоматически закрыты.В
AutoCloseable определен метод:
void close() throws Exception;
То есть, метод
close() может выбрасывать любое исключение (Exception).2️⃣
Closeable наследует AutoCloseable, более специфичен и предназначен в основном для потоков ввода-вывода (I/O). В
Closeable метод close() может выбрасывать только IOException.#java #Closeable #AutoCloseable
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15❤1
В Java 22 появился
Foreign Function & Memory API, который позволяет взаимодействовать с C-библиотеками без JNI.• Безопаснее – нет Unsafe.• Проще – не нужно писать C-обёртки.• Быстрее – меньше накладных расходов.strlen из библиотеки C:
static long invokeStrlen(String s) throws Throwable {
try (Arena arena = Arena.ofConfined()) {
// Allocate off-heap memory and
// copy the argument, a Java string, into off-heap memory
MemorySegment nativeString = arena.allocateUtf8String(s);
// Link and call the C function strlen
// Obtain an instance of the native linker
Linker linker = Linker.nativeLinker();
// Locate the address of the C function signature
SymbolLookup stdLib = linker.defaultLookup();
MemorySegment strlen_addr = stdLib.find("strlen").get();
// Create a description of the C function
FunctionDescriptor strlen_sig =
FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS);
// Create a downcall handle for the C function
MethodHandle strlen = linker.downcallHandle(strlen_addr, strlen_sig);
// Call the C function directly from Java
return (long)strlen.invokeExact(nativeString);
}
}
JNI.#java #foreignapi #native
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤1
Collections1️⃣
Collections.sort() — сортировка списка
import java.util.*;
public class Main {
public static void main(String[] args) {
List<String> names = Arrays.asList("Вика", "Андрей", "Сергей");
Collections.sort(names);
System.out.println(names); // [Андрей, Вика, Сергей]
}
}
📌 Работает с
Comparable. Можно передавать Comparator для кастомной сортировки.2️⃣
Collections.reverse() — реверс списка
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Collections.reverse(numbers);
System.out.println(numbers); // [5, 4, 3, 2, 1]
3️⃣
Collections.shuffle() — перемешивание элементов
List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5);
Collections.shuffle(nums);
System.out.println(nums); // случайный порядок, например [3, 1, 5, 2, 4]
💡 Полезно для перемешивания карт, вопросов в викторине и т. д.
#java #Collections #sort #reverse #shuffle
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤1🔥1
FilesЧтение всего файла в список строк (
readAllLines)
import java.nio.file.*;
import java.io.IOException;
import java.util.List;
public class Main {
public static void main(String[] args) throws IOException {
Path path = Paths.get("example.txt");
List<String> lines = Files.readAllLines(path);
lines.forEach(System.out::println);
}
}
📌 Читает весь файл в List<String>, удобно для небольших файлов.
Запись в файл (
write)
List<String> lines = List.of("Первая строка", "Вторая строка");
Files.write(Paths.get("output.txt"), lines);
📌 Если файла нет — создаст, если есть — перезапишет.
Добавление в файл (без перезаписи):
Files.write(Paths.get("output.txt"), lines, StandardOpenOption.APPEND);
#java #Files #readAllLines #write
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18❤1
Stream.reduce()Метод
reduce() используется для агрегирования (свёртки) элементов стрима в одно значение. Это мощный инструмент для вычислений, таких как сумма, произведение, конкатенация строк и т. д.1️⃣
T reduce(T identity, BinaryOperator<T> accumulator)identity – начальное значение (например, 0 для суммы, 1 для произведения).accumulator – функция, которая объединяет элементы.✅ Пример: сумма чисел
List<Integer> numbers = List.of(1, 2, 3, 4, 5);
int sum = numbers.stream().reduce(0, Integer::sum);
System.out.println(sum); // 15
2️⃣
reduce(accumulator) (без начального значения)
Optional<T> reduce(BinaryOperator<T> accumulator)
📌 Здесь возвращается
Optional<T>, потому что стрим может быть пустым.✅ Пример: наибольшее число
Optional<Integer> max = numbers.stream().reduce(Integer::max);
max.ifPresent(System.out::println); // 5
3️⃣
reduce(identity, accumulator, combiner) (для параллельных потоков)
<U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner)
✅ Пример: длина всех строк в списке
List<String> words = List.of("Java", "Stream", "Reduce");
int totalLength = words.parallelStream()
.reduce(0, (sum, word) -> sum + word.length(), Integer::sum);
System.out.println(totalLength); // 16
Здесь:
sum + word.length() – считает длину строк,Integer::sum – объединяет результаты.💡 Совет: Для простых случаев (сумма, максимум) используйте
sum(), max(), count(), а reduce() – для сложных операций.#java #reduce
Please open Telegram to view this post
VIEW IN TELEGRAM
5👍18❤3
1️⃣
Collections.min() и Collections.max()
List<Integer> list = Arrays.asList(10, 5, 30, 7);
System.out.println(Collections.min(list)); // 5
System.out.println(Collections.max(list)); // 30
2️⃣
Collections.fill() — заполнение списка одним значением
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
Collections.fill(list, "X");
System.out.println(list); // [X, X, X]
3️⃣
Collections.replaceAll() — замена значений
List<String> list = new ArrayList<>(Arrays.asList("яблоко", "груша", "яблоко"));
Collections.replaceAll(list, "яблоко", "банан");
System.out.println(list); // [банан, груша, банан]
4️⃣
Collections.frequency() — подсчет вхождений элемента
List<String> list = Arrays.asList("A", "B", "A", "C", "A");
int count = Collections.frequency(list, "A");
System.out.println(count); // 3
#java #Collections #min #max #fill #replaceAll #frequency
Please open Telegram to view this post
VIEW IN TELEGRAM
5👍15❤6
Compact Strings – как Java экономит память на строках?В Java 9 появилась
Compact Strings, уменьшающая использование памяти на 30-40%.String хранила char[], занимающий 2 байта на символ.byte[], если все символы – ASCII.-XX:+CompactStrings // Включить (по умолчанию)
-XX:-CompactStrings // Выключить
#java #strings #memoryoptimization
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17❤1
finalize() устарел! Как правильно освобождать ресурсы?Метод
finalize() объявлен устаревшим в Java 9 и удалён в Java 18, так как он ненадёжный и медленный.try-with-resources для Closeable объектов:try (FileInputStream fis = new FileInputStream("file.txt")) {
// Работа с файлом
}AutoCloseable:class MyResource implements AutoCloseable {
@Override
public void close() {
System.out.println("Ресурс закрыт");
}
}AutoCloseable.#java #finalize #autocloseable
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12❤1
java.lang.Record vs Lombok @Value – что лучше?Многие используют Lombok для DTO, но с Java 14 появился
record. Стоит ли переходить?record лучше Lombok?toString(), equals(), hashCode().
// Java Record
public record User(String name, int age) {}
// Lombok
@Value
public class User {
String name;
int age;
}
record, если вам не нужен полный функционал Lombok – код будет чище.#java #record #lombok #bestpractices
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15❤1🤔1
JVM Warm-up – почему Java работает медленно при старте?JVM использует JIT-компилятор, но оптимизация занимает время. Это приводит к медленному запуску.
jaotc --output=app.aot MyApp.class
java -XX:AOTLibrary=app.aot MyApp
for (int i = 0; i < 10000; i++) {
someMethod(); // Прогреваем JIT-компилятор
}
#java #jvm #performance
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥2❤🔥1👏1🤯1
📌 Для чего нужен
StructuredTaskScope?StructuredTaskScopeFuture, CompletableFuture и ExecutorService.
import java.util.concurrent.*;
public class StructuredTaskScopeExample {
public static void main(String[] args) throws InterruptedException, ExecutionException {
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
// Запускаем две параллельные задачи
var task1 = scope.fork(() -> fetchDataFromAPI("API 1"));
var task2 = scope.fork(() -> fetchDataFromAPI("API 2"));
// Дожидаемся завершения (или отмены в случае ошибки)
scope.join();
scope.throwIfFailed(); // Выбросит исключение, если одна из задач завершилась с ошибкой
// Получаем результаты
String result1 = task1.get();
String result2 = task2.get();
System.out.println("Result 1: " + result1);
System.out.println("Result 2: " + result2);
}
}
private static String fetchDataFromAPI(String apiName) throws InterruptedException {
Thread.sleep(1000); // Имитация задержки запроса
if (Math.random() > 0.8) throw new RuntimeException(apiName + " failed!"); // Имитация ошибки
return apiName + " response";
}
}
#java #concurrency #structuredconcurrency
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14
В Java 17 появился ZGC – он обещает минимальную задержку. Но лучше ли он G1GC?
+------+----------+-----------+----------+
| GC | Паузы | Поддержка | CPU |
| | | хипа | нагрузка |
+------+----------+-----------+----------+
| G1GC | До 200ms | До 16ТБ | Средняя |
| ZGC | <10ms | До 16ТБ | Низкая |
+------+----------+-----------+----------+
-XX:+UseZGC
#java #gc #performance
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15
Модификатор
final может применяться к переменным, параметрам методов, полям и методам класса или самим классам.✔️ Класс не может иметь наследников;
✔️ Метод не может быть переопределен в классах наследниках;
✔️ Поле не может изменить свое значение после инициализации;
✔️ Параметры методов не могут изменять своё значение внутри метода;
✔️ Локальные переменные не могут быть изменены после присвоения им значения.
#java #final
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15❤2🔥1
Работа с JSON – частая задача, но Jackson, Gson и JSON-B работают по-разному. Какой выбрать?
• Jackson – самый быстрый (использует ByteBuffer).• Gson – медленнее, так как использует Reflection.• JSON-B – стандартный API, но проигрывает по производительности.
ObjectMapper objectMapper = new ObjectMapper();
// Объект → JSON (сериализация)
Person person = new Person("Alice", 30);
String json = objectMapper.writeValueAsString(person);
System.out.println("Jackson Serialized: " + json);
// JSON → Объект (десериализация)
Person deserialized = objectMapper.readValue(json, Person.class);
System.out.println("Jackson Deserialized: " + deserialized.name + ", " + deserialized.age);
Gson gson = new Gson();
// Объект → JSON (сериализация)
Person person = new Person("Bob", 25);
String json = gson.toJson(person);
System.out.println("Gson Serialized: " + json);
// JSON → Объект (десериализация)
Person deserialized = gson.fromJson(json, Person.class);
System.out.println("Gson Deserialized: " + deserialized.name + ", " + deserialized.age);
Jsonb jsonb = JsonbBuilder.create();
// Объект → JSON (сериализация)
Person person = new Person("Charlie", 35);
String json = jsonb.toJson(person);
System.out.println("JSON-B Serialized: " + json);
// JSON → Объект (десериализация)
Person deserialized = jsonb.fromJson(json, Person.class);
System.out.println("JSON-B Deserialized: " + deserialized.name + ", " + deserialized.age);
#java #json #jackson #performance
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12❤3🔥3🤔1
❇️Инлайн-классы (или value-классы) представляют собой ключевую часть проекта Valhalla, который значительно изменяет подход к организации данных в Java. Основная идея заключается в объединении производительности примитивов с гибкостью объектов, что позволяет создавать легковесные структуры данных без накладных расходов на размещение в куче.
1.
2.
3.
Пример использования инлайн-класса:
Рассмотрим класс Point,который представляет координаты на плоскости:
public primitive class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
Ключевое слово
1.
2.
3.
Пример работы с массивом:
Point[] points = new Point[100];
for (int i = 0; i < points.length; i++) {
points[i] = new Point(i, i * 2);
}
System.out.println(points[50].getX()); // 50
В данном случае массив points занимает меньше памяти и обрабатывается быстрее по сравнению с обычными объектами.
1.
2.
3.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥4❤1
Records, введенные в Java 14, предоставляют лаконичный способ создания неизменяемых классов данных. Sealed classes, появившиеся в Java 17, позволяют ограничивать наследование.
public sealed interface PaymentMethod permits CreditCard, BankTransfer, PayPal {
boolean isValid();
void process();
}
public record CreditCard(String cardNumber, String expiryDate, String cvv) implements PaymentMethod {
@Override
public boolean isValid() {
return cardNumber != null && cardNumber.length() == 16
&& expiryDate != null && cvv != null;
}
@Override
public void process() {
System.out.println("Processing credit card payment");
}
}
public record BankTransfer(String accountNumber, String bankCode) implements PaymentMethod {
@Override
public boolean isValid() {
return accountNumber != null && bankCode != null;
}
@Override
public void process() {
System.out.println("Processing bank transfer");
}
}
public record PayPal(String email) implements PaymentMethod {
@Override
public boolean isValid() {
return email != null && email.contains("@");
}
@Override
public void process() {
System.out.println("Processing PayPal payment");
}
}
public record Payment(UUID id, BigDecimal amount, PaymentMethod method) {
public boolean processPayment() {
if (method.isValid()) {
method.process();
return true;
}
return false;
}
}
1. Типобезопасность: Компилятор гарантирует, что только определенные классы могут реализовывать PaymentMethod.
2. Неизменяемость: Records обеспечивают неизменяемость данных.
3. Краткость кода: Records автоматически генерируют методы.
Пример использования:
public void handlePayment(Payment payment) {
if (payment.processPayment()) {
switch (payment.method()) {
case CreditCard cc -> handleCreditCardPayment(cc);
case BankTransfer bt -> handleBankTransferPayment(bt);
case PayPal pp -> handlePayPalPayment(pp);
}
} else {
handleFailedPayment(payment);
}
}
Этот подход особенно полезен для моделирования бизнес-доменов и реализации паттерна "Состояние".
Он позволяет создавать более безопасный и поддерживаемый код.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10❤🔥2