Files
examination/topics/thumbup/heavykeeper-topk/single_choice.json
T

168 lines
7.9 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"topic": "heavykeeper-topk",
"type": "single_choice",
"schema_version": "1.0.0",
"generated": "2026-09-09T21:42:00+08:00",
"questions": [
{
"id": "sc-001",
"type": "single_choice",
"difficulty": 2,
"tags": [
"heavykeeper-topk",
"heavykeeper"
],
"question": "HeavyKeeper 算法的核心设计目标是什么?",
"options": {
"A": "对所有元素进行精确频率计数",
"B": "从海量数据流中高效探测 Top-K 热点 Key",
"C": "替代 Bloom Filter 实现集合成员判定",
"D": "对数据流进行无损压缩存储"
},
"answer": "B",
"explanation": "HeavyKeeper 是一种面向流式数据的 Top-K 热 Key 探测算法,其核心设计目标是在有限内存下,从海量数据流中高效、准确地找出频率最高的 K 个 Key。它不是做全量精确计数(A),也不替代 Bloom Filter(C),更不是通用压缩(D)。其名字中的 'Heavy' 直接指向对热点(heavy hitter)的检测。",
"source": null,
"related": []
},
{
"id": "sc-002",
"type": "single_choice",
"difficulty": 2,
"tags": [
"heavykeeper-topk",
"heavykeeper"
],
"question": "HeavyKeeper 中 depth 参数(例如 depth=5)的含义是什么?",
"options": {
"A": "每个 Key 最多被计数 5 次",
"B": "数据结构维护 5 层独立的桶数组,每层独立散列",
"C": "Top-K 排序时保留前 5 个候选",
"D": "衰减淘汰的最大轮数为 5"
},
"answer": "B",
"explanation": "depth 表示 HeavyKeeper 的行数(层数)。整个数据结构是 depth × width 的二维桶矩阵(Bucket[][]),每一层使用相同的哈希算法但独立维护一组桶。一个 Key 会被散列到每一层的对应桶中,查询时取各层计数的最大值作为频率估计。多层设计通过冗余降低误判概率。",
"source": null,
"related": []
},
{
"id": "sc-003",
"type": "single_choice",
"difficulty": 3,
"tags": [
"heavykeeper-topk",
"heavykeeper"
],
"question": "在 HeavyKeeper 的 add() 方法中,当某个桶已有指纹不同的其他 Key(即发生冲突)时,算法如何处理?",
"options": {
"A": "直接覆盖桶中原有指纹,计数重置",
"B": "将两个 Key 的频率取平均值存入桶中",
"C": "按指数衰减概率递减桶的计数,有机会腾空桶后替换指纹",
"D": "将冲突 Key 溢出到相邻桶中"
},
"answer": "C",
"explanation": "HeavyKeeper 面对冲突时采用概率衰减淘汰策略:对于 increment 次尝试,每次以 lookupTable[bucket.count] 的概率(即约 0.92^count)递减桶计数。桶计数越大,衰减概率越低,热 Key 越难被淘汰。如果桶计数被减到 0,则腾空该桶并写入新 Key 的指纹和计数。这与 CMS 的简单计数累加形成鲜明对比。",
"source": null,
"related": []
},
{
"id": "sc-004",
"type": "single_choice",
"difficulty": 3,
"tags": [
"heavykeeper-topk",
"cms"
],
"question": "与 Count-Min Sketch (CMS) 相比,HeavyKeeper 在处理冷 Key 冲突时的关键优势是什么?",
"options": {
"A": "HeavyKeeper 使用更多的哈希函数,冲突概率更低",
"B": "HeavyKeeper 的冷 Key 会通过概率衰减被自动淘汰,不会持续污染热 Key 的计数",
"C": "HeavyKeeper 不会产生任何误判",
"D": "HeavyKeeper 使用更大的桶数组,冲突概率更低"
},
"answer": "B",
"explanation": "CMS 的致命缺点是:冷 Key 与热 Key 哈希到同一位置时,冷 Key 的计数会累加到热 Key 上,且永远不会减少,导致热 Key 频率被持续高估(污染)。HeavyKeeper 通过概率衰减机制,冷 Key(频率低)对应的桶计数小,衰减概率高,容易被清零淘汰,从而避免对热 Key 的长期污染。",
"source": null,
"related": []
},
{
"id": "sc-005",
"type": "single_choice",
"difficulty": 3,
"tags": [
"heavykeeper-topk",
"heavykeeper"
],
"question": "HeavyKeeper 中 lookupTable 数组预计算 0.92^i 的主要目的是什么?",
"options": {
"A": "用于对桶计数进行归一化处理",
"B": "避免运行时反复调用 Math.pow(),用查表法加速指数衰减概率的计算",
"C": "作为桶计数的上界阈值",
"D": "用于计算 Top-K 的排序分数"
},
"answer": "B",
"explanation": "lookupTable 是一个预计算的查找表,存储了 0.92^0, 0.92^1, ..., 0.92^255 的值。在 add() 的衰减逻辑中,每次需要计算衰减概率 decay = 0.92^count。如果每次用 Math.pow() 计算,性能开销很大。通过预计算并查表,将指数运算降为 O(1) 数组访问,显著提升吞吐量。",
"source": null,
"related": []
},
{
"id": "sc-006",
"type": "single_choice",
"difficulty": 4,
"tags": [
"heavykeeper-topk",
"heavykeeper"
],
"question": "HeavyKeeper 的 fading() 方法对所有桶执行 `bucket.count = bucket.count >> 1`,这种右移操作的实际效果是?",
"options": {
"A": "将计数除以 2 并向上取整",
"B": "将计数除以 2 并向下取整(等价于整数除法)",
"C": "将计数乘以 2",
"D": "将计数清零"
},
"answer": "B",
"explanation": "Java 中的右移运算符 `>>` 对正整数等价于整数除以 2 并向下取整。例如:5 >> 1 = 2,7 >> 1 = 3,1 >> 1 = 0。fading() 利用这一特性实现全局衰减,让所有桶的计数减半,模拟时间窗口滑动的效果,使算法能适应数据流分布的变化。",
"source": null,
"related": []
},
{
"id": "sc-007",
"type": "single_choice",
"difficulty": 4,
"tags": [
"heavykeeper-topk",
"heavykeeper"
],
"question": "HeavyKeeper 在桶中同时存储 fingerprint(指纹)和 count(计数),fingerprint 的核心作用是什么?",
"options": {
"A": "加速桶的哈希定位过程",
"B": "作为轻量级身份标识,用于验证桶中存储的是否是当前 Key,避免全 Key 比较",
"C": "替代 Bloom Filter 做存在性判定",
"D": "用于 Top-K 排序的优先级计算"
},
"answer": "B",
"explanation": "如果桶中只存计数而不标识属于哪个 Key,则无法区分当前桶是属于当前 Key 还是冲突的其他 Key。存储完整 Key 字符串又太耗内存。fingerprint 是 Key 的哈希值(如 64 位),作为轻量级身份标识,在 add() 和查询时用于快速判断桶是否属于当前 Key。虽然存在指纹碰撞可能,但概率极低。",
"source": null,
"related": []
},
{
"id": "sc-008",
"type": "single_choice",
"difficulty": 4,
"tags": [
"heavykeeper-topk",
"heavykeeper"
],
"question": "HeavyKeeper 中 minCount 参数(例如 minCount=10)的作用是什么?",
"options": {
"A": "桶计数低于此值时触发 fading 衰减",
"B": "只有累计频率超过此阈值的 Key 才有资格进入 Top-K 最小堆",
"C": "设置每个桶的计数上限",
"D": "控制哈希函数的最小散列粒度"
},
"answer": "B",
"explanation": "minCount 是一个入门门槛:当某个 Key 的估计频率达到 minCount 时,它才有资格被插入到维护 Top-K 的最小堆(minHeap)中。这一设计避免了将大量低频 Key 放入堆中,节省内存和排序开销。只有真正可能成为热点的 Key 才会参与 Top-K 竞争。",
"source": null,
"related": []
}
]
}