面试中遇到的设计题

本文探讨了设计秒杀系统的关键技术,包括前端的防刷单校验、静态资源部署、前端缓存策略;后端接口性能优化、高并发处理、系统稳定性保障等。此外,还介绍了红包系统的模型设计、高并发支持方案、唯一ID生成器设计、分布式限流机制,以及高考排名、数组去重排序等算法应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 如何设计秒杀系统

前端:

a. 一些防刷单校验,拉长整个交易流程,起到一个削峰作用

b. 静态资源多CDN部署

c. 前端缓存,有些页面的切换,不需要调用后端接口

后端:

接口性能优化:使用缓存,异步,多线程,功能降级等手段

还有些高并发时保证系统稳定性的手段:扩容, 升配,限流,降级

还有是想做系统隔离/数据隔离的方案 这种成本很高。

需要关注的点:读请求/写请求

读请求:

商详页:包括商详接口/促销活动接口/评论接口等。不是交易强依赖的接口可以考虑降级,如评论

商详接口如何支撑更高的qps:本地缓存,redis多数据副本,增加redis副本集群。

后续交易的接口,相比商详会低很多。

写请求:

更多关注库存:库存扣减qps在300左右。要支持的到超过redis单点瓶颈,可能需要考虑多副本的方式。

2. 红包系统怎么设计

1. 模型设计

红包池表,红包账户表,红包池表

2. 怎么支持高并发?

 高并发需要考虑这个并发是有多高?拿redis可支撑的写入速度作为分界线,8万/秒。

如果并发低于这个值?这个场景较好处理,使用redis作为主要的存储介质,需要使用lua脚本完成红包金额生成,红包扣减等动作。

如果高于这个值?可以考虑下吗几种方案?

一是. 使用消息队列,异步的方式,处理抢红包的请求,起到一个削峰的作用。配合的玩法,用户抢到红包后,需要一定的时间后才能打开红包。

二是. 一种类似分段id的方式,每个pod都会从db中取到一个子红包落在redis中,后面都可以依赖这个redis缓存进行扣减,如果本pod的缓存处理完,再充db中取一个子红包进行扣减。当db中扣减为0之后,再按照预设的规则尝试获取其它节点的缓存扣减。

最后,为了保证系统的稳定,一定要做限流。预期外的流量,不要接受。

3. 怎么做一个唯一id的生成器

雪花算法

41位的时间戳 + 10位机器码(机房id+机器id) + 12位序列号

时间戳是毫秒级;机器码由用户指定可能有重复的风险;12位序列号的范围是0~4096;

4. 分布式限流怎么做

使用令牌桶。原理:算法以固定的速度向桶中存放令牌;桶有一定的容量,如果桶满了,则将新生成的令牌丢弃;有请求过来会消耗令牌。

主要有4种算法:

固定窗口:边界值,无法精确限流,不可控。

滑动窗口:更为精确,但是没办法处理短时的高峰流量。

漏桶:处理请求的速度是恒定的,没有办法快速处理短暂的高峰流量

令牌:可以处理短暂的高峰流量,并且后面可以做到匀速的处理请求

面试必备:4种经典限流算法讲解 - 文章详情

如何选择QPS限流算法和令牌桶算法_金融分布式架构-阿里云帮助中心

5. 100万考生,高考排名怎么做?

思路1:计数排序

假设最高分是700

700,699,698.。。500。。。。4,3,2,1,0

每个分数一个bucket,然后存储分数对应的学生数量

6. 10亿数组去重排序

思路1:如知数组中的范围,可以按数值范围分成多个组,比如1-10000,10001-20000等。遍历原数组将每个数投递到对应范围的数组中。当然最极致的做法就是每个组一个元素,这样不需要排序就是有序的了。

如果不知道范围:

借助hash算法思想,把一个大文件哈希分割到多个小文件中,而哈希冲突的数字

一定会在同一个小文件中,从而保证了子问题的独立性,小文件可以使用set结构去重,然后就可以单独对小文件通过快速排序来排序。最后再通过多指针的方式进行全局范围的排序

7. 游戏top实时排行榜

思路1:小顶堆

8. 设计微信摇一摇功能(设计微信附近的人功能)

假设自己的位置的经纬度是j,w, i 表示范围。那么附近的人的原理就是检索范围在j-i<经度<j+i, w - i<维度< w + i;

使用数据库来做也是可以的。但是如果直接这么做的话,当用户数上亿后,检索效率会很差。

 幸运的是redis中的geo结构,可以解决这个问题。

redis中的geo接口,直接提供附近x公里内,最近的n个人,并支持排序和显示实际距离。

geo,底层实现,使用二刀法,将整个地球切成无数的小块。每个小块都有固定的编码,每个编码都有负责的经纬度范围(使用base32算法)。当向geo结构中加用户时,会根据用户的经纬度确定用户在的区域块,在同一个块上的用户就会有一样的编码。所以,后面搜索附近的人的时候,就可以减少搜索的范围,在自己的小块或者周围的小块进行搜索。

9. 如何去设计一个feed流的系统

feed流系统的基本功能:比如朋友圈,一个用户的feed流,他需要展示所有好友发布的帖子。

大致的方案有3类:

        1. 推型:每发一条帖子,需要向自己的所有好友。

                优点:对于好友少的用户是可行的,写扩散的范围可控。

                缺点:如果一个用户的好友有1万,用户每生成1条朋友圈,就会产生1万条记录

        2. 拉型:用户浏览拉取所有好友的朋友圈,不主动推送

                优点:比较简单,不会有写扩展

                缺点:会产生读扩散,需要拉取所有好友的帖子,一起按时间排序

        3. 推拉结合:先采用打标签的方式将用户分为两类:活跃和不活跃。对于活动的用户,采用推送的方式。对于不活跃的,采用拉的方式。

优点:在资源有限的情况下,至少保证核心用户的体验。

缺点:推型和拉型的缺点都是有的。

总结:相比微博大V有近的粉丝的场合,微信1万好友的上线已经是非常小了。所以在写扩散可控的情况下,可采用推型的方案。

而如果是微博这种,使用推拉结合的方式会更好些,毕竟僵尸用户比较多,只推些活跃用户就可以,没必要全量推。

怎么设计feed流的删除/更新场景?

像微信是不支持更新的,删除场景的话,其实删除点原贴就好,feed流中其实存的是帖子的id,如果原贴没有了,根据id找不到记录就是删除后了。所以发贴人将帖子删除,他的好友是立即就看不到了的。

更新的场景:因为帖子的内容只存一份,不存在写扩散,所以也很简单。

10.如何设计一个短链系统

核心功能:

        短链生成:生成唯一key(只要唯一就可以,是否依据内容无所谓),将key换成62进制。然后短链为key,长链为value存放在redis和db中。最后将生成的短链返回给客户端。

        短链换成长链:从缓存或db中,根据短链获取长链。

11. 超高并发场景下的直播红包发放业务的架构设计

核心问题:单个红包如果抢的人数达到100万,怎么设计这个架构。

思路:redis写场景,单点的qps上限10万。 100万,超过了单点redis的极限。所以这里的数据可能是要拆的。

思路:使用redis多副本节点,节点数据来自db。每个pod,可以按规则指定轮训消费不同副本的数据。如果消费完,需要从db里面再取。db里面没有,再去轮训消费其它副本的数据。

方案1:创建reids数组,数组里是也是数组,内层数的大小比如是10,存放的内容是红包的key。用户获取红包的请求,打到应用,应用访问redis获取可分配的红包数组,并存在本地。拿到可分配的红包key之后,查询redis获取红包。

-- 问题:在负载均衡不那么平衡的情况下,有些应用可能红包消耗的快些。用户端会出现第一次点提示红包抢完,第二次点,出现红包抢成功的情况。但是这种情况也是少量,问题不大。

方案2:将红包服务设计成可相互通信的有状态服务,本pod如果红包分配完,可以将请求转给有红包的pod

方案一的补充:如果红包金额不是等额的。创建红包时,可以提前生成每个红包的数值(这种方式,避免了在领取时计算,需要依赖红包余额的情况,避免单点数据依赖瓶颈),数据格式key-value:key是(红包id+自增id),value是对应的红包金额(这块数据可以存在db中,增加领取状态和领取的用户id)。这块数据使用使用时,需要加载到redis中。领取红包请求到pod时,可以直接使用内存的红包映射找到,具体的金额。领取红包请求获取到具体金额后,就可以投递到消息中间件了,然后向客户端返回领取的金额。扣主播红包,记录领取记录等动作可以后面再支持。

-- 存在问题:红包编码和金额映射,会暂用很多的内存空间。按一个key-value=20by计算,100万占用20M。但是,集群模式的redis,数据是分散分布,内存问题也好解决。

总结:100万的热点写并发,确实是个很难得场景,解决起来是很麻烦的。

参考:超高并发场景下的直播红包发放业务的架构设计

12. id生成算法有哪些?

UUId:java的uuid使用的是版本4, 通常使用伪随机数生成器(PRNG)或加密安全随机数生成器(CSPRNG)来生成, 但理论上碰撞概率极低(2^122 的可能性),可以认为在实际应用中是唯一的。

自增id:数据库自增id、数据库段号模式(id生成服务使用)

雪花算法:毫秒时间搓 + 机房id+机器id+自增数(0-4096)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值