This media is not supported in your browser
VIEW IN TELEGRAM
Подборка статей по Java, где разобраны ключевые темы: базовый синтаксис, ООП (классы, объекты, инкапсуляция), а также серверная часть — сервлеты и работа веб-приложений. Всё подано в формате шпаргалок с примерами кода и краткими пояснениями, чтобы быстро освежить фундамент или закрыть пробелы.
Оставляю ссылочку: virand.ru
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8❤6👍5
Знаете, что в Java можно не писать отдельный класс с полями, конструктором, геттерами и toString() вручную?
Например, для DTO часто создают обычный класс:
Но если объект нужен просто для хранения данных, можно использовать record:
Java сама создаст конструктор, методы доступа, equals(), hashCode() и toString().
Обращение к полям выглядит немного иначе:
record хорошо подходит для DTO, ответов API, событий, команд, настроек и небольших неизменяемых объектов.
Например, можно удобно вернуть данные из REST-контроллера:
Важно помнить: record по смыслу должен быть простым носителем данных. Если внутри начинает появляться много бизнес-логики, сложных состояний и изменяемых полей, лучше подумать об обычном классе.
Так код становится короче, понятнее и меньше засоряется шаблонными методами.
👉 Java Ready | #совет
Например, для DTO часто создают обычный класс:
public class UserDto {
private final Long id;
private final String name;
private final String email;
public UserDto(Long id, String name, String email) {
this.id = id;
this.name = name;
this.email = email;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
}Но если объект нужен просто для хранения данных, можно использовать record:
public record UserDto(
Long id,
String name,
String email
) {}
Java сама создаст конструктор, методы доступа, equals(), hashCode() и toString().
Обращение к полям выглядит немного иначе:
user.name()
user.email()
record хорошо подходит для DTO, ответов API, событий, команд, настроек и небольших неизменяемых объектов.
Например, можно удобно вернуть данные из REST-контроллера:
return new UserDto(1L, "Alex", "alex@mail.com");
Важно помнить: record по смыслу должен быть простым носителем данных. Если внутри начинает появляться много бизнес-логики, сложных состояний и изменяемых полей, лучше подумать об обычном классе.
Так код становится короче, понятнее и меньше засоряется шаблонными методами.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤3🔥3
В ней ты узнаешь:
• Как продумать структуру микросервиса
• Как разделить проект на слои
• Как описывать API понятнее
• Как работать с DTO и моделямиПродолжай читать на Habr!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤3🔥3
Знаете, что в Java лучше проверять строки через isBlank(), а не только через isEmpty()?
Но строка из пробелов для него уже не пустая:
А вот
Это удобно для валидации имён, логинов, комментариев, форм и любых пользовательских данных.
Так код становится надёжнее, потому что строка из пробелов больше не проходит как нормальное значение.
👉 Java Ready | #совет
isEmpty() проверяет только длину строки:"".isEmpty()
Но строка из пробелов для него уже не пустая:
" ".isEmpty()
А вот
isBlank() учитывает пробелы, табы и переносы строк:" ".isBlank()
Это удобно для валидации имён, логинов, комментариев, форм и любых пользовательских данных.
Так код становится надёжнее, потому что строка из пробелов больше не проходит как нормальное значение.
isBlank() это простой способ аккуратнее проверять текст в Java.Please open Telegram to view this post
VIEW IN TELEGRAM
❤10👍7🔥5
С помощью этого ты можешь добавлять и убирать элементы слева и справа. Подходит и для очередей, и для стеков.Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11❤3👍3🤝2
This media is not supported in your browser
VIEW IN TELEGRAM
Это AI-платформа, которая помогает не просто находить научные статьи, а оценивать их качество через анализ цитирований. Сервис показывает, как именно используется работа: поддерживают ли её другие исследования, опровергают или просто упоминаю. Scite также умеет искать релевантные публикации и показывать контекст цитирования внутри текста.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11❤4🔥4
Знаете, что в Java switch можно использовать как выражение, а не только как отдельный блок кода?
Раньше для выбора значения часто писали так:
Работает, но кода много, и легко забыть break.
В современном Java можно записать это короче:
Такой switch сразу возвращает значение, поэтому его удобно использовать для конфигов, статусов, ролей, типов платежей, уровней логирования и любых фиксированных сценариев.
Если логика в ветке сложнее, можно использовать yield:
Код получается компактнее, а Java помогает следить, чтобы результат действительно был получен.
👉 Java Ready | #совет
Раньше для выбора значения часто писали так:
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 помогает следить, чтобы результат действительно был получен.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤12👍6🔥4
Как устроена JVM под капотом?
Например, когда ты запускаешь Java-программу, JVM не просто “выполняет код”.
Сначала
Потом данные попадают в
А уже
Сохрани, чтобы быстрее разобраться в JVM!
👉 Java Ready | #ресурс
Например, когда ты запускаешь 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!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤18👍8🔥6
This media is not supported in your browser
VIEW IN TELEGRAM
В репозитории собраны лучшие библиотеки, фреймворки, инструменты, статьи и сервисы для разработки. Всё аккуратно разложено по категориям и собрано в одном месте, экономит огромное количество времени на поиске инструментов и материалов. Полезно тем, кто работает с backend на Java.
Оставляю ссылочку: GitHub📱
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14❤3🔥2
Знаете, что для денег в Java лучше не использовать double?
На первый взгляд кажется, что цена это обычное число:
Но результат может удивить:
Причина в том, что double хранит числа в бинарном формате, и многие десятичные дроби не представляются точно.
Для денег, налогов, скидок и балансов лучше использовать BigDecimal:
Важно создавать BigDecimal из строки, а не из double:
А вот так лучше не делать:
При делении обязательно указывай округление:
Так код становится предсказуемым, а расчёты не ломаются из-за погрешностей.
👉 Java Ready | #совет
На первый взгляд кажется, что цена это обычное число:
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);
Так код становится предсказуемым, а расчёты не ломаются из-за погрешностей.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥5❤3
Иерархия Java Collections Framework!
На картинке собрана структура коллекций Java: интерфейсы, абстрактные классы и основные реализации.
Например, List, Set, Queue и Deque идут от Collection, а Map стоит отдельно, потому что хранит данные в формате ключ-значение.
По схеме удобно увидеть, чем связаны ArrayList, LinkedList, HashSet, TreeSet, HashMap, LinkedHashMap, PriorityQueue и другие классы.
Такая картинка помогает быстрее понять, что выбирать под задачу: список, множество, очередь или map.
Сохрани, чтобы не путаться в коллекциях Java!
👉 Java Ready | #ресурс
На картинке собрана структура коллекций Java: интерфейсы, абстрактные классы и основные реализации.
Например, List, Set, Queue и Deque идут от Collection, а Map стоит отдельно, потому что хранит данные в формате ключ-значение.
По схеме удобно увидеть, чем связаны ArrayList, LinkedList, HashSet, TreeSet, HashMap, LinkedHashMap, PriorityQueue и другие классы.
Такая картинка помогает быстрее понять, что выбирать под задачу: список, множество, очередь или map.
Сохрани, чтобы не путаться в коллекциях Java!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13❤6🔥4
Проблема примитивной одержимости в Java!
Primitive Obsession - это ситуация, когда в коде слишком много важных бизнес-сущностей хранятся как обычные
Например:
На первый взгляд всё нормально. Но со временем такой код становится опасным.
Потому что BigDecimal сам по себе не говорит, что это именно деньги. String не говорит, что это валюта. А email можно случайно передать туда, где ожидался userId.
Пример ошибки:
Код компилируется, но логика уже сломана: email и currency перепутаны местами.
В реальных системах такое часто происходит с id, email, phone, currency, amount, status, role, countryCode и другими значимыми полями.
Корректный подход, выносить важные значения в отдельные value object:
Теперь метод становится понятнее:
Так сложнее случайно перепутать параметры, а валидация живёт рядом с самим значением.
Например, деньги тоже можно оформить отдельным типом:
Теперь отрицательная сумма не сможет незаметно пройти дальше по бизнес-логике.
Такой подход особенно полезен в доменной логике, платежах, заказах, авторизации, CRM, банковских системах и любых проектах, где ошибка в одном поле может стоить дорого.
👉 Java Ready | #практика
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, банковских системах и любых проектах, где ошибка в одном поле может стоить дорого.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤11🔥4👍3
This media is not supported in your browser
VIEW IN TELEGRAM
AI-сервис, который помогает превращать заметки, PDF, статьи, видео и другие материалы в карточки для обучения и квизы. Нейросеть автоматически выделяет главное, генерирует вопросы и помогает быстрее запоминать информацию с помощью повторения и интерактивного формата обучения.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10❤3👍2
Знаете, что в Java можно сделать неизменяемую копию коллекции?
Иногда нужно передать список дальше по коду, но не хочется, чтобы его случайно изменили.
Например:
Если внутри process() кто-то вызовет clear() или add(), исходный список тоже изменится.
Для таких случаев удобно использовать copyOf():
Теперь safeIds нельзя изменить:
То же самое есть у Set и Map:
Это полезно для DTO, настроек, прав доступа, списков ID, результатов из базы и любых данных, которые после создания не должны меняться.
Важно: copyOf() делает коллекцию неизменяемой, но если внутри лежат mutable-объекты, сами эти объекты всё ещё можно менять.
Здесь нельзя добавить нового User в список, но можно изменить поля существующего объекта, если сам User изменяемый.
👉 Java Ready | #совет
Иногда нужно передать список дальше по коду, но не хочется, чтобы его случайно изменили.
Например:
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 изменяемый.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10👍7🔥4
Например, HTTP/2 работает поверх TCP и мультиплексирует запросы через одно соединение, а HTTP/3 использует QUIC поверх UDP и избавляется от Head-of-Line Blocking между потоками.
На картинке — простое сравнение HTTP/2 и HTTP/3: как работают streams, почему TCP может тормозить все запросы сразу.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9❤5👍4