Java Portal | Программирование
12.7K subscribers
1.26K photos
105 videos
38 files
1.23K links
Присоединяйтесь к нашему каналу и погрузитесь в мир для Java-разработчика

Связь: @devmangx

РКН: https://clck.ru/3H4WUg
Download Telegram
Spring Boot: можно использовать spring.jpa.hibernate.ddl-auto=validate, чтобы проверять случайные изменения схемы в продакшене.

Если что-то не совпадает, приложение не запустится
Это можно комбинировать с инструментами миграций, например Flyway или Liquibase

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍52
Твоя база данных не медленная.
Медленный у тебя цикл обратной связи.

Один сеньор написал практический гайд, где показано, как разработчику на Java анализировать производительность PostgreSQL из Quarkus-приложения с помощью pg_stat_statements, hypopg и PostgreSQL MCP-сервера через IBM Bob.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍61
Совет: держите код рядом. Следите, чтобы вычисление было как можно ближе к месту, где используется это значение. Это улучшает читаемость и удобство рефакторинга, снижает вероятность багов и делает код более устойчивым к ошибкам.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
7
Совет по Java: используйте Collectors.groupingBy(...), чтобы группировать результаты стрима по классификатору.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👀5
Пессимистическая vs оптимистическая блокировка

Частый вопрос на собеседованиях по backend.

[Пессимистическая блокировка]: -

- Запись недоступна другим потокам, пока текущий поток не закончит с ней работу.
- Даже чтение данных другими потоками невозможно, пока блокировка не снята.
- Пример: EntityManager.lock(entity, LockModeType.PESSIMISTIC_WRITE) в JPA.
- Минусы: снижает производительность при высоком уровне конкуренции.
- Когда использовать: когда критически важна точность данных.

[Оптимистическая блокировка]: -

- Не блокирует данные при чтении, но при сохранении проверяет версию записи.
- Пример: аннотация @Version в JPA (колонка для хранения версии).
- Если версия изменилась другим потоком, выбрасывается OptimisticLockException.
- Минусы: нужно разруливать конфликты.
- Когда использовать: когда чтений много, а вероятность конфликтов низкая.

Какой подход ты чаще используешь в своих проектах?

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Задумывался, как работают ActiveMQ и RabbitMQ?

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

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

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

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

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

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

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

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

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

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
4
Почему твой бэкенд начинает тупить на 10k юзеров, хотя на 100 всё летало

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

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

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

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

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

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

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

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥112
Совет по Java: Stream.toArray(Type[]::new) это аккуратный и типобезопасный способ получить массив из стрима.

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

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍62
Вопрос для интервью по 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(https://dto.email());
https://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
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍3
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
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥51
Видел интересное видео от CTO Zerodha про то, как они масштабировали Postgres с 7+ млн таблиц.
Технология просто выносит мозг, а если копнуть глубже, становится еще веселее:

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

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

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

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯3
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
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍1
This media is not supported in your browser
VIEW IN TELEGRAM
5 часто задаваемых вопросов на собеседованиях по Java Generics.

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

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

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

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

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

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

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯101
Совет по 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
Please open Telegram to view this post
VIEW IN TELEGRAM
8
Как прогреть кэши в Spring Boot?

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

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

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

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

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

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

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

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

@SpringBootTest(useMainMethod = SpringBootTest.UseMainMethod.ALWAYS)


👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7
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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍51
Что такое 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
Please open Telegram to view this post
VIEW IN TELEGRAM
6
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
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥21
9 000₽ за вечер. Без кода. Без офиса. Без опыта.

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

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

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