Java библиотека
СтатистикаКниги, статьи, мемы и многое другое для Java программиста! По сотрудничеству и рекламе: @NadikaKir Канал в перечне РКН: https://vk.cc/cJrT4A Мы на бирже: https://telega.in/c/javalib/ Сообщество VK https://vk.com/javatutorial
- Последний пост
- 10:08
- Последнее чтение
- 14:14
- Постов за неделю
- 25
- Всего постов
- 33
- Тип
- открытый
- Язык
- русский
- Категория
- Книги
- В каталоге с
- 12 авг.
- 1/24сутки в ленте
- 1 671
- 1/48двое суток
- 1 899
- 1/72трое суток
- 2 048
Медиана по постам, которые мы застали свежими и померили через сутки.
Посты
TimSort в Java Arrays.sort(Object[]) и Collections.sort() используют TimSort — алгоритм, разработанный Тимом Петерсом для Python в 2002 году и портированный в Java 7. Для примитивов используется dual-pivot quicksort, но для объектов — только TimSort, и причина этого выбора нетривиальна. 🟢Почему не quicksort для объектов Quicksort не стабилен — одинаковые элементы могут поменяться местами. Для примитивов это безразлично: два одинаковых int неразличимы. Для объектов же критично: Comparator может считать два объекта равными по одному критерию, но они остаются разными объектами. Нестабильная сортировка ломает составные компараторы и пользовательские ожидания. Merge sort стабилен, но требует O(n) дополнительной памяти и не использует частичную упорядоченность входных данных. 🟢Как работает TimSort TimSort строится на наблюдении: реальные данные редко полностью случайны. Массивы часто содержат уже упорядоченные подпоследовательности — runs. Алгоритм: 1. Проходит по массиву, находя естественные runs — уже отсортированные (возрастающие или убывающие) подпоследовательности. Убывающие разворачиваются на месте. 2. Если run короче минимального порога (minRun, вычисляется от размера массива, обычно 32-64 элемента) — расширяется insertion sort'ом. Insertion sort эффективен на почти отсортированных коротких последовательностях. 3. Runs помещаются в стек и сливаются попарно через merge sort. Merge происходит не сразу — алгоритм поддерживает инвариант на стеке runs для гарантии O(n log n) в худшем случае. 🟢Galloping mode При слиянии двух runs TimSort переключается в режим gallopping если обнаруживает что элементы из одного run идут длинными сериями подряд. Вместо поэлементного сравнения — бинарный поиск: ищет где именно заканчивается серия из первого run. Это даёт O(n) на уже отсортированных данных вместо O(n log n). Порог переключения в gallopping — MIN_GALLOP = 7. Если 7 раз подряд «выиграл» один run — переключаемся. Порог динамически адаптируется: если gallopping оказывается неэффективным, порог растёт. 🟢Сложность → Лучший случай (уже отсортированный массив): O(n) — один run, ничего сливать не нужно. → Средний и худший: O(n log n). → Память: O(n) в худшем случае, но на практике меньше — временный буфер для merge не всегда равен половине массива. 🟢Практическое следствие Если данные поступают уже частично отсортированными — TimSort это эксплуатирует автоматически. Повторная сортировка почти отсортированного массива значительно дешевле первичной сортировки случайных данных. Это важно для пайплайнов где данные сортируются инкрементально или приходят из источника с естественным порядком. Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
видео или голосовое, без подписи
👩💻 Spring Boot: почему нельзя делать длинные транзакции Длинные транзакции - одна из самых частых причин деградации системы, хотя код при этом может выглядеть «нормально». Что происходит на самом деле: - транзакция держит lock в базе - другие запросы начинают ждать - растёт latency - падает throughput - система перестаёт масштабироваться 📉 Итог - узкое место появляется не в коде, а в БД ❌ Плохой подход: начать транзакцию → делать бизнес-логику → ходить во внешние API → потом commit Проблема: ты держишь блокировки всё это время ✅ Правильный подход: сначала сделать всю тяжёлую работу (API, расчёты) потом быстро открыть транзакцию → записать → commit 🧠 Простое правило: транзакция должна быть максимально короткой только чтение/запись - ничего лишнего 🔥 Большинство оптимизирует запросы но сильный рост даёт именно контроль времени транзакций Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
видео или голосовое, без подписи
Вопрос с собеседования Почему String считается безопасным ключом для HashMap? Ответ: Объекты класса String в Java неизменяемы — это значит, что после создания их значение не может быть изменено. Это важно, потому что ключ в HashMap должен оставаться стабильным: и хеш, и сравнение не должны меняться со временем. Кроме того, String кэширует результат hashCode(), что делает доступ к элементам быстрее и стабильнее при многократном использовании. Благодаря этим свойствам String — надёжный и предсказуемый ключ для хеш-таблиц. Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
Инженерия данных. Паттерны проектирования (2026) PDF Основополагающая книга по паттернам проектирования систем инженерии данных. Рассматриваются различные шаблоны и рецепты для решения типичных задач в области инженерии данных, организации конвейеров данных, очистки, классификации и отслеживания данных в высоконагруженных системах. Материал сопровождается архитектурными диаграммами и минимальными примерами кода, иллюстрирующими каждый паттерн.
видео или голосовое, без подписи
👩💻 Шпаргалка по Spring аннотациям в Java! Например, @RestController объединяет контроллер и @ResponseBody, а @Autowired связывает зависимости внутри Spring-компонента. На картинке основные Spring Boot, Web и Framework-аннотации: @SpringBootApplication, @Controller, @RequestMapping, @PathVariable, @Configuration, @ComponentScan, @Service, @Bean, @Primary, @Profile и другие. Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
видео или голосовое, без подписи
видео или голосовое, без подписи
Основные команды Maven для Java-разработчиков Maven — это мощный инструмент автоматизации сборки, который используется в основном для Java-проектов. Он помогает управлять зависимостями, сборкой и жизненным циклом проекта $ mvn archetype:generate Создание нового Maven-проекта $ mvn clean Очистка директории target $ mvn compile Компиляция исходного кода $ mvn test Запуск unit-тестов $ mvn package Сборка проекта в JAR/WAR $ mvn install Установка артефакта в локальный Maven-репозиторий $ mvn install -DskipTests Пропустить тесты при сборке $ mvn spring-boot:run Запуск Spring Boot приложения (если используется spring-boot-maven-plugin) $ mvn dependency:resolve Обновление зависимостей $ mvn dependency:tree Вывод дерева зависимостей $ mvn clean compile package Запуск целей в указанной фазе $ mvn validate Проверка структуры проекта Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
видео или голосовое, без подписи
Приложение простояло 918 мс, а сборщик мусора отработал за одну: разбираемся, куда ушло остальное Секундная пауза в Java‑приложении легко выглядит как проблема сборщика мусора, хотя сам GC может отработать за миллисекунду. Разберём, как safepoint’ы заставляют JVM ждать отдельные потоки, почему профилировщик способен указать не туда и какими инструментами найти реального виновника. Читать статью Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
видео или голосовое, без подписи
Как починить мертвый ThreadLocal в пуле потоков Если положить RequestId / userId / traceId в ThreadLocal и передать задачу в ExecutorService в итоге значение пропадёт. InheritableThreadLocal помогает только при явном создании потока, но не при переиспользовании из пула. Alibaba решили это ещё в 2013 году, а библиотека до сих пор активно поддерживается → TransmittableThreadLocal (TTL). 🔹 Подключается: <dependency> <groupId>com.alibaba</groupId> <artifactId>transmittable-thread-local</artifactId> <version>2.14.5</version> </dependency> 🔹 Используется как обычный ThreadLocal, только умнее: TransmittableThreadLocal<String> traceId = new TransmittableThreadLocal<>(); traceId.set("req-123"); ExecutorService pool = TtlExecutors.getTtlExecutorService( Executors.newFixedThreadPool(4) ); pool.submit(() -> { // "req-123" — доступен здесь, в потоке из пула System.out.println(traceId.get()); }); 🔹 Три способа интеграции → Обернуть Runnable/Callable — TtlRunnable.get(task) → Обернуть пул — TtlExecutors.getTtlExecutorService(pool) → Java Agent — вообще без изменений в коде: -javaagent:transmittable-thread-local.jar Агентовый режим особенно полезен, когда нужно прозрачно встроить TTL в легаси-проект или сторонний фреймворк — он патчит JDK-классы пулов на уровне байткода. 0 зависимостей. Работает с виртуальными потоками (Project Loom). Поддерживает кастомный TtlCopier для глубокого копирования значений при передаче в дочерний поток. Актуально везде, где есть distributed tracing, MDC, tenant isolation или любой per-request контекст в многопоточке. ⚠️ README встретит иероглифами, не пугайся, английская версия лежит в README-EN.md. 🖥 Репозиторий на GitHub Полезные ресурсы по Java 👩💻| Мы в МАКС 📲
видео или голосовое, без подписи
Число прописью на Java 25: алгоритм для количественных числительных Пишем алгоритм, который превращает количество в виде числа типа long в корректное числительное на русском языке: от нуля и простых значений до Long.MAX_VALUE. Отрицательные числа отклоняем через IllegalArgumentException. Разберём триады, числа от 10 до 19, род числительных и формы «тысяча — тысячи — тысяч». Реализация выполнена на Java 25 в формате compact source. 🌐🗣СМОТРЕТЬ VKVIDEO 📺🗣СМОТРЕТЬ RUTUBE 🎞🗣СМОТРЕТЬ YOUTUBE Полезные ресурсы по Java 👩💻| Мы в МАКС 📲
видео или голосовое, без подписи
Как мониторить Java-приложения: метрики, алерты и правило 80/20 Хороший мониторинг помогает быстро понять, что происходит с приложением и куда смотреть в первую очередь. Для этого не нужно пытаться измерить всё: базовый набор технических метрик покрывает большинство типовых проблем, а бизнес-метрики, SLO и анализ аномалий помогают заранее замечать нетипичные отклонения. В Календаре мы называем этот подход правилом 80/20. Всем привет! Меня зовут Настя, я бэкенд-разработчик в Яндекс 360 и отвечаю за надёжность Календаря. В этой статье я покажу, какие метрики стоит взять за основу, как выбирать полезные алерты и чем дополнять базовый набор для оставшихся 20%. Читать статью Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
👩💻 Spring Boot ошибка, которую делают почти все Большинство просто добавляет: spring-boot-starter-web и не думает дальше. Но вот в чём проблема 👇 Этот стартер тянет за собой: - встроенный сервер (Tomcat) - лишние зависимости - ненужный overhead 👉 даже если тебе нужен только MVC 💡 Правильный подход: Если тебе нужен только Spring MVC — используй: spring-boot-starter-webmvc Что это даёт: • меньше зависимостей • быстрее запуск • чище архитектура • меньше ресурсов 🔥 Когда это критично - микросервисы - serverless - high-load системы - оптимизация старта 🧠 Инсайт Чем меньше лишнего ты тащишь в проект → тем проще его поддерживать 👉 Не ставь "на всякий случай" Ставь только то, что реально нужно Полезные ресурсы по Java 👩💻| Мы в МАКС 📲