Java: fill the gaps
Привет! Меня зовут Диана, и я занимаюсь разработкой с 2013. Здесь пишу просто и понятно про джава бэк 🔥Тот самый курс по многопочке🔥 https://fillthegaps.ru/mt Комплименты, вопросы, предложения: @utki_letyat
显示更多📈 Telegram 频道 Java: fill the gaps 的分析概览
频道 Java: fill the gaps (@java_fillthegaps) 俄语 语言赛道中的 是活跃参与者。目前社区聚集了 12 549 名订阅者,在 技术与应用 类别中位列第 10 120,并在 俄罗斯 地区排名第 52 841 位。
📊 受众指标与增长动态
自 невідомо 创建以来,项目保持高速增长,吸引了 12 549 名订阅者。
根据 07 六月, 2026 的最新数据,频道保持稳定运转。过去 30 天订阅人数变化为 -46,过去 24 小时变化为 0,整体触达仍然可观。
- 认证状态: 未认证
- 互动率 (ER): 平均受众互动率为 34.72%。内容发布后 24 小时内通常能获得 N/A% 的反应,占订阅者总量。
- 帖子覆盖: 每篇帖子平均可获得 0 次浏览,首日通常累积 0 次浏览。
- 互动与反馈: 受众积极参与,单帖平均反应数为 0。
- 主题关注点: 内容集中在 redis, hashmap, linkedhashmap, индекс, фича 等核心主题上。
📝 描述与内容策略
作者将该频道定位为表达主观观点的平台:
“Привет! Меня зовут Диана, и я занимаюсь разработкой с 2013. Здесь пишу просто и понятно про джава бэк
🔥Тот самый курс по многопочке🔥
https://fillthegaps.ru/mt
Комплименты, вопросы, предложения: @utki_letyat”
凭借高频更新(最新数据采集于 08 六月, 2026),频道始终保持新鲜度与高覆盖。分析显示受众积极互动,使其成为 技术与应用 类别中的关键影响点。
public void do() {
File f=new File("t.txt");
// Создаём объект File, ресурс "t.txt" теперь наш
// что-то делаем
}
// вышли из метода: объект f уже не нужен, ресурс "t.txt" освобождается
RAII легко реализовать в С++. В конструкторе пишем логику "открытия" ресурса, а в деструкторе - "закрытия". Конструктор и деструктор явно прописываются, поэтому ЖЦ объекта и ресурса под контролем.
В java так не получится. Деструктор выполнится неизвестно когда, а ресурс - штука ценная. Поэтому в java нужно явно вызвать метод закрытия. В стандартных библиотеках это close().
В java 7 появилась специальная конструкция для ресурсов:
try (PrintWriter writer = new PrintWriter(…)) {
// что-то делаем
}
Ресурс реализует интерфейс AutoCloseable, и после завершения блока для него вызовется close(). try-with-resources считается java реализацией RAII.
Но такой формат не идеален. Внутри try всегда определяется новый объект. Когда ресурсов два и больше, код становится громоздким:
try (DatagramChannel udpServer = …;
Selector selector = …) {
// …
}
В java 9 в блок try можно передать переменные:
DatagramChannel udpServer = …;
Selector selector = …;
try (udpServer;selector) {
// …
}
С одной стороны это удобно. Код выглядит приятно.
С другой - после try остаются переменные с закрытыми ресурсами. Теперь нельзя сказать, что java реализует RAII.
Ну и ладно, никто не расстроился🙂 Языки разные, и классно замечать, как по-разному в них реализуются идеи, и как они меняются с течением времени.git stash save "stash name"В IDEA: VCS → Git → Stash Changes... Вернуть изменения на место: 🔸git stash apply "stash name" и оставить stash в локальном репозитории 🔸git stash pop "stash name" и удалить стэш В IDEA: VCS → Git → Unstash Changes... Что важно: ✅ Сохраняются ВСЕ текущие изменения в ветке ✅ Обратно применяются ВСЕ изменения в стэше ✅ Изменения хранятся в локальном git репозитории Shelve Удобная фича IDEA для сохранения части изменений: VCS → Shelve Changes... Галочками отмечаем, что сохранить. Чтобы вернуть обратно: Вкладка Git (Alt + 9 или найдите внизу) → Shelve. Отмечайте, какие изменения применить к коду. ✅ Можно выбрать, что сохранять ✅ Можно указать, что восстановить ✅ Изменения хранятся в локальном IDEA проекте
public final class State extends Enum {
public static final State NEW;
public static final State VALIDATED;
// init блок
State() {...}
// static блок
}
Возникла проблема. Перед вызовом конструктора надо закончить со статическими полями. А статические поля - экземпляры этого же класса. Замкнутый круг.
В такой ситуации JVM создаёт экземпляры NEW и VALIDATED перед статическими блоками. Получается такой порядок:
1️⃣ Создаём экземпляр State NEW:
▫️блок инициализации S-Init
▫️конструктор S-Constr
2️⃣ Повторяем тот же процесс для VALIDATED
3️⃣ Выполняем статический блок S-Static
Поэтому правильный ответ - G:
▫️enum NEW(Init-Constr)
▫️enum VALIDATED(Init-Constr)
▫️enum-Static
▫️объект User (Init-Constr)if (state == UserState.NEW) {…}
2️⃣ Паттерн Singleton
Вообще синглтон - антипаттерн и антитренд. Если без него никак - рассмотрите вариант с enum. Если вы склонны к риску, можно сделать изменяемые поля.
✅ Может быть несколько объектов в рамках одного enum
✅ Доступ из любого места в коде
✅ Ленивая инициализация
3️⃣ Паттерн State
Более продвинутый вариант, чем "набор констант". Здесь фокус на данных: используются связанные значения, а не элемент enum сам по себе.
Пример: в статус пользователя вносим дополнительные поля - необходимость подтверждения личности и максимальный размер скидки:
enum UserState {
NEW(true, 10),
VALIDATED(false, 25),
FRAUD(true, 0);
boolean needConfirmation;
int maxDiscount;
}
4️⃣ Паттерн Strategy
Здесь фокус на разнице в поведении. Абстрактный метод переопределяется для каждого экземпляра:
NEW { boolean check(Order){…}},
VALIDATED { boolean check(Order){…}};
abstract boolean check(Order order)
✅ Подойдёт для алгоритмов, конвертеров, сортировок
✅ Простая иерархия, всё в одном классе
✅ Список всех значений доступен через values()
😐 Весь код в одном файле. Не всегда удобно
❌ Сложно связать с другими объектами
❌ Нарушается принцип open for extension but closed for modification
Получается специфическая альтернатива полиморфизму, но иногда ок.
Enum - не просто набор констант. Инструмент своеобразный, но полезно знать и такие реализации паттернов. Чем шире арсенал разработчика, тем выше шанс найти подходящее решение.public final class Planet extends Enum {
public static final Planet EARTH;
public static final Planet MARS;
}
Полноценные классы c конструкторами, методами, полями и статическими элементами. У экземпляров есть состояние и определённое поведение.
Но есть нюансы:
🔸 Суперкласс Enum
От суперкласса Enum наследуются методы name(), ordinal() и статический метод values().
name() возвращает имя переменной, ordinal() - порядковый номер в списке. На практике эти методы достаточно бесполезны.
Метод values() используется чаще и возвращает массив всех объектов. Можно пройтись по нему в цикле:
for (Planet p : Planet.values()) {…}
или через Stream API:
Arrays.stream(Planet.values()).forEach(…)🔸 Интерфейсы суперкласса Enum реализует три интерфейса: Comparable, Serializable, Constable. Первые два всем знакомы. Интерфейс Constable определяет методы для размещения объектов в пуле констант внутри JVM. 🔸 Создание экземпляров Этим занимается JVM на старте приложения. Экземпляры енума создаются через приватный конструктор, недоступный вне енума. 🔸 Поля Указываются для каждого экземпляра, инициализируются в конcтрукторе:
public enum Planet {
MARS(3389),
EARTH(6371);
int radius;
Planet(int radius) {
this.radius = radius;
}
}
🔸 Два типа методов
▫️Обычные
public int getRadius()
Используется для геттеров и простых вычислений.
В теории можно сделать set* метод и поменять поле у любого экземпляра. Но на практике так никто не делает. Когда объект доступен из любого места системы, то проще жить, если он неизменяемый.
▫️Абстрактные
Каждый экземпляр определяет свою реализацию:
public enum Planet {
MARS {
int distanceFrom(int) {…}
},
EARTH {
int distanceFrom(int) {…}
};
abstract int distanceFrom(int);
}
🔸 Наследование
Любой enum - это final класс с уже определённым суперклассом. Единственный шанс встроить enum в иерархию - добавить для него интерфейс.
Иногда это удобно. Если у енумов и классов один интерфейс, то с ними можно работать через один метод:
interface SpaceObject
enum Planet implements SpaceObject
class Meteor implements SpaceObject
public void getInfo(SpaceObject so)-XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:+UseJVMCICompiler map.compute(key,(key,value)->value+1)
Покрыта ветка В. Если элемента с ключом key нет, то в качестве value будет null. Велика вероятность NullPonterException
🔹 map.computeIfPresent(key,(key,value)->value+1)
Покрыта ветка Б. Нет элемента - ничего не делаем
🔹 map.merge(key,defaultValue,(oldValue,newValue) -> oldValue+1);
Покрывает ветки А и В:
▫️ Если элемента нет, добавляем (key, default)
▫️ Если элемент есть, обновляем по правилу
Итого, как сценарные ветки покрыты методами:
Ветка А: merge
Ветка Б: computeIfPresent
Ветка В: merge, compute
Все сценарии покрываются двумя методами - computeIfPresent и merge.
Метод compute в этом случае избыточен. Избыточность - ок, если метод добавляет удобства и не увеличивает вероятность ошибок. В случае compute это не так, так как появляется вероятность получения NPE.
На этом небольшом примере видно, как проверить дизайн нового API. Методы должны быть удобными, понятными и не заставлять разработчиков запоминать особые случаи.
现已上线!2025 年 Telegram 研究 — 年度关键洞察 
