news 2026/10/27 12:05:14

软考软件设计师考点笔记:数据结构、排序查找与编码速查

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
软考软件设计师考点笔记:数据结构、排序查找与编码速查

简介:面向备考软考中级软件设计师的考生,这份考点笔记精华版以docx单文件形式整理,聚焦高频核心知识与易错难点,适合冲刺阶段系统复盘与查漏补缺。压缩包内共1个docx文件,整体约3.37MB,内容按数据结构、查找方法、排序算法等模块展开,便于在电脑端检索和标注。笔记结合例题梳理邻接矩阵在无向图、有向图中的度与出入度计算,比较顺序、链式、散列与索引存储结构的适用场景,并串讲满二叉树、平衡二叉树、哈夫曼树及WPL计算。查找部分覆盖二分查找、分块查找的适用条件与平均查找长度,排序部分则汇总直接插入、简单选择、冒泡、希尔、快速、堆、归并、基数排序的思路,并用表格对比时间复杂度、辅助空间与稳定性。已有382人学习,适合需要快速建立知识框架、针对公式和易错点反复记忆的考生使用。

1. 为什么一堆「树和图」的笔记能救命:软考中级在考什么

打过牌的人都懂,抓一手散牌时最怕的不是牌差,是不知道该往哪个方向组。翻开软件设计师的真题集,第一感觉也差不多:前一题问图的邻接矩阵,后一题问冒泡排序的时间复杂度,再下一题突然跳进原码补码和指令寻址,像是从三本书里随机撕页粘起来的。可做过几套之后就会摸到门道——这些题问的其实是同一件事:你对「数据怎么放、怎么找、怎么排、怎么表示」有没有形成直觉。软考中级这类考证筛人的方式,从来不是比谁背的公式多,而是看谁能在有限时间里认出题型。很多人卡住的地方也在这儿:概念都听说过,一到具体题目就懵,因为脑子里装的是一堆孤立名词,不是一张能互相勾连的网。这份考点笔记干的就是把名词串成网这件事。

2. 数据结构的地基:邻接矩阵、存储结构与那棵「会排序的树」

数据结构这一块最容易被误会成「背诵区」,实际上它是整张卷子里最讲因果的部分。每一种结构的存在,都是因为某类操作的代价太高,于是有人发明了一种新摆法把它压下去。搞懂了这个「为什么」,剩下的名字只是代号。

2.1 邻接矩阵:一张表格把「图」说清楚

图的本质是「谁和谁有关系」。邻接矩阵的做法特别朴素:把顶点排成行和列,行列交叉的格子填 1 或 0,表示这两个顶点之间有没有边。就像一张班级座位表,横竖都是同学名字,交叉处打个勾,就代表这俩人认识。

这个朴素做法藏着一个非常实用的性质。无向图的边没有方向,A 认识 B 意味着 B 也认识 A,矩阵沿对角线对称,于是第 i 行元素的和,就是顶点 i 的度——也就是这个顶点连出去几条边。原文里举的例子很典型:顶点 4 的度就是第四行的和,加起来是 2。

有向图就不对称了,边有箭头,所以行和列的含义要分开看:第 i 行之和是顶点 i 的出度,第 j 列之和是顶点 j 的入度。这两个词在考场上极易互换,但只要记住「行看出去、列看进来」,方向感就不会乱。

# 用二维列表表示一个有向图的邻接矩阵,1 表示有一条有向边 graph = [ [0, 1, 0, 0], [0, 0, 1, 1], [1, 0, 0, 1], [0, 0, 1, 0], ] n = len(graph) for i in range(n): out_deg = sum(graph[i]) # 第 i 行求和 = 顶点 i 的出度 in_deg = sum(graph[j][i] for j in range(n)) # 第 i 列求和 = 顶点 i 的入度 print(f"顶点{i}: 出度={out_deg}, 入度={in_deg}")

代码里的graph[i]取的是整行,graph[j][i]是按列取值,两个求和方向正好对应出度和入度。如果换成无向图,矩阵对称,行和列算出来的数字必然一样,那时候统一叫「度」就行,不必分出入口。参数上唯一需要留意的是顶点规模:邻接矩阵要占 n×n 个格子,顶点一多,空间就吃不消,所以它适合顶点数目不多的场景。

2.2 顺序存储还是链式存储:先看你是查得多还是改得多

存储结构的争论,本质是一个取舍问题,没有绝对优劣。

顺序存储用一组地址连续的存储单元,依次存放线性表的各个数据元素。因为地址连续,第几个元素在哪儿可以直接算出来,查询特别快;代价是一旦要在中间插入或删除,后面所有元素都得整体搬家。通俗地说,就像图书馆按编号把书排满一整排,找书飞快,但中间想塞一本新书,得把后面全挪一遍。

链式存储则相反,用一组任意的存储单元存放元素,这些单元可以连续也可以不连续,元素之间靠指针牵线。插入删除只需要改几根指针,非常省事;代价是不能直接跳到第几个元素,只能从头顺着走。这就像把书散放在各个书架上,每本书里夹张纸条写着下一本在哪,加书容易,找第 50 本就得一本本跟过去。

所以判断标准很干脆:频繁查询用顺序存储,频繁插入、删除、更新用链式存储。

链表还有几个变体要分清楚。单链表只有一个指针域,只能单向走;循环链表把尾节点的指针指回头节点,形成一个环,适合需要绕圈处理的场景;双链表有两个指针域,前后都能走。因为多了一个指针域,双链表的灵活度优于单链表,但开支也更大一些——多出来的空间和维护成本,就是灵活度的价格。

散列存储走的是另一条路:在数据元素的存储位置和关键码之间建立一个确定的对应关系,也就是常说的键值对。它不靠比较来找,而是靠算,所以查找性能很好,代价是要处理冲突。索引存储则是另外建一份「目录」:索引是一个单独的、物理的数据库结构,它是某个表中一列或若干列值的集合,以及相应的、指向表中物理标识这些值的数据页的逻辑指针清单。把它想成书末的索引页,先查关键词拿到页码,再翻到那一页,比从头翻快得多。

2.3 二叉排序树与哈夫曼树:一个管查找,一个管压缩

树结构里最常考的两棵,作用完全不同,混在一起记最容易翻车。

二叉排序树的规矩只有三条:若左子树非空,左子树上所有节点的值都小于根节点的值;若右子树非空,右子树上所有节点的值都大于等于根节点的值;左右子树本身也分别是二叉排序树。这三条带来一个漂亮的性质——中序遍历这棵树,能得到一个递增序列。查找时顺着大小关系往左或往右走,每一步都能砍掉一半的候选。还有个常被忽略的细节:关键字最大的结点可以有左子树,但一定没有右子树,因为再往右就找不到比它更大的了。

平衡二叉树(AVL 树)是在二叉排序树上加的约束:它是一棵空树,或者其左右两个子树的高度差的绝对值不超过 1,并且左右两个子树都是平衡二叉树。为什么要加这条?因为排序树如果按递增顺序插入,会退化成一条链,查找优势全没了。平衡的意义就是把树「压扁」,让高度维持在 logarithm 级别。顺便提一句,AVL 树和 AVL 算法是两回事,名字撞车但内容无关。

满二叉树的定义则是另一套语言:除最后一层无任何子节点外,每一层上的所有结点都有两个子结点或 0 个子节点。注意这里说的是「有 2 个或 0 个」,不是「必须有 2 个」,措辞上的差别经常决定一道判断题的对错。

哈夫曼树(最优二叉树)的目标很明确:它是带权路径长度(WPL)最短的树,权值越大的叶子节点越靠近根节点。为什么这样能省?把权值想成使用频率,常用的字符走短路径,不常用的走长路径,总代价自然最低。构造方法是反复挑出两个权值最小的节点合并成一个新节点,新节点权值为两者之和,放回候选集合继续挑,直到只剩一个根。

原文那道例题很能说明问题:文件里出现了 6 个字符 a 到 f,若采用定长编码,码长是多少?6 个字符至少需要能区分 6 种情况,3 位二进制可以表示 000 到 101 共 6 种,所以答案是 3 位。所谓定长编码,就是用多少位二进制足够表示所有字符,4 位当然也行,但题目找的是最合适的。第二问用哈夫曼编码表示「face」,做法是找到这 4 个字母在树中的位置,从根节点出发,把经过的路径按左 0 右 1 记下来。要注意哈夫曼树的左节点未必要比右节点小,只是通常做题时写成左小右大的形式,再左 0 右 1 赋值,所以同一组字符可能出现不同的合法编码串,得分点在于路径而不是固定答案。

3. 排序与查找:为什么背复杂度表不如先分清「快在哪、慢在哪」

排序算法有八九种,硬背复杂度表是最低效的复习方式,因为表格里的数字彼此长得太像。真正该抓住的是每种算法「靠什么减少比较次数」,理解了机制,复杂度是推得出来的。

3.1 八种排序各自的脾气

直接插入排序的模型就是斗地主摸牌:每摸一张,按大小插进手里已排好的牌中间,直到全部插完。它的优点是数据本来就接近有序时特别快,最坏情况才是平方级。

简单选择排序是每趟从待排序的记录里选出关键字最小的记录,顺序放在已排序序列的末尾。它不管数据长什么样,比较次数都是固定的,所以最好和最坏一样慢。

冒泡排序两两比较待排序的关键字,交换不满足次序要求的那一对,直到整个表都满足要求。它的名气大于实力,效率不高,但胜在稳定、好理解。

希尔排序把记录按步长 gap 分组,对每组用直接插入排序,随着步长逐渐减小,每组包含的记录越来越多,当步长减到 1 时,整个数据合成一组,构成有序记录。它是插入排序的加速版,先让数据「大致有序」,最后一步就轻松了。

快速排序通过一趟排序把数据分割成独立的两部分,分割点左边都是比它小的数,右边都是比它大的数,然后对这两部分递归重复。它用的是分治法,平均表现极好,但遇到已经有序的输入又选了糟糕的基准,就会退化成平方级——这也是它「最坏情况」的由来。

堆排序要先懂堆的定义:n 个元素的序列 {k1, k2, …, kn},当且仅当满足 ki ≤ k2i 且 ki ≤ k2i+1,或者 ki ≥ k2i 且 ki ≥ k2i+1(i 从 1 到 n 向下取整的一半),才称为堆。前者是小顶堆,后者是大顶堆。判断一个序列是不是堆,就看每个父节点和它两个孩子的大小关系是否统一。原文那道选择题问哪个是堆,按定义逐个比一遍就能选出答案。

归并排序把待排序序列看成 n 个长度为 1 的有序序列,把相邻的有序表成对归并,得到 n/2 个长度为 2 的有序表,再继续归并得到 n/4 个长度为 4 的有序序列,如此反复,最后得到一个长度为 n 的有序序列。它的特点是不挑数据,代价是要额外空间。

基数排序和前七种都不一样,它不比较关键字的大小,而是根据关键字中各位的值,通过若干趟「分配」与「收集」来实现排序。举个具体例子:初始序列 R {50, 123, 543, 187, 49, 30, 0, 2, 11, 100},把 0 到 9 看成 10 个桶,先按个位数把每个数丢进对应的桶,再按桶编号从小到大依次取出,得到 {50, 30, 0, 100, 11, 2, 123, 543, 187, 49},此时个位数已经呈递增趋势。接着按十位、百位重复同样的分配与收集,最终整个序列有序。这类「按位分桶」的思路在处理定长编码、整数集合时特别顺手。

3.2 二分查找与分块查找:有序是门票

二分查找(折半查找)的适用情况是不经常变动而查找频繁的有序列表。它的做法是:假设表中元素按升序排列,将表中间位置记录的关键字与查找关键字比较,相等则查找成功;否则用中间位置把表分成前后两个子表,如果中间位置的关键字大于查找关键字,就在前一子表继续找,否则在后一子表找。重复这个过程,直到找到记录,或者子表不存在为止,此时查找不成功。

它的优点是比较次数少、查找速度快、平均性能好;缺点同样鲜明:要求待查表必须是有序表,而且插入删除困难。这两条恰好解释了为什么它只适合「不经常变动而查找频繁」的场景——维护有序性的成本,被高频查询摊薄了才划算。

分块查找则是折中方案。它把一个大的线性表分解成若干块,每块中的节点可以任意存放,但块与块之间必须排序。假设按关键码值非递减,那么对任意的 i,第 i 块中所有节点的关键码值都必须小于第 i+1 块中所有节点的关键码值。此外还要建立一个索引表,把每块中的最大关键码值作为索引表的关键码值,按块的顺序存放到一个辅助数组中。查找时先在索引表里确定目标所在的块,索引表有序,所以可以用顺序查找也可以用折半查找;确定了块之后,再在块内顺序查找。

它适用的是节点动态变化的情况,速度比顺序查找快得多,但不如折半查找。平均查找长度也和分块方式有关:假设线性表共有 n 个节点,分成大小相等的 b 块,每块 s = n/b 个节点,索引查找和块内查找的代价要合起来算。

3.3 复杂度表怎么读,而不是怎么背

排序方法最好平均最坏辅助空间稳定性
直接插入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^1.3)不存在O(1)不稳定
快速排序O(nlog₂n)O(nlog₂n)O(n²)O(log₂n)不稳定
堆排序O(nlog₂n)O(nlog₂n)O(nlog₂n)O(1)不稳定
归并排序O(nlog₂n)O(nlog₂n)O(nlog₂n)O(n)稳定
基数排序O(d(n+r))O(d(n+r))O(d(n+r))O(r)稳定

这张表真正要读出来的是三件事。第一,哪些算法「看数据脸色」:直接插入和冒泡在最好情况下能到线性,说明它们对接近有序的输入友好;简单选择、堆排序则一条直线,数据长什么样都一样。第二,谁在拿空间换时间:归并排序要多开一个和原数组同量级的辅助空间,快速排序的递归栈要 log₂n 的空间,其余大多是常数。第三,稳定性。稳定指的是关键字相等的元素,排序前后相对次序保持不变。归并、基数、冒泡、直接插入是稳定的;简单选择、希尔、快速、堆是不稳定的。

稳定性为什么重要?想象一份按学号排好的成绩单,现在要按分数重排,如果排序稳定,同分的人仍然按学号先后排列,这份成绩单还能继续用;如果排序不稳定,同分者的顺序被打乱,想恢复就得再排一次。这就是那个看起来「没什么用」的列,在真实场景里最常被想起的原因。

def insertion_sort(arr): for i in range(1, len(arr)): # 从第二个元素开始,逐个往前插 key = arr[i] j = i - 1 while j >= 0 and arr[j] > key: # 比 key 大的元素整体后移一位 arr[j + 1] = arr[j] j -= 1 arr[j + 1] = key # 空出来的位置放 key return arr

这段代码里,key是当前要插入的元素,j是已排序区的末尾下标。循环条件arr[j] > key用的是严格大于,所以相等元素不会被跨过,排序因此是稳定的——把>改成>=,稳定性就没了。这个细节在分析稳定性时非常好用:看比较符号带不带等号,基本能判断一半。

4. 进制与编码:原码、反码、补码、移码到底在解决什么问题

这一章是很多人的噩梦来源,因为四种码的名字太像,定义又都绕着「取反加一」打转。但只要先问一句「为什么要有这么多种」,后面的定义会自己站好队。

4.1 三种写法,其实只在负数上有分歧

原码的规则最简单:正数的原码等于自身的二进制数,负数的原码第一位为 1(符号位,表示负数),后面为自身的二进制数。它符合人的直觉,但机器用它做加减很别扭——符号位要单独处理,减法还得先判断谁大谁小。

反码是对原码的修补:正数的反码等于自身,负数的反码符号位不动,其余各位按位取反。补码再往前走一步:正数的补码等于自身,负数的补码是在反码的基础上加 1。

为什么最后是补码胜出?因为它把减法变成了加法。在补码体系里,减去一个数等于加上它的补码,符号位可以一起参与运算,不用特判。计算机里最适合做数字加减运算的数字编码就是补码,这句话不是结论,是几百年前就写好的设计取舍。

def to_twos_complement(n, bits=8): if n >= 0: return format(n, f'0{bits}b') # 正数:补码等于原码 return format((1 << bits) + n, f'0{bits}b') # 负数:2^bits + n print(to_twos_complement(5)) # 00000101 print(to_twos_complement(-5)) # 11111011

这里的bits是机器字长,1 << bits就是 2 的 bits 次方。负数用「模值加原数」得到补码,和「取反加一」是同一件事的两种写法。字长一旦确定,能表示的负数就比正数多一个,这也是补码范围看起来不对称的原因。

4.2 移码为什么专门留给浮点数的阶码

移码(又叫增码)的规则短得离谱:无论正负数,只要把补码的符号位取反就行。它在数值上等价于给真值加上一个固定偏移量,所以整数的移码表示,大小顺序和它的二进制串顺序是一致的。

这个性质正是浮点数需要的。浮点数的阶码要比较大小,如果按补码存,负数的二进制串看起来比正数「大」,比较逻辑就得额外判断符号。用移码存,从全 0 到全 1 单调递增,硬件直接按位比较就行。所以在计算机中最适合表示浮点数阶码的数字编码是移码,原因不在数学,而在硬件实现的省事。

4.3 定点数的范围,用一条记忆公式锁住

所谓定点数,就是小数点的位置固定不变的数。小数点通常有两种约定:定点整数(纯整数,小数点在最低有效数值位之后)和定点小数(纯小数,小数点在最高有效数值位之前)。

机器字长为 n 时,各种码制表示的带符号数范围如下:

码制定点整数定点小数
原码[-(2^(n-1)-1), 2^(n-1)-1][-(1-2^-(n-1)), 1-2^-(n-1)]
反码[-(2^(n-1)-1), 2^(n-1)-1][-(1-2^-(n-1)), 1-2^-(n-1)]
补码[-2^(n-1), 2^(n-1)-1][-1, 1-2^-(n-1)]
移码[-2^(n-1), 2^(n-1)-1][-1, 1-2^-(n-1)]

记的时候不要逐个背,令 A = 2^(n-1),B = 1 - 2^-(n-1),表格立刻变成:原码和反码的定点整数都是 [-(A-1), A-1],定点小数都是 [-B, B];补码和移码的定点整数都是 [-A, A-1],定点小数都是 [-1, B]。差别集中在两处:补码和移码多表示一个最小负数,小数端则从 ±B 变成 -1 到 B。理解了「多出来的是哪个数」,就不用死记。

4.4 指令寻址与 CPU 组成:题眼在「操作数在哪」

寻址方式的题目几乎每年都换汤不换药,判断的关键只有一句话:操作数本身在哪儿,或者操作数的地址在哪儿。

立即寻址的操作数直接包含在指令中,取操作数是最快的,因为不用再访存;直接寻址的地址写在指令里,要按地址去取;寄存器寻址的操作数就在寄存器中,速度也很快;寄存器间接寻址则是操作数的地址在寄存器中,还得再访一次存。四者的速度排序,本质上就是「要不要多跑一趟内存」的排序。

CPU 的组成也不复杂:运算器、控制器、寄存器和内部总线。其中控制器不仅要保证程序的正确执行,而且要能够处理异常事件——这句话常被忽略,但它点出了控制器不只是个发号施令的角色,还得负责在出岔子时接管局面。

5. 常见误区:五个概念最容易在考场上混成一片

有些错不是不会,而是「以为会了」。下面这五组,是概念题里翻车率最高的地方,每一组都值得单独拎出来对照一遍。

5.1 满二叉树、完全二叉树、平衡二叉树:三个「满」字不是一回事

易混点:看到「每个节点都有两个子节点」就往满二叉树上套,看到「左右差不多高」就往平衡二叉树上套。

为什么混:三个名字都在描述「形状整齐」,但整齐的标准完全不同。满二叉树看的是每一层是否铺满,平衡二叉树看的是左右子树高度差,二叉排序树看的是节点值的大小关系。

怎么区分:满二叉树的定义是除最后一层无任何子节点外,每一层上的所有结点都有两个子结点或 0 个子节点——它约束的是层与层之间的填充度。平衡二叉树约束的是任意节点左右两个子树的高度差的绝对值不超过 1,且左右子树也各自平衡。二叉排序树压根不管形状,只管值的大小排布。三者可以叠加:一棵树可以既是二叉排序树又是平衡二叉树,但它未必是满二叉树。

5.2 前缀与后缀表达式:扫描方向和栈顶位置一起变

易混点:算前缀表达式时按从左往右扫描,或者弹出两个数后搞不清谁 op 谁。

为什么混:两种记法的规则几乎是镜像的,记混一半就会全错。

怎么区分:记住两句话。前缀表达式从右至左扫描,遇到数字压栈,遇到运算符弹出栈顶的两个数,用「栈顶元素 op 次顶元素」计算;后缀表达式从左至右扫描,遇到数字压栈,遇到运算符同样弹出两个数,但计算顺序是「次顶元素 op 栈顶元素」。扫描方向反了,操作数顺序也跟着反。

以原文的「- × + 3 4 5 6」为例:从右往左压入 6、5、4、3;遇到 + 弹出 3 和 4,算出 7 入栈;遇到 × 弹出 7 和 5,算出 35 入栈;最后遇到 -,算出 35-6=29。而对应的后缀式「3 4 + 5 × 6 -」,则是从左往右压 3、4,遇 + 弹出算 7,压 5,遇 × 算 35,压 6,遇 - 算 29。两条路径,同一个结果。

5.3 邻接矩阵的行与列:出度入度只差一个方向

易混点:把有向图的入度也算成行和。

为什么混:无向图里行和列的结果一样,习惯了「行和就是度」,换成有向图就容易照搬。

怎么区分:先问自己「这条边从谁出发」。从顶点 i 出发的边,会落在第 i 行上,所以行和是出度;指向顶点 j 的边,会落在第 j 列上,所以列和是入度。一句话:行出列入。无向图因为对称,行和列恰好相等,才让人误以为只有一种算法。

5.4 稳定性与时间复杂度:两个不同维度,不能互相替代

易混点:觉得「快排平均最快,所以它最好」,忽略稳定性;或者觉得「稳定排序一定更快」。

为什么混:两者都写在复杂度表里,看起来像同一类指标。

怎么区分:时间复杂度衡量的是「要花多少步」,稳定性衡量的是「相等元素的相对次序会不会变」,两者之间没有因果关系。快速排序平均 O(nlog₂n) 但不稳定,归并排序同样 O(nlog₂n) 却稳定,代价是多花 O(n) 的辅助空间。选择排序算法时,先问数据规模,再问是否要求稳定,最后才看常数因子。

5.5 广义表的长度与深度:删括号和数括号

易混点:把长度当成元素总个数,把深度当成最大元素个数。

为什么混:广义表里嵌套着括号,视觉上数不清层级。

怎么区分:长度是将最外面那层括号删掉以后,剩下元素(组)的个数;深度是括号的层数。原文给了三个例子:L1 = ((a,(a,b),((a,b),c))) 的长度是 1、深度是 4;L2 = ((1,2,3)) 的长度是 1、深度是 2;L3 = (1,2,3) 的长度是 3、深度是 1。对照着看就明白了:L3 最外层删掉后剩三个元素,所以长度 3,只有一层括号,所以深度 1;L1 最外层删掉后只剩一个大组,所以长度 1,但括号套了四层,所以深度 4。

6. 什么时候该翻这份笔记,什么时候别只翻笔记

概念类的资料,价值集中在两个时刻:一是第一次建立框架,二是查漏补缺。第一种情况适合从头顺着读,把邻接矩阵、存储结构、树、查找排序、编码这几块按因果串起来,不求记住细节,只求知道每块解决什么问题。第二种情况适合带着具体的错题去翻,比如某道题算错了入度,就只去看邻接矩阵那一节,把「行出列入」重新过一遍。这种用法效率最高,因为问题是你自己撞出来的,印象比通读深得多。

不适合的情况也很明确。

第一种是把它当刷题的替代品。笔记能告诉你哈夫曼树的构造规则,但不动手画一遍树、不亲自算一次 WPL,考场上照样会卡在「左小右大」还是「左大右小」这种细节上。概念和手感是两回事,笔记负责前者,草稿纸负责后者。

第二种是只收藏不打开。这类资料最容易变成「存了就等于学了」的心理安慰,尤其是章节齐全、公式密集的版本,翻两页就有种「我已经掌握了」的错觉。真实情况是,没经过自己复述的概念,三天后基本清零。

第三种是跳过推导直接背结论。复杂度表、定点数范围、广义表长度深度,这些内容背后的推导都不长,花十分钟推一遍,比背十遍都稳。原文里那句「当 A = 2^(n-1),B = 1-2^-(n-1) 时」的记忆技巧,就是典型例子——它不是让你多背一组符号,而是把四行表格压缩成两个变量,记的量少了一半。

我自己的血泪经验是:曾经把一份考点笔记从头到尾划了三遍重点,信心满满进考场,结果第一道关于补码范围的题就翻车,因为划重点时只是「看懂了」,从没自己动手算过 -128 的补码长什么样。从那以后我每次复习这类概念资料,都强制走一遍「合上资料,用自己的话复述一遍,再找道题验证」的流程,哪怕只花五分钟。这个习惯比多刷十套卷更管用。

具体到这份软件设计师(中级)考点笔记,它的定位很清楚:把数据结构、查找排序、编码表示、指令系统这几块的核心定义、公式和易错点集中在一份文档里,适合当复习阶段的索引和速查表。需要完整版的话,从页面下方的资源入口拿就行。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/27 12:05:12

SupMed医疗AI平台:多智能体协同架构与临床实践

1. 项目概述&#xff1a;SupMed医疗AI平台初探 上周在医疗AI开发者社区首次接触到SupMed这个号称"医疗界OpenClaw"的新平台&#xff0c;作为三甲医院信息化建设组的成员&#xff0c;我立即申请了内测资格。经过72小时的深度测试&#xff0c;这套系统展现出的临床辅助…

作者头像 李华
网站建设 2026/10/27 12:04:09

TCC分布式事务原子性实现原理与落地避坑指南

分布式事务里最容易被讲得云山雾罩的一个点&#xff0c;就是 TCC 的原子性到底从哪来。很多人第一次接触 TCC&#xff0c;脑子里冒出来的疑问都差不多&#xff1a;Try、Confirm、Cancel 明明是三次独立的远程调用&#xff0c;中间还可能隔着网络抖动、服务重启、超时重试&#…

作者头像 李华
网站建设 2026/10/27 12:03:45

Flutter滚动组件选型指南:SingleChildScrollView与GridView性能对比

1. 从一次列表卡顿说起&#xff1a;为什么这两个组件值得单独拎出来讲Flutter 里滚动相关的组件不少&#xff0c;但真正在日常开发中被反复用到、又反复被误解的&#xff0c;SingleChildScrollView和GridView绝对排得上号。我见过太多项目&#xff0c;一开始图省事&#xff0c;…

作者头像 李华
网站建设 2026/10/27 12:02:39

代驾系统微服务容器化与Kubernetes部署实战

1. 代驾系统微服务架构解析 代驾系统作为典型的O2O服务场景&#xff0c;其业务复杂度主要体现在实时订单匹配、司机调度、路径规划、支付结算等环节。采用微服务架构后&#xff0c;我们将系统拆分为以下核心服务&#xff1a; 用户服务&#xff1a;处理用户注册、登录、信息管理…

作者头像 李华
网站建设 2026/10/27 12:02:01

STR混合图谱解析四问:分类建模、非负最小二乘与小波去噪

简介&#xff1a;面向2025深圳杯数学建模竞赛D题参赛者与数学建模学习者的完整分析论文PDF&#xff0c;围绕赛题给出从问题重述、问题分析、模型假设与符号定义到多问建模求解的系统框架&#xff0c;适合赛前梳理思路、赛后复盘及机器学习建模方法参考。资源包共1个PDF文件&…

作者头像 李华
网站建设 2026/10/27 12:01:44

5G智慧园区架构设计与关键技术解析

1. 项目背景与核心价值5G智慧园区作为新基建的重要落地场景&#xff0c;正在重新定义传统产业园区运营模式。这个方案最吸引我的地方在于"融合"二字——它不是简单叠加5G和物联网设备&#xff0c;而是通过系统级整合实现园区管理效能的指数级提升。去年参与某科技园区…

作者头像 李华