12073
Присоединяйтесь к нашему каналу и погрузитесь в мир для Java-разработчика Связь: @devmangx РКН: https://clck.ru/3H4WUg
JetBrains использует IDE-нативные возможности понимания кода, чтобы делать ИИ-агентов эффективнее на больших кодовых базах.
Зачем тратить время и токены на grep, если в IDE уже есть семантический поиск, навигация по символам и рефакторинги?
Интересный момент: Codex, судя по наблюдениям, заметно лучше использует такие инструменты, чем Claude Code.
👉 Java Portal
Spring Boot: использование Spring Cloud Config для централизованного управления конфигурацией — важная практика.
Вместо того чтобы каждый сервис хранил свой application.yml, конфигурация подтягивается из единого источника.
Сначала нужно сконфигурировать сервер конфигурации.
Поднимается отдельное приложение сервера конфигурации с аннотацией @EnableConfigServer и Git-репозиторий, где лежат все .yml файлы.
Сервер отдает конфигурацию по HTTP, клиенты подтягивают её при старте.
<!-- Setting Up the Config Server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
// Enable it with @EnableConfigServer annotation
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
# Point it to your Git repository
spring:
cloud:
config:
server:
git:
uri: https://github.com/your-org/config-repo
default-label: main
clone-on-start: true
server:
port: 8888
{application-name}-{profile}.yml{application-name}/{profile}.yml<!-- Add the client dependency -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
# Configure the application to fetch config from the config server
spring:
application:
name: order-service
config:
import: "optional:configserver:http://localhost:8888"
cloud:
config:
profile: dev
server:
port: 8080
@RefreshScope:package ...;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
@Service
@RefreshScope
public class PricingService {
@Value("${pricing.discount.percentage:0}")
private int discountPercentage;
// This value updates when config changes, no restart needed
}
curl -X POST http://localhost:8080/actuator/refresh
Java-совет : можно использовать List.of() и Set.of() для создания неизменяемых коллекций.
✅ Это быстрый способ создать немодифицируемые списки и множества без использования Collections.unmodifiableList().
#Java #Коллекции
👉 Java Portal
В Java можно ставить метку на выражение, которое уже промечено другой меткой. И так хоть до бесконечности.
Полезно? Вряд ли.
Стоит ли использовать? Точно нет.
Но как факт — это работает
Пример:
String question;
to: be: or: not: that: is: the: question = "What?";
out.println(question);
to:, be:, or: и т.д.) игнорируются, если не используются в break или continueWhat?
Spring Boot: можно добавить глобальные метаданные OpenAPI через аннотацию @OpenAPIDefinition.
✅ Её размещают на основном классе приложения Spring Boot или в отдельном конфигурационном классе.
#SpringBoot #JavaDev
👉 Java Portal
Паттерны в Java: паттерн «Строитель» позволяет гибко и прозрачно конструировать сложные объекты. #Java #ПаттерныПроектирования
👉 Java Portal
Используй Files.isSameFile(path1, path2), чтобы проверить, указывают ли два пути на один и тот же файл. Метод также резолвит симлинки.
Проверяет, ссылаются ли два объекта Path на один и тот же реальный файл в файловой системе.
#Java #РазработкаПО
👉 Java Portal
На фото показана проблема 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: начиная с Java 14 можно использовать records для создания коротких неизменяемых объектов, предназначенных для хранения данных.
✅ короче обычных POJO
✅ имеют встроенные equals(), hashCode(), toString()
✅ по умолчанию неизменяемые
#JavaDev #Records
👉 Java Portal
Значения области видимости финализированы в Java 25.
Более чистая альтернатива переменным, привязанным к потоку, с ограниченным временем жизни и хорошей совместимостью с виртуальными потоками.
static final ScopedValue<User> USER = ScopedValue.newInstance();
ScopedValue.where(USER, user)
.run(() -> UserService.updateUser());
В Java лямбда-выражение создаёт экземпляр функционального интерфейса. Во время выполнения этот экземпляр создаётся с помощью класса LambdaMetaFactory
Следующий код на Java создаёт объект Function<String, String>
Function<String, String> f = s -> s.toUpperCase();
@SuppressWarnings("unchecked")
void main() throws Throwable {
MethodHandles.Lookup lookup;
lookup = MethodHandles.lookup();
CallSite callSite;
callSite = LambdaMetafactory.metafactory(
lookup,
"apply",
MethodType.methodType(Function.class),
MethodType.methodType(Object.class, Object.class),
lookup.findStatic(
getClass(),
"lambda",
MethodType.methodType(String.class, String.class)
),
MethodType.methodType(String.class, String.class)
);
MethodHandle target;
target = callSite.getTarget();
Function<String, String> f;
f = (Function<String, String>) target.invokeExact();
String msg;
msg = f.apply("Hello, World!");
IO.println(msg);
}
private static String lambda(String s) {
return s.toUpperCase();
}
HELLO, WORLD! ❤️
Этот Dockerfile для Spring Boot создаёт образ, который потребляет на 33% меньше памяти по сравнению с образом, собранным с помощью Buildpacks (рекомендуемый Spring способ сборки Docker-образов) 💪
👉 Java Portal
Для кого-то неожиданно узнать, что Java не конкатенирует строки на этапе выполнения в таком кейсе:String c = "a" + "b";
Что важно:
Строка в Java хранится как byte[] + флаг кодировки:0 — LATIN1 (1 байт на символ, для ASCII экономия памяти)1 — UTF-16 (2 байта на символ)
Строки размещаются в двух областях:
- куча
- пул строковых констант (SCP)
Пример:
String a = "hello", b = "hello";
a == b → true, обе переменные указывают на один объект из пулаString a = "hello", b = new String("hello");a == b → false, разные объекты в кучеString c = "a" + "b";
String c = "ab";
java id="xq7v2m"
String a = "a", b = "b", c = a + b;
invokedynamic с StringConcatFactoryStringBuilder, где код фактически превращался в цепочку append() и финальный toString().
На собесе по Java понимание устройства JVM и управления памятью сильно влияет на оценку. Ниже — сжатое покрытие всех 25 тем без воды.
1. Heap vs Stack
Heap — аллокация объектов, шарится между потоками.
Stack — фреймы методов, локальные переменные, примитивы.
Объекты в heap, ссылки — в stack.
2. Сборка мусора
GC освобождает недостижимые объекты.
Сборщики: Serial, Parallel, CMS (устаревший), G1.
Объект попадает под GC при отсутствии достижимости по графу ссылок.
3. Области памяти JVM
Heap (Young/Old), Stack, Metaspace (вместо Method Area), Native Stack.
Metaspace хранит метаданные классов.
4. Алгоритмы GC
Minor GC — Young, Major/Full GC — Old.
Mark-and-Sweep, Copying, Mark-Compact.
5. Параметры JVM-Xms, -Xmx — размер heap.-XX:NewRatio — соотношение поколений.
GC-логи анализируются для поиска пауз и аллокаций.
6. Утечки памяти
Причины: статические коллекции, кеши без очистки, listener’ы.
Инструменты: VisualVM, JConsole, Eclipse MAT.
7. OutOfMemoryError
Heap overflow, Metaspace overflow, Direct memory.
Решения: тюнинг heap, профилинг, оптимизация аллокаций.
8. Типы ссылок
Soft — для кешей.
Weak — сборка при следующем GC.
Phantom — для пост-очистки.
9. ThreadLocal
Утечки из-за хранения значений без remove().
Проблема усиливается в пуле потоков.
10. finalize()
Непредсказуемый вызов, влияет на GC.
Замена — Cleaner или try-with-resources.
11. Direct Memory
Off-heap через ByteBuffer.allocateDirect.
Контроль сложнее, GC не управляет напрямую.
12. JEP по GC
ZGC (JEP 307) — низкие паузы.
Shenandoah (JEP 189) — конкурентная очистка.
13. Архитектура JVM
ClassLoader, Runtime Data Areas, Execution Engine, JNI.
14. Загрузка классов
Loading → Linking → Initialization.
Загрузчики: Bootstrap, Platform (бывш. Extension), System.
15. Байткод
Инструкции JVM, стековая модель исполнения.
Интерпретируется и оптимизируется JIT.
16. JIT-компилятор
Горячий код компилируется в машинный.
Оптимизации: инлайнинг, удаление мертвого кода.
17. Структура .class
Magic number, constant pool, методы, атрибуты.
18. Жизненный цикл потоков
NEW → RUNNABLE → BLOCKED/WAITING → TERMINATED.
JVM управляет планированием через ОС.
19. JNI
Связка с нативным кодом (C/C++).
Используется для low-level операций.
20. Профилинг JVM
CPU, память, потоки.
Инструменты: VisualVM, JConsole.
21. HotSpot
Основная реализация JVM.
Использует адаптивную оптимизацию и JIT.
22. Манипуляция байткодом
ASM, BCEL, Javassist.
Применяется в прокси, AOP, фреймворках.
23. Инструменты диагностики
jstack — дамп потоков.
jmap — heap dump.
jstat — статистика GC.
24. Безопасность классов
Верификация байткода.
Security Manager (устаревший, но концепт важен).
25. Java Memory Model (JMM)
Правила видимости и happens-before.
Ключевые примитивы: volatile, synchronized.
👉 Java Portal
Клёвый тренажёр+учебник по 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