TGViewer
Channel Public Channel
Библиотека джависта | Java, Spring, Maven, Hibernate

Библиотека джависта | Java, Spring, Maven, Hibernate

@javaproglib

Все самое полезное для Java-разработчика в одном канале.

Учиться у нас: clc.to/AATM8w

Для обратной связи: @proglibrary_feeedback_bot

По рекламе: @tproger_sales_bot

РКН: https://gosuslugi.ru/snet/67a5bbda1b17b35b6c1a55c4
Subscribers
22K
Photos
2.5K
Videos
57
Links
3.7K

Showing posts older than #7645 · Back to latest

Older Posts 20 shown
Post #7642 2.33K
❌ ThreadLocal + Virtual Threads = утечка памяти

Если вы перешли на virtual threads, но продолжаете использовать ThreadLocal, то у вас проблема, которая пока просто не выстрелила.

ThreadLocal хранит данные в ThreadLocalMap — по одной map на каждый тред. Когда тредов было 200 в пуле, это было терпимо. Когда виртуальных тредов сотни тысяч, каждый несёт свою map, и heap начинает гореть. Плюс мутабельность: ThreadLocal.set() в глубоком call stack — это неявное состояние, которое легко забыть почистить через .remove(). В try-finally это работает до первого необработанного исключения.

Java 21 предлагает замену — ScopedValue.

🔹 Ключевые отличия

ScopedValue.where(TENANT_ID, tenant).run(() -> { ... }) — значение привязано к scope, а не к треду. Вышли из блока и значение автоматически недоступно. Никакого .remove(), никакого «забыл почистить».

Иммутабельность по дизайну. Нельзя сделать .set(). Если нужно другое значение, создаёте вложенный scope. Это убирает целый класс багов с «протеканием» контекста между запросами.

Легковесность. Внутри массив вместо HashMap. При масштабе в 100k+ тредов разница в потреблении памяти ощутимая.

Работает в связке со StructuredTaskScope: дочерние виртуальные треды автоматически наследуют scoped values родителя. Не нужно вручную пробрасывать контекст.

Практический вывод: если вы мигрируете на virtual threads, аудит ThreadLocal — обязательный шаг. ScopedValue пока preview, но API стабилизируется, и направление очевидно. Как минимум стоит уже сейчас заменить ThreadLocal на ReentrantLock-protected shared state или ScopedValue там, где передаёте tenant ID, request context, trace ID и подобные per-request данные.

══════ Навигация ══════
Вакансии • Задачи • Собесы

🐸 Библиотека джависта

#CoreJava
  • 👍 6
  • ❤ 2
  • 🔥 1
Post #7640 2.28K
🔐 SAP NetWeaver + Keycloak: SAML за два клика, а потом начинается боль

Включить SAML в SAP NetWeaver AS Java дело двух кликов. Отключить возможность обойти Keycloak и зайти напрямую через SAP — уже интереснее. А когда у пользователей два аккаунта с одним email и федерация по Email type, то уже совсем весело.

Ребята из «Инфосистемы Джет» коротко и по делу разобрали:

— как прикрутить Keycloak как IdP к SAP через SAML;
— почему обязательно нужно поднять SAML2LoginModule наверх и сделать его обязательным;
— что делать, когда Keycloak лёг, а configtool.sh ваш единственный друг;
— зачем менять federation type с Email на Logon ID и как это выглядит на стороне Keycloak.

Без воды, со скриншотами каждого шага. Пригодится тем, кто работает с SAP-стеком и не хочет оставлять ключи под ковриком.

🔗 Подробнее

══════ Навигация ══════
Вакансии • Задачи • Собесы

🐸 Библиотека джависта

#Enterprise
  • ❤ 3
  • 👍 2
  • 🔥 1
Post #7638 2.27K
😮 Топ-вакансий для джавистов за неделю

Middle Java разработчик — Гибрид (Нижний Новгород) — Nexign

Java-разработчик (YaIoT-платформа) — 330 000 —‍ 550 000 ₽ — удалёнка/гибрид (Москва, Санкт-Петербург)

Разработчик Java — 330 000 —‍ 550 000 ₽ — гибрид (Москва)

➡️ Еще больше топовых вакансий — в нашем канале Java jobs
  • 🔥 3
  • 👍 1
Post #7637 2.43K
🔥 Знакомьтесь с экспертом Proglib.academy: Эмиль Сатаев

Эмиль — эксперт с 8-летним опытом в разработке, который специализируется на внедрении LLM и агентных подходов в реальные коммерческие сервисы. Он точно знает, как проектировать архитектуру так, чтобы ИИ-функции работали стабильно в связке с внешними системами.

🏃‍♀️ Уже 14 мая Эмиль проведет открытый вебинар!

Обсудим самую «больную» тему: «Почему AI-продукты на базе LLM ломаются и как сделать, чтобы работало».

🗓 Когда: 14 мая в 19:00 (Мск)

Почему Эмиля стоит послушать:

🟣 8+ лет в разработке (Backend и Frontend)
Прошел путь от фулстека до Backend Platform Developer в SMIT.Studio.


🟣 Международный исследовательский опыт
Работал исследователем в Институте ИИ НИУ ВШЭ и в Национальном университете Сингапура (NUS).


🟣 Преподаватель-практик
Ведет семинары в НИУ ВШЭ, в том числе по проектированию и разработке агентских систем.


🟣 Мастер интеграции AI в Backend
Его главная суперсила — умение правильно встраивать LLM через API, выстраивать workflow и агентную логику в сложных распределенных системах.


🔗 Зарегистрироваться на вебинар
Post #7636 2.09K
🧠 Профдеформация: симптомы, которые точно узнаешь

Жена тыкает «дождь» в Яндекс Погоде, а ты: «Зачем ты повышаешь цены на такси?!».

Знакомо?
Бэкенд-разработчик из ОТП собрал свои симптомы в одну статью. На курсах «войти в айти» о таком не рассказывают.

Пишите, какие симптомы замечали за собой? 👇

📖 Полная статья на Хабре

🐸 Библиотека джависта

#DevLife
  • 😁 6
  • 🔥 2
  • 👍 1
Post #7634 2.23K
⌛ backup PostgreSQL с минимальной нагрузкой на прод

Разберём эффективный способ бэкапа PostgreSQL с помощью pg_basebackup + реплики.

Сценарий: есть продовый PostgreSQL и настроенная горячая реплика (streaming replication). Зачем использовать реплику для бэкапа?

🔵 Причины

— На проде бэкап может замедлить отклик приложения.
— Реплика отличный способ разгрузить основной сервер.
— Бэкап с pg_basebackup возможен только на стопнутой БД или через репликацию.

🔵 Как сделать
pg_basebackup -h replica.host -U repl_user -D /backup/pg -F tar -z -P


🔵 Пояснения

-h — адрес реплики
-U — пользователь с правами репликации
-D — куда класть бэкап
-F tar -z — формат архива и сжатие
-P — прогресс в консоли

А ещё можно добавить в cron и получить стабильный ночной бэкап.

══════ Навигация ══════
Вакансии • Задачи • Собесы

🐸 Библиотека джависта

#Enterprise
  • 👍 6
  • ❤ 1
  • 🔥 1
Post #7633 2.28K
🔼 Virtual Threads: где спасают, а где нет

С Java 21 virtual threads стали stable (JEP 444). Вместо тяжёлых OS-тредов — легковесные потоки, которыми управляет JVM. Код остаётся синхронным и читаемым, а рантайм под капотом делает M:N scheduling: когда виртуальный тред блокируется на I/O, он паркуется и отпускает carrier thread другому.

На практике это значит одно: Executors.newFixedThreadPool(200) с танцами вокруг размера пула заменяется на Executors.newVirtualThreadPerTaskExecutor(). Блокирующий вызов больше не сжигает OS-тред, пока ждёт ответа от базы.

🔹 Где работает

— веб-сервисы с большим числом конкурентных запросов;
— I/O-heavy бэкенды (база, сеть, файлы);
— замена реактивщины там, где она была вынужденной, а не осознанной.

🔹 Где не работает и не должно


— connection pool базы всё ещё bottleneck.
— CPU-bound задачи не получают выигрыша, т.к. carrier threads и так заняты вычислениями.
— synchronized блоки пинят виртуальный тред к carrier thread (починили в JDK 24). Если у вас hot path с synchronized, переходите на ReentrantLock.
— Внешние API с rate limit'ами никуда не денутся.

══════ Навигация ══════
Вакансии • Задачи • Собесы

🐸 Библиотека джависта

#CoreJava
  • 👍 6
  • ❤ 4
  • 🔥 2
Post #7631 2.46K
⚡️ Магия curl

Сервис отвечает 500-кой, а вы не понимаете — проблема в сети, DNS, SSL или бэкенд лёг? Прежде чем лезть в логи и разворачивать Wireshark, попробуйте curl -w и получите полный таймлайн запроса за секунду.

🔹 Зачем это нужно

— Разбивает запрос на фазы: DNS, TCP-коннект, TLS-хендшейк, ожидание первого байта, передача данных.
— Моментально показывает, где именно bottleneck — на уровне сети или приложения.
— Работает везде: на проде, в контейнере, на CI-раннере.

🔹 Как использовать

— Полный таймлайн запроса:
curl -o /dev/null -s -w "\n  DNS: %{time_namelookup}s\n  TCP: %{time_connect}s\n  TLS: %{time_appconnect}s\n  TTFB: %{time_starttransfer}s\n  Total: %{time_total}s\n" https://your-api.com/health


— Если time_namelookup высокий, проблема в DNS, смотрите резолвер.
— Если между time_connect и time_appconnect большой разрыв, тормозит TLS, проверяйте сертификаты.
— Если time_starttransfer зашкаливает при нормальном коннекте, бэкенд думает слишком долго.
— Удобно завернуть в алиас и дёргать по крону для бедняцкого мониторинга latency.

💡 Про-тип: сохраните шаблон в файл и вызывайте через curl -w имя_файла. Не придётся каждый раз гуглить формат переменных.

══════ Навигация ══════
Вакансии • Задачи • Собесы

🐸 Библиотека джависта

#Enterprise
  • 👍 12
  • 🔥 3
  • ❤ 2
Post #7630 2.42K
🧹 Git-команда, которая спасёт ваш репозиторий от мусора

Проблема: вы удалили ветки, сделали git reset, отменили мёржи, но репозиторий почему-то весит всё больше. git clone на новом месте занимает вечность. Куда уходит место?

Дело в том, что Git — барахольщик. Он хранит все объекты: старые блобы, недостижимые коммиты, забытые stash'ы. Даже то, что вам давно не нужно.

💡 Решение: git gc и его старший брат git gc --aggressive

Рассмотрим все все возможности git gc.

1️⃣ Сколько мусора накопилось

git count-objects -vH

Обратите внимание на size-pack — это реальный вес вашего репо.

2️⃣ Самые тяжёлые объекты в истории

git rev-list --objects --all \
| git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' \
| awk '/^blob/ {print $3, $4}' \
| sort -rn \
| head -10

Часто находятся артефакты сборки, дампы БД или случайно закоммиченные .jar на 200 МБ 😬

3️⃣ Запустите агрессивную сборку мусора

git gc --aggressive --prune=now

--aggressive заставляет Git перепаковать объекты с нуля, а --prune=now удаляет недостижимые объекты немедленно, не дожидаясь дефолтных двух недель.

4️⃣ Сравните результат
git count-objects -vH

На живых проектах с историей в 2+ года разница бывает в разы.

⚠️ --prune=now безвозвратно удалит объекты, на которые нет ссылок. Если вы планировали восстановить что-то через git reflog — сделайте это до запуска.

💡 Бонус для CI/CD: если ваш пайплайн клонирует репо каждый раз — добавьте git gc в ночной cron. Экономия трафика и времени сборки может приятно удивить.

══════ Навигация ══════
Вакансии • Задачи • Собесы

🐸 Библиотека джависта

#Enterprise
  • 👍 10
  • 🔥 2
  • ❤ 1
  • 👏 1
Post #7629 2.3K
🗓 14 мая в 19:00 (Мск) встречаемся в онлайне.

Тема: Почему AI-продукты на базе LLM ломаются и как сделать, чтобы работало.

В кружке выше Эмиль Сатаев рассказал, какие именно проблемы с LLM в проде будем разбирать.

Что в программе:
- Разберем реальные кейсы стартапов и ограничения LLM.
- Обсудим рабочие архитектуры: RAG, human-in-the-loop, контроль качества.
- Ответим на ваши вопросы и разберем кейсы участников.


🎁 Бонусы: в конце вебинара подарим промокод на скидку 10.000 ₽ на курсы и разыграем подписки на полезные AI-сервисы.

👉 Зарегистрироваться на вебинар
  • ❤ 2
  • 🥱 1
Post #7624 2.81K
🕵️ P6Spy — видишь реальный SQL, который уходит в базу

Включаешь show_sql=true у Hibernate, а в логах всё равно:

where user0_.id=?


Потому что Hibernate логирует до того, как JDBC подставляет значения.

P6Spy садится между твоим кодом и JDBC-драйвером как proxy и пишет запрос уже с реальными значениями — ничего в коде менять не нужно.

→ github.com/p6spy/p6spy ⭐️ 2.2k

🔹 Maven:
<dependency>
<groupId>p6spy</groupId>
<artifactId>p6spy</artifactId>
<version>3.9.1</version>
</dependency>


🔹 application.yml — меняешь только URL и драйвер:
spring:
datasource:
url: jdbc:p6spy:postgresql://localhost/mydb
driver-class-name: com.p6spy.engine.spy.P6SpyDriver


🔹 spy.properties в classpath:
appender=com.p6spy.engine.spy.appender.Slf4JLogger
logMessageFormat=com.p6spy.engine.spy.appender.MultiLineFormat


В логах получишь:
select * from users
where id = 42
and status = 'ACTIVE'
-- took 3 ms


Что ещё умеет:

→ время выполнения каждого запроса: сразу видно N+1 и медленные места
→ свой MessageFormattingStrategy: формат лога под себя
→ фильтрация по пакету или категории запроса

⚠️ Только dev/staging. В prod каждый запрос проходит через proxy.

══════ Навигация ══════
Вакансии • Задачи • Собесы

🐸 Библиотека джависта

#Enterprise
  • ❤ 9
  • 👍 6
  • 🔥 1
Post #7623 2.48K
🤔 Ты уверен, что твой HikariCP настроен правильно?

Если все настройки — это maximumPoolSize = 32 и в прод, не проходи мимо.

А то потом реплики × 12, PostgreSQL орёт too many connections, p95 ползёт вверх, и база упадёт именно тогда, когда нельзя.

Свежая статья на Хабре про то, как считать размер пула по-настоящему: формула из PostgreSQL wiki, Little's Law, Kubernetes, PgBouncer и 10+ типовых ошибок, которые тихо живут в продовых конфигах.

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

🔗 Читать на Хабре

══════ Навигация ══════
Вакансии • Задачи • Собесы

🐸 Библиотека джависта

#Enterprise
  • 👍 3
  • ❤ 1
  • 🔥 1
Older posts →
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →