JavaEE初阶(1)计算机是如何工作的
TL;DR:计算机从底层到上层,本质是一条由简单部件层层堆叠而成的链路——电子开关组成逻辑门,逻辑门搭出能算数的 ALU 和能记忆的寄存器/RAM,控制单元 CU 用时钟驱动"取码-解码-执行"的指令周期,编程语言再把人类指令翻译成 0 和 1,最后由操作系统用进程抽象统一管理硬件资源。读完本文,你将彻底看穿计算机这台"黑箱"。
目录
- 一、冯·诺依曼体系:现代计算机的统一骨架
- 二、第一块多米诺骨牌:电子开关
- 三、逻辑门:计算机世界的"原子"
- 四、ALU:计算机的"数学大脑"
- 五、寄存器与内存:让计算机"记住"东西
- 六、控制单元 CU 与指令周期:计算机是如何"自己动起来"的
- 七、编程语言:从拨 0/1 开关到高级语言
- 八、操作系统:站在硬件与程序之间的管理者
- 结语
一、冯·诺依曼体系:现代计算机的统一骨架
人类对"计算"的需求驱动着工具演进:一般计算工具 → 机械计算机 → 电子计算机。而今天几乎所有计算机都遵循同一套结构——冯·诺依曼体系(Von Neumann Architecture)。
它由五大部件组成:
| 部件 | 职责 |
|---|---|
| 输入设备 | 用户给计算机发号施令(键盘、鼠标) |
| 输出设备 | 计算机向用户汇报结果(显示器、音箱) |
| 存储器 | 存储数据和指令,全部用二进制,分内存和外存 |
| 运算器 | 做算术运算和逻辑判断 |
| 控制器 | 指挥各部件协同工作 |
其中运算器 + 控制器 = CPU(中央处理器)。数据沿着"输入设备 → 存储器 ↔ CPU → 输出设备"流动。
两个必须刻进脑子的不等式:
存储空间大小: 硬盘 > 内存 >> CPU
数据访问速度: CPU >> 内存 > 硬盘
这正是"为什么CPU要配高速缓存""为什么程序要先加载进内存才能跑"这类问题的根源。
冯·诺依曼(John von Neumann,1903–1957),美籍匈牙利数学家、计算机科学家、物理学家,被称为"现代计算机之父"“博弈论之父”。
下面进入最硬核的部分:CPU究竟是怎么用一堆开关造出来的。
二、第一块多米诺骨牌:电子开关
一切的起点是机械继电器(Mechanical Relay)——一个电子开关:下方线圈通电产生磁场,吸合上方机械臂,电路导通;断电则弹开。
它就像一个水龙头:打开有水,关闭断水。输入 TRUE 输出 TRUE,输入 FALSE 输出 FALSE。
别小看这个"只表示 1 位(bit)"的笨器件——后来的真空管、晶体管,物理原理更复杂,本质都在做同一件事:用通电/断电表示 1 和 0。
把这些开关巧妙组合,就能造出真正有用的东西——门电路(Gate Circuit)。
三、逻辑门:计算机世界的"原子"
用电子开关可以搭出四种最基础的逻辑门,它们各自对应一张真值表:
- 非门 NOT:输入取反(进1出0,进0出1)
- 与门 AND:两个输入全为1才输出1(两个开关串联)
- 或门 OR:只要有一个为1就输出1(两个开关并联)
- 异或门 XOR:两个输入不同才输出1(可由 AND / OR / NOT 组合而成)
┌─────┐ A ─┐ ┌─────┐
1 ───│ NOT ├──0 ├─ AND ├── ┌─────┐
└─────┘ B ─┘ └─────┘ A,B不同才出1 → XOR
逻辑门看起来简单,但它是数学与电路的第一次握手。接下来,见证奇迹的时刻——用它们造一个会算数的部件。
四、ALU:计算机的"数学大脑"
**ALU(Arithmetic & Logic Unit,算术逻辑单元)**是计算机里做算数和逻辑运算的核心部件。著名的 Intel 74181 就是一块经典的 4 位 ALU 芯片。
要理解它,先回到进制。
4.1 二进制:一切数字的底色
十进制 183 = 1×100 + 8×10 + 3×1,每位权重是 10 的幂;
二进制同理,每位权重是 2 的幂:
183 = 1×128 + 1×32 + 1×16 + 1×4 + 1×2 + 1×1
= 10110111 (二进制)
二进制相加和十进制竖式完全一样,只是逢二进一:
10110111 (183)
+ 00010011 ( 19)
-----------
11001010 (202)
4.2 半加器:两个 1 位相加
两个 1 位二进制数 A、B 相加,结果有两部分:和(SUM) 与 进位(CARRY)。
- 和 = A XOR B
- 进位 = A AND B
一个 XOR + 一个 AND,就组成了半加器(Half Adder):
| A | B | 进位 | 和 |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 0 | 1 | 0 | 1 |
| 1 | 0 | 0 | 1 |
| 1 | 1 | 1 | 0 |
4.3 全加器与 8 位加法器
半加器只能处理两个输入,但竖式加法中第二位开始还要加上来自低位的进位,于是有三个输入。用两个半加器 + 一个或门组成全加器(Full Adder)。
再把 1 个半加器和 7 个全加器像链条一样串联(低位进位喂给高位),就得到一个完整的 8 位加法器。
至此,一个能算 8 位数加法的运算器,就被我们从无到有"焊"了出来。继续组合逻辑门,减法、乘法、除法都能实现(乘除法器更复杂)。这就是 ALU 中算术单元的来历。
4.4 逻辑单元
ALU 的另一半是逻辑单元,负责与、或、非以及大小比较等。比如把 8 位数字逐位接进一串 OR 门,只要有一位是 1 输出就是 1——这就是一个"8 位非 0 判断器"(判断结果是否为 0,再取反即可)。
最终的 ALU 对外长这样:吃进两个 8 位输入 A、B,接收一个 4 位操作码 opcode告诉它做什么运算,输出 8 位结果,同时给出溢出、是否为 0、正负数等标志位。
再复杂的现代 64 位 ALU,也是工程师这样一层一层抽象出来的。
五、寄存器与内存:让计算机"记住"东西
光会算没用,得有地方存数据。存储同样能用门电路造出来,而且关键特性是:必须保持通电,一旦断电数据就丢失(易失 volatile)——这就是内存断电即失的硬件原因。
5.1 锁存器:1 位的记忆
用 AND、OR、NOT 门交叉反馈,可以搭出 AND-OR 锁存器(Latch),它能"咬住"一个状态不放。再封装成带数据输入(Data)和使能线(Write Enable)的门锁(Gated Latch):
- 使能线置位:输入什么就存什么(进1存1,进0存0);
- 使能线关闭:写入无效,保持原值。
5.2 从寄存器到 RAM
- 把 8 个门锁并排,共用一根使能线,就是一个 8 位寄存器(Register);
- 把海量这样的存储单元排成矩阵,配上地址线、数据线、读/写使能线,就构成了 RAM(Random Access Memory,随机存取存储器)。
RAM 可以通过地址直接定位到任意一格,访问时间与位置无关——这正是 O(1) 时间复杂度,也是为什么编程语言里"数组用下标访问是 O(1)"的硬件支撑。
六、控制单元 CU 与指令周期:计算机是如何"自己动起来"的
有了 ALU(会算)和存储(会记),还差一个"发号施令"的角色——控制单元 CU(Control Unit)。它负责指挥 ALU 去算什么、何时去内存取数。
CU 内部有两个关键寄存器:
- PC(Program Counter,程序计数器):保存下一条要执行的指令在内存中的地址;
- IR(Instruction Register,指令寄存器):保存当前这条指令本身。
6.1 指令:CPU 唯一能听懂的话
指令(Instruction)= 操作码(opcode)+ 被操作数。
- 操作码说明"做什么动作";
- 被操作数说明"对谁操作",可能是内存地址,也可能是寄存器编号。
指令本身也是一个数字,以二进制形式躺在内存里。一张简化指令表:
| 指令 | 功能 | opcode | 操作数 |
|---|---|---|---|
| LOAD_A | 从 RAM 指定地址取数到寄存器 A | 0010 | 4 位地址 |
| LOAD_B | 取数到寄存器 B | 0001 | 4 位地址 |
| STORE_A | 把 A 的数据写回 RAM 指定地址 | 0100 | 4 位地址 |
| ADD | 两个寄存器相加,结果放回第二个 | 1000 | 两个寄存器 ID |
6.2 完整跑一条指令
以内存第 0 格存着 0010 1110 为例:
- 取码(Fetch):CU 按 PC 的值(0),从内存地址 0 把指令
00101110读入 IR; - 解码(Decode):查表得知前 4 位
0010是 LOAD_A,后 4 位1110= 十进制 14,即"把内存地址 14 的数据读到寄存器 A"; - 执行(Execute):CU 指挥完成动作,把地址 14 的数据搬进寄存器 A;
- PC 自增 +1,指向下一条指令,循环往复。
这就是永不停歇的指令周期(Instruction Cycle):
取码 Fetch
│
▼
解码 Decode ──────► 执行 Execute ──┐
▲ │
└────────────────────────────┘
这个周期不是 CPU 自己"想"出来的节奏,而是由一颗**时钟(Clock)**周期性驱动的。CPU 主频粗略地讲就是时钟每秒震荡的次数,可以近似看作每秒能执行的指令节拍数——这就是你在"我的电脑属性"里看到的 1.60GHz / 2.11GHz。
至此:ALU + CU + 寄存器 + 时钟 = CPU。CPU 通过地址总线告诉内存要哪个地址、通过数据总线取回或写入数据。
贴士:
- PC 寄存器决定了 CPU 下一条执行哪条指令;
- 指令由动作 + 操作对象组成;
- CPU 眼中只有指令,没有"文件""图片"这些概念。
七、编程语言:从拨 0/1 开关到高级语言
程序(Program)= 一组指令 + 这组指令要处理的数据。 狭义上,它通常表现为磁盘上的一组文件。
最早的微型电脑 Altair 8800,编程真的要靠面板上的开关,一位一位地把 0、1 拨进去——门槛极高。为了把人从二进制里解放出来,编程语言经历了三层演进:
高级语言(C / Java …)
│ 编译 compile + 链接 link
▼
汇编语言(LOAD_A、ADD 这类助记符,与机器指令一一对应)
│ 汇编 assemble(汇编器 assembler)
▼
机器语言(0 和 1,CPU 唯一直接执行的东西)
- 汇编语言:用人类好记的符号一一对应机器指令,但程序员仍需掌握全部硬件细节,且换一类机器就不通用;
- 高级语言(C、Java 等):屏蔽硬件细节,经编译器(compiler)、链接器(linker)、汇编器层层翻译成机器语言。
注意:高级语言里的**一条语句(Statement),往往对应很多条机器指令(Instruction)**才能完成。
封装让编程越来越容易,但也让很多程序员把计算机当成"黑箱"。理解这一层,你就明白自己写的代码最终是如何变成 0 和 1 去驱动硬件的。
八、操作系统:站在硬件与程序之间的管理者
**操作系统(OS)**是一组做计算机资源管理的软件的统称(Windows、Linux、macOS、Android、iOS、鸿蒙等)。
系统的分层视图:
┌─────────────────────────────┐
│ 应用程序 │
├─────────────────────────────┤
│ 操作系统 │
├──────────┬────────┬─────────┤
│ 处理器 │ 主存 │ I/O设备 │
└──────────┴────────┴─────────┘
它有两个基本功能:
- 防止硬件被失控的应用程序滥用;
- 向应用程序提供简单一致的接口,去控制那些复杂且差异巨大的底层硬件。
8.1 进程:最重要的抽象之一
每个程序运行时,OS 都会制造一种"这台机器上只有我在独占运行"的假象。这个抽象就是进程(Process / Task):
- 进程是对一个正在运行的程序的抽象,可以理解为"程序的一次运行过程";
- 在 OS 内部,进程又是资源分配的基本单位。
OS 用一个数据结构描述每个进程——PCB(Process Control Block,进程控制块),里面记录进程标识 pid、关联的程序与内存区域、占用的资源、调度信息等。可以类比成 Java 里的一个对象:
// 伪码,仅用于说明概念
class PCB {
long pid; // 进程唯一标识
// 关联的程序信息、加载到内存的区域
// 分配到的各类资源
// 调度信息
}
OS 再用线性表、搜索树等结构把这些 PCB 组织起来,方便增删查改。
8.2 进程调度与内存管理
- CPU 分配 —— 进程调度(时间模式):在单 CPU 上,多个进程在不同时间段轮流使用 CPU,制造并行的错觉;
- 内存分配 —— 内存管理(空间模式):不同进程使用内存中的不同区域,彼此隔离、互不干扰。
8.3 进程间通信 IPC
隔离保证了安全,但复杂业务又需要进程协作,于是有了进程间通信(IPC)。主流机制包括:
- 管道 2. 共享内存 3. 文件 4. 网络 5. 信号量 6. 信号
其中网络最特殊:它不仅支持同一台主机上的两个进程通信,还能跨越不同主机。
结语
电子开关 → 逻辑门 → 加法器/ALU → 锁存器/寄存器/RAM → CU 驱动指令周期(取码-解码-执行)→ 汇编/高级语言翻译成指令 → 操作系统用进程抽象统一管理资源。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐
所有评论(0)