Go
全面学习 Go 语言。从包、变量和控制流入手,深入探索结构体、接口、并发、测试、HTTP 服务器、数据库、泛型、性能分析,以及将真实二进制文件发布到生产环境。
共 20 节,按顺序
- 125 分钟
你好,Go
欢迎。如果你以前从来没写过代码,那你来对地方了。Go 是一门编程语言,也就是一种给计算机下达一步步指令的方式,写出来的样子有点像加了不少标点的英文。学完这一课,你会跑通自己写的第一个 Go 程序,也会知道什么是包。这就是全部任务。我们不着急。
Package mainImportFunc mainFmt.PrintlnGo run - 225 分钟
变量与类型
上一课你打印了一段固定的文本。真正的程序需要记住会变的东西:客户的名字、一件商品的价格、某个勾选框有没有勾上。变量是一个名字,代表存放在内存里的某个值,这样你的代码就能提到"价格",而不必到处重打 4.50。Go...
Var declarationShort declaration :=IntFloat64StringBool+2 - 330 分钟
控制流:if 与 for
到目前为止,你写的每个程序都是从上到下一行接一行地跑,路上没有任何选择。真实的程序需要作出反应:大额订单收另一种运费,对成年人和未成年人打印不同的话,反复向服务器要响应直到拿到一个。控制流 (control flow) 是一门语言中决定"哪些行会运行、运行多少次"的那部分的统称,而 Go...
IfElse ifElseFor loopFor as whileInfinite for+2 - 430 分钟
函数
到目前为止,你写过的每个程序都活在 func main() 里面。十来行代码这样写没问题,但真实的程序常常需要在不止一个地方算同一件事:校验年龄、格式化价格、判断一个数是不是偶数。到处复制粘贴同样的三行代码,就是一个小缺陷变成十个缺陷的方式,每份副本里都有一个。函数是一段有名字、可以复用的代码块,它...
Func keywordParametersReturn valuesMultiple return valuesNamed return valuesBlank identifier - 535 分钟
切片(slices)与映射(maps)
到目前为止你用过的每个变量都只装一个值:一个名字、一个年龄、一个价格。而现实中的大多数问题涉及的是一组东西:一份学生名册、一个购物车、一张按商品名查价格的对照表。Go...
Slice literalAppendLenIndexingRangeMap literal+2 - 635 分钟
结构体(structs)与指针(pointers)
到目前为止,这门课里你写过的每个变量都只装着一个孤零零的值:一个数字,一个字符串,一个切片。可现实中的数据很少是单个出现的。屏幕上的一个点,需要 x 和 y 待在一起。一个用户,需要名字和电子邮件待在一起。你当然可以用 pointX、pointY...
Struct definitionField accessZero values for structsPointer types& and * operatorsPointer receivers vs value receivers+1 - 735 分钟
方法(methods)与接口(interfaces)
上一课教你把相关的字段打包进一个结构体,但结构体本身只装数据,没有行为。如果你想让 Rectangle 自己会算面积,要么写一个普通函数、把 Rectangle 当实参传进去,要么把行为直接挂到类型上,让它跟着数据一起走。Go...
Method declarationReceiver typesPointer vs value receiversInterface definitionImplicit interface satisfactionSmall interfaces+1 - 835 分钟
错误处理
在这门课程里,你已经不止一次敲下 if err != nil,却没有停下来问一句 err 到底是什么、又从哪来。函数会以各种平常且在意料之中的方式失败:调用方要的文件不在磁盘上,调用方给的数字超出了范围,除法的分母是零。程序需要一种方式来报告“这件事没成,原因在这里”,而这种报告要跟真的崩溃区分开,...
Error interfaceFmt.Errorf with %wErrors.IsErrors.AsCustom error typesPanic vs error+1 - 935 分钟
模块(modules)与项目结构
这门课程里你到目前为止写过的每个程序,都只是一个文件,一条命令就能运行。真实的 Go 项目几乎从来不会一直这么小:代码随着增长会拆到许多文件和文件夹里,其中一部分会被别的程序共用,还有一部分依赖别人写好并发布出来的代码。一旦涉及不止一个文件,三个单文件程序从来不用回答的问题立刻就冒出来了:你自己的一...
Go mod initGo.mod and go.sumImport pathsPackage vs moduleInternal/ folderCmd/ layout+1 - 1040 分钟
迷你 CLI 综合项目
到目前为止,你写过的每个程序,输入都是硬编码在源码里的。想加另外几个数字,就得改文件再跑一遍。学习阶段这样没问题,可作为工具就毫无用处,因为工具是你交给别人、由别人来决定它处理什么的东西。
Os.ArgsStrconv.AtoiError handling with if err != nilOs.ExitGo buildPutting it together - 1140 分钟
标准库之旅
学任何一门语言,都会有那么一刻:你不再琢磨循环怎么写,开始琢磨怎么读一个文件,怎么格式化一个日期,怎么把自己的数据变成别的程序看得懂的东西。在很多语言里,答案是出门采购:找一个包,看看还有没有人维护,加进项目,然后祈祷。
FmtStringsStrconvTimeOsBufio+1 - 1240 分钟
测试与基准测试(benchmarks)
你写了一个函数,运行程序,看到正确的答案,然后就往下走了。一周后你改了旁边的某样东西,这个函数悄无声息地开始对负数返回错误结果。一个月里没人发现。软件就是这样坏掉的,这不是因为程序员水平差,而是因为改了新东西之后没人回头重新检查旧东西。
Go testTesting.TTable-driven testsT.Run subtestsTesting.B benchmarks_test.go file naming+1 - 1340 分钟
协程(goroutines)与通道(channels)
你的程序要下载二十个文件。按最普通的写法,它下载第一个,等着,再下载第二个,再等着,如此往复。这段时间里几乎全部都在干等,等一个比处理器慢上几百万倍的网络。如果这些等待能重叠起来,活儿早就干完了,快二十倍。
The go keywordGoroutine lifetimeUnbuffered channelsBuffered channelsSend and receiveRange over channel+1 - 1445 分钟
并发模式
协程(goroutine)和通道是原材料,就像木头和螺丝。知道它们是什么,并不等于知道怎么做一把椅子。实践中,几乎所有并发的 Go 代码都是由少数几种一眼能认出来的形状拼起来的,一旦你能叫出它们的名字,就会在打开的每一份真实代码库里看到它们,而且每次都在干同一件事。
Select statementContext.Context for cancellationSync.WaitGroupSync.MutexWorker pool patternFan-out fan-in idea - 1535 分钟
泛型(generics)
你写了一个函数,从一个 int 切片里找出最大的数。接着你需要一个 float64 版本,于是复制一份,改两个词。然后又要一个 string 版本。现在有三个几乎一样的函数摆在那里,等你修好其中一个的缺陷,还得记得另外两个。
Type parameters with [T any]ConstraintsComparableTilde approximation ~intGeneric Map and FilterWhen generics help, when they do not - 1645 分钟
HTTP 服务器
在大多数语言里,"写一个 Web 服务"的第一步是挑一个框架,而且这个选择很要紧,因为框架决定了路由怎么工作、一个处理器长什么样、你又该怎么把各种行为组合起来。在 Go 里,基本不存在这一步。标准库的 net/http...
Net/httpHttp.HandleFuncHttp.ServerJSON responsesRequest routingMiddleware via http.Handler wrapping+1 - 1745 分钟
使用 database/sql 的数据库
到目前为止你写的每个程序,一退出就把什么都忘光了。对于一个把输入变换一下就收工的小工具来说这没问题,但凡涉及用户、订单、会话或历史记录,它就毫无用处。Go 程序迟早要把数据放到一个比它自己活得更久的地方,而对多数程序来说,那个地方就是关系型数据库。
Database/sql packageDriver importsSql.Open and sql.DB poolExec vs Query vs QueryRowPrepared statementsScanning rows+1 - 1840 分钟
性能与分析
某天有人说服务变慢了,你打开代码,一眼就看到那个"肯定是它"的循环。你把它重写了,现在写得聪明多了,而服务和之前一样慢,因为真正的开销在三层调用之外的一次 JSON 编码上,谁都没想到那儿。
Go test -benchPprof CPU and heap profilesEscape analysis with -gcflags=-mAvoiding unnecessary allocationsPreallocating slicesSync.Pool intuition - 1940 分钟
Go 语言中的设计模式
程序会越写越大。一个两百行时还完全说得通的文件,慢慢变成这样一个地方:改动一小处,三个文件之外的东西就坏了;测试越来越慢、越来越难写,直到干脆没人写。这不是能力不够,而是当程序里任何东西都能碰到其他任何东西时,本来就会这样。
Functional options patternRepository patternDependency injection via interfacesContext propagation through call stacksConstructor functions - 2045 分钟
部署与生产
一个能在你笔记本电脑上跑起来的程序,和一个你愿意放着通宵运行的程序之间,是有差距的。填上这道差距不是什么光鲜的工作,多半是机械性的活,这其实是好消息:每次冒出来的都是同样那五件事,而 Go 恰好对这五件事都准备得异常充分。
CGO_ENABLED=0 static binariesCross-compile with GOOS and GOARCHGraceful shutdown with http.Server and signal.NotifyContextMinimal Dockerfile with scratch or distrolessReading config from environment variables
用你的语言学习 Go
每一节课、测验和导师回复都以你的语言显示。AI 导师会用你提问的语言来回答。
Roles that use Go
See how hiring teams interview engineers on Go, in production-like environments.
Backend Engineer (Go, Rust, Java)
Hire backend engineers in real services with real databases, real concurrency and real latency budgets. Live or take-home, fully recorded.
See the interviewDistributed Systems Engineer
Hire distributed systems engineers in workspaces with real Kafka, real consensus and real partition tooling. Live or take-home, fully recorded.
See the interviewPlatform Engineer
Hire platform engineers who reduce friction for every team. Real golden-path templates, real internal CLIs, real service onboarding flows. We record every step.
See the interview