Что такое кольцевой буфер (циклический буфер)?

Ответ

Кольцевой буфер (Circular Buffer) — это структура данных в виде массива фиксированного размера, логически организованного в кольцо: последний элемент связан с первым. При заполнении новые данные перезаписывают самые старые, начиная с начала.

Ключевые характеристики:

  • Фиксированная емкость — размер задается при создании.
  • Две указательные переменныеhead (начало для чтения) и tail (конец для записи).
  • Эффективное использование памяти — перезапись старых данных без реаллокации.

Основные операции:

  • enqueue(item) — добавление элемента в конец. Если буфер полон, head сдвигается, перезаписывая старый элемент.
  • dequeue() — извлечение элемента из начала.

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

public class CircularBuffer<T> {
    private final T[] buffer;
    private int head = 0;
    private int tail = 0;
    private int count = 0;

    @SuppressWarnings("unchecked")
    public CircularBuffer(int capacity) {
        buffer = (T[]) new Object[capacity];
    }

    public void enqueue(T item) {
        buffer[tail] = item;
        tail = (tail + 1) % buffer.length;
        if (count == buffer.length) {
            head = (head + 1) % buffer.length; // Перезапись при переполнении
        } else {
            count++;
        }
    }

    public T dequeue() {
        if (count == 0) throw new IllegalStateException("Buffer is empty");
        T item = buffer[head];
        buffer[head] = null; // Помощь сборщику мусора
        head = (head + 1) % buffer.length;
        count--;
        return item;
    }
}

Применение: буферизация в потоковой обработке данных (аудио/видео), реализация очереди с ограничением размера, кэширование последних N элементов, планирование задач.

Ответ 18+ 🔞

Слушай, вот есть такая штука — кольцевой буфер. Представь себе бочку, ёпта, но не простую, а такую, где дно прикручено к крышке, получился такой бублик из памяти, блядь. Размер у него фиксированный, как твоя зарплата — не разгуляешься.

Суть его, блядь, в чём:

  • Ёмкость одна на всю жизнь — задал при рождении и терпи, как в тюрьме.
  • Два указателя, как рога у чёртаhead (отсюда читаем) и tail (сюда пишем).
  • Память использует, как жмот — когда место кончается, новые данные просто пиздят самые старые, без всяких реаллокаций, нахуй.

Что он умеет, эта мартышлюшка:

  • enqueue(item) — сунуть элемент в хвост. Если буфер уже забит под завязку, то head сдвинется, и старый элемент отправится в утиль. Жестоко, но эффективно.
  • dequeue() — выдернуть элемент из головы. Если там пусто — получишь исключение прямо в ебальник.

Вот, смотри, как это на Java выглядит, ядрёна вошь:

public class CircularBuffer<T> {
    private final T[] buffer;
    private int head = 0;
    private int tail = 0;
    private int count = 0;

    @SuppressWarnings("unchecked")
    public CircularBuffer(int capacity) {
        buffer = (T[]) new Object[capacity];
    }

    public void enqueue(T item) {
        buffer[tail] = item;
        tail = (tail + 1) % buffer.length;
        if (count == buffer.length) {
            head = (head + 1) % buffer.length; // Перезапись при переполнении
        } else {
            count++;
        }
    }

    public T dequeue() {
        if (count == 0) throw new IllegalStateException("Buffer is empty");
        T item = buffer[head];
        buffer[head] = null; // Помощь сборщику мусора
        head = (head + 1) % buffer.length;
        count--;
        return item;
    }
}

Где эту хитрожопую хуйню применяют? Да везде, где поток данных идёт, а память — нет! Обработка аудио, видео, очередь последних сообщений, кэш, ёбушки-воробушки. В общем, вещь!