我有一个面试问题,说我需要存储几百万个缓存,然后我需要跟踪20个最旧的缓存,一旦缓存集合的阈值增加,用下一个最旧的缓存集替换20个最旧的缓存
我回答为它保留一个哈希映射,问题又增加了 如果我们想快速访问hashmap上的任何元素,该怎么做呢? 做,所以我告诉它的地图所以访问不会花时间,但是 面试官不满意。那么应该是什么样的闲置方式 场景。
答案 0 :(得分:4)
queue非常适合查找和删除最老的成员。
作为双向链表实现的队列在两端都有O(1)插入和删除。
priority queue有助于为队列中的不同项目赋予不同的权重(例如,某些队列元素可能比其他队列元素更昂贵)。
您可以使用哈希映射来保存实际元素,并根据哈希键快速找到它们,并使用哈希键的队列来跟踪缓存元素的年龄。
答案 1 :(得分:0)
通过为队列使用双链表并维护元素的哈希映射,您应该能够创建支持最大大小(甚至是LRU缓存)的缓存。这应该导致对存储3次的对象的引用,而不是存储两次的对象,如果你实现了这一点,请务必检查这个(一种简单的方法来避免这种情况只是对散列键进行排队)
检查溢出时,只需从队列中弹出最后一项,然后将其从哈希映射中删除
访问项目时,您可以使用哈希映射查找缓存项目。然后,如果您正在实现LRU缓存,只需将其从队列中删除并将其添加回开头即可。
通过使用此结构,插入,更新,读取,删除都将是O(1)
。
预期的后续问题是,面试官要求项目具有根据缓存项目而变化的生存时间(TTL)的能力。为此你需要有另一个队列来维护按生存时间排序的项目,这里唯一的问题是插入现在变为O(n)
,因为你必须扫描TTL队列并找到要到期的位置,所以你必须确定将TTL队列存储为n树的内存使用是否值得(从而产生O(log n)
插入时间)。或者您可以将TTL队列实现为每个~1分钟间隔或类似的桶,您仍然可以进行〜O(1)
插入,只会略微降低过期后台进程的性能,但不会太大(并且它是后台进程)。 / p>