实战任务与检查清单¶
学习目标¶
本章用于收束“计算机基础导论”课程。学习者需要通过几个小任务,确认自己已经建立后端工程师的基本系统认知。
完成本章后,学习者应该能够:
- 用自己的话解释后端服务如何运行。
- 启动并验证一个本地服务。
- 画出一个请求链路。
- 初步判断常见访问失败原因。
- 为后续 Go、网络、操作系统和 Web 后端课程做好准备。
任务一:验证本地文档服务¶
在本项目目录下启动 MkDocs:
打开:
用命令行验证:
记录下面信息:
| 检查项 | 记录 |
|---|---|
| 服务是否启动 | |
| 监听端口 | |
| 进程 ID | |
| HTTP 状态码 | |
| 如果停止服务后再访问,错误是什么 |
任务二:画出请求链路¶
画出你访问 http://127.0.0.1:8000/ 时的链路。
至少包含:
- 浏览器或命令行客户端。
- 本机网络。
- MkDocs 服务进程。
- 文件读取。
- HTTP 响应。
然后再画一个生产环境版本,至少包含:
- 用户。
- 浏览器或 App。
- DNS。
- 网关或负载均衡。
- Go 后端服务。
- 数据库。
- Redis。
- 日志和监控。
思考两个链路有什么不同。
任务三:分析一次访问失败¶
假设用户反馈“页面打不开”,请按顺序写出你的排查步骤。
建议从下面方向开始:
- 用户访问的 URL 是否正确?
- 域名是否能解析?
- 端口是否能连通?
- 服务进程是否存在?
- 服务是否监听正确地址?
- 网关是否转发正确?
- 后端日志是否有错误?
- 数据库或缓存是否异常?
- 最近是否发布过新版本?
要求:不要只写“看日志”,要说明看什么日志、为了确认什么问题。
任务四:实现一个最小 Go 服务¶
实现一个最小 HTTP 服务:
package main
import (
"fmt"
"log"
"net/http"
)
func main() {
http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
_, _ = fmt.Fprintln(w, "ok")
})
http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
name := r.URL.Query().Get("name")
if name == "" {
name = "world"
}
_, _ = fmt.Fprintf(w, "hello, %s\n", name)
})
log.Println("listening on :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
运行:
验证:
课程检查清单¶
完成本课程后,学习者应该能勾选:
- 我知道后端工程师不只是写接口。
- 我能说出一个请求从客户端到服务端的大致过程。
- 我知道 CPU、内存、磁盘、网络会如何影响服务。
- 我能用命令行确认端口是否监听。
- 我能用 HTTP 工具验证服务是否可访问。
- 我知道 DNS、TCP、TLS、HTTP 分别处在请求链路的什么位置。
- 我知道配置、日志、健康检查对服务运行很重要。
- 我能解释同步任务和异步任务的基本区别。
- 我知道服务退出也需要设计。
阶段总结¶
本阶段不是为了把计算机基础讲深,而是让学习者形成一张后端系统地图。
后续课程会继续沿着这张地图深入:
- 数据结构与算法:训练问题抽象和复杂度意识。
- 操作系统:深入进程、线程、内存、IO、文件描述符和容器底层。
- 计算机网络:深入 TCP、HTTP、DNS、TLS 和网络排障。
- Go 语言:把这些基础落到 Go 的运行时、并发模型和服务开发中。
- Web 后端:学习如何设计和实现真实 API 服务。
综合面试题¶
1. 后端工程师为什么需要理解计算机基础?¶
参考答案
后端服务运行在真实计算机系统上,会受到 CPU、内存、磁盘、网络、操作系统、数据库和外部依赖的影响。理解计算机基础,才能解释服务为什么慢、为什么超时、为什么 OOM、为什么连接失败。
如果只会写业务代码,遇到线上问题时很容易停留在猜测。计算机基础能帮助工程师从现象定位到资源、链路和系统边界。
2. 如何确认一个服务“真的启动成功”?¶
参考答案
要确认进程存在、端口监听正确、健康检查接口返回正常、关键依赖连接成功、日志没有启动错误,并且可以通过 HTTP 或 RPC 客户端拿到预期响应。
“控制台打印启动成功”不够。真实工程中还要确认监听地址、配置、数据库、缓存、权限和网络路径是否正确。
3. 从浏览器输入 URL 到后端返回响应,中间经历了哪些关键步骤?¶
参考答案
关键步骤包括 URL 解析、DNS 查询、TCP 连接建立、TLS 握手、HTTP 请求发送、网关或负载均衡转发、后端服务处理、访问数据库或缓存、生成响应、HTTP 响应返回浏览器。
面试回答时可以按分层说明:DNS 负责找地址,TCP 负责可靠连接,TLS 负责安全通道,HTTP 负责请求响应语义,后端服务负责业务逻辑和数据访问。
4. 如果一个接口变慢,你会先从哪些系统资源方向判断?¶
参考答案
可以先从 CPU、内存、磁盘、网络和外部依赖几个方向判断。CPU 高可能是计算、编解码或 GC;内存上涨可能是大对象、缓存或泄漏;磁盘慢可能影响日志和数据库;网络慢可能是服务间调用或第三方接口;数据库和缓存慢也会直接拖慢接口。
更好的方式是结合监控指标、请求日志、链路追踪、慢 SQL、pprof 和资源使用情况,定位耗时主要发生在哪一段。
5. 为什么服务需要健康检查?¶
参考答案
健康检查让部署平台、负载均衡或运维系统知道服务是否可用。它可以避免流量打到未准备好的实例,也可以在服务异常时触发重启或摘流。
健康检查通常分为存活检查和就绪检查。存活检查关注进程是否还活着,就绪检查关注服务是否已经准备好处理请求。
6. 为什么配置不能硬编码在代码里?¶
参考答案
配置硬编码会导致环境切换困难、敏感信息泄露、发布风险增加。不同环境的数据库地址、Redis 地址、日志级别、第三方 API、密钥和超时时间通常都不同,应该通过配置文件、环境变量或配置中心管理。
配置和代码分离后,同一份代码可以部署到不同环境,只需要改变配置。这是工程化和可维护性的基础。
7. 为什么生产服务需要优雅退出?¶
参考答案
生产服务退出时可能仍有请求、事务、消息消费、日志写入或后台任务在进行。如果直接杀掉进程,可能造成请求失败、数据不一致、消息重复或日志丢失。
优雅退出会先停止接收新流量,再等待正在处理的任务完成,最后释放资源并退出。它对滚动发布、扩缩容和故障恢复都很重要。