第一章:Go新手训练营入门导览
欢迎加入 Go 新手训练营!本章将带你完成从零开始的首次 Go 体验——无需预装环境,只需一台联网设备,即可快速验证语言核心特性并运行第一个程序。
安装与验证
推荐使用官方安装包(golang.org/dl)或通过包管理器安装。macOS 用户可执行:
brew install go
Linux 用户可下载二进制包并解压至 /usr/local,随后将 /usr/local/go/bin 加入 PATH。安装完成后,在终端运行:
go version
# 输出示例:go version go1.22.4 darwin/arm64
go env GOPATH
# 查看 Go 工作区路径(默认为 $HOME/go)
编写你的第一个程序
创建目录并初始化模块:
mkdir hello-go && cd hello-go
go mod init hello-go
新建 main.go 文件,内容如下:
package main // 声明主包,每个可执行程序必须以此开头
import "fmt" // 导入标准库 fmt 包,用于格式化输入输出
func main() { // 程序入口函数,名称固定且首字母小写
fmt.Println("Hello, 世界!") // 打印 UTF-8 字符串,Go 原生支持 Unicode
}
保存后执行:
go run main.go
# 输出:Hello, 世界!
Go 工具链初识
| 命令 | 用途 | 典型场景 |
|---|---|---|
go run |
编译并立即执行单文件或多文件程序 | 快速验证逻辑 |
go build |
生成可执行二进制文件(当前平台) | 发布部署前构建 |
go fmt |
自动格式化代码,统一缩进与换行 | 提交前标准化风格 |
go vet |
静态检查潜在错误(如未使用的变量) | 开发中提升健壮性 |
Go 的设计哲学强调“显式优于隐式”与“工具即语言一部分”。所有命令均开箱即用,无需额外配置插件或依赖管理器。现在,你已具备运行、调试和构建 Go 程序的基础能力。
第二章:Go语言核心语法精讲与动手实践
2.1 变量声明、类型推导与零值机制——从Hello World到类型安全初探
Go 的变量声明兼顾简洁性与类型安全。var 显式声明、:= 短变量声明、const 常量定义构成基础三角:
var name string = "Alice" // 显式类型 + 初始化
age := 30 // 类型推导为 int
const pi = 3.14159 // untyped constant,上下文决定类型
逻辑分析:
age := 30中编译器根据字面量30推导出底层类型为int(非int64),该推导在编译期完成,无运行时开销;pi是无类型常量,参与float64(pi * 2)运算时自动升格为float64。
所有类型均有确定零值:(数值)、""(字符串)、nil(指针/切片/map/chan/func)。这消除了未初始化内存的不确定性。
| 类型 | 零值 | 安全意义 |
|---|---|---|
int |
|
避免野指针或越界访问 |
*string |
nil |
强制显式解引用检查 |
[]byte |
nil |
len() 返回 0,安全遍历 |
graph TD
A[声明变量] --> B{是否使用 := ?}
B -->|是| C[编译期类型推导]
B -->|否| D[显式指定类型]
C & D --> E[分配零值]
E --> F[类型系统全程校验]
2.2 控制结构与错误处理模型——if/for/select实战与defer-panic-recover调试演练
if/for/select 的语义边界
Go 中 if 不需括号,for 统一替代 while/for-each,select 则专用于 channel 多路复用:
ch1, ch2 := make(chan int), make(chan string)
go func() { ch1 <- 42 }()
go func() { ch2 <- "done" }()
select {
case n := <-ch1:
fmt.Println("int:", n) // 阻塞直到任一 case 就绪
case s := <-ch2:
fmt.Println("str:", s)
default: // 非阻塞分支
fmt.Println("no ready channel")
}
逻辑分析:select 随机选取就绪 case(避免饥饿),default 实现轮询非阻塞;若无 default 且所有 channel 未就绪,则永久阻塞。
defer-panic-recover 调试链
func risky() {
defer func() {
if r := recover(); r != nil {
log.Printf("recovered: %v", r) // 捕获 panic 值
}
}()
panic("unexpected I/O failure") // 触发栈展开,执行 defer
}
defer 按后进先出压入栈,recover() 仅在 defer 函数内有效,且仅能捕获当前 goroutine 的 panic。
| 机制 | 触发时机 | 可中断性 | 典型用途 |
|---|---|---|---|
defer |
函数返回前 | 否 | 资源清理、日志收尾 |
panic |
显式调用或运行时 | 否 | 不可恢复的严重错误 |
recover |
defer 中调用 |
是 | 错误降级、中间件兜底 |
graph TD
A[函数执行] --> B[defer 语句注册]
B --> C[遇到 panic]
C --> D[停止正常流程]
D --> E[按 LIFO 执行 defer]
E --> F{defer 中调用 recover?}
F -->|是| G[捕获 panic 值,继续执行]
F -->|否| H[程序崩溃]
2.3 函数定义与多返回值设计——构建可测试的最小业务逻辑单元(Demo 03)
核心设计原则
- 单一职责:每个函数只封装一个确定性业务动作
- 显式契约:输入参数与返回值类型完全明确,无隐式状态依赖
- 可测试性优先:不耦合 I/O、数据库或全局变量
用户注册校验函数示例
// RegisterValidate 验证用户注册请求,返回校验结果、错误信息和建议操作
func RegisterValidate(email, password string) (valid bool, errCode string, action string) {
if email == "" {
return false, "ERR_EMPTY_EMAIL", "prompt_email"
}
if len(password) < 8 {
return false, "ERR_WEAK_PASSWORD", "suggest_stronger"
}
return true, "", "proceed"
}
逻辑分析:函数接收原始字符串输入,纯内存计算;三返回值分别表达「是否通过」「错误分类码」「前端交互指令」,避免 error 类型滥用,便于单元测试断言各维度。
多返回值语义对照表
| 返回位 | 类型 | 含义 | 测试关注点 |
|---|---|---|---|
valid |
bool |
业务规则是否满足 | 边界值触发 false 路径 |
errCode |
string |
结构化错误标识 | 断言精确码而非 error 文本 |
action |
string |
前端可执行引导指令 | 驱动 UI 状态机流转 |
2.4 结构体与方法集——面向对象思维迁移与接口隐式实现验证(Demo 07)
Go 不提供类,但通过结构体+方法集天然支持面向对象的封装与多态。关键在于:接口实现无需显式声明,只要类型实现了全部接口方法,即自动满足。
隐式实现验证示例
type Speaker interface {
Speak() string
}
type Dog struct{ Name string }
func (d Dog) Speak() string { return d.Name + " says: Woof!" } // ✅ 自动实现 Speaker
type Cat struct{ Name string }
func (c *Cat) Speak() string { return c.Name + " says: Meow!" } // ✅ 指针方法也有效
Dog值类型方法集包含Speak(),可赋值给Speaker;*Cat指针类型方法集也含Speak(),但Cat{}值本身不满足该接口(因方法集仅含*Cat方法)。这是方法集规则的核心差异。
方法集对照表
| 类型 | 值方法集包含 | 指针方法集包含 |
|---|---|---|
T |
func(T) |
func(T), func(*T) |
*T |
func(T), func(*T) |
func(T), func(*T) |
接口适配流程
graph TD
A[定义接口] --> B[结构体实现方法]
B --> C{方法接收者是 T 还是 *T?}
C -->|T| D[值/指针均可赋值]
C -->|*T| E[仅指针可赋值]
2.5 包管理与模块初始化——go.mod生命周期管理与init()函数执行时序分析
Go 程序启动时,go.mod 定义的模块依赖图决定编译边界,而 init() 函数则在包加载阶段按依赖拓扑序自动执行。
init() 执行顺序规则
- 同一包内多个
init()按源文件字典序执行 - 不同包间严格遵循:被依赖包 → 依赖包(即
import "a"的包a先于当前包初始化)
// a/a.go
package a
import "fmt"
func init() { fmt.Println("a.init") }
// main.go
package main
import _ "a" // 触发 a.init
func init() { println("main.init") }
func main() {}
// 输出:
// a.init
// main.init
逻辑分析:
go build解析main.go时发现导入_ "a",先加载并执行a包的init();完成后才执行main包自身init()。_导入仅触发初始化,不引入符号。
go.mod 生命周期关键节点
| 阶段 | 触发动作 |
|---|---|
go mod init |
创建初始 go.mod,设定模块路径 |
go build |
解析 require,校验 sum 一致性 |
go mod tidy |
自动增删依赖,更新 go.sum |
graph TD
A[go mod init] --> B[go build]
B --> C{依赖解析}
C --> D[加载 go.mod]
C --> E[验证 go.sum]
D --> F[执行 import 链 init]
第三章:Go工程化开发基础
3.1 Go标准库核心包实战——fmt/io/os/path/filepath在文件处理Demo中的协同应用
文件扫描与路径规范化
使用 filepath.Walk 遍历目录,配合 path.Clean 和 filepath.Base 提取标准化路径:
err := filepath.Walk("/tmp/data", func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() {
cleanPath := path.Clean(path) // 去除冗余分隔符和`.` `..`
fmt.Printf("→ %s → %s\n", cleanPath, filepath.Base(cleanPath))
}
return nil
})
filepath.Walk 自动处理符号链接与权限错误;path.Clean 保证路径语义一致;filepath.Base 安全提取文件名(不依赖 strings.Split)。
协同职责对比
| 包 | 关键能力 | 典型用途 |
|---|---|---|
fmt |
格式化输出/解析字符串 | 日志打印、调试信息 |
io |
通用读写接口(Reader/Writer) | 流式处理大文件 |
os |
系统级文件操作(Open/Stat) | 权限检查、元数据获取 |
path/filepath |
跨平台路径构造与分割 | 构建安全相对路径 |
数据同步机制
graph TD
A[filepath.Walk] --> B{IsDir?}
B -->|否| C[os.Open]
C --> D[io.Copy to backup]
D --> E[fmt.Printf success]
3.2 并发原语深度解析——goroutine调度模型与channel阻塞/非阻塞通信模式(Demo 12)
Go 的并发本质是 M:N 调度模型:多个 goroutine(G)由运行时复用到少量 OS 线程(M),通过处理器(P)协调本地队列与全局队列。
goroutine 调度关键角色
- G:轻量级协程,栈初始仅 2KB,按需扩容
- M:绑定 OS 线程,执行 G
- P:逻辑处理器,持有本地运行队列(LRQ)、自由 G 池、timer 等资源
ch := make(chan int, 1)
ch <- 1 // 非阻塞:缓冲区有空位
select {
case ch <- 2: // 尝试发送
default: // 非阻塞分支,立即返回
}
该
select块实现无等待发送:若缓冲区满或无接收者,default立即执行,避免 goroutine 挂起。make(chan int, 1)创建容量为 1 的带缓冲 channel,其底层 ring buffer 支持 O(1) 入队/出队。
channel 通信模式对比
| 模式 | 阻塞行为 | 适用场景 |
|---|---|---|
ch <- v |
若无接收者且无缓冲则阻塞 | 同步协作、背压控制 |
select { case ch<-v: ... default: } |
永不阻塞 | 心跳上报、异步投递降级 |
graph TD
A[goroutine 发送] --> B{ch 有缓冲?}
B -->|是,有空位| C[写入缓冲区,继续执行]
B -->|否 或 已满| D{存在接收者?}
D -->|是| E[直接移交数据,唤醒接收者]
D -->|否| F[挂起 G,入 sendq 等待]
3.3 错误处理与日志规范——error interface定制、log/slog结构化日志集成(Demo 15)
Go 1.21+ 推荐统一使用 slog 替代 log,配合自定义 error 类型实现语义化错误链路追踪。
自定义错误类型(带上下文与码)
type AppError struct {
Code string
Message string
Err error
}
func (e *AppError) Error() string { return e.Message }
func (e *AppError) Unwrap() error { return e.Err }
Code 用于监控告警分类(如 "auth.invalid_token"),Unwrap() 支持 errors.Is/As 标准链式判断,Error() 仅返回用户友好消息。
结构化日志输出示例
slog.With(
slog.String("code", err.Code),
slog.String("path", r.URL.Path),
).Error("request failed", "err", err.Error())
参数说明:slog.String() 构建键值对,"err" 字段自动序列化为字符串,避免 fmt.Sprintf 拼接丢失结构。
| 字段名 | 类型 | 用途 |
|---|---|---|
code |
string | 错误分类标识,便于聚合 |
path |
string | 请求路径,辅助定位问题 |
err |
string | 原始错误消息(非堆栈) |
graph TD
A[HTTP Handler] --> B[业务逻辑]
B --> C{失败?}
C -->|是| D[Wrap as *AppError]
D --> E[slog.Error with attributes]
C -->|否| F[Success Response]
第四章:VS Code全链路调试环境搭建与效能提升
4.1 Delve调试器集成与断点策略——launch.json配置详解与条件断点实战(Demo 18)
Delve 是 Go 生态中功能完备的原生调试器,VS Code 通过 launch.json 实现深度集成。
核心 launch.json 配置片段
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch with Delve",
"type": "go",
"request": "launch",
"mode": "test", // 支持 "auto"/"exec"/"test"/"core"
"program": "${workspaceFolder}",
"env": { "GODEBUG": "mmap=1" },
"args": ["-test.run=TestFetchData"],
"dlvLoadConfig": { // 控制变量加载深度
"followPointers": true,
"maxVariableRecurse": 3
}
}
]
}
dlvLoadConfig 决定调试时变量展开层级,避免大结构体阻塞 UI;mode: "test" 启动测试专用调试会话。
条件断点设置方式
- 在代码行号左侧右键 → Add Conditional Breakpoint
- 输入表达式如
len(items) > 10 && status == 200
常用断点策略对比
| 场景 | 推荐方式 | 优势 |
|---|---|---|
| 数据过滤逻辑验证 | 条件断点 | 避免手动单步跳过无效迭代 |
| 并发竞态定位 | 读写断点(dlv CLI) |
精确捕获内存访问 |
| 初始化异常 | 启动后延迟断点 | 绕过 runtime 初始化阶段 |
graph TD
A[启动调试] --> B{是否命中断点?}
B -->|否| C[继续执行]
B -->|是| D[评估条件表达式]
D -->|true| E[暂停并加载栈帧]
D -->|false| C
4.2 Go Test调试工作流——test文件断点注入、覆盖率可视化与benchmark对比分析
Go 的 go test 工具链支持深度集成式调试,无需额外插件即可在 _test.go 文件中直接设置断点。
断点注入实践
在 VS Code 中启用 dlv-dap 后,于 example_test.go 中任意测试函数内行号左侧点击即可设断点:
func TestCalculateSum(t *testing.T) {
t.Log("before calc") // ← 断点可设在此行
result := CalculateSum(2, 3)
if result != 5 {
t.Fatal("unexpected result")
}
}
逻辑说明:
go test -gcflags="all=-N -l"禁用内联与优化,确保源码行与 DWARF 调试信息精确对齐;-race可选启用竞态检测。
覆盖率可视化
执行以下命令生成 HTML 报告:
go test -coverprofile=coverage.out && go tool cover -html=coverage.out -o coverage.html
Benchmark 对比分析
| 版本 | BenchmarkAdd-8 | 时间(ns/op) | 内存分配 |
|---|---|---|---|
| v1.0(朴素) | 12.4 ns/op | 0 B/op | 0 allocs |
| v1.1(缓存) | 3.7 ns/op | 0 B/op | 0 allocs |
graph TD
A[go test -bench=. -benchmem] --> B[解析 benchmark 输出]
B --> C[提取 ns/op & allocs/op]
C --> D[生成横向对比表格]
4.3 Go语言服务器(gopls)优化配置——智能补全、跳转、重命名与文档提示调优
核心配置项解析
gopls 的行为高度依赖 settings.json 中的精细化参数。关键字段包括:
"gopls.completeUnimportedPackages":启用跨模块未导入包的补全"gopls.usePlaceholders":在函数调用中插入带占位符的参数模板"gopls.semanticTokens":开启语义高亮,提升跳转与重命名精度
推荐 workspace 配置片段
{
"gopls": {
"build.buildFlags": ["-tags=dev"],
"analyses": {
"shadow": true,
"unusedparams": true
},
"staticcheck": true
}
}
此配置启用构建标记隔离开发依赖,并激活
shadow(变量遮蔽检测)与unusedparams(冗余参数诊断),显著提升重命名安全性与跳转上下文准确性。
性能与体验平衡表
| 功能 | 启用建议 | 影响面 |
|---|---|---|
fuzzyMatching |
强烈推荐 | 补全响应速度 +30% |
deepCompletion |
慎用 | 内存占用上升 15–20% |
文档提示增强机制
graph TD
A[光标悬停] --> B{是否在 func/struct/const 上?}
B -->|是| C[提取 godoc 注释 + 类型签名]
B -->|否| D[回退至类型推导摘要]
C --> E[渲染富文本 Markdown 片段]
4.4 多环境调试支持——Docker容器内Go进程远程调试与WSL2跨平台配置(Demo 23)
调试准备:启用Delve服务端
在 Dockerfile 中添加调试支持:
# 启用调试模式,暴露dlv端口
FROM golang:1.22-alpine
RUN go install github.com/go-delve/delve/cmd/dlv@latest
COPY . /app
WORKDIR /app
# 关键:禁用优化以保证源码映射准确
RUN go build -gcflags="all=-N -l" -o server ./cmd/server
CMD ["dlv", "exec", "./server", "--headless", "--api-version=2", "--addr=:2345", "--continue"]
--headless启用无界面调试服务;-N -l禁用内联与优化,确保断点精准命中源码行;--addr=:2345暴露标准dlv端口,需在docker run时映射-p 2345:2345。
WL2本地调试连接
WSL2中启动容器后,VS Code通过 .vscode/launch.json 连接:
{
"name": "Remote Docker",
"type": "go",
"request": "attach",
"mode": "core",
"port": 2345,
"host": "localhost",
"trace": true
}
环境兼容性要点
| 组件 | WSL2 (Ubuntu) | Docker Desktop | 注意事项 |
|---|---|---|---|
| Delve 版本 | v1.22.0 | v1.22.0 | 版本必须严格一致,否则协议不兼容 |
| 文件路径映射 | /home/user/app |
/app |
VS Code 需配置 substitutePath |
graph TD
A[VS Code on Windows] -->|TCP 2345| B[WSL2 Ubuntu]
B -->|Docker bridge| C[Go Container]
C --> D[dlv server]
D --> E[源码断点/变量检查]
第五章:23个最小可行Demo学习路径图谱
构建技术能力不应始于宏大的架构设计,而应扎根于可立即运行、可调试、可验证的最小可行Demo(MVP Demo)。本图谱精选23个覆盖前端、后端、数据、AI与基础设施领域的轻量级实践单元,每个Demo均满足:代码行数≤200、依赖≤3个、可在60秒内完成本地启动、具备明确输入/输出可观测性。
前端交互闭环
用原生HTML+CSS+JS实现一个支持 localStorage 持久化的待办清单,包含添加、勾选、清空三项功能。无需框架,仅需一个 index.html 文件。演示命令:npx http-server -c-1 启动静态服务后访问 http://localhost:8080 即可交互验证状态留存。
HTTP服务端探针
使用 Python Flask 编写一个 /health 接口,返回 JSON { "status": "ok", "uptime_seconds": 127 },并自动记录每次请求时间戳至内存列表。启动后执行 curl -s http://localhost:5000/health | jq 可实时观测服务心跳与运行时长。
SQLite嵌入式CRUD
创建单文件数据库 notes.db,含 id INTEGER PRIMARY KEY, title TEXT, content TEXT 表;提供 insert_note.py、list_notes.py、delete_note.py 三个独立脚本,分别实现增、查、删操作。所有脚本均不依赖 ORM,直调 sqlite3 标准库。
WebSocket实时计数器
Node.js + ws 库实现双客户端协同计数器:Client A 点击“+1”触发广播,Client B 界面实时更新数字。服务端代码仅43行,含连接管理与消息分发逻辑。部署后打开两个浏览器标签页即可验证双向实时性。
Docker化Python微服务
将上述 Flask 健康检查服务打包为 Docker 镜像:Dockerfile 仅5行(FROM、COPY、RUN、EXPOSE、CMD),构建命令 docker build -t demo-health .,运行命令 docker run -p 5000:5000 demo-health 即可获得容器化服务实例。
Git版本原子操作链
通过一组连续 Git 命令复现典型协作场景:git init → echo "v1" > README.md && git add . && git commit -m "init" → git checkout -b feat/login → echo "login form" >> README.md && git commit -am "add login" → git rebase main。每步执行后 git log --oneline --graph 可视化分支演进。
Mermaid 学习路径依赖图
graph LR
A[HTML/CSS/JS基础] --> B[HTTP协议实践]
B --> C[REST API设计]
C --> D[SQLite本地存储]
D --> E[Docker容器封装]
E --> F[Git协作流]
F --> G[CI/CD流水线]
OpenAPI契约先行开发
编写 openapi.yaml 描述 /users/{id} GET 接口(含 200/404 响应定义),使用 openapi-generator-cli 生成 FastAPI 服务骨架,再填充内存模拟数据层。验证方式:启动服务后访问 /docs 查看自动生成的 Swagger UI,并用 curl 调用真实端点。
Prometheus指标埋点
在 Flask 健康检查服务中集成 prometheus_client,暴露 /metrics 端点,新增 http_requests_total{method="GET",endpoint="/health"} 计数器。启动后访问 http://localhost:5000/metrics 可见文本格式指标流。
| Demo编号 | 技术栈 | 启动耗时 | 关键验证点 | 适用角色 |
|---|---|---|---|---|
| 07 | Nginx静态路由 | curl -I http://localhost/css 返回200 |
运维/全栈 | |
| 12 | Redis计数缓存 | 2s | 两次请求间 counter 值递增 |
后端/数据工程师 |
| 19 | GitHub Actions | 45s | push后自动运行 pytest | DevOps/测试工程师 |
多环境配置切换
使用 dotenv + Python configparser 实现 .env.development 与 .env.production 双配置加载,服务启动时通过 ENV=production python app.py 切换行为:开发环境打印 SQL 日志,生产环境禁用。
无服务器函数快照
用 AWS SAM CLI 初始化一个 hello-world Lambda 函数,本地执行 sam local invoke 模拟云端运行环境,输出 {"message": "hello from lambda"}。整个过程不涉及云账号绑定,纯离线验证函数签名与序列化逻辑。
纯CSS响应式网格
仅用 CSS Grid 与媒体查询实现三栏布局:桌面端横向排列,平板端双列,手机端单列。HTML 中无任何 JavaScript,通过 Chrome DevTools 切换设备尺寸即可验证断点生效。
Markdown转HTML管道
用 Pandoc 构建极简文档处理链:echo "# Hello" | pandoc -f markdown -t html5 -o index.html,再配合 http-server 快速预览渲染效果。全程零 Node.js 依赖,适合 CI 环境批量生成文档站点。
TCP Socket回声服务
Python socket 模块编写 32 行 TCP 服务端,监听 localhost:8888,接收任意字符串并原样返回。客户端使用 telnet localhost 8888 手动输入即可获得即时响应,直观理解传输层通信本质。
GraphQL单字段查询
用 Apollo Server 搭建最简 GraphQL 服务,仅暴露 hello: String 字段,启动后访问 http://localhost:4000/graphql,执行 { hello } 查询返回 {"data":{"hello":"Hello world!"}}。无 schema stitching,无 resolver 复杂逻辑。
Shell自动化日志归档
编写 archive-logs.sh:遍历 ./logs/*.log,按日期重命名(如 app-2024-06-15.log),打包为 logs_20240615.tar.gz,最后清空原始目录。手动执行一次即完成完整运维动作闭环。
CSV流式解析器
用 Python csv 模块实现内存友好的大文件处理:逐行读取 sales.csv(10万行),过滤出 amount > 1000 的记录,写入 high-value.csv。全程内存占用恒定
WebAssembly计算器
Rust 编写加法函数 pub fn add(a: i32, b: i32) -> i32 { a + b },编译为 .wasm,通过 JavaScript WebAssembly.instantiateStreaming() 加载并调用,控制台输出 add(5, 7) === 12。验证跨语言调用通路。
OAuth2授权码模拟
用 Flask 搭建极简授权服务器:/authorize 返回固定 code,/token 接收 code 并返回 mock access_token。前端用 fetch 完成完整三步流程(重定向→获取code→换取token),跳过真实第三方平台依赖。
Kafka本地事件总线
使用 Bitnami Kafka Docker Compose 模板启动单节点集群,生产者脚本 kafka-console-producer.sh 发送 "event: user_login",消费者脚本 kafka-console-consumer.sh 实时打印该消息。5分钟内构建完整事件驱动链路。
WASI系统调用沙箱
用 Wasmtime 运行 WASI 兼容模块:Rust 编译 println!("Hello from WASI!"); 为目标 wasm32-wasi,执行 wasmtime hello.wasm 输出日志。验证 WebAssembly 在非浏览器环境的标准系统接口能力。
基于LLM的CLI问答器
用 Ollama 运行 llama3 模型,结合 prompt-toolkit 构建命令行交互界面:输入 What is Kubernetes?,程序调用 ollama run llama3 流式返回答案。全程离线运行,无 API 密钥或网络请求。
