太长不看版:
你那些设置了分组可见(不可见)的朋友圈,在发出去的一刹就决定了哪些人而不是哪些组能(不能)看到。即使你在发完这条朋友圈之后更改了分组里面的成员,你的好友能否看到这条朋友圈,也和你后续的更改操作无关!
————————————————————
1
想象这样一个场景:
A是你的领导但还不是你的微信好友;
你在朋友圈发状态吐槽“领导脑子瓦特了”,发送时选择对“同事”分组不可见;
后来你因为某个机会加了A领导为好友,你机智的在添加好友时,就把A分在了“同事”组。
请抢答:
你的领导在翻你朋友圈时,能不能看到你说他“脑子瓦特了”的那条朋友圈?
答案是:
领导能看到!能看到!看到!卒...
(但是,你之前发的那些对“同事”分组可见的加班熬夜朋友圈,你的老板却并不能看见)
生活是不是充满了惊吓?但这就是微信朋友圈可见权限的实现机制。我们在经过多次实验和分析,发现微信的朋友圈的每一条在发送时设了分组的状态,都是被直接链接到人,而不是链接到分组的。
2
为了搞清楚这种权限机制,我们(H、W和我)做了这样一组实验:
第一步:
我把H加进“测试”分组;
(这里说的分组,当然是好友分组标签,不是一个微信组)
第二步:
我发送一条对“测试”分组不可见的朋友圈“test”;
(H看不见test,W能看见test)
第三步:
我把W加进“测试”分组;
(H看不见test,W依然能看见test)
第四步:
我发送一条对“测试”分组不可见的朋友圈“test2”;
(H看不见test和test2;W能看见test,看不见test2)
第五步:
我把H移出“测试”分组;
(H还是看不见test和test2)
第六步:
我发送一条对“测试”分组可见的朋友圈“test3”;
(H看不见test3,W能看见test3)
第七步:
我把W移出“测试”分组;
(W还是能看见test3)
到此,实验完成了。在整个过程中,H看不见test、test2以及test3,W能看见test和test3但不能看见test2。并且他们能否看见一条朋友圈的事实,没有随着发完朋友圈后我对他们分组的改变而改变。
3
这个权限机制是如何实现的呢?
从关系型数据库表结构的角度分析,可以用很多种复杂的表结构来实现这个功能,但是我们推测在微信的数据库里,与朋友圈相关的表大概率有以下几张:
a、主表
b、好友表
c、朋友圈表
表间关系如下图(只把主要及相关的画出来了,并不完整):
当A刷新/访问C的朋友圈时,相当于发出了一个请求:我来看C啦!
于是通过C主表里的朋友圈表地址找到C所有的朋友圈,按时间逆序逐条执行以下操作:
由于可见/不可见名单的内容在每一条朋友圈产生时,就一起写入了朋友圈表,所以该名单和当前分组情况并不相关。而具体分组很可能是仅存在于用户前端的逻辑,避免在数据库中占用资源。
4
如果要避免第1节中场景描述的情况,朋友圈的权限机制应该如何设计?
更改数据表的结构就可以做到,下图是一种可行的更改后的表结构(红色表示改动部分):
修改过程包括在数据库中新增每个分组的表,以及把朋友圈表里原来直接链接到一个确定名单的方式,改成了链接到分组的地址。
这样调整一下,就能一劳永逸的解决问题了!
5
第4节中提到了解决问题的方案。但是这两种方案的优劣应该如何评价呢?微信提供的权限机制不尽如人意,是忽略了这样的细节设计,还是为了其他性能或功能而进行了这种权衡?
在评价一种算法的时候,我们常用执行时的时间复杂度(花了多少运算时间)和空间复杂度(花了多少运算空间)进行衡量。所以在这份不权威不靠谱的分析中,我就从上述两个概念以及存储空间的角度,对比一下这两种方案的优势劣势。(因为我懒,下文用A方案表示微信当前采用的方案,B方案表示第4节提出的修改方案)
首先做一个还算合理的假设:每个人平均有n个微信好友、发了m条朋友圈、设了k个分组。从统计角度,n的数量级是10^3,m是10^2,k是10^1。
运算时间:
A方案刷新每一条分组朋友圈时,需要在一份长度为10^3量级的名单中查找某个目标,这个查找过程对于tree结构来说,时间复杂度是O(log(n)),对于Hash Table结构来说,最优复杂度可以达到O(1)。
B方案刷新每一条分组朋友圈时,需要在k份长度为10^3量级的分组名单中查找某个目标,运算时间是A方案的k倍。
由于k的量级只是10^1,对于单次响应,B方案并不比A方案慢太多(毫秒级别)。
运算空间:
A方案刷新每一条分组朋友圈时,需要把这条朋友圈对应的长度为10^3量级名单从云端数据库读取到云端缓存中;而B方案需要把k份长度为10^3量级的分组名单读取到云端缓存中。
B方案对于运算空间的占用是A方案的k倍。对于微信这个10亿用户体量的应用而言,并发的用户请可能求会在有限的运算资源情况下带来明显的延迟效果。
存储空间:
A方案中,一个微信用户的每一条分组朋友圈,都需要保存一份长度为10^3量级名单。假设一个用户ID长度为4 byte,一份名单的长度就是4*10^3 byte,大约为0.004M。对于一个平均发了100条分组朋友圈的用户,这部分功能需要的存储空间大约为0.4M。假设微信有10亿用户,这里总共需要的存储空间的量级约为10^8M。
B方案需要把用户的每个分组新建一张长度量级为10^3的表保存在数据库中,共占用k*10^3的存储空间,但对于朋友圈表,则不需要新增可见/不可见名单。这种方案,对于一个用户,相关的存储空间需求是k*10^3。同样假设一个用户ID长度为4 byte,这里的存储空间相当于0.04M。假设微信有10亿用户,这里总共需要的最大存储空间的量级约为10^7M。
总结
A方案在执行效率上优于B方案;而在存储空间上,由于估算的误差,并不能说A、B方案有显著差异。
所以选择用A方案而不是B方案,实际上是执行效率和用户权限机制满意程度的一种trade off。基于“响应时间的增加会极大的影响用户体验”这一互联网圈的共识,A方案在一定程度上比B方案更适合微信。
6
看到这里,我就快讲完了。
是不是很失望?你作为一个用户,并没有办法改变这种权限机制。而你发分组朋友圈,也必须在“让不该看见的人看见”和“让该看见的人看不见”之间做选择。
既然看到这里了,我也嫑脸的求个关注吧!
我们的团队是来自中国香港科技大学计算机系的在读研究生和博士。这个微信公众号,目前有三个小伙伴一起运营,主要会用接地气的方式给大家分享一些区块链的技术及应用,以及互联网产品视角下的一些思考。欢迎大家提出问题和我们一起探讨,也欢迎来监督我们持续更新!
领取专属 10元无门槛券
私享最新 技术干货