51mee - AI智能招聘平台Logo
模拟面试题目大全招聘中心会员专区

在用户文件管理系统中,如何设计缓存策略?比如用户文件列表的缓存,使用LRU或LFU,结合热点数据(如常用文件),如何实现缓存雪崩、缓存穿透、缓存击穿?

万兴科技后端开发难度:中等

答案

1) 【一句话结论】:用户文件列表的缓存设计需结合热点数据优先,采用多级缓存(本地+分布式),并配合LRU/LFU淘汰策略,同时通过缓存预热、布隆过滤器、互斥锁等机制,有效规避缓存雪崩、穿透、击穿问题,核心是分层缓存+热点数据保护+容错处理。

2) 【原理/概念讲解】:
首先解释缓存策略中的LRU(最近最少使用):类比图书馆,最近被借阅次数最少的书籍会被移到不常用的位置,而频繁借阅的书籍保留在易取位置,缓存中淘汰的是最近最久未访问的记录。
接着解释LFU(最近最频使用):类似热门书籍,借阅次数多的书籍优先保留,淘汰的是访问次数最少的记录。
然后解释三大问题:

  • 缓存雪崩:当大量缓存数据同时过期失效时,所有请求都落库,导致数据库压力激增(如雪球越滚越大)。
  • 缓存穿透:无效key(如不存在的文件ID)查询时,缓存和数据库均无数据,导致所有请求都无效,持续消耗资源(如刺穿玻璃的针)。
  • 缓存击穿:热点key(如用户常用文件列表的根节点)同时过期失效,高并发请求瞬间落库,导致数据库瞬间压力过大(如玻璃突然碎裂)。

3) 【对比与适用场景】:

特性LRU(最近最少使用)LFU(最近最频使用)
定义淘汰最近最久未访问的缓存记录淘汰访问次数最少的缓存记录
核心逻辑时间维度,关注“最近”访问时间频率维度,关注“访问次数”
适用场景数据访问模式变化快,冷热数据区分不明显数据有明显的冷热之分,且热点数据访问频率高(如电商热销商品)
注意点可能误淘汰真正常访问但最近未访问的“冷热切换”数据可能导致新访问的“冷数据”被频繁淘汰,影响体验

4) 【示例】:
伪代码示例(请求文件列表):

def get_file_list(user_id):
    # 1. 检查本地缓存(如Redis的LRU)
    local_cache = redis_client.get(f"user_files_{user_id}")
    if local_cache:
        return json.loads(local_cache)
    
    # 2. 检查分布式缓存(如Redis集群)
    distributed_cache = redis_cluster.get(f"user_files_{user_id}")
    if distributed_cache:
        # 更新本地缓存
        redis_client.set(f"user_files_{user_id}", distributed_cache, ex=3600)
        return json.loads(distributed_cache)
    
    # 3. 从数据库获取
    db_data = db.query(f"SELECT * FROM files WHERE user_id = {user_id}")
    # 更新缓存(本地+分布式)
    redis_client.set(f"user_files_{user_id}", json.dumps(db_data), ex=3600)
    redis_cluster.set(f"user_files_{user_id}", json.dumps(db_data), ex=3600)
    return db_data

# 缓存预热示例(定时任务,加载热点数据)
def cache_warmup():
    hot_files = db.query("SELECT file_id FROM files WHERE is_hot = 1")  # 热点文件
    for file in hot_files:
        redis_client.set(f"hot_file_{file.file_id}", json.dumps(file), ex=86400)  # 24小时过期

5) 【面试口播版答案】:
面试官您好,关于用户文件列表的缓存设计,核心思路是分层缓存结合热点数据优先,同时处理三大问题。首先,缓存策略选LRU或LFU,比如LRU适合文件列表访问模式变化,LFU适合常用文件(热点)保留。然后,处理缓存雪崩:通过缓存预热(定时任务加载热点数据,设置稍长过期时间),或者设置随机过期时间。缓存穿透:用布隆过滤器过滤无效key,或者缓存空对象(设置极短过期时间)。缓存击穿:对热点key加互斥锁或分布式锁,或者设置短时间过期(比如1秒),避免同时失效。具体实现上,请求文件列表时,先查本地缓存(如Redis的LRU),若不存在,再查分布式缓存,若仍无,则从数据库获取,并更新缓存(本地+分布式,本地优先,减少分布式压力)。对于热点文件,比如用户经常访问的文件,可以设置更长的过期时间,或者加入热点缓存池,优先保留。总结来说,通过多级缓存、热点数据优先、以及针对雪崩、穿透、击穿的容错机制,提升文件列表的访问性能和稳定性。

6) 【追问清单】:

  • 问题1:如何实现缓存预热?
    回答要点:通过定时任务(如cron job)加载热点数据到缓存,设置稍长过期时间(如24小时),避免频繁失效。
  • 问题2:布隆过滤器如何处理缓存穿透?
    回答要点:布隆过滤器用于快速判断key是否可能存在,若不存在则直接返回,减少无效请求;若存在则再查询缓存/数据库。
  • 问题3:互斥锁在缓存击穿中如何优化?
    回答要点:对热点key加分布式互斥锁(如Redis的SETNX),保证同一时间只有一个请求更新缓存,其他请求等待,避免高并发落库。
  • 问题4:分布式缓存和本地缓存如何配合?
    回答要点:本地缓存(如进程内缓存)优先,减少分布式缓存压力;分布式缓存作为备份,本地缓存失效时回源分布式缓存,分布式缓存失效时回数据库。
  • 问题5:缓存淘汰策略的参数如何调整?
    回答要点:通过监控访问频率(如LRU的淘汰频率、LFU的访问次数阈值),动态调整缓存大小或淘汰策略,比如热点数据设置更长的过期时间,冷数据设置更短的过期时间。

7) 【常见坑/雷区】:

  • 坑1:忽略热点数据,所有文件用统一缓存策略,导致冷数据占用缓存资源,热点数据被淘汰。
  • 坑2:缓存雪崩时未做预热,导致全量请求落库,数据库瞬间崩溃。
  • 坑3:缓存穿透未处理,无效key持续查询,导致数据库压力持续增加。
  • 坑4:缓存击穿时未加锁,导致高并发请求同时落库,数据库瞬间压力过大。
  • 坑5:未考虑缓存击穿和穿透的边界情况,比如热点key的过期时间设置不合理(如过期时间过长导致缓存击穿,过短导致频繁更新)。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1