获得徽章 7
- 在 Go(Golang)中,**数据类型**分为两大类:
- **值类型(Value Types)**
- **引用类型(Reference Types)**
理解这两类的区别非常重要,因为它直接影响到赋值、参数传递和内存管理的行为。
---
## 📘 一、引用类型(Reference Types)
在 Go 中,**以下四类是引用类型**:
| 类型 | 说明 |
|------|------|
| `slice`(切片) | 对底层数组的引用。多个切片可以共享同一个底层数组。 |
| `map`(映射) | 类似哈希表,内部实际是一个引用结构。复制 map 变量时,只会复制引用。 |
| `channel`(通道) | goroutine 之间通信的引用类型。复制 channel 变量不会复制底层通道。 |
| `function`(函数) | 函数类型的变量实际上是指向函数体的引用。 |
---
### 1. **slice**
切片由三部分组成:
- 指针(指向底层数组)
- 长度(len)
- 容量(cap)
```go
a := []int{1, 2, 3}
b := a // b 引用了同一个底层数组
b[0] = 99
fmt.Println(a[0]) // 输出 99,说明两者共享底层数据
```
---
### 2. **map**
`map` 是一个引用类型。它内部使用哈希表实现,但变量本身只是对底层哈希结构的引用。
```go
m1 := map[string]int{"x": 1}
m2 := m1
m2["x"] = 100
fmt.Println(m1["x"]) // 输出 100
```
---
### 3. **channel**
`channel` 用于 goroutine 间通信。复制通道变量不会创建新的通道。
```go
ch1 := make(chan int)
ch2 := ch1
go func() {
ch2 <- 10
}()
fmt.Println(<-ch1) // 输出 10,说明 ch1 和 ch2 引用了相同通道
```展开赞过评论2 - ### Operator 工作原理
```
Reconciliation Loop(调谐循环):
1. 观察当前状态
↓
2. 读取期望状态(从CRD)
↓
3. 比较差异
↓
4. 执行操作使当前状态 → 期望状态
↓
5. 回到步骤1(不断循环)展开赞过11 - // LeetCode 704: 二分查找
func search(nums []int, target int) int {
return BinarySearch(nums, target)
}
// LeetCode 35: 搜索插入位置
func searchInsert(nums []int, target int) int {
left, right := 0, len(nums)-1
for left <= right {
mid := left + (right-left)/2
if nums[mid] == target {
return mid
} else if nums[mid] < target {
left = mid + 1
} else {
right = mid - 1
}
}
return left // 返回插入位置
}
// LeetCode 34: 在排序数组中查找元素的第一个和最后一个位置
func searchRange(nums []int, target int) []int {
first := FindFirst(nums, target)
if first == -1 {
return []int{-1, -1}
}
last := FindLast(nums, target)
return []int{first, last}
}
```
## 八、记忆口诀
```
二分查找三要素:
1. 左闭右闭定边界 (left, right := 0, len-1)
2. 循环条件带等号 (left <= right)
3. 中点防溢出公式 (left + (right-left)/2)
更新规则记心间:
- 找到目标直接返
- 小于目标左加一 (left = mid + 1)
- 大于目标右减一 (right = mid - 1)展开赞过21 - 在Linux/Unix系统中,**僵尸进程**会占用资源,而孤儿进程不会造成额外的资源占用问题。
## 僵尸进程(Zombie Process)
**会占用系统资源**,但占用量很小:
- 进程已经终止,释放了内存、文件描述符等大部分资源
- 但进程表(PCB)中的条目仍然保留,包含退出状态信息
- 占用一个进程ID(PID)
- 如果僵尸进程大量累积,会耗尽系统的进程表空间,导致无法创建新进程
**产生原因**:子进程终止后,父进程没有调用wait()或waitpid()来回收子进程的退出状态。
## 孤儿进程(Orphan Process)
**不会造成资源占用问题**:
- 孤儿进程是正常运行的进程,只是父进程提前终止了
- 系统会自动将孤儿进程过继给init进程(PID为1)或systemd
- init/systemd会负责回收这些进程,当它们终止时会自动调用wait()
- 孤儿进程作为正常进程运行,使用正常的系统资源
**产生原因**:父进程先于子进程终止。
## 总结
僵尸进程是需要关注的问题,特别是当父进程编写不当,长期不回收子进程时。而孤儿进程则是被系统妥善处理的,不会造成资源泄漏。展开评论点赞 - 两阶段提交流程:
完整流程:
1. 执行器调用InnoDB开始事务
2. InnoDB修改数据,写入undo log(记录旧值)
3. InnoDB更新内存(Buffer Pool)
4. InnoDB写入redo log,状态为 prepare
5. 执行器生成binlog,写入磁盘
6. 执行器调用InnoDB提交事务
7. InnoDB将redo log状态改为 commit展开评论点赞 - MVCC 负责解决 普通查询(SELECT) 时的幻读问题(基于版本快照,看到的行数据一致)。
间隙锁(Gap Lock)+ 临键锁(Next-Key Lock) 起作用于 更新(UPDATE / DELETE / INSERT) 时,
锁定「记录之间的间隙」从而防止新的行被插入,消除了幻读。1点赞 **TCP 三次握手简答版(面试速记版)**
> TCP 建立连接要经过三次握手:
> 1️⃣ **第一次**:客户端发送 `SYN` 报文,请求建立连接;
> 2️⃣ **第二次**:服务器收到后回复 `SYN+ACK`,表示同意并确认客户端请求;
> 3️⃣ **第三次**:客户端收到后再回 `ACK` 确认,连接正式建立。
📘 **目的:**
让双方都确认彼此的 **发送和接收能力正常**,并防止历史连接的干扰。展开评论点赞