Skip to content

Commit

Permalink
docs: optimze details
Browse files Browse the repository at this point in the history
suyuan32 committed Jan 29, 2024
1 parent e4b604b commit f1170a9
Showing 6 changed files with 104 additions and 148 deletions.
17 changes: 5 additions & 12 deletions src/en/guide/concepts/database/1-database-basic.md
Original file line number Diff line number Diff line change
@@ -21,8 +21,7 @@ The difference between the primary key and the unique key:
- The primary key cannot be null, the unique key can be null
:::

<details>
<summary>Example</summary>
::: details Example

Assume there are two tables

@@ -39,7 +38,7 @@ Assume there are two tables
- Candidate Key: For example, in the `student` table: `student.id` `student.identify_card`
- Foreign Key: `student.teacher_id`

</details>
:::

## Table Join

@@ -61,10 +60,7 @@ For example, `X={a,b}` `Y={1,2}` then the Cartesian product of X and Y is

::: info Sample Table

<details>
<summary>Sample Table</summary>

### Sample Table
::: details Sample Table

The following queries are all around this sample table:

@@ -96,8 +92,6 @@ The following queries are all around this sample table:
| 12 | Justin Rogers | 13 | 8 |


</details>

:::

::: warning
@@ -118,8 +112,7 @@ select * from a join b;
select * from a inner join b;
```

<details>
<summary>Example</summary>
::: details Example

```sql
select * from student s inner join course c on s.course_id=c.id;
@@ -139,7 +132,7 @@ Result

**You can see that only the data columns that satisfy `s.course_id=c.id` are returned**

</details>
:::

### Outer Join

82 changes: 36 additions & 46 deletions src/en/guide/interview/golang/basic/1-basic.md
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ title: "Basic"
## Pointer

### What is a pointer and a pointer variable?
<details> <summary>Click to expand</summary>
::: details Answer
Ordinary variables store data, while pointer variables store the address of the data.

- Learning about pointers mainly involves two operators `&` and `*`.
@@ -28,10 +28,10 @@ fmt.Println(ptr) //output: for example: 0xc000086020
tamp := *ptr
fmt.Println(tamp) //output: 99
```
</details>
:::

### Why use pointers?
<details> <summary>Click to expand</summary>
::: details Answer

**Significance One: Easy Coding**

@@ -45,12 +45,11 @@ Pointers can pass references of data between functions, instead of copying the e
Pointers can directly access and modify data in memory. Through pointers, we can dynamically allocate memory at runtime to meet the needs of the program, and release memory when it is not needed, avoiding memory leaks.

Pointers can dynamically allocate memory during program execution. Through dynamic memory allocation, we can allocate and release memory as needed, thereby improving the flexibility and efficiency of the program.
</details>
:::

### Which objects can be addressed and which cannot?

<details>
<summary>Click to expand</summary>
::: details Answer

The following objects can be addressed using `&` to obtain their memory addresses:

@@ -69,12 +68,12 @@ The following objects cannot be addressed:
- Non-pointer elements of maps
- Array literals

</details>
:::

## Literal

### What does literal mean?
<details> <summary>Click to expand</summary>
::: details Answer
- The text of these basic type values below is a basic type literal.

| Basic Type | Collection |
@@ -100,10 +99,10 @@ n := 10 // 10 is the literal value
```
"hello,world" "123"
```
</details>
:::

### Can different literals have the same value?
<details> <summary>Click to expand</summary>
::: details Answer

- A value can be represented by multiple literals. For example, the decimal value 21 can be represented by three different literals

@@ -120,10 +119,10 @@ func main() {
fmt.Println(21 == 0b0001 0101)
}// The result of the run shows that they are equal
```
</details>
:::

### What is the difference between a literal and a variable?
<details> <summary>Click to expand</summary>
::: details Answer

- A literal is an unnamed constant, just like a constant, it is not addressable.

@@ -154,10 +153,10 @@ func main() {
fmt.Println(&t)
}
```
</details>
:::

### What is a composite literal?
<details> <summary>Click to expand</summary>
::: details Answer

- A composite literal is a way to define and initialize an object together. In other words, a composite literal is used to construct values for structures, arrays, slices, and maps, and each time a new value is created. They are followed by the type of the literal, curly braces, and a list of elements. Each element can optionally be preceded by a related key.

@@ -214,12 +213,12 @@ colours := [3]string{"black", "red", "white"}
s := []string{"red", "black"}
// The capacity and length of the slice will be automatically filled in
```
</details>
:::


## Others
### What is the difference between `rune` and `byte` in Go?
<details> <summary>Click to expand</summary>
::: details Answer

In Go language, `byte` and `rune` are both types used to represent characters, but there are some differences between them:

@@ -249,12 +248,12 @@ fmt.Printf("a occupies %d bytes\nb occupies %d bytes", unsafe.Sizeof(a), unsafe.
#### Different character ranges represented:
Since the value that the byte type can represent is limited, there are only 2^8=256. So if you want to represent Chinese, you can only use the rune type.

</details>
:::

Here is the English translation of your text:

### What are deep copy and shallow copy in golang?
<details> <summary>Click to expand</summary>
::: details Answer

- What is copying?

@@ -330,12 +329,11 @@ func main() {
[7 8 9]
```

</details>
:::

### What's the difference between `make` and `new`?

<details>
<summary>Click to expand</summary>
::: details Answer

`new` is used to allocate memory for any type and return a pointer to that type, initializing the value to zero.

@@ -373,23 +371,21 @@ func main() {
}
```

</details>
:::

### What's the difference between arrays and slices?

<details>
<summary>Click to expand</summary>
::: details Answer

- The length of an array is fixed, determined at creation, and cannot be changed. The length of a slice is dynamic and will automatically expand based on the data added.
- When passing parameters in functions, data is passed by value, while slices are passed by reference.
- Slices have a capacity (capacity) parameter, arrays do not.

</details>
:::

### If `for range` adds data at the same time, will `for range` execute indefinitely?

<details>
<summary>Click to expand</summary>
::: details Answer

No, when executing `for range`, what is actually traversed is a copy of the variable, so changing the traversed variable will not have an impact.

@@ -409,12 +405,11 @@ func main() {
}
```

</details>
:::

### What is the execution order of multiple defers?

<details>
<summary>Click to expand</summary>
::: details Answer

The execution order is similar to a stack, first in, last out.

@@ -444,12 +439,11 @@ func main() {

```

</details>
:::

### What is data overflow?

<details>
<summary>Click to expand</summary>
::: details Answer

When using numeric types, if the data reaches the maximum value, the next data will overflow, such as `uint` will start from 0 after overflow, `int` will become negative after overflow.

@@ -478,12 +472,11 @@ How to avoid?
- Use uint for positive numbers first, the range is larger
- Add judgment code to determine whether it overflows

</details>
:::

### Should function parameters use value or pointer?

<details>
<summary>Click to expand</summary>
::: details Answer

- Value transfer

@@ -493,15 +486,14 @@ Generally speaking, value transfer can be used for common types. The advantage o

The advantage of using pointer transfer is that it directly transfers the address of the variable, without the need for extra space. The disadvantage is that data modification during concurrent operations will affect the original data. Passing in a slice is actually passing the pointer of the slice to avoid repeated copying. If an array is passed in, it is value transfer, and a copy will be made.

</details>
:::


## Map

### Can an uninitialized Map read a key?

<details>
<summary>Click to expand</summary>
::: details Answer

Yes, an uninitialized `map` that hasn't undergone `make` initialization will return the zero value of the current type for any `key` read.

@@ -519,12 +511,11 @@ func main() {
// Output:
// 0
```
</details>
:::

### What happens if you assign a value to an uninitialized Map?

<details>
<summary>Click to expand</summary>
::: details Answer

It will trigger a `panic` exception error.

@@ -541,12 +532,11 @@ func main() {
// panic: assignment to entry in nil map
```

</details>
:::

### What happens if you delete a key from an uninitialized Map?

<details>
<summary>Click to expand</summary>
::: details Answer

In earlier versions, performing a `delete` operation on an uninitialized `map` would throw a `panic` error. In current versions, performing a `delete` operation on an uninitialized `map` will not cause an error.

@@ -563,4 +553,4 @@ func main() {
//
```

</details>
:::
25 changes: 10 additions & 15 deletions src/en/guide/interview/golang/basic/2-medium.md
Original file line number Diff line number Diff line change
@@ -5,42 +5,38 @@ title: "Medium"

### Have you used `context`? What are the use cases for `context`?

<details>
<summary>Click to expand</summary>
::: details Answer

| Scenario | Introduction |
| ------------------- | ------------------------------------------------------------------------------------------------------------------ |
| Timeout handling | By using `context`, you can easily set a timeout, and the coroutine will automatically terminate after the timeout |
| Terminate coroutine | By using the `cancel()` method, coroutines can be easily terminated |
| Data transfer | We can write data into `context` to transfer data between different coroutines |

</details>
:::

### Is `channel` thread-safe?

<details>
<summary>Click to expand</summary>
::: details Answer

`channel` is thread-safe, the reason is that `channel` has implemented a lock mechanism internally,

</details>
:::


### Is the traversal of a Map using range ordered or unordered?

<details>
<summary>Click to expand</summary>
::: details Answer

**Unordered**

Internally, Map uses a hash algorithm to place elements. When it automatically expands, it recalculates the hash values, so the addresses of the elements keep changing. To prevent users from thinking that the arrangement of Map elements is ordered, it directly returns in a random order, so the traversal is unordered.

</details>
:::

### Is Map concurrency-safe?

<details>
<summary>Click to expand</summary>
::: details Answer

**Map cannot guarantee concurrency safety**

@@ -49,12 +45,11 @@ To ensure concurrency safety, use the following methods:
- Manually add read-write locks
- Use `sync.Map`

</details>
:::

### Will the memory of a key be released after the key is deleted from the Map?

<details>
<summary>Click to expand</summary>
::: details Answer

If the value of the map is

@@ -70,4 +65,4 @@ If the value of the map is
[Code combat analysis](https://articles.zsxq.com/id_4w1a11i6xrw0.html)
:::

</details>
:::
17 changes: 5 additions & 12 deletions src/guide/concepts/database/1-database-basic.md
Original file line number Diff line number Diff line change
@@ -21,8 +21,7 @@ title: "数据库基础"
- 主键不能为空,唯一键可以为空
:::

<details>
<summary>例子</summary>
::: details 例子

假设有两张表

@@ -39,7 +38,7 @@ title: "数据库基础"
- 候选键: 以 `student` 表为例: `student.id` `student.identify_card`
- 外键: `student.teacher_id`

</details>
:::

## 表连接

@@ -63,10 +62,7 @@ title: "数据库基础"

::: info 示例表

<details>
<summary>示例表</summary>

### 示例表
::: details 示例表

接下来的查询都是围绕该示例表

@@ -98,8 +94,6 @@ title: "数据库基础"
| 12 | Justin Rogers | 13 | 8 |


</details>

:::

::: warning
@@ -120,8 +114,7 @@ select * from a join b;
select * from a inner join b;
```

<details>
<summary>例子</summary>
::: details 例子

```sql
select * from student s inner join course c on s.course_id=c.id;
@@ -141,7 +134,7 @@ select * from student s inner join course c on s.course_id=c.id;

**可以看到只有满足 `s.course_id=c.id` 的数据列被返回了**

</details>
:::

### 外连接 (outer join)

86 changes: 38 additions & 48 deletions src/guide/interview/golang/basic/1-basic.md
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ title: "基础"
## 指针

### 什么是指针和指针变量?
<details> <summary>展开查看</summary>
::: details 答案
普通变量存储数据,而指针变量存储的是数据的地址。

- 学习指针,主要有两个运算符号`&``*`
@@ -24,10 +24,10 @@ fmt.Println(ptr) //输出: 例如:0xc000086020
tamp := *ptr
fmt.Println(tamp) //输出: 99
```
</details>
:::

### 为什么使用指针?
<details> <summary>展开查看</summary>
::: details 答案

**意义一:容易编码**

@@ -41,12 +41,11 @@ fmt.Println(tamp) //输出: 99
指针可直接访问和修改内存中的数据,通过指针,我们可以在运行时动态地分配内存,以满足程序的需求,并在不需要时释放内存,避免内存泄漏。

指针可在程序运行时动态地分配内存。通过动态内存分配,我们可以根据需要分配和释放内存,从而提高程序的灵活性和效率。
</details>
:::

### 哪些对象可以获取地址,哪些不行?

<details>
<summary>展开查看</summary>
::: details 答案

可以使用 `&` 获取内存地址的对象:

@@ -65,13 +64,13 @@ fmt.Println(tamp) //输出: 99
- map 非指针元素
- 数组字面量

</details>
:::


## 字面量

### 字面量是什么意思?
<details> <summary>展开查看</summary>
::: details 答案

- 下面这些基本类型赋值的文本,就是基本类型字面量。

@@ -95,10 +94,10 @@ n := 10 // 10 就是字面量
```
"hello,world" "123"
```
</details>
:::

### 什么是有类型常量和无类型常量?
<details> <summary>展开查看</summary>
::: details 答案

- Golang 中,常量分为有类型常量和无类型常量。

@@ -154,10 +153,10 @@ func main() {
//出错: cannot use A (type int8) as type int16 in assignment
}
```
</details>
:::

### 不同字面量可能同值吗?
<details> <summary>展开查看</summary>
::: details 答案

- 一个值可存在多种字面量表示,如下十进制的数值 21,可由三种字面量表示

@@ -174,10 +173,10 @@ func main() {
fmt.Println(21 == 0b0001 0101)
}// 由运行结果得出他们相等
```
</details>
:::

### 字面量和变量的区别是什么?
<details> <summary>展开查看</summary>
::: details 答案

- 字面量,就是未命名的常量,跟常量一样,是不可寻址的。

@@ -208,10 +207,10 @@ func main() {
fmt.Println(&t)
}
```
</details>
:::

### 什么是组合字面量?
<details> <summary>展开查看</summary>
::: details 答案

- 组合字面量就是把对象的定义和初始化放在了一起,进一步说,组合字面量是为结构体、数组、切片和map构造值,并且每次都会创建新值。它们由字面量的类型后紧跟大括号及元素列表。每个元素前面可以选择性的带一个相关key。

@@ -269,12 +268,12 @@ colours := [3]string{"black", "red", "white"}
s := []string{"red", "black"}
//会自动补上切片的容量和长度
```
</details>
:::


## 其他
### Go 中的 `rune``byte` 有什么区别?
<details> <summary>展开查看</summary>
::: details 答案

在 Go 语言中,`byte``rune` 都是用于表示字符的类型,但它们之间有一些区别:

@@ -304,11 +303,11 @@ fmt.Printf("a 占用 %d 个字节数\nb 占用 %d 个字节数", unsafe.Sizeof(a
#### 表示的字符范围不同:
由于 byte 类型能表示的值是有限的,只有 2^8=256 个。所以想表示中文只能使用 rune 类型。

</details>
:::


### Golang中的深拷贝和浅拷贝是什么?
<details> <summary>展开查看</summary>
::: details 答案

- 什么是拷贝?

@@ -385,13 +384,12 @@ func main() {
[7 8 9]
```

</details>
:::


### `make``new` 有什么区别?

<details>
<summary>展开查看</summary>
::: details 答案

`new` 用于给任意的类型分配内存地址,并返回该类型的指针,且初始化值为零值。

@@ -429,23 +427,21 @@ func main() {
}
```

</details>
:::

### 数组和切片有什么区别?

<details>
<summary>展开查看</summary>
::: details 答案

- 数组的长度是固定的,在创建的时候就已经确定,且不可改变。切片的长度是动态的,会根据添加的数据自动扩容。
- 在函数参数传递时数据是值传递,切片是引用传递
- 切片有容量 (capacity) 参数,数组没有

</details>
:::

### 如果 `for range` 同时添加数据, `for range` 会无限执行吗?

<details>
<summary>展开查看</summary>
::: details 答案

不会,在执行 `for range` 的时候实际遍历的是变量的副本,所以改变遍历的变量是不会有影响的

@@ -465,12 +461,11 @@ func main() {
}
```

</details>
:::

### 多个 defer 的执行顺序是什么?

<details>
<summary>展开查看</summary>
::: details 答案

执行的顺序类似堆栈,先进后出

@@ -500,12 +495,11 @@ func main() {

```

</details>
:::

### 什么是数据溢出?

<details>
<summary>展开查看</summary>
::: details 答案

在使用数字类型时如果数据达到最大值,则接下来的数据将会溢出,如 `uint` 溢出后会从 0 开始, `int` 溢出后会变为负数。

@@ -534,12 +528,11 @@ func main() {
- 正数优先使用 uint, 范围更大
- 添加判断代码判断是否溢出

</details>
:::

### 函数参数使用值还是指针?

<details>
<summary>展开查看</summary>
::: details 答案

- 值传递

@@ -549,14 +542,13 @@ func main() {

使用指针传递的好处是直接传递变量的地址,不需要额外的空间,缺点是并发操作时数据修改会影响到原始的数据。传入切片实际上就是传递切片的指针,避免重复拷贝,若传入数组则是值传递,会拷贝一份。

</details>
:::

## Map

### 未初始化的 Map 可以读取 key 吗?

<details>
<summary>展开查看</summary>
::: details 答案

可以的,未执行 `make` 初始化的 `map` 读取任何 `key` 都会返回当前类型的空值

@@ -574,12 +566,11 @@ func main() {
// 结果:
// 0
```
</details>
:::

### 如果对未初始化的 Map 赋值会怎么样?

<details>
<summary>展开查看</summary>
::: details 答案

会触发 `panic` 异常错误

@@ -596,12 +587,11 @@ func main() {
// panic: assignment to entry in nil map
```

</details>
:::

### 如果对未初始化的 Map 进行删除 key 的操作会发生什么?

<details>
<summary>展开查看</summary>
::: details 答案

早期如果对未初始化的 `map` 进行 `delete` 操作会报 `panic` 错误, 现在的版本对于未初始化的 `map` 进行 `delete` 是不会报错的。

@@ -618,4 +608,4 @@ func main() {
//
```

</details>
:::
25 changes: 10 additions & 15 deletions src/guide/interview/golang/basic/2-medium.md
Original file line number Diff line number Diff line change
@@ -5,8 +5,7 @@ title: "进阶"

### 使用过 `context` 吗? `context` 有哪些使用场景?

<details>
<summary>展开查看</summary>
::: details 答案

| 场景 | 介绍 |
| -------- | --------------------------------------------------------------- |
@@ -15,32 +14,29 @@ title: "进阶"
| 传递数据 | 我们可以将数据写入 `context`, 在不同协程间传递数据 |


</details>
:::

### channel 是线程安全的吗?

<details>
<summary>展开查看</summary>
::: details 答案

`channel` 是线程安全的,原因是 channel 内部实现了锁的机制,

</details>
:::

### Map 使用 range 遍历时是有序还是无序的?

<details>
<summary>展开查看</summary>
::: details 答案

**无序的**

Map 在内部使用哈希算法放置元素,在自动扩容时又会重新计算哈希值,因此元素的地址会不断变化,官方为了避免用户认为 Map 元素排列是有序的,直接采用随机顺序返回,所以遍历是无序的。

</details>
:::

### Map 并发安全吗?

<details>
<summary>展开查看</summary>
::: details 答案

**Map不能保证并发安全**

@@ -49,12 +45,11 @@ Map 在内部使用哈希算法放置元素,在自动扩容时又会重新计
- 手动加读写锁
- 使用 `sync.Map`

</details>
:::

### Map 的 key 删除后 key 的内存会被释放吗?

<details>
<summary>展开查看</summary>
::: details 答案

若 map 的 value 为

@@ -70,4 +65,4 @@ Map 在内部使用哈希算法放置元素,在自动扩容时又会重新计
[代码实战解析](https://articles.zsxq.com/id_4w1a11i6xrw0.html)
:::

</details>
:::

0 comments on commit f1170a9

Please sign in to comment.