Что выведет код?
#Tasks
@SpringBootApplication
@EnableAsync
public class Task130326 implements CommandLineRunner {
@Autowired
private AsyncService130326 service;
public static void main(String[] args) {
SpringApplication.run(Task130326.class, args);
}
@Override
public void run(String... args) {
service.directCall();
service.proxyCall();
}
}
@Component
class AsyncService130326 {
@Lazy
@Autowired
private AsyncService130326 self;
@Async
public void asyncMethod() {
System.out.println("asyncMethod: " + Thread.currentThread().getName());
}
public void directCall() {
System.out.println("directCall: " + Thread.currentThread().getName());
asyncMethod();
}
public void proxyCall() {
System.out.println("proxyCall: " + Thread.currentThread().getName());
self.asyncMethod();
}
}
#Tasks
👍2
Что такое Java Memory Model (JMM)? 🤓
Ответ:
Java Memory Model (JMM) — это формальная модель, описывающая, как потоки взаимодействуют через память и какое поведение можно ожидать в многопоточной среде.
JMM определяет правила, когда изменения, сделанные одним потоком, становятся видимыми для других потоков. Она описывает отношение "happens-before", которое гарантирует видимость и упорядоченность действий. Без JMM компилятор и процессор могли бы переупорядочивать инструкции так, что многопоточный код работал бы непредсказуемо.
Ключевые слова synchronized, volatile, final обеспечивают определенные гарантии видимости в рамках JMM.
#собеседование
Ответ:
JMM определяет правила, когда изменения, сделанные одним потоком, становятся видимыми для других потоков. Она описывает отношение "happens-before", которое гарантирует видимость и упорядоченность действий. Без JMM компилятор и процессор могли бы переупорядочивать инструкции так, что многопоточный код работал бы непредсказуемо.
Ключевые слова synchronized, volatile, final обеспечивают определенные гарантии видимости в рамках JMM.
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
История технологий сегодня — 14 марта
ℹ️ Кто родился в этот день
Станислав Алексеевич Кудж (род. 14 марта 1979, Москва, РСФСР, СССР) — российский учёный, специалист в области автоматизированных систем государственного управления, многопрофильных и многофункциональных информационных систем.
🌐 Знаковые события
1956 — американская компания Ampex продемонстрировала первый в мире видеомагнитофон VR-1000.
1994 — релиз Linux версии 1.0.0.
#Biography #Birth_Date #Events #14марта
Станислав Алексеевич Кудж (род. 14 марта 1979, Москва, РСФСР, СССР) — российский учёный, специалист в области автоматизированных систем государственного управления, многопрофильных и многофункциональных информационных систем.
1956 — американская компания Ampex продемонстрировала первый в мире видеомагнитофон VR-1000.
1994 — релиз Linux версии 1.0.0.
#Biography #Birth_Date #Events #14марта
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
С 07.03 по 13.03
Предыдущий пост(с 28.02 по 06.03)
Воскресный мотивационный пост:
Не было мотивации
Запись встреч/видео:
Видео в процессе подготовки...
Обучающие статьи:
Раздел 8. Stream API и функциональный стиль
Глава 5: Контракты. Почему equals, hashCode и иммутабельность — закон
equals/hashCode в операциях distinct, groupingBy, toSet
Иммутабельность данных в потоке — не прихоть, а необходимость
Советы по Java:
[Совет по Java #013]
Тема: Аннотация @Transactional не работает на private и protected методах
[Совет по Java #014]
Тема: Инъекция через конструктор предпочтительнее инъекции в поле
[Совет по Java #015]
Тема: @Async по умолчанию не работает внутри того же класса
Полезные статьи и видео:
Java без розовых очков: какие знания отделяют грейды
Как и всегда, задачи можно найти под тегом - #Tasks, вопросы с собеседований - #собеседование
Предыдущий пост(с 28.02 по 06.03)
Воскресный мотивационный пост:
Не было мотивации
Запись встреч/видео:
Видео в процессе подготовки...
Обучающие статьи:
Раздел 8. Stream API и функциональный стиль
Глава 5: Контракты. Почему equals, hashCode и иммутабельность — закон
equals/hashCode в операциях distinct, groupingBy, toSet
Иммутабельность данных в потоке — не прихоть, а необходимость
Советы по Java:
[Совет по Java #013]
Тема: Аннотация @Transactional не работает на private и protected методах
[Совет по Java #014]
Тема: Инъекция через конструктор предпочтительнее инъекции в поле
[Совет по Java #015]
Тема: @Async по умолчанию не работает внутри того же класса
Полезные статьи и видео:
Java без розовых очков: какие знания отделяют грейды
Как и всегда, задачи можно найти под тегом - #Tasks, вопросы с собеседований - #собеседование
👍2
История технологий сегодня — 15 марта
ℹ️ Кто родился в этот день
Жоре́с Ива́нович Алфёров (бел. Жарэс Іванавіч Алфёраў; 15 марта 1930, Витебск — 1 марта 2019, Санкт-Петербург) — советский и российский учёный-физик. Политический деятель. Лауреат Нобелевской премии по физике (2000 год, за разработку полупроводниковых гетероструктур и создание быстрых опто- и микроэлектронных компонентов).
🌐 Знаковые события
1892 — американский изобретатель Джесс Рено (англ. Jesse Reno) запатентовал первый эскалатор.
1985 — зарегистрирован первый домен в зоне .com
#Biography #Birth_Date #Events #15марта
Жоре́с Ива́нович Алфёров (бел. Жарэс Іванавіч Алфёраў; 15 марта 1930, Витебск — 1 марта 2019, Санкт-Петербург) — советский и российский учёный-физик. Политический деятель. Лауреат Нобелевской премии по физике (2000 год, за разработку полупроводниковых гетероструктур и создание быстрых опто- и микроэлектронных компонентов).
1892 — американский изобретатель Джесс Рено (англ. Jesse Reno) запатентовал первый эскалатор.
1985 — зарегистрирован первый домен в зоне .com
#Biography #Birth_Date #Events #15марта
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Вы соскучились по встречам?
Anonymous Poll
56%
Да!
4%
Нет!
0%
Похер
36%
Встреча с кем?
4%
Что я тут делаю?
👍1
История технологий сегодня — 16 марта
ℹ️ Кто родился в этот день
Ричард Мэттью Столлман (англ. Richard Matthew Stallman; род. 16 марта 1953, Манхэттен, Нью-Йорк), также упоминаемый как rms, — основатель движения свободного программного обеспечения, проекта GNU, Фонда свободного программного обеспечения и Лиги за свободу программирования. Автор концепции «копилефта», призванной защищать идеалы движения; эту концепцию он с помощью юристов позже воплотил в лицензии GNU General Public License (GNU GPL) для ПО. Ранее также известный программист. Из авторских программ можно отметить GNU Emacs, Коллекция компиляторов GNU (GCC) и Отладчик GNU (GDB). С середины 1990-х годов Столлман стал программировать значительно меньше, посвятив себя распространению идей свободного ПО.
Э́ндрю Стюарт Таненба́ум (англ. Andrew Stuart Tanenbaum; род. 16 марта 1944, Нью-Йорк, Нью-Йорк), иногда упоминаемый под псевдонимом AST или Papá Tanenbaum — голландский учёный-компьютерщик американского происхождения, почётный профессор компьютерных наук в Амстердамском свободном университете в Нидерландах. Известен как автор MINIX (свободная Unix-подобная операционная система для учебных целей) и RFID-вируса. Автор книг по информатике, которые считаются стандартами в данной области. Сам он считает свою преподавательскую деятельность наиболее важной. Является главным разработчиком пакета «Amsterdam Compiler Kit».
Фре́дерик Ра́йнес (англ. Frederick Reines; 16 марта 1918, Патерсон, штат Нью-Джерси, США — 26 августа 1998, Ориндж, штат Калифорния, США) — американский физик, профессор, лауреат Нобелевской премии по физике (1995) за открытие нейтрино.
🌐 Знаковые события
1936 — с конвейера Горьковского автомобильного завода сошла первая советская легковая автомашина — лимузин марки «М-1».
#Biography #Birth_Date #Events #16марта
Ричард Мэттью Столлман (англ. Richard Matthew Stallman; род. 16 марта 1953, Манхэттен, Нью-Йорк), также упоминаемый как rms, — основатель движения свободного программного обеспечения, проекта GNU, Фонда свободного программного обеспечения и Лиги за свободу программирования. Автор концепции «копилефта», призванной защищать идеалы движения; эту концепцию он с помощью юристов позже воплотил в лицензии GNU General Public License (GNU GPL) для ПО. Ранее также известный программист. Из авторских программ можно отметить GNU Emacs, Коллекция компиляторов GNU (GCC) и Отладчик GNU (GDB). С середины 1990-х годов Столлман стал программировать значительно меньше, посвятив себя распространению идей свободного ПО.
Э́ндрю Стюарт Таненба́ум (англ. Andrew Stuart Tanenbaum; род. 16 марта 1944, Нью-Йорк, Нью-Йорк), иногда упоминаемый под псевдонимом AST или Papá Tanenbaum — голландский учёный-компьютерщик американского происхождения, почётный профессор компьютерных наук в Амстердамском свободном университете в Нидерландах. Известен как автор MINIX (свободная Unix-подобная операционная система для учебных целей) и RFID-вируса. Автор книг по информатике, которые считаются стандартами в данной области. Сам он считает свою преподавательскую деятельность наиболее важной. Является главным разработчиком пакета «Amsterdam Compiler Kit».
Фре́дерик Ра́йнес (англ. Frederick Reines; 16 марта 1918, Патерсон, штат Нью-Джерси, США — 26 августа 1998, Ориндж, штат Калифорния, США) — американский физик, профессор, лауреат Нобелевской премии по физике (1995) за открытие нейтрино.
1936 — с конвейера Горьковского автомобильного завода сошла первая советская легковая автомашина — лимузин марки «М-1».
#Biography #Birth_Date #Events #16марта
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Раздел 8. Stream API и функциональный стиль в Java
Глава 5: Контракты. Почему equals, hashCode и иммутабельность — закон
(Практика): Саботаж и починка в «Библиотеке»
Создание «сломанного» класса Book
Создайте или обновите класс Book с минимальными полями:
Частичная реализация equals (только по title)
Добавьте equals, сравнивающий только название:
Намеренно не добавляйте hashCode!
Демонстрация проблемы в Stream API
Проблема 1: distinct() «слипает» разные книги
Создайте тестовый метод в Library или Main:
Ожидаемый вывод:
Что произошло: distinct() использует hashCode и equals. Поскольку hashCode не переопределён, наследуется от Object — разные адреса памяти → разные хэши. Но equals говорит, что книги равны по названию.
На самом деле поведение непредсказуемо: distinct() внутри использует HashSet, который сначала сравнивает hashCode, потом equals. Если хэши разные (а они будут разные), элементы попадают в разные бакеты и никогда не сравниваются через equals. Толстой и Достоевский останутся оба!
Проверьте: Запустите код. Если обе «Войны и мира» остались — hashCode разные спасает. Если одна пропала — вы попали в коллизию (редко, но возможно).
Проблема 2: toMap и потеря значений
Создайте Map книга → количество на складе:
Анализ:
toMap использует hashCode для выбора бакета, equals для проверки существования ключа
Без переопределённого hashCode — разные объекты, разные бакеты
Даже если equals сказал бы «равны», HashMap не найдёт элемент из-за разных хэшей
lookup и lookupWrongAuthor оба вернут null или случайное значение
Глава 5: Контракты. Почему equals, hashCode и иммутабельность — закон
(Практика): Саботаж и починка в «Библиотеке»
Создание «сломанного» класса Book
Создайте или обновите класс Book с минимальными полями:
public class Book {
private final String title;
private final String author;
public Book(String title, String author) {
this.title = Objects.requireNonNull(title, "title не может быть null");
this.author = Objects.requireNonNull(author, "author не может быть null");
}
public String getTitle() { return title; }
public String getAuthor() { return author; }
@Override
public String toString() {
return "Book[title=" + title + ", author=" + author + "]";
}
}Частичная реализация equals (только по title)
Добавьте equals, сравнивающий только название:
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Book)) return false;
Book book = (Book) o;
return title.equals(book.title); // Только title! Автор игнорируется.
}
Намеренно не добавляйте hashCode!
Демонстрация проблемы в Stream API
Проблема 1: distinct() «слипает» разные книги
Создайте тестовый метод в Library или Main:
public void demonstrateDistinctProblem() {
List<Book> books = Arrays.asList(
new Book("Война и мир", "Толстой"),
new Book("Война и мир", "Достоевский"), // Другой автор!
new Book("1984", "Оруэлл")
);
List<Book> distinct = books.stream()
.distinct()
.collect(Collectors.toList());
System.out.println("Исходный список: " + books.size() + " книг");
System.out.println("После distinct: " + distinct.size() + " книг");
System.out.println("Уникальные книги: " + distinct);
}Ожидаемый вывод:
Исходный список: 3 книг
После distinct: 2 книг
Уникальные книги: [Book[title=Война и мир, author=Толстой], Book[title=1984, author=Оруэлл]]
Что произошло: distinct() использует hashCode и equals. Поскольку hashCode не переопределён, наследуется от Object — разные адреса памяти → разные хэши. Но equals говорит, что книги равны по названию.
На самом деле поведение непредсказуемо: distinct() внутри использует HashSet, который сначала сравнивает hashCode, потом equals. Если хэши разные (а они будут разные), элементы попадают в разные бакеты и никогда не сравниваются через equals. Толстой и Достоевский останутся оба!
Проверьте: Запустите код. Если обе «Войны и мира» остались — hashCode разные спасает. Если одна пропала — вы попали в коллизию (редко, но возможно).
Проблема 2: toMap и потеря значений
Создайте Map книга → количество на складе:
public void demonstrateToMapProblem() {
List<Book> inventory = Arrays.asList(
new Book("Война и мир", "Толстой"),
new Book("Война и мир", "Достоевский")
);
Map<Book, Integer> stock = inventory.stream()
.collect(Collectors.toMap(
Function.identity(),
b -> 10, // количество на складе
(a, b) -> a + b // слияние при коллизии
));
System.out.println("Map: " + stock);
// Попытка получить значение по «эквивалентной» книге
Book lookup = new Book("Война и мир", "Толстой");
System.out.println("Поиск " + lookup + ": " + stock.get(lookup));
Book lookupWrongAuthor = new Book("Война и мир", "Гоголь");
System.out.println("Поиск " + lookupWrongAuthor + ": " + stock.get(lookupWrongAuthor));
}Анализ:
toMap использует hashCode для выбора бакета, equals для проверки существования ключа
Без переопределённого hashCode — разные объекты, разные бакеты
Даже если equals сказал бы «равны», HashMap не найдёт элемент из-за разных хэшей
lookup и lookupWrongAuthor оба вернут null или случайное значение
👍5
Проблема 3: groupingBy ломается
Ожидаемо: 3 группы (все разные авторы) или 1 группа (если equals/hashCode считают их одинаковыми).
Фактически: Непредсказуемо из-за отсутствующего hashCode.
Исправление: корректные equals и hashCode
Правильная реализация по всем полям
Обновите класс Book:
Контракт equals и hashCode:
Рефлексивность: x.equals(x) всегда true
Симметричность: x.equals(y) ⇔ y.equals(x)
Транзитивность: x.equals(y) и y.equals(z) → x.equals(z)
Консистентность: повторные вызовы дают тот же результат
С null: x.equals(null) всегда false
Критически: Если x.equals(y), то x.hashCode() == y.hashCode()
Проверка исправления
Повторите все демонстрации
Ожидаемый результат: 3 уникальных книги, Map с 3 записями, поиск находит значение.
#Java #для_новичков #beginner #stream_api #практика
public void demonstrateGroupingProblem() {
List<Book> books = Arrays.asList(
new Book("Война и мир", "Толстой"),
new Book("Война и мир", "Достоевский"),
new Book("Война и мир", "Тургенев")
);
Map<Book, List<Book>> byBook = books.stream()
.collect(Collectors.groupingBy(Function.identity()));
System.out.println("Групп: " + byBook.size());
byBook.forEach((k, v) -> System.out.println(k + " -> " + v.size()));
}Ожидаемо: 3 группы (все разные авторы) или 1 группа (если equals/hashCode считают их одинаковыми).
Фактически: Непредсказуемо из-за отсутствующего hashCode.
Исправление: корректные equals и hashCode
Правильная реализация по всем полям
Обновите класс Book:
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Book)) return false;
Book book = (Book) o;
return title.equals(book.title) &&
author.equals(book.author); // Теперь оба поля!
}
@Override
public int hashCode() {
return Objects.hash(title, author); // Консистентно с equals
}
Контракт equals и hashCode:
Рефлексивность: x.equals(x) всегда true
Симметричность: x.equals(y) ⇔ y.equals(x)
Транзитивность: x.equals(y) и y.equals(z) → x.equals(z)
Консистентность: повторные вызовы дают тот же результат
С null: x.equals(null) всегда false
Критически: Если x.equals(y), то x.hashCode() == y.hashCode()
Проверка исправления
Повторите все демонстрации
public void demonstrateFixed() {
List<Book> books = Arrays.asList(
new Book("Война и мир", "Толстой"),
new Book("Война и мир", "Достоевский"),
new Book("1984", "Оруэлл")
);
// distinct() — теперь 3 уникальные книги
System.out.println("distinct: " + books.stream().distinct().count());
// toMap — теперь 3 записи
Map<Book, Integer> stock = books.stream()
.collect(Collectors.toMap(
Function.identity(),
b -> 10,
Integer::sum
));
System.out.println("Map size: " + stock.size());
// Поиск работает
Book lookup = new Book("Война и мир", "Толстой");
System.out.println("Найдено: " + stock.get(lookup));
}Ожидаемый результат: 3 уникальных книги, Map с 3 записями, поиск находит значение.
#Java #для_новичков #beginner #stream_api #практика
👍4
Альтернативные стратегии equals/hashCode
Стратегия 1: Только неизменяемый идентификатор (ISBN)
Если Book имеет уникальный ISBN:
Плюсы: Эффективно, надёжно. Минусы: Требует уникального поля.
Стратегия 2: Все поля
Плюсы: Корректно для value objects. Минусы: Медленнее, чувствительно к изменениям.
Стратегия 3: Не переопределять (только identity)
Если Book — entity с уникальным ID в базе данных, и вы никогда не сравниваете разные объекты с одинаковым ID:
Плюсы: Просто. Минусы: distinct(), toMap, groupingBy работают по ссылке, не по содержимому.
Практические задания
Задача 1: воспроизвести все три проблемы
В проекте «Библиотека» создайте класс BrokenBook с equals только по title и без hashCode.
Продемонстрируйте:
distinct() «проглатывает» книги или нет (зависит от хэш-коллизий)
toMap создаёт больше записей, чем ожидается
groupingBy разбивает на неожиданное количество групп
Зафиксируйте наблюдения в комментариях.
Задача 2: исправить и сравнить
Создайте FixedBook с корректной парой equals/hashCode. Повторите те же операции.
Убедитесь, что:
Толстой, Достоевский, Тургенев — три разные книги с одинаковым названием
distinct() оставляет все три
toMap создаёт три записи
Поиск по ключу находит правильное значение
Задача 3: специфический equals для бизнес-логики
Добавьте в Library метод findByTitle(String title), который находит все книги с данным названием (независимо от автора).
Реализуйте через filter с кастомным предикатом, не через equals:
Объясните, почему это безопаснее, чем менять equals для всего класса.
Задача 4: кеширование hashCode (звёздочка)
Если поля title и author неизменяемы, закешируйте hashCode:
Сравните производительность при частом использовании в HashMap для миллиона операций.
#Java #для_новичков #beginner #stream_api #практика
Стратегия 1: Только неизменяемый идентификатор (ISBN)
Если Book имеет уникальный ISBN:
private final String isbn; // уникальный, неизменяемый
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Book)) return false;
return isbn.equals(((Book) o).isbn);
}
@Override
public int hashCode() {
return isbn.hashCode();
}
Плюсы: Эффективно, надёжно. Минусы: Требует уникального поля.
Стратегия 2: Все поля
Плюсы: Корректно для value objects. Минусы: Медленнее, чувствительно к изменениям.
Стратегия 3: Не переопределять (только identity)
Если Book — entity с уникальным ID в базе данных, и вы никогда не сравниваете разные объекты с одинаковым ID:
// Нет equals/hashCode — используем Object
Плюсы: Просто. Минусы: distinct(), toMap, groupingBy работают по ссылке, не по содержимому.
Практические задания
Задача 1: воспроизвести все три проблемы
В проекте «Библиотека» создайте класс BrokenBook с equals только по title и без hashCode.
Продемонстрируйте:
distinct() «проглатывает» книги или нет (зависит от хэш-коллизий)
toMap создаёт больше записей, чем ожидается
groupingBy разбивает на неожиданное количество групп
Зафиксируйте наблюдения в комментариях.
Задача 2: исправить и сравнить
Создайте FixedBook с корректной парой equals/hashCode. Повторите те же операции.
Убедитесь, что:
Толстой, Достоевский, Тургенев — три разные книги с одинаковым названием
distinct() оставляет все три
toMap создаёт три записи
Поиск по ключу находит правильное значение
Задача 3: специфический equals для бизнес-логики
Добавьте в Library метод findByTitle(String title), который находит все книги с данным названием (независимо от автора).
Реализуйте через filter с кастомным предикатом, не через equals:
public List<Book> findByTitle(String title) {
return books.stream()
.filter(b -> b.getTitle().equals(title))
.collect(Collectors.toList());
}Объясните, почему это безопаснее, чем менять equals для всего класса.
Задача 4: кеширование hashCode (звёздочка)
Если поля title и author неизменяемы, закешируйте hashCode:
private int hashCode; // 0 = не вычислено
@Override
public int hashCode() {
int result = hashCode;
if (result == 0) {
result = Objects.hash(title, author);
hashCode = result;
}
return result;
}
Сравните производительность при частом использовании в HashMap для миллиона операций.
#Java #для_новичков #beginner #stream_api #практика
👍5
Что выведет код?
#Tasks
public class Task160326 {
public static void main(String[] args) {
String s1 = " hello ".trim();
String s2 = " hello ".strip();
String s3 = "\u2000hello\u2000".trim();
String s4 = "\u2000hello\u2000".strip();
System.out.println(s1.equals(s2));
System.out.println(s3.length());
System.out.println(s4.length());
}
}#Tasks
👍2
👍2
Что такое Profiling и для чего он нужен? 🤓
Ответ:
Profiling — это процесс динамического анализа работающего приложения для измерения его производительности, использования памяти и поведения потоков.
Профилировщики (например, JProfiler, VisualVM, YourKit) собирают данные о:
CPU Profiling — какие методы потребляют больше всего процессорного времени;
Memory Profiling — какие объекты занимают память, поиск утечек памяти;
Thread Profiling — состояние потоков, поиск deadlock'ов.
Это незаменимый инструмент для оптимизации производительности и диагностики проблем в сложных приложениях.
#собеседование
Ответ:
Профилировщики (например, JProfiler, VisualVM, YourKit) собирают данные о:
CPU Profiling — какие методы потребляют больше всего процессорного времени;
Memory Profiling — какие объекты занимают память, поиск утечек памяти;
Thread Profiling — состояние потоков, поиск deadlock'ов.
Это незаменимый инструмент для оптимизации производительности и диагностики проблем в сложных приложениях.
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
История технологий сегодня — 17 марта
ℹ️ Кто родился в этот день
Влади́мир Па́влович Барми́н (4 (17) марта 1909 года, Москва — 17 июля 1993 года, там же) — советский учёный, конструктор реактивных пусковых установок, ракетно-космических и боевых стартовых комплексов. Один из основоположников советской космонавтики. С 1947 года под руководством Бармина были разработаны стартовые комплексы для многих ракет конструкции Королёва: Р-1, Р-2, Р-11, Р-5, Р-5М — первой стратегической ракеты с ядерным боезарядом Р-5М. В 1957 году завершены работы над стартовым комплексом первой в мире межконтинентальной баллистической ракеты Р-7, которая вывела на орбиту Земли первый искусственный спутник Земли и первого космонавта Юрия Гагарина.
Готтлиб Вильгельм Даймлер (нем. Gottlieb Wilhelm Daimler); собственно Доймлер (Däumler; 17 марта 1834, Шорндорф, Королевство Вюртемберг, Германский союз — 6 марта 1900, Бад-Канштатт, Королевство Вюртемберг, Германская империя) — немецкий инженер, конструктор и промышленник. Совместно с Вильгельмом Майбахом Даймлер разработал один из первых автомобилей и несколько типов бензиновых двигателей внутреннего сгорания.
🌐 Знаковые события
1966 — первый пуск с космодрома Плесецк: ракетой-носителем «Восток-2» на орбиту Земли выведен искусственный спутник «Космос-112».
#Biography #Birth_Date #Events #17марта
Влади́мир Па́влович Барми́н (4 (17) марта 1909 года, Москва — 17 июля 1993 года, там же) — советский учёный, конструктор реактивных пусковых установок, ракетно-космических и боевых стартовых комплексов. Один из основоположников советской космонавтики. С 1947 года под руководством Бармина были разработаны стартовые комплексы для многих ракет конструкции Королёва: Р-1, Р-2, Р-11, Р-5, Р-5М — первой стратегической ракеты с ядерным боезарядом Р-5М. В 1957 году завершены работы над стартовым комплексом первой в мире межконтинентальной баллистической ракеты Р-7, которая вывела на орбиту Земли первый искусственный спутник Земли и первого космонавта Юрия Гагарина.
Готтлиб Вильгельм Даймлер (нем. Gottlieb Wilhelm Daimler); собственно Доймлер (Däumler; 17 марта 1834, Шорндорф, Королевство Вюртемберг, Германский союз — 6 марта 1900, Бад-Канштатт, Королевство Вюртемберг, Германская империя) — немецкий инженер, конструктор и промышленник. Совместно с Вильгельмом Майбахом Даймлер разработал один из первых автомобилей и несколько типов бензиновых двигателей внутреннего сгорания.
1966 — первый пуск с космодрома Плесецк: ракетой-носителем «Восток-2» на орбиту Земли выведен искусственный спутник «Космос-112».
#Biography #Birth_Date #Events #17марта
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
[Совет по Java #016]
Тема: Ленивая загрузка в Hibernate (FetchType.LAZY) не работает после закрытия сессии.
Проблема: Hibernate использует шаблон ленивой загрузки для оптимизации производительности — связанные сущности подгружаются только при первом обращении к ним.
Однако для этого необходима открытая сессия (persistence context). Когда сессия закрывается (например, после завершения транзакции), доступ к неинициализированным прокси-объектам вызывает исключение LazyInitializationException.
Это классическая проблема при передаче сущностей на уровень представления (view) или при работе с ними вне транзакционного контекста.
Решение: Существует три основных подхода.
Первый — продлить транзакцию на весь сервисный метод, чтобы сессия оставалась открытой до полной обработки данных.
Второй — инициализировать все необходимые связи явно через JOIN FETCH в HQL/JPQL или через EntityGraph.
Третий — использовать паттерн Open Session in View (OSIV), который держит сессию открытой до завершения HTTP-запроса, но это антипаттерн для production из-за проблем с производительностью и риска утечек соединений.
Объяснение: Корень проблемы — отделение уровня персистентности от уровня представления.
Самое надежное решение — не передавать сущности наружу, а преобразовывать их в DTO (Data Transfer Objects) внутри транзакции.
Если все же нужны сущности, то либо продлевайте транзакцию (@Transactional на весь метод контроллера — плохо), либо инициализируйте все необходимое до закрытия сессии. OSIV (spring.jpa.open-in-view=true) включен по умолчанию в Spring Boot — это удобно для разработки, но в production может держать соединения с БД долго и маскировать проблемы с производительностью.
#Java #советы
Тема: Ленивая загрузка в Hibernate (FetchType.LAZY) не работает после закрытия сессии.
Проблема: Hibernate использует шаблон ленивой загрузки для оптимизации производительности — связанные сущности подгружаются только при первом обращении к ним.
Однако для этого необходима открытая сессия (persistence context). Когда сессия закрывается (например, после завершения транзакции), доступ к неинициализированным прокси-объектам вызывает исключение LazyInitializationException.
Это классическая проблема при передаче сущностей на уровень представления (view) или при работе с ними вне транзакционного контекста.
Решение: Существует три основных подхода.
Первый — продлить транзакцию на весь сервисный метод, чтобы сессия оставалась открытой до полной обработки данных.
Второй — инициализировать все необходимые связи явно через JOIN FETCH в HQL/JPQL или через EntityGraph.
Третий — использовать паттерн Open Session in View (OSIV), который держит сессию открытой до завершения HTTP-запроса, но это антипаттерн для production из-за проблем с производительностью и риска утечек соединений.
@Entity
public class Order {
@Id private Long id;
@ManyToOne(fetch = FetchType.LAZY)
private User user; // ленивая загрузка
@OneToMany(mappedBy = "order", fetch = FetchType.LAZY)
private List<Item> items;
// геттеры/сеттеры
}
@Service
public class OrderService {
@PersistenceContext
private EntityManager em;
//Антипаттерн: сессия закрыта при доступе к ленивым полям
public Order badFind(Long id) {
Order order = em.find(Order.class, id);
// Транзакция закончилась, сессия закрыта
order.getUser().getName(); // LazyInitializationException!
return order;
}
//Решение 1: @Transactional на уровне сервиса
@Transactional
public Order goodFindTransactional(Long id) {
Order order = em.find(Order.class, id);
order.getUser().getName(); // Ок, сессия открыта
return order;
}
//Решение 2: JOIN FETCH в запросе
@Transactional(readOnly = true)
public Order findWithJoinFetch(Long id) {
return em.createQuery(
"SELECT o FROM Order o JOIN FETCH o.user WHERE o.id = :id", Order.class)
.setParameter("id", id)
.getSingleResult(); // user уже загружен
}
//Решение 3: EntityGraph
@Transactional(readOnly = true)
public Order findWithEntityGraph(Long id) {
EntityGraph<?> graph = em.getEntityGraph("Order.withUserAndItems");
return em.find(Order.class, id,
Collections.singletonMap("javax.persistence.fetchgraph", graph));
}
}
// DTO-подход — лучшая практика
@Data
class OrderDTO {
private Long id;
private String userName; // только нужные поля, без прокси
}
@Service
class OrderDTOService {
@PersistenceContext
private EntityManager em;
public OrderDTO findDTO(Long id) {
return em.createQuery(
"SELECT NEW com.example.OrderDTO(o.id, u.name) " +
"FROM Order o JOIN o.user u WHERE o.id = :id", OrderDTO.class)
.setParameter("id", id)
.getSingleResult(); // Никаких прокси, только данные
}
}
Объяснение: Корень проблемы — отделение уровня персистентности от уровня представления.
Самое надежное решение — не передавать сущности наружу, а преобразовывать их в DTO (Data Transfer Objects) внутри транзакции.
Если все же нужны сущности, то либо продлевайте транзакцию (@Transactional на весь метод контроллера — плохо), либо инициализируйте все необходимое до закрытия сессии. OSIV (spring.jpa.open-in-view=true) включен по умолчанию в Spring Boot — это удобно для разработки, но в production может держать соединения с БД долго и маскировать проблемы с производительностью.
#Java #советы
👍6
Что выведет код?
#Tasks
import java.util.*;
public class Task170326 {
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
list1.add(null);
list1.add("text");
list1.remove(1);
List<String> list2 = new ArrayList<>();
list2.add("text");
list2.remove(0);
System.out.println(list1.isEmpty());
System.out.println(list2.isEmpty());
System.out.println(list1.size() == 0);
System.out.println(list2.size() == 0);
}
}
#Tasks
👍2
Варианты ответа:
Anonymous Quiz
11%
true true true true
0%
true false true false
78%
false true false true
11%
false false false false
🤯3
Что такое Maven и Gradle? 🤓
Ответ:
Maven и Gradle — это инструменты для автоматизации сборки и управления зависимостями.
Maven использует XML (файл pom.xml) для конфигурации и строго следует концепции жизненного цикла. Он декларативен — вы описываете, что хотите, а не как.
Gradle использует Groovy или Kotlin DSL, что делает скрипты более компактными и гибкими. Gradle основан на графе задач (task-based) и поддерживает инкрементальную сборку, что часто делает его быстрее Maven.
Gradle предлагает более плавный и мощный способ настройки сборки.
#собеседование
Ответ:
Maven использует XML (файл pom.xml) для конфигурации и строго следует концепции жизненного цикла. Он декларативен — вы описываете, что хотите, а не как.
Gradle использует Groovy или Kotlin DSL, что делает скрипты более компактными и гибкими. Gradle основан на графе задач (task-based) и поддерживает инкрементальную сборку, что часто делает его быстрее Maven.
Gradle предлагает более плавный и мощный способ настройки сборки.
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7