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),频道始终保持新鲜度与高覆盖。分析显示受众积极互动,使其成为 技术与应用 类别中的关键影响点。
interface Интерфейс {
public void метод();
}
Классы реализуют эти методы под угрозой ошибки компиляции:
class M implements Интерфейс {
public void метод() {…};
}
Java 8
Появились 2 новых возможности:
1️⃣ Метод по умолчанию с заданной реализацией:
default void метод() {…};
Конкретный класс переопределяет его при необходимости.
❓Зачем они нужны?
Дефолтные методы уместны в трёх случаях, об этом будет статья в среду.
2️⃣ Статические методы с реализацией:
static void метод() {…};
Статические методы не наследуются и не переопределяются. Вызвать такой метод можно только через имя интерфейса:
Интерфейс.метод()❓Зачем они нужны? В интерфейсе определяется необходимый минимум методов. Например, в Collection это методы add(), remove() и другие. Чем меньше методов, тем больше свободы действий у конкретных классов. Эти базовые методы комбинируются между собой в другие полезные методы: ▪️Поиск элемента, ▪️Поиск минимального элемента, ▪️Скопировать коллекцию, Каждый из этих методов - всего лишь комбинация базовых, которая не зависит от конкретного класса. Чтобы не копировать код в каждый класс, сделайте такой метод статическим методом в интерфейсе:
static E min() {…};
До java 8 статические методы объединяли в утилитный класс с похожим именем. Например, методы binarySearch, copy, min реализованы в классе Collections.
Java 9
Можно добавить private и private static методы с реализацией:
private void m() {…};
private static void m() {…};
Эти методы недоступны для классов, реализующих интерфейс.
❓Зачем они нужны?
Чтобы выделить под-методы в дефолтных и статических методах, таким образом улучшить читаемость и избежать дублирования кода.
С методами разобрались, а какие поля можно добавлять в интерфейс?
Только константы с модификаторами public static. Из-за того, что других вариантов нет, в Intellij IDEA модификаторы public и static подсвечиваются как избыточные и вместо
public static int NUM = 1;допустима запись:
int NUM = 1;Такие поля компилируются в статические! Правильный ответ на вопрос: Ошибку компиляции в последней версии java вызовут варианты:
default int get(); private int get(); public static int get();У приватных, статических и дефолт методов в интерфейсах должна быть реализация.
String.join("-","1","2");
// 1-2
Можно использовать со списком строк:
List<String> list = ...;
String.join("-", list);
🔸Убрать пробелы и служебные символы
▪️с начала строки:
str.stripLeading();
▪️в конце строки:
str.stripTrailing();
▪️с обеих сторон:
str.strip();
В классе уже присутствует метод trim(), который тоже стирает неподходящие символы. strip() корректнее определяет недопустимые символы, в том числе экзотические виды пробелов ('\u00A0', '\u2007', '\u202F').
🔸Проверить, что строка пуста:
str.isBlank()На замену StringUtils.isBlank() из библиотеки Apache Commons. 🔸Создать стрим из строки. Можно разделить текст ▪️по линиям:
str.lines()
▪️по символам: str.chars()
🔸Продублировать строку:
"<td>".repeat(3);
// <td><td><td>String str;Ассоциированный объект имеет тот же тип или производный. Т.к типы известны заранее, проверка аргументов происходит во время компиляции. ✅ Отлавливается много ошибок. ✅ Быстро работает в рантайме. ✅ Предсказуемое поведение. ✅ Легко тестировать. При динамической типизации указатель не имеет типа. Во время работы программы в переменную можно записать любые значения:
value = "а" value = 4Аргументы проверяются во время вызова метода. Такие программы в разы короче и легко адаптируются к изменениям. Java является языком со статической типизацией. Второй вопрос, на который отвечает система типов: что делать, если метод принимает тип А, но приходит объект типа Б? Можно: ▪️Бросить ошибку. ▪️Преобразовать Б в тип А. У языка сильная типизация, если допустимо мало преобразований. Если много, то типизация слабая. Речь идёт о неявных преобразованиях, которые делает компилятор или исполняющая среда. Пример:
5L + 1
Язык Ruby не разрешает складывать числа разных типов, а java приведёт единицу к типу long и выполнит сложение. Выражение
5 + trueв java вызовет ошибку компиляции. JavaScript спокойно переведёт true в единицу. Компилятор java может перевести: - подкласс в суперкласс - long в int и наоборот - int в Integer и наоборот и так далее. Некоторые правила работают в одних условиях, некоторые в других. В целом java считается языком с сильной типизацией. Вернёмся к вопросу перед постом. Метод
id ожидает аргумент типа Long, а передаётся примитивный int. В правилах преобразований нет перехода int → Long, поэтому будет ошибка компиляции. Достичь цели можно в 2 шага:
int → long
long → Long
Компилятор может выполнить только один шаг, второе преобразование делает программист. Поэтому подходящий ответ:
(long) intValuefilter(...).findFirst().isPresent()
а можно короче, понятнее и быстрее:
noneMatch(...)
Иногда стримы даже не нужны, много полезных методов есть в интерфейсе Collections. Например, максимальный элемент в списке быстрее найти через Collections.max(...), чем с использованием стрима.
Больше примеров
4️⃣ Объединить однотипные операции.
Чаще это касается сложной фильтрации:
filter(1).filter(2).filter(3)
можно ускорить в 2-4 раза, если объединить условия:
filter(1 & 2 & 3)try-catch-finally в спецификации описывается через 24 предложения "если". Логика запутанная, и легко допустить ошибку.
Чтобы решать такие задачки, воспользуйтесь следующей моделью:
Результатом блока try-catch-finally могут быть 3 варианта:
🔸Ничего
🔸Возврат значения
🔸Исключение
Представим, что результат записывается в переменную result. В начале работы там "ничего".
Блоки обрабатываются в строгом порядке:
1️⃣ try
2️⃣ catch
3️⃣ finally
На каждом шаге переменная result может быть перезаписана. Итоговое значение result и будет результатом выполнения. Особый случай — при вызове System.exit(0) выполнение прекращается сразу же .
Разберём пример из опроса:
▫️try установит результат на "вернуть try".
▫️Блока catch нет.
▫️В finally результат меняется на "вернуть finally".
Итог: вернётся "finally"
Другой пример:
try { throw new NPE(); }
catch (SecurityEx e)
{ return "ex"; }
finally {}
▫️В блоке try результатом станет "NPE".
▫️Блок catch пропускается, т.к нет подходящего типа исключения.
▫️В блоке finally результат не переопределяется.
Итог: выброс NPE.
Этот пример важен, потому что такие ошибки часто встречаются на практике. Блок finally - не оберег от исключений. Если результат "исключение" дальше не переопределён, он пробрасывается в вышестоящий метод.String info(Request req) {
return req.toString(); }
Для нормальной работы параметр req не должен быть пустым. Мы можем:
1️⃣ Оставить как есть: тогда JVM выбросит NullPointerException(NPE)
2️⃣ Добавить проверку и самим бросить исключение:
if (req==null) throw new NPE();3️⃣ Добавить проверку и вернуть null:
if (req==null) return null;4️⃣ Добавить проверку и вернуть Optional.empty():
if (req==null) return Optional.empty();Оценим их с точки зрения производительности и дизайна. Начнём с производительности. Запустим каждый вариант миллион раз: ▪️14 мс - JVM исключение ▪️2 мс - явный выброс исключения ▪️0,03 мс - null ▪️0,03 мс - Optional.empty() Что это значит? 1️⃣ Создание исключения гораздо дольше, чем выход из метода. Время уходит на создание стек-трейса - чем он глубже, тем хуже производительность. Стек-трейс из сервиса на Spring Boot собирается в 50-100 раз дольше, чем стек-трейс из метода main. 2️⃣ Если исключение явно создаётся в коде, JVM переиспользует ранее собранный стэк-трейс. Так получается выигрыш в 5-10 раз, но разница с вариантом без исключения всё ещё внушительна. По этим цифрам легко решить, что исключения - удар по производительности. 10 лет назад была тенденция избегать исключений любой ценой. Например, возвращать из метода пару (результат, код_ошибки). В 2020 это уже не актуально. Если взаимодействие в системе не построено на исключениях, то это капля в море относительно других операций. В примере сверху исключение создаётся миллион раз подряд - такого в продакшене обычно нет. Исключения делают код чище: 🔹Понятное возвращаемое значение 🔹В части throws явно обозначены непредвиденные ситуации 🔹Логика метода и обработка ошибок разделены Теперь сравним создание исключения и возврат null с точки зрения дизайна. Исключение подразумевает обработку ошибки, например: 🔸Показать пользователю сообщение. 🔸Прекратить работу с файлом. 🔸Поменять формат данных. Optional.empty(), null или объект по умолчанию возвращается, когда реагировать на ситуацию необязательно. Например, когда данные быстро устаревают. Возвращаемый тип Optional удобнее использовать: не нужно смотреть в документации, возвращает ли функция пустой результат, и как он обозначается: null, -1 или 0.
static, private, final. Метод определяется по типу ссылки во время компиляции, и его нельзя переопределить. Благодаря раннему связыванию JVM не тратит ресурсы во время работы программы, поэтому скорость вызова этих методов чуть выше.
Позднее связывание работает для остальных public и protected методов. JVM в рантайме определяет тип объекта и метод, который нужно вызвать. Этот механизм лежит в основе полиморфизма, наследования и инкапсуляции.
Статические методы в классах Parent и Child не переопределяют друг друга и относятся к разным классам. Над методом в классе Child нельзя даже поставить @Override и вызвать внутри super.getName();
Поэтому правильный ответ в опросе выше — "Parent", потому что метод определён во время компиляции по типу указателя.
Если посмотреть на вызов метода у объекта, то непонятно, статический он или обычный, учитывается тип экземпляра или нет. Это приводит к ошибкам и считается плохой практикой. Настолько плохой, что для объекта Intellij IDEA даже не показывает статические методы в выпадающем списке. Хороший вариант — вызывать статические методы, обращаясь к классу:
println(Parent.getName());На собеседованиях встречается модификация этого вопроса — один метод
getName() статический, а другой — нет. В этом случае будет ошибка компиляции, потому что непонятно, какой механизм связывания использовать.
现已上线!2025 年 Telegram 研究 — 年度关键洞察 
