Статистика
Статистика от MaxFrame.ruПодписчики
1 388
+3день
+7неделя
+13месяц
Охват поста
236
236за 24 часа
263в среднем
Вовлечённость
17%
17%за 24 часа
19%в среднем
Упоминания в других каналах
Канал упомянули 42 раза в 3 каналах
Чем больше упоминаний и каналов — тем заметнее канал в своей нише.
О канале
Описание в MAX
Книги, статьи, мемы и многое другое для Java программиста! По сотрудничеству и рекламе: ссылка скрыта или в ЛС сообщества ВК ссылка скрыта Канал в перечне РКН: ссылка скрыта Мы на бирже: ссылка скрыта Сообщество VK ссылка скрыта
- Аудитория
- Смешанная аудитория
О подписчиках
Вк, телеграм, макс
Оценки и отзывы
Формат размещения
700 ₽
топ 1 час · сутки в ленте · цена напрямую от автора
💎Эффективность за эти деньги
2,97 ₽
CPV · за показ
2 966,10 ₽
CPM · за 1000
Пересчитывается от формата и охвата 236/24ч
Гарантия выхода поста и возврат средств
Надёжность сделки
Время ответа админа
Обычно отвечает быстро
Размещений через Помогач
Первое размещение — за вами
Посты в канале
Java библиотека
MAX · канал
Почему 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 Библиотека | Мы в Телеграм
101 просм.18 окт., 23:34
👩💻 Как автоматизировать code style в Java-проекте
Checkstyle проверяет исходники по заданному набору правил и помогает держать единый стиль во всей кодовой базе.
Можно использовать готовые стандарты Google и Sun или собрать собственную конфигурацию: проверять импорты, именование, форматирование и другие правила.
⛓ Ссылка на GitHub
Java Библиотека | Мы в Телеграм
178 просм.18 окт., 17:58
➡️ MapStruct
MapStruct — это библиотека для автоматического преобразования данных между Java объектами. Она упрощает создание мапперов и конвертеров, минимизируя необходимость ручного написания кода для преобразования данных между различными слоями приложения.
🗣 MapStruct — это отличный инструмент для разработчиков, которые хотят автоматизировать преобразование данных и улучшить читаемость и поддержку кода. Если вам нужно легко маппировать объекты без лишнего шаблонного кода, MapStruct поможет вам достичь этого.
🔗 Ссылочка на доку
Java Библиотека | Мы в Телеграм
204 просм.18 окт., 12:49
Java: почему месяц `5` может оказаться июнем
В Calendar месяцы нумеруются с нуля: январь 0, май 4, июнь 5. Простая ловушка, которая легко превращается в баг.
Начиная с Java 8, для нового кода выбирайте java.time:
LocalDate date = LocalDate.of(2026, 5, 31);
LocalDate deadline = date.plusDays(7);
String text = deadline.format(
DateTimeFormatter.ISO_LOCAL_DATE
);
// 2026-06-07
Здесь 5 означает май, а plusDays() возвращает новый объект, сохраняя исходную дату. Основные типы java.time неизменяемы и безопасны для совместного использования потоками.
Помните: `LocalDateTime` не содержит часового пояса. Для однозначного момента события используйте Instant или задавайте пояс явно.
Java Библиотека | Мы в Телеграм
223 просм.18 окт., 07:00
👩💻 Что такое API и зачем оно нужно?
Простой разбор API, endpoints, JSON и взаимодействия frontend с backend на примере маркетплейса.
Подойдет новичкам перед погружением в REST и Spring.
⛓ Читать статью
Java Библиотека | Мы в Телеграм
231 просм.17 окт., 22:54
👩💻 Большая база вопросов для Java-собеседований
Основные разделы:
🫡 Java Core и JVM;
🫡 Collections и Stream API;
🫡 Concurrency и virtual threads;
🫡 Spring и Spring Boot;
🫡 Hibernate и JPA;
🫡 Maven и Gradle;
🫡 Microservices и REST;
🫡 SQL и транзакции;
🫡 Kafka и RabbitMQ;
🫡 System Design и Kubernetes.
Подойдет как roadmap для подготовки и быстрый чек-лист перед интервью.
⛓ Ссылка на репозиторий
Java Библиотека | Мы в Телеграм
232 просм.17 окт., 17:16
Виртуальные потоки в Java 21+ хорошо подходят для задач, которые большую часть времени проводят в ожидании.
Общий Semaphore ограничивает число одновременных обращений к зависимому сервису: каждая задача получает собственный виртуальный поток, но одновременно выполнять вызов API могут не более 10 задач.
Java Библиотека | Мы в Телеграм
251 просм.17 окт., 12:15
Измеряйте покрытие кода тестами, но не гонитесь за 100%.
Покрытие показывает, какие строки выполнились, а не то, что они работают правильно.
Даже при полном покрытии реальные баги могут остаться незамеченными.
Содержательные проверки наиболее рискованных сценариев важнее идеального показателя.
Java Библиотека | Мы в Телеграм
247 просм.17 окт., 07:00
Механизм try-with-resources
Механизм try-with-resources — это способ автоматического закрытия ресурсов после их использования. Появился этот механизм в Java 7.
Он работает для классов, реализующих интерфейс AutoCloseable (например, потоки), уменьшает количество кода и упрощает обработку исключений.
Ресурсы объявляются в скобках после try и закрываются автоматически по завершении этого блока. Ресурсы закрываются в обратном порядке создания при нормальном или аварийном завершении.
По сравнению с блоком try-catch-finally этот механизм позволяет лаконичнее писать код с автозакрытием ресурсов.
В этом примере в блоке try создаются объекты FileReader и BufferedReader для чтения данных из файла.
После завершения блока try оба ресурса будут автоматически закрыты, даже если произойдет исключение.
Java Библиотека | Мы в Телеграм
258 просм.16 окт., 21:51
BeanFactory
BeanFactory — это интерфейс, который предоставляет механизм для управления объектами bean в контейнере Inversion of Control (IoC).
BeanFactory является основой фреймворка Spring, где используется для создания приложений по принципу IoC и Dependency Injection. Он позволяет создавать гибкие, легко тестируемые приложения с инверсией управления и внедрением зависимостей.
Java Библиотека | Мы в Телеграм
262 просм.16 окт., 16:45
Предпочитайте делегирование наследованию: отношение «является» тесно связывает ваш класс с суперклассом.
Подкласс наследует весь доступный API родителя, поэтому изменения в родительском классе могут сломать ваш код.
Java Библиотека | Мы в Телеграм
277 просм.16 окт., 12:22
Проблема в продакшене. Приложение зависло.
Вы запускаете:
jstack
Через несколько секунд получаете:
Found one Java-level deadlock
Но главный вопрос… Как JVM обнаружила взаимную блокировку? Что происходит внутри?
Java Библиотека | Мы в Телеграм
291 просм.16 окт., 07:00
Spring Boot 4: DevTools больше не запускает сервер LiveReload по умолчанию
Автоматический перезапуск приложения при изменениях в classpath работает как раньше.
Для включения LiveReload задайте spring.devtools.livereload.enabled=true.
Порт 35729 больше не занимается автоматически — удобно, когда на одной машине запущено несколько приложений.
Java Библиотека | Мы в Телеграм
309 просм.15 окт., 23:49
Connection Pool, Thread Pool и Object Pool: в чём разница?
Общая идея одна: повторно использовать дорогие ресурсы вместо постоянного создания новых. Но каждый пул управляет своим типом ресурсов.
• Connection Pool — пул соединений. Хранит соединения, например с базой данных. Приложение берёт свободное соединение, выполняет запросы и возвращает его в пул.
• Thread Pool — пул потоков. Повторно использует рабочие потоки для выполнения задач. Не нужно создавать отдельный поток под каждую новую задачу.
• Object Pool — пул объектов. Позволяет брать готовые объекты, использовать их, сбрасывать состояние и возвращать для следующего вызова.
Пример: Spring Boot с обычной блокирующей обработкой запросов. Рабочий поток обрабатывает HTTP-запрос и выполняет бизнес-логику. Когда требуется доступ к БД, приложение получает соединение из пула.
После завершения работы с БД соединение возвращается в пул. После обработки запроса рабочий поток освобождается для следующей задачи. Это два отдельных ресурса с разным временем использования.
А стоит ли переиспользовать обычные Java-объекты? Не всегда. JVM эффективно выделяет память под короткоживущие объекты и собирает их сборщиком мусора. Пул имеет смысл прежде всего для объектов с дорогим созданием или ресурсов с ограниченным количеством.
Больше ресурсов не означает быстрее:
• Слишком много соединений может перегрузить базу.
• Слишком много платформенных потоков увеличивает расход памяти и затраты на переключение контекста.
• Неудачный пул объектов удерживает память и создаёт конкуренцию за доступ.
Поэтому важен не только сам пул, но и его размер. Переиспользование полезно, когда оно действительно дешевле повторного создания.
Java Библиотека | Мы в Телеграм
315 просм.15 окт., 18:39
Serializable, Externalizable и Protocol Buffers: в чём разница?
Все три подхода позволяют представить данные в виде байтов, но отличаются управлением форматом и совместимостью.
Serializable — стандартная сериализация Java
Класс реализует Serializable, а ObjectOutputStream записывает объект и связанные с ним сериализуемые объекты. По умолчанию сохраняются нестатические поля, не помеченные transient; поведение можно настроить.
Это механизм Java, чувствительный к изменениям классов и не предназначенный для удобного обмена данными между разными языками.
Externalizable — явное управление записью и чтением
Класс реализует writeExternal() и readExternal(). Разработчик определяет, какие данные записать, в каком порядке и как восстановить объект.
Так можно сократить объём данных, но меньший размер и лучшая скорость не гарантированы. Совместимость версий и соответствие логики записи и чтения тоже придётся поддерживать самостоятельно.
Protocol Buffers — обмен данными по схеме
Структура сообщения описывается в .proto:
message User {
int64 id = 1;
string name = 2;
}
Из схемы генерируется код для Java, Go, Python, C# и других языков. Приложения обмениваются сообщениями в компактном бинарном формате.
Подходит для межсервисного взаимодействия, gRPC и систем, где важна совместимость между языками. При изменении схемы нужно соблюдать правила эволюции — например, не переиспользовать номера удалённых полей.
Как запомнить:
• Serializable: Java берёт на себя стандартную запись состояния объекта.
• Externalizable: разработчик управляет записью и восстановлением.
• Protobuf: приложения обмениваются данными по общей схеме.
Важное уточнение: сериализация — общее название процесса, и Protobuf тоже является способом сериализации. Здесь сравниваются именно механизмы Java и отдельный формат обмена данными.
Java Библиотека | Мы в Телеграм
326 просм.15 окт., 13:12
Можно ли самому для себя устанавливать СКЗИ, если нет лицензии? На этот вопрос отвечает Альфа, изучив новое Постановление Правительства.
Подписывайтесь на канал, чтобы вовремя узнавать о приказах про информационную безопасность.
https://tglink.io/568d6b9e015aaf?erid=2W5zFHgNZWy 👈 здесь про обработку персональных данных, объекты КИИ, а также анализ требований ФСТЭК РФ, ФСБ и РКН.
#реклама
О рекламодателе
213 просм.14 окт., 09:10
Что выведет эта программа?
Ответ:
Первый оператор вывода напечатает «false», второй — «true». Так происходит из-за ошибки округления чисел с плавающей точкой. Только степени двойки можно точно представить в двоичной записи. Числа, которые не являются степенями двойки, округляются так, чтобы поместиться в ограниченное количество битов. В этом примере Java использует использует тип double, поэтому для представления десятичных чисел доступно только 64 бита. Следовательно, 0.1*3 не будет равняться 0.3.
Java Библиотека | Мы в Телеграм
364 просм.14 окт., 09:00
Почему после 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 Библиотека | Мы в Телеграм
338 просм.13 окт., 16:43
3 бесплатных ресурса для изучения Java
• Effective Java — конспект — основные идеи книги Джошуа Блоха о том, как писать качественный Java-код.
• Java Design Patterns — паттерны проектирования с объяснениями и примерами реализации на Java.
• Подготовка к собеседованиям — алгоритмы, структуры данных и примеры решений на Java.
Сохраняйте, чтобы вернуться к практике
Java Библиотека | Мы в Телеграм
351 просм.13 окт., 12:35
ИИ пишет скрипты, разбирает логи и режет видео. Но половина кода так и остаётся в чате
«Нейросети | AI-агентура» — канал для тех, кто собирает себе рабочих ИИ-агентов, а не коллекцию подписок.
Здесь выходят:
— готовые ТЗ на ботов, каждый собирается за вечер;
— локальные модели: что влезает на одну карту, а что в браузер;
— приемы добавления точности в ответах нейросетей и реальные лимиты бесплатных тарифов, сверенные с документацией;
— 99 рабочих рецептов от Anthropic;
— разбор необычных ситуации в мире ИИ
Подпишись на канал:
👉 https://max.ru/channel_ai_agentura
erid: 2W5zFHJH9Ff
246 просм.13 окт., 11:30
👩💻 Как ускорить UI-тесты на Java в несколько раз
Автор предлагает превратить логин из UI-сценария в быстрое предусловие.
Схема выглядит так:
🫡 Получить access token через API;
🫡 Не писать токены и пароли в Allure и CI-логи;
🫡 Кэшировать состояние по конкретной test identity;
🫡 Проверять TTL перед повторным использованием токена;
🫡 Положить cookie или localStorage в браузер;
🫡 Сделать это до старта SPA через WebDriver BiDi;
🫡 Проверить, что backend принял токен, а frontend действительно стартовал авторизованным.
На примере 180 тестов время подготовки авторизации снизилось с 6–9 до 0,4–0,7 секунды на сценарий.
⛓ Читать статью
Java Библиотека | Мы в Телеграм
336 просм.13 окт., 07:00
Java, Spring Boot, React, микросервисы… А чем веб-сервер отличается от сервера приложений?
У кандидата в резюме несколько full-stack проектов и внушительный стек. Но простой вопрос на собеседовании поставил его в тупик.
• Веб-сервер принимает HTTP-запросы, отдаёт статические файлы и может перенаправлять запросы приложению как reverse proxy. Примеры: Nginx, Apache HTTP Server.
• Сервер приложений предоставляет среду для выполнения приложения и его бизнес-логики. В экосистеме Java примеры — WildFly и Payara.
При этом граница не строгая: сервер приложений может сам принимать HTTP-запросы. Например, Spring Boot со встроенным Tomcat способен обслуживать их без отдельного Nginx, хотя Tomcat точнее называть контейнером сервлетов.
Собрать проект из десяти технологий полезно. Понимать, за что отвечает каждая, — не менее важно.
Java Библиотека | Мы в Телеграм
356 просм.12 окт., 23:04
Spring Boot 4: переименовали property для exception translation
Было:
spring.dao.exceptiontranslation.enabled
Стало:
spring.persistence.exceptiontranslation.enabled
Функциональность та же: Spring продолжает переводить persistence-исключения в DataAccessException для @Repository.
Чтобы не пропустить такие изменения при миграции на Boot 4, подключите Spring Boot Properties Migrator — он покажет устаревшие и переименованные настройки.
Мелочь, которая легко ломает конфиг после обновления.
Java Библиотека | Мы в Телеграм
356 просм.12 окт., 17:30
👩💻 Spring Boot под нагрузкой: почему сервис работает локально и падает в production
Приглашаем на открытый урок.
🗓 22 октября в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «Разработчик на Spring Framework».
На занятии мы разберем:
✔️Сервис, с которым «всё хорошо». Возьмём Spring Boot-приложение с PostgreSQL и внешним HTTP-сервисом, которое локально и на тестах работает без проблем.
✔️Создадим production-проблему. Увеличим задержку внешней системы и посмотрим, почему начинают расти транзакции, заканчиваются соединения с БД и деградирует весь сервис.
✔️Разберём причины. Посмотрим на границы @Transactional, HTTP timeout, connection pool, опасные retries и механизм каскадных отказов.
✔️Исправим архитектуру. Разберём корректные transaction boundaries, timeout, retry/backoff, ограничение параллелизма и защиту зависимостей.
✔️Найдём проблему через observability. Посмотрим, какие метрики и distributed tracing помогают увидеть причину деградации до того, как сервис окончательно упадёт.
🔗 Ссылка на регистрацию: https://vk.cc/d2PNdf
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
367 просм.12 окт., 14:17
Как HashMap устроен внутри
• Вычисляет хеш ключа.
• Определяет индекс корзины во внутреннем массиве.
• Сохраняет запись в узле с хешем, ключом и значением.
• При коллизиях использует связный список, а начиная с Java 8 при определённых условиях преобразует его в красно-чёрное дерево.
Если такой ключ уже существует, put() заменяет его значение.
Java Библиотека | Мы в Телеграм
403 просм.11 окт., 17:42
Как менялись языки программирования
Каждое поколение языков помогало решать новые задачи: от управления железом до разработки веб-приложений и распределённых систем.
История по десятилетиям появления:
• 1940-е: машинный код и первые ассемблеры.
• 1950-е: FORTRAN, Lisp, COBOL.
• 1960-е: BASIC.
• 1970-е: C, Pascal.
• 1980-е: C++, Objective-C.
• 1990-е: Python, Ruby, Java, JavaScript, PHP.
• 2000-е: C#, Scala, Go.
• 2010-е: Rust, Kotlin, Swift.
2020-е — распространение разработки с AI-помощниками. Это уже изменение способа работы с кодом, а не отдельное поколение языков.
Новые инструменты не делают старые языки ненужными. C остаётся важным для операционных систем, Java — для корпоративных приложений, JavaScript — для веба, Python — для анализа данных и машинного обучения.
А на каком языке вы написали свой первый Hello, World?
Java Библиотека | Мы в Телеграм
400 просм.11 окт., 12:45
➡️ Objenesis
Objenesis — это Java-библиотека, которая позволяет создавать объекты классов без вызова их конструкторов. Это особенно полезно в тех случаях, когда нужно создать объект для сериализации, прокси или в ситуациях, когда конструктор имеет побочные эффекты, которые следует избегать.
🗣 Objenesis — это отличный инструмент для тех, кто работает с фреймворками, связанными с сериализацией или AOP, и нуждается в возможности создания объектов без вызова их конструкторов. Если вы сталкивались с проблемами при создании экземпляров классов с приватными конструкторами или сложной инициализацией, Objenesis может стать вашим незаменимым помощником.
🔗 Ссылочка на доку
Java Библиотека | Мы в Телеграм
357 просм.11 окт., 07:00
Откуда в Spring Boot берётся веб-сервер?
Запускаете приложение:
java -jar app.jar
И оно начинает принимать HTTP-запросы. Без отдельной установки Tomcat и развёртывания WAR-файла.
Секрет — во встроенном сервере. Для обычного Spring MVC-приложения зависимость веб-стартера по умолчанию подтягивает Tomcat. Его библиотеки входят в исполняемый JAR, а Spring Boot автоматически настраивает и запускает сервер вместе с приложением.
Это упрощает запуск и развёртывание: приложение и сервер поставляются как единое целое, с согласованными версиями и настройками. Такой JAR удобно запускать локально, на сервере или в контейнере.
Embedded не означает, что сервера нет. Он работает внутри процесса вашего Java-приложения. Tomcat — не единственный вариант: например, приложения на Spring WebFlux по умолчанию используют Reactor Netty.
Java Библиотека | Мы в Телеграм
377 просм.10 окт., 21:06
ForkJoinPool, ExecutorService и Virtual Threads: что выбирать в Java?
Всё зависит от нагрузки: задачи в основном вычисляют или ждут ответа базы и внешних сервисов? При этом сравниваются разные уровни: ExecutorService — интерфейс управления задачами, ForkJoinPool — одна из его реализаций, а виртуальные потоки — тип потоков. Их можно использовать вместе.
ForkJoinPool — для параллельных вычислений. Хорошо подходит для задач, которые можно разбить на независимые части: рекурсивных алгоритмов, обработки массивов и других CPU-intensive вычислений.
Использует work-stealing: свободный рабочий поток забирает задачи из очередей других потоков. Но не любая тяжёлая операция требует ForkJoinPool. Для независимых вычислительных задач может быть достаточно обычного фиксированного пула.
ExecutorService — для запуска и управления задачами. Позволяет отправлять задачи на выполнение, получать результаты через Future и управлять завершением исполнителя. Конкретная реализация определяет, как выполняются задачи.
ExecutorService executor =
Executors.newFixedThreadPool(10);
Здесь одновременно работают не более 10 потоков. Однако очередь задач у такого исполнителя не ограничена: при постоянной перегрузке она может расти. Для выполнения по расписанию используется ScheduledExecutorService.
Virtual Threads — для большого количества ожидающих задач. Виртуальные потоки стали стандартной возможностью в Java 21. Они особенно полезны, когда задачи много времени проводят в блокирующих вызовах к БД или HTTP-сервисам. Их тоже можно использовать через ExecutorService:
try (var executor =
Executors.newVirtualThreadPerTaskExecutor()) {
executor.submit(() -> callExternalApi());
}
Каждая задача получает отдельный виртуальный поток. Создавать пул для переиспользования виртуальных потоков не нужно.
Что важно в продакшене:
• Виртуальные потоки не добавляют процессорных ядер и сами по себе не ускоряют вычисления.
• Тысячи виртуальных потоков не означают, что база выдержит тысячи одновременных запросов. Нужны отдельные ограничения, например пул соединений или Semaphore.
• Ограничение числа рабочих потоков не равно ограничению очереди задач.
ForkJoinPool помогает распараллеливать вычисления. ExecutorService управляет выполнением задач. Virtual Threads позволяют эффективно организовать множество задач, ожидающих I/O.
Java Библиотека | Мы в Телеграм
396 просм.10 окт., 15:41
👩💻 Что реально спрашивают на Java-собеседованиях
Разбор 247 интервью: HashMap, equals/hashCode, MVCC, Hibernate N+1, Spring Transactions, Kafka, блокировки и другие регулярно повторяющиеся темы.
Особенно полезен блок про @Transactional и self-invocation — классическую ловушку на Spring-собесах.
⛓ Подробнее в статье
Java Библиотека | Мы в Телеграм
456 просм.8 окт., 17:59
Зубчатый массив в Java
Зубчатый массив (BitSet) — это специальная структура данных для эффективного хранения и манипулирования наборами битов.
Представляет собой массив битов, который увеличивается динамически по мере добавления элементов. Занимает меньше памяти, чем обычные структуры данных для хранения булевых значений.
Позволяет выполнять операции над битами: установка, сброс, инверсия, логические операции.
Зубчатый массив полезен при решении задач: поиск в множествах, хранение состояний и флагов, оптимизация расхода памяти и в целом при необходимости эффективно хранить и манипулировать большим количеством булевых значений.
Java Библиотека | Мы в Телеграм
422 просм.8 окт., 12:40
Какова иерархия коллекций?
В Java есть два основных интерфейса для коллекций - Collection и Map.
Interface Collection находится на верху иерархии и определяет общие методы для работы с коллекциями, такие как add(), remove(), size() и другие. От него наследуются конкретные реализации коллекций.
Наиболее часто используемые реализации Collection - это List, Set и Queue.
Map интерфейс реализует отдельную структуру данных. Он представляет отображение ключ-значение. Основные реализации - HashMap и TreeMap.
Java Библиотека | Мы в Телеграм
424 просм.8 окт., 07:00
Разработчик больше не обязан выполнять каждую задачу вручную. Но сможет ли ИИ-агент действительно помочь в работе?
ИИ-агенты уже умеют анализировать код, работать с инструментами, искать ошибки и выполнять последовательность действий. Но важно понимать, какие задачи им можно доверить, где они действительно экономят время и как сохранить контроль над результатом.
На открытом уроке 19 октября в 20:00 МСК в преддверие старта курса «Разработка ИИ-агентов» разберем, как создавать и применять агентов в реальной разработке. Вы узнаете, какие задачи можно делегировать ИИ-агентам, как они работают с кодовой базой и внешними системами, где помогают ускорить процессы, а где требуется участие разработчика.
Урок будет полезен разработчикам, техническим специалистам и тимлидам, которые хотят использовать возможности ИИ не только для генерации кода. Откройте новый подход к разработке. Регистрируйтесь на открытый урок: https://vk.cc/d2DDFt
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
421 просм.7 окт., 14:01
Java-разработчики, ConcurrentHashMap потокобезопасен.
Но он не блокирует всю коллекцию при каждом обновлении. Что же происходит, когда несколько потоков изменяют её одновременно?
До Java 8 → блокировки на уровне сегментов.
Java 8+ → CAS + синхронизация на уровне корзин.
Как это улучшает работу с конкурентным доступом? И когда ConcurrentHashMap всё ещё нужны блокировки?
Java Библиотека | Мы в Телеграм
468 просм.6 окт., 19:00
👩💻 Что нового появилось в Java 27
Релиз небольшой, но несколько изменений JVM действительно заслуживают внимания:
🫡 Compact Object Headers теперь включены по умолчанию и уменьшают заголовок объекта с 12 до 8 байт;
🫡 G1 стал стандартным сборщиком мусора во всех окружениях;
🫡 TLS 1.3 получил гибридный постквантовый обмен ключами;
🫡 JFR автоматически скрывает пароли, токены, API-ключи и другие чувствительные значения;
🫡 Structured Concurrency дошла до седьмого Preview;
🫡 Vector API остался в Incubator и получил уже двенадцатую итерацию.
По сути, Java 27 стала ещё одним шагом подготовки платформы к следующему LTS-релизу.
⛓ Читать статью
Java Библиотека | Мы в Телеграм
510 просм.5 окт., 10:50
⚠️ Я ДУМАЛ, ЧТО ЧТОБЫ БРАТЬ ЗАКАЗЫ НА РАЗРАБОТКУ ИЛИ ДИЗАЙН, НУЖНО УМЕТЬ ПРОГРАММИРОВАТЬ И БЫТЬ ПРОФЕССИНАЛЬНЫМ ДИЗАЙНЕРОМ
Писать код.
Разбираться в языках программирования.
Уметь работать в графических редакторах.
Знать композицию, типографику и дизайн.
Месяцами учиться.
👇 Оказалось, сейчас это уже не обязательно
Часть задач по разработке и дизайну можно объяснить нейросети обычными словами и собрать результат вместе с ней.
Причём речь про реальные задачи, за которые платят деньги:
➖ собрать презентацию и оформить слайды
➖ сделать визуалы и графику
➖ сделать Telegram-бота
➖ спарсить и обработать данные
➖ автоматизировать рутину
➖ собрать небольшой сервис
И вот это меняет правила игры.
Потому что раньше между:
«Я хочу освоить удалённую профессию»
и
«Я могу выполнить заказ»
могли стоять месяцы или годы обучения.
Сейчас Семён Красинцев решил показать весь процесс вживую.
На бесплатном эфире «Роботяга» он берёт реальный заказ с биржи фриланса и выполняет его нейронкой прямо при зрителях.
Заказ от 10 000 ₽.
На выполнение около 15 минут.
И самое интересное.
Семён не программист.
Он 20 лет занимается 3D-графикой и ставит задачи ИИ обычными словами.
На эфире покажет:
✅ как пройти путь от установки инструментов до выполнения заказов
✅ какие 5 ошибок чаще всего губят попытки самоучек
✅ где заканчиваются возможности бесплатных нейросетей
✅ как выполнять задачи без VPN и зарубежной карты
✅ какой инструмент можно использовать для старта
Причём инструмент тоже дадут бесплатно прямо на эфире.
Если давно смотрите на нейросети, но кажется:
«Я не технарь»
«Я не умею программировать»
«Я не дизайнер и не умею делать красивый визуал»
«Нужно сначала полгода учиться»
посмотрите, как нейросети помогают выполнять реальные заказы от начала до конца.
🎁 Участие бесплатное + дают курс по нейросетям для новичков.
👉 ЗАРЕГИСТРИРОВАТЬСЯ НА БЕСПЛАТНЫЙ ЭФИР И ПОСМОТРЕТЬ, КАК ИИ ВЫПОЛНЯЕТ ЗАКАЗ ЗА 15 МИНУТ
#реклама
О рекламодателе
287 просм.4 окт., 12:02
Следим за появлением файлов в папке через WatchService!
Создадим наблюдатель и зарегистрируем каталог. Папка должна существовать заранее:
Path dir = Path.of("incoming");
try (WatchService watcher = FileSystems.getDefault().newWatchService()) {
dir.register(watcher, ENTRY_CREATE, ENTRY_MODIFY);
Константы ENTRY_CREATE и ENTRY_MODIFY берутся из StandardWatchEventKinds. try-with-resources закроет наблюдатель при выходе из блока.
Дальше ждём сигнал. Метод take блокирует поток, пока событие не появится:
while (true) {
WatchKey key = watcher.take();
for (WatchEvent event : key.pollEvents()) {
Контекст события содержит имя относительно наблюдаемой папки, а не готовый абсолютный путь. Не подставляй его отдельно от dir:
if (event.kind() == OVERFLOW) continue;
Path file = dir.resolve((Path) event.context());
System.out.println(event.kind() + " " + file);
}
После обработки обязательно сбросим ключ. Если каталог удалён или больше недоступен, reset вернёт false:
if (!key.reset()) break;
}
}
События могут повторяться, а при перегрузке наблюдатель сообщит OVERFLOW. Поэтому важную обработку лучше делать идемпотентной и предусмотреть повторное сканирование каталога после переполнения.
Java Библиотека | Мы в Телеграм
594 просм.2 окт., 09:38
Ленивая инициализация через Supplier — элегантная альтернатива double-checked locking
Когда нужно отложить создание тяжёлого объекта до первого обращения, многие вспоминают double-checked locking:
private volatile SomeHeavyObject obj;
public SomeHeavyObject getObj() {
if (obj == null) {
synchronized (this) {
if (obj == null) {
obj = new SomeHeavyObject();
}
}
}
return obj;
}
Многословно, хрупко, легко ошибиться. Есть лучше.
Современный подход — использовать Supplier с ленивой инициализацией:
private final Supplier lazyObj = Suppliers.memoize(SomeHeavyObject::new);
public SomeHeavyObject getObj() {
return lazyObj.get();
}
Suppliers.memoize — из Guava. Он гарантирует потокобезопасную инициализацию один раз при первом вызове get().
Плюсы:
— Читается за секунду
— Потокобезопасно
— Нет дублирования кода
— Легко тестировать и заменять
Альтернатива в чистой Java: использовать AtomicReference и updateAndGet, но это уже длиннее и менее выразительно.
Если используешь Spring — можно просто обернуть бин в @Lazy. Но вне Spring, в обычных Java-приложениях или утилитах — Supplier с memoize() идеален.
Java Библиотека | Мы в Телеграм
556 просм.30 сент., 21:51
Почему trim() может не убрать пробелы по краям строки?
В Java часто очищают пользовательский ввод так:
String name = input.trim();
Но trim() ориентируется на символы с кодом не выше U+0020. Некоторые пробельные символы Unicode под это правило не попадают.
Например, строка может начинаться и заканчиваться широким пробелом U+2003:
String input = "\u2003admin\u2003";
System.out.println(input.trim().length());
Видимые на экране отступы останутся. Это может сломать сравнение логина, поиск ключа или проверку поля формы.
Начиная с Java 11 есть strip(), который опирается на определение пробельного символа в Character.isWhitespace:
String name = input.strip();
System.out.println(name.equals("admin"));
Если нужна очистка только с одной стороны, есть отдельные методы:
String left = input.stripLeading();
String right = input.stripTrailing();
Для проверки строки, состоящей только из пробелов, пригодится isBlank():
if (input.isBlank()) {
throw new IllegalArgumentException("Empty name");
}
strip() не удаляет все символы, которые выглядят как пробелы. Для специальных форматов ввода полезно отдельно определить допустимые символы.
Java Библиотека | Мы в Телеграм
474 просм.30 сент., 09:43
Java: не создавайте тяжёлые объекты раньше времени
Если объект дорогой в создании, но нужен только в редких сценариях, eager initialization может зря тратить время и память.
Вместо этого используйте lazy initialization:
private HeavyAnalyzer analyzer;
private HeavyAnalyzer analyzer() {
if (analyzer == null) {
analyzer = new HeavyAnalyzer();
}
return analyzer;
}
Так HeavyAnalyzer создастся только при первом реальном обращении.
Где особенно полезно:
- кэши;
- API-клиенты;
- тяжёлая конфигурация;
- анализаторы;
- объекты с дорогой инициализацией.
Для более чистого кода можно использовать Supplier, holder pattern или современные lazy-механизмы Java.
Если доступ идёт из нескольких потоков, простая проверка if (analyzer == null) уже недостаточна - нужна потокобезопасная реализация.
Java Библиотека | Мы в Телеграм
468 просм.29 сент., 09:37
Во многих приложениях есть такой эндпоинт.
Фронтенд удаляет JWT после того, как пользователь нажимает «Выйти». Но вот вопрос… Действительно ли пользователь вышел из системы?
Что, если:
• JWT скопировали до выхода?
• Срок действия токена ещё не истёк?
• Другое устройство всё ещё использует тот же токен?
Будет ли ваш бэкенд по-прежнему принимать этот JWT? Как вы реализуете выход из системы в архитектуре со stateless JWT?
Java Библиотека | Мы в Телеграм
449 просм.28 сент., 18:37
Почему одни ИИ-агенты помогают разработчикам экономить время, а другие требуют постоянной доработки? При создании агентных систем важно не только подключить LLM, но и правильно организовать логику работы агентов. Без единых подходов разработка замедляется: одни и те же решения приходится создавать заново, а поведение системы становится сложнее контролировать.
На открытом уроке 1 октября в 20:00 МСК разберем, как Agent Skills помогают ускорить создание ИИ-агентов, стандартизировать их логику и повторно использовать готовые решения. Вы узнаете, какие ИИ-инструменты помогают разработчикам быстрее собирать агентные системы и как применять эти подходы на практике.
Урок пройдет в преддверие старта курса «Разработка ИИ-агентов». Занятие подойдет разработчикам, ИИ-инженерам и техническим специалистам, которые создают агентные решения и хотят повысить скорость и качество разработки.
➡️Научитесь создавать более предсказуемые ИИ-агенты и тратить меньше времени на рутинную реализацию: https://vk.cc/d2a7Mw
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
394 просм.28 сент., 13:01
Что такое механизм try-with-resources?
Механизм try-with-resources в Java — это конструкция, которая упрощает работу с ресурсами, требующими закрытия (например, файлы, сокеты, соединения с БД и т.д.). Он автоматически закрывает ресурсы после завершения блока try, избавляя от необходимости писать finally вручную.
Поддерживается с Java 7
Ресурсы должны реализовывать интерфейс AutoCloseable
Пример:
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
String line = reader.readLine();
System.out.println(line);
} catch (IOException e) {
e.printStackTrace();
}
// reader будет закрыт автоматически, даже если произойдёт исключение
Почему это важно:
* Уменьшает boilerplate-код
* Исключает утечки ресурсов
* Упрощает обработку исключений
Совет:
С Java 9 можно использовать уже объявленные переменные, если они final или effectively final:
BufferedReader reader = new BufferedReader(new FileReader("file.txt"));
try (reader) {
System.out.println(reader.readLine());
}
Java Библиотека | Мы в Телеграм
417 просм.28 сент., 09:25
Запускаем внешнюю команду через ProcessBuilder!
Иногда Java-приложению нужно вызвать системную утилиту, например git, ffmpeg или собственный скрипт деплоя. Склеивать такую команду в одну строку опасно, особенно если параметры приходят извне.
ProcessBuilder принимает аргументы отдельно. Так пробелы и специальные символы не превращаются в случайный shell-код.
var process = new ProcessBuilder(
"git", "status", "--short")
.redirectErrorStream(true)
.start();
redirectErrorStream(true) объединяет обычный вывод и ошибки. Это не даёт процессу зависнуть, когда буфер stderr заполняется, пока приложение читает только stdout.
try (var reader = process.inputReader()) {
var lines = reader.lines().toList();
lines.forEach(System.out::println);
}
После чтения обязательно дождитесь завершения и проверьте код возврата. Нулевой код обычно означает успех.
int exitCode = process.waitFor();
if (exitCode != 0) {
throw new IllegalStateException("Command failed");
}
Для долгих команд добавьте waitFor с таймаутом и уничтожайте процесс при превышении лимита. Так интеграция с внешним инструментом не сможет навсегда заблокировать поток приложения.
Java Библиотека | Мы в Телеграм
407 просм.27 сент., 21:26
🌞 Hibernate выполняет SQL не в том порядке, в котором ты его написал
Код читается сверху вниз, а Hibernate так не работает. При flush'е Hibernate складывает все действия в ActionQueue и выполняет их в строго фиксированном порядке по типу операции, а не по порядку вызова в коде:
1. orphan removal
2. INSERT
3. UPDATE
4. удаление коллекций
5. обновление коллекций
6. вставка коллекций
7. DELETE
Классический пример с unique-ограничением:
repo.delete(oldRow); // (1) в коде сначала удаляем
repo.save
(newRow); // (2) потом вставляем с тем же unique-значением
// commit -> ConstraintViolationException
На flush Hibernate переставит это в INSERT → DELETE. Вставка отработает до удаления, ловит конфликт по уникальному ключу, и падает, хотя в твоём коде последовательность была валидной.
🟡 Варианты решения:
— явный flush() между операциями, чтобы зафиксировать порядок;
— deferred (отложенные) constraints на стороне БД;
— пересмотр модели, чтобы коллизии в принципе не возникало.
Главное не считать, что порядок методов = порядок SQL. Это не так (для Hibernate).
Java Библиотека | Мы в Телеграм
416 просм.27 сент., 18:08
👩💻 Как сделать Java-сервис устойчивее к сбоям
Resilience4j добавляет готовые паттерны CircuitBreaker, Retry, RateLimiter и Bulkhead без необходимости писать их с нуля.
Есть интеграции со Spring Boot, Reactor и Micrometer, а новая major-версия работает с Java 21+.
⛓ Ссылка на GitHub
Java Библиотека | Мы в Телеграм
396 просм.27 сент., 12:02
Java: используйте Deque вместо Stack для работы по принципу LIFO («последним пришёл — первым вышел»).
Stack — устаревший класс, который наследуется от Vector и синхронизирует каждый вызов.
Deque предоставляет те же методы push, pop и peek.
Используйте ArrayDeque: он быстрее и рекомендуется начиная с Java 6.
Java Библиотека | Мы в Телеграм
662 просм.26 сент., 23:45
Многие разработчики используют Java каждый день. Но мало кто знает, почему он стал одним из самых успешных языков в мире.
Вот его основные особенности:
Независимость от платформы
Скомпилируйте код в байт-код один раз и запускайте его на любой машине с JVM.
Объектно-ориентированный подход
Всё строится вокруг классов и объектов, что упрощает организацию и сопровождение крупных приложений.
Надёжность
Автоматическая сборка мусора, строгая проверка типов и обработка исключений помогают избежать многих распространённых проблем во время выполнения.
Высокая производительность
JIT-компилятор (Just-In-Time) оптимизирует часто выполняемый код, обеспечивая скорость, близкую к нативной.
Многопоточность
Встроенные API для работы с конкурентностью упрощают параллельное выполнение нескольких задач.
Проверен на практике
Банковские системы, платформы электронной коммерции, Android-приложения и корпоративные бэкенды: Java лежит в основе критически важного ПО в самых разных отраслях.
Java Библиотека | Мы в Телеграм
428 просм.26 сент., 18:45
Продвинутый Java-совет: используйте `ClassValue`
Если нужно кешировать метаданные отдельно для каждого класса, не обязательно создавать ConcurrentHashMap, Metadata>.
private static final ClassValue CACHE =
new ClassValue<>() {
@Override
protected Metadata computeValue(Class type) {
return scan(type);
}
};
Metadata metadata = CACHE.get(MyClass.class);
ClassValue лениво вычисляет значение, безопасно работает при конкуренции потоков и хранит отдельный результат для каждого Class. Сбросить кеш можно через remove().
Полезно для reflection, сериализации, мапперов и собственных фреймворков.
Java Библиотека | Мы в Телеграм
447 просм.25 сент., 18:31
⌨️ void и Void
В языке программирования Java ключевое слово void используется для указания, что метод не возвращает никакого значения. Метод с возвращаемым типом void выполняет определенные действия, но не производит результат, который можно было бы использовать в вызывающей части программы.
Для void еще есть класс обёртка Void. Класс Void — это класс-заполнитель который нельзя создать и который хранит ссылку на объект Class, представляющий ключевое слово Java void.
Этот класс можно использовать, например, в случаях, когда у вас есть обобщенный класс и вы хотите, чтобы метод ничего не возвращал (т.е. чтобы пользователь класса не ожидал ничего особенного оттуда получить):
interface I {
T doStuff();
}
class A implements I {
@Override
public Void doStuff() {
// ничего другого вернуть нельзя
return null;
}
}
Или если в проекте регулярно используется Callable для выполнения каких-то асинхронных задач и в тех ситуациях, когда результат работы задачи ничего не должен возвращать, можно реализовать Callable.
Java Библиотека | Мы в Телеграм
646 просм.25 сент., 13:23
Посты загружаются автоматически из канала. Администрация сайта не несёт ответственности за их содержание и размещённые в них ссылки.
