Caching 如何存储数百万个缓存,然后跟踪20个最旧的缓存

Caching 如何存储数百万个缓存,然后跟踪20个最旧的缓存,caching,data-structures,language-agnostic,Caching,Data Structures,Language Agnostic,我收到一个采访问题,说我需要存储数百万个缓存,然后我需要跟踪20个最旧的缓存,一旦缓存收集阈值增加,就用下一组最旧的缓存替换20个最旧的缓存 我回答为它保留一个hashmap,问题再次增加 如果我们想快速访问hashmap上的任何元素怎么办 是的,所以我告诉了它的地图,所以访问不会花费时间,但是 面试官并不满意。那么,对于这些人来说,什么才是空闲的方式呢 情景 A非常适合查找和删除最老的成员 实现为双链表的队列在两端都有O(1)个插入和删除 A有助于为队列中的不同项目赋予不同的权重(例如,重新创

我收到一个采访问题,说我需要存储数百万个缓存,然后我需要跟踪20个最旧的缓存,一旦缓存收集阈值增加,就用下一组最旧的缓存替换20个最旧的缓存

我回答为它保留一个hashmap,问题再次增加 如果我们想快速访问hashmap上的任何元素怎么办 是的,所以我告诉了它的地图,所以访问不会花费时间,但是 面试官并不满意。那么,对于这些人来说,什么才是空闲的方式呢 情景

A非常适合查找和删除最老的成员

实现为双链表的队列在两端都有O(1)个插入和删除

A有助于为队列中的不同项目赋予不同的权重(例如,重新创建某些队列元素可能比其他队列元素更昂贵)


您可以使用哈希映射来保存实际元素并根据哈希键快速查找它们,使用哈希键队列来跟踪缓存元素的年龄。

通过使用队列的双链接列表并维护元素的哈希映射,您应该能够创建支持最大大小的缓存(甚至LRU缓存)。这将导致对对象的引用被存储3次,而不是对象被存储两次,如果您实现了这一点,请确保对此进行检查(避免这种情况的一种简单方法是将哈希键排队)

检查溢出时,只需从队列中弹出最后一项,然后将其从哈希映射中删除

访问项目时,可以使用哈希映射查找缓存的项目。然后,如果要实现LRU缓存,只需将其从队列中移除,并将其添加回起始位置,如下所示

通过使用此结构,插入、更新、读取和删除都将成为
O(1)


接下来的问题是,面试官会问,每个缓存的项目都有不同的生存时间(TTL)。为此,您需要另一个队列来维护按生存时间排序的项目,这里唯一的问题是插入现在变成
O(n)
,因为您必须扫描TTL队列并找到过期点,因此您必须决定将TTL队列存储为n树的内存使用是否值得(从而产生
O(log n)
插入时间)。或者,您可以将您的TTL队列实现为每~1分钟或类似时间间隔的存储桶,您仍然会得到~
O(1)
插入,只是稍微降低了过期后台进程的性能,但不会太大(这是一个后台进程).

这意味着保留一个单独的队列,该队列将保留20个最早的地图项目的引用,但在地图中存储数百万条记录是最有效的方法吗。。。具有一个队列,其中包含对所有缓存元素的引用。映射在基于哈希键查找元素时非常有效,但在基于搜索条件(如时间戳)查找元素时效率极低。队列只能保存哈希键。。。使用队列根据年龄对元素进行排队和出列,并使用hashmap保存实际对象。您的采访者似乎在描述一个似乎没有任何琐碎实现的对象。应该有助于有趣的学习。。。