Java: fill the gaps
Привет! Меня зовут Диана, и я занимаюсь разработкой с 2013. Здесь пишу просто и понятно про джава бэк 🔥Тот самый курс по многопочке🔥 https://fillthegaps.ru/mt Комплименты, вопросы, предложения: @utki_letyat
Ko'proq ko'rsatish📈 Telegram kanali Java: fill the gaps analitikasi
Java: fill the gaps (@java_fillthegaps) Rus til segmentidagi kanali faol ishtirokchi. Hozirda hamjamiyat 12 549 obunachidan iborat bo'lib, Texnologiyalar & Aralashmalar toifasida 10 120-o'rinni va Rossiya mintaqasida 52 841-o'rinni egallagan.
📊 Auditoriya ko‘rsatkichlari va dinamika
невідомо sanasidan buyon loyiha tez o‘sib, 12 549 obunachiga ega bo‘ldi.
07 Iyun, 2026 dagi oxirgi ma’lumotlarga ko‘ra kanal barqaror faollikka ega. Oxirgi 30 kunda obunachilar soni -46 ga, so‘nggi 24 soatda esa 0 ga o‘zgardi va umumiy qamrov yuqori darajada qolmoqda.
- Tasdiqlash holati: Tasdiqlanmagan
- Jalb etish (ER): Auditoriya o‘rtacha 34.72% darajada jalb etiladi. Nashrdan keyingi dastlabki 24 soatda kontent odatda umumiy obunachilar sonining N/A% ini tashkil etuvchi reaksiyalarni to‘playdi.
- Post qamrovi: Har bir post o‘rtacha 0 marta ko‘riladi; birinchi sutkada odatda 0 ta ko‘rish yig‘iladi.
- Reaksiyalar va o‘zaro ta’sir: Auditoriya faol: har bir postga o‘rtacha 0 ta reaksiya keladi.
- Tematik yo‘nalishlar: Kontent redis, hashmap, linkedhashmap, индекс, фича kabi asosiy mavzularga jamlangan.
📝 Tavsif va kontent siyosati
Muallif resursni shaxsiy fikrni ifoda etish maydoni sifatida ta’riflaydi:
“Привет! Меня зовут Диана, и я занимаюсь разработкой с 2013. Здесь пишу просто и понятно про джава бэк
🔥Тот самый курс по многопочке🔥
https://fillthegaps.ru/mt
Комплименты, вопросы, предложения: @utki_letyat”
Yuqori yangilanish chastotasi (oxirgi ma’lumot 08 Iyun, 2026 da olingan) sababli kanal doimo dolzarb va katta qamrovli bo‘lib qoladi. Analitika auditoriya kontent bilan faol hamkorlik qilishini, uni Texnologiyalar & Aralashmalar toifasidagi muhim ta’sir nuqtasiga aylantirishini ko‘rsatadi.
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. Методы должны быть удобными, понятными и не заставлять разработчиков запоминать особые случаи.
Endi mavjud! Telegram Tadqiqoti 2025 — yilning asosiy insaytlari 
