Статистика
Подписчики
30 539
-8день
-24неделя
-96месяц
Охват поста
1 296
1 296за 24 часа
1 381в среднем
Вовлечённость
4,2%
4,2%за 24 часа
7,1%в среднем
Упоминания в других каналах
Канал упомянули 579 раз в 77 каналах
Чем больше упоминаний и каналов — тем заметнее канал в своей нише.
О канале
Описание в Telegram
Книги, статьи, мемы и многое другое для Java программиста! По сотрудничеству и рекламе: ссылка скрыта Канал в перечне РКН: ссылка скрыта Мы на бирже: ссылка скрыта Сообщество VK ссылка скрыта
- Аудитория
- Смешанная аудитория
О подписчиках
Вк, телеграм
Оценки и отзывы
Формат размещения
4 500 ₽
топ 1 час · сутки в ленте · цена напрямую от автора
💎Эффективность за эти деньги
3,47 ₽
CPV · за показ
3 472,22 ₽
CPM · за 1000
Пересчитывается от формата и охвата 1 296/24ч
Гарантия выхода поста и возврат средств
Надёжность сделки
Время ответа админа
Обычно отвечает быстро
Размещений через Помогач
Первое размещение — за вами
Посты в канале
Java библиотека
Telegram · канал
Не прячьте обязательные действия в peek или map
Stream может пропустить промежуточные операции, если результат терминальной операции можно получить без обработки элементов. Пример — count() для источника с известным размером:
long size = List.of("A", "B").stream()
.peek(System.out::println)
.count();
Печать здесь не гарантирована. Замена peek() на map(), возвращающий тот же элемент, не создаёт такой гарантии.
Если действие обязательно для каждого элемента, вынесите его в обычный цикл или выберите подходящую терминальную операцию. Для последовательного обхода с понятным управлением ошибками цикл часто проще.
peek удобно использовать для диагностики потока, но бизнес-операции не должны зависеть от его побочных эффектов.
#Java
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
1 062 просм.22 окт., 15:01
1 166 просм.22 окт., 11:01
1 214 просм.22 окт., 11:01
👨🏻💻 AI в бэкенд-задачах — на Podlodka Backend Crew
Код теперь может написать агент, но за результат всё ещё отвечаете вы. Организаторы Podlodka Backend Crew собрали конференцию о том, как работать с бэкендом после того, как AI написал код.
Причём в программе нет докладов в жанре «у нас все получилось» — только реальная практика. Конференция пройдёт с 26 по 30 октября.
🧠️️️️️️ Участники сезона:
• Разберут пулл‑реквесты от агента и попробуют предотвратить возможные инциденты на рулетке кейсов
• Выяснят, какие неожиданные ловушки скрываются в OpenAPI и на что обращать внимание при разработке контрактов
• Разберут антипаттерны в AI-юнит-тестах, узнают, как их избежать с помощью современных инструментов, и заберут себе новый агентский скилл
• Спроектируют бэкенд дейтинг-приложения на архитектурной кате и решат, где в нём действительно нужен AI.
Формат Podlodka Backend Crew — комфортный онлайн: 5 дней, утренние и вечерние сессии в Zoom.
Отдельный плюс — цена: заметно ниже привычных конференций, при этом вы не просто слушаете о чужом опыте, а разбираете PR и отвечаете за релиз, проектируете систему в команде и расследуете чужие провалы.
Такого вовлечения не получить на обычной конференции.
🔗 Изучайте программу и присоединяйтесь: https://podlodka.io/becrew
1 089 просм.22 окт., 11:01
1 213 просм.22 окт., 11:01
1 209 просм.22 окт., 11:01
DIP и DI: направление зависимости и способ сборки
Dependency Inversion Principle относится к архитектуре: политика приложения зависит от подходящего контракта, а детали реализуют его. Dependency Injection — способ передать зависимость объекту.
Например, сервису оформления заказа нужен контракт сохранения заказа. Он может получить его через конструктор и не знать, используется JDBC или внешний API.
Сам факт наличия интерфейса не исправляет архитектуру. Если контракт заставляет бизнес-слой оперировать ResultSet или деталями конкретного хранилища, зависимость от инфраструктуры осталась.
В Spring constructor injection делает обязательные зависимости видимыми. Но решение о границах модулей всё равно принимает разработчик.
#Java
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
1 278 просм.22 окт., 08:51
JCTools: сначала выберите модель очереди
В JCTools есть конкурентные очереди для разных схем обмена данными. В названии зашифрованы ограничения:
• SPSC — один производитель и один потребитель.
• MPSC — несколько производителей и один потребитель.
• MPMC — несколько производителей и потребителей.
Если очередь рассчитана на SPSC, нельзя без проверки начать писать в неё из нескольких потоков. Выбор алгоритма должен соответствовать реальным участникам обмена.
Также проверьте ограниченность ёмкости и обработку отказа offer(). Преимущество по скорости нужно измерять на своём сценарии.
Репозиторий JCTools.
#Java
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
1 451 просм.21 окт., 17:02
🔥Станьте архитектором, который проектирует не код, а системы: курс OTUS «Архитектор программного обеспечения»!
📅Старт - 27 ноября, продолжительность - 4 месяца.
Вы научитесь принимать решения, за которые не стыдно перед бизнесом:
• Паттерны под нагрузкой: Event-Driven, CQRS, DDD, Event Sourcing.
• Управление API: API First, оркестрация, версионирование.
• Сложные архитектуры: микрофронтенды, Kappa/Lambda, ETL vs ELT.
• Наблюдаемость: мониторинг, алертинг, логирование.
• Бонус: модуль по работе с ИИ для ускорения рутины.
👥Для Backend‑, Frontend‑, FullStack‑разработчиков, системных аналитиков, архитекторов ПО и Team Lead. Требуется опыт разработки и работы с БД; писать код на курсе не нужно.
🏁В финале — выпускной проект (например, «Room with a view»): спроектируете систему и получите консультации преподавателей.
🚀Спрос на архитекторов растёт — систематизируйте практики и применяйте их в реальных проектах.
💸Скидка 10 % на раннее бронирование — с 12 по 25 октября.
📅Бесплатные вебинары с преподавателем курса:
— 9 ноября, 20:00 — «Монолит или микросервисы? Руководство для архитекторов, которые ценят свои нервы»
— 23 ноября, 20:00 — «NoSQL в бою: как Cassandra помогает строить отказоустойчивый бэкенд»
Записаться на вебинары и узнать детали: https://vk.cc/d36WJ1
Пройдите тест и получите персональные рекомендации: https://vk.cc/d36WVN
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
1 381 просм.21 окт., 13:02
LibGDX
LibGDX — это кроссплатформенный фреймворк для разработки 2D- и 3D-игр на Java. Он позволяет создавать игры для настольных компьютеров, мобильных устройств, веб-браузеров и даже консолей. LibGDX популярен среди разработчиков игр благодаря своей простоте использования, производительности и большому сообществу.
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
1 512 просм.21 окт., 06:01
Шпаргалка по модификаторам доступа в Java!
private доступен только внутри класса, package-private работает в пределах пакета, protected также открывает доступ наследникам, а public виден отовсюду.
На картинке сравнивается доступ из класса, пакета, подкласса и внешнего кода.
Сохрани, чтобы не потерять!
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
1 319 просм.21 окт., 01:05
volatile, Atomic и synchronized: какие гарантии нужны
volatile подходит для публикации изменений одной переменной между потоками. Но count++ состоит из чтения, изменения и записи, поэтому volatile не делает этот инкремент атомарным.
AtomicInteger предоставляет атомарную операцию:
var counter = new AtomicInteger();
counter.incrementAndGet();
Несколько отдельных вызовов Atomic не образуют одну общую транзакцию.
synchronized защищает критическую секцию одним монитором. Все обращения к защищаемому состоянию должны соблюдать ту же схему синхронизации.
Выбирайте механизм по требуемому инварианту. Утверждение «Atomic всегда быстрее» неверно: результат зависит от конкуренции и работы внутри операции.
#Java
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
1 341 просм.20 окт., 23:03
Logpoint: диагностика без println в исходнике
В IntelliJ IDEA можно настроить breakpoint так, чтобы он выводил выражение и не приостанавливал выполнение. Это logpoint.
Он полезен, когда нужно проследить идентификатор запроса или значение переменной без временной правки кода и повторной сборки. Нужна отладочная сессия с доступом к процессу.
Выражение вычисляется в целевой JVM. Тяжёлая операция в часто вызываемом методе может повлиять на приложение; вызов метода из выражения также способен изменить состояние.
Начинайте с простых значений и узкого условия срабатывания. Logpoint не даёт доступ к произвольному сервису без подключения debugger.
#Java
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
1 435 просм.20 окт., 21:04
String.split принимает regex, а не разделитель
Точка в регулярном выражении означает любой символ. Для буквальной точки нужны два уровня экранирования:
String[] parts = "app.log".split("\\.");
// [app, log]
Если разделитель приходит из переменной, используйте Pattern.quote:
String[] parts = line.split(Pattern.quote(separator), -1);
Отрицательный limit сохраняет пустые поля справа: у "a,b," их три, последнее — пустая строка. Без limit завершающие пустые элементы удаляются.
Такой split подходит для простого текстового формата. Полноценный CSV с кавычками и запятыми внутри значений требует парсера CSV.
#Java
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
1 602 просм.20 окт., 14:19
retainAll изменяет исходное множество
Метод оставляет в коллекции элементы, которые есть в переданной коллекции. Чтобы сохранить исходное множество, работайте с копией:
var left = Set.of(1, 2, 3, 4);
var right = Set.of(3, 4, 5);
var intersection = new HashSet(left);
intersection.retainAll(right);
System.out.println(intersection); // элементы 3 и 4
Порядок вывода HashSet не гарантирован. Вызов retainAll на неизменяемом множестве вроде Set.of(...) завершится UnsupportedOperationException.
Возвращаемый boolean сообщает, изменилась ли коллекция, а не является ли пересечение непустым.
#Java
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
1 631 просм.20 окт., 09:03
Иерархия коллекций в Java!
На картинке показаны интерфейсы Iterable, Collection, List, Queue и Set, а также классы, которые их реализуют. Цвета отделяют интерфейсы от конкретных коллекций.
Например, ArrayList и LinkedList относятся к List, ArrayDeque реализует Deque, а HashSet и TreeSet относятся к Set. Map в эту иерархию не входит, поэтому на схеме его нет.
Сохрани, чтобы не потерять!
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
1 525 просм.20 окт., 06:02
Защищаем распаковку ZIP от выхода за каталог!
Архив может содержать запись с именем вроде ../../outside.txt. Если просто склеить её с папкой назначения, файл окажется за пределами каталога распаковки. Проверим нормализованный путь до того, как создавать файл.
Для каждого архива создаём отдельную пустую директорию и получаем её абсолютный нормализованный путь:
Path root = Files.createTempDirectory("unpacked-").toRealPath();
Отдельная новая папка исключает неожиданные совпадения с уже существующими файлами. Для постоянного каталога назначения дополнительно нужно контролировать его права и не допускать заранее созданных символических ссылок.
Перед записью проверяем, что конечный путь остаётся внутри root:
Path target = root.resolve(entry.getName()).normalize();
if (!target.startsWith(root)) {
throw new IOException("Entry escapes destination directory");
}
startsWith сравнивает компоненты пути, поэтому каталог /tmp/unpacked-evil не считается вложенным в /tmp/unpacked. Проверку важно выполнить до createDirectories и копирования содержимого.
После проверки создаём папки и переносим байты записи:
if (entry.isDirectory()) {
Files.createDirectories(target);
} else {
Files.createDirectories(target.getParent());
Files.copy(zip, target);
}
Повторяющаяся запись завершится ошибкой, а не молча перезапишет уже извлечённый файл. Так распаковщик сохраняет структуру архива и не позволяет путям с .. выйти за установленную границу.
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
1 333 просм.20 окт., 01:02
NullPointerException: явно задайте контракт
Null-безопасность начинается с договора о данных. Если аргумент обязателен, проверяйте его на границе:
Objects.requireNonNull(user, "user");
Objects.requireNonNull(user.getName(), "user.name");
Для сравнения двух nullable-значений используйте Objects.equals(a, b). Вызов "ready".equals(value) тоже безопасен для nullable value.
String.valueOf(obj) для null-ссылки типа Object вернёт строку "null". Это удобно при диагностике, но не исправляет отсутствующие бизнес-данные.
Optional может выразить отсутствие результата. @Nullable и @NotNull полезны анализаторам и фреймворкам, однако сами по себе не заставляют JVM проверять каждый вызов. Если метод возвращает коллекцию, обычно проще вернуть пустую коллекцию.
#Java
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
1 576 просм.19 окт., 21:24
LLM: инструкции и контекст решают разные задачи
Промпт задаёт задачу, ограничения и формат ответа. Контекст предоставляет данные, на которые модель может опираться: документы, код, результаты поиска и инструменты.
Для помощника по Java полезно явно передать версию JDK, сигнатуру метода, сообщение ошибки и небольшой пример входа. Просьба «исправь код» без этих данных вынуждает модель угадывать.
Если результат нужен программе, задайте схему ответа и проверяйте её на своей стороне. Валидный JSON подтверждает формат, но не истинность содержимого.
Документы из поиска и содержимое репозитория следует обрабатывать как данные. Инструкции внутри них не должны менять права инструментов или правила доступа.
#Java
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
1 721 просм.19 окт., 17:03
Retry: считайте повторы во всей цепочке
Повторный запрос безопасен, только когда понятны причина сбоя и возможный результат первой попытки. Тайм-аут не доказывает, что сервер ничего не сделал.
Проверьте три вещи:
• Какие ошибки временные, а какие повторять бессмысленно.
• Где уже включены retry: HTTP-клиент, обработчик Kafka, бизнес-логика.
• Как получатель распознаёт повтор одной операции.
Несколько независимых политик повторов могут умножить нагрузку. Ограничивайте число попыток, используйте backoff и учитывайте идемпотентность обработчика.
Разбор исходного автора.
#Java
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
1 693 просм.19 окт., 10:39
Чтение файла: укажите кодировку и закройте ресурс
Для небольшого UTF-8 файла подходит:
String text = Files.readString(
Path.of("input.txt"), StandardCharsets.UTF_8
);
Весь файл окажется в памяти. Большой файл удобнее обрабатывать построчно:
try (var reader = Files.newBufferedReader(
Path.of("input.txt"), StandardCharsets.UTF_8)) {
String line;
while ((line = reader.readLine()) != null) {
process(line);
}
}
Оба варианта могут выбросить IOException — обработайте его или передайте вызывающему коду. try-with-resources закроет reader и при исключении. Кодировка должна соответствовать файлу, а не настройкам компьютера разработчика.
#Java
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
1 423 просм.19 окт., 08:37
Узнаем размер памяти компьютера
Для получения информации о памяти компьютера в Java можно использовать класс Runtime.
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
1 286 просм.19 окт., 05:01
Публикуем готовый отчёт без частично записанного файла!
Допустим, другая программа постоянно проверяет папку с отчётами. Если записывать сразу в итоговый файл, читатель может открыть его посреди записи и увидеть только половину содержимого. Подготовим данные во временном файле, а затем опубликуем готовый результат одним перемещением.
Создадим временный файл прямо в целевой папке. Это важно для атомарного перемещения, которое обычно возможно только внутри одной файловой системы:
Path dir = Path.of("reports");
Files.createDirectories(dir);
Path temp = Files.createTempFile(dir, ".report-", ".tmp");
Итоговое имя сделаем уникальным для этой публикации. Здесь предполагается, что содержимое уже находится в строке report:
Path target = dir.resolve(UUID.randomUUID() + ".txt");
Если запись не удалась, временный файл нужно убрать. Поместим запись и перенос в try, а очистку в finally:
try {
Files.writeString(temp, report, StandardCharsets.UTF_8);
Files.move(temp, target, StandardCopyOption.ATOMIC_MOVE);
} finally {
Files.deleteIfExists(temp);
}
При успешном переносе временного пути уже нет, поэтому deleteIfExists ничего не удалит. Если операция сорвалась, он уберёт незавершённый файл. Другой процесс увидит итоговое имя только после перемещения, а не во время записи.
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
1 223 просм.19 окт., 03:02
Testcontainers: настоящая БД в интеграционных проверках
Мок репозитория не проверяет SQL и особенности конкретной СУБД. Testcontainers поднимает временные контейнеры с PostgreSQL, MySQL и другими зависимостями рядом с проверяемым приложением.
Это полезно для миграций, ограничений таблиц, транзакций и запросов, поведение которых зависит от диалекта БД. Для запуска нужен доступ к совместимому контейнерному окружению.
Практический порядок: поднимите нужную версию БД, примените миграции и передайте приложению адрес и учётные данные контейнера. Окружение можно создавать на проверку или на набор — это влияет на изоляцию и время запуска.
Официальный репозиторий.
#Java
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
1 625 просм.18 окт., 21:04
План изучения Java: от языка к сервису
План удобнее строить вокруг работающих проектов, а срок подбирать под свою нагрузку. «6–12 месяцев» — ориентир, а не обещание трудоустройства.
1. Язык: типы, ООП, исключения, коллекции, generics. Напишите консольное приложение с сохранением данных.
2. Стандартная библиотека: файлы, даты, Stream API и основы многопоточности.
3. Хранение данных: SQL, JDBC, затем JPA и транзакции.
4. Веб: Spring Boot, REST API, валидация и обработка ошибок.
5. Качество: JUnit, интеграционные проверки, Git, Maven или Gradle.
6. Эксплуатация: Docker, конфигурация, логи, метрики и базовые правила безопасности.
ИИ полезен для объяснения ошибки и сравнения решений. Каждый сгенерированный фрагмент нужно уметь объяснить: какие данные он принимает, где может упасть и как проверить результат.
#Java
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
1 819 просм.18 окт., 14:50
Log4j 2: куда отправлять логи
Appender отвечает за место назначения: консоль, файл, сокет или другое хранилище. Layout задаёт формат записи.
Минимальная консольная конфигурация:
Для ротации файлов в Log4j 2 используйте RollingFile с политикой ротации. Примеры с DailyRollingFileAppender из Log4j 1 нельзя переносить в конфигурацию Log4j 2 без изменений.
#Java
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
1 857 просм.18 окт., 09:00
👩💻 Большая база для подготовки к Java-собеседованиям
Полезный GitHub-репозиторий с базой по структурам данных, алгоритмам и сложности.
Внутри:
🫡 Linked List, Stack и Queue; 🫡 Trees, Heap и Hash Map; 🫡 Графы и обходы DFS/BFS; 🫡 Алгоритмы сортировки; 🫡 Dijkstra, Bellman-Ford и Floyd-Warshall; 🫡 Greedy Algorithms; 🫡 Оценка временной сложности; 🫡 Ссылки на задачи, книги и видеолекции.⛓ Ссылка на репозиторий Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
1 906 просм.17 окт., 18:01
📱 Gradle опять сломал сборку? А нужную библиотеку приходится искать часами?
Хорошие инструменты и решения не всегда легко найти. Особенно когда нужно было ещё вчера.
🔥 Android Developer — канал с полезными находками для Android-разработчиков.
🟢 Kotlin, Jetpack Compose и Gradle
🛠 Библиотеки, плагины и инструменты
💻 Open-source проекты с GitHub
🧠 Практические разборы и вопросы с собеседований
Меньше бесполезного поиска. Больше полезных решений.
👉 Подписывайся: https://t.me/android_dev_ru
1 820 просм.17 окт., 16:25
GC есть, а утечки памяти в Java всё равно возможны
Сборщик мусора освобождает недостижимые объекты. Если ненужный объект всё ещё удерживается сильной ссылкой, он остаётся в памяти.
Статические коллекции, кэши и слушатели могут удерживать объекты дольше необходимого.
Коллекция, которая постоянно растёт без удаления элементов, увеличивает потребление памяти.
Отписывайте слушатели, ограничивайте кэши и удаляйте ненужные ссылки. Слабые ссылки используйте там, где это соответствует логике приложения.
Объект больше не нужен — ещё не значит, что GC может его удалить.
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
1 831 просм.17 окт., 14:40
🎯
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
1 781 просм.17 окт., 09:00
Топ-3 товаров через Map.merge
Есть названия покупок с повторами. Сначала считаем частоты, затем сортируем записи:
Map counts = new HashMap();
for (String item : purchases) {
counts.merge(item, 1, Integer::sum);
}
counts.entrySet().stream()
.sorted(Map.Entry.
comparingByValue().reversed()
.thenComparing(Map.Entry.comparingByKey()))
.limit(3)
.forEach(System.out::println);
Второй критерий делает порядок при одинаковой частоте предсказуемым. Пример предполагает непустые, ненулевые названия.
Для большого количества разных товаров полная сортировка может быть лишней: топ-k можно поддерживать ограниченной кучей. Сначала оцените размер данных.
#Java
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
1 923 просм.16 окт., 22:00
Почему equals у массивов в Java не сравнивает содержимое?
В Java массив выглядит как контейнер значений, поэтому легко ожидать, что equals сравнит элементы внутри.
Но массивы не переопределяют equals для содержимого. Обычный equals у массива работает почти как сравнение ссылок.
Например, два массива с одинаковыми числами не будут равны через equals:
int[] a = {1, 2, 3};
int[] b = {1, 2, 3};
System.out.println(a.equals(b));
Результат будет false, потому что это два разных объекта в памяти.
Для одномерных массивов нужно использовать Arrays.equals:
System.out.println(Arrays.equals(a, b));
Теперь Java сравнит элементы по порядку и вернёт true.
С массивами объектов логика такая же:
String[] left = {"java", "ready"};
String[] right = {"java", "ready"};
System.out.println(Arrays.equals(left, right));
Но для вложенных массивов Arrays.equals уже недостаточно. Он сравнит внутренние массивы как объекты.
Для двумерных структур нужен deepEquals:
int[][] x = {{1, 2}, {3, 4}};
int[][] y = {{1, 2}, {3, 4}};
System.out.println(Arrays.deepEquals(x, y));
То же самое касается вывода. Обычный toString у массива покажет служебное имя, а не элементы.
Для нормального вывода используют Arrays.toString:
System.out.println(Arrays.toString(a));
Если массив вложенный, нужен deepToString:
System.out.println(Arrays.deepToString(x));
Массивы в Java стоит сравнивать и выводить через Arrays. Иначе код может выглядеть логично, но проверять совсем не то.
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
1 761 просм.16 окт., 17:55
Какая структура данных в коллекции List?
В Java интерфейс List представляет упорядоченную коллекцию элементов, допускающую дубликаты. В зависимости от конкретной реализации (ArrayList, LinkedList, Vector), используется разная структура данных.
Основные реализации `List` и их структуры данных
ArrayList
Динамический массив
Структура данных: массив
Быстрая индексация O(1), но медленное удаление/вставка в середину O(n).
List list = new ArrayList();
LinkedList
Двусвязный список
Структура данных: двусвязный список
Быстрое добавление/удаление элементов O(1), но медленный доступ по индексу O(n).
List list = new LinkedList();
Vector
Динамический массив (синхронизирован)
Структура данных: массив (как ArrayList), но с синхронизацией.
Устарел, используется редко из-за synchronized методов (медленнее ArrayList).
List list = new Vector();
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
1 869 просм.16 окт., 13:40
1 633 просм.16 окт., 10:54
Знали, что Map.getOrDefault может вызвать загрузку, даже когда ключ уже есть?
Java сначала вычисляет аргументы метода, и только потом вызывает сам метод.
Поэтому дорогой вызов справа выполнится заранее:
User user = users.getOrDefault(id, loadUser(id));
Даже если users уже содержит id, loadUser(id) успеет выполниться. Если это запрос к базе, сеть или вычисление, приложение потратит время зря.
Для ленивого вычисления значения подойдёт computeIfAbsent:
User user = users.computeIfAbsent(id, this::loadUser);
Функция загрузки вызывается только тогда, когда ключ отсутствует или связан с null. Возвращённое ненулевое значение добавляется в map и дальше берётся из неё.
Проверь и семантику отсутствующего результата. Если загрузчик вернёт null, запись не появится, и следующий вызов снова попробует загрузить пользователя:
User user = users.computeIfAbsent(id, key -> findUser(key).orElse(null));
Ещё один нюанс касается конкурентного доступа. Для параллельных потоков выбирай подходящую concurrent map и не помещай в функцию долгую блокирующую работу без понимания гарантий конкретной реализации.
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
1 972 просм.16 окт., 09:03
👩💻 Подводные камни Retry Policy в Java
В статье на реальных примерах показывают retry-штормы, фантомные повторы, дубли записей, особенности Spring Retry и работу с Kafka.
Хороший материал для тех, кто проектирует отказоустойчивые Java-сервисы.
⛓ Читать статью
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
2 166 просм.15 окт., 21:00
Память в Java растёт? Сначала выясните, что удерживает объекты
Рост потребления памяти не всегда означает утечку или проблему со сборщиком мусора. GC может освободить только те объекты, которые больше недостижимы.
Если ненужные объекты остаются в статической Map, безразмерном кэше или коллекции, которую никто не очищает, они продолжают занимать память. Это уже может быть утечкой на уровне приложения.
Увеличение -Xmx даст больше времени, но не устранит причину.
Анализируйте heap dump: какие объекты накапливаются, кто хранит ссылки на них и почему они остаются достижимыми.
Важен не только объём занятой памяти, но и причина, по которой объекты всё ещё живы.
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
2 273 просм.15 окт., 14:55
Собираете строку в цикле? Используйте StringBuilder вместо +=.
Строки в Java неизменяемы: при последовательной конкатенации приходится создавать новые строки и копировать накопленное содержимое. Чем больше итераций, тем выше затраты.
StringBuilder добавляет данные в изменяемый буфер, расширяя его при необходимости:
StringBuilder builder = new StringBuilder();
for (String item : items) {
builder.append(item);
}
String result = builder.toString();
Для накопления текста в цикле это обычно эффективнее.
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
2 264 просм.15 окт., 09:04
Почему большинство объектов в Java «умирают молодыми»?
Приложение может создавать миллионы объектов:
for (int i = 0; i < 1_000_000; i++) {
User user = new User();
}
Многие нужны лишь на время выполнения метода, обработки запроса или промежуточного вычисления. Когда объект становится недостижимым, сборщик мусора может освободить его память.
На этом наблюдении основана слабая поколенческая гипотеза: большинство объектов живут недолго. Поколенческие сборщики мусора используют её так:
• Новые объекты обычно размещаются в молодом поколении.
• Оно очищается чаще: сборщик сохраняет выжившие объекты и освобождает остальную память.
• Достаточно долго живущие объекты переводятся в старое поколение, которое собирается реже.
Так GC может освобождать память короткоживущих объектов, не обрабатывая каждый раз всю кучу.
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
2 216 просм.14 окт., 18:14
🧠 Почему BigDecimal считает 2.0 и 2.00 разными
Что выведут эти две строки?
var a = new BigDecimal("2.0");
var b = new BigDecimal("2.00");
System.out.println(a.equals(b));
System.out.println(a.compareTo(b));
true и 0
false и 0
false и -1
👇 Правильный ответ:
false и 0.
equals() сравнивает и числовое значение, и scale: у 2.0 он равен 1, у 2.00 — 2. А compareTo() сравнивает значения, поэтому возвращает 0.
Когда проверяете равенство сумм по величине, нужен compareTo() == 0. Но ключи HashMap и элементы HashSet используют equals() и hashCode(): эти объекты останутся разными.
🔗 Источник
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
2 238 просм.14 окт., 13:15
Описывайте состояния через enum вместо строк
Именованные константы помогают избежать опечаток в статусах и явно задают набор состояний.
Используйте PENDING, APPROVED, REJECTED вместо произвольных строк.
Держите правила допустимых переходов рядом с описанием состояний.
Используйте проверку полноты switch, если язык и выбранная конструкция её поддерживают.
Но enum сам по себе не запрещает неверные переходы — эту логику нужно реализовать отдельно.
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
2 307 просм.14 окт., 01:33
Почему нельзя просто проигнорировать InterruptedException?
Поток может ждать завершения задачи, блокировки или таймера. Другой поток вправе попросить его остановиться через interrupt. Например, worker делает паузу между проверками:
while (!Thread.currentThread().isInterrupted()) {
processNext();
Thread.sleep(1000);
}
Если вызвать interrupt во время sleep, метод выбросит InterruptedException. При этом флаг прерывания будет очищен. Это важный момент: после перехвата исключения простая проверка isInterrupted уже не увидит запрос на остановку.
Такой обработчик теряет сигнал:
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("continue");
}
Программа продолжит работу, будто отмены не было. Это особенно неприятно в пуле потоков и при остановке сервиса, вызывающий код считает, что попросил завершить задачу, а она выполняется дальше.
Если метод может передать исключение выше, оставь его в сигнатуре:
void pause() throws InterruptedException {
Thread.sleep(1000);
}
Тогда решение об остановке примет вызывающий уровень. А если исключение приходится перехватить внутри Runnable или другого метода без throws, восстанови флаг и заверши работу:
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
Восстановленный флаг увидит внешний код, который проверяет состояние потока.
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
1 987 просм.13 окт., 22:55
Почему String.format может заменить точку на запятую?
Представим, что программа сохраняет числовое значение в текстовый файл. Хочется получить 12.50, поэтому пишем:
String value = String.format("%.2f", 12.5);
Но результат без явной локали зависит от настроек среды, в которой запущена JVM. На одной машине это будет 12.50, на другой 12,50. Для интерфейса пользователя локальные правила полезны, а для машинного формата такой сюрприз может испортить импорт.
Разницу легко показать без изменения настроек компьютера:
String de = String.format(Locale.GERMANY, "%.2f", 12.5);
Здесь получится 12,50. Если строку должен читать другой сервис с точкой в качестве разделителя, укажите нейтральную локаль явно:
String stable = String.format(Locale.ROOT, "%.2f", 12.5);
Теперь получится 12.50 независимо от локали пользователя. Это важно для логов с фиксированным форматом.
Для текста, который читает человек, наоборот, можно передать нужную ему локаль:
String label = String.format(userLocale, "%.2f", 12.5);
Так отображение будет привычным для пользователя. Но если вы записываете структурированные данные, лучше использовать подходящий формат и библиотеку, например JSON-сериализатор, а не собирать документ через String.format.
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
2 044 просм.13 окт., 17:26
Почему после Stream.toList() нельзя добавить элемент?
При работе со Stream часто нужно собрать результаты обратно в список. Короткая запись выглядит естественно:
var names = Stream.of("Ana", "Bob").toList();
Но у Stream.toList() есть важное свойство, он возвращает немодифицируемый список. Такой код не добавит третье имя:
names.add("Cyd");
Вместо изменения списка программа получит UnsupportedOperationException. То же произойдёт при remove или set.
Если нужен готовый результат только для чтения, это как раз удобно:
List labels = users.stream()
.map(User::name)
.toList();
Вызывающий код не сможет случайно поменять состав labels. При этом сами элементы могут оставаться изменяемыми, не модифицируемость списка не делает глубоко неизменяемыми объекты внутри него.
Если список нужно дополнять после сбора, задайте изменяемую коллекцию явно:
var names = Stream.of("Ana", "Bob")
.collect(Collectors.toCollection(ArrayList::new));
Теперь add и remove доступны. Есть и вариант обернуть готовый результат:
var names = new ArrayList(stream.toList());
Выбирайте способ сбора по тому, что будет происходить со списком дальше. Для чтения подойдёт toList(), для дальнейших изменений лучше явно создать ArrayList.
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
2 223 просм.13 окт., 09:02
Что выведет эта программа?
Ответ:
Первый оператор вывода напечатает «false», второй — «true». Так происходит из-за ошибки округления чисел с плавающей точкой. Только степени двойки можно точно представить в двоичной записи. Числа, которые не являются степенями двойки, округляются так, чтобы поместиться в ограниченное количество битов. В этом примере Java использует использует тип double, поэтому для представления десятичных чисел доступно только 64 бита. Следовательно, 0.1*3 не будет равняться 0.3.
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
2 236 просм.13 окт., 01:33
3 бесплатных ресурса для изучения Java
• Effective Java — конспект — основные идеи книги Джошуа Блоха о том, как писать качественный Java-код.
• Java Design Patterns — паттерны проектирования с объяснениями и примерами реализации на Java.
• Подготовка к собеседованиям — алгоритмы, структуры данных и примеры решений на Java.
Сохраняйте, чтобы вернуться к практике
Полезные ресурсы по Java 👩💻| Наш канал в MAX 🟪
2 272 просм.12 окт., 18:11
Посты загружаются автоматически из канала. Администрация сайта не несёт ответственности за их содержание и размещённые в них ссылки.
