1. 位图法 bimap算法
应用场景:快速在大量的数中查找一个数、去除重复的数
优点:节省内存、查找速度快
- 假设有1亿个数,要在1亿个数里面找到是否存在666这个数,那么可以构建一个bitmap结构。用一个数组存0、1,将这一亿个数存到这个数组,数组只存0、1,默认数组所有位置的值设置为0,将一亿个数的值作为数组的下标将对应数组的位置赋值为1,比如数字10则将array[10]=1,构建好bitmap结构后查找一个数是否存在只需要o1,比如查找666这个数是否存在这一亿个数里面,只需要判断array[666]是否为1即可。
- 利用bitmap算法统计在线用户, 将用户id作为对应的位,1表示用户在线,0表示不在线。可以通过redis的setbit、getbit命令实现,例子 : setbit user_login 666 1。通过getbit user_login 666获取到userid为666的值为1即可知道该用户在线,通过bitcount user_login即可获取到在线用户数。
2. 布隆过滤器
应用场景:基于bitmap的扩展,可用于判断某个字符串一定不存在,但不能判断某个字符串一定存在
优点:节省内存空间,查找速度快
基于bitmap思想,由于字符串无法当作数组下标,因此可以通过多种hash算法,计算字符串的hash值,将获取到的hash值作为数组下标,之所以要用多种hash算法是为了提高准确性,避免过多hash碰撞导致准确率过低。假设3个hash算法,首先要构建一个数组,将每个要存放的字符串通过三种hash算法计算得到三个hash值,将hash值作为数组下标,将数组对应下标的值置为1。如果要查找字符串abcd是否一定不存在,则对abcd进行hash,假设算出hash值10、21、34三个值,通过判断数组这三个下标的值是否都为1即可判断一个字符串是否一定不存在。
为什么是只能判断一定不存在,不能判断一定存在?因为不管有几个hash算法,都会存在碰撞的情况,假设abcd字符串算出的三个hash值对应的数组位置之前已经都被置为1了,那么这个时候就不能说这三个位置都为1所以abcd一定存在。而且hash算法个数也不是越多越好,越多说明一个字符串占位越多,占用的空间和碰撞的机率也会提高。
基于以上的点有一条计算公式k表示hash算法个数,m表示数组容量,n表示插入的元素个数,k=m/n * ln2
redis同样也有布隆过滤器相关支持的插件,这里就不扩展,可参考掘金里这篇文章 https://juejin.im/post/5bc7446e5188255c791b33