2.计算机基础
冯诺依曼体系
1945年,约翰·冯·诺依曼(John von Neumann)在论文《EDVAC的设计草案》中首次系统地提出了现代计算机的体系结构原则,这套原则后来被称为"冯·诺依曼体系结构",也叫"存储程序计算机"概念。它奠定了今天几乎所有通用计算机的基础。

五大核心部件
冯·诺依曼明确提出,电子计算机应该由以下五个基本部分组成

| 序号 | 部件名称 | 现代对应部件 | 主要功能 |
|---|---|---|---|
| 1 | 运算器 | CPU中的ALU(算术逻辑单元) | 执行算术运算(加减乘除)、逻辑运算(与或非、比较)、移位等数据加工操作 |
| 2 | 控制器 | CPU中的控制单元(CU) | 解释指令、发出控制信号、协调各部件有序工作,是计算机的"大脑" |
| 3 | 存储器 | 内存(RAM)+外存(硬盘/SSD) | 存放程序和数据,程序和数据以二进制形式统一存储,按地址访问 |
| 4 | 输入设备 | 键盘、鼠标、触摸屏、扫描仪等 | 把外部世界的程序和数据转换成计算机能识别的二进制形式输入到存储器中 |
| 5 | 输出设备 | 显示器、打印机、音箱等 | 把存储器或CPU中的运算结果转换成人能理解的形式输出 |
注:现代计算机把"运算器 + 控制器"合并成了我们常说的中央处理器(CPU)。
工作流程
txt
输入设备 → 存储器(内存)
↑ ↓
控制器 ←→ 运算器 ←┓
↑ CPU
存储器(取指令、取数据、存结果)
↓
输出设备
- 1.用户通过输入设备把程序和数据送入内存
- 2.CPU的程序计数器(PC)指向内存中第一条指令的地址
- 3.控制器从内存取指令 → 译码 → 发出控制信号
- 4.若需要数据,控制器再指挥从内存取操作数到CPU内部寄存器
- 5.运算器完成计算,结果写回寄存器或内存
- 6.控制器修改程序计数器,进入下一条指令
- 7.需要时把最终结果从内存送到输出设备显示
核心特征
- 二进制:一切信息都用0、1表示
- 存储程序:程序和数据统一存储在内存中
- 五大部件:运算器、控制器、存储器、输入、输出
- 顺序执行:CPU按地址逐条取指令执行
- 可编程:程序可被修改、复制、传播
计算机语言
"所有计算机语言的终极使命都是:把人类的意图翻译成CPU能执行的 0 和 1 序列,只是翻译方式和抽象层次不同而已。"
什么是计算机语言?
语言的本意是"沟通的工具"
- 自然语言:人与人沟通(如中文、英文)
- 计算机语言:人与计算机沟通的工具,让人类能指挥计算机干活
计算机只认识 0 和 1,因此人类必须用某种方式把自己的想法翻译成 0、1 序列。
计算机语言层级
| 层级 | 语言类型 | 代表语言 | 计算机可读性 | 人类可读性 | 跨平台性 | 典型特点 |
|---|---|---|---|---|---|---|
| 第1级 | 机器语言 | 纯二进制指令(如 10101100) | CPU直接执行 | ★☆☆☆☆ | 无 | 完全由0、1组成,每种CPU指令集都不一样 |
| 第2级 | 汇编语言 | ADD、MOV、JMP、INT等 | CPU(需汇编器) | ★★☆☆☆ | 差 | 用助记符代替二进制,几乎1对1对应机器指令 |
| 第3级 | 高级语言 | C、Java、Python、Go等 | CPU(需编译/解释) | ★★★★☆ | 好 | 接近自然语言和数学表达式 |
机器语言(Machine Language)
表达形式:一串固定长度的二进制数(如 32位、64位)
示例:(x86)
10110000 01100001
把数值 97 送入 AL 寄存器(也就是把字符 'a' 送入寄存器)
缺点: 极难读、难写、难记、易出错、不同CPU完全不通用
汇编语言(Assembly Language)
用英文助记符代替二进制,大幅提高可读性
示例:
MOV AX, 5 ; 把5送入AX寄存器
ADD AX, BX ; AX = AX + BX
仍然是"面向机器"的语言,但是必须经过"汇编器(Assembler)"翻译成机器语言才能运行
机器语言 + 汇编语言 \= 低级语言
高级语言(High-level Language)
-
接近人类自然语言和数学表达式
示例(C语言):
cint a = 5; int b = 10; int c = a + b; -
程序员只需要关心"做什么",不用关心具体CPU怎么做
-
必须经过"编译器"或"解释器"转换成机器语言
高级语言的两种执行方式对比
| 项目 | 编译型语言(Compiled) | 解释型语言(Interpreted) / 虚拟机型 |
|---|---|---|
| 代表语言 | C、C++、Go、Rust、Swift | Java、Python、JavaScript、C#、Ruby |
| 编译过程 | 源代码 → 直接生成 本地机器码(.exe) | 源代码 → 字节码(Bytecode) → 虚拟机执行 |
| 执行速度 | ★★★★★(最快) | ★★★☆☆(较慢,但现代JIT技术已大幅缩小差距) |
| 跨平台性 | 差(需要为每种CPU/OS重新编译) | 优秀(一次编写,到处运行) |
| 是否需要运行环境 | 不需要(生成独立可执行文件) | 需要(需要安装JVM、Python解释器等) |
| 典型代表执行方式 | gcc/clang直接生成CPU指令 | Java → javac → .class → JVM执行 |
| Go → go build → 可执行文件 | Python → python解释器逐行解释执行 |
- Go 语言:虽然是高级语言,但属于静态编译型,编译后生成本地可执行文件,不依赖虚拟机,兼具C语言速度和高级语言易用性。
- Java 的真实执行路径:源码 → 字节码 → JVM(即时编译JIT把热点代码变成机器码),所以实际运行速度很快。
程序到底是什么
程序 = 算法 + 数据结构 ------ Niklaus Wirth(Pascal语言之父)《算法 + 数据结构 = 程序》
程序的核心
| 要素 | 解释 | 举例说明 |
|---|---|---|
| 数据 | 程序要处理的对象(一切程序的核心) | 学生成绩、商品库存、游戏角色坐标、聊天消息 |
| 数据结构 | 数据在内存中的"居住方式"和"组织关系" | 数组、链表、哈希表、树、图、栈、队列 |
| 算法 | 对数据进行的"加工处理步骤" | 排序、搜索、遍历、加密、压缩、路径规划 |
写高性能程序的黄金法则
先根据业务特点选数据结构,再为这个数据结构选择最优算法
只有选对了数据结构,算法才能发挥最高效率
| 业务需求 | 最佳数据结构 | 推荐算法 | 时间复杂度对比 |
|---|---|---|---|
| 快速查找(身份证→姓名) | 哈希表(HashMap) | 哈希查找 | O(1) |
| 频繁插入删除(排行榜) | 平衡二叉树/跳表 | 红黑树插入删除 | O(log n) |
| 动态顺序访问(播放列表) | 数组/动态数组 | 顺序遍历 | O(1) 随机访问 |
| 后进先出(函数调用栈) | 栈(Stack) | 压栈/弹栈 | O(1) |
| 先进先出(任务队列) | 队列(Queue) | 入队/出队 | O(1) |
| 最短路径(导航) | 图(邻接表) | Dijkstra / A* | O((V+E)log V) |
写程序的四大难点
| 难点序号 | 真实难点 | 典型表现症状 | 解决方法 |
|---|---|---|---|
| 1 | 理不清业务数据 | 不知道要存哪些数据、数据之间什么关系 | 先画"实体-关系图"(E-R图)或写数据表格 |
| 2 | 搞不清处理方法(算法想不出来) | 脑子里一片空白,不知道从哪下手 | 拆解问题 → 找最近子问题 → 套经典算法模板 |
| 3 | 无法把"现实数据"转成"数据结构" | 知道要存学生信息,但不会设计结构体/类 | 练习:每个业务实体都对应一个struct/class |
| 4 | 不会使用"设计范式"写程序 | 代码一团乱,改一个地方崩一堆 | 掌握 OOP、函数式、模块化、分层架构等范式 |
程序设计的正确思考路径
- 1.明确要处理的数据(先问:我到底要存什么?)
- 2.设计合适的数据结构(数组?链表?哈希?树?)
- 3.确定要对数据做什么操作(增删改查、排序、遍历、最短路径...)
- 4.选择或设计对应的算法
- 5.选择合适的编程范式(面向过程、面向对象、函数式...)
- 6.编码 → 测试 → 重构
原文链接 :https://www.rzzz.net/go/basic/1/3-computer-basics.html