← Назад к вопросам
Ограниченное хранение данных в map
1.6 Junior🔥 201 комментариев
#Основы Go
Условие
Реализуйте структуру данных - map с ограничением по количеству элементов. При превышении лимита удаляется самый старый элемент (FIFO).
Интерфейс
type LimitedMap struct {
// ваши поля
}
func NewLimitedMap(maxSize int) *LimitedMap
func (m *LimitedMap) Set(key string, value interface{})
func (m *LimitedMap) Get(key string) (interface{}, bool)
func (m *LimitedMap) Delete(key string)
func (m *LimitedMap) Len() int
Требования
- При добавлении нового элемента, если достигнут лимит, удалить самый старый
- Сохранять порядок добавления элементов
- Операция Get не влияет на порядок (в отличие от LRU)
Пример
m := NewLimitedMap(3)
m.Set("a", 1)
m.Set("b", 2)
m.Set("c", 3)
m.Set("d", 4) // удаляется "a"
_, ok := m.Get("a") // ok = false
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Ограниченное хранилище (FIFO Map)
Описание задачи
Мап с максимальным размером где при превышении лимита удаляется самый старый элемент (FIFO - First In First Out).
Отличие от LRU:
- LRU: Get перемещает элемент в конец (свежий)
- FIFO: Get не влияет на порядок, только время добавления
Архитектура
Используем две структуры:
- map[string]interface{} - для быстрого доступа O(1)
- []string - очередь ключей в порядке добавления
Это дешевле чем двусвязный список как в LRU.
Реализация FIFO
Непосредственно используем:
- Mutex для синхронизации
- map для быстрого Get/Set
- slice для отслеживания порядка
Алгоритм Set:
- Если key уже существует: обновляем значение, порядок не меняем
- Если key новый: a. Если длина меньше maxSize: добавляем в конец queue b. Если длина равна maxSize: удаляем первый элемент из map и queue, добавляем новый
- Обновляем значение в map
Алгоритм Get:
- Простой lookup в map
- Возвращаем значение и флаг
- Порядок не меняется
Алгоритм Delete:
- Удаляем из map
- Удаляем из queue
Сложность
- Set: O(n) - удаление из начала queue требует переноса элементов
- Get: O(1) - простой lookup в map
- Delete: O(n) - поиск и удаление из queue
- Len: O(1) - длина map
Оптимизация: Deque
Для O(1) Remove из начала используем container/ring или реализуем deque:
Вместо []string queue используем:
- Двусвязный список для O(1) удаления
- map[string]*Node для быстрого поиска
Это дает O(1) для всех операций.
Особенности реализации
- При обновлении существующего ключа порядок не меняется
- Get не создает side effects
- Delete удаляет из обеих структур данных
- При превышении лимита удаляется из очереди в порядке FIFO
Тестовые случаи
- Добавление элементов до лимита
- Добавление элемента при достижении лимита (должен удалиться первый)
- Обновление существующего элемента (порядок не меняется)
- Удаление элемента
- Get несуществующего элемента
- Get существующего элемента
- Проверка длины после операций
Разница между FIFO и LRU
Пример с лимитом 2: Добавляем: a, b, c
FIFO (эта задача):
- Очередь: [b, c]
- Удален a (самый старый по времени добавления)
LRU:
- Очередь зависит от Get операций
- Если делали Get(a) перед добавлением c, то удалится b
- Если не делали Get, удалится a
Edge cases
- maxSize = 0: не добавляем ничего
- maxSize = 1: только один элемент
- Обновление элемента в очереди
- Delete элемента в середине очереди
- Одновременные операции (нужен Mutex)