diff --git a/about/index.html b/about/index.html index 8fb56fbfe..349042d41 100644 --- a/about/index.html +++ b/about/index.html @@ -276,7 +276,7 @@

- 58 + 59 日志 diff --git a/archives/2018/01/index.html b/archives/2018/01/index.html index 0aad095f1..3feec63d3 100644 --- a/archives/2018/01/index.html +++ b/archives/2018/01/index.html @@ -169,7 +169,7 @@

Potter's 个人博客

- 不错! 目前共计 58 篇日志。 继续努力。 + 不错! 目前共计 59 篇日志。 继续努力。
@@ -269,7 +269,7 @@

Potter's 个人博客

- 58 + 59 日志
diff --git a/archives/2018/03/index.html b/archives/2018/03/index.html index 45bfbf788..533091227 100644 --- a/archives/2018/03/index.html +++ b/archives/2018/03/index.html @@ -169,7 +169,7 @@

Potter's 个人博客

- 不错! 目前共计 58 篇日志。 继续努力。 + 不错! 目前共计 59 篇日志。 继续努力。
@@ -269,7 +269,7 @@

Potter's 个人博客

diff --git a/archives/2018/index.html b/archives/2018/index.html index 9c0505e95..7e7a48bb8 100644 --- a/archives/2018/index.html +++ b/archives/2018/index.html @@ -169,7 +169,7 @@

Potter's 个人博客

- 不错! 目前共计 58 篇日志。 继续努力。 + 不错! 目前共计 59 篇日志。 继续努力。
@@ -289,7 +289,7 @@

Potter's 个人博客

diff --git a/archives/2020/01/index.html b/archives/2020/01/index.html index 6ee8933ea..daf1fb858 100644 --- a/archives/2020/01/index.html +++ b/archives/2020/01/index.html @@ -169,7 +169,7 @@

Potter's 个人博客

- 不错! 目前共计 58 篇日志。 继续努力。 + 不错! 目前共计 59 篇日志。 继续努力。
@@ -269,7 +269,7 @@

Potter's 个人博客

diff --git a/archives/2020/index.html b/archives/2020/index.html index 92de3723a..9bf91f915 100644 --- a/archives/2020/index.html +++ b/archives/2020/index.html @@ -169,7 +169,7 @@

Potter's 个人博客

- 不错! 目前共计 58 篇日志。 继续努力。 + 不错! 目前共计 59 篇日志。 继续努力。
@@ -269,7 +269,7 @@

Potter's 个人博客

diff --git a/archives/2022/02/index.html b/archives/2022/02/index.html index 0ac8ee652..c25d3badd 100644 --- a/archives/2022/02/index.html +++ b/archives/2022/02/index.html @@ -169,7 +169,7 @@

Potter's 个人博客

- 不错! 目前共计 58 篇日志。 继续努力。 + 不错! 目前共计 59 篇日志。 继续努力。
@@ -269,7 +269,7 @@

Potter's 个人博客

diff --git a/archives/2022/05/index.html b/archives/2022/05/index.html index a6bb0341a..b1c79a5bc 100644 --- a/archives/2022/05/index.html +++ b/archives/2022/05/index.html @@ -169,7 +169,7 @@

Potter's 个人博客

- 不错! 目前共计 58 篇日志。 继续努力。 + 不错! 目前共计 59 篇日志。 继续努力。
@@ -269,7 +269,7 @@

Potter's 个人博客

diff --git a/archives/2022/06/index.html b/archives/2022/06/index.html index 1f86dc012..c20f381c9 100644 --- a/archives/2022/06/index.html +++ b/archives/2022/06/index.html @@ -169,7 +169,7 @@

Potter's 个人博客

- 不错! 目前共计 58 篇日志。 继续努力。 + 不错! 目前共计 59 篇日志。 继续努力。
@@ -269,7 +269,7 @@

Potter's 个人博客

diff --git a/archives/2022/index.html b/archives/2022/index.html index 3de249b46..9f422d974 100644 --- a/archives/2022/index.html +++ b/archives/2022/index.html @@ -169,7 +169,7 @@

Potter's 个人博客

- 不错! 目前共计 58 篇日志。 继续努力。 + 不错! 目前共计 59 篇日志。 继续努力。
@@ -309,7 +309,7 @@

Potter's 个人博客

diff --git a/archives/2024/01/index.html b/archives/2024/01/index.html index f67eaf544..357329480 100644 --- a/archives/2024/01/index.html +++ b/archives/2024/01/index.html @@ -169,7 +169,7 @@

Potter's 个人博客

- 不错! 目前共计 58 篇日志。 继续努力。 + 不错! 目前共计 59 篇日志。 继续努力。
@@ -289,7 +289,7 @@

Potter's 个人博客

diff --git a/archives/2024/04/index.html b/archives/2024/04/index.html index e72cb030f..3d05492d8 100644 --- a/archives/2024/04/index.html +++ b/archives/2024/04/index.html @@ -169,7 +169,7 @@

Potter's 个人博客

- 不错! 目前共计 58 篇日志。 继续努力。 + 不错! 目前共计 59 篇日志。 继续努力。
@@ -209,8 +209,8 @@

Potter's 个人博客

-
@@ -229,8 +229,8 @@

Potter's 个人博客

-
@@ -269,8 +269,8 @@

Potter's 个人博客

-
@@ -289,8 +289,8 @@

Potter's 个人博客

-
@@ -452,7 +452,7 @@

Potter's 个人博客

diff --git a/archives/2024/04/page/2/index.html b/archives/2024/04/page/2/index.html index a35378e06..3ef6640d7 100644 --- a/archives/2024/04/page/2/index.html +++ b/archives/2024/04/page/2/index.html @@ -169,7 +169,7 @@

Potter's 个人博客

- 不错! 目前共计 58 篇日志。 继续努力。 + 不错! 目前共计 59 篇日志。 继续努力。
@@ -452,7 +452,7 @@

Potter's 个人博客

diff --git a/archives/2024/04/page/3/index.html b/archives/2024/04/page/3/index.html index 82fb1e2d8..ec8b08969 100644 --- a/archives/2024/04/page/3/index.html +++ b/archives/2024/04/page/3/index.html @@ -169,7 +169,7 @@

Potter's 个人博客

- 不错! 目前共计 58 篇日志。 继续努力。 + 不错! 目前共计 59 篇日志。 继续努力。
@@ -289,8 +289,8 @@

Potter's 个人博客

-
@@ -309,8 +309,8 @@

Potter's 个人博客

-
@@ -452,7 +452,7 @@

Potter's 个人博客

diff --git a/archives/2024/04/page/4/index.html b/archives/2024/04/page/4/index.html index e852e44af..3003d5c85 100644 --- a/archives/2024/04/page/4/index.html +++ b/archives/2024/04/page/4/index.html @@ -169,7 +169,7 @@

Potter's 个人博客

- 不错! 目前共计 58 篇日志。 继续努力。 + 不错! 目前共计 59 篇日志。 继续努力。
@@ -309,8 +309,8 @@

Potter's 个人博客

-
@@ -329,8 +329,8 @@

Potter's 个人博客

-
@@ -452,7 +452,7 @@

Potter's 个人博客

diff --git a/archives/2024/04/page/5/index.html b/archives/2024/04/page/5/index.html index 1d422227d..a600c8bf2 100644 --- a/archives/2024/04/page/5/index.html +++ b/archives/2024/04/page/5/index.html @@ -169,7 +169,7 @@

Potter's 个人博客

- 不错! 目前共计 58 篇日志。 继续努力。 + 不错! 目前共计 59 篇日志。 继续努力。
@@ -272,7 +272,7 @@

Potter's 个人博客

diff --git a/archives/2024/05/index.html b/archives/2024/05/index.html index 23283d351..46af20214 100644 --- a/archives/2024/05/index.html +++ b/archives/2024/05/index.html @@ -169,7 +169,7 @@

Potter's 个人博客

- 不错! 目前共计 58 篇日志。 继续努力。 + 不错! 目前共计 59 篇日志。 继续努力。
@@ -177,6 +177,26 @@

Potter's 个人博客

2024
+ +
@@ -429,7 +449,7 @@

Potter's 个人博客

diff --git a/archives/2024/index.html b/archives/2024/index.html index 482706240..6cbe979e6 100644 --- a/archives/2024/index.html +++ b/archives/2024/index.html @@ -169,7 +169,7 @@

Potter's 个人博客

- 不错! 目前共计 58 篇日志。 继续努力。 + 不错! 目前共计 59 篇日志。 继续努力。
@@ -177,6 +177,26 @@

Potter's 个人博客

2024
+ +
@@ -356,26 +376,6 @@

Potter's 个人博客

- -
@@ -452,7 +452,7 @@

Potter's 个人博客

diff --git a/archives/2024/page/2/index.html b/archives/2024/page/2/index.html index 308b86596..c9488c627 100644 --- a/archives/2024/page/2/index.html +++ b/archives/2024/page/2/index.html @@ -169,7 +169,7 @@

Potter's 个人博客

- 不错! 目前共计 58 篇日志。 继续努力。 + 不错! 目前共计 59 篇日志。 继续努力。
@@ -189,8 +189,8 @@

Potter's 个人博客

-
@@ -229,8 +229,8 @@

Potter's 个人博客

-
@@ -249,8 +249,8 @@

Potter's 个人博客

-
@@ -289,8 +289,8 @@

Potter's 个人博客

-
@@ -309,8 +309,8 @@

Potter's 个人博客

-
@@ -322,15 +322,15 @@

Potter's 个人博客

-
@@ -342,15 +342,15 @@

Potter's 个人博客

-
@@ -362,15 +362,15 @@

Potter's 个人博客

-
@@ -452,7 +452,7 @@

Potter's 个人博客

diff --git a/archives/2024/page/3/index.html b/archives/2024/page/3/index.html index 4714b4735..cc0f12786 100644 --- a/archives/2024/page/3/index.html +++ b/archives/2024/page/3/index.html @@ -169,7 +169,7 @@

Potter's 个人博客

- 不错! 目前共计 58 篇日志。 继续努力。 + 不错! 目前共计 59 篇日志。 继续努力。
@@ -177,6 +177,26 @@

Potter's 个人博客

2024
+ +
@@ -356,26 +376,6 @@

Potter's 个人博客

- -
@@ -452,7 +452,7 @@

Potter's 个人博客

- 58 + 59 日志
diff --git a/archives/2024/page/4/index.html b/archives/2024/page/4/index.html index 9bb5087d2..55ff6b603 100644 --- a/archives/2024/page/4/index.html +++ b/archives/2024/page/4/index.html @@ -169,7 +169,7 @@

Potter's 个人博客

- 不错! 目前共计 58 篇日志。 继续努力。 + 不错! 目前共计 59 篇日志。 继续努力。
@@ -189,8 +189,8 @@

Potter's 个人博客

-
@@ -209,8 +209,8 @@

Potter's 个人博客

-
@@ -229,8 +229,8 @@

Potter's 个人博客

-
@@ -249,8 +249,8 @@

Potter's 个人博客

-
@@ -269,8 +269,8 @@

Potter's 个人博客

-
@@ -309,8 +309,8 @@

Potter's 个人博客

-
@@ -322,15 +322,15 @@

Potter's 个人博客

-
@@ -349,8 +349,8 @@

Potter's 个人博客

-
@@ -369,8 +369,8 @@

Potter's 个人博客

-
@@ -452,7 +452,7 @@

Potter's 个人博客

- 58 + 59 日志
diff --git a/archives/2024/page/5/index.html b/archives/2024/page/5/index.html index fd43955b8..a09d4344d 100644 --- a/archives/2024/page/5/index.html +++ b/archives/2024/page/5/index.html @@ -169,7 +169,7 @@

Potter's 个人博客

- 不错! 目前共计 58 篇日志。 继续努力。 + 不错! 目前共计 59 篇日志。 继续努力。
@@ -189,8 +189,8 @@

Potter's 个人博客

-
@@ -209,8 +209,8 @@

Potter's 个人博客

-
@@ -229,8 +229,8 @@

Potter's 个人博客

-
@@ -249,8 +249,8 @@

Potter's 个人博客

-
@@ -269,8 +269,8 @@

Potter's 个人博客

-
@@ -289,8 +289,8 @@

Potter's 个人博客

-
@@ -329,8 +329,8 @@

Potter's 个人博客

-
@@ -349,8 +349,8 @@

Potter's 个人博客

-
@@ -369,8 +369,8 @@

Potter's 个人博客

-
@@ -452,7 +452,7 @@

Potter's 个人博客

- 58 + 59 日志
diff --git a/archives/2024/page/6/index.html b/archives/2024/page/6/index.html index aca010f48..709a5c0a1 100644 --- a/archives/2024/page/6/index.html +++ b/archives/2024/page/6/index.html @@ -169,7 +169,7 @@

Potter's 个人博客

- 不错! 目前共计 58 篇日志。 继续努力。 + 不错! 目前共计 59 篇日志。 继续努力。
@@ -177,6 +177,26 @@

Potter's 个人博客

2024
+
+
+ + + +
+ +
+ +
+
+
@@ -292,7 +312,7 @@

Potter's 个人博客

diff --git a/archives/index.html b/archives/index.html index dd7c8238b..646265d10 100644 --- a/archives/index.html +++ b/archives/index.html @@ -169,7 +169,7 @@

Potter's 个人博客

- 不错! 目前共计 58 篇日志。 继续努力。 + 不错! 目前共计 59 篇日志。 继续努力。
@@ -177,6 +177,26 @@

Potter's 个人博客

2024
+ +
@@ -356,26 +376,6 @@

Potter's 个人博客

- - @@ -452,7 +452,7 @@

Potter's 个人博客

diff --git a/archives/page/2/index.html b/archives/page/2/index.html index 4106530e4..8b4b93aa6 100644 --- a/archives/page/2/index.html +++ b/archives/page/2/index.html @@ -169,7 +169,7 @@

Potter's 个人博客

- 不错! 目前共计 58 篇日志。 继续努力。 + 不错! 目前共计 59 篇日志。 继续努力。
@@ -189,8 +189,8 @@

Potter's 个人博客

-
@@ -229,8 +229,8 @@

Potter's 个人博客

-
@@ -249,8 +249,8 @@

Potter's 个人博客

-
@@ -289,8 +289,8 @@

Potter's 个人博客

-
@@ -309,8 +309,8 @@

Potter's 个人博客

-
@@ -322,15 +322,15 @@

Potter's 个人博客

-
@@ -342,15 +342,15 @@

Potter's 个人博客

-
@@ -362,15 +362,15 @@

Potter's 个人博客

-
@@ -452,7 +452,7 @@

Potter's 个人博客

diff --git a/archives/page/3/index.html b/archives/page/3/index.html index a08caa730..4017c689f 100644 --- a/archives/page/3/index.html +++ b/archives/page/3/index.html @@ -169,7 +169,7 @@

Potter's 个人博客

- 不错! 目前共计 58 篇日志。 继续努力。 + 不错! 目前共计 59 篇日志。 继续努力。
@@ -177,6 +177,26 @@

Potter's 个人博客

2024
+ +
@@ -356,26 +376,6 @@

Potter's 个人博客

- - @@ -452,7 +452,7 @@

Potter's 个人博客

diff --git a/archives/page/4/index.html b/archives/page/4/index.html index 7786ee798..ef037f284 100644 --- a/archives/page/4/index.html +++ b/archives/page/4/index.html @@ -169,7 +169,7 @@

Potter's 个人博客

- 不错! 目前共计 58 篇日志。 继续努力。 + 不错! 目前共计 59 篇日志。 继续努力。
@@ -189,8 +189,8 @@

Potter's 个人博客

-
@@ -209,8 +209,8 @@

Potter's 个人博客

-
@@ -229,8 +229,8 @@

Potter's 个人博客

-
@@ -249,8 +249,8 @@

Potter's 个人博客

-
@@ -269,8 +269,8 @@

Potter's 个人博客

-
@@ -309,8 +309,8 @@

Potter's 个人博客

-
@@ -322,15 +322,15 @@

Potter's 个人博客

-
@@ -349,8 +349,8 @@

Potter's 个人博客

-
@@ -369,8 +369,8 @@

Potter's 个人博客

-
@@ -452,7 +452,7 @@

Potter's 个人博客

diff --git a/archives/page/5/index.html b/archives/page/5/index.html index b43e8b6e3..3d1ee5eb2 100644 --- a/archives/page/5/index.html +++ b/archives/page/5/index.html @@ -169,7 +169,7 @@

Potter's 个人博客

- 不错! 目前共计 58 篇日志。 继续努力。 + 不错! 目前共计 59 篇日志。 继续努力。
@@ -189,8 +189,8 @@

Potter's 个人博客

-
@@ -209,8 +209,8 @@

Potter's 个人博客

-
@@ -229,8 +229,8 @@

Potter's 个人博客

-
@@ -249,8 +249,8 @@

Potter's 个人博客

-
@@ -269,8 +269,8 @@

Potter's 个人博客

-
@@ -289,8 +289,8 @@

Potter's 个人博客

-
@@ -329,8 +329,8 @@

Potter's 个人博客

-
@@ -349,8 +349,8 @@

Potter's 个人博客

-
@@ -369,8 +369,8 @@

Potter's 个人博客

-
@@ -452,7 +452,7 @@

Potter's 个人博客

diff --git a/archives/page/6/index.html b/archives/page/6/index.html index 8f2d41633..73af33fa2 100644 --- a/archives/page/6/index.html +++ b/archives/page/6/index.html @@ -169,7 +169,7 @@

Potter's 个人博客

- 不错! 目前共计 58 篇日志。 继续努力。 + 不错! 目前共计 59 篇日志。 继续努力。
@@ -177,6 +177,26 @@

Potter's 个人博客

2024
+ +
@@ -421,7 +441,7 @@

Potter's 个人博客

diff --git a/categories/index.html b/categories/index.html index 90f0f18c1..4fe7063fe 100644 --- a/categories/index.html +++ b/categories/index.html @@ -269,7 +269,7 @@

categories diff --git a/css/main.css b/css/main.css index 3d8795ea7..e2387e718 100644 --- a/css/main.css +++ b/css/main.css @@ -1168,7 +1168,7 @@ pre .javascript .function { } .links-of-author a::before, .links-of-author span.exturl::before { - background: #ffb06a; + background: #21bdff; border-radius: 50%; content: ' '; display: inline-block; diff --git a/index.html b/index.html index 828232982..267947c44 100644 --- a/index.html +++ b/index.html @@ -164,6 +164,157 @@

Potter's 个人博客

+
+ + + + + +
+

+ + +

+ + +
+ + + + +
+ + +

ZooKeeper简介

什么是ZooKeeper?

ZooKeeper是Apache开源的一个分布式协调服务,用于管理分布式应用中的配置、同步、命名等信息,提供高效可靠的分布式数据一致性服务。

+

ZooKeeper的主要特性有哪些?

    +
  • 一致性:所有服务器保存相同的数据副本,保证数据一致性。
  • +
  • 可靠性:只要超过半数的服务器可用,ZooKeeper就能提供服务。
  • +
  • 原子性:所有操作都是原子性的,成功执行或完全失败。
  • +
  • 顺序性:所有更新按照严格的顺序执行,保证数据的顺序性。
  • +
  • 高性能:适合读多写少的场景。
  • +
+

ZooKeeper的核心概念

什么是ZNode?

ZNode是ZooKeeper数据模型中的数据节点,每个ZNode可以存储数据和子节点。ZNode路径类似于文件系统,分为持久节点和临时节点。

+

什么是会话?

会话是客户端与ZooKeeper服务器之间的连接,每个会话有一个唯一的会话ID。会话超时时间可以配置,当客户端在超时时间内没有心跳,服务器会关闭会话并清除临时节点。

+

什么是版本号?

每个ZNode有三个版本号:数据版本(dataVersion)、子节点版本(childrenVersion)、ACL版本(aclVersion)。版本号用于实现乐观锁机制,保证数据的一致性和原子性。

+

什么是Watcher?

Watcher是ZooKeeper的事件监听机制,客户端可以对ZNode设置Watcher,当ZNode发生变化时,服务器会通知客户端。Watcher是一次性触发的,需要重新注册。

+

ZooKeeper的架构

ZooKeeper的架构是怎样的?

ZooKeeper采用主从架构,集群由一个Leader和多个Follower组成。Leader负责处理所有的写请求,Follower负责处理读请求和转发写请求。通过Paxos算法保证数据一致性。

+

ZooKeeper的选举机制是怎样的?

ZooKeeper的选举机制基于Fast Paxos算法。当Leader挂掉时,集群通过选举机制选出新的Leader。选举过程包括投票、票数统计和Leader确认,选举成功后,集群恢复正常工作。

+

什么是ZAB协议?

ZAB(ZooKeeper Atomic Broadcast)协议是ZooKeeper实现数据一致性的重要协议。ZAB协议包含崩溃恢复和消息广播两个阶段,通过广播保证数据的顺序一致性,通过崩溃恢复保证系统的可靠性。

+

ZooKeeper的应用场景

ZooKeeper常用的应用场景有哪些?

    +
  • 配置管理:集中管理分布式系统的配置信息,动态更新配置。
  • +
  • 服务发现:注册和发现分布式系统中的服务,简化服务调用。
  • +
  • 分布式锁:实现分布式系统中的锁机制,保证数据一致性。
  • +
  • 领导者选举:选举分布式系统中的Leader,保证高可用性。
  • +
  • 队列管理:实现分布式消息队列,保证消息的顺序性和一致性。
  • +
+

ZooKeeper的操作

如何启动ZooKeeper集群?

ZooKeeper集群由多个服务器节点组成,启动前需要配置zoo.cfg文件,包括服务器列表和相关参数。启动命令如下:

+
zkServer.sh start
+ +

如何连接ZooKeeper?

可以通过ZooKeeper客户端工具(如zkCli.sh)或程序化接口(如Java API)连接ZooKeeper服务器。连接命令如下:

+
zkCli.sh -server 127.0.0.1:2181
+ +

如何创建ZNode?

可以通过create命令创建ZNode,命令格式如下:

+
create /path data
+

例如,创建一个名为/myNode的ZNode:

+
create /myNode myData
+ +

如何读取ZNode数据?

可以通过get命令读取ZNode的数据,命令格式如下:

+
get /path
+

例如,读取/myNode的ZNode数据:

+
get /myNode
+ +

如何更新ZNode数据?

可以通过set命令更新ZNode的数据,命令格式如下:

+
set /path data
+

例如,更新/myNode的ZNode数据:

+
set /myNode newData
+ +

如何删除ZNode?

可以通过delete命令删除ZNode,命令格式如下:

+
delete /path
+

例如,删除/myNode的ZNode:

+
delete /myNode
+ +

ZooKeeper的高级特性

什么是事务(multi)操作?

事务操作允许在一次请求中执行多个ZooKeeper操作,保证所有操作的原子性。通过multi命令可以执行事务操作,示例如下:

+
multi
+create /node1 data1
+set /node2 data2
+delete /node3
+commit
+ +

什么是ACL?

ACL(Access Control List)用于控制ZNode的访问权限,包括创建、读取、写入、删除等操作。可以通过setAcl命令设置ACL,例如:

+
setAcl /path world:anyone:r
+ +

如何实现分布式锁?

可以通过创建临时顺序节点实现分布式锁。锁的实现步骤包括创建节点、判断节点顺序、删除节点。例如:

+
String lockPath = "/lock";
+String myNode = zk.create(lockPath + "/seq-", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
+List<String> nodes = zk.getChildren(lockPath, false);
+Collections.sort(nodes);
+if (myNode.equals(nodes.get(0))) {
+    // 获取锁
+} else {
+    // 等待锁
+}
+ +

ZooKeeper的常见问题

ZooKeeper的性能如何优化?

    +
  • 合理配置服务器:增加服务器数量,提高集群的可用性和负载能力。
  • +
  • 优化数据模型:减少ZNode的数量和大小,避免频繁的读写操作。
  • +
  • 使用批量操作:合并多次操作,减少网络通信次数,提高性能。
  • +
  • 调整会话超时:根据业务需求调整会话超时时间,减少不必要的会话重连。
  • +
+

如何解决ZooKeeper的“羊群效应”?

“羊群效应”是指大量客户端同时收到Watcher通知,导致瞬时流量激增。解决方法包括:

+
    +
  • 分散Watcher:减少Watcher的数量和频率,避免集中通知。
  • +
  • 批量处理:合并多个通知,减少网络流量和处理压力。
  • +
  • 异步处理:使用异步方式处理Watcher通知,提高处理效率。
  • +
+

如何处理网络分区问题?

网络分区会导致ZooKeeper集群中的部分服务器无法通信,影响数据一致性。处理方法包括:

+
    +
  • 设置合理的超时:通过合理设置会话超时和连接超时,减少网络分区的影响。
  • +
  • 监控网络状况:通过监控工具实时监控网络状况,及时发现和解决网络问题。
  • +
  • 数据备份:定期备份数据,防止网络分区导致的数据丢失。
  • +
+

如何处理ZooKeeper服务器宕机问题?

服务器宕机会影响ZooKeeper集群的可用性和数据一致性。处理方法包括:

+
    +
  • 自动重启:配置ZooKeeper服务器自动重启机制,减少宕机时间。
  • +
  • 数据恢复:通过备份数据和快照恢复机制,快速恢复数据。
  • +
  • 高可用部署:通过增加服务器数量和合理的负载均衡,提高集群的高可用性。
  • +
+ + +
+ + + + +
+
+
+
+ + + + + + +
@@ -2813,389 +2964,6 @@

- - - - - -
-

- - -

- - -
- - - - -
- - -

什么是集合

java中集合也叫容器,由两大派类接口而来,一类是Conllection接口,存放的是单类型的元素,一类是Map,存放的是键值对。Collection接口主要有三大子接口分别为List、Set、Queue(线性表、链表、栈、队列都在这些接口中)

- - -

List、Set、Queue、Map的区别

    -
  • List 存储的元素是有序可以重复的。
  • -
  • Set 存储的元素是无序不可以重复。
  • -
  • Queue 存储的元素有先后的顺序
  • -
  • Map 存储的是一对键值对,key是无序不可以重复的,value是无序可以重复的。
  • -
-

List

ArrayList和Array的区别

ArrayList是基于动态数组实现的,Array是一个静态数组。

-
    -
  • 存储空间:数组是固定长度的,集合可变长度的。
  • -
  • 存储类型:ArrayList只能存储引用数据类型,Array可以存储基本数据类型,也可以存储引用数据类型
  • -
  • 存储内容:ArrayList可以存储不同数据类型的对象,Array只能存储一种数据类型的元素
  • -
-

ArrayList和Array转换

// 数组转换ArrayList的方法
-public static void ArrayToArrayList() {
-        String[] array = {"a", "b", "c", "d"};
-        //1. use Arrays.asList()
-        List<String> listOne = Arrays.asList(array);
-        //2. use Collections.addAll()
-        List<String> listTwo = new ArrayList<>();
-        Collections.addAll(listTwo,array);
-        //3. use Constructor
-        List<String> listThree = new ArrayList<>(Arrays.asList(array));
-        //4. use lambda
-        List<String> listFour = Stream.of(array).collect(Collectors.toList());
-    }
-// ArrayList转换数组的方法
-public static void ArrayListToArray() {
-        List<String> list = new ArrayList<>(Arrays.asList("a","b","c","d"));
-        //1. 转成Object数组
-        Object[] objects = list.toArray();
-        //2. 转成指定类型的数组
-        String[] stringOne = list.toArray(new String[0]);
-        //3. 使用lambda的方式转换成数组
-        String[] stringsTwo = list.stream().toArray(String[]::new);
-    }
- -

ArrayList和Vector的区别

    -
  • ArrayList是List的主要实现类,线程不安全

    -
  • -
  • Vector是List的古老实现类,线程安全。

    -
  • -
-

Vector和Stack的关系

Stack继承Vector,Stack实现了后进先出的栈,Vector是一个列表,两个都是线程安全。

-

ArrayList的插入和删除的时间复杂度

插入:

-
    -
  • 头插法:O(n)
  • -
  • 尾插法:O(1)
  • -
  • 指定位置插入:O(n)
  • -
-

删除:

-
    -
  • 头删法:O(n)
  • -
  • 尾删法:O(1)
  • -
  • 指定位置删除:O(n)
  • -
-

LinkedList的插入和删除的时间复杂度

    -
  • 头插法/删法:O(1)
  • -
  • 尾插法/删法:O(1)
  • -
  • 指定位置插入/删除:O(n)
  • -
-

LinkedList为什么没有实现RandomAccess接口

RandomAccess是一个标记接口,用来表明实现该接口的类支持随机访问(通过元素下标访问)。LinkedList底层是双向链表,内存不连续,无法支持随机访问。

-

ArrayList和LinkedList的区别

    -
  • 数据结构:ArrayList是基于动态数组实现的,是顺序存储,支持随机访问,LinkedList是基于双向链表实现的(JDK 1.6之前为循环双向链表,JDK 1.7取消了循环)不支持顺序存储和随机访问
  • -
  • 效率:ArrayList如果涉及数组重组的插入和删除的操作效率较低,查询比较快,LinkedList查询效率比较低,插入删除效率比较高。
  • -
-

Set

Comparable 和 Comparator 的区别

Comparable 可以看作是“对内”进行排序接口,而 Comparator 是“对外”进行排序的接口。

-
    -
  • 含义区别:comparable是比较,comparator是比较器的意思。
  • -
  • 重写方法:comparable要重写compareTo方法,comparator要重写compare方法。
  • -
  • 应用方式:comparable一般是在类中重写,comparator一般在集合工具类中传入匿名内部类。
  • -
-

基于comparator实现

@Data
-@AllArgsConstructor
-public class Subject {
-    Integer subject_id;
-    String subject_name;
-}
- -
public class BasicOfComparator {
-    public static void main(String[] args) {
-        Subject s1 = new Subject(10,"java");
-        Subject s2 = new Subject(8,"mysql");
-        Subject s3 = new Subject(14,"redis");
-        List<Subject> list = new ArrayList<Subject>(){
-            {
-                add(s1);
-                add(s2);
-                add(s3);
-            }
-        };
-        Collections.sort(list, new Comparator<Subject>() {
-            @Override
-            public int compare(Subject o1, Subject o2) {
-                return o2.getSubject_id().compareTo(o1.getSubject_id());
-            }
-        });
-        for (Subject subject : list) {
-            System.out.println(subject.toString());
-        }
-    }
- -

基于comparbale实现

@Data
-@AllArgsConstructor
-public class Subject implements Comparable<Subject>{
-    Integer subject_id;
-    String subject_name;
-
-    @Override
-    public int compareTo(Subject o) {
-        return o.getSubject_id().compareTo(this.getSubject_id());
-    }
-}
- -
public class BasicOfComparable {
-    public static void main(String[] args) {
-        Subject s1 = new Subject(10,"java");
-        Subject s2 = new Subject(8,"mysql");
-        Subject s3 = new Subject(14,"redis");
-        List<Subject> list = new ArrayList<Subject>(){
-            {
-                add(s1);
-                add(s2);
-                add(s3);
-            }
-        };
-        Collections.sort(list);
-        for (Subject subject : list) {
-            System.out.println(subject.toString());
-        }
-    }
-}
- -

如何理解SET集合无序性和不可重复性

Set是一个基于Hash算法的数组,它的无序性体现在元素经过hash算法以后,存储在数组中的位置是无序的,不可重复性是指元素经过hash算法之后,计算出来的数组下标,如果存在数据元素,根据equals方法判断是否是同一个,如果是则新的覆盖旧的,所以set里面没有重复的元素。

-

HashSet、LinkedHashSet、TreeSet的区别

相同点:都是Set集合的实现类,元素唯一不重复,都不是现成安全

-

区别:

-

数据结构:HashSet是底层是哈希表,基于hashmap实现的,LinkedHashSet底层是链表和哈希表,满足FIFO,TreeSet底层是红黑树,元素是有序的。

-

应用场景:HashSet应用不保证插入和取出元素顺序的场景,LinkedHashSet应用于FIFO场景,TreeSet应用于排序场景

-

Queue

Queue和Deque的区别

Queue是单端队列,只能从一端插入元素,另一端删除元素。Queue扩展了collection的接口分为两类方法,一类是操作失败后抛出异常,另一种是返回特殊值

- - - - - - - - - - - - - - - - - - - - - - - -
Queue 接口抛出异常返回特殊值
插入队尾add(E e)offer(E e)
删除队首remove()poll()
查询队首元素element()peek()
-

Deque是双端队列,可以在队尾和队首进行插入元素和删除元素。Deque扩展了Queue的接口,增加了队尾和队首的进行删除和插入的方法,根据失败后处理方式的不同分为两类。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Deque 接口抛出异常返回特殊值
插入队首addFirst(E e)offerFirst(E e)
插入队尾addLast(E e)offerLast(E e)
删除队首removeFirst()pollFirst()
删除队尾removeLast()pollLast()
查询队首元素getFirst()peekFirst()
查询队尾元素getLast()peekLast()
-

ArrayDeque与LinkedList的区别

相同点:ArrayDeque和LinkedList都实现了Deque接口,两个都有队列的功能。

-

区别:

-
    -
  • ArrayDeque是基于可变长数组和双指针实现的,而LinkedList是基于链表实现的
  • -
  • ArrayDeque不能存储Null数据,LinkedList可以存储
  • -
  • ArrayDeque当容量满了以后涉及扩容会复制整个数组,丢弃旧数组,涉及了内存复制性能较低,当数据量大的时候LinkedList处理效率比较低,整体而言优先使用ArrayDeque实现队列
  • -
-

为什么有Stack还要用Deque实现栈

Stack继承了vector属于线程安全的,当处理大量数据的时候效率比较低。

-

什么是优先级队列

优先级队列(Priority Queue)跟普通的队列有相似的行为,都是遵循队列的基本原则—先进先出(FIFO), 但它有一个额外的特性:每个元素都有各自的“优先级”。

-

在优先级队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先被访问。优先级队列有两个常见的应用场景:

-
    -
  1. 数据压缩:优先级队列常常被用于数据压缩,特别是霍夫曼编码。

    -
  2. -
  3. Dijkstra算法:优先级队列也是实现Dijkstra算法的关键工具。

    -
  4. -
-

优先级队列是通过二叉堆实现的,它提供了O(log n)的添加和删除时间复杂度,以及O(1)的查询最大 / 最小元素时间复杂度。

-

特点:

-

PriorityQueue 利用了二叉堆的数据结构来实现的,底层使用可变长的数组来存储数据

-

PriorityQueue 通过堆元素的上浮和下沉,实现了在 O(logn) 的时间复杂度内插入元素和删除堆顶元素。

-

PriorityQueue 是非线程安全的,且不支持存储 NULLnon-comparable 的对象。

-

PriorityQueue 默认是小顶堆,但可以接收一个 Comparator 作为构造参数,从而来自定义元素优先级的先后。

-

什么是阻塞队列

阻塞队列(Blocking Queue)是一种特殊的队列,当队列为空时,消费者尝试从队列里取出元素的操作会被阻塞,直到队列中有可用元素;同样,当队列已满时,生产者尝试向队列添加元素的操作也会被阻塞,直到队列有可用空间。

-

阻塞队列的实现类

    -
  1. ArrayBlockingQueue:是一个由数组支持的有界阻塞队列,队列的容量在初始化时设定。

    -
  2. -
  3. LinkedBlockingQueue:是一个由链表支持的可选定长(即可以选择是否定长)阻塞队列。

    -
  4. -
  5. PriorityBlockingQueue:是一个不限大小的并发阻塞队列。队列中的元素可按自然顺序进行排序,也可以通过Comparator接口进行排序。

    -
  6. -
  7. DelayQueue:是一个在定时未到时,不能从中获取元素的无界阻塞队列,其内部实现是一个PriorityQueue。元素由其时间戳的长短决定队列中的排序,队头对象的定时时间最长。

    -
  8. -
  9. SynchronousQueue:不存储元素的阻塞队列,每一个put操作必须等待一个take操作,反之亦然。

    -
  10. -
  11. LinkedTransferQueue:是一种由链表结构组成的无界阻塞TransferQueue队列,相当于其他队列的综合体。TransferQueue是一种阻塞队列,其中的生产者的等待可能是为了将元素转移/传递到消费者。

    -
  12. -
  13. LinkedBlockingDeque:是一个由链表结构组成的双向阻塞队列。在最初提供的阻塞队列中,LinkedBlockingDeque是唯一一个支持前后两端插入和移除元素的队列。

    -
  14. -
-

ArrayBlockingQueue和LinkedBlockingDeque的区别

    -
  1. 数据结构:ArrayBlockingQueue基于数组实现的。LinkedBlockingDeque基于链表实现的。

    -
  2. -
  3. 性能:LinkedBlockingDeque基于链表结构,插入和移除元素效率比较高。

    -
  4. -
  5. 双端访问:LinkedBlockingDeque支持从两端插入和移除元素。而ArrayBlockingQueue只能在队尾插入,在对头移除。

    -
  6. -
  7. 灵活性:LinkedBlockingDeque支持双端插入和移除,且可以选择是否定长,更具灵活性。

    -
  8. -
-

Map

HashMap和HashTable的区别

线程安全:HashMap非线程安全,HashTable内部方法用了synchronized修饰是线程安全的

-

效率问题:HashMap不是线程安全的,效率比较高,考虑线程安全的请看,一般用concurrenthashmap

-

NULL值和NULL键问题:hashmap允许一个null键多个null值,hashtable不允许null键和null值。

-

初始容量和扩容问题:hashtable初始容量是11,扩容是2n+1,hashmap初始容量是16,扩容是2n

-

底层数据结构:hashmap是数组+链表组成的,当链表长度大于8且数组长度大于64会转换为红黑树,hashtable也是数组和链表组成的,但是不会有生成红黑树的机制

-

遍历方式:hashmap可以通过iterator和foreach遍历,hashtable只能通过iterator遍历。

-

HashMap和HashSet的关系

HashSet基于HashMap实现的,hashmap存储的key-value pair,而hashset只存储对象

-

HashMap和TreeMap的关系

HashMap和TreeMao都实现了AbstractMap,但是TreeMap实现了NavigableMap和SortedMap两个接口,NavigableMap接口可以实现对集合内的元素搜索的能力,SortedMap接口实现了对集合的键进行排序的能力。

-

HashSet如何检查重复

hashset添加一个对象的时候,首先计算这个对象的hashcode,找到数组下标的位置,如果这个位置是空的直接插入,如果不是空的就会使用equals()方法判断,两个hashcode相等的对象是否真的相同,如果相同的话就不会让它加入进去。

-

HashMap的底层实现

hashmap解决冲突用的链地址法,jdk 1.8之前用数组和链表的数据结构,1.8以后优化成了数组+链表+红黑树,当数组长度大于64,链表长度大于8链表部分会转换为红黑树。

-

红黑树:叫自平衡二叉搜索树,根节点都是黑色的,其余的节点可以是红色也可以是黑色的,插入、搜索、删除操作时间复杂度都是在O(log n)

-

HashMap长度为什么是2的幂次方

hash(key) % array.length

-
    -
  1. 逻辑与计算索引快:当确定键值对应的桶的位置时,需要对哈希编码进行一次模运算,即hash(key) % array.length。当数组长度为2的幂时,这个运算可以用更快的位操作来完成,即hash(key) & (array.length - 1),位操作的速度一般要快于除法和求余数运算。

    -
  2. -
  3. 散列更均匀:数组长度为2的幂次模运算后的散列的更加均匀

    -
  4. -
-

HashMap的遍历方式

public class HashMapIterator {
-    public static void main(String[] args) {
-        Map<String,String> map = new HashMap<>();
-        map.put("1", "Java");
-        map.put("2", "JDK");
-        map.put("3", "Spring Framework");
-        map.put("4", "MyBatis framework");
-        map.put("5", "Redis");
-        System.out.println("迭代器");
-        Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
-        while (iterator.hasNext()){
-            Map.Entry<String, String> entry = iterator.next();
-            System.out.println(entry.getKey()+" : "+entry.getValue());
-        }
-        Iterator<String> iterator1 = map.keySet().iterator();
-        while (iterator1.hasNext()){
-            String string = iterator1.next();
-            System.out.println(string+" : "+map.get(string));
-        }
-        System.out.println("foreach");
-        Set<Map.Entry<String, String>> entries = map.entrySet();
-        for (Map.Entry<String, String> entry : entries) {
-            System.out.println(entry.getKey()+" : "+entry.getValue());
-        }
-        Set<String> strings = map.keySet();
-        for (String string : strings) {
-            System.out.println(string+" : "+map.get(string));
-        }
-        System.out.println("lambda");
-        map.forEach((key,value)->{
-            System.out.println(key+" : "+value);
-        });
-        map.entrySet().stream().forEach((stringStringEntry)->{
-            System.out.println(stringStringEntry.getKey()+" : "+stringStringEntry.getValue());
-        });
-    }
-}
- -

什么是concurrenthashmap

jdk1.8之前concurrenthashmap由segment数组和hashentry数组和链表组成,将数据分为一段一段的就是segment,是对每个segment进行加锁保证线程安全,由于segment初始化之后就固定容量,所以concurrenthashmap最多支持16个并发线程。

-

jdk1.8中concurrenthashmap由Node数组和链表和红黑树组成,采用Node+cas+synchronized保证线程安全,锁粒度更细,synchronized 只锁定当前链表或红黑二叉树的首节点。

-

1.CAS是一种无锁算法,它通过比较当前值和预期值,如果相同则进行更新,不同则重新操作的方式,减小了对整个数据的锁定概率。这属于乐观锁的一种,尝试不通过加锁的方式达到线程安全,但在高并发情况下,可能导致大量的失败重试。

-

2.ConcurrentHashMap不能由NUll值NULL键。

-

集合注意事项

Collections工具类

collections工具类常用的方法有三大类,排序、查找、线程安全方法(不推荐使用)

-

集合判空

判断集合元素是否为空,使用isempty()

-

集合转Map

在使用 java.util.stream.Collectors 类的 toMap() 方法转为 Map 集合时,一定要注意当 value 为 null 时会抛 NPE 异常。

-

集合遍历

不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator 方式,如果并发操作,需要对 Iterator 对象加锁。

-

集合去重

可以利用 Set 元素唯一的特性,可以快速对一个集合进行去重操作,避免使用 Listcontains() 进行遍历去重或者判断包含操作。

- - -
- - - - -
-
-
-

- - - -