Java Ready | Программирование
9.11K subscribers
1.42K photos
77 videos
1 file
749 links
Авторский канал по разработке на Java.
Ресурсы, гайды, задачи, шпаргалки.
Информация ежедневно пополняется!

Cотрудничество: @energy_c
Download Telegram
Собираем сортировку задач по зависимостям!

Нужно получить порядок выполнения задач, где одна задача может зависеть от другой. Например, сначала build, потом test, а deploy только после test.

В этой задаче:
• описываем граф зависимостей
• считаем входящие связи
• кладём свободные задачи в очередь


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

👉 Java Ready | #задача
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4👍1🔥1
Почему Collections.unmodifiableList не делает настоящую копию?

В Java часто нужно отдать список наружу так, чтобы вызывающий код не мог его изменить. Например, из getter-метода, DTO, настроек или внутреннего состояния сервиса.

Для этого часто используют Collections.unmodifiableList.
List<String> roles = new ArrayList<>();
List<String> view = Collections.unmodifiableList(roles);


Через view действительно нельзя вызвать add или remove. Такой вызов закончится исключением.

Но важный нюанс в том, что unmodifiableList создаёт не копию, а представление поверх исходного списка.

Если изменить оригинальный список, изменения будут видны и через view.
roles.add("admin");
System.out.println(view);


На экране появится новое значение, хотя сам view вроде бы неизменяемый. Он просто запрещает менять список через себя, но не защищает от изменений оригинала.

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

Если нужна именно независимая копия, лучше использовать List.copyOf.
List<String> snapshot = List.copyOf(roles);


Теперь snapshot не связан с дальнейшими изменениями исходного списка. Это уже снимок состояния на момент создания.

Разница особенно заметна в классах с внутренним состоянием.
class User {
private final List<String> roles = new ArrayList<>();

List<String> roles() {
return List.copyOf(roles);
}
}


Так вызывающий код получает безопасный результат и не может случайно повлиять на объект изнутри.

Если элементы списка сами изменяемые, копия списка не делает глубокую копию элементов. Например, список объектов UserRole всё ещё будет содержать те же самые объекты.

Поэтому для настоящей неизменяемости важно думать не только о коллекции, но и о типах внутри неё. Для строк, чисел, enum и record-объектов такой подход обычно работает хорошо.

Плохой вариант выглядит так.
class User {
private final List<String> roles;

User(List<String> roles) {
this.roles = roles;
}
}


Если внешний код сохранит ссылку на исходный список, он сможет поменять состояние объекта уже после создания.

Безопаснее делать defensive copy прямо в конструкторе.
this.roles = List.copyOf(roles);


Тогда объект получает своё стабильное состояние. Даже если исходный список потом очистят или дополнят, поле внутри User не изменится.

👉 Java Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9🔥7👍5
Шпаргалка по устройству JVM!

Например, Heap хранит объекты и делится на young/old generation, а Stack содержит фреймы вызовов, локальные переменные и работает отдельно для каждого потока.

На картинке основные области памяти JVM: Heap, Stack, Metaspace, PC Register и Native Method Stack, а также краткая логика работы GC и сравнение популярных сборщиков мусора.

Сохрани, чтобы не потерять!

👉 Java Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12❤6🔥6
Как в Java чище проверять тип через pattern matching?

Раньше при проверке типа часто писали так:
if (value instanceof String) {
String text = (String) value;
System.out.println(text.length());
}


Код рабочий, но в нём есть лишнее приведение типа. Сначала Java уже проверила, что value это String, а потом мы всё равно руками делаем cast.

В современном Java можно записать короче:
if (value instanceof String text) {
System.out.println(text.length());
}


Переменная text доступна только там, где проверка точно прошла.

Это удобно для валидации:
if (input instanceof String text && !text.isBlank()) {
return text.trim();
}


И для обработки разных входных объектов:
if (event instanceof LoginEvent login) {
audit(login.userId());
}


При этом Java не даст использовать переменную вне безопасной области:
if (!(value instanceof String text)) {
return;
}

System.out.println(text.length());


Здесь text уже доступен после return, потому что дальше код дойдёт только если value действительно String.

Такой синтаксис особенно приятен в коде с Object, событиями, DTO, sealed-иерархиями и обработкой внешних данных.

👉 Java Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👍6❤5
Media is too big
VIEW IN TELEGRAM
Tutorialspoint Java Tutorial - большой справочник по Java!

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

Оставляю ссылочку на Tutorialspoint

👉 Java Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
❤13👍5🔥5
Хорошая статья про JWT-авторизацию на Spring Security!

Автор показывает, как собрать авторизацию через access tokens и связать Spring Security с регистрацией, логином, ролями и проверкой токена в защищённых запросах.

В статье автор показывает:
• как настроить регистрацию и вход пользователя
• как выпускать и проверять JWT-токен
• как подключить фильтр авторизации к SecurityFilterChain

Продолжай читать на Habr


👉 Java Ready | #статья
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9👍5🔥4
Собираем простой шаблонизатор строк на Java!

Нужно заменить плейсхолдеры вида {name} и {orderId} значениями из Map. Если значение отсутствует, оставим плейсхолдер как есть, чтобы ошибка была заметна в итоговом тексте.

В этой задаче:
• находим плейсхолдеры через Pattern
• достаём имя переменной из группы
• безопасно подставляем значение


Такой шаблонизатор полезен для писем, логов, уведомлений, CLI-сообщений и генерации простых текстов без подключения тяжёлого template engine.

👉 Java Ready | #задача
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤3🔥3
Разбираем CompletableFuture: 7 приёмов для асинхронного Java-кода!

CompletableFuture помогает строить цепочки асинхронных операций без ручного управления Thread. С ним удобно запускать фоновые задачи, преобразовывать результаты, объединять независимые запросы, обрабатывать ошибки и ограничивать время ожидания.

👉 Java Ready | #шпора
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11❤3👍3🤝2
Полезный разбор Java-приложений в Kubernetes!

Автор собирает практики, которые помогают запускать JVM-сервисы в контейнерах предсказуемо и без лишних проблем с ресурсами, healthcheck и завершением процесса.

В статье автор показывает:
• как учитывать память контейнера при настройке JVM
• зачем нужны readiness и liveness probes
• почему graceful shutdown важен для сервисов под нагрузкой

Продолжай читать на Habr


👉 Java Ready | #статья
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5👍3🔥2