前端面试题系列之手写LUR缓存

306 阅读2分钟
LUR缓存原理:
    将数据按照顺序放在一个固定大小的容器中。当访问一个数据时:
        1. 该数据不在容器中,则设置该数据的优先级为最高并放入容器中
        2. 该数据在容器中,则更新该数据的优先级至最高
        3. 当数据的总量达到上限后,则移除容器中优先级最低的数据
举例:
有一个固定长度为4的数组const arr = [1,2,3,4]
当arr.push(5),则长度超过4,则删除arr中的最前面的1,此时数组变为[2,3,4,5]
当查询arr的第一个数据时,即arr[1],则会将arr[1]放置到最后面,变为最新的数据,此时数组变为[3,4,5,2]

通俗点解释:只缓存最近使用的,最先加入的没有使用的则删除
核心API有:set  get
分析:
    1. 要考虑时间复杂度,set get的时间复杂度都为o(1),使用哈希表存储数据
    2. 数据存储必须是有序的,常用的数据放在最后面
    3. 哈希表 + 有序 ==> Map

思路:
    1. 使用Map数据结构来存储数据,查询和获取的时间复杂度都为O(1)
    2. set方法,设置时如果已经存在,则先删除,后加入到最后面,变为最新数据;如果超出指定长度后,则删除最前面的数据
    3. get方法,先删除后添加
    
有了思路,那么写代码跟着思路来就行了
class LUR{
    data = new Map()
    constructor(length) {
        this.length = length
    }
    set(key,value) {
        const data = this.data
        
        if(data.has(key)) data.delete(key)
        data.set(key, value)
        
        if(data.size > this.length){
            const oldKey = data.keys().next().value
            data.delete(oldKey)
        }
    }
    get(key) {
        const data = this.data
        
        if (!data.has(key)) return null
        
        const value = data.get(key)
        data.delete(key)
        data.set(key, value)

        return value
    }
}

就这么简单的实现了,下面测试一下
const arr = new LUR(4)
arr.set('a','a');
arr.set('b','b');
arr.set('c','c');
arr.set('d','d');

console.log(arr)
arr.get('a')
console.log(arr)

arr.set('f','f');
console.log(arr);

查看输出结果,非常简单了

image.png

Snipaste_2022-10-06_20-03-32.png

31.png