J
Java библиотека
17.07.2026 09:09 · 👁 1.2K
Polling vs Long Polling vs Webhooks vs SSE
Четыре способа получать обновления от сервера. Каждый даёт свой баланс между простотой, эффективностью и «почти реалтайм» доставкой.
Вот как они отличаются:
— Polling
Клиент каждые несколько секунд отправляет запрос: «есть что-то новое?». Сервер отвечает сразу — независимо от наличия данных. Большинство ответов пустые, что тратит ресурсы клиента и сервера. Подходит для сценариев вроде статуса заказа, где допустима задержка и важна простота реализации.
— Long Polling
Клиент отправляет запрос, а сервер держит HTTP-соединение открытым до появления данных или таймаута. Пустых ответов значительно меньше, чем в обычном polling. Использовался, например, в чатах для приближения к реалтайм-доставке сообщений.
— SSE (Server-Sent Events)
Клиент открывает постоянное HTTP-соединение, сервер стримит события по мере появления. Односторонний канал, лёгкий, работает поверх обычного HTTP. Многие AI-интерфейсы стримят ответы токен за токеном именно через SSE.
— Webhooks
Вместо опроса клиентом, сервис сам отправляет HTTP POST на заранее зарегистрированный callback URL при наступлении события. Stripe использует для подтверждения платежей, GitHub — для событий push. Клиент не держит соединение и не делает запросы, просто принимает вызовы.
Часто используется комбинация: polling для простых статусов, SSE для стриминга, webhooks для событий.
J
Java библиотека
16.07.2026 15:54 · 👁 1.8K
👩💻 Spring Boot DevTools - must-have для разработки
DevTools делает жизнь проще: следит за изменениями в коде и конфиге и автоматически перезагружает приложение.
Что даёт:
✅ Auto-restart при изменениях Java-классов
✅ Авто-рефреш application.properties / application.yml
✅ Быстрее итерации - меньше ручных рестартов, больше скорости разработки
Подключение (Maven):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
Подписывайся на наш канал в Mакс 🟪
J
Java библиотека
16.07.2026 13:39 · 👁 1.7K
Узнайте о технологиях для ваших сложных задач
Главная конференция Yandex Cloud 24 сентября: треки AI, Infra + DevTools, Data, Security, Deep Tech, а ещё воркшопы по ИИ и интерактивы.
Участие бесплатное!
Зарегистрироваться
#реклама 16+
scale.yandex.cloud
О рекламодателе
J
Java библиотека
16.07.2026 10:05 · 👁 1.8K
Совет по Java 👩💻: используйте Files.walk() для рекурсивной обработки файлов в директории.
Подписывайся на наш канал в Mакс 🟪
J
Java библиотека
16.07.2026 03:12 · 👁 1.8K
Телеграм канал AI для бизнеса
AI - не будущее. Это настоящее вашего бизнеса.
Телеграм-канал "AI для бизнеса" знает все о внедрении и использовании искусственного интеллекта в бизнесе в России и мира. Только со своими подписчиками канал делится:
- как внедрить искусственный интеллект в реальные бизнес-процессы,
- разборами кейсов: как компании сократили затраты на 30-50% с помощью AI,
- лайфхаками по автоматизации рутинных задач,
- новостями мира AI и разборами трендов.
Сами давно читаем и вам советуем подписаться.
Подписаться
#реклама 16+
О рекламодателе
J
Java библиотека
15.07.2026 20:02 · 👁 1.7K
Внутреннее устройство Map.computeIfAbsent()
computeIfAbsent() — это не просто «get или put». Это атомарная операция с ленивым вычислением, которая решает классическую проблему check-then-act в многопоточном коде.
📦 Что такое computeIfAbsent()
— Поведение
1. Если ключ существует и value != null → вернуть value
2. Если ключа нет или value == null → вызвать mappingFunction
3. Результат функции put в map
4. Вернуть computed value
— Классический use case:
// ❌ Старый способ — race condition!
if (!map.containsKey(key)) {
map.put(key, expensiveOperation());
}
// ✅ Новый способ — атомарно
map.computeIfAbsent(key, k -> expensiveOperation());
🔍 Упрощённый код из JDK:
public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
if (mappingFunction == null)
throw new NullPointerException();
int hash = hash(key);
Node<K,V>[] tab = table;
Node<K,V> first = tab[index];
// Поиск существующего entry
if (first != null) {
Node<K,V> e = first;
do {
if (e.hash == hash &&
Objects.equals(key, e.key)) {
V v = e.value;
if (v != null) {
return v; // Найден, не вызываем функцию!
}
}
} while ((e = e.next) != null);
}
// Ключа нет — вызов mappingFunction
V newValue = mappingFunction.apply(key);
if (newValue != null) {
putVal(hash, key, newValue, true, true);
}
return newValue;
}
📊 Performance
Benchmark: 1M операций
// Старый способ: containsKey + put
if (!map.containsKey(key)) {
map.put(key, new ArrayList<>());
}
// Time: ~45ms, 2 hash lookups
// computeIfAbsent
map.computeIfAbsent(key, k -> new ArrayList<>());
// Time: ~30ms, 1 hash lookup
computeIfAbsent() на 33% быстрее!
✅ Делайте
— Используйте для lazy initialization
— Используйте ConcurrentHashMap для thread-safety
— Держите mappingFunction быстрым и простым
❌ Не делайте
— Не вызывайте computeIfAbsent рекурсивно на том же ключе
— Не модифицируйте map внутри mappingFunction
— Не возвращайте null если хотите кэшировать отсутствие
— Не используйте для побочных эффектов (только для вычисления value)
🔗 Документация
Подписывайся на наш канал в Mакс 🟪
J
Java библиотека
14.07.2026 23:34 · 👁 2K
👩💻 Java Совет : Helper-классы - да. “God class” - нет.
Хорошая практика в Java - выносить повторяющуюся логику в helper / utility классы.
Это делает код чище и уменьшает дублирование.
Но есть опасная крайность - God class:
класс, который “умеет всё” и постепенно превращается в помойку.
✅ Правильно (helper класс)
Например TextUtils, который делает только одну вещь:
- форматирование текста
- обработка строк
- простые операции над конкретной областью
❌ Плохо (God class)
Типичный DoThings, где впихнули всё подряд:
- работа с файлами
- логирование
- бизнес-операции
- управление задачами
- и ещё 20 методов “на всякий случай”
Почему это плохо:
- сложно тестировать
- сложно поддерживать
- сложно менять (ломается всё)
- растёт связанность и хаос
Правило:
Helper-класс должен иметь одну ответственность.
Если класс делает слишком много несвязанных вещей - разбивай на отдельные компоненты.
Подписывайся на наш канал в Mакс 🟪
J
Java библиотека
14.07.2026 20:27 · 👁 1.7K
👩💻 Spring Boot: Используйте spring.mvc.publish-request-params=true только в dev-среде. Это опасно в production.
В production логирование деталей запроса может привести к раскрытию чувствительной информации.
Когда вы настраиваете свойства Spring-приложения в dev со следующими параметрами:
# Включить публикацию параметров
spring.mvc.publish-request-params=true
# Установить уровни логирования, чтобы видеть вывод
logging.level.org.springframework.web=DEBUG
logging.level.org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor=DEBUG
и конфигурацию фильтра примерно такую:
@Bean
public CommonsRequestLoggingFilter logFilter() {
CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter();
filter.setIncludeQueryString(true); // 2) Query-параметры
filter.setIncludeHeaders(true); // 1) Заголовки запроса
filter.setIncludePayload(true); // 3) Данные формы
filter.setMaxPayloadLength(1000);
filter.setAfterMessagePrefix("COMPLETE REQUEST: ");
return filter;
}
вы включаете логирование:
1. заголовков запроса (Request headers)
2. query-параметров (Query parameters)
3. данных формы (Form data)
Без этого Spring маскирует или опускает многие из этих деталей, чтобы избежать утечки информации.
Не используйте это в production, иначе вы раскроете чувствительную информацию, например пароли:
POST /login
Body: {"username":"john","password":"mypassword"}
Подписывайся на наш канал в Mакс 🟪
J
Java библиотека
14.07.2026 15:27 · 👁 1.8K
🔴 Завтра тестовое собеседование с Java-разработчиком
15 июля(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.
Как это будет:
📂 Сергей Чамкин, старший разработчик из Uzum, ex-WildBerries, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Cергей будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Сергею
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot
Реклама.
О рекламодателе.
J
Java библиотека
14.07.2026 13:09 · 👁 1.8K
👩💻 Главное правило многопоточности в Java:
не делитесь состоянием между потоками.
Большинство багов в concurrency появляются из-за одного —
несколько потоков одновременно изменяют одни и те же данные.
Как избежать проблем?
1. Используйте неизменяемые объекты (Immutable)
Если объект нельзя изменить —
его безопасно читать из любого количества потоков.
Пример:
- record в Java - идеальный immutable-тип
- поля final
- никакой синхронизации не нужно
2. Общайтесь через сообщения, а не через общее состояние
Вместо:
- менять общие переменные
Делайте так:
- один поток отправляет данные в очередь
- другой поток их получает
Например:
- BlockingQueue
- put() → отправка
- take() → получение
Плюсы подхода:
- Нет гонок данных (race conditions)
- Нет сложных synchronized
- Нет дедлоков
- Код проще и стабильнее
Золотое правило concurrency:
Shared state — это проблема.
Message passing + immutability — это решение.
Подписывайся на наш канал в Mакс 🟪