Java Portal | Программирование
13.1K subscribers
1.18K photos
99 videos
37 files
1.09K links
Присоединяйтесь к нашему каналу и погрузитесь в мир для Java-разработчика

Связь: @devmangx

РКН: https://clck.ru/3H4WUg
Download Telegram
Когда ты уже не джун и даже не мидл, на собеседованиях по Java почти не задают вопросы в стиле «что такое HashMap». В ход идут сценарии из реальной жизни.

Разберём типичный кейс.

Твой сервис — оркестратор. Он дергает несколько downstream-сервисов, чтобы обработать запрос.
Один из них проблемный: медленный и периодически отвечает 503 Service Unavailable.

1. Как сделать сервис устойчивым к ненадёжному downstream

Первое, что здесь просится » Circuit Breaker.

Идея простая: если зависимый сервис начинает фейлиться, мы перестаём его дёргать, чтобы:

- не тратить ресурсы,
- не увеличивать латентность,
- не убивать весь сервис каскадными таймаутами.

Реализация с Resilience4j:

Подключаем зависимость и оборачиваем вызов проблемного сервиса в CircuitBreaker.

Ключевые состояния:

Всё нормально. Запросы проходят. Ошибки считаются.

Порог ошибок превышен. Все вызовы сразу фейлятся, downstream даже не вызывается.

Пробный режим. Ограниченное число запросов, чтобы проверить — ожил сервис или нет.

Пример:

@CircuitBreaker(name = "inventoryService", fallbackMethod = "inventoryFallback")
public InventoryResponse getInventory(String productId) {
return inventoryClient.getInventory(productId);
}


Конфиг обычно задаётся через application.yml:

- процент ошибок
- sliding window
- waitDurationInOpenState
- permittedNumberOfCallsInHalfOpenState

2. Что делать, когда circuit открыт (fallback)

Тут нет универсального ответа » зависит от бизнеса.

Типовые варианты:

🔹Кэш

Если данные не критичны к свежести:

- Redis
- локальный cache
- stale-данные лучше, чем 503

private InventoryResponse inventoryFallback(String productId, Throwable ex) {
return cacheService.getInventory(productId);
}


🔹Дефолтный ответ

Если можно вернуть «безопасное» значение:

- пустой список
- available = false
- статус UNKNOWN

🔹Очередь

Если запрос важен, но не срочный:

- кладём событие в Kafka / Rabbit
- обрабатываем асинхронно
- отвечаем клиенту 202 Accepted

На практике часто комбинируют:
кэш + деградация функциональности.

3. Глобальная обработка ошибок через @RestControllerAdvice

Чтобы не размазывать try/catch по всему коду, делаем централизованный обработчик.

Пример бизнес-исключения

public class ProductNotFoundException extends RuntimeException {
public ProductNotFoundException(String id) {
super("Product not found: " + id);
}
}


Глобальный handler

@RestControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(ProductNotFoundException.class)
public ResponseEntity<ErrorResponse> handleProductNotFound(ProductNotFoundException ex) {
ErrorResponse error = new ErrorResponse(
"PRODUCT_NOT_FOUND",
ex.getMessage()
);
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
}
}

JSON-ответ
{
"code": "PRODUCT_NOT_FOUND",
"message": "Product not found: 123"
}


Плюсы подхода:

- чистые контроллеры
- единый формат ошибок
- нормальная мапа бизнес-ошибок на HTTP-статусы

Итог

На таком вопросе проверяют не знание аннотаций, а мышление:

- понимаешь ли ты отказоустойчивость
- умеешь ли деградировать сервис
- разделяешь ли бизнес-ошибки и технические фейлы

Это уже разговор не про «Java», а про архитектуру продакшн-сервисов

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍114
Spring Boot наконец получил нативную поддержку gRPC

Забудьте о сторонних стартерах и костылях — Spring gRPC 1.0 GA уже здесь. Теперь можно строить высокопроизводительные RPC-сервисы с Protocol Buffers прямо из коробки, без плясок с бубном.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
9
Kubernetes-совет:

Java-приложения обычно требуют больше CPU на старте, чем во время обычной работы ☕️

Эта политика Kyverno:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: resize-pod-policy
spec:
mutateExistingOnPolicyUpdate: false
rules:
- name: resize-pod-policy
match:
any:
- resources:
kinds:
- Pod/status
- Pod
preconditions:
all:
- key: "{{request.object.status.containerStatuses[0].ready}}"
operator: Equals
value: true
mutate:
targets:
- apiVersion: v1
kind: Pod.resize
name: "{{request.object.iss.onetadata.name}}"
patchStrategicMerge:
spec:
containers:
- (name): sample-app-on-kubernetes
resources:
limits:
cpu: 0.5


- отслеживает момент завершения старта pod’а
- обновляет ресурсы pod’а прямо на месте
- снижает CPU-лимиты после старта

Итог: более быстрый запуск и меньшие затраты

Вот моя статья об этом

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔62👍1
Java-совет: избегайте глубоко вложенных if/else.

Используйте guard clauses (ранние выходы из метода) вместо этого.

 Вложенные if-else:

public void processOrder(Order order) {
if (order != null) {
if (order.isPaid()) {
if (order.getItems().size() > 0) {
// Обработка заказа
System.out.println("Заказ обработан");
} else {
System.out.println("В заказе нет позиций");
}
} else {
System.out.println("Заказ не оплачен");
}
} else {
System.out.println("Заказ равен null");
}
}

Использование guard clauses (читается проще):

public void processOrder(Order order) {
if (order == null) {
System.out.println("Заказ равен null");
return;
}

if (!order.isPaid()) {
System.out.println("Заказ не оплачен");
return;
}

if (order.getItems().isEmpty()) {
System.out.println("В заказе нет позиций");
return;
}

// Обработка заказа
System.out.println("Заказ обработан");


👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍94
🔴 Завтра тестовое собеседование с Java-разработчиком

24 декабря(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.

Как это будет:
📂 Сергей Чамкин, старший разработчик из Uzum, ex-WildBerries, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Cергей будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Сергею

Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.

Переходи в нашего бота, чтобы получить ссылку на эфир →
@shortcut_sh_bot

Реклама.
О рекламодателе.
Please open Telegram to view this post
VIEW IN TELEGRAM
1
Создаём первый Minecraft мод и подробно разбираем Mixin. Просто и понятно

Эта статья была написана из-за отсутствия адекватных русскоязычных руководств по моддингу, особенно для новых версий Minecraft. То, что описано в статье, будет применимо для таких загрузчиков модов, как Fabric и Forge, а также для реализации различных функций.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
14👍3🔥1
Spring Boot: для новых приложений выбирайте WebClient вместо RestTemplate

~ Реактивный и неблокирующий
~ Работает на event-loop, а не на модели один поток на запрос
~ Отлично подходит для микросервисной архитектуры

 RestTemplate (blocking)

@Service
public class ItemService {

private final RestTemplate restTemplate;

public ItemService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}

public Item getItem(Long id) {
return restTemplate.getForObject(
"https://api.example.com/items/{id}",
Item.class,
id
);
}
}

WebClient (non-blocking)

@Service
public class ItemService {

private final WebClient webClient;

public ItemService(WebClient webClient) {
this.webClient = webClient;
}

public Mono<Item> getItem(Long id) {
return webClient.get()
.uri("/items/{id}", id)
.retrieve()
.bodyToMono(Item.class);
}
}


👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍75
This media is not supported in your browser
VIEW IN TELEGRAM
Если у тебя Spring Boot приложение подключено как вложенный модуль и оно использует поддержку Docker Compose, то в IntelliJ IDEA нужно задать MODULE_WORKING_DIRECTORY, чтобы среда смогла корректно определить, где лежит файл compose.yaml.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍62
Spring Boot: можно добавить глобальные метаданные OpenAPI с помощью аннотации @OpenAPIDefinition.

Размести её на главном классе приложения Spring Boot или в отдельном конфигурационном классе.

@SpringBootApplication
@OpenAPIDefinition(
info = @Info(
title = "Product Management API",
version = "v1.0",
description = "Product API Example",
termsOfService = "https://www.example.com/terms",
contact = @Contact(
name = "API Support",
email = "[email protected]",
url = "https://example.com/support"
),
license = @License(
name = "Apache 2.0",
url = "https://www.apache.org/licenses/LICENSE-2.0"
)
)
)
public class ApiApplication {
}
👍3
⭐️ Road To Highload: Крупноблочная архитектура

В видеопроекте Road to Highload Сергей Трегуб, руководитель бэкенд‑разработки продуктовых сервисов Яндекс 360, рассказывает, как крупноблочная архитектура упрощает коммуникацию между разными командами разработки и помогает быстро принимать решения: в каком компоненте разместить новую бизнес‑логику и какие дополнительные блоки потребуются для её поддержки.

Road to Highload — это цикл видеоматериалов от Яндекс 360 о том, как строятся системы, которыми ежедневно пользуются миллионы людей и тысячи компаний. Здесь обсуждаются high‑load и отказоустойчивость не по учебникам, а на основе многолетнего практического опыта.


Смотрите проект, чтобы узнать, как создаются одни из крупнейших облачных сервисов в России:

Сайт проекта
VK Видео
Ютуб
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Типы Серверов в Современных Системах

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
8👍3
Spring Boot: аккуратно задавайте границы @ComponentScan, чтобы случайно не просканировать целиком весь пакет.

Предположим, вы пишете что-то вроде @ComponentScan("com.mycompany"), хотя на самом деле нужно сканировать только часть подпакетов com.mycompany:

- Увеличивается время сканирования classpath
- Замедляется старт приложения
- Подтягиваются классы, которые вообще не должны регистрироваться как Spring-бины

Лучшие практики:

Полагайтесь на дефолты:

@SpringBootApplication
public class MyApplication { }


По умолчанию Spring сканирует только подпакеты пакета, в котором лежит MyApplication.

Сканируйте конкретные подпакеты:

@ComponentScan({
"com.mycompany.myapp.product",
"com.mycompany.myapp.order"
})


👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
3
This media is not supported in your browser
VIEW IN TELEGRAM
Какие фичи C++ реально стоят того, чтобы ими пользоваться каждый день — а какие живут только в докладах и спорах на форумах?

Во втором выпуске «АйТир Листа» встретились два практикующих разработчика —
Данил Черепанов (МойОфис) и Антон Полухин (Яндекс) — и разобрали любимые и спорные возможности C++. Где-то всё было однозначно, а местами мнения разошлись кардинально 🙂


👉 Выпуск ЗДЕСЬ

Реклама
ООО "НОВЫЕ ОБЛАЧНЫЕ ТЕХНОЛОГИИ"
ИНН: 7703807270
erid: 2W5zFJaQXLt