ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

360研发笔试题深度拆解:数组指针、Linux与系统底层考点全解析

360研发笔试题深度拆解:数组指针、Linux与系统底层考点全解析 360的研发笔试题在圈子里口碑一直很两极喜欢的人觉得它考得实在不玩虚的觉得它难的人往往吃亏在“基础太熟反而想多”上。这份2016年的第二套笔试题二是典型的360风格——选择题占比不低但真正拉开差距的是那几道需要手写代码、分析内存布局、推演边界条件的题。我当时做完最大的感受是它不是在考你会不会背八股而是在考你写代码的时候有没有形成“条件反射”。如果你正在准备各厂商的研发岗笔试这套题里的数组与指针、Linux、Java、网络协议这些点放到今天依然是高频考点值得静下心来刷一遍。1. 笔试题二的整体设计逻辑与考点拆解1.1 第二套试卷在整轮考核中的定位2016年那会儿360的研发工程师招聘流程已经比较成熟了一般要经历“简历筛选 → 在线笔试 → 技术面试 → HR面”几个环节。笔试通常不止一套试卷而是按岗位方向拆成A、B卷或者一二三这样的组合。第二套试卷的定位很有意思它比第一套更偏底层比第三套更偏工程。什么意思呢第一套往往是通用能力筛查范围广但深度浅数据结构、网络、数据库、逻辑题都沾一点主要是把基础不牢的人筛掉。第三套则更贴近具体业务线比如你做Windows客户端开发可能会大量出现Win32 API、消息循环、内存映射这些题。而第二套正好卡在中间它既要检验你对操作系统和编程语言底层的掌握又要看你能不能把知识落到实际工程场景里。所以你会看到它同时出现Linux命令分析、Java内存模型和C指针运算这不是出题人随意拼盘而是标准的“中间层筛选”。对于候选人来说如果第二套试卷做题过程比较顺畅说明你具备两个特质一是基本功扎实二是知识面没有明显短板。这两点在360这种业务庞杂、既有安全产品又有IoT和搜索广告的公司里确实很重要。说白了360不是一个“一招鲜吃遍天”的地方研发岗经常要在不同技术栈之间切换所以笔试第二套考的就是你的“技术迁移能力”。1.2 从常考题型反推能力模型网上能搜到的360研发工程师笔试题二碎片很多整理下来出现频率最高的几个方向大概是C/C尤其数组与指针、操作系统原理、Linux操作、网络协议、数据结构与算法、Java基础。这个结构其实对应了一套很清晰的能力模型第一层是语言底层理解力。不管是C还是Java你不能只停留在“会用”层面得知道变量在内存里怎么布局、指针和数组在编译器和运行时分别代表什么、Java的堆和栈到底什么时候分配。第二层是系统资源掌控力。进程和线程的区别不是背概念而是要知道它们创建、调度、同步时各自的代价Linux命令不是机械记忆而是通过命令去理解系统的行为。第三层是算法与代码实现的稳定性。笔试里的算法题不会太偏门但会在边界条件上做文章考察你短时间内写出正确且健壮代码的能力。这三个层面叠在一起基本就把“能做研发”和“只能做题”区分开了。很多基础不错的人挂在这种试卷上往往不是因为不会而是因为“想太多”。我记得有道很经典的字符串相关题目表面考KMP实际上只要用简单的哈希就能AC。出题人给你留了多条路但你要具备快速判断复杂度的敏感性不然就会掉进“标准解”的陷阱里。2. 核心考点解析数组和指针为什么是重头戏2.1 数组与指针看着简单错得莫名其妙在360这道笔试题二里数组和指针相关的题目数量相当可观而且难度梯度拉得很开。从最简单的“sizeof一个int数组和sizeof一个int指针分别等于多少”到“二维数组用指针访问时步长怎么算”再到“函数参数退化为指针后为什么修改不了外部值”每一层都有人掉坑。我见过太多人在这一块翻车问题集中在三个方面第一分不清“数组名”和“指向数组首元素的指针”在语法语义上的差别。数组名在绝大多数表达式中会退化为指针但在sizeof、取地址符等少数场景里不会这个细节是选择题的经典陷阱。第二搞不清楚指针运算的步长。int* p; p1到底加几个字节取决于sizeof(int)这在32位和64位环境下还不一样如果你默认“指针就是4字节”在高版本编译器下很容易出问题。第三混淆“指针数组”和“数组指针”两者写起来只差一个括号含义却天差地别。实际笔试时这类题往往不是单独出现而是和内存布局、函数传参混合在一起考。你不仅要知道答案还要能解释为什么。比如char str[] hello; char *p hello; printf(%zu %zu\n, sizeof(str), strlen(p));str是一个数组占据6个字节包含末尾的\0strlen(p)计算的是字符串长度5。但如果有人把sizeof(str)答成5说明他没搞明白sizeof和strlen的区别sizeof是编译期计算操作数所占内存大小strlen是运行时扫描到\0为止。这种题考的不是记忆而是你对C语言内存模型的本能反应。2.2 指针题背后的工程价值有些同学会问现在写业务代码谁还天天碰指针其实你一旦进入安全、系统底层、高性能组件、嵌入式这些方向指针就是家常便饭。360的核心业务里有大量安全攻防、扫描引擎、网络协议栈相关开发这些代码对内存布局的精确控制是刚需。一段越界读写线上可能就是崩溃或者被利用的漏洞。笔试考指针本质上是在筛选“对内存敏感”的工程师。我建议你在准备这类题时不要只记结论而是养成在纸上画内存图的习惯。画一个数组标出每个元素的地址画一个指针变量画出它指向的目标。遇到二维数组和指针数组就画表格式的格子图。画几次之后很多“玄学”会变成直觉。这也是我当年刷题的一个心得**所有指针题的错误都是因为脑子里没内存模型光靠语法去猜。**你一旦把内存图画出来99%的题都不会做错。另外C/C方向还有一道高频题是“为什么数组作为函数参数传递时会退化为指针”。因为C语言函数参数是按值传递的数组名代表整个数组这一信息在编译时无法作为值整体拷贝所以标准规定它退化为指向首元素的指针。这也是为什么在函数内部用sizeof(参数)得不到数组长度的原因。理解了这一层你就明白为什么许多代码规范要求数组传参时同时传入长度参数。3. 操作系统与Linux从笔试题目看系统思维3.1 进程、线程和同步不只是背概念第二套试卷在操作系统板块的命题往往从“现象”切入再要求你分析“本质”。比如它可能给你一段多线程程序问你最终输出是什么以及有没有竞态条件。这种题比单纯问“进程和线程的区别”要难得多因为它要求你理解线程调度的不确定性。备考时我推荐你把这三组概念理透进程和线程的创建代价、上下文切换代价、共享内存方式互斥锁、读写锁、信号量、条件变量适用的场景死锁产生的四个必要条件以及实际工程中如何避免。这里最容易出错的是信号量和互斥锁的区别。信号量可以表示资源数量能做到“允许N个线程同时访问”互斥锁只能被一个线程持有语义更严格。有些题会让你用信号量模拟互斥锁或者反过来用互斥锁配合计数器模拟信号量这都属于经典考法。你在现场如果没有把这几种同步原语的使用场景理清楚很容易写出“看起来对跑起来死锁”的伪代码。内存管理也是必须啃的硬骨头。虚拟地址空间怎么划分栈为什么向下生长堆为什么容易产生碎片malloc和free背后发生了什么出现段错误和内存泄漏时操作系统层面是什么表现。360这类偏底层的公司特别爱考这些因为它们和实际开发中的稳定性问题强相关。3.2 Linux命令题越基础的越容易暴露短板Linux相关的笔试题在这套卷子里通常不难但覆盖面广常见的有查看进程的命令ps/top、查看端口占用netstat/ss注意新版系统ss更常用、文件权限管理chmod/chown、文本处理grep/awk/sed、软链接硬链接的区别ln -s。很多人在硬链接和软链接上栽过跟头。硬链接本质是同一个inode的多个目录项删除一个链接只要还有别的链接指向这个inode文件数据就不丢失软链接是一个独立的文件里面存的是目标路径目标被删除后软链接就变成“悬空链接”。有个很经典的题目对软链接执行ls -l看到的大小是它自己存储的路径长度而不是目标文件的大小。如果你没实操过光靠背是记不住这种细节的。我的建议是刷题的同时在Linux环境里把命令都实际敲一遍。不用多复杂你可以在临时目录里创建文件、做软硬链接、修改权限、用管道组合几条命令再观察结果。这样做的收益是双重的既应付了笔试里的选择题也为后续面试中“你平时怎么排查线上问题”这种开放题积累了素材。我当年就是靠“top看到CPU高 → 用ps定位进程 → 用strace看系统调用 → 再用gdb看调用栈”这条链路在面试里跟面试官聊了十几分钟最后拿到了不错的评价。4. 数据结构与算法从笔试代码题看解题节奏4.1 高频算法题型的“最小完备集”第二套试卷里的算法题不会像ACM竞赛那么偏但也不全是“反转链表”这种入门级。我在整理常见回忆题时发现出现率最高的集中在这么几类链表操作反转、环的检测、合并有序链表、二叉树遍历与重建二叉树的前中后序、层序、根据遍历序列还原树、排序与查找快排、归并、二分变形、字符串处理子串匹配、去重、括号匹配、以及简单的动态规划背包、爬楼梯变种。如果你时间有限我的建议是先确保自己能“闭着眼睛”写出下面五个代码骨架单链表反转迭代版和递归版快速排序注意轴点选取和partition写法二叉树中序遍历递归版和迭代版二分查找注意上下界和循环不变量字符串转整数含溢出和非法字符处理这五个骨架覆盖了笔试中80%的代码环节。尤其是链表反转和二分查找你不仅要会写还要能讲清楚每一步为什么。360这类公司面试时经常让你在白板上写代码写完还会追问时间复杂度和边界条件。你如果能做到“不假思索地写出来并且对每个判断条件都给出理由”这部分基本稳了。4.2 一道典型题目手写链表反转的边界处理我以链表反转为例说说笔试代码题的正确打开方式。很多人能写出核心循环但一遇到空链表、只有一个节点、算不清楚“pre/cur/next”三个指针的关系就卡住了。这时候你需要的不是更多的题而是固定的思考顺序。先明确定义反转后的链表头应该是原来的尾节点。迭代法的思路是用pre保存已经反转好的部分链表的头节点用cur指向当前要处理的节点用next保存cur原本的下一个节点防止断链。Node* reverseList(Node* head) { Node* pre NULL; Node* cur head; while (cur) { Node* next cur-next; cur-next pre; pre cur; cur next; } return pre; }注意这里while循环的条件是cur不是cur-next后者会让最后一个节点没有被处理。还有一点返回的是pre不是cur因为循环结束时cur已经走到NULL了只有pre才是新的头节点。这些细节我在批改别人代码时发现经常有人搞错。递归版也很值得掌握逻辑更短但理解门槛高一些Node* reverseListRecursive(Node* head) { if (!head || !head-next) return head; Node* newHead reverseListRecursive(head-next); head-next-next head; head-next NULL; return newHead; }递归版的关键在于先反转后面的链表再把当前节点的下一个节点的next指回当前节点。你需要特别注意最后把head-next置为NULL否则会形成环。这个“断开”的步骤经常被遗漏是笔试题反馈里很容易遗漏的点。4.3 现场做题的时间分配策略笔试的时间分配同样重要。整套卷子大概涵盖选择、简答和编程题我个人的建议是选择题控制在总时间的三分之一内简答题控制在三分之一最后三分之一留给编程题和检查。选择题如果卡住超过两分钟果断先标记跳过。编程题优先写最容易验证的解法先保证准确率再考虑优化。不要一上来就写一个复杂的优化版本结果调试花了大量时间反而丢分。另外一个容易被忽略的策略读题时把“输入范围”圈出来。如果题目告诉你输入规模是10^5量级那O(n^2)基本会被卡你要想O(nlogn)或O(n)的解法。如果输入规模很小那暴力解法也能接受。这道题在当年笔试里经常用这种方式来考察候选人的复杂度敏感度。5. Java方向在笔试题二中的身影5.1 JVM内存区域与内存泄漏判断虽然360的笔试偏底层但并不意味着Java岗位就会绕过这些底层知识。事实上第二套试卷里Java相关的题也不少而且往往是拿Java的底层实现来考同样的系统知识。比如JVM的内存区域划分程序计数器、虚拟机栈、本地方法栈、堆、方法区/元空间。每个区域存什么、什么时候可能抛异常都是高频题。我在整理相关搜索热词时看到“java笔试题大全带答案”和“亚信科技笔试题java”这类词说明Java方向依然是研发岗笔试的大头。这里有个常见误区不少人觉得只要会Spring和业务CRUD就能做Java研发但笔试不会陪你玩这个。它考的是你new出来的对象在哪里分配栈上分配和TLAB是什么为什么长生命周期的对象容易进老年代Full GC阶段会不会STW这些问题看起来“底层”但它们直接决定了你在高并发场景下怎么调优JVM参数怎么排查线上OOM。有一个典型的笔试题型给你一段代码里面有个静态集合不断add对象问会不会内存泄漏为什么。答案是静态变量持有引用导致GC无法回收这些对象。看似简单但很多人会漏掉“静态变量生命周期与类一致比对象长”这个关键点。这种题的价值在于它考察的不是你会不会背概念而是你能否在代码里识别出内存泄漏的隐患。5.2 Java多线程与框架底层的考察点Java多线程在笔试里几乎从不缺席。Thread和Runnable的区别、Callable和Future的用法、synchronized和ReentrantLock的区别、volatile的可见性和禁止重排序语义、线程池的核心参数corePoolSize、maximumPoolSize、workQueue、handler如何搭配这些都是高频点。你会发现这些知识点和前面提到的操作系统线程同步其实是相通的只是换了一套Java的壳。线程池是重灾区。很多人能背出参数却不理解当提交的任务数超过corePoolSize且队列未满时任务会进队列而不是立即创建新线程。只有当队列也满了才会创建新线程直到maximumPoolSize如果还处理不了就交给RejectedExecutionHandler决定怎么拒绝。这是一套完整的资源饱和处理机制。笔试里经常出一个场景问你“核心线程数5最大线程数10队列容量100连续提交多少个任务后开始创建非核心线程”如果你不理解队列优先的逻辑很容易答错。我的建议是线程池就把它想象成银行柜台核心线程是固定窗口队列是排队的凳子最大线程是紧急加开的窗口拒绝策略就是告诉客户“今天办不了改天再来”。6. 常见问题与避坑经验结合多年刷题和面试官的复盘6.1 候选人在笔试里常踩的五个坑我结合自己当年做题以及后来帮同事审校笔试题的经验整理了五个最典型的失分点这些地方比“知识不会”更可惜。第一审题不仔细。题目问“以下哪个是错误的”你当成“以下哪个是正确的”来选一错就是整题丢分。第二边界条件缺失。写代码题时不检查空指针、空字符串、负数、极端大数这在笔试里几乎是必扣分的点。第三复杂度分析没写。有些编程题要求你写出时间复杂度和空间复杂度很多人实现完就结束了白白丢分。第四习惯性依赖编译调试。在线笔试环境里第一遍就写对比反复调试重要得多尽量在提交前做静态检查。第五时间分配失衡。在选择题上反复纠结结果编程题只写了半截这是最常见的失败模式。6.2 常见问题速查表问题类型典型错误正确的处理思路sizeof(数组名)以为是数组长度区分字符串长度和内存大小注意末尾\0指针自增以为是地址加1字节实际加的是sizeof(指向类型)的字节数函数传入数组在函数内用sizeof求长度数组退化为指针需同时传长度参数死锁判断只死记四个必要条件结合加锁顺序和资源竞争实例分析子线程修改共享变量不加同步直接读考虑可见性和原子性必要时用volatile/lock递归边界忘记终止条件或断链先写出递归出口再处理递归体线程池参数搭配背参数但不理解触发顺序按“核心线程→队列→非核心线程→拒绝策略”顺序分析二分查找循环条件写成left right根据搜索区间确定left right注意mid取值这张表是我带项目组新人时经常发的基本能覆盖笔试中最常见的失分点。你可以把它们当成一个自测清单每道题做完后对照检查一遍。6.3 如何高效利用历年真题和小伙伴的考题回忆网上关于360笔试的真题碎片很多但大多不完整。我的建议是不要迷信“原题”而是把重点放在“题型归纳”上。你把能找到的题目按知识点分类然后针对每个分类做专项练习。比如数组和指针题收集十五道二叉树题收集十道Linux命令题收集二十道。刷完之后你会发现很多新题其实是旧题的变体出题人只是改了数据规模或者换了一层业务包装。另外我特别推荐“费曼输出法”每做完一套题挑三道最有代表性的题目用讲课的方式把自己讲懂。讲的时候你会发现很多地方模棱两可这些地方就是你真正的知识盲区。补上这些盲区比多做十道新题都有用。这个方法我用了很多年从自己备战笔试到后来带团队面试都屡试不爽。7. 一些可以“抄作业”的实操准备建议7.1 考前一周的冲刺清单如果你离笔试还有一周我的建议是不要再去啃全新的知识点了而是把精力放在三件事上。第一把常见的C/C指针和内存题目快速过一遍确保基础题不丢分。第二手写五道高频算法题包括链表反转、快排、二分、二叉树遍历、字符串处理每道题写到自己能顺畅讲清楚为止。第三把Linux常用命令过一遍尤其是进程、端口、文件权限、文本处理这些高频场景。为什么这么安排因为笔试的分数结构通常呈金字塔型基础题最多中等题次之难题最少。你先把“基础题不丢分”这个底线守住就已经能超过很多人了。很多能力强的候选人反而是因为基础题粗心导致整体分数不理想这真的很冤枉。7.2 笔试现场的心态和细节笔试现场的节奏感很关键。拿到卷子后先不要急着动笔花三到五分钟把整张卷子浏览一遍在心里给每道题标一个难度档位。先做会做的再做需要思考的最后啃硬骨头。遇到完全没思路的题不要直接放弃把你能想到的相关公式、思路、伪代码写上去。笔试阅卷时部分题目是按得分点给分的你写出的每一个正确分析都可能拿分。还有一点容易被忽略代码题的变量命名和注释。在线笔试系统一般不会因为你注释写得好而加分但如果你能在现场保持清晰的命名和必要的注释会大大降低自己出错的概率。我见过很多考生提交的代码里全是a、b、c这种变量名写到后面自己都分不清了。与其这样不如用head、cur、pre、next这种语义清晰的命名代码的可靠性能一下子提高不少。7.3 后续面试里怎么把笔试内容“用起来”笔试不是终点而是面试的素材库。如果你笔试里遇到了某个让你印象深刻的题目面试时恰好被问到相关领域你可以主动提起“我笔试时遇到过类似问题当时的思考是这样的……”这比被动回答问题要加分得多。面试官会觉得你是真的在思考问题而不只是在背题库。另外笔试中写过的代码如果有优化空间建议考后立刻复盘一遍。比如链表反转你笔试时用了迭代法面试时能不能顺手写出递归法如果能那就展示了你对同一个问题有多角度思考的能力。这种东西在面试里非常加分。从我个人的体验来看准备360这类公司的研发工程师笔试最重要的事情不是做多少套卷子而是建立起一套属于自己的“问题分析框架”。看到一道题你脑子里应该自动浮现它在考什么知识点、有哪些边界条件、应该用什么复杂度的方法去解、如果时间不够怎么拿部分分。当你拥有了这套框架不管题目怎么变你都能保持稳定发挥。这套框架说起来有点玄其实完全是通过反复分析和复盘练出来的。希望这份拆解能让你少走一些弯路剩下的关键就在亲手写代码了。
返回列表