程序小白概念扫盲手册

配套学习资料,建议与《小白入门-GitHub项目部署使用指南.md》一起看 整理日期:2026/05/01


📚 阅读说明 & 配套资料

本手册是知识地图——告诉你”每个名词是什么、它们之间什么关系”。

同目录下还有两份配套资料:

文件定位什么时候看
📗 本文件(概念扫盲手册)知识地图:名词、原理、关系想搞懂”是什么”时
📘 小白入门-GitHub项目部署使用指南.md实操手册:流程、命令、踩坑想动手做”怎么做”时
🃏 五看一跑_小白工程运行部署学习文档.md速查卡:30 秒口令记忆版临时回忆流程时

推荐阅读路径:

第一次接触 → 第零章(全景图)          ← 你在这里!先看这一章建立全局观
              │
              ▼
        《部署使用指南》动手实操
              │
              ▼
        遇到陌生名词时 → 回本手册查对应章节
              │
              ▼
        想深挖某个工具 → 看本手册第 1~10 章

📌 第零章是本手册的”地图章”——它会告诉你后面 1~10 章每个概念属于”软件流水线”的哪一段,帮你快速定位。


目录


第零章:软件工程知识全景图(按使用场景)

在学具体名词之前,先看一张地图。 这张地图的目标:让你知道每个工具属于流水线的哪一段,以及哪些是必学的,哪些可以先跳过


0.1 全景图:写代码到上线的完整流水线

把”做一个软件”想象成开一家面包店做面包再上架卖。整个流水线分 7 段:

你(人)
 │
 │ ① 在编辑器里敲代码        ← 写菜谱
 ▼
[ 场景 1:写代码 ]
   编辑器 + 编程语言 + 框架
 │
 │ ② 改了的代码要存档、能回退  ← 把每天的菜谱版本归档
 ▼
[ 场景 2:管理代码版本 ]
   Git + GitHub
 │
 │ ③ 我的菜谱要用别人调好的酱料 ← 不重复造轮子
 ▼
[ 场景 3:管理依赖 ]
   npm / pnpm / yarn / pip
 │
 │ ④ 试做一份在自己厨房吃         ← 本地能跑
 ▼
[ 场景 4:本地启动 & 调试 ]
   Node.js / Python 解释器 + 开发服务器
 │
 │ ⑤ 把生鲜原料做成可以装盒的成品  ← 打包压缩、优化
 ▼
[ 场景 5:构建 & 打包 ]
   Vite / Webpack / TypeScript 编译器
 │
 │ ⑥ 把成品放到店里让顾客买       ← 上线让别人能用
 ▼
[ 场景 6:部署上线 ]
   Vercel / Nginx / Docker / Cloud
 │
 │ ⑦ 整个面包店运转的水电煤       ← 隐藏在最底下
 ▼
[ 场景 7:底层支撑(默默工作)]
   操作系统 + 文件系统 + 网络 + 硬件

📌 关键认知:你不需要每段都精通。小白阶段只需要知道每个工具属于哪一段,会用前 4 段足够搞定 80% 的事。


0.2 场景 1:写代码

这一段在干啥: 用编辑器把你的想法变成代码文件。

工具全称/类型你的关系学习深度
VS Code / Cursor编辑器(IDE = Integrated Development Environment,集成开发环境)🔥 高频天天用必学(基本操作)
JavaScript / TypeScript编程语言🔥 高频必学(前端方向)
Python编程语言🔥 高频必学(数据/AI 方向)
React / Vue前端框架🌤️ 看方向选学(前端方向必学一个)

📌 VS Code vs Cursor:VS Code 是微软出的免费编辑器(最流行);Cursor 是基于 VS Code 改的 AI 编辑器,内置 GPT/Claude 协助写代码。新手先用 VS Code 即可

类比: 编辑器=厨房工作台,语言=做菜的语法,框架=半成品调料包

给小白的建议:

  • 装一个 VS Code 或 Cursor,先用熟”打开文件夹、搜索、分屏”这几个动作
  • 编程语言不要贪多,挑一门主攻(前端选 JS/TS,数据选 Python)

0.3 场景 2:管理代码版本

这一段在干啥: 给代码做”时间机器”——能回退、能多人协作、能看谁什么时候改了什么。

工具类型你的关系学习深度
Git版本控制软件(本地)🔥 高频必学 4 个命令:clone / pull / commit / push
GitHub代码托管平台(云端)🔥 高频必学(注册账号、看 README)
GitLab / GiteeGitHub 的同行🌤️ 看公司了解(用法基本一样)

类比: Git=单机存档系统,GitHub=云端的”游戏存档备份服务器”

给小白的建议:

  • 第一个月只学 4 个核心命令:clone(下载项目)、pull(更新代码)、commit(保存版本)、push(推到云端)。够用。
  • 看到 branch(分支)、merge(合并)、merge conflict(合并冲突)这些词不用慌——它们是协作场景才需要的进阶概念,本手册第十二章会讲,现在路过即可。

0.4 场景 3:管理依赖

这一段在干啥: 你写代码时不会从零造轮子,会用别人写好的”包”(包 = package = 别人封装好的一组功能代码,类似 Word 里的”插件”),比如:

  • react(前端框架,组件化写网页)
  • axios(处理网络请求的工具库)
  • numpy(Python 数据计算库,AI 必备)
  • lodash(JavaScript 工具函数集合)

“包管理器” 就是负责下载、安装、更新这些包的工具。

工具全称用于哪种语言你的关系
npmNode Package ManagerJavaScript / Node.js🔥 装 Node 自带
pnpmperformant npm同 npm(替代品)🌤️ 性能更好
yarnYarn同 npm(替代品)🌤️
pipPip Installs PackagesPython🔥
poetry / uv现代 Python 包管理Python(替代 pip)🌤️
Maven / Gradle-Java看方向

类比: 包管理器 = 应用商店;锁文件(lock 文件)= 你装了哪些 App 的清单

给小白的建议:

  • 跟语言走:写 JS 学 npm,写 Python 学 pip
  • 进阶后可以试试 pnpm(节省磁盘)

0.5 场景 4:本地启动 & 调试

这一段在干啥: 把你写的代码在自己电脑上跑起来,看效果、改 bug。

工具类型你的关系
Node.jsJavaScript 运行环境🔥 写 JS 必装
Python 解释器Python 运行环境🔥 写 Python 必装
Vite Dev Server前端开发服务器(HMR = Hot Module Replacement,热模块替换:保存代码后浏览器自动刷新看到效果)🔥
浏览器开发者工具调试网页(按键盘上的 F12 键打开,或者右键页面 → “检查”)🔥 必学
VS Code 调试器断点调试(在某行代码”打断点”,程序运行到那一行会暂停,让你查看变量)🌤️ 进阶必学

类比: 运行时 = 给代码”装发动机”;开发服务器 = 试车场;调试器 = 透视眼镜

给小白的建议:

  • 学会按 F12 打开浏览器开发者工具——它能让你看到网页背后所有秘密(HTML 结构、网络请求、报错信息)
  • npm run dev 启动后浏览器看效果,是前端最高频操作

0.6 场景 5:构建 & 打包

这一段在干啥: 你写的源代码(TS、JSX、SCSS 等”高级写法”)浏览器看不懂,需要”翻译+压缩+打包”成浏览器认识的 HTML/JS/CSS。

📌 这几个缩写是啥?

  • TS(TypeScript)= JavaScript + 类型,写起来更安全
  • JSX(JavaScript XML)= JS 里直接写 HTML 标签的语法(React 用),如 <div>{name}</div>
  • SCSS(Sassy CSS)= CSS 的增强版,可以嵌套、定义变量 这些都是”开发友好但浏览器不认识”的语法,必须经过构建工具转换。
工具类型你的关系
Vite新一代构建工具🔥 现代项目主流
Webpack老牌构建工具🌤️ 看到能认出即可
esbuild / Rollup / SWC底层打包/转译器隐藏(被 Vite 调用)
TypeScript 编译器 (tsc)TS → JS🔥(写 TS 必用)
BabelJS 新语法 → 老语法隐藏

类比: 构建工具 = 食品加工厂(生鲜原料 → 真空包装预制菜)

给小白的建议:

  • 不需要懂构建工具的内部原理——会用 npm run build 即可
  • 看到 vite.config.ts 这种文件,知道是配置即可,不用立刻全看懂

0.7 场景 6:部署上线

这一段在干啥: 把成品挂到公网,让别人能访问。

工具类型你的关系学习优先级
Vercel / Netlify一键部署平台🔥 推荐先学⭐⭐⭐⭐⭐
GitHub Pages免费静态托管🌤️⭐⭐⭐⭐
NginxWeb 服务器🌤️ 自己有服务器才用⭐⭐⭐
Docker容器化部署🌤️ 中级开始学⭐⭐⭐
Kubernetes (K8s)容器编排❄️ 几乎用不到
AWS / 阿里云 / 腾讯云云服务器🌤️ 看公司⭐⭐

类比: Vercel = 全自动印刷+上架;自己服务器+Nginx = 自己开店;Docker = 集装箱搬家

给小白的建议:

  • 第一个项目用 Vercel 部署,几分钟搞定
  • Docker 等做过 2~3 个项目再学,不然概念太抽象
  • K8s 很久以后再考虑,多数人一辈子用不上

0.8 场景 7:底层支撑(默默工作的)

这一段在干啥: 上面所有工具都跑在这一层之上。你看不见它,但它无处不在。

概念类型你的关系
操作系统(macOS / Linux / Windows)OS🔥 你电脑就是
文件系统(硬链接、软链接、权限)OS 子系统隐藏
网络(端口、TCP/IP、DNS)OS 子系统偶尔接触
进程 / 线程OS 概念偶尔接触
CPU / 内存 / 磁盘硬件完全隐藏

类比: 这层是面包店的”水电煤气”——你不用懂电网怎么发电,但断电了得知道找谁修

给小白的建议:

  • 只需要知道有这层,遇到问题(比如端口被占、权限不够)能联想到这一层即可
  • 进阶后可以学一点 Linux 命令(cd / ls / cat / grep),受益终身

0.9 学习优先级总表(小白照着学)

优先级工具/概念备注
🥇 第 1 阶段(前 1 个月)编辑器 + 1 门语言 + Git 4 命令 + npm/pip + F12能跑通”clone + install + run” 流程
🥈 第 2 阶段(1~3 个月)1 个框架(React/Vue 选一)+ Vercel 部署能做出小作品并上线给朋友看
🥉 第 3 阶段(3~6 个月)TypeScript + Vite 配置 + 调试器 + Linux 基础能解决大部分常见问题
🏅 第 4 阶段(6 个月+)Docker + Nginx + 后端语言 + 数据库能独立完成全栈项目
🎖️ 进阶(1 年+)K8s + 云服务 + 微服务转向工程师/架构师方向

0.10 这张全景图能帮你回答的几个问题

Q1:我看到一个新名词,怎么知道它是干啥的? → 套进上面 7 个场景里找它的位置。比如听到 “esbuild”,发现它在场景 5 里 → 哦,是构建工具的一种。

Q2:学这个东西有没有意义? → 看它在哪个阶段、对应哪个场景。如果你才第 1 阶段,碰到 K8s 直接跳过即可。

Q3:这个工具/那个工具到底有什么区别? → 大概率是同一场景里的同行。npm/pnpm/yarn 都在场景 3,互相替代。Vercel/Nginx/Docker 都在场景 6,但侧重不同。

Q4:我老是觉得”东西太多学不完”怎么办? → 因为你试图同时学所有场景。按场景顺序学:先跑通 1→2→3→4,能让代码动起来再说。


0.11 给小白的 3 个心法

  1. 不必”全栈”:知道每一层的”边界”和”接口”就够了,不用每层都精通
  2. 跟着项目学:纯看概念会疲劳,做一个具体项目,碰到啥学啥
  3. 学会”识别同行”:看到陌生工具先问”它是哪个场景的?跟我已知的哪个相似?“

第一章:核心名词关系梳理

1.1 node、Node.js、npm、npx 的关系

名词全称是什么类比
Node.js(没有缩写,就叫 Node.js)一个让 JavaScript 能在电脑上直接跑的运行环境给 JS 装了个”发动机”
nodeNode.js 自带的命令行工具你在终端敲的那个命令,比如 node app.js发动机的”启动按钮”
npmNode Package ManagerNode.js 的包管理器,装 Node 时自带应用商店(装/管理依赖)
npxNode Package execute临时执行一个包,不用先安装一次性试用某个工具

关系图:

装 Node.js
   │
   ├─→ 自动有了 node 命令(运行 JS 文件)
   ├─→ 自动有了 npm 命令(管理依赖)
   └─→ 自动有了 npx 命令(临时执行)

举例对比:

  • node app.js → 用 Node 直接执行 app.js 这个文件
  • npm install react → 把 react 这个包装到当前项目
  • npx create-react-app my-app → 临时调用 create-react-app 工具创建项目,用完不留

📌 提示:除了 npm,还有两个常见的”同行”——pnpmyarn,它们都是包管理器,详见下一节。


1.2 三大包管理器:npm vs pnpm vs yarn

JS 世界里管理依赖的工具有三个主流选手,它们干的事一样,但实现方式和速度不同

各自介绍

工具全称出品方出现时间一句话特点
npmNode Package ManagerNode.js 官方2010最老、最通用,装 Node 自带
yarn(非缩写,就叫 Yarn,“纱线”之意)Facebook2016主要为了解决早期 npm 的速度和锁文件问题
pnpmperformant npm(高性能 npm)社区(Zoltan Kochan)2017用”硬链接”省磁盘空间,速度最快

核心差异:怎么存依赖

npm / yarn 的做法(传统):

项目A/node_modules/react/...     ← 一份完整副本
项目B/node_modules/react/...     ← 又一份完整副本
项目C/node_modules/react/...     ← 又又一份完整副本

→ 同一个包在每个项目里都装一份,磁盘空间浪费严重(动辄几个 GB)

pnpm 的做法(创新):

全局仓库 ~/.pnpm-store/
   └─ react/v19.1.0/...     ← 全局只存一份真实文件

项目A/node_modules/react   → 硬链接到全局
项目B/node_modules/react   → 硬链接到全局
项目C/node_modules/react   → 硬链接到全局

同一个版本的包全局只存一份,省磁盘 + 安装快

速度与磁盘占用对比

场景npmyarnpnpm
首次安装速度🐢 慢🐰 中🚀 快
二次安装(已有缓存)🐰 中🚀 快⚡ 极快
磁盘占用小(约为 1/3)
处理依赖冲突一般一般严格(更安全)

命令对照表(功能基本一一对应)

操作npmyarnpnpm
安装所有依赖npm installyarnpnpm install
安装某个包npm install reactyarn add reactpnpm add react
安装开发依赖npm install -D viteyarn add -D vitepnpm add -D vite
卸载包npm uninstall reactyarn remove reactpnpm remove react
全局安装npm install -g xxxyarn global add xxxpnpm add -g xxx
运行脚本npm run devyarn devpnpm dev
临时执行npx <命令>yarn dlx <命令>pnpm dlx <命令>

📌 小白记忆:如果会用 npm,把 npm install 改成 pnpm install 就能用 pnpm,几乎没有学习成本。

锁文件区别

先解释什么是”锁文件”

  • 你的 package.json 只写了”我要 react”——没说要哪个版本
  • 但实际安装时 npm 会下载精确到某个版本号的 react(比如 19.1.0)
  • “锁文件”就是把这次实际下载的所有依赖精确版本号都记下来,下次别人在不同电脑装时也能装到一模一样的版本,避免”在我电脑能跑,你电脑不行”

每个包管理器都有自己的”锁文件”:

工具锁文件
npmpackage-lock.json
yarnyarn.lock
pnpmpnpm-lock.yaml

📌 重要规则:一个项目只用一个包管理器,不要混用!否则会有多个锁文件互相冲突。 看到项目里有哪个锁文件,就说明作者用的是哪个。

怎么判断一个项目用哪个?

打开项目根目录看锁文件:

  • 看到 pnpm-lock.yaml → 这项目用 pnpm,你也应该用 pnpm install
  • 看到 yarn.lock → 这项目用 yarn,你也应该用 yarn
  • 看到 package-lock.json → 这项目用 npm,用 npm install

你这个 gpt_image_playground 项目里只有 package-lock.json,所以是用 npm 的。

怎么安装 pnpm?

pnpm 不是 Node 自带的,需要单独装。三种方式任选:

# 方式 1:用 npm 装 pnpm(最常见)
npm install -g pnpm
 
# 方式 2:用 Homebrew 装(macOS)
brew install pnpm
 
# 方式 3:用官方脚本(不依赖 Node)
curl -fsSL https://get.pnpm.io/install.sh | sh -

验证安装:

pnpm -v   # 显示版本号即装好

实战建议(小白选择)

情况建议
跟着教程学习教程用啥你用啥,别折腾
自己新项目推荐 pnpm(快、省空间、严格)
公司项目看团队约定,统一即可
改别人的开源项目看锁文件用对应工具

同类对照(拓展)

其他语言也有自己的包管理器,思路一样:

语言主流包管理器
JavaScript / Node.jsnpm / pnpm / yarn
Pythonpip / poetry / uv
JavaMaven / Gradle
Rustcargo
Gogo mod
PHPcomposer
Rubygem / bundler

1.3 React、Vite、src 的关系

名词是什么干啥用
ReactFacebook(现 Meta)开源的前端框架用来写交互式网页的”脚手架”
Vite一个前端构建工具(Vue 作者尤雨溪开发)启动开发服务器、把代码打包成可发布的网站。读音类似”vee-t”
srcsource 的缩写项目源代码文件夹(约定俗成的命名)

协作关系:

你在 src/ 里用 React 写代码
           │
           ▼
     Vite 帮你把代码
       「启动起来」(npm run dev)
       或「打包出来」(npm run build)
           │
           ▼
     浏览器能打开的网页

类比:

  • React 是”乐高积木”(提供组件化能力)
  • Vite 是”组装+装箱机器”(开发时调试 + 打包发布)
  • src 是”放积木的工作台”(代码存放位置)

1.4 同类竞品对照

前端框架(React 的同行)

框架出品方特点
ReactMeta(Facebook)最流行,生态丰富
Vue尤雨溪中文文档好,国内流行
AngularGoogle企业级,学习曲线陡
Svelte社区新生代,编译时优化

构建工具(Vite 的同行)

工具特点
Vite新一代,开发启动极快
Webpack老牌,配置复杂但功能全
Rollup适合做库
esbuildGo 写的,速度极快

第二章:开源协议(MIT 等)

2.1 MIT 协议是啥

MIT = Massachusetts Institute of Technology(麻省理工学院)

这是一份只有几百字、最宽松的开源协议。核心规则只有两条:

  1. 你可以随便用:商用、改、卖、闭源、做衍生品都可以
  2. ⚠️ 必须保留原作者的版权声明:在你的代码里要带上原协议文字

2.2 常见开源协议对比

协议宽松度主要限制典型项目
MIT⭐⭐⭐⭐⭐ 最宽松几乎没有限制React、Vue
Apache 2.0⭐⭐⭐⭐ 宽松多了”专利授权”条款Kubernetes、Android
BSD⭐⭐⭐⭐⭐ 宽松类似 MITFreeBSD
MPL 2.0⭐⭐⭐ 中等修改的文件必须开源Firefox
LGPL⭐⭐ 较严格修改后开源,但可被闭源软件链接调用部分库
GPL v3⭐ 严格用了就必须开源你自己的代码(“传染性”)Linux、Git
AGPL v3最严格GPL + 网络服务也要开源MongoDB(旧版)、Ghost

2.3 实战判断

你的需求建议选择
商业产品想用别人的代码选 MIT、Apache、BSD
自己开源不想被白嫖选 GPL、AGPL
写一个开源库给别人用选 MIT(最受欢迎)

📌 小白记忆:看到 MIT License = 放心用,标个原作者名字就行。


第三章:Fork 与 GitHub 协作

3.1 Fork 是啥

Fork(叉子的”叉”,引申为”分叉”)

在 GitHub 语境里 = 把别人的仓库”复制一份”到你自己的账号下,从此与原仓库平行存在。

3.2 典型工作流

  1. 你看到 cooksleep/gpt_image_playground 想改改
  2. 点右上角 Fork → 仓库变成 你的用户名/gpt_image_playground
  3. git clone 到本地,随便改自己 fork 出来的版本,不影响原作者
  4. 改好后推回自己的远程仓库
  5. 如果改得好,可以发 Pull Request(PR) 请求原作者把你的修改合并回去

关系图:

原作者仓库(upstream / 上游)
        │
        │ Fork(云端 → 云端)
        ▼
  你的远程仓库(origin)
        │
        │ git clone(云端 → 本地)
        ▼
  你的本地电脑
        │
        │ 修改代码 + git push
        ▼
  你的远程仓库(origin)
        │
        │ Pull Request
        ▼
  原作者审核,决定是否合并

3.3 关键概念区分

操作发生在哪干啥
ForkGitHub 网站复制别人的仓库到自己账号
Clone命令行把远程仓库下载到本地电脑
Pull命令行同步远程最新代码到本地
Push命令行把本地修改推到远程
Pull Request (PR)GitHub 网站请求别人合并你的修改
Sync ForkGitHub 网站同步原作者最新代码到你的 fork

📌 类比:Fork 像”把书从图书馆复印一本回家”,可以在复印件上随便涂改。

💡 想立刻学 Git 命令实战? → 跳到 第十二章:Git 常用命令实战图解(按学习节奏,看完本章 Fork 概念后立刻学第十二章最自然)。


第四章:终端命令参数详解

4.1 通用规则

终端命令里以 - 开头的叫选项(option)标志(flag)

  • 单字母 → 用一个 -,如 -d
  • 完整单词 → 用两个 --,如 --detach
  • 很多参数有”短写 + 长写”两种形式:-d 等同于 --detach

重要原则:同一个字母在不同命令里含义不同! 不能死记硬背,要看上下文。

查任意命令的所有参数:

<命令> --help
# 例如
docker run --help
git clone --help

4.2 Docker 常用参数速查

参数全称含义
-f--file指定文件路径
-t--tag给镜像打标签/起名字
-d--detach后台运行(脱离终端)
-p--publish端口映射(外部端口:容器端口)
-v--volume文件夹挂载(外部路径:容器路径)
-e--env设置环境变量
-i--interactive交互模式(保持 stdin 打开)
--name(无简写)给容器起名字(不是镜像)
--rm(无简写)容器停止后自动删除

4.3 其他常见命令参数(拓展)

Git 常用参数

参数含义
-m写提交信息(git commit -m "msg"
-b创建并切换分支(git checkout -b new-branch
--all所有分支/所有内容

Linux 通用命令参数

参数在 ls / cp / rm 里的含义
-lls:长格式列表
-als:显示隐藏文件
-rrm/cp:递归(处理文件夹)
-frm:强制删除不询问
-v多数命令:详细输出(verbose)

📌 同一个 -fdocker build 里是”指定文件”,在 rm 里是”强制”,含义完全不同!


第五章:Docker 使用与管理

💡 小白提示:本章假设你已经知道”Docker 是什么”——如果你看完第二部分还不太理解 Docker 的概念(容器、镜像),建议先看第七章「容器与容器化部署」,理解概念再回到这里学命令。 阅读顺序建议:第七章(概念) → 第五章(操作) → 第十章(深入:pnpm + Docker)

5.1 用完了要不要关闭?要不要卸载?

容器层面(你跑的那个程序)

用完不需要刻意关,但建议关掉——容器会一直在后台占内存。

# 查看正在运行的容器
docker ps
 
# 查看所有容器(包括已停止的)
docker ps -a
 
# 停止某个容器(替换 ID 或名字)
docker stop <容器ID或名>
 
# 删除已停止的容器
docker rm <容器ID或名>
 
# 删除镜像(如果以后不用了)
docker rmi <镜像>

操作流程:

  1. 用完 → docker stop 停止容器
  2. 不再用了 → docker rm 删容器,再 docker rmi 删镜像

Docker Desktop(这个软件本身)

情况建议
短期内还会用不卸载,但可以”退出 Docker Desktop”(菜单栏图标右键 → Quit),它就不占内存了
几个月用不上可以卸载,下次需要时再装

Docker Desktop 的代价:

  • 后台一直占 1~2GB 内存
  • macOS 上还会建一个虚拟机(Linux 容器需要 Linux 内核)
  • 启动慢

📌 建议:不用的时候就 Quit,别留着它跑。

5.2 Docker 完整生命周期命令

# === 镜像层面 ===
docker build -t <镜像> .          # 构建镜像
docker images                       # 列出所有镜像
docker rmi <镜像>                  # 删除镜像
docker pull <镜像>                 # 从远程仓库拉镜像
docker push <镜像>                 # 推送镜像到远程仓库
 
# === 容器层面 ===
docker run -d -p 8080:80 <镜像>   # 启动容器
docker ps                           # 查看运行中的容器
docker ps -a                        # 查看所有容器(含已停止)
docker stop <容器>                 # 停止容器
docker start <容器>                # 启动已停止的容器
docker restart <容器>              # 重启容器
docker rm <容器>                   # 删除容器
docker logs <容器>                 # 查看容器日志
docker exec -it <容器> bash        # 进入容器内部

5.3 清理一切(节省磁盘)

# 删除所有已停止的容器
docker container prune
 
# 删除所有未使用的镜像
docker image prune -a
 
# 删除所有未使用的资源(容器+镜像+网络+卷)
docker system prune -a

第六章:Nginx 是什么

6.1 基本介绍

Nginx(读音:engine-x,“引擎 X”),开源的 Web 服务器

它具体干啥?简单说,三件事:

1. 提供静态文件服务(最常见)

你浏览器访问 https://example.com/index.html,Nginx 就把服务器上的 index.html 文件发给你。

浏览器请求 /index.html
        │
        ▼
    Nginx 监听 80/443 端口
        │
        ▼
   读取文件返回给浏览器

2. 反向代理(Reverse Proxy)

把请求转发到后端的另一个程序。比如:

  • 浏览器访问 /api/xxx → Nginx 转发到后端 Node.js 服务(端口 3000)
  • 浏览器访问 / → Nginx 直接返回前端 HTML

3. 负载均衡(Load Balancing)

如果一个服务有 5 台服务器,Nginx 可以把请求轮流分配给它们,减轻单台压力。

6.2 在 gpt_image_playground 项目里的角色

deploy/Dockerfiledeploy/nginx.conf

  1. Vite 构建出静态文件(HTML/JS/CSS)放在 dist/
  2. Docker 镜像里装了 Nginx
  3. Nginx 用配置文件 nginx.conf 监听端口
  4. 用户访问时,Nginx 把 dist/ 里的文件返回出去
  5. 还能做”API 代理”,把 /api-proxy/ 开头的请求转发到 OpenAI

📌 类比:Nginx 是餐厅的”传菜员+迎宾员”——它不做菜(不跑代码),只负责把菜(静态文件)端给客人,或者把客人引到对应的房间(反向代理)。

6.3 同行竞品

名字特点
Nginx高性能、配置简单,最流行
Apache老牌、功能多但配置复杂
Caddy自动 HTTPS,新一代选手
Traefik容器友好,K8s 常用

第七章:容器与容器化部署

7.1 容器是什么

容器(Container)= 隔离的、独立的运行环境

最直观的类比:集装箱

  • 海运集装箱发明前:货物千奇百怪,装船麻烦、容易损坏
  • 集装箱发明后:所有货物先装进标准集装箱,船、卡车、火车都能直接搬

软件世界的”集装箱”:

  • 容器化前:软件依赖五花八门,部署到不同机器经常出问题(“在我电脑上能跑啊!”)
  • 容器化后:软件 + 依赖打包成集装箱,到哪都能跑

7.2 容器 vs 虚拟机

对比项虚拟机 (VM)容器 (Container)
隔离级别完整操作系统共享主机的内核,只隔离应用
启动速度几十秒~几分钟几秒
占用资源GB 级MB 级
性能开销较大几乎没有
类比一栋独立别墅公寓里的一户人家

7.3 容器化部署的好处

  1. 环境一致:“开发环境能跑,生产环境也能跑”
  2. 快速搬家:一个 docker pull 就能在新机器上跑起来
  3. 资源利用高:一台服务器能跑几十上百个容器
  4. 方便扩展:流量大了?再启动 5 个一样的容器分担
  5. 版本回滚快:出问题了切回旧镜像即可

7.4 容器化部署完整流程

开发阶段:
   写代码 → 写 Dockerfile → docker build → 得到镜像
                                              │
发布阶段:                                     │
   docker push → 把镜像传到镜像仓库(如 Docker Hub)
                                              │
                                              ▼
部署阶段:
   服务器上 docker pull 拉镜像 → docker run 启动容器 → 服务上线
                                              │
                                              ▼
更新阶段:
   改代码 → 重新 build 新镜像 → 新版本号 → push → 服务器 pull → 替换旧容器

7.5 容器生态名词扫盲

名词全称/中文是什么
Docker(专有名词)最流行的容器化工具
Docker Hub-Docker 官方的镜像仓库(类似”应用商店”)
Image镜像静态的、可分发的容器模板
Container容器镜像启动后的实例(在运行的程序)
Dockerfile(专有名词)描述如何构建镜像的文本文件
K8sKubernetes容器编排工具(管理几百上千个容器)
Composedocker-compose一次启动多个相关容器(如 web + 数据库)
Registry镜像仓库存储/分发镜像的服务(Docker Hub、阿里云ACR等)
Layer镜像由多个只读层叠加而成,可复用以省空间

第八章:常用缩写完整对照表

8.1 编程相关

缩写全称中文
npmNode Package ManagerNode 包管理器
pnpmperformant npm高性能 npm(节省磁盘的包管理器)
yarn(非缩写,Yarn = “纱线”)Facebook 出的包管理器
npxNode Package executeNode 包执行器
MITMassachusetts Institute of Technology麻省理工学院(开源协议名)
HTMLHyperText Markup Language超文本标记语言
CSSCascading Style Sheets层叠样式表
JSJavaScriptJavaScript(注意:和 Java 没关系)
TSTypeScriptTypeScript(JS 的超集,加了类型)
JSONJavaScript Object NotationJS 对象表示法(数据格式)
XMLeXtensible Markup Language可扩展标记语言
YAMLYAML Ain’t Markup Language(递归缩写)配置文件格式
MDMarkdown轻量级标记语言

8.2 网络相关

缩写全称中文
APIApplication Programming Interface应用程序接口
URLUniform Resource Locator统一资源定位符(网址)
URIUniform Resource Identifier统一资源标识符
HTTPHyperText Transfer Protocol超文本传输协议
HTTPSHTTP Secure加密的 HTTP
TCPTransmission Control Protocol传输控制协议
UDPUser Datagram Protocol用户数据报协议
IPInternet Protocol网络协议(也指 IP 地址)
DNSDomain Name System域名系统
CDNContent Delivery Network内容分发网络
SSL/TLSSecure Sockets Layer / Transport Layer Security安全协议
RESTREpresentational State Transfer一种 API 设计风格
CORSCross-Origin Resource Sharing跨域资源共享

8.3 工具与平台

缩写全称中文
SDKSoftware Development Kit软件开发工具包
CLICommand Line Interface命令行界面
GUIGraphical User Interface图形用户界面
IDEIntegrated Development Environment集成开发环境
OSOperating System操作系统
VMVirtual Machine虚拟机
K8sKubernetes(中间 8 个字母)容器编排平台
CI/CDContinuous Integration / Continuous Deployment持续集成/持续部署
DevOpsDevelopment + Operations开发运维一体化

8.4 GitHub / 协作相关

缩写全称中文
PRPull Request拉取请求(提合并)
MRMerge Request合并请求(GitLab 叫法,等同 PR)
MVPMinimum Viable Product最小可行产品
TODO(非缩写,“to do”)待办事项标记
FIXME(非缩写,“fix me”)待修复标记
WIPWork In Progress进行中的工作
LGTMLooks Good To Me看起来不错(同意合并)

8.5 前端常用

缩写全称中文
PWAProgressive Web App渐进式网页应用
SPASingle Page Application单页应用
SSRServer-Side Rendering服务端渲染
CSRClient-Side Rendering客户端渲染
HMRHot Module Replacement热模块替换(保存即刷新)
DOMDocument Object Model文档对象模型
AJAXAsynchronous JavaScript And XML异步 JS 与 XML(异步请求技术)
SEOSearch Engine Optimization搜索引擎优化
UIUser Interface用户界面
UXUser eXperience用户体验

8.6 数据库相关

缩写全称中文
SQLStructured Query Language结构化查询语言
DBDatabase数据库
RDBMSRelational Database Management System关系型数据库管理系统
ORMObject-Relational Mapping对象关系映射
CRUDCreate Read Update Delete增删改查

第九章:实战命令逐字拆解

9.1 拆解 Docker 构建命令

docker build -f deploy/Dockerfile -t my-gpt-image .
部分含义
docker build”构建镜像”这个动作
-f deploy/Dockerfilefile:指定 Dockerfile 的路径(默认会找当前目录的 Dockerfile,但这里 Dockerfile 在 deploy/ 文件夹下,所以要手动指定)
-t my-gpt-imagetag:给做出来的镜像起个名字(标签)
.当前目录作为构建上下文(注意这个点很重要!它告诉 Docker “构建时能访问的文件范围”)

整句翻译:

「按照 deploy/Dockerfile 这份菜谱,用当前目录的内容做一份名叫 my-gpt-image 的预制菜」

9.2 拆解 Docker 启动命令

docker run -d -p 8080:80 my-gpt-image
部分含义
docker run”启动容器”这个动作
-ddetach:后台运行(不占用当前终端,关掉终端容器还在跑)
-p 8080:80port:端口映射,把容器内的 80 端口映射到你电脑的 8080 端口
my-gpt-image用哪个镜像启动

整句翻译:

「用 my-gpt-image 这份预制菜启动一个容器,让它在后台跑,把容器里的 80 端口暴露到我电脑的 8080」

9.3 端口映射图解

你的浏览器                    你电脑                       Docker 容器内
访问 localhost:8080  ──→   8080 端口  ──→   80 端口(容器里 Nginx 在听)

为什么要做映射?

  • 容器内部默认 Web 服务跑在 80 端口
  • 但你电脑的 80 端口可能已被占用,或者你想跑多个容器
  • 所以”翻译”一下:你访问电脑的 8080 → Docker 转给容器的 80

9.4 常见组合命令拆解

进入正在跑的容器(调试用)

docker exec -it <容器> bash
参数含义
exec在容器里执行命令
-iinteractive:保持输入流打开
-tterminal:分配一个伪终端
bash要执行的命令(启动 bash shell)

挂载宿主机文件夹到容器(持久化数据)

docker run -v /Users/<your-username>/data:/app/data my-image
参数含义
-v 宿主路径:容器路径把电脑的 /Users/<your-username>/data 文件夹挂载到容器内的 /app/data

设置环境变量

docker run -e API_KEY=sk-xxx -e DEBUG=true my-image
参数含义
-e KEY=VALUE给容器内传入环境变量

第十章:pnpm 共用机制 与 Docker 隔离的碰撞

⚠️ 本章是进阶内容:如果你还没用过 Docker,或者还没碰到过”项目装依赖太慢/磁盘空间不够”的真实问题,建议直接跳过本章——等做过 1~2 个 Docker 项目后再回来看,理解会深刻得多。

这是一个”两个概念碰撞”的好问题: pnpm 强调”全局共用一份依赖”,但 Docker 又强调”每个容器完全隔离”。 那么 Docker 里用 pnpm 还有意义吗?怎么共用?


10.1 pnpm 说的”共用”具体是怎么实现的?

技术名词:硬链接(hard link)+ 软链接(symbolic link / symlink)

先理解硬链接是什么

硬链接 ≠ 复制文件,而是给同一份文件起多个名字

举例:你有一份照片 photo.jpg,文件实际数据在磁盘某个位置(假设占 5MB)。

ln /Users/<your-username>/photo.jpg /Users/<your-username>/Desktop/相册.jpg

执行后:

  • 磁盘上还是只有一份 5MB 的数据
  • 但有两个”路径名”都能访问它
  • 删除其中一个,另一个还在
  • 改任何一个,另一个跟着变(因为是同一份数据)

这和”复制一份”完全不同! 复制是磁盘上多了一份 5MB;硬链接是磁盘上只有一份,多了一个”名字”。

软链接(symlink)vs 硬链接

类型本质类比
硬链接 (hard link)同一文件的多个名字(指向同一磁盘块)同一个人的不同绰号
软链接 (symlink)一个”快捷方式”,指向另一个路径Windows 桌面快捷方式

差别:

  • 删除原文件 → 硬链接还能用(数据还在),软链接失效(断链)
  • 跨磁盘 → 硬链接不行,软链接可以

pnpm 的实际工作方式

全局存储区(只有这里有真实文件)
~/.pnpm-store/
   ├─ react@19.1.0/    ← 真正的 react 文件,5MB,全电脑只此一份
   ├─ vite@6.3.2/      ← 真正的 vite 文件
   └─ ...其他几千个包

项目A/node_modules/react/   ──硬链接──→ 指向全局存储区的 react@19.1.0
项目B/node_modules/react/   ──硬链接──→ 指向全局存储区的 react@19.1.0
项目C/node_modules/react/   ──硬链接──→ 指向全局存储区的 react@19.1.0

结果: 你电脑上有 100 个项目都用 react,磁盘上 react 只占 1 份 5MB 的空间。

📌 类比:“小区共用洗衣房”

  • npm/yarn = 每家自己买一台洗衣机(每个项目存一份完整依赖)
  • pnpm = 小区有一个公共洗衣房,每户人家拿钥匙就能用(每个项目链接到全局存储)

重要前提

硬链接只能在同一个文件系统/磁盘分区上工作,跨磁盘就不行。 所以 pnpm 的全局存储必须和你的项目在同一块硬盘上。


10.2 Docker 是怎么”隔离”的?

Docker 容器有自己独立的文件系统,跟你电脑(宿主机)的文件系统是完全隔开的

你电脑(宿主机)
├─ /Users/<your-username>/...         ← 你能看到
├─ ~/.pnpm-store/           ← 你能看到
└─ Docker 容器
    ├─ /app/                ← 容器内看到自己的 /app
    ├─ /root/               ← 容器内自己的 /root
    └─ /...                 ← 整个文件系统是独立的
        ↑
        容器里的进程看不到宿主机的任何东西

关键点:

  • 容器里跑的程序,看到的”根目录 /”是容器自己的根目录
  • 容器默认看不到宿主机的 ~/.pnpm-store/
  • 容器跑完销毁后,里面的文件全没了

10.3 那 Docker 里用 pnpm 还有意义吗?

有意义,但”共用”的范围变了。 分三种场景看:

场景 1:单个容器内部,依然能”共用”

很多大型项目是 monorepo(一个仓库多个子项目),比如:

my-monorepo/
├─ apps/web/         ← 子项目1,用 react
├─ apps/admin/       ← 子项目2,也用 react
└─ packages/ui/      ← 子项目3,也用 react

容器内跑 pnpm install 时,容器内部有自己的 .pnpm-store,三个子项目共用同一份 react。

这就是”容器内的小区共用洗衣机”——隔离的是容器跟宿主机,不是容器内部的子项目之间。

场景 2:多次构建之间——用 BuildKit 缓存”共用”

Docker 构建镜像可能每天跑很多次(每次代码改动都构建一次)。如果每次都重新下载依赖,太慢。

新版 Docker 的 BuildKit 提供”缓存挂载”功能:

# Dockerfile 里写
RUN --mount=type=cache,target=/root/.pnpm-store pnpm install

意思是:「每次构建时,把宿主机上一个特殊的缓存目录临时挂进容器的 .pnpm-store 位置」。

第一次构建:下载 react → 存进缓存目录
              ↓
第二次构建:发现缓存里有 react → 直接用,不下载
              ↓
第三次构建:依然能用上次的缓存

这是”工地复用上次的建材,但施工完就退场”。

场景 3:开发阶段——用 Volume “把宿主机的洗衣房搬进容器”

开发时你可能想让容器直接用你电脑上已有的 pnpm 缓存:

docker run -v ~/.pnpm-store:/root/.pnpm-store my-image

-v 是”挂载”参数,意思是:「把宿主机的 ~/.pnpm-store 这个文件夹,直接接到容器内的 /root/.pnpm-store 位置」。

宿主机                          容器
~/.pnpm-store/   ←─挂载─→   /root/.pnpm-store/
(同一份数据,两边都能访问、都能改)

容器一启动,立刻就能”看到”你电脑里已下好的依赖,无需重新下载。

📌 挂载(mount)打破隔离的本质:在隔离的墙上开了一扇门,让两边能共享指定区域。


10.4 全局总结图

┌─────────────────────────────────────────────────────────────────┐
│                     你的电脑(宿主机)                            │
│                                                                  │
│   ┌─────────────┐                                                │
│   │ ~/.pnpm-    │                                                │
│   │   store/    │←─── 项目A、B、C 都硬链接到这里(同一磁盘)       │
│   └─────────────┘                                                │
│                                                                  │
│   ┌──────────────────────────────────────────────────────┐       │
│   │            Docker 容器(隔离的世界)                  │       │
│   │                                                       │       │
│   │   ┌────────────┐                                     │       │
│   │   │/.pnpm-store│ ← 容器内子项目共用(场景1)           │       │
│   │   └────────────┘                                     │       │
│   │       ↑                                              │       │
│   │       └─ 可以通过以下方式与宿主机连通:               │       │
│   │           • -v 挂载(场景3)                          │       │
│   │           • BuildKit cache mount(场景2)             │       │
│   └──────────────────────────────────────────────────────┘       │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

10.5 实战建议速查

你在干啥建议怎么用
普通本地开发,没用 Docker直接用 pnpm,全自动享受全局共用
Docker 内单纯跑个项目pnpm 的优势相对变小,但仍比 npm 快
Docker 镜像构建(CI/CD)用 BuildKit 缓存挂载(场景 2)
Docker 里做开发调试-v 挂载本地 store(场景 3)
部署到生产服务器通常不需要”共用”——镜像里只装需要的依赖即可

10.6 相关概念名词速查

概念含义
硬链接 (hard link)同一份文件的多个”名字”,必须同磁盘
软链接 (symlink)类似 Windows 快捷方式,指向另一个路径
卷 / VolumeDocker 里的持久化存储机制
挂载 / Mount把宿主机或卷接入容器的某个路径
BuildKitDocker 新的构建引擎,支持缓存等高级功能
monorepo单一仓库多个子项目(mono = 单一,repo = 仓库的简写)
CASContent-Addressable Storage,内容寻址存储(pnpm store 的实现机制)

10.7 一句话总结

pnpm 通过”硬链接”实现项目间共用一份依赖;Docker 通过”独立文件系统”实现容器与宿主机隔离。 要让两者结合,靠的是”挂载(mount)“——它在隔离的墙上开一扇门,让指定区域能共享。


第十一章:编程语言识别图鉴

目标:拿到任何陌生项目,3 秒判断出它用什么语言写的。 这是程序员的”看片识人”基本功,识别准确率不需要 100%——能猜对主语言就够了。


11.1 三种识别方法(按可靠度排序)

🥇 方法 1:看根目录的「标志性文件」(最权威)

每种语言都有它独有的”身份证文件”——光看一眼根目录就能高准确率判断(约 90%,剩下 10% 是少数特殊框架,比如 Deno 也用 package.json)。

看到这个文件大概率是这种项目包管理器
package.jsonJavaScript / Node.js / TypeScriptnpm / pnpm / yarn
requirements.txtpyproject.tomlsetup.pyPythonpip / poetry / uv
pom.xmlJava(用 Maven)Maven
build.gradlebuild.gradle.ktsJava / Kotlin(用 Gradle)Gradle
go.modGogo mod
Cargo.tomlRustcargo
composer.jsonPHPComposer
GemfileRubybundler
*.csproj*.slnC# / .NETNuGet
*.xcodeprojPackage.swiftSwift(iOS / macOS)Swift PM
pubspec.yamlDart / Flutterpub
CMakeLists.txtC / C++-
Makefile可能是 C / C++ / Go / Python 等(不是独占文件,需结合其他线索判断)-

📌 就一招:拿到任何项目,先看根目录有没有这些文件——90% 的情况一秒就知道用什么语言。

🥈 方法 2:看文件后缀名(最直接)

后缀语言
.jsJavaScript
.ts / .tsxTypeScript(.tsx = TS + React 组件)
.jsxJavaScript + React 组件
.pyPython
.javaJava
.ktKotlin
.cC
.cpp / .cc / .cxxC++
.csC#
.goGo
.rsRust
.phpPHP
.rbRuby
.swiftSwift
.dartDart(Flutter)
.html / .css网页(HTML/CSS 不算编程语言,是”标记语言”)
.shShell 脚本(macOS/Linux)
.sql数据库查询语言

🥉 方法 3:看 GitHub 仓库右上角的「Language」条(最直观)

打开任意 GitHub 仓库主页,右上角会自动显示一个彩色比例条,告诉你这个项目用了哪些语言、各占多少。

比如 gpt_image_playground 的 GitHub 页面右侧会显示:
■ TypeScript  92.3%   ← 主语言
■ JavaScript   4.1%
■ CSS          2.5%
■ HTML         1.1%

第一种语言就是项目的”主语言”。

📌 GitHub 是用一个开源工具叫 linguist 自动分析的,准确率很高。


11.2 常见 10 种语言「长相图鉴」(一眼就能认出)

光看一段代码的”风格”,老手就能秒判断是哪种语言。给你看每种语言的”招牌长相”:

1. JavaScript / TypeScript(前端 / Node.js)

特点:花括号 {}、分号、箭头函数 =>

function hello(name) {
  console.log(`Hello, ${name}!`);
}
const add = (a, b) => a + b;

TypeScript 多了类型标注:

function hello(name: string): void {
  console.log(`Hello, ${name}!`);
}

2. Python(数据 / AI / 脚本)

特点:靠缩进区分代码块、没有花括号、def 定义函数、: 结尾

def hello(name):
    print(f"Hello, {name}!")
 
if __name__ == "__main__":
    hello("World")

看到大量缩进、没有 {}; → 99% 是 Python

3. Java(企业后端 / Android)

特点:每个文件都得有 public class、类型声明在前

public class Hello {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

看到 public class XXX 开头 → Java

4. C / C++(系统级 / 游戏引擎)

特点:#includeint main()、指针 * &

#include <stdio.h>
 
int main() {
    printf("Hello, World!\n");
    return 0;
}

5. C#(微软系 / Unity 游戏)

特点:跟 Java 很像,但用 using 而不是 import

using System;
 
class Hello {
    static void Main() {
        Console.WriteLine("Hello, World!");
    }
}

6. Go(云原生 / 后端)

特点:package mainfunc 定义函数、没有分号

package main
 
import "fmt"
 
func main() {
    fmt.Println("Hello, World!")
}

7. Rust(系统级 / 区块链 / 高性能)

特点:fn 定义函数、let 声明变量(默认不可变)/ let mut(可变)、! 后缀(宏)

fn main() {
    let name = "World";       // 不可变变量(默认)
    let mut count = 0;         // 可变变量需要 mut
    println!("Hello, {}!", name);
}

看到 fnprintln! 那个感叹号 → Rust

8. PHP(传统 Web 后端)

特点:<?php 开头、变量前面有 $

<?php
$name = "World";
echo "Hello, $name!";
?>

9. Ruby(Rails 全栈框架)

特点:def...end 配对、puts 输出

def hello(name)
  puts "Hello, #{name}!"
end
 
hello("World")

10. Swift(苹果生态:iOS / macOS)

特点:funcvar/let、字符串插值用 \()

func hello(name: String) {
    print("Hello, \(name)!")
}

11.3 给小白的「3 秒判断法」

按这个顺序自检,3 秒能判断 90% 的项目:

打开 GitHub 仓库 / 项目目录
        │
        ▼
看右上角语言条 ─────────→ 直接告诉你了 ✅
        │(如果是本地)
        ▼
看根目录有 package.json?  → JS/TS 项目 ✅
        │否
        ▼
有 requirements.txt?      → Python 项目 ✅
        │否
        ▼
有 pom.xml / build.gradle?→ Java 项目 ✅
        │否
        ▼
有 go.mod?               → Go 项目 ✅
        │否
        ▼
有 Cargo.toml?           → Rust 项目 ✅
        │否
        ▼
看 src/ 里文件后缀(.cpp / .rb / .php / ...)

11.4 按「应用领域」反推语言

不同语言擅长的领域不一样,看到项目类型也能反推:

你看到的项目大概率用的语言
网页前端JavaScript / TypeScript
网页后端 APINode.js / Python / Java / Go / PHP
数据分析 / AI / 机器学习Python(90%+)
移动 App(iOS)Swift / Objective-C
移动 App(Android)Kotlin / Java
移动 App(跨平台)Flutter (Dart) / React Native (JS)
Windows 桌面软件C# / C++
Mac 桌面软件Swift / Objective-C
游戏(PC / 主机)C++ / C# (Unity)
游戏(手机休闲)C# (Unity) / Lua
操作系统 / 驱动C / Rust
区块链 / 加密货币Rust / Go / Solidity
云原生 / 容器(Docker / K8s)Go(几乎全用)
老牌企业系统Java / C#
WordPress 插件 / 老网站PHP
数据库本身C / C++ / Rust
Shell 自动化脚本Bash / Python

11.5 实战练习:拆解 gpt_image_playground

按上面的方法套一遍:

  1. 看根目录 → 有 package.json
  2. 看后缀src/ 里全是 .tsx.ts
  3. 看 package.json 里的 scriptstsc -b && vite build(tsc = TypeScript Compiler)
  4. 看 GitHub 语言条 → TypeScript 占大头

结论:这是一个 TypeScript + React 的前端项目。


11.6 混合型项目怎么办?

很多大项目是多语言混合的,比如:

some-project/
├── frontend/     ← TypeScript(前端)
├── backend/      ← Python(后端 API)
├── scripts/      ← Bash(部署脚本)
└── docker/       ← Dockerfile(部署)

这种情况下:

  • 看子目录:每个子项目独立判断
  • 看 GitHub 语言条:自动给你按比例显示
  • 看 README:作者通常会说明架构

11.7 一些容易混淆的「兄弟语言」

新手常被这些”长得像”的语言搞混,记住关键差异:

对比区分关键
JavaScript vs TypeScriptTS 比 JS 多了类型标注name: string);后缀 .ts/.tsx
Java vs JavaScript完全两种语言!只是名字撞车(“Java 是 JavaScript 的关系类似 Car 和 Carpet”)
Java vs Kotlin都跑在 JVM 上,Kotlin 更现代简洁;后缀 .java vs .kt
C vs C++ vs C#C 最底层,C++ 加了面向对象,C# 是微软的 .NET 语言(跟 Java 更像)
Python 2 vs Python 3Python 2 已死,现在新项目都是 Python 3。print "x" 是 2,print("x") 是 3
TypeScript vs Java都是强类型,但 TS 跑在浏览器/Node,Java 跑在 JVM

11.8 记住这一节的「3 句话总结」

  1. 看根目录”身份证文件” → 90% 的项目能瞬间识别
  2. 看后缀名 → 兜底方法
  3. GitHub 仓库右上角语言条 → 最快最直观

📌 不要去”背”每种语言的全部特征——会用工具识别就够了


第十二章:Git 常用命令实战图解

目标:让你能用 Git 完成 95% 的日常操作,不需要”精通”,但绝不能”懵逼”。 方法:图解 + 生活类比 + 真实场景 + 命令拆解。


12.1 先建立 Git 的「心智模型」(最重要!)

很多人学 Git 越学越乱,就是因为没建立正确的心智模型——把 Git 当成”网盘”或”同步盘”。

Git ≠ 网盘

类型关注点例子
网盘(百度云/iCloud)“最新的文件”改了就同步覆盖
Git”每次改了什么、为什么改”完整保留每次修改的历史和原因

💡 核心认知:Git 是一个时间机器,不是同步盘。你每次”提交”就是给当下打一个存档点,未来可以回到任意一个存档点。

四个核心区域(Git 的世界)

┌──────────────┐  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐
│   工作区     │  │   暂存区     │  │  本地仓库    │  │  远程仓库    │
│              │  │              │  │              │  │              │
│ Working Dir  │  │   Staging    │  │  Local Repo  │  │  Remote Repo │
│              │  │     Area     │  │              │  │  (GitHub)    │
│  你正在改的  │  │  打算下次    │  │  已经存档的  │  │  云端的      │
│  那些文件    │  │  提交的清单  │  │  历史快照    │  │  备份/分享   │
└──────┬───────┘  └──────┬───────┘  └──────┬───────┘  └──────┬───────┘
       │                  │                  │                  │
       │   git add        │   git commit     │   git push       │
       └────────────────→ └─────────────────→└─────────────────→│
       │                                                        │
       │              git pull / git fetch                      │
       └────────────────────────────────────────────────────────┘

用「写论文 + 备份到云」类比

Git 区域论文场景类比
工作区你 Word 文档里正在打的字
暂存区你勾选了”这一段我改好了,待会儿存档”
本地仓库点了”另存为:v1、v2、v3”在自己电脑上
远程仓库把这些版本备份到了百度云/Google Drive

四个核心命令对应四个动作:

打字           → 工作区有改动
git add        → 把改动放进"待存档清单"
git commit     → 真正打一个存档点(带说明文字)
git push       → 把所有存档同步到云端

12.2 一次性的配置(注册个”作者身份”)

第一次用 Git 之前,告诉 Git “你是谁”,相当于注册账号:

# 设置你的名字(提交记录里会显示这个)
git config --global user.name "你的名字"
 
# 设置你的邮箱(建议用 GitHub 注册的那个邮箱)
git config --global user.email "your@email.com"
 
# 把默认分支名设为 main(现代 Git 推荐,跟 GitHub 一致)
git config --global init.defaultBranch main
 
# 查看已设置的配置
git config --list

📌 --global 表示”对所有项目生效”。设一次就行。

⚠️ 关于第三条:老版本 Git 默认创建的分支叫 master(“主人”含义在欧美社区有歧义),现在 GitHub 已统一改成 main。如果不设置这条,后面 git push -u origin main 可能报错(因为本地分支是 master)。

类比

你去图书馆借书前要办借书证(写名字+联系方式),办完一次以后所有图书馆都能用。


12.3 场景一:把别人的项目下载到本地(最常见)

命令

git clone https://github.com/cooksleep/gpt_image_playground.git

图解

GitHub.com (远程仓库)              你的电脑
┌────────────────────┐             ┌────────────────────┐
│ gpt_image_         │             │                    │
│  playground/       │  git clone  │  gpt_image_        │
│   ├── src/         │ ─────────→  │   playground/      │
│   ├── package.json │             │   ├── src/         │
│   └── README.md    │             │   ├── package.json │
└────────────────────┘             │   ├── README.md    │
                                    │   └── .git/   ←── 完整历史 │
                                    └────────────────────┘

📌 clone 不是简单下载——它把完整的历史记录都搬下来了,藏在 .git/ 文件夹里。


12.4 场景二:自己写代码 → 推到 GitHub(完整流程)

这是最常用、也最容易搞混的流程。我用面包店类比串起来:

完整 7 步流程图

你(面包师傅)每天做面包,要把日记+成品都备份到云端。

第 1 步:建立工作记录簿
git init                       ← 在新文件夹初始化 Git,相当于新开本日记簿

第 2 步:今天做了 3 个面包
(编辑文件 a.txt, b.txt, c.txt)  ← 工作区改动

第 3 步:选择哪些要写进日记
git add a.txt b.txt            ← 把 a 和 b 放进暂存区(c 暂时不写)

第 4 步:写日记盖个章
git commit -m "今天做了甜甜圈"  ← 创建一个存档点,附说明

第 5 步:跟云端账户绑定(首次需要)
git remote add origin https://github.com/你/仓库.git

第 6 步:把存档同步到云端
git push -u origin main        ← 推送到 GitHub

第 7 步:以后再修改
(修改文件)→ git add → git commit → git push
   循环这 3 步即可

命令逐字拆解

命令干啥关键参数
git init在当前目录初始化 Git
git status看当前状态(必学!哪些改了、哪些待提交)
git add <文件>把指定文件加入暂存区git add . = 加入所有改动
git commit -m "说明"提交存档,带说明文字-m = message
git remote add origin <url>绑定一个远程仓库,起名 originorigin 是惯例名字
git push -u origin main推送到远程的 main 分支-u 第一次要加,记住对应关系

实战例子:从零到 GitHub

# 1. 创建并进入项目文件夹
mkdir ~/Desktop/我的小项目
cd ~/Desktop/我的小项目
 
# 2. 初始化
git init
 
# 3. 创建几个示例文件(写代码)
echo "<h1>Hello</h1>" > index.html
echo "body { color: red; }" > style.css
 
# 4. 看看状态
git status
# 输出:Untracked files: index.html, style.css
 
# 5. 把所有新文件加入暂存区
git add .
 
# 6. 第一次提交
git commit -m "首次提交:项目初始化"
 
# 7. 在 GitHub 网站上手动建一个空仓库(点 New repository)
#    然后复制它的 URL
 
# 8. 绑定远程仓库
git remote add origin https://github.com/你的用户名/你的仓库.git
 
# 9. 推送
git push -u origin main

📌 第一次推送可能要登录 GitHub。现在 GitHub 不允许密码登录,要用 Personal Access Token(在 GitHub 设置里生成)或 SSH key


12.5 场景三:日常工作的 3 步循环

项目搭好之后,每天的工作就是这个循环

        改代码
          │
          ▼
   ┌──────────┐
   │  改完了? │── 否 ─→ 继续改
   └────┬─────┘
        │ 是
        ▼
   git status        ← 看看改了哪些(自检)
        │
        ▼
   git add .         ← 把改动加入暂存
        │
        ▼
   git commit -m "本次干了啥"   ← 存档
        │
        ▼
   git push          ← 同步到云端
        │
        └──→ 回到"改代码"

提交说明(commit message)怎么写?

❌ 不好的提交说明✅ 好的提交说明
update修复登录页面密码框无法输入的 bug
123新增用户头像上传功能
wip重构数据库连接池,提升 30% 性能

简单原则:让未来的自己(或同事)看到这条说明,能一眼明白这次改了什么。


12.6 场景四:和远程仓库同步

如果别人也在改同一个项目(或者你在多台电脑工作),就需要同步。

两个最重要的命令

git pull   # 把远程的改动拉下来合并到本地
git push   # 把本地的改动推到远程

图解:你和同事的协作(双泳道时间线)

时间 ↓                你(本地)              远程仓库            同事(本地)
─────────────────────────────────────────────────────────────────────
T1:起点         git pull ←─── commit A ───→ git pull
                  本地 = A                       本地 = A
─────────────────────────────────────────────────────────────────────
T2:各自改代码   改 a.txt                                       改 b.txt
                  git commit                                    git commit
                  本地 = A→B(你)                                 本地 = A→C(同事)
─────────────────────────────────────────────────────────────────────
T3:同事先推     ─────────────→ 同事 push ───→ 远程 = A→C
─────────────────────────────────────────────────────────────────────
T4:你想推       git push ❌
                  报错:远程比你新(远程是 A→C,你是 A→B)
─────────────────────────────────────────────────────────────────────
T5:你先拉       git pull ←─── 远程 A→C ───
                  本地变成 A→C→合并(B+C)
─────────────────────────────────────────────────────────────────────
T6:你再推       git push ───→ 远程 = A→C→合并 ✅
─────────────────────────────────────────────────────────────────────

黄金法则

📌 每次开始工作前先 git pull,每次推送前再 git pull


12.7 场景五:查看历史 / 对比改动

git log —— 查看历史提交

git log              # 完整历史
git log --oneline    # 简洁版(每条一行)
git log --graph      # 带图形分支结构
git log -5           # 只看最近 5 条

输出示例:

* a3f9c12 (HEAD -> main) 修复登录 bug
* 7b8e3d4 新增用户头像上传
* 5c1d2a8 重构数据库连接
* d4e5f6a 首次提交

每行:短哈希 + 提交说明。哈希是这次提交的”身份证号”,可以用它定位。

git diff —— 看改了啥

git diff              # 看工作区相对于暂存区的改动
git diff --staged     # 看暂存区相对于上次提交的改动
git diff a3f9c12      # 看当前相对于某次提交的改动

输出:以”+“和”-“显示新增/删除的行(红绿对比)。


12.8 场景六:版本回退 / 救命操作

⚠️ 这一节涉及红灯区操作(可能丢失代码),做之前一定看清楚!

先理解一个概念:HEAD 是啥?

HEAD = 当前分支最新提交的指针,可以理解为”你当前所在的位置”。

git log 历史:
   d4e5f6a   ← 首次提交
   ↑
   5c1d2a8   ← 重构数据库
   ↑
   7b8e3d4   ← 新增头像功能
   ↑
   a3f9c12   ← 修复 bug    ← HEAD 指向这里(最新提交)

衍生写法:

  • HEAD~1HEAD^ = HEAD 的上一个提交(也就是 7b8e3d4)
  • HEAD~2 = HEAD 的上上个提交(5c1d2a8)
  • HEAD~3 = 再往前一个

💡 类比:HEAD 像是你看书时书签夹的位置,HEAD~1 就是”往回翻一页”。

三种”回到过去”的方式(区别非常重要)

命令干啥危险度何时用
git checkout <commit><文件>把某个文件恢复到某次提交时的样子⭐ 安全改坏了某个文件想恢复
git revert <commit>新建一个反向提交,撤销某次改动⭐⭐ 安全已经推到远程,要撤销
git reset —hard <commit>强行把分支拨回到某次提交,之后的改动全丢⭐⭐⭐⭐⭐ 危险只本地、且 100% 确定

图解三者区别

原始历史:  A ── B ── C ── D (最新)

git revert C:
            A ── B ── C ── D ── C'(反向C)
            (历史保留,新增一个抵消 C 的提交)

git reset --hard B:
            A ── B
            (C 和 D 直接消失!本地未推送时还能救,已推送会出大问题)

git checkout A -- 文件.txt:
            历史不变,只是把"文件.txt"恢复到 A 时的内容

实战建议

你想做的事推荐命令
”我刚改坏了某个文件,想恢复到上次提交的样子”git checkout -- 文件名
”我刚 commit 了,但还没 push,想撤销这次 commit”git reset --soft HEAD~1(保留改动)
git reset --hard HEAD~1(连改动都丢)
“已经推到远程了,要撤销”git revert <提交哈希>,再 push
”完全乱了想回到 3 次提交之前”git log 找到那次提交的哈希,再决定用 reset 还是 revert

📌 新手保险法:操作前先 git statusgit log 看清楚,不确定就别敲 --hard


12.9 场景七:分支(Branch)—— Git 的精髓

什么是分支?

把”主线代码”想象成一棵树的主干。分支 = 从主干分出来的旁支,可以在上面随便实验,不影响主干。

主分支 main:     A ── B ── C ────────── F (合并后)
                       \              /
开发分支 feature:       D ── E ──────/
                       (在分支上开发新功能)

为什么要用分支?

  1. 同时做多个功能,互不干扰
  2. 实验性改动出了问题不影响主线
  3. 多人协作时各自占一个分支

常用分支命令

git branch                    # 查看本地所有分支(带 * 的是当前分支)
git branch <>              # 创建新分支
git checkout <>            # 切换到某个分支(老语法)
git switch <>              # 切换分支(新语法,更直观)
git checkout -b <>         # 创建并切换(最常用)
git switch -c <>           # 同上(新语法)
git merge <>               # 把某个分支合并到当前分支
git branch -d <>           # 删除已合并的分支
git branch -D <>           # 强制删除(红灯区)

实战例子:在分支上加功能

# 1. 当前在 main 分支,看一眼
git status
# 输出:On branch main
 
# 2. 创建并切换到新分支
git switch -c feature-login
# 输出:Switched to a new branch 'feature-login'
 
# 3. 在这个分支上随便改、提交(不会影响 main)
# ...编辑代码...
git add .
git commit -m "实现登录功能"
 
# 4. 功能做完了,切回 main
git switch main
 
# 5. 把 feature-login 的改动合并进 main
git merge feature-login
 
# 6. 删掉用过的分支
git branch -d feature-login
 
# 7. 推到远程
git push

分支合并图解

合并前:
  main:        A ── B ── C
                    \
  feature-login:     D ── E
                      ↑ 你在这分支上加了登录功能

git switch main + git merge feature-login

合并后:
  main:        A ── B ── C ────── F   ← F 是合并提交
                    \           /
  feature-login:     D ── E ───/

12.10 场景八:合并冲突(Merge Conflict)—— 新手最怕的

什么是冲突?

你和同事同时改了同一个文件的同一行,Git 不知道该听谁的,就会”卡住”,等你手动解决。

冲突长什么样?

打开冲突的文件会看到这种”奇怪标记”:

正常的代码...
<<<<<<< HEAD
你写的版本
=======
同事写的版本
>>>>>>> feature-login
正常的代码...

解决步骤

1. git pull / git merge 失败,提示冲突
        │
        ▼
2. git status 看哪些文件有冲突
        │
        ▼
3. 打开冲突文件,找到 <<<<<<< 标记
        │
        ▼
4. 决定怎么改(核心规则:保留你想要的内容,删干净所有标记行)
        │
        ▼
5. git add <冲突文件>     ← 告诉 Git "我解决好了"
        │
        ▼
6. git commit              ← 完成合并提交

第 4 步详解:到底怎么改?

冲突文件长这样(5 行:3 个标记行 + 2 段内容):

<<<<<<< HEAD                    ← 标记行 1
你写的版本                       ← 内容 A
=======                          ← 标记行 2
同事写的版本                     ← 内容 B
>>>>>>> feature-login            ← 标记行 3

核心规则:决定保留哪段内容,然后把所有 <<<<<<< ======= >>>>>>> 三种标记行全部删掉。

你想要的结果操作改完文件长这样
只保留你的版本删 3 个标记行 + 删”同事写的版本”那行你写的版本
只保留同事版本删 3 个标记行 + 删”你写的版本”那行同事写的版本
两段都要(合并)删 3 个标记行,两段内容都留下你写的版本
同事写的版本
自己重写删 3 个标记行 + 删两段,写一段新的(你重新写的内容)

💡 铁律:改完后,文件里绝对不能再有任何 <<<<<<<=======>>>>>>> ——只要还剩一个,git add 就还会报冲突未解决。

类比

你和同事合写一篇文章,同时改了第 3 段。Git 把两个版本都贴出来,问你”留谁的?或者怎么揉一起?“——决定权在你。


12.11 必须知道的 .gitignore 文件

有些文件永远不该提交到 Git

  • node_modules/(依赖,太大)
  • .env(含密码、API Key)
  • dist/ build/(构建产物)
  • .DS_Store(macOS 系统文件)
  • *.log(日志)

在项目根目录创建一个名为 .gitignore 的文件,列出要忽略的:

# 依赖
node_modules/
__pycache__/
 
# 构建产物
dist/
build/
 
# 环境变量(敏感!)
.env
.env.local
 
# 系统文件
.DS_Store
Thumbs.db
 
# 日志
*.log
 
# IDE 配置
.vscode/
.idea/

📌 不同语言的项目有不同的 .gitignore 模板,可以去 https://github.com/github/gitignore 抄。


12.12 一张终极速查图

┌─────────────────────────────────────────────────────────────┐
│                     Git 命令速查                              │
├─────────────────────────────────────────────────────────────┤
│ 【入门 4 件套(每天用)】                                     │
│   git status                ← 看现状                          │
│   git add <文件>             ← 加入暂存区                     │
│   git commit -m "说明"       ← 存档                           │
│   git push                  ← 同步到云端                      │
│                                                              │
│ 【克隆与同步】                                                │
│   git clone <url>            ← 下载远程项目                   │
│   git pull                  ← 拉取并合并远程改动              │
│   git fetch                 ← 只拉取不合并                    │
│                                                              │
│ 【查看与对比】                                                │
│   git log --oneline          ← 查看历史                       │
│   git diff                  ← 看改动                          │
│   git blame <文件>           ← 看每行是谁写的                 │
│                                                              │
│ 【分支】                                                      │
│   git branch                ← 看分支                          │
│   git switch -c <名>         ← 新建并切换                     │
│   git merge <名>             ← 合并                           │
│   git branch -d <名>         ← 删除                           │
│                                                              │
│ 【撤销与回退】                                                │
│   git checkout -- <文件>     ← 恢复某文件                     │
│   git reset --soft HEAD~1   ← 撤销上次 commit(保留改动)    │
│   git reset --hard HEAD~1   ← 撤销上次 commit(丢弃改动)⚠️   │
│   git revert <hash>         ← 新建反向提交                    │
│                                                              │
│ 【其他高频】                                                  │
│   git stash                 ← 临时藏起改动                    │
│   git stash pop             ← 把藏起的恢复                    │
│   git remote -v             ← 看远程仓库                      │
└─────────────────────────────────────────────────────────────┘

12.13 给小白的「Git 5 条铁律」

  1. 每次开工前先 git pull,避免冲突
  2. commit 信息写清楚,未来的你会感谢现在的你
  3. 不要把 .envnode_modules、密钥提交到仓库(用 .gitignore)
  4. --hard 这种参数想 3 遍再敲,不可恢复
  5. 不确定的时候先 git statusgit log,看清楚再操作

12.14 常见报错速查

报错信息原因解决
fatal: not a git repository当前目录没初始化 Gitgit init 或换到正确目录
Your branch is behind远程比本地新git pull
rejected (non-fast-forward)同上git pull,解决冲突再 push
Authentication failed密码/Token 错重新生成 Personal Access Token
merge conflict合并冲突看 12.10 节解决步骤
Permission denied (publickey)SSH key 没配在 GitHub 添加 SSH key
Please tell me who you are没配置 user.name/email跑 12.2 节的命令

12.15 实战练习(强烈推荐做一遍)

# ============ 练习:从零搭一个仓库并推到 GitHub ============
 
# 1. 在桌面建测试目录
mkdir ~/Desktop/git-练习
cd ~/Desktop/git-练习
 
# 2. 初始化
git init
 
# 3. 创建一个文件
echo "Hello Git" > hello.txt
 
# 4. 看状态
git status        # 应该看到 hello.txt 是 Untracked
 
# 5. 加入暂存
git add hello.txt
git status        # 现在 hello.txt 是 to be committed
 
# 6. 提交
git commit -m "首次提交"
git log           # 看到你的第一条记录!
 
# 7. 修改文件
echo "再来一行" >> hello.txt
 
# 8. 看改动
git diff          # 看到 +再来一行
 
# 9. 提交
git add .
git commit -m "新增第二行"
 
# 10. 创建分支并切换
git switch -c experiment
echo "实验内容" > exp.txt
git add . && git commit -m "实验提交"
 
# 11. 切回主分支
git switch main
ls               # 看不到 exp.txt(因为它在 experiment 分支)
 
# 12. 合并实验分支
git merge experiment
ls               # 现在能看到 exp.txt 了
 
# 13. 看完整历史
git log --oneline --graph

走完这 13 步,你就完整理解 Git 了。


12.16 进阶补充(rebase / stash / reflog 等)

本章覆盖了 90% 的日常 Git 场景。剩下 10%——协作整理历史 / 误操作救命 / 短期切换上下文——单独整理在另一篇:

📖 Git 进阶速查 — 6 个进阶命令 + 实战练习

  • stash 临时藏起改动(最常用,每天都可能用到)
  • reflog 救命操作(误删 / 误回退后找回)
  • rebase 整理 commit 历史
  • --force-with-lease--force 安全的强推
  • cherry-pick 单挑一个 commit
  • tag 版本号管理

附录:学习路径推荐

阶段一:能跑起来(1~2 周)

  1. ✅ 学会 git clone、npm install、npm run dev 这套流程
  2. ✅ 看懂 README.md 的安装步骤
  3. ✅ 用 Vercel 部署一个静态网站

阶段二:能改东西(1~2 个月)

  1. 学 HTML / CSS / JavaScript 基础
  2. 学 React 或 Vue 任选一个
  3. 自己改改别人项目的样式、文字

阶段三:能做点东西(3~6 个月)

  1. 自己从 0 创建一个 React 项目
  2. 用 Docker 部署
  3. 学一点后端(Node.js / Python)

阶段四:能独立开发(6 个月+)

  1. 数据库、API 设计
  2. CI/CD 自动化
  3. 云服务、容器编排(K8s)

附录:实用资源

中文学习资源

工具网站

命令速查


🎯 看完本手册后,下一步去哪?

你的状态下一步建议
想动手实操翻《小白入门-GitHub项目部署使用指南》跟着 7 步走
想跑通第一个项目拿你电脑上的 gpt_image_playground,按指南执行 npm installnpm run dev
想巩固名词重点回看 第零章 + 第八章(缩写表)
想深入某个具体工具直接定位本手册第 1~10 章
想交叉验证找一个 GitHub 项目从头部署一遍,碰到的所有名词都查得到