java架构师面试题——分布式篇

13.分布式锁面试题(高频面试题) 面试经常被问到分布式锁,今天我就带大家深入剖析下分布式锁的各种方案,redis分布式锁,zookeeper分布式锁等等,我给大家深入剖析每种解决方案的优缺点以及应用场景。 阅读详情

1、分布式幂等性如何设计?

在高并发场景的架构里,幂等性是必须得保证的。比如说支付功能,用户发起支付,如果后台没有

做幂等校验,刚好用户手抖多点了几下,于是后台就可能多次受到同一个订单请求,不做幂等很容

易就让用户重复支付了,这样用户是肯定不能忍的。

解决方案

1,查询和删除不在幂等讨论范围,查询肯定没有幂等的说,删除:第一次删除成功后,后面来删

除直接返回0,也是返回成功。

2,建唯一索引:唯一索引或唯一组合索引来防止新增数据存在脏数据 (当表存在唯一索引,并发

时新增异常时,再查询一次就可以了,数据应该已经存在了,返回结果即可)。

3,token机制:由于重复点击或者网络重发,或者nginx重发等情况会导致数据被重复提交。前端

在数据提交前要向后端服务的申请token,token放到 Redis 或 JVM 内存,token有效时间。提交后

后台校验token,同时删除token,生成新的token返回。redis要用删除操作来判断token,删除成

功代表token校验通过,如果用select+delete来校验token,存在并发问题,不建议使用。

4,悲观锁

select id ,name from table_# where id='##' for update;

悲观锁使用时一般伴随事务一起使用,数据锁定时间可能会很长,根据实际情况选用(另外还要考

虑id是否为主键,如果id不是主键或者不是 InnoDB 存储引擎,那么就会出现锁全表)。

5,乐观锁,给数据库表增加一个version字段,可以通过这个字段来判断是否已经被修改了

update table_xxx set name=#name#,version=version+1 where version=#version#

6,分布式锁,比如 Redis 、 Zookeeper 的分布式锁。单号为key,然后给Key设置有效期(防止支

付失败后,锁一直不释放),来一个请求使用订单号生成一把锁,业务代码执行完成后再释放锁。

7,保底方案,先查询是否存在此单,不存在进行支付,存在就直接返回支付结果。

2,简单一次完整的 HTTP 请求所经历的步骤?

1、 DNS 解析(通过访问的域名找出其 IP 地址,递归搜索)。

2、HTTP 请求,当输入一个请求时,建立一个 Socket 连接发起 TCP的 3 次握手。

如果是 HTTPS 请求,会略微有不同。等到 HTTPS 小节,我们在来讲。

3.1、客户端向服务器发送请求命令(一般是 GET 或 POST 请求)。

这个是补充内容,面试一般不用回答。

客户端的网络层不用关心应用层或者传输层的东西,主要做的是通过查找路由表确定如何

到达服务器,期间可能经过多个路由器,这些都是由路由器来完成的工作,我不作过多的

描述,无非就是通过查找路由表决定通过那个路径到达服务器。

客户端的链路层,包通过链路层发送到路由器,通过邻居协议查找给定 IP 地址的 MAC 地

址,然后发送 ARP 请求查找目的地址,如果得到回应后就可以使用 ARP 的请求应答交换

的 IP 数据包现在就可以传输了,然后发送 IP 数据包到达服务器的地址。

3.2、客户端发送请求头信息和数据。

4.1、服务器发送应答头信息。

4.2、服务器向客户端发送数据。

5、服务器关闭 TCP 连接(4次挥手)。

这里是否关闭 TCP 连接,也根据 HTTP Keep-Alive 机制有关。

同时,客户端也可以主动发起关闭 TCP 连接。

6、客户端根据返回的 HTML 、 CSS 、 JS 进行渲染。

3、说说你对分布式事务的了解

分布式事务是企业集成中的一个技术难点,也是每一个分布式系统架构中都会涉及到的一个东西,

特别是在微服务架构中,几乎可以说是无法避免。

首先要搞清楚:ACID、CAP、BASE理论。

ACID

指数据库事务正确执行的四个基本要素:

1. 原子性(Atomicity)

2. 一致性(Consistency)

3. 隔离性(Isolation)

4. 持久性(Durability)

CAP

CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性

(Availability)、分区容忍性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同

时实现两点,不可能三者兼顾。

一致性:在分布式系统中的所有数据备份,在同一时刻是否同样的值。

可用性:在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。

分区容忍性:以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数

据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。

BASE理论

BASE理论是对CAP中的一致性和可用性进行一个权衡的结果,理论的核心思想就是:我们无法做到

强一致,但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性。

Basically Available(基本可用)

Soft state(软状态)

Eventually consistent(最终一致性)

4、你知道哪些分布式事务解决方案?

我目前知道的有五种:

1. 两阶段提交(2PC)

2. 三阶段提交(3PC)

3. 补偿事务(TCC=Try-Confirm-Cancel)

4. 本地消息队列表(MQ)

5. Sagas事务模型(最终一致性)

说完上面五种,面试官一般都会继续问下面这几个问题(可能就问一两个,也可能全部问)。

5,什么是二阶段提交?

两阶段提交2PC是分布式事务中最强大的事务类型之一,两段提交就是分两个阶段提交:

第一阶段询问各个事务数据源是否准备好。

第二阶段才真正将数据提交给事务数据源。

为了保证该事务可以满足ACID,就要引入一个协调者(Cooradinator)。其他的节点被称为参与者

(Participant)。协调者负责调度参与者的行为,并最终决定这些参与者是否要把事务进行提交。

处理流程如下:

阶段一

a) 协调者向所有参与者发送事务内容,询问是否可以提交事务,并等待答复。

b) 各参与者执行事务操作,将 undo 和 redo 信息记入事务日志中(但不提交事务)。

c) 如参与者执行成功,给协调者反馈 yes,否则反馈 no。

阶段二

如果协调者收到了参与者的失败消息或者超时,直接给每个参与者发送回滚(rollback)消息;否则,

发送提交(commit)消息。两种情况处理如下:

情况1:当所有参与者均反馈 yes,提交事务

a) 协调者向所有参与者发出正式提交事务的请求(即 commit 请求)。

b) 参与者执行 commit 请求,并释放整个事务期间占用的资源。

c) 各参与者向协调者反馈 ack(应答)完成的消息。

d) 协调者收到所有参与者反馈的 ack 消息后,即完成事务提交。

情况2:当有一个参与者反馈 no,回滚事务

a) 协调者向所有参与者发出回滚请求(即 rollback 请求)。

b) 参与者使用阶段 1 中的 undo 信息执行回滚操作,并释放整个事务期间占用的资源。

c) 各参与者向协调者反馈 ack 完成的消息。

d) 协调者收到所有参与者反馈的 ack 消息后,即完成事务。

问题

1) 性能问题:所有参与者在事务提交阶段处于同步阻塞状态,占用系统资源,容易导致性能瓶颈。

2) 可靠性问题:如果协调者存在单点故障问题,或出现故障,提供者将一直处于锁定状态。

3) 数据一致性问题:在阶段 2 中,如果出现协调者和参与者都挂了的情况,有可能导致数据不一

致。

优点:尽量保证了数据的强一致,适合对数据强一致要求很高的关键领域。(其实也不能100%保证

强一致)。

缺点:实现复杂,牺牲了可用性,对性能影响较大,不适合高并发高性能场景。

6、什么是三阶段提交?

三阶段提交是在二阶段提交上的改进版本,3PC最关键要解决的就是协调者和参与者同时挂掉的问

题,所以3PC把2PC的准备阶段再次一分为二,这样三阶段提交。

处理流程如下 :

阶段一

a) 协调者向所有参与者发出包含事务内容的 canCommit 请求,询问是否可以提交事务,并等待所

有参与者答复。

b) 参与者收到 canCommit 请求后,如果认为可以执行事务操作,则反馈 yes 并进入预备状态,否

则反馈 no。

阶段二

协调者根据参与者响应情况,有以下两种可能。

情况1:所有参与者均反馈 yes,协调者预执行事务

a) 协调者向所有参与者发出 preCommit 请求,进入准备阶段。

b) 参与者收到 preCommit 请求后,执行事务操作,将 undo 和 redo 信息记入事务日志中(但不

提交事务)。

c) 各参与者向协调者反馈 ack 响应或 no 响应,并等待最终指令。

情况2:只要有一个参与者反馈 no,或者等待超时后协调者尚无法收到所有提供者的反馈,即中断

事务

a) 协调者向所有参与者发出 abort 请求。

b) 无论收到协调者发出的 abort 请求,或者在等待协调者请求过程中出现超时,参与者均会中断事

务。

阶段三

该阶段进行真正的事务提交,也可以分为以下两种情况。

情况 1:所有参与者均反馈 ack 响应,执行真正的事务提交

a) 如果协调者处于工作状态,则向所有参与者发出 do Commit 请求。

b) 参与者收到 do Commit 请求后,会正式执行事务提交,并释放整个事务期间占用的资源。

c) 各参与者向协调者反馈 ack 完成的消息。

d) 协调者收到所有参与者反馈的 ack 消息后,即完成事务提交。

情况2:只要有一个参与者反馈 no,或者等待超时后协调组尚无法收到所有提供者的反馈,即回滚

事务。

a) 如果协调者处于工作状态,向所有参与者发出 rollback 请求。

b) 参与者使用阶段 1 中的 undo 信息执行回滚操作,并释放整个事务期间占用的资源。

c) 各参与者向协调组反馈 ack 完成的消息。

d) 协调组收到所有参与者反馈的 ack 消息后,即完成事务回滚。

优点:相比二阶段提交,三阶段提交降低了阻塞范围,在等待超时后协调者或参与者会中断事务。

避免了协调者单点问题。阶段 3 中协调者出现问题时,参与者会继续提交事务。

缺点:数据不一致问题依然存在,当在参与者收到 preCommit 请求后等待 do commite 指令时,

此时如果协调者请求中断事务,而协调者无法与参与者正常通信,会导致参与者继续提交事务,造

成数据不一致。

7、什么是补偿事务?

TCC (Try Confirm Cancel)是服务化的二阶段编程模型,采用的补偿机制:

TCC 其实就是采用的补偿机制,其核心思想是:针对每个操作,都要注册一个与其对应的确认和补

偿(撤销)操作。

它分为三个步骤:

Try 阶段主要是对业务系统做检测及资源预留。

Confirm 阶段主要是对业务系统做确认提交,Try阶段执行成功并开始执行 Confirm阶段时,默

认 Confirm阶段是不会出错的。即:只要Try成功,Confirm一定成功。

Cancel 阶段主要是在业务执行错误,需要回滚的状态下执行的业务取消,预留资源释放。

举个例子,假入你要向 老田 转账,思路大概是: 我们有一个本地方法,里面依次调用步骤: 1、

首先在 Try 阶段,要先调用远程接口把 你 和 老田 的钱给冻结起来。 2、在 Confirm 阶段,执行远

程调用的转账的操作,转账成功进行解冻。 3、如果第2步执行成功,那么转账成功,如果第二步执

行失败,则调用远程冻结接口对应的解冻方法 (Cancel)。

优点:

性能提升:具体业务来实现控制资源锁的粒度变小,不会锁定整个资源。

数据最终一致性:基于 Confirm 和 Cancel 的幂等性,保证事务最终完成确认或者取消,保证数据

的一致性。

可靠性:解决了 XA 协议的协调者单点故障问题,由主业务方发起并控制整个业务活动,业务活动

管理器也变成多点,引入集群。

缺点:TCC 的 Try、Confirm 和 Cancel 操作功能要按具体业务来实现,业务耦合度较高,提高了开

发成本。

8、消息队列是怎么实现的?

本地消息表(异步确保)

本地消息表这种实现方式应该是业界使用最多的,其核心思想是将分布式事务拆分成本地事务进行

处理,这种思路是来源于ebay。我们可以从下面的流程图中看出其中的一些细节:

基本思路就是:

消息生产方,需要额外建一个消息表,并记录消息发送状态。消息表和业务数据要在一个事务里提

交,也就是说他们要在一个数据库里面。然后消息会经过MQ发送到消息的消费方。如果消息发送

失败,会进行重试发送。

消息消费方,需要处理这个消息,并完成自己的业务逻辑。此时如果本地事务处理成功,表明已经

处理成功了,如果处理失败,那么就会重试执行。如果是业务上面的失败,可以给生产方发送一个

业务补偿消息,通知生产方进行回滚等操作。

生产方和消费方定时扫描本地消息表,把还没处理完成的消息或者失败的消息再发送一遍。如果有

靠谱的自动对账补账逻辑,这种方案还是非常实用的。

这种方案遵循BASE理论,采用的是最终一致性,笔者认为是这几种方案里面比较适合实际业务场景

的,即不会出现像2PC那样复杂的实现(当调用链很长的时候,2PC的可用性是非常低的),也不会像

TCC那样可能出现确认或者回滚不了的情况。

优点: 一种非常经典的实现,避免了分布式事务,实现了最终一致性。在 .NET中 有现成的解决方

案。

缺点: 消息表会耦合到业务系统中,如果没有封装好的解决方案,会有很多杂活需要处理。

MQ 事务消息

有一些第三方的MQ是支持事务消息的,比如RocketMQ,他们支持事务消息的方式也是类似于采用

的二阶段提交,但是市面上一些主流的MQ都是不支持事务消息的,比如 RabbitMQ 和 Kafka 都不

支持。

以阿里的 RocketMQ 中间件为例,其思路大致为:

第一阶段Prepared消息,会拿到消息的地址。 第二阶段执行本地事务,第三阶段通过第一阶段拿到

的地址去访问消息,并修改状态。

也就是说在业务方法内要想消息队列提交两次请求,一次发送消息和一次确认消息。如果确认消息

发送失败了RocketMQ会定期扫描消息集群中的事务消息,这时候发现了Prepared消息,它会向消

息发送者确认,所以生产方需要实现一个check接口,RocketMQ会根据发送端设置的策略来决定是

回滚还是继续发送确认消息。这样就保证了消息发送与本地事务同时成功或同时失败。

遗憾的是,RocketMQ并没有 .NET 客户端。有关 RocketMQ的更多消息,大家可以查看这篇博客

优点: 实现了最终一致性,不需要依赖本地数据库事务。

缺点: 实现难度大,主流MQ不支持,没有.NET客户端,RocketMQ事务消息部分代码也未开源。

9、那你说说Sagas事务模型

Saga模式是一种分布式异步事务,一种最终一致性事务,是一种柔性事务,有两种不同的方式来实

现saga事务,最流行的两种方式是:

一、 事件/编排Choreography:没有中央协调器(没有单点风险)时,每个服务产生并聆听其他

服务的事件,并决定是否应采取行动。

该实现第一个服务执行一个事务,然后发布一个事件。该事件被一个或多个服务进行监听,这些服

务再执行本地事务并发布(或不发布)新的事件,当最后一个服务执行本地事务并且不发布任何事

件时,意味着分布式事务结束,或者它发布的事件没有被任何Saga参与者听到都意味着事务结束。

处理流程说明:

订单服务保存新订单,将状态设置为pengding挂起状态,并发布名为ORDER_CREATED_EVENT的

事件。

支付服务监听ORDER_CREATED_EVENT,并公布事件BILLED_ORDER_EVENT。

库存服务监听BILLED_ORDER_EVENT,更新库存,并发布ORDER_PREPARED_EVENT。

货运服务监听ORDER_PREPARED_EVENT,然后交付产品。最后,它发布

ORDER_DELIVERED_EVENT。

最后,订单服务侦听ORDER_DELIVERED_EVENT并设置订单的状态为concluded完成。

假设库存服务在事务过程中失败了。进行回滚:

库存服务产生PRODUCT_OUT_OF_STOCK_EVENT

订购服务和支付服务会监听到上面库存服务的这一事件:

①支付服务会退款给客户。

②订单服务将订单状态设置为失败。

优点:事件/编排是实现Saga模式的自然方式; 它很简单,容易理解,不需要太多的努力来构建,所

有参与者都是松散耦合的,因为他们彼此之间没有直接的耦合。如果您的事务涉及2至4个步骤,则

可能是非常合适的。

二、 命令/协调orchestrator:中央协调器负责集中处理事件的决策和业务逻辑排序。

saga协调器orchestrator以命令/回复的方式与每项服务进行通信,告诉他们应该执行哪些操作。

订单服务保存pending状态,并要求订单Saga协调器(简称OSO)开始启动订单事务。

OSO向收款服务发送执行收款命令,收款服务回复Payment Executed消息。

OSO向库存服务发送准备订单命令,库存服务将回复OrderPrepared消息。

OSO向货运服务发送订单发货命令,货运服务将回复Order Delivered消息。

OSO订单Saga协调器必须事先知道执行“创建订单”事务所需的流程(通过读取BPM业务流程XML配置

获得)。如果有任何失败,它还负责通过向每个参与者发送命令来撤销之前的操作来协调分布式的回

滚。当你有一个中央协调器协调一切时,回滚要容易得多,因为协调器默认是执行正向流程,回滚

时只要执行反向流程即可。

优点:

避免服务之间的循环依赖关系,因为saga协调器会调用saga参与者,但参与者不会调用协调器。

集中分布式事务的编排。

只需要执行命令/回复(其实回复消息也是一种事件消息),降低参与者的复杂性。

在添加新步骤时,事务复杂性保持线性,回滚更容易管理。

如果在第一笔交易还没有执行完,想改变有第二笔事务的目标对象,则可以轻松地将其暂停在协调

器上,直到第一笔交易结束。

10,分布式ID生成有几种方案?

分布式ID的特性

唯一性:确保生成的ID是全网唯一的。

有序递增性:确保生成的ID是对于某个用户或者业务是按一定的数字有序递增的。

高可用性:确保任何时候都能正确的生成ID。

带时间:ID里面包含时间,一眼扫过去就知道哪天的交易。

分布式ID生成方案

1. UUID

算法的核心思想是结合机器的网卡、当地时间、一个随记数来生成UUID。

优点:本地生成,生成简单,性能好,没有高可用风险

缺点:长度过长,存储冗余,且无序不可读,查询效率低

2. 数据库自增ID

使用数据库的id自增策略,如 MySQL 的 auto_increment。并且可以使用两台数据库分别设置不同

步长,生成不重复ID的策略来实现高可用。

优点:数据库生成的ID绝对有序,高可用实现方式简单

缺点:需要独立部署数据库实例,成本高,有性能瓶颈

3. 批量生成ID

一次按需批量生成多个ID,每次生成都需要访问数据库,将数据库修改为最大的ID值,并在内存中

记录当前值及最大值。

优点:避免了每次生成ID都要访问数据库并带来压力,提高性能

缺点:属于本地生成策略,存在单点故障,服务重启造成ID不连续

4. Redis生成ID

Redis的所有命令操作都是单线程的,本身提供像 incr 和 increby 这样的自增原子命令,所以能保

证生成的 ID 肯定是唯一有序的。

优点:不依赖于数据库,灵活方便,且性能优于数据库;数字ID天然排序,对分页或者需要排

序的结果很有帮助。

缺点:如果系统中没有Redis,还需要引入新的组件,增加系统复杂度;需要编码和配置的工作

量比较大。

考虑到单节点的性能瓶颈,可以使用 Redis 集群来获取更高的吞吐量。假如一个集群中有5台

Redis。可以初始化每台 Redis 的值分别是1, 2, 3, 4, 5,然后步长都是 5。

5. Twitter的snowflake算法(重点)

Twitter 利用 zookeeper 实现了一个全局ID生成的服务 Snowflake

如上图的所示,Twitter 的 Snowflake 算法由下面几部分组成:

1位符号位:

由于 long 类型在 java 中带符号的,最高位为符号位,正数为 0,负数为 1,且实际系统中所使用

的ID一般都是正数,所以最高位为 0。

41位时间戳(毫秒级):

需要注意的是此处的 41 位时间戳并非存储当前时间的时间戳,而是存储时间戳的差值(当前时间

戳 - 起始时间戳),这里的起始时间戳一般是ID生成器开始使用的时间戳,由程序来指定,所以41

位毫秒时间戳最多可以使用 (1 << 41) / (1000x60x60x24x365) = 69年 。

10位数据机器位:

包括5位数据标识位和5位机器标识位,这10位决定了分布式系统中最多可以部署 1 << 10 = 1024

s个节点。超过这个数量,生成的ID就有可能会冲突。

12位毫秒内的序列:

这 12 位计数支持每个节点每毫秒(同一台机器,同一时刻)最多生成 1 << 12 = 4096个ID

加起来刚好64位,为一个Long型。

优点:高性能,低延迟,按时间有序,一般不会造成ID碰撞

缺点:需要独立的开发和部署,依赖于机器的时钟

6. 百度UidGenerator

UidGenerator是百度开源的分布式ID生成器,基于于snowflake算法的实现,看起来感觉还行。不

过,国内开源的项目维护性真是担忧。

7. 美团Leaf

Leaf 是美团开源的分布式ID生成器,能保证全局唯一性、趋势递增、单调递增、信息安全,里面也

提到了几种分布式方案的对比,但也需要依赖关系数据库、Zookeeper等中间件。

11,幂等解决方法有哪些?

什么是幂等?

常见描述:对于相同的请求应该返回相同的结果,所以查询类接口是天然的幂等性接口。

真正的回答方式:幂等指的是相同请求(identical request)执行一次或者多次所带来的副作

用(side-effects)是一样的。

什么常见会出现幂等?

前端调后端接口发起支付超时,然后再次发起重试。可能会导致多次支付。

Dubbo中也有重试机制。

页面上多次点击。

我们想要的是:接口的幂等性实际上就是接口可重复调用,在调用方多次调用的情况下,接口最终

得到的结果是一致的 。

解决方案

在插入数据的时候,插入去重表,利用数据库的唯一索引特性,保证唯一的逻辑。

悲观锁,select for update,整个执行过程中锁定该订单对应的记录。注意:这种在DB读大于写的

情况下尽量少用。

先查询后修改数据,并发不高的后台系统,或者一些任务JOB,为了支持幂等,支持重复执行,简

单的处理方法是,先查询下一些关键数据,判断是否已经执行过,在进行业务处理,就可以了。注

意:核心高并发流程不要用这种方法。

状态机幂等,在设计单据相关的业务,或者是任务相关的业务,肯定会涉及到状态机,就是业务单

据上面有个状态,状态在不同的情况下会发生变更,一般情况下存在有限状态机,这时候,如果状

态机已经处于下一个状态,这时候来了一个上一个状态的变更,理论上是不能够变更的,这样的

话,保证了有限状态机的幂等。

token机制,防止页面重复提交:

集群环境:采用token加redis(redis单线程的,处理需要排队)或者

单JVM环境:采用token加redis或token加jvm内存

数据提交前要向服务的申请token,token放到redis或jvm内存,设置token有效时间,提交后后台

校验token,同时删除token,生成新的token返回。token特点:要申请,一次有效性,可以限流。

全局唯一ID,如果使用全局唯一ID,就是根据业务的操作和内容生成一个全局ID,在执行操作前先

根据这个全局唯一ID是否存在,来判断这个操作是否已经执行。如果不存在则把全局ID,存储到存

储系统中,比如数据库、redis等。如果存在则表示该方法已经执行。

12,常见负载均衡算法有哪些?

13、你知道哪些限流算法?

限流算法有四种常见算法:

计数器算法(固定窗口)

滑动窗口

漏桶算法

令牌桶算法

14、说说什么是计数器(固定窗口)算法

计数器算法是使用计数器在周期内累加访问次数,当达到设定的限流值时,触发限流策略。下一个

周期开始时,进行清零,重新计数。

此算法在单机还是分布式环境下实现都非常简单,使用redis的incr原子自增性和线程安全即可轻松

实现。

这个算法通常用于QPS限流和统计总访问量,对于秒级以上的时间周期来说,会存在一个非常严重

的问题,那就是临界问题,如下图:

假设1min内服务器的负载能力为100,因此一个周期的访问量限制在100,然而在第一个周期的最

后5秒和下一个周期的开始5秒时间段内,分别涌入100的访问量,虽然没有超过每个周期的限制

量,但是整体上10秒内已达到200的访问量,已远远超过服务器的负载能力,由此可见,计数器算

法方式限流对于周期比较长的限流,存在很大的弊端。

15、说说什么是滑动窗口算法

滑动窗口算法是将时间周期分为N个小周期,分别记录每个小周期内访问次数,并且根据时间滑动

删除过期的小周期。

如下图,假设时间周期为1min,将1min再分为2个小周期,统计每个小周期的访问数量,则可以看

到,第一个时间周期内,访问数量为75,第二个时间周期内,访问数量为100,超过100的访问则

被限流掉了

由此可见,当滑动窗口的格子划分的越多,那么滑动窗口的滚动就越平滑,限流的统计就会越精

确。

此算法可以很好的解决固定窗口算法的临界问题。

16、说说什么是漏桶算法

漏桶算法是访问请求到达时直接放入漏桶,如当前容量已达到上限(限流值),则进行丢弃(触发

限流策略)。漏桶以固定的速率进行释放访问请求(即请求通过),直到漏桶为空。

17、说说什么是令牌桶算法

令牌桶算法是程序以r(r=时间周期/限流值)的速度向令牌桶中增加令牌,直到令牌桶满,请求到

达时向令牌桶请求令牌,如获取到令牌则通过请求,否则触发限流策略

18、数据库如何处理海量数据?

对数据库进行:分库分表,主从架构,读写分离。

水平分库/分表,垂直分库/分表。

水平分库/表,各个库和表的结构一模一样。

垂直分库/表,各个库和表的结构不一样。

读写分离:主机负责写,从机负责读。

19、如何将长链接转换成短链接,并发送短信?

短 URL 从生成到使用分为以下几步:

有一个服务,将要发送给你的长 URL 对应到一个短 URL 上.例如 www.baidu.com -> www.t.cn/

1。

把短 url 拼接到短信等的内容上发送。

用户点击短 URL ,浏览器用 301 / 302 进行重定向,访问到对应的长 URL。

展示对应的内容。

20、长链接和短链接如何互相转换?

思路是建立一个发号器。每次有一个新的长 URL 进来,我们就增加一。并且将新的数值返回.第一

个来的 url 返回"www.x.cn/0",第二个返回"www.x.cn/1"。

21、长链接和短链接的对应关系如何存储?

如果数据量小且 QPS 低,直接使用数据库的自增主键就可以实现。 还可以将最近/最热门的对应关

系存储在 K-V 数据库中,这样子可以节省空间的同时,加快响应速度。

22、如何提高系统的并发能力?

使用分布式系统。

部署多台服务器,并做负载均衡。

使用缓存(Redis)集群。

数据库分库分表 + 读写分离。

引入消息中间件集群。

Java中级面试题进阶(十二)-分布式锁篇 使用Zookeeper可以实现阻塞的锁,客户端可以通过在ZK中创建顺序节点,并且在节点上绑定监听器,一旦节点有变化,Zookeeper会通知客户端,客户端可以检查自己创建的节点是不是当前所有节点中序号最小的,如果是,那么自己就获取到锁,便可以执行业务逻辑了。使用Zookeeper也可以有效的解决不可重入的问题,客户端在创建节点的时候,把当前客户端的主机信息和线程信息直接写入到节点中,下次想要获取锁的时候和当前最小的节点中的数据比对一下就可以了。同时,其可以避免服务宕机导致的锁无法释放,而产生的死锁问题。 阅读详情

相关推荐

java面试题速刷---事务和分布式锁

事务:一组对数据库的操作,要么同时成功要么同时失败原子性:指的是一个事务应该是一个最小的无法分割的单元,不允许部分成功部分失败,只能同时成功,或者同时失败持久性:一旦提交事务,那么数据就应该持久化,保证数据不会丢失隔离性:两个事务修改同一个数据,必须按顺序执行,并且前一个事务如果未完成,那么中间状态对另一个事务不可见一致性:要求任何写到数据库的数据都必须满足预先定义的规则,它基于其他三个特性实现的。

m0_54620396的博客 385

Java架构师之路:分布式面试题

现在的面试已经与前些年有很大的不同了,早些年,2010年之气基本是ssh或者ssm的方式进行项目的开发,面试也主要考察这些内容,那个时候都很少提及到分布式,随着移动互联网的发展,系统的复杂度增加以及庞大的互联网用户规模,分布式架构也应运而生,2012年阿里开源了一个Dubbo,称为分布式开发的一个分水岭,推动了分布式架构的发展,现在如果出去面试,不知道什么是分布式,那真的会被虐得体无完肤,当然最近两年,从2017年下半年开始又出现了微服务。本课程从面试的角度带你刷一波分布式相关的面试题。

Java架构师和大数据架构师的区别是什么?哪个更有发展前景?

[Java]是我们耳熟能详的编程语言,[大数据]更是当今科技的明星技术,那Java和Java大数据架构学习的内容是一样的吗?两者有什么区别呢?今天千锋广州Java的老师就从Java和大数据架构的以下方面谈谈两者的区别。 [ 01 [架构师](需要考虑四个问题 1. 确定系统干什么不干什么,也就是说系统的边界在哪里? 2. 确定架构内部的模块与模块之间的关系,以及模块与外部之间的关系是什么? 3. 架构确定以后,有能力去指导开发去继续设计和演化,如果开发设计和演化出来的东西和架构不一致也是有问题的。

m0_67618432的博客 3453

Java——《面试题——分布式篇》

第一阶段询问各个事务数据源是否准备好。第二阶段才真正将数据提交给事务数据源。为了保证该事务可以满足ACID,就要引入一个协调者(Cooradinator)。其他的节点被称为参与者 (Participant)。协调者负责调度参与者的行为,并最终决定这些参与者是否要把事务进行提交。阶段一a) 协调者向所有参与者发送事务内容,询问是否可以提交事务,并等待答复。b) 各参与者执行事务操作,将 undo 和 redo 信息记入事务日志中(但不提交事务)。

行秋的博客 7116

架构师职位常见面试题

一、架构师的日常职责是什么? 总体而言,架构师负责软件领域的顶层设计。 架构师需要根据公司的发展,规划企业未来若干年的架构,制定可落地的架构方案,解决技术难题,做技术选型与攻关,落地具体的架构。优秀的架构师既能做架构方案,也能写具体的架构代码。 二、开发工程师和架构师有何区别? 工作重点不同:架构师重点在于前期的架构规划,需要制定可落地的架构方案,结合公司的业务场景、团队的技术水平等因素...

科技D人生 1万+

嵌入式开发实战:LWIP中PPP协议配置全流程(含CHAP认证避坑指南)

本文是一份嵌入式开发实战指南,详细解析了如何在STM32平台上配置LWIP协议栈中的PPP协议,实现从串口到IP网络的完整连接。内容涵盖工程搭建、源码整合、关键配置、串口驱动绑定、状态管理以及CHAP认证等核心流程,并重点提供了CHAP认证失败的排查与避坑指南,帮助开发者高效打通嵌入式设备的网络连接。

plant的博客 464

Java高级进阶学习资料!最全的BAT大厂面试题整理

Java架构师成长笔记: 首先肯定是Java基础复习 SpringBoot快速上手 Web编程探索 SSM从入门到精通 1-3年高级工程师 微服务 并发编程进阶 深入Tomcat底层 JVM深度剖析 3-5年资深高级架构师 中间件&分布式 数据库 Spark 最后 我还通过一些渠道整理了一些大厂真实面试主要有:蚂蚁金服、拼多多、阿里云、百度、唯品会、携程、丰巢科技、乐信、软通动力、OPPO、银盛支付、中国平安等初,中级,高级Java面试题集合,附带超详细答案,希望能帮助到大家。

m0_56835488的博客 291

从指令到坐标:深度解析307系列基站定位的AT指令实战与排错

本文深度解析了ML307系列模组基站定位的AT指令实战应用与排错方法。重点剖析了AT+MLBSCFG和AT+MLBSLOC两条核心指令的配置、执行流程及异步响应机制,并针对高德与OneOs两种主流定位服务提供了完整的配置指南。文章结合常见错误码(如126、127)和硬件注意事项,分享了确保定位成功的实战经验与稳健的程序框架。

weixin_29057695的博客 490

Java架构师全路线总结+高频面试题(2021年最新版),快手三面面试真题

======= 并发编程进阶 (并发工具类实战+CAS+显示锁解析+线程池内部机制+性能优化) JVM深度剖析 (理解运行时数据区+堆外内存解读+JDK+内存泄漏问题排查+Arthas+GC算法和垃圾回收器+类加载机制等) MySQL深度进阶 深入Tomcat底层 (线程模型+性能调优) 3-5年资深: ======= 数据库(调优+事务+锁+集群+主从+缓存等) Linux(命令+生产环境+日志等) 中间件&分布式 (dubbo+MQ/kafka、Elasti

m0_63174420的博客 1681

解决Anaconda环境下catkin_make编译报错:Python路径冲突与empy模块缺失

本文详细分析了在Anaconda环境下使用catkin_make编译时出现的Python路径冲突与empy模块缺失问题,提供了快速解决方案和永久性环境配置方法。通过显式指定Python解释器路径或调整Anaconda配置,有效解决编译报错问题,适用于ROS开发与科学计算并行的场景。

weixin_28829629的博客 354

Python控制tek示波器(1)

如何使用Python来控制tek示波器

m0_47441496的博客 3379

架构师必备!为了避免数据库中数据的丢失或损坏

Java架构师成长笔记: 首先肯定是Java基础复习 SpringBoot快速上手 Web编程探索 SSM从入门到精通 1-3年高级工程师 微服务 并发编程进阶 深入Tomcat底层 JVM深度剖析 3-5年资深高级架构师 中间件&分布式 数据库 Spark 最后分享一波我的面试宝典——一线互联网大厂Java核心面试题库 以下是我个人的一些做法,希望可以给各位提供一些帮助: 点击《一线互联网大厂Java核心面试题库》即可免费领取,整理了很长一段时间,拿来复习面试刷题非常合适,

m0_57767600的博客 150

别再死记硬背了!用‘小乌龟’实战图解ROS1核心指令(rosnode/rostopic/rosparam保姆级手册)

本文通过经典的turtlesim乌龟仿真器,以可视化实战方式讲解ROS1核心指令(rosnode/rostopic/rosparam),帮助初学者摆脱死记硬背,在操控乌龟的过程中轻松掌握节点管理、话题通信和参数设置等ROS1核心概念。

weixin_28731223的博客 371

免费Java高级工程师学习资源,看这篇足矣了!

Java架构进阶之面试篇 面试这一块,分别有基础、中级、高级等三部分,一步一步检测。 Java基础面试+解析 Java中级开发面试+解析 Java高级面试+解析 Java架构进阶之技能导图篇 筑基 框架 分布式 微服务 Java架构进阶之架构筑基篇 架构筑基篇:Java基础+并发编程+JVM+MySQL+Tomcat+网络+数据结构与算法 JAVA基础:反射+注解+内部类+泛型+序列化+复制 并发编程 JVM MySQL Tomcat架

m0_57624732的博客 212

麒麟服务器操作系统QT系列软件工具手册

对Qt提供的开发工具进行了一系列的优化之后,在日常的修复bug和维护框架的过程中,桌面研发对Qt的基础软件库也进行了部分优化工作,包括qtbase、qtwayland、qtscript、qt4-x11等Qt基础组件,涉及的Qt框架版本主要涉及到5.9和5.12两个版本。qt 的翻译,是由 ts 文件生成 qm 文件然后进行翻译,国产操作系统上qt 的翻译是由单独的qttranslations包中进行维护,其次部分汉化问题也是qt组件维护工作的一部分,qt的翻译机制如图4-7所示。

太极淘的博客 543

3步搞定.NET Core在UOS上的部署?手把手教你从零到上线!

本文详细介绍了如何在统信UOS系统上部署.NET Core应用程序的完整流程。首先,通过安装.NET Core SDK,确保UOS系统能够编译和运行C#代码。接着,创建一个简单的控制台应用,并验证其本地运行情况。最后,通过发布应用、传输文件到UOS服务器,并解决权限问题,确保应用能够在UOS上顺利运行。文章还提供了常见问题的解决方案,如依赖缺失、权限不足和服务启动失败等,帮助开发者避免常见陷阱。通过本文的指导,开发者可以轻松将.NET Core应用部署到UOS系统,并实现24/7的稳定运行。

java专栏 589

java跑批任务防止重复,Java架构师成长路线

第1大技能:程序设计和开发 数据结构和算法:常用数据结构,排序,检索等 面向对象编程、设计模式,掌握建模语言和建模工具:UML、MVC编程思想 高质量编码能力:重用性,低耦合,可扩展性,高性能,可维护性,安全性高 集成开发,版本控制,构建等工具:eclipse, svn, maven 等 脚本语言:Perl,PHP, Ruby, Python, Groovy等 第2大技能:Java开发 Java语言基础:异常处理,泛型,reflection,annotation; Java基本

m0_56255097的博客 166

vue3:最新实现腾讯人脸核身+增强版人脸核身使用方法及示例源码,Vue3如何使用腾讯云慧眼人脸核身,提供人脸核身案例、身份信息核验、活体检测与核身比对等示例代码(后端spring与thinkphp)

vue3接入腾讯人脸核身,腾讯云人脸核身Vue3+后端代码,H5人脸核身,vue3 H5如何使用腾讯人脸核身sdk,vue3+thinkphp腾讯人脸核身,Spring Boot接入腾讯云人脸核身教程,hinkphp腾讯人脸核身,vue3人脸核身插件接入流程,vue+spring boot实现腾讯人脸核身,vue3接入腾讯云【增强版人脸核身接入】,vue3 h5微信公众号网页腾讯云慧眼人脸核身,tvue3接入人脸核身SDK,vue3+typescrip+vite接入慧眼实名认证,vue3腾讯云活体人脸核身(

✅ 精选推荐文章 4121

Java岗面试必问!docker加速源

Java架构师成长笔记: 首先肯定是Java基础复习 SpringBoot快速上手 Web编程探索 SSM从入门到精通 1-3年高级工程师 微服务 并发编程进阶 深入Tomcat底层 JVM深度剖析 3-5年资深高级架构师 中间件&分布式 数据库 Spark 总结 蚂蚁面试比较重视基础,所以Java那些基本功一定要扎实。蚂蚁的工作环境还是挺赞的,因为我面的是稳定性保障部门,还有许多单独的小组,什么三年1班,很有青春的感觉。面试官基本水平都比较高,基本都P7以上,除了基础还问了不

m0_56662269的博客 182

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Java程序员:java面向对象编程总结

第1大技能:程序设计和开发 数据结构和算法:常用数据结构,排序,检索等 面向对象编程、设计模式,掌握建模语言和建模工具:UML、MVC编程思想 高质量编码能力:重用性,低耦合,可扩展性,高性能,可维护性,安全性高 集成开发,版本控制,构建等工具:eclipse, svn, maven 等 脚本语言:Perl,PHP, Ruby, Python, Groovy等 第2大技能:Java开发 Java语言基础:异常处理,泛型,reflection,annotation; Java基本

m0_57285455的博客 292

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

可能是最全的java架构师面试题

架构师必读 最全最新java面试题系列全家桶(带答案) 架构师职位常见面试题 源码分析 常用设计模式 23种经典设计模式都有哪些,如何分类 阿里java设计模式面试题 Spring 框架中都用到了哪些设计模式 开发中都用到了那些设计模式?用在什么场合? 微服务架构的六种常用设计模式是什么? 1、proxy代理模式 2、factory工厂模式 3、singleton单例模式 4、delegate委派...

jovisoft的专栏 2万+

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Java 架构师面试题解析(2024 年版)

分布式事务是指在分布式系统中,涉及多个节点的事务操作。由于分布式系统的复杂性,传统的单机事务处理方式已经不能满足需求,需要采用专门的分布式事务解决方案。两阶段提交(2PC)准备阶段:事务协调者向所有参与者发送准备请求,参与者执行事务操作,但不提交,然后向协调者回复是否准备成功。提交阶段:如果所有参与者都回复准备成功,协调者向所有参与者发送提交请求,参与者提交事务;否则,协调者向所有参与者发送回滚请求,参与者回滚事务。优点:实现简单,对事务的强一致性有较好的保证。

爱好技术的小老头 6361

大厂 Java 架构师面试题全解析

在竞争激烈的 Java 开发领域,想要晋升为架构师,面临的面试挑战不容小觑。大厂的面试官往往会从多个维度深入考察候选人的技术功底、架构设计能力、问题解决思维等。以下精心整理了 30 道大厂 Java 架构师面试题,助你一臂之力。

爱好技术的小老头 3541

JAVA架构师面试题,如何成为架构师

JAVA架构师面试题,如何成为架构师 经常面试一些候选人,整理了下我面试使用的题目,陆陆续续整理出来的题目很多,所以每次会抽一部分来问。答案会在后面的文章中逐渐发布出来。 基础题目 Java线程的状态 进程和线程的区别,进程间如何通讯,线程间如何通讯 HashMap的数据结构是什么?如何实现的。和HashTable,ConcurrentHashMap的区别

huangshulang1234的博客 2万+

43道Java架构师面试题以及答案解析,快测试一下你会不会?

前言 2021年通用架构师面试问题,面试中较为笼统的部分不一定只专注于您的简历。它还可能包含一些有关您从事的项目以及如何管理时间和优先级的问题。作为架构师去参加面试的时候只有自己平时的积累可能是源源不够的,我们还要去了解一些平时工作中可能不会接触到的技术相关来丰富我们自己的眼界,也需要去了解所要面试公司的架构的演进,有一个对应的了解,会对我们的职业生涯带来更多的帮助。 ## 一、架构师的日常职责是什么 ? 总体而言,架构师负责软件领域的顶层设计。 架构师需要根据公司的发展,规划企业未来若干年的架构,制定可

weixin_56667968的博客 2万+

java架构师_Java架构师职位常见面试题

一、架构师的日常职责是什么 ?总体而言,架构师负责软件领域的顶层设计。架构师需要根据公司的发展,规划企业未来若干年的架构,制定可落地的架构方案,解决技术难题,做技术选型与攻关,落地具体的架构。优秀的架构师既能做架构方案,也能写具体的架构代码。二、开发工程师和架构师有何区别?工作重点不同:架构师重点在于前期的架构规划,需要制定可落地的架构方案,结合公司的业务场景、团队的技术水平等因素做技术选型,解决...

weixin_39915668的博客 1589
上一篇: java架构师面试题——Zookeeper篇
下一篇: java架构师面试题——网络篇
杜引强
博客等级 码龄13年 806粉丝 68原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值