场景题:排行榜怎么设计?
刷到此贴的友友春招/暑期必上岸!!!
鼠鼠在秋招的过程中多次被问到场景题,中大厂的考察频率相当之高,一般会放在最后一个问题用来拖时间,也遇到过上来就问你怎么设计一个系统(面试官以此来决定后面对你的态度)。所以鼠鼠准备开这个场景题栏目,分享在秋招过程中遇到的场景题以及如何进行回答,感兴趣和感觉有帮助的友友点个关注和赞吧,你们的点赞和关注是鼠鼠持续更新下去的最大动力!!!
话不多说开启今天的主题,排行榜设计吧!!!
排行榜是很常见的一个功能,在社交软件、游戏等各种场景中都有应用,积分、点赞、礼物、战绩排名等各类排行榜功能,这些排行本质都是基于计数进行排序的。不同的场景会有细微的设计差异,这里只讲通用的排行榜系统该如何设计,遇到具体的场景再做细微的调整即可,就算在面试过程中只能答出本文所设计的通用排行榜,也足够了,毕竟对于应届生也只会考察到这个程度,面试是尽可能多的回答问题,很难追求所有问题都能回答出来……
大家可能看过一些八股文,会回答直接使用zset进行试试排行即可。
鼠鼠也曾在面试中这样回答过:将每个用户的得分作为zset中元素的score,将用户ID作为元素的value。使用zset提供的排序功能,可以按照分数从高到低排序。
当时面试官说如果分数相同,按照默认的排序规则会按照value值排序,他希望按照时间顺序排序,也就是分数相同的情况下先上榜的排在前面。
当时把鼠鼠给难住了,面完后才找到一个可行的方案:
为了实现分数相同按照时间顺序排序,可以将分数score设置为一个浮点数,其中整数部分为得分,小数部分为时间戳
即:score = 分数 + 1 - 时间戳/1e13
此时在分数相同的情况下,时间早的时间戳小,除以一个很大的数后得到的数字就小,被1减去以后得到的差就会大,也就实现了
分数相同的情况下先上榜的排在前面。
但面试官后面希望我聊一些系统设计的思路,当时鼠鼠完全没有系统设计的思路,不管后面复盘后也总结出了一套方法论,在这里分享给大家。
(1)明晰项目诉求:在这里就是设计出一个根据积分或点赞等数据进行排序。同时关注请求量,是否需要做高并发/高可用的扩展设计;此外对实时性是否也要要求,追求强一致性还是最终一致性
(2)确定业务逻辑:新用户上榜后排行榜要产生变化;用户积分发生变化后调整排名
(3)架构设计:存储(MySQL/Redis)+服务(是否需要拆分为多个服务)
大体上排行榜由两部分组成,排序结构和信息汇总结构。也就是我们在排行榜上看到的根据点赞数排出前一百,而信息汇总则是我们点击某一个用户头像可以看到其具体的用户信息。 系统设计初期,前端同步调用排行榜系统,对于并发量不大的情况,可以直接使用MySQL作为存储,直接操作数据库io即可,这里数据库的极限在5000/s。也可以先把全量数据从数据库里取出来后在内存中进行排序(前提是数据量不大的情况下)
但随着并发量和用户量上升,这种强依赖的同步调用会增加接口延迟。 这时可以增加中间层,也就是应对接口性能提不上去的三板斧之一(缓存,消息队列,分库分表)。如使用Rocket MQ或Kafka等消息队列(MQ)。流量大时可对排行榜系统起到削峰作用,还可批量插入数据库减少IO次数,提高插入效率。不过,使用MQ后要做好幂等处理(八股提问,MQ的消息幂等有哪些方式可以实现)。 当流量和并发量持续上升,数据库读写锁竞争加剧,可采用主从分离等方式均摊读压力,当然也可以直接考虑使用Redis作为排行榜。利用Redis的sortset类型排序(这里需要掌握zset,相关的八股文也要熟悉,可能会被问到),如排行评论数可使用ZINCRBY命令更新,查询用ZREVRANGE命令获取前N名排名和分数。 架构上可以由Redis作为消费者,它订阅MQ消息,消费时做幂等判断,用Lua脚本保证操作原子性。(这段话可以作为经典话术使用)
总结:
针对排行榜,简单的就直接可以使用Redis排序,但如果需要保证时间戳小的在前面就需要做一点小处理。
面对设计一个通用的排行榜系统,考察系统设计能力,这里就可以从我前面列举的方法论进行展开,多多关注我的文章,积累经验,相信友友们一定会越来越游刃有余。
PS:
其实在整个分析过程中大家可以发现,场景题其实就会把我们背的那些八股和技术运用起来,所以在学习场景题的时候就可以把八股文进行问题,有点像单词背不住就去读阅读文章,在读文章的时候记住八股文,在上面的分析过程中我也有几处进行了随机的八股提问。排行榜这个过程系统设计过程中有用到MQ,那友友们是不是可以顺带复习一下MQ的相关八股呢?
(1)如何保证MQ的消息幂等性?
(2)MQ的推模式和拉模式是什么?
(3)如何保证MQ消息不丢?
……
以上都是鼠鼠在面试中只要遇到Redis就一定会被问到的,不一定是全部问到,但至少都是三选一了…
好了如果大家有什么问题的话欢迎来评论区交流。包括但不限于文章创作改正意见,后续分享内容(面经,知识输出,经验分享等等),都看到这了,点个免费的关注和赞不过分吧