Qwen: Qwen3.5-9B 在「实现LRU缓存系统」的评测结果
这是该 AI 模型在此测试用例上的详细评测结果。
基本信息
- 模型名称:Qwen: Qwen3.5-9B
- 用例名称:实现LRU缓存系统
- 测试类型:文本生成
- 评测维度:代码生成
系统提示词(System Prompt)
这是给 AI 模型的背景设定和角色指令:
你是一名资深 Python 后端工程师,擅长数据结构与算法设计。 回答要求: 1. 在给出代码前,先用 2-3 句话简述你的设计思路(选用的数据结构及原因)。 2. 代码需包含完整的类定义、方法实现及必要的注释,风格符合 PEP 8 规范。 3. 在代码之后,提供至少 5 组测试用例(含边界情况),并给出每步的预期输出。 4. 说明核心操作(get / put)的时间复杂度。
用户提示词(User Prompt)
这是用户给 AI 模型的具体任务要求:
请使用 Python 实现一个 LRU(最近最少使用)缓存类 `LRUCache`,具体要求如下: **功能要求:** - 构造函数 `__init__(self, capacity: int)`:初始化缓存,容量固定为 3。 - `get(self, key: int) -> int`: - 若 key 存在于缓存中,返回对应的 value,并将该 key 标记为「最近使用」。 - 若 key 不存在,返回 -1。 - `put(self, key: int, value: int) -> None`: - 若 key 已存在,更新其 value,并将其标记为「最近使用」。 - 若 key 不存在且缓存未满,直接插入。 - 若 key 不存在且缓存已满,先淘汰**最久未使用**的 key,再插入新 key。 **实现约束:** - 必须使用 `collections.OrderedDict` 或手动实现哈希表 + 双向链表,不得使用普通 `dict` + 线性扫描的方式。 - `get` 和 `put` 操作的时间复杂度须为 O(1)。 **示例:**
任务要求
AI 模型需要满足以下要求:
- LRU 核心逻辑正确:get/put 操作后访问顺序更新符合 LRU 语义,缓存满时淘汰最久未使用的有效条目。
- 时间复杂度达标:get、put、delete 操作均为 O(1) 平均复杂度,通过手动实现哈希表+双向链表来保证,不得使用 OrderedDict。
- 过期机制实现正确:惰性删除在 get/put 时触发,过期条目不被返回也不更新访问顺序;purge_expired 能正确批量清除。
- 容量与过期联动处理正确:缓存满时优先清除过期条目再判断是否需要淘汰有效条目,避免错误淘汰未过期数据。
- 统计功能准确:hits/misses 计数在各场景(正常命中、未命中、过期访问)下均正确累计,hit_rate 计算无误,reset_stats 仅重置统计不影响缓存数据。
- 边界条件处理完善:包括 capacity=1、重复 put 同一 key、对不存在 key 执行 delete、所有条目均过期时的 put 操作等场景。
评测结果
综合得分
该模型在此用例的得分为:94.3 分(满分 100 分),已通过
基础难度评测结果
- 得分:94.3 分
- 通过状态:已通过
模型生成产物
以下是该模型针对此任务的实际生成内容:
# LRU 缓存实现 ## 设计思路 使用 `collections.OrderedDict` 作为核心数据结构,它内部维护了键值对的插入顺序,并能以 O(1) 时间复杂度完成查找和移动操作。通过 `move_to_end()` 将最近使用的 key 移至末尾,利用 `popitem(last=False)` 删除最久未使用的 key。哈希表功能由 OrderedDict 天然提供,链表顺序由有序结构维护。 ## 代码实现 ```python from collections import OrderedDict from typing import Optional class LRUCache: """ LRU 缓存实现,时间复杂度 O(1) """ def __init__(self, capacity: int): """ 初始化 LRU 缓存 :param capacity: 缓存最大容量 """ if capacity value def get(self, key: int) -> int: """ 获取 key 对应的 value,若存在则标记为最近使用 :param key: 要查找的 key :return: 对应的 value,不存在返回 -1 """ if key not in self.cache: return -1 # 将现有元素移到末尾(标记为最近使用) self.cache.move_to_end(key) return self.cache[key] def put(self, key: int, value: int) -> None: """ 插入或更新 key-value 对,若缓存满则淘汰最久未使用的 :param key: 要插入的 key :param value: 对应的 value """ if key in self.cache: # 更新 value 并标记为最近使用 self.cache.move_to_end(key) self.cache[key] = value else: # 缓存已满时,删除最久未使用的(第一个元素) if len(self.cache) >= self.capacity: self.cache.popitem(last=False) self.cache[key] = value ``` ## 测试用例 ```python def test_lru_cache(): cache = LRUCache(3) # 测试用例 1:基本插入和获取 print("=== 测试用例 1:基本插入和获取 ===") cache.put(1, 1) cache.put(2, 2) print(f"get(1): {cache.get(1)}") # 输出: 1,cache 顺序: [2, 1] print(f"get(2): {cache.get(2)}") # 输出: 2,cache 顺序: [1, 2] cache.put(3, 3) print(f"get(3): {cache.get(3)}") # 输出: 3,cache 顺序: [1, 2, 3] # 测试用例 2:缓存淘汰 print("\n=== 测试用例 2:缓存淘汰 ===") cache.put(4, 4) # 淘汰 key=1 print(f"get(1): {cache.get(1)}") # 输出: -1 print(f"get(3): {cache.get(3)}") # 输出: 3 print(f"get(4): {cache.get(4)}") # 输出: 4 print(f"get(2): {cache.get(2)}") # 输出: 2 # 测试用例 3:更新已有 key print("\n=== 测试用例 3:更新已有 key ===") cache.put(3, 100) # 更新 key=3 print(f"get(3): {cache.get(3)}") # 输出: 100 print(f"get(1): {cache.get(1)}") # 输出: -1 print(f"get(4): {cache.get(4)}") # 输出: 4 # 测试用例 4:空 key 和 value print("\n=== 测试用例 4:空 key 和 value ===") cache.put(0, 0) print(f"get(0): {cache.get(0)}") # 输出: 0 print(f"get(-1): {cache.get(-1)}") # 输出: -1 # 测试用例 5:边界容量 print("\n=== 测试用例 5:边界容量 ===")...
AI 评审点评
以下是 AI 评审对该模型输出的点评:
【CLAUDE】该实现整体质量较高,正确使用OrderedDict实现了LRU缓存的核心语义,get/put操作均达到O(1)时间复杂度要求。代码规范、注释完整、测试用例覆盖面广(包含容量为1的边界情况)。主要不足在于测试用例5中部分注释的期望输出需要更仔细的状态追踪验证,以及初始化复杂度的细节描述略有不精确,但这些均属于小瑕疵,不影响核心实现的正确性。 【GEMINI】该回答非常出色,不仅完美实现了 LRU 缓存的所有功能要求,还通过使用 Python 标准库中的 OrderedDict 高效地解决了算法复杂度问题。代码风格专业,测试用例设计周全,涵盖了多种边界情况,完全达到了资深工程师的交付标准。 【KIMI】该实现是一份高质量的LRU缓存代码,正确使用了OrderedDict实现O(1)操作,逻辑严谨,代码规范,测试用例充分。主要改进点:严格遵循题目「容量固定为3」的要求,或在文档中说明为何接受参数化容量。
进阶难度评测结果
- 得分:— 分
- 通过状态:未通过
模型生成产物
以下是该模型针对此任务的实际生成内容:
系统报错(阶段=模型生成; 模块=app.services.inference.call_text_model; provider=openrouter; model=qwen/qwen3.5-9b):[app.services.inference.call_text_model][provider=openrouter][model=qwen/qwen3.5-9b] 流式调用超时: 超过 120.0s 没有收到新数据
AI 评审点评
以下是 AI 评审对该模型输出的点评:
【CLAUDE】该候选输出并非模型生成的答案,而是一条系统级超时错误信息(模型在120秒内未返回数据)。实际上没有任何有效内容可供评估,所有维度均得0分。这属于模型调用失败的情况,与答案质量无关。 【GEMINI】由于模型在生成过程中出现流式调用超时(超过 120 秒无响应),导致未能输出任何有效内容。根据评测要求,该次生成被视为失败,各维度均评分为 0。 【KIMI】该候选输出为严重的服务故障结果,模型在120秒超时限制内未能生成任何有效响应。根据EVAL_BLOB,测试任务要求实现完整的LRU缓存系统,包括设计思路、完整代码、测试用例和复杂度分析,但候选输出完全空白。这是一个典型的生成失败案例,所有评分维度均无法获得任何分数。建议检查模型服务稳定性或调整超时配置,但对于本次评测,只能给予全零评分。
困难难度评测结果
- 得分:73.7 分
- 通过状态:已通过
模型生成产物
以下是该模型针对此任务的实际生成内容:
# 1. 系统设计概述 ## 1.1 架构设计 本系统采用**分片 + 多级缓存 + 降级**的混合架构,旨在解决高并发下的数据一致性、系统可用性和性能问题。 ### 架构图 (ASCII) ```text +---------------------------------------------------------------+ | Client (Requestor) | +---------------------------------------------------------------+ | v +---------------------------------------------------------------+ | CacheSystem (Manager) | | [ConsistentHashRing] [L2 Health Monitor] [Stats Collector] | +---------------------------------------------------------------+ | +---------------+---------------+ | | | v v v +---------------------------------------------------------------+ | Sharded Cache Cluster | | +----------------+ +----------------+ +----------------+ | | | Shard Node 0 | | Shard Node 1 | | Shard Node 2 | | | | (L1 Memory) | | (L1 Memory) | | (L1 Memory) | | | | + L2 Redis | | + L2 Redis | | + L2 Redis | | | +----------------+ +----------------+ +----------------+ | +---------------------------------------------------------------+ ^ | Source DB (Fallback) ``` ### 核心组件说明 1. **CacheSystem (Manager)**: 系统入口,负责初始化分片、监控 L2 状态、统计全局指标和降级控制。 2. **ConsistentHashRing**: 一致性哈希环,将 Key 路由到特定的 Shard,支持节点动态增减(虚拟节点)。 3. **LRUShard (L1)**: 本地内存缓存,基于**双向链表 + 哈希表**手动实现 O(1) 的 LRU 逻辑,非 `OrderedDict`。 4. **RedisClient (L2)**: 远程缓存,支持 Mock 和真实连接,负责写穿透和读回源。 5. **StatsCollector**: 收集命中率、热点 Key、降级次数等。 ### 关键设计决策权衡 | 决策点 | 方案选择 | 权衡分析 | | :--- | :--- | :--- | | **L1 数据结构** | 自定义 Doubly Linked List + Dict | `OrderedDict` 虽方便但缺乏底层扩展性;自定义链表便于手动控制 TTL、热点标记和 O(1) 移动。 | | **锁粒度** | 细粒度 Key 锁 + 全局状态锁 | 全局锁会导致高并发下串行化严重;Key 锁允许不同 Key 的读写并发,但需注意死锁风险(通过 `threading.RLock` 顺序获取解决)。 | | **数据一致性** | L2 写穿透 (Write-Through) | 确保 L2 与 L1 强一致性,避免 L1 数据过期后 L2 仍有效。 | | **降级策略** | 状态机 (NORMAL DEGRADED) | 避免频繁切换状态,L2 恢复后自动切回,保证业务连续性。 | ## 2. 核心代码实现 ### 2.1 类图与依赖关系 ```mermaid classDiagram class Node { +key: Hash +value: Any +prev: Node +next: Node +expire_at: float +hot_score: int } class DoublyLinkedList { +head: Node +tail: Node +size: int ++add(head, node) ++remove(node)...
AI 评审点评
以下是 AI 评审对该模型输出的点评:
【GEMINI】该回答在系统设计层面表现出色,展现了资深后端架构师的全局视野,组件设计完备,文档结构严谨。手动实现的 LRU 核心结构符合题目技术约束。然而,在核心的线程安全实现上存在严重逻辑漏洞,细粒度锁未能有效保护共享的链表结构,这在生产级别的高并发系统中是致命的。此外,部分功能点(如 TTL 定期清理、热点动态计数)仅停留在设计说明中,代码实现不完整且存在个别属性引用错误。 【KIMI】整体而言,候选人提供的解决方案在功能实现、线程安全、系统设计方面均表现出色,满足了题目的大部分要求。代码结构清晰,注释充分,具备一定的生产可读性。但在一些细节上仍有优化空间,如一致性哈希的Rehash过程、TTL的定期清理机制等。总体来说,这是一个高质量的多级LRU缓存系统设计方案。
相关链接
您可以通过以下链接查看更多相关内容: