中兴的软件类笔试,特别是这份“试卷A”,在通信设备厂商里属于比较典型的一套组合拳。它不像互联网大厂那样海量刷算法题,而是更看重C语言功底、操作系统底层理解、网络协议基础,以及嵌入式开发的基本素养。这套题覆盖的知识面比较广,但深度属于“够用就行”,核心目的是筛出那些真正写过代码、调过板子、对计算机系统有感觉的人,而不是只会背八股文的选手。
我拿到这份卷子复盘了一下,发现它的题型分布和考察侧重点其实很有规律。无论你是准备投中兴的嵌入式软件岗,还是想进类似的通信设备厂商(华为、烽火、大唐等),这套试卷的复习思路都值得参考。下面我把整张卷子拆开揉碎,从题型分析到考点精讲,再到避坑指南,一次性说清楚。
1. 试卷整体结构与考核定位分析
1.1 题型分布与分值逻辑
先说整体感受。中兴软件类笔试试卷A的题型结构大致可以分成四块:单选题/多选题、填空题、简答题、编程题。如果还有一部分在线评测(OJ)形式的算法题,那通常放在最后,分值占比不高。
从分值设置来看,选择题和填空题往往占据50%-60%的分数,简答题占20%左右,编程题占20%-30%。这个比例和互联网公司的笔试差异很大——互联网大厂往往是一上来就是两道hard级别的算法题,而中兴这类传统通信设备商更愿意花选择题去考基础知识覆盖面。
注意:通信设备厂商的软件岗和互联网应用软件岗对人才的要求是两条路线。前者的代码要跑在资源受限的嵌入式环境里,和硬件打交道多;后者主要关注高并发、分布式、业务逻辑。因此需要针对性地准备。
之所以这样设计,是因为嵌入式软件(尤其是通信设备里的软件)出bug的代价极高。基站设备如果软件崩溃了,那不是一个App闪退那么简单,而是整片区域的通信中断。所以这类企业对基础知识的扎实程度有很高的要求,宁可招一个基础扎实但不算特别聪明的人,也不愿意招一个思维活跃但基础不牢的人。
1.2 核心能力模型拆解
从试卷考察的内容反推,中兴软件岗笔试对候选人的能力模型是清晰的:
第一是C语言基本功。指针、内存管理、结构体、位运算这些基础到不能再基础的东西,却恰恰是嵌入式开发的命根子。试卷里一定会有关于指针运算、数组越界、内存泄漏的题目。
第二是操作系统原理。进程与线程的区别、同步互斥机制、死锁条件、内存分页分段,这些是选择题和简答题的常客。很多自学编程的人在这里容易吃亏,因为平时写业务代码根本接触不到这些概念。
第三是计算机网络基础。TCP三次握手、四次挥手、TCP与UDP的区别、IP地址分类、子网划分,这些几乎是通信设备厂商必考的题目。中兴本身就是做通信的,如果连TCP/IP协议栈的原理都说不清楚,那确实说不过去。
第四是数据结构与基础算法。链表操作(反转、合并)、二叉树遍历、排序算法的时间复杂度对比,这些属于编程题的常考范围。难度大致在leetcode easy到medium之间。
此外,试卷还会零星出现一些与通信相关的常识,比如OSI七层模型、IP报文的格式、甚至可能有一道关于5G或4G网络架构的选择题。这类题目对通信专业的学生比较友好,但对纯计算机背景的同学来说可能需要额外补充一点行业常识。
2. 选择题与填空题:高频考点逐项拆解
2.1 C语言考点:指针与内存是永远的主角
选择题里C语言相关的题目,我个人复盘下来可以总结成一个不等式:指针相关 > 内存管理 > 关键字细节 > 预处理。
指针这块,最常见的考法是给一段代码,让你判断输出结果或者程序是否出错。比如:
#include <stdio.h> int main() { int a[5] = {1, 2, 3, 4, 5}; int *p = a; printf("%d\n", *(p++)); // 输出1,p后移 printf("%d\n", *p++); // 输出2,p后移 printf("%d\n", (*p)++); // 输出3,但a[2]变成4 printf("%d\n", *p); // 输出4,因为上一步自增了 return 0; }这种题目考察的是p++、*p++、(*p)++三者之间的区别。简单来说:*p++相当于*(p++),先取p指向的值再移动指针;(*p)++是先取p指向的值,然后把这个值加1,指针不动。
另外一道经典的送命题是sizeof和strlen的区别:
char str[] = "hello"; char *p = str; sizeof(str) // 6,包括末尾的'\0' sizeof(p) // 8或4,取决于平台位数,64位系统是8 strlen(str) // 5,不含'\0' strlen(p) // 5做题的时候一定要注意区分“数组名”和“指针变量”,在sizeof运算符面前它们是两码事。
内存管理方面,堆内存和栈内存的区别是必考项。栈上的变量由系统自动分配和释放,堆上的内存需要手动malloc/free。笔试题常常会问:以下哪段代码存在内存泄漏?其实核心思路就是一条:检查每个malloc是否都有对应的free,以及是否有指针在被释放后继续使用(悬空指针)。
还有一类必考题是const关键字的不同位置。我当年复习的时候自己总结了一张表,这里分享给大家:
| 写法 | 含义 |
|---|---|
const int *p | 指针指向的值不能通过p修改 |
int *const p | 指针本身不能指向别处 |
const int *const p | 指针和值都不能修改 |
这类题目翻来覆去就是这个套路,把上面三种情况搞清楚基本不会丢分。
2.2 操作系统考点:从进程线程到死锁
操作系统这块,选择题比较爱考的是进程状态转换。就绪态、运行态、阻塞态三者之间的转换关系,很多人背了又忘。这里提供一个记忆技巧:只有运行态可以主动进入阻塞态(比如等待I/O),也只有就绪态可以进入运行态(被调度器选中)。阻塞态不能直接进入运行态,必须先变成就绪态再等待调度。
进程间通信方式(IPC)也是高频考点:管道(pipe)、消息队列、共享内存、信号量、信号、套接字。选择题会问哪种方式效率最高——答案是共享内存,因为它不需要内核拷贝数据。但共享内存没有同步机制,所以需要配合信号量使用。如果题目问“哪种方式最适合传输大量数据”,优先选共享内存。
死锁产生的四个必要条件(互斥、占有并等待、不可剥夺、循环等待)这是老生常谈,但需要注意中兴的卷子喜欢换个马甲考:不是直接问你四个条件是什么,而是给一个场景,问“以下哪种措施可以预防死锁?”或者“银行家算法是为了解决什么问题?”这种考法更贴近实际工程思维。
线程和进程的对比也是选择题里一定会出现的。核心区别就两条:进程是资源分配的基本单位,线程是CPU调度的基本单位;同一进程的线程共享地址空间,进程之间地址空间相互隔离。
提示:中兴的笔试题里偶尔会出现“协程”的概念。虽然C语言开发中用的不多,但如果你了解协程是用户态调度、切换成本比线程更低,这个知识点就能拿分了。
2.3 计算机网络考点:通信厂商的必答题
网络协议是中兴笔试的重头戏。选择题里TCP和UDP的对比是雷打不动的,主要围绕以下几点:
- TCP面向连接,UDP无连接
- TCP可靠传输,UDP不可靠
- TCP有流量控制和拥塞控制,UDP没有
- TCP首部最小20字节,UDP首部只有8字节
- TCP是流式协议,UDP是报文协议
关于TCP三次握手,笔试题不太会纸上谈兵,更常见的是问“为什么需要三次握手而不是两次?”答案要点是:防止已失效的连接请求报文突然又传到服务器端,从而产生错误连接。假设只有两次握手,客户端发送的SYN报文在网络中滞留,超时后客户端重发SYN并完成连接、传输数据、释放连接。此时滞留的旧SYN报文到达服务器,服务器会误以为客户端发起了新连接,于是分配资源等待客户端发送数据——这就是资源浪费。
IP地址和子网划分也会考一两题。比如给一个IP地址和子网掩码,问网络号和广播地址。计算方法不复杂:IP和掩码做按位与得到网络号,掩码按位取反再和IP做按位或得到广播地址。最好熟练掌握这种方法,考试时能省不少时间。
2.4 数据结构和算法考点:基础但不容小觑
选择题里的数据结构题目难度不大,以基础概念为主。比如各种排序算法的时间复杂度对比,二叉树的先序/中序/后序遍历推断,哈希表的冲突解决方法(开放定址法、链地址法)等。
值得一提的是,中兴的卷子对“链表”有特别的偏好。选择题、简答题、编程题都可能出现链表相关的内容。比如:
- 如何判断链表有环(快慢指针法)
- 如何反转链表(迭代法)
- 如何找到链表的中间节点(快慢指针法)
这些题目本身不难,但如果你平时刷题只用Python写列表,突然改用C语言手写链表节点结构体,很容易在边界条件上翻车。
3. 简答题:考察表达能力和工程思维
3.1 典型的简答题类型
简答题是中兴笔试里比较有区分度的一类题型。选择题还能蒙,简答题是真要按照自己的理解把知识点写清楚。根据对不同年份试卷的复盘,简答题常见的有以下几类:
第一类是概念对比题,比如“请简述进程和线程的区别与联系”、“请说明TCP与UDP的区别及应用场景”。这类题目考察的是知识的系统性和表达的条理性。
第二类是原理说明题,比如“请简述TCP三次握手的过程”、“请说明死锁产生的必要条件及预防方法”。这类题目考察的是对基础原理的深度理解。
第三类是实际问题分析题,比如“如果系统出现CPU占用率过高,如何排查定位?”这类题目没有标准答案,考察的是项目经验和解决问题的思路。
我个人的体会是,简答题的答题策略不是“面面俱到”,而是“结构清晰+关键点完整”。不需要像写论文一样洋洋洒洒几百字,但需要把核心概念写准确、分条罗列清楚、逻辑顺畅。改卷人每天看几百份卷子,一份卷子停留时间不超过两分钟,结构清晰、关键词突出的回答更容易拿分。
3.2 答题技巧与模板
以“进程和线程的区别”为例,一个容易拿高分的答题结构是这样的:
定义先行:进程是操作系统进行资源分配和调度的基本单位,是程序的一次执行过程。线程是进程内的一个执行单元,是CPU调度和分派的基本单位。
区别列表:
- 进程拥有独立的地址空间,线程共享进程的地址空间
- 进程是资源分配的基本单位,线程是调度的基本单位
- 进程间通信需要借助IPC机制,线程间可以直接读写共享数据
- 进程创建和销毁的开销大,线程创建和销毁的开销小
- 进程之间的隔离性更好,一个进程崩溃不影响其他进程;线程之间的隔离性较差,一个线程崩溃可能导致整个进程退出
联系说明:一个进程可以包含多个线程,这些线程共享进程的资源。线程依赖于进程存在,进程退出后其所有线程也随之终止。
这种“定义+列表+联系/延伸”的结构对任何简答题都适用。如果考试时遇到不会的题目,也可以尝试从这个模板出发,写出你知道的部分,尽量不要留白。很多时候写了就能拿到部分分数。
4. 编程题:C语言手写代码的实战演练
4.1 高频编程题类型与解题框架
编程题是整套试卷里含金量最高的部分,也是很多人最容易失分的部分。中兴软件类笔试的编程题一般采用C语言完成,题目类型主要集中在以下几类:
链表操作类:反转链表、合并两个有序链表、找链表中倒数第k个节点、判断链表是否有环。如果时间紧张,优先准备这类题目,因为中兴对链表的偏好非常明显。
字符串处理类:实现字符串拷贝、字符串反转、统计字符串中字符出现的次数、判断回文字符串。这类题目看似简单,但考察的是对指针操作的熟练度和边界条件的处理。
数组处理类:数组去重、求两个数组的交集、寻找数组中的最大值/最小值、将数组中的0移动到末尾。这类题目算法本身不难,但要求写出健壮的代码。
排序与查找类:手写快速排序、二分查找。这类题目虽然算法思路比较清晰,但细节容易出错,比如快速排序的边界条件。
以反转链表为例,我给出一个可以直接当作模板使用的C语言实现:
#include <stdio.h> #include <stdlib.h> struct ListNode { int val; struct ListNode *next; }; struct ListNode* reverseList(struct ListNode* head) { struct ListNode *prev = NULL; struct ListNode *curr = head; while (curr != NULL) { struct ListNode *nextTemp = curr->next; // 先保存下一个节点 curr->next = prev; // 反转指针 prev = curr; // prev前移 curr = nextTemp; // curr前移 } return prev; }解题的关键就卡在这句话上:在修改节点的next指针之前,必须先把下一个节点保存下来。很多人在面试现场写这道题时,因为忘了保存下一个节点,指针一旦丢失就全乱了。
再来一道二分查找的模板,这套题考的频率也很高:
int binarySearch(int arr[], int size, int target) { int left = 0; int right = size - 1; while (left <= right) { int mid = left + (right - left) / 2; // 防止left+right溢出 if (arr[mid] == target) { return mid; } else if (arr[mid] < target) { left = mid + 1; } else { right = mid - 1; } } return -1; }注意一个细节:mid的计算推荐使用left + (right - left) / 2,而不是(left + right) / 2。虽然两者在数学上等价,但后者在left + right极大时存在整数溢出风险。这种细节往往是面试官和评卷人判断你是否真正理解代码的加分项。
4.2 手写代码时的注意事项
实际考试是在牛客网或者赛码网这类在线评测系统上进行的。虽然编译器会帮你检查语法错误,但你依然需要做到以下几点:
一定要先理清思路再动手写。好多同学看到题目很兴奋,上来就写,写到一半发现思路有问题,推倒重来,时间全浪费了。建议先花两分钟在草稿纸上画一画流程图,哪怕只能写出伪代码,也能大大提高一次通过率。
注意边界条件。空链表、单个节点、数组为空、目标值在数组首尾,这些边界情况最容易出错。写完代码后不要急着提交,先自己手动跑几个极端用例。
变量命名要有意义。虽然在线评测系统不检查命名规范,但万一你的代码需要人工复查(部分岗位会有这个环节),清爽的命名风格一定能加分。
如果没有C语言环境,选自己最熟悉的语言。虽然C语言在嵌入式领域更贴合,但如果题目没有强制要求,用Python或Java完成算法题也比写不出来强。关键是AC,不是语言。
4.3 编程题实战案例:数组去重
最后分享一道我当年实际遇到的编程题:给定一个已排序的数组,请在不使用额外数组空间的条件下,原地删除重复出现的元素,使每个元素只出现一次,返回删除后数组的新长度。
int removeDuplicates(int* nums, int numsSize) { if (numsSize == 0) { return 0; } int slow = 0; for (int fast = 1; fast < numsSize; fast++) { if (nums[fast] != nums[slow]) { slow++; nums[slow] = nums[fast]; } } return slow + 1; }这道题用到的“快慢指针”技巧在数据结构题目里很常见。快指针负责遍历,慢指针负责记录不重复元素的位置。它的精妙之处在于:当你有两个指针配合工作时,总能找到一种让空间复杂度降到O(1)的解法。类似的题目还包括移动零、最长连续递增序列等,建议备考时把这类“双指针”题目集中刷一遍。
5. 通信与嵌入式常识:容易被忽略的附加分
5.1 通信基础常识的考察方式
中兴作为通信设备厂商,软件类笔试偶尔会夹带一些通信领域的通识题。这类题目不深,但如果完全没有接触过,确实会措手不及。常见的有:
OSI七层模型和TCP/IP四层模型的对应关系。这个考点与其说是通信知识,不如说是网络基础。物理层、数据链路层、网络层、传输层、会话层、表示层、应用层,中文名要能默写出来。TCP/IP的四层模型把它简化成了网络接口层、网际层、传输层、应用层。
TCP报文段的首部格式,尤其是源端口、目的端口、序号、确认号这几个字段的作用。如果之前没看过TCP报文格式,建议花十分钟看一下,因为笔试选择题可以直接考。
还有一个容易被忽视的点是IPv4和IPv6的区别。IPv6地址长度从32位扩展到128位,解决了IPv4地址枯竭的问题。如果题目问IPv6的地址位数,答案是128位,这个属于送分题。
5.2 嵌入式开发的常规考察
软件类岗位如果偏向嵌入式方向,还会涉及一些硬件相关的知识。比如:
- 大端和小端的区别。大端模式是数据的高字节保存在内存的低地址中,小端模式是数据的低字节保存在内存的低地址中。可以通过一个
union来检测本机是大端还是小端。 - 中断和轮询的区别。中断是外设主动通知CPU,轮询是CPU不断查询外设状态。中断的实时性好,但需要处理上下文切换;轮询简单但浪费CPU资源。
- volatile关键字的作用。告诉编译器该变量可能被意外修改,每次使用时都必须重新从内存中读取,不能优化到寄存器中。典型场景是硬件寄存器、中断服务程序中修改的全局变量。
- 栈的生长方向。在x86平台上,栈是从高地址向低地址生长的。栈溢出攻击的原理就和这个有关。
这些知识点在简历上如果写了“嵌入式开发经验”,那笔试考到的概率会大大增加。如果没写过嵌入式,也不用太担心,这类题占分不多。
5.3 Linux基础命令与工具
通信设备里的软件大部分跑在Linux系统上,所以Linux命令也可能出现在选择题里。比如:
- 查看进程的命令:
ps -ef或top - 查看端口的命令:
netstat -anp或ss -lntp - 修改文件权限的命令:
chmod - 查找文件的命令:
find / -name "xxx"
这些命令不复杂,但如果你平时开发用的Windows系统,最好在虚拟机或云服务器上装个Linux环境,上手敲一遍。笔试考命令题往往不考具体参数,而是考“用什么命令完成什么操作”这种级别。
特别提醒:如果你是纯Java/Python后端方向,建议花时间把C语言的基础重新捡起来,尤其是结构体、指针、动态内存分配这三块。中兴软件岗笔试的编程题和填空题基本都是围绕这三块展开的。
6. 备考策略与实战心得
6.1 时间规划与复习优先级
如果你离笔试还有两周以上,可以参考下面的复习节奏:
第一周重点放在C语言和数据结构上。具体来说,把指针、结构体、内存分配、链表、栈、队列、二叉树这些基础知识过一遍。每天花1小时刷与链表和数组相关的编程题,目标是能把反转链表、合并有序链表、数组去重这类题目默写出来。
第二周重点放在操作系统和网络上。进程线程、死锁、TCP/IP、OSI模型,这些内容偏理论,通过做题来记忆是最有效的。可以去找“软考软件设计师”的历年真题做,尤其是上午的选择题部分,很多考点是重合的。中兴的笔试难度和软考中级上午题比较接近,但更偏实战一些。
考试前一天不要再做新题了,把之前做错的题翻出来重新看一遍。特别是那些以为自己会做、结果做错的题,说明存在知识盲区,考前过一遍印象最深刻。
6.2 还需要准备什么
除了题目本身,还有几项软技能也会影响你的笔试结果:
时间分配。笔试总时长一般在90分钟到120分钟之间。建议按分数占比分配时间:选择题和填空题最多花一半时间,简答题控制在20分钟内,剩下的时间全部留给编程题。不要在一道选择题上纠结超过3分钟,可以先标记跳过,最后有时间再回来想。
在线编程环境提前适应。中兴笔试一般使用牛客网或赛码网,你需要提前熟悉它们在线编译器的操作方式。特别是输入输出的格式,牛客网要求你写完整可运行的代码,和leetcode只需要写函数体不一样。
字迹工整。如果笔试是纸质试卷(有些线下宣讲会会用纸质试卷),简答题的字迹一定要工整。改卷人一天要批阅大量试卷,字迹潦草的内容很容易被误判。
6.3 面试官视角的几点忠告
我在和一些参与过校园招聘的工程师朋友聊过,他们说中兴这一类通信厂商看笔试,其实最看重的不是你能不能做出所有题目,而是基础是否扎实、是否值得培养。
三道编程题你哪怕只做出来一道,但是思路清晰、代码规范、边界条件处理得当,面试官对你的评价可能比三道题全AC但代码写得一团糟的选手还要高。因为实际工程开发中,代码的可读性和健壮性往往比炫技更重要。
相反,如果选择题靠蒙、简答题全在扯淡、编程题编译不通过,那印象分会大打折扣。尤其是简答题,千万不要抄题目当作答案来凑字数,宁可只写三行核心结论,也不要写一大段正确的废话。
另外,如果你有Linux使用经验、嵌入式项目经验或者熟悉某种RTOS,在简历里要明确写出来。笔试题是统一成卷的,但面试官在拿到你的笔试成绩后,会结合你的简历背景做综合评估。中兴的软件岗分很多方向,有些偏通信协议,有些偏驱动开发,有些偏上层应用,你需要在简历中突出和意向方向匹配的技术积累。
6.4 常见失分点与考场表现细节
这是我自己参加过多次类似笔试之后总结出的常见问题清单,建议考试时贴在旁边:
- 选择题没看清“不正确”还是“正确”就下手,这题白白丢分特别可惜。题目问“下列说法不正确的是”,往往很多人只看了前半段就开始选。
- C语言程序题没有在草稿纸上推演,直接盯着屏幕选答案。如果试卷允许在题目旁做标记,推荐把指针变化的过程画出来,正确率会明显提升。
- 编程题定义变量后在循环里忘记初始化,导致程序运行结果不确定。这个问题在笔试环境没有调试器的情况下很容易被忽略,所以写完代码后建议在脑中逐行走一遍。
- 简答题只写关键词不写完整句子,如果改卷人看不懂你的表达逻辑,很难给分。
- 在不会的编程题上死磕太久,导致后面的简答题没有时间写。编程题可以只写思路伪代码,简答题留白才是真正的零分行为。
考场上的策略是“先易后难、先分高后分低”。先把有把握的分数全部拿到手,再回来啃硬骨头。编程题如果遇到完全没思路的,把时间花在检查前面的选择题和简答题上,性价比要高得多。
这套试卷的核心价值,其实并不在于题目的难易程度,而在于它清晰地告诉了你:一个通信设备软件工程师需要哪些底层能力。与其焦虑地到处找“原题”,不如按照上面梳理的知识地图,老老实实把每个知识点弄明白。基础扎实的人,无论试卷怎么换,都能从容应对。