Библиотека джависта | Java, Spring, Maven, Hibernate
24.9K subscribers
1.86K photos
38 videos
42 files
2.64K links
Все самое полезное для Java-разработчика в одном канале.

Список наших каналов: https://yangx.top/proglibrary/9197

Обратная связь: @proglibrary_feedback_bot

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

РКН: https://gosuslugi.ru/snet/67a5bbda1b17b35b6c1a55c4
加入频道
🗑 Как устроен сборщик мусора?

В Java управление памятью происходит автоматически, но работа сборщика мусора (GC) гораздо сложнее. Разберем ключевые аспекты работы GC.

🔍 Генерации памяти (Heap Generations)

GC делит память на несколько областей или генераций, каждая из которых соответствует "возрасту" объектов:

🔹 Young Generation (Молодое поколение): Эта область для новых объектов, которые живут кратковременно. Молодое поколение делится на:
▪️ Eden Space: В этой области создаются все новые объекты.
▪️ Survivor Spaces (S0 и S1): Выжившие после очистки в Eden объекты перемещаются сюда. Объекты могут несколько раз перемещаться между S0 и S1, и после определенного количества циклов они переходят в Старое поколение. Эти перемещения также позволяют JVM определять «горячие» (т.е. часто используемые) объекты.
🔹 Old Generation (Старое поколение): Сюда попадают долгоживущие объекты, которые успешно пережили несколько циклов очистки в Young Generation. Эта область требует менее частых, но более длительных операций очистки.
🔹 Metaspace: Содержит метаданные классов, информацию о методах и другую информацию, не относящуюся к объектам напрямую.

⚙️ Алгоритмы и процессы очистки:

🔹 Minor GC (очистка молодого поколения):

- При заполнении Eden Space происходит Minor GC. Этот процесс быстрый, так как большинство объектов в молодом поколении недолговечны.
- GC проверяет ссылки на объекты в Eden и перемещает выжившие объекты в Survivor Space.
- Minor GC обычно не вызывает длительных пауз в программе, так как при использовании многопоточных алгоритмов паузы минимальны. В процессе применяется "write barrier", что позволяет избежать необходимости полного сканирования ссылок из Старого поколения.

🔹 Major GC (или Full GC):

- Когда Old Generation заполняется, запускается Major GC или Full GC. Этот процесс требует больше времени, так как нужно обработать долгоживущие объекты.
- В этом процессе может возникать пауза Stop-the-World, когда JVM останавливает выполнение приложения на время очистки.
- В Major GC используется либо маркировка-сжатие (Mark-Compact), либо маркировка-очистка (Mark-Sweep), что позволяет устранить фрагментацию памяти.

Алгоритмы и стратегии GC

- Mark-Sweep-Compact: Алгоритм сначала маркирует живые объекты, затем удаляет неиспользуемые, а в конце сжимает память, чтобы устранить фрагментацию.
- Copying (для Young Generation): Используется для быстрого перемещения объектов из Eden в Survivor Space, что позволяет быстро очищать Eden.
- Generational Hypothesis: Основная гипотеза GC — большинство объектов "умирает" молодыми, поэтому Young Generation обрабатывается быстрее и чаще.

💡 Особенности различных типов GC

- Serial GC: Однопоточный, использует Stop-the-World паузы и подходит для небольших приложений.
- Parallel GC: Применяет многопоточность для быстрого удаления мусора, что повышает пропускную способность.
- G1 GC (Garbage-First GC): Подразделяет память на регионы и работает с ними независимо, что минимизирует фрагментацию и "Stop-the-World" паузы. Подходит для приложений с большими объемами памяти.
- ZGC и Shenandoah GC: Эти алгоритмы разработаны для работы практически без остановок, что актуально для интерактивных и критичных приложений.

🛠 Выбор GC зависит от требований приложения


Если критичны низкие задержки, предпочтителен ZGC или Shenandoah GC.
Для приложений с высокой нагрузкой и большим объемом данных — G1 GC.
Для часто выделяющих и освобождающих объекты приложений, таких как веб-приложения, G1 или ZGC также могут обеспечить оптимальную производительность.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔐 🔑 OAuth 2: как работает современная авторизация

Помнишь кнопку «Войти через Google»? Та самая кнопка, которая избавляет от необходимости запоминать очередной пароль. Сегодня разберем, как работает эта магия изнутри, почему гиганты вроде Spotify и Medium используют такой способ входа, и как внедрить его в свое приложение. Спойлер: это проще, чем кажется, и гораздо безопаснее традиционной формы регистрации.

Читать статью
📊 CI/CD Pipeline

CI/CD пайплайн — это система, которая позволяет автоматизировать ключевые этапы разработки: от сборки и тестирования до развертывания программного обеспечения. Такой подход объединяет все стадии жизненного цикла проекта — написание кода, его проверку, тестирование и публикацию — в единый поток, где каждый шаг выполняется автоматически и последовательно.

На диаграмме выше представлены инструменты, которые часто используются для создания эффективного CI/CD пайплайна.

💬 Вы применяете какие-то из них в своих проектах?
Please open Telegram to view this post
VIEW IN TELEGRAM
🕯 Паттерн Синглтон (Singleton)

Singleton — это порождающий паттерн, который гарантирует, что у класса есть только один экземпляр, и предоставляет глобальную точку доступа к этому экземпляру. Он часто используется для управления доступом к общим ресурсам, таким как базы данных, файлы конфигурации или сетевые соединения.

Использование:

🔹 Когда необходимо гарантировать, что класс имеет только один экземпляр (например, для работы с конфигурацией приложения).
🔹 Когда требуется предоставить глобальную точку доступа к объекту.
🔹 В случаях, когда управление состоянием одного объекта критично для приложения (например, пул соединений).

Преимущества:

1️⃣ Гарантирует наличие только одного экземпляра, что удобно для управления ресурсами и предотвращения конфликтов.
2️⃣ Обеспечивает ленивую инициализацию, что позволяет создавать объект только при необходимости (если реализовано правильно).
3️⃣ Удобен для централизованного управления состоянием или ресурсами в системе.

Недостатки:

1️⃣ Нарушает принцип единственной ответственности (SRP), так как класс управляет своим созданием и жизненным циклом.
2️⃣ Усложняет тестирование, поскольку сложно замещать или мокать объект.
3️⃣ Может создавать скрытые зависимости, что приводит к сложности поддержки и масштабирования кода.
4️⃣ В многопоточной среде требуется дополнительная синхронизация для обеспечения безопасности, что может снижать производительность.

📌 Паттерн полезен, если требуется строгий контроль над количеством экземпляров класса. Например, он часто применяется в логировании, управлении настройками приложения или в реализации драйверов доступа к базам данных. Однако его использование должно быть обоснованным, так как чрезмерное применение может усложнить архитектуру.
Please open Telegram to view this post
VIEW IN TELEGRAM
🛠️ Свежий релиз Docker Desktop 4.35

🐳 Токены доступа для организаций (Beta) — Эта функция улучшает управление доступом на уровне организаций. Она позволяет централизовано управлять правами пользователей, обеспечивая лучшее управление и масштабируемость для бизнеса.

🐳 Docker Home (Beta) — Новый интерфейс Docker Home служит центральным «хабом» для доступа к продуктам Docker, управления подписками и настройками.

🐳 Интерфейс терминала в Docker Desktop — Эта функция позволяет интегрировать терминал в интерфейс Docker Desktop, упрощая работу разработчиков и снижая необходимость переключаться между CLI и GUI.

🐳 Резервное копирование томов — В Docker Desktop теперь доступна улучшенная функция резервного копирования томов, которая упрощает процесс создания бэкапов данных и делает его более удобным.

🐳 Улучшенная производительность на macOS — Введение Docker VMM для Apple Silicon улучшает производительность на Mac, ускоряя выполнение множества задач.

📎 Подробнее в блоге компании
🚀 Как ускорить распределенные системы: 8 стратегий снижения времени ожидания

Высокая latency — это скрытый враг, превращающий приложение в тормозящую телегу. Особенно в распределённых системах, где данные путешествуют между серверами и каждая задержка становится катастрофой. Знаете ли вы, какие 8 стратегий помогут превратить "задумчивое" приложение в настоящего чемпиона?

Что эффективнее: кэшировать, сжимать или оптимизировать запросы к базе? А что, если правильный ответ — балансировка нагрузки или вообще CDN?

💡 Найдите недостающий элемент в вашем стеке и максимально ускорьте свои приложения.

🔗 Читать статью
🔗 Зеркало
🚀 Apache Pulsar 4.0: новые горизонты для работы с потоками данных

Apache Pulsar, одна из самых популярных платформ для работы с потоками данных, представила версию 4.0, и это событие заслуживает внимания. 🌟

Что нового:


1️⃣ Улучшенная реализация подписки Key_Shared: обеспечивает более эффективную и надежную обработку сообщений с использованием подписки типа Key_Shared.
2️⃣ Безопасная Docker-среда на базе Alpine Linux и Java 21: новые Docker-образы основаны на Alpine Linux, что уменьшает размер образа и повышает безопасность. Включение Java 21 с Generational ZGC улучшает производительность.
3️⃣ Поддержка OpenTelemetry: внедрение OpenTelemetry-метрик в клиенте Pulsar позволяет более эффективно отслеживать и анализировать производительность приложений.
4️⃣ Обновления в управлении нагрузкой: внедрение новых алгоритмов балансировки нагрузки, таких как AvgShedder, улучшает распределение ресурсов и повышает стабильность системы.
5️⃣ Поддержка Geo-Replication с началом с самой ранней позиции: обеспечивает более гибкое управление репликацией данных между кластерами.

🔗 Узнать больше

💬 Кто уже использует Apache Pulsar?
Please open Telegram to view this post
VIEW IN TELEGRAM
ℹ️ Что такое нормализация базы данных, и какие существуют нормальные формы?

Нормализация — это процесс приведения структуры базы данных к оптимальному виду для устранения избыточности данных и обеспечения их целостности. Процесс состоит из последовательных этапов, соответствующих нормальным формам (НФ).

Основные нормальные формы (НФ):

1️⃣ Первая нормальная форма (1НФ):
Данные делятся на атомарные (неделимые) значения.
Пример: В одной ячейке таблицы не может быть списка телефонов, вместо этого создается отдельная строка для каждого телефона.

2️⃣ Вторая нормальная форма (2НФ):
Требует выполнения 1НФ и исключения зависимости от части составного первичного ключа. Это устраняет проблему дублирования данных.
Пример: Если таблица использует составной ключ (например, "Курс" и "Студент"), информация, относящаяся только к "Курсу", выносится в отдельную таблицу.

3️⃣ Третья нормальная форма (3НФ):
Выполняется 2НФ и устраняются транзитивные зависимости — неключевые атрибуты должны зависеть только от ключа.
Пример: Если в таблице есть "ID сотрудника", "Отдел" и "Название отдела", то "Название отдела" переносится в отдельную таблицу "Отделы".

Редко используемые нормальные формы:

- Нормальная форма Бойса-Кодда (BCNF): Уточнённая версия 3НФ, где каждое определяющее множество является суперключом. Используется для устранения более сложных аномалий.
- Четвёртая нормальная форма (4НФ): Устраняет многозначные зависимости, которые появляются при использовании нескольких связей между одними и теми же атрибутами.
- Пятая нормальная форма (5НФ): Делает базу данных устойчивой к разделению данных, устраняя зависимости соединений.

Эти формы применяются в сложных сценариях, например, при проектировании корпоративных систем с огромным количеством взаимосвязей. Для большинства приложений 3НФ оказывается достаточной.
Please open Telegram to view this post
VIEW IN TELEGRAM
❗️Вакансии «Библиотеки программиста» — ждем вас в команде!

Мы постоянно растем и развиваемся, поэтому создали отдельную страницу, на которой будут размещены наши актуальные вакансии. Сейчас мы ищем:
👉контент-менеджеров для ведения телеграм-каналов

Подробности тут

Мы предлагаем частичную занятость и полностью удаленный формат работы — можно совмещать с основной и находиться в любом месте🌴

Ждем ваших откликов 👾
Какой компонент в Apache Kafka отвечает за сохранение сообщений в топиках?
Anonymous Quiz
9%
Consumer
19%
Producer
45%
Broker
19%
Zookeeper
7%
Controller
🤖🛠 11 лучших ИИ-инструментов для разработки в 2024 году

В мире разработки программного обеспечения искусственный интеллект становится незаменимым помощником, способным значительно повысить продуктивность и качество кода. Представьте себе инструменты, которые не только автоматически дополняют ваш код, но и генерируют целые фрагменты, преобразуют дизайн в готовый код и обеспечивают безопасность вашего приложения. Хотите узнать, какие ИИ-инструменты помогут вам быть на шаг впереди в 2024 году? Откройте для себя решения, которые сделают ваш рабочий процесс более эффективным и инновационным.

🔗 Читать статью
🔗 Зеркало
Привет, друзья! 👋

Мы готовим статью о том, как эффективно изучать программирование, и хотим услышать ваше мнение! 🤓💻 Поделитесь своим опытом, и самые полезные советы войдут в нашу публикацию.
💡 Какой совет вы бы дали начинающим программистам? Поделитесь своими мыслями в комментариях👇
🧑‍💻 Статьи для IT: как объяснять и распространять значимые идеи

Напоминаем, что у нас есть бесплатный курс для всех, кто хочет научиться интересно писать — о программировании и в целом.

Что: семь модулей, посвященных написанию, редактированию, иллюстрированию и распространению публикаций.

Для кого: для авторов, копирайтеров и просто программистов, которые хотят научиться интересно рассказывать о своих проектах.

👉Материалы регулярно дополняются, обновляются и корректируются. А еще мы отвечаем на все учебные вопросы в комментариях курса.
📊 Как работает ConcurrentHashMap под капотом?

ConcurrentHashMap – это высокопроизводительная реализация Map, специально разработанная для многопоточной среды. Она гарантирует безопасность данных при одновременном доступе и минимизирует использование блокировок.

💡 Основные механизмы:

🔹 Сегментация данных (до 8 java): Данные разделялись на сегменты, и блокировка происходила на уровне сегмента, а не всей карты. Это обеспечивало параллельный доступ к разным частям карты.

🔹 Кассовые таблицы (Java 8+): Вместо сегментов используется структура на основе Node[] – массив узлов. Это сделало структуру более гибкой. Вместо сегментации применяется механизм Fine-Grained Locking и Compare-And-Swap:
- Compare-And-Swap используется для операций записи, что позволяет избегать блокировок для большинства операций. Операции с разными бакетами могут выполняться параллельно, поскольку локальная блокировка применяется только к отдельному узлу или бакету.
- Fine-Grained Locking минимизирует область блокировок. Например, если требуется масштабирование (resize) или обработка коллизий, потоки могут продолжать работу с другими бакетами, даже если один из них временно заблокирован.
- synchronized применяется только для случаев, когда CAS не справляется (например, при реорганизации данных или сложных операциях). Это помогает поддерживать баланс между безопасностью и производительностью.

🔹 Масштабируемый массив (Resizable Array): Масштабирование в ConcurrentHashMap происходит градуально, чтобы избежать блокировки всей структуры. Новый массив создаётся с увеличенным размером, и данные переносятся постепенно, по частям. Во время переноса используется специальный узел ForwardingNode, который перенаправляет операции к новому массиву, обеспечивая корректную работу всех потоков.

📚 Основные методы:

▪️ get(Object key):
Легковесная операция, не требует блокировок. Ключ хэшируется, затем вычисляется индекс сегмента. Если в сегменте есть соответствующий узел, он возвращается.

▪️ put(K key, V value):
- Сначала используется CAS для вставки нового элемента.
- Если CAS не срабатывает (например, при наличии коллизии), включается локальная блокировка на соответствующей корзине.

▪️ computeIfAbsent/compute:
Более сложные операции, которые комбинируют вычисления с модификацией. Используются короткие локи для минимизации блокировки других потоков.

⚠️ Особенности:

- ConcurrentHashMap не допускает хранения null для ключей и значений. Это связано с невозможностью различать отсутствие значения и реальное хранение null.
- Итерации по карте предоставляют "слабо согласованные" данные, что означает, что изменения, происходящие параллельно, могут быть частично видны.

Документация
Please open Telegram to view this post
VIEW IN TELEGRAM
💡 Как избавиться от WebSockets и сэкономить $1 млн в год: неожиданные решения для оптимизации

Как снизить расходы на инфраструктуру и повысить эффективность? Оказывается, отказ от WebSockets может сэкономить миллионы. Вместо привычного подхода можно использовать решения, которые не только проще, но и лучше подходят для определённых задач, как, например, асинхронные очереди или SSE.

Знаете ли вы, как выбрать стратегию, которая одновременно сократит затраты и улучшит масштабируемость? Разберитесь в тонкостях оптимизации и найдите способ выжать максимум из вашей системы. 🚀

🔗 Читать статью
🔗 Зеркало