Что такое ленивая загрузка (Lazy Loading) в программировании?

Ответ

Ленивая загрузка (Lazy Loading) — это паттерн отложенной инициализации, при котором ресурсоёмкий объект или данные создаются/загружаются не в момент создания родительского объекта, а только при первом обращении к ним.

Цель: оптимизация производительности и потребления памяти за счёт загрузки только необходимых в данный момент ресурсов.

Ключевой принцип: "Не делай работу, пока в ней нет необходимости".

Пример реализации на Java с Supplier:

public class Lazy<T> {
    private Supplier<T> supplier;
    private T value;
    private volatile boolean initialized = false; // для потокобезопасности

    public Lazy(Supplier<T> supplier) {
        this.supplier = supplier;
    }

    public T get() {
        if (!initialized) {
            synchronized (this) {
                if (!initialized) { // Double-checked locking
                    value = supplier.get(); // Дорогая операция выполняется здесь
                    initialized = true;
                }
            }
        }
        return value;
    }
}

// Использование
Lazy<ExpensiveObject> lazyResource = new Lazy<>(() -> {
    System.out.println("Creating expensive object...");
    return new ExpensiveObject(); // Создание происходит только при первом get()
});

// Объект ExpensiveObject ещё не создан
ExpensiveObject obj = lazyResource.get(); // Создание происходит сейчас
ExpensiveObject obj2 = lazyResource.get(); // Возвращается уже созданный объект

Типичные примеры применения:

  • ORM (Hibernate/JPA): Загрузка связанных коллекций (@OneToMany(fetch = FetchType.LAZY)). Коллекция загружается только при явном обращении к getItems().
  • Загрузка ресурсов: Изображения на веб-странице загружаются по мере прокрутки (lazy load images).
  • Создание тяжёлых объектов: Конфигурации, подключения к БД, которые могут не понадобиться.

Альтернатива: Eager Loading (жадная загрузка), когда все связанные данные загружаются сразу.

Ответ 18+ 🔞

А, ну это же про ленивую загрузку, блядь! Слушай, это как твой сосед по хате, который обещал полгода назад помочь с ремонтом, а когда ты ему наконец звонишь — он такой: «А, бля, ну щас, только проснулся». Ресурс создаётся не сразу, а только когда ты к нему впервые пристаёшь, сука.

Суть в чём: не делай работу, если тебя об этом ещё не просили. Зачем, блядь, грузить все фотки на странице, если пользователь их нихуя не увидит, пока вниз не промотает? Или зачем тащить из базы все заказы клиента, если ты просто его имя смотришь? Это же пиздец какой расход!

Смотри, как это выглядит в коде, на примере Java:

public class Lazy<T> {
    private Supplier<T> supplier;
    private T value;
    private volatile boolean initialized = false; // чтобы в потоках не наебаться

    public Lazy(Supplier<T> supplier) {
        this.supplier = supplier;
    }

    public T get() {
        if (!initialized) {
            synchronized (this) {
                if (!initialized) { // Двойная проверка, классика, ёпта
                    value = supplier.get(); // Вот тут-то и происходит вся дорогая хуйня!
                    initialized = true;
                }
            }
        }
        return value;
    }
}

// Использование
Lazy<ExpensiveObject> lazyResource = new Lazy<>(() -> {
    System.out.println("Creating expensive object...");
    return new ExpensiveObject(); // Объект спит, пока его не тронут
});

// ExpensiveObject ещё не родился, он в астрале
ExpensiveObject obj = lazyResource.get(); // А вот теперь, мать его, родился!
ExpensiveObject obj2 = lazyResource.get(); // А тут уже просто отдаётся готовый, второй раз не паримся

Где это, блядь, применяется? Да везде!

  • В Hibernate: когда ставишь FetchType.LAZY на связь. Ты запрашиваешь пользователя, а его список заказов лежит, пока ты специально не скажешь: «Ну-ка, сука, покажи, что там у тебя!»
  • Веб-страницы: картинки грузятся не все сразу, а по мере того, как юзер скроллит. А то он мог и не доскроллить, а ты уже всю полосу пропускания, идиот, проёбал.
  • Конфиги и подключения: зачем тебе сразу коннект к базе, если ты ещё даже не понял, будет ли он нужен? Инициализируй лениво, ебать мои старые костыли.

Противоположность этому — жадная загрузка (Eager Loading). Это как прийти в магазин за хлебом и купить сразу всё, включая утюг и три мешка картошки — на всякий случай, а вдруг пригодится? Ну, иногда и так надо, но чаще это просто пиздопроебибна и трата ресурсов.