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

17 KiB
Raw Permalink Blame History

tags, create time
tags create time
Go
考试
Week01
武科大服务端
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 闭包捕获的是命名返回值的引用。执行流程:

  1. return 2 先将 r 赋值为 2
  2. defer 函数执行,r += 1 → r 变为 3
  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] 下划线 _ 的多重用途

  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 配合模式

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 = "" — 包级别变量声明,带初始值

关联笔记