八股文之方案设计

miloyang
0 评论
/ /
275 阅读
/
5431 字
09 2024-01

扫码登录到底是怎么实现的?

扫码登录的本质是,通过已经登录过的App 应用,扫描未登录的Web 端程序中的二维码, 通过某种机制触发登录凭证的写入从而实现Web 端自动登录的过程。

  • 在网页端打开登录页面,展示一个二维码,这个二维码有一个唯一编号就是服务端生成的,然后浏览器定时轮询这个二维码的状态。
  • app扫描这个二维码,把ap的token、二维码id发给服务端,服务端收到请求后修改这个二维码的扫码状态,生成一个临时的token。
  • 网页端在轮询,收到提示后,二维码状态改变变为待确认。
  • app扫码后会进行确认授权的操作。
  • 用户确认后,携带临时token给server,server完成二维码状态并为网页端生成新的授权token。
  • 网页端还在轮询,获取到新token的时候,静默登录。

怎么理解接口幂等,项目中如何保证的接口幂等

简单来说,就是一个接口,使用相同的参数重复执行的情况下,对数据造成的改变只发生一次。比如支付操作,如果支付接口被重复调了N 次,那资金的扣减只发生一次,这就是幂等。 有如下方案:

  • 使用数据库唯一索引的方式实现, 我们可以专门创建一个消息表,里面有一个消息内容的字段并且设置为唯一索引,每次收到消息以后生成md5 值插入到这个消息表里面。一旦出现重复消息,就会抛异常,我们可以捕获这个异常来避免重复对数据做变更。
  • 使用Redis 里面的setNx 命令,我们可以把当前请求中带有唯一标识的信息存储到Redis 里面,根据setNx 命令返回的结果来判断是否是重复执行,如果是则丢弃该请求。
  • 使用状态机的方式来实现幂等,在很多的业务场景中,都会存在业务状态的流转,并且这些状态流转只会前进,所以我们在对数据进行修改的时候,只需要在条件里面带上状态,就能避免数据被重复修改的问题。

订单超时自动取消功能如何设计?

  • 轮询,但是轮询数据库,会给数据库造成很大的压力,如果订单表的数据量比较大的情况下,轮询的效率也会比较低。

  • 时间轮算法(如图),这种算法是采用了一个环状数组+链表的方式来管理延迟任务,我们只需要计算这个订单的超时时间,再加入到时间轮里面即可。时间轮算法唯一的缺点就是无法持久化,所以需要在服务重启后做一次数据预热。

  • 利用主流MQ 中的功能,比如rbmq就有相关插件。

  • 利用redis的TTL时间来设计。

消息推送中的已读消息和未读消息设计难题

  • 使用Redis 中的Set 集合来保存已经读取过的消息id。
  • 当用户读取了未读消息后, 就直接在redis 的已读消息id 的set 中新增一条记录。
  • 在已经得知到已读消息的数量和具体消息id 的情况下,我们可以直接使用消息id 来查询没有消费过的数据。

布隆过滤器到底是什么东西?它有什么用

BitMap 的基本原理就是用一个bit 位来存储当前数据是否存在的状态值,也就是把一个数据通过hash 运算取模后落在bit 位组成的数组中,通过1 对该位置进行标记。这种方式适用于大规模数据,但数据状态又不是很多的情况,通常是用来判断某个数据存不存在的。

tqM0LHgKyCu2s3BPFI.png

布隆过滤器就是在位图的基础上做的一个优化设计{如图}。它的原理是,

  • 当一个元素被加入集合时,通过K 个散列函数将这个元素映射成一个位数组中的K 个点,把它们置为1。
  • 检索的时候,使用同样的方式去映射,只要看到每个映射的位置的值是不是1,就可以大概知道该元素是否存在集合中了。
  • 如果这些点有任何一个0,则被检查的元素一定不在;
  • 如果都是1,则被检查的元素很可能存在。

会员批量过期的方案怎么实现?

第一种,系统不主动轮询,而是等用户登录到系统以后,触发一次检查。

如果发现会员的过期时间小于设定的阈值,就触发一次弹窗和邮件提醒。这种方式规避了轮询问题,不会对数据库和后端应用程序造成任何压力。缺点是,如果用户一直不登陆,就一直无法实现会员过期,并且也无法提前去根据运营策略发送续期的提醒消息。

第二种,我们可以使用搜索引擎,比Elasticsearch。

把会员表里面的会员id 和会员到期时间存储一份到搜索引擎中。搜索引擎的优势在于大数据量的快速检索,并且具有高可扩展性和高可靠性,非常适合大规模数据的处理。

第三种,可以使用Redis 来实现。

用户开通会员以后,在Redis 里面存储这个会员id,以及设置这个id 的过期时间。然后可以使用redis 的过期提醒功能,把配置项notify-keyspace-events 改为notify-keyspace-events "Ex"当Redis 里面的key 过期以后,会触发一个key 过期事件,我们可以在应用程序中监听这个事件来处理。

第四种,可以直接使用MQ 提供的延迟队列

当用户开通会员以后,直接计算这个会员的过期时间,然后发送一个延迟消息到MQ 上,一旦消息达到过期时间,消费者就可以消费这个消息来触发会员过期的提醒。

常见的限流算法有哪些?

首先,限流算法是一种系统保护策略,主要是避免在流量高峰导致系统被压垮,造成系 统不可用的问题。常见的限流算法有4 种。

1:计数器限流,一般用在单一维度的访问频率限制上,比如短信验证码每隔60s 只能发送一次,或者接口调用次数等。

2:滑动窗口限流,本质上也是一种计数器,只是通过以时间为维度的可滑动窗口设计,来减少了临界值带来的并发超过阈值的问题。

3:漏桶算法,它是一种恒定速率的限流算法,不管请求量是多少,服务端的处理效率是恒定的。基于MQ 来实现的生产者消费者模型,其实算是一种漏桶限流算法。

4:令牌桶算法,相对漏桶算法来说,它可以处理突发流量的问题。它的核心思想是,令牌桶以恒定速率去生成令牌保存到令牌桶里面,桶的大小是固定的,令牌桶满了以后就不再生成令牌。

限流的本质是实现系统保护,最终选择什么样的算法,一方面取决于统计的精准度,另一方面考虑限流维度和场景的需求。

如果让你设计一个秒杀系统,怎么设计?

设计秒杀系统需要考虑高并发、高性能和防止超卖的问题。以下是一个简单的设计方案:

  1. 架构设计 前端:静态资源采用CDN加速,前端使用缓存技术如CDN缓存、前端页面静态化,减轻后端压力。 后端:采用分布式架构,将请求分散到多个服务器上,采用负载均衡技术分发流量。 数据库:选用高性能的数据库如Redis作为缓存,减少数据库压力。使用分布式缓存和数据库,例如Redis Cluster或者集群化的数据库系统。
  2. 接口设计 限流控制:设置接口限流,防止过多请求进入系统,可以采用令牌桶、漏桶等算法进行限流。 排队机制:利用消息队列(如RabbitMQ、Kafka)进行排队,将请求放入队列中,避免直接压垮后端服务。 异步处理:采用异步处理秒杀请求,通过消息队列异步下单和处理订单,提高系统并发能力。
  3. 业务逻辑 库存控制:利用Redis等缓存数据库进行库存控制,使用乐观锁或分布式锁确保库存不超卖。 防止重复购买:使用用户标识符(如手机号、用户ID)限制单个用户的购买次数,避免同一用户多次购买。 限时操作:设定秒杀活动的时间窗口,确保在规定时间内完成秒杀操作。
  4. 安全防护 验证码和身份验证:对用户进行验证码或身份验证,减少恶意请求。 防刷机制:通过IP限制、Token验证等方式防止恶意刷单行为。
  5. 系统监控 实时监控:设置系统监控,对服务器、数据库、缓存等进行实时监控,及时发现问题并解决。 日志记录:记录关键操作日志,方便追踪问题和分析系统瓶颈。
  6. 测试与优化 压力测试:进行系统压力测试,模拟高并发场景,发现系统瓶颈并进行优化。 持续优化:根据测试结果和实际运行情况,持续对系统进行优化改进,提高系统性能和稳定性。 这些是设计秒杀系统的基本考虑方向,但具体实现需要根据业务需求和技术栈进行合理选择和调整。

敏感数据怎么加解密和传输?

常见的加密算法有两种,一种是对称加密,就是通信双方共享同一个密钥
另一种是非对称加密,也就是通过公钥和私钥两个密钥分别进行加密和解密。
对于客户端和服务端之间的数据传输(如图),可以采用非对称加密的方式实现。
首先客户端用提前分配好的公钥对数据加密,然后再把密文传输到服务端,服务端通过私钥来解密。

除了加密以外,还需要通过安全的通信协议进行传输,这里可以采用https 协议。
最后,还需要确保公钥和私钥的安全性,防止被第三方拿到了密钥后破解内容。

如何提升接口的性能?

影响接口性能的因素有很多,我分别从自己理解的几个维度来回答 从接口本身的实现维度来说,可以从几个方面来优化
a. 如果在接口中有操作数据库层面的代码,可以优化数据库IO 的效率,比如SQL优化、数据库层面的优化等
b. 如果存在部分频繁访问数据库的热数据,可以采用缓存机制
c. 如果涉及到远程调用或者耗时的方法调用,可以采用异步方式避免同步阻塞,从而提升程序运行效率
d. 代码本身的优化,可以利用合适的算法减少时间复杂度、避免一些很明显的重复计算等问题

从宏观链路维度来说,可以关注几个方面
a. 网络带宽,带宽的大小会影响数据的传输效率
b. 服务器硬件资源如CPU、内存等,会影响到接口中代码的执行效率
c. 但个部署节点的计算能力瓶颈,也会影响接口性能,可以采用分布式部署的方式来优化
总的来说,接口的性能优化涉及到的因素比较多,如果真的出现性能问题,可以根据系统日志以及压测的情况去分析瓶颈点

对接第三方接口要考虑什么?

基于我的经验,主要考虑以下几个方面的问题:

安全性问题,由于和第三方接口对接涉及到数据的跨网络传输,为了防止数据被拦截和篡改,需要采用安全的通信机制,比如https 协议,以及数据签名等。

接口稳定性和可靠性,这两个方面会直接影响用户体验和业务的正常流转,所以需要做相对充分的评估和测试

接口是否存在访问限制或者费用,如果存在并发量的限制,需要评估是否满足当前业务需求; 如果存在费用,需要评估是否符合预算

事务消息是否了解?场景题:比如下单清空购物车,你是如何设计

通过MQ来发起

你们是微服务架构嘛?如果你来设计一个类似淘宝的系统,你怎么划分微服务?

  1. 可以按业务领域、功能、重要程度进行划分。
  2. 可以按业务领域,按照用户、社区、商品信息、消息等模块等划分。
  3. 单一功能职责,按功能拆分,比如订单、支付、物流、权限。
  4. 按重要程度划分,区分核心和非核心功能,比如支付、订单就是核心功能
人未眠
工作数十年
脚步未曾歇,学习未曾停
乍回首
路程虽丰富,知识未记录
   借此博客,与之共进步