Skip to content

Commit

Permalink
reformat title style
Browse files Browse the repository at this point in the history
  • Loading branch information
howieyuen committed Jan 23, 2024
1 parent 35eacdc commit 8170fbc
Show file tree
Hide file tree
Showing 39 changed files with 669 additions and 653 deletions.
3 changes: 2 additions & 1 deletion content/docs/XaC/cicd/argocd.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
author: howieyuen
date: 2021-10-21
title: 使用 Argo CD ApplicationSet 管理多集群
tag: [argocd]
tags: [ArgoCD]
categories: [CI/CD]
---

> 本文翻译自
Expand Down
3 changes: 2 additions & 1 deletion content/docs/XaC/infra-as-code/getting-started-of-acorn.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
---
date: 2022-12-16
title: Acorn:k8s 应用部署框架
tag: [acorn, iac]
tags: [Acorn]
categories: [IaC]
---

## 概述
Expand Down
5 changes: 4 additions & 1 deletion content/docs/XaC/infra-as-code/terraform-workflow.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
---
date: 2022-12-16
title: Terraform 执行状态和阶段关系
tag: [terraform, iac]
tag: [Terraform]
categories: [IaC]
---

Terraform 每次运行都经过多个操作阶段(Pending、Plan、Cost Estimation、Policy Check、Apply 和 Completion),Terraform Cloud 将这些阶段的进度显示为运行状态。
在 Terraform Cloud 主页上的工作区列表中,每个工作区都显示了它当前正在处理的运行状态。(或者,如果没有正在进行的运行,则为最近完成的运行的状态。)

<!--more-->

## Pending

阶段状态:
Expand Down
3 changes: 2 additions & 1 deletion content/docs/XaC/secret-as-code/external-secret-operator.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
author: howieyuen
date: 2022-11-2
title: External Secrets Operator
tag: [sac, secret, operator]
tags: [ExternalSecret]
categories: [SaC]
---

## 概述
Expand Down
3 changes: 2 additions & 1 deletion content/docs/XaC/secret-as-code/helm-secrets.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
author: howieyuen
date: 2023-09-27
title: Helm Secrets
tag: [SaC, helm, secret]
tag: [helm secret]
categories: [SaC]
---

## 概述
Expand Down
3 changes: 2 additions & 1 deletion content/docs/XaC/secret-as-code/kamus.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
author: howieyuen
date: 2023-09-27
title: Kamus
tag: [SaC, kamus, secret]
tag: [KamusSecret]
categories: [SaC]
---

## 概述
Expand Down
3 changes: 2 additions & 1 deletion content/docs/XaC/secret-as-code/sealed-secrets.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
author: howieyuen
date: 2022-10-15
title: Sealed Secrets
tag: [SaC, secret]
tags: [SealedSecret]
categories: [SaC]
---

# 概述
Expand Down
3 changes: 2 additions & 1 deletion content/docs/XaC/secret-as-code/secrets-store-csi-driver.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
author: howieyuen
date: 2022-11-02
title: Secrets Store CSI Driver
tag: [SaC, secret, csi]
tag: [SecretProviderClass]
categories: [SaC]
---

## 概述
Expand Down
2 changes: 1 addition & 1 deletion content/docs/getting-started/circle-ci.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Circle CI
date: 2021-12-14
tags: [CircleCI, Orb]
tags: [CircleCI]
categories: [CI/CD]
---

Expand Down
32 changes: 19 additions & 13 deletions content/docs/golang/data-structure/chan.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
author: Yuan Hao
date: 2020-12-14
title: chan
tag: [golang, chan]
tags: [chan]
categories: [Golang]
---

# 1. 引言
Go 语言中最常见的、也是经常被人提及的设计模式就是 —— 不要通过共享内存的方式进行通信,而是应该通过通信的方式共享内存。

**先入先出**
Expand All @@ -14,7 +14,10 @@ Go 语言中最常见的、也是经常被人提及的设计模式就是 ——
- 先从 Channel 读取数据的 Goroutine 会先接收到数据;
- 先向 Channel 发送数据的 Goroutine 会得到先发送数据的权利;

# 2. 数据结构
<!--more-->

## 数据结构

```go
type hchan struct {
qcount uint // 当前队列中剩余元素个数
Expand All @@ -32,7 +35,8 @@ type hchan struct {
```
从数据结构可以看出 channel 由队列、类型信息、goroutine 等待队列组成,下面分别说明其原理。

## 2.1 环形队列
### 环形队列

chan 内部实现了一个环形队列作为其缓冲区,队列的长度是创建 chan 时指定的。

下图展示了一个可缓存 6 个元素的 channel 示意图:
Expand Down Expand Up @@ -63,7 +67,8 @@ chan 内部实现了一个环形队列作为其缓冲区,队列的长度是创
- sendx 指示后续写入的数据存储的位置,取值 [0, 6);
- recvx 指示从该位置读取数据,取值 [0, 6);

## 2.2 等待队列
### 等待队列

从 channel 读数据,如果 channel 缓冲区为空或者没有缓冲区,当前 goroutine 会被阻塞。
向 channel 写数据,如果 channel 缓冲区已满或者没有缓冲区,当前 goroutine 会被阻塞。

Expand Down Expand Up @@ -99,17 +104,17 @@ chan 内部实现了一个环形队列作为其缓冲区,队列的长度是创
注意,一般情况下 recvq 和 sendq 至少有一个为空。只有一个例外,
那就是同一个 goroutine 使用 select 语句向 channel 一边写数据,一边读数据。

## 2.3 类型信息
### 类型信息
一个 channel 只能传递一种类型的值,类型信息存储在 hchan 数据结构中。
- elemtype 代表类型,用于数据传递过程中的赋值;
- elemsize 代表类型大小,用于在 buf 中定位元素位置。

## 2.4
###
一个 channel 同时仅允许被一个 goroutine 读写。

# 3. channel 读写
## channel 读写

## 3.1 创建 channel
### 创建 channel
创建 channel 的过程实际上是初始化 hcha 结构。其中类型信息和缓冲区长度由 make 语句传入,
buf 的大小则与元素 大小和缓冲区长度共同决定。

Expand Down Expand Up @@ -148,7 +153,7 @@ func makechan(t *chantype, size int) *hchan {
}
```

## 3.2 发送数据
### 发送数据

向一个 channel 中发送数据简单过程如下:
1. 如果等待接收队列 recvq 不为空,说明缓冲区中没有数据或者没有缓冲区,
Expand All @@ -172,7 +177,7 @@ F -.-> G[被唤醒,数据被取走]
G -.-> H
{{< /mermaid >}}

## 3.3 接收数据
### 接收数据

从一个 channel 接收数据简单过程如下:
1. 如果等待发送队列 sendq 不为空,且没有缓冲区,直接从 sendq 中取出 G,
Expand Down Expand Up @@ -203,14 +208,15 @@ d1 --> e0[从G中读出数据]
e0 --> d3
{{< /mermaid >}}

## 3.4 关闭 channel
### 关闭 channel

关闭 channel 时会把 recvq 中的 G 全部唤醒,本该写入 G 的数据位置为 nil。把 sendq 中的 G 全部唤醒,但这些 G 会 panic。
除此之外,panic 出现的常见场景还有:
1. 关闭值为 nil 的 channel
2. 关闭已经被关闭的 channel
3. 向已经关闭的 channel 写数据

# 4. 参考资料
## 参考资料

- [Go Channel 实现原理精要](https://draveness.me/golang/docs/part3-runtime/ch06-concurrency/golang-channel/)
- [Go 专家编程:1.1 chan](https://www.bookstack.cn/read/GoExpertProgramming/chapter01-1.1-chan.md)
25 changes: 14 additions & 11 deletions content/docs/golang/data-structure/map.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,27 @@
author: Yuan Hao
date: 2020-5-14
title: map
tag: [golang, map]
tags: [map]
categories: [Golang]
---

# 1. 引言

粗略的讲,Go 语言中 map 采用的是哈希查找表,
由一个 key 通过哈希函数得到哈希值,
64 位系统中就生成一个 64 bit 的哈希值,
由这个哈希值将 key 对应到不同的桶(bucket)中,
当有多个哈希映射到相同的的桶中时,使用链表解决哈希冲突。

## 1.1 hash 函数
<!--more-->

## 哈希表

### hash 函数

首先要知道的就是 map 中哈希函数的作用,go 中 map 使用 hash 作查找,
就是将 key 作哈希运算,得到一个哈希值,根据哈希值确定 key-value 落在哪个 bucket 的哪个 cell。
golang 使用的 hash 算法和 CPU 有关,如果 CPU 支持 aes,那么使用 aes hash,否则使用 memhash。

## 1.2 数据结构
### 数据结构

**hmap** 可以理解为 header of map 的缩写,即 map 数据结构的入口。

Expand Down Expand Up @@ -89,11 +92,11 @@ type bmap struct {
如果 `overflow bucket` 也溢出了呢?那就再给 `overflow bucket` 新建一个 `overflow bucket`,用指针串起来就形成了链式结构,
map 本身有 2^B 个 bucket,只有当发生哈希碰撞后才会在 bucket 后链式增加 `overflow bucket`

# 2. map 内存布局
## 内存布局

![memory-layout-of-map.png](/golang/data-structure/map/memory-layout-of-map.png)

## 2.1 扩容
### 扩容

1. 装填因子是否大于 6.5

Expand All @@ -108,7 +111,7 @@ map 本身有 2^B 个 bucket,只有当发生哈希碰撞后才会在 bucket

**等量扩容**:重新排列,极端情况下,重新排列也解决不了,map 成了链表,性能大大降低,此时哈希种子 hash0 的设置,可以降低此类极端场景的发生。

## 2.2 查找
### 查找

1. 根据 key 计算出哈希值
2. 根据哈希值低位确定所在 bucket
Expand All @@ -117,21 +120,21 @@ map 本身有 2^B 个 bucket,只有当发生哈希碰撞后才会在 bucket
5. 对应位置有数据则对比完整的哈希值,确定是否是要查找的数据
6. 如果当前处于 map 进行了扩容,处于数据搬移状态,则优先从 oldbuckets 查找。

## 2.3 插入
### 插入

1. 根据 key 计算出哈希值
2. 根据哈希值低位确定所在 bucket
3. 根据哈希值高 8 位确定在 bucket 中的存储位置
4. 查找该 key 是否存在,已存在则更新,不存在则插入

## 2.4 map 无序
### map 无序

map 的本质是散列表,而 map 的增长扩容会导致重新进行散列,这就可能使 map 的遍历结果在扩容前后变得不可靠,
Go 设计者为了让大家不依赖遍历的顺序,**故意在实现 map 遍历时加入了随机数**
让每次遍历的起点--即起始 bucket 的位置不一样,即不让遍历都从 bucket0 开始,
所以即使未扩容时我们遍历出来的 map 也总是无序的。

# 3. 参考资料
## 参考资料

- [Golang map 底层实现](https://bettertxt.top/post/go-map/)
- [Go 语言之 map:map 的用法到 map 底层实现分析](https://blog.csdn.net/chenxun_2010/article/details/103768011)
Expand Down
39 changes: 26 additions & 13 deletions content/docs/golang/data-structure/slice.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,19 @@
author: Yuan Hao
date: 2020-5-14
title: slice
tag: [golang, slice]
tag: [slice]
categories: [Golang]
---

# 1. 数据结构
slice 的底层数据是数组,slice 是对数组的封装,它描述一个数组的片段。两者都可以通过下标来访问单个元素。
数组是定长的,长度定义好之后,不能再更改。在 Go 中,数组是不常见的,因为其长度是类型的一部分,
限制了它的表达能力,比如 `[3]int``[4]int` 就是不同的类型。
而切片则非常灵活,它可以动态地扩容。切片的类型和长度无关。
数组就是一片连续的内存, slice 实际上是一个结构体,包含三个字段:长度、容量、底层数组。

<!--more-->

## 数据结构

```go
type slice struct {
Expand All @@ -19,38 +28,42 @@ type slice struct {
- `len` 代表这个 slice 的元素个数
- `cap` 表示 slice 指向的底层数组容量

**对 slice 的赋值,以值作为函数参数时,只拷贝 1 个指针和 2 个 int 值。**
{{<hint info>}}
对 slice 的赋值,以值作为函数参数时,只拷贝 1 个指针和 2 个 int 值。
{{</hint>}}

# 2. 操作
## 操作

## 2.1 创建
### 创建

- `var []T``[]T{}`
- `func make([]T,len,cap) []T`

## 2.2 nil 切片和空切片
### nil 切片和空切片

- nil 切片被用在很多标准库和内置函数中,描述一个不存在的切片的时候,就需要用到 nil 切片。比如函数在发生异常的时候,返回的切片就是 nil 切片。**nil 切片的指针指向 nil**.
- 空切片一般会用来表示一个**空集合**。比如数据库查询,一条结果也没有查到,那么就可以返回一个空切片。

## 2.3 扩容
### 扩容

### 2.3.1 计算策略
#### 计算策略

- 若 Slice cap 大于 doublecap,则扩容后容量大小为 新 Slice 的容量(超了基准值,我就只给你需要的容量大小)
- 若 Slice len **小于 1024** 个,在扩容时,**增长因子为 1**(也就是 3 个变 6 个)
- 若 Slice len **大于 1024** 个,在扩容时,**增长因子为 0.25**(原本容量的四分之一)

### 2.3.2 内存策略
#### 内存策略

- **翻新扩展**:当前元素为 `kindNoPointers`,也就是**非指针类型**,将在老 Slice cap 的地址后继续申请空间用于扩容
- **举家搬迁**:重新申请一块内存地址,整体迁移并扩容

## 2.4 拷贝
### 拷贝

`slicecopy()` 方法会把源切片值(即 from Slice ) 中的元素复制到目标切片(即 to Slice ) 中,并返回被复制的元素个数,copy 的两个类型必须一致。`slicecopy()` 方法最终的**复制结果取决于较短的那个切片**,当较短的切片复制完成,整个复制过程就全部完成了。
`slicecopy()` 方法会把源切片值(即 from Slice ) 中的元素复制到目标切片(即 to Slice ) 中,
并返回被复制的元素个数,copy 的两个类型必须一致。`slicecopy()` 方法最终的**复制结果取决于较短的那个切片**
当较短的切片复制完成,整个复制过程就全部完成了。

# 3. 特性
## 特性

slice 的 array 存储在连续内存上,因此具有以下特点:

Expand All @@ -60,7 +73,7 @@ slice 的 array 存储在连续内存上,因此具有以下特点:
4. 新、老 slice 共用底层数组,对底层数组的更改都会影响到彼此;
5. append 可以掰断新老 slice 共用底层数组的关系;

# 4. 参考资料
## 参考资料

- [深入解析 Go 中 Slice 底层实现](https://halfrost.com/go_slice/)
- [深入解析 Go Slice](https://segmentfault.com/a/1190000017341615)
Loading

0 comments on commit 8170fbc

Please sign in to comment.