Ответ вслух Senior Дженерики обновлено

Обобщённый потокобезопасный кеш

Вопрос

Спроектируйте вслух обобщённый потокобезопасный кеш Cache[K, V] с TTL. Какие ограничения на типы, какие методы, как устроите вытеснение?

Попробуйте сами

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

Тип Cache[K comparable, V any]: ключ должен быть comparable, потому что это ключ мапы. Внутри map[K]entry[V], где entry хранит значение и expiresAt.

Что должно прозвучать в ответе

  • Сигнатура `Cache[K comparable, V any]`, comparable нужен для ключа мапы

  • Хранение `map[K]entry[V]` с временем истечения, sync.RWMutex или шардирование

  • Get возвращает `(V, bool)` и нулевое значение при промахе

  • Удаление просроченных: лениво при чтении плюс фоновая горутина с ticker и способом её остановить

  • Ограничение размера: LRU через container/list или кольцо

  • Защита от лавины: singleflight при загрузке

Что могут спросить следом

  • Как избежать утечки фоновой горутины?
  • Как тестировать TTL без реального ожидания?

Разбор

Тип Cache[K comparable, V any]: ключ должен быть comparable, потому что это ключ мапы. Внутри map[K]entry[V], где entry хранит значение и expiresAt. Защита: sync.RWMutex, а при высокой конкуренции шардирование на N мап по хешу ключа. Get(k) (V, bool): при промахе или истёкшей записи возвращаю var zero V и false, просроченное удаляю лениво. Фоновая очистка: горутина с time.Ticker, которая останавливается методом Close или по context, иначе горутина утечёт вместе с кешем. Для ограничения размера добавляю LRU: двусвязный список container/list и мапа на элементы списка, при вставке сверх лимита удаляю хвост. Для загрузки при промахе GetOrLoad с singleflight, чтобы сто одновременных промахов не пошли в базу сто раз. Время подменяю функцией now func() time.Time в тестах, а в Go 1.25 для этого есть ещё testing/synctest с фиктивными часами.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.