PassFront
  1. PassFront
  2. База знаний
  3. Массивы и списки

Что такое кольцевой буфер и где он применяется?

Массивы и списки

Кольцевой буфер — массив фиксированного размера с индексами чтения и записи, которые при достижении конца переходят в начало; он даёт очередь FIFO с O(1) на операцию и без аллокаций после создания.

Устройство

class RingBuffer {
  #buf;
  #head = 0; // откуда читать
  #size = 0;
  constructor(cap) { this.#buf = new Array(cap); }
  push(x) {
    if (this.#size === this.#buf.length) return false; // или перезаписать старый
    this.#buf[(this.#head + this.#size) % this.#buf.length] = x;
    this.#size++;
    return true;
  }
  shift() {
    if (this.#size === 0) return undefined;
    const x = this.#buf[this.#head];
    this.#buf[this.#head] = undefined; // не держим ссылку для GC
    this.#head = (this.#head + 1) % this.#buf.length;
    this.#size--;
    return x;
  }
}

Тонкости

  • «Полный» и «пустой» при голых head === tail неразличимы: храните счётчик или оставляйте одну ячейку пустой.
  • Ёмкость-степень двойки позволяет заменить % на маску & (cap − 1).
  • При переполнении есть две политики: отклонять запись (очередь задач) или затирать самое старое (логи, метрики).

Где встречается

  • Аудио- и видеобуферы, кольца приёма и передачи сетевых карт.
  • Очереди io_uring, kfifo в ядре Linux, LMAX Disruptor.
  • «Последние N событий»: скользящее окно, история команд.

Коротко для собеседования

Кольцевой буфер — очередь фиксированного размера поверх массива, где индексы заворачиваются по модулю, поэтому нет ни сдвигов, ни аллокаций. Заранее решите, что делать при переполнении — отклонять запись или затирать старое; при одном писателе и одном читателе его легко сделать lock-free.

Другие вопросы раздела