自己整理的JAVA集合

news2024/9/25 1:18:02

在这里插入图片描述

概括:

数组,链表,散列表,二分查找树,红黑树是五种不同的数据结构,它们有各自的特点和用途。ArrayList,LinkedList,HashTable,LinkedHashMap,HashMap 是 Java 中的五个类,它们分别实现了 List 和 Map 接口,用来表示列表和映射。它们之间的对应关系如下:
1.ArrayList 是基于数组的列表,它使用一个动态扩展的数组来存储元素。
2.LinkedList 是基于双向链表的列表,它使用一个双向链表来存储元素。
3.HashTable 是基于散列表的映射,它使用一个数组和一个哈希函数来存储键值对。它是线程安全的,但是效率较低。
4.LinkedHashMap 是基于散列表和双向链表的映射,它使用一个数组和一个哈希函数来存储键值对,并且使用一个双向链表来维护键值对的插入顺序或者访问顺序。
5.HashMap 是基于散列表和红黑树的映射,它使用一个数组和一个哈希函数来存储键值对,并且当一个数组位置有多个键值对时,使用一个红黑树来存储这些键值对。
所以,你可以把这五个类分为两类:列表和映射。列表是一种有序的集合,它允许重复的元素,并且可以按照下标来访问或者修改元素。映射是一种无序的集合,它不允许重复的键,并且可以按照键来访问或者修改值。

List

list接口通常表示一个列表(数组、队列、链表、栈等),其中的元素可以重复,常用实现类为ArrayList和LinkedList及不常用的Vector。另外,LinkedList还是实现了Queue接口,因此也可作为队列使用。
同类型,可重复,有序性
list允许重复:指的是可以插入相同的名称 比如 两个张三,还有可以插入多个null值。
在这里插入图片描述

ArrayList

基于数组实现,可以通过下标索引直接查找到指定位置的元素,因此查找效率高,但每次插入或删除元素,就要大量地移动元素,插入删除元素的效率低。不是线程安全的。
批量处理数组 System.arraycopy(),对于ArrayList里面,add和remove等方法都用到了.

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
        

可以看到ArrayList类实现了Serializable接口,因此它支持序列化,能够通过序列化传输,实现了RandomAccess接口,支持快速随机访问,实现了Cloneable接口,能被克隆。实现类RandomAccess接口(标记接口),说明它支持快速访问。对于ArrayList来说,采用for循环遍历更快,对于LinkedList来说,采用迭代器遍历更快。

LinkedList

内部存储用的数据结构是双向链表,动态的插入和删除,访问遍历比较慢.
LinkedList是线程不安全的,若想使LinkedList变成线程安全的,可以使用如下方式:

List list=Collections.synchronizedList(new LinkedList(...));

LinkedList与ArrayList的区别

顺序插入的速度ArrayList快于LinkedList。因为ArrarList只是在指定的位置上赋值即可,而LinkedList则需要创建Node对象,并且需要建立前后关联,如果对象较大的话,速度会慢一些。
基于上面的理解LinkedList的占用的内存空间要大一些。
数组遍历的方式ArrayList推荐使用for循环,而LinkedList则推荐使用foreach,如果使用for循环,效率将会很慢。
一般我们这样认为:ArrarList查询和获取快,修改和删除慢;LinkedList修改和删除快,查询和获取慢。其实这样说不准确的。
LinkedList做插入、删除的时候,慢在寻址,快在只需要改变前后Entry的引用地址;
ArrayList做插入、删除的时候,慢在数组元素的批量copy,快在寻址。

Vector

它是非同步的,若涉及到多线程,用Vector会比较好一些,在非多线程环境中,Vector对于元素的查询、添加、删除和更新操作效果不是很好
Vector类中的capacity()/size()/isEmpty()/indexOf()/lastIndexOf()/removeElement()/addElement() 等方法
均是 sychronized 的,所以,对Vector的操作均是线程安全的,但也不完全原子性操作,中间有间隙。

Vector与ArrayList的区别

Vector 和 ArrayList 实现了同一接口 List, 但所有的 Vector 的方法都具有 synchronized 关键修饰。但对于复合操作,Vector 仍然需要进行同步处理
想要ArrayList安全 :使用同步包装器(Collections.synchronizedList),还可以使用J.U.C中的CopyOnWriteArrayList。

Set

接口通常表示一个集合,其中的元素不允许重复(通过hashcode和equals函数保证),常用实现类有HashSet和TreeSet,HashSet是通过Map中的HashMap实现的,而TreeSet是通过Map中的TreeMap实现的。另外,TreeSet还实现了SortedSet接口,因此是有序的集合(集合中的元素要实现Comparable接口,并覆写Compartor函数才行)。
set不允许重复,指的是,就算添加两个相同的值 也是只有一个出现。

在这里插入图片描述

HashSet 是基于散列表的集合
LinkedHashSet 是基于散列表和双向链表的集合
TreeSet 是基于红黑树的集合

Map

HashMap

底层基于哈希表,每一个元素是key-value对,采用数组存储数据,使用链表来解决哈希碰撞。在JDK1.8中引入了红黑树来解决链表长度过长导致的查询速度下降问题。HashMap是非线程安全的,只是用于单线程环境中,多线程环境中采用concurrent并发包下的concurrentHashMap,

1.HashMap是非线程安全的,允许key为null,value为null,遍历时无序。不允许重复
2.底层数据结构是数组称为哈希桶,每个桶里面放的是链表,链表中的每个节点,就是哈希表中的每个元素。
3.在JDK8中,当链表长度达到8,会转化成红黑树,以提升它的查询、插入效率.

在这里插入图片描述

数组链表转红黑树:

我可以尝试用更简单的语言来解释一下数组链表转红黑树的过程。你可以想象一个 HashMap 就像一个书架,它有很多格子,每个格子里可以放很多本书。每本书都有一个编号,这个编号就是它的哈希值,它决定了这本书应该放在哪个格子里。如果一个格子里只有一本书,那么我们很容易就能找到它。但是如果一个格子里有很多本书,那么我们就需要一个个地翻看,这样就很慢。为了加快查找的速度,我们可以把一个格子里的书按照编号的顺序排列起来,这样就形成了一个链表。这样我们就可以用二分法来查找,比如我们要找编号为 5 的书,我们先看中间的书是不是 5,如果不是,再看它是大于 5 还是小于 5,然后再在相应的一半里继续查找,直到找到或者没有为止。
但是有时候,一个格子里的书太多了,即使排成链表也还是很慢。比如说,如果一个格子里有 1000 本书,那么最坏的情况下,我们可能需要查找 10 次才能找到或者确定没有。为了进一步加快查找的速度,我们可以把一个格子里的书按照编号的高位和低位分成两堆,比如说,编号的前两位是 00 的放在一堆,编号的前两位是 01 的放在另一堆,以此类推。然后我们再把每一堆里的书按照编号的顺序排列起来,这样就形成了一个树形结构。这样我们就可以用树形搜索来查找,比如我们要找编号为 0101 的书,我们先看第一堆里有没有,如果没有,再看第二堆里有没有,如果有,再在第二堆里按照编号的顺序查找。这样最坏的情况下,我们只需要查找 4 次就能找到或者确定没有。
但是有时候,一个格子里的书分成两堆还是不够平均,比如说,编号的前两位是 00 的有 900 本书,编号的前两位是 01 的只有 100 本书。这样的话,我们查找编号为 00 开头的书还是很慢。为了让每一堆里的书更加平均分布,我们可以用一种特殊的树形结构来存储和查找书籍,这种树形结构叫做红黑树。红黑树有以下几个特点:
每个节点(即每本书)都有一个颜色属性,要么是红色要么是黑色。
根节点(即第一本书)必须是黑色。
每个叶子节点(即空节点)都是黑色。
如果一个结点是红的,则它两个子节点都是黑的。也就是说在一条路径上不能出现相邻的两个红色结点。
从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。正是这些性质的限制,使得红黑树中任一节点到其子孙叶子节点的最长路径不会长于最短路径的2倍,因此它是一种接近平衡的二叉树
红黑树的引入,既是为了平衡寻找的次数,也是为了加速查找速率。因为平衡寻找的次数,就意味着减少了最坏情况下的查找时间。比如说,如果一个格子里有 1000 本书,用链表存储和查找,最坏的情况下,我们需要查找 1000 次;用普通的二叉搜索树存储和查找,最坏的情况下,我们可能需要查找 1000 次(如果树退化成链表);用红黑树存储和查找,最坏的情况下,我们只需要查找 10 次。所以,红黑树相比于链表和普通的二叉搜索树,都能提高查找速率。

HashTable

是基于key-value键值对,采用桶位+链表结构实现。不允许存null,如果put null,会 npe

HashTable与HashMap的区别

1.hashmap中key和value均可以为null,但是hashtable中key和value均不能为null。
2.hashmap采用的是数组(桶位)+链表+红黑树结构实现,而hashtable中采用的是数组(桶位)+链表实现。
3.hashmap中出现hash冲突时,如果链表节点数小于8时是将新元素加入到链表的末尾,而hashtable中出现hash冲突时采用的是将新元素加入到链表的开头。
4.hashmap中数组容量的大小要求是2的n次方,如果初始化时不符合要求会进行调整,而hashtable中数组容量的大小可以为任意正整数。
5.hashmap中的寻址方法采用的是位运算按位与,而hashtable中寻址方式采用的是求余数。
6.hashmap不是线程安全的,而hashtable是线程安全的,hashtable中的get和put方法均采用了synchronized关键字进行了方法同步。
7.hashmap中默认容量的大小是16,而hashtable中默认数组容量是11。

LinkedHashMap

1.LinkedHashMap是非线程安全的。
2.LinkedHashMap中加入了一个head头结点,将所有插入到该LinkedHashMap中的Entry按照插入的先后顺序依次加入到以head为头结点的双向循环链表的尾部
3.LinkedHashMap是HashMap和LinkedList两个集合类存储结构的结合,所有put进来的Entry都保存在一个哈希表中,但它又额外定义了一个以head为头结点的空的双向循环链表,每次put进来Entry,除了将其保存到对哈希表中对应的位置上外,还要将其插入到双向循环链表的尾部。
4.LinkedHashMap继承自HashMap,同样允许key和value为null。
5.accessOrder标志属性,当为false时,表示双向链表中的元素按照Entry插入LinkedHashMap到中的先后顺序排序,当它为true时,表示双向链表中的元素按照访问的先后顺序排列。
6.LinkedHashMap如何实现LRU。首先,当accessOrder为true时,才会开启按访问顺序排序的模式,才能用来实现LRU算法。我们可以看到,无论是put方法还是get方法,都会导致目标Entry成为最近访问的Entry,因此便把该Entry加入到了双向链表的末尾,这样便把最近使用了的Entry放入到了双向链表的后面,多次操作后,双向链表前面的Entry便是最近没有使用的,这样当节点个数满的时候,删除的最前面的Entry(head后面的那个Entry)便是最近最少使用的Entry。

TreeMap

1.TreeMap是根据key进行排序的,它的排序和定位需要依赖比较器或覆写Comparable接口,也因此不需要key覆写hashCode方法和equals方法,就可以排除掉重复的key,而HashMap的key则需要通过覆写hashCode方法和equals方法来确保没有重复的key。
2.TreeMap的查询、插入、删除效率均没有HashMap高,一般只有要对key排序时才使用TreeMap。
3.TreeMap的key不能为null,而HashMap的key可以为null。

ConcurrentHashMap

在这里插入图片描述

在这里插入图片描述

总结1.7和1.8区别

结构区别:JDK7的是由一个Segment数组组成,每个Segment是一个类似于HashMap的结构,它包含一个Node数组和一个链表。JDK8的是由一个Node数组组成,每个Node是一个键值对,它可以连接成一个链表或者一个红黑树。

锁区别:JDK7的使用了分段锁的机制,每个Segment继承了ReentrantLock,对Segment进行读写操作时需要加锁。JDK8的取消了分段锁,而是使用了synchronized和CAS来实现对每个节点的细粒度锁控制。

扩容区别:JDK7的在扩容时,需要对整个Segment加锁,然后将原来的Node数组复制到新的数组中,并重新计算哈希值和索引。JDK8的ConcurrentHashMap在扩容时,不需要加锁,而是使用CAS来保证原子性,然后将原来的Node数组分成两个部分,一部分保持不变,另一部分迁移到新的数组中,并使用高位运算来计算索引。

插入区别:JDK7的在插入节点时,使用了头插法,也就是说新插入的节点会放在链表的头部。这样在扩容时,原来的链表顺序会被反转。JDK8的在插入节点时,使用了尾插法,也就是说新插入的节点会放在链表的尾部。这样在扩容时,原来的链表顺序不会改变。

优化区别:JDK8的在处理哈希冲突时,有一个优化措施,就是当链表长度达到一定阈值(默认是8)时,会将链表转换为红黑树,这样可以提高查找效率。JDK7的ConcurrentHashMap没有这个优化措施。

Java 7

初始化

1.必要参数校验。
2.校验并发级别 concurrencyLevel 大小,如果大于最大值,重置为最大值。无参构造默认值是 16.
3.寻找并发级别 concurrencyLevel 之上最近的 2 的幂次方值,作为初始化容量大小,默认是 16。
4.记录 segmentShift 偏移量,这个值为【容量 = 2 的 N 次方】中的 N,在后面 Put 时计算位置时会用到。默认是 32 - sshift = 28.
5.记录 segmentMask,默认是 ssize - 1 = 16 -1 = 15.
6.初始化 segments[0],默认大小为 2,负载因子 0.75,扩容阀值是 2*0.75=1.5,插入第二个值时才会进行扩容。

segmentShift和segmentMask是ConcurrentHashMap在JDK1.7中使用的两个变量,
它们用于定位Segment对象在segments数组中的位置。segmentShift是一个位移量,
它表示hash值右移多少位后,再与segmentMask进行与运算,得到Segment对象的索引。segmentMask是一个掩码,它是一个二进制数,所有位都是1,它的大小等于segments数组的
长度减1。例如,如果segments数组的长度是16,那么segmentShift是28,segmentMask
是15。32是hash值的位数,4是segments数组的长度的以2为底的对数。也就是说,
segments数组的长度是2的4次方,也就是16。为了从hash值中提取出Segment对象的索引,
需要将hash值右移32-4=28位,这样就只剩下高4位,然后与segmentMask进行与运算,
得到0到15之间的一个整数,作为Segment对象的索引。这样可以保证hash值在segments
数组中均匀分布,减少锁竞争。

put

简单总结;
1.Segment 段和初始化 Segment 段的操作
2.开始put,tryLock() 获取锁,获取不到使用 scanAndLockForPut 方法继续获取
3.获取的 HashEntry,不存在(是否大于阈值,大于就扩容,不大于就直接插入)
4.获取的 HashEntry,存在,当前元素 key 和 hash 值是否和要 put 的 key 和 hash 值一致。一致则替换值
不一致继续向下获取链表,直到找到为止,大于阈值扩容,否则插入

扩容

ConcurrentHashMap 的扩容只会扩容到原来的两倍。老数组里的数据移动到新的数组时,位置要么不变,要么变为
index+ oldSize,参数里的 node 会在扩容之后使用链表头插法插入到指定位置

get

1.计算得到 key 的存放位置。
20遍历指定位置查找相同 key 的 value 值。

Java 8

初始化initTable

从源码中可以发现 ConcurrentHashMap 的初始化是通过自旋和 CAS 操作完成的。里面需要注意的是变量 sizeCtl ,它的值决定着当前的初始化状态。
1.-1 说明正在初始化
2.-N 说明有 N-1 个线程正在进行扩容
3.0 表示 table 初始化大小,如果 table 没有初始化
4.>0 表示 table 扩容的阈值,如果 table 已经初始化。

put

1.根据 key 计算出 hashcode 。
2.判断是否需要进行初始化。
3.即为当前 key 定位出的 Node,如果为空表示当前位置可以写入数据,利用 CAS 尝试写入,失败则自旋保证成功。
4.如果当前位置的hashcode == MOVED == -1 则需要进行扩容。
5.如果都不满足,则利用 synchronized 锁写入数据。
6.如果数量大于TREEIFY_THRESHOLD则要执行树化方法,在treeifyBin中会首先判断当前数组长度 ≥64 时才会将链表转换为红黑树。

get

1.根据 hash 值计算位置。
2.查找到指定位置,如果头节点就是要找的,直接返回它的 value.
3.如果头节点 hash 值小于 0 ,说明正在扩容或者是红黑树,查找之。
4.如果是链表,遍历查找之。

各种树,链表,数组结构

链接: https://juejin.cn/post/6844903625236430862

参考地址:
JavaGuide/docs/java/collection/concurrent-hash-map-source-code.md

jdk-sourcecode-analysis/note/ConcurrentHashMap/concurrenthashmap.md

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/810284.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Camera组件

Clear Flags&#xff1a; Skybox&#xff1a;天空盒 Solid Color&#xff1a;填充颜色&#xff0c;当有空白处时填充背景颜色 Depth Only&#xff1a;只渲染想要渲染的层级 Dont Clear&#xff1a;不清除上一帧所留下来的数据&#xff0c;可以做类似残影的效果 Culling Mas…

Unity Addressable

Unity重要目录 工程中的几个重要目录 Assets存放资源、代码、配置Library大部分的资源导入到Assets目录之后&#xff0c;会转化成Unity认可的文件&#xff0c;转化后的文件会存储在这个目录Logs日志文件Packages第三方插件ProjectSettings存放各种项目设定UserSettings用户偏好…

CentOS 8 错误: Error setting up base repository

配置ip、掩码、网关、DNS VMware网关可通过如下查看 打开网络连接 配置镜像的地址 vault.centos.org/8.5.2111/BaseOS/x86_64/os/

java 阿里云 发送短信功能实现

1. 注册短信平台(以阿里云为例) 常用短信服务平台&#xff1a;阿里云、华为云、腾讯云、京东、梦网、乐信等 2. 注册成功后&#xff0c;开通短信服务 3. 设置短信签名、短信模板、AccessKey AccessKey 是访问阿里云 API 的密钥&#xff0c;具有账户的完全权限&#xff0c;我们…

C语言实现三子棋游戏

test.c源文件 - 三子棋游戏测试 game.h头文件 - 三子棋游戏函数的声明 game.c源文件 - 三子棋游戏函数的实现 主函数源文件&#xff1a; #define _CRT_SECURE_NO_WARNINGS 1#include"game.h" //自己定义的用"" void menu() {printf("*************…

代码随想录算法训练营day43

文章目录 Day43 最后一块石头的重量II题目思路代码 目标和题目思路代码 一和零题目思路代码 Day43 最后一块石头的重量II 1049. 最后一块石头的重量 II - 力扣&#xff08;LeetCode&#xff09; 题目 有一堆石头&#xff0c;每块石头的重量都是正整数。 每一回合&#xff0…

2023-07-30 LeetCode每日一题(环形链表 II)

2023-07-30每日一题 一、题目编号 142. 环形链表 II二、题目链接 点击跳转到题目位置 三、题目描述 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 n…

【探索C++中的顺序表】手动实现vector容器

&#x1f680;write in front&#x1f680; &#x1f4dc;所属专栏&#xff1a;初阶数据结构 &#x1f6f0;️博客主页&#xff1a;睿睿的博客主页 &#x1f6f0;️代码仓库&#xff1a;&#x1f389;VS2022_C语言仓库 &#x1f3a1;您的点赞、关注、收藏、评论&#xff0c;是对…

Fourier变换及其应用(Brad G. Osgood)——第2章——Fourier变换

第2章 Fourier变换 2.1 初识Fourier变换(A First Look at the Fourier Transform) 我们即将从Fourier级数过渡到Fourier变换。“过渡(transition)”是合适的词&#xff0c;因为我们选择了Fourier变换从周期函数到非周期函数的引出路径。 为了完成这一旅程&#xff0c;我们将把…

【优选算法题练习】day10

文章目录 一、137. 只出现一次的数字 II1.题目简介2.解题思路3.代码4.运行结果 二、剑指 Offer 53 - II. 0&#xff5e;n-1中缺失的数字1.题目简介2.解题思路3.代码4.运行结果 三、153. 寻找旋转排序数组中的最小值1.题目简介2.解题思路3.代码4.运行结果 总结 一、137. 只出现一…

登录报错 “msg“:“Request method ‘GET‘ not supported“,“code“:500

1. 登录失败 2. 排查原因, 把 PostMapping请求注释掉, 或改成GetMapping请求就不会报错 3. 找到SecurityConfig.java , 新增 .antMatchers("/**/**").permitAll() //匹配允许所有路径 4. 登录成功

【算法基础:动态规划】5.4 状态压缩DP

文章目录 例题列表291. 蒙德里安的梦想⭐⭐⭐⭐⭐91. 最短Hamilton路径⭐⭐⭐ 相关链接 例题列表 291. 蒙德里安的梦想⭐⭐⭐⭐⭐ https://www.acwing.com/problem/content/293/ 当横向方格摆放完成后&#xff0c;纵向方格的拜访方式就已经确定了。&#xff08;因为我们只要求…

井字棋(TicTacToe)

目录 三种游戏 习题 1. 传统设置 2. 中间的网格 三种游戏 “选15”、“井字棋”、“魔幻15”游戏本质上是同一个游戏。 function tictactoe(job) % TICTACTOE Pick15, TicTacToe, and Magic3. % % Pick15. Pick single digit numbers. Each digit can be chosen % on…

蓝海卓越计费管理系统远程命令执行

活着&#xff0c;就要时刻准备承受磨难&#xff01; 漏洞描述 蓝海卓越计费管理系统存在命令调试页面&#xff0c;导致攻击者可以远程命令执行 漏洞复现 访问 debug.php页面 远程调试命令执行 /debug.php漏洞证明 文笔生疏&#xff0c;措辞浅薄&#xff0c;望各位大佬不吝…

GIS基础制图之地形图

数据:地理空间数据云(http://www.gscloud.cn/)下一张北京地区DEM(30m),统一用这一张来做。 晶格 工具运行窗口不贴了,因为参数设置基本上都是默认没有什么要改的 1、「3D Analyst」—「转换」—「由栅格转出」—「栅格转TIN」 2、「3D Analyst」—「转换」—「由TIN转出」—…

【Rust教程 | 基础系列 | Cargo工具】Cargo介绍及使用

文章目录 前言一&#xff0c;Cargo介绍1&#xff0c;Cargo安装2&#xff0c;创建Rust项目2&#xff0c;编译项目&#xff1a;3&#xff0c;运行项目&#xff1a;4&#xff0c;测试项目&#xff1a;5&#xff0c;更新项目的依赖&#xff1a;6&#xff0c;生成项目的文档&#xf…

MP的开发流程

MP的开发流程 1、添加依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.ap…

微服务04 分布式搜索引擎 elasticsearch DSL数据聚合 自动补全 数据同步 集群 微服务保护 Sentinel

微服务03 分布式搜索引擎 elasticsearch ELK kibana RestAPI 索引库 DSL查询 RestClient 黑马旅游 分布式搜索引擎03 1.数据聚合 聚合&#xff08;aggregations&#xff09;可以让我们极其方便的实现对数据的统计、分析、运算。例如&#xff1a; 什么品牌的手机最受欢迎&…

无涯教程-jQuery - Transfer方法函数

Transfer 效果可以与effect()方法一起使用。这会将元素的轮廓转移到另一个元素。尝试可视化两个元素之间的交互时非常有用。 Transfer - 语法 selector.effect( "transfer", {arguments}, speed ); 这是所有参数的描述- className - 传输元素将收到的可选类名。…

Doris安装部署入门

文章目录 一 Doris 介绍1.1 使用场景1.1.2 Doris架构 二 Doris单机部署2.1 下载 Doris2.2 配置 Doris2.2.1 配置 FE2.2.2 启动 FE2.2.3 查看 FE 运行状态2.2.4 连接 FE2.2.5 停止 FE 节点2.2.6 配置 BE2.2.7 启动 BE2.2.8 添加 BE 节点到集群2.2.9 查看 BE 运行状态2.2.10 停止…