Java: fill the gaps
Привет! Меня зовут Диана, и я занимаюсь разработкой с 2013. Здесь пишу просто и понятно про джава бэк 🔥Тот самый курс по многопочке🔥 https://fillthegaps.ru/mt Комплименты, вопросы, предложения: @utki_letyat
Больше📈 Аналитический обзор Telegram-канала Java: fill the gaps
Канал Java: fill the gaps (@java_fillthegaps) языкового сегмента Русский является активным участником. Сейчас сообщество объединяет 12 561 подписчиков, занимая 10 092 место в категории Технологии и приложения и 52 768 место в регионе Россия.
📊 Показатели аудитории и динамика
С момента создания невідомо проект демонстрирует стремительный рост, собрав аудиторию из 12 561 подписчиков.
Согласно последним данным от 03 июня, 2026, канал показывает стабильную активность. За последние 30 дней изменение числа участников составило -39, а за последние 24 часа — -3, при этом общий охват остаётся высоким.
- Статус верификации: Не верифицирован
- Уровень вовлечённости (ER): Средний показатель вовлечённости аудитории составляет 34.68%. В первые 24 часа после публикации контент обычно набирает N/A% реакций от общего числа подписчиков.
- Охват публикаций: В среднем каждый пост получает 0 просмотров. В течение первых суток публикация набирает 0 просмотров.
- Реакции и взаимодействия: Аудитория активно поддерживает контент: среднее количество реакций на один пост — 0.
- Тематические интересы: Контент сосредоточен на ключевых темах, таких как redis, hashmap, linkedhashmap, индекс, фича.
📝 Описание и контентная политика
Автор описывает ресурс как площадку для выражения субъективного мнения:
“Привет! Меня зовут Диана, и я занимаюсь разработкой с 2013. Здесь пишу просто и понятно про джава бэк
🔥Тот самый курс по многопочке🔥
https://fillthegaps.ru/mt
Комплименты, вопросы, предложения: @utki_letyat”
Благодаря высокой частоте обновлений (последние данные получены 04 июня, 2026) канал поддерживает актуальность и высокий уровень охвата публикаций. Аналитика показывает, что аудитория активно взаимодействует с контентом, что делает его важной точкой влияния в категории Технологии и приложения.
@MockitoBean, @MockitoSpyBean или @TestBean, Spring создает для него прокси. Получается уникальный контекст, который нужно поднимать отдельно и нельзя в дальнейшем переиспользовать.
К новому контексту приводит переопределение свойств, указание профиля, конфигурация MockMvc и тд
Ответ на вопрос перед постом - прогон тестов будет занимать чуть больше 6 минут, потому что формируется 3 контекста. Для тестов BidProcessingIT и AccountProcessingIT используется один контекст.
🤔 Как оптимизировать выполнение тестов?
Популярный прием, которая помогает зафиксировать контекст - базовый класс с тестовой конфигурацией. В базовом классе настраивается тестовый конфиг, тестконтейнеры, решается вопрос с секьюрити, наполнением и очисткой БД и тд
@SpringBootTest
@AutoConfigureMockMvc
@TestPropertySource(…)
@TestExecutionListeners(…)
@ActiveProfile("test")
// куча других аннотаций
public abstract class BaseIntegrationTest {
// тестконтейнеры
// заглушки
}
Остальные классы наследуются от базового:
class UserIT extends BaseIntegrationTest {
@Autowired
private MockMvc mockMvc;
@Test
public void shouldCreateUser() {…}
}
При такой схеме важно следить, чтобы в наследниках не заменялись бины, свойства и тд. Иначе для них будет создан новый контекст.
На практике редко используется один базовый класс, чаще это иерархия под разные случаи. При грамотном проектировании и сознательности разработчиков интеграционные тесты выполняются за адекватное время даже для больших проектов👌@SpringBootTest
public class UserIT{...}
@ActiveProfiles("test")
@SpringBootTest
public class BidProcessingIT{...}
@SpringBootTest(properties = {
"user.rebalance.enabled=true"
})
public class RebalanceAccountIT{...}
@ActiveProfiles("test")
@SpringBootTest
public class AccountProcessingIT{...}При создании value объекта через new, JVM может не создавать новый объект, а найти уже такой же существующий. == для таких объектов будет возвращать true.Подобная идея лежит в основе пулов для базовых типов. При вызове new Integer(127) не создаётся новый объект, а берётся уже существующий из пула. Для классов-обёрток это существенная экономия. Текущая цель модификатора value и концепта identity (вернее его отсутствия) - обозначить, к каким объектам можно применить пачку оптимизаций. Новый тип и рассуждение про доменные сущности выглядит пока натянуто. Нужно явно обозначить определения, границы и ожидаемые эффекты от value. Типы данных - база, одна из первых тем при освоении языка. Должно быть простое объяснение, чем отличаются типы, без погружения в дебри возможных оптимизаций. Должно быть конкретное определение identity, если оно важно для выбора типа. Годы работы и преподавания не проходят бесследно. Если что-то может быть понятно неверно - оно будет понято неверно💯 Поэтому пока оцениваю новую фичу на троечку И ответ на вопрос перед постом. Сейчас в консоли будет false, объекты сравниваются по ссылке. Возможно, после введения value types тот же код вернёт true, и популярный вопрос с собеседований получит вторую жизнь. Но может и нет💅
value class LocalDate {
int year;
int month;
int day;
// конструкторы, методы
}
Поля класса становятся final, сам класс тоже final. Но главное, что в памяти список LocalDate будет лежать плоско, без лишних заголовков и прыжков по куче.
Глядите на картинку👇 Слева список объектов, справа - набор value. Работа со списками обещает быть blazingly fast🚀
Value types прекрасно вписываются в текущие тренды. Сейчас через сервисы проходит море данных, которые в большинстве своём неизменяемые. Уплощение структуры даст буст в скорости обработки. Поэтому value types так ждут.
Модификатор value уже получили 30 базовых классов:
▫️ обёртки примитивов: Integer, Long, …
▫️ Optional*
▫️ классы дат: LocalDate, LocalDateTime, …
Классы выше - база, поэтому перфоманс подрастёт просто при переходе на JDK с value типами. Такое мы любим.
Ещё немного странного/интересного:
🤔 value можно добавить абстрактному классу. Тогда наследники тоже станут value классами. В JEP написано, что наследники могут отказаться от value модификатора, но как - непонятно:)
🤔 value class vs record
Record - final класс с final полями, идеальный кандидат, чтобы стать value классом по умолчанию. Но это не так, для records нужно явно прописывать value. В самом JEP объяснение сводится к утверждению
Не каждый value класс можно сделать recordЧто, безусловно, верно. Но непонятно, почему неверно обратное. Остаётся только додумывать про обратную совместимость с уже существующими рекордс 🤔 String не стал value классом Опять же, могу найти техническую причину. Хэш строки вычисляется лениво, а в value классе поля должны быть final. Здесь помогла бы другая фича, которая сейчас в превью — StableValue, ленивая инициализация final полей. Но в JEP пишут, что дело в наличии идентичности (identity) у строки. Про концепт идентичности напишу отдельный пост, но если кратко: identity определяет возможность сравнения 2 объектов с одинаковыми значениями. Почему у строк есть identity, мне непонятно. Пул строк, дедупликация и прочие оптимизации явно не уважают право String на идентичность. Это только основное, на что точно следует обратить внимание. В тексте ещё очень много интересного, куча намёков на будущие фичи и оптимизации. Давно не читала JEP с таким интересом😊
Что делать, если сервис взял лок, но умер? Что будет, если один сервис отправит 2 команды захватить лок? Может ли сервис отпустить лок, который он не держит? Что делать, если порядок запросов нарушится, и сначала на лок пришла команда "отпустить", а потом "взять"? Кто будет создавать локи? Будет ли атомарно работать связка "создать и захватить лок"? Сколько сервис будет пытаться захватить лок? С какими интервалами? Если сервис встаёт в очередь к локу - сколько времени ждать? можно ли выйти из очереди? Кто и когда будет удалять локи?Многие вопросы снимаются инструментами, но не все. Race condition в распределенных системах встречается сплошь и рядом. Взять хотя бы недавний сбой Амазона, где всё началось с того, что 2 сервера одновременно накатывали апдейт и помешали друг другу. Ещё одна проблема с локами - тестирование. В большинстве случаев разработчик проверит вручную пару кейсов с помощью Thread.sleep. Но это детский сад, конечно. Написать автоматизированные тесты для распределенных локов очень сложно. Поэтому даже если система маленькая, всё крутится на одном сервере и сетевые проблемы сведены к минимуму, рекомендую рассмотреть альтернативы. Например ✔️ Сделать задачу идемпотентной и безопасной для многократного выполнения ✔️ Провернуть Inversion of control. Ресурсы распределяются по исполнителям, а не исполнители борются за ресурсы Оба подхода можно протестировать, и общая логика часто упрощается. Берите на заметку, квинтэссенция многолетнего опыта:) Но если сердце не видит преград, и сделать лок хочется, вот пара заметок: 💫 Лок можно реализовать на Postgres (SELECT … FOR UPDATE), Redis, Zookeeper, Kubernetes 💫 ID держателя лока удобно записывать в лок. ID каждого участника должен быть постоянным 💫 Вместо плясок с TTL можно положиться на связь сервиса и лока. В Zookeeper есть ephemeral nodes, которые исчезают, если связь с сервисом пропадает. Транзакция в Postgres может не сразу обнаружить разрыв соединения, но тоже в итоге откатится Что почитать: 🔥 Cтатья Alibaba Cloud 2024 года. Обзор решений на джаве и их нюансов 🔥 Статья Клепмана (автор книги с кабанчиком) про недостатки распределенного лока в Redis . Статья старая (2016 год) и специфичная, но полезна для полноты картины
class Employee extends Person {
Employee(int age) {
if (age < 18)
throw new IllegalArgumentException(...);
super(age);
}
}
🍑 JEP 506: Scoped Values
ScopedValue - новый класс, чтобы передавать служебные данные между методами без явной передачи через параметры.
Традиционно для этих целей используется ThreadLocal. Яркий пример - SecurityContext из Spring Security. Мы не тащим SecurityContext в каждый метод, но информация о текущем пользователе всегда под рукой.
Scoped Value - это ThreadLocal Premium:
👑 Доступен только в пределах заданной области
👑 Значение неизменяемое
👑 Автоматически удаляется после использования
👑 Совместим с виртуальными потоками
Остальные фичи довольно специфичны, опишу их кратко
🍑 JEP 510: Key Derivation Function API
Квантовые компьютеры активно развиваются, они очень мощные и будут щёлкать текущие алгоритмы как орешки. Этот JEP - часть работ по внедрению в джаву Post-Quantum Cryptography - новых алгоритмов безопасности.
🍑 JEP 511: Импорт модулей
Вместо
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
Можно написать короче:
import module java.base;Любая IDE управляет импортами за нас, поэтому полезность фичи под вопросом. Возможно, разработчики джавы не вспомнили названия модулей, когда подтверждали свои навыки на HH. Но это не точно. 🍑 JEP 503: Remove the 32-bit x86 Port Не учитывать в дальнейшей разработке 32х-битные процессоры 🍑 JEP 512: Compact Source Files and Instance Main Methods Более короткий Hello World:
void main() {
IO.println("Hello, World!");
}
🍑 JEP 520: JFR Method Timing & Tracing, JEP 515: Ahead-of-Time Method Profiling, JEP 520: JFR Method Timing & Tracing
Профайлинг стал точнее и стартует чуть быстрее.
🍑 JEP 521: Generational Shenandoah
Сборщик мусора Shenandoah теперь делит объекты на старые и новые, раньше это была экспериментальная фича.
Такой вот релиз будет завтра✨В интернете есть списки вопросов, на ютубе мок собесы, а ещё ИИ, чем бот лучше?Вместо тысячи слов - возьмите пробный период и оцените сами @awesome_java_bot А если хочется слов, вот 4 главных плюса: 1️⃣ Вопросы Вопросы крутятся вокруг тем и моментов, с которыми у многих случаются сложности. Это не просто список с собесов. Я дополнила их вопросами на понимание, вопросами-кейсами, формулировками с другого ракурса. В одном отзыве на курс многопоточки ученик написал, что я использую метод Сократа. Из википедии:
Этот метод часто подразумевает дискуссию, в которой собеседник, отвечая на заданные вопросы, высказывает суждения, обнаруживая свои знания или, напротив, своё неведение.Это прекрасно описывает стратегию бота. Многие вопросы не встречаются на собеседовании в явном виде, но помогают найти пробелы в знаниях или понимании темы. Ни одна нейросеть не соберёт вам такое. 2️⃣ Активная работа Читать списки вопросов или смотреть видео - это пассивное потребление информации. Мозг включается минимально, кажется, что всё понятно и легко. А через минуту забываешь, что вообще смотрел и читал. Тесты - не идеальный вариант проверки знаний, но уже переводит мозг из пассивного режима в активный. Потому что надо обдумать варианты и сделать выбор. Плюс мгновенная обратная связь. Сразу понятно, есть ли пробел с какой-то темой или всё чётко. 3️⃣ Материалы Краткое пояснение, конспект в базе знаний, ссылки на доп.материалы. Удобно и экономит время. 4️⃣ Напоминания Каждый день бот предлагает повторить какую-то тему. Фича простая, но помогает делать маленькие регулярные шаги, которые в перспективе дают отличный результат. Короче, кому надо — тот оценит. В ближайшее время буду активно наполнять бот вопросами. Когда этот эпичный труд будет закончен, цена станет более справедливой. Сейчас это копейки. Плюс до конца дня действует скидка для любимых подписчиков. Отличный шанс зафиксировать низкую цену: @awesome_java_bot Популярный вопрос - можно ли оплатить не российской картой? К сожалению, пока нет. Но если появится альтернативный способ оплаты, я напишу
Уже доступно! Исследование Telegram 2025 — ключевые инсайты года 
