大意失字节

98 阅读3分钟

前几天面试,字节前面聊得很好,从百草园聊到三味书屋。感觉氛围也不错,然后剩下就是喜闻乐见手撕算法环节了。定睛一看,实现一个带过期时间的LRU(最近最少使用) 缓存),

下附:leetcode 146. LRU 缓存,只是多了一步如果一段时间内没有任何操作,就去清空缓存。

我一看到这题当时就乐了,这么简单冲(我还写过),看我不秒了他。

but! 我马上就被打脸了。我刚想动笔(呸,键盘),面试官打断了我,说:能说一下你的思路吗?

  • 我:就是利用map哈希表这个数据结构,它内部是有序的,可以记录set的插入顺序。利用这个机制去实现lru.
  • 面试官:嗯嗯,那怎么去实现清除缓存呢?
  • 我:emmm,我觉得可以在初始化时候设置一个变量去保存settimeout计时器,然后去判断清楚?
  • 面试官:那如果是你要做redis 这种缓存系统,同时有大量缓存需要处理?如果都使用计时器会不会性能不好?
  • 我:。。。(无话可说中,尬住了)
  • 面试官:那先来写一下settimeout吧。

话不多说先上代码吧

const lru = function(time,n){
   this.map =new Map();
   this.capacity = n; //容量
   this.timer = null; //计时器
   this.time = time; //倒计时
}
lru.prototype.get = function(id){
   if(this.timer){
    clearTimeout(this.timer)
   }
   this.timer = setTimeout(() => {
     this.map.clear();
   },this.time);
   const res = this.map.get(id)
//    this.map.delete(id);
//    this.map.set(id,res);
   return res;
}

lru.prototype.set = function(id,obj){
    if(this.timer){
        clearTimeout(this.timer)
       }
    this.timer = setTimeout(() => {
         this.map.clear();
    },this.time);
    //    this.map.delete(id);
    //    this.map.set(id,res);
    this.map.set(id,this.map.get(id)?this.map.get(id):obj);
    if(this.map.size>this.capacity){
       this.map.delete(id);
    }
}

如上所示。

我写完之后,刚准备调试,面试官说,不调试了,你先说一下思路吧。我心想嗯? 我写这么好?不调试?;

然后我就开始,一股脑的输出。后面自己都给自己吹出自信了。面完过后,立即找hr说有消息通知我,我自我感觉良好。

then

晚上我就收到了,不合适的通知,原因就是说理论知识掌握可以,就是动手能力不行!

what?

我立即复盘,回想自己的代码,都把自己看吐了。相信眼尖的小伙伴们都看出了。下面我放出改进后的代码对比一下

const lru = function(time,n){
   this.map =new Map();
   this.capacity = n; //容量
   this.timer = null; //计时器
   this.time = time; //倒计时
}
lru.prototype.get = function(id){
   if(this.timer){
    clearTimeout(this.timer)
   }
   this.timer = setTimeout(() => {
     this.map.clear();
   },this.time);
   const res = this.map.get(id)
   this.map.delete(id);
   this.map.set(id,res);
   return res;
}

lru.prototype.set = function(id,obj){
    if(this.timer){
        clearTimeout(this.timer)
       }
    this.timer = setTimeout(() => {
         this.map.clear();
    },this.time);
       this.map.delete(id);
       this.map.set(id,res);
    //this.map.set(id,this.map.get(id)?this.map.get(id):obj);
    if(this.map.size>this.capacity){
       this.map.delete(id);
    }
}

相比上面,我把注释内容释放出来,方便对比,我犯了致命错误,最开始的代码连基本需求都没实现。map 内部是会去记录set 的顺序,但是get操作的顺序没有记录,为了保持操作之后的顺序,每次set,get 时都要先去删除再去set ,get 。按照原来写的,我根本就没保证顺序。等于就没去实现。

怪不得,面试官没有给我去调试的机会。。。

可惜,I have a long way to go.

我后面又想了好久实在没想到怎么去不用settimeout实现清楚操作。希望评论区给出答案哈~