1. 这门课为什么总让人“看了就忘”
计算机概论几乎是每个计算机相关专业的第一门必修课。我当年第一次翻开教材时,感觉整本书就是一本大杂烩——硬件、软件、操作系统、网络、数据库、算法、编程语言全塞在一起,每一章讲得都不深,但覆盖面却特别广。结果就是上课听懂了,合上书全忘了,考前突击背名词解释,考完一周又归零。
后来我总结出一个教训:这门课的核心价值不在于记住多少名词,而在于建立一张“计算机系统全景图”。你不需要背下每个协议的端口号,但你必须知道数据从键盘输入到屏幕显示,中间到底经过了多少层、每一层分别解决什么问题。有了这张地图,后面学操作系统、组成原理、网络、数据库时,你才能知道每个细节点是在地图的哪个位置。
这篇文章想做的,就是帮你把教材里散落的知识点重新串成一条线。我不打算按教材章节顺序平铺直叙,而是按“数值与编码 → 硬件组成 → 指令与程序 → 操作系统 → 网络 → 数据管理”这条主线,把核心概念、常考点、容易混淆的地方一起捋一遍。适合正在备考的在校生,也适合想系统回顾基础的职场新人。
2. 先从“计算机在算什么”说起:数与编码
2.1 进制转换,别只会除2取余
进制转换是这门课第一个拦路虎,也是后面所有内容的基础。很多同学十进制转二进制背了“除2取余法”,二进制转十六进制背了“四位一组”,但一做题就乱。我倒建议你抓住一条根本规则:一个数的值,取决于它的每一位数字乘上该位的权值,然后求和。十进制的“123”就是 1×10² + 2×10¹ + 3×10⁰,二进制、八进制、十六进制同理,只是把底数10换成对应的2、8、16而已。
有了这条规则,你会发现所有进制转换其实只有两类问题:
- 十进制转任意进制:对整数部分不断除以目标进制,取余数,从下往上排列;对小数部分不断乘以目标进制,取整数部分,从上往下排列。
- 任意进制转十进制:按“位权展开求和”直接算。
八进制和十六进制与二进制之间的转换,则是利用它们与2的幂次关系(8=2³,16=2⁴)做快捷映射。这里有个易错点:二进制转十六进制时,小数部分要从小数点开始向右每四位一组,最后一组不足四位时,必须在右边补0,而不是左边。比如 0.101 转十六进制,0.1010 才是对应关系,补0位置错了结果就差出一倍。
注意:考试里经常出现“二进制小数能否用十进制精确表示”这个判断题。二进制只能表示那些能写成若干2的负幂次之和的数,像 0.1(十进制)在二进制里是一个无限循环小数。这个知识点后面学浮点数时会有大用。
2.2 原码、反码、补码,理解比背公式重要
原码、反码、补码这块,是很多人的噩梦。死记“正数的补码等于原码,负数的补码等于反码加一”虽然能做对简单题,但遇到“为什么 -8 的补码是 1000”这类追问就卡住了。
我建议换个角度理解:补码的设计目标,是把减法变成加法,让计算机只需要一套加法电路。以4位二进制为例,我们可以认为补码本质上是在做“模运算”——4位二进制能表示 2⁴ = 16 种状态,算满一圈就归零。正数从 0000 到 0111(0到7),负数则用 1000 到 1111(-8到-1)表示,这样任意两个数的加法都只需要按普通二进制相加,溢出位丢弃即可。正因为 1000 这个状态在模运算里代表“借位后剩下-8”,它才能被合法地利用起来。
补码的运算法则里,有一个特别实用的小技巧可以分享:快速求一个数的相反数的补码,可以“从右往左找到第一个1,把它左边所有位取反,它本身及右边不变”。练熟这个技巧,做“已知补码求相反数”的题目时可以省下不少时间。另外,补码的加减法运算中,符号位也可以参与运算,这正是它相比原码、反码最大的工程优势。
2.3 浮点数:规格化、阶码、尾数
如果进制转换只是计算量大,浮点数就是概念上的分水岭。IEEE 754 单精度浮点数用32位存储,三部分分别是:1位符号位、8位阶码(偏移127)、23位尾数。这里面最容易栽跟头的点有两个:
- 阶码使用“移码”而非补码存储,目的是让指数可以方便地比较大小。所谓移码,就是把真实指数加上一个偏移量,使得原本可能为负的指数变成非负数。单精度是 真实指数 + 127,双精度是真实指数 + 1023。
- 规格化要求尾数的整数部分必须是1,并且这个1在存储时可以省去,称为“隐含位”。因为二进制规格化数的整数部分恒为1,存储时不必浪费一位,这能多出一位精度。
一个常考的计算点是:单精度浮点数的表示范围大致从 ±1.2×10⁻³⁸ 到 ±3.4×10³⁸。为什么会有这个范围?因为阶码8位,除去全0和全1两个特殊值,真实指数范围是 -126 到 127,对应 2⁻¹²⁶ 就是最小规格化数,2¹²⁷ 乘以尾数最大值约等于 3.4×10³⁸。
我建议备考时亲手做一遍“把十进制数 -6.75 转成单精度浮点数”的完整流程:先转二进制,再规格化,再算阶码,最后拼装。整个过程做两遍以后,相关知识会牢固很多,比背十遍定义都有用。
3. 硬件体系:CPU、内存和I/O是怎么协作的
3.1 冯·诺依曼体系结构的核心思想
几乎每本《计算机概论》的第一章都会提到冯·诺依曼体系,关键点就是“存储程序”这四个字——指令和数据一样以二进制形式存放在存储器中,计算机按顺序一条一条取指令、执行指令。这个思想奠定了现代计算机的基本形态,也直接导致了指令和数据在内存中共存的结构。
与之相对的是哈佛结构(指令存储器和数据存储器分开),常被拿来做对比。现代处理器内部普遍采用改进型哈佛结构,但在外部统一寻址,这样既保留了“存储程序”的灵活性,又减少了指令和数据访问的冲突。理解这个演变过程,对你后面学组成原理里的“指令cache和数据cache分离”会有很大帮助。
3.2 总线与各部件的工作流程
很多人把总线理解成一组电线,其实不够。总线本质是一套共享通信协议,包括数据总线、地址总线、控制总线三类。地址总线宽度决定可寻址内存空间的大小,比如32位地址总线理论上可寻址 2³² = 4GB,这个计算在考试里反复出现。这里有一个常见误区:x86体系下4GB内存限制是物理寻址范围的限制,而不是操作系统瓶颈。实际能用到多少内存,还受到操作系统位数和具体硬件映射的影响。
CPU执行一条指令的完整流程,可以概括为:取指(Fetch)→ 译码(Decode)→ 执行(Execute)→ 写回(Write Back)。取指时要根据程序计数器PC中的地址去内存取指令,指令执行完后PC自动更新指向下一条指令,顺序流程靠PC保证,分支和跳转则修改PC值。这个流程看似简单,但建议你把这个过程对照“程序是如何运行的”这个问题完整讲一遍。
3.3 存储器层次结构:为什么L1 Cache比内存快几个数量级
存储器这块,除了记住“寄存器最快、Cache次之、内存再次、外存最慢”这个排序,更重要的是理解为什么要有这样的层次。根本原因是“速度越快、成本越高、容量越小”,单一存储技术无法同时满足大容量和高速访问的需求,所以用层次化结构在成本和性能之间折中。
Cache工作的理论基础是局部性原理:时间局部性(刚访问的数据很可能再次被访问)和空间局部性(刚访问数据周边的数据也大概率会被访问)。这个原理在后面的操作系统内存管理、数据库缓存设计里都会反复出现。考试常考的Cache映射方式有直接映射、全相联映射、组相联映射,关键在于理解每种方式的“索引”是怎么确定的,以及什么是命中率。
提示:写程序时也能利用局部性原理。比如二维数组在内存中是按行优先存储的,如果你按列遍历,缓存几乎每次都不命中,程序可能慢一个数量级。这不是夸张,我在实际项目里就见过同样的数据、仅仅调整循环顺序,执行时间差了6倍。
3.4 I/O控制方式:轮询、中断、DMA
I/O这块,最容易被忽视的是三种控制方式的演进逻辑。轮询是CPU不断主动问外设“好了吗”,忙等浪费CPU;中断是外设主动通知CPU“我好了”,CPU可以先去干别的,效率提升明显;DMA则是让专用控制器直接在外设和内存之间搬运数据,搬运完成才打断CPU一次。这个演进过程本质上是在“减少CPU参与I/O操作的时间”。
对于需要高速传输的设备(比如磁盘、网卡),DMA几乎是必然选择。理解这一点的工程意义在于:在写高性能I/O程序时,你会主动去考虑“CPU是不是在无谓地等I/O”,这正是后面学异步、协程、事件驱动模型的思想源头。
4. 指令与程序:机器怎么理解你的代码
4.1 指令格式与寻址方式
指令是CPU能执行的最小操作单元,一般包含操作码和操作数两部分。操作码指明做什么(加、减、跳转、读写内存),操作数指明对什么做。但操作数本身怎么给出,就有多种寻址方式:
- 立即寻址:操作数以常量的形式直接放在指令里。速度最快,但只能表示固定常数。
- 直接寻址:指令中给出操作数的内存地址。直观,但地址空间受指令长度限制。
- 寄存器寻址:指令中给出寄存器编号。速度仅次于立即寻址。
- 间接寻址:指令中给出的地址,那个地址里存的是一个指向真正操作数的地址。灵活性高,但需要多次访问内存。
- 变址寻址:基地址加上偏移量得出有效地址,在数组访问中非常关键。
之所以要讲寻址方式,是因为理解它才能看懂汇编代码,也才能理解高级语言中“指针变量”“数组名”“引用”在底层到底是怎样被处理的。
4.2 高级语言到机器码的旅程
源程序到可执行文件的过程:预处理 → 编译 → 汇编 → 链接。每一步的输出分别是:预处理后的代码、汇编代码、目标文件(机器码加重定位信息)、可执行文件。这里面容易混淆的是编译和汇编:编译是将高级语言翻译成汇编语言(或直接翻译成机器码);汇编是将汇编语言翻译成机器码。真正的语义分析、语法分析都发生在编译阶段,汇编基本是机械替换。
我在复习时最深的体会是:学完编译过程以后,很多之前“想当然”的问题都有了答案。为什么头文件写错了会在预处理阶段报错?因为预处理只是展开文本。为什么同一个函数在多个文件中使用会报重复定义?因为每个目标文件都包含了函数实现,链接时冲突了。为什么使用未初始化的局部变量值不确定?因为它对应栈上某段未清理的内存。这些知识串起来以后,编程中很多“玄学”问题都会变成“有依据”的问题。
4.3 指令流水线与并行基础
CPU执行多条指令时可以重叠进行:第一条在执行时,第二条已经在译码,第三条已经在取指。这就是指令流水线。理想情况下,流水线可以让吞吐率提升n倍(n为流水级数),但前提是每条指令占用时间均匀且没有冲突。现实中有三类冲突:结构冲突(硬件资源不够用)、数据冲突(后一条指令依赖前一条的结果)、控制冲突(分支指令导致预取指令失效)。
其中控制冲突造成的流水线停顿最头疼,因此现代CPU普遍采用分支预测技术。考试喜欢问“理想流水线的加速比”和“最简单无冲突的流水线性能计算方法”,建议你掌握一个标准模型:在k级流水线上执行n条指令,理想情况下总耗时为 k + (n - 1) 个周期。
5. 操作系统:它是怎么管理大大小小的资源
5.1 进程与线程,很多人的第一道坎
进程和线程的区别,几乎是面试必问,也是计算机概论的核心考点。进程是资源分配的基本单位:每个进程有独立的地址空间、打开的文件、上下文信息;线程是CPU调度的基本单位:多个线程共享同一个进程的地址空间和资源。所以创建进程的开销远大于创建线程,切换进程的开销也远大于切换线程。
这里值得深挖的问题是:为什么进程切换慢?因为要切换地址空间(涉及TLB失效)、内核栈、寄存器状态等;而线程切换只需切换栈和寄存器等轻量状态。还有一个容易混淆的点:同一个进程中的两个线程共享哪些内容?共享代码段、数据段、堆、打开的文件;但每个线程有自己的栈和寄存器。这个“共享与私有”的边界,必须能清晰列出来。
5.2 调度算法排行榜
进程调度算法是必考重点,我建议按“适用场景 + 优缺点”来对比记忆,而不是孤立背定义:
| 算法 | 核心思想 | 优点 | 缺点 |
|---|---|---|---|
| FCFS(先来先服务) | 按到达顺序排队 | 实现简单、公平 | 平均等待时间长,可能产生护航效应 |
| SJF(短作业优先) | 选择预计运行时间最短的进程 | 平均等待时间最少(理论最优) | 难以预知运行时间,可能饿死长作业 |
| 优先级调度 | 按优先级顺序执行 | 可以区分任务重要程度 | 低优先级进程可能饿死,需要老化机制 |
| RR(时间片轮转) | 每个进程轮流运行一个时间片 | 响应时间短、公平 | 时间片选择影响性能,太短切换开销大 |
| 多级反馈队列 | 多个队列,优先级由高到低,时间片逐级变长 | 兼顾响应时间和吞吐量,实用性强 | 参数配置复杂 |
这里我想特别强调SJF的“不可能实现”问题。它是理论最优,但操作系统无法预知未来进程的CPU执行时间。实际系统用的多级反馈队列,正是通过“运行得越多、优先级越低”的动态反馈来近似SJF的思想。理解了这个设计动机,多级反馈队列的细节就不需要死背了。
5.3 内存管理中的虚拟内存是干什么的
虚拟内存可能是这门课里最精彩的思想之一。每个进程拥有独立的虚拟地址空间,操作系统和硬件(MMU,内存管理单元)共同负责把虚拟地址翻译成物理地址,翻译过程中以页为单位进行映射。这样带来的好处:
- 进程之间内存隔离,一个进程的内存不会被另一个进程破坏。
- 程序不再受限于物理内存大小,可以运行比物理内存更大的程序。
- 同一份代码(比如动态库)可以被多个进程共享同一份物理页。
常考点是页式存储的地址计算:虚拟地址分为虚页号和页内偏移,物理地址分为物理页号和页内偏移。这里最关键的捷径是:页内偏移位数 = log2(页大小),比如4KB大小的页需要12位偏移。
另外要记住缺页中断的处理流程:当访问的页不在内存时,MMU触发缺页异常,操作系统从磁盘换入页,并更新页表。这个过程涉及磁盘I/O,所以首次访问一个页面会非常慢,这也是为什么程序局部性好能显著提升性能——它会降低缺页率。
5.4 死锁:四个必要条件与预防策略
死锁是并发程序里非常经典的问题,四个必要条件分别是:互斥、持有并等待、不可剥夺、循环等待。注意理解这四者不是“充分条件”,而是“必要条件”——也就是说,只要系统不发生死锁,那么这四个条件中至少有一个不成立;但如果四个都成立,系统也不一定就发生死锁,只是有风险。
应对策略有四种思路:预防(破坏四个条件之一)、避免(银行家算法)、检测与恢复(死锁检测后强制释放资源)、鸵鸟策略(不管它)。其中银行家算法是考试重点,建议亲手模拟几次“安全性检查”过程:时刻保持一个可用资源向量表,每次尝试分配前先检查是否所有进程都能在某种顺序下完成,能找到就是安全状态。
6. 计算机网络:分层是最大的主线
6.1 OSI七层模型与TCP/IP四层模型
网络部分最核心的线索是分层。OSI参考模型七层:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。TCP/IP实际模型四层:网络接口层、网络层、传输层、应用层。考试高频题是“数据在各层之间传递时如何封装”:应用层产生数据 → 传输层加TCP/UDP头 → 网络层加IP头 → 数据链路层加帧头和帧尾 → 物理层转成比特流发送;接收方则逐层解封装。
我个人觉得,学网络最有效的方式是抓两件贯穿始终的事:一是数据的封装与拆封,二是每一层解决什么问题。物理层解决比特怎么在介质上传输;数据链路层解决相邻节点之间怎么可靠地传帧;网络层解决跨网络寻址和路由;传输层解决端到端的可靠通信或高效通信;应用层解决具体业务协议(HTTP、DNS、FTP、SMTP等)。
6.2 IP地址、子网划分、CIDR
IPv4地址这块,最大的坑是“计算子网掩码”和“可用主机数”。一个C类网络(默认掩码255.255.255.0)最多有256个地址,但可用地址要减去网络地址和广播地址两个,所以是254个。这个“减2”法则在各种变长子网划分中都要用。
子网掩码的作用,是把IP地址拆成“网络号 + 主机号”。计算网络地址的经典方法:IP地址和子网掩码按位做“与”运算。CIDR(无类域间路由)写作如 192.168.1.0/26,斜杠后的26表示网络号占26位,主机号只剩6位,可用主机数是 2⁶ - 2 = 62个。考试中出现“给定IP和掩码,算出该网段的网络地址、广播地址、可用主机范围”这类题时,我建议一定按二进制老老实实算一遍,不要依赖经验猜测。
6.3 TCP与UDP的区别,TCP三次握手为什么是三次
TCP与UDP是传输层两大主角。TCP提供面向连接的可靠字节流服务,有确认、重传、排序、流量控制;UDP是无连接、不可靠、低延迟的数据报服务。选择哪个协议,本质上是在“可靠性”和“效率”之间做取舍:文件传输、网页浏览要TCP;实时音视频、DNS查询要UDP。
三次握手的过程我就不重复默写了,我想重点聊一句:为什么握手要三次,而不是两次或四次?最经典的解释是,两次握手无法确认接收方的接收能力和发送能力都没问题。客户端发SYN、服务器回SYN+ACK、客户端再回ACK,这样双方都确认“我能发、我能收、对方能收、对方能发”。如果只有两次,服务器无法确定自己发的SYN+ACK是不是被客户端正确收到了;如果四次又多余,因为第三次ACK已经足够建立双向通道。
6.4 DNS解析过程、HTTP协议要点
DNS是把域名解析为IP地址的分布式系统。完整解析流程一般是:浏览器缓存 → 操作系统缓存 → 本地DNS服务器(递归查询) → 根DNS服务器 → 顶级域DNS服务器 → 权威DNS服务器。考试常考递归查询和迭代查询的区别:递归查询是“对方帮我查完再告诉我结果”,迭代查询是“对方告诉我下一步该找谁”。
HTTP协议重点在于无状态、请求-响应模型、常见状态码。状态码中最容易混淆的几组:301永久重定向 vs 302临时重定向;403禁止访问 vs 404未找到;500服务器内部错误 vs 503服务不可用。做Web开发时排查故障,第一步永远先看状态码,这会省掉大量时间。顺便说一句,HTTP是无状态协议,因此才需要Cookie/Session机制来维持会话状态,这个考点经常和Web开发基础连在一起考。
7. 数据管理与算法:计算机的“组织”与“计算”能力
7.1 数据结构的核心:线性表、树、图
数据结构部分,我认为重点是理解每种结构的“适用场景”和“增删改查代价”,而不是背代码实现。
| 结构 | 优点 | 缺点 | 典型场景 |
|---|---|---|---|
| 顺序表(数组) | 随机访问O(1) | 插入删除需要大量移动元素 | 查找频繁、大小固定的数据 |
| 链表 | 插入删除O(1)(已知位置),动态扩容 | 随机访问O(n) | 频繁增删、大小不可预知的场景 |
| 栈 | 后进先出 | 只能操作栈顶 | 函数调用、表达式求值、括号匹配 |
| 队列 | 先进先出 | 只能两端操作 | 任务调度、缓冲区、广度优先搜索 |
| 二叉树/二叉搜索树 | 查找/插入/删除平均O(log n) | 退化可能到O(n) | 动态有序数据查找 |
| 哈希表 | 查找/插入/删除平均O(1) | 冲突处理、无序 | 快速查找、缓存 |
二叉搜索树的退化问题值得展开。当插入数据恰好有序时,二叉搜索树会退化成一条链表,查找复杂度从O(log n)变成O(n)。所以才有平衡二叉树(AVL)、红黑树等改进方案。考试中经常问“AVL树和二叉搜索树的区别”,核心答案就是平衡因子限制,确保任意节点的左右子树高度差不超过1。
7.2 排序算法怎么选:稳定性和复杂度都要看
排序算法的考点集中在“时间复杂度、空间复杂度、稳定性”。稳定性的定义是:如果两个相等的元素,排序后相对顺序不变,则该排序算法是稳定的。
我建议用一张表记核心结论:
| 算法 | 平均时间复杂度 | 最好情况 | 最坏情况 | 空间复杂度 | 稳定性 |
|---|---|---|---|---|---|
| 冒泡排序 | O(n²) | O(n) | O(n²) | O(1) | 稳定 |
| 插入排序 | O(n²) | O(n) | O(n²) | O(1) | 稳定 |
| 选择排序 | O(n²) | O(n²) | O(n²) | O(1) | 不稳定 |
| 快速排序 | O(n log n) | O(n log n) | O(n²) | O(log n) | 不稳定 |
| 归并排序 | O(n log n) | O(n log n) | O(n log n) | O(n) | 稳定 |
| 堆排序 | O(n log n) | O(n log n) | O(n log n) | O(1) | 不稳定 |
有两个进阶理解值得记录。一是为什么快速排序最坏情况是O(n²)?因为当每次选中的基准都是当前区间最大或最小值时,划分极不均匀,递归深度会退化为n。优化方式是随机选基准或取三数取中。二是为什么归并排序需要O(n)额外空间?因为它合并两个有序数组时不能在原数组上直接原地合并,必须借用临时数组。
7.3 算法复杂度:大O记号别死记,要会算
很多同学分不清O(1)、O(log n)、O(n)、O(n log n)、O(n²)对应的实际增长速度。建议在你脑子里形成一幅比例感:当n从1000增加到10000(10倍)时,O(n)耗时也增加10倍,O(n²)增加100倍,O(n log n)约增加10倍多一点。这种数量级直觉在做题和工程决策里都非常有用。
计算递归算法复杂度是另一个难点。经典例子是二分查找的复杂度。二分查找每轮把规模减半,所以执行次数是log₂n,复杂度O(log n)。而菲波那契数列的朴素递归,T(n)=T(n-1)+T(n-2)+O(1),用主定理或画出递归树都能看出是O(2ⁿ)指数级增长——这也是为什么实际项目里必须用迭代或备忘录优化,而不是直接递归。
7.4 数据库:从ER模型到SQL
数据库的核心考点有两个:关系模型和SQL基本操作。ER模型的三要素是实体、属性、联系,联系有三种类型:一对一、一对多、多对多。将ER图转换为关系模式时,有一条基本规则:多对多联系必须新建一张关系表,这张表通常包含双方的主键作为外键,再加上联系自身的属性。
SQL方面,最容易被混淆的是DELETE和DROP的区别:DELETE删除数据但保留表结构,可以回滚;DROP直接删除表结构和数据,不可恢复。还有一个高分考点是连接查询:内连接(只返回两边都匹配的行)、左外连接(返回左表所有行,右表无匹配则补NULL)、右外连接、全外连接。做题时先看“以哪张表为准”,再去想NULL怎么补,错误率会下降很多。
8. 复习节奏与实战建议:这样安排效率最高
8.1 三轮复习法,把知识过够三遍
计算机概论的内容覆盖面太大,一轮就想全部记住基本不现实。我比较推荐三轮复习:
第一轮重“理解框架”:先不管细节,把“数制与编码 → 硬件 → 指令 → 操作系统 → 网络 → 数据与算法”这条主线走一遍。目的是建立宏观地图,知道每章在哪个位置、前后有什么关联。本轮建议配教材目录做思维导图,不要把时间耗在单个难点上。
第二轮重“攻克重点”:针对高频考点深入强化,比如补码运算、浮点数规格化、Cache映射、进程调度、TCP三次握手、子网划分、排序算法稳定性。这一轮要大量刷题,尤其是计算类题目,每类题至少亲手算10道,算到形成肌肉记忆。
第三轮重“查漏补缺”:做模拟卷或历年题,把错的题对应到知识点,回到教材补这一块。同时把容易混淆的概念集中整理成对比表,比如进程和线程、TCP和UDP、路由器与交换机、内连接与左连接。
8.2 必须亲手算的几类题目
根据我个人的参考经验,以下题型值得你反复练习。它们是考卷上的常客,也是理解的试金石:
- 进制转换综合题:包含整数、小数、负数,各种进制互转。
- 补码运算题:给定8位补码,计算加减法,并判断溢出。
- 浮点数规格化题:给定十进制数,写出32位IEEE 754存储形式。
- 流水线性能题:给定k级流水线和n条指令,计算加速比和吞吐率。
- 进程调度题:给定进程到达时间和服务时间,计算FCFS、SJF、RR的周转时间与平均等待时间。
- 虚拟内存地址题:给定页大小和虚拟地址,计算物理地址,判断是否缺页。
- 子网划分题:给定IP和掩码,计算网络地址、广播地址、可用主机范围。
- 二叉树遍历题:已知前序和中序,推出后序;或已知中序和后序,推出前序。
- 排序过程题:手写一趟快排或归并的过程,并判断稳定性。
8.3 考前一周的冲刺策略
考前一周不建议再学新内容,重心应该放在“错题重做”和“高频公式默写”上。比如补码的表示范围、Cache的三种映射方式、TCP报文段的标志位、子网掩码速算表这些内容,建议每天默写一遍。
另外要提醒的是,计算机概论的考试往往不只是考记忆,更多是考“能不能把知识联系起来”。比如问你“程序运行过程中,从硬盘读取数据到CPU缓存,涉及了哪些知识点”,你需要把磁盘I/O、DMA、内存管理、Cache、指令流水线全部串起来回答。这种综合题才是真正的拉分题,建议复习时多练习“以某个场景为线索,把多个章节的知识串起来”。
我个人在复习过程中还有一个习惯:把每一章的标题改写成“问题”。比如把“处理器”改为“CPU是如何执行一条指令的?”,把“虚拟内存”改为“为什么程序可以超过物理内存运行?”。带着问题去看书,比漫无目的地从头翻到尾高效得多。
9. 计算机概论复习中的高频疑点快查
9.1 概念容易混淆的地方
复习到最后阶段,你会发现自己真正搞不清的不是复杂计算,而是那些“长得很像、用法不同”的成对概念。我整理了复习中最高频的几组,建议对照自查:
- 原码 / 反码 / 补码 / 移码:本质区别在于对符号位的处理和零的表示方式。补码中0只有一种表示,所以能多表示一个负数(比如8位是-128)。
- 进程 / 线程:资源分配单位 vs CPU调度单位。
- 并发 / 并行:并发是逻辑上同时发生(交替执行),并行是物理上同时执行(多核)。
- 路由器 / 交换机:路由器工作在网络层,根据IP地址转发;交换机主要工作在数据链路层,根据MAC地址转发。三层交换机则是同时具备两者能力的设备。
- 栈 / 堆:栈用于函数调用,后进先出,由编译器管理;堆用于动态内存分配,由程序员/运行时管理。
- 同步 / 异步:同步是等待结果返回再继续,异步是不等待、通过回调或事件通知来获取结果。
- 内连接 / 外连接:内连接只返回匹配行,外连接保留一边或两边的所有行。
- 死锁 / 饥饿:死锁是多个进程互相等待,都不前进;饥饿是一个进程长时间得不到所需的资源,但其他进程可以继续推进。
9.2 计算类题目的速查公式
把零散公式集中起来,考前反复看,是我的最后一招。这些公式基本覆盖了计算机概论最难的几类计算题:
- 二进制位数与表示范围:n位无符号数范围 0 到 2ⁿ-1;n位补码范围 -2ⁿ⁻¹ 到 2ⁿ⁻¹-1。
- 地址位数与可寻址空间:可寻址字节数 = 2^(地址总线宽度)。
- Cache容量:容量 = 块大小 × 组数 × 每组行数,行内偏移位数 = log2(块大小)。
- 流水线执行时间:k级流水线执行n条指令的理论时间 = (k + n - 1) × 时钟周期。
- 虚拟地址与物理地址:页内偏移位数 = log2(页大小),虚页号位数 = 虚拟地址位数 - 页内偏移位数。
- 子网可用主机数:2^主机号位数 - 2。
- 平均周转时间 = 各进程(完成时间 - 到达时间)之和 ÷ 进程数。
- 比特率换算:1 Byte = 8 bit,网络带宽通常按bit/s计算,下载速度通常按Byte/s计算。所以100Mbps带宽的理论下载速度是12.5MB/s。
9.3 冲刺阶段的心态和体力建议
说一句不太像考点但很重要的题外话:计算机概论内容多、知识点碎,最后两周拼的其实是体力分配。大脑在连续高负荷记忆后的效率会明显下降,所以保持每天7小时以上的睡眠、每学习90分钟活动10分钟,比多刷一套题带来的收益更大。另外建议睡前回忆“今天复习的章节讲了几个核心问题”,这种主动回忆比睡前刷手机强得多。
我自己当年复习到后期最大的感受就是:这门课其实是一个很大的拼图,每个知识点都是一块碎片。单独看某一章,觉得零散无趣;全部拼起来以后,你会发现计算机系统的运转逻辑清晰得像一条流水线。把这个图景印在脑子里,哪怕某些细节忘了,你也能用自己的逻辑把它推理出来。这也是计算机概论作为第一门专业基础课,真正想教会我们的东西。