Java Geek
الذهاب إلى القناة على Telegram
Практичные советы, лайфхаки и код для Java-разработчиков. Каждый пост — реальная польза. Учим Java на примерах. По всем вопросам @evgenycarter
إظهار المزيد2 449
المشتركون
لا توجد بيانات24 ساعات
+27 أيام
+530 أيام
أرشيف المشاركات
2 449
🔴 Завтра тестовое собеседование с Java-разработчиком
21 января(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.
Как это будет:
📂 Сергей Чамкин, старший разработчик из Uzum, ex-WildBerries, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Cергей будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Сергею
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot
Реклама.
О рекламодателе.
2 449
☕️ Java Tips: Инициализация карты в одну строку с
Map.of()
Помните, как раньше приходилось создавать Map с заранее известными значениями? Куча вызовов .put(), статические блоки или (не дай бог) двойные фигурные скобки. Начиная с Java 9, у нас есть красивый и лаконичный способ - Map.of().
Разберем, как это работает и, главное, чего нельзя делать.
🆚 До и После
Как было раньше (The Old Way):
Map<String, Integer> map = new HashMap<>();
map.put("One", 1);
map.put("Two", 2);
map.put("Three", 3);
// Результат: много строк кода ради простых данных
Как сейчас (The Modern Way):
Map<String, Integer> map = Map.of(
"One", 1,
"Two", 2,
"Three", 3
);
// Результат: чисто, читаемо, одна инструкция
⚠️ Важные нюансы (Gotchas)
Использование Map.of() - это не просто синтаксический сахар для HashMap. Это создание неизменяемой (Immutable) структуры.
1. Нельзя менять данные
Попытка добавить или удалить элемент приведет к ошибке.
var colors = Map.of("Red", "#FF0000");
colors.put("Blue", "#0000FF");
// ❌ Ошибка: UnsupportedOperationException
2. Никаких null
В отличие от HashMap, здесь нельзя использовать null ни в ключах, ни в значениях.
Map.of("Key", null);
// ❌ Ошибка: NullPointerException
3. Лимит в 10 пар
Метод Map.of() перегружен для приема до 10 пар ключ-значение. Если нужно больше, используйте Map.ofEntries():
Map.ofEntries(
Map.entry("k1", "v1"),
Map.entry("k2", "v2"),
// ... хоть 100 пар
Map.entry("k100", "v100")
);
🚀 Когда использовать?
Идеально подходит для конфигураций, статических словарей, тестовых данных и справочников, которые не меняются во время работы программы.
#Java #CodeTips #Programming #Java9
👉 @java_geek2 449
📌 Декоратор в Java: Как добавить логику без изменения кода?
🔹 Когда использовать?
- Когда нужно добавить поведение к объекту динамически.
- Когда нельзя или не хочется менять исходный код класса.
- Когда необходимо сохранить принцип открытости/закрытости (OCP из SOLID).
🔹 Как это работает?
Декоратор — это обёртка вокруг базового объекта. Он реализует тот же интерфейс, но внутри может добавлять новую логику.
✅ Пример использования
Допустим, у нас есть базовый интерфейс
Notifier, который отправляет уведомления:
public interface Notifier {
void send(String message);
}
И его простая реализация:
public class BasicNotifier implements Notifier {
@Override
public void send(String message) {
System.out.println("Отправка сообщения: " + message);
}
}
Теперь добавим декораторы, которые расширяют функциональность:
1️⃣ Декоратор для отправки в Slack:
public class SlackNotifierDecorator implements Notifier {
private final Notifier wrapped;
public SlackNotifierDecorator(Notifier wrapped) {
this.wrapped = wrapped;
}
@Override
public void send(String message) {
wrapped.send(message); // вызываем базовый метод
System.out.println("Дополнительно отправляем в Slack: " + message);
}
}
2️⃣ Декоратор для отправки в Email:
public class EmailNotifierDecorator implements Notifier {
private final Notifier wrapped;
public EmailNotifierDecorator(Notifier wrapped) {
this.wrapped = wrapped;
}
@Override
public void send(String message) {
wrapped.send(message);
System.out.println("Дополнительно отправляем Email: " + message);
}
}
🚀 Использование:
public class Main {
public static void main(String[] args) {
Notifier notifier = new BasicNotifier();
notifier = new SlackNotifierDecorator(notifier);
notifier = new EmailNotifierDecorator(notifier);
notifier.send("Привет, мир!");
}
}
🔥 Что произойдет?
Отправка сообщения: Привет, мир!
Дополнительно отправляем в Slack: Привет, мир!
Дополнительно отправляем Email: Привет, мир!
🎯 Итог:
✅ Мы не изменяли код BasicNotifier, но добавили новую функциональность.
✅ Гибкость: можем легко комбинировать декораторы в любом порядке.
✅ Код остаётся чистым и расширяемым.
👉 @java_geek2 449
🔴 Завтра тестовое собеседование с Java-разработчиком
24 декабря(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.
Как это будет:
📂 Сергей Чамкин, старший разработчик из Uzum, ex-WildBerries, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Cергей будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Сергею
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot
Реклама.
О рекламодателе.
2 449
☕️ Лямбды и Функциональные интерфейсы: Как это работает под капотом?
Мы все любим лямбды в Java за краткость. Но задумывались ли вы, как строго типизированная Java понимает запись
x -> x * 2, не зная типа переменной x?
Все дело в Функциональных интерфейсах. Давайте разберем механику, которая превращает "бойлерплейт" в элегантный код.
🧩 Что такое SAM?
В основе лежит концепция SAM (Single Abstract Method). Функциональный интерфейс - это интерфейс, у которого есть ровно один абстрактный метод.
Лямбда-выражение - это не самостоятельный объект. Это ленивая реализация этого самого единственного метода "на лету".
🔥 До vs После
Взгляните, как функциональный интерфейс Predicate<T> убивает лишний шум:
// ❌ До Java 8 (Анонимный класс)
// Куча лишнего кода ради одной проверки
Predicate<String> isLong = new Predicate<String>() {
@Override
public boolean test(String s) {
return s.length() > 5;
}
};
// ✅ С Лямбдой
// Компилятор видит Predicate -> ищет метод test -> подставляет логику
Predicate<String> isLong = s -> s.length() > 5;
⚙️ Магия invokedynamic
Многие думают, что лямбда - это просто "сахар" для анонимных классов. Это не так!
💜 Анонимный класс создает реальный .class файл на диске при компиляции.
💜 Лямбда использует инструкцию байт-кода invokedynamic. Она связывает метод динамически только когда это нужно.
👉 Итог: Меньше мусора в памяти и быстрее загрузка приложения.
📚 Шпаргалка: "Великолепная четверка"
В java.util.function есть интерфейсы на все случаи жизни. Запомните базу:
1. Predicate<T> ➜ boolean
💜 Суть: Проверка условия (фильтры).
💜 Пример: stream().filter(x -> x > 0)
2. Consumer<T> ➜ void
💜 Суть: Потребитель. Что-то делает с объектом, ничего не возвращая.
💜 Пример: list.forEach(System.out::println)
3. Function<T, R> ➜ R
💜 Суть: Преобразователь. Берет T, возвращает R.
💜 Пример: stream().map(User::getName)
4. Supplier<T> ➜ T
💜 Суть: Поставщик. Ничего не принимает, отдает объект.
💜 Пример: Optional.orElseGet(() -> new User())
💡Всегда ставьте аннотацию @FunctionalInterface над своими интерфейсами. Это защитит от случайного добавления второго абстрактного метода, который сломает все лямбды в проекте.
👉 @java_geek2 449
🔍 Завтра тестовое собеседование с Java-разработчиком
17 декабря(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.
Как это будет:
📂 Сергей Чамкин, старший разработчик из Uzum, ex-WildBerries, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Cергей будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Сергею
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot
Реклама.
О рекламодателе.
2 449
🚀 Hibernate: Эффективное обновление с
@DynamicUpdate
Часто ли вы задумывались, почему Hibernate при обновлении одного поля в сущности генерирует SQL-запрос, который включает все поля? Это может быть неэффективно, особенно для сущностей с десятками колонок.
Именно здесь на помощь приходит аннотация @DynamicUpdate!
💡 В чем проблема? (Без @DynamicUpdate)
По умолчанию, когда вы вызываете repository.save(entity) для существующей сущности, Hibernate генерирует UPDATE запрос, который устанавливает значения для всех полей, кроме первичного ключа.
// Without @DynamicUpdate
update employee
set
age=?, // даже если только age изменился
first_name=?, //... и это тоже
last_name=?
where
id=?
Если изменилось только age, остальные поля обновляются на те же значения, что были.
✨ Решение: @DynamicUpdate(true)
Если вы добавите @DynamicUpdate к вашей сущности, Hibernate будет генерировать SQL-запрос UPDATE, который включает только те поля, которые были изменены (dirty-checking) с момента загрузки или создания сущности.
Смотрим на код:
@Entity
@DynamicUpdate // ✨ Добавляем эту аннотацию!
public class Employee extends AbstractPersistable<Long> {
@Column
String firstName;
@Column
String lastName;
@Column
Integer age;
// ...
}
// В EmployeeService:
// var entity = employeeRepository.findById(1L).get();
// entity.setAge(22); // Изменили только возраст
// employeeRepository.save(entity);
Сгенерированный SQL:
// With @DynamicUpdate
update employee
set
age=? // ✅ Обновляется ТОЛЬКО измененное поле
where
id=?
⚖️ Когда использовать?
- Используйте, если у вас большие сущности (много колонок) и вы часто обновляете только небольшую часть полей. Это сэкономит трафик и немного ускорит базу данных.
- Имейте в виду, что Hibernate придется динамически строить SQL-запрос при каждом обновлении, что может добавить небольшой оверхед, но обычно выгода от оптимизации SQL его перевешивает.
Сделайте ваш код более чистым и эффективным! 🛠️
❓ А вы используете @DynamicUpdate в своих проектах? Поделитесь в комментариях! 👇
P.S. Не путайте с @DynamicInsert, который делает то же самое для INSERT запросов (включает только не-null поля).
👉 @java_geek2 449
Что такое пул строк? Это набор строк, хранящийся в Heap.
☕ Пул строк возможен благодаря неизменяемости строк в Java и реализации идеи интернирования строк;
☕ Пул строк помогает экономить память, но по этой же причине создание строки занимает больше времени;
☕ Когда для создания строки используются ", то сначала ищется строка в пуле с таким же значением, если находится, то просто возвращается ссылка, иначе создается новая строка в пуле, а затем возвращается ссылка на неё;
☕ При использовании оператора new создаётся новый объект String. Затем при помощи метода intern() эту строку можно поместить в пул или же получить из пула ссылку на другой объект String с таким же значением;
☕ Пул строк является примером паттерна «Приспособленец» (Flyweight).
👉 @java_geek
2 449
🔍Тестовое собеседование с ТехЛидом из МТС уже завтра
3 декабря(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.
Как это будет:
📂 Илья Аров, старший разработчик в МТС, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Илья будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Илье
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot
Реклама.
О рекламодателе.
2 449
Что не так с кодом?
Он не скомпилируется. Это вопрос на знание иерархии исключений: FileNotFoundException унаследован от IOException, первый catch будет перехватывать все исключения, а в следующий блок catch управление передано не будет. Поэтому возникнет ошибка: exception FileNotFoundException has already been caught.
👉 @java_geek
2 449
О чем говорит ключевое слово throws?
Ответ:
Модификатор throws прописывается в заголовке метода и указывает на то, что метод потенциально может выбросить исключение с указанным типом.
👉 @java_geek
2 449
Блиц-опрос Scala-разработчиков — самые полезные и бесполезные вещи в работе
Смотрите подкаст «Криптонит говорит» о Scala! В нём айтишники обсуждают:
🔹Scala, Java и их перспективы;
🔹как успешно пройти собеседование в айти;
🔹что нужно делать, чтобы стать хорошим программистом;
🔹и когда нейросети смогут делать code review на уровне старшего разработчика и многое другое.
📺 VK Видео
📺 YouTube
📺 Rutube
💬 Подкаст в телеграме
🎵 Яндекс.Музыка
Смотрите и подписывайтесь на подкаст «Криптонит говорит» — обсуждаем айти, искусственный интеллект, языки программирования и криптографию.
Реклама АО НПК «Криптонит» ИНН 9701115253, erid: 2VtzqveAsgd
2 449
Что такое «сессия»?
Сессия — это сеанс связи между клиентом и сервером, устанавливаемый на определенное время. Сеанс устанавливается непосредственно между клиентом и веб-сервером в момент получения первого запроса к веб-приложению. Каждый клиент устанавливает с сервером свой собственный сеанс, который сохраняется до окончания работы с приложением.
👉 @java_geek
2 449
«Мы поняли, что мы как Тринити и Морфеус. Нам нужен был Нео». Как ночной портье за 3 месяца разобрался в инжиниринге данных
Смотрите подкаст «Криптонит говорит» о дата-инженерах! В нём эксперты оюсуждают:
🔹достигла ли пика профессия дата-инженера;
🔹какой стек нужно знать дата-инженерам;
🔹какие намечаются тренды отрасли.
📺 YouTube
📺 Rutube
💙 VK видео
💬 Подкаст в телеграме
🎵 Яндекс.Музыка
Смотрите и подписывайтесь на подкаст «Криптонит говорит» — обсуждаем айти, искусственный интеллект, языки программирования и криптографию.
Реклама. ООО «Агентство интернет-маркетинга "Ви 8"», ОГРН 1102468051333, erid: 2VtzqveAsgd
2 449
Что такое Local Variable?
Популярный вопрос на собеседовании Java-разработчика. Local variable — это переменная, которая определена внутри метода и существует вплоть до того момента, пока выполняется этот метод. Как только выполнение закончится, локальная переменная перестанет существовать.
Вот программа, которая использует локальную переменную helloMessage в методе main().
👉 @java_geek
2 449
Зачем нужен HashMap, если есть Hashtable?
☕ Методы класса Hashtable синхронизированы, что приводит к снижению производительности, а HashMap - нет;
☕ HashTable не может содержать элементы null, тогда как HashMap может содержать один ключ null и любое количество значений null;
☕ Iterator у HashMap, в отличие от Enumeration у HashTable, работает по принципу «fail-fast» (выдает исключение при любой несогласованности данных).
Hashtable это устаревший класс и его использование не рекомендовано.
👉 @java_geek
2 449
🔍 Завтра тестовое собеседование с Java-разработчиком
19 ноября(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.
Как это будет:
📂 Сергей Чамкин, старший разработчик из Uzum, ex-WildBerries, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Cергей будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Сергею
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot
Реклама.
О рекламодателе.
2 449
Расскажите о различиях вложенных классов: простых и статических?
Простые вложенные классы используются для тесной связи с внешним классом, а статические — когда нужно логически сгруппировать некоторый функционал.
Основные различия:
- Простой вложенный класс имеет доступ к членам внешнего класса, статический - нет.
- Для создания экземпляра простого вложенного класса нужен экземпляр внешнего класса, для статического - нет.
- Простой вложенный класс зависит от экземпляра внешнего класса, статический - нет.
👉 @java_geek
متاح الآن! بحث تيليغرام 2025 — أهم رؤى العام 
