@Fenng前几天发了三道产品经理面试题。面试的时候有点意外,不过这道题是很好的产品设计和系统分析题。系统分析也是我们“产品经理技术”系列文章策划的一部分,也是我们所说的技术“升华”的一部分。下面我们试着回答这个问题。这是一个好的开始。如果你有好的答案,可以给我们留言讨论。朋友圈的基本数据结构设计是怎样的?既能实现独占读权限设置,又能兼顾性能?新闻的基本数据,如文字、图片、时间、地点等,不一一列举。这些数据基本上和权限、性能关系不大,可以理解为单独存储,纯技术性的。这里只讨论权限和性能相关的数据结构。在权限管理上,微信使用“标签”对用户进行分组,这个标签的分组与微信通讯录一致。在数据上,就是给每一个关系加上一个“标签”标记。这里需要注意的是,虽然微信关系对于产品使用中的用户来说是双向的(即相互关注),但是在存储的时候,关系数据是为这两个相互关联的用户建立的,即每个人独立拥有你自己的“地址簿”。这可以通过删除自己的朋友,而不是从其他人的通讯录中删除来看到。这是标签分组的基础数据,也是后面朋友圈权限管理的基础。对于个人朋友圈时间线可以看到的消息,按照一般的逻辑,先获取所有好友的消息,然后删除没有授权给你看的消息,删除用户消息您已阻止的信息,然后获取您当前看到的信息。时间线。如果是这样的逻辑,那就意味着每次刷新朋友圈,都要去所有的消息池中查找上面通讯录中好友的消息,判断用户是否有阅读每条消息的权限成立。这显然是一种低效的方式,更何况微信有这么大的流量和数据。因此,这种数据结构设计是不可行的。一般逻辑下,每次读取朋友圈的过程就解决了这个性能问题。大意是把需要大量计算的过程分散到平时分散的时间。这里的思路是:平时根据权限设置准备每个用户需要的时间线数据,使用时直接读取准备好的内容(刷新朋友圈)。那么答案就出来了:除了存储上面提到的文字、图片等基本信息外,还需要为每个用户存储一条时间线数据。请注意,它是每个用户一件。当然这里的“每份”不需要保存完整的信息,只需要保存消息的ID和时间(可能需要)。大家在刷新朋友圈的时候,只需要读取自己的数据即可。不需要在消息池中过滤,也不需要判断用户权限。那么如何实现权限控制呢?当用户发布一条消息时,会根据上面提到的标签设置相关权限,服务器会将这条消息写入到每个有权限接收消息的用户的时间线上。也就是说,在用户发布的那一刻,就进行了权限安排,而不是等到阅读的时候。这样自然减少了读取时的计算量,提高了效率。发布时进行权限控制(示意图,其实比这个复杂多了)。至于分库分表,就不展开了,知道有这么个东西就知道了。有时这种技术设计也限制了产品设计。那么你如何证明上述说法呢?有兴趣的同学可以去测试一下:先发一条有阅读权限的消息,比如允许某个标签的人阅读。然后给这个标签添加一个新人。结果是这个新人看不到这个消息,因为发布的时候权限划分好了,新人添加标签的时间是发布之后,所以没办法得到这个的权限分配机会消息,虽然他后来在标签组里,但还是没办法看到这条消息。这就是上述问题的答案。其实主要考察的是在产品设计中能否考虑到技术方案的局限性。我把上面的回答贴在知乎上,有人问:微信产品组是不是在设计之初就考虑到了这个问题,还是经过不断的迭代才变成这样的?这是一个很好的问题。一个好的产品经理在设计的时候应该考虑到这种情况,至少应该有相应的预案,才不会出现问题或者被研发攻击的时候束手无策。这种情况下,微信是一开始考虑的还是迭代的都无所谓了。对于微信的“朋友圈”来说,本来就是一个迭代产品。最早的权限管理是和通讯录分开的。当时是纯外挂。模式,现在才和通讯录共享分组模式进行权限管理。如果以上技术对产品设计的影响还不是很清楚,那就再问两个问题(好的产品经理不仅会答题,还会问问题^_^):1.朋友圈新闻为什么不能被编辑,只被删除?我理解这是产品设计和技术实现之间取得平衡的结果。对于以发照片和即时消息为主的朋友圈来说,编辑功能并不是硬性要求。然而,在上述技术框架下,编辑功能在技术上难以实现。具体来说:我们前面说过,权限的控制是在发布的时候就确定的。如果增加了编辑功能,意味着一旦用户在编辑时调整了阅读权限,需要将之前的权限写到删除用户时间线数据再写,这在技术实现上也是一笔不小的开销,并且需要更新大量数据(必须更新此消息涉及的所有用户的时间线数据)。因此,平衡的结果是让用户删除转发而不是提供编辑功能。你可能又会问了,删除的时候不需要更新相关人的时间线吗?首先,删除比写入要简单得多,其次,用户时间线的数据可能真的不需要删除。具体原因我就不说了。如果您想了解,请给我们留言单独说明。2、在释放时,上述权限分配规则是否考虑被屏蔽者?也就是说,如果用户A拉黑了某人B的朋友圈,那么B发布的消息是否会进入A时间线的准备数据(不是指用户在微信中看到的)?先说一下我的回答:发布时的权限控制不会考虑被屏蔽的人。前面我们说过,当一条消息发布时,服务器会根据用户设置的权限信息,有选择地将这条消息放入有权限阅读的人的时间线中。如果这时候需要考虑屏蔽的人,就得把每个有阅读权限的人的屏蔽人列表都读一遍,然后根据每个人的列表决定是否放到该人的时间线中。很显然,这又会增加多少计算量。那么有人会问,如何实现屏蔽功能呢?实现方式有两种,一种是在用户刷新用户读取的时间线数据(包括被拉黑者的消息)时,在服务端过滤掉被拉黑者的消息;另一种是读取时,服务端原样发送给客户端,客户端根据存储的屏蔽列表进行过滤,被屏蔽的不显示给用户。两种方式的执行效率几乎没有区别。从使用微信的经验来看,我比较容易被客户端过滤。其实这个也是有办法验证的,这里就不做了。这种屏蔽方案也是基于上述“将需要大量计算的过程分散到平时分散的时间”。那么如何验证上面关于屏蔽的逻辑是否正确呢?上面我们在“发布时分配权限”的验证中提到,后面添加标签组的人将看不到之前发布的组权限消息。这里我们也可以用类似的方法验证一下:拉黑一个用户后,该用户的所有消息都看不到了,但是解拉后,朋友圈里立马可以看到,包括之前发布的消息,但未读的消息。***我想说的是,作为微信设计的旁观者,以上回答是从系统分析的角度考虑用户的,并不代表微信确实是这样的设计思路,而是解决方案中的答案已经完成。或许可以验证。答案中没有涉及具体的技术,只是一个系统分析思路。很高兴看到越来越多的产品经理招聘开始关注技术技能。前段时间,各大互联网公司产品经理的校招中出现了很多与“技术”相关的试题,说明业界已经开始意识到技术能力在产品设计中的辅助作用。再次,技术不是产品设计所必需的,但如果有,效率会大大提高。
