Java: fill the gaps
Привет! Меня зовут Диана, и я занимаюсь разработкой с 2013. Здесь пишу просто и понятно про джава бэк 🔥Тот самый курс по многопочке🔥 https://fillthegaps.ru/mt Комплименты, вопросы, предложения: @utki_letyat
Показати більше📈 Аналітичний огляд Telegram-каналу Java: fill the gaps
Канал Java: fill the gaps (@java_fillthegaps) у мовному сегменті Російська є активним учасником. На даний момент спільнота об'єднує 12 548 підписників, посідаючи 10 113 місце в категорії Технології та додатки та 52 819 місце у регіоні Росія.
📊 Показники аудиторії та динаміка
З моменту свого створення невідомо, проект продемонстрував стрімке зростання, зібравши аудиторію у 12 548 підписників.
За останніми даними від 08 червня, 2026, канал демонструє стабільну активність. Хоча за останні 30 днів спостерігається зміна кількості учасників на -43, а за останні 24 години на -3, загальне охоплення залишається високим.
- Статус верифікації: Не верифікований
- Рівень залученості (ER): Середній показник залученості аудиторії становить 34.73%. Протягом перших 24 годин після публікації контент зазвичай збирає N/A% реакцій від загальної кількості підписників.
- Охоплення публікацій: В середньому кожен допис отримує 0 переглядів. Протягом першої доби публікація в середньому набирає 0 переглядів.
- Реакції та взаємодія: Аудиторія активно підтримує контент: середня кількість реакцій на один пост – 0.
- Тематичні інтереси: Контент зосереджений навколо ключових тем, таких як redis, hashmap, linkedhashmap, индекс, фича.
📝 Опис та контентна політика
Автор описує ресурс як майданчик для висловлення суб'єктивної думки:
“Привет! Меня зовут Диана, и я занимаюсь разработкой с 2013. Здесь пишу просто и понятно про джава бэк
🔥Тот самый курс по многопочке🔥
https://fillthegaps.ru/mt
Комплименты, вопросы, предложения: @utki_letyat”
Завдяки високій частоті оновлень (останні дані отримано 09 червня, 2026), канал підтримує актуальність та високий рівень охоплення публікацій. Аналітика показує, що аудиторія активно взаємодіє з контентом, що робить його важливою точкою впливу в категорії Технології та додатки.
README.md в корневую директорию. Иногда это единственное, на что посмотрит посторонний человек. Не пожалейте времени, тщательно опишите:
▪️О чём проект
▪️Основные функции
▪️Архитектуру (нарисуйте схему)
▪️Используемые технологии
2️⃣ Проработайте структуру проекта - дайте модулям и классам понятные имена. Функции, указанные в README, должно быть легко найти в коде.
Эти простые действия помогут сориентироваться в проекте и лучше оценить Вашу работу.System.out.println.
Продвинутый вариант:
🔸Добавить брейкпойнт, зажав Shift.
🔸Щёлкнуть галочку Evaluate and log.
🔸Вписать нужное выражение.
В этом случае отладчик не будет останавливать выполнение, а запишет в консоль значение выражения. Очень полезно для отладки многопоточных приложений🔥 Дополнительный бонус: можно использовать в коде сторонних библиотек.
3️⃣ Отключение.
Если брейкпойнт пока не нужен, его можно не удалять, а отключить одним из двух способов:
▪️Щёлкнуть колёсиком по брейкпойнту.
▪️Правый щёлчок по брейкпойнту, снять галочку с Enabled.
4️⃣ Массовое удаление.
Когда в проекте очень много брейкпойнтов, IDE может подтормаживать при дебаге. Чтобы посмотреть полный список брейкпойнтов и удалить ненужные:
▫️Правый клик по любому брейкпойнту
▫️Ссылка More
▫️Слева видим список брейкпойнтов
▫️Удаляем ненужные
В этом же окне находятся фильтры для выборочной остановки, но обычно удобнее пользоваться условиями из п.1java.lang.String.
❓Почему для классов JDK используется 2 загрузчика?
✅ Bootstrap работает на уровне виртуальной машины и загружает необходимый минимум классов на старте приложения. Extension ClassLoader - java объект, который загружает дополнительные модули JDK по мере необходимости.
❓Почему для отложенной загрузки классов нужны разные ClassLoader?
✅ Для безопасности классов JDK. Cуществует 4 модификатора доступа - private, protected, public и default. Последний ещё называют "доступ по умолчанию". Он даёт доступ к классам и методам того же пакета. Если мы назовём класс java.lang.Smth, он сможет работать с классами из пакета java.lang. Поэтому класс получает доступ к default полям другого класса только если:
🔸У него совпадает название пакета.
🔸Загружен тем же ClassLoader'ом.
JDK классы используют Bootstrap/Extension загрузчик, а наш java.lang.Smth - Application загрузчик, поэтому внутренние классы JDK недоступны классу Smth.
❓Что изменилось в java 9?
✅ Схема взаимодействия загрузчиков осталась той же. Поскольку JDK библиотеки (rt.jar, tools.jar) теперь разбиты на модули, работа с ними поменялась:
1️⃣ Изменились внутренние классы и методы загрузчиков. Проекты, которые используют загрузчики классов напрямую, столкнулись с проблемами совместимости.
2️⃣ Extension ClassLoader переименован в Platform ClassLoader. Теперь он загружает классы из модулей JDK и сторонних библиотек, одобренных Java Community: JDBC, JMS, JAX-RS и т.д. .class. Когда в программе встречается имя нового класса, JVM "загружает" его: ищет файл с таким же именем и создаёт экземпляр типа Class. В этом объекте содержится информация о полях, методах и обо всём, что нужно для создания экземпляра.
Базовые классы JDK, такие как Object, String, ArrayList, являются основой для других объектов. Поэтому они загружаются на старте приложения, этим занимается объект JVM под названием Bootstrap ClassLoader.
Любая программа использует много сторонних библиотек. Чтобы не тратить ресурсы на загрузку лишних объектов, классы подгружаются по мере необходимости.
❓Какие события вызывают загрузку класса?
🔸Создание экземпляра:
new Example();🔸Ссылка на статические поля/методы этого класса:
Example.getFormat();🔸Явная загрузка класса:
cl.loadClass("Example");
Extension ClassLoader загружает редкие модули JDK: java.sql, jdk.httpserver и тд. Application ClassLoader загружает пользовательские классы.
Схема поиска подходящего .class файла выглядит так:char[].
В Java 9 вышло обновление Compact Strings, которое меняет структуру хранения строки.
Символы теперь лежат в byte[] и хранятся в одной из двух кодировок. Сама кодировка записана в новом параметре coder. Возможны 2 варианта:
1️⃣ Если все символы строки умещаются в 1 байт(латиница и цифры), то записываются в одну ячейку массива. Выставляется кодировка Latin-1.
2️⃣ Если хотя бы один символ требует 16 байт, все элементы занимают 2 ячейки массива. Выставляется кодировка UTF-16.
❓Можно ли было перевести строки на UTF-8, символы с переменной длиной?
Да, расход памяти стал бы ещё меньше, но производительность бы упала. Если символы в массиве одной длины, то по индексу можно быстро найти адрес символа в памяти. Если элементы с переменной длиной - адрес вычисляется на основе предыдущих элементов, а это долго. Все методы класса String работали бы дольше.
Строки в разных кодировках по-разному лежат в памяти, и работать с ними нужно тоже по-разному. Каждый метод в классе String начинается с проверки кодировки и разделяется на две ветки — для Latin-1 и UTF-16. Их код вынесен в отдельные классы StringLatin1 и StringUTF16.
❓Память сэкономили, кода стало в 3 раза больше, не упала ли производительность?
Любая дополнительная проверка снижает скорость обработки, особенно при работе с маленькими строками. Поэтому на уровне JVM и JIT добавлены оптимизации проверки кодировки и сравнения строк, изменён механизм конкатенации и других операций. Именно за счёт внутренних оптимизаций компактные строки работают в среднем на 20% быстрее и создают на 30% меньше промежуточных объектов.
Самое главное - эти изменения никак не отразились на интерфейсе String. I/O классы, StringBuilder, StringBuffer тоже адаптированы без внешних изменений. Нужно просто перейти на java 9 и приложение будет занимать на 5-15% меньше памяти.hash % 16 hash & 15Результат будет одинаковый, но логическое И выполняется в 2 раза быстрее. Вычисление бакета — частая операция в HashMap, и такая микрооптимизация даёт хороший прирост в производительности. ❓Что такое load factor и зачем он нужен? HashMap быстро работает, когда в бакете 0 или 1 элемент. При добавлении элементов повышается шанс, что в одном бакете их будет несколько, a HashMap станет менее эффективен. Поэтому HashMap периодически расширяется. Параметр load factor определяет, когда это происходит. По умолчанию равен 0.75. Пример: в HashMap 20 элементов и 32 бакета. Когда элементов будет 32*0.75=24, количество бакетов удвоится и элементы перераспределятся по ним. ❓Какие недостатки у HashMap? 1️⃣ Cильная зависимость от функции распределения хэшей. 2️⃣ Неэкономный расход памяти. При load factor = 0.75 будет пустовать 25% памяти. При неравномерном распределении хэшей — ещё больше. ❓В конструкторе HashMap проставляются свойства, а массив бакетов создаётся только при первой вставке. Зачем нужна ленивая инициализация? Расширение HashMap — долгая операция. Когда добавляется набор элементов, можно сразу увеличить массив до необходимого размера. Очень популярный случай - когда в пустой HashMap добавляютcя элементы другой map:
Map result=new HashMap(); ... result.putAll(anotherMap);Если бы внутренняя структура result создавалась в конструкторе, пришлось бы тут же её расширять. С отложенной инициализацией можно этого избежать. А теперь разберём вопрос про порядок элементов: ✅ Обход HashMap происходит последовательно - бакет за бакетом. Поэтому задание сводится к определению бакетов, в которые попадут значения. Это и будет порядок вывода элементов:
10 % 16 = 10 20 % 16 = 4 30 % 16 = 14Ответ: 20 10 30
String
▫️sout
System.out.println();
▫️main
public static void main(String[] args){}
▫️prsf
private static final
Некоторые сокращения разворачиваются в методы с параметрами для автозаполнения. Перемещаться между ними можно с помощью Tab:
▫️ fori
for (int i=0; i< ; i++) {}
▫️ifn
if (args == null) {}
▫️mx
= Math.max(, );
▫️lazy
if (obj == null)
{ obj = new Integer(); }
2️⃣ Code completion.
Дополнение имен классов, методов и полей на основе контекста. Варианты появляются в выпадающем списке. Можно писать только начало:
▫️Int → Integer
▫️Cust → Customer
Можно писать заглавные буквы в названиях классов:
▫️NPE → NullPointerException
▫️CHM → ConcurrentHashMap
Можно оборачивать код в синтаксические конструкции:
▫️count == 4.if
if (count == 4) {}
▫️list.for
for(Integer i : list) {}
▫️obj.opt
Optional.of(obj)
▫️answer.switch
switch (answer) {}
Полный список таких дополнений в File/Settings/Editor/General/Postfix Completion. Есть варианты не только для Java, но и для Kotlin и JS.Iterator it=list.iterator(); while(it.hasNext()) int result = it.next();Метод next() возвращает текущий элемент и сразу сдвигает указатель на следующий. Метод hasNext() проверяет, ссылается ли этот указатель куда-нибудь. Этот паттерн повторяется снова и снова и называется Iteration. Важно - указатель на следующий элемент вычисляется заранее. Итератор лежит в основе синтаксиса
for (T e: collection).
❌ Так как следующий элемент известен заранее, итератор может показать удалённый элемент. Или не вывести только что добавленный.
ArrayList, HashMap, HashSet и тд. не синхронизированы. Если одновременно итерировать и менять коллекцию разными потоками, можно нарушить целостность данных. Есть два способа этого избежать:
1️⃣ Fail-fast итераторы бросают ConcurrentModificationException при изменениях во время итерации.
2️⃣ Fail-safe итераторы работают с неизменяемой структурой.
Большинство однопоточных коллекций реализуют fail-fast подход.
ConcurrentHashMap потокобезопасен, поэтому изменения во время обхода разрешены. Обход через for реализован через итератор. Указатель на следующий элемент вычисляется заранее. Более подходящий новый элемент не отображается, и выводится 2 элемента.
Метод forEach в ConcurrentHashMap использует подход траверс и вычисляет следующий элемент только когда он запрашивается. Поэтому новый ключ подхватывается и выводится 3 элемента.
❓Почему нельзя использовать траверс по умолчанию?
➡️ Потому что итератор проще и работает быстрее, а условия для пропуска элемента при обходе встречаются редко.
❓Зачем нужно несколько вариантов?
➡️ ConcurrentHashMap может перестраиваться во время обхода. Чтобы во время перестройки не выводить пользователю дубликаты, используется траверс со сложной логикой.
Итого: при выводе элементов ConcurrentHashMap через for и forEach используются разные алгоритмы обхода, поэтому результат вывода тоже разный.
❗️Cинтаксис forEach реализован и для однопоточных коллекций, но там используется итератор, поэтому разницы с for нет.
Вже доступно! Дослідження Telegram за 2025 — головні інсайти року 
