Files
cs-note/hhs/EXAM/Week01.md
T

679 lines
17 KiB
Markdown
Raw Normal View History

2026-05-24 11:42:38 +08:00
---
tags: [Go, 考试, Week01, 武科大服务端]
create time: 2026-05-14 12:00
---
# 金山考试 - 武科大服务端-第一次课
## 概述
本次考试覆盖 Go 语言基础核心知识点,包括 Git 版本控制基础、字符编码、变量声明、流程控制(`if` / `for` / `switch`)、函数与 `defer`、`panic` / `recover` 错误处理、字符串不可变性等。适合用于检验 Go 入门学习成果。
**知识点地图:**
```mermaid
graph LR
A[Go 语言基础] --> B[Git 基础]
A --> C[字符编码 Unicode / UTF-8]
A --> D[变量与类型 rune / string]
A --> E[流程控制 if for switch]
A --> F[函数 init / defer]
A --> G[错误处理 panic recover]
A --> H[包管理 go mod]
```
## 正文
### 一、单选题
#### 1. Git 查看状态命令
【单选题】在 Git 中,如何查看当前状态的最简命令是什么?(5分)
A. `git log`
B. `git status`
C. `git diff`
D. `git commit`
**正确答案:**B
**作答答案:**B
---
#### 2. Go 注释方式
【单选题】在Go语言中,以下哪种注释方式是正确的?(5分)
Go 语言支持 `//` 形式的单行注释和 `/* */` 形式的多行注释。
A. `// 这是单行注释`
B. `/* 这是多行注释 */`
C. `# 这是单行注释`
D. A和B都正确
**正确答案:**D
**作答答案:**D
> [!tip] 注意
> Go 不像 Python 或 Shell 脚本使用 `#` 做注释。这是很多初学者容易混淆的地方。
---
#### 3. 函数可见性(Export)
【单选题】在Go语言中,如果一个函数需要被外部包访问,函数名应该如何书写?(5分)
A. 首字母小写并使用 public 关键字
B. 首字母大写
C. 完全小写
D. 使用 func 关键字作为前缀
**正确答案:**B
**作答答案:**B
> [!info] Go 没有 public / private 关键字
> Go 的包可见性遵循简单规则:**首字母大写 = 导出(公共),首字母小写 = 不导出(私有)**。同样适用于变量、常量、类型等。
---
#### 4. UTF-8 英文字符字节数
【单选题】在UTF-8编码中,一个英文字符通常占用多少字节?(5分)
A. 1字节
B. 2字节
C. 3字节
D. 4字节
**正确答案:**A
**作答答案:**A
---
#### 5. Unicode 与 UTF-8 的关系
【单选题】Unicode和UTF-8之间的关系是什么?(5分)
A. Unicode是一种字符集,UTF-8是Unicode的一种编码方式
B. Unicode和UTF-8都是编程语言
C. UTF-8是一种字符集,Unicode是UTF-8的一种编码方式
D. 没有任何关系
**正确答案:**A
**作答答案:**C
> [!warning] 易错题 — Unicode vs UTF-8
> - **Unicode**:字符集(Character Set),为每个字符分配唯一编号(码点 Code Point),如 `U+0041` → 'A'
> - **UTF-8**:编码方案(Encoding Scheme),将码点转换成字节序列存储
> - 三者常见关系:Unicode(字符集)→ UTF-8 / UTF-16 / UTF-32(编码方式)
**对比表:**
| 概念 | 类比 | 作用 |
|------|------|------|
| Unicode | 电报码本 | 给每个字符编号 |
| UTF-8 | 传输协议 | 把编号变成可传输的字节 |
---
#### 6. rune 类型用途
【单选题】在Go语言中,rune类型通常用于处理什么?(5分)
A. 整型数据
B. 浮点数数据
C. Unicode字符
D. 布尔型数据
**正确答案:**C
**作答答案:**C
> [!info] rune 的本质
> `rune` 就是 `int32` 的别名,专门用于表示 Unicode 码点(字符)。在 Go 中遍历字符串时,用 `range` 循环得到的就是 `rune` 类型的单个字符。
---
#### 7. defer 与命名返回值
【单选题】下面代码能编译通过吗?可以的话,输出什么?(5分)
```go
func DeferTest2(i int) (r int) {
defer func() {
r += i
}()
return 2
}
func main() {
fmt.Println(DeferTest2(1))
}
```
A. 1
B. 2
C. 3
D. 以上都不是
**正确答案:**C
**作答答案:**C
> [!important] defer + 命名返回值陷阱
> `defer` 闭包捕获的是**命名返回值的引用**。执行流程:
> 1. `return 2` 先将 `r` 赋值为 `2`
> 2. `defer` 函数执行,`r += 1` → `r` 变为 `3`
> 3. 函数返回 `r = 3`
>
> **关键记忆:有命名返回值时,defer 修改它会影响最终返回值。**
```mermaid
sequenceDiagram
participant Main as main
participant Func as DeferTest2(1)
participant Defer as defer closure
Main->>Func: 调用 DeferTest2(1)
Func->>Func: return 2 → r = 2
Func->>Defer: 执行 defer: r += 1
Defer-->>Func: r = 3
Func-->>Main: 返回 3
```
---
#### 8. fallthrough 语义
【单选题】下面代码输出什么?(5分)
```go
func main() {
isMatch := func(i int) bool {
switch(i) {
case 1:
fallthrough
case 2:
return true
}
return false
}
fmt.Println(isMatch(1))
fmt.Println(isMatch(2))
}
```
A. `false true`
B. `true true`
C. `false false`
D. `true false`
**正确答案:**B
**作答答案:**B
> [!tip] fallthrough 的执行逻辑
> - `case 1:` 后跟 `fallthrough` → 跳过 case 1 剩余代码,直接进入 case 2 并执行
> - case 2 中有 `return true` → 所以传入 1 也返回 true
> - 传入 2 → 直接命中 case 2 → 返回 true
> - 因此两次输出均为 `true`
```mermaid
flowchart TD
i[输入值 i] --> check1{i == 1?}
check1 -->|是| fall[falsthrough<br/>进入 case 2]
check1 -->|否| check2{i == 2?}
check2 -->|是| retTrue[return true]
fall --> retTrue
check2 -->|否| retFalse[return false]
retTrue --> OUT1[输出: true]
retFalse --> OUT2[输出: false]
```
---
#### 9. 字符串不可变性
【单选题】下面代码输出什么?(5分)
```go
func main() {
str := "hello"
str[0] = 'x'
fmt.Println(str)
}
```
A. hello
B. xello
C. compilation error
D. 其他
**正确答案:**C
**作答答案:**C
> [!warning] Go 字符串是只读的!
> Go 中的 `string` 是不可变的(immutable),不能像切片那样通过索引赋值修改。如果需要修改字符串,应转为 `[]byte` 或 `[]rune`:
>
> ```go
> b := []byte("hello")
> b[0] = 'x'
> fmt.Println(string(b)) // 输出: xello
> ```
---
#### 10. Go 包管理工具
【单选题】Go语言包管理工具是哪个?(5分)
A. dep
B. go mod
C. glide
D. gopkg
**正确答案:**B
**作答答案:**B
> [!info] Go 包管理演进
> - **dep**:早期官方实验性工具(已废弃)
> - **glide**:社区流行但不再维护
> - **go mod**:Go 1.11+ 引入,Go 1.16+ 成为默认标准
> - **gopkg.in**:第三方包分发服务,非官方工具
---
#### 11. break 跳出循环
【单选题】在 Go 语言中,以下哪个关键字用于跳出当前的 for 循环?( )(5分)
A. `break`
B. `continue`
C. `return`
D. `goto`
**正确答案:**A
**作答答案:**A
---
#### 12. 创建 Go Module
【单选题】在Go语言中,如何创建一个新的module?(5分)
A. 使用 `go create` 命令
B. 使用 `go mod init` 命令
C. 使用 `go new` 命令
D. 直接创建一个新文件夹
**正确答案:**B
**作答答案:**B
---
#### 13. 全局变量声明
【单选题】在Go中全局声明和初始化一个名为"counter"的整型变量正确的方式是?(5分)
A. `var counter = int(0)`
B. `var counter int = 0`
C. `int counter = 0`
D. `counter := 0`
**正确答案:**B
**作答答案:**B
> [!info] var 声明 vs 短变量声明
> - 选项 D `counter := 0` 是短变量声明,只能在**函数内部**使用,不能在包级别(全局)使用
> - 选项 B `var counter int = 0` 在全局和局部均可使用
> - 实际开发中常用简化写法:`var counter = 0`(省略类型,自动推断)
---
#### 14. 短变量声明
【单选题】以下哪种是 Go 语言的短变量声明方式?(5分)
A. `var x = 5`
B. `x := 5`
C. `x int = 5`
D. `let x = 5`
**正确答案:**B
**作答答案:**B
---
#### 15. init 函数参数
【单选题】Go语言中的init函数可以接受参数吗?(5分)
A. 可以,可以接受任意类型的参数
B. 可以,但只能接受同一个包内的类型为参数
C. 不可以,init函数不能有参数,也不能定义返回值
D. 可以,但只能接受基本类型的参数
**正确答案:**C
**作答答案:**C
---
#### 16. 下划线 _ 的作用
【单选题】在 Go 语言中,以下关于下划线的作用描述正确的是?( )(5分)
A. 作为变量名,用于存储无用的值
B. 表示私有变量
C. 用于注释
D. 以上都不对
**正确答案:**A
**作答答案:**A
> [!info] 下划线 _ 的多重用途
> 1. **忽略值**:`_, err := os.Open("file")` — 不需要 err
> 2. **导入包副作用**:`import _ "image/png"` — 仅注册,不使用
> 3. **空标识符**:用作占位符,避免编译器报错
---
#### 17. 转义符号
【单选题】在 Go 语言中,字符串转义使用的符号是?(5分)
A. @
B. `\`
C. `/`
D. #
**正确答案:**B
**作答答案:**B
---
#### 18. defer + recover 处理 panic
【单选题】如何在Go中用`defer`和`recover`处理panic?(5分)
A. 在defer函数中使用panic
B. 在defer函数中调用recover进行错误恢复
C. 使用defer来抛出错误
D. defer和recover无法一起使用
**正确答案:**B
**作答答案:**B
> [!info] defer 与 recover 配合模式
> ```go
> defer func() {
> if r := recover(); r != nil {
> fmt.Println("Recovered from:", r)
> }
> }()
> ```
> - `recover()` 必须放在 `defer` 中才能捕获 panic
> - 若未发生 panic,`recover()` 返回 `nil`
---
#### 19. 引发异常的关键字
【单选题】在Go程序中,使用哪个关键字可以引发一个异常?(5分)
A. throw
B. error
C. exception
D. panic
**正确答案:**D
**作答答案:**D
---
#### 20. defer 执行顺序
【单选题】下面的Go代码块中,使用defer关键字的输出顺序是什么?(5分)
```go
package main
import "fmt"
func main() {
defer fmt.Println("First")
defer fmt.Println("Second")
defer fmt.Println("Third")
fmt.Println("Done")
}
```
A. `First Second Third Done`
B. `Done Third Second First`
C. `Third Second First Done`
D. `Done First Second Third`
**正确答案:**B
**作答答案:**B
> [!important] defer 是 LIFO(后进先出)栈
> defer 语句按照声明的**逆序**执行,类似栈的 push/pop:
> - 先 defer `First` → 最后执行 `First`
> - 再 defer `Second` → 倒数执行 `Second`
> - 最后 defer `Third` → 最先执行 `Third`
> - 正常 `fmt.Println("Done")` → 最先执行
```mermaid
stateDiagram-v2
[*] --> MainCode
MainCode --> Deferred_Fist : defer Println("First")
Deferred_Fist --> Deferred_Second : defer Println("Second")
Deferred_Second --> Deferred_Third : defer Println("Third")
Deferred_Third --> Normal_Println : Println("Done")
Normal_Println --> Third_Exec : defer 开始执行
Third_Exec --> Second_Exec : Println("Third")
Second_Exec --> First_Exec : Println("Second")
First_Exec --> Exit : Println("First")
Exit --> [*]
note right of Normal_Println
<b>输出: Done Third Second First</b>
defer 按声明逆序执行
end note
```
---
### 二、多选题
#### 1. main() 函数特性
【多选题】关于 main() 函数,下面说法正确的是?(5分)
A. 不能带参数;
B. 不能定义返回值;
C. 所在的包必须为 main 包;
D. 可以使用 flag 包来获取和解析命令行参数;
**正确答案:**ABCD
**作答答案:**ABCD
---
#### 2. switch 语句特性(一)
【多选题】关于 switch 语句,下面说法正确的是?(5分)
A. 单个 case 中,可以出现多个结果选项;
B. 需要使用 break 来明确退出一个 case;
C. 只有在 case 中明确添加 fallthrough 关键字,才会继续执行紧跟的下一个 case;
D. 条件表达式必须为常量或者整数;
**正确答案:**AC
**作答答案:**AC
> [!tip] Go switch 与 C/C++ switch 的区别
> - Go 的 case 后**隐式自带 break**,不需要手动写
> - 要穿透需显式使用 `fallthrough`
> - 条件表达式可以是任意类型(不限于整数)
---
#### 3. defer 的实际应用
【多选题】Go语言defer的实际应用场景(5分)
A. 在打开文件后立即使用defer来安排文件的关闭
B. 在数据库连接成功后使用defer来安排断开连接
C. 仅在程序的主函数中使用defer来进行错误处理
D. 使用defer来执行重要的日志记录
**正确答案:**ABD
**作答答案:**ABD
---
#### 4. bool 变量 if 判断规范
【多选题】flag 是 bool 型变量,下面 if 表达式符合编码规范的是?(5分)
A. `if flag == 1`
B. `if flag`
C. `if flag == false`
D. `if !flag`
**正确答案:**BCD
**作答答案:**C
> [!warning] 易错题
> - Go 不支持将整数隐式转为 bool,A 选项 `flag == 1` 语法上就不通(除非 flag 定义为 int)
> - Go Code Review Comments 推荐:`if condition` 而非 `if condition == true`
> - 作答选 C 可能是因为理解偏差——实际上 B 和 D 是最符合 Go 惯用法的选择
---
#### 5. 函数声明语法
【多选题】关于函数声明,下面语法正确的是?(5分)
A. `func f(a, b int) (value int, err error)`
B. `func f(a int, b int) (value int, err error)`
C. `func f(a, b int) (value int, error)`
D. `func f(a int, b int) (int, int, error)`
**正确答案:**ABD
**作答答案:**AB
> [!info] 要点解析
> - A ✅:合并相同类型的参数 `a, b int` 是合法的
> - B ✅:逐个写类型也是合法的
> - C ❌:混合了命名和无命名返回值,`error` 缺少类型名(应为 `e error`)
> - D ✅:匿名返回值是完全合法的写法
---
#### 6. 变量的自增和自减
【多选题】关于变量的自增和自减操作,下面语句正确的是?(5分)
A. `i := 1; i++`
B. `i := 1; j = i++`
C. `i := 1; ++i`
D. `i := 1; i--`
**正确答案:**AD
**作答答案:**ABD
> [!warning] Go 的独特限制
> - Go **只有** `++` 和 `--` 两个复合运算符,且它们是**语句**,不是表达式
> - 不能出现在赋值右侧:❌ `j = i++`(选项 B 错误)
> - 不支持前置形式:❌ `++i`、`--i`(选项 C 错误)
> - 只能单独使用:✅ `i++`、`i--`
---
#### 7. bool 变量赋值错误用法
【多选题】关于 bool 变量 b 的赋值,下面错误的用法是?(5分)
A. `b = true`
B. `b = 1`
C. `b = bool(1)`
D. `b = (1 == 2)`
**正确答案:**BC
**作答答案:**BC
> [!info] Go 强类型约束
> - Go 不允许整数到 bool 的隐式转换,也不允许 `bool(1)` 这种强制转换
> - `1 == 2` 本身就是 bool 类型,赋值合法(选项 D 是正确的写法)
---
#### 8. switch 语句特性(二)
【多选题】关于switch语句,下面说法正确的有?(5分)
A. 条件表达式必须为常量或者整数;
B. 单个case中,可以出现多个结果选项;
C. 需要用break来明确退出一个case;
D. 只有在case中明确添加fallthrough关键字,才会继续执行紧跟的下一个case;
**正确答案:**BD
**作答答案:**BD
> [!note] 对比第 2 题
> - 本题第 D 项和第 2 题第 C 项表述略有不同——注意区分"单个 case 中多个结果选项"(`case 1, 2, 3:`)和 fallthrough 穿透是两个不同机制
> - Go switch 的 case 可以是任意类型,不限于整数
---
#### 9. 循环语句特性
【多选题】关于循环语句,下面说法正确的有(5分)
A. 循环语句既支持 for 关键字,也支持 while 和 do-while;
B. 关键字 for 的基本使用方法与 C/C++ 中没有任何差异;
C. for 循环支持 continue 和 break 来控制循环,但是它提供了一个更高级的 break,可以选择中断哪一个循环;
D. for 循环不支持以逗号为间隔的多个赋值语句,必须使用平行赋值的方式来初始化多个变量;
**正确答案:**CD
**作答答案:**ACD
> [!info] Go 只有 for 一种循环
> ```go
> // 经典三要素
> for i := 0; i < 10; i++ {}
> // while 风格
> for condition {}
> // 无限循环
> for {}
> ```
> - Go **没有** while 和 do-while(选项 A 错)
> - Go 的 for 比 C/C++ 简化了许多场景(选项 B 错)
> - 多变量需平行赋值:`for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {}`(选项 D 对)
---
#### 10. 全局字符串变量声明
【多选题】定义一个包内全局字符串变量,下面语法正确的是()(5分)
A. `var str string`
B. `str:=""`
C. `str=""`
D. `var str=""`
**正确答案:**AD
**作答答案:**AD
> [!info] 全局 vs 局部
> - A ✅:`var str string` — 包级别变量声明,零值为 `""`
> - B ❌:`:=` 只在函数体内可用
> - C ❌:包级别不能用简单赋值
> - D ✅:`var str = ""` — 包级别变量声明,带初始值
---
## 关联笔记
- [[hhs/EXAM/Week05]]
- [[hhs/EXAM/Week06]]
- [[Go/基础语法/变量与类型]]
- [[Go/基础语法/流程控制]]
- [[Go/基础语法/函数]]
- [[Go/进阶/defer与panic]]