如果一个boy看到一个girl的照片,心动右滑了她(like),
同时,这个girl也右滑了他,就匹配成功。
这就是探探APP社交匹配模式。
你有没有想过后台是怎么让他们找到对方的,他们真的是互相点了对方的名字吗?
或许,某些程序员会微微一笑。我们一步步猜测下,探探是怎样实现匹配的。
匹配实现,非探探官方,一切只是猜测首先,第一个方案,将数据存储进数据库,当A右滑B,就select下B是否右滑A。
虽然简单快捷,缺点却很明显,速度慢,浪费系统和数据库资源,存储空间大。
第二个方案,采用BitMap,如A用BitMap记录自己喜欢的人,B右滑A时去检查下A的BitMap有没有B即可。
用java.util.BitSet写个的实现如下:
这样,就是真真切切的,你喜欢她,她喜欢你。
BitMap是使用一个位记录一条信息,相对于第一个方案,确实是少了空间,并提升了速度。
其实,空间占用还是很大的,一个long有64位,只能记录64条数据。如果有10个用户,就有10亿个BitSet,分布式系统放redis的话,就有10亿个key。想想,心都凉凉。
换个角度,只用一个key如果A喜欢B,写下誓言【BofA】,放到池子里.....
一段时间后,B喜欢A,先去查找池子里有没有【BofA】,如果有就证明A喜欢B,A和B匹配成功。
如此,问题就转换为字符串查重。
此时此景,是不是让你浮想联翩,是不是有很多面试题涌现脑海,比如40亿个URL查找重复的等等。
实现字符串查重,可以采用布隆算法和Trie树。
Trie树在之前文章《》有提到过,在这里就不累述。
布隆算法的思路,跟BitMap其实有类似的地方,BitMap用一个位为1去记录一条信息,bloomfilter是用n个位为1去记录一条信息。那bloomfilter能记录的信息是多了,还是少了,取决于n的取值。这样一来,就成排列组合问题。
比如8位取2位记录一个信息,总共只能记录28个信息。如果要记录的信息超过28个会怎么样呢?
这个就是布隆算法的缺陷,存在误判,官方术语叫做false-positive(假阳性)。当然,bloomfilter并不是按排列组合随意选取下标的。
拿google guava bloomfilter实现来说吧,它是现将字符串用murmurhash3算法转换为一个128位的数组,接着取低64位用一个哈希函数取得hash1,再取高64位用另一个函数函数取得hash2,采用以下公式取得n个位置的下标
hash = hash1 i*hash2 0=<i<=n
从上面分析来看,采用bloomfilter是节省了很大的空间的,相信也会是大部分公司选择的方案。
这样,就会存在0.001(fpp=0.001)的概率,你喜欢她,她不喜欢你,可你却matches了她。误判,也是一种缘分。
上图是使用guava bloomfilter写的实现。最后,写了个jmh的基准测试。
以下是benchmark
Copyright © 2008-2022 秒下下载站
m.down10s.com .All Rights Reserved