
简介软件设计师中级考点笔记精华版面向正在备考软考中级的考生用于快速回顾高频考点、难点公式与易错点。文档系统覆盖数据结构与存储结构包括邻接矩阵、顺序存储、链式存储、散列存储和索引存储深入解析二叉排序树、满二叉树、平衡二叉树、哈夫曼树等内容并给出哈夫曼树构造、WPL计算等典型例题。查找部分涵盖二分查找和分块查找排序部分梳理直接插入、简单选择、冒泡、希尔、快速、堆、归并、基数等常用算法并附时间复杂度与稳定性对比。压缩包内共有1个Word文档包体大小3.37MB要点式整理、结构紧凑适合考前突击、日常查阅和自行标注重点复习时可随时按章节索引结合例题与对比表格巩固记忆。该笔记已有381位学习者下载可帮助考生快速定位薄弱环节理解算法适用条件与典型陷阱提升复习效率。1. 软考中级在考什么数据结构模块的考点分布与拿分策略软件设计师中级备考上午科目里性价比最高的模块就是数据结构。软考中级每年在这块稳定出十几道选择题图的邻接矩阵、哈夫曼树、八大排序复杂度、原码补码范围几乎轮着考单个考点分值不高但出现的概率极高。这份考点笔记的精华恰好集中在这里每个考点都带判定模板和真题解析把能拿的分先攥住。考证复习时间紧的人建议从数据结构切进去内容不算多规律性强但概念相近“看着都熟、一做就错”的题占一半。下面按考点模块过一遍高频考点、真题做法和容易踩的坑照着背能少翻车。2. 图与存储结构邻接矩阵求度、四种存储结构选型与真题2.1 邻接矩阵无向图看行、有向图分出行和列图的表示里邻接矩阵是选择题常客。它的规则很简洁无向图的邻接矩阵是对称矩阵第 i 行元素之和就是顶点 i 的度有向图要分开算第 i 行元素之和是顶点 i 的出度第 j 列元素之和是顶点 j 的入度。考试很少让你建一棵完整的图通常直接给你矩阵某一行或某一列问度数。比如原文里的例题顶点 4 的度就是第四行元素求和结果是 2。这类题真正考的不是“会不会遍历矩阵”而是有没有记住“无向看行、有向出度看行、入度看列”这个方向。用一段代码模拟一遍比死记口诀更快# 4顶点无向图的邻接矩阵索引从0开始 graph [ [0, 1, 1, 0], # 顶点1 [1, 0, 1, 1], # 顶点2 [1, 1, 0, 1], # 顶点3 [0, 1, 1, 0], # 顶点4 ] # 求顶点4的度第4行索引3所有元素求和 degree sum(graph[3]) print(degree) # 输出2从代码里能直接看到第 4 行只有两个位置是 1分别对应顶点 2 和顶点 3所以顶点 4 的度是 2。为什么无向图的矩阵对称因为一条边是双向的顶点 2 和顶点 3 之间有边那么第 2 行第 3 列和第 3 行第 2 列都会同时写成 1上面的 graph 里第 2 行和第 3 行就是互相镜像的。对角线的位置在没有自环时总是 0有些题目会特意问“邻接矩阵第 i 行第 i 列为什么是 0”答案就是该顶点到自身没有边。如果题目换成有向图答题方向立刻变化行和是出度列和是入度。原文给的例子“顶点 3 的出度和入度分别为 5 和 16”意思是第 3 行有 5 个非零元素第 3 列有 16 个非零被 16 条边指进来。答题时先看题目说的是“有向”还是“无向”再看问的是“行”还是“列”两步定位就能拿分。还有一个小细节邻接矩阵的空间开销是 O(n^2)所以它适用在顶点数目不多的时候顶点多了矩阵会非常稀疏题目偶尔会拿这个点做迷惑项。2.2 顺序、链式、散列、索引四种存储结构怎么选存储结构的题几乎都以“适合什么场景”的形式出现。顺序存储结构用一组地址连续的存储单元依次存放数据元素适合频繁查询链式存储结构在计算机中用一组任意的存储单元存放单元可以连续也可以不连续通过指针把前后元素串起来适合频繁插入、删除、更新。单链表、循环链表、双链表都属于链式存储双链表有两个指针域灵活度高于单链表但每个结点多占一个指针域的内存开支也更大。散列存储把数据元素的存储位置和关键码建立确定对应关系本质就是键值对查找技术哈希表是它的典型形态。索引存储是单独的物理数据库结构存的是某个表中一列或若干列值的集合以及指向这些值的数据页逻辑指针清单数据库索引就是最典型的应用。记忆上可以抓一条主线查询为主选顺序变动为主选链式找得快选散列数据库里的大表检索选索引。真遇到“既要频繁插入删除、又要查询”的题通常还是选链式因为顺序表在中间插入要整体挪动后续元素代价太大。链表内部也要看清分支单链表一个指针域只能往后走循环链表尾结点指向头结点形成环双链表前后都能走灵活度最高。选择题如果同时出现“循环链表”和“双链表”优先确认是不是只在两个端点增删双端操作多时循环链表和双链表各有优势别一看到双链表就直接选。存储结构核心特点典型适用场景顺序存储地址连续随机访问快频繁查询数据稳定不常变链式存储存储单元任意指针串联频繁插入、删除、更新散列存储关键码与存储位置建立对应关系按关键字快速定位索引存储单独结构存值集合和逻辑指针数据库检索避免全表扫描2.3 真题演练无向图和有向图的度数计算把原文例题当作真题走一遍题目问“顶点 4 的度是多少”先确认矩阵是无向图再定位到第四行。第四行元素求和得 2所以答案是 2。这类题容易错的地方在于行号从 0 开始还是从 1 开始题目如果写“顶点 4”行下标记得是第 4 行而不是 graph[4]因为索引是从 0 起算的实际要访问 graph[3]这个偏移量就是一道送命题。有向图的变形题也是同一套思路给出邻接矩阵问某顶点的出度和入度出度看对应行有多少个非零元素入度看对应列有多少个非零元素。原文里的 5 和 16 就是行和列分别统计出来的结果。这里有个血泪经验求入度时总有人惯性去看行因为“入”是往里的方向但邻接矩阵的列才是箭头的终点看列才是入度。另外如果题目给的是带权邻接矩阵问度数时只数非零格子就行可不要顺手把权值全部加起来度是边的条数不是边权之和这两者千万别混。3. 树结构高频考点二叉排序树、哈夫曼树与AVL树的判定模板3.1 二叉排序树中序递增、左小右大、最大结点无右子树二叉排序树是树结构里的基础考点。它的定义有三句话左子树所有节点的值都小于根节点的值右子树所有节点的值都大于等于根节点的值左右子树本身也分别是二叉排序树。注意这里是“大于等于”有些教材会强调重复值放右子树考试按这个约定走。查找的时候对树做中序遍历得到的序列是递增的反过来给你一棵二叉树只要中序遍历结果不是递增序列它就不是二叉排序树这是最稳的判定法。还有一个反直觉的结论关键字最大的结点可以有左子树但一定没有右子树。很多考生把“最大”理解成“一定是叶子”其实只要它没有右孩子仍然可以带着一棵左子树。比如根是 50右子树里有个结点 60它的左孩子是 55这时 60 是整棵树最大的关键字但它不是叶子。答题时遇到“最大关键字结点的右指针一定为空”的说法是对的遇到“一定没有左子树”就是错的。这类选择题的套路很固定题目给出一组插入顺序或者一棵树的形态问是否符合二叉排序树定义答案无外乎两种解法。一种是模拟插入看每个新值是不是按比较路径走到正确位置另一种直接中序遍历序列递增就没错。后一种速度最快遇到递归形态的树先别急着画全图把中序序列写出来再判断。3.2 哈夫曼树WPL最短、每次取两个最小权值合并哈夫曼树也叫最优二叉树定义是带权路径长度 WPL 最短的树权值越大的叶子节点越靠近根节点。构造步骤很简单从所有节点里取出权值最小的两个合成一个新的父节点父节点权值等于两者之和再放回候选集合反复执行直到只剩一棵树。考试里默认的做题模板是“左小右大、左 0 右 1”新节点画成左小右大的顺序给左分支记 0、右分支记 1每个字符的编码就是从根出发到该叶子经过的所有分支拼接。用代码模拟一遍合并过程能帮你看懂为什么权值大的自然编码短import heapq # 示例频率仅演示构造流程真题频率以题目给的表格为准 freq [(a, 45), (b, 13), (c, 12), (d, 16), (e, 9), (f, 5)] heap [[w, [s, ]] for s, w in freq] heapq.heapify(heap) while len(heap) 1: left heapq.heappop(heap) # 每次取当前两个最小频率 right heapq.heappop(heap) for node in left[1:]: node[1] 0 node[1] # 左分支前缀0 for node in right[1:]: node[1] 1 node[1] # 右分支前缀1 heapq.heappush(heap, [left[0] right[0]] left[1:] right[1:]) for s, code in sorted(heap[0][1:], keylambda x: (len(x[1]), x[0])): print(f{s}: {code})这段代码的关键在 while 循环里每次弹出两个最小值左边的编码统一在前面加 0右边的统一加 1然后合成新节点放回堆里。频率越小的节点越容易被早期合并编码也就越长反过来频率大的节点越晚进入合并编码长度就越短这正好对应“权值大靠近根”的性质。真题里给的频率数据各不相同不能直接套用代码里的数字但构造流程永远是这样反复取最小两个合并。原文里那道经典真题是一个文件中出现 6 个字符若采用定长编码码长应为多少若采用 Huffman 编码字符序列 face 的编码是多少。第一问答案选 B3 位因为 6 个字符用 2^24 不够覆盖2^38 刚好够用所以码长最少是 3。第二问需要先在草稿纸上画出哈夫曼树按左 0 右 1 赋值然后从根节点走到 f、a、c、e 四个字符把经过的分支值依次连起来得到 110001001101所以答案选 A。这类题最怕的是树画对了但方向反了左 1 右 0 会导致所有编码全部镜像因此画树之前先在草稿纸边缘写下“左 0 右 1”这点算算是一个血泪经验。3.3 平衡二叉树与满二叉树判定的边界别搞混平衡二叉树又称 AVL 树性质是一棵空树或者左右两个子树的高度差绝对值不超过 1并且左右两个子树也都是平衡二叉树。判定时要递归检查每个结点不是只看根结点左右高度相等就够了。最常见的失分场景是给一棵左子树高度 3、右子树高度 1 的树表面看“左边比右边高 2”已经失衡但有人会先中序遍历发现递增就误判成合法的二叉排序树这里忘记检查平衡因子。满二叉树在原文里描述为除最后一层无任何子节点外每一层上的所有结点都有两个子结点或 0 个子节点。这个描述更直观画图就能检验逐层扫过去每个内部结点要么有两个孩子要么是叶子不存在只有一个孩子的中间结点。满二叉树和平衡二叉树的判定是两个动作一个数孩子个数一个数高度差别同时只做一次就收工。考试里如果同时给出“是二叉排序树、是平衡二叉树、是满二叉树”三个选项要分别验证三条线中序递增验证排序树性质高度差验证平衡性孩子数验证满树结构三条都过才能选“三者都满足”。4. 查找与排序二分查找、分块查找与八大排序复杂度总表4.1 二分查找有序表才能用比较次数少但插入删除难二分查找也叫折半查找适用情况是“不经常变动而查找频繁”的有序列表。优点是很明确的比较次数少、查找速度快、平均性能好缺点同样致命要求待查表必须有序插入删除困难。选择题最爱把“有序”和“频繁变动”两个条件拆出来做陷阱看到“无序列表直接用二分”基本可以秒排除。标准实现是三个分支不停缩区间def binary_search(a, target): low, high 0, len(a) - 1 while low high: mid (low high) // 2 if a[mid] target: # 中间位置记录与查找关键字相等 return mid elif a[mid] target: # 中间位置记录的关键字大于查找关键字 high mid - 1 # 去前一半子表继续找 else: low mid 1 # 去后一半子表继续找 return -1 # 子表不存在时说明没找到代码里的核心是每次比较后都把区间缩小一半。mid 大于目标就往左缩小于目标就往右缩最终要么找到位置要么 low 超过 high。如果题目问的是“比较次数”记住每次砍半的特性n 个元素最多需要约 log2(n1) 次比较这是二分查找平均性能好的数学基础。答题时若题目给的是链表而不是数组基本不能直接二分因为链表无法随机定位到中间位置这也是常考的一个隐含条件。4.2 分块查找索引表定块、块内顺序查找适合动态变化分块查找介于顺序查找和折半查找之间。它的做法是把一个大线性表分解成若干块每块里的节点可以任意存放但块与块之间必须排序。更准确地说按关键码值非递减排列时第 i 块中的所有节点关键码值必须小于第 i1 块中的所有节点。同时还要建一个索引表把每块的最大关键码值作为索引项按块顺序存到一个辅助数组里这个辅助数组本身是有序的。查找分两步先在索引表中查确定要找的节点属于哪一块因为索引表有序可以用顺序查找也可以用折半查找再在对应的块内部用顺序查找逐项比对。分块查找的适用场景是节点动态变化的情况速度比顺序查找快得多但又不如折半查找。平均查找长度的估算公式常按“索引表查找长度 块内查找长度”相加若 n 个节点分成大小相等的 b 块每块有 sn/b索引用顺序查找则约为 (b1)/2 (s1)/2。遇到数值题就先把块数和块长算出来再代入注意块长是不是能被整除。4.3 八大排序复杂度总表稳定性、最坏情况与辅助空间排序部分的考点高度集中于一张总表。直接插入排序每趟把一个记录插入到有序队列的合适位置像斗地主抓牌理牌简单选择排序每趟选出关键字最小的记录放到已排序序列末尾冒泡排序两两比较并交换不满足次序的对希尔排序按步长分组组内做直接插入步长逐步减小到 1快速排序一趟把数据分成“左边都比它小、右边都比它大”两部分再递归堆排序基于完全二叉树的堆结构归并排序把相邻有序序列成对合并基数排序不比较关键字大小而是按各位数值做分配与收集。排序方法最好时间复杂度平均时间复杂度最坏时间复杂度辅助空间稳定性直接插入O(n)O(n^2)O(n^2)O(1)稳定简单选择O(n^2)O(n^2)O(n^2)O(1)不稳定冒泡排序O(n)O(n^2)O(n^2)O(1)稳定希尔排序不存在O(n^1.3)不存在O(1)不稳定快速排序O(nlog2n)O(nlog2n)O(n^2)O(log2n)不稳定堆排序O(nlog2n)O(nlog2n)O(nlog2n)O(1)不稳定归并排序O(nlog2n)O(nlog2n)O(nlog2n)O(n)稳定基数排序O(d(nrd))O(d(nrd))O(d(nrd))O(rd)稳定这张表不要死背整片先分阵营O(n^2)家族是直接插入、简单选择、冒泡外加快速排序的最坏情况O(nlog2n)家族是快速、堆、归并希尔排序平均约 O(n^1.3)它没有公认的最好和最坏标准所以表里写“不存在”。稳定性记一个口诀直接插入、冒泡、归并、基数稳定其余四个不稳定。快速排序虽然平均性能最好但它不稳定这一点是每年都有人翻车的黑匣子出题人最喜欢拿“快速排序是稳定的”这种假命题做迷惑项。4.4 真题演练堆排序候选序列判定与多路归并路数堆排序的判定题给的是一个层序序列需要用堆的定义逐项检验。堆要求序列满足对每个 i1,2,…,⌊n/2⌋有 ki ≤ k(2i) 且 ki ≤ k(2i1)这是小顶堆或者 ki ≥ k(2i) 且 ki ≥ k(2i1)这是大顶堆。原文给出四个序列正确答案选 B原因是把它按层序写成完全二叉树后每个父结点都小于等于自己的左右孩子满足小顶堆条件。用代码验证最直观def is_min_heap(arr): n len(arr) for i in range(1, n // 2 1): # 只需检查到最后一个非叶结点 left 2 * i # 左孩子下标 right 2 * i 1 # 右孩子下标 if left n and arr[i-1] arr[left-1]: return False # 父结点大于左孩子不是小顶堆 if right n and arr[i-1] arr[right-1]: return False # 父结点大于右孩子不是小顶堆 return True candidates [ (10, 50, 80, 30, 60, 20, 15, 18), (10, 18, 15, 20, 50, 80, 30, 60), (10, 15, 18, 50, 80, 30, 60, 20), (10, 30, 60, 20, 15, 18, 50, 80), ] for cand in candidates: print(is_min_heap(cand)) # 只有第二组输出True代码用 1 开始编号的层序位置i 遍历到 n//2 就够因为最后一个非叶结点之后全是叶子不需要检查。每个父结点只要大于任何一个孩子就立刻返回 False。手算时也按同样思路画完全二叉树自顶向下检查所有父结点别只比相邻元素大小堆不是简单的递减递增序列它要求的是整棵树的父子关系。归并路数这道题也常考若对 27 个元素只进行三趟多路归并排序选取的归并路数是几。背公式“归并趟数 ⌈log_k m⌉”m 是元素个数k 是路数。这里反过来给趟数求路数log_k(27)3所以 k3答案选 B。这类题要注意公式方向题目给的是趟数让你反推路数还是给路数让你算趟数代入前先写清楚未知量是谁。5. 高频失分点码制范围、表达式出栈、广义表、寻址方式与稳定性5.1 失分点一四种码制的定点数范围记混错在哪问 n 位机器字长补码定点整数的表示范围时填成和原码一样的 ±(2^(n-1)-1)漏掉那个最负的数。为什么错原码、反码、补码、移码的范围不是四条都相同只有原码和反码的上下界一样补码和移码的下界会多出一个最负值。怎么答对记住这个记忆技巧设 A2^(n-1)B1-2^(-(n-1))四张表可以压缩成一对规律码制定点整数范围定点小数范围原码[-(A-1), A-1][-B, B]反码[-(A-1), A-1][-B, B]补码[-A, A-1][-1, B]移码[-A, A-1][-1, B]为什么补码能多表示一个最小负数因为原码和反码里 0 都有两种表示比如 1000 和 0000 都代表 0浪费了一个位置补码把负零的编码腾出来表示最负的数。由此也带出两个必背结论计算机做数字加减运算最适合用补码浮点数的阶码最适合用移码。选择题不会让你真算边界一般就是考“谁的表示范围比原码多一个数”以及“加减用补码、阶码用移码”。5.2 失分点二前缀表达式和后缀表达式的出栈顺序搞反错在哪后缀表达式“3 4 ”里弹出栈顶 4 和次顶 3正确的运算是 34有人按“先弹出放左边”的错误规则算成 43减法一出现就彻底算错。为什么错后缀表达式从左往右扫描前缀表达式从右往左扫描两边的弹出顺序和运算方向不一样很多考生把两者的规则混成一套。怎么答对用一句操作口令后缀是“次顶元素 op 栈顶元素”前缀是“栈顶元素 op 次顶元素”。拿原文例子验证后缀“3 4 5 × 6 -”从左扫到 时弹出 4 和 3算出 347再入栈遇到 × 弹出 5 和 7算 7×535最后遇到 - 弹出 6 和 35算 35-629。前缀“- × 3 4 5 6”从右扫先把 6、5、4、3 全部入栈遇到 弹出 3 和 4算 347遇到 × 弹出 7 和 5算 7×535遇到 - 弹出 6 和 35算 35-629。两个表达式指向同一个结果扫的方向相反但规则对称。用代码实现后缀求值能把顺序固定下来def eval_suffix(expr): stack [] for token in expr: if token.isdigit(): stack.append(int(token)) else: b stack.pop() # 先弹出的是右边操作数 a stack.pop() # 后弹出的是左边操作数 if token : stack.append(a b) elif token -: stack.append(a - b) elif token *: stack.append(a * b) elif token /: stack.append(a / b) return stack[0] print(eval_suffix([3, 4, , 5, *, 6, -])) # 输出29代码里的 b 和 a 的赋值顺序就是得分关键b 先 pop 代表右侧操作数a 后 pop 代表左侧操作数。减法 3-4 和 4-3 结果是完全不同的考试时慢三步也要把弹出顺序写对宁可多画一个栈示意也不要凭感觉直接心算。5.3 失分点三广义表的长度和深度数错层数错在哪把“长度”理解为全部原子元素的个数把“深度”理解为有多少个数字或字母。为什么错这两个概念都跟括号层数绑定长度是去掉最外层括号后剩下的元素个数深度是括号的最大嵌套层数。怎么答对剥括号的时候只剥一层数这一层里有多少个由逗号隔开的元素元素本身可以是一个子表深度则从最外层往里一层层数看括号最多套了几层。原文给过一组对照答案L1((a,(a,b),((a,b),c)))L2((1,2,3))L3(1,2,3)。它们的长度和深度分别是L1 为 4 和 4L2 为 1 和 2L3 为 3 和 1。只看 L2 和 L3 最有感觉L2 剥掉最外层括号剩下的是一个整体 (1,2,3)所以长度是 1但它从外到内有两层括号深度是 2L3 剥掉最外层括号剩下 1、2、3 三个元素长度是 3深度是 1。考试遇到复杂嵌套时先在草稿纸上把每一层括号标序号再分别数逗号就不会把深度和长度搅在一起。5.4 失分点四寻址方式里“操作数”和“操作数的地址”分不清错在哪把立即寻址和直接寻址混成一种或者把寄存器寻址和寄存器间接寻址反过来。为什么错考题描述只换几个字比如“操作数包含在指令中”和“操作数的地址在指令中”很多考生扫一眼就凭印象选。怎么答对盯住一个判断标准指令里装的是数本身还是数的存放地址寻址方式指令里的内容理解要点立即寻址操作数本身获取操作数最快不用访存直接寻址操作数的地址按地址再去内存取数寄存器寻址操作数在寄存器中数在寄存器里直接读寄存器间接寻址操作数的地址在寄存器中寄存器里放的是地址这套题经常搭配 CPU 组成一起出。CPU 由运算器、控制器、寄存器和内部总线组成控制器不仅要保证程序正确执行还要能处理异常事件。选择题如果问“获取操作数最快的是哪种寻址”答案永远是立即寻址因为操作数直接躺在指令里连读内存都省了。而“操作数的地址在寄存器中”这种描述必须选寄存器间接寻址不要把“寄存器”和“数在寄存器中”画等号。5.5 失分点五排序稳定性凭感觉乱标快速排序最常被冤枉错在哪看到快速排序平均时间复杂度最优就顺手标成“稳定”。为什么错稳定性的定义跟复杂度完全无关它指的是关键字相同的两个元素在排序前后相对顺序是否保持不变快速排序的交换过程会打乱相同元素的相对位置所以不稳定。怎么答对直接背四稳定四不稳定稳定阵营是直接插入、冒泡、归并、基数不稳定阵营是简单选择、希尔、快速、堆。再记一个关联线索三个 O(nlog2n) 的高效排序里只有归并稳定快速和堆都不稳定说明“高效”和“稳定”没有任何绑定关系。真题如果给“下列排序算法中不稳定的是”这类选项用这个表逐项排除十秒内能出答案。6. 考场答题顺序与押题方向考前最后一小时怎么用6.1 上午题的时间分配先吃数据结构再算码制和表达式上午题时间看起来够但计算题一多就容易崩。建议按“熟悉度优先”的次序数据结构里的邻接矩阵度数、哈夫曼、堆判定、二分查找这类题目属于看完题干就能落笔的先做码制范围、表达式求值需要列式或者画栈放到第二梯队。每道题控制在 60 到 90 秒超过两分钟果断标记跳过等整卷做完再回头算。跳过不是放弃而是避免陷入单题死磕的情绪。6.2 考前最后一小时的三张默写清单最后冲刺不要再看新题把三张表默写一遍第一张是八种排序的复杂度和稳定性总表重点默写哪些稳定、哪些有 O(n^2) 最坏情况第二张是四种码制的定点数范围规律记住“补码移码下界多一个最负值”和“加减用补码、阶码用移码”第三张是四种寻址方式的一句话描述立即寻址最快、直接寻址给地址、寄存器寻址数在寄存器、寄存器间接寻址寄存器里放地址。默写完顺手画出哈夫曼“左 0 右 1”和表达式“后缀先弹右操作数”两个小提醒考试时看到同类题直接套模板不用现场推导。6.3 押题方向这几个高频位置值得多花十分钟从往年趋势看邻接矩阵求度、哈夫曼编码计算、二分查找比较次数、堆的判定、广义表长度深度、前缀后缀表达式求值、补码定点范围、排序稳定性这八类几乎是必出组合。前四类是数据结构的基础盘后四类是拿来做压轴计算题的常见素材。复习时每类准备两道真题练手重点不是做对而是把答题路径固定下来先写判断依据再列步骤最后核对答案。从那以后我每次考前都会把这三张表和两个提醒强制默写一遍考场上看到邻接矩阵先写“无观看行、有向出行入列”看到表达式先写扫描方向基本没再丢过这类送分题。希望这套梳理对你有用把高频考点先攥稳软考中级的上午题就能拿到一个不拖后腿的分数。本文还有配套的精品资源点击获取