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

Автор: @energy_it

Реклама на бирже: https://telega.in/c/java_ready
Download Telegram
👩‍💻 Сегодня разбираем Deque — универсальная очередь с двух сторон!

С помощью этого ты можешь добавлять и убирать элементы слева и справа. Подходит и для очередей, и для стеков.

👉 Java Ready | #шпора
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥113👍3🤝2
This media is not supported in your browser
VIEW IN TELEGRAM
☕️ Scite — нейросеть для анализа научных статей и проверки источников!

Это AI-платформа, которая помогает не просто находить научные статьи, а оценивать их качество через анализ цитирований. Сервис показывает, как именно используется работа: поддерживают ли её другие исследования, опровергают или просто упоминаю. Scite также умеет искать релевантные публикации и показывать контекст цитирования внутри текста.

📌 Оставляю ссылочку: scite.ai

👉 Java Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
👍114🔥4
Знаете, что в Java switch можно использовать как выражение, а не только как отдельный блок кода?

Раньше для выбора значения часто писали так:
int timeout;

switch (env) {
case "dev":
timeout = 5;
break;
case "test":
timeout = 10;
break;
case "prod":
timeout = 30;
break;
default:
throw new IllegalArgumentException(env);
}

Работает, но кода много, и легко забыть break.

В современном Java можно записать это короче:
int timeout = switch (env) {
case "dev" -> 5;
case "test" -> 10;
case "prod" -> 30;
default -> throw new IllegalArgumentException(env);
};


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

Если логика в ветке сложнее, можно использовать yield:
int price = switch (type) {
case "vip" -> {
int discount = 20;
yield basePrice - discount;
}
default -> basePrice;
};


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

👉 Java Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
12👍6🔥4
Как устроена JVM под капотом?

Например, когда ты запускаешь Java-программу, JVM не просто “выполняет код”.

Сначала Class Loader загружает классы, проходит этапы Loading, Linking и Initialization.

Потом данные попадают в Runtime Data Area: туда входят Heap, Stack, Method Area, PC Register и Native Method Stack.

А уже Execution Engine выполняет байткод через интерпретатор и JIT-компилятор, а Garbage Collector следит за памятью и очищает неиспользуемые объекты.

Сохрани, чтобы быстрее разобраться в JVM!

👉 Java Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
18👍8🔥6
This media is not supported in your browser
VIEW IN TELEGRAM
💅 Awesome Java — большая база материалов для Java-разработчика!

В репозитории собраны лучшие библиотеки, фреймворки, инструменты, статьи и сервисы для разработки. Всё аккуратно разложено по категориям и собрано в одном месте, экономит огромное количество времени на поиске инструментов и материалов. Полезно тем, кто работает с backend на Java.

Оставляю ссылочку: GitHub 📱


👉 Java Ready | #репозиторий
Please open Telegram to view this post
VIEW IN TELEGRAM
👍143🔥2
Знаете, что для денег в Java лучше не использовать double?

На первый взгляд кажется, что цена это обычное число:
double price = 0.1;
double total = price + price + price;

System.out.println(total);


Но результат может удивить:
0.30000000000000004


Причина в том, что double хранит числа в бинарном формате, и многие десятичные дроби не представляются точно.

Для денег, налогов, скидок и балансов лучше использовать BigDecimal:
BigDecimal price = new BigDecimal("0.10");
BigDecimal total = price
.add(price)
.add(price);


Важно создавать BigDecimal из строки, а не из double:
new BigDecimal("0.10")


А вот так лучше не делать:
new BigDecimal(0.10)


При делении обязательно указывай округление:
amount.divide(count, 2, RoundingMode.HALF_UP);


Так код становится предсказуемым, а расчёты не ломаются из-за погрешностей.

👉 Java Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥53
Иерархия Java Collections Framework!

На картинке собрана структура коллекций Java: интерфейсы, абстрактные классы и основные реализации.

Например, List, Set, Queue и Deque идут от Collection, а Map стоит отдельно, потому что хранит данные в формате ключ-значение.

По схеме удобно увидеть, чем связаны ArrayList, LinkedList, HashSet, TreeSet, HashMap, LinkedHashMap, PriorityQueue и другие классы.

Такая картинка помогает быстрее понять, что выбирать под задачу: список, множество, очередь или map.

Сохрани, чтобы не путаться в коллекциях Java!

👉 Java Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
👍136🔥4
Проблема примитивной одержимости в Java!

Primitive Obsession - это ситуация, когда в коде слишком много важных бизнес-сущностей хранятся как обычные String, int, long или BigDecimal.

Например:
public void pay(BigDecimal amount, String currency, String email) {
// код
}


На первый взгляд всё нормально. Но со временем такой код становится опасным.

Потому что BigDecimal сам по себе не говорит, что это именно деньги. String не говорит, что это валюта. А email можно случайно передать туда, где ожидался userId.

Пример ошибки:
pay(
new BigDecimal("100.00"),
"user@mail.com",
"USD"
);


Код компилируется, но логика уже сломана: email и currency перепутаны местами.

В реальных системах такое часто происходит с id, email, phone, currency, amount, status, role, countryCode и другими значимыми полями.

Корректный подход, выносить важные значения в отдельные value object:
public record Email(String value) {
public Email {
if (value == null || value.isBlank()) {
throw new IllegalArgumentException("Email is blank");
}
}
}


Теперь метод становится понятнее:
public void pay(Money amount, CurrencyCode currency, Email email) {
// код
}


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

Например, деньги тоже можно оформить отдельным типом:
public record Money(BigDecimal amount) {
public Money {
if (amount == null || amount.signum() < 0) {
throw new IllegalArgumentException("Invalid amount");
}
}
}


Теперь отрицательная сумма не сможет незаметно пройти дальше по бизнес-логике.

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

👉 Java Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
11🔥4👍3
This media is not supported in your browser
VIEW IN TELEGRAM
✍️ Gizmo AI — нейросеть для обучения и запоминания информации!

AI-сервис, который помогает превращать заметки, PDF, статьи, видео и другие материалы в карточки для обучения и квизы. Нейросеть автоматически выделяет главное, генерирует вопросы и помогает быстрее запоминать информацию с помощью повторения и интерактивного формата обучения.

📌 Оставляю ссылочку: gizmo.ai

👉 Java Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥103👍2
Знаете, что в Java можно сделать неизменяемую копию коллекции?

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

Например:
List<Long> ids = new ArrayList<>();
ids.add(10L);
ids.add(20L);

process(ids);


Если внутри process() кто-то вызовет clear() или add(), исходный список тоже изменится.

Для таких случаев удобно использовать copyOf():
List<Long> safeIds = List.copyOf(ids);


Теперь safeIds нельзя изменить:
safeIds.add(30L); // UnsupportedOperationException


То же самое есть у Set и Map:
Set<Long> uniqueIds = Set.copyOf(ids);

Map<String, Integer> copy = Map.copyOf(stats);


Это полезно для DTO, настроек, прав доступа, списков ID, результатов из базы и любых данных, которые после создания не должны меняться.

Важно: copyOf() делает коллекцию неизменяемой, но если внутри лежат mutable-объекты, сами эти объекты всё ещё можно менять.
List<User> users = List.copyOf(originalUsers);


Здесь нельзя добавить нового User в список, но можно изменить поля существующего объекта, если сам User изменяемый.

👉 Java Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
9👍7🔥4
📂 Напоминалка по HTTP/2 и HTTP/3!

Например, HTTP/2 работает поверх TCP и мультиплексирует запросы через одно соединение, а HTTP/3 использует QUIC поверх UDP и избавляется от Head-of-Line Blocking между потоками.

На картинке — простое сравнение HTTP/2 и HTTP/3: как работают streams, почему TCP может тормозить все запросы сразу.

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

👉 Java Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥95👍4
Создание CSV-файла с данными!

CSV — самый простой формат хранения таблиц. Строки это записи, значения разделяются запятыми. Java позволяет создать такой файл без библиотек.

Готовим список строк, которые попадут в CSV:
var rows = java.util.List.of(
"name,age,city",
"Alice,22,Paris",
"Bob,30,Berlin"
);


Преобразуем строки в единый текст:
var csv = String.join("\n", rows);


Сохраняем CSV-файл в проект:
java.nio.file.Files.writeString(
java.nio.file.Path.of("users.csv"),
csv
);


🔥 В итоге получаем готовый файл users.csv, который можно открыть в Excel, Numbers или Google Sheets.

👉 Java Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
7👍2🔥2
😎 Хочешь понять, как Java-сервис поведёт себя под нагрузкой ещё до релиза? Тогда эта статья тебе точно пригодится!

В ней ты узнаешь:
• Как использовать Virtual Threads для запуска большого количества задач
• Как локально имитировать нагрузку на сервис
• Как смотреть, где приложение упирается в память, CPU или базу данных
• Как собирать простые метрики во время теста


Продолжай читать на Хабре!


👉 Java Ready | #статья
Please open Telegram to view this post
VIEW IN TELEGRAM
6🔥4👍3
📂 Шпаргалка по аннотациям Spring Boot!

Например, @RestController используется для создания REST API, @Autowired — для внедрения зависимостей, а @Transactional помогает управлять транзакциями.

На картинке — основные аннотации Spring Boot, Spring MVC, JPA, Security, Validation и тестирования, которые чаще всего используются в реальных проектах.

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

👉 Java Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
20👍11🔥6
Знаете, что в Java можно безопасно создать файл и не перезаписать старый?

Обычно при записи легко случайно затереть существующий файл:
Files.writeString(path, json);


Если файл уже есть, его содержимое будет заменено.

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

В таких случаях можно использовать
StandardOpenOption.CREATE_NEW:

Files.writeString(path, json, StandardOpenOption.CREATE_NEW);


Теперь Java создаст файл только если его ещё нет.

Если файл уже существует, будет выброшено исключение:
FileAlreadyExistsException


Это удобно, когда нужно защититься от случайной перезаписи важных данных.

Например, можно явно обработать ситуацию:
try {
Files.writeString(path, json, StandardOpenOption.CREATE_NEW);
} catch (FileAlreadyExistsException e) {
throw new IllegalStateException("Export already exists", e);
}


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

👉 Java Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
7👍5🔥2
📂 Иерархия исключений в Java!

На картинке собрана структура Java exceptions: от базового Throwable до Exception, RuntimeException, IOException, Error и популярных наследников.

Например, NullPointerException, IllegalArgumentException, IndexOutOfBoundsException и ClassCastException относятся к RuntimeException.

Это unchecked-исключения: Java не заставляет явно ловить их через try-catch или прописывать в throws.

Сохрани, чтобы не путаться в checked, unchecked и Error!

👉 Java Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
9👍4🔥4
Проблема неправильного использования Optional в Java!

Optional часто используют как “защиту от null”, но если применять его везде подряд, код может стать сложнее, а не безопаснее.

Например, плохая практика - хранить Optional в поле класса:

public class User {
private Optional<String> email;
}


На первый взгляд кажется удобно: email может быть, а может не быть.

Но Optional задумывался в первую очередь как возвращаемое значение метода, а не как тип поля.

Лучше хранить само значение:

public class User {
private String email;
}


А Optional возвращать из метода, где отсутствие результата является нормальным сценарием:

public Optional<String> getEmail() {
return Optional.ofNullable(email);
}


Ещё один частый антипример принимать Optional как параметр метода:

public void updateEmail(Optional<String> email) {
}


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

Обычно понятнее сделать перегрузку метода или принять обычное nullable-значение с явной проверкой:

public void updateEmail(String email) {
if (email == null || email.isBlank()) {
throw new IllegalArgumentException("Email is blank");
}

this.email = email;
}


Также опасно вызывать get() без проверки:

User user = findUser(id).get();


Если пользователя нет, код упадёт с NoSuchElementException.

Безопаснее обработать отсутствие явно:

User user = findUser(id)
.orElseThrow(() -> new UserNotFoundException(id));


Или задать fallback:

String name = user.getName()
.orElse("Guest");


Optional хорошо подходит там, где метод может ничего не найти:

public Optional<User> findUser(Long id) {
return userRepository.findById(id);
}


Но если значение обязательно по бизнес-логике, лучше не прятать ошибку в Optional, а валидировать данные раньше.

👉 Java Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
9👍5🔥4
This media is not supported in your browser
VIEW IN TELEGRAM
🤔 RavesliJava — обучение и основы Java для начинающих!

На сайте собран курс, который помогает освоить язык с нуля. Здесь разбираются основы синтаксиса, переменные, циклы, методы, массивы, ООП, классы и другие темы, необходимые для старта в Java-разработке. Материал подаётся последовательно и сопровождается примерами кода, благодаря чему обучение проходит проще и понятнее.

📌 Оставляю ссылочку: ravesli.com

👉 Java Ready | #сайт
Please open Telegram to view this post
VIEW IN TELEGRAM
👍84🔥2
Проблема “анемичных” запросов без валидации в Java!

В backend-коде часто создают DTO, которые просто переносят данные из API внутрь приложения.

Например:

public record CreateUserRequest(
String email,
String name
) {}


На первый взгляд всё нормально: есть email, есть имя.

Но если такой объект проходит дальше без проверки, в бизнес-логику могут попасть пустые строки, null, мусорные email и другие некорректные значения.

new CreateUserRequest("", " ");


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

Почему это опасно в реальных системах:
• ошибки появляются далеко от места ввода данных
• сервисы начинают дублировать одни и те же проверки
• в базе могут оказаться некорректные значения


Один из вариантов, это валидировать данные прямо на границе системы.

Например, через Bean Validation:

public record CreateUserRequest(
@Email String email,
@NotBlank String name
) {}


В Spring Boot такой объект можно проверить автоматически:

@PostMapping("/users")
public UserDto create(@Valid @RequestBody CreateUserRequest request) {
return userService.create(request);
}


Теперь некорректный запрос не пройдёт дальше контроллера.

Но важно помнить: API-валидация не заменяет доменную модель.

Если email важная часть бизнес-логики, лучше вынести его в отдельный value object:

public record Email(String value) {
public Email {
if (value == null || value.isBlank()) {
throw new IllegalArgumentException("Email is blank");
}
}
}


Тогда внутри приложения уже нельзя случайно создать пользователя с пустым email.

👉 Java Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
10🔥4👍2
This media is not supported in your browser
VIEW IN TELEGRAM
❤️ Java Learning Roadmap — структурированное изучение Java!

Этот репозиторий хорошо подойдёт тем, кто хочет изучать Java без поиска информации. Здесь собрано много полезного материала для обучения: книги, roadmap’ы, практика, полезные репозитории, YouTube-каналы и материалы для подготовки к собеседованиям. Всё удобно разложено по разделам.

Оставляю ссылочку: GitHub 📱


👉 Java Ready | #репозиторий
Please open Telegram to view this post
VIEW IN TELEGRAM
10🔥5👍2