From 2a0fdd33925461cbe264005466a9e4a5d78161f1 Mon Sep 17 00:00:00 2001 From: sanbuphy Date: Mon, 23 Feb 2026 01:40:56 +0800 Subject: [PATCH] chore: save local history restorations from accidental git restore --- .prettierignore | 1 + docs/.vitepress/config.mjs | 485 +++++++++++--- .../appendix/api-design/ApiStyleCompare.vue | 479 ++++++++++++++ .../api-design/DataFieldDesignDemo.vue | 533 +++++++++++++++ .../api-design/ErrorResponseDesignDemo.vue | 575 ++++++++++++++++ .../api-design/ResponseStructureDemo.vue | 603 +++++++++++++++++ .../appendix/api-design/RestfulApiFlow.vue | 417 ++++++++++++ .../backend-evolution/ContainerDockerDemo.vue | 76 +-- .../computer-fundamentals/AdderDemo.vue | 478 +++----------- .../CpuArchitectureDemo.vue | 380 +++++++++++ .../computer-fundamentals/FilesystemDemo.vue | 521 ++++++++------- .../FunctionalUnitDemo.vue | 369 +++++++++++ .../computer-fundamentals/LogicGateDemo.vue | 197 +++--- .../computer-fundamentals/MemoryDemo.vue | 505 +++++++------- .../computer-fundamentals/ProcessDemo.vue | 522 +++++++++------ .../computer-fundamentals/RegisterDemo.vue | 240 ++----- .../SandToIntelligenceDemo.vue | 168 +++++ .../computer-fundamentals/TransistorDemo.vue | 279 ++++---- .../data-encoding/DataTransmissionDemo.vue | 122 +++- .../appendix/javascript-intro/ScopeDemo.vue | 25 +- .../typescript-intro/TypeInferenceDemo.vue | 72 +- docs/.vitepress/theme/index.js | 8 + .../computer-networks.md | 625 ++---------------- .../operating-systems.md | 258 ++------ .../transistor-to-cpu.md | 316 ++++----- .../browser-as-os-rendering.md | 2 +- .../4-server-and-backend/api-design.md | 458 +++++++++++-- 27 files changed, 5971 insertions(+), 2743 deletions(-) create mode 100644 .prettierignore create mode 100644 docs/.vitepress/theme/components/appendix/api-design/ApiStyleCompare.vue create mode 100644 docs/.vitepress/theme/components/appendix/api-design/DataFieldDesignDemo.vue create mode 100644 docs/.vitepress/theme/components/appendix/api-design/ErrorResponseDesignDemo.vue create mode 100644 docs/.vitepress/theme/components/appendix/api-design/ResponseStructureDemo.vue create mode 100644 docs/.vitepress/theme/components/appendix/api-design/RestfulApiFlow.vue create mode 100644 docs/.vitepress/theme/components/appendix/computer-fundamentals/CpuArchitectureDemo.vue create mode 100644 docs/.vitepress/theme/components/appendix/computer-fundamentals/FunctionalUnitDemo.vue create mode 100644 docs/.vitepress/theme/components/appendix/computer-fundamentals/SandToIntelligenceDemo.vue diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..de05607 --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +**/*.md diff --git a/docs/.vitepress/config.mjs b/docs/.vitepress/config.mjs index d92d8eb..daa4551 100644 --- a/docs/.vitepress/config.mjs +++ b/docs/.vitepress/config.mjs @@ -573,74 +573,224 @@ export default defineConfig({ text: '一、计算机是怎么回事', collapsed: false, items: [ - { text: '从晶体管到 CPU', link: '/zh-cn/appendix/1-computer-fundamentals/transistor-to-cpu' }, - { text: '操作系统(进程 / 内存 / 文件系统)', link: '/zh-cn/appendix/1-computer-fundamentals/operating-systems' }, - { text: '数据的编码、存储与传输', link: '/zh-cn/appendix/1-computer-fundamentals/data-encoding-storage' }, - { text: '网络:两台电脑如何对话', link: '/zh-cn/appendix/1-computer-fundamentals/computer-networks' }, - { text: '数据结构', link: '/zh-cn/appendix/1-computer-fundamentals/data-structures' }, - { text: '算法思维入门', link: '/zh-cn/appendix/1-computer-fundamentals/algorithm-thinking' }, - { text: '编程语言图谱', link: '/zh-cn/appendix/1-computer-fundamentals/programming-languages' }, - { text: '类型系统与编译原理入门', link: '/zh-cn/appendix/1-computer-fundamentals/type-systems-compilers' } + { + text: '从晶体管到 CPU', + link: '/zh-cn/appendix/1-computer-fundamentals/transistor-to-cpu' + }, + { + text: '操作系统(进程 / 内存 / 文件系统)', + link: '/zh-cn/appendix/1-computer-fundamentals/operating-systems' + }, + { + text: '数据的编码、存储与传输', + link: '/zh-cn/appendix/1-computer-fundamentals/data-encoding-storage' + }, + { + text: '网络:从输入网址到返回结果的过程', + link: '/zh-cn/appendix/1-computer-fundamentals/computer-networks' + }, + { + text: '数据结构', + link: '/zh-cn/appendix/1-computer-fundamentals/data-structures' + }, + { + text: '算法思维入门', + link: '/zh-cn/appendix/1-computer-fundamentals/algorithm-thinking' + }, + { + text: '编程语言图谱', + link: '/zh-cn/appendix/1-computer-fundamentals/programming-languages' + }, + { + text: '类型系统与编译原理入门', + link: '/zh-cn/appendix/1-computer-fundamentals/type-systems-compilers' + } ] }, { text: '二、开发环境与工具', collapsed: false, items: [ - { text: '集成开发环境 (IDE) 基础', link: '/zh-cn/appendix/2-development-tools/ide-basics' }, - { text: '命令行与 Shell 脚本', link: '/zh-cn/appendix/2-development-tools/command-line-shell' }, - { text: 'Git:代码的时光机', link: '/zh-cn/appendix/2-development-tools/git-version-control' }, - { text: '环境变量与 PATH', link: '/zh-cn/appendix/2-development-tools/environment-path' }, - { text: '端口与 localhost', link: '/zh-cn/appendix/2-development-tools/ports-localhost' }, - { text: 'SSH 与密钥认证', link: '/zh-cn/appendix/2-development-tools/ssh-authentication' }, - { text: '包管理器(npm / pip / cargo)', link: '/zh-cn/appendix/2-development-tools/package-managers' }, - { text: '调试的艺术', link: '/zh-cn/appendix/2-development-tools/debugging-art/' }, - { text: '正则表达式', link: '/zh-cn/appendix/2-development-tools/regex' } + { + text: '集成开发环境 (IDE) 基础', + link: '/zh-cn/appendix/2-development-tools/ide-basics' + }, + { + text: '命令行与 Shell 脚本', + link: '/zh-cn/appendix/2-development-tools/command-line-shell' + }, + { + text: 'Git:代码的时光机', + link: '/zh-cn/appendix/2-development-tools/git-version-control' + }, + { + text: '环境变量与 PATH', + link: '/zh-cn/appendix/2-development-tools/environment-path' + }, + { + text: '端口与 localhost', + link: '/zh-cn/appendix/2-development-tools/ports-localhost' + }, + { + text: 'SSH 与密钥认证', + link: '/zh-cn/appendix/2-development-tools/ssh-authentication' + }, + { + text: '包管理器(npm / pip / cargo)', + link: '/zh-cn/appendix/2-development-tools/package-managers' + }, + { + text: '调试的艺术', + link: '/zh-cn/appendix/2-development-tools/debugging-art/' + }, + { + text: '正则表达式', + link: '/zh-cn/appendix/2-development-tools/regex' + } ] }, { text: '三、浏览器与前端', collapsed: false, items: [ - { text: 'JavaScript 语言深入', link: '/zh-cn/appendix/3-browser-and-frontend/javascript-deep-dive' }, - { text: 'TypeScript:给 JS 加上类型系统', link: '/zh-cn/appendix/3-browser-and-frontend/typescript' }, - { text: '前端框架对比(React / Vue / Svelte / Angular)', link: '/zh-cn/appendix/3-browser-and-frontend/frontend-frameworks' }, - { text: '浏览器是一个操作系统', link: '/zh-cn/appendix/3-browser-and-frontend/browser-as-os' }, - { text: '浏览器渲染管道', link: '/zh-cn/appendix/3-browser-and-frontend/browser-as-os-rendering' }, - { text: 'HTML / CSS 布局体系', link: '/zh-cn/appendix/3-browser-and-frontend/html-css-layout' }, - { text: 'JavaScript 运行时', link: '/zh-cn/appendix/3-browser-and-frontend/javascript-runtime' }, - { text: '前端框架的本质', link: '/zh-cn/appendix/3-browser-and-frontend/frontend-framework-nature' }, - { text: '状态管理哲学', link: '/zh-cn/appendix/3-browser-and-frontend/state-management' }, - { text: '路由与导航', link: '/zh-cn/appendix/3-browser-and-frontend/routing-navigation' }, - { text: '图形与动画(Canvas / SVG / WebGL)', link: '/zh-cn/appendix/3-browser-and-frontend/graphics-animation' }, - { text: '实时通信(WebSocket / SSE)', link: '/zh-cn/appendix/3-browser-and-frontend/realtime-communication' }, - { text: '网页性能的度量与优化', link: '/zh-cn/appendix/3-browser-and-frontend/web-performance' }, - { text: '前端工程化全貌', link: '/zh-cn/appendix/3-browser-and-frontend/frontend-engineering' }, - { text: '无障碍与国际化', link: '/zh-cn/appendix/3-browser-and-frontend/a11n-i18n' } + { + text: 'JavaScript 语言深入', + link: '/zh-cn/appendix/3-browser-and-frontend/javascript-deep-dive' + }, + { + text: 'TypeScript:给 JS 加上类型系统', + link: '/zh-cn/appendix/3-browser-and-frontend/typescript' + }, + { + text: '前端框架对比(React / Vue / Svelte / Angular)', + link: '/zh-cn/appendix/3-browser-and-frontend/frontend-frameworks' + }, + { + text: '浏览器是一个操作系统', + link: '/zh-cn/appendix/3-browser-and-frontend/browser-as-os' + }, + { + text: '浏览器渲染管道', + link: '/zh-cn/appendix/3-browser-and-frontend/browser-as-os-rendering' + }, + { + text: 'HTML / CSS 布局体系', + link: '/zh-cn/appendix/3-browser-and-frontend/html-css-layout' + }, + { + text: 'JavaScript 运行时', + link: '/zh-cn/appendix/3-browser-and-frontend/javascript-runtime' + }, + { + text: '前端框架的本质', + link: '/zh-cn/appendix/3-browser-and-frontend/frontend-framework-nature' + }, + { + text: '状态管理哲学', + link: '/zh-cn/appendix/3-browser-and-frontend/state-management' + }, + { + text: '路由与导航', + link: '/zh-cn/appendix/3-browser-and-frontend/routing-navigation' + }, + { + text: '图形与动画(Canvas / SVG / WebGL)', + link: '/zh-cn/appendix/3-browser-and-frontend/graphics-animation' + }, + { + text: '实时通信(WebSocket / SSE)', + link: '/zh-cn/appendix/3-browser-and-frontend/realtime-communication' + }, + { + text: '网页性能的度量与优化', + link: '/zh-cn/appendix/3-browser-and-frontend/web-performance' + }, + { + text: '前端工程化全貌', + link: '/zh-cn/appendix/3-browser-and-frontend/frontend-engineering' + }, + { + text: '无障碍与国际化', + link: '/zh-cn/appendix/3-browser-and-frontend/a11n-i18n' + } ] }, { text: '四、服务器与后端', collapsed: false, items: [ - { text: '后端语言对比(Node.js / Go / Java / Rust)', link: '/zh-cn/appendix/4-server-and-backend/backend-languages' }, - { text: '客户端语言对比(Swift / Kotlin / Dart)', link: '/zh-cn/appendix/4-server-and-backend/client-languages' }, - { text: '跨平台方案对比(React Native / Flutter / Electron / Tauri)', link: '/zh-cn/appendix/4-server-and-backend/cross-platform' }, - { text: 'HTTP 协议', link: '/zh-cn/appendix/4-server-and-backend/http-protocol' }, - { text: '一个请求的完整旅程', link: '/zh-cn/appendix/4-server-and-backend/request-journey' }, - { text: 'Web 框架的本质', link: '/zh-cn/appendix/4-server-and-backend/web-frameworks' }, - { text: 'API 入门', link: '/zh-cn/appendix/4-server-and-backend/api-intro' }, - { text: 'API 设计哲学(REST / GraphQL / gRPC)', link: '/zh-cn/appendix/4-server-and-backend/api-design' }, - { text: '序列化与数据格式', link: '/zh-cn/appendix/4-server-and-backend/serialization' }, - { text: '认证与授权体系', link: '/zh-cn/appendix/4-server-and-backend/auth-authorization' }, - { text: '并发、异步与多线程', link: '/zh-cn/appendix/4-server-and-backend/concurrency-async' }, - { text: '缓存的层次与策略', link: '/zh-cn/appendix/4-server-and-backend/caching' }, - { text: '消息队列与事件驱动', link: '/zh-cn/appendix/4-server-and-backend/message-queues' }, - { text: '异步任务队列与生产消费模型', link: '/zh-cn/appendix/4-server-and-backend/async-task-queues' }, - { text: '限流与背压控制', link: '/zh-cn/appendix/4-server-and-backend/rate-limiting-backpressure' }, - { text: '搜索引擎原理', link: '/zh-cn/appendix/4-server-and-backend/search-engines' }, - { text: '文件存储与对象存储', link: '/zh-cn/appendix/4-server-and-backend/file-storage' }, - { text: '后端分层架构', link: '/zh-cn/appendix/4-server-and-backend/backend-layered-architecture' } + { + text: '后端语言对比(Node.js / Go / Java / Rust)', + link: '/zh-cn/appendix/4-server-and-backend/backend-languages' + }, + { + text: '客户端语言对比(Swift / Kotlin / Dart)', + link: '/zh-cn/appendix/4-server-and-backend/client-languages' + }, + { + text: '跨平台方案对比(React Native / Flutter / Electron / Tauri)', + link: '/zh-cn/appendix/4-server-and-backend/cross-platform' + }, + { + text: 'HTTP 协议', + link: '/zh-cn/appendix/4-server-and-backend/http-protocol' + }, + { + text: '一个请求的完整旅程', + link: '/zh-cn/appendix/4-server-and-backend/request-journey' + }, + { + text: 'Web 框架的本质', + link: '/zh-cn/appendix/4-server-and-backend/web-frameworks' + }, + { + text: 'API 入门', + link: '/zh-cn/appendix/4-server-and-backend/api-intro' + }, + { + text: 'API 设计哲学(REST / GraphQL / gRPC)', + link: '/zh-cn/appendix/4-server-and-backend/api-design' + }, + { + text: '序列化与数据格式', + link: '/zh-cn/appendix/4-server-and-backend/serialization' + }, + { + text: '认证与授权体系', + link: '/zh-cn/appendix/4-server-and-backend/auth-authorization' + }, + { + text: '并发、异步与多线程', + link: '/zh-cn/appendix/4-server-and-backend/concurrency-async' + }, + { + text: '缓存的层次与策略', + link: '/zh-cn/appendix/4-server-and-backend/caching' + }, + { + text: '消息队列与事件驱动', + link: '/zh-cn/appendix/4-server-and-backend/message-queues' + }, + { + text: '异步任务队列与生产消费模型', + link: '/zh-cn/appendix/4-server-and-backend/async-task-queues' + }, + { + text: '限流与背压控制', + link: '/zh-cn/appendix/4-server-and-backend/rate-limiting-backpressure' + }, + { + text: '搜索引擎原理', + link: '/zh-cn/appendix/4-server-and-backend/search-engines' + }, + { + text: '文件存储与对象存储', + link: '/zh-cn/appendix/4-server-and-backend/file-storage' + }, + { + text: '后端分层架构', + link: '/zh-cn/appendix/4-server-and-backend/backend-layered-architecture' + } ] }, { @@ -648,77 +798,218 @@ export default defineConfig({ collapsed: false, items: [ { text: 'SQL', link: '/zh-cn/appendix/5-data/sql' }, - { text: '数据库原理(索引 / 事务 / 查询优化)', link: '/zh-cn/appendix/5-data/database-fundamentals' }, - { text: '数据模型全景(文档 / 图 / 时序 / 向量)', link: '/zh-cn/appendix/5-data/data-models' }, - { text: '数据埋点与用户行为采集', link: '/zh-cn/appendix/5-data/data-tracking' }, - { text: '数据分析基础(统计 / 指标 / 漏斗)', link: '/zh-cn/appendix/5-data/data-analysis' }, - { text: 'A/B 测试与实验驱动', link: '/zh-cn/appendix/5-data/ab-testing' }, - { text: '数据可视化与仪表盘', link: '/zh-cn/appendix/5-data/data-visualization' }, - { text: '数据治理与数据质量', link: '/zh-cn/appendix/5-data/data-governance' } + { + text: '数据库原理(索引 / 事务 / 查询优化)', + link: '/zh-cn/appendix/5-data/database-fundamentals' + }, + { + text: '数据模型全景(文档 / 图 / 时序 / 向量)', + link: '/zh-cn/appendix/5-data/data-models' + }, + { + text: '数据埋点与用户行为采集', + link: '/zh-cn/appendix/5-data/data-tracking' + }, + { + text: '数据分析基础(统计 / 指标 / 漏斗)', + link: '/zh-cn/appendix/5-data/data-analysis' + }, + { + text: 'A/B 测试与实验驱动', + link: '/zh-cn/appendix/5-data/ab-testing' + }, + { + text: '数据可视化与仪表盘', + link: '/zh-cn/appendix/5-data/data-visualization' + }, + { + text: '数据治理与数据质量', + link: '/zh-cn/appendix/5-data/data-governance' + } ] }, { text: '六、架构与系统设计', collapsed: false, items: [ - { text: '从单体到微服务的演进', link: '/zh-cn/appendix/6-architecture-and-system-design/monolith-to-microservices' }, - { text: '分布式系统的挑战', link: '/zh-cn/appendix/6-architecture-and-system-design/distributed-systems' }, - { text: '高可用与容灾', link: '/zh-cn/appendix/6-architecture-and-system-design/high-availability' }, - { text: '系统设计方法论', link: '/zh-cn/appendix/6-architecture-and-system-design/system-design-methodology' } + { + text: '从单体到微服务的演进', + link: '/zh-cn/appendix/6-architecture-and-system-design/monolith-to-microservices' + }, + { + text: '分布式系统的挑战', + link: '/zh-cn/appendix/6-architecture-and-system-design/distributed-systems' + }, + { + text: '高可用与容灾', + link: '/zh-cn/appendix/6-architecture-and-system-design/high-availability' + }, + { + text: '系统设计方法论', + link: '/zh-cn/appendix/6-architecture-and-system-design/system-design-methodology' + } ] }, { text: '七、基础设施与运维', collapsed: false, items: [ - { text: 'Linux 基础', link: '/zh-cn/appendix/7-infrastructure-and-operations/linux-basics' }, - { text: 'Docker 容器化', link: '/zh-cn/appendix/7-infrastructure-and-operations/docker-containers' }, - { text: 'Kubernetes 编排', link: '/zh-cn/appendix/7-infrastructure-and-operations/kubernetes' }, - { text: 'CI / CD 自动化', link: '/zh-cn/appendix/7-infrastructure-and-operations/ci-cd' }, - { text: '域名、DNS 与 HTTPS', link: '/zh-cn/appendix/7-infrastructure-and-operations/dns-https' }, - { text: '负载均衡与网关', link: '/zh-cn/appendix/7-infrastructure-and-operations/load-balancing-gateway' }, - { text: '网关与反向代理', link: '/zh-cn/appendix/7-infrastructure-and-operations/gateway-proxy' }, - { text: '云平台实战', link: '/zh-cn/appendix/7-infrastructure-and-operations/cloud-platforms' }, - { text: 'IAM 权限管理', link: '/zh-cn/appendix/7-infrastructure-and-operations/cloud-iam' }, - { text: '对象存储与 CDN', link: '/zh-cn/appendix/7-infrastructure-and-operations/cloud-storage-cdn' }, - { text: '基础设施即代码', link: '/zh-cn/appendix/7-infrastructure-and-operations/infrastructure-as-code' }, - { text: '监控、日志与告警', link: '/zh-cn/appendix/7-infrastructure-and-operations/monitoring-logging' }, - { text: '故障排查与应急响应', link: '/zh-cn/appendix/7-infrastructure-and-operations/incident-response' } + { + text: 'Linux 基础', + link: '/zh-cn/appendix/7-infrastructure-and-operations/linux-basics' + }, + { + text: 'Docker 容器化', + link: '/zh-cn/appendix/7-infrastructure-and-operations/docker-containers' + }, + { + text: 'Kubernetes 编排', + link: '/zh-cn/appendix/7-infrastructure-and-operations/kubernetes' + }, + { + text: 'CI / CD 自动化', + link: '/zh-cn/appendix/7-infrastructure-and-operations/ci-cd' + }, + { + text: '域名、DNS 与 HTTPS', + link: '/zh-cn/appendix/7-infrastructure-and-operations/dns-https' + }, + { + text: '负载均衡与网关', + link: '/zh-cn/appendix/7-infrastructure-and-operations/load-balancing-gateway' + }, + { + text: '网关与反向代理', + link: '/zh-cn/appendix/7-infrastructure-and-operations/gateway-proxy' + }, + { + text: '云平台实战', + link: '/zh-cn/appendix/7-infrastructure-and-operations/cloud-platforms' + }, + { + text: 'IAM 权限管理', + link: '/zh-cn/appendix/7-infrastructure-and-operations/cloud-iam' + }, + { + text: '对象存储与 CDN', + link: '/zh-cn/appendix/7-infrastructure-and-operations/cloud-storage-cdn' + }, + { + text: '基础设施即代码', + link: '/zh-cn/appendix/7-infrastructure-and-operations/infrastructure-as-code' + }, + { + text: '监控、日志与告警', + link: '/zh-cn/appendix/7-infrastructure-and-operations/monitoring-logging' + }, + { + text: '故障排查与应急响应', + link: '/zh-cn/appendix/7-infrastructure-and-operations/incident-response' + } ] }, { text: '八、人工智能', collapsed: false, items: [ - { text: 'AI 简史与核心概念', link: '/zh-cn/appendix/8-artificial-intelligence/ai-history' }, - { text: '神经网络与深度学习', link: '/zh-cn/appendix/8-artificial-intelligence/neural-networks' }, - { text: 'Transformer 与注意力机制', link: '/zh-cn/appendix/8-artificial-intelligence/transformer-attention' }, - { text: '大语言模型的工作原理', link: '/zh-cn/appendix/8-artificial-intelligence/llm-principles' }, - { text: '提示词工程', link: '/zh-cn/appendix/8-artificial-intelligence/prompt-engineering' }, - { text: '上下文工程', link: '/zh-cn/appendix/8-artificial-intelligence/context-engineering' }, - { text: '多模态模型(视觉 / 音频 / 视频)', link: '/zh-cn/appendix/8-artificial-intelligence/multimodal-models' }, - { text: '图像生成原理', link: '/zh-cn/appendix/8-artificial-intelligence/image-generation' }, - { text: '语音合成与识别', link: '/zh-cn/appendix/8-artificial-intelligence/speech-synthesis-recognition' }, - { text: 'Embedding 与向量检索', link: '/zh-cn/appendix/8-artificial-intelligence/embedding-vector-retrieval' }, - { text: 'RAG 架构', link: '/zh-cn/appendix/8-artificial-intelligence/rag' }, - { text: 'AI Agent 与工具调用', link: '/zh-cn/appendix/8-artificial-intelligence/ai-agents' }, - { text: 'AI 协议(MCP & A2A)', link: '/zh-cn/appendix/8-artificial-intelligence/ai-protocols' }, - { text: '模型微调与部署', link: '/zh-cn/appendix/8-artificial-intelligence/model-finetuning-deployment' }, - { text: 'AI 原生应用设计', link: '/zh-cn/appendix/8-artificial-intelligence/ai-native-app-design' }, - { text: 'AI 能力词典', link: '/zh-cn/appendix/8-artificial-intelligence/ai-capability-dictionary' } + { + text: 'AI 简史与核心概念', + link: '/zh-cn/appendix/8-artificial-intelligence/ai-history' + }, + { + text: '神经网络与深度学习', + link: '/zh-cn/appendix/8-artificial-intelligence/neural-networks' + }, + { + text: 'Transformer 与注意力机制', + link: '/zh-cn/appendix/8-artificial-intelligence/transformer-attention' + }, + { + text: '大语言模型的工作原理', + link: '/zh-cn/appendix/8-artificial-intelligence/llm-principles' + }, + { + text: '提示词工程', + link: '/zh-cn/appendix/8-artificial-intelligence/prompt-engineering' + }, + { + text: '上下文工程', + link: '/zh-cn/appendix/8-artificial-intelligence/context-engineering' + }, + { + text: '多模态模型(视觉 / 音频 / 视频)', + link: '/zh-cn/appendix/8-artificial-intelligence/multimodal-models' + }, + { + text: '图像生成原理', + link: '/zh-cn/appendix/8-artificial-intelligence/image-generation' + }, + { + text: '语音合成与识别', + link: '/zh-cn/appendix/8-artificial-intelligence/speech-synthesis-recognition' + }, + { + text: 'Embedding 与向量检索', + link: '/zh-cn/appendix/8-artificial-intelligence/embedding-vector-retrieval' + }, + { + text: 'RAG 架构', + link: '/zh-cn/appendix/8-artificial-intelligence/rag' + }, + { + text: 'AI Agent 与工具调用', + link: '/zh-cn/appendix/8-artificial-intelligence/ai-agents' + }, + { + text: 'AI 协议(MCP & A2A)', + link: '/zh-cn/appendix/8-artificial-intelligence/ai-protocols' + }, + { + text: '模型微调与部署', + link: '/zh-cn/appendix/8-artificial-intelligence/model-finetuning-deployment' + }, + { + text: 'AI 原生应用设计', + link: '/zh-cn/appendix/8-artificial-intelligence/ai-native-app-design' + }, + { + text: 'AI 能力词典', + link: '/zh-cn/appendix/8-artificial-intelligence/ai-capability-dictionary' + } ] }, { text: '九、工程素养', collapsed: false, items: [ - { text: '代码质量与重构', link: '/zh-cn/appendix/9-engineering-excellence/code-quality-refactoring' }, - { text: '测试策略', link: '/zh-cn/appendix/9-engineering-excellence/testing-strategies' }, - { text: '设计模式', link: '/zh-cn/appendix/9-engineering-excellence/design-patterns' }, - { text: '安全思维与攻防基础', link: '/zh-cn/appendix/9-engineering-excellence/security-thinking' }, - { text: '技术文档写作', link: '/zh-cn/appendix/9-engineering-excellence/technical-writing' }, - { text: '开源协作', link: '/zh-cn/appendix/9-engineering-excellence/open-source-collaboration' }, - { text: '技术选型方法论', link: '/zh-cn/appendix/9-engineering-excellence/technology-selection' } + { + text: '代码质量与重构', + link: '/zh-cn/appendix/9-engineering-excellence/code-quality-refactoring' + }, + { + text: '测试策略', + link: '/zh-cn/appendix/9-engineering-excellence/testing-strategies' + }, + { + text: '设计模式', + link: '/zh-cn/appendix/9-engineering-excellence/design-patterns' + }, + { + text: '安全思维与攻防基础', + link: '/zh-cn/appendix/9-engineering-excellence/security-thinking' + }, + { + text: '技术文档写作', + link: '/zh-cn/appendix/9-engineering-excellence/technical-writing' + }, + { + text: '开源协作', + link: '/zh-cn/appendix/9-engineering-excellence/open-source-collaboration' + }, + { + text: '技术选型方法论', + link: '/zh-cn/appendix/9-engineering-excellence/technology-selection' + } ] } ] diff --git a/docs/.vitepress/theme/components/appendix/api-design/ApiStyleCompare.vue b/docs/.vitepress/theme/components/appendix/api-design/ApiStyleCompare.vue new file mode 100644 index 0000000..a386aff --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/api-design/ApiStyleCompare.vue @@ -0,0 +1,479 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/api-design/DataFieldDesignDemo.vue b/docs/.vitepress/theme/components/appendix/api-design/DataFieldDesignDemo.vue new file mode 100644 index 0000000..1016674 --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/api-design/DataFieldDesignDemo.vue @@ -0,0 +1,533 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/api-design/ErrorResponseDesignDemo.vue b/docs/.vitepress/theme/components/appendix/api-design/ErrorResponseDesignDemo.vue new file mode 100644 index 0000000..e8f6ce2 --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/api-design/ErrorResponseDesignDemo.vue @@ -0,0 +1,575 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/api-design/ResponseStructureDemo.vue b/docs/.vitepress/theme/components/appendix/api-design/ResponseStructureDemo.vue new file mode 100644 index 0000000..6268a5a --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/api-design/ResponseStructureDemo.vue @@ -0,0 +1,603 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/api-design/RestfulApiFlow.vue b/docs/.vitepress/theme/components/appendix/api-design/RestfulApiFlow.vue new file mode 100644 index 0000000..07ef39a --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/api-design/RestfulApiFlow.vue @@ -0,0 +1,417 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/backend-evolution/ContainerDockerDemo.vue b/docs/.vitepress/theme/components/appendix/backend-evolution/ContainerDockerDemo.vue index 4c5b82f..09d5ebe 100644 --- a/docs/.vitepress/theme/components/appendix/backend-evolution/ContainerDockerDemo.vue +++ b/docs/.vitepress/theme/components/appendix/backend-evolution/ContainerDockerDemo.vue @@ -14,30 +14,15 @@ >
传统部署
-
- 应用 A -
-
- 依赖冲突! -
-
- 依赖库 v1.0 -
-
- 操作系统 -
-
- 物理服务器 -
+
应用 A
+
依赖冲突!
+
依赖库 v1.0
+
操作系统
+
物理服务器
-
- VS -
+
VS
-
- 应用 A -
-
- 依赖 v1.0 -
+
应用 A
+
依赖 v1.0
-
- 应用 B -
-
- 依赖 v2.0 -
+
应用 B
+
依赖 v2.0
-
- Docker Engine -
-
- 宿主机操作系统 -
-
- 物理服务器 -
+
Docker Engine
+
宿主机操作系统
+
物理服务器
@@ -110,9 +81,17 @@ const showDocker = ref(false) const showConflict = ref(false) const benefits = [ - { icon: '📦', title: '环境一致性', desc: '开发、测试、生产环境完全一致,告别"在我机器上能跑"' }, + { + icon: '📦', + title: '环境一致性', + desc: '开发、测试、生产环境完全一致,告别"在我机器上能跑"' + }, { icon: '🚀', title: '快速部署', desc: '秒级启动,镜像分发,滚动更新无停机' }, - { icon: '📊', title: '资源隔离', desc: 'CPU/内存限制,互不干扰,一台机器跑多个应用' }, + { + icon: '📊', + title: '资源隔离', + desc: 'CPU/内存限制,互不干扰,一台机器跑多个应用' + }, { icon: '🔄', title: '版本管理', desc: '镜像版本化,随时回滚,灰度发布' } ] @@ -219,8 +198,13 @@ const benefits = [ } @keyframes pulse { - 0%, 100% { opacity: 1; } - 50% { opacity: 0.5; } + 0%, + 100% { + opacity: 1; + } + 50% { + opacity: 0.5; + } } .containers { diff --git a/docs/.vitepress/theme/components/appendix/computer-fundamentals/AdderDemo.vue b/docs/.vitepress/theme/components/appendix/computer-fundamentals/AdderDemo.vue index 0f69089..313bdd8 100644 --- a/docs/.vitepress/theme/components/appendix/computer-fundamentals/AdderDemo.vue +++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/AdderDemo.vue @@ -1,164 +1,82 @@ @@ -224,164 +135,25 @@ const resultDec = computed(() => border: 1px solid var(--vp-c-divider); border-radius: 8px; background: var(--vp-c-bg-soft); - padding: 1rem; + padding: 1rem 1.2rem; margin: 1rem 0; } -.demo-header { - display: flex; - align-items: center; - gap: 0.5rem; - margin-bottom: 0.75rem; -} - -.demo-header .icon { font-size: 1.25rem; } -.demo-header .title { font-weight: bold; font-size: 1rem; } -.demo-header .subtitle { color: var(--vp-c-text-2); font-size: 0.85rem; margin-left: 0.25rem; } - -.intro-section { - background: var(--vp-c-bg-alt); - border-radius: 6px; - padding: 0.75rem; - margin-bottom: 0.75rem; -} - -.intro-title { +.demo-label { + font-size: 0.78rem; font-weight: bold; - font-size: 0.85rem; - margin-bottom: 0.5rem; - color: var(--vp-c-text-1); -} - -.decimal-demo { - display: flex; - align-items: center; - gap: 0.5rem; - margin-bottom: 0.5rem; -} - -.decimal-column { - display: flex; - flex-direction: column; - gap: 0.15rem; -} - -.decimal-column.op-col { - min-width: 2rem; - text-align: center; -} - -.decimal-row { - font-size: 0.85rem; -} - -.decimal-row.label-row { - color: var(--vp-c-text-3); - font-size: 0.75rem; -} - -.decimal-row.num-row { - font-family: monospace; - font-size: 1.1rem; - font-weight: bold; -} - -.decimal-row.num-row.result { - color: var(--vp-c-brand-1); -} - -.d-digit { - display: inline-block; - min-width: 1.5rem; - text-align: center; -} - -.intro-hint { - display: flex; - align-items: flex-start; - gap: 0.35rem; - font-size: 0.8rem; color: var(--vp-c-text-2); - line-height: 1.5; -} - -.intro-hint .icon { - flex-shrink: 0; -} - -.concept-section { margin-bottom: 0.75rem; + letter-spacing: 0.2px; } -.concept-title { - font-weight: bold; - font-size: 0.85rem; - margin-bottom: 0.5rem; - color: var(--vp-c-text-1); -} - -.concepts-grid { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 0.5rem; -} - -.concept-card { - background: var(--vp-c-bg); - border: 1px solid var(--vp-c-divider); - border-radius: 6px; - padding: 0.6rem; -} - -.concept-name { - font-weight: bold; - font-size: 0.9rem; - margin-bottom: 0.15rem; -} - -.concept-simple { - font-size: 0.8rem; - color: var(--vp-c-brand-1); - font-weight: 600; - margin-bottom: 0.25rem; -} - -.concept-detail { - font-size: 0.75rem; - color: var(--vp-c-text-2); - line-height: 1.5; -} - -.concept-detail p { - margin: 0; -} - -.concept-detail .formula { - margin-top: 0.2rem; - font-family: monospace; - color: var(--vp-c-text-3); -} - -.half-adder .concept-name { color: var(--vp-c-brand-1); } -.full-adder .concept-name { color: #8b5cf6; } - -.demo-section { - margin-bottom: 0.5rem; -} - -.demo-title { - font-weight: bold; - font-size: 0.85rem; - margin-bottom: 0.5rem; - color: var(--vp-c-text-1); -} - +/* ── controls ── */ .control-row { display: flex; align-items: center; - gap: 0.4rem; + gap: 0.5rem; flex-wrap: wrap; - margin-bottom: 0.5rem; + margin-bottom: 0.6rem; } .input-group { @@ -391,67 +163,70 @@ const resultDec = computed(() => } .input-label { - font-size: 0.8rem; + font-size: 0.82rem; + font-weight: 600; color: var(--vp-c-text-2); } .num-input { - width: 3rem; - padding: 0.2rem 0.35rem; + width: 3.2rem; + padding: 0.25rem 0.4rem; border: 1px solid var(--vp-c-divider); border-radius: 4px; - font-size: 0.85rem; + font-size: 0.9rem; background: var(--vp-c-bg); color: var(--vp-c-text-1); } .op-sign { font-weight: bold; - color: var(--vp-c-text-2); + color: var(--vp-c-text-3); } .result-num { font-weight: bold; color: var(--vp-c-brand-1); - font-size: 0.95rem; + font-size: 1rem; } +/* ── binary ── */ .binary-display { background: var(--vp-c-bg-alt); border-radius: 6px; padding: 0.5rem 0.75rem; - margin-bottom: 0.5rem; + margin-bottom: 0.6rem; } .binary-row { display: flex; align-items: center; gap: 0.5rem; - margin-bottom: 0.2rem; + margin-bottom: 0.15rem; font-size: 0.85rem; } .binary-label { color: var(--vp-c-text-2); min-width: 2.5rem; + font-weight: 600; } .binary-bits { display: flex; gap: 0.2rem; - font-family: monospace; + font-family: 'JetBrains Mono', monospace; } .bit { display: inline-block; - min-width: 1.2rem; + min-width: 1.3rem; text-align: center; padding: 0.1rem 0.15rem; border-radius: 3px; - transition: all 0.15s ease; + transition: all 0.15s; } -.bit.highlight { +.bit.hl { background: var(--vp-c-brand-soft); color: var(--vp-c-brand-1); font-weight: bold; @@ -459,11 +234,11 @@ const resultDec = computed(() => .binary-dec { color: var(--vp-c-text-3); - font-size: 0.8rem; + font-size: 0.78rem; margin-left: 0.25rem; } -.result-row .binary-bits { +.sum-row .binary-bits { font-weight: bold; color: var(--vp-c-brand-1); } @@ -472,30 +247,31 @@ const resultDec = computed(() => display: flex; gap: 0.2rem; margin-left: 3rem; - margin-top: 0.15rem; + margin-top: 0.1rem; } .bit-label { - min-width: 1.2rem; + min-width: 1.3rem; text-align: center; - font-size: 0.65rem; + font-size: 0.6rem; color: var(--vp-c-text-3); } +/* ── stages ── */ .stages-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.4rem; + margin-bottom: 0.5rem; } .stage-card { background: var(--vp-c-bg); border: 1px solid var(--vp-c-divider); border-radius: 6px; - padding: 0.4rem; + padding: 0.45rem; cursor: pointer; - transition: all 0.15s ease; - position: relative; + transition: all 0.15s; } .stage-card.active { @@ -503,25 +279,25 @@ const resultDec = computed(() => box-shadow: 0 0 0 1px var(--vp-c-brand-1); } -.stage-header { +.stage-head { display: flex; justify-content: space-between; align-items: center; - margin-bottom: 0.25rem; - padding-bottom: 0.2rem; + margin-bottom: 0.2rem; + padding-bottom: 0.15rem; border-bottom: 1px solid var(--vp-c-divider); } .stage-pos { - font-size: 0.7rem; + font-size: 0.68rem; font-weight: bold; color: var(--vp-c-text-2); } .stage-type { - font-size: 0.65rem; + font-size: 0.6rem; font-weight: bold; - padding: 0.1rem 0.25rem; + padding: 0.08rem 0.25rem; border-radius: 3px; } @@ -538,22 +314,24 @@ const resultDec = computed(() => .stage-io { display: flex; flex-direction: column; - gap: 0.15rem; + gap: 0.1rem; } -.io-line { +.io-item { display: flex; align-items: center; - justify-content: space-between; - gap: 0.2rem; + gap: 0.25rem; + font-family: 'JetBrains Mono', monospace; + font-size: 0.78rem; } .io-tag { - font-size: 0.6rem; + font-size: 0.55rem; font-weight: bold; - padding: 0.05rem 0.2rem; + padding: 0.04rem 0.18rem; border-radius: 2px; color: white; + font-family: system-ui; } .io-tag.a { background: var(--vp-c-brand-1); } @@ -562,59 +340,21 @@ const resultDec = computed(() => .io-tag.s { background: var(--vp-c-green-1, #16a34a); } .io-tag.cout { background: #d97706; } -.io-val { - font-family: monospace; - font-size: 0.8rem; - font-weight: bold; -} - -.io-val.sum { - color: var(--vp-c-green-1, #16a34a); -} - .stage-divider { height: 1px; background: var(--vp-c-divider); margin: 0.2rem 0; } -.carry-arrow { - position: absolute; - right: -0.5rem; - top: 50%; - transform: translateY(-50%); - font-size: 0.6rem; - color: #d97706; - white-space: nowrap; -} - -.carry-arrow.hasCarry { - font-weight: bold; -} - -.info-box { - display: flex; - align-items: flex-start; - gap: 0.35rem; - background: var(--vp-c-bg-alt); - padding: 0.6rem 0.75rem; - border-radius: 6px; - font-size: 0.8rem; - color: var(--vp-c-text-2); - line-height: 1.5; -} - -.info-box .icon { - flex-shrink: 0; +.demo-caption { + font-size: 0.72rem; + color: var(--vp-c-text-3); + text-align: center; } @media (max-width: 600px) { .stages-row { grid-template-columns: repeat(2, 1fr); } - - .concepts-grid { - grid-template-columns: 1fr; - } } diff --git a/docs/.vitepress/theme/components/appendix/computer-fundamentals/CpuArchitectureDemo.vue b/docs/.vitepress/theme/components/appendix/computer-fundamentals/CpuArchitectureDemo.vue new file mode 100644 index 0000000..1c446f8 --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/CpuArchitectureDemo.vue @@ -0,0 +1,380 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/computer-fundamentals/FilesystemDemo.vue b/docs/.vitepress/theme/components/appendix/computer-fundamentals/FilesystemDemo.vue index 93ec518..d0a68a9 100644 --- a/docs/.vitepress/theme/components/appendix/computer-fundamentals/FilesystemDemo.vue +++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/FilesystemDemo.vue @@ -1,303 +1,314 @@ diff --git a/docs/.vitepress/theme/components/appendix/computer-fundamentals/FunctionalUnitDemo.vue b/docs/.vitepress/theme/components/appendix/computer-fundamentals/FunctionalUnitDemo.vue new file mode 100644 index 0000000..77f9194 --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/FunctionalUnitDemo.vue @@ -0,0 +1,369 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/computer-fundamentals/LogicGateDemo.vue b/docs/.vitepress/theme/components/appendix/computer-fundamentals/LogicGateDemo.vue index d4d4279..b2ecbfc 100644 --- a/docs/.vitepress/theme/components/appendix/computer-fundamentals/LogicGateDemo.vue +++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/LogicGateDemo.vue @@ -1,56 +1,56 @@ @@ -59,82 +59,81 @@ const truthRows = [ border: 1px solid var(--vp-c-divider); border-radius: 8px; background: var(--vp-c-bg-soft); - padding: 1rem; + padding: 1rem 1.2rem; margin: 1rem 0; } -.demo-header { +.demo-label { + font-size: 0.78rem; + font-weight: bold; + color: var(--vp-c-text-2); + margin-bottom: 0.75rem; + letter-spacing: 0.2px; +} + +.gates-grid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 0.5rem; +} + +.gate-card { + background: var(--vp-c-bg); + border: 1px solid var(--vp-c-divider); + border-radius: 6px; + padding: 0.6rem; + text-align: center; +} + +.gate-name { + font-weight: bold; + font-size: 0.9rem; + color: var(--vp-c-brand-1); + margin-bottom: 0.15rem; +} + +.gate-rule { + font-size: 0.72rem; + color: var(--vp-c-text-3); margin-bottom: 0.5rem; } -.demo-header .title { - font-weight: bold; - font-size: 1rem; -} - -.intro { - font-size: 0.9rem; - color: var(--vp-c-text-2); - margin: 0 0 0.75rem; - line-height: 1.5; -} - -.truth-section { - margin-bottom: 0; -} - -table { +.mini-truth { width: 100%; border-collapse: collapse; - table-layout: fixed; - font-size: 0.88rem; - margin-bottom: 0.75rem; + font-size: 0.8rem; + font-variant-numeric: tabular-nums; } -th, -td { +.mini-truth th, +.mini-truth td { border: 1px solid var(--vp-c-divider); - padding: 0.4rem 0.5rem; - vertical-align: middle; + padding: 0.2rem 0.3rem; text-align: center; - font-variant-numeric: tabular-nums; } -th { +.mini-truth th { background: var(--vp-c-bg-alt); + font-size: 0.72rem; font-weight: 600; -} - -.col-meaning { - margin: 0; - padding-left: 1.25rem; - font-size: 0.85rem; color: var(--vp-c-text-2); - line-height: 1.6; } -.col-meaning li { - margin-bottom: 0.25rem; +.result-cell.one { + color: var(--vp-c-brand-1); + font-weight: bold; } -.col-meaning strong { - color: var(--vp-c-text-1); - font-variant-numeric: tabular-nums; +.demo-caption { + font-size: 0.72rem; + color: var(--vp-c-text-3); + margin-top: 0.6rem; + text-align: center; } -.info-box { - display: flex; - gap: 0.25rem; - background: var(--vp-c-bg-alt); - padding: 0.75rem; - border-radius: 6px; - font-size: 0.85rem; - color: var(--vp-c-text-2); - margin-top: 0.75rem; -} - -.info-box strong { - white-space: nowrap; - flex-shrink: 0; +@media (max-width: 600px) { + .gates-grid { + grid-template-columns: repeat(2, 1fr); + } } diff --git a/docs/.vitepress/theme/components/appendix/computer-fundamentals/MemoryDemo.vue b/docs/.vitepress/theme/components/appendix/computer-fundamentals/MemoryDemo.vue index a1348c5..774c9a1 100644 --- a/docs/.vitepress/theme/components/appendix/computer-fundamentals/MemoryDemo.vue +++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/MemoryDemo.vue @@ -1,80 +1,65 @@ @@ -82,215 +67,273 @@ diff --git a/docs/.vitepress/theme/components/appendix/computer-fundamentals/ProcessDemo.vue b/docs/.vitepress/theme/components/appendix/computer-fundamentals/ProcessDemo.vue index 1caec59..a8b28e5 100644 --- a/docs/.vitepress/theme/components/appendix/computer-fundamentals/ProcessDemo.vue +++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/ProcessDemo.vue @@ -1,272 +1,356 @@ diff --git a/docs/.vitepress/theme/components/appendix/computer-fundamentals/RegisterDemo.vue b/docs/.vitepress/theme/components/appendix/computer-fundamentals/RegisterDemo.vue index 1d0e24d..595bf39 100644 --- a/docs/.vitepress/theme/components/appendix/computer-fundamentals/RegisterDemo.vue +++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/RegisterDemo.vue @@ -1,60 +1,38 @@ @@ -69,9 +47,7 @@ const isWriting = ref(false) const writeOnce = () => { isWriting.value = true storedData.value = inputData.value - window.setTimeout(() => { - isWriting.value = false - }, 400) + setTimeout(() => { isWriting.value = false }, 400) } @@ -80,75 +56,44 @@ const writeOnce = () => { border: 1px solid var(--vp-c-divider); border-radius: 8px; background: var(--vp-c-bg-soft); - padding: 1rem; + padding: 1rem 1.2rem; margin: 1rem 0; } -.demo-header { - margin-bottom: 0.5rem; -} - -.demo-header .title { - display: block; +.demo-label { + font-size: 0.78rem; font-weight: bold; - font-size: 1rem; -} - -.demo-header .subtitle { - display: block; - font-size: 0.82rem; color: var(--vp-c-text-2); - font-weight: normal; -} - -.why-what-box { - background: var(--vp-c-bg-alt); - border: 1px solid var(--vp-c-divider); - border-radius: 6px; - padding: 0.65rem 0.85rem; margin-bottom: 0.75rem; - font-size: 0.85rem; - color: var(--vp-c-text-2); - line-height: 1.55; + letter-spacing: 0.2px; } -.why-what-box .why-p { - margin: 0 0 0.4rem; -} - -.why-what-box .what-p { - margin: 0; -} - -.why-what-box .term { - font-weight: 600; - color: var(--vp-c-text-1); -} - -.control-panel { +/* ── panel ── */ +.reg-panel { display: flex; - flex-wrap: wrap; align-items: center; gap: 0.6rem; - padding: 0.5rem 0.7rem; + flex-wrap: wrap; + padding: 0.6rem 0.8rem; border: 1px solid var(--vp-c-divider); border-radius: 8px; background: var(--vp-c-bg); - margin-bottom: 0.75rem; } -.ctrl-group { - display: inline-flex; +.reg-block { + display: flex; + flex-direction: column; align-items: center; - gap: 0.35rem; + gap: 0.25rem; } -.ctrl-label { - font-size: 0.82rem; - color: var(--vp-c-text-2); +.reg-title { + font-size: 0.7rem; + font-weight: 600; + color: var(--vp-c-text-3); } -.input-toggle { +.toggle-btn { width: 2.2rem; height: 2.2rem; border-radius: 6px; @@ -156,26 +101,28 @@ const writeOnce = () => { background: var(--vp-c-bg-alt); font-weight: bold; font-size: 1rem; + font-family: 'JetBrains Mono', monospace; cursor: pointer; transition: all 0.2s; } -.input-toggle.on { - border-color: var(--vp-c-brand); - color: var(--vp-c-brand); +.toggle-btn.on { + border-color: var(--vp-c-brand-1); + color: var(--vp-c-brand-1); background: var(--vp-c-brand-soft); } .write-btn { - padding: 0.35rem 0.8rem; + padding: 0.35rem 0.7rem; border-radius: 6px; border: 2px solid var(--vp-c-warning-1, #d97706); background: var(--vp-c-bg); color: var(--vp-c-warning-1, #d97706); - font-size: 0.85rem; + font-size: 0.82rem; font-weight: bold; cursor: pointer; transition: all 0.2s; + white-space: nowrap; } .write-btn:hover { @@ -187,93 +134,44 @@ const writeOnce = () => { color: white; } -.stored-val, -.output-val { +.val-box { display: inline-flex; align-items: center; justify-content: center; - min-width: 2rem; - height: 2rem; - padding: 0 0.4rem; + width: 2.2rem; + height: 2.2rem; border-radius: 6px; border: 2px solid var(--vp-c-divider); background: var(--vp-c-bg-alt); font-weight: bold; - font-family: monospace; + font-family: 'JetBrains Mono', monospace; font-size: 1rem; + transition: all 0.2s; } -.stored-val.on, -.output-val.on { - border-color: var(--vp-c-brand); - color: var(--vp-c-brand); +.val-box.on { + border-color: var(--vp-c-brand-1); + color: var(--vp-c-brand-1); background: var(--vp-c-brand-soft); } -.visualization-area { - margin-bottom: 0.75rem; +.val-box.flash { + box-shadow: 0 0 0 3px var(--vp-c-warning-soft, rgba(217, 119, 6, 0.25)); } -.flow-strip { - display: flex; - flex-wrap: wrap; - align-items: center; - gap: 0.4rem; - padding: 0.6rem 0.8rem; - border: 1px solid var(--vp-c-divider); - border-radius: 8px; - background: var(--vp-c-bg); - font-size: 0.9rem; +.val-box.out { + border-style: dashed; } -.flow-item { - font-weight: bold; -} - -.flow-store { - color: var(--vp-c-brand); -} - -.flow-store.flash { - box-shadow: 0 0 0 2px var(--vp-c-warning-1); - border-radius: 4px; -} - -.flow-arrow { +.status-line { + margin-top: 0.5rem; + font-size: 0.78rem; color: var(--vp-c-text-3); - font-size: 0.82rem; } -.flow-arrow.active { - color: var(--vp-c-warning-1); - font-weight: bold; -} - -.flow-hint { - margin: 0.4rem 0 0; - font-size: 0.82rem; - color: var(--vp-c-text-2); -} - -.info-box { - display: flex; - gap: 0.25rem; - background: var(--vp-c-bg-alt); - padding: 0.75rem; - border-radius: 6px; - font-size: 0.85rem; - color: var(--vp-c-text-2); -} - -.info-box strong { - white-space: nowrap; - flex-shrink: 0; -} - -@media (max-width: 520px) { - .control-panel { - flex-direction: column; - align-items: flex-start; +@media (max-width: 480px) { + .reg-panel { + justify-content: center; } } diff --git a/docs/.vitepress/theme/components/appendix/computer-fundamentals/SandToIntelligenceDemo.vue b/docs/.vitepress/theme/components/appendix/computer-fundamentals/SandToIntelligenceDemo.vue new file mode 100644 index 0000000..aa7d9d8 --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/SandToIntelligenceDemo.vue @@ -0,0 +1,168 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/computer-fundamentals/TransistorDemo.vue b/docs/.vitepress/theme/components/appendix/computer-fundamentals/TransistorDemo.vue index 3b2b0d8..4c1cd54 100644 --- a/docs/.vitepress/theme/components/appendix/computer-fundamentals/TransistorDemo.vue +++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/TransistorDemo.vue @@ -1,47 +1,45 @@ diff --git a/docs/.vitepress/theme/components/appendix/data-encoding/DataTransmissionDemo.vue b/docs/.vitepress/theme/components/appendix/data-encoding/DataTransmissionDemo.vue index 5757d30..013aaee 100644 --- a/docs/.vitepress/theme/components/appendix/data-encoding/DataTransmissionDemo.vue +++ b/docs/.vitepress/theme/components/appendix/data-encoding/DataTransmissionDemo.vue @@ -6,13 +6,19 @@
@@ -31,7 +37,7 @@ :key="i" class="bit" :class="{ sent: sentBits.includes(i) }" - >{{ bit }} + >{{ bit }}
@@ -45,7 +51,7 @@ :key="'p' + i" class="particle" :style="{ left: p.progress + '%', top: '50%' }" - >{{ p.bit }} + >{{ p.bit }}
@@ -55,7 +61,7 @@ v-if="parallelParticle && parallelParticle.lane === l - 1" class="particle" :style="{ left: parallelParticle.progress + '%', top: '50%' }" - >{{ parallelBits[l - 1] || '·' }} + >{{ parallelBits[l - 1] || '·' }}
@@ -69,9 +75,13 @@ v-for="(bit, i) in receivedBits" :key="'r' + i" class="bit received" - >{{ bit }} + >{{ bit }} -
+
{{ checksumResult ? '✓ 校验通过' : '✕ 校验失败' }}
@@ -85,7 +95,9 @@
传输速率 - {{ mode === 'serial' ? '1 位/次' : '8 位/次' }} + {{ + mode === 'serial' ? '1 位/次' : '8 位/次' + }}
状态 @@ -99,8 +111,10 @@
- 提示:等等,串行不是更慢吗?
- 表面上是的——但现代串行接口(USB 4、PCIe)传输频率高达每秒 数百亿次,而并行线路之间会产生 信号串扰(Crosstalk),反而限制了速度。所以高速接口全面转向了串行。 + 提示:等等,串行不是更慢吗?
+ 表面上是的——但现代串行接口(USB 4、PCIe)传输频率高达每秒 + 数百亿次,而并行线路之间会产生 + 信号串扰(Crosstalk),反而限制了速度。所以高速接口全面转向了串行。
@@ -109,7 +123,7 @@ import { ref, computed } from 'vue' const mode = ref('serial') -const dataBits = ref([1,0,1,1,0,0,1,0]) // "Hello" first byte 0b10110010 +const dataBits = ref([1, 0, 1, 1, 0, 0, 1, 0]) // "Hello" first byte 0b10110010 const sentBits = ref([]) const receivedBits = ref([]) const particles = ref([]) @@ -141,7 +155,9 @@ const statusColor = computed(() => { return '' }) -function sleep(ms) { return new Promise(r => setTimeout(r, ms)) } +function sleep(ms) { + return new Promise((r) => setTimeout(r, ms)) +} async function send() { if (isSending.value) return @@ -156,7 +172,7 @@ async function send() { // Checksum simulation await sleep(400) - checksumResult.value = true // always pass in demo + checksumResult.value = true // always pass in demo isSending.value = false } @@ -171,7 +187,7 @@ async function sendSerial() { p.progress = prog await sleep(35) } - particles.value = particles.value.filter(x => x !== p) + particles.value = particles.value.filter((x) => x !== p) receivedBits.value.push(bit) await sleep(30) } @@ -181,7 +197,10 @@ async function sendParallel() { sentBits.value = dataBits.value.map((_, i) => i) parallelBits.value = [...dataBits.value] for (let prog = 0; prog <= 100; prog += 8) { - parallelParticle.value = { progress: prog, lane: Math.floor(Math.random() * 8) } + parallelParticle.value = { + progress: prog, + lane: Math.floor(Math.random() * 8) + } await sleep(40) } parallelParticle.value = null @@ -249,10 +268,17 @@ async function sendParallel() { width: 100px; } -.device-icon { font-size: 2rem; } -.device-label { font-size: 0.8rem; font-weight: bold; color: var(--vp-c-text-2); } +.device-icon { + font-size: 2rem; +} +.device-label { + font-size: 0.8rem; + font-weight: bold; + color: var(--vp-c-text-2); +} -.data-bits, .received-bits { +.data-bits, +.received-bits { display: flex; flex-wrap: wrap; gap: 2px; @@ -273,8 +299,15 @@ async function sendParallel() { transition: all 0.2s; } -.bit.sent { background: var(--vp-c-brand-soft); border-color: var(--vp-c-brand); } -.bit.received { background: #d1fae5; border-color: #059669; color: #065f46; } +.bit.sent { + background: var(--vp-c-brand-soft); + border-color: var(--vp-c-brand); +} +.bit.received { + background: #d1fae5; + border-color: #059669; + color: #065f46; +} .checksum-badge { margin-top: 4px; @@ -283,8 +316,14 @@ async function sendParallel() { border-radius: 4px; font-weight: bold; } -.checksum-badge.ok { background: #d1fae5; color: #065f46; } -.checksum-badge.fail { background: #fee2e2; color: #991b1b; } +.checksum-badge.ok { + background: #d1fae5; + color: #065f46; +} +.checksum-badge.fail { + background: #fee2e2; + color: #991b1b; +} /* Wires */ .wire-container { @@ -311,8 +350,14 @@ async function sendParallel() { overflow: hidden; } -.wire-group.serial .wire { height: 20px; } -.parallel-group { display: flex; flex-direction: column; gap: 2px; } +.wire-group.serial .wire { + height: 20px; +} +.parallel-group { + display: flex; + flex-direction: column; + gap: 2px; +} .particle { position: absolute; @@ -337,11 +382,25 @@ async function sendParallel() { padding: 0.6rem 0.85rem; } -.status-item { display: flex; flex-direction: column; gap: 2px; } -.s-label { font-size: 0.72rem; color: var(--vp-c-text-3); } -.s-val { font-size: 0.88rem; font-weight: bold; } -.s-val.green { color: #059669; } -.s-val.yellow { color: #d97706; } +.status-item { + display: flex; + flex-direction: column; + gap: 2px; +} +.s-label { + font-size: 0.72rem; + color: var(--vp-c-text-3); +} +.s-val { + font-size: 0.88rem; + font-weight: bold; +} +.s-val.green { + color: #059669; +} +.s-val.yellow { + color: #d97706; +} .send-btn { padding: 0.5rem 1.2rem; @@ -356,7 +415,10 @@ async function sendParallel() { align-self: flex-start; } -.send-btn:disabled { opacity: 0.6; cursor: not-allowed; } +.send-btn:disabled { + opacity: 0.6; + cursor: not-allowed; +} .note-box { background: var(--vp-c-bg-alt); diff --git a/docs/.vitepress/theme/components/appendix/javascript-intro/ScopeDemo.vue b/docs/.vitepress/theme/components/appendix/javascript-intro/ScopeDemo.vue index ae948a9..a54d68e 100644 --- a/docs/.vitepress/theme/components/appendix/javascript-intro/ScopeDemo.vue +++ b/docs/.vitepress/theme/components/appendix/javascript-intro/ScopeDemo.vue @@ -35,8 +35,10 @@ const scopes = [ const updateExplanation = () => { const texts = { global: '在全局作用域,只能使用全局变量 appName', - function: '在函数作用域,可以使用自己的 message 和全局的 appName(作用域链查找)', - block: '在块级作用域,可以使用自己的 greeting,以及外层的 message 和 appName' + function: + '在函数作用域,可以使用自己的 message 和全局的 appName(作用域链查找)', + block: + '在块级作用域,可以使用自己的 greeting,以及外层的 message 和 appName' } explanation.value = texts[activeScope.value] } @@ -68,13 +70,13 @@ updateExplanation() v-for="scope in scopes" :key="scope.id" class="level" - :class="{ active: activeScope === scope.id, dimmed: activeScope !== scope.id }" + :class="{ + active: activeScope === scope.id, + dimmed: activeScope !== scope.id + }" :style="{ borderLeftColor: scope.color }" > -
+
{{ scope.name }}
@@ -86,10 +88,7 @@ updateExplanation() > {{ v.name }} = {{ v.value }} - ← {{ v.from }} + ← {{ v.from }}
@@ -97,9 +96,7 @@ updateExplanation()
-
- 💡 当前位置可见的变量 -
+
💡 当前位置可见的变量
{{ explanation }}
diff --git a/docs/.vitepress/theme/components/appendix/typescript-intro/TypeInferenceDemo.vue b/docs/.vitepress/theme/components/appendix/typescript-intro/TypeInferenceDemo.vue index ccc9cfd..923d179 100644 --- a/docs/.vitepress/theme/components/appendix/typescript-intro/TypeInferenceDemo.vue +++ b/docs/.vitepress/theme/components/appendix/typescript-intro/TypeInferenceDemo.vue @@ -86,14 +86,18 @@ const bestPractices = ref([ const codeComparisons = ref([ { scenario: '函数返回值', - withInference: 'function add(a: number, b: number) {\n return a + b // 推断为 number\n}', - withAnnotation: 'function add(a: number, b: number): number {\n return a + b\n}', + withInference: + 'function add(a: number, b: number) {\n return a + b // 推断为 number\n}', + withAnnotation: + 'function add(a: number, b: number): number {\n return a + b\n}', recommendation: '推荐使用推断' }, { scenario: '复杂对象', - withInference: 'const user = {\n name: "张三",\n age: 25,\n email: "test@example.com"\n} // 类型自动推断', - withAnnotation: 'interface User {\n name: string\n age: number\n email: string\n}\n\nconst user: User = { ... }', + withInference: + 'const user = {\n name: "张三",\n age: 25,\n email: "test@example.com"\n} // 类型自动推断', + withAnnotation: + 'interface User {\n name: string\n age: number\n email: string\n}\n\nconst user: User = { ... }', recommendation: '复杂结构建议用接口' } ]) @@ -107,12 +111,13 @@ const codeComparisons = ref([
-
- 🧠 -
+
🧠

什么是类型推断?

-

TypeScript 很聪明,它能根据你写的代码自动推断出变量的类型,不需要每次都手动标注。

+

+ TypeScript + 很聪明,它能根据你写的代码自动推断出变量的类型,不需要每次都手动标注。 +

@@ -124,15 +129,16 @@ const codeComparisons = ref([
{{ example.code }}
-
- → {{ example.inferredType }} -
+
→ {{ example.inferredType }}
@@ -148,9 +154,7 @@ const codeComparisons = ref([
{{ currentExample.code }}
-
- → -
+
@@ -164,9 +168,7 @@ const codeComparisons = ref([
-
- 💡 -
+
💡
{{ currentExample.explanation }}
@@ -183,16 +185,8 @@ const codeComparisons = ref([
- - +
@@ -210,10 +204,7 @@ const codeComparisons = ref([ {{ practice.title }}
@@ -234,15 +225,11 @@ const codeComparisons = ref([
-
- 使用推断 -
+
使用推断
{{ comparison.withInference }}
-
- 显式注解 -
+
显式注解
{{ comparison.withAnnotation }}
@@ -265,7 +252,8 @@ const codeComparisons = ref([ background: var(--vp-c-bg); } -h3, h4 { +h3, +h4 { margin: 0 0 16px 0; font-weight: 600; color: var(--vp-c-text-1); @@ -380,7 +368,8 @@ h4 { } } -.code-panel, .type-panel { +.code-panel, +.type-panel { flex: 1; border: 2px solid var(--vp-c-border); border-radius: 8px; @@ -398,7 +387,8 @@ h4 { gap: 8px; } -.code-icon, .type-icon { +.code-icon, +.type-icon { font-size: 16px; } diff --git a/docs/.vitepress/theme/index.js b/docs/.vitepress/theme/index.js index a207d35..273529f 100644 --- a/docs/.vitepress/theme/index.js +++ b/docs/.vitepress/theme/index.js @@ -559,6 +559,10 @@ import RestfulUrlDemo from './components/appendix/api-design/RestfulUrlDemo.vue' import StatusCodeDemo from './components/appendix/api-design/StatusCodeDemo.vue' import ErrorHandlingDemo from './components/appendix/api-design/ErrorHandlingDemo.vue' import ApiVersioningDemo from './components/appendix/api-design/ApiVersioningDemo.vue' +import ApiStyleCompare from './components/appendix/api-design/ApiStyleCompare.vue' +import ResponseStructureDemo from './components/appendix/api-design/ResponseStructureDemo.vue' +import DataFieldDesignDemo from './components/appendix/api-design/DataFieldDesignDemo.vue' +import ErrorResponseDesignDemo from './components/appendix/api-design/ErrorResponseDesignDemo.vue' // JavaScript Intro Components import VariableBoxDemo from './components/appendix/javascript-intro/VariableBoxDemo.vue' @@ -1172,6 +1176,10 @@ export default { app.component('StatusCodeDemo', StatusCodeDemo) app.component('ErrorHandlingDemo', ErrorHandlingDemo) app.component('ApiVersioningDemo', ApiVersioningDemo) + app.component('ApiStyleCompare', ApiStyleCompare) + app.component('ResponseStructureDemo', ResponseStructureDemo) + app.component('DataFieldDesignDemo', DataFieldDesignDemo) + app.component('ErrorResponseDesignDemo', ErrorResponseDesignDemo) // Database Intro Extra Components Registration app.component('DatabaseEvolutionDemo', DatabaseEvolutionDemo) diff --git a/docs/zh-cn/appendix/1-computer-fundamentals/computer-networks.md b/docs/zh-cn/appendix/1-computer-fundamentals/computer-networks.md index dc7518a..66614b5 100644 --- a/docs/zh-cn/appendix/1-computer-fundamentals/computer-networks.md +++ b/docs/zh-cn/appendix/1-computer-fundamentals/computer-networks.md @@ -1,625 +1,84 @@ -# 网络:两台电脑如何对话 +# 计算机网络:从输入网址到返回结果的过程 + ::: tip 🎯 核心问题 -**当你在浏览器输入 www.baidu.com 并按下回车,到底发生了什么?** 这个简单动作背后,其实隐藏着一个庞大的"快递系统":从填写订单(URL)到查询地址簿(DNS),从建立运输通道(TCP)到快递员送货(HTTP),最终在你屏幕上展示(渲染)。本章带你完整理解这个神奇的过程。 +**当你在浏览器输入 www.google.com 并按下回车,到底发生了什么?** + +这个看似简单的动作,背后隐藏着一个庞大精密的跨国“快递系统”。从填写订单(URL解析)到查询地址簿(DNS解析),从建立运输通道(TCP握手)到快递员送货(HTTP请求与响应),最终在你屏幕上拆开包裹组装(浏览器渲染)。本章带你零基础、完整理解这个神奇的过程。 ::: --- -## 0. 五层模型总览:快递公司的组织架构 +## 全景演示:网络世界的快递系统 -现代计算机网络就像一个**快递公司**,采用五层分层模型,每层负责不同的工作: +你可以通过下方的交互组件,直观地体验从输入网址到看到网页的 5 个关键步骤。先自己点一点,然后再看底下的详细解释! - - -::: tip 💡 为什么需要分层? -想象一个没有分工的快递公司: - -- **每个人什么都干**:接电话、分拣、打包、开车送货... -- **效率极低**:没人专精,什么都做不好 -- **难以扩展**:想加个"航空运输",所有员工都要重新培训 - -**分层设计**解决了这些问题: - -- **模块化**:每层独立设计和实现,改一层不影响其他层 -- **易维护**:网络慢了?查物理层和数据链路层;安全问题?查应用层 -- **标准化**:统一的接口和协议,不同厂商的设备能互相通信 -- **可扩展**:新技术可以替换某一层,比如从铜线换成光纤,只需改物理层 - ::: - -| 层级 | 技术名称 | 快递公司类比 | 核心职责 | 常见协议/设备 | -| ----- | ---------- | ---------------- | ---------------------------------------- | ------------------ | -| **5** | 应用层 | **客户服务部门** | 处理具体业务(网页、邮件、文件传输) | HTTP, FTP, SMTP | -| **4** | 传输层 | **包裹分拣组** | 确保包裹可靠送达(_TCP_)或快速送达(_UDP_) | TCP, UDP | -| **3** | 网络层 | **路由规划部** | 规划最佳运输路线,选择走哪条路 | IP, 路由器 | -| **2** | 数据链路层 | **车队管理** | 管理车辆之间的通信,MAC 地址寻址 | 以太网, 交换机 | -| **1** | 物理层 | **道路和车辆** | 实际的物理传输(电缆、光纤、无线电波) | 网线, 光纤, 无线电 | - -::: tip 📊 逐行解读这张表 -**第5层(应用层)**:这是你直接接触的层。浏览器打开网页、邮件客户端收发邮件,都是在调用这一层的服务。它负责处理"具体的业务逻辑"。 - -**第4层(传输层)**:应用层把数据给它,它负责决定用什么方式"寄送"。TCP 像挂号信(可靠但慢),UDP 像平信(快但可能丢)。这一层用**端口号**区分不同的应用程序。 - -**第3层(网络层)**:这是"全球定位系统"层。IP 地址就在这一层,路由器根据 IP 地址规划路线:"从北京到上海,应该走哪条高速公路?" - -**第2层(数据链路层)**:这一层负责"两站之间"的运输。就像快递车从北京分拣中心开到天津分拣中心,这一段路的通信规则由数据链路层规定。MAC 地址(设备身份证)也在这一层。 - -**第1层(物理层)**:这是最底层,实实在在的物理介质。网线里的电信号、光纤里的光信号、Wi-Fi 的无线电波,都是物理层负责的。 -::: + --- -## 1. 物理层:道路和车辆 +## 1. 填写购物单 (URL 解析) -### 1.1 基本概念 +当你在浏览器的地址栏中输入 `https://www.google.com` 这样一段地址并按下回车,这就像是你准备去商店买东西,首先要在**购物单**上写清楚: -::: tip 💡 物理层是什么? -物理层负责在物理介质上传输原始的比特流(0 和 1)。 +- **交通方式 (Protocol)**:例如 `https://`,代表你想坐安全级别的最高的“运钞车”(加密通信)去。如果是单纯的 `http://`,就相当于坐普通的“大巴”(明文传输),路上可能会被人偷看行李。 +- **店铺地址 (Host)**:例如 `www.google.com`,也就是你要去哪家店(域名)。 +- **商品位置 (Path)**:例如 `/search`,意思是进了商店之后,你要去哪个货架找什么东西(即请求的具体资源路径)。 -**生活类比**:想象快递公司需要有**道路**和**运输车辆**: - -- 道路可以是:高速公路(光纤)、普通公路(网线)、航空线路(无线电波) -- 车辆可以是:卡车(有线传输)、飞机(无线传输) -- 货物(数据)最终都要变成能在这些道路上运输的形式 - ::: - -**关键任务**: - -- **定义物理设备标准**:RJ45 网线接口长什么样、光纤接口怎么接 -- **规定传输介质**: - - 有线:双绞线(网线)、光纤、同轴电缆 - - 无线:Wi-Fi、蓝牙、4G/5G -- **确定电气特性**: - - 用多少电压代表 0 和 1? - - 信号频率是多少? - - 怎么编码(比如曼彻斯特编码)? - -### 1.2 传输介质 - -**有线介质**: - -| 类型 | 速度 | 距离 | 特点 | 用途 | -| ------------ | ---------------- | -------- | ------------------------ | ------------------------ | -| **双绞线** | 100Mbps - 10Gbps | 100m | 成本低,易安装,抗干扰一般 | 家庭、办公室网络 | -| **光纤** | 1Gbps - 100Tbps | 几十公里 | 速度极快,抗干扰强,成本高 | 长距离、高带宽(跨海光缆) | -| **同轴电缆** | 10Mbps - 1Gbps | 500m | 抗干扰好,但较粗 | 早期以太网、有线电视 | - -::: tip 💡 为什么光纤这么快? -光纤用**光**而不是电信号传输: - -- 光的频率极高,能调制大量数据(就像用不同颜色的光同时传输) -- 光在光纤中几乎不衰减,能传输几十公里 -- 不受电磁干扰(高压电线、雷电都不怕) - -这就像用电信号寄快递(铜线)vs 用光速寄快递(光纤),速度差异是本质级别的。 -::: - -**无线介质**: - -| 类型 | 频段 | 速度 | 距离 | 用途 | -| --------- | -------------------- | ------------------- | ------ | -------------------- | -| **Wi-Fi** | 2.4GHz / 5GHz / 6GHz | 几十 Mbps - 几 Gbps | 几十米 | 家庭、办公室无线网络 | -| **蓝牙** | 2.4GHz | 1-3 Mbps | 10m | 耳机、键鼠等短距设备 | -| **4G/5G** | 700MHz - 39GHz | 10Mbps - 10Gbps | 几公里 | 移动网络 | - -### 1.3 常见设备 - -**中继器(Repeater)**: - -- **作用**:放大信号,延长传输距离 -- **生活类比**:快递中转站。快递车开了 500 公里需要加油、司机换班,中继器就是让信号"休息充电"的地方 -- **为什么需要**:电信号在铜线传输会衰减,传几百米就弱得识别不出了 - -**集线器(Hub)**: - -- **作用**:多端口中继器,从一个口收到的信号复制到所有口 -- **缺点**:效率低,已被**交换机**取代 -- **生活类比**:一个大厅,一个人喊话,所有人都能听到,但不是喊给谁的 +浏览器第一步要做的,就是把这段“人类语言”拆解开,看看你到底想要什么。 --- -## 2. 数据链路层:车队管理 +## 2. 查找店铺地址 (DNS 解析) -### 2.1 基本概念 +网络世界的“快递员”(路由器设备)是不懂英文的,它们只认数字(也就是 **IP 地址**)。 -::: tip 💡 数据链路层做什么? -数据链路层负责在**直连的两个节点**间传输数据帧。 +它们需要知道对方的精确数字坐标!这就像快递员不知道“王府井百货”在哪,他必须先查地图,找到“北京市东城区王府井大街255号”这个确切的门牌号(比如 `142.250.66.4`)。 -**生活类比**:快递公司的**车队管理**: - -- 快递车从北京分拣中心开到天津分拣中心(点对点) -- 车上有司机(负责驾驶)、装卸工(负责搬运) -- 两边分拣中心之间有约定:"每天 8 点发车""用标准尺寸的快递箱" - ::: - -**核心功能**: - -- **物理地址寻址(MAC 地址)**:每个网卡都有全球唯一的身份证号 -- **帧的封装和解封装**:把网络层的数据包"装进车厢" -- **错误检测**:通过 CRC 校验,发现数据是否损坏 -- **介质访问控制**:多个设备共享一条线时,谁先谁后?(比如 Wi-Fi 多台设备连一个路由器) - -### 2.2 MAC 地址:设备的身份证 - -**MAC 地址格式**:`00:1A:2B:3C:4D:5E` - -::: tip 💡 MAC 地址 vs IP 地址 -这是初学者最容易混淆的两个概念: - -| 特性 | MAC 地址 | IP 地址 | -| ------------ | ----------------------- | --------------------------- | -| **作用范围** | 局域网内(同一个 Wi-Fi) | 全球互联网 | -| **分配方式** | 网卡出厂时烧录,全球唯一 | 由网络管理员动态分配 | -| **变化** | 一般不变(除非换网卡) | 经常变化(连不同 Wi-Fi 会变) | -| **类比** | 身份证号(跟随你一生) | 家庭住址(搬家就变) | -| **层级** | 数据链路层(第2层) | 网络层(第3层) | - -**生活类比**:你要寄快递: - -- **MAC 地址** = 收件人身份证号(唯一标识这个人) -- **IP 地址** = 收件人家庭住址(用于路由) - -快递员实际上需要"住址"才能送货,但身份证号能确保"这个人"是唯一的。 -::: - -**查看你的 MAC 地址**: - -```bash -# Windows -ipconfig /all -# 找到 "物理地址",类似: 00-1A-2B-3C-4D-5E - -# macOS/Linux -ifconfig -# 找到 "ether",类似: 00:1a:2b:3c:4d:5e -``` - -### 2.3 以太网帧:快递车厢的结构 - -**以太网帧**就是数据链路层的"快递车厢",有一套标准格式: - -``` -+------------+----------+---------+-----+----------+ -| 目标 MAC | 源 MAC | 类型 | 数据 | FCS | -| (6 bytes) | (6 bytes) | (2 bytes)| | (4 bytes) | -+------------+----------+---------+-----+----------+ -``` - -::: tip 💡 逐行理解帧结构 -**目标 MAC (6字节)**:这帧数据给谁的?就像快递单上的收件人 - -**源 MAC (6字节)**:这帧数据谁发的?就像寄件人信息 - -**类型 (2字节)**:车厢里装的是什么? - -- `0x0800` = IPv4 数据包 -- `0x0806` = ARP 请求(查询 MAC 地址) -- `0x86DD` = IPv6 数据包 - -**数据(46-1500字节)**:实际要传输的内容,就是网络层的 IP 数据包 - -**FCS (4字节)**:帧校验序列。接收方用这个检查数据是否损坏,就像快递单上的"完好无损"签章 -::: - -### 2.4 交换机:聪明的交通指挥 - -**交换机**是数据链路层的核心设备。 - -::: tip 💡 交换机 vs 集线器 -**集线器**: - -- 收到数据后,简单地"广播"到所有端口 -- 所有设备都能看到,不是给自己的也得收下来再丢弃 -- 效率低,安全性差 - -**交换机**: - -- **学习 MAC 地址**:记住哪个端口连了哪个 MAC 地址 -- **智能转发**:只把数据发到目标设备所在的端口 -- **效率高**:设备 A 和 B 通信,设备 C 不会收到 - ::: - -**交换机工作流程**: - -1. **学习**:设备 A (MAC: 11:11...) 发数据给交换机端口1 - - 交换机记下:"11:11... 在端口1" - -2. **转发**:设备 A 要发数据给设备 B (MAC: 22:22...) - - 交换机查表:"22:22... 在端口3" - - 只把数据从端口3 发出去 - -3. **广播**:如果交换机不知道目标 MAC 在哪(比如第一次通信) - - 向所有端口(除了来源端口)广播 - - "谁是 22:22...?" 目标设备回应后,交换机学习到它的位置 +- **本地缓存**:浏览器会先翻翻自己的备忘录(看之前有没有访问过该网站)。 +- **DNS 系统**:如果在本地找不到,它就会向互联网的“查号台”(DNS 服务器)打电话询问:“请问 google.com 的数字地址是什么?”。一旦获得了对应的 IP 地址,浏览器的快递车就知道该往哪里开了。 --- -## 3. 网络层:路由规划部 +## 3. 建立通话 (TCP 握手) -### 3.1 IP 地址:互联网的门牌号 +拿到了地址,浏览器不能直接冲过去,万一店今天没开门呢?所以,要先进行一次**“电话确认”**(这叫建立 TCP 连接)。为了确保通话稳定可靠,会有三次非常严谨的“确认打招呼”机制,行业里叫**三次握手 (Three-way Handshake)**: -::: tip 💡 IP 地址是什么? -**IP 地址**就像互联网上的**家庭住址**,每台联网设备都需要一个。 +- **第一次握手 (浏览器)**:“喂,你好,我要来买东西,你在吗?” (SYN) +- **第二次握手 (服务器)**:“我在的,欢迎光临!你也听得到我说话吗?” (SYN-ACK) +- **第三次握手 (浏览器)**:“我也听到了!那我就要过来了!” (ACK) -**IPv4 地址格式**:`192.168.1.1` - -- 32 位,通常用点分十进制表示 -- 分为**网络部分**(前3段)和**主机部分**(最后1段) -- `192.168.1` 是网络号(这个小区) -- `.1` 是主机号(这个小区的1号房) - ::: - -**IP 地址分类(像城市规模)**: - -| 类别 | 范围示例 | 网络数 | 每个网络主机数 | 用途 | 类比 | -| -------- | --------------------- | --------- | -------------- | ---------------- | ---------- | -| **A 类** | 1.0.0.0 - 126.x.x.x | 126 | 16,777,214 | 超大型网络(早期) | 特大城市 | -| **B 类** | 128.0.0.0 - 191.x.x.x | 16,384 | 65,534 | 中型网络 | 中等城市 | -| **C 类** | 192.0.0.0 - 223.x.x.x | 2,097,152 | 254 | 小型网络(最常见) | 小区、村庄 | - -::: tip 💡 私有 IP 地址:内网 vs 外网 -有些 IP 地址段被保留为"私有",不能直接在互联网上使用: - -| 类别 | 私有 IP 范围 | 为什么用私有 IP? | -| -------- | ------------------------------- | -------------------- | -| **A 类** | `10.0.0.0 - 10.255.255.255` | 大型企业内网 | -| **B 类** | `172.16.0.0 - 172.31.255.255` | 中型企业内网 | -| **C 类** | `192.168.0.0 - 192.168.255.255` | 家庭、小公司(最常见) | - -**生活类比**: - -- **私有 IP** = 你家的门牌号("3单元501室") -- **公网 IP** = 你家在地图上的地址("XX市XX区XX路XX号") - -快递员(互联网)只能送到公网地址(你家楼门口),然后需要"路由器/NAT"转换到你家的私有地址。 -::: - -### 3.2 子网划分:把大楼分成多个单元 - -::: tip 💡 为什么要划分子网? -想象一个公司: - -- **不划分子网**:财务部、技术部、市场部都在 `192.168.1.0` 网段 - - 广播风暴:一个人发广播,所有人都能收到 - - 安全问题:技术部的开发服务器,市场部也能访问 - - 管理混乱:网络出问题,不知道是哪个部门的 - -**划分子网**: - -- 财务部:`192.168.1.0/24` -- 技术部:`192.168.2.0/24` -- 市场部:`192.168.3.0/24` - -各部门隔离,广播不出部门,管理更清晰。 -::: - -**子网掩码的作用**: - -子网掩码用来区分 IP 地址的哪部分是"网络号",哪部分是"主机号"。 - -``` -IP: 192.168.1.10 -掩码: 255.255.255.0 ------------------------ -网络号: 192.168.1.0 (前3段) -主机号: .10 (最后1段) -``` - -**CIDR 表示法**:`192.168.1.0/24` - -- `/24` 表示前 24 位是网络位 -- 剩余 8 位是主机位(2^8 - 2 = 254 个可用 IP) - - - -### 3.3 路由器:GPS 导航 - -**路由器**是网络层的核心设备,负责"规划最佳路线"。 - -::: tip 💡 路由器怎么工作? -**生活类比**:GPS 导航软件 - -- 你输入:"从北京天安门到上海外滩" -- GPS 查询地图数据库,规划出最佳路线 -- 路线可能是:"北京 → 天津 → 济南 → 南京 → 上海" - -**路由器的工作**: - -1. 收到数据包,查看目标 IP 地址 -2. 查询**路由表**(路由器的"地图数据库") -3. 选择最佳路径:"下一站该去哪个路由器?" -4. 转发到下一跳 - ::: - -**路由表示例**: - -``` -目标网络 子网掩码 网关 接口 -192.168.1.0 255.255.255.0 0.0.0.0 eth0 -192.168.2.0 255.255.255.0 192.168.1.2 eth0 -0.0.0.0 0.0.0.0 192.168.1.1 eth0 (默认网关) -``` - -::: tip 💡 理解路由表 -**第1行**:"发往 192.168.1.0 网段的包,直接从 eth0 接口发出去"(本地网络,不需要网关) - -**第2行**:"发往 192.168.2.0 网段的包,发给 192.168.1.2(它是这个网络的'门')" - -**第3行(默认网关)**:"不知道怎么走的包,全部发给 192.168.1.1(它连接互联网,会继续帮你转发)" - -这就像你去外地: - -- 在本地:走路就到(直接路由) -- 去隔壁城市:坐大巴(走网关) -- 去国外:先到机场,再转机(默认网关 → 层层转发) - ::: - -### 3.4 ICMP:网络诊断工具 - -**ICMP (Internet Control Message Protocol)** 用于网络诊断,最常用的就是 `ping` 命令。 - -**Ping 命令**: - -```bash -ping google.com - -# 输出示例 -PING google.com (142.250.185.238): 56 data bytes -64 bytes from 142.250.185.238: icmp_seq=0 ttl=117 time=12.4 ms -64 bytes from 142.250.185.238: icmp_seq=1 ttl=117 time=11.8 ms -``` - -::: tip 💡 理解 ping 的输出 -**`64 bytes`**:数据包大小(64 字节) - -**`icmp_seq=0`**:这是第 0 个包(序列号) - -**`ttl=117`**:Time To Live(生存时间) - -- 每经过一个路由器减 1 -- 防止数据包在网络中无限循环 -- 117 表示这个包经过了 255-117=138 个路由器 - -**`time=12.4 ms`**:往返时间(RTT, Round Trip Time) - -- 你的电脑发送请求 → google.com 收到 → google.com 回应 → 你的电脑收到 -- 整个过程花了 12.4 毫秒 -- 数值越小,网络延迟越低,网速越快 - ::: +经过这三次确认,双方都知道了彼此的听力和表达能力都没问题,一条稳定可靠的通信通道就正式建立了。 --- -## 4. 传输层:可靠送达 vs 快速送达 +## 4. 购买商品 (HTTP 请求与响应) -### 4.1 端口:应用的门牌号 +通道建好后,业务正式开始。 -::: tip 💡 为什么需要端口号? -想象一台服务器: - -- **只有 IP 地址**:数据包到了服务器,服务器不知道给哪个程序 - - Web 服务器要? - - 邮件服务器要? - - 数据库服务器要? - -**端口号**就像"公司里的部门号": - -- IP: 公司地址(XX 市XX 路 XX 号) -- 端口: 部门(301 财务部、302 技术部、303 市场部) - -数据包到了公司,前台(操作系统)根据"部门号"(端口)转发给对应部门(应用程序)。 -::: - -**端口号范围**: - -| 范围 | 类型 | 示例 | 需要权限? | -| --------------- | -------- | ----------------------------- | --------------------------------- | -| **0-1023** | 系统端口 | 80(HTTP)、443(HTTPS)、22(SSH) | ✅ 需要(防止普通用户占用关键服务) | -| **1024-49151** | 注册端口 | 3306(MySQL)、5432(PostgreSQL) | ❌ 不需要 | -| **49152-65535** | 动态端口 | 客户端临时使用 | ❌ 不需要 | - -**常见端口速查**: - -| 端口 | 服务 | 用途 | -| --------- | ---------- | --------------- | -| **21** | FTP | 文件传输 | -| **22** | SSH | 远程登录(安全) | -| **80** | HTTP | 网页(不安全) | -| **443** | HTTPS | 网页(安全,加密) | -| **3306** | MySQL | 数据库 | -| **5432** | PostgreSQL | 数据库 | -| **6379** | Redis | 缓存数据库 | -| **27017** | MongoDB | 数据库 | - -### 4.2 TCP vs UDP:挂号信 vs 平信 - - - -**选择建议**: - -| 场景 | 选择 | 原因 | -| ------------------ | ------- | ----------------------------------------- | -| **邮件、文件传输** | **TCP** | 不能丢数据,一个字节错误都可能导致文件损坏 | -| **视频、直播** | **UDP** | 实时性优先,丢几帧没关系,但不能卡顿 | -| **网页浏览** | **TCP** | 可靠性重要,网页内容必须完整 | -| **在线游戏** | **UDP** | 速度优先,位置信息晚到比没到好 | - -::: tip 💡 深入理解:TCP 为什么可靠? -TCP 通过以下机制保证可靠: - -1. **三次握手**:确保双方都能发送和接收 -2. **序列号**:每个字节都有编号,丢包能发现 -3. **确认应答**:收到数据必须回复 ACK,没收到就重传 -4. **流量控制**:接收方告诉发送方"我的缓冲区快满了,慢点发" -5. **拥塞控制**:网络拥堵时,降低发送速度,避免"堵死" - -这就像寄挂号信: - -- 要签收(ACK) -- 丢了邮政局会重传 -- 太多信件会积压,需要控制发送速度 - ::: - -### 4.3 TCP 三次握手:建立可靠连接 - -``` -客户端 服务器 - | | - | -------- SYN(seq=x) ---------> | 第1次:你好,我想和你通信(SYN) - | | (x 是随机数,防止伪造) - | | - | <--- SYN-ACK(seq=y, ack=x+1) ---| 第2次:收到!我也想和你通信(SYN) - | | 我收到了你的 x,所以 ack=x+1 - | | - | -------- ACK(ack=y+1) --------> | 第3次:我收到了你的 y,所以 ack=y+1 - | | 连接建立成功! -``` - -::: tip 💡 为什么需要三次,不是两次? -想象打电话: - -- **A**:你好!(SYN) -- **B**:你好!(SYN-ACK) —- 此时 B 确认了 A 能收到,但 A 还不确定 B 能不能收到 -- **A**:我听到了!(ACK) —- 现在双方都知道对方能收能发 - -如果只有两次: - -- A 发 SYN -- B 回 SYN-ACK -- 连接建立...但 B 不知道 A 有没有收到 SYN-ACK!如果 A 没收到,会重复发 SYN,但 B 以为已经建立连接,会出现问题 - ::: +- **浏览器(买家)提交订单**:浏览器会打包一份极其规范的订单表格(**HTTP 请求报文**),里面写着:“老板,请给我拿一份你的主页 HTML 文件,我是用 Chrome 浏览器来访问的哦。” +- **服务器(卖家)根据订单发货**:位于地球另一端的 Google 服务器收到请求后,立刻开始在仓库里配货,生成网页的 HTML 代码,然后打包成包裹(**HTTP 响应报文**),发回给你的浏览器。包裹外面还会贴个标签“200 OK”,意思是“交易成功,你要的货全齐了”。 --- -## 5. 应用层:具体的业务 +## 5. 拆盒组装 (浏览器渲染) -### 5.1 HTTP/HTTPS:网页的对话协议 +最后一步,货物送到了你的电脑。但发过来的只是一堆代码(HTML、CSS、JavaScript),这就好比你网购买了一箱乐高积木,还需要自己组装: -**HTTP (HyperText Transfer Protocol)** 是浏览器和服务器之间的"对话规则"。 +1. **看说明书 (解析 HTML)**:浏览器先把 HTML 代码解读出来,拼装成网页的骨架(DOM 树)。 +2. **涂抹颜色 (解析 CSS)**:然后检查 CSS 代码,看看字体要多大、按钮是什么颜色,给网页穿上漂亮的外衣(CSSOM 树)。 +3. **计算布局并拼装 (Layout & Paint)**:浏览器计算好每个元素在屏幕上的确切位置,用画笔把它们画在你的显示器上。 +4. **注入灵魂 (执行 JavaScript)**:最后,各种能点击、能滑动的交互效果都通过 JavaScript 激活。 -| 特性 | HTTP | HTTPS | -| ---------- | ------------------------ | ----------------------------- | -| **加密** | ❌ 否(明文,任何人都能看) | ✅ 是(TLS/SSL 加密) | -| **端口** | 80 | 443 | -| **安全性** | 低(密码、账号会被窃取) | 高(即使被拦截,看到的也是乱码) | -| **性能** | 略快(无加密开销) | 略慢(加密解密需要时间) | -| **SEO** | 不友好(搜索引擎会降权) | 友好(搜索引擎优先收录 HTTPS) | - -**HTTP 请求方法**: - -| 方法 | 描述 | 生活类比 | 示例 | -| ---------- | ---------------------- | ---------------------------- | ---------------------- | -| **GET** | 获取资源 | "我要看这个商品的详情" | 查看网页、加载图片 | -| **POST** | 提交数据 | "我要下单,这是我的收货信息" | 登录、注册、提交表单 | -| **PUT** | 更新资源(整体替换) | "我要完整更新这个商品的信息" | 修改用户资料(全部字段) | -| **PATCH** | 部分更新 | "我只想改商品的名称" | 修改用户资料(只改名字) | -| **DELETE** | 删除资源 | "我要删除这个订单" | 删除文章、删除评论 | -| **HEAD** | 只获取响应头(不要内容) | "这个文件还在吗?有多大?" | 检查资源是否存在 | - -**HTTP 状态码**(服务器给你的"回复"): - -``` -2xx 成功 -- 200 OK:请求成功,这是你要的内容 -- 201 Created:创建成功(比如注册新用户) - -3xx 重定向 -- 301 Moved Permanently:永久搬家了,请用新地址 -- 302 Found:暂时搬迁,请访问新地址 - -4xx 客户端错误(你发的问题) -- 400 Bad Request:请求格式错误,服务器看不懂 -- 401 Unauthorized:未授权,请先登录 -- 403 Forbidden:禁止访问,即使登录也不行 -- 404 Not Found:资源不存在(网址错了?) - -5xx 服务器错误(服务器的问题) -- 500 Internal Server Error:服务器内部出错了 -- 502 Bad Gateway:网关错误,服务器连不上后端 -- 503 Service Unavailable:服务暂时不可用(过载或维护) -``` - -### 5.2 DNS:互联网的地址簿 - -**DNS (Domain Name System)** 域名系统,把人类可读的域名转换成机器可读的 IP 地址。 - -::: tip 💡 为什么需要 DNS? -**没有 DNS 的世界**: - -- 你需要记住所有网站的 IP 地址 -- 访问百度:`https://110.242.68.66`(你能记住吗?) -- IP 地址会变(服务器迁移),你需要重新记住 - -**有 DNS 的世界**: - -- 记住域名:`baidu.com` -- DNS 帮你转换:`baidu.com` → `110.242.68.66` -- IP 变了?更新 DNS 记录就行,域名不用变 - ::: - -**DNS 查询过程**: - -``` -你(浏览器) - ↓ 问:baidu.com 的 IP 是多少? -本地 DNS 服务器(你的网络运营商,如电信/联通) - ↓ 不知道? 问: -根域名服务器(全球13组,管理所有顶级域) - ↓ 告诉:去问 .cn 的管理者 -顶级域名服务器(Verisign 管理 .cn) - ↓ 告诉:去问 baidu.com 的管理者 -权威 DNS 服务器(Baidu 自己的 DNS) - ↓ 告诉:baidu.com 的 IP 是 110.242.68.66 -返回 IP 地址给浏览器 -``` - -**DNS 记录类型**: - -| 类型 | 用途 | 示例 | -| --------- | ---------------- | ------------------------------------------------------ | -| **A** | 域名 → IPv4 地址 | `www.example.com → 93.184.216.34` | -| **AAAA** | 域名 → IPv6 地址 | `www.example.com → 2606:2800:220:1:248:1893:25c8:1946` | -| **CNAME** | 别名 | `www.baidu.com → a.baidu.com`(多个域名指向同一个 IP) | -| **MX** | 邮件服务器 | `@example.com → mail.example.com`(邮件发到哪里) | +**只要短短的几百毫秒,所有的步骤就已全部完成,你也就看到了那个熟悉的页面!** --- -## 6. 总结:网络五层模型核心要点 +## 总结:从微观到宏观 -| 层级 | 核心概念 | 关键技术 | 生活类比 | -| -------------- | ------------------- | -------------------- | ---------------------------------- | -| **应用层** | 应用程序之间的通信 | HTTP, FTP, SMTP, DNS | 具体业务(寄快递、发邮件、浏览网页) | -| **传输层** | 端到端的可靠传输 | TCP(可靠), UDP(快速) | 快递方式(挂号信 vs 平信) | -| **网络层** | 路由选择,寻址 | IP, 路由器, ICMP | GPS 导航,规划路线 | -| **数据链路层** | 点对点传输,MAC 寻址 | 以太网, 交换机, MAC | 车队管理,车辆之间通信 | -| **物理层** | 实际的物理传输 | 光纤, 网线, 无线电波 | 道路和运输工具 | +如果我们把目光再拉远一点,整个网络通讯的本质,就是在做**接力跑和翻译**: -**学习建议**: +- 我们上面看到的这五步,大多是发生在你眼前的**应用程序**层面的事情。 +- 在肉眼看不见的底层,刚才那个充满代码的 HTML 包裹,会被切分成无数块极小的碎片(数据包)。这些碎片顺着你家墙上的网线、海底的万兆光缆,像接力棒一样在各种路由器之间传递。 +- 最终,这一切碎片完好无损地抵达,并在哪怕是几十个毫秒的时间里,化成你屏幕上的绚丽像素。 -- ✅ **从应用层往下学**:你每天都在用 HTTP,DNS,从熟悉的开始 -- ✅ **多用工具**:ping, traceroute, Wireshark,观察实际网络 -- ✅ **理解协议细节**:阅读 RFC 文档(比如 RFC 791 定义 IP) -- ✅ **抓包分析**:用 Wireshark 观察 TCP 三次握手、HTTP 请求 -- ✅ **关注安全**:了解 DDoS、中间人攻击等常见威胁 - -掌握计算机网络,你就能理解互联网的运作原理,写出更高效的网络应用! - ---- - -## 附录:名词速查表 - -| 名词 | 英文 | 用人话解释 | -| --------------- | ----------------------------- | ------------------------------------------- | -| **OSI 模型** | Open Systems Interconnection | 七层网络模型(理论标准) | -| **TCP/IP 模型** | - | 实际使用的四层/五层模型 | -| **MAC 地址** | Media Access Control | 网卡的物理地址,全球唯一,像身份证 | -| **IP 地址** | Internet Protocol | 设备在互联网上的逻辑地址,像住址 | -| **子网掩码** | Subnet Mask | 区分 IP 地址的网络部分和主机部分 | -| **端口** | Port | 应用程序的"门牌号",区分同一台设备的不同服务 | -| **TCP** | Transmission Control Protocol | 可靠传输协议,三次握手,不丢包 | -| **UDP** | User Datagram Protocol | 快速传输协议,不保证可靠,可能丢包 | -| **DNS** | Domain Name System | 域名系统,把域名转成 IP 地址 | -| **HTTP** | HyperText Transfer Protocol | 超文本传输协议,网页通信规则 | -| **HTTPS** | HTTP Secure | 加密的 HTTP,更安全 | -| **路由器** | Router | 网络层设备,规划路线,连接不同网络 | -| **交换机** | Switch | 数据链路层设备,智能转发数据帧 | -| **TTL** | Time To Live | 生存时间,防止数据包无限循环 | -| **RTT** | Round Trip Time | 往返时间,数据从发送到接收确认的时间 | +这就是计算机网络的神奇魅力! diff --git a/docs/zh-cn/appendix/1-computer-fundamentals/operating-systems.md b/docs/zh-cn/appendix/1-computer-fundamentals/operating-systems.md index ca60a6c..225a9f8 100644 --- a/docs/zh-cn/appendix/1-computer-fundamentals/operating-systems.md +++ b/docs/zh-cn/appendix/1-computer-fundamentals/operating-systems.md @@ -1,255 +1,99 @@ -# 操作系统(进程 / 内存 / 文件系统) +# 操作系统:给电脑请个"大管家" ::: tip 🎯 核心问题 -**操作系统是做什么的?** 你可能每天都在用 Windows、macOS 或 Linux,但你知道它到底在忙什么吗?为什么需要它?没有它电脑还能用吗?本章带你理解操作系统的三大核心职责:管理进程、管理内存、管理文件。 +**有了完美的 CPU 和无限的内存,电脑就能直接用了吗?** +在上一章,我们见证了晶体管如何组合成强大的 CPU。但其实,如果直接使用这些冷冰冰的硬件,哪怕只是想在屏幕上打出一个字母,你都需要手写几百行晦涩的机器指令。 + +为了不让大家在每次用电脑时都被逼疯,前辈们创造了一个夹在“硬件”和“你”之间的超级管家——**操作系统(Operating System, 简称 OS)**。本章我们不谈深奥的理论,只聊聊这个大管家是怎么通过三大“障眼法”,把复杂的硬件调教得服服帖帖的。 ::: --- -## 0. 全景图:操作系统的角色 +## 0. 承上启下:如果没有操作系统会怎样? -想象你开了一家餐厅。你需要: -- **安排员工工作**:谁做菜、谁端盘子、谁收银(进程管理) -- **管理厨房空间**:冰箱放什么、操作台怎么分配(内存管理) -- **整理仓库物资**:食材怎么存放、怎么找(文件系统) +上一章我们提到,CPU 是一个不知疲倦的无情计算机器,通电后就会一行一行地执行指令。 -操作系统就是电脑的"餐厅经理",它负责协调所有资源,让程序能顺利运行。 +但这带来了几个现实的灾难: +1. **CPU 独占危机**:CPU 一次只能干一件事。如果你正在听歌,想切出去看个网页?抱歉,没有操作系统的调度,你的电脑必须停下音乐,才能去加载网页。 +2. **内存踩踏事故**:微信和游戏都在使用内存。如果没有保安管理,游戏一不小心把数据写到了微信的内存地盘,微信当场崩溃。 +3. **硬盘迷宫**:硬盘本质上只是一张密密麻麻刻满 0 和 1 的巨大光盘。要想找到你昨天存的照片,你必须准确记住它存放在第 12345 圈磁道的第 678 个扇区。 -**操作系统的三大核心职责:** - -| 职责 | 管理对象 | 核心问题 | 类比 | -|------|---------|---------|------| -| **进程管理** | CPU 时间 | 谁先用 CPU?用多久? | 员工排班 | -| **内存管理** | 内存空间 | 程序放哪里?怎么不冲突? | 厨房空间分配 | -| **文件系统** | 磁盘数据 | 数据怎么存?怎么找? | 仓库物资管理 | - -::: tip 📊 逐行解读这张表 -**进程管理**:CPU 是最宝贵的资源,操作系统要决定哪个程序先用、用多久。就像餐厅经理安排员工轮班,不能让所有人同时挤在厨房里。 - -**内存管理**:内存是程序的"工作台",操作系统要给每个程序分配空间,还要保证它们互不干扰。就像厨房空间有限,要合理分配给不同的厨师。 - -**文件系统**:磁盘是"仓库",操作系统要把数据有序地存进去,需要时能快速找到。就像仓库管理员整理货架,按类别、编号存放。 -::: +为了解决这些噩梦,操作系统诞生了。它对外提供了一套优雅的“幻觉”,这就是它的三大核心魔法:**进程(管理 CPU)**、**虚拟内存(管理内存)** 和 **文件系统(管理硬盘)**。 --- -## 1. 进程管理:程序的"分身术" +## 1. 进程管理:制造“同时运行”的幻觉 -### 1.1 什么是进程? +你平时用电脑,常常是一边挂着微信,一边听着音乐,还能一边打字。但如果你买的电脑其实只有一个 CPU 核心,它是怎么同时做这三件事的? + +答案是:**它并没有同时做**。是操作系统在进行疯狂的“时间管理”。 -::: tip 💡 程序 vs 进程 -这是初学者最容易混淆的概念: +::: tip 💡 核心原理解析:时间片轮转(Time Slicing) +操作系统把 CPU 的时间切成了极其微小的片段(比如 10 毫秒)。 +- 第 1-10 毫秒:让 CPU 去执行**微信**的接收消息逻辑。 +- 第 11-20 毫秒:把微信强制暂停,让 CPU 去执行**音乐**的播放逻辑。 +- 第 21-30 毫秒:把音乐暂停,让 CPU 去响应你的**键盘打字**。 -| 概念 | 定义 | 类比 | 特点 | -|------|------|------|------| -| **程序** | 静态的代码文件 | 菜谱 | 存在磁盘上,不会动 | -| **进程** | 程序的运行实例 | 正在按菜谱做菜 | 在内存中运行,会变化 | +因为切换的速度实在太快了(一秒钟切换成百上千次),在人类迟钝的感知中,就觉得这三个软件是“同时”在运行的。 -**关键区别**: -- 一个程序可以启动多个进程(比如打开多个浏览器窗口) -- 每个进程有独立的内存空间,互不干扰 -- 进程有生命周期:创建、运行、等待、终止 +在操作系统的术语里,运行中的程序就被称为**进程(Process)**。操作系统就是这群进程的冷酷无情的排班经理。 ::: -### 1.2 进程的状态 - -进程在运行过程中会在不同状态之间切换: - -| 状态 | 含义 | 什么时候进入 | 类比 | -|------|------|-------------|------| -| **就绪 (Ready)** | 准备好运行,等 CPU | 进程刚创建,或从等待恢复 | 员工在休息室等排班 | -| **运行 (Running)** | 正在 CPU 上执行 | 被调度器选中 | 员工正在工作 | -| **等待 (Waiting)** | 等待 I/O 或其他资源 | 需要读磁盘、等网络 | 员工在等食材送达 | -| **终止 (Terminated)** | 运行结束 | 程序退出或出错 | 员工下班 | - -### 1.3 进程调度:谁先用 CPU? - -::: tip 💡 为什么需要调度? -CPU 核心数有限,但进程可能有几十上百个。操作系统需要决定: -- 哪个进程先运行? -- 运行多久? -- 什么时候切换? - -这就是**进程调度**要解决的问题。 -::: - -**常见调度算法:** - -| 算法 | 思路 | 优点 | 缺点 | -|------|------|------|------| -| **先来先服务 (FCFS)** | 谁先到谁先运行 | 简单公平 | 短任务可能等很久 | -| **短作业优先 (SJF)** | 短任务优先 | 平均等待时间最短 | 需要预知任务长度 | -| **时间片轮转 (RR)** | 每人运行一小段时间 | 公平,响应快 | 切换开销大 | -| **优先级调度** | 重要任务优先 | 重要任务响应快 | 可能导致低优先级任务饿死 | - --- -## 2. 内存管理:程序的"工作台" +## 2. 内存管理:给每个程序画个“海市蜃楼” -### 2.1 为什么需要内存管理? +解决了 CPU 轮流用的问题,接下来是存放数据的内存。如果所有的进程都挤在同一块物理内存里,很容易发生互相干扰和偷看数据的危险。 + +操作系统的第二大魔法,叫作**虚拟内存(Virtual Memory)**。 -::: tip 💡 如果没有内存管理会怎样? -想象一个没有管理的厨房: +::: tip 💡 核心原理解析:内存映射 +操作系统对每一个启动的进程撒了一个弥天大谎:“嘿,你独占了整整 4GB 的纯净内存空间,随便用!”(这就是**虚拟内存**)。 -- **冲突**:两个厨师同时用同一个灶台,菜都糊了 -- **浪费**:有人占了整个厨房,其他人没地方做饭 -- **安全问题**:有人偷吃了别人的食材 +但实际上,当进程往这个“虚拟空间”里放东西时,操作系统的底层会拿出一个**映射表(页表)**,偷偷把数据塞进**真实物理内存(Physical Memory)**中各种零碎、不连续的角落里。 -操作系统通过**内存管理**解决这些问题: -- 给每个进程分配独立的内存空间 -- 防止进程互相干扰(内存保护) -- 高效利用有限的内存资源 +**这么做有两个巨大的好处:** +1. **绝对安全**:微信永远只能看到自己的虚拟空间,它根本不知道音乐的数据在物理内存的哪个角落,自然就不会发生“踩踏”。 +2. **碎片利用**:物理内存就算被用得像狗皮膏药一样稀碎,映射给进程的虚拟空间依然是连续且整齐的。 ::: -### 2.2 虚拟内存:让每个进程都"以为"自己独占内存 - -::: tip 💡 什么是虚拟内存? -**虚拟内存**是操作系统的一个"魔术": - -- 每个进程都以为自己有 4GB(或更多)的内存空间 -- 实际上物理内存可能只有 8GB、16GB -- 操作系统通过"映射"把虚拟地址转换成物理地址 - -**生活类比**:想象一个酒店: -- 每个客人都以为自己独占整个酒店(虚拟空间) -- 实际上酒店只有 100 间房(物理内存) -- 前台(操作系统)负责分配房间、记录谁住哪里 -::: - -**虚拟内存的好处:** - -| 好处 | 说明 | 为什么重要 | -|------|------|-----------| -| **隔离保护** | 进程间内存互不干扰 | 一个崩溃不影响其他 | -| **内存扩展** | 用磁盘当内存用 | 可以运行比物理内存大的程序 | -| **简化编程** | 不用关心物理地址 | 程序员写代码更简单 | - -### 2.3 内存分配策略 - -当进程需要内存时,操作系统如何分配? - -| 策略 | 思路 | 特点 | -|------|------|------| -| **首次适应** | 找到第一个够大的空闲块 | 速度快 | -| **最佳适应** | 找最小的够大的空闲块 | 内存利用率高 | -| **最坏适应** | 找最大的空闲块 | 减少小碎片 | - --- -## 3. 文件系统:数据的"档案柜" +## 3. 文件系统:把“荒地”变成“档案馆” -### 3.1 什么是文件系统? +如果你买了一块崭新的硬盘,它里面其实是一片荒芜的存储单元。如果你想存一张照片,硬盘硬件只会问你:“请告诉我你要存在第几个字节地址?”这显然反人类。 + +操作系统的第三大魔法是**文件系统(File System)**,它为你构建了我们最熟悉的:文件夹(目录)和文件的概念。 -::: tip 💡 文件系统是什么? -**文件系统**是操作系统管理磁盘数据的方式。 - -**生活类比**:想象一个图书馆: -- 书架 = 磁盘 -- 书 = 文件 -- 目录卡片 = inode -- 分类编号 = 路径 - -没有文件系统,磁盘就是一堆杂乱的数据。有了文件系统,我们可以: -- 用"路径"找到文件(如 `/home/user/document.txt`) -- 创建、删除、修改文件 -- 控制谁能访问哪些文件 -::: - -### 3.2 inode:文件的"身份证" - -::: tip 💡 inode 是什么? -每个文件都有一个 **inode**(索引节点),记录了文件的元数据: - -| 信息 | 说明 | -|------|------| -| inode 编号 | 文件的唯一标识 | -| 文件大小 | 多少字节 | -| 权限 | 谁能读写 | -| 时间戳 | 创建、修改、访问时间 | -| 数据块位置 | 文件内容存在哪些磁盘块 | - -**关键理解**: -- 文件名不在 inode 里!文件名只是目录中的一个条目 -- 一个文件可以有多个名字(硬链接) -- 删除文件只是删除目录项,inode 可能还在 -::: - -### 3.3 常见文件系统 - -| 文件系统 | 操作系统 | 特点 | -|---------|---------|------| -| **NTFS** | Windows | 支持大文件、权限控制 | -| **APFS** | macOS | 加密、快照、高效 | -| **ext4** | Linux | 稳定、高效、广泛使用 | -| **FAT32** | 通用 | 兼容性好,但单文件最大 4GB | -| **exFAT** | 通用 | 支持大文件,适合 U 盘 | - ---- - -## 4. 进程、内存、文件系统的协作 - -这三个子系统是如何配合工作的?让我们看一个完整的例子: - -**场景:打开一个文档文件** - -``` -1. 用户双击文件 - ↓ -2. 文件系统:根据路径找到 inode,读取文件内容 - ↓ -3. 进程管理:创建新进程(文档编辑器),分配 PID - ↓ -4. 内存管理:为新进程分配内存,加载程序代码和数据 - ↓ -5. 进程运行:编辑器进程读取文件内容,显示在屏幕上 -``` - -::: tip 💡 理解这个流程 -每一步都涉及操作系统的核心功能: - -1. **文件系统**:负责"找到文件" -2. **进程管理**:负责"启动程序" -3. **内存管理**:负责"给程序分配空间" - -这三者紧密协作,才能完成一个看似简单的"打开文件"操作。 +::: tip 💡 核心原理解析:从地址到路径 +文件系统本质上是一个超级大型的“翻译官”加“账本”: +1. **账本功能**:它悄悄地把硬盘切分成无数个小块(Block),然后用一个账本记录下来“哪几个小块现在是空的可以存数据,哪几个小块已经存了东西”。 +2. **翻译功能**:当你双击一层层文件夹,打开 `D盘/照片/宠物.jpg` 时,并不是硬盘真的长出了树枝一样的结构。而是文件系统在它的账本里疯狂翻阅,最终翻译出:哦,这个路径其实对应的是硬盘上的第 1056、1057 和 998 块小地方,然后把数据取出来交给你。 ::: --- -## 5. 总结:操作系统是"大管家" +## 4. 总结:伟大的幕后英雄 -让我们用一个比喻总结操作系统的三大职责: +让我们通过一个你每天都在经历的场景,串联起今天学到的知识。当你**双击鼠标打开一个游戏**时,为了伺候你,大管家做了什么? -| 职责 | 比喻 | 核心任务 | -|------|------|---------| -| **进程管理** | 餐厅排班员 | 安排谁先工作、工作多久 | -| **内存管理** | 厨房管理员 | 分配工作台、防止冲突 | -| **文件系统** | 仓库管理员 | 整理物资、快速查找 | +1. **文件系统**:立刻从底层硬盘的杂乱数据块中,拼凑出游戏的执行文件和美术资产。 +2. **内存管理**:为你分配一个巨大的虚拟内存空间,制造出“这台电脑只有这一个游戏”的幻觉,并把刚才找到的文件放进物理内存的空隙里。 +3. **进程管理**:在它的名册上新建一个“游戏进程”,并在下一个瞬间,立刻剥夺其他正在运行软件的 CPU 权利,把 CPU 的计算力全盘移交给你的游戏。 -::: tip 💡 核心启示 -**操作系统的本质是"资源管理"**。 - -- CPU 时间是资源 → 进程管理 -- 内存空间是资源 → 内存管理 -- 磁盘空间是资源 → 文件系统 - -理解了这一点,你就会明白: -- 为什么电脑会变慢(进程太多、内存不足) -- 为什么需要重启(清理资源、释放内存) -- 为什么文件要整理(提高查找效率) -::: +我们之所以能那么轻松、优雅地在数字世界里冲浪,全都是因为底层的操作系统在替我们负重前行。 --- ## 延伸阅读 -- **操作系统原理**:深入学习进程调度、内存分页、文件系统实现 -- **Linux 系统编程**:学习如何与操作系统交互(系统调用) -- **并发编程**:学习多进程、多线程编程 -- **系统监控**:学习使用 top、htop、vmstat 等工具监控系统状态 +如果你觉得操作系统的各种“管理学”十分有趣,你可以看看这些进阶话题: +- **进程与线程的区别**:除了进程,还有一种叫作“线程”的东西,它们是干什么用的?(为什么 Google Chrome 那么吃内存?) +- **页面置换算法**:当物理内存全都塞满了,但你又打开了一个新软件,操作系统该把谁的数据临时踢到硬盘里?(LRU 算法) +- **操作系统的多态**:Windows 和 macOS 会在底层实现上有什么不同?为什么有些软件只能在特定系统上运行? diff --git a/docs/zh-cn/appendix/1-computer-fundamentals/transistor-to-cpu.md b/docs/zh-cn/appendix/1-computer-fundamentals/transistor-to-cpu.md index efa426d..d56d6d2 100644 --- a/docs/zh-cn/appendix/1-computer-fundamentals/transistor-to-cpu.md +++ b/docs/zh-cn/appendix/1-computer-fundamentals/transistor-to-cpu.md @@ -8,96 +8,73 @@ ## 0. 全景图:从沙子到智能 -现代计算机的"思考"能力,归根结底来自于一个简单的东西:**开关**。 +在探索计算机底层的过程中,常常会遇到一个最根本的问题:**现代计算机的“思考”能力,究竟从何而来?** -想象你有一个开关,可以控制灯的亮灭。现在,如果你有几十亿个这样的开关,并且能用它们组合出各种复杂的逻辑,会发生什么?这就是计算机的奥秘。 +如果剥开电脑闪亮的外壳,我们看到的通常只是一堆金属、塑料和硅晶片。它们本身没有生命,不懂数学,更不懂何为智能。但当电流穿过它们时,一切开始运转起来。归根结底,这一切都来自于一个再简单不过的物理抽象:**开关**。 -**从沙子到智能的层次结构:** +想象你面前有一个控制灯泡的开关。按下灯亮,表示为“1”;断开灯灭,表示为“0”。如果我们拥有几十亿个这样的开关,并且能够让**一个开关的输出去控制另一个开关**,从而组合出无比复杂的逻辑网络,会发生什么? -| 层级 | 名称 | 数量级 | 作用 | 类比 | -| ----- | -------- | ------ | ---------------------------- | -------- | -| **1** | 晶体管 | 数十亿 | 最基本的开关单元 | 一个开关 | -| **2** | 逻辑门 | 数亿 | 实现基本逻辑运算 | 开关组合 | -| **3** | 功能单元 | 数百 | 实现特定功能(加法、存储等) | 功能模块 | -| **4** | CPU 核心 | 1-128 | 完整的处理器 | 大脑 | +答案是一台能执行任意逻辑的通用计算平台。理解计算机系统的关键在于“抽象(Abstraction)”。就像搭积木一样,我们通过层叠的封装来控制底层的复杂度。以下是从沙子到智能的四个核心层级: -::: tip 逐行解读这张表 -**第1层(晶体管)**:这是最底层的"开关"。现代 CPU 使用的是 MOSFET(金属氧化物半导体场效应晶体管),它的特点是:给栅极加电压,源极和漏极之间就导通;不加电压,就断开。这就是"用电控制电"的开关。 +::: tip 逐层解构:从沙子到智能 +- **第一层:晶体管(数百亿级)** + 这是最底层的“开关”。现代 CPU 内部主要使用 MOSFET(金属氧化物半导体场效应晶体管)。给栅极施加电压,源极和漏极之间就导通。这就是“用电控制电”的物理起点,解决的核心问题是:**如何用电信号控制另一个电信号?** -**第2层(逻辑门)**:把晶体管组合起来,就能实现"与"、"或"、"非"等逻辑运算。比如 AND 门:两个输入都为 1 时输出才为 1。这就像两个串联的开关,必须都按下灯才会亮。 +- **第二层:逻辑门(数十亿级)** + 当我们把特定的晶体管串联或并联,奇妙的转换就发生了——电路变成了数学。例如 AND(与)门必须两个输入都是 1,输出才是 1;这构成了布尔代数在物理电路上的映射,解决的核心问题是:**如何把物理通断转化为基于 0 和 1 的逻辑运算?** -**第3层(功能单元)**:把逻辑门组合起来,就能实现更复杂的功能。加法器能做加法,寄存器能存储数据,多路选择器能选择数据。这些是 CPU 的"器官"。 +- **第三层:功能单元(数百级)** + 把基础的逻辑门拼装在一起,就能构建出有特定用途的计算模块。加法器处理算术运算,多路选择器控制数据流向,而寄存器赋予了电路记忆能力。解决的核心问题是:**如何构造出能够执行加法计算和记忆状态的机器?** -**第4层(CPU 核心)**:把功能单元组合起来,加上控制器、总线等,就形成了一个完整的 CPU 核心。它能取指令、解码、执行、写回结果——这就是"计算"的全部过程。 +- **第四层:CPU 核心(1-128核)** + 这是整个微架构的指挥中心。当你写下一行代码时,CPU 内部的各个部件正以每秒几十亿次的频率协同工作,执行着取指、解码、执行、写回的整个流程。解决的核心问题是:**如何让各模块协同一致,自动执行指定的程序序列?** ::: --- ## 1. 晶体管:数字世界的开关 +让我们从微观世界开始。下面这个组件展示了晶体管的基本原理,你可以试着操作一下,观察电流是如何流动的: + ### 1.1 什么是晶体管? -::: tip 晶体管是什么? -**晶体管(Transistor)** 是一种半导体器件,它可以像开关一样控制电流的通断。 +::: tip 概念引入 +在工程学中,**晶体管(Transistor)** 是一种改变了人类历史的半导体器件。在数字电路的语境下,我们可以直接把它抽象为一个完美的“开关”。 -**生活类比**:想象一个水龙头: +为什么我们需要晶体管?想想生活中的水龙头。你用手拧开阀门,水流就涌出。**晶体管其实就是一个纳米级的水龙头**: +- **源极 (Source)** 和 **漏极 (Drain)** 就如同水管的两端。 +- **栅极 (Gate)** 就是那个用来控制水流的阀门。 -- **水龙头**:你用手拧开关,控制水流 -- **晶体管**:用电压控制开关,控制电流 - -关键区别是:晶体管不是用手拧,而是用"电"来控制。这意味着一个开关可以控制另一个开关,从而实现"自动控制"。 +关键的区别在于:我们不是用手去拧开关,而是用**电压信号**。当一种开关能够被另一种开关产生的电信号所控制时,我们就跨过了从“人工干预”到“自动运算”的巨大鸿沟。 ::: -**晶体管的三个极:** - -| 极 | 名称 | 作用 | 类比 | -| ----------------- | -------- | -------------- | ---------- | -| **源极 (Source)** | 电流入口 | 电流从这里进入 | 水管入口 | -| **漏极 (Drain)** | 电流出口 | 电流从这里流出 | 水管出口 | -| **栅极 (Gate)** | 控制端 | 控制是否导通 | 水龙头开关 | - ### 1.2 晶体管如何表示 0 和 1? -计算机只认识 0 和 1,这和晶体管有什么关系? +你可能会问:计算机所谓的“只认识 0 和 1”,在物理世界中究竟是什么样子?难道芯片里真的流淌着微小的 0 和 1 吗? -::: tip 用电压表示 0 和 1 -**核心思想**:用电压的高低来表示 0 和 1。 +当然不是。这一切全靠人为的**抽象约定**。我们要摒弃对连续模拟信号的执念,设定两个极端阈值: -- **高电压(如 3.3V)**:表示 1 -- **低电压(如 0V)**:表示 0 +- 我们把**高电压(比如 3.3V 或 1.0V)** 强行定义为逻辑的 **1**(True)。 +- 把**低电压(接近 0V)** 强行定义为逻辑的 **0**(False)。 -这就像灯泡的亮和灭: +这就是所谓的数字抽象能力:我们把充满噪音的模拟世界,硬生生地切分成了干净利落的 0 和 1。栅极输入高电压,晶体管导通,相当于开关合上;栅极输入低电压,开关断开。 -- 灯亮 = 1 -- 灯灭 = 0 +### 1.3 晶体管数量的演进 -晶体管的作用就是"控制灯泡的亮灭"——给栅极加高电压,源极和漏极导通,"灯泡"亮了(输出 1);给栅极低电压,源极和漏极断开,"灯泡"灭了(输出 0)。 -::: +一个晶体管只能控制通断,显得极其微不足道。但如果把几十亿个这样的开关组合起来呢?观察下面这张体现摩尔定律的表格,了解一下现代芯片的发展。 -### 1.3 从一个开关到几十亿 +| 时代标志 | 处理器芯片 | 晶体管数量 | 制程节点 | 时代意义 | +| -------- | ---------------- | ---------- | -------- | ---------------------- | +| 1971 | Intel 4004 | 2,300 | 10微米 | 微处理器黎明开端 | +| 1993 | Intel Pentium | 310万 | 800纳米 | 个人电脑全面普及 | +| 2006 | Intel Core 2 Duo | 2.91亿 | 65纳米 | 多核架构成为主流 | +| 2020 | Apple M1 | 160亿 | 5纳米 | 移动端架构的反哺革命 | +| 2023 | Apple M3 Max | 920亿 | 3纳米 | 接近原子的物理学极限 | -你可能好奇:一个开关能做什么?答案是:一个开关做不了什么,但几十亿个开关组合起来,就能做任何计算。 - -**现代 CPU 的晶体管数量:** - -| 年份 | CPU | 晶体管数量 | 制程工艺 | -| ---- | ------------- | ---------- | -------- | -| 1971 | Intel 4004 | 2,300 | 10μm | -| 1993 | Intel Pentium | 310万 | 0.8μm | -| 2006 | Intel Core 2 | 2.91亿 | 65nm | -| 2020 | Apple M1 | 160亿 | 5nm | -| 2023 | Apple M3 Max | 920亿 | 3nm | - -::: tip 什么是制程工艺? -**制程工艺**(如 5nm、3nm)指的是晶体管的尺寸。数字越小,晶体管越小,同样面积能容纳的晶体管越多。 - -- **5nm**:大约是 50 个原子的宽度 -- **3nm**:大约是 30 个原子的宽度 - -制程越小,CPU 性能越强、功耗越低。但制造难度也指数级增加。 -::: +> **深入思考:什么是 “3nm”?** +> 当我们在新闻里听到 5nm、3nm 时,可以想象它有多微小。一个硅原子的直径大约是 0.2 纳米。所以在 3nm 的制程下,晶体管最关键的结构,只有几十个原子那么宽幅!这意味着我们是在量子力学规律生效的尺度边缘,来打造人类最庞大的算力堡垒。 --- @@ -105,184 +82,165 @@ ### 2.1 从晶体管到逻辑门 -一个晶体管只是一个开关,但把多个晶体管组合起来,就能实现"逻辑运算"。 +正如之前所说,单个晶体管只是对电流的简单控制。但当你把多个晶体管按照特定的结构排列时,物理学就变成了数学逻辑。在这个全新的维度上,我们不再谈论繁琐的电压和电流,而是直接谈论纯粹的逻辑“真”(1)与“假”(0)。 + +请通过下面的逻辑门演示,直观地感受一下开关组合的效果: -### 2.2 基本逻辑门详解 +### 2.2 基本逻辑门介绍 -**AND 门(与门)**: +在我们的计算机体系结构中,有几种最基础的逻辑门,所有的超级计算机都是由这些积木搭建而成的: -- **规则**:两个输入都为 1,输出才为 1 -- **生活类比**:串联的两个开关,必须都按下灯才亮 -- **应用**:判断"多个条件是否同时满足" +- **AND 门(与门)**: + - **规则**:只有当所有输入都为 1 时,输出才为 1。 + - **直觉理解**:把两个晶体管**串联**。电流要想通过,必须同时打开两道关卡。如同开启银行金库,必须经理和主管同时插入各自的钥匙。 -**OR 门(或门)**: +- **OR 门(或门)**: + - **规则**:只要有一个输入为 1,输出就为 1。 + - **直觉理解**:把两个晶体管**并联**。多条并行的通道,只要有一条路通了,电流就能流向彼岸。 -- **规则**:任一个输入为 1,输出就为 1 -- **生活类比**:并联的两个开关,按任意一个灯就亮 -- **应用**:判断"是否满足任一条件" +- **NOT 门(非门 / 反相器)**: + - **规则**:输入 1 必定输出 0,输入 0 必定输出 1。 + - **直觉理解**:这是专门用来翻转状态的门,也是电路设计中经常用于信号整形的关键防线。 -**NOT 门(非门)**: +- **XOR 门(异或门)**: + - **规则**:当两个输入**不相同**时,输出恰好为 1。 + - **直觉理解**:你可以把它理解为一个“侦测差异”的精密机器。这是我们在电路中执行二进制加法的杀手锏。 -- **规则**:输入和输出相反 -- **生活类比**:反相器,开变关、关变开 -- **应用**:取反操作 +### 2.3 用逻辑门实现加法 -**XOR 门(异或门)**: +如果刚才介绍的逻辑门只能做简单的条件判断,那计算机到底是如何做数学运算的呢? -- **规则**:两个输入不同时输出 1 -- **生活类比**:判断"两个值是否不同" -- **应用**:比较、加法运算 +我们先回想一下手算加法的方式:对应位相加,如果超出了限制(十进制是满十进一,二进制是满二进一),就向更高位“进位”。 -### 2.3 用逻辑门做加法 +在二进制中,只有 0 和 1。对于一位数的加法,可能的情况只有四种: +- `0 + 0 = 0` (本位是 0,不进位) +- `0 + 1 = 1` (本位是 1,不进位) +- `1 + 0 = 1` (本位是 1,不进位) +- `1 + 1 = 10` (本位是 0,进位 1) + +仔细观察这四种情况,你会发现: +1. **本位的结果**,只有在两个输入**不同**时才为 1,这正是 **XOR 门(异或门)** 的逻辑。 +2. **进位的结果**,只有在两个输入**都为 1** 时才为 1,这正是 **AND 门(与门)** 的逻辑。 + +因此,只要把一个 XOR 门和一个 AND 门组合起来,我们就得到了能计算一位数加法的电路,这也是最基础的**半加器(Half Adder)**。 -::: tip 💡 加法器是怎么工作的? -**半加器**:处理两个 1 位二进制数相加 - -- 输入:A、B(各 1 位) -- 输出:和(S)、进位(C) -- 公式:S = A XOR B,C = A AND B - -**全加器**:处理两个 1 位二进制数相加,加上上一位的进位 - -- 输入:A、B、Cin(进位输入) -- 输出:和(S)、Cout(进位输出) - -**多位加法器**:把多个全加器级联起来 - -- 第 1 位加法器的进位输出,连接到第 2 位加法器的进位输入 -- 就像我们手算加法时"逢二进一" +::: tip 核心解析:分解加法器 +为了处理真实世界中更复杂的数字,加法器需要像搭积木一样拼装: + +1. **半加器(Half Adder)**:它可以处理两个一位数相加(即上述 XOR 和 AND 门的组合)。它计算了本位和进位,但没法接收来自更低位的进位。 +2. **全加器(Full Adder)**:在多位计算中,中间位数除了要把 A 和 B 加起来,还要处理来自低位的进位(Carry In)。把低位进位也加入逻辑后,就是全加器。 +3. **行波进位加法器(Ripple Carry Adder)**:要想处理 32 位或 64 位的数字,只需要把几十个全加器串联起来。进位信号便像波浪一样从低位一层层涌向高位,从而完成任意大小的加法。 ::: --- ## 3. 功能单元:逻辑门的组合 -### 3.1 常见功能单元 +现在,手里握着逻辑门构成的积木,我们可以向更高的抽象层跃进了。单单计算加法是不够的,我们将成组的逻辑门打包,组装成具有特定功能的模块。这些模块我们统称为**功能单元(Functional Units)**。 -| 单元 | 功能 | 组成 | 类比 | -| -------------- | -------- | ---------------- | ---------------- | -| **加法器** | 做加法 | 多个全加器级联 | 计算器的加法功能 | -| **多路选择器** | 选择数据 | AND 门 + OR 门 | 多选一开关 | -| **译码器** | 解码指令 | 多个 AND 门 | 翻译器 | -| **寄存器** | 存储数据 | 触发器(锁存器) | 临时笔记本 | -| **计数器** | 计数 | 触发器级联 | 计分牌 | +### 3.1 常见功能模块分类 + +在设计 CPU 时,有一些经过时间考验的经典预制模块: + +| 模块名称 | 承担的核心使命 | 内部的逻辑构造本质 | 现实生活中的绝佳隐喻 | +| -------------- | ------------------------------------ | ------------------------------------ | -------------------- | +| **加法器(Adder)** | 处理各种类型的算术运算引擎 | 海量全加器的高级按位级联 | 不知疲倦的算盘 | +| **多路选择器(MUX)** | 控制数据的流向途径,实现多选一通道 | 巧妙融合 AND 门作为开关、OR 门进行汇总 | 铁路线上的精密道岔 | +| **译码器(Decoder)** | 破解并翻译外部传入的二进制死指令 | 基于输入状态精确点亮特定输出的门阵列 | 破获密电的翻译员 | +| **触发器(Flip-Flop)**| 突破电信号转瞬即逝的限制,记录历史 | 极其微妙的交叉反馈环路构成双稳态模式 | 会保持状态的跷跷板 | + +为了直观地感受这些功能单元是如何工作的,你可以操作下面的组件,分别查看**多路选择器**和**译码器**的内部逻辑: + + + +请通过下面这款组件实验,亲自窥探其中最令人着迷的部分——**记忆是如何凭空产生的**: -### 3.2 寄存器:存储 1 位数据 +### 3.2 寄存器:数据的存储单元 -::: tip 💡 寄存器是怎么存储数据的? -寄存器使用**触发器**电路来存储数据。触发器的特点是:一旦设置了状态,就能保持住,直到下一次改变。 +除了计算,计算机还需要能够长期或临时地记住数据。如果在运算过程中丧失了对前一秒的记忆,那任何复杂的计算都无法进行。计算机必须拥有某种手段保留过去的状态,这种能力主要仰仗于一种名为**触发器(Flip-Flop)**的电路结构。 -**生活类比**:想象一个跷跷板: +::: tip 深入理解:记忆本质上是一种循环 +大多数逻辑电路的信号流向都是向前的(前馈回路)。而要产生持续的“记忆”,早期的先驱们想到了一个绝妙的设计:将输出的电波重新反馈回输入端。 -- 推一下左边,左边就沉下去,右边翘起来 -- 即使你松手,跷跷板也会保持这个状态 -- 只有再推一下,才会改变状态 +如同一个有着两个稳定静止点的精巧跷跷板结构。只要不受外界扰动,它凭借其闭环的设计,会永久性稳固在“左高右低(例如这就是记住了 0)”抑或是相反状态(记住了 1)。即便是转瞬即逝的状态改变,也能因闭环相互锁定而被长久“深锁”。 -触发器就是这样的"电子跷跷板",能"记住"上一次被设置的状态。 +当我们将 32 个抑或 64 个这种触发器整齐地编排成一列,施加同一种强劲的时钟频率信号(Clock)来号令它们统一行动时,**寄存器(Register)**便应运而生了。它身居 CPU 系统的心脏位置,被当做极速的“工作草稿纸”,默默捍卫着你每一个即时的关键变量。 ::: --- ## 4. CPU 架构:从功能单元到处理器 +随着各种运算模块和记忆组件设计完毕,现在到了核心的综合阶段。如何将这些模块组合起来,让它们变成能自动执行指令的中央处理器(CPU)? + ### 4.1 CPU 的核心组件 -CPU 不是单一部件,而是多个功能单元协作工作: +如果把 CPU 看作一个分工明确的机器,那么每个单元都有自己不可替代的位置: -| 组件 | 做什么 | 类比 | -| ------------ | ------------------------------ | ------------------------ | -| **控制器** | 取指、解码、发出控制信号 | 像指挥员,安排谁何时工作 | -| **ALU** | 加减、与、或、比较等运算 | 像计算器,做算术与逻辑 | -| **寄存器组** | 保存最常用的数据和中间结果 | 像桌面便签,比内存更快 | -| **内部总线** | 在模块间传数据、地址、控制信息 | 像高速通道,把组件连成整体 | - -一句话:控制器负责调度,ALU 负责计算,寄存器负责高速暂存,总线负责连接与传输。 +- **算术逻辑单元 (ALU)**:负责“干活”的运算单元,专门执行加减乘除和各种逻辑运算。 +- **寄存器组 (Register File)**:工作台上的临时抽屉,容量很小但速度极快,用于暂存当前正在计算的紧迫参数。 +- **内部总线 (Internal Bus)**:系统里的传送带,负责在各个模块之间搬运数据和信号。 +- **控制单元 (Control Unit)**:总指挥。它的使命就是从内存中读取用 0 和 1 组成的指令,解析出应该做什么,并向其他模块传达具体的控制信号,调度它们各司其职。 ### 4.2 CPU 是如何执行指令的? -CPU 执行一条指令,需要经过四个阶段: +不管写下的高级编程语言有多么复杂,最终都会变成内存中的一条条底层指令。CPU 执行任何指令的过程,本质上都在重复以下典型的四个步骤: -| 阶段 | 名称 | 做什么 | 类比 | -| ----- | ----------------- | ---------------- | ------------------ | -| **1** | 取指 (Fetch) | 从内存读取指令 | 从书架上取书 | -| **2** | 解码 (Decode) | 分析指令要做什么 | 阅读书的内容 | -| **3** | 执行 (Execute) | 执行运算 | 按书中的指示行动 | -| **4** | 写回 (Write Back) | 把结果存回寄存器 | 把结果记在笔记本上 | +1. **取指 (Fetch)**:循着当前程序执行的光标地址,探入相对漫长迟缓的缓存之中,把下一套二进制“指令”硬生生抓进核心。 +2. **译码 (Decode)**:指挥大脑马上分析:这道命令具体是要我移动内存,还是呼叫加法器拼凑运算?立刻将所需电路彻底连通唤醒。 +3. **执行 (Execute)**:指令派单到达诸如 ALU 等业务工厂车间,机器轰鸣,全力以赴进行硬核逻辑翻转。 +4. **写回 (Write Back)**:成果凝结时刻,将刚刚得手的答案慎重写至特定的寄存器或反馈回宽阔的内存。 -::: tip 💡 指令周期 -这四个阶段组成一个**指令周期**。CPU 不断重复这个周期,一条一条执行指令,就实现了"计算"。 +点击下方的“时钟脉冲”,观察在这个死循环中,指令是如何一步步被拆解、执行,并涉及哪些硬件模块的: -现代 CPU 使用**流水线技术**,让多个指令的不同阶段并行执行: + -- 第 1 条指令在执行时 -- 第 2 条指令在解码 -- 第 3 条指令在取指 +::: tip 追求效率的极致:流水线(Pipeline) +如果必须等上一条指令经历了这四个步骤后才开始下一条指令,效率显然太低。 -这就像工厂流水线,大大提高了效率。 +就像工厂的流水线一样,芯片工程师引入了**指令流水线技术**。这意味着当第一部分电路在对指令 A 进行“执行”时,之前的电路并没有闲着,而是去对指令 B 进行“解码”,甚至是把指令 C 提前“取指”拿了出来。通过这种并行的重叠方式,CPU 的执行效率得到了极大的提升。 ::: -### 4.3 CPU 性能的关键指标 - -| 指标 | 含义 | 影响 | 典型值 | -| ---------- | ---------------------- | ---------------------- | -------- | -| **主频** | 每秒执行多少个时钟周期 | 主频越高,执行越快 | 3-5 GHz | -| **核心数** | 独立的处理器数量 | 核心越多,并行能力越强 | 4-64 核 | -| **缓存** | CPU 内部的高速存储 | 缓存越大,访问内存越少 | 8-64 MB | -| **指令集** | CPU 能理解的指令集合 | 决定兼容性和功能 | x86、ARM | - --- -## 5. 总结:从沙子到智能 +## 5. 总结:跨越抽象层级 -每一层都是对下一层的抽象封装,从沙子到可运行软件的完整路径如下: +回顾这一路,我们经历了计算机体系结构中最核心的层层抽象。这是将底层物理材料变为通用计算平台的完整路径: -1. **沙子(硅)** — 原材料:地球上最丰富的元素之一,提炼出高纯度硅。 - ↓ 提纯 → 切割成晶圆 +1. **宏观物理:沙子(二氧化硅晶体)** + → *接受人类冶炼、切片、剧毒气体蚀刻等种种苛刻雕琢后* +2. **微观物理:海量的晶体管开关** (以微电控微电) + → *经过工程大牛不眠不休的密集拉线,实现了惊人的数字抽象约束* +3. **数字代数:AND / OR / NOT 逻辑门体系** + → *无情抹杀误差,以完美真值表衍生出基础行为* +4. **微架构模块:功能单元积木集(加法器等组件)** + → *加入了系统生命节拍与记忆特性,进化为完整功能体* +5. **复杂体系结构:庞大而精妙的 CPU 联合阵列** + → *面向全世界开发极客,彻底敞开了通往虚拟应用世界的大门* +6. **万千应用王国:算法、系统级软件以及繁花似锦的互联网宇宙** -2. **硅晶圆** — 基底:直径约 30cm 的单晶硅片,表面极其光滑。 - ↓ 光刻 → 蚀刻 → 掺杂 +计算机科学中最令人着迷的部分在于,**每一层封装都完美地隐藏了下一层的复杂细节**。作为一个软件开发者,当你写下 `salary = base + bonus` 时,完全不需要考虑底层电子的漂移以及半加器内电流的走向;同样,芯片硬件设计师也不需要操心这块芯片未来将运行什么软件。 -3. **晶体管(开关)** — 数百亿个/芯片:Gate=1 导通,Gate=0 断开,用电压控制电流。 - ↓ 组合成逻辑电路 +正是极端的层级解耦以及高度互不干扰的黑盒封装,合力孕育、铺就了现代科技的狂欢盛世。 -4. **逻辑门** — 数十亿个:AND / OR / NOT / XOR,实现基本布尔运算。 - ↓ 组合成功能模块 +::: tip 终极思考 +**归根究底,所谓的算力,不过是有限的密闭空间内海量开关重组的变幻;伴随着时钟的节拍,在这片小小的硅片上完成了复杂的运算。** -5. **功能单元** — 数百个:加法器、寄存器、多路选择器……各司其职。 - ↓ 集成为完整处理器 - -6. **CPU 核心** — 1~128 核:ALU + 控制器 + 寄存器组,执行取指→解码→执行→写回。 - ↓ 软件编程 - -7. **软件应用** — 无限可能:操作系统 / AI 模型 / 游戏 / 网页……一切皆指令。 - -计算机的本质是「开关的组合」:通过一层层抽象封装,最底层的物理材料最终变成能执行任意逻辑的通用计算平台。 - -::: tip 核心启示 -**计算机的本质是"开关的组合"**。 - -- 一个开关做不了什么 -- 但几十亿个开关,按特定方式组合,就能执行任何计算 -- 这就是"量变引起质变"的最好例证 - -理解这一点,你就会明白: - -- 为什么计算机只认识 0 和 1 -- 为什么编程语言最终都要翻译成机器码 -- 为什么算法效率如此重要(因为每一步操作都需要大量晶体管参与) +“量变最终引发质的飞跃”,这句话在计算机体系结构中被不断验证。当我们敲下键盘,注视着屏幕时,可以试着想象:在极其微小的硅基深处,此刻正有百亿级极小的晶体管,在电光火石之间拼尽全力进行着精密的协同。这或许就是最独特的计算机科学之美。 ::: --- ## 延伸阅读 -- **计算机组成原理**:深入了解 CPU、内存、I/O 的工作原理 -- **数字电路**:学习逻辑门、触发器、时序电路的设计 -- **计算机体系结构**:研究 CPU 的性能优化、流水线、缓存等 -- **汇编语言**:直接和 CPU 对话,理解指令执行过程 +如果你对底层技术充满好奇,可以尝试在以下几个方向继续探索: +- **经典教材**:《计算机组成与设计(软硬件接口)》是深入学习体系结构的一本很好的参考书。 +- **数字逻辑仿真**:尝试使用逻辑仿真软件或基础元器件,动手搭建一个简单的 8 位加法器或模拟器。 +- **体系结构前沿**:了解多级缓存如何缓解“内存墙”问题、指令乱序执行的原理,以及 GPU 的特殊运算机制等。 +- **底层与汇编语言**:尝试学习一些基础汇编语言,理解高级语言最终是如何被转化为机器可以执行的十六进制指令的。 diff --git a/docs/zh-cn/appendix/3-browser-and-frontend/browser-as-os-rendering.md b/docs/zh-cn/appendix/3-browser-and-frontend/browser-as-os-rendering.md index d3250af..0670b47 100644 --- a/docs/zh-cn/appendix/3-browser-and-frontend/browser-as-os-rendering.md +++ b/docs/zh-cn/appendix/3-browser-and-frontend/browser-as-os-rendering.md @@ -755,7 +755,7 @@ console.log('4. End') `setTimeout(0)`不保证立即执行,它至少会被延迟到当前调用栈清空、微任务队列清空之后。 ::: - + diff --git a/docs/zh-cn/appendix/4-server-and-backend/api-design.md b/docs/zh-cn/appendix/4-server-and-backend/api-design.md index 4f63cbd..e11adff 100644 --- a/docs/zh-cn/appendix/4-server-and-backend/api-design.md +++ b/docs/zh-cn/appendix/4-server-and-backend/api-design.md @@ -78,7 +78,46 @@ HTTP/1.1 200 OK --- -## 2. RESTful 设计:让 URL 会说话 +## 2. API 设计哲学:RPC / REST / GraphQL / gRPC + +在开始具体的 RESTful 设计之前,先了解四种主流的 API 设计风格: + + + +### 2.1 REST vs RESTful:有什么区别? + +很多人会混淆这两个概念: + +| 概念 | 含义 | 说明 | +| :--- | :--- | :--- | +| **REST** | 一种架构风格 | 由 Roy Fielding 提出的设计理念,包含一组约束条件 | +| **RESTful** | 符合 REST 风格的 | 形容词,表示 API 设计遵循了 REST 原则 | + +**类比**: +- REST 就像"极简主义"——一种设计理念 +- RESTful API 就像"极简风格的房间"——应用了这个理念的具体实现 + +**REST 的六大约束**: + +| 约束 | 说明 | +| :--- | :--- | +| **客户端-服务器分离** | 前后端独立开发,接口解耦 | +| **无状态** | 每个请求包含所有必要信息,服务器不保存会话状态 | +| **可缓存** | 响应应标明是否可缓存,提高性能 | +| **统一接口** | 使用标准的 HTTP 方法和状态码 | +| **分层系统** | 客户端无需知道连接的是哪层服务器 | +| **按需代码**(可选) | 服务器可以扩展客户端功能 | + +::: tip 💡 为什么 REST 最常用? +1. **学习成本低**:HTTP 协议本身就体现了 REST 思想 +2. **生态成熟**:工具、框架、文档丰富 +3. **通用性强**:任何语言、任何平台都能调用 +4. **易于缓存**:GET 请求天然可缓存,CDN 友好 +::: + +--- + +## 3. RESTful 设计:让 URL 会说话 **REST**(Representational State Transfer)是一种架构风格,核心思想是: @@ -86,7 +125,7 @@ HTTP/1.1 200 OK - 用 URL 标识资源 - 用 HTTP 方法操作资源 -### 2.1 用仓库来类比 +### 3.1 用仓库来类比 | 仓库概念 | REST 对应 | 示例 | | :--- | :--- | :--- | @@ -96,21 +135,21 @@ HTTP/1.1 200 OK **关键原则**:URL 是名词,不是动词。 -### 2.2 URL 设计规则 +### 3.2 URL 设计规则 | 规则 | 错误示例 | 正确示例 | 说明 | | :--- | :--- | :--- | :--- | -| **用名词不用动词** | `GET /getUsers`
`POST /createOrder` | `GET /users`
`POST /orders` | URL 是资源地址,HTTP 方法已表达操作 | -| **用复数形式** | `GET /user`
`GET /order` | `GET /users`
`GET /users/123` | 统一用复数,避免 `/user` 和 `/users` 混用 | -| **小写+连字符** | `GET /UserProfiles`
`GET /user_profiles` | `GET /user-profiles`
`GET /order-items` | URL 大小写敏感,统一小写最安全 | -| **避免层级过深** | `GET /users/123/orders/456/items/789` | `GET /users/123/orders`
`GET /order-items/789` | 超过 3 层考虑重构,用扁平化路径 | -| **过滤用查询参数** | `GET /products/category/phone/price/5000` | `GET /products?category=phone&price_max=5000` | 过滤、排序、分页都用查询参数 | +| 用名词不用动词 | `/getUsers` | `/users` | URL 表示资源,HTTP 方法表示操作 | +| 用复数形式 | `/user` | `/users` | 统一复数风格 | +| 小写+连字符 | `/UserProfiles` | `/user-profiles` | URL 大小写敏感 | +| 避免层级过深 | `/a/b/c/d/e` | `/a/b/c` | 最多 3 层 | +| 过滤用查询参数 | `/products/phone/5000` | `/products?cat=phone` | 过滤条件用 `?` 参数 | ::: tip 💡 URL 大小写敏感 统一用小写 + 连字符(-)是最安全的做法,避免大小写混乱和下划线风格不一致的问题。 ::: -### 2.3 HTTP 方法选择 +### 3.3 HTTP 方法选择 | 方法 | 用途 | 幂等性 | 安全性 | 典型场景 | | :--- | :--- | :--- | :--- | :--- | @@ -131,11 +170,11 @@ HTTP/1.1 200 OK --- -## 3. 状态码:让错误"会说话" +## 4. 状态码:让错误"会说话" HTTP 状态码是服务器告诉客户端"发生了什么"的标准方式。 -### 3.1 状态码分类 +### 4.1 状态码分类 | 分类 | 含义 | 典型状态码 | | :--- | :--- | :--- | @@ -144,7 +183,7 @@ HTTP 状态码是服务器告诉客户端"发生了什么"的标准方式。 | **4xx** | 客户端错误 | 400 参数错误、401 未认证、404 不存在 | | **5xx** | 服务端错误 | 500 内部错误、503 服务不可用 | -### 3.2 常用状态码演示 +### 4.2 常用状态码演示 👇 **动手试试看**:点击下方按钮,了解常见状态码的含义: @@ -152,7 +191,7 @@ HTTP 状态码是服务器告诉客户端"发生了什么"的标准方式。 --- -## 4. 错误处理:优雅地"拒绝" +## 5. 错误处理:优雅地"拒绝" 好的错误处理能让客户端"看状态码就知道怎么回事",而不是去猜。 @@ -188,7 +227,7 @@ HTTP/1.1 500 Internal Server Error 危险:暴露了代码结构、数据库查询,攻击者可以利用这些信息。 -### 4.2 正确的错误处理演示 +### 5.2 正确的错误处理演示 👇 **动手试试看**:对比"好的"和"差的"错误响应设计: @@ -196,9 +235,9 @@ HTTP/1.1 500 Internal Server Error --- -## 5. 版本控制:API 的"向后兼容" +## 6. 版本控制:API 的"向后兼容" -### 5.1 为什么要版本控制? +### 6.1 为什么要版本控制? 场景:你的 App 有 100 万用户,需要修改订单接口。 @@ -210,7 +249,7 @@ HTTP/1.1 500 Internal Server Error - `/v1/orders` - 旧接口,继续服务旧 App - `/v2/orders` - 新接口,新功能在这里 -### 5.2 版本控制策略 +### 6.2 版本控制策略 | 策略 | 示例 | 优点 | 缺点 | | :--- | :--- | :--- | :--- | @@ -218,66 +257,251 @@ HTTP/1.1 500 Internal Server Error | **请求头** | `Accept: vnd.api.v2+json` | URL 干净 | 不便调试 | | **查询参数** | `/users?version=2` | 简单 | 不够标准 | -### 5.3 版本控制演示 +### 6.3 版本演进示例 -👇 **动手试试看**:了解 API 版本控制的策略和最佳实践: +以用户接口为例,展示 v1 到 v2 的演进: - +| 接口 | v1(旧版) | v2(新版) | 变化说明 | +| :--- | :--- | :--- | :--- | +| **获取用户** | `GET /v1/users`
返回:`name, email` | `GET /v2/users`
返回:`name, email, avatar, phone` | 新增头像、手机号字段 | +| **创建订单** | `POST /v1/orders`
接收:`items[]` | `POST /v2/orders`
接收:`items[], coupons[]` | 新增优惠券支持 | +| **批量操作** | 无 | `POST /v2/orders/batch` | 新增批量创建接口 | ---- - -## 6. 响应结构:标准化的"数据契约" - -无论成功还是失败,响应结构应该保持一致: - -### 6.1 标准响应格式 - -```json -{ - "code": 0, - "message": "success", - "data": { ... }, - "request_id": "req-550e8400", - "timestamp": "2024-01-15T09:30:00.000Z" -} -``` - -| 字段 | 类型 | 说明 | -| :--- | :--- | :--- | -| `code` | number | 业务状态码,0 表示成功 | -| `message` | string | 状态描述 | -| `data` | any | 业务数据 | -| `request_id` | string | 请求唯一标识,用于问题追踪 | -| `timestamp` | string | 响应时间戳 | - -### 6.2 分页响应格式 - -```json -{ - "code": 0, - "data": { - "items": [...], - "pagination": { - "page": 1, - "page_size": 20, - "total": 156, - "total_pages": 8 - } - } -} -``` - -::: tip 💡 为什么要 request_id? -**request_id** 是问题追踪的关键: - -1. 用户反馈:"支付失败,错误 ID 是 abc123" -2. 技术人员直接在日志里搜索 abc123,立即定位问题 -3. 分布式系统中,每个服务都记录相同的 request_id,可以把所有相关日志聚合起来 +::: tip 💡 版本控制最佳实践 +- **保持向后兼容**:v1 接口至少维护 6-12 个月,给客户端升级时间 +- **文档同步更新**:每个版本有独立的 API 文档 +- **废弃公告**:提前通知 v1 将在何时下线,引导迁移 +- **监控使用情况**:统计 v1 调用量,确认可以安全下线后再停止服务 ::: --- -## 7. 实战:电商系统 API 设计示例 +## 7. 响应结构设计 + +响应结构是前后端协作的"数据契约",统一格式能大幅降低沟通成本。 + + + +### 7.1 大厂实践参考 + +::: details Google API 设计指南 +参考 [Google API Design Guide](https://cloud.google.com/apis/design/errors),Google 要求所有 API 错误响应必须包含 `google.rpc.Status` 消息结构: + +```json +{ + "error": { + "code": 429, + "message": "资源不足,请稍后重试", + "status": "RESOURCE_EXHAUSTED", + "details": [ + { + "@type": "type.googleapis.com/google.rpc.ErrorInfo", + "reason": "RESOURCE_AVAILABILITY", + "domain": "compute.googleapis.com", + "metadata": { + "zone": "us-east1-a", + "service": "compute" + } + } + ] + } +} +``` + +**核心要求**: +- 必须包含 `ErrorInfo` 提供机器可读的错误标识 +- `message` 面向开发者,用简洁语言描述问题和解决方案 +- `details` 数组可包含 `LocalizedMessage`(本地化消息)、`Help`(帮助链接)等 +::: + +::: details Microsoft REST API 指南 +参考 [Microsoft REST API Guidelines](https://github.com/microsoft/api-guidelines/blob/vNext/Guidelines.md),微软强调响应的一致性: + +**错误与故障的分类**: +- **错误(Error)**:客户端传递无效数据导致,返回 4xx,不影响 API 可用性 +- **故障(Fault)**:服务端无法正确响应有效请求,返回 5xx,影响 API 可用性 + +**响应标头规范**: +- `Date`:必须返回,使用 RFC 5322 格式(GMT 时区) +- `Content-Type`:必须返回 +- `ETag`:支持乐观并发控制的资源必须返回 +::: + +::: details 阿里巴巴 Java 开发手册 +参考 [阿里巴巴 Java 开发手册](https://developer.aliyun.com/special/tech-java),阿里对 API 响应有以下规范: + +**统一返回对象**: +```java +public class Result { + private Integer code; + private String message; + private T data; + private String requestId; +} +``` + +**错误码分段设计**: +| 范围 | 类型 | 示例 | +| :--- | :--- | :--- | +| 0 | 成功 | 0 | +| 1xxxx | 参数错误 | 10001 缺少必填参数 | +| 2xxxx | 业务错误 | 20001 余额不足 | +| 3xxxx | 认证错误 | 30001 未登录 | +| 5xxxx | 系统错误 | 50001 数据库异常 | +::: + +::: details Stripe API 响应设计 +参考 [Stripe API Documentation](https://docs.stripe.com/api/errors),Stripe 的错误响应设计非常精细: + +```json +{ + "error": { + "type": "card_error", + "code": "card_declined", + "message": "Your card was declined.", + "param": "number", + "decline_code": "insufficient_funds", + "doc_url": "https://stripe.com/docs/error-codes/card-declined" + } +} +``` + +**设计亮点**: +- `type` 区分错误类型:`api_error`、`card_error`、`invalid_request_error` +- `param` 指出具体哪个参数出错,前端可直接定位表单字段 +- `doc_url` 提供文档链接,开发者可深入了解 +- `decline_code` 提供更细粒度的错误原因 +::: + +::: details JSON:API 规范 +参考 [JSON:API Specification](https://jsonapi.org/format/),这是一个业界广泛采纳的 JSON API 响应规范: + +```json +{ + "data": { + "type": "articles", + "id": "1", + "attributes": { + "title": "JSON:API 规范详解" + }, + "relationships": { + "author": { + "data": { "type": "users", "id": "9" } + } + } + }, + "included": [ + { + "type": "users", + "id": "9", + "attributes": { + "name": "张三" + } + } + ] +} +``` + +**核心设计**: +- `data` 包含主资源,必须有 `type` 和 `id` +- `attributes` 存放资源属性 +- `relationships` 描述资源关联 +- `included` 避免重复请求,一次性返回关联数据 +::: + +::: details GitHub REST API 响应设计 +参考 [GitHub REST API Documentation](https://docs.github.com/en/rest),GitHub 的响应设计注重开发者体验: + +**成功响应**: +```json +{ + "id": 1296269, + "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", + "name": "Hello-World", + "full_name": "octocat/Hello-World", + "owner": { + "login": "octocat", + "id": 1, + "avatar_url": "https://github.com/images/error/octocat_happy.gif" + }, + "private": false, + "html_url": "https://github.com/octocat/Hello-World" +} +``` + +**错误响应**: +```json +{ + "message": "Bad credentials", + "documentation_url": "https://docs.github.com/rest" +} +``` + +**设计亮点**: +- 响应包含多种 URL 格式(`html_url`、`url`)方便不同场景使用 +- 错误响应包含 `documentation_url` 指向文档 +- 使用 `Link` 响应头实现分页导航 +::: + +::: details Twitter/X API v2 响应设计 +参考 [Twitter API v2 Documentation](https://developer.twitter.com/en/docs/twitter-api),Twitter API v2 采用简洁的响应格式: + +```json +{ + "data": { + "id": "1460323737035677698", + "text": "Hello, Twitter!" + }, + "includes": { + "users": [ + { + "id": "2244994945", + "name": "Twitter Dev", + "username": "TwitterDev" + } + ] + } +} +``` + +**设计亮点**: +- `data` 包含主数据,`includes` 包含关联数据(类似 JSON:API) +- 支持字段选择:`?tweet.fields=created_at,public_metrics` +- 分页使用 `next_token` 和 `previous_token` +::: + +### 7.2 最佳实践总结 + +综合以上规范,响应结构设计应遵循以下原则: + +1. **一致性优先**:所有接口使用相同的响应结构,前端可统一封装请求层 +2. **机器可读**:错误码 + 错误原因(reason)让程序能自动处理 +3. **人类友好**:message 描述清晰,包含解决建议 +4. **可追踪**:request_id 贯穿请求全链路,便于问题定位 +5. **国际化支持**:通过 details 扩展本地化消息 + +### 7.3 data 字段设计规范 + +`data` 是响应的核心,其设计直接影响前端开发效率。 + + + +### 7.4 错误响应设计进阶 + + + +::: tip 参考链接 +- [Google API Design Guide - Errors](https://cloud.google.com/apis/design/errors) +- [Microsoft REST API Guidelines](https://github.com/microsoft/api-guidelines) +- [阿里巴巴 Java 开发手册](https://developer.aliyun.com/special/tech-java) +- [Heroku HTTP API Design Guide](https://github.com/interagent/http-api-design) +- [Stripe API - Errors](https://docs.stripe.com/api/errors) +- [JSON:API Specification](https://jsonapi.org/format/) +::: + +--- + +## 8. 实战:电商系统 API 设计示例 ``` # 用户模块 @@ -300,6 +524,100 @@ GET /v1/products?category=phone&price_max=5000&sort=price_desc&page=1 --- +## 9. 用 AI 辅助设计 API + +AI 可以帮助你快速生成符合规范的 API 设计。关键在于提供清晰的上下文和约束条件。 + +### 9.1 提示词模板 + +``` +你是一位资深的后端架构师,精通 RESTful API 设计。请帮我设计一套 API 接口。 + +## 业务背景 +[描述你的业务场景,例如:电商系统、博客平台、任务管理等] + +## 功能需求 +[列出需要的功能模块,例如: +- 用户管理:注册、登录、个人信息 +- 订单管理:创建订单、查询订单、取消订单 +- 商品管理:商品列表、商品详情、搜索] + +## 设计要求 +1. 遵循 RESTful 规范 +2. URL 使用名词复数,小写+连字符 +3. 正确使用 HTTP 方法(GET/POST/PUT/PATCH/DELETE) +4. 统一的响应格式:{ code, message, data, request_id } +5. 合理的状态码使用 +6. 版本控制:URL 路径方式(/v1/) + +## 输出格式 +请按以下格式输出: + +### 接口列表 +| 方法 | URL | 描述 | 请求体 | 响应体 | +|------|-----|------|--------|--------| + +### 请求/响应示例 +[关键接口的详细示例] + +### 状态码说明 +[使用的状态码及其含义] +``` + +### 9.2 实战示例:电商订单 API + +**输入提示词:** + +``` +你是一位资深的后端架构师,精通 RESTful API 设计。请帮我设计一套电商订单系统的 API 接口。 + +## 业务背景 +一个 B2C 电商平台,用户可以浏览商品、下单购买、查看订单状态。 + +## 功能需求 +- 订单模块:创建订单、查询订单列表、查询订单详情、取消订单、支付订单 +- 购物车模块:添加商品、修改数量、删除商品、查看购物车 + +## 设计要求 +1. 遵循 RESTful 规范 +2. URL 使用名词复数,小写+连字符 +3. 正确使用 HTTP 方法 +4. 统一的响应格式 +5. 版本控制:/v1/ +``` + +**AI 输出示例:** + +| 方法 | URL | 描述 | +| :--- | :--- | :--- | +| `POST` | `/v1/orders` | 创建订单 | +| `GET` | `/v1/orders` | 查询订单列表 | +| `GET` | `/v1/orders/{id}` | 查询订单详情 | +| `PATCH` | `/v1/orders/{id}/status` | 更新订单状态(取消/支付) | +| `GET` | `/v1/users/{id}/cart` | 获取购物车 | +| `POST` | `/v1/users/{id}/cart/items` | 添加商品到购物车 | +| `PATCH` | `/v1/users/{id}/cart/items/{itemId}` | 修改购物车商品数量 | +| `DELETE` | `/v1/users/{id}/cart/items/{itemId}` | 删除购物车商品 | + +### 9.3 AI 辅助设计的注意事项 + +| 注意点 | 说明 | +| :--- | :--- | +| **提供完整上下文** | 业务背景、用户角色、数据关系都要说清楚 | +| **明确约束条件** | 命名规范、版本策略、响应格式等要提前定义 | +| **迭代优化** | 第一次输出可能不完美,追问细节、要求修改 | +| **人工审核** | AI 生成的内容需要人工检查是否符合业务需求 | +| **补充边界情况** | 让 AI 考虑错误处理、权限控制、分页等边界情况 | + +::: tip 💡 追问技巧 +- "请补充每个接口的错误响应示例" +- "请考虑分页、排序、过滤参数" +- "请添加接口的权限控制说明" +- "请检查是否符合 RESTful 最佳实践" +::: + +--- + ## 名词速查表 | 名词 | 英文 | 解释 |