💡 Java совет:
Начиная с Java 19, можно использовать *виртуальные потоки* - лёгкие потоки, которые управляются самой JVM, а не операционной системой.
Что это даёт:
- можно запускать тысячи и даже миллионы задач без нагрузки на ОС
- проще писать высоконагруженные приложения без сложной асинхронности
- более понятный и чистый код по сравнению с CompletableFuture и callback-подходами
Виртуальные потоки — главный шаг Java к масштабируемой конкурентности.
#Java #JavaDev
Начиная с Java 19, можно использовать *виртуальные потоки* - лёгкие потоки, которые управляются самой JVM, а не операционной системой.
Что это даёт:
- можно запускать тысячи и даже миллионы задач без нагрузки на ОС
- проще писать высоконагруженные приложения без сложной асинхронности
- более понятный и чистый код по сравнению с CompletableFuture и callback-подходами
Виртуальные потоки — главный шаг Java к масштабируемой конкурентности.
#Java #JavaDev
👍7❤6🔥6👎1
This media is not supported in your browser
VIEW IN TELEGRAM
🧠JAVA ИСПОЛЬЗУЙ TREESET ПРАВИЛЬНО #java
Если в Java нужно убрать дубликаты из списка и отсортировать элементы - используй TreeSet. Он автоматически удаляет повторяющиеся значения и сортирует их либо по естественному порядку, либо по кастомному правилу через Comparator.
Если в Java нужно убрать дубликаты из списка и отсортировать элементы - используй TreeSet. Он автоматически удаляет повторяющиеся значения и сортирует их либо по естественному порядку, либо по кастомному правилу через Comparator.
Естественный порядок
List<String> colors = Arrays.asList("red", "green", "red", "orange", "turquoise");
Set<String> colorsSet = new TreeSet<>(colors);
for (String color : colorsSet) {
System.out.println(color);
}
Сортировка по длине строки
Comparator<String> byLength = Comparator.comparingInt(String::length);
Set<String> sortedSet = new TreeSet<>(byLength);
sortedSet.addAll(colors);
for (String color : sortedSet) {
System.out.println(color);
}
👍8❤3👎3
💡 Java совет: рекурсивная обработка файлов с Files.walk()
Если нужно пройтись по всем файлам в директории и её подкаталогах, не пиши рекурсию вручную — используй
Пример: найти все `.java`-файлы в проекте
Почему это хороший подход:
- Рекурсивный обход «из коробки»
- Работает через Stream API
- Легко фильтровать, маппить и агрегировать
- Автоматически закрывает ресурсы (try-with-resources)
Полезно для:
- анализа исходников
- линтеров и кодогенерации
- поиска файлов по расширению
- утилит и dev-скриптов
#Java #IO
Если нужно пройтись по всем файлам в директории и её подкаталогах, не пиши рекурсию вручную — используй
Files.walk().Пример: найти все `.java`-файлы в проекте
Path startPath = Paths.get("src");
try (Stream<Path> paths = Files.walk(startPath)) {
paths
.filter(Files::isRegularFile)
.filter(path -> path.toString().endsWith(".java"))
.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
Почему это хороший подход:
- Рекурсивный обход «из коробки»
- Работает через Stream API
- Легко фильтровать, маппить и агрегировать
- Автоматически закрывает ресурсы (try-with-resources)
Полезно для:
- анализа исходников
- линтеров и кодогенерации
- поиска файлов по расширению
- утилит и dev-скриптов
#Java #IO
❤8👍7🔥2👎1
⚡ Spring Boot: как отключить лишнюю авто-конфигурацию
Иногда Spring Boot запускает больше, чем вам нужно.
Если у вас:
- кастомная конфигурация
- конфликт с дефолтными настройками
- ошибки при старте DataSource или JPA
— проблема может быть в auto-configuration.
Решение — отключить ненужные модули через
Пример:
Когда это полезно:
• вы используете свою конфигурацию базы
• приложение не работает с БД, но зависимости есть
• тестовые или lightweight-сервисы
• миграция старого проекта
Spring Boot умный.
Но иногда ему нужно сказать: “не делай это за меня”.
#SpringBoot #Java #Backend
Иногда Spring Boot запускает больше, чем вам нужно.
Если у вас:
- кастомная конфигурация
- конфликт с дефолтными настройками
- ошибки при старте DataSource или JPA
— проблема может быть в auto-configuration.
Решение — отключить ненужные модули через
@SpringBootApplication.Пример:
@SpringBootApplication(
exclude = {
DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class
}
)
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
Когда это полезно:
• вы используете свою конфигурацию базы
• приложение не работает с БД, но зависимости есть
• тестовые или lightweight-сервисы
• миграция старого проекта
Spring Boot умный.
Но иногда ему нужно сказать: “не делай это за меня”.
#SpringBoot #Java #Backend
❤8👍3🔥2
🚀 Spring Boot: не отдавайте JPA Entity напрямую в API - используйте DTO на границах
Если возвращать Entity из контроллера, вы жёстко связываете API с внутренней моделью базы. Любое изменение в persistence-слое может сломать внешний контракт.
DTO решает сразу несколько проблем:
• API становится независимым от слоя данных
• Избегаете ошибок LazyInitializationException
• Не утечёт лишняя информация (например, password, internalNote)
• Улучшается безопасность и контроль над тем, что видит клиент
Идея простая:
Entity - для базы
DTO - для API
Конвертируйте Entity → DTO в сервисе или через mapper (MapStruct / manual mapping).
Чистые границы = стабильный API и меньше багов.
#SpringBoot #Java #Backend #SoftwareEngineer
Если возвращать Entity из контроллера, вы жёстко связываете API с внутренней моделью базы. Любое изменение в persistence-слое может сломать внешний контракт.
DTO решает сразу несколько проблем:
• API становится независимым от слоя данных
• Избегаете ошибок LazyInitializationException
• Не утечёт лишняя информация (например, password, internalNote)
• Улучшается безопасность и контроль над тем, что видит клиент
Идея простая:
Entity - для базы
DTO - для API
Конвертируйте Entity → DTO в сервисе или через mapper (MapStruct / manual mapping).
Чистые границы = стабильный API и меньше багов.
#SpringBoot #Java #Backend #SoftwareEngineer
❤10👍5🥰2
⚠️ Spring Boot: не включайте publish-request-params в production
В Spring Boot есть настройка:
spring.mvc.publish-request-params=true
Она включает логирование параметров HTTP-запросов.
Это удобно в dev-среде, потому что можно видеть:
• request headers
• query parameters
• form data
Обычно это используют вместе с фильтром:
Но есть важная проблема.
В production такие логи могут случайно сохранить чувствительные данные пользователей.
Например:
Если включено логирование payload, такие данные могут попасть в:
• application logs
• log-агрегаторы
• мониторинг системы
А это уже серьёзная уязвимость безопасности.
Поэтому правило простое:
- включайте
- никогда не логируйте
- маскируйте чувствительные поля (`password`,
Маленькая настройка -
но может привести к утечке данных.
#SpringBoot #Java #Backend #Security
⚡️ Полезные ресурсы по Java 🚀 Max
@javatg
В Spring Boot есть настройка:
spring.mvc.publish-request-params=true
Она включает логирование параметров HTTP-запросов.
Это удобно в dev-среде, потому что можно видеть:
• request headers
• query parameters
• form data
Обычно это используют вместе с фильтром:
@Bean
public CommonsRequestLoggingFilter logFilter() {
CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter();
filter.setIncludeQueryString(true);
filter.setIncludeHeaders(true);
filter.setIncludePayload(true);
filter.setMaxPayloadLength(1000);
filter.setAfterMessagePrefix("COMPLETE REQUEST: ");
return filter;
}
Но есть важная проблема.
В production такие логи могут случайно сохранить чувствительные данные пользователей.
Например:
POST /login
{
"username": "john",
"password": "mypassword"
}
Если включено логирование payload, такие данные могут попасть в:
• application logs
• log-агрегаторы
• мониторинг системы
А это уже серьёзная уязвимость безопасности.
Поэтому правило простое:
- включайте
publish-request-params только в dev - никогда не логируйте
request body в production - маскируйте чувствительные поля (`password`,
token, `authorization`)Маленькая настройка -
но может привести к утечке данных.
#SpringBoot #Java #Backend #Security
⚡️ Полезные ресурсы по Java 🚀 Max
@javatg
❤7👍6🔥2
☕ Java Tip: рекурсивный обход файловой системы
В Java есть удобный способ рекурсивно обойти все файлы в директории - метод
Он возвращает Stream<Path>, что позволяет легко фильтровать и обрабатывать файлы через Stream API.
Пример - найти все
Что происходит:
• Files.walk(startPath) - рекурсивно проходит по всем папкам
• filter(Files::isRegularFile) - оставляет только файлы
• endsWith(".java") - фильтр по расширению
• forEach - обработка найденных файлов
Это намного чище, чем писать собственную рекурсивную функцию обхода директорий.
#Java #JavaDev #Programming
⚡️ Полезные ресурсы по Java 🚀 Max
@javatg
В Java есть удобный способ рекурсивно обойти все файлы в директории - метод
Files.walk().Он возвращает Stream<Path>, что позволяет легко фильтровать и обрабатывать файлы через Stream API.
Пример - найти все
.java файлы в папке src:
import java.io.IOException;
import java.nio.file.*;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
Path startPath = Paths.get("src");
try (Stream<Path> paths = Files.walk(startPath)) {
paths
.filter(Files::isRegularFile)
.filter(path -> path.toString().endsWith(".java"))
.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Что происходит:
• Files.walk(startPath) - рекурсивно проходит по всем папкам
• filter(Files::isRegularFile) - оставляет только файлы
• endsWith(".java") - фильтр по расширению
• forEach - обработка найденных файлов
Это намного чище, чем писать собственную рекурсивную функцию обхода директорий.
#Java #JavaDev #Programming
⚡️ Полезные ресурсы по Java 🚀 Max
@javatg
❤4👍2🔥2
☕ Java совет: сравнение времени без ловушек точности
Иногда при сравнении времени в Java проверки равенства могут неожиданно падать, потому что значения отличаются на миллисекунды или наносекунды.
Например:
Если сравнивать напрямую, они разные.
Но если вам важна точность до минуты, это можно легко исправить.
Используйте Instant.truncatedTo():
Метод truncatedTo() обрезает время до нужной точности:
• ChronoUnit.MINUTES
• ChronoUnit.HOURS
• ChronoUnit.DAYS
Это помогает избежать проблем, когда значения отличаются только в миллисекундах или наносекундах.
Полезно для:
• логов
• временных окон
• аналитики
• дедупликации событий
Маленький приём —
но часто спасает от неочевидных багов в time-логике.
#Java #JavaDev #Backend #Programming
⚡️ Полезные ресурсы по Java 🚀 Max
@java_library
Иногда при сравнении времени в Java проверки равенства могут неожиданно падать, потому что значения отличаются на миллисекунды или наносекунды.
Например:
Instant a = Instant.parse("2025-10-01T10:42:11Z");
Instant b = Instant.parse("2025-10-01T10:42:44Z");
Если сравнивать напрямую, они разные.
Но если вам важна точность до минуты, это можно легко исправить.
Используйте Instant.truncatedTo():
boolean sameMinute =
a.truncatedTo(ChronoUnit.MINUTES)
.equals(b.truncatedTo(ChronoUnit.MINUTES));
System.out.println(sameMinute); // true
Метод truncatedTo() обрезает время до нужной точности:
• ChronoUnit.MINUTES
• ChronoUnit.HOURS
• ChronoUnit.DAYS
Это помогает избежать проблем, когда значения отличаются только в миллисекундах или наносекундах.
Полезно для:
• логов
• временных окон
• аналитики
• дедупликации событий
Маленький приём —
но часто спасает от неочевидных багов в time-логике.
#Java #JavaDev #Backend #Programming
⚡️ Полезные ресурсы по Java 🚀 Max
@java_library
❤3👍3🔥1
Forwarded from Java
🚀 Java 26 стала умнее — особенно в pattern matching
Теперь работа с pattern matching выражениями стала заметно стабильнее и предсказуемее
Что улучшили:
🟢 Более надёжный type inference
компилятор лучше понимает типы в сложных условиях
🟢 Меньше edge-case ошибок
меньше неожиданных падений и предупреждений
🟢 Консистентное поведение
одинаковая логика в if и switch
Что это даёт на практике:
раньше при усложнении условий
компилятор мог “теряться”
теперь:
- анализ потока стал умнее
- переменные из pattern matching корректно распознаются
- код становится чище и безопаснее
Java становится всё ближе к современным языкам
с удобным и предсказуемым контролем типов
#Java #JavaDev
⚡️ Полезные ресурсы по Java 🚀 Max
@javatg
Теперь работа с pattern matching выражениями стала заметно стабильнее и предсказуемее
Что улучшили:
🟢 Более надёжный type inference
компилятор лучше понимает типы в сложных условиях
🟢 Меньше edge-case ошибок
меньше неожиданных падений и предупреждений
🟢 Консистентное поведение
одинаковая логика в if и switch
Что это даёт на практике:
раньше при усложнении условий
компилятор мог “теряться”
теперь:
- анализ потока стал умнее
- переменные из pattern matching корректно распознаются
- код становится чище и безопаснее
Java становится всё ближе к современным языкам
с удобным и предсказуемым контролем типов
#Java #JavaDev
⚡️ Полезные ресурсы по Java 🚀 Max
@javatg
❤5👍1🔥1
🚀 Java - regex без боли
Нашли интересную библиотеку - Sift. Она заменяет весь этот ад с регулярками на нормальный fluent API.
Теперь вместо нечитаемых строк вида:
^[0-9a-fA-F]{6}$
Пишешь код, который реально понимаешь:
.char('#')
.then()
.exactly(6)
.hexDigits()
📌 Что это дает:
- Читаемый и понятный код
- Меньше ошибок в regex
- Быстрее разработка и поддержка
По сути — это как “переводчик” с языка регулярных выражений на человеческий Java-код.
Если когда-нибудь ломал голову над regex -это прям must-have.
#Java #JavaDev
Нашли интересную библиотеку - Sift. Она заменяет весь этот ад с регулярками на нормальный fluent API.
Теперь вместо нечитаемых строк вида:
^[0-9a-fA-F]{6}$
Пишешь код, который реально понимаешь:
.char('#')
.then()
.exactly(6)
.hexDigits()
📌 Что это дает:
- Читаемый и понятный код
- Меньше ошибок в regex
- Быстрее разработка и поддержка
По сути — это как “переводчик” с языка регулярных выражений на человеческий Java-код.
Если когда-нибудь ломал голову над regex -это прям must-have.
#Java #JavaDev
❤7👍4