期末季、测评周一到,计科和软工的同学最怕的不是概念默写,而是一堆“计算实例”:时间复杂度的推导、页面置换的缺页次数、子网掩码的主机数、PERT三点估算……这些题看着不难,但一上手总会漏步骤、记混公式、算错单位。这篇整理就是把我在计科、软工课程里反复踩过的计算题考点集中梳理一遍,帮你建立一套“看到题目就知道算法流程”的解题模板,无论是期末复习、考研408、软考还是面试刷题,都能直接拿来做参考。
这篇内容覆盖两个方向:计科更偏底层机制,像组成原理、操作系统、网络协议中的计算;软工更偏工程度量,像功能点估算、进度网络、质量指标。我会把每个高频计算场景拆成:考点在考什么、标准解题步骤、我亲身踩过的坑。最后再分享一套我整理计算题用的“一页纸清单法”,适合考前快速过一遍。
1. 计科与软工的计算题到底在考什么
1.1 计科方向的高频计算场景
计算机科学与技术专业(也就是标题里的“计科”)的计算题,核心从来不是考数学,而是考“机制理解”。比如进制转换、补码运算,背后是CPU里数据怎么存储;页面置换算法,背后是虚拟内存的管理策略;子网划分,背后是IP地址的编址规则。所以解题时别急着套公式,先把机制流程走一遍,答案自然就出来了。
计科常见高频计算包括:
- 数据结构:时间复杂度、空间复杂度、哈希表平均查找长度、图的最短路径与关键路径
- 计算机组成原理:进制转换、补码/反码/原码、IEEE 754浮点数、数据的定点表示范围
- 操作系统:页面置换缺页次数、磁盘调度平均寻道长度、银行家算法安全序列、信号量同步问题
- 计算机网络:IP子网划分、CRC校验、信道容量、传输时延计算
另一个容易忽略的点是:计科计算题特别喜欢连环设坑,第一步算错后面全错。所以我在后面每一节都强调“先判断模型,再动手算”,这是计科制胜的关键习惯。
1.2 软工方向的高频计算场景
软件工程(也就是标题里的“软工”)方向的计算题,核心是“工程权衡”。它不会让你去算CPU时钟周期,而是让你在需求不确定的情况下,估算出一个项目的工作量、工期、成本,甚至要在“提前交付”和“质量稳定”之间做取舍。
软工常见高频计算包括:
- 工作量估算:代码行估算、功能点估算、COCOMO模型
- 进度管理:PERT三点估算、标准差与概率计算、关键路径工期
- 质量度量:软件缺陷密度、测试覆盖率、千行代码缺陷率
- 工程决策:模块内聚与耦合的级别判断、内聚/耦合对比排序
这类题目最大的特点是没有“唯一答案”,但评分标准很清晰:看你有没有把估算公式用对、有没有把影响因子考虑进去。软工方向的同学经常觉得计算题“太虚”,我的经验是:把它当成判断题来练,反而更容易拿分,核心是识别题目属于哪个分析场景。
1.3 为什么“整理”比“盲目刷题”更重要
我见过太多人复习计算题的方法是“狂刷题”,一套卷子两套卷子从头做到尾。但真实考试里,大部分计算题是换数字不换模型。你把“广度优先遍历”的时间复杂度搞明白,不管它链式存储还是邻接矩阵存储,都能推导;你把“页面置换FIFO”的流程画出来,不管它内存是3块还是5块,缺页数都能算对。所以整理比刷题重要得多。
我个人的整理方法是把计算题分成三个维度:模型、流程、易错点。模型就是“这是什么类型的题”,流程就是“标准的解题步骤”,易错点就是“我曾经在哪里丢过分”。比如看到“给定访问序列和内存块数,求缺页次数”,第一反应不是“这题我会”,而是“我先固定流程:画行数、逐列填状态、置换时标记”。考试时你其实在默写流程,而不是临场分析。
另外推荐大家用表格代替大段抄写。一页A4纸,左边一列写标准步骤,右边一列写这个步骤最容易踩的坑。考前只看右边那列,效率非常高。后面第6章我会给出具体版式。
2. 数据结构与算法:最经典的计算实例
2.1 时间复杂度推导:找循环变量变化规律
时间复杂度计算是计科和软工共同的“第一道门槛”,也是很多同学丢分最多的地方。原因很统一:只知道大O表示法,不知道如何分析循环次数。
我的核心解法是先看循环变量的变化方式。最简单的是单层循环,变量每次加1,循环体执行n次,复杂度就是O(n)。但考试喜欢考嵌套循环和变量指数增长。
举个典型例子:
int i = 1; while (i < n) { i = i * 2; }i的取值是1、2、4、8……直到超过n,所以循环执行次数约等于log2(n)。时间复杂度就是O(log n)。
再来一个更容易错的:
int sum = 0; for (i = 1; i <= n; i = i * 2) { for (j = 1; j <= i; j++) { sum++; } }如果只看内外层,容易以为复杂度是O(n log n),但其实不对。内层循环执行次数是1+2+4+8+…,直到接近n,总和大约是2n-1,所以整体时间复杂度是O(n),不是O(n log n)。
我当年就在这里栽过跟头,所以建议:凡是外层变量跳变的,先把循环次数列成序列,再求总和。还有递归式复杂度,比如T(n)=2T(n/2)+n,直接套主定理,结果是O(n log n)。主定理不需要背证明,只需要记住三种形态:递归增长速度、额外工作增长速度、n的几次方。考试时间有限,能快速判断就快速判断。
2.2 哈希表装载因子与平均查找长度:先定位再算账
哈希表计算题考察的是“冲突处理”和“查找长度”两个概念。记住一个前提:平均查找长度不是装元素个数越少就越短,它和装载因子、冲突处理方式强相关。
装载因子公式是:α = 表中元素个数 / 表长。考试大概率会问平均查找长度ASL。
我以线性探测法为例给一个完整流程,题目是:散列表长为11,H(key) = key % 11,依次插入关键字序列:22、44、9、30、12,求查找成功的平均查找长度。
第一步:依次计算哈希地址。
- 22 % 11 = 0,位置0为空,直接放入,查找长度是1
- 44 % 11 = 0,冲突,线性探测到位置1,放入,查找长度是2
- 9 % 11 = 9,位置9为空,直接放入,查找长度是1
- 30 % 11 = 8,位置8为空,直接放入,查找长度是1
- 12 % 11 = 1,位置1被44占用,探测到2,放入,查找长度是2
所以查找成功的ASL = (1 + 2 + 1 + 1 + 2) / 5 = 1.4。
这里有个特别容易错的点:查找失败的ASL计算方式完全不同。考试若问“查找失败平均查找长度”,公式是:对所有散列位置(0到10,共11个位置)都试一遍,若查找某个位置,一直比较到空位才算失败,把每个位置探测的比较次数加起来,再除以11。
比如位置0被22占用,线性探测到1,1被44占用,探测到2,2被12占用,再探测到3,3为空,需要比较4次,所以位置0的失败比较次数是4。位置1开始,探测到2、3空,需要比较3次;位置8开始,8有30,9有9,10空,需要比较3次;位置10开始,直接空,比较1次。把所有位置的失败比较次数加起来再除以11。
我个人的记忆口诀是:“查找成功看已装元素,查找失败看所有槽位”。
2.3 图计算:最短路径与关键路径
图的两类计算题应该分清楚:最短路径考的是“松弛更新”,关键路径考的是“事件时间”。
Dijkstra算法手算时,我推荐用表格法。维护一个集合S(已确定最短路径的节点)和每个节点的当前最短距离,每次从集合外选距离最小的加入S,然后更新它邻居的距离。有一个常见错误:选最小的距离时直接把值抄上去,忘了“松弛”操作,这样的表格数据不完整,容易被扣步骤分。
举个简单例子,节点1到2、3、4,初始dist[1]=0,dist[2]=7,dist[3]=3,dist[4]=∞。第一次选3,然后尝试从3到4,如果dist[3]+4=7,小于∞,更新dist[4]=7,这就是松弛。表格写清楚“当前最小值、更新来源、是否更新”,一目了然。
关键路径的计算稍微抽象,但本质是:先求每个事件的最早发生时间(正推,取最大);再从汇点反推每个事件的最迟发生时间(逆推,取最小);最迟最早相等的事件就是关键事件。连接关键事件的路径就是关键路径,项目总工期就是汇点的最早时间。
有一年我帮忙辅导学弟,他总在“正推取最大、逆推取最小”这个点上记反。我给了一个生活类比:最早开始时间就是“所有前序工作都完成的最早可能时间”,所以必须等最慢的前序完成,取最大;最迟开始时间就是“不影响后续工作的最晚时间”,所以要看后续最紧迫的那条,取最小。这样一解释,再没记反过。
3. 计算机组成与操作系统里的硬核计算
3.1 进制、补码与浮点数:每一步都不能跳
计科复习绕不开进制转换、补码和浮点数。这三类题的共同特点是:步骤多、符号位多,任何一步省略都容易出错。
进制转换没什么难的,重点是多练习查错。比如十进制转二进制,整数部分除2取余,小数部分乘2取整。我强调一句:如果题目给小数,转换后做到题目要求的精度即可,不要无限算下去。
补码的考点有两个:一是范围,二是由补码求真值。n位补码能表示的范围是[-2^(n-1), 2^(n-1)-1]。比如8位补码范围是-128到127,很多同学会问为什么不是-127到127,原因是补码的0只有一种表示,节省出来的全1编码可以多表示一个-128。
由补码求真值,注意最高位是符号位。负数的补码要转原码,方法是“符号位不变,其余按位取反,末位加1”。有个更快的技巧:从右往左找到第一个1,这个1左边(除符号位外)全部取反,右边不变。考试时这个方法写草稿非常快,但最后卷面上还是建议写标准步骤,避免阅卷老师看不懂。
IEEE 754单精度浮点数计算是我见过最整齐的题型。格式是:1位符号位、8位阶码、23位尾数。阶码用移码表示,偏移量是127。
实际计算时,先把十进制数转成二进制,再写成“1.xxx × 2^e”的规格化形式,阶码部分存的是e+127的二进制,尾数部分存去掉整数位的1之后的23位。
比如-12.75这个例子:
- 12.75转二进制:1100.11
- 规格化:1.100011 × 2^3
- 符号位:1(负数)
- 指数:3+127=130,二进制10000010
- 尾数:100011后面补0到23位
最终拼接起来就是完整的32位表示。这个流程我会反复和学生强调:千万别忘了偏置值127,也别忘把整数位的1隐去再存尾数。
3.2 页面置换算法:OPT/FIFO/LRU手算的通用套路
页面置换的可考点非常固定:给一个页面走向序列,给内存块数(页框数),要求计算缺页次数或缺页率。这是典型的“流程题”,矩阵画对,步骤走对,基本就满分。
我自己手算的格式是:每一行代表一个页框,每一列代表一次访问。访问某个页时,如果命中,不改变状态;如果缺页,就发生置换。
FIFO最简单:页面按进入内存的先后排队,谁先进来谁先被换出。注意它可能出现Belady异常——内存块数增多缺页反而增多。遇到这个概念题,一定举出反例。
LRU稍微复杂,需要判断“最久未使用”。我推荐用时间戳法:每访问一个页面,把该页设置为“最近使用”,其他页面如果未使用,时间戳递增。替换时找时间戳最大的那页。这样手算清晰,不会瞎猜。
OPT最难,因为需要预知未来:替换时看当前时刻之后,哪个页面最长时间不被使用,就换掉它。计算时先往后扫描访问序列,找到每个候选页面下一次出现的位置,选“下一次出现位置最远”的换出。
给大家一个可练的简单序列:7 0 1 2 0 3 0 4,内存3块。前3次7、0、1都缺页装入。访问2时内存满了,FIFO换出7,LRU也换出7(因为7最远未用),OPT也应换出7(因为7后续不出现)。从第5次开始不同算法的差异就出来了。同学们自己画一遍就能理解,“命中”和“缺页”的区别不是看页面在不在内存,而是看当前访问前页面是否已经被装入。
3.3 磁盘调度:平均寻道长度计算的边界判断
磁盘调度也是高频计算题,核心是“顺序”和“方向”的问题。常见算法有FCFS(先来先服务)、SSTF(最短寻道时间优先)、SCAN(电梯算法)、C-SCAN(循环扫描)。
我以标准例题来看解法。假设当前磁头在53磁道,请求队列顺序是98、183、37、122、14、124、65、67,用FCFS计算平均寻道长度:
- 53到98,移动45
- 98到183,移动85
- 183到37,移动146
- 37到122,移动85
- 122到14,移动108
- 14到124,移动110
- 124到65,移动59
- 65到67,移动2
总移动距离=45+85+146+85+108+110+59+2=640,平均寻道长度=640/8=80。
SCAN的重点是方向。题目可能说“向磁道号增大方向移动”,也可能说“从当前位置向小的方向”。还有一种常见问法:当前磁头正在向某个方向移动,问电梯算法会先服务哪些请求。这里注意SCAN是一路走到最远端再反向,而C-SCAN只走到一个方向的端点后直接回到起点,然后再扫描。很多人把C-SCAN的“回程不服务请求”这个特点忽略掉,导致计算结果差很多。
我建议手算SCAN时先画一条磁道坐标轴,标出当前磁头位置、请求位置、磁盘两端(0和最大磁道号),再用箭头表明移动方向。这样每段距离可以直接数格子,不容易漏算。
4. 计算机网络里的“算分题”
4.1 IP地址与子网划分:三步算出可用主机数
子网划分是网络部分最常出的计算题,掌握了套路,这类题基本是送分题。标准解法就三步:找网络号、找广播地址、算可用主机数。
第一步,把IP地址和子网掩码转成二进制,按位做“与”运算得到网络地址。比如192.168.1.37/26,斜线后的26表示子网掩码前26位是1,后6位是0。转换成点分十进制就是255.255.255.192。
37的第四字节二进制是00100101,192的二进制是11000000,两者按位与得到00000000,所以网络地址是192.168.1.0。
第二步,把主机位全部置1得到广播地址。主机位是第四字节后6位,直接算64-1=63,所以广播地址是192.168.1.63。
第三步,可用主机数 = 2^(32-26) - 2 = 2^6 - 2 = 62。减2是因为网络地址和广播地址不能分配给主机。
划分多个子网时道理一样。比如一个C类网络192.168.1.0需要划分成5个子网,每个子网有接近相同的主机数,这时候借3位主机位作为子网号,子网掩码变成/27,每个子网可用主机数为2^5-2=30。很多同学会问“5个子网不是需要3位吗,但3位可以表示8个子网,够用了”。对,借位按2的幂来算,能满足需求的最小借位数就是3位。
4.2 CRC校验:模2除法一步步算
CRC(循环冗余校验)计算题常以“给定信息位和生成多项式,求码字”的形式出现。解题流程非常固定:先在信息位后面补R个0,R等于生成多项式最高次数;然后用生成多项式对应的二进制串,对补零后的数据做模2除法;最后得到的余数就是CRC校验码,把校验码替换补的0位置,得到发送码字。
这里强调“模2除法”不是普通除法:不借位、不比较大小,每位做异或运算。同一位上相同为0,不同为1。
举个例子,信息位是1011001,生成多项式G(x)=x^4+x^3+1,对应二进制是11001,最高次数是4,所以先在信息位后补4个0,得到10110010000,然后做模2除法。
除法流程:取前5位10110,和11001异或得到01111,丢掉最高位,把下一一位拉下来,变成11110,再和11001异或,得到00111;继续拉低位……直到把补的4个0处理完。最终余数就是校验码。
我提醒你一个最容易翻车的点:余数的位数必须等于生成多项式的最高次数。如果余数位数不足,前面补0。发送时信息位和校验码合并,接收端用同样的生成多项式再次做模2除法,如果余数为0,就认为传输没有出错。
如果考试给的是十六进制或八进制,先转成二进制再算,不要直接按十进制做异或,很容易算错。
4.3 信道容量与传输时间:公式套用技巧
网络部分还有个必考考点是信道容量和传输时延计算。奈奎斯特公式C=2W log2(V),用于无噪声信道,带宽为W,信号电平数为V。香农公式C=W log2(1+S/N),用于有噪声信道,S/N是信噪比。
这里有一个高频陷阱:题目给信噪比30dB,实际S/N=1000。换算公式是dB值 = 10log10(S/N),所以30dB对应S/N=1000。很多人直接在公式里写30,结果差几个数量级,白白丢分。
传输时延计算同样需要细心。1MB文件在10Mbps链路上传输,理论时间不是1秒,因为1MB是1M字节,1Mbps是1M比特每秒,所以先把文件大小换算成比特:1MB=1×1024×1024×8≈8388608bit,除以10Mbps约0.839秒。考试如果标的比较严格,一般按1MB=1000KB来算也可以,但要在草稿上写清楚换算过程,避免单位不统一。
我还想补充一个常见变体:分组交换传输时间计算。总时延 = 发送时延 + 传播时延 + 处理/排队时延。发送时延 = 数据大小/带宽,传播时延 = 距离/传播速率。考试经常把距离、光速给出来,让你计算。这类题本身不难,错就错在单位,比如km和m、毫秒和秒没统一。
5. 软件工程里的估算与度量计算实例
5.1 代码行与功能点估算:从需求到人月
软工计算题里,工作量估算出现的概率极高。代码行估算常用的是“三点估算”思路:对每个模块分别估计最乐观(a)、最可能(m)、最悲观(b),然后加权平均,期望值 = (a + 4m + b) / 6。这是PERT里的经典公式,用在这里做LOC估算也成立。
举个例子:某个模块最乐观500行,最可能800行,最悲观1500行,那么期望代码行 = (500 + 4×800 + 1500) / 6 = 900行。如果一个人日均产出150行,那么这个模块需要6人日。再结合人力成本,就可以折算成项目预算。
功能点估算更贴近业务视角。基础步骤是:识别五类功能——外部输入、外部输出、外部查询、内部逻辑文件、外部接口文件,分别按照复杂度打分。标准权重表要熟悉,比如外部输入低复杂度3、平均4、高复杂度6;外部输出低4、平均5、高7;外部查询低3、平均4、高6。把每个功能数量和对应权重相乘再求和,得到未调整的功能点。
然后还需要乘一个调整因子。调整因子 = 0.65 + 0.01 × ΣDI,其中DI是14个通用系统特性(数据通信、分布式处理、性能要求等)的影响程度,每个取值范围0到5。如果项目分布式要求高,DI总和就大,调整后功能点会增加。这个调整因子是整个功能点计算里最容易被忽略的,千万要注意。
5.2 PERT三点估算与进度工期:概率题也别怕
PERT计算在软工试卷中非常常见,而且一旦考到往往是“送分题中的送分题”。平均活动工期 = (乐观时间 + 4×最可能时间 + 悲观时间) / 6,标准差 = (悲观时间 - 乐观时间) / 6。
如果一个活动的乐观时间是2天,最可能4天,悲观6天,那么平均工期=(2+16+6)/6=4天,标准差=(6-2)/6≈0.67天。
如果整个关键路径由多个活动串联,项目总工期的期望 = 各关键活动期望之和,项目总标准差 = 各关键活动方差之和再开平方。注意这里是“方差和的平方根”,不是标准差直接相加。很多人在这里图省事直接相加,被扣分很冤。
概率部分的核心是记住正态分布比例:工期在期望值±1个标准差的概率约68%,±2个标准差约95%,±3个标准差约99.7%。题目问“项目在多少天以内完工的概率是多少”时,先算期望工期、标准差,再判断目标值处于第几个标准差区间。比如期望18天,标准差2天,问20天内完工概率:20天 = 18 + 2 = 期望+1σ,对应概率是50%+34%=84%。
我做软工题目时,会把“概率”两个字标在题号旁边,提醒自己先把标准差算出来。因为概率题和普通工期题混在一张卷子里时,很容易只算平均数就收手。
5.3 内聚与耦合的判断:不是算数但考逻辑
你可能觉得内聚和耦合不是计算题,但在很多软工试卷里,它们会以“判断以下模块关系属于哪类内聚/耦合”的形式出现,本质上和计算题一样需要“推理+排错”。
内聚度从低到高排列是:偶然内聚、逻辑内聚、时间内聚、过程内聚、通信内聚、顺序内聚、功能内聚。耦合度从低到高排列是:非直接耦合、数据耦合、标记耦合、控制耦合、外部耦合、公共耦合、内容耦合。
考试常用题型是给两个模块调用关系,让你判断耦合类型。比如模块A把数组整体传给模块B,B只使用其中一部分,这是标记耦合;如果A传一个参数,B直接根据参数跳转不同分支,这是控制耦合;如果A和B都访问同一个全局变量区,这是公共耦合。
我的判断口诀是:直传数据是数据耦合,传数据结构是标记耦合,传标志位是控制耦合,共享全局数据是公共耦合,直接修改对方内部数据是内容耦合。
这类题不需要算数字,但需要快速排序。考前把“内聚从低到高、耦合从低到高”各背一遍,再把典型场景对应上去,基本就稳了。
6. 整理这些计算实例的实操心得
6.1 我的清单整理法:一页纸一个模型
回到标题里的“整理”二字。我做了这么多年复习资料,发现最有用的方式不是抄题,而是做一个“一页纸模型清单”。
具体做法是:每类计算题占一页A4纸,分成三列。第一列写适用场景,也就是看到哪些关键词用这个模型;第二列写标准步骤,用1、2、3编号;第三列写易错点,只写自己或别人经常丢分的地方。
举个例子,页面置换这一页纸,第一列写“缺页、页框、页面走向、缺页率”;第二列写“画表、逐列判断、置换标记、统计缺页”;第三列写“判断命中后再算缺页、OPT要往后看多次、FIFO注意Belady异常”。考前半小时只看第三列,比重新推一遍整个流程省时间得多。
我还会把公式做成“指令卡”。像信道容量、平均工期、功能点调整因子,每个公式配两个数字例子,这样看到题目直接知道套哪个公式。千万不要把公式抄完就完事,那样等于没整理。
6.2 两周刷题节奏:从识别题型到限时模拟
计算题复习不能一把抓,我建议考前两周按节奏推进。
第一周按章节做分类训练,每天只练一到两类计算题。比如周一做哈希查找和页面置换,周二做IP划分和CRC,周三做PERT和功能点,周四再回头做错题。分类训练的核心是让自己“看到题干关键词就立刻反应出模型”。
第二周开始混刷,就是把不同科目的题混合在一起限时做。计科和软工的同学可以在真题或模拟卷里选15-20道计算题,限时50分钟完成,模拟真实考试节奏。混刷有两个好处:一是训练题型切换能力,避免上一题是补码、下一题是子网时脑子转不过来;二是暴露自己的“知识盲区”,比如你会算PERT但不会判断关键路径,那第二周就要重点补。
我在辅导时常见的问题是:很多人刷题只求算对结果,不写中间过程。计算题都是按步骤给分的,就算结果错了,只要步骤对,也能拿大半分。所以平时训练就按考试标准写,养成“每一步都写清依据”的习惯。
6.3 答题细节:这些坑我踩过不止一次
最后分享一些我在考试和实操中反复踩过、也帮别人纠正过的细节。
第一个坑是单位换算。网络带宽是Mbps,文件大小经常是MB,每秒传输字节数要除以8。操作系统里磁盘大小有时用KB有时用扇区数,题目明明给了512字节扇区,算总容量时漏乘512的人不在少数。
第二个坑是浮点数阶码偏置值。算IEEE 754时很多人用“阶码=真实指数”直接转二进制,忘记加127。负数时更明显:-12.75的阶码是3+127=130,如果忘记加偏置,结果完全不对。
第三个坑是哈希查找失败ASL的分母。有人除以已插入元素个数,正确的是除以散列地址空间大小(表长或地址位数对应的可能值总数)。这个一错,整题白算。
第四个坑是页面置换缺页计数的起点。题目说“内存开始为空”,那前几个页面装入时算不算缺页?多数参考书把前几次也算缺页,但有些题目自己定义了“初始已装入”,你要认真读题。我的建议是哪怕前几次算缺页,也在草稿上标注“初始缺页”,让阅卷老师看到你清楚这个边界条件。
第五个坑是PERT标准差的加法。多个活动组合的方差等于各自方差之和,标准差不是相加。一个活动的标准差是1天,另一个也是1天,总工期标准差是√(1²+1²)≈1.414天,不是2天。
这些细节单独拿出来都不难,但混在高压考场里特别容易疏忽。我把它们记在“一页纸清单”的第三列,考前瞄一眼,比刷十道题还有用。
在我自己的复习和带教经验里,计算题真的是软件工程、计科专业性价比最高的分数来源。只要把模型的适用场景判断清楚,把步骤按固定流程走,再把易错点背熟,大部分题都能稳定拿分。后面如果你在复习时碰到具体的计算题不知道从哪里下手,可以拿这份整理里的流程对照一遍,大概率能排查出问题所在。