360公司2016研发工程师笔试题(一)能教会现在的你什么
2016年秋招那阵子,我在一个求职群里看到有人贴出刚考完的360研发工程师笔试题(一),评论区瞬间炸锅:有人喊“选择题太多了,根本做不完”,有人抱怨“好几道C++的题每个选项看着都对”,还有人直接说“第三道大题我连题意都没读懂”。那段时间几乎每家公司都在校招,笔试题五花八门,但360这套题给很多人的印象格外深——它不像有些公司只考几道LeetCode让你碰运气,而是用大篇幅的客观题把计算机网络、操作系统、C/C++内存机制、数据结构和基础算法全部扫了一遍,然后在最后留几道需要写代码或推理的问题。说白了,这套题不是考你会不会刷题,而是考你大学四年有没有真的搞懂计算机这门学科。
这篇文章想把当年这套题背后的考点逻辑、做题策略和对今天求职者的参考价值拆开讲清楚。不管你是准备校招的在校生,还是想跳槽的工程师,这篇内容都会对你有用。我会从卷面结构、模块考点、答题节奏、题目风格变迁、以及笔试与工程能力的映射关系几个角度展开,尽量把我自己当时备考和后来参与技术招聘时的经验都放进去,用最直白的话讲清楚这些笔试背后的门道。
1. 还原一下当年的卷子:为什么这套笔试被叫“知识广度压力测试”
1.1 卷面结构给人的第一印象:题量大、模块杂、没有废话
360研发工程师笔试题(一)不是那种上来就甩两道编程题的卷子。它更大的比重放在选择题上,覆盖面特别广,基本是按照“计算机专业核心课程大纲”出的。很多人拿到卷子后会先翻一遍,然后发现:C语言指针、C++对象模型、操作系统进程调度、死锁、TCP三次握手、HTTP状态码、数据库索引、Linux常用命令、概率题、逻辑推理、智力题——全都有。这种结构的潜台词是:公司不想只招到一个会写代码的人,它希望候选人有完整的计算机知识体系。
2016年这个时间节点比较特殊。移动互联网还在高速增长,Android/iOS开发岗位特别多,安全方向又是360的看家本领,所以这套笔试题(一)在研发岗里其实带着很强的“基础能力筛选”属性。它不以“能不能写出惊艳的算法”为核心,而以“基础知识是不是扎实”为核心。这种出题思路和当时许多大厂类似:先用客观题快速筛掉一批基础不牢的人,再进入下一轮技术面试。从这个角度看,那张卷子本质上不是难度测试,而是广度测试加细心测试。
另外,题目的表述普遍比较干练,没有太多场景包装。比如一道题就是直接问“以下哪种方式可以避免死锁”,选项给出银行家算法、资源有序分配法、抢占式调度等。这种风格对基础扎实的人友好,对靠背题突击的人不友好,因为选项里经常只有细微差别,背不准确就会选错。
1.2 安全基因渗透到题目的各个角落
360当时以安全业务闻名,这个背景在笔试题(一)里也有体现。最明显的地方是,网络和Linux相关题目占比不低,而且有些题目会往缓冲区溢出、常见Web漏洞原理、权限管理等方向靠近。不是所有研发岗位都做安全产品,但公司希望研发团队对安全有基本敏感度,这个思路在笔试中体现得很直接。
举个例子,这类卷子中经常出现关于“栈溢出”“堆溢出”的选择题,或者给你一段有问题的字符串处理代码,问它存在什么风险。这其实是安全方向的基础题,但用来考研发工程师也合理——如果一个写C/C++的人不了解内存越界会引发什么后果,那上线后很容易埋雷。甚至有些题目会直接考“为什么不能把用户输入拼进SQL语句”,这对所有后端研发岗位都是底线认知。
所以说,如果你现在要准备类似的笔试,别只埋头刷LeetCode,把网络原理、操作系统、数据库基础、安全常识这些“硬核八股”也认真过一遍,否则遇到360这种风格的卷子会很吃亏。
1.3 2016年的技术语境和今天有什么不同
把时间拉回2016年,你会发现几个背景:Stack Overflow年度调查显示最流行的语言还是JavaScript、Java、C/C++;Python在Web开发和数据分析领域已经起来了,但在很多公司笔试里还没成为默认选项;云原生和Kubernetes还是新鲜词,容器化远没有今天这么普及;移动端原生开发是香饽饽,跨端方案还在萌芽期。因此,当时的笔试题很少考Docker、K8s、云服务这些内容,更不会让你设计微服务架构。
这道题换成现在的校招标准来看,有些考点会显得“古典”。比如现在很多公司笔试题直接放在在线OJ上,纯客观题比例下降;而2016年还是线下纸质笔试或简单在线答题的时代,选择题占比高,试卷上甚至还要手写代码。这种形式上的差异,决定了当时的复习思路更偏向“知识体系完整度”,而不是“编程题熟练度”。如果你现在拿这套题练手,可能会觉得有些知识没学过——这很正常,但反过来也说明计算机基础的核心内容十年间变化没那么大。
2. 核心考点模块拆解:每一类题目到底在考什么能力
2.1 C/C++与内存机制:不是考语法,是考你懂不懂计算机怎么执行你的代码
如果在2016年参加360研发工程师笔试,C/C++相关题目基本是跑不掉的。它们会集中在指针、数组、内存布局、构造析构顺序、虚函数机制、类型转换这些点上。单纯背语法过不了这类题,因为出题人真正想测的是你对“代码在内存里如何运行”的理解。
举一类典型问题:给你一段包含结构体定义、指针运算和强制类型转换的代码,问输出什么。这种题在纸上推演,得先把结构体字段偏移算清楚,再考虑系统字节序,最后看printf的格式化参数是否匹配。如果只是大概知道指针是“存地址的变量”,碰到这类题就会卡住。我当时复习时的经验是:把《C专家编程》里关于数组和指针的部分反复读,理解“数组名在表达式里会退化为指针”到底意味着什么,然后拿编译器动手验证每一个不确定的细节。
C++部分则更爱考构造函数、析构函数、拷贝控制、继承和虚函数。有一类经典陷阱题是:一个基类指针指向派生类对象,delete这个指针时,如果基类析构函数不是虚函数,会发生什么?答案不是“内存泄漏”这么简单,而是未定义行为,实际运行可能只调用基类析构函数,派生类资源没被释放。笔试里遇到这种题,正确率直接反映你有没有真正理解“运行时多态”的边界。
还有一个容易被忽略的点:位运算和整型提升。这类题在选择题里出现频率极高,比如问“~0xa5”的值是多少,或者判断一个有符号数右移的语义。很多非科班同学或者平时只写脚本语言的候选人,在这些题上会丢很多分。解决方法是刷一遍“位运算面试题合集”,把补码表示、溢出行为、整型提升规则彻底弄明白,这些知识在工作中排查线上问题也经常用到。
2.2 数据结构与经典算法:准备重点应该是“考得广”而不是“考得深”
2016年的研发笔试,数据结构题目的覆盖面大于深度。选择题会涉及数组、链表、栈、队列、二叉树、图、哈希表、堆的查找/插入/删除复杂度;还会考排序算法的稳定性、时间/空间复杂度、何时适用;以及一些经典算法思想,比如动态规划、贪心、分治的适用场景。给我印象最深的是“堆排序建堆时间复杂度”这道题目,它经常以选择题形式出现,答案是O(n)而不是O(nlogn),但很多人上来就选错——因为大家只记得排序过程是O(nlogn),忘了建堆有更紧的界。
这说明出题人不是想把大家考倒,而是想测你有没有真正理解数据结构背后的性质。再比如,问“ hash表解决冲突有哪些方法”,选项里可能同时出现链地址法、开放定址法、再哈希法,看起来都对,但题干如果强调“在Java的HashMap中”,那么链地址法才是正解。这种题要求的不只是背概念,还得把概念放到具体工程语境里判断。
编程大题方面,这套题(一)通常不会直接放一道超难算法题,更多是考察“能否把问题转化为数据结构操作”的能力。2016年那会儿没有现在这么多在线OJ,答题经常是手写伪代码或者C++/Java代码。手写代码有个特点:阅卷人看重整体思路和关键逻辑,语法小错误往往可容忍。如果你在卷面上写“用递归把二叉树中序遍历的结果存进数组”这类题,只要递归边界正确、访问顺序写明白,基本就能拿分。但如果你连函数签名都写不清楚,那阅卷人很难相信你能交付代码。
我的建议是:准备这类笔试时,先保证每种基础数据结构都能手写实现一遍(链表反转、栈的数组实现、二叉树的三种遍历、堆的上浮下沉、哈希表开链法),然后针对笔试常考算法做归纳(排序比较、二分边界、DFS/BFS、简单DP),不要一上来就刷困难题。这套考试考察的是知识覆盖率,你能覆盖得越全面,分数越稳。
2.3 操作系统与Linux:笔试里的“系统感”决定了你的上限
操作系统在研发笔试里的地位非常高,2016年尤其如此。选择题高频考点包括:进程和线程的区别、进程状态转换、调度算法、死锁的四个必要条件与处理方法、虚拟内存与分页、页面置换算法、中断与系统调用、用户态与内核态切换等。这些概念看起来繁杂,但有一条主线——操作系统是在管理资源,所有题目都在问“资源如何分配、如何调度、如何保护”。
举个例子,关于“死锁”的题目,选项里经常出现“破坏互斥条件”“破坏请求与保持条件”“破坏不可剥夺条件”“破坏循环等待条件”。这种题不难,但你可以进一步问自己:在实际工程里,哪种方式最常用?答案是破坏循环等待,比如给资源编号再按序申请。如果笔试里出了一道“如何避免死锁”的代码设计题,你答“按固定顺序加锁”就会比单纯背概念的人高一个档次,因为你有工程意识。
Linux命令和Shell相关知识,在2016年的研发笔试里也占有一定份额。题目会问:如何查看进程的CPU和内存占用?如何查看端口被哪个进程占用?如何统计一个文件的行数?如何查找日志中关键字并去重统计?这些题对应的是top、ps、netstat、ss、wc、grep、sort、uniq、awk、sed等基础命令。说实话,如果平时开发不用Linux,这些题确实只能靠背。但它们背后的意图很明确:公司希望招进来的人能直接连服务器看日志、查问题,而不是连基本的排查命令还要现学。
操作系统和Linux这块,我给一个可执行的复习方案:一边看《深入理解计算机系统》的虚拟内存和异常控制流章节,一边在虚拟机或云服务器上把文件、进程、网络相关的命令都过一遍。不要只看书,因为笔试里关于命令的题目,选项会非常具体,比如“哪个命令可以实时刷新进程状态”,你没用过top就很容易混淆成ps。
2.4 计算机网络:背会了图,还得会讲“数据包的一生”
计算机网络是另一大块重点,而且360这边的卷子对网络的重视程度更高。选择题基本涵盖OSI七层模型和TCP/IP分层、TCP与UDP的区别、TCP三次握手与四次挥手、TCP拥塞控制(慢启动、拥塞避免、快重传、快恢复)、HTTP协议报文结构与状态码含义、DNS解析过程、IP地址与子网划分、NAT等。这些内容没有太多需要“智商”的地方,重点在于记忆的准确性和理解的深度。
很多同学容易在TCP三次握手上翻车,不是不知道有“三次”,而是不理解为什么是“三次”。如果题目问“为什么TCP建立连接需要三次握手,而不是两次”,你需要回答:为了防止已失效的连接请求报文突然又传到服务器端,从而产生错误连接。这个回答必须基于“网络报文可能延迟重放”的事实,而不是背一句“三次更安全”。笔试题如果以简答题形式出现,阅卷人一眼就能看出你是真懂还是背的。
比起纯理论,我建议你在准备网络笔试时,多尝试用自己的话讲一遍“一个数据包从浏览器输入URL到页面渲染完成之间的完整旅程”。这个过程需要你把DNS、HTTP、TCP、IP、ARP、路由、服务端处理、响应返回全部串起来。能把这个流程讲清楚的人,在这类笔试里几乎不会失分,而且面试时也很加分。反过来,如果只是零散地记名词,碰到“连接建立后第一次发送数据会被延迟多久”这种结合TCP_NODELAY的题目——虽然2016年未必考这么细——你会明显感觉吃力。
2.5 数据库与SQL:不写代码的笔试怎么考“数据能力”
数据库题目在研发工程师笔试里通常会控制在一个合理的比例,但很少缺席。选择题高频集中在数据库范式(1NF、2NF、3NF、BCNF)、事务的ACID特性、隔离级别、索引类型与B+树、SQL语句优化、表连接的区别(INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL JOIN)等。有些公司会放一道手写SQL的编程题,但360这套笔试题(一)更多还是客观题为主。
关于索引,有一个高频选择题是“为什么数据库索引使用B+树而不是红黑树”。答案需要从磁盘IO次数和范围查询两个角度分析:B+树非叶子节点不存数据,单节点能存储更多索引项,树高更矮,磁盘IO更少;B+树叶子节点用链表串联,适合范围扫描。这道题如果你在笔试里只答“因为B+树更矮”,得分不会高;如果能在此基础上说“叶子节点链表对范围查询友好,而红黑树在中序遍历上表现不如B+树”,就有区分度。
SQL练习题,我的建议是把牛客或LeetCode上的SQL简单/中等题刷一遍。虽然笔试里SQL题目占比不高,但它是少数可以稳定拿分的部分——因为规则清晰、答案确定。如果你的目标岗位是后端研发,SQL能力是必须的;如果你做客户端,至少也得懂基本查询和事务概念。2016年的题目可能不会考窗口函数(那会儿窗口函数还不像现在这样普及),但今天准备笔试的人,窗口函数也值得花时间学会。
3. 做题节奏与答题策略:这套卷子拼的不只是知识,还有取舍能力
3.1 “三遍做题法”应对题量大的试卷
面对题量大、覆盖面广的笔试试卷,绝对不要想着一口气从头做到尾。我自己总结了一个“三遍做题法”,在应对2016年这种风格的笔试时非常有效:
第一遍,快速扫一遍全卷,把一眼就能确定答案的题直接做掉。这类题通常是概念型、计算型,不需要反复推敲。做的时候顺手在草稿纸上记录题号和答案,避免后面涂卡出错。这一遍的目标是把基本盘稳住,确保不是因粗心丢分。
第二遍,集中精力做那些“有思路但需要计算或推理”的题。比如C/C++代码输出题、网络报文分析题、逻辑推理题。这些题花费时间较多,但属于你能力范围之内的,是区分度的来源。
第三遍,回头啃那些完全没思路的题。这时候要运用排除法和选项对比,尽量提高猜中概率。千万不要在第三遍之前就把时间耗在一道不会做的题上。
我当年吃过亏:在一道指针和强制类型转换结合的选择题上较劲了十几分钟,结果后面有几道会做的网络题没有时间做。后来我给自己定了一个铁律——选择题思考时间超过3分钟直接跳过,最后统一蒙一个概率最高的选项。这个策略不能保证满分,但能保证你拿到所有“应得”的分数。
3.2 选择题的排除法不是瞎猜:每一个错误选项都值得分析
高质量的笔试题,错误选项往往比正确选项更值得看。它们要么是常见误解,做出来就是为了“坑”你;要么是相近概念,用来考验你的辨析能力。比如在C语言题目里,选项可能同时出现“在栈上分配”“在堆上分配”“在静态存储区分配”这三个,而代码里定义了一个全局数组——正确答案显然是静态存储区,但如果你把“全局”和“堆”搞混,就会掉坑。
所以我的建议是:选择题不要只满足于选对,平时刷题时要把每个错误选项为什么不选写出来。这个习惯在考试时能帮你快速识别出题人的“陷阱模式”。举几个当年常见的陷阱类型:
概念被加修饰词变味:比如“TCP是可靠的传输层协议”是对的,但“TCP保证数据包不丢失”也是对的吗?不对,TCP可以提供可靠传输,但不等于物理上不丢包,而是通过重传保证数据的最终可靠性。这种修饰词变化是选择题最爱考的点。
边界条件被忽略:比如排序算法稳定性判断题,“选择排序是不稳定的”,但有人可能会被“元素相同不交换”误导。边界条件没有分析清楚,就选错了。
选项之间互斥:有时候两个选项互为矛盾,那么正确选项必为其中之一。比如“进程切换一定会发生用户态到内核态的切换”和“进程切换不会发生用户态到内核态的切换”这两个选项,前者是对的。利用选项互斥关系,能快速缩小范围。
3.3 编程题的答题姿势:先给思路再写代码,阅卷体验很重要
2016年的研发工程师笔试题(一)通常不会只有选择题,还会带上手写编程或算法设计的大题。这是整张卷子里最考验输出能力的地方,也是很多平时只做题不看写法的人容易失分的区域。
核心经验是:即使题目只要写代码,也要先在试卷空白处用一两句话写清你的思路,再写代码。这样做有几个好处:第一,能够倒逼自己理清逻辑,避免边写边想导致代码混乱;第二,如果代码有小错误,阅卷人看到思路是对的,会酌情给分;第三,在时间紧张的时候,写下思路至少证明你掌握了解题方向,比留白强太多。
写手写代码时,字迹工整、变量命名有意义、缩进层次清晰,这些“看起来不重要”的点其实会影响阅卷人的判断。我之前参与过帮忙阅卷的活动,说实话,面对大量试卷,结构清晰、注释得当的答案天然会获得更多好感;而一团乱麻的代码,即使思路对,也可能因为读不懂而被扣分。
另外特别注意:用熟悉的语言作答。这套笔试题(一)的时代背景是C++/Java为主流,如果你平时写Python,而题目要求用C++实现链表操作,还是尽量不要临时切换。笔试不是为了炫技,用最熟练的语言把问题解决才是上策。
3.4 草稿纸和状态管理:这些“软实力”经常被低估
线下笔试会发草稿纸,线上笔试也有在线记事本。很多人不重视草稿纸的使用,直接在试卷上画来画去,最后搞得一片混乱。我当时的习惯是:把草稿纸分成几个区域,一个区域专门做指针/地址/内存布局的计算,一个区域做网络报文流的推演,一个区域做大题的思路草稿。这样检查的时候,我能快速找到当初的计算过程,重点复核可能的失误点。
状态管理方面,笔试时间一般在90到120分钟之间,题量又不小,如果连续做30分钟高强度的选择题,脑力消耗很快。我的经验是:做完一遍选择题后,稍微闭眼休息10秒钟,深呼吸一下,再进入第二遍。这个简单的动作对维持判断力很有帮助。还有,做题顺序也可以调整,如果你网络知识比C++好,可以考虑先做网络部分的题,保证优势模块的分数全部拿到。
4. 同一套题放在今天:哪些考点“过时”了,哪些依然锋利
4.1 被时代淘汰的题目类型:从“重语言细节”到“重工程素养”
如果把2016年的这套题原封不动放到今天的校招里,会有些“错位感”。最具代表性的是C/C++细节点考查。如今很多研发岗位默认使用Java、Go、Python,甚至TypeScript,对于C/C++内存细节的要求不像当年那么普适;即使是C++岗位,面试也更倾向于通过一个具体场景让你设计类或排查问题,而不是做一堆“指针+类型转换”的选择题。因此,像“指定结构体在32位机器上占用多少字节”这类计算题,在今天的大厂笔试中占比显著下降。
另一个“过时”的点是Linux命令背诵题。不是说Linux不再重要,而是现在的技术栈更复杂了。今天更常见的考法可能是给你一段Dockerfile或者K8s YAML配置,让你指出问题;或者直接考你排查线上问题的思路。这种变化反映的是整个行业从单体应用到云原生的演进——基础命令依然是底层能力,但它不再是考核的终点。
数据库方面,当年笔试还停留在“B+树、事务ACID、SQL基本查询”的层面,而今天后端笔试题已经逐渐加入分库分表、Redis缓存一致性、消息队列可靠性等分布式系统相关考点。这种变化不是2016年出题人没水平,而是当时分布式技术还没大规模渗透到校招笔试的范畴。
4.2 不变的是“计算机系统”的底层心智模型
尽管题型和考点在变化,但2016年这套题背后想测的底层能力并没有变,甚至更加重要。什么是底层能力?就是你对计算机系统的整体理解能力:一个程序从源码到进程,从内存到磁盘,从单机到网络,它的数据是怎么流转的,资源是怎么被管理的,故障是怎么发生的。这套笔试题(一)中关于指针、内存、进程、TCP、文件系统的题目,本质上都在考察这个心智模型。
今天面试中常见的“设计一个短链系统”“如果线上接口突然超时你怎么排查”“Redis为什么快”等问题,表面上是新八股,但底层的支撑依然是计算机系统知识。比如接口超时排查,你至少需要理解网络超时重传、线程池排队、数据库连接池耗尽、CPU争抢、GC停顿等因素,这些恰恰是2016年笔试里那些操作系统和网络选择题背后的知识。所以说,那套题经典就经典在它搭建了一个基本框架,用十年的维度来看,框架没有塌。
4.3 现在的刷题方式反而可能丢失了“笔试能力”
在LeetCode和各类在线OJ普及的今天,很多人的备考方式变成“刷题+看题解”。这确实提高了算法题的解题能力,但也带来一个新的问题:知识面严重收窄。有些候选人数据库、操作系统、网络的知识停留在面试前两天的背诵状态,题目稍微变个说法就反映不过来。2016年那种大范围客观题的笔试模式,虽然看起来“古老”,但它逼迫你必须全面复习,这种广度训练其实是一种非常有效的系统学习方式。
所以我的观点是:你现在不该只为了应付某种题型去刷题,而应该把“系统学习”放在“应试技巧”之前。即使你遇到的笔试全是纯编程题,掌握了操作系统和网络知识也能让你写出更健壮的代码——比如你会知道为什么多线程下需要加锁,为什么网络请求要设置超时,为什么数据库查询要避免全表扫描。这些东西笔试不一定直接考,但面试和工作中随时会遇到。
5. 从笔试题到工程能力:这套卷子筛出来的人,在工作中什么样
5.1 笔试考点与真实工作场景的映射关系
我后来参与过技术招聘的简历筛选和面试,再回头看2016年这套笔试题的考点,发现它跟真实工作有很强的映射关系。下面列几个我印象深刻的对应关系:
选择题里的“内存布局与指针”对应的是工作中排查线上崩溃问题。服务进程突然coredump,你需要用gdb查看堆栈,判断是空指针解引用、数组越界还是内存碎片问题。大学期间有没有学过内存布局,决定了你遇到这种问题时是被动重启服务,还是能快速定位根因。
“TCP三次握手和四次挥手”对应的是排查连接异常问题。线上服务出现大量TIME_WAIT或CLOSE_WAIT连接,你需要理解TCP状态转换图,才能判断是客户端没关连接、服务端没接收完数据,还是负载均衡配置有问题。这个能力不是面试时临时背的,而是对网络协议本质的理解。
“进程调度与死锁”对应的是并发编程和锁设计。研发工程师写多线程代码时,如果对死锁的四个必要条件有本能反应,写加锁代码时就会自然注意加锁顺序;如果只知道“要加锁”,很容易在复杂业务逻辑下留下死锁隐患。
“B+树索引与事务隔离级别”对应的是数据库线上调优。慢SQL出现时,你知道建什么索引、怎么避免锁冲突、如何调整隔离级别,这些都是笔试知识在工作里的直接延伸。
所以,如果你现在觉得某些笔试题目“学了又用不上”,不妨换个角度:它们不是知识点的终点,而是工程判断力的起点。2016年那个时间点没有现在这么多中间件和云服务,但计算机体系的底层逻辑到现在依然发挥着作用。
5.2 一道笔试难题对应的真实排查案例
说一个我记忆里比较有画面感的例子。某次在业务开发中,服务在高峰期偶尔出现接口超时,但不是每一次都失败。我和同事一开始怀疑是网络问题,后来发现每次超时的间隔很有规律,怀疑是否与JVM老年代GC有关。查看监控后发现,GC日志确实显示老年代回收频繁。当时我们在现场用命令看了堆内存、GC线程、对象分布,最终定位的是某个全局缓存对象在热点数据访问时被频繁更新,导致大量对象晋升到老年代。修复方式很简单,改为局部缓存加异步更新。
这个故事和2016年的笔试题有什么联系?回想那张卷子,有道选择题是“关于JVM垃圾回收,以下哪种说法是正确的”,选项涉及新生代、老年代、Minor GC和Full GC。如果当初只是把选项背下来,可能无法迁移到真实问题中;但如果理解了“对象生命周期和内存分区的关系”,你看到GC频繁时就会本能地想到“是不是有大对象或缓存对象频繁创建”。笔试考的不是那道题本身,而是通过那道题把你引导到正确的思考维度上去。
5.3 从“应试者”到“出题人视角”,反哺自己的知识体系
如果你已经过了笔试那一关,进入日常工程开发阶段,我强烈推荐你做一件事:时不时站在“出题人”的角度审视自己掌握的知识。比如你可以试着给自己出几道关于自己业务的笔试题:如果一个新同学来做这个项目,我最希望他掌握哪些前置知识?用哪些选择题能快速判断他有没有掌握?
这个习惯价值很大。它逼着你把隐性经验变成显性知识,把“会做”升级为“会教”。你会开始注意自己每天敲的那些命令为什么有效,自己写的那些SQL为什么走了索引,自己部署的服务为什么能稳定运行。2016年那套笔试题所考核的“知识广度”,其实不应该在校招结束就被抛弃,而应该成为你职业成长中不断回望的基础路线图。
6. 备考这套题的实用路线:以“知识体系”而非“题库数量”为目标
6.1 第一步:建立知识地图,不要盲目刷题
如果你现在想用2016年360研发工程师笔试题(一)来训练自己,我建议第一步不是立刻做题,而是先画一张知识地图。把笔试题可能涉及的模块列出来:C/C++语言、数据结构和算法、操作系统、Linux、计算机网络、数据库、安全基础、逻辑推理。然后针对每个模块,用几个问题来自测:我能不能用简单的语言讲清楚这个概念?能不能举出实际例子?能不能说出常见的坑?
这个自测的过程会直接暴露你的薄弱点。比如你可能数据结构掌握得不错,但子网掩码计算不熟练;或者算法题刷得多,但一看到http状态码403和404的区别含糊不清。这时候不要急着补齐所有东西,先集中精力突破最薄弱的两个模块,因为笔试的分数结构是“短板决定下限”,只有补上短板,你的总分才能稳定提升。
6.2 第二步:高质量刷题与复盘的具体方法
刷题不是越多越好,质量远比数量重要。我建议把两类题目作为重点:一类是历年校招真题,尤其是跟你目标公司同城的、同领域的公司笔试题;另一类是经典教材课后题和考研题中的选择题部分,2016年那套卷子的风格和考研408统考有不少重叠,这一点很多过来人都深有体会。
具体做法是:每一道题做完后,不要只看正确答案,一定要看解析,并追问“出题人为什么用这个选项做干扰项”。把每道题涉及的考点和不熟悉的知识点记录到一个错题本里,每周复盘一次。这个错题本不是简单粘贴题目,而是写下自己的理解,比如“我以为A对,其实A错在把无状态和不可靠混为一谈”。这种“自我对话式”的复盘,效果远好于反复刷题。
6.3 第三步:考前模拟,关键是模拟“时间压力”
笔试和平时刷题最大的区别是时间压力和心理压力。建议在考前一周做几次完整的模拟:找一套真题,按正式考试时间来做,关闭手机,严格限制答题时间,做完后给自己打分。第一次模拟可能会让你意识到时间不够用,这非常正常——模拟的意义正是为了让你在真正考试前体验这种紧张感,并有意识地调整做题顺序和时间分配。
我当时模拟时发现,自己在指针计算题上花费过多时间,导致后面的数据库题没时间细想。后来我调整策略:把指针计算题统一留到第二轮再做,先保证网络、数据库这些相对熟悉的知识点拿分。这个策略在正式考试中帮了我大忙。
6.4 笔试只是起点:拿到面试机会后要做什么
笔试通过后,紧接着就是技术面试。很多人在准备笔试时只盯着“怎么过笔试”,忘了笔试刷题时的知识积累可以直接变成面试素材。比如你说“我了解TCP的拥塞控制”,面试官让你详细讲讲慢启动和拥塞避免的区别,如果你只是在笔试里选了正确的选项,没有真正理解,很可能回答得支支吾吾。
我的建议是:笔试备考期间,每复习一个知识点,顺手给自己列一个“如果面试被问到,我该怎样展开讲讲”的提纲。比如复习到B+树索引,提纲可以是:B+树结构特点、为什么适合磁盘存储、与红黑树的对比、联合索引和最左前缀原则、覆盖索引和回表。当你能够自然地把这些内容讲成一段有逻辑的话,笔试和面试就形成了一个完整的闭环。
写在最后:当年那套卷子,最珍贵的产出不是分数
2016年那场360研发工程师笔试题(一),如今或许已经变成网盘里的一份旧PDF,但对每一个认真准备过、认真做完、认真复盘过的人来说,它的价值远超过一张成绩单。它像一次计算机基础知识的“全面体检”,帮你看到自己在庞大的知识体系里,哪些地方有优势、哪些地方有漏洞。我到现在还记得,考完那套题后,我花了一整个星期把C++对象模型和TCP状态图重新啃了一遍,那种“查漏补缺”的充实感,比接到面试通知还让人踏实。
如果你现在正在准备笔试,不管是不是360的题,我都建议你别太迷信“押题”和“题库”,而是回到知识的源头,把每一个基础概念落到实处。笔试题会变,出题风格会变,但计算机科学的核心逻辑一直是稳定的。把底层框架打牢,无论考什么、做什么,你都不会慌。