diff --git a/docs/.vitepress/theme/components/appendix/computer-fundamentals/AdderDemo.vue b/docs/.vitepress/theme/components/appendix/computer-fundamentals/AdderDemo.vue new file mode 100644 index 0000000..d583dbf --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/AdderDemo.vue @@ -0,0 +1,300 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/computer-fundamentals/AlgorithmDemo.vue b/docs/.vitepress/theme/components/appendix/computer-fundamentals/AlgorithmDemo.vue new file mode 100644 index 0000000..de2b34c --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/AlgorithmDemo.vue @@ -0,0 +1,535 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/computer-fundamentals/CompilerDemo.vue b/docs/.vitepress/theme/components/appendix/computer-fundamentals/CompilerDemo.vue new file mode 100644 index 0000000..aa380ea --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/CompilerDemo.vue @@ -0,0 +1,598 @@ + + + + + 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..b1d3dc2 --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/CpuArchitectureDemo.vue @@ -0,0 +1,245 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/computer-fundamentals/DataStructureDemo.vue b/docs/.vitepress/theme/components/appendix/computer-fundamentals/DataStructureDemo.vue new file mode 100644 index 0000000..7b35040 --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/DataStructureDemo.vue @@ -0,0 +1,529 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/computer-fundamentals/EncodingDemo.vue b/docs/.vitepress/theme/components/appendix/computer-fundamentals/EncodingDemo.vue new file mode 100644 index 0000000..a82176c --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/EncodingDemo.vue @@ -0,0 +1,265 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/computer-fundamentals/FilesystemDemo.vue b/docs/.vitepress/theme/components/appendix/computer-fundamentals/FilesystemDemo.vue new file mode 100644 index 0000000..0920868 --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/FilesystemDemo.vue @@ -0,0 +1,292 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/computer-fundamentals/LanguageMapDemo.vue b/docs/.vitepress/theme/components/appendix/computer-fundamentals/LanguageMapDemo.vue new file mode 100644 index 0000000..2711c7f --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/LanguageMapDemo.vue @@ -0,0 +1,404 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/computer-fundamentals/LogicGateDemo.vue b/docs/.vitepress/theme/components/appendix/computer-fundamentals/LogicGateDemo.vue new file mode 100644 index 0000000..f198b86 --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/LogicGateDemo.vue @@ -0,0 +1,374 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/computer-fundamentals/MemoryDemo.vue b/docs/.vitepress/theme/components/appendix/computer-fundamentals/MemoryDemo.vue new file mode 100644 index 0000000..39369c9 --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/MemoryDemo.vue @@ -0,0 +1,282 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/computer-fundamentals/NetworkLayers.vue b/docs/.vitepress/theme/components/appendix/computer-fundamentals/NetworkLayers.vue new file mode 100644 index 0000000..6e21a92 --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/NetworkLayers.vue @@ -0,0 +1,361 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/computer-fundamentals/ProcessDemo.vue b/docs/.vitepress/theme/components/appendix/computer-fundamentals/ProcessDemo.vue new file mode 100644 index 0000000..44f6ff2 --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/ProcessDemo.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/computer-fundamentals/StorageDemo.vue b/docs/.vitepress/theme/components/appendix/computer-fundamentals/StorageDemo.vue new file mode 100644 index 0000000..d0c689d --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/StorageDemo.vue @@ -0,0 +1,246 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/computer-fundamentals/SubnetCalculator.vue b/docs/.vitepress/theme/components/appendix/computer-fundamentals/SubnetCalculator.vue new file mode 100644 index 0000000..55e5f48 --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/SubnetCalculator.vue @@ -0,0 +1,432 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/computer-fundamentals/TcpUdpComparison.vue b/docs/.vitepress/theme/components/appendix/computer-fundamentals/TcpUdpComparison.vue new file mode 100644 index 0000000..e009723 --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/TcpUdpComparison.vue @@ -0,0 +1,584 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/computer-fundamentals/TransistorDemo.vue b/docs/.vitepress/theme/components/appendix/computer-fundamentals/TransistorDemo.vue new file mode 100644 index 0000000..6804ff6 --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/TransistorDemo.vue @@ -0,0 +1,201 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/computer-fundamentals/TransmissionDemo.vue b/docs/.vitepress/theme/components/appendix/computer-fundamentals/TransmissionDemo.vue new file mode 100644 index 0000000..a109f74 --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/TransmissionDemo.vue @@ -0,0 +1,345 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/computer-fundamentals/TypeSystemDemo.vue b/docs/.vitepress/theme/components/appendix/computer-fundamentals/TypeSystemDemo.vue new file mode 100644 index 0000000..26e703c --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/computer-fundamentals/TypeSystemDemo.vue @@ -0,0 +1,481 @@ + + + + + diff --git a/docs/.vitepress/theme/index.js b/docs/.vitepress/theme/index.js index 5b46221..8659bee 100644 --- a/docs/.vitepress/theme/index.js +++ b/docs/.vitepress/theme/index.js @@ -107,6 +107,26 @@ import TcpUdpComparison from './components/appendix/web-basics/TcpUdpComparison. import SubnetCalculator from './components/appendix/web-basics/SubnetCalculator.vue' import NetworkTroubleshooting from './components/appendix/web-basics/NetworkTroubleshooting.vue' +// Computer Fundamentals Components +import TransistorDemo from './components/appendix/computer-fundamentals/TransistorDemo.vue' +import LogicGateDemo from './components/appendix/computer-fundamentals/LogicGateDemo.vue' +import AdderDemo from './components/appendix/computer-fundamentals/AdderDemo.vue' +import CpuArchitectureDemo from './components/appendix/computer-fundamentals/CpuArchitectureDemo.vue' +import ProcessDemo from './components/appendix/computer-fundamentals/ProcessDemo.vue' +import MemoryDemo from './components/appendix/computer-fundamentals/MemoryDemo.vue' +import FilesystemDemo from './components/appendix/computer-fundamentals/FilesystemDemo.vue' +import EncodingDemo from './components/appendix/computer-fundamentals/EncodingDemo.vue' +import StorageDemo from './components/appendix/computer-fundamentals/StorageDemo.vue' +import TransmissionDemo from './components/appendix/computer-fundamentals/TransmissionDemo.vue' +import DataStructureDemo from './components/appendix/computer-fundamentals/DataStructureDemo.vue' +import AlgorithmDemo from './components/appendix/computer-fundamentals/AlgorithmDemo.vue' +import LanguageMapDemo from './components/appendix/computer-fundamentals/LanguageMapDemo.vue' +import TypeSystemDemo from './components/appendix/computer-fundamentals/TypeSystemDemo.vue' +import CompilerDemo from './components/appendix/computer-fundamentals/CompilerDemo.vue' +import CFNetworkLayers from './components/appendix/computer-fundamentals/NetworkLayers.vue' +import CFSubnetCalculator from './components/appendix/computer-fundamentals/SubnetCalculator.vue' +import CFTcpUdpComparison from './components/appendix/computer-fundamentals/TcpUdpComparison.vue' + // Deployment appendix components import DeploymentOverviewDemo from './components/appendix/deployment/DeploymentOverviewDemo.vue' import DeploymentBuildDemo from './components/appendix/deployment/DeploymentBuildDemo.vue' @@ -611,6 +631,27 @@ export default { app.component('TcpUdpComparison', TcpUdpComparison) app.component('SubnetCalculator', SubnetCalculator) app.component('NetworkTroubleshooting', NetworkTroubleshooting) + + // Computer Fundamentals Components Registration + app.component('TransistorDemo', TransistorDemo) + app.component('LogicGateDemo', LogicGateDemo) + app.component('AdderDemo', AdderDemo) + app.component('CpuArchitectureDemo', CpuArchitectureDemo) + app.component('ProcessDemo', ProcessDemo) + app.component('MemoryDemo', MemoryDemo) + app.component('FilesystemDemo', FilesystemDemo) + app.component('EncodingDemo', EncodingDemo) + app.component('StorageDemo', StorageDemo) + app.component('TransmissionDemo', TransmissionDemo) + app.component('DataStructureDemo', DataStructureDemo) + app.component('AlgorithmDemo', AlgorithmDemo) + app.component('LanguageMapDemo', LanguageMapDemo) + app.component('TypeSystemDemo', TypeSystemDemo) + app.component('CompilerDemo', CompilerDemo) + app.component('CFNetworkLayers', CFNetworkLayers) + app.component('CFSubnetCalculator', CFSubnetCalculator) + app.component('CFTcpUdpComparison', CFTcpUdpComparison) + // Deployment appendix app.component('DeploymentOverviewDemo', DeploymentOverviewDemo) app.component('DeploymentBuildDemo', DeploymentBuildDemo) diff --git a/docs/zh-cn/appendix/1-computer-fundamentals/algorithm-thinking.md b/docs/zh-cn/appendix/1-computer-fundamentals/algorithm-thinking.md index 22558c4..f09ca1f 100644 --- a/docs/zh-cn/appendix/1-computer-fundamentals/algorithm-thinking.md +++ b/docs/zh-cn/appendix/1-computer-fundamentals/algorithm-thinking.md @@ -1,3 +1,230 @@ # 算法思维入门 -> 待实现 +::: tip 🎯 核心问题 +**如何高效地解决问题?** 你可能遇到过这样的困惑:同一个问题,有人写的代码跑几秒就出结果,有人写的跑几分钟还在转。差别往往在于算法。本章带你理解算法的核心思维方式。 +::: + +--- + +## 0. 全景图:算法是什么? + +想象你要在一本字典里找一个单词: + +- **方法一**:从第一页开始,一页一页翻(线性查找) +- **方法二**:根据首字母定位,再二分查找(二分查找) + +两种方法都能找到,但效率天差地别。**算法就是解决问题的方法**。 + + + +**算法的核心指标:** + +| 指标 | 含义 | 为什么重要 | +|------|------|-----------| +| **时间复杂度** | 运行时间随数据量增长的趋势 | 预测大规模数据的性能 | +| **空间复杂度** | 内存占用随数据量增长的趋势 | 评估内存消耗 | +| **正确性** | 是否总能得到正确结果 | 算法的基本要求 | + +::: tip 📊 逐行解读这张表 +**时间复杂度**:用大 O 表示法描述。O(n) 表示数据量翻倍,时间翻倍;O(n²) 表示数据量翻倍,时间变成 4 倍。 + +**空间复杂度**:同样用大 O 表示法。有些算法用空间换时间(如哈希表),有些用时间换空间(如压缩算法)。 + +**正确性**:算法必须对所有可能的输入都能给出正确结果。边界条件(空输入、极大输入)最容易出错。 +::: + +--- + +## 1. 二分查找:每次排除一半 + +### 1.1 二分查找的原理 + +::: tip 💡 二分查找如何工作? +**前提**:数据必须有序 + +**过程**: +1. 找到中间元素 +2. 如果中间元素等于目标,找到! +3. 如果目标小于中间元素,在左半部分继续 +4. 如果目标大于中间元素,在右半部分继续 +5. 每次排除一半,直到找到或确定不存在 + +**时间复杂度**:O(log n) + +**生活类比**:猜数字游戏。我想一个 1-100 的数,你每次猜中间,我告诉你大了还是小了。最多猜 7 次就能猜中(因为 2⁷ = 128 > 100)。 +::: + +### 1.2 为什么二分查找这么快? + +| 数据量 | 线性查找 | 二分查找 | +|--------|---------|---------| +| 100 | 100 次 | 7 次 | +| 1,000 | 1,000 次 | 10 次 | +| 1,000,000 | 1,000,000 次 | 20 次 | +| 1,000,000,000 | 1,000,000,000 次 | 30 次 | + +::: tip 💡 对数增长的威力 +二分查找的时间复杂度是 O(log n),这意味着: + +- 10 亿数据,最多查找 30 次 +- 1 万亿数据,最多查找 40 次 + +这就是对数增长的威力——数据量增加 1000 倍,查找次数只增加 10 次。 +::: + +--- + +## 2. 排序:将无序变有序 + +### 2.1 常见排序算法 + +| 算法 | 时间复杂度 | 特点 | 适用场景 | +|------|-----------|------|---------| +| **冒泡排序** | O(n²) | 简单但慢 | 教学、小数据量 | +| **选择排序** | O(n²) | 简单但慢 | 小数据量 | +| **插入排序** | O(n²) | 对近乎有序的数据快 | 小数据、近乎有序 | +| **快速排序** | O(n log n) | 实际最快 | 通用排序 | +| **归并排序** | O(n log n) | 稳定排序 | 需要稳定性的场景 | +| **堆排序** | O(n log n) | 原地排序 | 内存受限场景 | + +### 2.2 为什么快速排序"快"? + +::: tip 💡 快速排序的原理 +**核心思想**:分治法 + +1. 选一个"基准"元素 +2. 把比基准小的放左边,比基准大的放右边 +3. 对左右两部分递归排序 +4. 合并结果 + +**为什么快?** +- 每次划分后,基准元素就到了最终位置 +- 平均情况下,每次划分大约排除一半元素 +- 时间复杂度 O(n log n) + +**生活类比**:整理书架。先抽出一本书,把比它薄的放左边,比它厚的放右边。然后对左右两堆分别重复这个过程。 +::: + +--- + +## 3. 递归:自己调用自己 + +### 3.1 递归的本质 + +::: tip 💡 什么是递归? +**递归**是函数调用自身的编程技巧。 + +**两个关键要素**: +1. **基本情况**:什么时候停止递归? +2. **递归步骤**:如何把问题分解成更小的子问题? + +**经典例子:阶乘** +```js +function factorial(n) { + if (n <= 1) return 1 // 基本情况 + return n * factorial(n - 1) // 递归步骤 +} +``` + +**生活类比**:俄罗斯套娃。打开一个娃娃,里面是更小的娃娃,直到最小的那个打不开为止。 +::: + +### 3.2 递归 vs 迭代 + +| 特性 | 递归 | 迭代(循环) | +|------|------|-------------| +| **代码简洁度** | 通常更简洁 | 可能更复杂 | +| **内存消耗** | 较高(调用栈) | 较低 | +| **性能** | 稍慢(函数调用开销) | 更快 | +| **适用场景** | 树遍历、分治算法 | 简单重复任务 | + +::: warning ⚠️ 递归的陷阱 +**栈溢出**:递归层次太深,调用栈空间耗尽。 + +**解决方法**: +- 改用迭代 +- 使用尾递归优化(某些语言支持) +- 限制递归深度 +::: + +--- + +## 4. 贪心算法:每步选最优 + +### 4.1 贪心的思想 + +::: tip 💡 什么是贪心算法? +**贪心算法**在每一步都选择当前看起来最优的选择,希望最终得到全局最优解。 + +**适用条件**: +1. **贪心选择性质**:局部最优能导致全局最优 +2. **最优子结构**:问题的最优解包含子问题的最优解 + +**经典例子:硬币找零** +- 目标:用最少的硬币凑出指定金额 +- 贪心策略:每次选最大的硬币 +- 结果:67 元 = 50 + 10 + 5 + 1 + 1(5 枚) + +**生活类比**:登山时,每次都选最陡的路往上走。虽然不一定能到最高峰,但通常能到不错的位置。 +::: + +### 4.2 贪心的局限性 + +::: warning ⚠️ 贪心不一定得到最优解 +**反例:硬币找零** + +如果硬币面值是 [1, 3, 4],要凑 6 元: +- 贪心:4 + 1 + 1 = 3 枚 +- 最优:3 + 3 = 2 枚 + +贪心算法在这里失败了! + +**教训**:贪心算法简单高效,但不总是能得到最优解。使用前要证明问题满足贪心条件。 +::: + +--- + +## 5. 算法设计范式 + +| 范式 | 思想 | 典型算法 | 适用问题 | +|------|------|---------|---------| +| **分治** | 把问题分解成小问题 | 快速排序、归并排序 | 可分解的问题 | +| **贪心** | 每步选最优 | 最小生成树、霍夫曼编码 | 有贪心性质的问题 | +| **动态规划** | 记录子问题的解 | 背包问题、最短路径 | 有重叠子问题 | +| **回溯** | 试错,走不通就回退 | 八皇后、全排列 | 搜索问题 | + +--- + +## 6. 总结:算法是解决问题的艺术 + +让我们用一个比喻总结各种算法思想: + +| 思想 | 比喻 | 核心要点 | +|------|------|---------| +| **二分查找** | 猜数字 | 每次排除一半 | +| **排序** | 整理书架 | 建立秩序 | +| **递归** | 俄罗斯套娃 | 化大为小 | +| **贪心** | 登山选路 | 局部最优 | + +::: tip 💡 核心启示 +**算法的本质是"效率"和"正确性"的平衡。** + +- 好的算法能让程序效率提升几个数量级 +- 但过度优化可能引入复杂性 +- 先保证正确,再追求效率 + +理解算法思维,比记住具体算法更重要: +- 分治:把大问题分解成小问题 +- 贪心:每步选最优 +- 动态规划:记录子问题的解 +- 回溯:试错,走不通就回退 +::: + +--- + +## 延伸阅读 + +- **算法导论**:系统学习算法的经典教材 +- **LeetCode**:通过刷题提升算法能力 +- **算法可视化**:直观理解算法执行过程 +- **竞赛算法**:学习更高级的算法技巧 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 e610306..dc7518a 100644 --- a/docs/zh-cn/appendix/1-computer-fundamentals/computer-networks.md +++ b/docs/zh-cn/appendix/1-computer-fundamentals/computer-networks.md @@ -9,7 +9,7 @@ 现代计算机网络就像一个**快递公司**,采用五层分层模型,每层负责不同的工作: - + ::: tip 💡 为什么需要分层? 想象一个没有分工的快递公司: @@ -309,7 +309,7 @@ IP: 192.168.1.10 - `/24` 表示前 24 位是网络位 - 剩余 8 位是主机位(2^8 - 2 = 254 个可用 IP) - + ### 3.3 路由器:GPS 导航 @@ -431,7 +431,7 @@ PING google.com (142.250.185.238): 56 data bytes ### 4.2 TCP vs UDP:挂号信 vs 平信 - + **选择建议**: diff --git a/docs/zh-cn/appendix/1-computer-fundamentals/data-encoding-storage.md b/docs/zh-cn/appendix/1-computer-fundamentals/data-encoding-storage.md index bc245e1..d13c289 100644 --- a/docs/zh-cn/appendix/1-computer-fundamentals/data-encoding-storage.md +++ b/docs/zh-cn/appendix/1-computer-fundamentals/data-encoding-storage.md @@ -1,3 +1,244 @@ # 数据的编码、存储与传输 -> 待实现 +::: tip 🎯 核心问题 +**计算机如何表示和存储各种数据?** 文字、图片、视频、声音...这些在现实世界中形态各异的信息,是如何变成 0 和 1 的?又是如何存储和传输的?本章带你理解数据的编码、存储和传输原理。 +::: + +--- + +## 0. 全景图:数据的生命周期 + +想象你要寄一封信给朋友: + +1. **编码**:把想法变成文字(信息编码) +2. **存储**:写在纸上(数据存储) +3. **传输**:通过邮局寄出(数据传输) + +计算机处理数据也是类似的过程: + +| 阶段 | 做什么 | 核心问题 | 类比 | +|------|--------|---------|------| +| **编码** | 把信息变成 0 和 1 | 如何用二进制表示各种数据? | 把想法变成文字 | +| **存储** | 把数据保存起来 | 数据存在哪里?怎么组织? | 写在纸上 | +| **传输** | 把数据送到别处 | 如何可靠、高效地传输? | 邮局寄信 | + +::: tip 📊 逐行解读这张表 +**编码**:计算机只认识 0 和 1,所以所有数据都要"翻译"成二进制。文字用 ASCII 或 Unicode 编码,数字用二进制表示,图片用像素值,声音用采样值。 + +**存储**:编码后的数据需要保存起来。存储介质从快到慢有:寄存器 → 缓存 → 内存 → SSD → 硬盘 → 云存储。越快的存储越贵、容量越小。 + +**传输**:数据需要在不同设备间流动。传输方式有串行(一位一位传)和并行(多位同时传)。现代高速接口(USB、PCIe)多采用串行方式。 +::: + +--- + +## 1. 数据编码:用 0 和 1 表示一切 + +### 1.1 文本编码 + + + +::: tip 💡 字符编码的演变 +**ASCII(1963年)**: +- 用 7 位二进制表示 128 个字符 +- 包括英文字母、数字、常用符号 +- 问题:只能表示英语,无法表示中文等 + +**Unicode(1991年)**: +- 统一编码标准,覆盖世界上所有文字 +- 目前已收录超过 14 万个字符 +- 常用编码方式:UTF-8(变长编码,1-4 字节) + +**UTF-8 的巧妙设计**: +- ASCII 字符(0-127)只用 1 字节,完全兼容 +- 常用汉字用 3 字节 +- 根据"前导位"判断一个字符占几个字节 +::: + +**常见字符编码对比:** + +| 编码 | 字节数 | 支持字符 | 特点 | +|------|--------|---------|------| +| **ASCII** | 1 字节 | 128 个 | 仅英语,兼容性好 | +| **UTF-8** | 1-4 字节 | 所有文字 | 变长编码,主流标准 | +| **UTF-16** | 2-4 字节 | 所有文字 | 定长为主,Windows 常用 | +| **GBK** | 1-2 字节 | 中英文 | 中文专用,不推荐新项目使用 | + +### 1.2 数字编码 + +::: tip 💡 整数如何用二进制表示? +**无符号整数**:直接用二进制表示 +- 8 位可以表示 0-255 +- 32 位可以表示 0 到约 42 亿 + +**有符号整数**:用补码表示 +- 最高位是符号位(0 正 1 负) +- 正数:直接用二进制 +- 负数:正数的二进制取反加 1 + +**为什么用补码?** +- 加法减法统一处理 +- 0 的表示唯一 +- 硬件实现简单 +::: + +**浮点数表示(IEEE 754 标准):** + +| 部分 | 作用 | 位数(32位浮点) | +|------|------|-----------------| +| **符号位** | 正负 | 1 位 | +| **指数位** | 决定大小范围 | 8 位 | +| **尾数位** | 决定精度 | 23 位 | + +### 1.3 多媒体编码 + +**图像编码**: +- **位图**:每个像素用 RGB 值表示(红绿蓝各 8 位) +- **压缩**:JPEG(有损)、PNG(无损) +- **矢量图**:用数学公式描述形状(SVG) + +**音频编码**: +- **采样**:把连续声波变成离散点 +- **量化**:把采样值变成数字 +- **压缩**:MP3(有损)、FLAC(无损) + +**视频编码**: +- 视频是一帧帧图像 +- 关键技术:帧间压缩(只记录变化部分) +- 常见格式:H.264、H.265、VP9 + +--- + +## 2. 数据存储:速度与容量的权衡 + +### 2.1 存储层次结构 + + + +### 2.2 存储器类型 + +| 类型 | 原理 | 特点 | 应用 | +|------|------|------|------| +| **SRAM** | 触发器 | 极快,但昂贵 | CPU 缓存 | +| **DRAM** | 电容充放电 | 较快,需刷新 | 内存 | +| **Flash** | 浮栅晶体管 | 断电不丢失,有写入寿命 | SSD、U 盘 | +| **HDD** | 磁盘磁性记录 | 容量大,有机械延迟 | 机械硬盘 | + +### 2.3 存储的关键指标 + +::: tip 💡 如何评估存储性能? +**访问时间**:从发出请求到获得数据的时间 +- 内存:约 100 纳秒 +- SSD:约 100 微秒 +- HDD:约 10 毫秒 + +**吞吐量**:单位时间能传输的数据量 +- 内存:几十 GB/s +- SSD:几 GB/s +- HDD:100-200 MB/s + +**IOPS**:每秒能进行的读写操作次数 +- SSD:几万到几十万 +- HDD:几百 +::: + +--- + +## 3. 数据传输:从串行到并行 + +### 3.1 传输方式 + + + +### 3.2 常见接口标准 + +| 接口 | 类型 | 速度 | 应用 | +|------|------|------|------| +| **USB 3.0** | 串行 | 5 Gbps | 外设连接 | +| **USB 4** | 串行 | 40 Gbps | 高速外设 | +| **SATA III** | 串行 | 6 Gbps | 硬盘接口 | +| **PCIe 4.0 x16** | 串行(多通道) | 32 GB/s | 显卡、SSD | +| **以太网** | 串行 | 1-100 Gbps | 网络传输 | + +### 3.3 传输的可靠性 + +::: tip 💡 如何保证传输不出错? +**校验机制**: +- **奇偶校验**:简单的错误检测 +- **CRC 校验**:更强的错误检测能力 +- **校验和**:快速检测数据完整性 + +**纠错机制**: +- **重传**:发现错误就重新发送 +- **前向纠错**:发送冗余信息,接收方能自动纠正 + +**流量控制**: +- 防止发送方发太快,接收方来不及处理 +- 类似"确认收到再发下一个" +::: + +--- + +## 4. 编码、存储、传输的协作 + +让我们看一个完整的例子:**保存一张照片到云端** + +``` +1. 编码阶段 + - 相机传感器捕捉光线 → 模拟信号 + - ADC 转换 → 数字信号(RAW 格式) + - JPEG 编码 → 压缩后的二进制数据 + +2. 存储阶段 + - 写入手机内存(RAM)→ 临时存储 + - 写入手机闪存(Flash)→ 持久存储 + +3. 传输阶段 + - 读取闪存数据 → 内存 + - 通过 Wi-Fi/4G 发送 → 网络传输 + - 云端接收 → 写入云端存储 +``` + +::: tip 💡 理解这个流程 +每一步都涉及编码、存储、传输: + +1. **编码**:把图像变成二进制数据 +2. **存储**:在本地保存 +3. **传输**:通过网络发送到云端 + +这三个环节紧密配合,才能完成"保存照片到云端"这个看似简单的操作。 +::: + +--- + +## 5. 总结:数据的三重奏 + +让我们用一个比喻总结编码、存储、传输: + +| 概念 | 比喻 | 核心任务 | +|------|------|---------| +| **编码** | 翻译 | 把信息变成 0 和 1 | +| **存储** | 仓库 | 把数据保存起来 | +| **传输** | 快递 | 把数据送到目的地 | + +::: tip 💡 核心启示 +**数据处理的本质是"转换、保存、移动"**。 + +- 编码解决"如何表示"的问题 +- 存储解决"如何保存"的问题 +- 传输解决"如何传递"的问题 + +理解了这三点,你就会明白: +- 为什么不同文件格式要选择不同的编码方式 +- 为什么需要不同层次的存储介质 +- 为什么传输速度和可靠性需要平衡 +::: + +--- + +## 延伸阅读 + +- **字符编码详解**:深入学习 ASCII、Unicode、UTF-8 的设计原理 +- **存储技术发展**:了解从磁带到 SSD 的技术演进 +- **网络传输协议**:学习 TCP/IP 如何保证可靠传输 +- **数据压缩算法**:了解 ZIP、JPEG、MP3 等压缩原理 diff --git a/docs/zh-cn/appendix/1-computer-fundamentals/data-structures.md b/docs/zh-cn/appendix/1-computer-fundamentals/data-structures.md index 664382b..608d03b 100644 --- a/docs/zh-cn/appendix/1-computer-fundamentals/data-structures.md +++ b/docs/zh-cn/appendix/1-computer-fundamentals/data-structures.md @@ -1,3 +1,214 @@ # 数据结构 -> 待实现 +::: tip 🎯 核心问题 +**如何高效地组织和存储数据?** 你可能遇到过这样的困惑:为什么有些程序处理几万条数据很快,有些处理几百条就卡住了?答案往往在于数据结构的选择。本章带你理解常见数据结构的特点和适用场景。 +::: + +--- + +## 0. 全景图:数据结构是什么? + +想象你要整理一堆书: + +- **堆在地上**:找书要一本本翻(链表) +- **按编号放书架**:直接去对应位置拿(数组) +- **按类别分柜子**:先找柜子再找书(哈希表) +- **按书名排序**:二分查找,每次排除一半(树) + +不同的整理方式,找书的效率天差地别。**数据结构就是数据的"整理方式"**。 + + + +**常见数据结构分类:** + +| 类型 | 特点 | 典型代表 | 适用场景 | +|------|------|---------|---------| +| **线性结构** | 数据排成一排 | 数组、链表、栈、队列 | 顺序处理、历史记录 | +| **哈希结构** | 键值对映射 | 哈希表 | 快速查找、缓存 | +| **树形结构** | 层次关系 | 二叉树、B树 | 排序、搜索、文件系统 | +| **图结构** | 网状关系 | 有向图、无向图 | 社交网络、路径规划 | + +::: tip 📊 逐行解读这张表 +**线性结构**:最简单的数据组织方式,数据一个接一个排列。数组适合随机访问,链表适合频繁插入删除。 + +**哈希结构**:用"键"直接找到"值",查找速度最快。但需要处理"冲突"问题(两个键映射到同一位置)。 + +**树形结构**:有层次关系的数据。二叉搜索树适合排序和搜索,B树适合磁盘存储(数据库索引)。 + +**图结构**:最复杂的结构,表示任意的关系网络。社交网络、地图导航都用图来建模。 +::: + +--- + +## 1. 线性结构:最基础的组织方式 + +### 1.1 数组:连续存储 + +::: tip 💡 数组的特点 +**数组**是一块连续的内存空间,每个元素大小相同。 + +**优点**: +- 随机访问快:`arr[100]` 直接计算地址,O(1) +- 缓存友好:连续存储,CPU 缓存命中率高 + +**缺点**: +- 插入删除慢:需要移动后面所有元素,O(n) +- 大小固定:需要预先分配空间 + +**生活类比**:一排编号的储物柜,每个柜子大小相同。找第 10 号柜子直接去,但要在中间插入一个柜子,后面的都要往后挪。 +::: + +### 1.2 链表:节点相连 + +::: tip 💡 链表的特点 +**链表**由一系列节点组成,每个节点包含数据和指向下一个节点的指针。 + +**优点**: +- 插入删除快:只需修改指针,O(1) +- 大小灵活:可以动态增长 + +**缺点**: +- 访问慢:要从头开始遍历,O(n) +- 额外空间:每个节点需要存储指针 + +**生活类比**:寻宝游戏,每个线索指向下一个地点。要找第 10 个线索,必须从第 1 个开始一步步找。 +::: + +### 1.3 栈和队列:受限的线性结构 + +| 结构 | 规则 | 操作 | 类比 | 应用 | +|------|------|------|------|------| +| **栈** | 后进先出 (LIFO) | push/pop | 一摞盘子 | 函数调用、撤销操作 | +| **队列** | 先进先出 (FIFO) | enqueue/dequeue | 排队买票 | 任务调度、消息队列 | + +::: tip 💡 为什么要有"受限"的结构? +栈和队列看起来比数组、链表功能少,但正是这种"限制"让它们有明确的用途: + +- **栈**:函数调用时,最后调用的函数最先返回 +- **队列**:任务调度时,先来的任务先处理 + +限制带来简洁,简洁带来高效。 +::: + +--- + +## 2. 哈希表:最快的查找 + +### 2.1 哈希表原理 + +::: tip 💡 哈希表如何工作? +**哈希表**通过"哈希函数"把键映射到数组索引。 + +**工作流程**: +1. 输入键(如 "apple") +2. 哈希函数计算:`hash("apple") = 3` +3. 直接去数组索引 3 的位置找 + +**冲突处理**: +- 两个不同的键可能映射到同一索引 +- 解决方法:链地址法(同一位置用链表存储多个值) + +**生活类比**:图书馆按书名首字母分柜子。"Apple" 开头的书都放 A 柜,"Banana" 开头的放 B 柜。找书时先确定柜子,再在柜子里找。 +::: + +### 2.2 哈希表的时间复杂度 + +| 操作 | 平均情况 | 最坏情况 | +|------|---------|---------| +| **查找** | O(1) | O(n) | +| **插入** | O(1) | O(n) | +| **删除** | O(1) | O(n) | + +::: warning ⚠️ 什么时候会退化? +当所有键都映射到同一个索引时,哈希表退化为链表,所有操作变成 O(n)。 + +**避免方法**: +- 选择好的哈希函数 +- 动态扩容(负载因子超过阈值时扩容) +::: + +--- + +## 3. 树:层次结构 + +### 3.1 二叉搜索树 + +::: tip 💡 二叉搜索树的规则 +**二叉搜索树**是一种特殊的二叉树: +- 左子树的所有值 < 根节点 +- 右子树的所有值 > 根节点 + +**查找过程**: +1. 从根节点开始 +2. 如果目标值 < 当前值,往左走 +3. 如果目标值 > 当前值,往右走 +4. 每次比较排除一半节点 + +**时间复杂度**:O(log n),但最坏情况(变成链表)是 O(n) +::: + +### 3.2 平衡树 + +为了防止二叉搜索树退化,引入了**平衡树**: + +| 类型 | 平衡方式 | 特点 | +|------|---------|------| +| **AVL 树** | 严格平衡(高度差 ≤ 1) | 查找最快,插入删除稍慢 | +| **红黑树** | 近似平衡 | 综合性能好,应用最广 | +| **B 树** | 多路平衡 | 适合磁盘存储,数据库索引 | + +--- + +## 4. 如何选择数据结构? + +| 需求 | 推荐结构 | 原因 | +|------|---------|------| +| **快速随机访问** | 数组 | O(1) 索引访问 | +| **频繁插入删除** | 链表 | O(1) 插入删除 | +| **快速查找** | 哈希表 | O(1) 平均查找 | +| **有序数据** | 平衡树 | O(log n) 查找,保持有序 | +| **最近使用** | 栈 | LIFO 特性 | +| **任务排队** | 队列 | FIFO 特性 | + +::: tip 💡 选择数据结构的心法 +**没有最好的数据结构,只有最合适的数据结构。** + +选择时要考虑: +1. **主要操作是什么?** 查找?插入?删除? +2. **数据量多大?** 小数据量差别不大,大数据量要慎重 +3. **数据有序吗?** 有序数据可以用二分查找 +4. **内存限制?** 某些结构需要额外空间 +::: + +--- + +## 5. 总结:数据结构是程序的基础 + +让我们用一个比喻总结各种数据结构: + +| 结构 | 比喻 | 核心特点 | +|------|------|---------| +| **数组** | 编号储物柜 | 访问快,插入慢 | +| **链表** | 寻宝线索 | 插入快,访问慢 | +| **栈** | 一摞盘子 | 后进先出 | +| **队列** | 排队队伍 | 先进先出 | +| **哈希表** | 分类柜子 | 查找最快 | +| **树** | 家族族谱 | 层次结构 | + +::: tip 💡 核心启示 +**数据结构决定了程序的效率上限。** + +- 选对数据结构,问题迎刃而解 +- 选错数据结构,再好的算法也无济于事 + +理解数据结构,就是理解"如何高效地组织数据"。这是每个程序员的基本功。 +::: + +--- + +## 延伸阅读 + +- **数据结构实现**:自己动手实现各种数据结构,加深理解 +- **高级数据结构**:学习跳表、布隆过滤器、并查集等 +- **数据库索引**:了解 B+ 树在数据库中的应用 +- **缓存设计**:学习 LRU 缓存如何结合哈希表和链表 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 ef3449e..ca60a6c 100644 --- a/docs/zh-cn/appendix/1-computer-fundamentals/operating-systems.md +++ b/docs/zh-cn/appendix/1-computer-fundamentals/operating-systems.md @@ -1,3 +1,255 @@ # 操作系统(进程 / 内存 / 文件系统) -> 待实现 +::: tip 🎯 核心问题 +**操作系统是做什么的?** 你可能每天都在用 Windows、macOS 或 Linux,但你知道它到底在忙什么吗?为什么需要它?没有它电脑还能用吗?本章带你理解操作系统的三大核心职责:管理进程、管理内存、管理文件。 +::: + +--- + +## 0. 全景图:操作系统的角色 + +想象你开了一家餐厅。你需要: +- **安排员工工作**:谁做菜、谁端盘子、谁收银(进程管理) +- **管理厨房空间**:冰箱放什么、操作台怎么分配(内存管理) +- **整理仓库物资**:食材怎么存放、怎么找(文件系统) + +操作系统就是电脑的"餐厅经理",它负责协调所有资源,让程序能顺利运行。 + +**操作系统的三大核心职责:** + +| 职责 | 管理对象 | 核心问题 | 类比 | +|------|---------|---------|------| +| **进程管理** | CPU 时间 | 谁先用 CPU?用多久? | 员工排班 | +| **内存管理** | 内存空间 | 程序放哪里?怎么不冲突? | 厨房空间分配 | +| **文件系统** | 磁盘数据 | 数据怎么存?怎么找? | 仓库物资管理 | + +::: tip 📊 逐行解读这张表 +**进程管理**:CPU 是最宝贵的资源,操作系统要决定哪个程序先用、用多久。就像餐厅经理安排员工轮班,不能让所有人同时挤在厨房里。 + +**内存管理**:内存是程序的"工作台",操作系统要给每个程序分配空间,还要保证它们互不干扰。就像厨房空间有限,要合理分配给不同的厨师。 + +**文件系统**:磁盘是"仓库",操作系统要把数据有序地存进去,需要时能快速找到。就像仓库管理员整理货架,按类别、编号存放。 +::: + +--- + +## 1. 进程管理:程序的"分身术" + +### 1.1 什么是进程? + + + +::: tip 💡 程序 vs 进程 +这是初学者最容易混淆的概念: + +| 概念 | 定义 | 类比 | 特点 | +|------|------|------|------| +| **程序** | 静态的代码文件 | 菜谱 | 存在磁盘上,不会动 | +| **进程** | 程序的运行实例 | 正在按菜谱做菜 | 在内存中运行,会变化 | + +**关键区别**: +- 一个程序可以启动多个进程(比如打开多个浏览器窗口) +- 每个进程有独立的内存空间,互不干扰 +- 进程有生命周期:创建、运行、等待、终止 +::: + +### 1.2 进程的状态 + +进程在运行过程中会在不同状态之间切换: + +| 状态 | 含义 | 什么时候进入 | 类比 | +|------|------|-------------|------| +| **就绪 (Ready)** | 准备好运行,等 CPU | 进程刚创建,或从等待恢复 | 员工在休息室等排班 | +| **运行 (Running)** | 正在 CPU 上执行 | 被调度器选中 | 员工正在工作 | +| **等待 (Waiting)** | 等待 I/O 或其他资源 | 需要读磁盘、等网络 | 员工在等食材送达 | +| **终止 (Terminated)** | 运行结束 | 程序退出或出错 | 员工下班 | + +### 1.3 进程调度:谁先用 CPU? + +::: tip 💡 为什么需要调度? +CPU 核心数有限,但进程可能有几十上百个。操作系统需要决定: +- 哪个进程先运行? +- 运行多久? +- 什么时候切换? + +这就是**进程调度**要解决的问题。 +::: + +**常见调度算法:** + +| 算法 | 思路 | 优点 | 缺点 | +|------|------|------|------| +| **先来先服务 (FCFS)** | 谁先到谁先运行 | 简单公平 | 短任务可能等很久 | +| **短作业优先 (SJF)** | 短任务优先 | 平均等待时间最短 | 需要预知任务长度 | +| **时间片轮转 (RR)** | 每人运行一小段时间 | 公平,响应快 | 切换开销大 | +| **优先级调度** | 重要任务优先 | 重要任务响应快 | 可能导致低优先级任务饿死 | + +--- + +## 2. 内存管理:程序的"工作台" + +### 2.1 为什么需要内存管理? + + + +::: tip 💡 如果没有内存管理会怎样? +想象一个没有管理的厨房: + +- **冲突**:两个厨师同时用同一个灶台,菜都糊了 +- **浪费**:有人占了整个厨房,其他人没地方做饭 +- **安全问题**:有人偷吃了别人的食材 + +操作系统通过**内存管理**解决这些问题: +- 给每个进程分配独立的内存空间 +- 防止进程互相干扰(内存保护) +- 高效利用有限的内存资源 +::: + +### 2.2 虚拟内存:让每个进程都"以为"自己独占内存 + +::: tip 💡 什么是虚拟内存? +**虚拟内存**是操作系统的一个"魔术": + +- 每个进程都以为自己有 4GB(或更多)的内存空间 +- 实际上物理内存可能只有 8GB、16GB +- 操作系统通过"映射"把虚拟地址转换成物理地址 + +**生活类比**:想象一个酒店: +- 每个客人都以为自己独占整个酒店(虚拟空间) +- 实际上酒店只有 100 间房(物理内存) +- 前台(操作系统)负责分配房间、记录谁住哪里 +::: + +**虚拟内存的好处:** + +| 好处 | 说明 | 为什么重要 | +|------|------|-----------| +| **隔离保护** | 进程间内存互不干扰 | 一个崩溃不影响其他 | +| **内存扩展** | 用磁盘当内存用 | 可以运行比物理内存大的程序 | +| **简化编程** | 不用关心物理地址 | 程序员写代码更简单 | + +### 2.3 内存分配策略 + +当进程需要内存时,操作系统如何分配? + +| 策略 | 思路 | 特点 | +|------|------|------| +| **首次适应** | 找到第一个够大的空闲块 | 速度快 | +| **最佳适应** | 找最小的够大的空闲块 | 内存利用率高 | +| **最坏适应** | 找最大的空闲块 | 减少小碎片 | + +--- + +## 3. 文件系统:数据的"档案柜" + +### 3.1 什么是文件系统? + + + +::: 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. **内存管理**:负责"给程序分配空间" + +这三者紧密协作,才能完成一个看似简单的"打开文件"操作。 +::: + +--- + +## 5. 总结:操作系统是"大管家" + +让我们用一个比喻总结操作系统的三大职责: + +| 职责 | 比喻 | 核心任务 | +|------|------|---------| +| **进程管理** | 餐厅排班员 | 安排谁先工作、工作多久 | +| **内存管理** | 厨房管理员 | 分配工作台、防止冲突 | +| **文件系统** | 仓库管理员 | 整理物资、快速查找 | + +::: tip 💡 核心启示 +**操作系统的本质是"资源管理"**。 + +- CPU 时间是资源 → 进程管理 +- 内存空间是资源 → 内存管理 +- 磁盘空间是资源 → 文件系统 + +理解了这一点,你就会明白: +- 为什么电脑会变慢(进程太多、内存不足) +- 为什么需要重启(清理资源、释放内存) +- 为什么文件要整理(提高查找效率) +::: + +--- + +## 延伸阅读 + +- **操作系统原理**:深入学习进程调度、内存分页、文件系统实现 +- **Linux 系统编程**:学习如何与操作系统交互(系统调用) +- **并发编程**:学习多进程、多线程编程 +- **系统监控**:学习使用 top、htop、vmstat 等工具监控系统状态 diff --git a/docs/zh-cn/appendix/1-computer-fundamentals/programming-languages.md b/docs/zh-cn/appendix/1-computer-fundamentals/programming-languages.md index 27c6513..72530e5 100644 --- a/docs/zh-cn/appendix/1-computer-fundamentals/programming-languages.md +++ b/docs/zh-cn/appendix/1-computer-fundamentals/programming-languages.md @@ -1,3 +1,398 @@ # 编程语言图谱 -> 待实现 +::: tip 🎯 核心问题 +**为什么有这么多编程语言?它们之间有什么关系?** 从机器语言到现代高级语言,每种语言都有其设计哲学和适用场景。本章带你理解编程语言的演化历程和核心概念。 +::: + +--- + +## 0. 想象你要和外国人交流: + +- **直接用肢体语言**:最原始,但效率极低(机器语言) +- **学习对方的语言**:需要翻译,但表达丰富(高级语言) +- **使用世界语**:设计完美,但没人用(某些学术语言) +- **使用翻译软件**:自动转换,但可能不准确(编译器/解释器) + +**编程语言就是人类与计算机沟通的桥梁**,不同的语言有不同的设计哲学。 + + + +--- + +## 1. 编程语言的演化 + +### 1.1 第一代:机器语言(1940s) + +::: tip 💡 机器语言是什么? +直接用 0 和 1 编写程序,计算机可以直接执行。 + +**示例**:让计算机计算 1 + 2 +``` +10110000 00000001 ; 将 1 放入寄存器 +10110001 00000010 ; 将 2 放入另一个寄存器 +10100010 ; 执行加法 +``` + +**问题**: +- 人类难以理解和记忆 +- 容易出错,一个 0 写成 1 就全错了 +- 不同 CPU 有不同的机器语言 +::: + +### 1.2 第二代:汇编语言(1950s) + +用**助记符**代替 0 和 1: + +```asm +MOV AX, 1 ; 将 1 放入 AX 寄存器 +MOV BX, 2 ; 将 2 放入 BX 寄存器 +ADD AX, BX ; 将 BX 加到 AX +``` + +::: tip 💡 汇编语言 vs 机器语言 +| 特性 | 机器语言 | 汇编语言 | +|------|---------|---------| +| **可读性** | 极差 | 较好 | +| **执行效率** | 最高 | 最高(汇编器直接转换) | +| **移植性** | 无 | 无(依赖 CPU 架构) | +| **使用场景** | 几乎不用 | 嵌入式、操作系统内核 | +::: + +### 1.3 第三代:高级语言(1950s - 至今) + +**用接近自然语言的方式编程**: + +```c +int sum = 1 + 2; // C 语言 +``` + +**里程碑语言**: + +| 年代 | 语言 | 意义 | +|------|------|------| +| **1957** | Fortran | 第一个高级语言,科学计算 | +| **1958** | Lisp | 函数式编程鼻祖 | +| **1959** | COBOL | 商业数据处理 | +| **1972** | C | 系统编程,影响深远 | +| **1983** | C++ | 面向对象 + C 的效率 | +| **1991** | Python | 简洁优雅,AI 时代主角 | +| **1995** | Java | 跨平台,企业应用 | +| **1995** | JavaScript | Web 开发,无处不在 | +| **2009** | Go | 并发友好,云原生 | +| **2010** | Rust | 内存安全,系统编程新选择 | + +### 1.4 第四代:领域特定语言(DSL) + +为特定领域设计的语言: + +| 语言 | 领域 | 示例 | +|------|------|------| +| **SQL** | 数据库查询 | `SELECT * FROM users` | +| **HTML** | 网页结构 | `
Hello
` | +| **CSS** | 样式定义 | `color: red;` | +| **Regex** | 文本匹配 | `\d{3}-\d{4}` | +| **MATLAB** | 数学计算 | `A = [1 2; 3 4]` | + +--- + +## 2. 编程范式:思考问题的方式 + +::: tip 💡 什么是编程范式? +编程范式是**编程的思维方式**,决定了你如何组织代码和解决问题。 + +就像写作有不同的文体(诗歌、小说、论文),编程也有不同的"文体"。 +::: + +### 2.1 命令式编程(Imperative) + +**核心思想**:告诉计算机"怎么做" + +```c +// 计算数组总和 +int sum = 0; +for (int i = 0; i < n; i++) { + sum += arr[i]; +} +``` + +**特点**: +- 关注**过程**和**步骤** +- 通过**语句**改变程序状态 +- 最接近计算机实际执行方式 + +**代表语言**:C, Fortran, BASIC + +### 2.2 面向对象编程(OOP) + +**核心思想**:把数据和操作封装在"对象"中 + +```python +class Dog: + def __init__(self, name): + self.name = name + + def bark(self): + print(f"{self.name} says woof!") + +dog = Dog("Buddy") +dog.bark() # Buddy says woof! +``` + +**四大特性**: + +| 特性 | 含义 | 生活类比 | +|------|------|---------| +| **封装** | 隐藏内部细节 | 汽车方向盘,不需要知道引擎原理 | +| **继承** | 子类继承父类 | 儿子继承父亲的基因 | +| **多态** | 同一接口不同实现 | 不同动物发出不同叫声 | +| **抽象** | 提取共同特征 | "动物"是对猫、狗的抽象 | + +**代表语言**:Java, C++, Python, Ruby + +### 2.3 函数式编程(Functional) + +**核心思想**:把计算视为函数求值,避免状态变化 + +```haskell +-- 计算数组总和 +sum arr = foldl (+) 0 arr + +-- 或者更简洁 +sum = foldl (+) 0 +``` + +**核心原则**: + +| 原则 | 含义 | 好处 | +|------|------|------| +| **纯函数** | 相同输入永远产生相同输出 | 易测试、易推理 | +| **不可变数据** | 数据一旦创建就不变 | 无副作用、线程安全 | +| **高阶函数** | 函数可以作为参数和返回值 | 代码复用、灵活组合 | +| **无副作用** | 函数不修改外部状态 | 可预测、易调试 | + +**代表语言**:Haskell, Lisp, Erlang, F# + +### 2.4 声明式编程(Declarative) + +**核心思想**:告诉计算机"做什么",而不是"怎么做" + +```sql +-- 查询所有活跃用户 +SELECT name, email +FROM users +WHERE active = true +ORDER BY created_at DESC +``` + +**对比命令式**: + +| 命令式 | 声明式 | +|--------|--------| +| "从第一行开始遍历..." | "给我所有活跃用户" | +| "检查每个用户是否活跃..." | "按创建时间排序" | +| "如果活跃就加入结果..." | 数据库自己决定怎么执行 | +| "最后排序返回..." | | + +**代表语言**:SQL, Prolog, HTML + +--- + +## 3. 类型系统:数据的分类规则 + +::: tip 💡 什么是类型系统? +类型系统是编程语言的**交通规则**,规定数据如何分类和操作。 + +就像现实世界: +- **整数** = 整数类型(1, 2, 3...) +- **文字** = 字符串类型("hello") +- **是/否** = 布尔类型(true/false) +::: + +### 3.1 静态类型 vs 动态类型 + +| 特性 | 静态类型 | 动态类型 | +|------|---------|---------| +| **类型检查时机** | 编译时 | 运行时 | +| **代码示例** | `int x = 1;` | `x = 1` | +| **错误发现** | 编译期就发现 | 运行时才发现 | +| **灵活性** | 较低 | 较高 | +| **性能** | 较高(编译优化) | 较低(运行时检查) | +| **代表语言** | Java, C++, Rust, TypeScript | Python, JavaScript, Ruby | + +**静态类型示例(Java)**: + +```java +String name = "Alice"; +name = 123; // 编译错误!类型不匹配 +``` + +**动态类型示例(Python)**: + +```python +name = "Alice" +name = 123 # 没问题,运行时类型改变 +``` + +### 3.2 强类型 vs 弱类型 + +| 特性 | 强类型 | 弱类型 | +|------|--------|--------| +| **类型转换** | 不允许隐式转换 | 允许隐式转换 | +| **类型安全** | 高 | 低 | +| **代码示例** | `"1" + 1` 报错 | `"1" + 1 = "11"` | +| **代表语言** | Python, Java, Rust | JavaScript, PHP, C | + +**弱类型示例(JavaScript)**: + +```javascript +console.log("1" + 1) // "11" (字符串拼接) +console.log("1" - 1) // 0 (自动转数字) +console.log([] + []) // "" (空字符串) +console.log([] + {}) // "[object Object]" +``` + +**强类型示例(Python)**: + +```python +"1" + 1 # TypeError: can only concatenate str to str +``` + +### 3.3 类型推断 + +现代语言可以**自动推断**变量类型: + +```typescript +// TypeScript +let x = 1; // 推断为 number +let y = "hello"; // 推断为 string + +// Rust +let x = 1; // 推断为 i32 +let y = "hello"; // 推断为 &str +``` + +--- + +## 4. 编译型 vs 解释型 + +::: tip 💡 程序如何运行? +编程语言写的代码需要转换成机器能理解的指令,有两种主要方式: +::: + +### 4.1 编译型语言 + +**流程**:源代码 → 编译器 → 机器码 → 执行 + +``` +源代码 (main.c) + ↓ +编译器 (gcc) + ↓ +可执行文件 (main.exe) + ↓ +CPU 直接执行 +``` + +**特点**: + +| 优点 | 缺点 | +|------|------| +| 执行速度快 | 编译时间长 | +| 编译时发现错误 | 跨平台需要重新编译 | +| 不需要运行时环境 | 调试较困难 | + +**代表语言**:C, C++, Rust, Go + +### 4.2 解释型语言 + +**流程**:源代码 → 解释器 → 逐行执行 + +``` +源代码 (main.py) + ↓ +解释器 (python) + ↓ +逐行解释执行 +``` + +**特点**: + +| 优点 | 缺点 | +|------|------| +| 跨平台 | 执行速度慢 | +| 开发调试快 | 运行时才能发现错误 | +| 代码即运行 | 需要解释器环境 | + +**代表语言**:Python, JavaScript, Ruby, PHP + +### 4.3 混合型语言(JIT) + +**即时编译(Just-In-Time)**:先解释执行,热点代码编译成机器码 + +``` +源代码 + ↓ +字节码(中间代码) + ↓ +解释执行 + JIT 编译热点代码 + ↓ +执行 +``` + +**代表语言**:Java, JavaScript (V8), Python (PyPy) + +--- + +## 5. 如何选择编程语言? + +::: tip 💡 没有最好的语言,只有最适合的语言 +选择语言要考虑: +1. **问题领域**:Web 开发?系统编程?数据分析? +2. **团队熟悉度**:团队擅长什么? +3. **生态系统**:有没有现成的库? +4. **性能需求**:需要多高的性能? +5. **开发效率**:需要多快开发完成? +::: + +### 5.1 按应用场景选择 + +| 场景 | 推荐语言 | 原因 | +|------|---------|------| +| **Web 前端** | JavaScript, TypeScript | 浏览器原生支持 | +| **Web 后端** | Java, Go, Python, Node.js | 生态成熟,框架丰富 | +| **移动开发** | Swift (iOS), Kotlin (Android) | 官方推荐 | +| **数据分析** | Python, R | 库丰富,社区活跃 | +| **人工智能** | Python | TensorFlow, PyTorch | +| **系统编程** | C, C++, Rust | 性能高,控制精细 | +| **游戏开发** | C++, C#, Lua | 引擎支持 | +| **嵌入式** | C, Rust | 资源受限环境 | +| **云原生** | Go, Rust | 并发友好,部署简单 | + +### 5.2 学习路线建议 + +**初学者**: +1. Python(语法简单,应用广泛) +2. JavaScript(Web 开发必备) +3. 选择一门静态类型语言(Java 或 TypeScript) + +**进阶**: +1. 学习 C 理解底层 +2. 学习函数式编程思想(Haskell 或 F#) +3. 学习 Rust 理解内存安全 + +--- + +## 6. 总结 + +::: tip 📚 核心要点 +1. **编程语言演化**:从机器语言到高级语言,越来越接近人类思维 +2. **编程范式**:命令式、面向对象、函数式、声明式,各有优劣 +3. **类型系统**:静态/动态、强/弱类型,影响代码安全和灵活性 +4. **运行方式**:编译型快但需编译,解释型慢但灵活 +5. **选择语言**:没有银弹,根据场景选择合适的工具 +::: + +**下一步学习**: +- [类型系统与编译原理入门](./type-systems-compilers) - 深入理解类型系统和编译过程 +- [数据结构](./data-structures) - 理解数据的组织方式 +- [算法思维入门](./algorithm-thinking) - 学习解决问题的方法 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 05fad64..681be78 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 @@ -1,3 +1,259 @@ # 从晶体管到 CPU -> 待实现 +::: tip 🎯 核心问题 +**计算机是怎么"思考"的?** 你可能知道 CPU 是电脑的"大脑",但这个大脑到底是怎么工作的?它怎么从一堆金属和塑料变成能执行程序、处理数据的智能设备?本章带你从最底层的晶体管开始,一步步理解 CPU 的构造原理。 +::: + +--- + +## 0. 全景图:从沙子到智能 + + + +现代计算机的"思考"能力,归根结底来自于一个简单的东西:**开关**。 + +想象你有一个开关,可以控制灯的亮灭。现在,如果你有几十亿个这样的开关,并且能用它们组合出各种复杂的逻辑,会发生什么?这就是计算机的奥秘。 + +**从沙子到智能的层次结构:** + +| 层级 | 名称 | 数量级 | 作用 | 类比 | +|------|------|--------|------|------| +| **1** | 晶体管 | 数十亿 | 最基本的开关单元 | 一个开关 | +| **2** | 逻辑门 | 数亿 | 实现基本逻辑运算 | 开关组合 | +| **3** | 功能单元 | 数百 | 实现特定功能(加法、存储等) | 功能模块 | +| **4** | CPU 核心 | 1-128 | 完整的处理器 | 大脑 | + +::: tip 📊 逐行解读这张表 +**第1层(晶体管)**:这是最底层的"开关"。现代 CPU 使用的是 MOSFET(金属氧化物半导体场效应晶体管),它的特点是:给栅极加电压,源极和漏极之间就导通;不加电压,就断开。这就是"用电控制电"的开关。 + +**第2层(逻辑门)**:把晶体管组合起来,就能实现"与"、"或"、"非"等逻辑运算。比如 AND 门:两个输入都为 1 时输出才为 1。这就像两个串联的开关,必须都按下灯才会亮。 + +**第3层(功能单元)**:把逻辑门组合起来,就能实现更复杂的功能。加法器能做加法,寄存器能存储数据,多路选择器能选择数据。这些是 CPU 的"器官"。 + +**第4层(CPU 核心)**:把功能单元组合起来,加上控制器、总线等,就形成了一个完整的 CPU 核心。它能取指令、解码、执行、写回结果——这就是"计算"的全部过程。 +::: + +--- + +## 1. 晶体管:数字世界的开关 + +### 1.1 什么是晶体管? + +::: tip 💡 晶体管是什么? +**晶体管(Transistor)** 是一种半导体器件,它可以像开关一样控制电流的通断。 + +**生活类比**:想象一个水龙头: +- **水龙头**:你用手拧开关,控制水流 +- **晶体管**:用电压控制开关,控制电流 + +关键区别是:晶体管不是用手拧,而是用"电"来控制。这意味着一个开关可以控制另一个开关,从而实现"自动控制"。 +::: + +**晶体管的三个极:** + +| 极 | 名称 | 作用 | 类比 | +|---|------|------|------| +| **源极 (Source)** | 电流入口 | 电流从这里进入 | 水管入口 | +| **漏极 (Drain)** | 电流出口 | 电流从这里流出 | 水管出口 | +| **栅极 (Gate)** | 控制端 | 控制是否导通 | 水龙头开关 | + +### 1.2 晶体管如何表示 0 和 1? + +计算机只认识 0 和 1,这和晶体管有什么关系? + +::: tip 💡 用电压表示 0 和 1 +**核心思想**:用电压的高低来表示 0 和 1。 + +- **高电压(如 3.3V)**:表示 1 +- **低电压(如 0V)**:表示 0 + +这就像灯泡的亮和灭: +- 灯亮 = 1 +- 灯灭 = 0 + +晶体管的作用就是"控制灯泡的亮灭"——给栅极加高电压,源极和漏极导通,"灯泡"亮了(输出 1);给栅极低电压,源极和漏极断开,"灯泡"灭了(输出 0)。 +::: + +### 1.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 性能越强、功耗越低。但制造难度也指数级增加。 +::: + +--- + +## 2. 逻辑门:用开关做运算 + +### 2.1 从晶体管到逻辑门 + +一个晶体管只是一个开关,但把多个晶体管组合起来,就能实现"逻辑运算"。 + + + +### 2.2 基本逻辑门详解 + +**AND 门(与门)**: +- **规则**:两个输入都为 1,输出才为 1 +- **生活类比**:串联的两个开关,必须都按下灯才亮 +- **应用**:判断"多个条件是否同时满足" + +**OR 门(或门)**: +- **规则**:任一个输入为 1,输出就为 1 +- **生活类比**:并联的两个开关,按任意一个灯就亮 +- **应用**:判断"是否满足任一条件" + +**NOT 门(非门)**: +- **规则**:输入和输出相反 +- **生活类比**:反相器,开变关、关变开 +- **应用**:取反操作 + +**XOR 门(异或门)**: +- **规则**:两个输入不同时输出 1 +- **生活类比**:判断"两个值是否不同" +- **应用**:比较、加法运算 + +### 2.3 用逻辑门做加法 + + + +::: tip 💡 加法器是怎么工作的? +**半加器**:处理两个 1 位二进制数相加 +- 输入:A、B(各 1 位) +- 输出:和(S)、进位(C) +- 公式:S = A XOR B,C = A AND B + +**全加器**:处理两个 1 位二进制数相加,加上上一位的进位 +- 输入:A、B、Cin(进位输入) +- 输出:和(S)、Cout(进位输出) + +**多位加法器**:把多个全加器级联起来 +- 第 1 位加法器的进位输出,连接到第 2 位加法器的进位输入 +- 就像我们手算加法时"逢二进一" +::: + +--- + +## 3. 功能单元:逻辑门的组合 + +### 3.1 常见功能单元 + +| 单元 | 功能 | 组成 | 类比 | +|------|------|------|------| +| **加法器** | 做加法 | 多个全加器级联 | 计算器的加法功能 | +| **多路选择器** | 选择数据 | AND 门 + OR 门 | 多选一开关 | +| **译码器** | 解码指令 | 多个 AND 门 | 翻译器 | +| **寄存器** | 存储数据 | 触发器(锁存器) | 临时笔记本 | +| **计数器** | 计数 | 触发器级联 | 计分牌 | + +### 3.2 寄存器:存储 1 位数据 + +::: tip 💡 寄存器是怎么存储数据的? +寄存器使用**触发器**电路来存储数据。触发器的特点是:一旦设置了状态,就能保持住,直到下一次改变。 + +**生活类比**:想象一个跷跷板: +- 推一下左边,左边就沉下去,右边翘起来 +- 即使你松手,跷跷板也会保持这个状态 +- 只有再推一下,才会改变状态 + +触发器就是这样的"电子跷跷板",能"记住"上一次被设置的状态。 +::: + +--- + +## 4. CPU 架构:从功能单元到处理器 + +### 4.1 CPU 的核心组件 + + + +### 4.2 CPU 是如何执行指令的? + +CPU 执行一条指令,需要经过四个阶段: + +| 阶段 | 名称 | 做什么 | 类比 | +|------|------|--------|------| +| **1** | 取指 (Fetch) | 从内存读取指令 | 从书架上取书 | +| **2** | 解码 (Decode) | 分析指令要做什么 | 阅读书的内容 | +| **3** | 执行 (Execute) | 执行运算 | 按书中的指示行动 | +| **4** | 写回 (Write Back) | 把结果存回寄存器 | 把结果记在笔记本上 | + +::: tip 💡 指令周期 +这四个阶段组成一个**指令周期**。CPU 不断重复这个周期,一条一条执行指令,就实现了"计算"。 + +现代 CPU 使用**流水线技术**,让多个指令的不同阶段并行执行: +- 第 1 条指令在执行时 +- 第 2 条指令在解码 +- 第 3 条指令在取指 + +这就像工厂流水线,大大提高了效率。 +::: + +### 4.3 CPU 性能的关键指标 + +| 指标 | 含义 | 影响 | 典型值 | +|------|------|------|--------| +| **主频** | 每秒执行多少个时钟周期 | 主频越高,执行越快 | 3-5 GHz | +| **核心数** | 独立的处理器数量 | 核心越多,并行能力越强 | 4-64 核 | +| **缓存** | CPU 内部的高速存储 | 缓存越大,访问内存越少 | 8-64 MB | +| **指令集** | CPU 能理解的指令集合 | 决定兼容性和功能 | x86、ARM | + +--- + +## 5. 总结:从沙子到智能 + +让我们回顾一下从晶体管到 CPU 的完整路径: + +``` +沙子(硅) + ↓ 提纯、切割 +硅晶圆 + ↓ 光刻、蚀刻、掺杂 +晶体管(开关) + ↓ 组合 +逻辑门(AND、OR、NOT...) + ↓ 组合 +功能单元(加法器、寄存器...) + ↓ 组合 +CPU 核心(ALU、控制器、寄存器组...) + ↓ 编程 +软件应用 +``` + +::: tip 💡 核心启示 +**计算机的本质是"开关的组合"**。 + +- 一个开关做不了什么 +- 但几十亿个开关,按特定方式组合,就能执行任何计算 +- 这就是"量变引起质变"的最好例证 + +理解这一点,你就会明白: +- 为什么计算机只认识 0 和 1 +- 为什么编程语言最终都要翻译成机器码 +- 为什么算法效率如此重要(因为每一步操作都需要大量晶体管参与) +::: + +--- + +## 延伸阅读 + +- **计算机组成原理**:深入了解 CPU、内存、I/O 的工作原理 +- **数字电路**:学习逻辑门、触发器、时序电路的设计 +- **计算机体系结构**:研究 CPU 的性能优化、流水线、缓存等 +- **汇编语言**:直接和 CPU 对话,理解指令执行过程 diff --git a/docs/zh-cn/appendix/1-computer-fundamentals/type-systems-compilers.md b/docs/zh-cn/appendix/1-computer-fundamentals/type-systems-compilers.md index 2052730..a68f6ba 100644 --- a/docs/zh-cn/appendix/1-computer-fundamentals/type-systems-compilers.md +++ b/docs/zh-cn/appendix/1-computer-fundamentals/type-systems-compilers.md @@ -1,3 +1,478 @@ # 类型系统与编译原理入门 -> 待实现 +::: tip 🎯 核心问题 +**编程语言如何理解你的代码?** 当你写下 `int x = 10 + 5;` 时,编译器需要理解每个字符的含义、检查类型是否正确、优化代码、最终生成机器能执行的指令。本章带你理解这个神奇的过程。 +::: + +--- + +## 0. 想象你在翻译一本书: + +- **识别单词**:把句子拆成一个个单词(词法分析) +- **理解语法**:判断句子是否符合语法规则(语法分析) +- **理解含义**:确保句子意思正确(语义分析) +- **优化表达**:让句子更简洁(代码优化) +- **翻译输出**:翻译成目标语言(代码生成) + +**编译器就是编程语言的"翻译官"**,将人类可读的代码转换为机器可执行的指令。 + + + +--- + +## 1. 类型系统基础 + +### 1.1 什么是类型? + +::: tip 💡 类型的本质 +类型是对数据的**分类**,规定了数据可以进行的操作。 + +就像现实世界: +- **整数**:可以加减乘除,但不能分割 +- **字符串**:可以拼接、截取,但不能直接运算 +- **布尔**:只有 true/false,用于逻辑判断 +::: + +**基本数据类型**: + +| 类型 | 表示 | 占用空间 | 取值范围 | +|------|------|---------|---------| +| **整数** | int | 4 字节 | -2^31 到 2^31-1 | +| **浮点数** | float | 4 字节 | 约 ±3.4 × 10^38 | +| **双精度** | double | 8 字节 | 约 ±1.8 × 10^308 | +| **字符** | char | 1 字节 | 0 到 255 | +| **布尔** | bool | 1 字节 | true/false | + +### 1.2 静态类型 vs 动态类型 + +::: tip 💡 核心区别 +**静态类型**:变量类型在**编译时**确定 +**动态类型**:变量类型在**运行时**确定 +::: + +**静态类型示例(Java)**: + +```java +String name = "Alice"; // 编译时确定 name 是 String 类型 +name = 123; // 编译错误!类型不匹配 +``` + +**动态类型示例(Python)**: + +```python +name = "Alice" # 运行时 name 是 str 类型 +name = 123 # 运行时 name 变成 int 类型 +print(type(name)) # +``` + +**对比分析**: + +| 特性 | 静态类型 | 动态类型 | +|------|---------|---------| +| **类型检查时机** | 编译时 | 运行时 | +| **错误发现** | 早(编译期) | 晚(运行时) | +| **代码灵活性** | 低 | 高 | +| **执行性能** | 高(编译优化) | 低(运行时检查) | +| **IDE 支持** | 好(自动补全) | 差(运行时才知道类型) | +| **代表语言** | Java, C++, Rust, TypeScript | Python, JavaScript, Ruby | + +### 1.3 强类型 vs 弱类型 + +::: tip 💡 核心区别 +**强类型**:不允许隐式类型转换 +**弱类型**:允许隐式类型转换 +::: + +**弱类型示例(JavaScript)**: + +```javascript +console.log("1" + 1) // "11" - 字符串拼接 +console.log("1" - 1) // 0 - 自动转数字 +console.log([] + []) // "" - 空数组转空字符串 +console.log(true + 1) // 2 - 布尔转数字 +``` + +**强类型示例(Python)**: + +```python +"1" + 1 # TypeError: can only concatenate str to str +"1" - 1 # TypeError: unsupported operand type(s) +``` + +**类型系统四象限**: + +| | 强类型 | 弱类型 | +|---|--------|--------| +| **静态** | Java, Rust, Haskell | C, C++ | +| **动态** | Python, Ruby | JavaScript, PHP | + +### 1.4 类型推断 + +现代语言可以**自动推断**变量类型,结合静态类型的安全性和动态类型的简洁性: + +```typescript +// TypeScript +let x = 1; // 推断为 number +let arr = [1, 2, 3]; // 推断为 number[] +let fn = (x) => x; // 推断为 (x: any) => any + +// Rust +let x = 1; // 推断为 i32 +let s = "hello"; // 推断为 &str +let v = vec![1, 2]; // 推断为 Vec +``` + +--- + +## 2. 编译原理基础 + +### 2.1 编译器的任务 + +::: tip 💡 编译器做什么? +编译器将**源代码**转换为**目标代码**,主要完成: + +1. **理解代码**:分析源代码的结构和含义 +2. **检查正确性**:发现语法和语义错误 +3. **优化代码**:提高执行效率 +4. **生成代码**:输出目标机器的指令 +::: + + + +### 2.2 词法分析(Lexical Analysis) + +**任务**:将源代码分解为**词法单元(Token)** + +**示例**: + +``` +源代码: int x = 10 + 5; + +词法单元: +[int] → 关键字 +[x] → 标识符 +[=] → 运算符 +[10] → 整数字面量 +[+] → 运算符 +[5] → 整数字面量 +[;] → 分隔符 +``` + +**词法分析器的工作**: + +| 输入 | 处理 | 输出 | +|------|------|------| +| `int` | 匹配关键字表 | `KEYWORD(int)` | +| `x` | 匹配标识符规则 | `IDENTIFIER(x)` | +| `10` | 匹配数字规则 | `NUMBER(10)` | + +### 2.3 语法分析(Syntax Analysis) + +**任务**:根据语法规则,将 Token 流组织成**语法树(AST)** + +**示例**: + +``` +表达式: 1 + 2 * 3 + +语法树: + + + / \ + 1 * + / \ + 2 3 +``` + +::: tip 💡 为什么是这棵树? +根据运算优先级,`*` 优先级高于 `+`,所以 `2 * 3` 先结合。 + +如果表达式是 `(1 + 2) * 3`,语法树会变成: + +``` + * + / \ + + 3 + / \ + 1 2 +``` +::: + +**语法规则(文法)**: + +``` +表达式 → 表达式 + 项 | 表达式 - 项 | 项 +项 → 项 * 因子 | 项 / 因子 | 因子 +因子 → 数字 | (表达式) +``` + +### 2.4 语义分析(Semantic Analysis) + +**任务**:检查语义正确性,进行类型检查 + +**主要工作**: + +| 工作 | 说明 | 示例 | +|------|------|------| +| **类型检查** | 检查类型是否匹配 | `int x = "hello";` → 错误 | +| **作用域分析** | 检查变量是否声明 | 使用未声明变量 → 错误 | +| **符号表构建** | 记录所有标识符信息 | 变量名、类型、作用域 | +| **类型推断** | 推断表达式类型 | `1 + 2.0` → float | + +**符号表示例**: + +``` +int x = 10; +float y = 3.14; +string name = "Alice"; + +符号表: +┌──────────┬────────┬─────────┐ +│ 名称 │ 类型 │ 作用域 │ +├──────────┼────────┼─────────┤ +│ x │ int │ global │ +│ y │ float │ global │ +│ name │ string │ global │ +└──────────┴────────┴─────────┘ +``` + +### 2.5 中间代码生成 + +**任务**:生成平台无关的中间表示(IR) + +**三地址码示例**: + +``` +源代码: int x = (a + b) * c; + +三地址码: +t1 = a + b +t2 = t1 * c +x = t2 +``` + +::: tip 💡 为什么需要中间代码? +1. **平台无关**:一次编写,多平台编译 +2. **便于优化**:在 IR 层面进行优化 +3. **支持多语言**:不同语言可以编译到同一 IR + +例如 LLVM IR 支持 C、C++、Rust、Swift 等多种语言。 +::: + +### 2.6 代码优化 + +**任务**:提高代码执行效率 + +**常见优化技术**: + +| 优化技术 | 说明 | 示例 | +|---------|------|------| +| **常量折叠** | 编译时计算常量表达式 | `10 + 5` → `15` | +| **死代码消除** | 删除不会执行的代码 | `if (false) { ... }` → 删除 | +| **内联展开** | 函数调用替换为函数体 | `add(1, 2)` → `1 + 2` | +| **循环优化** | 减少循环开销 | 循环展开、循环不变量外提 | +| **公共子表达式消除** | 避免重复计算 | `a+b` 计算一次,多次使用 | + +**优化示例**: + +```c +// 优化前 +int x = 10 + 5; // 常量折叠 +int y = x * 2; // x 已知为 15 +if (false) { // 死代码 + printf("never"); +} + +// 优化后 +int x = 15; +int y = 30; +// if 语句被删除 +``` + +### 2.7 目标代码生成 + +**任务**:生成目标机器的机器码 + +**汇编代码示例**: + +```asm +; int x = 15; +mov eax, 15 +mov dword ptr [x], eax + +; int y = 30; +mov eax, 30 +mov dword ptr [y], eax +``` + +**代码生成的主要任务**: + +| 任务 | 说明 | +|------|------| +| **指令选择** | 选择合适的机器指令 | +| **寄存器分配** | 决定哪些变量放在寄存器 | +| **指令调度** | 安排指令顺序,提高流水线效率 | + +--- + +## 3. 编译型 vs 解释型 vs JIT + +### 3.1 编译型语言 + +**流程**:源代码 → 编译器 → 机器码 → 执行 + +``` +main.c → [编译器] → main.exe → [CPU] → 执行 +``` + +**特点**: +- ✅ 执行速度快 +- ✅ 编译期发现错误 +- ❌ 编译时间长 +- ❌ 跨平台需要重新编译 + +**代表语言**:C, C++, Rust, Go + +### 3.2 解释型语言 + +**流程**:源代码 → 解释器 → 逐行执行 + +``` +main.py → [解释器] → 逐行解释执行 +``` + +**特点**: +- ✅ 跨平台 +- ✅ 开发调试快 +- ❌ 执行速度慢 +- ❌ 运行时才能发现错误 + +**代表语言**:Python, Ruby, PHP + +### 3.3 JIT(即时编译) + +**流程**:源代码 → 字节码 → JIT 编译 → 执行 + +``` +源代码 → [编译器] → 字节码 → [JIT] → 机器码 → 执行 +``` + +**工作原理**: +1. 先将源代码编译成字节码(中间代码) +2. 解释器逐行执行字节码 +3. 发现热点代码(频繁执行),JIT 编译成机器码 +4. 后续直接执行机器码 + +**特点**: +- ✅ 兼顾性能和跨平台 +- ✅ 热点代码执行快 +- ❌ 启动慢(需要预热) +- ❌ 内存占用大 + +**代表语言**:Java (JVM), JavaScript (V8), Python (PyPy) + +--- + +## 4. 实践:手写简单解释器 + +### 4.1 目标 + +实现一个简单的计算器,支持加减乘除: + +``` +输入: 1 + 2 * 3 +输出: 7 +``` + +### 4.2 词法分析器 + +```python +import re + +Token = namedtuple('Token', ['type', 'value']) + +def tokenize(code): + tokens = [] + for match in re.finditer(r'\d+|[+\-*/()]', code): + value = match.group() + if value.isdigit(): + tokens.append(Token('NUMBER', int(value))) + else: + tokens.append(Token(value, value)) + return tokens + +# 测试 +print(tokenize('1 + 2 * 3')) +# [Token(type='NUMBER', value=1), Token(type='+', value='+'), ...] +``` + +### 4.3 语法分析器 + +```python +class Parser: + def __init__(self, tokens): + self.tokens = tokens + self.pos = 0 + + def parse(self): + return self.expr() + + def expr(self): + result = self.term() + while self.current() in ('+', '-'): + op = self.consume() + right = self.term() + if op == '+': + result += right + else: + result -= right + return result + + def term(self): + result = self.factor() + while self.current() in ('*', '/'): + op = self.consume() + right = self.factor() + if op == '*': + result *= right + else: + result //= right + return result + + def factor(self): + token = self.consume() + if token.type == 'NUMBER': + return token.value + elif token.value == '(': + result = self.expr() + self.consume() # ) + return result +``` + +### 4.4 完整解释器 + +```python +def evaluate(code): + tokens = tokenize(code) + parser = Parser(tokens) + return parser.parse() + +print(evaluate('1 + 2 * 3')) # 7 +print(evaluate('(1 + 2) * 3')) # 9 +print(evaluate('10 - 2 * 3')) # 4 +``` + +--- + +## 5. 总结 + +::: tip 📚 核心要点 +1. **类型系统**:静态/动态、强/弱类型,影响代码安全和灵活性 +2. **编译流程**:词法分析 → 语法分析 → 语义分析 → 中间代码 → 优化 → 代码生成 +3. **执行方式**:编译型快但需编译,解释型慢但灵活,JIT 兼顾两者 +4. **实践价值**:理解编译原理有助于写出更好的代码 +::: + +**下一步学习**: +- [编程语言图谱](./programming-languages) - 了解更多编程语言 +- [数据结构](./data-structures) - 理解数据的组织方式 +- [算法思维入门](./algorithm-thinking) - 学习解决问题的方法