17 KiB
tags, create time
| tags | create time | ||||
|---|---|---|---|---|---|
|
2026-05-14 12:00 |
金山考试 - 武科大服务端-第一次课
概述
本次考试覆盖 Go 语言基础核心知识点,包括 Git 版本控制基础、字符编码、变量声明、流程控制(if / for / switch)、函数与 defer、panic / recover 错误处理、字符串不可变性等。适合用于检验 Go 入门学习成果。
知识点地图:
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分)
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闭包捕获的是命名返回值的引用。执行流程:
return 2先将r赋值为2defer函数执行,r += 1→r变为3- 函数返回
r = 3关键记忆:有命名返回值时,defer 修改它会影响最终返回值。
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分)
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
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分)
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: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] 下划线 _ 的多重用途
- 忽略值:
_, err := os.Open("file")— 不需要 err- 导入包副作用:
import _ "image/png"— 仅注册,不使用- 空标识符:用作占位符,避免编译器报错
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 配合模式
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分)
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")→ 最先执行
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 一种循环
// 经典三要素 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 = ""— 包级别变量声明,带初始值