Вопрос для интервью по Java Spring Boot:
С тех пор как AI начал активно залезать в мир разработки, паттерны на собеседованиях меняются.
Тренд, который я недавно наблюдал: дают сниппет кода, и ты должен его проревьюить и отрефакторить логику под прод.
[Дано]:
Команда написала логику отправки письма после регистрации пользователя. На проде иногда бывает ситуация: письма приходят, а пользователя в базе нет. Найди проблему и почини:
[Задачи]:
- Объясни, в каком сценарии письмо будет отправлено, но пользователь не сохранится
- Исправь код так, чтобы событие обрабатывалось только после того, как пользователь сохранён
Код:
👉 Java Portal
@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();
}
}
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4👍3
Ищу хороший репозиторий с Claude skills для Java, Spring Boot и т.п. Нашёл вот этот: https://github.com/decebals/claude-code-java.
👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
GitHub
GitHub - decebals/claude-code-java: Reusable AI development infrastructure for Java projects, optimized for Claude Code
Reusable AI development infrastructure for Java projects, optimized for Claude Code - decebals/claude-code-java
🔥4💊2😁1
Spring Boot:
1.
2.
3. Никакого Tomcat (и других встроенных серверов).
4. Запросы выполняются внутри через
👉 Java Portal
@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.Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5❤2
Видел интересное видео от CTO Zerodha про то, как они масштабировали Postgres с 7+ млн таблиц.
Технология просто выносит мозг, а если копнуть глубже, становится еще веселее:
- синхронщина? не масштабируется, значит выкидываем.
- все в async. тяжелую генерацию отчетов ставим в очередь.
- независимый middleware, которому все равно на базу и на приложение.
- собрали “DungBeetle” на Go: обобщенные, независимые от СУБД HTTP API, чтобы тянуть отчеты из любой базы.
- результаты сливаем в отдельную Results DB, а приложение читает уже оттуда.
Вот так выглядит настоящий масштаб.
Смотреть видео
👉 Java Portal
Технология просто выносит мозг, а если копнуть глубже, становится еще веселее:
- синхронщина? не масштабируется, значит выкидываем.
- все в async. тяжелую генерацию отчетов ставим в очередь.
- независимый middleware, которому все равно на базу и на приложение.
- собрали “DungBeetle” на Go: обобщенные, независимые от СУБД HTTP API, чтобы тянуть отчеты из любой базы.
- результаты сливаем в отдельную Results DB, а приложение читает уже оттуда.
Вот так выглядит настоящий масштаб.
Смотреть видео
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯3
Java tip: Начиная с Java 12 можно использовать
✅ Добавление пробелов:
✅ Удаление пробелов:
👉 Java Portal
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));
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2👍1
This media is not supported in your browser
VIEW IN TELEGRAM
5 часто задаваемых вопросов на собеседованиях по Java Generics.
На сколько из них ты сможешь ответить?
1. В чем разница между
2. В чем разница между
3. В чем разница между
4. Можно ли добавлять элементы в
5. Чем
👉 Java Portal
На сколько из них ты сможешь ответить?
1. В чем разница между
Object<?> и Object в Java?2. В чем разница между
List<?> и List<Object>?3. В чем разница между
List<? extends Number> и List<? super Number>?4. Можно ли добавлять элементы в
List<?>?5. Чем
T отличается от ? в дженериках?Please open Telegram to view this post
VIEW IN TELEGRAM
🤯10❤2
Совет по Spring Boot: со Spring Boot и Spring Security ты можешь легко защитить эндпоинты.
✅ Чтобы защитить следующий REST-эндпоинт:
✅ Можно написать такую конфигурацию:
-
-
-
-
👉 Java Portal
@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.Please open Telegram to view this post
VIEW IN TELEGRAM
❤9
Как прогреть кэши в Spring Boot?
Или вообще как выполнить что-то на старте Spring Boot приложения?
Обычно такие операции делают в
Если “прогрев” находится в
Более элегантный способ “прогреть кэши”
Смотри:
Код выглядит как на картинке:
Плюс: В интеграционных тестах с
Когда “прогрев” все-таки нужен в тестах, добавляем параметр
👉 Java Portal
Или вообще как выполнить что-то на старте Spring Boot приложения?
Обычно такие операции делают в
@PostConstruct или подписываются на событие ApplicationReadyEvent. Но у этих вариантов есть заметный минус.Если “прогрев” находится в
@PostConstruct, как отключить его в тестах? Можно добавить флаг, сделать сабкласс и подменить его в тестовой конфигурации, но это не всегда помогает и часто выглядит как костыль.Более элегантный способ “прогреть кэши”
Смотри:
SpringApplication.run(...) возвращает полностью готовый контекст. Можно достать из него компонент и вызвать нужный метод “прогрева”.Код выглядит как на картинке:
Плюс: В интеграционных тестах с
@SpringBootTest метод main не запускается. Соответственно, код внутри него не выполняется. Никаких костылей вокруг @PostConstruct, все чисто и красиво.Когда “прогрев” все-таки нужен в тестах, добавляем параметр
use main method:@SpringBootTest(useMainMethod = SpringBootTest.UseMainMethod.ALWAYS)
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7❤1
Java: используй
1. Read lock (лок на чтение): позволяет нескольким потокам читать одновременно, пока ни один поток не пишет.
2. Write lock (лок на запись): позволяет писать только одному потоку и блокирует всех остальных читателей и писателей, пока лок не будет освобожден.
Используй
1. Твой код часто читает разделяемые данные.
2. Записи происходят редко.
3. Ты хочешь выжать максимум параллелизма: разрешить нескольким читателям работать одновременно, но гарантировать, что запись идет строго эксклюзивно.
Пример:
👉 Java Portal
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();
}
}
}Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤2
Что такое BeanPostProcessor в Java Spring Boot?
Это интерфейс, который позволяет вмешиваться в процесс создания и инициализации бинов в Spring-контейнере.
Он предоставляет два основных метода, которые вызываются на разных этапах жизненного цикла бина:
1.
Вызывается до инициализации бина (до вызова метода с
2.
Вызывается после инициализации бина (после того, как все методы инициализации завершились).
Зачем нужен BeanPostProcessor?
Он используется для дополнительной обработки и кастомизации бинов после их создания, но до того, как они будут переданы клиентскому коду.
Примеры:
- Добавление проксирования бинов (например, для AOP или транзакций)
- Валидация или изменение свойств бина
- Логирование жизненного цикла
- Добавление кастомных аннотаций
- Обработка marker-интерфейсов
Как это работает?
1. Spring сканирует контекст на наличие бинов, которые реализуют интерфейс
2. Если такие бины найдены, они применяются ко всем бинам в приложении.
3. Методы
👉 Java Portal
Это интерфейс, который позволяет вмешиваться в процесс создания и инициализации бинов в 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.Please open Telegram to view this post
VIEW IN TELEGRAM
❤7
Java-совет: начиная с Java 9 можно использовать
👉 Java Portal
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]
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2🔥2
9 000₽ за вечер. Без кода. Без офиса. Без опыта.
Именно столько платят за одного чат-бота для бизнеса начинающим спецам.
Берёшь шаблон → собираешь бота → сдаёшь клиенту. Первые деньги — в первую же неделю.
Показываю, как новичку делать чат-ботов для бизнеса за дорого:
👉 @other_digital_bot
Именно столько платят за одного чат-бота для бизнеса начинающим спецам.
Берёшь шаблон → собираешь бота → сдаёшь клиенту. Первые деньги — в первую же неделю.
Показываю, как новичку делать чат-ботов для бизнеса за дорого:
👉 @other_digital_bot
❤3😁3🌭1
Я побывал по обе стороны собеседований по 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
Ниже темы, которые нужно изучить, чтобы действительно хорошо в этом разбираться:
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
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7
Совет по Spring Boot: ускорить приложение можно с помощью
🟢 Позволяет избежать повторных вызовов к БД и API
🟢 Снижает задержки
🟢 По умолчанию Spring использует in-memory map, но в проде можно подключить внешний провайдер кеша
👉 Java Portal
@EnableCaching и @Cacheable.Please open Telegram to view this post
VIEW IN TELEGRAM
❤1👍1
API Gateway, если по-человечески:
Клиент не должен ходить в 6 разных сервисов.
Он должен ходить в одну точку.
Gateway стоит перед всей системой и берёт на себя:
- маршрутизацию входящих запросов в нужный сервис
- валидацию токенов, например JWT и OAuth, ещё до того, как запрос вообще дойдёт до сервисов
- rate limiting, чтобы API не абьюзили
- логирование, чтобы наблюдаемость была в одном месте
- балансировку нагрузки между инстансами сервисов
Без gateway каждый сервис заново городит у себя аутентификацию, логирование и rate limiting.
С gateway всё это решается один раз, централизованно.
Вот и вся суть: одна точка входа и единый слой контроля.
👉 Java Portal
Клиент не должен ходить в 6 разных сервисов.
Он должен ходить в одну точку.
Gateway стоит перед всей системой и берёт на себя:
- маршрутизацию входящих запросов в нужный сервис
- валидацию токенов, например JWT и OAuth, ещё до того, как запрос вообще дойдёт до сервисов
- rate limiting, чтобы API не абьюзили
- логирование, чтобы наблюдаемость была в одном месте
- балансировку нагрузки между инстансами сервисов
Без gateway каждый сервис заново городит у себя аутентификацию, логирование и rate limiting.
С gateway всё это решается один раз, централизованно.
Вот и вся суть: одна точка входа и единый слой контроля.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤1