Библиотека джависта | 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
加入频道
ℹ️ Что такое BeanFactoryPostProcessor в Spring?

BeanFactoryPostProcessor — это интерфейс из Spring Framework, который позволяет вмешиваться в процесс создания бинов в BeanFactory до их инициализации, но после того, как Spring их создал. Он предоставляет один основной метод:

▪️ postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) — вызывается до инициализации бинов. В этом методе можно изменять конфигурацию бинов, например, добавлять или изменять их свойства, влиять на их типы или даже на порядок их создания.

Зачем нужен BeanFactoryPostProcessor?

Он используется для того, чтобы дать возможность кастомизировать настройки Spring контейнера, не вмешиваясь в сам процесс создания объектов. Примеры:

- Изменение параметров конфигурации бинов, которые уже были определены в контексте.
- Использование кастомных значений или свойств для бинов до их создания.
- Управление зависимостями на уровне контейнера.
- Добавление пользовательских конфигураций, таких как создание собственных PropertyEditors или манипуляции с BeanDefinition.

Как это работает?

1️⃣ Spring сканирует контекст на наличие бинов, реализующих интерфейс BeanFactoryPostProcessor.
2️⃣ Эти бины выполняются до создания бинов в контейнере, и вы можете изменить BeanDefinition в контейнере.
3️⃣ Вы можете, например, изменять параметры и настройки бинов, задавать или корректировать их зависимости, которые будут использованы при создании бинов Spring.

Пример реализации:

@Component
public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Пример изменения beanDefinition
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("someBean");
beanDefinition.getPropertyValues().add("someProperty", "newValue");
}
}

В этом примере изменяются настройки существующего бина до его создания, что позволяет управлять его поведением в контейнере.
Please open Telegram to view this post
VIEW IN TELEGRAM
Сколько объектов станут доступны для сборщика мусора после удаления ссылки на сет?
Anonymous Quiz
15%
0
18%
1
12%
2
17%
3
39%
4
Какой инструмент для работы с БД вы чаще используете?

🔥 Spring Data JPA
👍🏼 Hibernate
⚡️ JDBC
❤️ MyBatis
👾 JOOQ

💬 Пишите в комментарии, про какой инструмент было бы интересно почитать на канале
Please open Telegram to view this post
VIEW IN TELEGRAM
📊 Как работает ConcurrentSkipListMap под капотом?

ConcurrentSkipListMap — это потокобезопасная и отсортированная реализация интерфейса NavigableMap, которая работает на основе skip list (списка с пропусками). Skip list — это многослойная структура данных, состоящая из нескольких уровней связных списков: нижний уровень содержит все элементы в порядке сортировки, а верхние уровни — лишь часть элементов для ускорения поиска. При добавлении элемента случайно выбирается его "высота" (количество уровней, на которых он присутствует), что позволяет "перепрыгивать" через блоки данных на верхних уровнях и выполнять операции со сложностью O(log n).

Пример структуры:
lvl 3: 1 ------ 8
lvl 2: 1 --- 7 -- 8
lvl 1: 1 - 3 - 7 - 8 - 10


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

🔹 Skip List: Многослойный список с пропусками, где верхние уровни помогают быстро достигать нужного диапазона элементов, снижая количество переходов по связям.
🔹 Потокобезопасность обеспечивается за счёт использования CAS (Compare-And-Swap) операций и минимального блокирования. Модификации происходят безопасно без полной блокировки структуры.
🔹 Элементы всегда хранятся в отсортированном порядке по их ключам, что позволяет выполнять операции вроде поиска диапазонов или итераций по упорядоченным ключам очень эффективно.
🔹 Высокая доступность: чтение не блокируется, даже если выполняются параллельные операции вставки или удаления.

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

▪️ Операции чтения (например, get или containsKey) выполняются быстро и без блокировок благодаря структуре skip list.
▪️ Операции записи (например, put и remove) синхронизированы, но производительность сохраняется за счёт оптимизации с использованием CAS.
▪️ Поддерживает натуральный порядок ключей или порядок, определённый переданным компаратором.
▪️ Эффективен для сценариев, где важны отсортированные данные и параллельный доступ, но количество обновлений не слишком велико.

🚀 Когда использовать ConcurrentSkipListMap?

- Если нужен параллельный доступ к отсортированной мапе.
- Для обработки диапазонов данных или частых операций чтения в упорядоченном виде.

🔗 Документация
Please open Telegram to view this post
VIEW IN TELEGRAM
🧑‍💻 Статьи для IT: как объяснять и распространять значимые идеи

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

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

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

👉Материалы регулярно дополняются, обновляются и корректируются. А еще мы отвечаем на все учебные вопросы в комментариях курса.
Вакансии «Библиотеки программиста» — ждем вас в команде!

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

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

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

Ждем ваших откликов 👾
🌐 Как работает GraphQL и чем он лучше RESTful API

GraphQL не следует путать с SQL — он не используется для прямых запросов к таблицам базы данных. GraphQL — это, скорее, формат или структура, которая задаёт контракт между клиентом и сервером API. Его можно рассматривать как спецификацию или новый стандарт API, похожий на REST, но более эффективный и гибкий.

В новой статье делаем детальный разбор преимуществ и недостатков GraphQL с примерами кода. Помогаем понять, стоит ли переходить на эту технологию в вашем проекте.

👉 Читать по этой ссылке
👑🧟 Король спама: насколько сильно ты бесишь коллег в рабочих чатах

Признайся, ты тоже иногда отправляешь голосовые сообщения из маршрутки? Или может быть, ты тот самый человек, который пишет «Привет» и исчезает на час? Всего 10 вопросов, которые помогут понять, являешься ли ты мастером цифрового этикета или главным спамером офиса. Готов узнать правду?

👉 Пройти тест
YYYY? yyyy!

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

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

Подробнее о том, как избежать подводных камней при работе с датой в статье.
Please open Telegram to view this post
VIEW IN TELEGRAM
📚 Pragmatic Unit Testing in Java with JUnit (2024)
✍️ Автор: Jeff Langr
📃 Страниц: 512

В этом издании вы узнаете, как создавать лаконичные и удобные в обслуживании модульные тесты. Новые главы содержат примеры для тестирования общих концепций, а также рекомендации по использованию современных инструментов искусственного интеллекта в разработке и тестировании. Обновленные темы включают повышение качества тестов с помощью мнемоник разработки, увеличение рентабельности инвестиций за счет рефакторинга тестового и производственного кода, а также использование тестов для стимулирования разработки.
Новый год — время для новых начинаний!
Пока все строят планы на будущее, подумайте, что поможет вам двигаться вперёд в карьере. Мы знаем, что навыки в IT открывают огромные возможности — и мы готовы помочь вам начать!

🔹 Почему IT?

- Большинство компаний активно ищут специалистов.
- Вы можете работать из любой точки мира — с гибким графиком и интересными задачами.
- А ещё IT — это высокий доход и стремительный карьерный рост.

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

📚 Как это работает?

- Несколько программ по цене одной — выбирайте всё, что вам нужно.
- Бессрочный доступ — учитесь в своём ритме и когда удобно.
- Это выгодно — вы получаете навыки, которые помогут вам расти профессионально и зарабатывать больше.

А для тех, кто решит сделать шаг в будущее до конца года, у нас есть кое-что особенное… 🎁 Узнайте больше

Как выбрать свой путь?
Мы предлагаем несколько уникальных комбинаций курсов, которые помогут вам стать настоящим экспертом:

🔵 Математика для Data Science + Алгоритмы и структуры данных — для тех, кто хочет готовиться к собеседованиям в топовые компании.

🔵 Алгоритмы + ML — чтобы не просто решать задачи, а понимать, как работают современные технологии.

🔵 Frontend + ML — создавайте приложения и учитесь работать с нейросетями.

🔵 И другие комбинации для разных целей.

Новогодний подарок, который будет работать на вас весь год — это отличная идея! 🎁 Начните сейчас

Развивайтесь в IT — и будущее уже будет в ваших руках!
🕯 Паттерн Легковес (Flyweight)

Flyweight — это структурный паттерн, который позволяет экономить память за счёт повторного использования уже имеющихся объектов, разделяя их состояние на внутреннее и внешнее. Внутреннее состояние хранится в самом объекте и не зависит от контекста, а внешнее передаётся извне.

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

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

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

1️⃣ Экономия памяти: значительно снижает количество создаваемых объектов за счёт их повторного использования.
2️⃣ Увеличение производительности: сокращает накладные расходы на создание и хранение объектов.
3️⃣ Чёткое разделение состояний: внутреннее состояние становится независимым от внешнего контекста.

Недостатки:


1️⃣ Усложнение кода: управление внешним состоянием может стать менее удобным.
2️⃣ Повышенные затраты на реализацию: требует точного анализа системы для выделения общего состояния.
3️⃣ Не всегда применим: если объекты не имеют повторяющихся данных, паттерн бесполезен.

📌 Flyweight отлично подходит для оптимизации ресурсов в играх (например, представление графических объектов) или при работе с большими наборами данных.
Please open Telegram to view this post
VIEW IN TELEGRAM
🌩 Что такое S3 и как его использовать в Java?

Amazon S3 (Simple Storage Service) — это облачное хранилище от AWS, которое позволяет безопасно сохранять и извлекать данные любого объёма и формата. S3 предоставляет масштабируемое решение для хранения файлов, данных резервного копирования, статического контента для веб-приложений и многого другого.

🔹 Ключевые особенности S3:


- Данные хранятся в виде объектов (файлов), которые организуются в бакеты.
- S3 легко интегрируется с приложениями благодаря API.
- Поддержка шифрования данных и управление доступом через IAM.
- От небольших проектов до огромных хранилищ данных.
- 99,999999999% (11 девяток!) долговечности данных.

🔹 Как начать работу с S3 в Java?

1️⃣ Подключите SDK:
Добавьте зависимость в ваш проект.

<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
<version>{actualVersion}</version>
</dependency>


2️⃣ Настройте доступ:
Создайте учетные данные AWS (Access Key и Secret Key). Эти ключи позволяют вашему приложению взаимодействовать с S3.

3️⃣ Пример загрузки/выгрузки файла в/из S3:

public class S3Example {
public static void main(String[] args) {
S3Client s3 = S3Client.create();

// Загрузка файла в S3
s3.putObject(
PutObjectRequest.builder()
.bucket("my-bucket-name")
.key("example.txt")
.build(),
Paths.get("path/to/local/file.txt")
);
System.out.println("Файл успешно загружен в S3");

// Выгрузка файла из S3
s3.getObject(
GetObjectRequest.builder()
.bucket("my-bucket-name")
.key("example.txt")
.build(),
Paths.get("path/to/downloaded/file.txt")
);
System.out.println("Файл успешно выгружен из S3");
}
}


💡 Где это пригодится?

- Хранение статического контента для веб-приложений.
- Бэкапы данных и журналов.
- Интеграция с микросервисами для обмена файлами.
- Хранение обучающих наборов данных для ML.
Please open Telegram to view this post
VIEW IN TELEGRAM
Где вы чаще всего пишете код?

❤️ IntelliJ IDEA
🔥 Vim/Emacs
👍🏼 Eclipse
⚡️ VS Code
😁 Notepad++

💬 Пишите в комментарии интересные/полезные фичи вашего инструмента
Please open Telegram to view this post
VIEW IN TELEGRAM
#дайджест #Javadevjob

Вакансии Java разработчиков уровня Junior

▪️ Программист Java (junior)
Гибрид (Челябинск), ЧЕЛЯБИНВЕСТБАНК
Подробнее

▪️ Java разработчик [Junior]
Офис (Омск), deeplay
Подробнее

Вакансии Java разработчиков уровня Middle

▪️ Java разработчик
Офис (Москва) / Удалёнка, ЛАНИТ
Подробнее

▪️ Java разработчик
Удалёнка (РФ), Sitronics Group
Подробнее

Вакансии Java разработчиков уровня Senior

▪️ Senior Java Developer
Удалёнка / Офис (Москва, Санкт-Петербург), Метр квадратный
Подробнее

▪️ Senior Java developer
Удалёнка (РФ), Газпромбанк
Подробнее

Понравились вакансии?
❤️ — да
🤔 — нет
👀 Задачи с собеседований: Поиск подмассива с максимальной суммой (middle)

— Дан массив целых чисел, необходимо найти подмассив с наибольшей суммой и вернуть эту сумму.

💡 Ключевые моменты:

- Подмассив — это непрерывная последовательность элементов исходного массива.
- Требуется определить такую последовательность, сумма элементов которой максимальна.
- Эффективное решение задачи достигается с помощью алгоритма Кадане, который позволяет найти максимальную сумму подмассива за линейное время O(n).

Реализация на картинке 👆🏻
Please open Telegram to view this post
VIEW IN TELEGRAM
ℹ️ Что такое ForkJoinPool?

ForkJoinPool — это специализированный пул потоков в Java, предназначенный для выполнения задач, которые можно разделить на более мелкие подзадачи и объединить результаты их выполнения. Этот пул является частью пакета java.util.concurrent и основан на принципе разделяй и властвуй (divide and conquer).

ForkJoinPool позволяет эффективно выполнять параллельные вычисления, автоматически распределяя задачи между доступными потоками и оптимизируя их выполнение. Он используется для задач, которые могут быть:

- Рекурсивно разделены на подзадачи.
- Выполнены параллельно.
- Объединены в один итоговый результат.

🔹 Как работает?

1️⃣ Разделение задачи (fork):
Большая задача разбивается на несколько подзадач, каждая из которых может быть выполнена независимо.

2️⃣ Выполнение подзадач:
Каждая подзадача отправляется в пул потоков для выполнения.

3️⃣ Объединение результатов (join):
После выполнения подзадачи результаты объединяются для получения итогового значения.

🔹 Пример использования:

Для работы с ForkJoinPool используются два ключевых абстрактных класса:

- RecursiveTask<V> — для задач, которые возвращают результат.
- RecursiveAction — для задач, которые ничего не возвращают.

Пример: нахождение суммы чисел массива с помощью RecursiveTask:

class SumTask extends RecursiveTask<Integer> {
private int[] array;
private int start, end;

public SumTask(int[] array, int start, int end) {
this.array = array;
this.start = start;
this.end = end;
}

@Override
protected Integer compute() {
if (end - start <= 10) {
int sum = 0;
for (int i = start; i < end; i++) {
sum += array[i];
}
return sum;
} else {
int mid = (start + end) / 2;
SumTask leftTask = new SumTask(array, start, mid);
SumTask rightTask = new SumTask(array, mid, end);

leftTask.fork();
int rightResult = rightTask.compute();
int leftResult = leftTask.join();

return leftResult + rightResult;
}
}
}

public class ForkJoinExample {
public static void main(String[] args) {
ForkJoinPool forkJoinPool = new ForkJoinPool();

int[] array = new int[100];
for (int i = 0; i < array.length; i++) {
array[i] = i + 1;
}

SumTask task = new SumTask(array, 0, array.length);
int result = forkJoinPool.invoke(task);

System.out.println("Сумма: " + result);
}
}


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


- Work-Stealing алгоритм:
Потоки берут задачи из очередей других потоков, если у них нет своей работы. Это минимизирует простои.

- Поддержка параллельных вычислений:
Упрощает разработку алгоритмов, которые можно разделить и выполнить параллельно.

- Автоматическая настройка потоков:
Количество потоков настраивается автоматически в зависимости от доступных процессорных ядер (Runtime.getRuntime().availableProcessors()).

🔹 Когда использовать?

- Для задач, которые можно рекурсивно разбить на подзадачи.
- Для вычислительных задач, таких как сортировка, поиск, суммирование, обработка больших данных.
- Когда требуется высокая производительность в многопоточной среде.
Please open Telegram to view this post
VIEW IN TELEGRAM