12073
Присоединяйтесь к нашему каналу и погрузитесь в мир для Java-разработчика Связь: @devmangx РКН: https://clck.ru/3H4WUg
Клёвый тренажёр+учебник по SQL
Тут можно потренироваться в хитрых джойнах, агрегациях и понабивать руку. Интерфейс очень приятный и позволяет потыкать схему БД, даёт подсказки как в коде, так и непосредственно по решению
В более сложные штуки (к примеру, в оконные функции) этот ресурс не лезет. Ну и запросы даже в самых сложных задачках получаются не сказать чтобы громоздкие
На сайте есть платная версия (которая позволяет смотреть авторские решения), но можно вполне обойтись и без неё
https://sql-academy.org/ru/trainer
👉 Java Portal
В России можно посещать IT-мероприятия хоть каждый день: как оффлайн, так и онлайн
Но где их находить? Как узнавать о них раньше, чем когда все начнут выкладывать фотографии оттуда?
Переходите на канал IT-Мероприятия России. В нём каждый день анонсируются мероприятия со всех городов России
📆 в канале размещаются как онлайн, так и оффлайн мероприятия;
👩💻 можно найти ивенты по любому стеку: программирование, frontend-backend разработка, кибербезопасность, дата-аналитика, osint, devops и другие;
🎙 разнообразные форматы мероприятий: митапы с коллегами по цеху, конференции и вебинары с известными опытными специалистами, форумы и олимпиады от важных представителей индустрии и многое другое
А чтобы не искать по разным форумам и чатам новости о предстоящих ивентах:
🚀 IT-мероприятия России — подписывайся и будь в курсе всех предстоящих мероприятий!
Основные команды Maven для Java-разработчиков
Maven — это мощный инструмент автоматизации сборки, который используется в основном для Java-проектов. Он помогает управлять зависимостями, сборкой и жизненным циклом проекта
$ mvn archetype:generate
Создание нового Maven-проекта
$ mvn clean
Очистка директории target
$ mvn compile
Компиляция исходного кода
$ mvn test
Запуск unit-тестов
$ mvn package
Сборка проекта в JAR/WAR
$ mvn install
Установка артефакта в локальный Maven-репозиторий
$ mvn install -DskipTests
Пропустить тесты при сборке
$ mvn spring-boot:run
Запуск Spring Boot приложения (если используется spring-boot-maven-plugin)
$ mvn dependency:resolve
Обновление зависимостей
$ mvn dependency:tree
Вывод дерева зависимостей
$ mvn clean compile package
Запуск целей в указанной фазе
$ mvn validate
Проверка структуры проекта
Spring Boot: эффективный способ обработки больших CSV-файлов — использовать возможности Spring Batch.
Spring Batch настраивается с такими опциями:
✅ Чанкинг
✅ Параллелизм
✅ Ретраи
#SpringBoot #РазработкаПО
👉 Java Portal
Кто-то выложил в опенсорс инструмент, который парсит бизнесы из Google Maps по всему миру.
Название, адрес, телефон, сайт, отзывы, часы работы — всё собирается. Достаточно ввести поисковый запрос, и он выгружает данные в CSV.
Проект на 100% с открытым исходным кодом.
👉 Java Portal
Spring Boot: можно обрабатывать CORS глобально через WebMvcConfigurer
CORS — это механизм, который позволяет веб-приложению на одном домене (origin) получать доступ к ресурсам с другого домена.
👉 Java Portal
Совет по Java: избегайте глубокой вложенности if-else — используйте guard clauses (ранний выход)
Одна из частых проблем в Java-коде — сильно вложенные условия. Формально код работает, но его сложно читать и поддерживать.
✗ Плохо: вложенные if-else
* сложно читать
* логика размазана
* любое изменение усложняет код
✓ Хорошо: guard clauses (ранний выход)
* проверки сразу отсекают невалидные состояния
* основной сценарий читается сверху вниз
* код короче и понятнее
Почему guard clauses — профессиональный подход:
* снижают когнитивную нагрузку
* делают бизнес-логику очевидной
* упрощают рефакторинг и тестирование
* хорошо сочетаются с fail-fast подходом
Правило простое:
если условие — это ошибка или отклонение от нормального потока, проверяйте его сразу и выходите из метода.
В результате код становится:
* линейным
* предсказуемым
* удобным для поддержки
На уровне синтаксиса это мелочь, но на уровне качества кода разница существенная.
👉 Java Portal
💡Spring Boot: задавайте границы @ComponentScan аккуратно, чтобы не сканировать целые пакеты по ошибке.
Предположим, вы используете что-то вроде @ComponentScan("com.mycompany"):
❌Увеличивается время сканирования classpath
❌Замедляется запуск приложения
❌Могут подгружаться классы, не предназначенные быть Spring-компонентами
Лучшие практики:
✅Полагаться на значения по умолчанию:
@SpringBootApplication
public class MyApplication { }
@ComponentScan({
"com.mycompany.myapp.product",
"com.mycompany.myapp.order"
})
Микросервисы — это хаос без этих паттернов
👉 Java Portal
Совет по Java:
Если нужно посчитать, сколько раз элемент встречается в списке, нет необходимости писать цикл вручную.
Используй готовый метод:Collections.frequency(...)
Пример:
int count = Collections.frequency(
List.of("red", "green", "red"),
"red"
);
System.out.println(count); // 2
Polling vs Long Polling vs Webhooks vs SSE
Четыре способа получать обновления от сервера. Каждый даёт свой баланс между простотой, эффективностью и «почти реалтайм» доставкой.
Вот как они отличаются:
— Polling
Клиент каждые несколько секунд отправляет запрос: «есть что-то новое?». Сервер отвечает сразу — независимо от наличия данных. Большинство ответов пустые, что тратит ресурсы клиента и сервера. Подходит для сценариев вроде статуса заказа, где допустима задержка и важна простота реализации.
— Long Polling
Клиент отправляет запрос, а сервер держит HTTP-соединение открытым до появления данных или таймаута. Пустых ответов значительно меньше, чем в обычном polling. Использовался, например, в чатах для приближения к реалтайм-доставке сообщений.
— SSE (Server-Sent Events)
Клиент открывает постоянное HTTP-соединение, сервер стримит события по мере появления. Односторонний канал, лёгкий, работает поверх обычного HTTP. Многие AI-интерфейсы стримят ответы токен за токеном именно через SSE.
— Webhooks
Вместо опроса клиентом, сервис сам отправляет HTTP POST на заранее зарегистрированный callback URL при наступлении события. Stripe использует для подтверждения платежей, GitHub — для событий push. Клиент не держит соединение и не делает запросы, просто принимает вызовы.
Часто используется комбинация: polling для простых статусов, SSE для стриминга, webhooks для событий.
👉 Java Portal
Реальная сила Stream Gatherers в Java 24: кастомная stateful-магия с ранним завершением
Java 24 добавляет Stream Gatherers (JEP 485) — серьёзное расширение Stream API.
Они позволяют создавать кастомные промежуточные операции с поддержкой stateful-преобразований, m-to-n отображений, раннего завершения и параллельного выполнения. В отличие от коллекторов (которые терминальные), Gatherers работают прямо внутри конвейера стримов.
Это убирает необходимость в костылях вроде сбора во временные списки или ручных циклов для сложной логики — скользящие окна, накопительные суммы, дедупликация, батчинг.
С Gatherers код на стримах остаётся ленивым, читаемым, композиционным и переиспользуемым. Теперь Stream API выглядит завершённым для реальных сценариев обработки данных.
👉 Java Portal
Подключения к базе данных — дорогая операция.
Открывать и закрывать их на каждый запрос?
Ещё хуже.
Я нашёл простой разбор того, как на самом деле работает пул соединений и почему это важно.
Ссылка: https://sagarshiroya.dev/posts/database-connection-and-pooling
#Database #SystemDesign
👉 Java Portal
В Java, если нужно интегрировать полноценного агента, который умеет вызывать инструменты, запускать циклы, хранить контекст и поднимать веб-интерфейс для отладки, не стоит каждый раз собирать это с нуля — здесь уже есть готовый встраиваемый движок.
Встраиваемый движок AI-агента для любого Java-приложения — CLI · REST API · веб Playground
Базовая логика максимально простая: когда модели нужно вызвать инструмент, она выполняет его, записывает результат обратно в контекст и продолжает выполнение. Весь этот цикл упакован в Java-библиотеку и слой приложения на Spring Boot, поэтому его можно напрямую встроить в бизнес-систему или использовать как CLI, REST-сервис или веб Playground.
👉 Java Portal
Для тех кто просил, наш канал с мемами для программистов и айтишников
👇
/channel/+VS5COdLqY_s4OTYy
На фото показана проблема N+1 в JPA и её решение.
🟣findAll() — вызывает 1 запрос к авторам + по 1 запросу на книги каждого автора → N+1 запросов
☑JOIN FETCH в @Query — решает проблему, загружая авторов и их книги одним SQL-запросом
Показана разница в коде и как избежать лишних запросов при загрузке связанных сущностей (Author → Book)
👉 Java Portal
Spring Boot: важно валидировать входные данные ваших API, даже внутренних.
#SpringBoot #РазработкаПО
👉 Java Portal
☕️ Optional.ifPresentOrElse()
Обрабатывает случаи, когда значение в Optional есть и когда оно отсутствует, одним вызовом.
if/else для Optional → ifPresentOrElse() (JDK 9+)
🔗https://javaevolved.github.io/streams/optional-ifpresentorelse.html
👉 Java Portal
System Design Cheat Sheet — 15 ключевых концепций
1. Сбор требований
* Определить функциональные и нефункциональные требования
* Описать пользовательские сценарии и воркфлоу
* Расставить приоритеты по бизнес-целям
* Зафиксировать зависимости и ограничения
2. Архитектура системы
* Определить компоненты системы и их взаимодействие
* Выбрать подходящие архитектурные паттерны и стиль
* Оптимизировать под масштабируемость и поддерживаемость
* Оценить трейд-оффы между монолитом и распределённой системой
3. Дизайн данных
* Спроектировать модели данных, схемы и связи
* Выбрать подходящую БД под масштаб и консистентность
* Определить политики хранения, бэкапы и архивирование
* Использовать нормализацию и денормализацию по необходимости
4. Доменная модель
* Разбить систему на бизнес-домены
* Инкапсулировать функциональность внутри доменных модулей
* Минимизировать междоменные зависимости
* Обеспечить владение данными внутри доменов
5. Масштабируемость
* Реализовать горизонтальное и вертикальное масштабирование
* Использовать балансировку нагрузки
* Оптимизировать партиционирование и шардинг
* Планировать автоскейлинг под пики нагрузки
6. Надёжность
* Проектировать отказоустойчивость и деградацию
* Настроить мониторинг, алерты и логирование
* Реализовать бэкапы и восстановление
* Использовать ретраи, circuit breaker и таймауты
7. Доступность
* Реплицировать данные между узлами
* Минимизировать даунтайм через failover
* Определить планы восстановления (RTO/RPO)
* Регулярно тестировать под нагрузкой
8. Производительность
* Оптимизировать задержки и пропускную способность
* Использовать кэширование для горячих данных
* Оптимизировать алгоритмы и запросы
* Применять сжатие для передачи данных
9. Безопасность
* Реализовать аутентификацию и авторизацию
* Шифровать данные в покое и при передаче
* Проводить сканирование уязвимостей и аудиты
* Защищать API и эндпоинты от атак
10. Поддерживаемость
* Писать модульный, читаемый и документированный код
* Автоматизировать деплой и версионирование
* Проектировать систему без ломания фич при росте
* Использовать CI/CD пайплайны
11. Тестирование
* Покрывать юнит-, интеграционные и e2e-тесты
* Проводить нагрузочное тестирование
* Валидировать API и корректность данных
* Проверять безопасность и соответствие требованиям
12. Пользовательский опыт
* Делать понятный и отзывчивый интерфейс
* Оптимизировать пользовательские сценарии
* Проводить юзабилити-тестирование
* Учитывать доступность
13. Оценка стоимости
* Считать инфраструктурные затраты
* Учитывать лицензии, масштабирование и операционные расходы
* Оптимизировать использование облачных ресурсов
* Закладывать бюджет на отказоустойчивость
14. Документация
* Поддерживать актуальные техдоки и архитектуру
* Писать API-справочники и руководства
* Использовать диаграммы
* Хранить всё с версионированием
15. План миграции
* Проверить совместимость старой и новой системы
* Составить пошаговую стратегию
* Прогнать миграцию на стенде
* Проверить целостность данных после переноса
👉 Java Portal
SOLID в Java: принцип подстановки Лисков (LSP) утверждает:
==> Объекты базового класса должны заменяться объектами подклассов без проблем.
× Плохой пример
* Есть класс Vehicle с методом startEngine().
* Наследуемся в Bicycle, но… у велосипеда нет двигателя, и метод выбрасывает исключение.
Такая иерархия:
class Vehicle {
public void startEngine() { ... }
}
class Bicycle extends Vehicle {
@Override
public void startEngine() {
throw new UnsupportedOperationException("Bicycles don't have engines!");
}
}interface Vehicle {}
interface Motorized {
void startEngine();
}
class Car implements Vehicle, Motorized {
public void startEngine() { ... }
}
class Bicycle implements Vehicle {
// без двигателя — всё корректно
}
Совет по Java: удаляйте неиспользуемые импорты и переменные — это улучшает читаемость кода.
До:
import java.util.Date; // неиспользуемый импорт
import java.util.Scanner;
public class Greeting {
private int age; // неиспользуемая переменная
public void sayHello() {
Scanner sc = new Scanner(System.in);
System.out.println("Hello, world!");
sc.close();
}
}
import java.util.Scanner;
public class Greeting {
public void sayHello() {
Scanner sc = new Scanner(System.in);
System.out.println("Hello, world!");
sc.close();
}
}
Основные области памяти JVM:
▪️Heap (куча)
Общая для потоков
Хранит объекты и экземпляры, управляется сборщиком мусора
▪️Method Area (область методов)
Общая для потоков
Метаданные классов, статические переменные, байткод
▪️Runtime Constant Pool (пул констант времени выполнения)
На класс, разделяется
Строковые литералы, ссылки на методы, константы
▪️JVM Stack (стек JVM)
На поток
Фреймы вызовов, локальные переменные, адреса возврата
▪️Native Stack (нативный стек)
На поток
Выполнение нативного кода через JNI
▪️Program Counter (PC регистр)
На поток
Текущая инструкция, которую выполняет поток
▪️Code Cache (кэш кода)
Общий
Машинный код после JIT-компиляции
▪️Direct Memory (off-heap)
Общая
Память вне кучи для высокопроизводительного ввода-вывода
Разбиение кучи:
▪️Eden
Новые объекты создаются здесь
▪️Survivor
Краткоживущие объекты перед продвижением
▪️Old Generation
Долгоживущие объекты
👉 Java Portal
Java: если нужно писать переносы строк, соответствующие ОС, используй System.lineSeparator().
👉 Java Portal
А что у нас здесь? Новая серия вебинаров по Java!
И первый вебинар от PVS-Studio посвящен современному Gradle для Java-разработчика.
Вы узнаете, зачем в современных проектах нужны модули и как они помогают масштабировать кодовую базу без хаоса. Поймете, как устроен жизненный цикл Gradle и какие механизмы стоят за его скоростью и гибкостью.
А еще:
- в формате лайвкодинга создадите с нуля базовую структуру мультимодульного проекта;
- настроите зависимости между модулями;
- обсудите лучшие практики организации кода;
- после вебинара получите понятную основу для построения поддерживаемых и расширяемых Java-проектов любой сложности.
Подробности и регистрация по ССЫЛКЕ.
Аккуратная идея из превью JDK 24: JEP 487, Scoped Values.
Scoped Values направлены на то, чтобы сделать общий неизменяемый контекст более предсказуемым по сравнению с ThreadLocal, особенно в современном конкурентном коде.
Небольшой пример 👇
В Java можно использовать Optional.orElseThrow() для реализации так называемого fail-fast поведения.
✅ Fail-fast означает, что ошибки фиксируются ближе к месту возникновения, за счёт чего стек вызовов проще читать и анализировать
#Java #РазработкаПО
👉 Java Portal
Совет по Java: можно избежать чрезмерного количества параметров метода, сгруппировав связанные значения в объекты. #Java #РазработкаПО
👉 Java Portal
Spring Boot: избегай FetchType.EAGER, если в этом нет реальной необходимости.
❌ Пометка связи как EAGER заставляет ORM загружать её при каждой загрузке сущности, независимо от того, вызываешь ли ты метод этой связи на самом деле.
#Springboot #РазработкаПО
👉 Java Portal
Java: Если нужно читать небольшие файлы, можно использовать Files.readAllLines() — это более прямой и простой способ.
#SpringBoot #JavaDev
👉 Java Portal
Java Generics — всё, что нужно знать
1. Box<T> → Обобщённый класс
• Используй, когда класс работает с любым типом (например, обёртка вокруг любого объекта, как Box<User>, Box<Integer>).
2. <T> void print(T val) → Обобщённый метод
• Используй, когда метод должен принимать любой тип (например, для печати любого объекта, логирования, сравнения и т.п.).
3. <T extends Number> → Ограниченный тип
• Называется верхней границей.
• Используй, когда тип должен быть подклассом чего-то (например, утилита для работы с int, double, float).
4. <T extends A & B> → Несколько ограничений
• Заставляет T реализовывать и A, и B.
• Используй, когда нужны обе особенности (например, сортировка объекта, который также требует валидации).
5. <?> → Неограниченный подстановочный тип
• Это означает неизвестный тип.
• Используй, когда не важен тип, нужно только читать (например, печать элементов из любого списка).
6. <? extends T> → Верхняя граница подстановочного типа
• Означает некоторый подкласс T.
• Используй при чтении из коллекции (например, чтение чисел из List<? extends Number> без модификации).
7. <? super T> → Нижняя граница подстановочного типа
• Означает некоторый суперкласс T.
• Используй при записи в коллекцию (например, добавление Integer в List<? super Integer>).
8. Правило PECS
• Producer Extends, Consumer Super.
• Используй extends для чтения, super для записи (например, API-вход против обработки ответа).
9. List list = new ArrayList(); → Сырой тип
• Это сырой тип.
• Избегай — тк теряется типовая безопасность (например, компилятор не поймает, если добавишь неверные типы).
10. Стирание типов
• Java удаляет всю информацию об обобщениях во время выполнения.
• Поэтому нельзя использовать T.class, new T(), или instanceof T (например, нельзя делать проверки или создавать объекты на основе T).
11. Обобщённый конструктор
<T> MyClass(T val) { }interface Mapper<F, T> { T map(F input); }List<int> — только List<Integer>. new T[] не работает. List<T> вместо (например, динамические коллекции). List<? extends Number>.<? super Number>, если нужна вставка (например, для пакетной обработки или модификации коллекции).