java面试每日一背 day1
1.什么是缓存穿透
缓存穿透是指查询一个数据库中根本不存在的数据,导致这个查询请求绕过缓存直接访问数据库的情况。这种情况如果频繁发生,会对数据库造成不必要的压力。
典型特征:
(1)查询的数据在数据库和缓存中都不存在
(2)恶意攻击者可能故意查询大量不存在的数据来攻击系统
解决方案 :
1. 缓存空对象
//优点:实现简单
//缺点:可能缓存大量无用的空键,占用内存
// 伪代码示例
public Object getData(String key) {Object value = cache.get(key);if (value != null) {if (value instanceof NullValue) { // 特殊标记的空对象return null;}return value;}value = db.get(key);if (value == null) {// 数据库不存在,缓存一个特殊空对象,设置较短过期时间cache.set(key, new NullValue(), 60); // 60秒过期} else {cache.set(key, value);}return value;
}
2.布隆过滤器
//优点:内存效率高
//缺点:有一定误判率(但不会漏判),需要维护布隆过滤器
// 伪代码示例
public Object getData(String key) {if (!bloomFilter.mightContain(key)) {return null; // 肯定不存在}Object value = cache.get(key);if (value != null) {return value;}value = db.get(key);if (value != null) {cache.set(key, value);}return value;
}
2.什么是布隆过滤器
布隆过滤器是一种空间效率极高的概率型数据结构,用于快速判断一个元素是否可能存在于集合中。它使用位数组和多个哈希函数实现,特点是查询速度快、占用内存小,但有一定误判率(可能误报存在,但绝不会漏报)。典型应用包括缓存穿透防护、爬虫URL去重等场景。
工作原理:
-
添加元素时,用k个哈希函数计算元素的哈希值,将位数组中对应位置设为1
-
查询元素时,同样计算k个哈希值,若所有对应位都为1则认为可能存在,任一为0则肯定不存在"
实际应用:
-
缓存系统:防止缓存穿透,如Redis缓存前先查布隆过滤器
-
网页爬虫:URL去重,避免重复爬取
-
安全领域:恶意网站/垃圾邮件过滤
-
数据库优化:减少不必要的磁盘查询"
优点:
-
内存占用极小(1亿元素约需114MB,误判率1%)
-
查询性能与数据量无关
-
可并行化处理
缺点:
-
不能删除元素(除非使用Counting Bloom Filter变种)
-
误判率随元素增加而升高
-
不支持获取实际存储的元素
"布隆过滤器的性能取决于三个参数:
-
位数组大小m:越大误判率越低
-
哈希函数数量k:过多会增加计算开销
-
元素数量n:实际插入的元素数
根据公式:最优哈希函数数量k ≈ (m/n)*ln2,工程中常用Guava库自动计算这些参数。