译者:飞龙
自豪地采用谷歌翻译
从 Twitter 的起初,趋势话题已经成为这个流行产品的核心特征之一。从 Twitter 的趋势中,你可以很容易得知现在流行什么。难怪许多公司喜欢在系统设计面试中让候选人设计趋势算法。
我们在之前的文章 - 如何设计 Twitter(第二部分)中简要介绍了这个主题。由于这个问题如此受欢迎,我决定写一篇它的深度文章。
同样,Gainlo 没有一个人在 Twitter 工作过,不同的面试官也有自己的系统设计面试风格。所以,这篇文章的重点绝对不是给你这个问题的标准答案,而是给你这个话题的更多想法。
由于 Twitter 如此流行,我只会在这里简单地澄清这个问题。
对于为 Twitter 设计一个趋势算法,系统应该能够提供当前流行的主题列表。我喜欢把这个问题弄得一般而且有点含糊,因为我想看看候选人如何处理这样一个开放式的问题。例如,这里的流行没有明确定义。
如果你之前没有想过这个问题,我会建议你至少花 15 分钟考虑一下。有自己的解决方案,然后与其他人比较总是比较好。
好的,我们开始。
一个普遍的想法是让我们用一个词(或一个词)来表示一个主题,它可以是一个标签(如#gainlo
)或者只是一个单词(如唐纳德·特朗普)。如果与过去相比,一个术语在最近的推文中大量提到,那么这个术语应该被认为是流行的。例如,如果今天有数百万人在讨论#gainlo
,但是过去只有数百人谈论这个问题,#gainlo
当然应该是当前的热门话题。
我们应该与过去的检索量比较,是因为对于“星期一”或“天气”这样的常见词汇来说,它们的检索量在任何时候都非常大,在大多数情况下都不应该选择为趋势。
综上所述,基本思路是,对于每个术语而言,如果最近几个小时内的检索量与前 X 天的检索量之比很高,则将其视为一个热门话题。
当然,热门话题应该立即显示,这意味着我们可以要求用户等待一个小时,以便系统可以计算和排列所有术语。 那么最低的基础设施是什么样的?
显然,考虑到每天的大量推文,计算可能开销较大。 在这种情况下,我们可以考虑使用离线流水线。
更具体地说,我们可以让多个流水线在离线状态下运行,计算每个术语的比率并将结果输出到某个存储系统。 假设短时间内没有大的差别,流水线可以每隔几小时刷新一次。 所以当用户从前端检查热门话题的时候,我们可以预先计算出这个结果。
基本的做法真的很朴素,你有什么想法来改进它吗? 可以从任何角度来看,如降低系统开销,提高数据质量等。下面我将介绍几点思路。
如果你只是按照上面的解释计算比例,我很肯定会选择一些非常奇怪的术语。想想下面的情况,假设只有 300 人在推特上发表一个奇怪的话题#gailo-mock-interview
,过去从来没有人谈论过这个话题。比率(过去几小时内的检索量/过去 X 天内的检索量)为 1,可以列在列表的顶部。
显然,这不是我们想要展示给用户的东西。我相信你已经在这里发现了问题。如果绝对量不够大,可能会选择一些不受欢迎的术语。你可以计算最近几个小时内的检索量/(最近 X 天内的检索量+ 10000)
的比值,这样小的检索量就会被稀释。或者,你可以使用单独的信号作为绝对检索量得分与比值结合使用。
另一个想法是,如果一些话题由高端人士讨论,他们可能更有趣,更受欢迎。
有很多方法来设计这个算法。一种方法是首先确定谁是高端人士。我们可以简单地使用粉丝数(虽然有很多冒牌的意见领袖买了粉丝)。如果某个主题被任何意见领袖发推,我们可以计算这个主题推了多少次。因此,只需基于意见领袖的流行度将推文数量乘以一个参数即可。
有人可能会争辩说,我们不应该给意见领袖更多的权重,因为如果一个话题是趋势,就必须有大量的普通用户在谈论这个话题。这可能是真的。这里的重点是,直到你试一试,你才会知道结果。所以我绝对不是说这是正确的做法,但可能值得做一个实验。
不同的人有不同的品味和兴趣。我们可以根据不同的用户调整趋势列表。这可能是相当复杂的,因为你可以做很多事情来使其个性化。
例如,你可以根据一些信号,包括他以前的推特,他跟随的人和他喜欢的推文等,计算每个主题和用户之间的相关性分数。然后可以将相关性分数与趋势比率一起使用。
另外,位置也应该是一个有价值的信号。我们甚至可以计算每个地点(也许是城市级别)的趋势主题。
还有更多有趣的话题我还没有涉及。例如,很多话题都是一样的,系统如何对它们去重复呢?有没有其他信号可以被整合,比如用户搜索历史?
趋势算法是非常有趣和有用的。尽管我们使用 Twitter 作为例子,但我们讨论过的很多东西也可以应用到 Facebook 或其他平台上。