字节实习一面代码题

实现一个带超时检测和容量限制的LRU缓存,面试的时候脑子浆糊没有写出来

package main

import (
	"container/list"
	"fmt"
	"sync"
	"time"
)

type Entry struct {
	Key, Val int
	Time     time.Time
}

type Cache struct {
	sync.Mutex
	mp         map[int]*list.Element
	ll         list.List
	size_limit int
	closed     bool
}

func (c *Cache) Get(key int) (int, bool) {
	c.Lock()
	defer c.Unlock()
	if elem, ok := c.mp[key]; ok {
		c.ll.MoveToFront(elem)
		value := elem.Value.(Entry).Val
		elem.Value = Entry{Key: key, Val: value, Time: time.Now()}
		return value, true
	}
	return 0, false
}

func (c *Cache) Set(key, val int) bool {
	c.Lock()
	defer c.Unlock()
	if elem, ok := c.mp[key]; ok {
		// key already exists, refresh the key
		elem.Value = Entry{Key: key, Val: val, Time: time.Now()}
		c.ll.MoveToFront(elem)
		return true
	}
	// create a new element
	elem := c.ll.PushFront(Entry{Key: key, Val: val, Time: time.Now()})
	c.mp[key] = elem
	for len(c.mp) > c.size_limit {
		deleted_elem := c.ll.Back()
		deleted_key, deleted_value := (deleted_elem.Value).(Entry).Key, (deleted_elem.Value).(Entry).Val
		c.ll.Remove(deleted_elem)
		delete(c.mp, deleted_key)
		fmt.Printf("#####     K-V pair (%d : %d) is removed due to limited capacity\n", deleted_key, deleted_value)
	}
	return true
}

func (c *Cache) Eliminate(life_span int) {
	for {
		if c.closed {
			fmt.Printf("Eliminator goroutine exits\n")
			break
		}
		c.Lock()
		// check the time of all K-V pairs
		for key, elem := range c.mp {
			if elem.Value.(Entry).Time.Add(10 * time.Second).Before(time.Now()) {
				// eliminate the K-V pair
				c.ll.Remove(elem)
				delete(c.mp, key)
				fmt.Printf("#####     K-V pair (%d : %d) is expired\n", key, elem.Value.(Entry).Val)
			}
		}
		c.Unlock()
	}
}

func main() {
	cache := Cache{
		mp:         make(map[int]*list.Element),
		ll:         list.List{},
		size_limit: 3,
		Mutex:      sync.Mutex{},
		closed:     false,
	}

	go cache.Eliminate(10)

	var operation string
	var key, value int

	for {
		fmt.Scan(&operation)
		if operation == `set` {
			fmt.Scan(&key, &value)
			cache.Set(key, value)
			fmt.Printf("K-V pair (%d : %d) is set\n", key, value)
		} else if operation == `get` {
			fmt.Scan(&key)
			v, ok := cache.Get(key)
			if ok {
				fmt.Printf("Value for key = %d is %d\n", key, v)
			} else {
				fmt.Printf("Key = %d doesn't exist\n", key)
			}
		} else if operation == `over` {
			cache.closed = true
			break
		} else {
			fmt.Printf("invalid operation\n")
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值