Нужна простая библиотека in-memory кеша по заданному интерфейсу. Вытеснения
нет — считаем, что память бесконечна. Кешем пользуются из многих горутин
одновременно.
type Store interface {
Set(k, v string)
Get(k string) (v string, ok bool)
}
func New() *Cache // *Cache реализует Store
Требования
Get возвращает последнее значение, записанное Set по этому ключу, и
ok == true. Для отсутствующего ключа — "", false.
- Пустая строка — нормальное значение:
Set("k", "") → Get("k") даёт
"", true.
Set и Get безопасно вызывать из любого числа горутин одновременно.
Код проходит go test -race.
- Работает «из коробки» после
New().
Пример
c := New()
c.Set("lang", "go")
v, ok := c.Get("lang") // "go", true
_, ok = c.Get("rust") // "", false
// now — источник времени (в проде time.Now, в тестах — фейковые часы).
func NewTTL(ttl time.Duration, now func() time.Time) *TTLCache
*TTLCache тоже реализует Store. Запись живёт ttl с момента последнего
Set по этому ключу; по истечении Get возвращает "", false.
- Повторный
Set продлевает жизнь ключа.
- Время берётся только из
now, а не из time.Now напрямую.
Устно: нагрузка чтение/запись 50/50 — поможет ли RWMutex, что делать
(шардирование)? Как чистить протухшие записи, чтобы они не копились?
Стоит ли кешировать «не найдено»? Что менять, если данных станет больше, чем
памяти?
Разбор и эталонное решение — после своей попытки: на собеседовании подсказок не будет.
Сначала попробуй сам — подсказки не дают готовый ответ.