Java Совет 🖥
Как понять, что Java‑код мог быть сгенерирован ИИ?
🟢 Если вы видите в коде
А
📌 Документация
✅ Java библиотека #java
Как понять, что Java‑код мог быть сгенерирован ИИ?
Collectors.toList(), а не Stream.toList() — это явный намёк 😉Stream.toList() появился только в Java 16. А
Collectors.toList() — с нами ещё с Java 8, поэтому его до сих пор полно в туториалах, на Stack Overflow и во всех датасетах, на которых обучают ИИ.Please open Telegram to view this post
VIEW IN TELEGRAM
😁18👍6❤5🔥4🎉1
Forwarded from Java Guru 🤓
Что будет результатом кода?
Anonymous Quiz
30%
10 11 12
18%
20 21 22
22%
Ошибка компиляции
12%
ConcurrentModificationException
18%
Непредсказуемый результат
👍15❤5🔥5
Ищете решение для построения масштабируемого микросервиса с использованием Event Sourcing и CQRS? AI поможет вам сгенерировать шаблон, который будет учитывать все архитектурные принципы и лучшие практики для сложных бизнес-логик.
📝 Промпт:
Generate a Spring Boot microservice that implements Event Sourcing and CQRS (Command Query Responsibility Segregation).
— Implement event storage (using EventStore or any other event-sourcing mechanism).
— Design the service layer using separate models for command and query operations.
— Use an event-driven approach with messaging (e.g., Kafka or RabbitMQ) to communicate between services.
— Secure the API with JWT authentication and role-based access control (Spring Security).
— Implement database persistence for event snapshots and projections (using Spring Data JPA).
— Добавьте
support asynchronous messaging with Kafka or RabbitMQ для обработки событий между микросервисами.— Добавьте
implement Command and Query models using CQRS для разделения логики записи и чтения данных.— Добавьте
integrate snapshotting mechanism for efficient aggregate recovery и управление состоянием событий.— Добавьте
enable monitoring and tracing with Spring Actuator and Zipkin для отслеживания производительности и запросов.Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤4🔥3
Задача:
Предположим, вы пишете сервис, в котором создаются задачи (например, отложенные действия):
public class TaskScheduler {
private final List<Runnable> tasks = new ArrayList<>();
public void scheduleTask(String name) {
String largeData = name.repeat(10_000); // имитируем большой объект
tasks.add(() -> {
System.out.println("Running task: " + name);
});
}
public void runAll() {
tasks.forEach(Runnable::run);
}
}
Теперь создайте 1_000_000 таких задач:
TaskScheduler scheduler = new TaskScheduler();
for (int i = 0; i < 1_000_000; i++) {
scheduler.scheduleTask("Task" + i);
}
Вопрос:
Почему
String largeData не освобождается сборщиком мусора, хотя он нигде явно не используется?Разбор:
На первый взгляд,
largeData нигде не используется — его можно было бы освободить. Но на самом деле лямбда-захват переменной
name удерживает весь стек метода scheduleTask, включая largeData.Это называется неявная утечка памяти через замыкания.
---
Как исправить?
Чтобы избежать утечки, выносите только нужные значения в лямбду:
public void scheduleTask(String name) {
String taskName = name; // только то, что действительно нужно
tasks.add(() -> {
System.out.println("Running task: " + taskName);
});
}
Или даже:
tasks.add(() -> System.out.println("Running task: " + name));
НО! Убедитесь, что переменные вне лямбды не держат в памяти тяжёлые объекты, которые не нужны после исполнения.
💡 Вывод:
- Java лямбды могут неявно захватывать контекст, включая большие объекты
- Это может привести к утечкам памяти, особенно в long-lived объектах (пулы задач, слушатели и т.п.)
- Профилируйте и проверяйте, что захватывает ваша лямбда
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥16👍8❤6
Для улучшения безопасности вашего приложения можно настроить фильтрацию запросов с использованием Spring Security, а также внедрить блокировку определённых IP-адресов.
В файл pom.xml добавьте следующие зависимости:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Создайте фильтр, который будет проверять IP-адрес пользователя и блокировать его, если он находится в списке запрещённых:
@Component
public class IpFilter extends OncePerRequestFilter {
private static final Set<String> blockedIps = new HashSet<>(Arrays.asList("192.168.1.100", "10.0.0.5"));
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String ipAddress = request.getRemoteAddr();
if (blockedIps.contains(ipAddress)) {
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
response.getWriter().write("Access Denied: Your IP is blocked.");
return;
}
filterChain.doFilter(request, response);
}
}
Теперь настроим Spring Security, чтобы наш фильтр IP-блокировки применялся ко всем входящим запросам:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private IpFilter ipFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/public/**").permitAll() // Доступ для публичных ресурсов
.anyRequest().authenticated() // Остальные запросы требуют аутентификации
.and()
.addFilterBefore(ipFilter, UsernamePasswordAuthenticationFilter.class); // Вставляем фильтр IP
}
}
Создадим простой контроллер с двумя маршрутами: один доступен всем пользователям, а другой требует аутентификации:
@RestController
public class TestController {
@GetMapping("/public/hello")
public String publicHello() {
return "Hello from public endpoint!";
}
@GetMapping("/private/hello")
public String privateHello() {
return "Hello from private endpoint, you are authenticated!";
}
}
Этот подход не является универсальной защитой от всех типов атак. Он помогает ограничить доступ для определённых IP-адресов, но не защищает от более сложных угроз, таких как атаки с подменой IP (например, через прокси-серверы).
Для более комплексной защиты используйте дополнительные механизмы, такие как WAF, анти-DDoS системы, а также более детальную настройку доступа через роли и права.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥5❤3
Представьте, что вы пишете in-memory кеш конфигураций. У вас есть
ConfigService, который должен:loadConfigFromDB()) 🔧 Что нужно сделать:
Реализуйте
ConfigService, который использует AtomicReference<Config> и Immutable-объекты, чтобы:1. Конфигурация всегда была консистентной
2. Потоки не блокировали друг друга
3. Обновления конфигурации были моментальными и безопасными
📦 Пример API:
class ConfigService {
public Config getCurrentConfig(); // read-only, вызывается часто
public void reload(); // обновить конфиг, редко
}
🧠 Хитрость: нельзя использовать synchronized, volatile массивы, CopyOnWrite, ReentrantLock, и т.п. — только атомарность и неизменяемость.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤3🔥3
Если обычный поиск по проекту вам тесен — попробуйте Structural Search and Replace (SSR). Это инструмент, который ищет и меняет код не по тексту, а по его структуре — как настоящий парсер.
Находит шаблоны кода в проекте с учётом синтаксиса языка. Можно искать любые конструкции — например, все System.out.println или пустые catch блоки — и сразу массово их переписывать.
— Автоматически находить антипаттерны.
— Глобально рефакторить одинаковые места.
— Быстро готовить проект к миграции или внедрению новых стандартов кодирования.
— Откройте Edit → Find → Search Structurally или нажмите Shift + Shift и введите Structural Search.
— Задайте шаблон — например, System.out.println($arg$);.
— IDEA выделит все совпадения по всей кодовой базе.
— Для массовой замены найдите в поиске Replace Structurally — можно указать новый шаблон, и IDEA всё подставит сама.
— Шаблоны можно сохранять и делиться ими с командой.
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥14👍12❤5
🌐 dnsjava — DNS-клиент и сервер на Java. Эта библиотека предлагает полную реализацию DNS-протокола с поддержкой современных стандартов — от DNSSEC и EDNS0 до TSIG-аутентификации. Проект позволяет не только выполнять запросы, но и организовывать трансфер зон, динамические обновления и даже разворачивать авторитативный сервер.
Инструмент имеет встроенный механизм валидации DNSSEC через
🖥 GitHub
✅ Java библиотека #java
Инструмент имеет встроенный механизм валидации DNSSEC через
ValidatingResolver и гибкая система конфигурации через системные свойства. Поддерживает Java 8+ и может заменять стандартный DNS-резолвер JVM. Please open Telegram to view this post
VIEW IN TELEGRAM
❤4👍4🔥2
Работаете с микросервисной архитектурой? Тогда знаете, как сложно обеспечить стабильные API-контракты между сервисами. Contract Testing решает эту проблему. А AI поможет быстро сгенерировать заготовку всей инфраструктуры для автоматизированной валидации контрактов.
📝 Промпт:
Generate a Java Spring Boot setup for contract testing using Spring Cloud Contract and Testcontainers.
— Configure a provider service and a consumer service.
— Use Spring Cloud Contract to define and verify contracts.
— Integrate with Testcontainers to run provider stubs in isolated environments.
— Add Gradle or Maven setup for running contract tests in CI.
— Provide examples for both producer and consumer side tests.
— Добавьте
integration with GitLab CI/CD or GitHub Actions для автоматической валидации контрактов при push'ах и pull request'ах.— Добавьте
generate stub JARs using Spring Cloud Contract Verifier для повторного использования контрактов на стороне потребителя.— Добавьте
handle contract mismatches gracefully with test reports and logs для быстрого выявления расхождений между сервисами и прозрачной отладки в CI.— Добавьте
include real-world example: REST endpoint for user profile with request validation and response structure как шаблон, который можно адаптировать под любую бизнес-логику.Please open Telegram to view this post
VIEW IN TELEGRAM
👍4❤3🔥2
🚀 Хочешь быстро разобраться, как использовать GraphQL с Spring Boot?
📦 Репозиторий содержит набор готовых микросервисов на Spring Boot, каждый из которых показывает разные аспекты интеграции с GraphQL: от простых запросов до работы с subnoscriptions и federated схемами.
Что внутри:
- 📌 Примеры с использованием Spring Boot 3 и GraphQL Java
- 🔗 Демонстрация схемы Federation с Apollo Gateway
- ☁️ Микросервисная архитектура + Docker Compose
- ⚙️ Использование Spring Data и JPA с GraphQL
- 🔄 Примеры запросов и мутаций через GraphiQL
Полезно как для новичков в GraphQL, так и для разработчиков, строящих продвинутые API на Spring Boot. Всё собрано и работает из коробки.
🖥 Репозиторий
📦 Репозиторий содержит набор готовых микросервисов на Spring Boot, каждый из которых показывает разные аспекты интеграции с GraphQL: от простых запросов до работы с subnoscriptions и federated схемами.
Что внутри:
- 📌 Примеры с использованием Spring Boot 3 и GraphQL Java
- 🔗 Демонстрация схемы Federation с Apollo Gateway
- ☁️ Микросервисная архитектура + Docker Compose
- ⚙️ Использование Spring Data и JPA с GraphQL
- 🔄 Примеры запросов и мутаций через GraphiQL
Полезно как для новичков в GraphQL, так и для разработчиков, строящих продвинутые API на Spring Boot. Всё собрано и работает из коробки.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤2🔥1
Если вы часто просматриваете стек вызовов или трассируете поведение методов — попробуйте «Call Hierarchy» (Ctrl + Alt + H). Этот инструмент показывает, кто вызывает ваш метод — и кто вызывает вызывающего, до самого верхнего уровня.
— Строит иерархию вызовов метода вверх или вниз.
— Помогает отследить влияние метода по всей кодовой базе.
— Работает даже с интерфейсами и абстрактными методами — покажет всех наследников.
— Находит неочевидные связи между частями кода.
— Упрощает работу с легаси: видно, какие методы безопасно менять.
— Быстро определяет, как ошибка «долетела» до нужного места.
— Поставьте курсор на метод → нажмите Ctrl + Alt + H.
— IDEA откроет дерево вызовов (Call Hierarchy).
— Вы можете «разворачивать» цепочку вверх по стеку или вниз.
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍20🔥3❤2
Проект сочетает desktop-приложение для визуальной работы и Kotlin Multiplatform библиотеку для программного взаимодействия с class-файлами. Поддерживает работу с JAR-архивами, предлагает темную тему и локализации на несколько языков.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8❤3👍2
Forwarded from Java Guru 🤓
Что будет результатом инжекта бина А?
Anonymous Quiz
18%
Выведутся сообщения: Ainitialized B initialized
7%
Приложение запустится, но "а" в В останется null.
46%
BeanCurrentlyInCreationException
5%
Будет создан только бин А
23%
Ошибка компиляции
👍7❤6🔥2
Автоматизация сборки, тестирования и деплоя — must-have даже для pet-проекта. Но настраивать GitLab CI или GitHub Actions вручную? Спросите AI — и получите готовый пайплайн, адаптированный под ваш стек.
📝 Промпт:
Generate a CI/CD pipeline for a Java Spring Boot application using GitLab CI.
— Include stages: build, test, integration-test, package, deploy.
— Use Gradle (or Maven) as the build tool.
— Include support for Docker image build and push to container registry.
— Run integration tests using Testcontainers.
— Use caching to speed up pipeline runs.
— Добавьте
environment-specific deployments: отдельные джобы для dev/stage/prod с переменными окружения, secrets и условиями по веткам (only/except или rules).— Интегрируйте
notifications в Telegram или Slack на стадии failed/success для быстрой обратной связи.— Добавьте
security scan stage: используйте Snyk или OWASP Dependency Check для анализа уязвимостей зависимостей.— Автоматизируйте
Docker image tagging: используйте Git tag или commit hash, чтобы образы были отслеживаемыми.Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤5🔥4
Основанный на принципе dependency injection, фреймворк особенно удобен для микросервисов. Достаточно добавить нужные модули через Maven и написать класс с main()-методом — приложение готово к работе без сложных настроек.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3🔥1
Правильное понимание Single Responsibility Principle (SRP)
О принципе единственной ответственности слышали все. Конечно правильный ответ согласно книги Роберта Мартина "Чистая архитектура": SRP - это принцип единой ответственности.
Но при попытке разобраться в более дательном понимании принципа его часто трактуют слишком буквально:
Да, это отчасти верно и такой принцип тоже есть, но он применяется на низшем уровне системы. SRP же применяется на более высоком уровне.
В итоге получаются сервисы, в которых вроде как всё «по SRP», но изменения в одном бизнес-сценарии ведут к каскадным правкам в десятках файлов. Это сигнал: принцип нарушен, несмотря на формальное соблюдение.
🟢 О чём на самом деле говорит SRP
В классическом изложении (по Роберту Мартину):
И под модулем понимается не метод и не даже один класс, а группа классов и интерфейсов, объединённая общим потребителем — актором.
🟢 Что это означает на практике
1. Определите акторов
Актор — это не всегда пользователь. Это может быть внешний сервис, внутренний инструмент, регламент. Важно: требования акторов не должны пересекаться. Если они меняются независимо — значит, им нужны отдельные модули.
2. Постройте модули вокруг акторов
Частая ошибка — «модуль пользователей», в котором и логика регистрации, и рассылка писем, и обработка GDPR-запросов.
Лучше разделить:
🔘 один модуль обслуживает end-user’а,
🔘 другой — юридические требования,
🔘 третий — внутреннюю админку.
3. Не дробите код ради SRP, если это нарушает целостность модуля
SRP — это не о размере, а о мотивации изменений. Метод в 100 строк, обслуживающий один сценарий, допустим. А вот класс, который реагирует на десяток независимых событий — нет.
🟢 Пример
❌ Плохо:
Этот класс изменится при любом изменении в бизнес-логике, в уведомлениях или в логировании. Три причины изменения — три актора.
✔️ Хорошо:
🔘 OrderProcessor — отвечает за бизнес-сценарий
🔘 NotificationService — отправка сообщений
🔘 AuditService — логирование
Каждый компонент обслуживает одного актора, имеет свою причину для изменений и независимую эволюцию.
🟢 Вывод
SRP стоит понимать как инструмент для проектирования архитектуры. Его задача — отделить контексты, которые меняются по разным причинам, и тем самым минимизировать связность и ограничить зону изменений. Не методы, не классы, а контексты и акторы.
✅ Java библиотека #java
О принципе единственной ответственности слышали все. Конечно правильный ответ согласно книги Роберта Мартина "Чистая архитектура": SRP - это принцип единой ответственности.
Но при попытке разобраться в более дательном понимании принципа его часто трактуют слишком буквально:
Метод должен реализовывать одну задачу
Класс должен отвечать за один функционал
Да, это отчасти верно и такой принцип тоже есть, но он применяется на низшем уровне системы. SRP же применяется на более высоком уровне.
В итоге получаются сервисы, в которых вроде как всё «по SRP», но изменения в одном бизнес-сценарии ведут к каскадным правкам в десятках файлов. Это сигнал: принцип нарушен, несмотря на формальное соблюдение.
В классическом изложении (по Роберту Мартину):
Модуль должен иметь только одну причину для изменения.
И под модулем понимается не метод и не даже один класс, а группа классов и интерфейсов, объединённая общим потребителем — актором.
1. Определите акторов
Актор — это не всегда пользователь. Это может быть внешний сервис, внутренний инструмент, регламент. Важно: требования акторов не должны пересекаться. Если они меняются независимо — значит, им нужны отдельные модули.
2. Постройте модули вокруг акторов
Частая ошибка — «модуль пользователей», в котором и логика регистрации, и рассылка писем, и обработка GDPR-запросов.
Лучше разделить:
3. Не дробите код ради SRP, если это нарушает целостность модуля
SRP — это не о размере, а о мотивации изменений. Метод в 100 строк, обслуживающий один сценарий, допустим. А вот класс, который реагирует на десяток независимых событий — нет.
public class OrderService {
public void placeOrder() { ... }
public void notifyCustomer() { ... }
public void saveAuditLog() { ... }
}Этот класс изменится при любом изменении в бизнес-логике, в уведомлениях или в логировании. Три причины изменения — три актора.
Каждый компонент обслуживает одного актора, имеет свою причину для изменений и независимую эволюцию.
SRP стоит понимать как инструмент для проектирования архитектуры. Его задача — отделить контексты, которые меняются по разным причинам, и тем самым минимизировать связность и ограничить зону изменений. Не методы, не классы, а контексты и акторы.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13👍8❤6
👨💻 Sentry для Java/Android — мониторинг ошибок в реальном времени. Этот инструмент помогает разработчикам быстро находить и исправлять ошибки в Java и Android-приложениях.
Инструмент отслеживает не только краши, но и проблемы производительности, интегрируясь с популярными библиотеками вроде Spring Boot и OkHttp. Он будет особенно полезен для команд, которые хотят улучшить стабильность мобильных и серверных приложений без лишнего ручного тестирования. Поддерживает нативный код через NDK.
🖥 GitHub
✅ Java библиотека #java
Инструмент отслеживает не только краши, но и проблемы производительности, интегрируясь с популярными библиотеками вроде Spring Boot и OkHttp. Он будет особенно полезен для команд, которые хотят улучшить стабильность мобильных и серверных приложений без лишнего ручного тестирования. Поддерживает нативный код через NDK.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4👍4🔥2
Как создать идеальную внутреннюю платформу для разработчиков:
опыт MWS Cloud Platform⬜️
В новой статье на Хабре инженер MWS рассказал, как построить эффективную команду Development Platform.
Автор поделился ключевыми принципами, которые помогут:
➡️ Наладить взаимодействие между инфраструктурными и продуктовыми командами
➡️ Минимизировать техдолг
➡️ Создать культуру общего кода
⏩️ Читать статью
опыт MWS Cloud Platform
В новой статье на Хабре инженер MWS рассказал, как построить эффективную команду Development Platform.
Автор поделился ключевыми принципами, которые помогут:
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3❤2🔥2