Skip to content

第01章 面试题精选 —— Go 入门篇

面试官最爱在简历开头问"你为什么选 Go?"——这一章的题目就是为你准备好的标准答案。


★ 基础题(必会)

Q1:为什么 Go 适合做后端服务?

参考答案:

  1. 性能高:Go 是编译型语言,编译为机器码直接运行,性能接近 C/C++,比 Python 快 10-100 倍
  2. 并发模型先进:goroutine 比线程轻量,1MB 内存可以开几千个 goroutine,能轻松支撑高并发
  3. 部署简单:单个二进制文件,没有依赖,特别适合容器化部署
  4. 标准库强:自带 HTTP 服务器、JSON、加密、模板,开箱即用
  5. 工程化好:go fmt 统一风格,go test 内置测试,工具链完整

💡 加分项:举一两个实际例子,比如"我了解到字节、滴滴的核心服务大量使用 Go"。


Q2:Go 和 Java 比有什么优劣?

参考答案:

维度GoJava
启动速度毫秒级秒级(JVM 预热)
内存占用小(无 JVM)大(JVM 自身占几百 MB)
部署单文件二进制JAR + JRE
并发goroutine + channel(轻量)线程 + 锁(重量)
生态较年轻,云原生强老牌,企业级框架多
学习曲线平缓陡峭(Spring 全家桶)
泛型1.18 才支持一直有

结论:Go 更适合云原生、微服务、网关、CLI;Java 更适合大型企业系统、银行核心、复杂业务建模。


Q3:一个最简单的 Go 程序长什么样?说说每一行的作用。

参考答案:

go
package main          // 声明本文件属于 main 包;可执行程序入口包必须叫 main
import "fmt"          // 导入 fmt 标准库(格式化输入输出)
func main() {         // main 函数是程序入口,无参数无返回值
    fmt.Println("hi") // 调用 fmt 包的 Println 函数,自动加换行
}                     // 函数结束

关键考点

  • main 包是入口包
  • 一个程序必须有且仅有一个 func main()
  • 大括号 { 必须紧跟在函数行末,不能换行写(编译器会自动加分号)
  • Go 没有写分号的习惯,但词法层面是有分号的

Q4:go rungo build 有什么区别?

参考答案:

命令行为留下产物场景
go run编译到临时目录 → 立即执行不留开发调试
go build编译到当前目录 → 不执行留二进制发布部署
go install编译 → 装到 $GOPATH/bin留在全局 bin全局命令

实操延伸go run 实际上等于 go build 到一个临时目录然后执行,所以多文件项目用 go run *.gogo run .


★★ 进阶题

Q5:什么是 GOROOT、GOPATH、GOPROXY?

参考答案:

  • GOROOT:Go 的安装目录(标准库所在地),通常不需要手动改
  • GOPATH:早期的工作空间,Go Module 出来之前所有代码都得放这里。现在主要用于存放 go install 的全局命令
  • GOPROXY:模块代理服务器,国内推荐设为 https://goproxy.cn,direct
bash
go env -w GOPROXY=https://goproxy.cn,direct
go env -w GOSUMDB=off    # 关闭校验(仅企业内网时)
go env -w GOPRIVATE=*.example.com   # 私有仓库不走代理

💡 2018 年 Go 1.11 引入 Go Module 后,项目位置就不再受限于 GOPATH 了。


Q6:Go 源码到可执行文件经历了哪些阶段?

参考答案:

源代码 .go
   ↓ 词法分析
   ↓ 语法分析  →  AST(抽象语法树)
   ↓ 类型检查
   ↓ SSA 中间代码
   ↓ 机器码生成 + 链接

可执行二进制(包含运行时 runtime)

关键点

  1. Go 是静态链接的——所有依赖(包括 runtime、GC、调度器)都打包到一个二进制里
  2. 编译速度极快,因为:①依赖分析简单 ②没有头文件 ③并行编译
  3. 编译出来的二进制可以跨平台GOOS=linux GOARCH=amd64 go build 就能在 Mac 上编译出 Linux 版

Q7:Go 的二进制为什么比 C 大很多?

参考答案:

一个 Hello World 的 Go 二进制文件大约 2MB,而 C 写的只有几十 KB。原因:

  1. Go 二进制内嵌了 runtime:包含 GC、协程调度器、反射、内存分配器
  2. 默认是静态链接:标准库的代码全部打包进来
  3. 包含了类型元信息:用于反射和 GC

优化方法

bash
# 去掉调试信息和符号表,能减小约 30%
go build -ldflags="-s -w" hello.go

# 进一步用 upx 压缩(大约能再减小 60%)
upx --best hello

Q8:Go 适合做哪些场景,不适合做哪些?

适合 ✅:

  • 后端服务、API 网关、微服务
  • 云原生中间件(K8s、Docker、etcd 都是 Go 写的)
  • CLI 工具(kubectl、terraform、gh)
  • 网络代理、消息队列
  • 区块链、底层基础设施

不太适合 ❌:

  • 桌面 GUI 应用(生态弱)
  • 移动开发(有 gomobile 但生态少)
  • 强 CPU 密集计算(不如 C/Rust)
  • 富 AI/ML 应用(Python 生态完胜)
  • 复杂的领域驱动设计(DDD)(Java/C# 更顺手)

★★★ 深度题

Q9:你了解 Go 的设计哲学吗?说说你的理解。

参考答案:

  1. "Less is More"(少即是多)

    • 关键字只有 25 个(vs Java 的 50+,C++ 的 80+)
    • 一种问题只推荐一种解法(vs Python 的 "There should be one obvious way")
  2. "Composition over Inheritance"(组合优于继承)

    • 没有 class、没有继承,只有 struct 嵌入
    • 接口隐式实现(duck typing),降低耦合
  3. "Don't communicate by sharing memory; share memory by communicating"

    • 推荐用 channel 传递数据,而不是共享变量+加锁
    • 这是 CSP(Communicating Sequential Processes)模型
  4. "Errors are values"

    • 错误是普通的值(error 接口),不是异常
    • 强制显式处理,不允许"忽略"
  5. 工程化优先

    • 强制 gofmt 格式化(消灭代码风格争论)
    • 内置 go testgo vetgo race detector
    • 编译速度优先于功能丰富度

Q10:Go 1.x 版本里有什么需要关注的里程碑?

参考答案(截至 2024):

版本时间关键特性
1.02012首个稳定版,定下兼容承诺
1.52015自举(Go 编译器用 Go 写)
1.112018Go Module(颠覆性)
1.132019error wrapping (%werrors.Is/As)
1.142020goroutine 异步抢占式调度
1.182022泛型(10 年来最大特性)
1.212023min/max/clear 内置函数、slog
1.222024for-range 循环变量重新声明、net/http 路由模式

💡 简历提示:写"熟悉 Go 1.21+ 新特性"会比"熟悉 Go"更专业。


📌 速记口诀

"包定 main,引入用 import,函数 main 启动;编译型,gc 自动管,并发用 goroutine"

记住这一句,回答前 4 道基础题没问题。


🎯 自测练习

  1. 不查资料,写出 Hello World 全部代码
  2. 解释 func main() 中的 func 是不是关键字
  3. 用一句话告诉别人 Go 的"杀手锏"是什么
  4. 装一遍 Go 环境,跑通 examples 里 3 个程序
  5. 把你电脑上的 hello 程序用 GOOS=linux go build 编译出 Linux 版本试试

完成 5 项就可以放心进入第02章了 🚀