2021面试总结

1,363 阅读7分钟

一、设计10亿级的数据库,每年增加1亿的数据量,用户id,性别?

mp.weixin.qq.com/s/EY1L-7GpZ…

二、CAP和BASE理论理解?

答:

					在分布式系统中无法同时满足CAP
  • Consistency(一致性): 在分布式系统中,数据在多个副本中是否保持一致,要么读到最新的数据,要么失败,强调的是数据的准确

  • Availability(高可用性):在分布式系统中提供的服务必须一致处于可用的状态,而且对于用户的每一个操作请求,总能够在有限的时间内获取到非错的响应(但不保证获取到最新的数据)。特点:一定会返回数据,不会返回错误,但不保证数据最新,强调的是不出错。任何时候读写都是成功的。

  • Partition tolerance (分区容错性):大多数分布式系统都是分布在多个子网路中,每一个子网络都是一个分区,分区容忍性是指当部分节点出现消息丢失或者分区故障的时候,分布式系统仍然能够继续对外提供满足一致性和可用性的服务。特点:系统一直运行、不管内部出现任何数据同步的问题,强调的是不挂掉

				BASE理论的意义在于,我们不必在A或C中做出选择,可以实现部分的A和C
  • Eventually consistent(最终一致性):因数据不可能一直都是软状态,必须在一个时间期限(这段时间为不一致窗口),在期限过后,必须保证所有副本数据保持一直,也就是保持最终的数据一致性。

  • Basically Available(基本可用):不追求CAP中的【任何时候,读写都是成功】。强调了分布式系统出现不可预知故障的时候,允许损失部分可用性,相比正常的系统,可能是响应时间的延长,保证核心功能可用,或者是服务的降级。

  • Soft state(软状态):软状态可以对应ACID中的原子性,原子性是一种"强状态",软状态则是允许当前系统中数据存在中间状态,并认为该状态不影响系统的整体可用性。即:允许系统在多个不同的数据副本存在数据延时。

三、限流算法?

  • 计数器算法

    采用计数器实现限流有点简单粗暴,一般我们会限制一秒钟的能够通过的请求数,比如限流qps为100,算法的实现思路就是从第一个请求进来开始计时,在接下去的1s内,每来一个请求,就把计数加1,如果累加的数字达到了100,那么后续的请求就会被全部拒绝。等到1s结束后,把计数恢复成0,重新开始计数。

具体的实现可以是这样的:对于每次服务调用,可以通过 AtomicLong#incrementAndGet()方法来给计数器加1并返回最新值,通过这个最新值和阈值进行比较。

这种实现方式,相信大家都知道有一个弊端:如果我在单位时间1s内的前10ms,已经通过了100个请求,那后面的990ms,只能眼巴巴的把请求拒绝,我们把这种现象称为 “突刺现象”

  • 漏桶算法

    为了消除"突刺现象",可以采用漏桶算法实现限流,漏桶算法这个名字就很形象,算法内部有一个容器,类似生活用到的漏斗,当请求进来时,相当于水倒入漏斗,然后从下端小口慢慢匀速的流出。不管上面流量多大,下面流出的速度始终保持不变。

不管服务调用方多么不稳定,通过漏桶算法进行限流,每10毫秒处理一次请求。因为处理的速度是固定的,请求进来的速度是未知的,可能突然进来很多请求,没来得及处理的请求就先放在桶里,既然是个桶,肯定是有容量上限,如果桶满了,那么新进来的请求就丢弃。

在算法实现方面,可以准备一个队列,用来保存请求,另外通过一个线程池定期从队列中获取请求并执行,可以一次性获取多个并发执行。

这种算法,在使用过后也存在弊端:无法应对短时间的突发流量。

  • 令牌桶算法

从某种意义上讲,令牌桶算法是对漏桶算法的一种改进,桶算法能够限制请求调用的速率,而令牌桶算法能够在限制调用的平均速率的同时还允许一定程度的突发调用。

在令牌桶算法中,存在一个桶,用来存放固定数量的令牌。算法中存在一种机制,以一定的速率往桶中放令牌。每次请求调用需要先获取令牌,只有拿到令牌,才有机会继续执行,否则选择选择等待可用的令牌、或者直接拒绝。

放令牌这个动作是持续不断的进行,如果桶中令牌数达到上限,就丢弃令牌,所以就存在这种情况,桶中一直有大量的可用令牌,这时进来的请求就可以直接拿到令牌执行,比如设置qps为100,那么限流器初始化完成一秒后,桶中就已经有100个令牌了,这时服务还没完全启动好,等启动完成对外提供服务时,该限流器可以抵挡瞬时的100个请求。所以,只有桶中没有令牌时,请求才会进行等待,最后相当于以一定的速率执行。

实现思路:可以准备一个队列,用来保存令牌,另外通过一个线程池定期生成令牌放到队列中,每来一个请求,就从队列中获取一个令牌,并继续执行。

集群限流

前面讨论的几种算法都属于单机限流的范畴,但是业务需求五花八门,简单的单机限流,根本无法满足他们。

比如为了限制某个资源被每个用户或者商户的访问次数,5s只能访问2次,或者一天只能调用1000次,这种需求,单机限流是无法实现的,这时就需要通过集群限流进行实现。

如何实现?为了控制访问次数,肯定需要一个计数器,而且这个计数器只能保存在第三方服务,比如redis。

大概思路:每次有相关操作的时候,就向redis服务器发送一个incr命令,比如需要限制某个用户访问/index接口的次数,只需要拼接用户id和接口名生成redis的key,每次该用户访问此接口时,只需要对这个key执行incr命令,在这个key带上过期时间,就可以实现指定时间的访问频率。

四、缓存(redis)和数据库的强一致性解决方案?

juejin.cn/post/685041…

五、final关键字使用极其作用?

juejin.cn/post/684490…

六、java对象的分配?

juejin.cn/post/689833…

七、慢sql优化思路?

1,数据库CPU负载高。 一般是查询语句中有很多计算逻辑,导致数据库cpu负载。

2,IO负载高导致服务器卡住。 这个一般和全表查询没索引有关系。

3,查询语句正常,索引正常但是还是慢。 如果表面上索引正常,但是查询慢,需要看看是否索引没有生效。

juejin.cn/post/684490…

八、monitor对象有哪些属性?