Files
examination/topics/networking/go-build-strip/fill_blank.json
T
wonder df63692a18
Deploy Examination / deploy (push) Successful in 31s
feat: add 180 questions (90 sc + 90 fb) for networking subtopics
Cover 9 subtopics from the computer networking documentation:
- http-handshake: TCP/TLS/HTTP2/HTTP3 handshakes
- http-connection-cost: connection resource overhead & million concurrency
- connection-pooling: pool reuse, HTTP/1.1 vs HTTP/2
- http-keepalive: Keep-Alive principle, head-of-line blocking
- keepalive-scenarios: when to enable/disable Keep-Alive
- domain-sharding: HTTP/1.1 hack, HTTP/2 obsolescence
- cdn: edge nodes, caching, DDoS protection
- cors: same-origin policy, preflight requests
- go-build-strip: -s -w flags, binary size optimization
2026-09-02 21:33:09 +08:00

200 lines
8.5 KiB
JSON
Raw 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.
{
"topic": "go-build-strip",
"type": "fill_blank",
"schema_version": "1.0.0",
"generated": "2026-09-02T21:20:00+08:00",
"questions": [
{
"id": "fb-001",
"type": "fill_blank",
"difficulty": 2,
"tags": [
"Go",
"编译",
"符号表"
],
"question": "使用 go build -____ 命令可以剥离 Go 二进制文件中的符号表(symbol table),从而减小文件体积。",
"answer": [
"s",
"-s"
],
"answer_rule": "any",
"explanation": "-s 标志告诉 Go 链接器在生成二进制文件时不写入符号表。符号表包含了所有函数名、变量名、类型名等调试信息,生产环境中通常不需要。去掉符号表后,go tool nm 等工具将无法列出符号,二进制体积也会减小。",
"source": null,
"related": []
},
{
"id": "fb-002",
"type": "fill_blank",
"difficulty": 2,
"tags": [
"Go",
"编译",
"DWARF",
"调试信息"
],
"question": "使用 go build -____ 命令可以剥离 DWARF 调试信息,进一步减小 Go 二进制文件体积。",
"answer": [
"w",
"-w"
],
"answer_rule": "any",
"explanation": "-w 标志会去掉 DWARF(Debugging With Attributed Record Formats)调试信息。DWARF 是一种标准化的调试数据格式,包含了源码行号、局部变量、类型信息等。去掉 DWARF 后,dlv(Delve)等调试器将无法正常工作,go tool addr2line 也无法将地址翻译为行号。",
"source": null,
"related": []
},
{
"id": "fb-003",
"type": "fill_blank",
"difficulty": 3,
"tags": [
"Go",
"编译",
"体积优化"
],
"question": "生产环境构建 Go 二进制时,推荐使用 go build -s -____ 组合标志,同时剥离符号表和 DWARF 调试信息以实现体积最小化。",
"answer": [
"w"
],
"answer_rule": "all",
"explanation": "-s 和 -w 组合使用可以最大程度地减小二进制体积。-s 去掉符号表,-w 去掉 DWARF 调试信息,两者独立且互补。通常可将二进制体积减少约 20%-30%。Go 编译器支持这两个标志独立或组合使用。注意:这个组合一旦应用,后续反查行号信息将不可用。",
"source": null,
"related": []
},
{
"id": "fb-004",
"type": "fill_blank",
"difficulty": 3,
"tags": [
"Go",
"编译",
"体积优化"
],
"question": "使用 -s -w 编译标志对 Go 二进制进行体积优化,通常可以将文件大小减少约____。",
"answer": [
"20-30%",
"20%到30%",
"20%-30%"
],
"answer_rule": "any",
"explanation": "根据实际测试,-s -w 组合通常能使 Go 二进制体积减少 20%-30%。具体比例取决于原始二进制中符号表和调试信息的占比。一般来说,包含大量函数和类型的大型项目减小效果更明显。例如一个原本 20MB 的 Go 二进制,去掉后可能只有 14-16MB。",
"source": null,
"related": []
},
{
"id": "fb-005",
"type": "fill_blank",
"difficulty": 3,
"tags": [
"Go",
"panic",
"堆栈信息"
],
"question": "使用 -s -w 编译的 Go 程序在发生 panic 时,堆栈跟踪信息中只能显示____名,而无法显示完整的源码路径。",
"answer": [
"文件",
"file",
"文件名"
],
"answer_rule": "any",
"explanation": "因为 -w 去掉了 DWARF 调试信息,panic 的堆栈跟踪虽然仍能显示函数名和文件名(这些信息被嵌入在 Go 运行时的 pclntab 中,与 DWARF 无关),但无法显示完整的源码绝对路径。函数名因为已编入 pclntab(Program Counter Line Table)所以仍然可用,但行号和路径信息不完整。",
"source": null,
"related": []
},
{
"id": "fb-006",
"type": "fill_blank",
"difficulty": 4,
"tags": [
"Go",
"pprof",
"性能分析"
],
"question": "对使用 -s -w 编译的 Go 二进制文件运行 pprof 进行性能分析时,函数调用栈中只会显示内存____,而无法显示具体的函数名和行号信息。",
"answer": [
"地址",
"address"
],
"answer_rule": "any",
"explanation": "pprof 在分析 profiling 数据时需要符号信息来将内存地址翻译为函数名+行号。如果二进制用了 -s 去掉符号表,pprof 就无法解析这些地址,只能显示原始的十六进制地址。即使只用了 -w 去 DWARF,pprof 仍能显示函数名(符号表还在),只是没有行号。要让 pprof 正常工作,最好保存未 strip 的调试版本。",
"source": null,
"related": []
},
{
"id": "fb-007",
"type": "fill_blank",
"difficulty": 3,
"tags": [
"Go",
"ldflags",
"编译时注入"
],
"question": "使用 go build -ldflags \"-X ____.version=1.0.0\" 可以在编译时注入版本号等变量,这与 -s -w 组合使用互不影响。",
"answer": [
"main",
"包路径"
],
"answer_rule": "any",
"explanation": "-ldflags \"-X importpath.name=value\" 用于在编译时设置 string 类型的包级变量值。完整路径格式为 \"fully/qualified/package.Path\"。例如 main 包中的 version 变量:-ldflags \"-X main.version=1.0.0\"。这个操作通过链接器完成,与 -s -w 的符号剥离独立——因为 -X 是在编译时直接将值写入二进制数据段,不需要运行时符号表参与。",
"source": null,
"related": []
},
{
"id": "fb-008",
"type": "fill_blank",
"difficulty": 2,
"tags": [
"Go",
"开发环境",
"调试"
],
"question": "在本地开发和调试阶段,构建 Go 程序时____使用 -s -w 标志,以保留完整的调试信息便于使用 Delve 调试器和 pprof 工具。",
"answer": [
"不应该",
"不建议",
"不要"
],
"answer_rule": "any",
"explanation": "本地开发阶段保留调试信息至关重要。Delve(dlv)调试器依赖 DWARF 信息来设置断点、查看变量值、单步调试;pprof 依赖符号表来解析函数名和行号。如果开发时用了 -s -w,调试体验会严重下降。最佳实践:开发/测试环境不 strip,仅在 CI/CD 的生产构建中使用 -s -w。",
"source": null,
"related": []
},
{
"id": "fb-009",
"type": "fill_blank",
"difficulty": 4,
"tags": [
"Go",
"addr2line",
"调试"
],
"question": "当使用 -s -w 编译的程序 panic 输出中包含十六进制地址时,可使用 go tool ____ 反查对应的源码文件和行号,前提是能找到对应的未 strip 二进制。",
"answer": [
"addr2line"
],
"answer_rule": "all",
"explanation": "go tool addr2line 接收二进制文件和地址列表,输出对应的源码文件和行号。但它需要未 strip 的二进制(包含 DWARF 信息)作为输入。因此生产中如果要保留事后调试能力,需要在构建时同时保存 strip 和未 strip 两个版本。未 strip 版本用于事后分析,strip 版本用于部署。",
"source": null,
"related": []
},
{
"id": "fb-010",
"type": "fill_blank",
"difficulty": 5,
"tags": [
"Go",
"Rust",
"Java",
"跨语言对比"
],
"question": "在 Rust 中通过 Cargo.toml 的 [profile.release] 设置 strip = true 可实现类似 Go 的 -s 效果;在 Java 中,____/R8 等工具通过代码缩减和混淆实现类似的二进制体积优化。",
"answer": [
"ProGuard"
],
"answer_rule": "all",
"explanation": "不同语言都有二进制体积优化手段:Go 用 -s -w 剥离符号和调试信息;Rust 在 Cargo.toml 中设置 strip = true 或使用 strip 命令,效果类似;Java 使用 ProGuard(开源)或 R8(Android 官方,Google 开发的 ProGuard 替代品)进行 tree-shaking(移除未使用的类和方法)、混淆和优化。虽然原理不同(Go/Rust 是剥离元数据,Java 是缩减代码),但目标一致——减小部署体积。其他语言也有类似工具:C/C++ 的 strip 命令、.NET 的 PublishTrimmed 等。",
"source": null,
"related": []
}
]
}