写点什么

一个 Java 程序员的面试心得,最终入职阿里

发布于: 17 小时前

1. 面试官:工作中使用过 Zookeeper 嘛?你知道它是什么,有什么用途呢?

小菜鸡的我:


  • 有使用过的,使用 ZooKeeper 作为 dubbo 的注册中心,使用 ZooKeeper 实现分布式锁

  • ZooKeeper,它是一个开放源码的分布式协调服务,它是一个集群的管理者,它将简单易用的接口提供给用户。

  • 可以基于 Zookeeper 实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能

  • Zookeeper 的用途:命名服务、配置管理、集群管理、分布式锁、队列管理


用途跟功能不是一个意思咩?

2. 面试官:说下什么是命名服务,什么是配置管理,又什么是集群管理吧

小菜鸡的我(幸好我刷过面试题),无所畏惧


  • 命名服务就是

  • 命名服务是指通过指定的名字来获取资源或者服务地址。Zookeeper 可以创建一个全局唯一的路径,这个路径就可以作为一个名字。被命名的实体可以是集群中的机器,服务的地址,或者是远程的对象等。一些分布式服务框架(RPC、RMI)中的服务地址列表,通过使用命名服务,客户端应用能够根据特定的名字来获取资源的实体、服务地址和提供者信息等。

  • 配置管理:

  • 实际项目开发中,我们经常使用.properties 或者 xml 需要配置很多信息,如数据库连接信息、fps 地址端口等等。因为你的程序一般是分布式部署在不同的机器上(如果你是单机应用当我没说),如果把程序的这些配置信息保存在 zk 的 znode 节点下,当你要修改配置,即 znode 会发生变化时,可以通过改变 zk 中某个目录节点的内容,利用 watcher 通知给各个客户端,从而更改配置。

  • 集群管理

  • 集群管理包括集群监控和集群控制,其实就是监控集群机器状态,剔除机器和加入机器。zookeeper 可以方便集群机器的管理,它可以实时监控 znode 节点的变化,一旦发现有机器挂了,该机器就会与 zk 断开连接,对用的临时目录节点会被删除,其他所有机器都收到通知。新机器加入也是类似酱紫,所有机器收到通知:有新兄弟目录加入啦。

3. 面试官:你提到了 znode 节点,那你知道 znode 有几种类型呢?zookeeper 的数据模型是怎样的呢?

小菜鸡的我(我先想想):

zookeeper 的数据模型

ZooKeeper 的视图数据结构,很像 Unix 文件系统,也是树状的,这样可以确定每个路径都是唯一的。zookeeper 的节点统一叫做 znode,它是可以通过路径来标识,结构图如下:


znode 的 4 种类型

根据节点的生命周期,znode 可以分为 4 种类型,分别是持久节点(PERSISTENT)、持久顺序节点(PERSISTENT_SEQUENTIAL)、临时节点(EPHEMERAL)、临时顺序节点(EPHEMERAL_SEQUENTIAL)


  • 持久节点(PERSISTENT)

  • 这类节点被创建后,就会一直存在于 Zk 服务器上。直到手动删除。

  • 持久顺序节点(PERSISTENT_SEQUENTIAL)

  • 它的基本特性同持久节点,不同在于增加了顺序性。父节点会维护一个自增整性数字,用于子节点的创建的先后顺序。

  • 临时节点(EPHEMERAL)

  • 临时节点的生命周期与客户端的会话绑定,一旦客户端会话失效(非 TCP 连接断开),那么这个节点就会被自动清理掉。zk 规定临时节点只能作为叶子节点。

  • 临时顺序节点(EPHEMERAL_SEQUENTIAL)

  • 基本特性同临时节点,添加了顺序的特性。

4、面试官:你知道 znode 节点里面存储的是什么吗?每个节点的数据最大不能超过多少呢?

小菜鸡的我:


znode 节点里面存储的是什么?

Znode 数据节点的代码如下


public class DataNode implements Record {    byte data[];                        Long acl;                           public StatPersisted stat;           private Set<String> children = null; }
复制代码


哈哈,Znode 包含了存储数据、访问权限、子节点引用、节点状态信息,如图:



  • data: znode 存储的业务数据信息

  • ACL: 记录客户端对 znode 节点的访问权限,如 IP 等。

  • child: 当前节点的子节点引用

  • stat: 包含 Znode 节点的状态信息,比如事务 id、版本号、时间戳等等。

每个节点的数据最大不能超过多少呢

为了保证高吞吐和低延迟,以及数据的一致性,znode 只适合存储非常小的数据,不能超过 1M,最好都小于 1K。

5、面试官:你知道 znode 节点上的监听机制嘛?讲下 Zookeeper watch 机制吧。

小菜鸡的我:



  • Watcher 机制

  • 监听机制的工作原理

  • Watcher 特性总结

Watcher 监听机制

Zookeeper 允许客户端向服务端的某个 Znode 注册一个 Watcher 监听,当服务端的一些指定事件触发了这个 Watcher,服务端会向指定客户端发送一个事件通知来实现分布式的通知功能,然后客户端根据 Watcher 通知状态和事件类型做出业务上的改变。


可以把 Watcher 理解成客户端注册在某个 Znode 上的触发器,当这个 Znode 节点发生变化时(增删改查),就会触发 Znode 对应的注册事件,注册的客户端就会收到异步通知,然后做出业务的改变。

Watcher 监听机制的工作原理


  • ZooKeeper 的 Watcher 机制主要包括客户端线程、客户端 WatcherManager、Zookeeper 服务器三部分。

  • 客户端向 ZooKeeper 服务器注册 Watcher 的同时,会将 Watcher 对象存储在客户端的 WatchManager 中。

  • 当 zookeeper 服务器触发 watcher 事件后,会向客户端发送通知, 客户端线程从 WatcherManager 中取出对应的 Watcher 对象来执行回调逻辑。

Watcher 特性总结

  • **一次性:**一个 Watch 事件是一个一次性的触发器。一次性触发,客户端只会收到一次这样的信息。

  • 异步的: Zookeeper 服务器发送 watcher 的通知事件到客户端是异步的,不能期望能够监控到节点每次的变化,Zookeeper 只能保证最终的一致性,而无法保证强一致性。

  • 轻量级: Watcher 通知非常简单,它只是通知发生了事件,而不会传递事件对象内容。

  • 客户端串行: 执行客户端 Watcher 回调的过程是一个串行同步的过程。

  • 注册 watcher 用 getData、exists、getChildren 方法

  • 触发 watcher 用 create、delete、setData 方法

6、面试官:你对 Zookeeper 的数据结构都有一定了解,那你讲下 Zookeeper 的特性吧

小菜鸡的我:(我背过书,啊哈哈)


Zookeeper 保证了如下分布式一致性特性:


  • 顺序一致性:从同一客户端发起的事务请求,最终将会严格地按照顺序被应用到 ZooKeeper 中去。

  • 原子性:所有事务请求的处理结果在整个集群中所有机器上的应用情况是一致的,也就是说,要么整个集群中所有的机器都成功应用了某一个事务,要么都没有应用。

  • 单一视图:无论客户端连到哪一个 ZooKeeper 服务器上,其看到的服务端数据模型都是一致的。

  • 可靠性: 一旦服务端成功地应用了一个事务,并完成对客户端的响应,那么该事务所引起的服务端状态变更将会被一直保留下来。

  • 实时性(最终一致性): Zookeeper 仅仅能保证在一定的时间段内,客户端最终一定能够从服务端上读取到最新的数据状态。

7、面试官:你刚提到顺序一致性,那 zookeeper 是如何保证事务的顺序一致性的呢?

小菜鸡的我:(完蛋了这题不会)


需要了解事务 ID,即 zxid。ZooKeeper 的在选举时通过比较各结点的 zxid 和机器 ID 选出新的主结点的。zxid 由 Leader 节点生成,有新写入事件时,Leader 生成新 zxid 并随提案一起广播,每个结点本地都保存了当前最近一次事务的 zxid,zxid 是递增的,所以谁的 zxid 越大,就表示谁的数据是最新的。


ZXID 的生成规则如下:



ZXID 有两部分组成:


  • 任期:完成本次选举后,直到下次选举前,由同一 Leader 负责协调写入;

  • 事务计数器:单调递增,每生效一次写入,计数器加一。


ZXID 的低 32 位是计数器,所以同一任期内,ZXID 是连续的,每个结点又都保存着自身最新生效的 ZXID,通过对比新提案的 ZXID 与自身最新 ZXID 是否相差“1”,来保证事务严格按照顺序生效的。

8、面试官:你提到了 Leader,你知道 Zookeeper 的服务器有几种角色嘛?Zookeeper 下 Server 工作状态又有几种呢?

小菜鸡的我:


Zookeeper 服务器角色

Zookeeper 集群中,有 Leader、Follower 和 Observer 三种角色


Leader


Leader 服务器是整个 ZooKeeper 集群工作机制中的核心,其主要工作:

  • 事务请求的唯一调度和处理者,保证集群事务处理的顺序性

  • 集群内部各服务的调度者


Follower


Follower 服务器是 ZooKeeper 集群状态的跟随者,其主要工作:

  • 处理客户端非事务请求,转发事务请求给 Leader 服务器

  • 参与事务请求 Proposal 的投票

  • 参与 Leader 选举投票


Observer


Observer 是 3.3.0 版本开始引入的一个服务器角色,它充当一个观察者角色——观察 ZooKeeper 集群的最新状态变化并将这些状态变更同步过来。其工作:

  • 处理客户端的非事务请求,转发事务请求给 Leader 服务器

  • 不参与任何形式的投票

Zookeeper 下 Server 工作状态

服务器具有四种状态,分别是 LOOKING、FOLLOWING、LEADING、OBSERVING。

  • 1.LOOKING:寻找 Leader 状态。当服务器处于该状态时,它会认为当前集群中没有 Leader,因此需要进入 Leader 选举状态。

  • 2.FOLLOWING:跟随者状态。表明当前服务器角色是 Follower。

  • 3.LEADING:领导者状态。表明当前服务器角色是 Leader。

  • 4.OBSERVING:观察者状态。表明当前服务器角色是 Observer。

9、面试官:你说到服务器角色是基于 ZooKeeper 集群的,那你画一下 ZooKeeper 集群部署图吧?ZooKeeper 是如何保证主从节点数据一致性的呢?

小菜鸡的我:


ZooKeeper 集群部署图


ZooKeeper 集群是一主多从的结构:


  • 如果是写入数据,先写入主服务器(主节点),再通知从服务器。

  • 如果是读取数据,既读主服务器的,也可以读从服务器的。

ZooKeeper 如何保证主从节点数据一致性

我们知道集群是主从部署结构,要保证主从节点一致性问题,无非就是两个主要问题:


  • 主服务器挂了,或者重启了

  • 主从服务器之间同步数据~


Zookeeper 是采用 ZAB 协议(Zookeeper Atomic Broadcast,Zookeeper 原子广播协议)来保证主从节点数据一致性的,ZAB 协议支持崩溃恢复和消息广播两种模式,很好解决了这两个问题:


  • 崩溃恢复:Leader 挂了,进入该模式,选一个新的 leader 出来

  • 消息广播: 把更新的数据,从 Leader 同步到所有 Follower


Leader 服务器挂了,所有集群中的服务器进入 LOOKING 状态,首先,它们会选举产生新的 Leader 服务器;接着,新的 Leader 服务器与集群中 Follower 服务进行数据同步,当集群中超过半数机器与该 Leader 服务器完成数据同步之后,退出恢复模式进入消息广播模式。Leader 服务器开始接收客户端的事务请求生成事务 Proposal 进行事务请求处理。

最后分享一波,Java 核心架构进阶知识点

面试成功其实都是必然发生的事情,因为在此之前我做足了充分的准备工作,不单单是纯粹的刷题,更多的还会去刷一些 Java 核心架构进阶知识点,比如:JVM、高并发、多线程、缓存、Spring 相关、分布式、微服务、RPC、网络、设计模式、MQ、Redis、MySQL、设计模式、负载均衡、算法、数据结构、kafka、ZK、集群等。而这些也全被整理浓缩到了一份 pdf——《Java 核心架构进阶知识点整理》,全部都是精华中的精华,本着共赢的心态,好东西自然也是要分享的





内容颇多,篇幅却有限,这就不在过多的介绍了,大家可根据以上截图自行脑补,不过这份《Java 核心架构进阶知识点整理 pdf》以及前面 P8 整理的全套系列大厂面试题皆可免费分享给有需要的你,点击这里即可免费领取文中所有资料

评论

发布
暂无评论
一个Java程序员的面试心得,最终入职阿里