🧠
Оба способа хороши для конфигурации, но используют их по-разному. И если ты всё ещё везде пихаешь
📌
✅ Хорошо для единичных значений
❌ Плохо для сложных структур, списков, валидации
❌ Трудно покрыть тестами (без
❌ Нет биндинга по префиксу → нет группировки
📌
💡 Используй с
✅ Удобно группировать и документировать
✅ Работает с вложенными структурами, коллекциями
✅ Поддерживает JSR-303 валидацию (
✅ Легче мокать в тестах
✅ Интеграция с Spring Boot Actuator (
⚠️ Не смешивай: не нужно тянуть
Если конфигурация простая —
📲 Мы в MAX
👉@BookJava
@Value vs @ConfigurationProperties — не выбирай наобумОба способа хороши для конфигурации, но используют их по-разному. И если ты всё ещё везде пихаешь
@Value, держи краткий гайд, когда лучше что:📌
@Value — просто, но не гибко:
@Value("${my.prop}")
private String value;
✅ Хорошо для единичных значений
❌ Плохо для сложных структур, списков, валидации
❌ Трудно покрыть тестами (без
TestPropertySource)❌ Нет биндинга по префиксу → нет группировки
📌
@ConfigurationProperties — сила и масштаб:
@ConfigurationProperties(prefix = "app.feature")
public class FeatureProperties {
private boolean enabled;
private List<String> items;
}
💡 Используй с
@EnableConfigurationProperties или аннотируй как @Component✅ Удобно группировать и документировать
✅ Работает с вложенными структурами, коллекциями
✅ Поддерживает JSR-303 валидацию (
@Validated)✅ Легче мокать в тестах
✅ Интеграция с Spring Boot Actuator (
/actuator/configprops)⚠️ Не смешивай: не нужно тянуть
@Value внутрь @ConfigurationProperties — это антипаттерн.Если конфигурация простая —
@Value норм. Но как только появляется структура, коллекции, логика — всегда используй @ConfigurationProperties.📲 Мы в MAX
👉@BookJava
👍5🔥2
Double-brace инициализация в Java — это идиома, которая используется для инициализации коллекций (и иногда других объектов) в краткой форме. Она выглядит как две открывающие фигурные скобки подряд
Как это работает:
Double-brace инициализация — это комбинация двух конструкций:
1. Анонимный внутренний класс:
Создаётся новый безымянный подкласс
2. Инициализатор экземпляра:
Это блок, который выполняется при создании объекта. В него можно вставлять вызовы методов (например,
Преимущества:
* Компактный и удобочитаемый синтаксис для заполнения коллекций.
* Можно использовать в полях
Недостатки:
1. Создаётся лишний анонимный класс — это увеличивает количество байткода и может мешать сериализации.
2. Утечки памяти — если такой класс находится внутри внешнего класса, он может неявно хранить ссылку на него.
3. Читаемость — не все разработчики знают, как это работает, и это может сбивать с толку.
4. Нарушение принципов OOP — логика инициализации размещается в конструкторе, который не явно виден.
Альтернативы:
Java 8+ (через
Статический метод инициализации:
Java 9+ (immutable):
Вывод:
Double-brace инициализация — это удобный, но потенциально опасный трюк, который не рекомендуется использовать в продакшене. Лучше предпочесть более читаемые и безопасные альтернативы, особенно с учётом новых возможностей Java 8+.
📲 Мы в MAX
👉@BookJava
{{ и имеет специфическое поведение. Пример:
import java.util.*;
List<String> list = new ArrayList<String>() {{
add("one");
add("two");
add("three");
}};
Как это работает:
Double-brace инициализация — это комбинация двух конструкций:
1. Анонимный внутренний класс:
new ArrayList<String>() { ... }
Создаётся новый безымянный подкласс
ArrayList.2. Инициализатор экземпляра:
{{ ... }}
Это блок, который выполняется при создании объекта. В него можно вставлять вызовы методов (например,
add()).Преимущества:
* Компактный и удобочитаемый синтаксис для заполнения коллекций.
* Можно использовать в полях
final, например:
private static final Set<String> set = new HashSet<>() {{
add("A");
add("B");
}};
Недостатки:
1. Создаётся лишний анонимный класс — это увеличивает количество байткода и может мешать сериализации.
2. Утечки памяти — если такой класс находится внутри внешнего класса, он может неявно хранить ссылку на него.
3. Читаемость — не все разработчики знают, как это работает, и это может сбивать с толку.
4. Нарушение принципов OOP — логика инициализации размещается в конструкторе, который не явно виден.
Альтернативы:
Java 8+ (через
Stream и Collectors):
List<String> list = Stream.of("one", "two", "three")
.collect(Collectors.toList());
Статический метод инициализации:
public static List<String> createList() {
List<String> list = new ArrayList<>();
list.add("one");
list.add("two");
return list;
}
Java 9+ (immutable):
List<String> list = List.of("one", "two", "three");
Set<String> set = Set.of("A", "B");
Вывод:
Double-brace инициализация — это удобный, но потенциально опасный трюк, который не рекомендуется использовать в продакшене. Лучше предпочесть более читаемые и безопасные альтернативы, особенно с учётом новых возможностей Java 8+.
📲 Мы в MAX
👉@BookJava
👍3❤1
📌 picocli — это современная библиотека для создания CLI-приложений на Java. Она упрощает разработку командных интерфейсов, обеспечивая:
* Автоматическую генерацию
* Поддержку подкоманд (как в
* Аргументы, параметры, опции с короткими и длинными флагами (
* Интеграцию с GraalVM (подходит для нативной компиляции)
* Поддержку аннотаций (аннотируй POJO — и готово!)
* Автоматическую валидацию аргументов
* Цветной вывод и гибкое форматирование
* Интерактивный режим и автодополнение
Проект активно развивается, полностью документирован и используется в сотнях продакшн-проектов. Если ты ищешь мощную и простую в использовании CLI-библиотеку на Java — picocli отличный выбор.
https://github.com/remkop/picocli
📲 Мы в MAX
👉@BookJava
* Автоматическую генерацию
--help и --version* Поддержку подкоманд (как в
git commit, git push)* Аргументы, параметры, опции с короткими и длинными флагами (
-v, --verbose)* Интеграцию с GraalVM (подходит для нативной компиляции)
* Поддержку аннотаций (аннотируй POJO — и готово!)
* Автоматическую валидацию аргументов
* Цветной вывод и гибкое форматирование
* Интерактивный режим и автодополнение
Проект активно развивается, полностью документирован и используется в сотнях продакшн-проектов. Если ты ищешь мощную и простую в использовании CLI-библиотеку на Java — picocli отличный выбор.
https://github.com/remkop/picocli
📲 Мы в MAX
👉@BookJava
👍5❤1🔥1
Что такое механизм try-with-resources?
Механизм
📌 Поддерживается с Java 7
📌 Ресурсы должны реализовывать интерфейс
💡 Пример:
🧠 Почему это важно:
* Уменьшает boilerplate-код
* Исключает утечки ресурсов
* Упрощает обработку исключений
⚠️ Совет:
С Java 9 можно использовать уже объявленные переменные, если они final или effectively final:
📲 Мы в MAX
👉@BookJava
Механизм
try-with-resources в Java — это конструкция, которая упрощает работу с ресурсами, требующими закрытия (например, файлы, сокеты, соединения с БД и т.д.). Он автоматически закрывает ресурсы после завершения блока try, избавляя от необходимости писать finally вручную.📌 Поддерживается с Java 7
📌 Ресурсы должны реализовывать интерфейс
AutoCloseable💡 Пример:
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
String line = reader.readLine();
System.out.println(line);
} catch (IOException e) {
e.printStackTrace();
}
// reader будет закрыт автоматически, даже если произойдёт исключение
🧠 Почему это важно:
* Уменьшает boilerplate-код
* Исключает утечки ресурсов
* Упрощает обработку исключений
⚠️ Совет:
С Java 9 можно использовать уже объявленные переменные, если они final или effectively final:
BufferedReader reader = new BufferedReader(new FileReader("file.txt"));
try (reader) {
System.out.println(reader.readLine());
}
📲 Мы в MAX
👉@BookJava
👍4
🧠 Ленивая инициализация через
Когда нужно отложить создание тяжёлого объекта до первого обращения, многие вспоминают double-checked locking:
⚠️ Многословно, хрупко, легко ошибиться. Есть лучше.
📌 Современный подход — использовать
💡
Плюсы:
— Читается за секунду
— Потокобезопасно
— Нет дублирования кода
— Легко тестировать и заменять
🔁 Альтернатива в чистой Java: использовать
Если используешь Spring — можно просто обернуть бин в
📲 Мы в MAX
👉@BookJava
Supplier — элегантная альтернатива double-checked lockingКогда нужно отложить создание тяжёлого объекта до первого обращения, многие вспоминают double-checked locking:
private volatile SomeHeavyObject obj;
public SomeHeavyObject getObj() {
if (obj == null) {
synchronized (this) {
if (obj == null) {
obj = new SomeHeavyObject();
}
}
}
return obj;
}
⚠️ Многословно, хрупко, легко ошибиться. Есть лучше.
📌 Современный подход — использовать
Supplier с ленивой инициализацией:
private final Supplier<SomeHeavyObject> lazyObj = Suppliers.memoize(SomeHeavyObject::new);
public SomeHeavyObject getObj() {
return lazyObj.get();
}
💡
Suppliers.memoize — из Guava. Он гарантирует потокобезопасную инициализацию один раз при первом вызове get().Плюсы:
— Читается за секунду
— Потокобезопасно
— Нет дублирования кода
— Легко тестировать и заменять
🔁 Альтернатива в чистой Java: использовать
AtomicReference и updateAndGet, но это уже длиннее и менее выразительно.Если используешь Spring — можно просто обернуть бин в
@Lazy. Но вне Spring, в обычных Java-приложениях или утилитах — Supplier с memoize() идеален.📲 Мы в MAX
👉@BookJava
👍2🔥2
Три похожих слова в Java —
🔒
Ключевое слово. Используется для ограничений:
*
*
*
📌 Особенно важно для immutability и thread-safety.
🧯
Блок в конструкции
💡 Используется для освобождения ресурсов: закрытия потоков, соединений и т.д.
⚰️
Метод из
⚠️ УСТАРЕЛ с Java 9, удалён в Java 18. Не используй.
🔪 Непредсказуем, плохо работает, тормозит GC. Вместо него —
🧠 Важно не путать:
*
*
*
📲 Мы в MAX
👉@BookJava
final, finally, finalize — но смысл у них совершенно разный. Разберёмся 🧠🔒
finalКлючевое слово. Используется для ограничений:
*
final class — нельзя наследовать.*
final method — нельзя переопределить.*
final variable — нельзя изменить значение (один раз присвоил — всё).📌 Особенно важно для immutability и thread-safety.
final int x = 10;
x = 20; // ошибка компиляции
🧯
finallyБлок в конструкции
try-catch-finally. Выполняется всегда, даже если был return или exception.💡 Используется для освобождения ресурсов: закрытия потоков, соединений и т.д.
try {
// что-то может выбросить исключение
} catch (Exception e) {
// обработка ошибки
} finally {
// всегда выполнится
}
⚰️
finalize()Метод из
Object, вызывался перед удалением объекта сборщиком мусора.⚠️ УСТАРЕЛ с Java 9, удалён в Java 18. Не используй.
🔪 Непредсказуем, плохо работает, тормозит GC. Вместо него —
AutoCloseable и try-with-resources.
@Override
protected void finalize() throws Throwable {
System.out.println("До свидания...");
}
🧠 Важно не путать:
*
final — про нельзя менять*
finally — про всегда выполнится*
finalize — про устаревший и бесполезный метод📲 Мы в MAX
👉@BookJava
❤4🔥2👍1
🧠 Dependency Inversion Principle (D в SOLID)
Зависимости должны идти от высокоуровневой политики к низкоуровневым деталям, а не наоборот. Абстракции — хозяева, реализации — обслуживающий персонал.
📌 Коротко о сути
* Модули верхнего уровня (бизнес-логика) зависят только от интерфейсов/абстракций.
* Модули нижнего уровня (база, сеть, файлы) также зависят от тех же абстракций.
* Сами абстракции не знают ничего о деталях, тем самым разрывая «бетонную» сцепку между слоями.
💡 Мини-пример (Java 17+, Spring Boot 3+)
BillingService может жить в модульном jar без spring-email-starter и SMTP-кода — протестировать его теперь элементарно.
⚠️ Где рождаются проблемы
1. Путаница DI container ≠ DIP
IoC/DI-фреймворк (Spring, CDI) — лишь удобный способ «сращивать» зависимости, но принцип работает и без контейнера (чистый constructor injection).
2. Абстракции ради галочки
Интерфейс OneImplService с единственной реализацией ломает читаемость, тесты и автоконфиг 📉.
➜ Создавай абстракцию, когда реально нужны сменяемость, тестируемость или расширяемость.
3. Утечки деталей
Если интерфейс таскает DTO из слоя хранения, ты всё ещё «протёк» к базе. Держи контракты чистыми.
4. Слепая вера в фреймворк
Жизненный цикл бинов, прокси, lazy-init — магия мешает понимать, кто кем владеет.
➜ Всегда можешь собрать объект вручную в юнит-тесте. Если сложно — запах нарушения DIP.
5. Слишком много уровней абстракций
«Контроллер → сервис → менеджер → порт → адаптер → репозиторий» превращает код в матрёшку. Дизайн важнее количества слоёв.
📝 Практические советы
* Используй constructor injection по умолчанию. Поле
* Группируй интерфейсы по use-case, а не по технологии (например,
* В тестах не мокай фреймворк — мокай контракт.
* Для одноразовых реализаций начни с
* Проверка себя: можно ли запустить модуль верхнего уровня без нижнего? Если да — DIP соблюдён.
💬 Итог
DIP — это не про «везде интерфейсы» и не про «подключи Spring». Это про правильное направление зависимостей, которое делает код гибким, тестируемым и не заложником технологий. А проблемы возникают, когда путают инструмент с принципом и забывают, что абстракция должна прятать детали, а не выпячивать их.
📲 Мы в MAX
👉@BookJava
Зависимости должны идти от высокоуровневой политики к низкоуровневым деталям, а не наоборот. Абстракции — хозяева, реализации — обслуживающий персонал.
📌 Коротко о сути
* Модули верхнего уровня (бизнес-логика) зависят только от интерфейсов/абстракций.
* Модули нижнего уровня (база, сеть, файлы) также зависят от тех же абстракций.
* Сами абстракции не знают ничего о деталях, тем самым разрывая «бетонную» сцепку между слоями.
💡 Мини-пример (Java 17+, Spring Boot 3+)
// 1️⃣ Абстракция — контракт
public interface NotificationSender {
void send(Message msg);
}
// 2️⃣ Верхний уровень — бизнес-служба
@Service
public class BillingService {
private final NotificationSender sender;
public BillingService(NotificationSender sender) {
this.sender = sender; // зависим от контракта
}
public void bill(Client c) {
// ...
sender.send(new Message("Invoice #42"));
}
}
// 3️⃣ Низкий уровень — деталь
@Component
public class EmailSender implements NotificationSender {
public void send(Message msg) {
// SMTP-магия
}
}
BillingService может жить в модульном jar без spring-email-starter и SMTP-кода — протестировать его теперь элементарно.
⚠️ Где рождаются проблемы
1. Путаница DI container ≠ DIP
IoC/DI-фреймворк (Spring, CDI) — лишь удобный способ «сращивать» зависимости, но принцип работает и без контейнера (чистый constructor injection).
2. Абстракции ради галочки
Интерфейс OneImplService с единственной реализацией ломает читаемость, тесты и автоконфиг 📉.
➜ Создавай абстракцию, когда реально нужны сменяемость, тестируемость или расширяемость.
3. Утечки деталей
Если интерфейс таскает DTO из слоя хранения, ты всё ещё «протёк» к базе. Держи контракты чистыми.
4. Слепая вера в фреймворк
Жизненный цикл бинов, прокси, lazy-init — магия мешает понимать, кто кем владеет.
➜ Всегда можешь собрать объект вручную в юнит-тесте. Если сложно — запах нарушения DIP.
5. Слишком много уровней абстракций
«Контроллер → сервис → менеджер → порт → адаптер → репозиторий» превращает код в матрёшку. Дизайн важнее количества слоёв.
📝 Практические советы
* Используй constructor injection по умолчанию. Поле
final = явная зависимость.* Группируй интерфейсы по use-case, а не по технологии (например,
TransferPort, а не JdbcTransferRepository).* В тестах не мокай фреймворк — мокай контракт.
* Для одноразовых реализаций начни с
class. Если появится второй вариант — быстро вынесешь интерфейс (IDE поможет).* Проверка себя: можно ли запустить модуль верхнего уровня без нижнего? Если да — DIP соблюдён.
💬 Итог
DIP — это не про «везде интерфейсы» и не про «подключи Spring». Это про правильное направление зависимостей, которое делает код гибким, тестируемым и не заложником технологий. А проблемы возникают, когда путают инструмент с принципом и забывают, что абстракция должна прятать детали, а не выпячивать их.
📲 Мы в MAX
👉@BookJava
👍4❤2🔥1
📌 Stream API: забудьте про peek()
Метод
⚠️ Почему не стоит полагаться на peek()?
*
* Поведение зависит от терминальной операции: например, при некоторых оптимизациях JDK (особенно в параллельных стримах) вызов
💡 Пример опасного кода:
🧠 Лучший подход: используйте
✅ Правильная замена:
Если нужно выполнить действие над каждым элементом, используйте явный и безопасный подход:
Или вообще вынесите логику за пределы стрима.
🧹 Держите код понятным и безопасным — забудьте про
📲 Мы в MAX
👉@BookJava
Метод
peek() в Java Stream API выглядит удобным для отладки, но его использование в реальном коде часто приводит к проблемам.⚠️ Почему не стоит полагаться на peek()?
*
peek() — промежуточная операция, которая не гарантирует вызов функции для каждого элемента стрима.* Поведение зависит от терминальной операции: например, при некоторых оптимизациях JDK (особенно в параллельных стримах) вызов
peek() может быть пропущен или работать непредсказуемо.💡 Пример опасного кода:
List<String> names = Stream.of("Java", "Spring", "Hibernate")
.peek(System.out::println) // 👈 анти-паттерн!
.collect(Collectors.toList());
🧠 Лучший подход: используйте
peek() исключительно для дебага, но никогда — для изменения состояния или важных операций.✅ Правильная замена:
Если нужно выполнить действие над каждым элементом, используйте явный и безопасный подход:
List<String> names = Stream.of("Java", "Spring", "Hibernate")
.map(name -> {
log.info("Processing: {}", name); // или другая логика
return name;
})
.collect(Collectors.toList());
Или вообще вынесите логику за пределы стрима.
🧹 Держите код понятным и безопасным — забудьте про
peek().📲 Мы в MAX
👉@BookJava
🔥3👍1👎1
📌 Обход коллекций в Java: делаем правильно!
Часто вижу, как разработчики по привычке используют старый подход с циклом
🧠 1. Foreach (Java 5+)
Коротко, ясно, подходит для большинства задач:
🧠 2. Метод forEach (Java 8+)
Отлично подходит для функционального стиля:
⚠️ Важно: нельзя модифицировать саму коллекцию во время такого обхода!
🧠 3. Stream API (Java 8+)
Идеален для сложной обработки с фильтрацией, маппингом и т.д.:
💡 Что выбрать?
* Простой перебор? Используй цикл foreach.
* Нужно быстро и функционально?
* Сложные манипуляции? Только Stream API.
📌 Используйте современные подходы, это читаемость и удобство поддержки вашего кода!
📲 Мы в MAX
👉@BookJava
Часто вижу, как разработчики по привычке используют старый подход с циклом
for. Сегодня напомню оптимальные способы перебора коллекций в Java.🧠 1. Foreach (Java 5+)
Коротко, ясно, подходит для большинства задач:
for (String item : collection) {
// обработка элемента
}
🧠 2. Метод forEach (Java 8+)
Отлично подходит для функционального стиля:
collection.forEach(item -> {
// обработка элемента
});
⚠️ Важно: нельзя модифицировать саму коллекцию во время такого обхода!
🧠 3. Stream API (Java 8+)
Идеален для сложной обработки с фильтрацией, маппингом и т.д.:
collection.stream()
.filter(Objects::nonNull)
.map(String::toUpperCase)
.forEach(System.out::println);
💡 Что выбрать?
* Простой перебор? Используй цикл foreach.
* Нужно быстро и функционально?
collection.forEach().* Сложные манипуляции? Только Stream API.
📌 Используйте современные подходы, это читаемость и удобство поддержки вашего кода!
📲 Мы в MAX
👉@BookJava
👍3
🚀 Подборка полезных IT каналов в Max
Системное администрирование, DevOps 📌
https://max.ru/i_odmin Все для системного администратора
https://max.ru/bash_srv Bash Советы
https://max.ru/sysadminof Книги для админов, полезные материалы
https://max.ru/i_odmin_book Библиотека Системного Администратора
https://max.ru/i_devops DevOps: Пишем о Docker, Kubernetes и др.
https://max.ru/tipsysdmin Типичный Сисадмин
https://max.ru/channel_win_sysadmin Системный Администратор Windows
https://max.ru/channel_linux_admin Linux: Системный администратор
https://max.ru/channel_linuxmod Linux
https://max.ru/channel_i_linux Системный администратор
https://max.ru/channel_devopslib DevOps, SRE, Sysadmin
https://max.ru/channel_devops_star DevOps Star (Звезда Девопса)
Excel лайфхак 📌
https://t.me/Excel_lifehack Excel лайфхак
Английский с нуля 🇬🇧
https://max.ru/UchuEnglish
1C разработка 📌
https://max.ru/odin1c_rus Cтатьи, курсы, советы, шаблоны кода 1С
https://max.ru/channel_DevLab1C 1С:Предприятие 8
Программирование C++📌
https://max.ru/cpp_lib Библиотека C/C++ разработчика
https://max.ru/channel_cpp_geek C++ geek
Программирование Go📌
https://max.ru/golang_lib Библиотека Go (Golang) разработчика
Программирование React📌
https://max.ru/react_lib React
Программирование Rust📌
https://max.ru/channel_rust_lib
Программирование Python 📌
https://max.ru/python_of Python академия.
https://max.ru/BookPython Библиотека Python разработчика
Java разработка 📌
https://max.ru/bookjava Библиотека Java разработчика
https://max.ru/channel_java_geek Java Geek
GitHub Сообщество 📌
https://max.ru/githublib Интересное из GitHub
Базы данных (Data Base) 📌
https://max.ru/database_info Все про базы данных
Фронтенд разработка 📌
https://max.ru/frontend_1 Подборки для frontend разработчиков
Библиотеки 📌
https://max.ru/programmist_of Книги по программированию
https://max.ru/proglb Библиотека программиста
https://max.ru/bfbook Книги для программистов
Программирование 📌
https://max.ru/bookflow Лекции, видеоуроки, доклады с IT конференций
https://max.ru/itmozg Программисты, дизайнеры, новости из мира IT
https://max.ru/php_lib Библиотека PHP программиста 👨🏼💻👩💻
Шутки программистов 📌
https://max.ru/itumor Шутки программистов
Защита, взлом, безопасность 📌
https://max.ru/thehaking Канал о кибербезопасности
https://max.ru/xakkep_1 Хакер Free
Книги, статьи для дизайнеров 📌
https://max.ru/odesigners Статьи, книги для дизайнеров
Математика 📌
https://max.ru/Pomatematike Канал по математике
https://max.ru/phismat_1 Обучающие видео, книги по Физике и Математике
Вакансии в IT📌
https://max.ru/progjob
https://max.ru/channel_rabotait
Мир технологий 📌
https://max.ru/mir_teh Канал для любознательных
Городские📌
https://max.ru/piterspb_78 Свежие новости Санкт-Петербурга
https://max.ru/mockva_life Свежие новости Москвы
https://max.ru/piterspb Питер Новости: Санкт-Петербург / СПБ / ДТП
https://max.ru/channel_krasnodar_novosty Краснодар Новости
https://max.ru/channel_novosibirsk_novosti Новосибирск
https://max.ru/channel_samara_novosti Новости Самары
https://max.ru/channel_ekaterinburg_novosti Новости Екатеринбурга
https://max.ru/channel_kazan_novosti Новости Казани
https://max.ru/channel_omsk_novosti Новости Омска
https://max.ru/channel_moskva_24 Москва 24
Системное администрирование, DevOps 📌
https://max.ru/i_odmin Все для системного администратора
https://max.ru/bash_srv Bash Советы
https://max.ru/sysadminof Книги для админов, полезные материалы
https://max.ru/i_odmin_book Библиотека Системного Администратора
https://max.ru/i_devops DevOps: Пишем о Docker, Kubernetes и др.
https://max.ru/tipsysdmin Типичный Сисадмин
https://max.ru/channel_win_sysadmin Системный Администратор Windows
https://max.ru/channel_linux_admin Linux: Системный администратор
https://max.ru/channel_linuxmod Linux
https://max.ru/channel_i_linux Системный администратор
https://max.ru/channel_devopslib DevOps, SRE, Sysadmin
https://max.ru/channel_devops_star DevOps Star (Звезда Девопса)
Excel лайфхак 📌
https://t.me/Excel_lifehack Excel лайфхак
Английский с нуля 🇬🇧
https://max.ru/UchuEnglish
1C разработка 📌
https://max.ru/odin1c_rus Cтатьи, курсы, советы, шаблоны кода 1С
https://max.ru/channel_DevLab1C 1С:Предприятие 8
Программирование C++📌
https://max.ru/cpp_lib Библиотека C/C++ разработчика
https://max.ru/channel_cpp_geek C++ geek
Программирование Go📌
https://max.ru/golang_lib Библиотека Go (Golang) разработчика
Программирование React📌
https://max.ru/react_lib React
Программирование Rust📌
https://max.ru/channel_rust_lib
Программирование Python 📌
https://max.ru/python_of Python академия.
https://max.ru/BookPython Библиотека Python разработчика
Java разработка 📌
https://max.ru/bookjava Библиотека Java разработчика
https://max.ru/channel_java_geek Java Geek
GitHub Сообщество 📌
https://max.ru/githublib Интересное из GitHub
Базы данных (Data Base) 📌
https://max.ru/database_info Все про базы данных
Фронтенд разработка 📌
https://max.ru/frontend_1 Подборки для frontend разработчиков
Библиотеки 📌
https://max.ru/programmist_of Книги по программированию
https://max.ru/proglb Библиотека программиста
https://max.ru/bfbook Книги для программистов
Программирование 📌
https://max.ru/bookflow Лекции, видеоуроки, доклады с IT конференций
https://max.ru/itmozg Программисты, дизайнеры, новости из мира IT
https://max.ru/php_lib Библиотека PHP программиста 👨🏼💻👩💻
Шутки программистов 📌
https://max.ru/itumor Шутки программистов
Защита, взлом, безопасность 📌
https://max.ru/thehaking Канал о кибербезопасности
https://max.ru/xakkep_1 Хакер Free
Книги, статьи для дизайнеров 📌
https://max.ru/odesigners Статьи, книги для дизайнеров
Математика 📌
https://max.ru/Pomatematike Канал по математике
https://max.ru/phismat_1 Обучающие видео, книги по Физике и Математике
Вакансии в IT📌
https://max.ru/progjob
https://max.ru/channel_rabotait
Мир технологий 📌
https://max.ru/mir_teh Канал для любознательных
Городские📌
https://max.ru/piterspb_78 Свежие новости Санкт-Петербурга
https://max.ru/mockva_life Свежие новости Москвы
https://max.ru/piterspb Питер Новости: Санкт-Петербург / СПБ / ДТП
https://max.ru/channel_krasnodar_novosty Краснодар Новости
https://max.ru/channel_novosibirsk_novosti Новосибирск
https://max.ru/channel_samara_novosti Новости Самары
https://max.ru/channel_ekaterinburg_novosti Новости Екатеринбурга
https://max.ru/channel_kazan_novosti Новости Казани
https://max.ru/channel_omsk_novosti Новости Омска
https://max.ru/channel_moskva_24 Москва 24
MAX
Системный Администратор | Sysadmin Windows & Linux Server. …
Купить рекламу: https://telega.in/m/i_odmin
Блог практикующего админа. Настройка Windows Server, Active Directory (AD), GPO и терминальных серверов (RDP). Раб…
Блог практикующего админа. Настройка Windows Server, Active Directory (AD), GPO и терминальных серверов (RDP). Раб…
👎4👍1
🧠 Проверяешь аргументы вручную? Используй мощь системы типов Java!
📌 Ситуация: часто в методах видишь явные проверки вроде:
⚠️ Это шумно и ненадежно: легко пропустить проверку или некорректно сформулировать сообщение.
💡 Современный подход (Java 17+): явно обозначь контракт метода через типы и аннотации, и пусть JVM делает проверки автоматически!
Используй стандартные средства:
или лаконично через Lombok:
🔸 Преимущества:
* Ясность кода и контракта.
* Меньше boilerplate и человеческого фактора.
* Fail fast: сразу ловим ошибки, не откладывая.
🧠 Запомни: чем строже твоя система типов и контрактов, тем меньше неожиданностей в продакшене.
📲 Мы в MAX
👉@BookJava
📌 Ситуация: часто в методах видишь явные проверки вроде:
public void process(User user) {
if (user == null || user.getName() == null) {
throw new IllegalArgumentException("User или его имя не могут быть null");
}
// код обработки...
}
⚠️ Это шумно и ненадежно: легко пропустить проверку или некорректно сформулировать сообщение.
💡 Современный подход (Java 17+): явно обозначь контракт метода через типы и аннотации, и пусть JVM делает проверки автоматически!
Используй стандартные средства:
import java.util.Objects;
public void process(User user) {
Objects.requireNonNull(user, "User не должен быть null");
Objects.requireNonNull(user.getName(), "Имя пользователя не должно быть null");
// код обработки...
}
или лаконично через Lombok:
import lombok.NonNull;
public void process(@NonNull User user) {
// Lombok автоматически вставит проверку на null
}
🔸 Преимущества:
* Ясность кода и контракта.
* Меньше boilerplate и человеческого фактора.
* Fail fast: сразу ловим ошибки, не откладывая.
🧠 Запомни: чем строже твоя система типов и контрактов, тем меньше неожиданностей в продакшене.
📲 Мы в MAX
👉@BookJava
👍1😢1