
前言FDE系列内容总纲【大纲】FDE 前沿部署工程师学习系列教程-CSDN博客前置课程列表见文档结尾附录。阶段2·Day 44Nginx 反向代理 Git 版本控制FDE 学习系列教程 · 第二阶段 · 第 5 周 · Day 4预计时长3 小时 | 难度★★★☆☆ | 前置知识Day 41-43 Docker/Compose、Linux 基础一句话目标配置 Nginx 反向代理让标准 80 端口转发到 FastAPI理解负载均衡原理掌握 Git 的提交、分支、回滚、远程推送全流程让代码有历史、可协作。 开场今天补齐两块标配拼图到昨天为止你的服务已经能docker compose up一键跑起来了。但还剩两个绕不开的现实问题问题一用户记不住 8000 端口。你的 API 跑在 8000数据库在 3306phpMyAdmin 在 8080。用户在浏览器敲http://服务器地址:8000既不专业也不安全。正常网站都是直接http://域名走 80 端口没人带端口号。中间需要一个前台接待把 80 端口的请求转进内部服务——这就是Nginx 反向代理。问题二代码还在裸跑。你现在改代码靠什么改坏了想退回昨天的版本怎么办多人一起开发怎么合并用文件夹复制出项目_备份1、项目_最终版、项目_最终版_真的最终这就是Git要解决的。上午 Nginx下午 Git都是 FDE 每天打交道的基础设施走起。第一部分Nginx 反向代理 一、正向代理 vs 反向代理两个名字都带代理但代理的对象完全相反。先分清这个配置就好理解了。对比正向代理反向代理代理谁客户端服务端谁知道代理存在用户知道用户不知道典型工具VPN、HTTP 代理Nginx、网关解决的问题帮用户访问外部帮服务器统一接待、隐藏内部结构Nginx 当反向代理能干啥两种安装方式在WSL 和这容器里安装主要是载体的区别WSL 和容器Docker是两个层面、目标不同但常配合使用的技术。维度WSLWindows Subsystem for Linux容器Docker是什么Windows 上运行 Linux 的兼容层/轻量虚拟机基于 Linux 内核特性的进程级隔离隔离单位一个完整的 Linux 发行版Ubuntu 等单个应用进程一个容器跑一个服务内核WSL2 有自己的真实 Linux 内核跑在轻量 VM 里共享宿主机内核Linux namespace cgroup解决的问题让 Windows 用户用上 Linux 工具链让应用及其依赖打包、随处一致运行粒度粗整个发行版细单服务启动秒级毫秒~秒级典型用途开发环境、命令行、跑 Linux 程序部署、微服务、环境一致性Windows 上的Docker Desktop 默认用 WSL2 作为后端它在 WSL2 里跑一个专用发行版docker-desktop来承载 Docker Engine你在 Windows 的 PowerShell 或 WSL 终端里都能用docker命令容器实际跑在 WSL2 内核上。场景容器内核来源普通 Linux 服务器跑 Docker宿主 Linux 内核Windows Docker Desktop(WSL2 后端)WSL2 的 Linux 内核WSL2 里直接装 Docker EngineWSL2 的 Linux 内核WSL1 里跑 Docker不行WSL1 无真实内核无 namespace/cgroup️ 二、方式一直接在 WSL 安装 Nginx先体验最朴素的安装方式和客户传统服务器一致,打开你的 WSL 终端依次执行sudo apt update sudo apt install -y nginx # 验证 nginx -v # nginx version: nginx/1.18.0 (Ubuntu) # Nginx 安装后通常自动启动了 curl http://localhost # 看到 !DOCTYPE html... Welcome to nginx! 说明 80 端口已在服务配置文件结构Ubuntu/Debian 系/etc/nginx/ ├── nginx.conf # 主配置文件全局设置 ├── sites-available/ # 可用的站点配置写在这里 │ └── fde-api # ← 我们要建的 └── sites-enabled/ # 已启用的站点放软链接到这里才生效 └── fde-api - ../sites-available/fde-api这种available enabled的两段式设计很经典配置写在 available想启用就在 enabled 里建个软链接快捷方式想下线删软链接即可配置文件本身不删。写反向代理配置# 以 root 权限用 nano 编辑器打开或新建一个名为 fde-api 的 Nginx 站点配置文件 sudo nano /etc/nginx/sites-available/fde-api写入server { listen 80; # Nginx 监听 80 端口 server_name localhost; # 域名/IP本地练习用 localhost # 所有请求/都转发给 FastAPI location / { proxy_pass http://127.0.0.1:8000; # ⭐ 核心转发目标 proxy_set_header Host $host; # 把原始域名带给后端 proxy_set_header X-Real-IP $remote_addr; # 真实客户端IP proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 原始协议 http/https } }启用 生效# ① 建软链接启用站点 sudo ln -s /etc/nginx/sites-available/fde-api /etc/nginx/sites-enabled/ # ② 删掉默认站点它也占 80 端口会冲突 sudo rm /etc/nginx/sites-enabled/default # ③ 测试配置语法改配置后必做 sudo nginx -t # nginx: configuration file /etc/nginx/nginx.conf test is successful # ④ 重载配置不断连接的平滑生效改完配置用 reload 而非 restart sudo systemctl reload nginx确保 FastAPI 在 8000 跑着用第 4 周学的 nohup或 docker 跑昨天的 api然后验证# 直接访问 80不带端口Nginx 转给 8000 的 FastAPI curl http://localhost/ # {msg:FDE Stack,...} curl http://localhost/health # {status:ok,db:connected}proxy_pass 与请求头逐项解释用户请求 Nginx :80 FastAPI :8000 http://localhost/ ─────────────proxy_pass─────────────► │ ├─ Host: $host │ 告诉后端用户原本访问的域名 │ 后端生成跳转链接时要用 │ ├─ X-Real-IP: $remote_addr │ 后端日志里记录的不再是 Nginx 的 IP │ 而是真实用户 IP审计、限流要用 │ └─ X-Forwarded-For / -Proto 经过的代理链、原始协议 为什么要传这些头经过反向代理后FastAPI 直接看到的来访者是 Nginx127.0.0.1不是真实用户。这些X-开头的请求头负责把原始信息一路带进去行业标准做法照抄即可。️ 三、方式二用容器跑 Nginx和 Compose 一体化推荐既然整个技术栈都容器化了Nginx 也应该进 Compose而不是装在宿主机上。这样整套环境还是一条 up 全起来。在昨天fde_stack的docker-compose.yml里加第三个服务# ---------- 服务 3Nginx 反向代理 ---------- nginx: image: nginx:alpine container_name: fde-nginx ports: - 80:80 # 对外只暴露 80 volumes: - ./nginx.conf:/etc/nginx/conf.d/default.conf # 挂载配置文件 depends_on: - api restart: unless-stopped新建nginx.conf注意容器版的转发地址写服务名 api不是 127.0.0.1# 定义后端服务器组负载均衡在这里配 upstream fde_backend { server api:8000; # api 是 Compose 服务名内部 DNS 解析 } server { listen 80; server_name localhost; location / { proxy_pass http://fde_backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }⚠️两种部署方式的转发地址区别极易错Nginx 装在宿主机、FastAPI 也在宿主机proxy_pass http://127.0.0.1:8000Nginx 在容器里、FastAPI 在另一个容器proxy_pass http://api:8000用服务名走 Compose 内部网络此时 api 服务不需要再把 8000 映射到宿主机可以删掉它的ports让它只通过内部网络供 Nginx 访问——更安全外部无法绕过 Nginx 直连 API。启动并验证docker compose up -d curl http://localhost/ # 走 80 → Nginx → api:8000 # {msg:FDE Stack,...}完整架构图用户浏览器 │ http://服务器地址80端口 ▼ ┌──────────────────┐ │ Nginx 容器 :80 │ ← 唯一对外暴露的入口 │ 反向代理 │ └────────┬─────────┘ │ proxy_pass内部网络服务名 api ┌────────▼─────────┐ ┌────────────────┐ │ FastAPI :8000 │ ───► │ MySQL :3306 │ │ 不对外暴露 │ │ 内部网络 │ └──────────────────┘ └────────────────┘ 对外只开一个 80 端口api/db 都藏在内部网络 四、负载均衡了解原理高频面试点upstream块的真正威力是后端有多台服务器时分发请求。假设你部署了 3 个 API 实例upstream fde_backend { # 默认轮询请求 1→api12→api23→api3循环 server api1:8000 weight3; # weight 权重分到的概率是别人的3倍 server api2:8000 weight1; server api3:8000 backup; # backup 备用前两台全挂了才启用 }Nginx ┌───────┼───────┐ ▼ ▼ ▼ api1 api2 api3 (权重3) (权重1) (备用) 常见调度策略 · 轮询默认 一个接一个均匀分发 · weight 加权轮询 性能强的机器多分点 · ip_hash 同一用户IP固定打到同一台会话保持 · least_conn 分给当前连接数最少的这块先理解原理小项目单实例用不上。但 FDE 遇到客户高并发、或要做灰度发布/多实例时就是这套配置。 Nginx 改配置的标准三步养成肌肉记忆改配置 →nginx -t测语法 → reload 平滑生效。永远不要不测试就 reload一个语法错误可能让整个站点挂掉。第二部分Git 版本控制 五、Git 解决什么问题先看没有 Git 的世界工单系统_最终版.doc 工单系统_最终版2.doc 工单系统_最终版_真的最终.doc 工单系统_最终版_真的最终_改.doc 工单系统_最终版_真的最终_改_给客户.doc ……代码同理。这种复制改名式版本管理有三个死穴看不出差异两个最终版到底改了哪几行回不去今天改坏了想退到上周能跑的版本难合不了你和同事同时改 main.py谁覆盖谁Git 是分布式版本控制系统每次提交都是一个带说明的存档点记录了那一刻所有文件的快照。你可以随时查看历史、对比差异、退回任意版本、开分支并行开发。提交commit就像游戏存档 ●────●────●────● 时间线 初始 加登录 修bug 加工单 ▲ ▲ └─ 任何时候都能读档回到这个点️ 六、Git 基础操作全流程git简介Git 是一个分布式版本控制系统由 Linus Torvalds 于 2005 年为管理 Linux 内核开发而创建。它的核心作用是记录代码/文件的历史变化支持多人协作并能随时回退到任意历史版本。核心特点分布式每个克隆都是完整仓库含全部历史可离线提交、查看历史不依赖中央服务器。快照式存储每次提交保存项目完整快照通过内容寻址去重存储上并不浪费而非逐版本存差异。内容寻址所有数据以 SHA-1/SHA-256 哈希为键存入对象库内容不可变天然防篡改。轻量分支分支只是一个指向提交的指针文件创建/切换极快鼓励频繁分支。完整性校验任何数据损坏或篡改都会导致哈希不匹配易于发现。强大的合并能力支持三方合并、变基、cherry-pick 等能处理复杂的并行开发。基本工作模型三个区域工作区、暂存区、仓库。提交历史构成有向无环图DAG合并提交有多个父节点。git原理Git 仓库的本质是一个键值存储key-value store。所有数据都以对象的形式保存在.git/objects目录下每个对象用其内容的 SHA-1或 SHA-256哈希值作为唯一键。四种对象类型对象类型作用存储内容blob存储文件内容只存文件字节不含文件名tree存储目录结构条目列表模式、类型、哈希、文件名commit存储一次提交指向一个 tree、父 commit 列表、作者/提交者、时间、消息tagannotated附注标签指向某对象、标签名、tagger、消息关键点blob 不含文件名。文件名和权限存在 tree 对象里。同样内容的不同文件只存一份 blob天然去重。tree 可以指向 blob 或其他 tree形成目录树。commit 指向一棵 tree该提交的完整快照根目录和零到多个父 commit。每个对象的内容一旦写入就不可变哈希值由内容决定。改一个字节哈希全变。对象如何存储对象先经 zlib 压缩再以objects/xx/yyyy...的松散对象形式存放前两位做目录。对象多了之后会打包成packfile.git/objects/pack/*.pack.idx使用 delta 压缩存储相似对象节省空间并加速传输。哈希计算Git 对对象做哈希时会在内容前加一个头类型 字节数\0再对整体求 SHA-1。所以blob、tree、commit的哈希空间互不冲突。安装安装 Git 的方法取决于你使用的操作系统。安装完成后通常还需要配置一下用户名和邮箱才能开始提交代码。Windows 系统最推荐的方式是从官网下载安装包或者使用包管理器。方式一安装包推荐访问 Git 官网下载页面 (git-scm.com/install/windows)下载最新的 64 位安装程序。双击运行安装包。安装过程中有多个选项对于大多数用户保持默认选项一路“Next”即可。关键一步在“Adjusting your PATH environment”界面建议选择中间的“Git from the command line and also from 3rd-party software”。这样你才能在 CMD 或 PowerShell 中直接使用git命令。安装完成后你可以在桌面或文件夹空白处右键选择 “Git Bash Here” 来打开 Git 终端。方式二命令行WinGet如果你习惯用命令行可以在 PowerShell 或 CMD 中运行以下命令winget install --id Git.Git -e --source wingetmacOS 系统macOS 上最简便的方法是使用 Xcode 命令行工具或 Homebrew。方式一Xcode 命令行工具最简单打开“终端”直接输入git --version。如果系统检测到未安装会自动弹窗提示你安装“命令行开发者工具”点击安装即可。方式二Homebrew如果你已经安装了 Homebrew运行以下命令即可安装最新版brew install gitLinux 系统直接使用你所用发行版的包管理器安装即可。Debian / Ubuntusudo apt install gitFedorasudo dnf install gitArch Linuxsudo pacman -S gitopenSUSEsudo zypper install gitGit 通常已经随系统或开发工具装好。先确认git --version # git version 2.34.x第 1 步一次性配置身份只做一次git config --global user.name 你的名字 git config --global user.email 你的邮箱example.com # 可选让默认分支名叫 main新版惯例 git config --global init.defaultBranch main # 查看配置 git config --list第 2 步初始化仓库cd ~/docker_lab/fde_stack # 进入你的项目目录 git init # Initialized empty Git repository in /home/fde/docker_lab/fde_stack/.git/这会建一个隐藏的.git/目录——Git 的全部历史和数据都存在这里面别动它。第 3 步写 .gitignore和 .dockerignore 同样重要新建.gitignore告诉 Git 哪些文件不纳入版本管理# Python __pycache__/ *.pyc venv/ .venv/ # 环境变量密码绝不提交 .env # 日志 *.log # 操作系统/IDE .DS_Store .vscode/ .idea/ # 数据库数据卷如果在本地目录 mysql_data/.env、密钥、venv、数据卷这些必须忽略密码进了 Git 历史尤其是推到 GitHub 公开仓库等于公开泄露venv 几百 MB 也不该进版本库别人用 requirements.txt 自己装。第 4 步查看状态、暂存、提交# ① 看状态哪些文件新增/修改/被忽略最高频命令随时敲 git status # ② 暂存add把改动放进购物车 git add . # 暂存所有改动 git add docker-compose.yml # 或只暂存指定文件 # ③ 提交commit把购物车的东西结账生成一个存档点 git commit -m feat: 初始化 FastAPIMySQLNginx 技术栈 # -m 后面是提交信息说清楚这次干了啥Git 的三个工作区核心模型为什么要多一个暂存区让你能挑选改动分批提交比如你一次改了 3 个文件其中 2 个是新功能、1 个是修 bug可以分两次 add commit历史更清晰。第 5 步查看历史与差异# 看提交历史 git log git log --oneline # 简洁版每个提交一行最常用 # a1b2c3d feat: 初始化 FastAPIMySQLNginx 技术栈 # d4e5f6g docs: 添加 README git log --oneline --graph # 图形化显示分支 # 看【还没暂存】的改动内容工作区 vs 暂存区 git diff # 看【已暂存】将被提交的内容 git diff --staged️ 七、分支平行宇宙式开发分支让你能在不影响主线的情况下开发新功能这是 Git 的灵魂。main主线始终保持可用 ●───────────●───────────●──────── \ ╱ ●──────●──────●────╱ feature/user-api功能分支在这折腾坏了不影响 main# 查看分支* 表示当前所在分支 git branch # * main # 创建并切换到新分支 git checkout -b feature/user-api # 等价于git branch feature/user-api git checkout feature/user-api # 新版也可以用git switch -c feature/user-api git branch # * feature/user-api # main # ……在分支上改代码、提交…… git add main.py git commit -m feat: 添加用户查询接口 # 切回主线工作区文件会变回 main 的样子 git checkout main # 把功能分支合并进 main git merge feature/user-api # 合并后删除功能分支已合并且不再需要 git branch -d feature/user-api常见分支约定了解即可分支用途main/master稳定可发布版本始终能跑develop团队开发集成线大项目feature/xxx开发新功能hotfix/xxx线上紧急修 bug FDE 个人项目最小工作流main保持可用 → 每个新功能开feature/xxx→ 做完测好合并回main→ 删分支。简单有效。️ 八、远程仓库GitHub/GitLab 协作与备份本地历史再全硬盘坏了也白搭。远程仓库既是云端备份又是多人协作中心。推送你的项目到 GitHub注册 GitHub 账号https://github.com建议装好 SSH key 或用凭据管理器在 GitHub 网页点New repository名字如fde-stack不要勾选初始化 README本地已有内容关联远程并推送# 给本地仓库添加远程地址惯例命名为 origin git remote add origin https://github.com/你的用户名/fde-stack.git # 第一次推送-u 把本地 main 和远程 main 关联以后直接 git push git push -u origin main # 以后提交完推送 git push协作三件套# 把远程最新改动拉下来并合并开工前先 pull避免冲突 git pull # 把别人的仓库完整克隆到本地含全部历史 git clone https://github.com/某人/某项目.git # 查看远程地址 git remote -v典型协作循环 ① git pull 先拉最新拿到同事的提交 ② 改代码 ③ git add / commit 本地存档 ④ git push 推上去 如果 push 被拒远程有新提交→ 先 pull 合并 → 再 push冲突conflict怎么处理你和同事改了同一文件的同一行Git 无法自动决定听谁的就会报冲突Auto-merging main.py CONFLICT (content): Merge conflict in main.py打开冲突文件会看到冲突标记 HEAD return {msg: 我的版本} ← 当前分支的内容 return {msg: 同事的版本} ← 要合并进来的内容 feature/xxx手动编辑删掉、、标记保留你想要的最终内容然后git add main.py git commit # 保存合并结果Git 会自动生成合并提交信息 九、后悔药常见撤销操作你想干嘛命令说明撤销工作区某文件的改动还没 addgit checkout -- main.py恢复成上次提交的样子改动丢失把文件移出暂存区add 错了git restore --staged main.py撤销 add改动还在工作区修改最近一次提交信息git commit --amend -m 新信息还没 push 时用撤销某次提交安全留痕git revert 提交ID生成一个反向提交抵消改动历史不被篡改回到历史版本危险git reset --hard 提交ID直接移动分支指针之后的提交消失revert vs reset 的区别重要 历史A ── B ── CC 是有问题的提交 git revert C A ── B ── C ── CC 是撤销C所做改动的新提交 历史完整保留安全适合已 push 的提交 ⭐ git reset --hard B A ── BC 直接从历史抹掉 改写历史只适合【没 push】的本地提交⚠️红线已经 push 到共享分支的提交不要用reset --hard 强制推送git push -f会把同事的提交搞丢。共享分支用revert。 本课小结Nginx 部分知识点一句话反向代理代理服务端用户不知道后端结构listen 80 / proxy_pass监听 80转发到内部 APIproxy_set_header传递真实 IP、域名等原始信息upstream定义后端服务器组负载均衡基础容器内转发地址写服务名api:8000不是 127.0.0.1改配置三步改 →nginx -t→reloadGit 部分知识点一句话git init初始化仓库.gitignore排除 venv/.env/日志add → commit先暂存后提交的两个区git status / log --oneline随时看状态和历史branch / checkout / merge开分支、切换、合并remote / push / pull / clone远程协作冲突手动编辑标记后 add commitrevert安全撤销加反向提交reset --hard危险回退仅限未 push 核心认知Nginx 是系统的统一门面对外只暴露 80/443内部服务藏在后面转发、负载、SSL、安全都在这一层处理。Git 是代码的时间机器 协作底座小步提交、分支隔离、远程备份是每个工程师的基本功。FDE 写的 Dockerfile、compose、脚本都应该进 Git。 课后练习练习 1Nginx 反向代理约 25 分钟在 Compose 栈中加入 nginx 服务和 nginx.confup -d启动用curl http://localhost/不带端口访问到 API故意把 proxy_pass 改成错误地址nginx -t还能通过吗reload 后访问现象是什么改回来尝试删掉 api 服务的ports: 8000:8000验证通过 Nginx 仍能访问但直接访问 localhost:8000 不通了练习 2Git 本地全流程约 30 分钟给 fde_stack 项目git init写好 .gitignore完成首次提交用git log --oneline查看创建feature/device-api分支给 main.py 加一个/devices/hot返回温度80的设备接口提交切回 main确认新接口消失了再 merge 分支确认它回来了删除功能分支练习 3推送到 GitHub约 20 分钟在 GitHub 新建仓库git remote add origin关联并push -u origin main在网页上确认文件都上去了并确认.env、venv没有被提交小实验删掉本地某个文件 →git status看到删除 →git checkout -- 文件名恢复 下节预告Docker、Compose、Nginx、Git 四样东西今天各自学了。明天是本周收官来一次完整的端到端实战把它们串成一条真实交付流水线Git 拉代码 → 配置环境变量 → Compose 构建 → 一键启动 APIMySQLNginx → curl 全链路验证 → 改代码后重新部署。你会得到一个可以放进作品集的完整项目结构并用一张大图把第 5 周知识全部串起来。明天见附录前置课程列表阶段一认知启蒙AI 认知与 FDE 角色AI 认知【FDE系列】阶段1Day 1AI 层级关系 — 四个嵌套的圈-CSDN博客【FDE系列】阶段1Day 2AI 三阶段发展史 — 会认 → 会判断 → 会创造-CSDN博客【FDE系列】阶段1Day 3符号 AI vs 机器学习 — 两条路线的本质区别-CSDN博客【FDE系列】阶段1Day 4Transformer 的历史意义 — 2017 年的分水岭-CSDN博客【FDE系列】阶段1Day 5本周复习与自测 — 检验你的 AI 认知地基-CSDN博客【FDE系列】阶段1Day 6Transformer 架构 — 一张图纸盖出千千万万栋楼-CSDN博客【FDE系列】阶段1Day 7LLM 本质 — 文字接龙机器-CSDN博客【FDE系列】阶段1Day 8Token — 模型眼中的最小单位-CSDN博客【FDE系列】阶段1Day 9AI 幻觉 — 为什么会一本正经地胡说八道-CSDN博客【FDE系列】阶段1Day 10上下文窗口 — 模型的记忆力上限 本周复习-CSDN博客【FDE系列】阶段1Day 11Prompt — 给模型立规矩-CSDN博客【FDE系列】阶段1Day 12Memory — 让模型记住上下文【FDE系列】阶段1Day 13RAG — 给模型配图书管理员-CSDN博客【FDE系列】阶段1Day 14Tool Use — 让模型动手操作-CSDN博客【FDE系列】阶段1Day 15MCP — 统一的工具接口标准 第三周复习-CSDN博客FDE 基础概念【FDE系列】阶段1Day 16什么是 FDE — 把 AI 变成客户结果的人-CSDN博客【FDE系列】阶段1Day 17FDE vs 传统实施 — 三大本质区别-CSDN博客【FDE系列】阶段1Day 18FDE 三重身份 C6 胜任力模型-CSDN博客【FDE系列】阶段1Day 19七阶段行动路径 行业经验的价值-CSDN博客【FDE系列】阶段1Day 20阶段总结与产出物 — 第一阶段收官-CSDN博客阶段二技术地基Python FastAPI SQL Docker API 集成Python基础【FDE系列】阶段2Day 21Python 环境搭建 — 写出你的第一行代码-CSDN博客【FDE系列】阶段2Day 22变量、数据类型、条件判断 — Python 的“记忆“和“判断“-CSDN博客【FDE系列】阶段2Day 23循环与函数 — 让代码跑 100 遍、把逻辑打包复用-CSDN博客【FDE系列】阶段2Day 24数据结构 — 列表、字典、集合、元组-CSDN博客【FDE系列】阶段2Day 25文件读写与 JSON — 让程序连通外部数据第一周收官-CSDN博客【FDE系列】阶段2Day 26模块化编程 — 把代码拆成“抽屉柜“-CSDN博客【FDE系列】阶段2Day 27异常处理与日志 — 让程序“摔不烂、查得到“-CSDN博客FastAPI入门到进阶【FDE系列】阶段2Day 28FastAPI 入门 — 把你的函数变成 API 服务-CSDN博客【FDE系列】阶段2Day 29FastAPI 进阶 — Pydantic 模型与完整 CRUD 实战-CSDN博客【FDE系列】阶段2Day 30生产代码规范 — 测试、类型注解、配置管理第二周收官-CSDN博客SQL基础【FDE系列】阶段2Day 31SQL 基础 — 增删改查一把梭-CSDN博客【FDE系列】阶段2Day 32多表查询 — JOIN 与聚合-CSDN博客【FDE系列】阶段2Day 33进阶查询 — 窗口函数与 CTE-CSDN博客【FDE系列】阶段2Day 34数据清洗 — 把脏数据捋干净-CSDN博客【FDE系列】阶段2Day 35Python SQL — 工单接入 MySQL 本周收官-CSDN博客Linux基础【FDE系列】阶段2Day 36Linux 入门与文件操作 — 扔掉鼠标的第一天-CSDN博客【FDE系列】阶段2Day 37权限、进程与文本三剑客-CSDN博客【FDE系列】阶段2Day 38Shell 脚本 — 把命令串起来自动跑-CSDN博客【FDE系列】阶段2Day 39Linux 综合实战 — 让服务无人值守-CSDN博客【FDE系列】阶段2Day 40Shell 进阶 — 生产级脚本与本周收官-CSDN博客Docker【FDE系列】阶段2Day 41Docker 入门 — 把环境装进盒子-CSDN博客【FDE系列】阶段2Day 41up详细版Docker 入门 — 把环境装进盒子-CSDN博客【FDE系列】阶段2Day 42Dockerfile 实战 — 把你的应用打包成镜像-CSDN博客【FDE系列】阶段2Day 42UP详细版Dockerfile 实战 — 把你的应用打包成镜像-CSDN博客【FDE系列】阶段2Day 43Docker Compose — 多容器一键编排-CSDN博客【FDE系列】阶段2Day 43UP详细版Docker Compose — 多容器一键编排-CSDN博客