java_iibrary | Unsorted

Telegram-канал java_iibrary - Java Portal | Программирование

12073

Присоединяйтесь к нашему каналу и погрузитесь в мир для Java-разработчика Связь: @devmangx РКН: https://clck.ru/3H4WUg

Subscribe to a channel

Java Portal | Программирование

Spring Boot: Используйте spring.mvc.publish-request-params=true только в dev-среде. Это опасно в production.

В production логирование деталей запроса может привести к раскрытию чувствительной информации.

Когда вы настраиваете свойства Spring-приложения в dev со следующими параметрами:

# Включить публикацию параметров
spring.mvc.publish-request-params=true

# Установить уровни логирования, чтобы видеть вывод
logging.level.org.springframework.web=DEBUG
logging.level.org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor=DEBUG


и конфигурацию фильтра примерно такую:

@Bean
public CommonsRequestLoggingFilter logFilter() {
CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter();
filter.setIncludeQueryString(true); // 2) Query-параметры
filter.setIncludeHeaders(true); // 1) Заголовки запроса
filter.setIncludePayload(true); // 3) Данные формы
filter.setMaxPayloadLength(1000);
filter.setAfterMessagePrefix("COMPLETE REQUEST: ");
return filter;
}


вы включаете логирование:

1. заголовков запроса (Request headers)
2. query-параметров (Query parameters)
3. данных формы (Form data)

Без этого Spring маскирует или опускает многие из этих деталей, чтобы избежать утечки информации.

Не используйте это в production, иначе вы раскроете чувствительную информацию, например пароли:

POST /login
Body: {"username":"john","password":"mypassword"}


👉 Java Portal

Читать полностью…

Java Portal | Программирование

💡Java tip: Начиная с Java 14 можно использовать switch-выражения, чтобы писать более короткую и чистую мультиветвящуюся логику.

// Old way:
String season;
switch (month) {
case 12:
case 1:
case 2:
season = "Winter";
break;
case 3:
case 4:
case 5:
season = "Spring";
break;
default:
season = "Invalid";
}

// New switch expression:
String season = switch (month) {
case 12, 1, 2 -> "Winter";
case 3, 4, 5 -> "Spring";
default -> "Invalid";
};

Читать полностью…

Java Portal | Программирование

Совет по Java : не полагайся полностью на сборщик мусора — утечки памяти всё ещё возможны.

👉 Java Portal

Читать полностью…

Java Portal | Программирование

В заповедной Карелии, среди сотен озёр и густой северной тайги, на берегу Онежского озера расположился бутик-отель «Заонежье». Здесь архитектура деликатно вписана в ландшафт: фасады из северного дерева и лемех, вырубленный вручную, перекликаются с традициями древнего зодчества Русского Севера. Каждое окно обращено к воде, позволяя бесконечному озёрному горизонту стать частью интерьера.

Тринадцать видовых номеров и четыре гостевых дома с дровяными каминами создают атмосферу приватности и спокойствия, а ресторан «Руна» предлагает авторскую гастрономию из локальных продуктов — от свежевыловленной рыбы до дичи и северных ягод. Пространство отеля продумано для размеренного отдыха: пирс, панорамный зал, экотропы и уединённые места для медитации среди леса.

Заонежье — край редкого шунгита, чистейшей воды и нетронутых лесов, где можно встретить орлана-белохвоста и увидеть северное сияние. Гостям доступны экспедиции на снегоходах и катерах, путешествия к острову Кижи, рыбалка, прогулки на каяках, сапах и тишина безкрайних пейзажей.

Здесь легко устроить digital detox или, напротив, провести частное гастрономическое событие у костра на берегу озера. Баня по-чёрному в соседней деревне, чаепитие из самовара, пикники на необитаемых островах.
«Заонежье» — это не просто отдых, а глубокое погружение в первозданную природу, где комфорт и культура соединяются с силой земли и воды.

Наш телеграм канал: @hotelzaonezhie

Забронировать номер: https://zaonezhie.com

Читать полностью…

Java Portal | Программирование

Гайд для новичков по созданию HTTP-сервера с нуля.

Хочешь своими руками написать HTTP-сервер и потом отправлять на него запросы и получать ответы?
Если да, вот как раз гайд, по которому можно пройтись.

Что нужно знать заранее

Нужно знать Java.
Если не знаешь, не страшно: шаги из гайда можно перенести почти на любой язык, с которым тебе удобно работать, просто используя семантически эквивалентные конструкции в коде.

Примечание: JS/TS для этого гайда я бы не рекомендовал.


Базовое понимание программирования и OOP.

Текстовый редактор и, возможно, много кофе. Как пойдет. 🤭

👉 Java Portal

Читать полностью…

Java Portal | Программирование

Java tip: используйте ThreadLocal.withInitial(...), чтобы у каждого потока было свое безопасное значение по умолчанию.

Значение создается лениво

👉 Java Portal

Читать полностью…

Java Portal | Программирование

API Gateway, если по-человечески:

Клиент не должен ходить в 6 разных сервисов.
Он должен ходить в одну точку.

Gateway стоит перед всей системой и берёт на себя:

- маршрутизацию входящих запросов в нужный сервис
- валидацию токенов, например JWT и OAuth, ещё до того, как запрос вообще дойдёт до сервисов
- rate limiting, чтобы API не абьюзили
- логирование, чтобы наблюдаемость была в одном месте
- балансировку нагрузки между инстансами сервисов

Без gateway каждый сервис заново городит у себя аутентификацию, логирование и rate limiting.
С gateway всё это решается один раз, централизованно.

Вот и вся суть: одна точка входа и единый слой контроля.

👉 Java Portal

Читать полностью…

Java Portal | Программирование

Я побывал по обе стороны собеседований по system design.

Ниже темы, которые нужно изучить, чтобы действительно хорошо в этом разбираться:

1. [Сервер]

2. [Задержка и пропускная способность]

3. [Масштабирование и его виды]
– Вертикальное и горизонтальное масштабирование

4. [Автомасштабирование]

5. [Прикидочные расчеты]

6. [Теорема CAP]

7. [Масштабирование базы данных]
– Индексы
– Партиционирование
– Архитектура master-slave
– Multi-master
– Шардирование базы данных
– Недостатки шардирования

8. [SQL и NoSQL базы данных и когда что использовать]

9. [База данных]
– SQL-база данных
– NoSQL-база данных
– Масштабирование в NoSQL и SQL
– Когда какую базу использовать?

10. [Микросервисы]
– Монолит vs микросервисы
– Зачем вообще разбивать приложение на микросервисы?
– Когда использовать микросервисы?
– Как клиенты делают запросы в микросервисной архитектуре?

11. [Глубокое погружение в load balancer]
– Зачем нужен load balancer?
– Алгоритмы load balancing

12. [Кеширование]
– Плюсы кеширования
– Типы кешей
– Redis

13. [Blob Storage]
– Что такое blob и зачем нужно blob storage?
– AWS S3

14. [CDN, Content Delivery Network]
– Как работает CDN?

15. [Message Broker]
– Асинхронное программирование
– Зачем ставить message broker между сервисами?
– Очередь сообщений
– Поток сообщений
– Когда использовать message broker

16. [Глубокое погружение в Apache Kafka]
– Когда использовать Kafka
– Внутреннее устройство Kafka

17. [Pub/sub в реальном времени]

18. [Event-Driven Architecture]
– Зачем использовать EDA?
– Простое уведомление о событии
– Передача состояния через событие

19. [Распределенные системы]

20. [Самовосстанавливающаяся система с election лидера]

21. [Глубокое погружение в consistency]
– Строгая согласованность
– Когда выбирать strong consistency
– Eventual consistency
– Когда выбирать eventual consistency
– Способы добиться strong consistency
– Способы добиться eventual consistency

22. [Consistent hashing]

23. [Избыточность данных и восстановление данных]
– Зачем делать базы данных избыточными?
– Разные способы резервного копирования
– Непрерывная избыточность

24. [Прокси]
– Forward proxy vs reverse proxy

👉 Java Portal

Читать полностью…

Java Portal | Программирование

Java-совет: начиная с Java 9 можно использовать Stream.takeWhile() для удобной "нарезки" списков через стримы.

List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9);

✗ Вместо:

List<Integer> result = new ArrayList<>();

for (Integer n : numbers) {
if (n < 5) {
result.add(n);
} else {
break;
}
}
System.out.println(result); // [1, 2, 3, 4]

✓ Можно так:

result = numbers.stream().takeWhile(n -> n < 5).toList();
System.out.println(result); // [1, 2, 3, 4]


👉 Java Portal

Читать полностью…

Java Portal | Программирование

Java: используй ReentrantReadWriteLock, если у тебя частые чтения и мало записей.

ReentrantReadWriteLock это утилита конкурентности в Java, которая дает два типа локов:

1. Read lock (лок на чтение): позволяет нескольким потокам читать одновременно, пока ни один поток не пишет.

2. Write lock (лок на запись): позволяет писать только одному потоку и блокирует всех остальных читателей и писателей, пока лок не будет освобожден.

Используй ReentrantReadWriteLock, когда:

1. Твой код часто читает разделяемые данные.

2. Записи происходят редко.

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

Пример:

public class SharedValue {
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private int value = 0;

public int readValue() {
lock.readLock().lock();
try {
return value;
} finally {
lock.readLock().unlock();
}
}

public void writeValue(int newValue) {
lock.writeLock().lock();
try {
value = newValue;
} finally {
lock.writeLock().unlock();
}
}
}


👉 Java Portal

Читать полностью…

Java Portal | Программирование

Совет по Spring Boot: со Spring Boot и Spring Security ты можешь легко защитить эндпоинты.

✅ Чтобы защитить следующий REST-эндпоинт:

@RestController
public class MyController {

@GetMapping
("/admin")
public String admin() {
...
}
...
}


✅ Можно написать такую конфигурацию:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin").authenticated()
.anyRequest().permitAll()
.and()
.httpBasic();
}
}



- authorizeRequests(): начинает описание эндпоинтов, которым нужна защита.
- antMatchers("/admin").authenticated(): требует аутентификацию для /admin.
- anyRequest().permitAll(): все остальные эндпоинты публичные.
- httpBasic(): включает HTTP Basic Auth.


👉 Java Portal

Читать полностью…

Java Portal | Программирование

Java tip: Начиная с Java 12 можно использовать String.indent(n), чтобы красиво форматировать многострочные строки, добавляя нужный отступ.

n > 0: добавляет n пробелов в начале каждой строки.
n < 0: удаляет до n ведущих пробелов из каждой строки.

✅ Добавление пробелов:

String text = "Text\ncontent";
System.out.println(text.indent(0));
System.out.println(text.indent(4));
System.out.println(text.indent(0));


✅ Удаление пробелов:

String text = "    Text\n    content";
System.out.println(text.indent(-4));



👉 Java Portal

Читать полностью…

Java Portal | Программирование

Spring Boot: @AutoConfigureMockMvc позволяет тестировать контроллеры, не поднимая сервер. Она говорит Spring Boot автоматически сконфигурировать экземпляр MockMvc в тестовом контексте.

@SpringBootTest
@AutoConfigureMockMvc
class UserControllerTest {

@Autowired
private MockMvc mockMvc;

@Test
void shouldReturnUser() throws Exception {
mockMvc.perform(get("/users/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id").value(1));
}
}


1. @SpringBootTest поднимает полный application context.
2. @AutoConfigureMockMvc настраивает MockMvc.
3. Никакого Tomcat (и других встроенных серверов).
4. Запросы выполняются внутри через DispatcherServlet от Spring.


👉 Java Portal

Читать полностью…

Java Portal | Программирование

Вопрос для интервью по Java Spring Boot: @Transactional + @EventListener

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

[Дано]:
Команда написала логику отправки письма после регистрации пользователя. На проде иногда бывает ситуация: письма приходят, а пользователя в базе нет. Найди проблему и почини:

[Задачи]:

- Объясни, в каком сценарии письмо будет отправлено, но пользователь не сохранится
- Исправь код так, чтобы событие обрабатывалось только после того, как пользователь сохранён

Код:

@Service

@RequiredArgsConstructor
public class UserService {

private final UserRepository userRepository;
private final ApplicationEventPublisher eventPublisher;


@Transactional

public void register(UserDto dto) {
User user = new User(http://dto.email());
http://userRepository.save(user);

eventPublisher.publishEvent(new UserRegisteredEvent(user));
}
}

@Component

@RequiredArgsConstructor
public class EmailListener {

private final EmailSender emailSender;
private final SomeOtherService someOtherService;


@EventListener

public void onUserRegistered(UserRegisteredEvent event) {
emailSender.sendWelcome(event.user().getEmail());
someOtherService.doSomething();
}
}


👉 Java Portal

Читать полностью…

Java Portal | Программирование

Почему твой бэкенд начинает тупить на 10k юзеров, хотя на 100 всё летало

Обычно причина одна из этих:

1️⃣N+1 запросы
→ один запрос незаметно триггерит сотню походов в БД

2️⃣Нет индексов
→ на каждом поиске полный проход по таблице

3️⃣Тяжелая работа синхронно
→ письма, обработка картинок прямо внутри request cycle

4️⃣Нет стратегии кеширования
→ один и тот же запрос в БД выполняется 1000 раз

5️⃣Единая точка отказа
→ один инстанс БД тащит на себе вообще всё

Приложение не стало внезапно медленным.
Оно просто доросло до момента, когда плохие решения стали заметны.

👉 Java Portal

Читать полностью…

Java Portal | Программирование

Совет по Spring AI

Запускаете локальные AI-модели через LM Studio и сталкиваетесь с зависанием соединения, когда ваше приложение Spring AI вызывает API, совместимый с OpenAI?

LM Studio не поддерживает HTTP/2, из-за чего запрос может зависать.

Решение: отключить HTTP/2 для`RestClient`.

👉 Java Portal

Читать полностью…

Java Portal | Программирование

Типы классов в Java:

1. Concrete Class (конкретный класс) — обычный класс с полной реализацией методов.

2. Abstract Class (абстрактный класс) — не может быть создан через new; может содержать абстрактные методы.

3. Final Class (финальный класс) — не может быть унаследован.

4. Static Class (вложенный статический класс) — статический внутренний класс внутри другого класса.

5. Inner Class (внутренний класс) — нестатический класс, объявленный внутри другого класса.

6. Local Class (локальный класс) — класс, определённый внутри метода.

7. Anonymous Class (анонимный класс) — класс без имени, обычно используется для кратковременных реализаций.

8. Singleton Class (синглтон-класс) — гарантирует существование только одного экземпляра класса.

9. POJO (Plain Old Java Object) — простой Java-класс без специальных ограничений или требований.

10. Record Class (Java 14+) — компактный класс для представления неизменяемых данных.

11. Enum Class (класс-перечисление) — определяет фиксированный набор констант.

👉 Java Portal

Читать полностью…

Java Portal | Программирование

Трюк, чтобы сэкономить место на диске и время при клонировании репозиториев из GitHub.

👉 Java Portal

Читать полностью…

Java Portal | Программирование

Совет по Java: List.reversed() возвращает неизменяемое (unmodifiable) представление исходного списка в обратном порядке.

👉 Java Portal

Читать полностью…

Java Portal | Программирование

Вопрос на Java-собеседовании:

Что такое Spring Bean Scope?

Spring Bean Scope определяет жизненный цикл и область видимости бина в контейнере.

Основные типы:

- singleton (по умолчанию) — один экземпляр на весь контейнер.
- prototype — новый экземпляр для каждого запроса.
- request — бин живет в рамках одного HTTP-запроса.
- session — бин живет в рамках одной HTTP-сессии.
- application — бин живет в рамках всего веб-приложения.
- websocket — бин живет на протяжении сессии WebSocket.

👉 Java Portal

Читать полностью…

Java Portal | Программирование

Не используйте ELSE 0 вместе с COUNT и CASE

Использование ELSE 0 - очень частая ошибка у новичков, когда они комбинируют функцию COUNT с выражением CASE. Обычно это происходит из-за непонимания того, как именно COUNT работает при применении к столбцу.

Когда используется COUNT(column), функция считает все значения, которые не равны NULL, включая нули. Это значит, что если в выражении CASE указан ELSE 0, каждая строка, не попавшая под условие, превращается в значение 0. В результате такие строки тоже попадают в подсчёт.

Вот наивный пример:

sql id="g4suvd"
SELECT
Department,
COUNT(CASE
WHEN Status = 'Active' THEN EmployeeID
ELSE 0
END) AS ActiveEmployees
FROM Employees
GROUP BY Department;


В этом запросе каждая строка, которая не удовлетворяет условию, превращается в 0, а это валидное значение, поэтому оно тоже учитывается в COUNT. Из-за этого результат может получиться вводящим в заблуждение.

Лучше всего вообще убрать ELSE. Когда ветка ELSE опущена, выражение CASE возвращает NULL для строк, которые не соответствуют условию. А так как COUNT() игнорирует NULL, будут посчитаны только строки, которые действительно удовлетворяют условию. Вот правильный вариант:

sql id="vxa5np"
SELECT
Department,
COUNT(CASE
WHEN Status = 'Active' THEN EmployeeID
END) AS ActiveEmployees
FROM Employees
GROUP BY Department;


В этой версии строки, не подходящие под условие, возвращают NULL, и COUNT() естественным образом исключает их из подсчёта. В итоге запрос получается чище, а подсчёт корректно отражает только те значения, которые реально соответствуют условию.

👉 Java Portal

Читать полностью…

Java Portal | Программирование

Совет по Spring Boot: ускорить приложение можно с помощью @EnableCaching и @Cacheable.

🟢Позволяет избежать повторных вызовов к БД и API
🟢 Снижает задержки
🟢 По умолчанию Spring использует in-memory map, но в проде можно подключить внешний провайдер кеша

👉 Java Portal

Читать полностью…

Java Portal | Программирование

9 000₽ за вечер. Без кода. Без офиса. Без опыта.

Именно столько платят за одного чат-бота для бизнеса начинающим спецам.

Берёшь шаблон → собираешь бота → сдаёшь клиенту. Первые деньги — в первую же неделю.

Показываю, как новичку делать чат-ботов для бизнеса за дорого:
👉 @other_digital_bot

Читать полностью…

Java Portal | Программирование

Что такое BeanPostProcessor в Java Spring Boot?

Это интерфейс, который позволяет вмешиваться в процесс создания и инициализации бинов в Spring-контейнере.

Он предоставляет два основных метода, которые вызываются на разных этапах жизненного цикла бина:

1. postProcessBeforeInitialization(Object bean, String beanName)
Вызывается до инициализации бина (до вызова метода с @PostConstruct или InitializingBean#afterPropertiesSet).

2. postProcessAfterInitialization(Object bean, String beanName)
Вызывается после инициализации бина (после того, как все методы инициализации завершились).

Зачем нужен BeanPostProcessor?

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

Примеры:

- Добавление проксирования бинов (например, для AOP или транзакций)
- Валидация или изменение свойств бина
- Логирование жизненного цикла
- Добавление кастомных аннотаций
- Обработка marker-интерфейсов

Как это работает?

1. Spring сканирует контекст на наличие бинов, которые реализуют интерфейс BeanPostProcessor.
2. Если такие бины найдены, они применяются ко всем бинам в приложении.
3. Методы postProcessBeforeInitialization и postProcessAfterInitialization вызываются для каждого бина, который создаёт Spring.

👉 Java Portal

Читать полностью…

Java Portal | Программирование

Как прогреть кэши в Spring Boot?

Или вообще как выполнить что-то на старте Spring Boot приложения?

Обычно такие операции делают в @PostConstruct или подписываются на событие ApplicationReadyEvent. Но у этих вариантов есть заметный минус.

Если “прогрев” находится в @PostConstruct, как отключить его в тестах? Можно добавить флаг, сделать сабкласс и подменить его в тестовой конфигурации, но это не всегда помогает и часто выглядит как костыль.

Более элегантный способ “прогреть кэши”

Смотри: SpringApplication.run(...) возвращает полностью готовый контекст. Можно достать из него компонент и вызвать нужный метод “прогрева”.

Код выглядит как на картинке:

Плюс: В интеграционных тестах с @SpringBootTest метод main не запускается. Соответственно, код внутри него не выполняется. Никаких костылей вокруг @PostConstruct, все чисто и красиво.

Когда “прогрев” все-таки нужен в тестах, добавляем параметр use main method:

@SpringBootTest(useMainMethod = SpringBootTest.UseMainMethod.ALWAYS)


👉 Java Portal

Читать полностью…

Java Portal | Программирование

5 часто задаваемых вопросов на собеседованиях по Java Generics.

На сколько из них ты сможешь ответить?

1. В чем разница между Object<?> и Object в Java?

2. В чем разница между List<?> и List<Object>?

3. В чем разница между List<? extends Number> и List<? super Number>?

4. Можно ли добавлять элементы в List<?>?

5. Чем T отличается от ? в дженериках?

👉 Java Portal

Читать полностью…

Java Portal | Программирование

Видел интересное видео от CTO Zerodha про то, как они масштабировали Postgres с 7+ млн таблиц.
Технология просто выносит мозг, а если копнуть глубже, становится еще веселее:

- синхронщина? не масштабируется, значит выкидываем.
- все в async. тяжелую генерацию отчетов ставим в очередь.
- независимый middleware, которому все равно на базу и на приложение.
- собрали “DungBeetle” на Go: обобщенные, независимые от СУБД HTTP API, чтобы тянуть отчеты из любой базы.
- результаты сливаем в отдельную Results DB, а приложение читает уже оттуда.

Вот так выглядит настоящий масштаб.

Смотреть видео

👉 Java Portal

Читать полностью…

Java Portal | Программирование

Ищу хороший репозиторий с Claude skills для Java, Spring Boot и т.п. Нашёл вот этот: https://github.com/decebals/claude-code-java.

👉 Java Portal

Читать полностью…

Java Portal | Программирование

Совет по Java: Stream.toArray(Type[]::new) это аккуратный и типобезопасный способ получить массив из стрима.

Избавляет от Object[] и ручных кастов.

👉 Java Portal

Читать полностью…

Java Portal | Программирование

Задумывался, как работают ActiveMQ и RabbitMQ?

В основе у них producer/consumer паттерн.

Как его реализовать?

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

Общий вид решения такой:

продюсер кладет объекты в специальную коллекцию, буфер. Когда консьюмер освобождается, он запрашивает из буфера один объект. Если буфер пустой, консьюмер блокируется и ждёт; если буфер переполнен, ждёт продюсер.

Реализовать этот паттерн можно по-разному.

Самый правильный способ для продакшена: брать готовую реализацию из стандартной библиотеки, например BlockingQueue.

На собеседованиях обычно просят написать реализацию с нуля. На картинке показан один из вариантов.

Модификатор synchronized гарантирует, что в один момент времени выполняется только один из методов и только одним потоком. Этого достаточно для корректной работы, пока буфер не пуст и не переполнен. Когда буфер пустой или полный, управление явно передаётся продюсеру или консьюмеру соответственно через notify() и wait().

👉 Java Portal

Читать полностью…
Subscribe to a channel