uk
Feedback
Java: fill the gaps

Java: fill the gaps

Відкрити в Telegram

Привет! Меня зовут Диана, и я занимаюсь разработкой с 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), канал підтримує актуальність та високий рівень охоплення публікацій. Аналітика показує, що аудиторія активно взаємодіє з контентом, що робить його важливою точкою впливу в категорії Технології та додатки.

12 548
Підписники
-324 години
-207 днів
-4330 день
Архів дописів
​​Java 25 лет! Java, выпущенная в 1995 году под руководством Джеймса Гослинга, используется на 3 миллиардах устройств по всей планете, от мобильного телефона и PC, до холодильника и компьютера в автомобиле. Более 10 миллионов разработчиков пишут на Java и других мощных языках, которые используют JVM: Kotlin, Scala, Groovy, Jython, JRuby, Clojure. Поздравляю всех причастных: разработчиков, тестировщиков, менеджеров, аналитиков! Java — это сила! Мы не знаем точно, что будет дальше в мире технологий, но Java явно войдет в историю. Быть причастным к этому и кодить на одном языке с массой крутых разработчиков очень приятно! С 25-летием, родная @java_developer

🥂

Домашний проект: от выбора темы до пункта в резюме. Написать работающую систему - важный шаг в обучении программированию. Закрепить теорию на практике, закрыть пробелы и попробовать новые технологии можно с помощью домашнего проекта. Давайте разберём популярные вопросы по этой теме: ❓Что писать? Необязательно придумывать стартап, который изменит мир. Но если идей совсем нет: 1️⃣ Реализуйте с нуля текущий рабочий проект. Это очень удобно: ✅ Знакомая предметная область ✅ Понятные задачи ✅ Можно обсудить с коллегами непонятные места и текущие решения 2️⃣ Если рабочий проект надоел или не нравится, напишите свою версию популярной системы: Tinder, Яндекс.Маркет, «Кто хочет стать миллионером?» и тд. Помните, Вы пишете не "очередной велосипед", а тренируетесь и изучаете лучшие практики. ✅ Понятный функционал ✅ Современные подходы и технологии ❌ Детали реализации оригинала не всегда доступны, поэтому не с чем сравнить результат ❓Как работать над проектом? Здесь Вы сами себе проджект-менеджер: ▫️Опишите функции до начала работы. Ориентируйтесь на текущие навыки и добавьте небольшой челлендж ▫️Декомпозируйте и отсортируйте задачи ▫️Составьте план ▫️Поставьте нестрогие дедлайны ▫️Двигайтесь от простого к сложному. Напишите основу на чистой java, добавьте maven/gradle, затем Spring, Spring Boot, базу данных и другие технологии ▫️Пишите тесты, это поможет найти узкие места ▫️Напишите эмулятор запросов, нагрузите приложение и изучите профайлеры ❓Нужно ли добавлять проект в резюме? Как хотите🙂 Это большой бонус, если: 🔸Вы только начинаете карьеру разработчика. 🔸Домашний проект больше соответствует вакансии, чем текущее место работы. 🔸Вы хотите показать область своих интересов. Это полезно при собеседовании в компанию с большим количеством проектов. ❓Как подготовить проект к показу? Прежде чем добавлять ссылку на проект в резюме, сделайте 2 несложных шага: 1️⃣ Добавьте файл README.md в корневую директорию. Иногда это единственное, на что посмотрит посторонний человек. Не пожалейте времени, тщательно опишите: ▪️О чём проект ▪️Основные функции ▪️Архитектуру (нарисуйте схему) ▪️Используемые технологии 2️⃣ Проработайте структуру проекта - дайте модулям и классам понятные имена. Функции, указанные в README, должно быть легко найти в коде. Эти простые действия помогут сориентироваться в проекте и лучше оценить Вашу работу.

У Вас есть домашний проект?
Anonymous voting

Брейкпойнты в Intellij IDEA: 4 полезных совета. Брейкпойнт - место в коде, в котором останавливается дебаггер. Его легко добавить и удалить - щёлкнуть справа от номера строки. 4 совета для быстрой и приятной отладки: 1️⃣ Условия остановки. Если метод часто вызывается, или брейкпойнт стоит в цикле, не тратьте время на ожидание нужных значений параметров: 🔹Правый щелчок по брейкпойнту. 🔹Добавить в Condition условие остановки — доступны все переменные и автозаполнение. 2️⃣ Вывод значений параметров. Если нужно посмотреть, как меняются переменные, не останавливая отладчик, можно вывести их в консоль через System.out.println. Продвинутый вариант: 🔸Добавить брейкпойнт, зажав Shift. 🔸Щёлкнуть галочку Evaluate and log. 🔸Вписать нужное выражение. В этом случае отладчик не будет останавливать выполнение, а запишет в консоль значение выражения. Очень полезно для отладки многопоточных приложений🔥 Дополнительный бонус: можно использовать в коде сторонних библиотек. 3️⃣ Отключение. Если брейкпойнт пока не нужен, его можно не удалять, а отключить одним из двух способов: ▪️Щёлкнуть колёсиком по брейкпойнту. ▪️Правый щёлчок по брейкпойнту, снять галочку с Enabled. 4️⃣ Массовое удаление. Когда в проекте очень много брейкпойнтов, IDE может подтормаживать при дебаге. Чтобы посмотреть полный список брейкпойнтов и удалить ненужные: ▫️Правый клик по любому брейкпойнту ▫️Ссылка More ▫️Слева видим список брейкпойнтов ▫️Удаляем ненужные В этом же окне находятся фильтры для выборочной остановки, но обычно удобнее пользоваться условиями из п.1

❓Почему так? ✅ Чтобы обеспечить однозначность и приоритет классов JDK. При такой схеме невозможно создать свой класс с именем java.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 и т.д.

Загрузчики классов в Java. Пост о том, зачем нужны загрузчики классов, и почему по умолчанию их 3. При компиляции исходный код преобразуется в файл с расширением .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 файла выглядит так:

Java 9: Сompact Strings. По данным OpenJDK не менее 25% объектов в памяти занимают строки. По той же статистике 95% строк содержат только латинские символы и цифры, числовое значение которых умещается в 1 байт, а 5-15% памяти заняты бесполезными нулями. Для хранения символов в java 8 используется тип char. Занимает 16 бит и содержит значение в кодировке UTF-16. Строка хранится как массив символов — 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% меньше памяти.

Кодировки: основы. Компактные строки - важное обновление в java 9. Чтобы лучше понять проблему и новое решение, разберём в этом посте отличия между кодировками. А в среду обсудим компактные строки. Символы хранятся в памяти в виде чисел. Кодировки отвечают за формат хранения и правила перевода символов в числа и обратно. Кодировки можно условно поделить на две группы: 1️⃣ ASCII-based 2️⃣ Unicode-based 1️⃣ ASCII В большинстве ASCII кодировок символ занимает 1 байт и содержит число от 0 до 256. Первые 128 значений транслируются одинаково во всех кодировках: 0-31: управляющие последовательности - перенос строки, конец файла и т.д. 32-127: латинский алфавит, цифры, знаки препинания. Специфичные символы языков отображаются на значения 128-255. Разные кодировки - разные наборы символов: 🔸Кириллица: ISO-8859-5, Windows-1251. 🔸Греческий алфавит: ISO-8859-7, Windows-1253. 🔸Исландские символы: OEM 861. 200 символ может стать Ш, Θ, È или чем-то ещё. Фраза «Я люблю Java” в другой кодировке отобразится как «Ď ŰîŃŰî Java». Итого: ✅ Один символ занимает 1 байт — компактно. ❌ Всего 256 значений — нет места для эмодзи. ❌ Неоднозначность трактовки. ❌ Нельзя использовать украинский и норвежский язык в одном тексте. 2️⃣ Unicode В основе преобразований лежит таблица с большинством символов, которые используются в мире. Но не со всеми, многие азиатские иероглифы записываются в памяти как комбинация 2-3 символов. Или эмоджи, например,👩‍❤️‍💋‍👩 - это сочетание 8 Unicode-кодов. Изначально Unicode использовал 2 байта для записи символа и кодировку UCS-2. После 256 символов ASCII казалось, что диапазона 0-65536 хватит навсегда. Эта кодировка использовалась в ранних версиях java для типа char. Со временем в таблицу добавилось больше символов и встал вопрос об эффективном хранении данных. Сегодня, чтобы однозначно представить символ юникода нужно 32 бита — так символы хранятся в UTF-32. ✅ Прямое отображение. ✅ Простота обработки. ❌ Неэффективный расход памяти — если использовать только латиницу с кодами типа 0..045 и 0...077, ¾ памяти будет занято нулями. На смену UCS-2 с фиксированными 2 байтами пришёл UTF-16 с переменной длиной. Если значение символа превышает 65536, то оно занимает 4 байта. Java перешла на UTF-16. Кодировка UTF-8 тоже использует переменное количество памяти. Для каждого символа задаётся, сколько он занимает места — 1, 2, 3 или 4 байта. ✅ Экономный расход памяти для латинских символов. ❌ Обработка и поиск происходят чуть медленнее. ❌ Отметка длины находится в первых 2 битах и уменьшает диапазон значений. Если в структуре 2 или больше байтов, то одни процессоры быстрее считывают их в прямом порядке, а другие — в обратном. Поэтому у UTF-16 и UTF-32 могут быть приставки LE или BE: Little/big endian. ASCII-кодировки не умеют читать символы больше 255, поэтому когда они встречают юникод-символы, то показывают ❓ и текст «я люблю Java” превращается в “? ????? Java”.

Будет напечатано:
Anonymous voting

Вопрос на закрепление: в каком порядке выведутся ключи, если задать HashMap размер 100?

HashMap в Java 8. О работе HashMap спрашивают и джуниоров, и сеньоров. Часто всё сводится к рассказу о бакетах и оценке сложности на базе статей 1998 года. С тех времён много изменилось. Этот пост о текущей структуре, особенностях и недостатках HashMap. ❓Как устроен HashMap? В основе HashMap лежит массив начальных элементов, которые называют бакетами. Их количество зависит от количества элементов — подбирается ближайшая степень двойки. Если элементов 20, то создаётся 32 бакета. Если хэш-функция ключа распределяет значения равномерно, то в каждом бакете будет 0 или 1 элемент. На практике такое происходит редко, и значения хэшей элементов иногда совпадают. Тогда элементы с одинаковым хэш кодом организуются в список. Если их становится больше 8, то элементы перестраиваются в двоичное дерево. ❓Как определяется нужный бакет? Популярное заблуждение - по остатку деления хэша на количество бакетов. Это не совсем так. Количество бакетов кратно степени двойки, и при вычислении используется логическое И. В массиве из 16 бакетов последний элемент имеет номер 15, в битовом представлении это 1111. Операция & оставит последние 4 бита числа. Сравним:
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

Что выведется в консоль?
Anonymous voting

photo content

Intellij IDEA: пишем код быстрее. 1️⃣ Live templates. Аббревиатуры для популярных синтаксических конструкций. Вводите и нажимаете Enter: 4 символа разворачиваются в 40, а курсор приходит в нужную позицию. Полный список сокращений в File/Settings/Editor/Live Templates. Есть для Java, Kotlin, JS, Groovy, для разработки под Android и React. Самые популярные для Java: ▫️St → 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.

Обход коллекций в Java. Чтобы ответить на вопросы выше, посмотрим на обход более сложных сущностей, например, графа. Граф - структура данных из вершин и рёбер. В графах часто встречаются циклические пути. Найти гамильтонов путь, то есть обойти вершины графа по одному разу - непростая задача. Алгоритм ведёт учёт посещённых вершин и перебирает разные варианты прежде, чем утвердить один из них. В computer science обход структуры данных называется traverse. Основная идея — выводим текущий элемент, следующий пока неизвестен и считается отдельно. Вернёмся в мир java. Здесь нет зацикленных графов, все просто — списки, множества, очереди, деревья. При обходе следующий элемент всегда однозначен, а его отсутствие означает конец работы. Поэтому обход выглядит так:
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 нет.

А сколько элементов выведется, если заменить for на forEach?
Anonymous voting

Вопрос #2

Сколько элементов выведется в консоль?
Anonymous voting

Вопрос #1