Please open Telegram to view this post
VIEW IN TELEGRAM
😁29💯5🔥3
State Machine Pattern для AI-агентов
Джависты знают: сложная бизнес-логика требует управления состоянием. В мире LLM хаос
Зачем это в Enterprise:
— предсказуемость: вы жёстко задаёте граф переходов;
— persistence: состояние агента можно сохранить в БД (Postgres) и восстановить при падении;
— type safety: контроль структуры данных между шагами.
Курс по архитектуре агентов уже стартовал.
Записаться на курс
Сомневаетесь? Гляньте первую лекцию — там база про устройство современных агентов.
Джависты знают: сложная бизнес-логика требует управления состоянием. В мире LLM хаос
LangChain сменился строгой структурой LangGraph. По сути, это реализация Finite State Machine, где переходы определяет нейросеть.Зачем это в Enterprise:
— предсказуемость: вы жёстко задаёте граф переходов;
— persistence: состояние агента можно сохранить в БД (Postgres) и восстановить при падении;
— type safety: контроль структуры данных между шагами.
Курс по архитектуре агентов уже стартовал.
Записаться на курс
Сомневаетесь? Гляньте первую лекцию — там база про устройство современных агентов.
❤10
🎧 Что послушать — #подкаст Javaswag #84
🔹 Ведущий: Дмитрий Волыхин
🔹 Гость: Иван Лягаев
🔹 Продолжительность: 1 час 50 минут
Иван рассказывает о Scala, её применении в банковской сфере, системе эффектов, платформенных задачах и кодогенерации. Также обсуждаются переходы между языками программирования, виртуальные потоки в Java, AI-ассистенты и работа с монорепозиториями.
🔹 Ключевые темы выпуска
04:36 — Парадигмы программирования
16:00 — Система эффектов в Scala
22:38 — Scala в банке
27:21 — Типичный Scala-сервис
33:17 — HTTP библиотеки
37:13 — Трассировка и мониторинг
44:37 — Контекст
49:30 — Переходы между языками программирования
51:54 — Type Class в Scala
57:13 — Java и Kotlin
01:00:38 — Проблемы, Сообщество и Scala
01:07:41 — Доклад о виртуальных потоках в Java
01:16:34 — ТехДолг
01:21:02 — Генерация клиентов и спецификаций API
01:29:16 — Кодогенерация
01:31:06 — Монорепозитории и многорепозитории
01:35:42 — Платформенные задачи
01:38:04 — AI-ассистенты
01:45:15 — Непопулярное мнение
🔗 Слушать выпуск
🐸 Библиотека джависта
#DevLife
🔹 Ведущий: Дмитрий Волыхин
🔹 Гость: Иван Лягаев
🔹 Продолжительность: 1 час 50 минут
Иван рассказывает о Scala, её применении в банковской сфере, системе эффектов, платформенных задачах и кодогенерации. Также обсуждаются переходы между языками программирования, виртуальные потоки в Java, AI-ассистенты и работа с монорепозиториями.
🔹 Ключевые темы выпуска
04:36 — Парадигмы программирования
16:00 — Система эффектов в Scala
22:38 — Scala в банке
27:21 — Типичный Scala-сервис
33:17 — HTTP библиотеки
37:13 — Трассировка и мониторинг
44:37 — Контекст
49:30 — Переходы между языками программирования
51:54 — Type Class в Scala
57:13 — Java и Kotlin
01:00:38 — Проблемы, Сообщество и Scala
01:07:41 — Доклад о виртуальных потоках в Java
01:16:34 — ТехДолг
01:21:02 — Генерация клиентов и спецификаций API
01:29:16 — Кодогенерация
01:31:06 — Монорепозитории и многорепозитории
01:35:42 — Платформенные задачи
01:38:04 — AI-ассистенты
01:45:15 — Непопулярное мнение
#DevLife
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4❤1🔥1👏1
🔧 Spring Boot Actuator: кастомные health indicators для мониторинга
В production приложениях часто недостаточно стандартных health checks от Spring Boot. Например, нужно проверить доступность внешнего API, очереди сообщений или специфичную бизнес-логику.
🔹 Решение
▪️ Создание custom health indicator
▪️ Настройка в application.yml
После добавления индикатор автоматически появится в /actuator/health. Spring вызывает метод health() при каждом запросе к endpoint'у. Можно добавить кеширование через @Cacheable с TTL 30-60 секунд, чтобы снизить нагрузку на внешние системы.
⚠️ Убедитесь, что /actuator/health доступен только для систем мониторинга (Prometheus, Kubernetes liveness probe), а не публично.
══════ Навигация ══════
Вакансии • Задачи • Собесы
🐸 Библиотека джависта
#Enterprise
В production приложениях часто недостаточно стандартных health checks от Spring Boot. Например, нужно проверить доступность внешнего API, очереди сообщений или специфичную бизнес-логику.
🔹 Решение
▪️ Создание custom health indicator
@Component
public class ExternalApiHealthIndicator implements HealthIndicator {
private final RestTemplate restTemplate;
private final String apiUrl;
@Override
public Health health() {
try {
ResponseEntity<String> response = restTemplate
.getForEntity(apiUrl + "/health", String.class);
if (response.getStatusCode().is2xxSuccessful()) {
return Health.up()
.withDetail("endpoint", apiUrl)
.withDetail("responseTime", "120ms")
.build();
}
return Health.down()
.withDetail("endpoint", apiUrl)
.withDetail("status", response.getStatusCode())
.build();
} catch (Exception e) {
return Health.down()
.withDetail("error", e.getMessage())
.withException(e)
.build();
}
}
}
▪️ Настройка в application.yml
management:
endpoint:
health:
show-details: always
health:
defaults:
enabled: true
После добавления индикатор автоматически появится в /actuator/health. Spring вызывает метод health() при каждом запросе к endpoint'у. Можно добавить кеширование через @Cacheable с TTL 30-60 секунд, чтобы снизить нагрузку на внешние системы.
══════ Навигация ══════
Вакансии • Задачи • Собесы
#Enterprise
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤1🔥1👏1
Stateful Architecture: как это работает в AI
Java-разработчики знают цену управлению состоянием. В мире AI к этому пришли только сейчас с появлением
Вместо хаотичных скриптов теперь строят графы, где состояние передаётся явно, как контекст в Spring. Это позволяет создавать надёжных агентов с долгосрочной памятью и транзакционной логикой выполнения задач.
На курсе разбираем эти паттерны. Даже если пишете на Java, понимание архитектуры агентов — мастхэв для интеграции AI в энтерпрайз.
Записаться на курс
Смотрите вводный урок бесплатно (про архитектуру и графы).
Java-разработчики знают цену управлению состоянием. В мире AI к этому пришли только сейчас с появлением
LangGraph.Вместо хаотичных скриптов теперь строят графы, где состояние передаётся явно, как контекст в Spring. Это позволяет создавать надёжных агентов с долгосрочной памятью и транзакционной логикой выполнения задач.
На курсе разбираем эти паттерны. Даже если пишете на Java, понимание архитектуры агентов — мастхэв для интеграции AI в энтерпрайз.
Записаться на курс
Смотрите вводный урок бесплатно (про архитектуру и графы).
📌 6 принципов безопасности API
API — это не просто интерфейс, а ворота в вашу систему. Без должной защиты они становятся уязвимой точкой для атак.
🔐 Ключевые принципы безопасности API
— Использование HTTPS
— Аутентификация и авторизация
— Ограничение запросов
— Валидация входных данных
— Управление доступом на основе ролей (RBAC)
— Мониторинг и логирование
🔗 Подробнее в статье
══════ Навигация ══════
Вакансии • Задачи • Собесы
🐸 Библиотека джависта
#CoreJava
API — это не просто интерфейс, а ворота в вашу систему. Без должной защиты они становятся уязвимой точкой для атак.
🔐 Ключевые принципы безопасности API
— Использование HTTPS
— Аутентификация и авторизация
— Ограничение запросов
— Валидация входных данных
— Управление доступом на основе ролей (RBAC)
— Мониторинг и логирование
══════ Навигация ══════
Вакансии • Задачи • Собесы
#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥1👏1
Где вы пишете свой прекрасный код? ☕️
Anonymous Poll
89%
IntelliJ IDEA
1%
Eclipse
6%
VS Code
0%
NetBeans
0%
Vim/Emacs
3%
Блокнот
😁13🤔2🔥1
useful-java-links — там собраны лучшие материалы по Java. В репозитории найдёте библиотеки, фреймворки, инструменты и образовательные материалы по разным направлениям
🔹 Отдельный акцент сделан на решениях для работы с СУБД, поисковиками, технологиями обработки больших данных и ML. Список регулярно пополняется новыми ссылками и остаётся актуальным.
══════ Навигация ══════
Вакансии • Задачи • Собесы
#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥4👏1
Please open Telegram to view this post
VIEW IN TELEGRAM
😁29🔥2❤1👍1
🔐 Spring Security 6 + JWT: Полная настройка за 10 минут
Настраиваем современную аутентификацию с JWT токенами в Spring Boot 3.x.
Шаг 1: Зависимости
Шаг 2: JWT Service
Настраиваем современную аутентификацию с JWT токенами в Spring Boot 3.x.
Шаг 1: Зависимости
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.12.3</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.12.3</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.12.3</version>
<scope>runtime</scope>
</dependency>
</dependencies>
Шаг 2: JWT Service
@Service
public class JwtService {
@Value("${jwt.secret}")
private String secretKey;
@Value("${jwt.expiration}")
private long jwtExpiration;
private Key getSigningKey() {
byte[] keyBytes = Decoders.BASE64.decode(secretKey);
return Keys.hmacShaKeyFor(keyBytes);
}
public String generateToken(UserDetails userDetails) {
Map<String, Object> claims = new HashMap<>();
claims.put("authorities", userDetails.getAuthorities()
.stream()
.map(GrantedAuthority::getAuthority)
.toList());
return Jwts.builder()
.claims(claims)
.subject(userDetails.getUsername())
.issuedAt(new Date())
.expiration(new Date(System.currentTimeMillis() + jwtExpiration))
.signWith(getSigningKey())
.compact();
}
public String extractUsername(String token) {
return extractClaim(token, Claims::getSubject);
}
public <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {
final Claims claims = extractAllClaims(token);
return claimsResolver.apply(claims);
}
private Claims extractAllClaims(String token) {
return Jwts.parser()
.verifyWith((SecretKey) getSigningKey())
.build()
.parseSignedClaims(token)
.getPayload();
}
public boolean isTokenValid(String token, UserDetails userDetails) {
final String username = extractUsername(token);
return username.equals(userDetails.getUsername())
&& !isTokenExpired(token);
}
private boolean isTokenExpired(String token) {
return extractExpiration(token).before(new Date());
}
private Date extractExpiration(String token) {
return extractClaim(token, Claims::getExpiration);
}
}
❤6👍4🔥1
Шаг 3: JWT Authentication Filter
Шаг 4: Security Configuration
Шаг 5: Application Configuration
@Component
@RequiredArgsConstructor
public class JwtAuthenticationFilter extends OncePerRequestFilter {
private final JwtService jwtService;
private final UserDetailsService userDetailsService;
@Override
protected void doFilterInternal(
@NonNull HttpServletRequest request,
@NonNull HttpServletResponse response,
@NonNull FilterChain filterChain
) throws ServletException, IOException {
final String authHeader = request.getHeader("Authorization");
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
filterChain.doFilter(request, response);
return;
}
final String jwt = authHeader.substring(7);
final String username = jwtService.extractUsername(jwt);
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
if (jwtService.isTokenValid(jwt, userDetails)) {
UsernamePasswordAuthenticationToken authToken =
new UsernamePasswordAuthenticationToken(
userDetails,
null,
userDetails.getAuthorities()
);
authToken.setDetails(
new WebAuthenticationDetailsSource().buildDetails(request)
);
SecurityContextHolder.getContext().setAuthentication(authToken);
}
}
filterChain.doFilter(request, response);
}
}
Шаг 4: Security Configuration
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
@RequiredArgsConstructor
public class SecurityConfig {
private final JwtAuthenticationFilter jwtAuthFilter;
private final AuthenticationProvider authenticationProvider;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/auth/**").permitAll()
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
.sessionManagement(session -> session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.authenticationProvider(authenticationProvider)
.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}
Шаг 5: Application Configuration
@Configuration
@RequiredArgsConstructor
public class ApplicationConfig {
private final UserRepository userRepository;
@Bean
public UserDetailsService userDetailsService() {
return username -> userRepository.findByEmail(username)
.orElseThrow(() -> new UsernameNotFoundException("User not found"));
}
@Bean
public AuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService());
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration config)
throws Exception {
return config.getAuthenticationManager();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
👍6❤4🔥2
Шаг 6: Auth Controller
Шаг 7: application.yml
Важно: генерируйте JWT_SECRET через Jwts.SIG.HS512.key().build() и храните в переменных окружения!
══════ Навигация ══════
Вакансии • Задачи • Собесы
🐸 Библиотека джависта
#Enterprise
@RestController
@RequestMapping("/api/auth")
@RequiredArgsConstructor
public class AuthController {
private final AuthenticationManager authenticationManager;
private final JwtService jwtService;
private final UserDetailsService userDetailsService;
@PostMapping("/login")
public ResponseEntity<AuthResponse> login(@RequestBody AuthRequest request) {
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
request.email(),
request.password()
)
);
UserDetails user = userDetailsService.loadUserByUsername(request.email());
String token = jwtService.generateToken(user);
return ResponseEntity.ok(new AuthResponse(token));
}
}
Шаг 7: application.yml
jwt:
secret: ${JWT_SECRET}
expiration: 86400000 # 24 hours
spring:
security:
filter:
dispatcher-types: REQUEST, ERROR, ASYNC
Важно: генерируйте JWT_SECRET через Jwts.SIG.HS512.key().build() и храните в переменных окружения!
══════ Навигация ══════
Вакансии • Задачи • Собесы
#Enterprise
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12❤6🔥3🥱1
Forwarded from Библиотека собеса по Java | вопросы с собеседований
readOnly = true — это
Что происходит:
—
—
—
Важно: это
#spring
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥2❤1👏1
🔥 Топ-10 интересных ошибок в реальных проектах
PVS-Studio собрали подборку самых интересных багов 2025 года из крупных Open Source проектов.
Тут есть всё: неочевидные языковые нюансы, которые ломают логику, ошибки из-за особенностей инициализации, проблемы с типами там, где их не ждёшь. Каждая ошибка разобрана с примерами кода и объяснением, почему она возникла.
Особенно понравится тем, кто любит копаться в деталях языка и понимать, как на самом деле работает JVM под капотом.
🔗 Читать на Habr
══════ Навигация ══════
Вакансии • Задачи • Собесы
🐸 Библиотека джависта
#CoreJava
PVS-Studio собрали подборку самых интересных багов 2025 года из крупных Open Source проектов.
Тут есть всё: неочевидные языковые нюансы, которые ломают логику, ошибки из-за особенностей инициализации, проблемы с типами там, где их не ждёшь. Каждая ошибка разобрана с примерами кода и объяснением, почему она возникла.
Особенно понравится тем, кто любит копаться в деталях языка и понимать, как на самом деле работает JVM под капотом.
══════ Навигация ══════
Вакансии • Задачи • Собесы
#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
😁5👍2🔥1
Наш подписчик спрашивает:
Вопрос к сообществу. Начальство загорелось идеей прикрутить к проекту AI. Проект на Spring Boot 3, Java 21. Юзал кто Spring AI? Подводные камни, баги, альтернативы?
Фреймворк на первый взгляд удобный, но я наткнулся на статью, где разраб жалуется, что между версиями меняются даже названия пакетов. Код с октября уже не работает. Примеры в интернете все разные в зависимости от даты написания.
P.S. Если хотите задать вопрос, заполните нашу гугл-форму. Это займет 5 минут.
#DevLife
Please open Telegram to view this post
VIEW IN TELEGRAM
😁8👍1🔥1
Java-разработчик — от 250 000 ₽ — офис (Екатеринбург)
Java-developer Middle/Middle+ — удалёнка
Java разработчик (senior) — удалёнка
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥1👏1
Please open Telegram to view this post
VIEW IN TELEGRAM
😁28💯4👍2
В статье рассмотрены 3 подхода к построению API. Также автор показывает, как объединить gRPC и GraphQL, чтобы фронт получал гибкие запросы, а бэк получал скорость и эффективность.
══════ Навигация ══════
Вакансии • Задачи • Собесы
#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥2❤1👏1
Forwarded from Библиотека задач по Java | тесты, код, задания
Что будет результатом кода?
Anonymous Quiz
14%
NPE
59%
a
6%
null
16%
Ошибка компиляции
4%
Посмотреть ответ
👍8🔥2
Когда проект разрастается до десятков микросервисов, появляется ряд вопросов, которые не возникают, если у тебя монолит:
— Как сервису А узнать, где сейчас живёт сервис Б (тем более, если адреса постоянно меняются)?
— Как не утонуть в километрах кода для HTTP-запросов?
— Как фронтенду работать с этой кучей сервисов?
Для этого есть три главных инструмента.
В облаке сервисы постоянно перезапускаются, меняют IP-адреса и порты. Хардкодить http://localhost:8082 не вариант.
Eureka Server работает как справочная служба
🔹 При старте каждый сервис стучится в Eureka: «Я на связи, вот мой адрес».
🔹 Когда сервису А нужно достучаться до Б, он обращается к Eureka: «Подскажи, где сейчас сервис Б».
Нужно добавить аннотацию
@EnableDiscoveryClient для работы Eureka. Сервисы будут находить друг друга по имени, а не по IP.Для отправки запросов между сервисами можно использовать RestTemplate. Но код получается довольно громоздким и не типизированным.
Вместо этого можно использовать Feign. Он позволяет вызывать удаленный REST-сервис так, будто это обычный метод интерфейса. А вся реализация генерируется под капотом.
@FeignClient(name = "account-service") // Имя сервиса в Eureka
public interface AccountClient {
@GetMapping("/account/{userId}")
List<Account> getAccount(@PathVariable Long userId);
}
// Использование в сервисе:
List<Account> accounts = accountClient.getAccount(13L);
Теперь следующая проблема: сервисы между собой нормально общаются, а вот фронт всё ещё не знает кому точно отправлять запрос. Можно сложить на фронт адреса каждого сервиса, но это сложно и небезопасно.
Тут на помощь и приходит Spring Cloud Gateway. Он выступает как КПП. Фронт стучится только в него, а он уже сам разруливает запрос к нужным сервисам.
Например: запросы на /users/** идут в UserService.
🔹 Что он делает
— Маршрутизация: смотрит на путь запроса и решает, в какой именно сервис его отправить.
— Безопасность: проверяет JWT токен один раз на входе.
— Rate Limiting: защита от спама (например, максимум 10 запросов в секунду с одного IP).
1. Сервисы стартуют и сообщают Eureka о себе.
2. Фронт отправляет запрос в Gateway.
3. Gateway узнаёт у Eureka, где живёт нужный сервис, и перенаправляет запрос.
4. Когда сервисам нужно поговорить друг с другом, в дело вступает Feign.
══════ Навигация ══════
Вакансии • Задачи • Собесы
#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🔥3❤1👏1