ar
Feedback
Java Portal | Программирование

Java Portal | Программирование

الذهاب إلى القناة على Telegram

Присоединяйтесь к нашему каналу и погрузитесь в мир для Java-разработчика Связь: @devmangx РКН: https://clck.ru/3H4WUg

إظهار المزيد

📈 نظرة تحليلية على قناة تيليجرام Java Portal | Программирование

تُعد قناة Java Portal | Программирование (@java_iibrary) في القطاع اللغوي الروسية لاعباً نشطاً. يضم المجتمع حالياً 12 130 مشتركاً، محتلاً المرتبة 10 402 في فئة التكنولوجيات والتطبيقات والمرتبة 54 525 في منطقة روسيا.

📊 مؤشرات الجمهور والحراك

منذ تأسيسه في невідомо، حقق المشروع نمواً سريعاً وجمع 12 130 مشتركاً.

بحسب آخر البيانات بتاريخ 07 يونيو, 2026، تحافظ القناة على نشاط مستقر. خلال آخر 30 يوماً تغيّر عدد الأعضاء بمقدار -138، وفي آخر 24 ساعة بمقدار 2، مع بقاء الوصول العام مرتفعاً.

  • حالة التحقق: غير موثّقة
  • معدل التفاعل (ER): يبلغ متوسط تفاعل الجمهور 11.37‎%. وخلال أول 24 ساعة من النشر يحصد المحتوى عادةً 6.26‎% من ردود الفعل نسبةً إلى إجمالي المشتركين.
  • وصول المنشورات: يحصل كل منشور على متوسط 1 379 مشاهدة. وخلال اليوم الأول يجمع عادةً 760 مشاهدة.
  • التفاعلات والاستجابة: يتفاعل الجمهور بانتظام؛ متوسط التفاعلات لكل منشور يبلغ 4.
  • الاهتمامات الموضوعية: يركز المحتوى على مواضيع رئيسية مثل boot, string, void, архитектура, resttemplate.

📝 الوصف وسياسة المحتوى

يصف المؤلف القناة بأنها مساحة للتعبير عن الآراء الذاتية:
Присоединяйтесь к нашему каналу и погрузитесь в мир для Java-разработчика Связь: @devmangx РКН: https://clck.ru/3H4WUg

بفضل وتيرة التحديث المرتفعة (أحدث البيانات بتاريخ 08 يونيو, 2026) تحافظ القناة على حداثتها ومستوى وصول مرتفع. وتُظهر التحليلات تفاعلاً نشطاً من الجمهور، ما يجعلها نقطة تأثير مهمة ضمن فئة التكنولوجيات والتطبيقات.

12 130
المشتركون
+224 ساعات
-287 أيام
-13830 أيام
أرشيف المشاركات
Spring Boot: можно добавить глобальные метаданные OpenAPI с помощью аннотации @OpenAPIDefinition. Размести её на главном клас
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 = "support@example.com",
            url = "https://example.com/support"
        ),
        license = @License(
            name = "Apache 2.0",
            url = "https://www.apache.org/licenses/LICENSE-2.0"
        )
    )
)
public class ApiApplication {
}

Если у тебя Spring Boot приложение подключено как вложенный модуль и оно использует поддержку Docker Compose, то в IntelliJ IDEA нужно задать MODULE_WORKING_DIRECTORY, чтобы среда смогла корректно определить, где лежит файл compose.yaml. 👉 Java Portal

Spring Boot: для новых приложений выбирайте WebClient вместо RestTemplate ~ Реактивный и неблокирующий ~ Работает на event-lo
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

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

🔴 Завтра тестовое собеседование с Java-разработчиком 24 декабря(уже завтра!) в 19:00 по мск приходи онлайн на открытое собес
🔴 Завтра тестовое собеседование с Java-разработчиком 24 декабря(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика. Как это будет: 📂 Сергей Чамкин, старший разработчик из Uzum, ex-WildBerries, будет задавать реальные вопросы и задачи разработчику-добровольцу 📂 Cергей будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью 📂 В конце можно будет задать любой вопрос Сергею Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы. Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot Реклама. О рекламодателе.

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

Kubernetes-совет: Java-приложения обычно требуют больше CPU на старте, чем во время обычной работы ☕️ Эта политика Kyverno: a
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.metadata.name}}"
        patchStrategicMerge:
          spec:
            containers:
              - (name): sample-app-on-kubernetes
                resources:
                  limits:
                    cpu: 0.5
- отслеживает момент завершения старта pod’а - обновляет ресурсы pod’а прямо на месте - снижает CPU-лимиты после старта Итог: более быстрый запуск и меньшие затраты Вот моя статья об этом 👉 Java Portal

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

Когда ты уже не джун и даже не мидл, на собеседованиях по Java почти не задают вопросы в стиле «что такое HashMap». В ход иду
Когда ты уже не джун и даже не мидл, на собеседованиях по 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

Java Tip: Начиная с Java 14 можно использовать record для создания компактных неизменяемых объектов, которые просто переносят
Java Tip: Начиная с Java 14 можно использовать record для создания компактных неизменяемых объектов, которые просто переносят данные. » Они короче обычных POJO » У них из коробки есть equals(), hashCode() и toString() » По умолчанию они неизменяемые Классический POJO:
public class Book {
    private final String title;
    private final int price;

    public Book(String title, int price) {
        this.title = title;
        this.price = price;
    }

    // геттеры, toString, equals и hashCode
}
Вместо этого можно создать record:
public record Book(String title, int price) {}
Смысл ровно тот же, но без бойлерплейта. 👉 Java Portal

Когда всё живёт в одной базе данных, с транзакциями всё просто. BEGIN → COMMIT → ROLLBACK. Но в распределённых системах всё резко усложняется. В чём реальная проблема ??? В распределённых системах нельзя сделать одну транзакцию на всё сразу по нескольким причинам: - несколько сервисов - несколько баз данных - множество возможных отказов Классического rollback больше не существует. И тут появляется паттерн Saga. Saga это последовательность локальных транзакций, которые координируются между собой. Каждый шаг: - выполняет своё изменение - фиксируется - и определяет, как себя компенсировать, если дальше что-то пойдёт не так Глобальной транзакции нет. Есть eventual consistency. Простой пример » Создание заказа может включать: 1. Создать заказ 2. Зарезервировать товар 3. Провести оплату Если на шаге 3 происходит сбой, глобального rollback нет. Выполняются компенсирующие действия: - освободить резерв - пометить заказ как отменённый Это и есть Saga. Два способа реализации Saga - Хореография: - сервисы реагируют на события - центрального координатора нет - слабая связность - сложнее проследить общий поток Оркестрация: - есть компонент-координатор - поток шагов явно описан - проще рассуждать о логике - выше связность
Ни один подход не является универсально лучшим. Всё зависит от системы и контекста.
Частая ошибка » Считать, что Saga — это замена ACID-транзакциям. Это не так. Saga меняет сам контракт: - допускаются промежуточные состояния - компенсации проектируются явно - принимается факт, что система может упасть на середине процесса Когда Saga действительно имеет смысл - долгоживущие процессы - несколько сервисов - реальные побочные эффекты: платежи, доставки, резервы - ситуации, где технического rollback не существует Если всё находится в одной базе данных, Saga не нужна. Здесь легко уйти в оверинжиниринг. Ключевая мысль:
Saga не убирает сложность. Она делает её явной.
Явная сложность лучше, чем спрятанная за предположениями, которые больше не работают. В распределённых системах сбои — это не исключение, а часть нормального потока. Паттерн Saga не избавляет от всех проблем, но помогает избежать беспорядка. А в продакшене это уже большая разница. ☃️ 👉 Java Portal

Этот проект показывает систему отслеживания местоположения курьера в реальном времени, похожую на то, как это реализовано в Zomato или Swiggy, и построенную на Spring Boot и Apache Kafka. 👉 Java Portal

Spring Boot 4 теперь полностью безопасен по работе с null — большой плюс для Kotlin-разработчиков. С поддержкой JSpecify в Kotlin 2.2 наконец-то можно избавиться от платформенных типов и получить корректную работу с null даже в обобщённых типах. Подробнее и попробовать Spring с Kotlin ☺️ 👉 Java Portal

Сегодня в рубрике crazy Java: этот код работает (на Java 25):
<T extends Integer> void test(T t) {
    t++;
    // t += 1;
    IO.println(t);
}

void main() {
    test(10);
}
Но если заменить t++ на t += 1, всё ломается. Ошибка:
Main.java:3: error: incompatible types: int cannot be converted to T
👉 Java Portal

В JDK 26 появилась новая фича: HttpClient, который входит в Java SE ещё со времён JDK 11, теперь поддерживает HTTP/3 😱
HttpClient client = HttpClient.newBuilder()
    .version(HttpClient.Version.HTTP_3)
    .build(); // создать экземпляр HttpClient с HTTP/3 в качестве предпочтительной версии

URI reqURI = new URI("https://www.google.com/");
HttpRequest req = HttpRequest.newBuilder()
    .uri(reqURI)
    .build(); // создать экземпляр запроса

final HttpResponse.BodyHandler<String> bodyHandler =
    BodyHandlers.ofString(StandardCharsets.UTF_8);

HttpResponse<String> resp = client.send(req, bodyHandler);
// отправить запрос и получить ответ в виде строки

System.out.println(
    "status code: " + resp.statusCode() +
    " HTTP protocol version: " + resp.version()
); // вывести код ответа и используемую версию HTTP
Подробнее 👉 Java Portal

Совет по Spring Boot: используйте TaskScheduler для реализации лёгких динамических задач. Для более сложных сценариев лучше смотреть в сторону Quartz. Инжектим и используем:
@Autowired
TaskScheduler scheduler;

scheduler.schedule(
    () -> System.out.println("Hello!"),
    new CronTrigger("0 */5 * * * *") // каждые 5 минут
);
Инжектируемый бин — это ThreadPoolTaskScheduler, встроенная реализация сразу TaskScheduler и ScheduledExecutorService При необходимости конфигурацию можно кастомизировать:
@Configuration
@EnableScheduling
public class SchedulerConfig {

    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(5);
        scheduler.setThreadNamePrefix("my-scheduler-");
        scheduler.initialize();
        return scheduler;
    }
}
👉 Java Portal

Случайные UUID убивают производительность базы данных. Ты перешел с целочисленных ID (1, 2, 3…) на UUID (a1b2-3c4d-…) ради безопасности или распределенной генерации. И вдруг записи в БД стали медленнее. Иногда намного. Вот почему. Фрагментация индексов. Большинство индексов в БД это B-Tree (сбалансированные отсортированные деревья). Физическое расположение данных имеет значение. 1. Последовательные ID Когда ты вставляешь последовательные числа (1, 2, 3), новые записи всегда попадают в самый правый лист индекса. Записи предсказуемые и последовательные. Максимальные cache hit’ы. Страницы индекса остаются заполненными на 100%. Это максимальная скорость, на которую способна твоя база. 2. Случайные UUIDv4 UUIDv4 равномерно случайные. Это значит, что каждая новая вставка может попасть в любое место дерева. Из-за этого: -» База постоянно подгружает случайные страницы с диска в память (random I/O). -» Page split. Если целевая страница заполнена, БД вынуждена делить ее пополам, в итоге получаются две полупустые страницы. -» Эффект швейцарского сыра. Индекс раздувается и заполняется дырками, зря тратя RAM и место на диске. -» Когда размер индекса превышает объем доступной памяти, пропускная способность на запись может просесть на 20–90%. 3. UUIDv7 Перестань использовать UUIDv4 в качестве primary key. Используй UUIDv7 (стандартизирован в RFC 9562). UUIDv7 содержит таймстемп в начале ID, поэтому он сортируемый. В итоге ты получаешь лучшее из двух миров: -» Распределенная генерация, без центрального счетчика. -» Монотонные вставки. В B-Tree они ведут себя почти как последовательные числа, без фрагментации. -» Безопасность. Нельзя просто угадать ID (атакующий не узнает, что пользователь 101 идет сразу после 100), хотя стоит учитывать, что время создания записи становится видно. Итог простой: ты сохраняешь удобство UUID и избавляешься от перфоманс-потерь. 👉 Java Portal

Реальная история: Дизайнерское агентство разработало интерфейс приложения в сервисе Figma, но из-за того, что карты Visa и Ma
Реальная история: Дизайнерское агентство разработало интерфейс приложения в сервисе Figma, но из-за того, что карты Visa и Mastercard оказались заблокированы, не смогли выгрузить проект. Осложнялось всё тем, что они могли олатить сервис только с корпоративной карты. Читпей организовали оплату в течение 10 минут. Ребята оплатили подписку, и выгрузили проект. Интерфейс приложения был спасён! Что делает CheatPay: 🔘Помогает оплатить зарубежные сервисы российскими картами, в том числе Visa и Mastercard. 🔘Восстанавливают доступ к аккаунту 🔘Работают прозрачно с оплатой на ИП и всеми закрывающими документами Например: Потеряли доступ к Zoom, Airtable, Atlassian, Canva и другим программам для управления IT-проектами? Простаивают проекты в Adobe Photoshop, Premiere Pro и After Effects? Другие сервисы? Помогут. Обращаться в https://t.me/cheatpay_ru

Тема Islands теперь используется по умолчанию во всех IDE от JetBrains. Более мягкий и сбалансированный внешний вид, рассчитанный на комфорт и концентрацию во время работы. Посмотреть подробнее 👉 https://jb.gg/discover-the-islands 👉 Java Portal

WebFlux часто вызывает путаницу, потому что его обычно объясняют со стороны инструмента, а не со стороны проблемы. Поэтому начнем с базы. Сначала: блокирующий vs неблокирующий код -» Блокирующий код: Поток встает и ждет, пока операция не завершится. Пока ждет, он ничего больше делать не может. -» Неблокирующий код: Поток делегирует ожидание и остается свободным для других задач. Когда результат готов, выполняется продолжение. Это не быстрее. Это просто более эффективное использование потоков. Еще одно ключевое понятие перед тем как идти дальше: Backpressure. Это способность системы регулировать поток данных, чтобы не перегружать потребителя. Представь так: потребитель может сказать продюсеру: «присылай только столько, сколько я успеваю обработать». Теперь к WebFlux. WebFlux позволяет строить полностью неблокирующие приложения end-to-end: -»Неблокирующий сервер (Netty) -»Неблокирующие API -»Проброс backpressure без перегрузки потребителя -»Реактивная модель (Mono, Flux) Ключевое слово здесь end-to-end. Если хотя бы одна часть блокирует, весь выигрыш размывается. Самая частая ошибка при работе с WebFlux Использовать WebFlux, а потом: -»Дернуть блокирующую базу данных -»Использовать SDK без реактивной поддержки -»Делать .block(), потому что так проще В итоге: -»Все равно все становится блокирующим -»Ты просто добавил сложности -»Ничего не выиграл WebFlux не превращает блокирующий код в неблокирующий. А Virtual Threads разве это не меняют? Меняют, и это важно. С Virtual Threads: -»Блокирующая модель снова становится жизнеспособной -»Цена ожидания резко падает -»Необходимость в WebFlux уменьшается Но есть нюанс. Virtual Threads не дают: -»Backpressure -»Контроль потока -»Композицию стримов -»Настоящий стриминг данных Они меняют tradeoff, но не убирают саму проблему. Когда WebFlux все еще имеет смысл WebFlux оправдан, когда: -»Нужен реальный backpressure -»Ты работаешь с непрерывными стримами (SSE, WebSockets) -»Есть fan-out из множества внешних вызовов -»Нужно явно контролировать поток данных По необходимости, а не потому что модно. Когда не стоит использовать WebFlux -»Классический CRUD -»Сложная бизнес-логика -»Команды без реактивного опыта -»Проекты, где читаемость важнее конкурентности -»Когда Virtual Threads решают задачу с меньшей когнитивной стоимостью WebFlux это другая модель исполнения. Если твоя проблема не в масштабной I/O-конкурентности, WebFlux тебе не поможет. А сегодня, с Virtual Threads, многим он уже просто не нужен. 👉 Java Portal