2024,Java最全的分布式面试题合集附答案,共2w字!,2024年最新java面试常问的算法题及答案

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
img

正文

  • Redis 数据分片原理是哈希槽(hash slot)。

  • Redis 集群有 16384 个哈希槽。每一个 Redis 集群中的节点都承担一个哈希槽的子集。

哈希槽让在集群中添加和移除节点非常容易。例如,如果我想添加一个新节点 D ,我需要从节点 A 、B、C 移动一些哈希槽到节点 D。同样地,如果我想从集群中移除节点 A ,我只需要移动 A 的哈希槽到 B 和 C。当节点 A 变成空的以后,我就可以从集群中彻底删除它。因为从一个节点向另一个节点移动哈希槽并不需要停止操作,所以添加和移除节点,或者改变节点持有的哈希槽百分比,都不需要任何停机时间(downtime)。

问:讲一下一致性 Hash 算法。

  • 一致性 Hash 算法将整个哈希值空间组织成一个虚拟的圆环, 我们对 key 进行哈希计算,使用哈希后的结果对 2 ^ 32 取模,hash 环上必定有一个点与这个整数对应。依此确定此数据在环上的位置,从此位置沿环顺时针“行走”,第一台遇到的服务器就是其应该定位到的服务器。

  • 一致性 Hash 算法对于节点的增减都只需重定位环空间中的一小部分数据,具有较好的容错性和可扩展性。

比如,集群有四个节点 Node A 、B 、C 、D ,增加一台节点 Node X。Node X 的位置在 Node B 到 Node C 直接,那么受到影响的仅仅是 Node B 到 Node X 间的数据,它们要重新落到 Node X 上。

所以一致性哈希算法对于容错性和扩展性有非常好的支持。

问:为什么 Redis Cluster 分片不使用 Redis 一致性 Hash 算法?

一致性哈希算法也有一个严重的问题,就是数据倾斜。

如果在分片的集群中,节点太少,并且分布不均,一致性哈希算法就会出现部分节点数据太多,部分节点数据太少。也就是说无法控制节点存储数据的分配。

问:集群的拓扑结构有没有了解过?集群是怎么连接的?

无中心结构。Redis-Cluster 采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。

问:讲一下 Redis 主从复制的过程。

从机发送 SYNC(同步)命令,主机接收后会执行 BGSAVE(异步保存)命令备份数据。

主机备份后,就会向从机发送备份文件。主机之后还会发送缓冲区内的写命令给从机。

当缓冲区命令发送完成后,主机执行一条写命令,就会往从机发送同步写入命令。

问:讲一下 Redis 哨兵机制。

下面是 Redis 官方文档对于哨兵功能的描述:

  • 监控(Monitoring):哨兵会不断地检查主节点和从节点是否运作正常。

  • 自动故障转移(Automatic Failover):当主节点不能正常工作时,哨兵会开始自动故障转移操作,它会将失效主节点的其中一个从节点升级为新的主节点,并让其他从节点改为复制新的主节点。

  • 配置提供者(Configuration Provider):客户端在初始化时,通过连接哨兵来获得当前 Redis 服务的主节点地址。

  • 通知(Notification):哨兵可以将故障转移的结果发送给客户端。

问:讲一下布隆过滤器。

布隆过滤器的主要是由一个很长的二进制向量和若干个(k 个)散列映射函数组成。因为每个元数据的存储信息值固定,而且总的二进制向量固定。所以在内存占用和查询时间上都远远超过一般的算法。当然存在一定的不准确率(可以控制)和不容易删除样本数据。

布隆过滤器的优点:大批量数据去重,特别的占用内存。但是用布隆过滤器(Bloom Filter)会非常的省内存。

布隆过滤器的特点:当布隆过滤器说某个值存在时,那可能就不存在,如果说某个值不存在时,那肯定就是不存在了。

布隆过滤器的应用场景:新闻推送(不重复推送)。解决缓存穿透的问题。

四、缓存


问:缓存雪崩是什么?

如果缓存数据设置的过期时间是相同的,并且 Redis 恰好将这部分数据全部删光了。这就会导致在这段时间内,这些缓存同时失效,全部请求到数据库中。这就是缓存雪崩。

问:怎么解决缓存雪崩?

解决方法:在缓存的时候给过期时间加上一个随机值,这样就会大幅度的减少缓存在同一时间过期。

问:缓存穿透是什么?

缓存穿透是指查询一个一定不存在的数据。由于缓存不命中,并且出于容错考虑,如果从数据库查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,失去了缓存的意义。

问:怎么解决缓存穿透?

问:什么是缓存与数据库双写一致问题?

问:如何保证缓存与数据库的一致性?

读的时候,先读缓存,缓存没有的话,就读数据库,然后取出数据后放入缓存,同时返回响应。

先删除缓存,再更新数据库。

问:为什么是先删除缓存,而不是先更新缓存?

问:先更新数据库,再删除缓存,会有什么问题?

先更新数据库,再删除缓存。可能出现以下情况:

如果更新完数据库, Java 服务提交了事务,然后挂掉了,那 Redis 还是会执行,这样也会不一致。

如果更新数据库成功,删除缓存失败了,那么会导致数据库中是新数据,缓存中是旧数据,数据就出现了不一致。

先删除缓存,再更新数据库。

如果删除缓存失败,那就不更新数据库,缓存和数据库的数据都是旧数据,数据是一致的。

如果删除缓存成功,而数据库更新失败了,那么数据库中是旧数据,缓存中是空的,数据不会不一致。因为读的时候缓存没有,所以去读了数据库中的旧数据,然后更新到缓存中。

问:先删除缓存,在写数据库成功之前,如果有读请求发生,可能导致旧数据入缓存,引发数据不一致,怎么处理?

分布式锁

问:Redis 如何实现分布式锁?

使用 set key value ex nx 命令。

当 key 不存在时,将 key 的值设为 value ,返回 1。若给定的 key 已经存在,则 setnx 不做任何动作,返回 0。

当 setnx 返回 1 时,表示获取锁,做完操作以后 del key ,表示释放锁,如果 setnx 返回 0 表示获取锁失败。

详细的命令如下:

set key value [EX seconds] [PX milliseconds] [NX|XX]

EX seconds:设置失效时长,单位秒

PX milliseconds:设置失效时长,单位毫秒

NX:key不存在时设置value,成功返回OK,失败返回(nil)

XX:key存在时设置value,成功返回OK,失败返回(nil)。

示例如下:

set name fenglin ex 100 nx

问:为什么不先 set nx ,然后再使用 expire 设置超时时间?

我们需要保证 setnx 命令和 expire 命令以原子的方式执行,否则如果客户端执行 setnx 获得锁后,这时客户端宕机了,那么这把锁没有设置过期时间,导致其他客户端永远无法获得锁了。

问:使用 Redis 分布式锁, key 和 value 分别设置成什么?

value 可以使用 json 格式的字符串,示例:

{

“count”:1,

“expireAt”:147506817232,

“jvmPid”:22224,

“mac”:“28-D2-44-0E-0D-9A”,

“threadId”:14

}

问:Redis 实现的分布式锁,如果某个系统获取锁后,宕机了怎么办?

系统模块宕机的话,可以通过设置过期时间(就是设置缓存失效时间)解决。系统宕机时锁阻塞,过期后锁释放。

问:设置缓存失效时间,那如果前一个线程把这个锁给删除了呢?

问:如果加锁和解锁之间的业务逻辑执行的时间比较长,超过了锁过期的时间,执行完了,又删除了锁,就会把别人的锁给删了。怎么办?

这两个属于锁超时的问题。

可以将锁的 value 设置为 Json 字符串,在其中加入线程的 id 或者请求的 id ,在删除之前, get 一下这个 key ,判断 key 对应的 value 是不是当前线程的。只有是当前线程获取的锁,当前线程才可以删除。

问:Redis 分布式锁,怎么保证可重入性?

可以将锁的 value 设置为 Json 字符串,在其中加入线程的 id 和 count 变量。

当 count 变量的值为 0 时,表示当前分布式锁没有被线程占用。

如果 count 变量的值大于 0 ,线程 id 不是当前线程,表示当前分布式锁已经被其他线程占用。

如果 count 变量的值大于 0 ,线程 id 是当前线程的 id ,表示当前线程已经拿到了锁,不必阻塞,可以直接重入,并将 count 变量的值加一即可。

这种思路,其实就是参考了 ReentrantLock 可重入锁的机制。

问:Redis 做分布式锁, Redis 做了主从,如果设置锁之后,主机在传输到从机的时候挂掉了,从机还没有加锁信息,如何处理?

可以使用开源框架 Redisson ,采用了 redLock。

问:讲一下 Redis 的 redLock。

问:Zookeeper 是怎么实现分布式锁的?

分布式锁:基于 Zookeeper 一致性文件系统,实现锁服务。锁服务分为保存独占及时序控制两类。

保存独占:将 Zookeeper 上的一个 znode 看作是一把锁,通过 createznode 的方式来实现。所有客户端都去创建 / distribute _ lock 节点,最终成功创建的那个客户端也即拥有了这把锁。用完删除自己创建的 distribute _ lock 节点就释放锁。

时序控制:基于/ distribute _ lock 锁,所有客户端在它下面创建临时顺序编号目录节点,和选 master 一样,编号最小的获得锁,用完删除,依次方便。

更详细的回答如下:

其实基于 Zookeeper ,就是使用它的临时有序节点来实现的分布式锁。

原理就是:当某客户端要进行逻辑的加锁时,就在 Zookeeper 上的某个指定节点的目录下,去生成一个唯一的临时有序节点, 然后判断自己是否是这些有序节点中序号最小的一个,如果是,则算是获取了锁。如果不是,则说明没有获取到锁,那么就需要在序列中找到比自己小的那个节点,并对其调用 exist() 方法,对其注册事件监听,当监听到这个节点被删除了,那就再去判断一次自己当初创建的节点是否变成了序列中最小的。如果是,则获取锁,如果不是,则重复上述步骤。

当释放锁的时候,只需将这个临时节点删除即可。

五、Zookeeper


问:Zookeeper 的原理是什么?

问:Zookeeper 是怎么保证一致性的?

zab 协议。

zab 协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者崩溃后, zab 就进入了恢复模式,当领导者被选举出来,且大多数 server 完成了和 leader 的状态同步以后,恢复模式就结束了。状态同步保证了 leader 和 server 具有相同的系统状态。

问:Zookeeper 有哪些应用场景?

Zookeeper 可以作为服务协调的注册中心。还可以做分布式锁(如果没有用过分布式锁就不要说)。

问:Zookeeper 为什么能做注册中心?

Zookeeper 的数据模型是树型结构,由很多数据节点组成, zk 将全量数据存储在内存中,可谓是高性能,而且支持集群,可谓高可用。另外支持事件监听(watch 命令)。

Zookeeper 可以作为一个数据发布/订阅系统。

问:Zookeeper 的节点有哪些类型?有什么区别?

临时节点,永久节点。更加细分就是临时有序节点、临时无序节点、永久有序节点、永久无序节点。

临时节点:当创建临时节点的程序停掉之后,这个临时节点就会消失,存储的数据也没有了。

问:Zookeeper 做为注册中心,主要存储哪些数据?存储在哪里?

IP、端口、还有心跳机制。数据存储在 Zookeeper 的节点上面。

问:心跳机制有什么用?

问:Zookeeper 的广播模式有什么缺陷?

广播风暴。

问:讲一下 Zookeeper 的读写机制。

Leader 主机负责读和写。

Follower 负责读,并将写操作转发给 Leader。Follower 还参与 Leader 选举投票,参与事务请求 Proposal 投票。

Observer 充当观察者的角色。Observer 和 Follower 的唯一区别在于:Observer 不参与任何投票。

问:讲一下 Zookeeper 的选举机制。

Leader 不可用时,会重新选举 Leader。超过半数的 Follower 选举投票即可,Observer 不参与投票。

问:你们的 Zookeeper 集群配置了几个节点?

3 个节点。注意:Zookeeper 集群节点,最好是奇数个的。

集群中的 Zookeeper 节点需要超过半数,整个集群对外才可用。

这里所谓的整个集群对外才可用,是指整个集群还能选出一个 Leader 来, Zookeeper 默认采用 quorums 来支持 Leader 的选举。

如果有 2 个 Zookeeper,那么只要有 1 个死了 Zookeeper 就不能用了,因为 1 没有过半,所以 2 个 Zookeeper 的死亡容忍度为 0 ;同理,要是有 3 个 Zookeeper,一个死了,还剩下 2 个正常的,过半了,所以 3 个 Zookeeper 的容忍度为 1 ;同理你多列举几个:2 -> 0 ; 3 -> 1 ; 4 -> 1 ; 5 -> 2 ; 6 -> 2 会发现一个规律, 2n 和 2n - 1 的容忍度是一样的,都是 n - 1 ,所以为了更加高效,何必增加那一个不必要的 Zookeeper 呢。

问:Zookeeper 的集群节点,如果不是奇数可能会出现什么问题?

可能会出现脑裂。

假死:由于心跳超时(网络原因导致的)认为 master 死了,但其实 master 还存活着。

脑裂:由于假死会发起新的 master 选举,选举出一个新的 master ,但旧的 master 网络又通了,导致出现了两个 master ,有的客户端连接到老的 master 有的客户端链接到新的 master。

六、消息队列


问:为什么使用消息队列?消息队列有什么优点和缺点?Kafka 、ActiveMQ 、RabbitMq 、RocketMQ 都有什么优点和缺点?

消息队列解耦,削峰,限流。

问:如何保证消息队列的高可用?(多副本)

问:如何保证消息不被重复消费?(如何保证消息消费的幂等性)

问:如何保证消息的可靠性传输?(如何处理消息丢失的问题)

问:如何保证消息的顺序性?

问:如何解决消息队列的延时以及过期失效问题?消息队列满了以后该怎么处理?有几百万消息持续积压几小时,说说怎么解决?

问:如果让你写一个消息队列,该如何进行架构设计啊?说一下你的思路。

七、Kafka


问:讲一下 Kafka。

Kafka 的简单理解

问:Kafka 相对其他消息队列,有什么特点?

持久化:Kafka 的持久化能力比较好,通过磁盘持久化。而 RabbitMQ 是通过内存持久化的。

吞吐量:Rocket 的并发量非常高。

消息处理:RabbitMQ 的消息不支持批量处理,而 RocketMQ 和 Kafka 支持批量处理。

高可用:RabbitMQ 采用主从模式。Kafka 也是主从模式,通过 Zookeeper 管理,选举 Leader ,还有 Replication 副本。

事务:RocketMQ 支持事务,而 Kafka 和 RabbitMQ 不支持。

问:Kafka 有哪些模式?

如果一个生产者或者多个生产者产生的消息能够被多个消费者同时消费的情况,这样的消息队列称为"发布订阅模式"的消息队列。

问:Kafka 作为消息队列,有哪些优势?

分布式的消息系统。

高吞吐量。即使存储了许多 TB 的消息,它也保持稳定的性能。

数据保留在磁盘上,因此它是持久的。

问:Kafka 为什么处理速度会很快?kafka 的吞吐量为什么高?

零拷贝:Kafka 实现了"零拷贝"原理来快速移动数据,避免了内核之间的切换。

消息压缩、分批发送:Kafka 可以将数据记录分批发送,从生产者到文件系统(Kafka 主题日志)到消费者,可以端到端的查看这些批次的数据。

批处理能够进行更有效的数据压缩并减少 I / O 延迟。

顺序读写:Kafka 采取顺序写入磁盘的方式,避免了随机磁盘寻址的浪费。

问:讲一下 Kafka 中的零拷贝。

数据的拷贝从内存拷贝到 kafka 服务进程那块,又拷贝到 socket 缓存那块,整个过程耗费的时间比较高, kafka 利用了 Linux 的 sendFile 技术(NIO),省去了进程切换和一次数据拷贝,让性能变得更好。

问:Kafka 的偏移量是什么?

消费者每次消费数据的时候,消费者都会记录消费的物理偏移量(offset)的位置。等到下次消费时,他会接着上次位置继续消费

问:Kafka 的生产者,是如何发送消息的?

生产者的消息是先被写入分区中的缓冲区中,然后分批次发送给 Kafka Broker。

生产者的消息发送机制,有同步发送和异步发送。

同步发送消息都有个问题,那就是同一时间只能有一个消息在发送,这会造成许多消息。

无法直接发送,造成消息滞后,无法发挥效益最大化。

异步发送消息的同时能够对异常情况进行处理,生产者提供了 Callback 回调。

问:Kafka 生产者发送消息,有哪些分区策略?

Kafka 的分区策略指的就是将生产者发送到哪个分区的算法。有顺序轮询、随机轮询、key - ordering 策略。

key - ordering 策略:Kafka 中每条消息都会有自己的 key ,一旦消息被定义了 Key ,那么你就可以保证同一个 Key 的所有消息都进入到相同的分区里面,由于每个分区下的消息处理都是有顺序的,故这个策略被称为按消息键保序策略。

问:Kafka 为什么要分区?

实现负载均衡和水平扩展。Kafka 可以将主题(Topic)划分为多个分区(Partition),会根据分区规则选择把消息存储到哪个分区中,只要如果分区规则设置的合理,那么所有的消息将会被均匀的分布到不同的分区中,这样就实现了负载均衡和水平扩展。另外,多个订阅者可以从一个或者多个分区中同时消费数据,以支撑海量数据处理能力。

问:Kafka 是如何在 Broker 间分配分区的?

在 broker 间平均分布分区副本。

假设有 6 个 broker ,打算创建一个包含 10 个分区的 Topic ,复制系数为 3 ,那么 Kafka 就会有 30 个分区副本,它可以被分配给这 6 个 broker ,这样的话,每个 broker 可以有 5 个副本。

要确保每个分区的每个副本分布在不同的 broker 上面:

假设 Leader 分区 0 会在 broker1 上面, Leader 分区 1 会在 broker2 上面, Leder 分区 2 会在 broker3 上面。

接下来会分配跟随者副本。如果分区 0 的第一个 Follower 在 broker2 上面,第二个 Follower 在 broker3 上面。分区 1 的第一个 Follower 在 broker3 上面,第二个 Follower 在 broker4 上面。

问:Kafka 如何保证消息的顺序性?

Kafka 可以保证同一个分区里的消息是有序的。也就是说消息发送到一个 Partition 是有顺序的。

问:Kafka 的消费者群组 Consumer Group 订阅了某个 Topic ,假如这个 Topic 接收到消息并推送,那整个消费者群组能收到消息吗?

Kafka 官网中有这样一句" Consumers label themselves with a consumer group name , and each record published to a topic is delivered to one consumer instance within each subscribing consumer group . "

表示推送到 topic 上的 record ,会被传递到已订阅的消费者群组里面的一个消费者实例。

问:如何提高 Kafka 的消费速度?

问:Kafka 出现消息积压,有哪些原因?怎么解决?

出现消息积压,可能是因为消费的速度太慢。

扩容消费者。之所以消费延迟大,就是消费者处理能力有限,可以增加消费者的数量。

扩大分区。一个分区只能被消费者群组中的一个消费者消费。消费者扩大,分区最好多随之扩大。

问:Kafka 消息消费者宕机了,怎么确认有没有收到消息?

ACK 机制,如果接收方收到消息后,会返回一个确认字符。

问:讲一下 Kafka 的 ACK 机制。

acks 参数指定了要有多少个分区副本接收消息,生产者才认为消息是写入成功的。此参数对消息丢失的影响较大。

如果 acks = 0 ,就表示生产者也不知道自己产生的消息是否被服务器接收了,它才知道它写成功了。如果发送的途中产生了错误,生产者也不知道,它也比较懵逼,因为没有返回任何消息。这就类似于 UDP 的运输层协议,只管发,服务器接受不接受它也不关心。

如果 acks = 1 ,只要集群的 Leader 接收到消息,就会给生产者返回一条消息,告诉它写入成功。如果发送途中造成了网络异常或者 Leader 还没选举出来等其他情况导致消息写入失败,生产者会受到错误消息,这时候生产者往往会再次重发数据。因为消息的发送也分为 同步 和 异步, Kafka 为了保证消息的高效传输会决定是同步发送还是异步发送。如果让客户端等待服务器的响应(通过调用 Future 中的 get() 方法),显然会增加延迟,如果客户端使用回调,就会解决这个问题。

如果 acks = all ,这种情况下是只有当所有参与复制的节点都收到消息时,生产者才会接收到一个来自服务器的消息。不过,它的延迟比 acks = 1 时更高,因为我们要等待不只一个服务器节点接收消息。

问:Kafka 如何避免消息丢失?

1、生产者丢失消息的情况

生产者(Producer) 调用 send 方法发送消息之后,消息可能因为网络问题并没有发送过去。

所以,我们不能默认在调用 send 方法发送消息之后消息消息发送成功了。为了确定消息是发送成功,我们要判断消息发送的结果。

可以采用为其添加回调函数的形式,获取回调结果。

如果消息发送失败的话,我们检查失败的原因之后重新发送即可!

可以设置 Producer 的 retries(重试次数)为一个比较合理的值,一般是 3 ,但是为了保证消息不丢失的话一般会设置比较大一点。

设置完成之后,当出现网络问题之后能够自动重试消息发送,避免消息丢失。

2、消费者丢失消息的情况

当消费者拉取到了分区的某个消息之后,消费者会自动提交了 offset。自动提交的话会有一个问题,

试想一下,当消费者刚拿到这个消息准备进行真正消费的时候,突然挂掉了,消息实际上并没有被消费,但是 offset 却被自动提交了。

手动关闭闭自动提交 offset ,每次在真正消费完消息之后之后再自己手动提交 offset 。

3 、Kafka 丢失消息

a、假如 leader 副本所在的 broker 突然挂掉,那么就要从 follower 副本重新选出一个 leader ,但是 leader 的数据还有一些没有被 follower 副本的同步的话,就会造成消息丢失。因此可以设置 ack = all。

b、设置 replication . factor >= 3 。为了保证 leader 副本能有 follower 副本能同步消息,我们一般会为 topic 设置 replication . factor >= 3。这样就可以保证每个

分区(partition) 至少有 3 个副本。虽然造成了数据冗余,但是带来了数据的安全性。

问:Kafka 怎么保证可靠性?

多副本以及 ISR 机制。

在 Kafka 中主要通过 ISR 机制来保证消息的可靠性。

ISR(in sync replica):是 Kafka 动态维护的一组同步副本,在 ISR 中有成员存活时,只有这个组的成员才可以成为 leader ,内部保存的为每次提交信息时必须同步的副本(acks = all 时),每当 leader 挂掉时,在 ISR 集合中选举出一个 follower 作为 leader 提供服务,当 ISR 中的副本被认为坏掉的时候,会被踢出 ISR ,当重新跟上 leader 的消息数据时,重新进入 ISR。

问:什么是 HW ?

HW(high watermark):副本的高水印值, replica 中 leader 副本和 follower 副本都会有这个值,通过它可以得知副本中已提交或已备份消息的范围, leader 副本中的 HW ,决定了消费者能消费的最新消息能到哪个 offset。

问:什么是 LEO ?

LEO(log end offset):日志末端位移,代表日志文件中下一条待写入消息的 offset ,这个 offset 上实际是没有消息的。不管是 leader 副本还是 follower 副本,都有这个值。

问:Kafka 怎么保证一致性?(存疑)

一致性定义:若某条消息对 client 可见,那么即使 Leader 挂了,在新 Leader 上数据依然可以被读到。

HW - HighWaterMark : client 可以从 Leader 读到的最大 msg offset ,即对外可见的最大 offset , HW = max(replica . offset)

对于 Leader 新收到的 msg , client 不能立刻消费, Leader 会等待该消息被所有 ISR 中的 replica 同步后,更新 HW ,此时该消息才能被 client 消费,这样就保证了如果 Leader fail ,该消息仍然可以从新选举的 Leader 中获取。

对于来自内部 Broker 的读取请求,没有 HW 的限制。同时, Follower 也会维护一份自己的 HW , Folloer . HW = min(Leader . HW , Follower . offset).

问:Kafka 怎么处理重复消息?怎么避免重复消费?

偏移量 offset :消费者每次消费数据的时候,消费者都会记录消费的物理偏移量(offset)的位置。等到下次消费时,他会接着上次位置继续消费。

一般情况下, Kafka 重复消费都是由于未正常提交 offset 造成的,比如网络异常,消费者宕机之类的。

使用的是 spring-Kafka ,所以把 Kafka 消费者的配置 enable.auto. commit 设为 false ,禁止 Kafka 自动提交 offset ,从而使用 spring-Kafka 提供的 offset 提交策略。

sprin-Kafka 中的 offset 提交策略可以保证一批消息数据没有完成消费的情况下,也能提交 offset ,从而避免了提交失败而导致永远重复消费的问题。

问:怎么避免重复消费?

将消息的唯一标识保存起来,每次消费时判断是否处理过即可。

问:如何保证消息不被重复消费?(如何保证消息消费的幂等性)

怎么保证消息队列消费的幂等性?其实还是得结合业务来思考,有几个思路:

比如你拿个数据要写库,你先根据主键查一下,如果这数据都有了,你就别插入了, update 一下好吧。

比如你是写 Redis ,那没问题了,反正每次都是 set ,天然幂等性。

如果是复杂一点的业务,那么每条消息加一个全局唯一的 id ,类似订单 id 之类的东西,然后消费到了之后,先根据这个 id 去比如 Redis 里查一下,之前消费过吗?

如果没有消费过,你就处理,然后这个 id 写 Redis。如果消费过了,那你就别处理了,保证别重复处理相同的消息即可。

问:Kafka 消息是采用 pull 模式,还是 push 模式?

pull 模式。

问:pull 模式和 push 模式,各有哪些特点?

pull 模式,准确性?可以较大保证消费者能获取到消息。

push 模式,即时性?可以在 broker 获取消息后马上送达消费者。

最后的内容

在开头跟大家分享的时候我就说,面试我是没有做好准备的,全靠平时的积累,确实有点临时抱佛脚了,以至于我自己还是挺懊恼的。(准备好了或许可以拿个40k,没做准备只有30k+,你们懂那种感觉吗)

如何准备面试?

1、前期铺垫(技术沉积)

程序员面试其实是对于技术的一次摸底考试,你的技术牛逼,那你就是大爷。大厂对于技术的要求主要体现在:基础,原理,深入研究源码,广度,实战五个方面,也只有将原理理论结合实战才能把技术点吃透。

下面是我会看的一些资料笔记,希望能帮助大家由浅入深,由点到面的学习Java,应对大厂面试官的灵魂追问

这部分内容过多,小编只贴出部分内容展示给大家了,见谅见谅!

  • Java程序员必看《Java开发核心笔记(华山版)》

  • Redis学习笔记

  • Java并发编程学习笔记

四部分,详细拆分并发编程——并发编程+模式篇+应用篇+原理篇

  • Java程序员必看书籍《深入理解 ava虚拟机第3版》(pdf版)

  • 大厂面试必问——数据结构与算法汇集笔记

其他像Spring,SpringBoot,SpringCloud,SpringCloudAlibaba,Dubbo,Zookeeper,Kafka,RocketMQ,RabbitMQ,Netty,MySQL,Docker,K8s等等我都整理好,这里就不一一展示了。

2、狂刷面试题

技术主要是体现在平时的积累实用,面试前准备两个月的时间再好好复习一遍,紧接着就可以刷面试题了,下面这些面试题都是小编精心整理的,贴给大家看看。

①大厂高频45道笔试题(智商题)

②BAT大厂面试总结(部分内容截图)

③面试总结

3、结合实际,修改简历

程序员的简历一定要多下一些功夫,尤其是对一些字眼要再三斟酌,如“精通、熟悉、了解”这三者的区别一定要区分清楚,否则就是在给自己挖坑了。当然不会包装,我可以将我的简历给你参考参考,如果还不够,那下面这些简历模板任你挑选:

以上分享,希望大家可以在金三银四跳槽季找到一份好工作,但千万也记住,技术一定是平时工作种累计或者自学(或报班跟着老师学)通过实战累计的,千万不要临时抱佛脚。

另外,面试中遇到不会的问题不妨尝试讲讲自己的思路,因为有些问题不是考察我们的编程能力,而是逻辑思维表达能力;最后平时要进行自我分析与评价,做好职业规划,不断摸索,提高自己的编程能力和抽象思维能力。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
etty,MySQL,Docker,K8s等等我都整理好,这里就不一一展示了。

[外链图片转存中…(img-xJuD6Q2Z-1713019818070)]

2、狂刷面试题

技术主要是体现在平时的积累实用,面试前准备两个月的时间再好好复习一遍,紧接着就可以刷面试题了,下面这些面试题都是小编精心整理的,贴给大家看看。

①大厂高频45道笔试题(智商题)

[外链图片转存中…(img-vLwavV1K-1713019818071)]

②BAT大厂面试总结(部分内容截图)

[外链图片转存中…(img-lwyzu88R-1713019818071)]

[外链图片转存中…(img-Ixck7t0j-1713019818071)]

③面试总结

[外链图片转存中…(img-KuuFxi9A-1713019818072)]

[外链图片转存中…(img-bP0iLm97-1713019818072)]

3、结合实际,修改简历

程序员的简历一定要多下一些功夫,尤其是对一些字眼要再三斟酌,如“精通、熟悉、了解”这三者的区别一定要区分清楚,否则就是在给自己挖坑了。当然不会包装,我可以将我的简历给你参考参考,如果还不够,那下面这些简历模板任你挑选:

[外链图片转存中…(img-uPkqqLVh-1713019818072)]

以上分享,希望大家可以在金三银四跳槽季找到一份好工作,但千万也记住,技术一定是平时工作种累计或者自学(或报班跟着老师学)通过实战累计的,千万不要临时抱佛脚。

另外,面试中遇到不会的问题不妨尝试讲讲自己的思路,因为有些问题不是考察我们的编程能力,而是逻辑思维表达能力;最后平时要进行自我分析与评价,做好职业规划,不断摸索,提高自己的编程能力和抽象思维能力。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-1CXvYfOm-1713019818072)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值