使用孩子兄弟表示法,可以轻松地遍历树结构,从根节点开始,通过第一个孩子指针和下一个兄弟指针访问每个节点的子节点和兄弟节点。这种表示方法节省了存储空间,并且在某些操作(如树的遍历和查找)上具有较好的性能。
孩子兄弟表示法常用于表示二叉树和森林(由多个不相交的树组成),尤其适用于树的动态操作和算法实现。
需要注意的是,孩子兄弟表示法在进行插入和删除操作时可能需要调整节点的指针,以维持正确的关系,并确保树的结构仍然有效。
孩子兄弟表示法是树结构的一种常用表示方法,但根据具体的应用需求和操作需求,选择适合的树表示方法是很重要的。
下面给出孩子兄弟表示法的存储结构定义:
typedef char DataType;
typedef struct CSNode
{
DataType data;
struct CSNode \* firstchild, \* rightsib;
} CSNode;
CsNode \*root; // 定义根指针
三、二叉树的逻辑结构
1.二叉树的定义
1.1 二叉树
二叉树(Binary Tree)是一种特殊的树结构,其中每个节点最多有两个子节点,分别称为左子节点和右子节点。
二叉树的定义如下:
- 空树(Empty Tree):一个没有节点的二叉树被称为空树。
- 根节点(Root Node):二叉树中的一个特殊节点被称为根节点,它是二叉树的顶部节点,没有父节点与之相连。
- 节点(Node):二叉树中的每个节点包含一个值或数据,并且可以连接到最多两个子节点。每个节点可以有零个、一个或两个子节点。
- 左子节点(Left Child Node):一个节点连接到它的左侧子节点的节点被称为左子节点。
- 右子节点(Right Child Node):一个节点连接到它的右侧子节点的节点被称为右子节点。
- 叶节点(Leaf Node):叶节点是没有子节点的节点,它们位于二叉树的末端。
需要注意的是,二叉树中的节点可以有一个子节点为空(缺失),但不能有两个子节点都为空的情况。
二叉树的特点是每个节点最多有两个子节点,其中左子节点和右子节点的顺序是有意义的,不可以随意的颠倒。二叉树的结构可用于模拟层次关系、排序和搜索等应用。
1.2 斜树
斜树(Skewed Tree)是一种特殊类型的二叉树,它的所有节点都只有一个子节点,要么都是左子节点,要么都是右子节点。
根据子节点的位置,斜树可以分为两种类型:
- 左斜树(Left Skewed Tree):所有节点都只有左子节点,没有右子节点。每个节点的右子节点为空。
1
/
2
/
3
/
4
- 右斜树(Right Skewed Tree):所有节点都只有右子节点,没有左子节点。每个节点的左子节点为空。
1
\
2
\
3
\
4
**斜树是二叉树的一种特殊情况,因为它的所有节点只有一个子节点,所以斜树的高度等于节点的数量。**斜树的形状类似于一个单向链表,只有一个方向上的连接。
斜树在某些特定场景下可能会出现,但在一般情况下并不常见。它的特殊性使得斜树的插入和删除操作相对简单,但访问和搜索效率较低,因为树的平衡性被破坏了。
需要注意的是,斜树是二叉树的一种特殊情况,与其他类型的二叉树(如平衡二叉树、完全二叉树等)相比,斜树的应用范围较为有限。在大多数情况下,我们更倾向于使用平衡性更好的二叉树结构。
1.3 满二叉树
满二叉树(Full Binary Tree)是一种特殊类型的二叉树,其中除了叶节点外,每个节点都有两个子节点,并且所有叶节点都在同一层级上。
满二叉树的定义如下:
- 空树(Empty Tree):一个没有节点的二叉树被称为空树。
- 根节点(Root Node):二叉树中的一个特殊节点被称为根节点,它是二叉树的顶部节点,没有父节点与之相连。
- 节点(Node):二叉树中的每个节点包含一个值或数据,并且可以连接到最多两个子节点。每个节点可以有零个、一个或两个子节点。
- 叶节点(Leaf Node):叶节点是没有子节点的节点,它们位于二叉树的末端。
- 每个非叶节点都有两个子节点:除了叶节点外,满二叉树的每个非叶节点都有两个子节点。
- 所有叶节点在同一层级上:满二叉树的所有叶节点都位于同一层级上,也就是说从根节点到叶节点的路径长度是相同的。
下图是一个示例,展示了一个满二叉树的结构:
A
/ \
B C
/ \ / \
D E F G
在上述示例中,每个非叶节点都有两个子节点,而且所有叶节点(D、E、F、G)都在同一层级上。
满二叉树具有良好的平衡性和规律性,它的高度(从根节点到最深层的叶节点的路径长度)为log2(n+1),其中n是满二叉树中的节点数量。满二叉树的节点数量为2^h - 1,其中h是满二叉树的高度。
满二叉树在一些算法和数据结构中具有重要的应用,例如堆排序、完全二叉树的表示等。由于其特定的性质,满二叉树的插入和删除操作相对复杂,但在某些场景下,满二叉树能够提供更高效的存储和访问方式。
1.4 完全二叉树
完全二叉树(Complete Binary Tree)是一种特殊类型的二叉树,除了最后一层外,所有层的节点都被填满,且最后一层的节点都尽可能地靠左排列。
完全二叉树的定义如下:
- 空树(Empty Tree):一个没有节点的二叉树被称为空树。
- 根节点(Root Node):二叉树中的一个特殊节点被称为根节点,它是二叉树的顶部节点,没有父节点与之相连。
- 节点(Node):二叉树中的每个节点包含一个值或数据,并且可以连接到最多两个子节点。每个节点可以有零个、一个或两个子节点。
- 最后一层节点靠左排列:在最后一层的节点中,从左到右依次排列,不留有空缺。
- 最后一层之前的层都是满的:除了最后一层外,所有的层都被填满,每一层的节点数都达到最大。
下图是一个示例,展示了一个完全二叉树的结构:
A
/ \
B C
/ \ /
D E F
在上述示例中,除了最后一层的节点(F)没有右子节点外,其他层的节点都被填满,且最后一层的节点都尽可能地靠左排列。
完全二叉树具有一些特性:由于它的结构相对规整,因此可以使用数组或顺序存储来表示,同时也便于使用索引进行节点的访问和操作。完全二叉树在一些算法和数据结构中具有重要的应用,例如优先队列(使用堆实现)和哈夫曼树等。
需要注意的是,完全二叉树不一定是满二叉树,因为最后一层可以不是满的。而满二叉树的定义是除了叶节点外,每个节点都有两个子节点,并且所有叶节点在同一层级上。
2.二叉树的基本性质
2.1 性质1
**在一棵二叉树中,如果叶子节点的个数为
n
0
n _0
n0,度为2的结点个数为
n
2
n_2
n2,则
n
0
=
n
2
1
n_0 = n_2 + 1
n0=n2+1。**
2.2 性质2
**二叉树的第 i 层最多有
2
i
−
1
2^{i - 1}
2i−1个结点(
i
=
1
i >= 1
i>=1)。**
2.3 性质3
**在一棵深度为 k 的二叉树中,最多有
2
k
−
1
2^k - 1
2k−1 个结点。**
2.4 性质4
**具有 n 个结点的完全二叉树的深度为
⌊
log
2
n
⌋
1
\left \lfloor \log_{2}{n} \right\rfloor + 1
⌊log2n⌋+1。**
2.5 性质5
对一棵具有n个结点的完全二叉树从1开始按层序编号,则对于编号为
i
(
1
<
=
i
<
=
n
)
i(1 <= i <= n)
i(1<=i<=n)的结点
i
i
i,有:
**1. 如果
i
1
i > 1
i>1,则结点
i
i
i的父节点编号为
⌊
i
/
2
⌋
\left \lfloor i/ 2 \right\rfloor
⌊i/2⌋ ;否则结点
i
i
i 是根结点, 无双亲。**
**2. 如果
2
i
<
=
n
2i <= n
2i<=n,则结点的左孩子编号为
2
i
2i
2i ;否则结点无左孩子。**
== **3. 如果
2
i
<
=
n
1
2i <= n + 1
2i<=n+1,则结点的右孩子编号为
2
i
1
2i + 1
2i+1 ;否则结点无右孩子。**
3.二叉树的抽象数据类型定义
和树一样,在不同的情况下,二叉树的基本操作不尽相同。下面给出一些二叉树抽象数据类型定义的例子,包含了部分基本操作:
ADT BiTree
DataModel
二叉树由一个根节点和两棵互不相交的左右子树构成,二叉树中的结点具有层次关系
Operation
InitBiTree
输入:无
功能:初始化一棵二叉树
输出:一个空的二叉树
CreatBiTree
输入:n 个结点的数据信息
功能:建立一棵二叉树
输出:含有n个结点的二叉树
DestoryBiTree
输入:无
功能:销毁一棵二叉树
输出:释放二叉树所占的内存空间
PreOrder
输入:无
功能:前序遍历二叉树
输出:二叉树的前序遍历序列
InOrder
输入:无
功能:中序遍历二叉树
输出:二叉树的中序遍历序列
PostOrder
输入:无
功能:后序遍历二叉树
输出:二叉树的后序遍历序列
LeverOrder
输入:无
功能:层序遍历二叉树
输出:二叉树的层序遍历序列
endADT
需要注意的是,二叉树的实现方式可以有多种,如链式存储(使用节点对象和引用)或数组存储(使用数组来表示节点及其关系),具体的实现方式可以根据需求和语言特性进行选择。以上定义给出了二叉树的操作接口,在具体实现时可以根据需要进行适当的调整。
4.二叉树的遍历操作
二叉树的遍历是指按照一定的顺序访问二叉树的所有节点。常见的二叉树遍历方式有三种:先序遍历、中序遍历和后序遍历。这些遍历方式可以通过递归或迭代的方式实现。
以下是关于二叉树遍历的一些常见操作:
先序遍历(Preorder Traversal):
先序遍历的顺序是:根节点 -> 左子树 -> 右子树。
递归实现:
- 如果树为空,则返回。
- 访问当前节点的值。
- 递归地对左子树进行先序遍历。
- 递归地对右子树进行先序遍历。
迭代实现:
- 创建一个空栈,并将根节点压入栈。
- 当栈不为空时,执行以下步骤:
- 弹出栈顶节点,访问该节点的值。
- 如果存在右子节点,则将右子节点压入栈。
- 如果存在左子节点,则将左子节点压入栈。
中序遍历(Inorder Traversal):
中序遍历的顺序是:左子树 -> 根节点 -> 右子树。
递归实现:
- 如果树为空,则返回。
- 递归地对左子树进行中序遍历。
- 访问当前节点的值。
- 递归地对右子树进行中序遍历。
迭代实现:
- 创建一个空栈。
- 初始化当前节点为根节点。
- 当栈不为空或当前节点不为空时,执行以下步骤:
- 将当前节点及其所有左子节点依次压入栈,直到当前节点为空。
- 弹出栈顶节点,访问该节点的值。
- 将当前节点更新为弹出节点的右子节点。
后序遍历(Postorder Traversal):
后序遍历的顺序是:左子树 -> 右子树 -> 根节点。
递归实现:
- 如果树为空,则返回。
- 递归地对左子树进行后序遍历。
- 递归地对右子树进行后序遍历。
- 访问当前节点的值。
迭代实现:
- 创建一个空栈。
- 初始化当前节点为根节点。
- 当栈不为空或当前节点不为空时,执行以下步骤:
- 将当前节点及其所有左子节点依次压入栈,直到当前节点为空。
- 如果栈顶节点的右子节点存在且未被访问过,则将当前节点更新为右子节点。
- 否则,弹出栈顶节点,访问该节点的值,并将当前节点置为空。
层序遍历(Level Order Traversal):
按照层级顺序逐层访问二叉树节点的遍历方式。
层序遍历的步骤如下:
- 创建一个空队列(可以使用数组或链表实现)。
- 将根节点入队。
- 当队列不为空时,执行以下步骤:
- 弹出队头节点,并访问该节点的值。
- 如果弹出的节点有左子节点,将左子节点入队。
- 如果弹出的节点有右子节点,将右子节点入队。
层序遍历会按照从上到下、从左到右的顺序逐层访问二叉树的节点。这意味着在同一层级上,左边的节点会在右边的节点之前被访问到。
下面是一个层序遍历的示例:
A
/ \
B C
/ \ /
D E F
层序遍历的结果为:A, B, C, D, E, F。
在实际实现中,可以使用队列来辅助层序遍历。首先将根节点入队,然后每次从队列中取出一个节点,访问该节点的值,并将其左右子节点(如果存在)依次入队。重复这个过程,直到队列为空,即可完成层序遍历。
层序遍历常用于广度优先搜索(BFS)等算法中,可以用于按层级遍历或搜索树的结构。
四、二叉树的存储结构
1.顺序存储结构
二叉树的顺序存储结构是一种使用数组来表示二叉树的方法。在顺序存储结构中,树的节点按照从上到下、从左到右的顺序依次存储在数组中,通过数组的索引来表示节点之间的关系。
假设二叉树的顺序存储结构使用一个一维数组 arr
来表示,其中根节点存储在索引为 0 的位置,对于任意节点存储在索引 i
的位置上,它的左子节点存储在索引 2i+1
的位置上,右子节点存储在索引 2i+2
的位置上。
下图是一个示例二叉树的顺序存储结构表示:
A
/ \
B C
/ \ / \
D E F G
对应的顺序存储结构数组为:['A', 'B', 'C', 'D', 'E', 'F', 'G']
。
在顺序存储结构中,可以通过数组的索引计算出节点之间的关系,例如,索引为 i
的节点的父节点索引为 (i-1)//2
,左子节点索引为 2i+1
,右子节点索引为 2i+2
。
顺序存储结构的优点是简单、易于实现和访问,不需要额外的指针和动态内存分配。然而,它对于非完全二叉树会浪费一定的空间,因为可能存在一些数组元素未被使用。
需要注意的是,顺序存储结构适用于静态的二叉树,即在构建树后不会改变其结构。如果需要频繁地进行插入、删除节点操作,顺序存储结构可能不是一个高效的选择,因为需要频繁地调整数组大小和移动元素位置。在这种情况下,链式存储结构(使用节点对象和引用)更为常用和灵活。
下面给出二叉树顺序存储结构的定义:
#define MaxSize 100 //假设二叉树的最大编号
typedef char DataType; //定义二叉树的数据类型,假设为char
typedef struct
{
DataType data[MaxSize];
int biTreeNum; //结点个数
} SeqBiTree;
2.二叉链表
2.1 二叉链表的存储结构定义
二叉链表是一种使用节点对象和引用来表示二叉树的存储结构。在二叉链表中,每个节点包含一个数据元素和两个指针,分别指向其左子节点和右子节点(如果存在)。
下面给出二叉链表的存储结构定义:
typedef char DataType;
typedef struct BiNode
{
DataType data;
struct BiNode \* lchild, \* rchild;
} BiNode;
2.2 二叉链表的实现
遍历操作是用递归写的,非递归的版本将放在七、拓展与提高当中
2.2.1 前序遍历
由二叉树前序遍历的操作定义,容易写出前序遍历的递归算法,代码如下:
void PreOrder(BiNode\* root)
{
if (root == NULL) return; //递归结束条件
printf("%c", root->data); //访问根节点的数据域
PreOrder(root->lchild); //前序递归遍历root左子树
PreOrder(root->rchild); //前序递归遍历root右子树
}
2.2.2 中序遍历
由二叉树中序遍历的操作定义,容易写出中序遍历的递归算法,代码如下:
void InOrder(BiNode\* root)
{
if (root == NULL) return; //递归结束条件
InOrder(root->lchild); //中序递归遍历root左子树
printf("%c", root->data); //访问根节点的数据域
InOrder(root->rchild); //中序递归遍历root右子树
}
2.2.3 后序遍历
由二叉树后序遍历的操作定义,容易写出后序遍历的递归算法,代码如下:
void PostOrder(BiNode\* root)
{
if (root == NULL) return; //递归结束条件
PostOrder(root->lchild); //后序递归遍历root左子树
PostOrder(root->rchild); //后序递归遍历root右子树
printf("%c", root->data); //访问根节点的数据域
}
2.2.4 层序遍历
在进行层序遍历时,访问某一层的结点后,在对各个节点的左孩子和右孩子顺序访问,这样一层一层进行,先访问的节点其左右孩子也要先访问,这符合队列的操作特性。因此,在进行层序遍历时,设置一个队列存放已访问的结点,代码如下:
void LevelOrder(BiNode\* root)
{
BiNode\* q = NULL, \* Q[QMaxSize]; //顺序队列
int front, rear; //队头队尾
front = rear = -1; //初始化为-1
if (root == NULL) return; //如果二叉树为空,函数结束
Q[++rear] = root; //非空根节点入队
while (front != rear)
{
q = Q[++front];
printf("%c", q->data);
if (q->lchild != NULL) Q[++rear] = q->lchild;
if (q->rchild != NULL) Q[++rear] = q->rchild;
}
}
2.2.5 二叉树的创建
先理清楚一个概念:
拓展二叉树: 将二叉树中每个节点的空指针指向一个虚结点,其值为一个特定值以表示其为空,把这样处理后的二叉树原二叉树的拓展二叉树。
我们知道,对于任意一组序列,无论是前序,中序,后序,还是层序,我们无论知道哪一个序列,大多数情况下都无法直接构造出正确的二叉树。
但我们构造时,使用拓展二叉树,就一定可以得到唯一确定的一棵二叉树。
这里以拓展二叉树的前序序列举例,代码如下:
BiNode\* CreatBiTree(BiNode\* root)
{
char ch;
scanf("%c", &ch); //输入结点信息
if (ch == '#') root = NULL; //递归结束
else
{
root = (BiNode\*)malloc(sizeof BiNode); //生成新节点
root->data = ch; //新节点数据域
root->lchild = CreatBiTree(root->lchild); //递归建立左子树
root->rchild = CreatBiTree(root->rchild); //递归建立右子树
}
return root;
}
2.2.6 二叉树的销毁
二叉链表是动态分配内存,二叉链表的结点是在程序运行过程中动态申请的,在二叉树表变量退出作用域前,要释放二叉链表的存储空间。可以对二叉链表进行后序遍历,在访问结点时进行释放,代码如下:
void DestoryBiTree(BiNode\* root)
{
if (root == NULL) return;
DestoryBiTree(root->lchild);
DestoryBiTree(root->rchild);
free(root);
}
3.三叉链表
三叉链表是一种链表数据结构的扩展形式,它允许每个节点同时链接到前一个节点、后一个节点以及一个额外的父节点。这使得三叉链表在某些场景下比传统的单向或双向链表更加灵活和方便。
三叉链表的节点通常由三个指针组成:prev
、next
和parent
。这些指针分别指向前一个节点、后一个节点和父节点。
通过这种结构,三叉链表可以实现以下功能:
- 正向和反向遍历:由于每个节点都有指向前一个和后一个节点的指针,你可以从任意节点开始遍历整个链表,无论是正向还是反向。
- 父节点链接:每个节点还有一个指针指向其父节点。这对于从某个节点向上导航至其父节点非常有用,尤其是在树形结构中。
- 多叉树表示:通过使用三叉链表,可以轻松地将多叉树表示为一个链表结构。每个节点的父节点指针可以指向其树中的父节点,而后续节点的指针可以指向其子节点。
尽管三叉链表提供了更多的灵活性和功能,但它也带来了更多的空间开销和复杂性。在实际应用中,需要根据具体情况权衡使用三叉链表的优势和劣势。
五、森林
1.森林的逻辑结构
在数据结构中,森林是由多个独立的树(树结构)组成的集合。每棵树都是由节点和它们之间的关联关系(通常是父子关系)构成的。
森林可以通过多种方式表示,其中两种常见的方法是:
- 使用多个根节点:每棵树都有一个根节点,根节点之间没有父子关系。这种表示方法适用于树的根节点集合已知的情况,每个根节点代表一棵树。
- 使用指针或链接:每个节点包含指向其子节点的指针或链接。节点之间通过这些指针或链接建立关联关系。通过这种方式,可以在森林中方便地遍历树的节点。
森林数据结构常用于解决一些特定的问题,例如图的连通分量、无向图的生成树等。它提供了一种有效的方式来组织和操作多个独立的树结构。
2.树、森林与二叉树的转换
物理结构上看,数的孩子兄弟表示法和二叉树的二叉链表是相同的,树的孩子兄弟表示法的第一个孩子指针和右兄弟指针分别相当于二叉链表的左孩子指针和右孩子指针。换言之,给定一棵树,可以找到唯一的一棵二叉树与之对应。
2.1 树转换成二叉树
将一棵树转换成二叉树的常见方法是通过改变节点之间的链接关系,以便每个节点最多有两个子节点。这可以通过以下步骤实现:
- 选择树的根节点作为二叉树的根节点。
- 对于树中的每个节点,将其第一个子节点作为其左子节点,并将其右兄弟节点作为其右子节点。如果节点没有右兄弟节点,则将其右子节点设置为null。
- 对于每个节点的右子节点,将其第一个子节点作为其左子节点,并将其右兄弟节点作为其右子节点。如果节点没有右兄弟节点,则将其右子节点设置为null。
- 递归地应用步骤2和步骤3,直到所有节点都被处理。
通过这种转换,原始的树结构被转换成了二叉树结构,其中每个节点最多有左子节点和右子节点。这种转换允许使用二叉树的算法和技巧来处理原始树的问题。
2.2 森林转化成二叉树
将森林转换成二叉树可以通过逐个处理森林中的每棵树,并将每棵树转换为对应的二叉树。
以下是将森林转换为二叉树的步骤:
-
对于森林中的每棵树:
- 选择一棵树的根节点作为二叉树的根节点。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Linux运维工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Linux运维全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Linux运维知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加VX:vip1024b (备注Linux运维获取)
为了做好运维面试路上的助攻手,特整理了上百道 【运维技术栈面试题集锦】 ,让你面试不慌心不跳,高薪offer怀里抱!
这次整理的面试题,小到shell、MySQL,大到K8s等云原生技术栈,不仅适合运维新人入行面试需要,还适用于想提升进阶跳槽加薪的运维朋友。
本份面试集锦涵盖了
- 174 道运维工程师面试题
- 128道k8s面试题
- 108道shell脚本面试题
- 200道Linux面试题
- 51道docker面试题
- 35道Jenkis面试题
- 78道MongoDB面试题
- 17道ansible面试题
- 60道dubbo面试题
- 53道kafka面试
- 18道mysql面试题
- 40道nginx面试题
- 77道redis面试题
- 28道zookeeper
总计 1000+ 道面试题, 内容 又全含金量又高
- 174道运维工程师面试题
1、什么是运维?
2、在工作中,运维人员经常需要跟运营人员打交道,请问运营人员是做什么工作的?
3、现在给你三百台服务器,你怎么对他们进行管理?
4、简述raid0 raid1raid5二种工作模式的工作原理及特点
5、LVS、Nginx、HAproxy有什么区别?工作中你怎么选择?
6、Squid、Varinsh和Nginx有什么区别,工作中你怎么选择?
7、Tomcat和Resin有什么区别,工作中你怎么选择?
8、什么是中间件?什么是jdk?
9、讲述一下Tomcat8005、8009、8080三个端口的含义?
10、什么叫CDN?
11、什么叫网站灰度发布?
12、简述DNS进行域名解析的过程?
13、RabbitMQ是什么东西?
14、讲一下Keepalived的工作原理?
15、讲述一下LVS三种模式的工作过程?
16、mysql的innodb如何定位锁问题,mysql如何减少主从复制延迟?
17、如何重置mysql root密码?
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
QL,大到K8s等云原生技术栈,不仅适合运维新人入行面试需要,还适用于想提升进阶跳槽加薪的运维朋友。**
[外链图片转存中…(img-HwqhiJ5k-1712887491808)]
本份面试集锦涵盖了
- 174 道运维工程师面试题
- 128道k8s面试题
- 108道shell脚本面试题
- 200道Linux面试题
- 51道docker面试题
- 35道Jenkis面试题
- 78道MongoDB面试题
- 17道ansible面试题
- 60道dubbo面试题
- 53道kafka面试
- 18道mysql面试题
- 40道nginx面试题
- 77道redis面试题
- 28道zookeeper
总计 1000+ 道面试题, 内容 又全含金量又高
- 174道运维工程师面试题
1、什么是运维?
2、在工作中,运维人员经常需要跟运营人员打交道,请问运营人员是做什么工作的?
3、现在给你三百台服务器,你怎么对他们进行管理?
4、简述raid0 raid1raid5二种工作模式的工作原理及特点
5、LVS、Nginx、HAproxy有什么区别?工作中你怎么选择?
6、Squid、Varinsh和Nginx有什么区别,工作中你怎么选择?
7、Tomcat和Resin有什么区别,工作中你怎么选择?
8、什么是中间件?什么是jdk?
9、讲述一下Tomcat8005、8009、8080三个端口的含义?
10、什么叫CDN?
11、什么叫网站灰度发布?
12、简述DNS进行域名解析的过程?
13、RabbitMQ是什么东西?
14、讲一下Keepalived的工作原理?
15、讲述一下LVS三种模式的工作过程?
16、mysql的innodb如何定位锁问题,mysql如何减少主从复制延迟?
17、如何重置mysql root密码?
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-PL6OENMr-1712887491808)]