Java Portal | Программирование
12.9K subscribers
1.14K photos
93 videos
36 files
1.02K links
Присоединяйтесь к нашему каналу и погрузитесь в мир для Java-разработчика

Связь: @devmangx

РКН: https://clck.ru/3H4WUg
Download Telegram
Парень собрал репозиторий, чтобы показать новые встроенные возможности отказоустойчивости в Spring Framework 7. Никаких дополнительных зависимостей вроде spring-retry — все уже под капотом 🤯

Можно использовать декларативную аннотацию Retry, чтобы настроить, как и когда нужно повторять выполнение

Можно написать свой listener, чтобы получить наблюдаемость за разными событиями.

Нужен больше контроля — бери RetryTemplate

Хочешь ограничить число одновременных подключений — используй Concurrent

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
8🔥6
Мы охотились за лишними 300 мс задержки в микросервисе. Думали, что это сборщик мусора в Java.

Два дня крутили настройки JVM. Ноль эффекта.

А настоящая проблема оказалась в git clone внутри init-контейнера.
Сервис случайно настроили так, что он на каждом старте клонировал репозиторий ради одного конфиг-файла.
Клонирование было медленным, но задержка терялась на фоне общего старта приложения.

Сервис не тормозил - он просто постоянно перезапускался.

Всегда проверяйте сайдкары и init-контейнеры раньше, чем лезете в логику приложения.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16🔥3🏆31
Каким будет результат?

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🤯2
IntelliJ IDEA начнет использовать JSpecify как основную null-safe библиотеку начиная с версии 2025.3.

"Переход на JSpecify это хороший пример того, как совместная работа в экосистеме Java приводит не просто к очередному стандарту, а к тому, который реально приносит пользу разработчикам."

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
5👍4
Многие ненавидят Java не потому что язык плохой, а потому что первое знакомство с ним вышло травматичным.

В универе его чаще всего преподавали на примерах из прошлого века, а преподаватели были больше заняты тем, чтобы сто раз написать public static void main, чем объяснить, почему всё устроено именно так. А ещё эта многословность, ошибки компиляции, необходимость сходу понимать классы, объекты, наследование… неудивительно, что после такой встречи у людей остаётся отвращение.

Плюс порог входа у Java выше, чем у более дружелюбных языков вроде Python или JavaScript. И хотя это уже давно не тот тормозной тяжёлый язык из 2000-х, многие до сих пор думают о нем именно так, не замечая, что сегодня он работает почти во всех крупных системах.

И тут самое забавное: пока в интернете его поливают грязью, компании всё так же активно ищут Java-разработчиков и платят им очень хорошие деньги. Потому что в реальном мире остаётся то, что работает и масштабируется.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
26
Совет по Java: можно использовать Collectors.joining(", ") чтобы собрать Stream в строку с разделителем запятая (или любым другим, если нужно).

Обычный способ:

List<String> items = List.of("a", "b", "c");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < items.size(); i++) {
sb.append(items.get(i));
if (i < items.size() - 1) {
sb.append(", ");
}
}
System.out.println(sb.toString());


Через joining:

List<String> items = List.of("a", "b", "c");
String result = items.stream().collect(Collectors.joining(", "));
System.out.println(result.toString());


👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
14👍3
API VERSIONING позволяет разработчикам поддерживать несколько версий эндпоинтов веб-сервиса (например, /users или /products), не ломая интеграции у клиентов при внесении изменений.

В новом Spring Boot 4 появилась встроенная поддержка версионирования API, и настраивается она очень просто.

→ Добавь строки в конфиг (application.properties) под твой сценарий. Можно использовать оба варианта одновременно — заголовки и query-параметры.

1 способ: версионирование через заголовок
(Клиент передает версию в header, например: api-version: 1 — название заголовка можно выбрать любое)

spring.mvc.apiversion.use.header = api-version


2 способ: версионирование через query-параметр
(Клиент передает версию в запросе, например: ?version=1)

spring.mvc.apiversion.use.query-parameter = version


→ Установка версии по умолчанию
(Используется версия 1.0, если клиент ничего не указал)

spring.mvc.apiversion.default = 1.0


Примечание: если версия указана и в заголовке, и в query-параметре, то приоритет у более высокой версии. Например, header = 2, query = 1 → в итоге будет 2.

Готово.

a) Без множества контроллеров
b) Без /v1/, /v2/ в URL
c) Код чище и проще поддерживать

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥72
Spring Boot: на этапе разработки можно включить spring.main.lazy-initialization=true, чтобы ускорить запуск приложения.

По умолчанию Spring Boot инициализирует все бины при старте. В среде разработки это приводит к:

Более долгому старту приложения, особенно в крупных проектах

Приходится ждать загрузки бинов, которые прямо сейчас даже не нужны

Чтобы избежать этого, в application.properties укажите:

spring.main.lazy-initialization=true


Важно сохранить поведение по умолчанию в проде, потому что:

Ошибки на старте выявляются раньше

Все компоненты готовы принимать запросы сразу

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7👍5
25 золотых правил системного дизайна

1. Система с упором на чтение
> Используй кэш (Redis/Memcached) для частых запросов вроде профилей пользователей

2. Низкая задержка
> Используй кэш и CDN (Cloudflare), чтобы раздавать статику ближе к пользователю

3. Система с упором на запись
> Используй Message Queue (Kafka) для буферизации большого объема записей (логи, аналитика)

4. ACID-требования
> Используй SQL (PostgreSQL) для строгих транзакций вроде банковских операций

5. Неструктурированные данные
> Используй NoSQL (MongoDB) для гибких схем, например каталогов товаров

6. Сложные медиа-ресурсы
> Используй Blob Storage (AWS S3) для видео, изображений и больших файлов

7. Сложные предварительные расчёты
> Используй Message Queue + Cache для асинхронной генерации контента (например ленты новостей)

8. Поиск при больших объемах данных
> Используй Elasticsearch для полнотекстового поиска и автокомплита

9. Масштабирование SQL
> Используй шардирование, чтобы разделить большие таблицы на несколько инстансов

10. Высокая доступность
> Используй Load Balancer (NGINX) чтобы распределять трафик и избегать перегрузки

11. Глобальная доставка данных
> Используй CDN для стабильного стриминга и раздачи контента по всему миру

12. Графовые данные
> Используй Graph DB (Neo4j) для соцсетей, рекомендаций и связей между сущностями

13. Масштабирование компонентов
> Используй горизонтальное масштабирование, а не просто апгрейд железа

14. Быстрые запросы к базе
> Используй индексы на ключевых колонках вроде email или user_id

15. Пакетные задачи
> Используй Batch Processing для отчётов, расчётов или периодических задач

16. Защита от злоупотреблений
> Используй Rate Limiter, чтобы предотвращать DDoS и спам запросов к API

17. Доступ к микросервисам
> Используй API Gateway для авторизации, маршрутизации и SSL-терминации

18. Единая точка отказа
> Добавляй Redundancy (Active-Passive), чтобы сервис продолжал работать при сбоях

19. Отказоустойчивость данных
> Используй репликацию (Master-Slave), чтобы данные не терялись при падении узлов

20. Реальное время
> Используй WebSockets для чатов, лайв-обновлений, лайв-результатов

21. Обнаружение сбоев
> Используй Heartbeat-пинг, чтобы проверять статус сервисов каждые несколько секунд

22. Целостность данных
> Используй Checksums (MD5/SHA) чтобы проверить, что загруженные файлы не повреждены

23. Децентрализованное состояние
> Используй Gossip Protocol, чтобы ноды обменивались статусами без центрального сервера

24. Эффективное кеширование
> Используй Consistent Hashing, чтобы добавлять или убирать кэш-ноды без полного пересчёта ключей

25. Работа с геоданными
> Используй Quadtree или Geohash для быстрых запросов вроде поиска ближайших водителей


👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥21
12 рекомендаций по дизайну API для бэкенд-разработчиков

(Их часто спрашивают на собеседованиях)

1. Понятные имена ресурсов

`GET /get-all-orders`  
`GET /orders`


2. Корректное использование HTTP-методов

- POST /users — создать пользователя
- GET /users/123 — получить пользователя
- PUT /users/123 — заменить полностью
- DELETE /users/123 — удалить

3. Идемпотентность

Клиент отправляет:

POST /payments
Idempotency-Key: abc-123


Если запрос повторится, сервер должен вернуть тот же результат, не создавая операцию заново.

4. Версионирование API

Рекомендуемый вариант — в URL:

GET /v1/products/42
GET /v2/products/42


5. Правильные статус-коды

Если пользователь не найден:

 `200 OK { "error": "user not found" }`  
`404 Not Found`


6. Пагинация

Пример:

GET /articles?page=2&limit=50


Ответ должен содержать элементы 51–100.

7. Фильтрация и сортировка

Пример:

GET /orders?status=shipped&sort=-created_at


8. Безопасность

Использование JWT в заголовках:

Authorization: Bearer <token>


9. Rate limiting

Например: 100 запросов в минуту.
После превышения — вернуть:

429 Too Many Requests


10. Кэширование

Запрос:

GET /blog/posts/123


Ответ содержит:

ETag: "abc"


Повторный запрос:

If-None-Match: "abc"


Если не изменилось — 304 Not Modified.

11. Документация

Используй:

- Swagger UI
- OpenAPI

Разработчики должны видеть схемы, параметры и иметь возможность тестировать запросы.

12. Быть прагматичным

Иногда лучше так:

POST /auth/login


чем строго REST-подход:

POST /sessions


Хороший API читается как логичная, предсказуемая система и экономит время всем, кто с ним работает.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍135🔥5
Только что выкатили демо, показывающее, почему Spring Data AOT реально важен для производительности.

Перенос парсинга запросов из рантайма в стадию компиляции дает:

- запуск приложения быстрее на 50–70%
- ошибки в запросах ловятся до деплоя
- SQL генерируется заранее на этапе сборки
- всё готово для GraalVM Native

Репозиторий:
https://github.com/danvega/spring-data-aot

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍52😁1
Одна простая привычка, которая сильно упрощает поддержку Dockerfile, это сортировка многострочных списков пакетов по алфавиту.

На первый взгляд мелочь, но влияние на читаемость и будущую поддержку заметное.

Когда ставишь пакеты в многострочном apt-get install или apk add блоке, легко случайно добавить дубликат или пропустить что-то, что затерялось в середине списка.

Алфавитная сортировка полностью снимает этот вопрос. Список можно быстро просканировать, сразу увидеть дубли и держать всё в едином стиле на разных окружениях.

Плюс уменьшаются шумные диффы в код-ревью.

Когда пакеты отсортированы, добавление или удаление одного пункта выглядит как аккуратное и предсказуемое изменение.

Без сортировки маленькое обновление часто превращается в огромный diff, и ревью становится сложнее, чем должно быть.

Этот подход особенно полезен, когда команда растёт.

Несколько человек, трогающих один Dockerfile, не начинают перетасовывать строки под свой вкус или форматировать по-разному.

Структура остаётся стабильной, и поддержка со временем становится проще.
Небольшое улучшение, но на сотнях билдов оно экономит заметно нервов и времени.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👍1
This media is not supported in your browser
VIEW IN TELEGRAM
Исәнмесез! Встречайте новый VK JT Meetup: ML + Java!

4 декабря VK приглашает ML-инженеров и Java-разработчиков Казани на офлайн-встречу.

В программе:
— Практические доклады от экспертов VK: управление облаком One-cloud, запуск генеративного поиска в мессенджере и выкатка RAG в прод
— Два потока на выбор: нетворкинг с настольными играми или решение реальных кейсов от VK с призами

Общайтесь с экспертами, находите лучшие решения и оставайтесь на афтепати: фуршет, нетворкинг, настолки и свободное общение.

Только офлайн, в Big Twin Arena.
🎟 Участие бесплатное, регистрация на сайте.
3🔥1😁1
Почему Redis однопоточный (и почему из-за этого он быстрый)

У тебя сервер на 32 ядра, а Redis грузит только одно.

На вид неэффективно. Но при этом Redis остается одной из самых быстрых in-memory баз.
Почему так?

Основной bottleneck обычно не CPU

Для типичных операций Redis вроде GET, SET, INCR CPU почти не тратится.

В реальных условиях упираешься в другое:

- пропускная способность сети (ответы клиентам)
- пропускная способность памяти (RAM <--> CPU cache)
- системные вызовы, TCP, epoll и другая возня ядра

В таких условиях добавление потоков не дает прироста, потому что ограничение в другом.

Почему мультипоточность сделала бы Redis медленнее?

Если бы несколько потоков трогали одну область данных, понадобились бы:

Локи
Чтобы безопасно читать или писать ключи. Ожидание блокировок добавляет задержки.

Context Switching
Переключение между 32 потоками сжигает ресурсы и ломает кэш-локальность.

Cache Coherence
Когда один поток обновляет данные, которые кэшировал другой, аппаратная часть должна инвалидировать кэши по ядрам.


Это создает "cache thrashing" и ест производительность.

Во многих сценариях эти накладные расходы больше, чем сама работа Redis-команды.

Секрет - однопоточный event loop


Redis работает на неблокирующем event loop (epoll/kqueue).
Он умеет держать тысячи соединений и обрабатывать только те сокеты, у которых есть данные.

Плюсы:

- без блокировок
- предсказуемые задержки
- строгий порядок операций
- минимальный overhead

Работая в памяти, один поток способен обработать сотни тысяч или даже миллионы команд в секунду.

Но небольшая поправка = Redis не полностью однопоточный

Redis однопоточен только в части, которая работает с данными.

Остальное вынесено в фоновые потоки.

✔️Главный поток

Выполняет команды и трогает dataset.

✔️BIO-потоки

Для долгих задач:

lazy delete (UNLINK)
синхронизация AOF
фоновые задачи модулей

✔️I/O threads (с версии Redis 6+)

Для чтения запросов и отправки ответов по сети.
При этом сами данные не трогаются, значит = без локов.
Так Redis получает выгоду от распараллеливания, не ломая простоту и предсказуемость.

Redis специально остается однопоточным в части доступа к данным, чтобы избежать локов, гонок и непредсказуемости.
При этом дополнительные потоки используются там, где они реально помогают.
В результате Redis часто обходится быстрее сложных многопоточных систем.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👀3