持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第23天,点击查看活动详情
关注(Follow)与取关(Unfollow)
若采用 Push 模型:
- 当一个用户 A 去 Follow 了用户 B 之后:将用户 B 的 Timeline 异步合并到 A 的 New Feed
- 当一个用户 A 去 Unfollow 了用户 B 之后:将用户 B 的 Timeline 异步从 A 的 New Feed 中删除
异步原因是这过程可能较慢,采用异步可迅速给到用户反馈,让用户觉得“已”关注或取关完成。随之问题是,用户在刷新自己的 News Feed 时发现,可能还会收到自己已经取关的用户的新鲜事。但终究该用户的 Timeline 中是会把自己已经取关的用户的新鲜事删掉。
明星出轨
惊群效应、缓存、缓存雪崩、缓存重建。《Scaling Memcache at Facebook》。
查询共同好友?
常规思路
没有一个系统会让你展现出来你所有的好友与你之间的共同好友,一般只要展示出来你和另一用户之间共同好友的 Top10 或 Top20,所以可简化系统设计。
若每次都去请求好友的好友list进行遍历,复杂度是 O(N * max(N,M)) :
- N,该用户的好友数
- M,他好友的好友数量
响应时间较慢,但其实可以提升响应速度而牺牲一点精确度(对用户体验牺牲也不 大),因为基于我们的需求,只需 TOP10即可 ,最终结果差一两名影响不大。
针对这一方案,也有对应优化策略:
- 每个用户额外使用一个表,记录与自己共同好友较多的 Top10 用户列表, 每次用户请求 Top10 时直接返回
- 当新加一个好友时,异步使用上述算法,求两个用户之间的共同好友,并且使用共同好友 Top10 表里面的最少共同好友的记录去比较,看是否需要更新结果。 同时,异步更新这两个好友的共同好友列表,因为有可能由于这次操作他们直接多了一个共同好友
还有个暴力方法,但也科学:
如对 QQ 来说,有好友上限的,假设为5000。针对系统来说,就算把一个用户的所有好友的 id 存放到缓存(比如 Redis)也就 80 KB左右,若计算交集,即便不使用 HashMap ,计算量的数量级大概在 10^7,系统计算反应时间也是ms级,其实直接使用缓存系统 + 暴力也可行。因为其实查询共同好友这一功能并不是一个非常常用的功能,通常也不会出现缓存雪崩或者缓存失效。
朋友圈的可见/不可见
总结
- 问清需求再设计
- 不做关键词大师
- 不试图设计一个最牛的系统,要设计一个够用的系统
- 先设计MVP,再逐步优化
- 系统设计无标准答案,和面试官一起探讨分析的过程比结果更重要