This repository has been archived on 2026-05-24. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
2026-05-15 16:26:14 +08:00

679 lines
17 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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]]