Datawhale组队学习 Task03:栈与递归(2天)
Task03:栈与递归(2天)
栈是我们经常使用的一种数据结构,如下图所示,手枪发射子弹的顺序与子弹压入弹夹的顺序是相反,即后压入弹夹的子弹先发射出来。
比如我们使用的Word、Excel、Photoshop等软件系统中的撤销操作,也是栈的具体应用,最后做的操作,一定是最先撤销的。下面我们就来详细介绍“栈”这种数据结构。
1. 栈的定义与操作
1.1 栈的定义
插入(入栈)和删除(出栈)操作只能在一端(栈顶)进行的线性表。即先进后出(First In Last Out)的线性表。
例1 :线性表(a0,a1,...,an)
进栈与出栈演示。
如上所示,栈有两种实现一种是顺序栈一种是链栈,这两种实现方式有什么区别呢,其实与顺序表和链表是一样的:
- 顺序栈是静态分配的但是链栈是动态分配的,所以比较起来链栈对于空间的利用率更高。因为顺序栈可能申请了较大的空间但是并没有全部都存储元素。
- 顺序栈虽然不用存储指针相比较链栈来说较为节省内存空间,但是链栈却可以将零碎的内存空间利用起来。
- 而且对于存储量未知的情况下,链栈更加适合,因为链栈通常不会出现栈满的情况。
- 对于顺序表和链表来说,链表对于插入和删除效率更高,顺序表对于查找效率更高。但是对于栈来说只能在栈顶进行操作,所以无法体现链表的效率更高。
1.2 栈的操作
- 入栈操作:将数据元素值插入栈顶。
- 出栈操作:移除栈顶的数据元素。
- 是否为空:判断栈中是否包含数据元素。
- 得到栈深:获取栈中实际包含数据元素的个数。
- 清空操作:移除栈中的所有数据元素。
- 获取栈顶元素。
以下代码为C#
版本:
using System;namespace LinearStruct
{/// <summary>/// 栈的抽象数据类型/// </summary>/// <typeparam name="T">栈中元素的类型</typeparam>public interface IStack<T> where T : IComparable<T>{/// <summary>/// 获取栈中实际包含元素的个数/// </summary>int Length { get; }/// <summary>/// 获取栈顶元素/// </summary>T StackTop { get; }/// <summary>/// 数据元素入栈/// </summary>/// <param name="data">要入栈的元素</param>void Push(T data);/// <summary>/// 数据元素出栈/// </summary>void Pop();/// <summary>/// 判断栈中是否包含元素/// </summary>/// <returns>如果包含元素返回false,否则返回true.</returns>bool IsEmpty();/// <summary>/// 从栈中移除所有元素/// </summary>void Clear();}
}
2. 栈的存储与实现
2.1 顺序存储(顺序栈)
顺序栈:利用顺序表实现的栈。
实现:
以下代码为C#
版本:
using System;namespace LinearStruct
{/// <summary>/// 用顺序存储结构实现的栈/// </summary>/// <typeparam name="T">顺序栈中元素的类型</typeparam>public class SeqStack<T> : IStack<T> where T : IComparable<T>{private readonly SeqList<T> _lst;/// <summary>/// 初始化SeqStack类的新实例/// </summary>/// <param name="max">SeqStack中最多包含元素的个数</param>public SeqStack(int max){if (max <= 0)throw new ArgumentOutOfRangeException();_lst = new SeqList<T>(max);}/// <summary>/// 获取SeqStack中实际包含元素的个数/// </summary>public int Length{get { return _lst.Length; }}/// <summary>/// 获取SeqStack中最多包含元素的个数/// </summary>public int MaxSize{get { return _lst.MaxSize; }}/// <summary>/// 获取SeqStack中的栈顶元素/// </summary>public T StackTop{get{if (_lst.IsEmpty())throw new Exception("栈为空.");return _lst[0];}}/// <summary>/// 数据元素入栈/// </summary>/// <param name="data">要入栈的元素</param>public void Push(T data){if (_lst.Length == _lst.MaxSize)throw new Exception("栈已达到最大容量.");_lst.Insert(0, data);}/// <summary>/// 数据元素出栈/// </summary>public void Pop(){if (_lst.IsEmpty())throw new Exception("栈为空.");_lst.Remove(0);}/// <summary>/// 判断SeqStack中是否包含元素/// </summary>/// <returns>如果包含元素返回false,否则返回true.</returns>public bool IsEmpty(){return _lst.IsEmpty();}/// <summary>/// 从SeqStack中移除所有元素/// </summary>public void Clear(){_lst.Clear();}}
}
2.2 链式存储(链栈)
链栈:利用单链表实现的栈。
实现:
以下代码为C#
版本:
using System;namespace LinearStruct
{/// <summary>/// 用链式存储结构实现的栈/// </summary>/// <typeparam name="T">栈中元素的类型</typeparam>public class LinkStack<T> : IStack<T> where T : IComparable<T>{private readonly SLinkList<T> _lst;/// <summary>/// 初始化LinkStack类的新实例/// </summary>public LinkStack(){_lst = new SLinkList<T>();}/// <summary>/// 获取LinkStack中实际包含元素的个数/// </summary>public int Length{get { return _lst.Length; }}/// <summary>/// 获取LinkStack中的栈顶元素/// </summary>public T StackTop{get{if (_lst.Length == 0)throw new Exception("栈为空.");return _lst[0];}}/// <summary>/// 数据元素入栈/// </summary>/// <param name="data">要入栈的元素</param>public void Push(T data){_lst.InsertAtFirst(data);}/// <summary>/// 数据元素出栈/// </summary>public void Pop(){if (_lst.Length == 0)throw new Exception("栈为空.");_lst.Remove(0);}/// <summary>/// 判断LinkStack中是否包含元素/// </summary>/// <returns>如果包含元素返回false,否则返回true.</returns>public bool IsEmpty(){return _lst.IsEmpty();}/// <summary>/// 从LinkStack中移除所有元素/// </summary>public void Clear(){_lst.Clear();}}
}
3. 递归
如果一个函数在内部调用自身本身,这个函数就是递归函数。
Sample01:求n的阶乘
n! = 1 x 2 x 3 x ... x n
循环:
以下代码为Python
版本:
n = 5
for k in range(1, 5):n = n * k
print(n) # 120
递归:
以下代码为Python
版本:
def factorial(n):if n == 1:return 1return n * fact(n - 1)print(factorial(5)) # 120
Samp02:斐波那契数列
f(n)=f(n-1)+f(n-2), f(0)=0 f(1)=1
循环:
以下代码为Python
版本:
i = 0
j = 1
lst = list([i, j])
for k in range(2, 11):k = i + jlst.append(k)i = jj = k
print(lst)
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
递归:
以下代码为Python
版本:
def recur_fibo(n):if n <= 1:return nreturn recur_fibo(n - 1) + recur_fibo(n - 2)lst = list()
for k in range(11):lst.append(recur_fibo(k))
print(lst)
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
注意:设置递归的层数,Python默认递归层数为 100
import syssys.setrecursionlimit(1000)
Sample03:汉诺塔问题
汉诺塔问题源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着 64 片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
如果我们要思考每一步怎么移可能会非常复杂,但是可以将问题简化。
我们可以先假设除 a 柱最下面的盘子之外,已经成功地将 a 柱上面的 63个盘子移到了 b 柱,这时我们只要再将最下面的盘子由 a 柱移动到 c 柱即可。
当我们将最大的盘子由 a 柱移到 c 柱后,b 柱上便是余下的 63 个盘子,a 柱为空。因此现在的目标就变成了将这 63 个盘子由 b 柱移到 c 柱。这个问题和原来的问题完全一样,只是由 a 柱换为了 b 柱,规模由 64 变为了 63。因此可以采用相同的方法,先将上面的 62 个盘子由 b 柱移到 a 柱,再将最下面的盘子移到 c 柱。
以此内推,再以 b 柱为缓冲,将 a 柱上面的 62 个圆盘最上面的 61 个圆盘移动到 b 柱,并将最后一块圆盘移到 c 柱。
我们已经发现规律,我们每次都是以 a 或 b 中一根柱子为缓冲,然后先将除了最下面的圆盘之外的其它圆盘移动到辅助柱子上,再将最底下的圆盘移到 c 柱子上,不断重复此过程。
这个反复移动圆盘的过程就是递归,例如我们每次想解决 n 个圆盘的移动问题,就要先解决(n-1)个盘子进行同样操作的问题。
于是可以编写一个函数,move(n, a, b, c)。可以这样理解:move(盘子数量, 起点, 缓冲, 终点)。
1. a 上只有一个盘子的情况,直接搬到 c,代码如下:
if n == 1:print(a, '-->', c)
2. a 上不止有一个盘子的情况:
首先,需要把 n-1 个盘子搬到 b 柱子缓冲。打印出的效果是:a --> b。
move(n - 1, a, c, b)
再把最大的盘子搬到 c 柱子,也是最大尺寸的一个。打印出:a–>c。
move(1, a, b, c)
最后,把剩下 b 柱的 n-1 个盘子搬到 c 上,此时缓冲变成了起点,起点变成了缓冲。
move(n - 1, b, a, c)
利用 Python 实现汉诺塔问题
i = 0def move(n, a, b, c):global iif (n == 1):i += 1print('移动第 {0} 次 {1} --> {2}'.format(i, a, c))returnmove(n - 1, a, c, b)move(1, a, b, c)move(n - 1, b, a, c)move(3, "a", "b", "c") # 移动第 1 次 a --> c
# 移动第 2 次 a --> b
# 移动第 3 次 c --> b
# 移动第 4 次 a --> c
# 移动第 5 次 b --> a
# 移动第 6 次 b --> c
# 移动第 7 次 a --> c
利用 C# 实现汉诺塔问题
class Program
{private static int i = 0;static void Move(int n, string a, string b, string c){if (n == 1){Console.WriteLine("移动第 {0} 次 {1}-->{2}", ++i, a, c);return;}Move(n - 1, a, c, b);Move(1, a, b, c);Move(n - 1, b, a, c);}static void Main(string[] args){Move(3, "a", "b", "c");}
}// 移动第 1 次 a --> c
// 移动第 2 次 a --> b
// 移动第 3 次 c --> b
// 移动第 4 次 a --> c
// 移动第 5 次 b --> a
// 移动第 6 次 b --> c
// 移动第 7 次 a --> c
4. 练习参考答案
车辆重排的程序代码,如下(C#
版本):
using System;
using LinearStruct;namespace TrainArrange
{class Program{/// <summary>/// 车厢重排算法/// </summary>/// <param name="p">入轨序列</param>/// <param name="k">缓冲轨条数</param>/// <returns>重排是否成功</returns>static bool RailRoad(int[] p, int k){LinkStack<int>[] h = new LinkStack<int>[k];for (int i = 0; i < h.Length; i++)h[i] = new LinkStack<int>();int nowOut = 1; //下一次要输出的车厢号int minH = int.MaxValue; //缓冲铁轨中编号最小的车厢int minS = -1; //minH号车厢对应的缓冲铁轨for (int i = 0; i < p.Length; i++){if (p[i] == nowOut){Console.WriteLine("移动车厢:{0}从入轨到出轨。", p[i]);nowOut++;//从缓冲铁轨中输出while (minH == nowOut){Output(ref minH, ref minS, h); //出轨nowOut++;}}else{//将p[i]送入某个缓冲铁轨if (Input(p[i], ref minH, ref minS, h) == false){return false;}}}return true;}/// <summary>/// 从缓冲轨移除车厢出轨/// </summary>/// <param name="minH">缓冲铁轨中编号最小的车厢</param>/// <param name="minS">minH号车厢对应的缓冲铁轨</param>/// <param name="h">缓冲轨道的集合</param>static void Output(ref int minH, ref int minS, LinkStack<int>[] h){h[minS].Pop(); //从堆栈minS中删除编号最小的车厢minHConsole.WriteLine("移动车厢:{0}从缓冲轨{1}到出轨。", minH, minS);//通过检查所有的栈顶,搜索新的minH和minSminH = int.MaxValue;minS = -1;for (int i = 0; i < h.Length; i++){if (h[i].IsEmpty() == false && h[i].StackTop < minH){minH = h[i].StackTop;minS = i;}}}/// <summary>/// 在一个缓冲铁轨中放入车厢C/// </summary>/// <param name="c">放入车厢编号</param>/// <param name="minH">栈顶编号的最小值</param>/// <param name="minS">栈顶编号最小值所在堆栈的编号</param>/// <param name="h">缓冲轨道的集合</param>/// <returns>如果没有可用的缓冲铁轨,则返回false,否则返回true。</returns>static bool Input(int c, ref int minH, ref int minS, LinkStack<int>[] h){int bestTrack = -1; //目前最优的铁轨int bestTop = int.MaxValue; //最优铁轨上的头辆车厢for (int i = 0; i < h.Length; i++){if (h[i].IsEmpty() == false){int x = h[i].StackTop;if (c < x && x < bestTop){bestTop = x;bestTrack = i;}}else{if (bestTrack == -1){bestTrack = i;break;}}}if (bestTrack == -1)return false;h[bestTrack].Push(c);Console.WriteLine("移动车厢:{0}从入轨到缓冲轨{1}。", c, bestTrack);if (c < minH){minH = c;minS = bestTrack;}return true;}static void Main(string[] args){int[] p = new int[] {3, 6, 9, 2, 4, 7, 1, 8, 5};int k = 1;bool result = RailRoad(p, k);do{if (result == false){Console.WriteLine("需要更多的缓冲轨道,请输入需要添加的数量:");k = k + Convert.ToInt32(Console.ReadLine());result = RailRoad(p, k);}} while (result == false);}}
}
相关文章:

sql_trace的介绍
sql_trace的介绍 --打开trace文件设置,把sql trace设置为true,就会在udump目录中增加一个trc文件。alter session set sql_tracetrue;show parameter sql_trace;(select * from v$parameter where namesql_trace;)修改后不生效呢&…

Console-算法[if,while]-一输入两个正整数m和n,求其最大公约数和最小公倍数
ylbtech-Arithmetic:Console-算法[if,while]-一输入两个正整数m和n,求其最大公约数和最小公倍数1.A,Demo(案例)输入两个正整数m和n,求其最大公约数和最小公倍数。 1.程序分析:利用辗除法。 1.B,Solution(解决方案)usin…

UI设计培训之如何将设计理论与实践相结合
学习UI设计理论知识与实践技术都是要有的,很多人都不爱去听理论知识,这对以后的工作是没有任何帮助的,只有将设计理论与实践相结合才能帮助到自己,那么如何将设计理论与实践相结合?来看看本期下面的详细介绍。 如何将设计理论与实…

Datawhale组队学习 Task04:队列(2天)
Task04:队列(2天) 队列也是我们经常使用的一种数据结构,如下图所示,购物结账,去食堂打饭等都需要排队,而结账或打饭的顺序与我们排队的顺序是相同的,即谁先排队就为谁先服务。 比如…

ios(iphone/ipad)开发笔记(1)
CGContextRefCGContextRefiphone开发刚刚入门 求个师傅iphone拨号键盘请问自己如果做sdkOpenGL ES 2.0有没有顶点光照的例子?socket通信哪位大侠帮帮忙?如何在tableView中使用自定义的cell?新手求指导Iphone按大圆钮时触发什么事件flash视频转…

如何查看Linq to SQL运行时,实际执行的Sql语句
调试Linq to sql代码是, 如果遇到错误,很难判断错误的原因是什么,如果能够输出实际执行的sql原文,对于我们寻找错误的原因有有很大帮助。 以下是我用到的方法: StringBuilder sql new StringBuilder();try{using (var context n…

Java培训零基础学员必须要知道的知识点
学习java那么遇到的知识点有很多,很多同学都会问到一些关于java的编程知识点,下面小编就为大家整理一下java培训零基础学员必须要知道的6个知识点。 Java培训零基础学员必须要知道的6个知识点: JVM作为java运行的基础来说,掌握透析…

SpringCloud Alibaba集成 Gateway(自定义负载均衡器)、Nacos(配置中心、注册中心)、Loadbalancer
要为未被某些网关路由谓词处理的请求提供相同的CORS配置,请将属性spring.cloud.gateway.globalcors.add-to-simple-url-handler-mapping设置为true。断言(Predicate):Java8中的断言函数,Spring Cloud Gateway中的断言函数输入类型是 Spring5.0框架中的ServerWebExchange。对于所有GET请求的路径,来自docs.spring.io的请求都将允许CORS请求。

并发编程下的集合:数组寻址、LinkedList、HashMap、ConcurrentHashMap
如果发现hash取模后的数组索引位下无元素则直接新增,若不是空那就说明存在hash冲突,则判断数组索引位链表结构中的第一个元素的key以及hash值是否与新的key一致则直接覆盖,若不一致则判断当前的数组索引下的链表结构是否为红黑树,若为红黑树则走红黑树的新增方法,若不为红黑树则遍历当前链表结构,遍历中发现某个节点元素的next为null是则直接将新元素指针与next进行关联,若在遍历到next为空前判断到,某个节点的key以及key的hash值与新的key与新的keyhash值一致时则走覆盖。

【日常开发之插件篇】IDEA plugins 神器助我!!
今早因为老代码的一些bug让我突然觉得Idea的一些插件特别好用,我准备将我平时所用到的一些插件做个推荐以及记录。

【日常开发之FTP】Windows开启FTP、Java实现FTP文件上传下载
FTP是一个专门进行文件管理的操作服务,一般来讲可以在任意的操作系统之中进行配置,但是如果考虑到简便性,一般来讲可以直接在Linux系统下进行安装。FTP (File Transfer Protocol、文件传输协议)是TCP/IP协议中的一部分,属于应用层协议。使用FTP最主要的功能是对文件进行管理,所以在FTP内部对于文件支持有两种传输模式:文本模式(ASCII、默认)和二进制模式(Binary),通常文本文件使用ASCIl模式,而对于图片、视频、声音、压缩等文件则会使用二进制的方式进行传输。

【Linux之升华篇】Linux内核锁、用户模式与内核模式、用户进程通讯方式
alloc_pages(gfp_mask, order),_ _get_free_pages(gfp_mask, order)等。字符设备描述符 struct cdev,cdev_alloc()用于动态的分配 cdev 描述符,cdev_add()用于注。外,还支持语义符合 Posix.1 标准的信号函数 sigaction(实际上,该函数是基于 BSD 的,BSD。从最初的原子操作,到后来的信号量,从。(2)命名管道(named pipe):命名管道克服了管道没有名字的限制,因此,除具有管道所具有的。

【Mongdb之数据同步篇】什么是Oplog、Mongodb 开启oplog,java监听oplog并写入关系型数据库、Mongodb动态切换数据源
oplog是local库下的一个固定集合,Secondary就是通过查看Primary 的oplog这个集合来进行复制的。每个节点都有oplog,记录这从主节点复制过来的信息,这样每个成员都可以作为同步源给其他节点。Oplog 可以说是Mongodb Replication的纽带了。

zookeeper集群部署以及zookeeper原理
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。ZooKeeper包含一个简单的原语集,提供Java和C的接口。

【日常开发之Windows共享文件】Java实现Windows共享文件上传下载
下拉框选择你选择的用户点击添加,然后共享确定。创建一个文件夹然后点击属性界面,点击共享。maven版本存在于SMB协议的兼容问题。首先开启服务,打开控制面板点击程序。点击启用或关闭Windows功能。我这边是专门创建了一个用户。SMB1.0选中红框内的。

rust wasm入门
demo## 编译 Rust 为 WebAssembly在本教程中,我们将使用 Rust 的 npm 包构建工具 wasm-pack 来构建一个 npm 包。

minikube环境搭建
📕作者简介:过去日记,致力于Java、GoLang,Rust等多种编程语言,热爱技术,喜欢游戏的博主。📘相关专栏系列、spring教程等,大家有兴趣的可以看一看📙系列,系列、系列正在发展中,喜欢Java,GoLang,Rust,的朋友们可以关注一下哦!@[TOC]# minikube## 安装### 前置条件已经安装docker### 乌班图安装科学上网是我你们安装的前提。```shell。

Pods/Nodes
Pod 容器组 是一个k8s中一个抽象的概念,用于存放一组 container,以及这些 container (容器)的一些共享资源。共享存储,称为卷(Volumes),即图上紫色圆柱网络,每个 Pod(容器组)在集群中有个唯一的 IP,pod(容器组)中的 container(容器)共享该IP地址container(容器)的基本信息,例如容器的镜像版本,对外暴露的端口等Pod(容器组)是 k8s 集群上的最基本的单元。

公布应用程序
当 worker node(节点)故障时,节点上运行的 Pod(容器组)也会消失。然后,Deployment (opens new window)可以通过创建新的 Pod(容器组)来动态地将群集调整回原来的状态,以使应用程序保持运行。举个例子,假设有一个图像处理后端程序,具有 3 个运行时副本。这 3 个副本是可以替换的(无状态应用),即使 Pod(容器组)消失并被重新创建,或者副本数由 3 增加到 5,前端系统也无需关注后端副本的变化。

伸缩应用程序和执行滚动更新
原本 Service A 将流量负载均衡到 4 个旧版本的 Pod 上2. 更新完 Deployment 部署文件中的镜像版本后,master 节点选择了一个 worker 节点,并根据新的镜像版本创建 Pod(紫色容器)。新 Pod 拥有唯一的新的 IP。同时,master 节点选择一个旧版本的 Pod 将其移除。此时,Service A 将新 Pod 纳入到负载均衡中,将旧Pod移除同步骤2,再创建一个新的 Pod 替换一个原有的 Pod。

Kubernetes对象的定义和操作
Kubernetes对象指的是Kubernetes系统的持久化实体,所有这些对象合起来,代表了你集群的实际情况。常规的应用里,我们把应用程序的数据存储在数据库中,Kubernetes将其数据以Kubernetes对象的形式通过 api server存储在 etcd 中。集群中运行了哪些容器化应用程序集群中对应用程序可用的资源应用程序相关的策略定义,例如,重启策略、升级策略、容错策略其他Kubernetes管理应用程序时所需要的信息。

名称和命名空间
📕作者简介:过去日记,致力于Java、GoLang,Rust等多种编程语言,热爱技术,喜欢游戏的博主。📘相关专栏系列、spring教程等,大家有兴趣的可以看一看📙系列,系列、系列正在发展中,喜欢Java,GoLang,Rust,的朋友们可以关注一下哦!

使用名称空间共享集群
可以限定使用某个名称空间的用户不能看到另外一个名称空间中的内容。默认情况下,安装Kubernetes集群时,会初始化一个 default 名称空间,用来将承载那些未指定名称空间的 Pod、Service、Deployment等对象。接下来,为 kubectl 定义一个上下文,以便在不同的名称空间中工作。此时,开发人员可以做任何他想要做的操作,所有操作都限定在名称空间 development 里,而无需担心影响到 production 名称空间中的内容。使用 kubectl 有两种方式可以创建名称空间。

k8s 标签和选择器
标签(Label)是附加在Kubernetes对象上的一组名值对,其意图是按照对用户有意义的方式来标识Kubernetes对象,同时,又不对Kubernetes的核心逻辑产生影响。管理这些对象时,很多时候要针对某一个维度的条件做整体操作,例如,将某个版本的程序整体删除,这种情况下,如果用户能够事先规划好标签的使用,再通过标签进行选择,就会非常地便捷。Kubernetes api server支持两种形式的标签选择器,equality-based 基于等式的 和 set-based 基于集合的。

iced 入门一
本教程的目标是创建一个简单的购物清单应用程序。我们希望允许添加和删除购物清单中的项目。在编写代码之前,我们必须首先了解 Iced 构建的结构:Elm 架构。它是 GUI 库使用的架构,最初用于 Elm 编程语言。它的核心原则很简单。它围绕三个概念构建:模型、视图和更新。

shell编程
简单来说“Shell 编程就是对一堆 Linux 命令的逻辑化处理”。

注解annotation
Kubernetes的系统组件(例如,kube-scheduler、kube-controller-manager、kube-apiserver、kubectl 或其他第三方组件)向用户的Kubernetes对象添加注解时,必须指定一个前缀。注解(annotation)可以用来向 Kubernetes 对象的 metadata.annotations 字段添加任意的信息。除了使用注解,您也可以将这类信息存放在一个外部的数据库,然而,在使用、分享这些信息的时候,可能会变得难以管理。

字段选择器
字段选择器(Field Selector)可以用来基于的一个或多个字段的取值来选取一组Kubernetes对象。

容器组_概述
Pod(容器组)是 Kubernetes 中最小的可部署单元。一个 Pod(容器组)包含了一个应用程序容器(某些情况下是多个容器)、存储资源、一个唯一的网络 IP 地址、以及一些确定容器该如何运行的选项。Pod 容器组代表了 Kubernetes 中一个独立的应用程序运行实例,该实例可能由单个容器或者几个紧耦合在一起的容器组成。一个 Pod 中只运行一个容器。“one-container-per-pod” 是 Kubernetes 中最常见的使用方式。

容器组_生命周期
只有一种例外,那就是 Pod 处于 Scucceeded 或 Failed 的 phase,并超过了垃圾回收的时长(在 kubernetes master 中通过 terminated-pod-gc-threshold 参数指定),kubelet 自动将其删除。每一个 Pod 都有一个数组描述其是否达到某些指定的条件。Pod phase 并不是用来代表其容器的状态,也不是一个严格的状态机。Kubernetes教程:在Kuboard中配置容器的健康检查/就绪检查。Kuboard 中配置健康检查/就绪检查。