
滴滴出行2018校园招聘内推笔试Linux内核工程师。看到这个标题估计不少当年投过这个岗位的同学都有印象。我当时收到笔试邮件的时候还在实验室调一个驱动bug说实话有点慌因为内推笔试和正式批笔试不一样没有太多往届真题可以参考。但考完之后回头复盘发现这场笔试出的题其实非常“正经”——不偏不怪就是扎扎实实考察Linux内核方向的基本功。我花了三个晚上把整张卷子涉及的考点全部梳理了一遍今天整理成这篇经验贴给准备投内核方向校招的同学一个完整的参考。很多人会问内推笔试到底和网申笔试有什么区别我的体会是内推笔试更看重基础深度题目量不小时间紧张但几乎没有“脑筋急转弯”式的题。整张卷子覆盖了操作系统原理、Linux内核核心子系统、C语言、数据结构和一点Linux运维命令基础。如果你平时只刷算法题没正儿八经啃过内核相关的书那这场笔试很容易翻车。下面我按考点模块把这场笔试的考察内容和答题思路逐一拆开讲。1. 从招聘JD反推笔试考点内核岗笔试的考察地图1.1 内推笔试的题型分布与时间压力先说一个很多人忽略的信息点拿到笔试通知后第一件事不是刷题而是反推这个岗位的JD。滴滴当年招聘Linux内核工程师的JD里写了几个关键词熟悉Linux内核、了解内存管理/进程调度/文件系统、熟悉C语言、有驱动或系统性能优化经验者优先。笔试题目基本就是围绕这些关键词展开的。从题型上看我这场笔试大约120分钟卷面分为几大块题型题量覆盖方向我的判断单选题15题左右C语言、操作系统、Linux基础快速拿分项但容易在编译原理细节上翻车多选题10题左右内核机制、数据结构错选不得分难度明显高于单选问答题4-5题内存管理、调度、同步、驱动真正拉开差距的部分编程题1-2题链表操作、内存分配相关用C实现不要求跑通但要求思路清晰说实话时间是非常紧的。选择题不能犹豫太久我给自己定的策略是选填题最多40分钟剩下的时间全部留给问答和编程。因为问答题分值高而且考察的是“表达逻辑”草草写几句话糊弄不过去。1.2 从当年的搜索热词看考察风向前阵子我翻到当年的一些搜索记录发现几个高频词特别有意思“linux内核学习”、“linux内核设计的艺术”、“linux面试题测试”、“linux常用命令大全”、“嵌入式linux项目”。这些热词恰好暴露了大家备考时的几个痛点“linux内核学习”和“linux内核设计的艺术”说明很多人是从《Linux内核设计的艺术》或者《深入理解Linux内核》开始啃的但不知道怎么筛选重点“linux面试题测试”说明大家还是在用“刷题”的方式准备内核岗这没错但要注意题目的质量“linux常用命令大全”是一个伏笔笔试里确实会考命令但考的不是ls、cd这种入门命令而是内核排查类的命令比如cat /proc/slabinfo、vmstat、dmesg这类。这说明什么说明这场笔试其实在筛选“知识面完整、能干活、能排查问题”的人而不是只会背概念的人。所以我建议复习的时候不要只抱着内核原理书啃还要适当看一些系统运维和性能排查的命令工具它们在内核岗面试中也经常被问到。2. 内存管理整张卷子里最重的一块肥肉2.1 伙伴系统与SLUB分配器的区别不能只背结论内存管理在笔试中的出现频率高到我甚至怀疑出题人就是做内存子系统方向的。最经典的一道题是kmalloc和vmalloc的区别是什么GFP_KERNEL和GFP_ATOMIC的使用场景有什么不同很多同学背过答案但笔试要的是“能讲清楚为什么”。我当时的回答思路是分三层从物理连续性角度kmalloc基于SLUB分配器从低端内存的物理连续区域分配适合小块内存和硬件DMA场景vmalloc通过页表映射把不连续的物理页映射到连续的虚拟地址空间适合大块内存但需要建立页表开销大。从睡眠角度kmalloc使用GFP_KERNEL标志时可能睡眠只能在进程上下文使用GFP_ATOMIC表示分配过程中不睡眠可以在中断上下文使用但成功率低需要做好失败处理。从性能角度kmalloc速度快vmalloc慢得多因为要刷新TLB。这三个层次一一写出来面试官就能看出你是真的理解还是背的八股。我记得题目还引申了一个问题为什么中断上下文不能用GFP_KERNEL答案的关键在于GFP_KERNEL允许睡眠而睡眠需要进程上下文和调度器配合中断上下文根本没有进程的概念强行睡眠会导致内核崩溃。2.2 Linux内核里的“缓冲”到底是什么从page cache到dirty页回写“内核缓冲”是我搜热词时看到的一个点笔试也考了。这里的“缓冲”不是一个笼统的概念而是一套机制页缓存page cache读文件时内核把磁盘上的数据页缓存到内存下次读同一页直接命中内存不再走磁盘Buffer cache在早期Linux版本里用于块设备的缓冲2.6版本后和page cache统一了但概念上仍然有影响dirty页回写应用程序写入文件时数据先到page cache标记为dirty由pdflush现在叫flush线程周期性地把脏页写回磁盘。笔试里考了一个实际场景题机器内存占用很高free -g显示available很低但业务进程的RSS并不高怀疑是page cache占用怎么判断这个题不仅考知识点还考命令。答案是看cat /proc/meminfo里的Cached和Dirty字段以及cat /proc/vmstat里的pgpgin/pgpgout。如果Dirty很大说明有大量脏页没来得及回写。从这一次考试之后我养成一个习惯给任何系统做内存问题排查第一步永远是free -g配合/proc/meminfo先定位内存都被谁吃了而不是直接怀疑应用泄漏。这个习惯后来在工作里救了我很多次。2.3 内存相关的经典编程题手写一个简单的内存池编程题的第二题就是内存分配相关的要求实现一个简单的内存池支持初始化、分配、释放。核心考察点有三个是否了解内存池为什么能降低开销避免频繁调用kmalloc/malloc产生的系统调用和内核锁竞争是否有基本的链表操作能力空闲块链表怎么维护、分配后怎么摘除、释放后怎么回插是否考虑了内存对齐很多笔试答案会忽略aligned但在内核里DMA等场景必须保证对齐。我当时写了一个固定大小块的内存池用free_list单链表串起空闲块初始化和销毁各一个函数。这个题不难但想拿高分必须在注释里写清楚“为什么不用malloc直接分配”、以及“这个池子的线程安全问题怎么解决”。面试官看的是你写代码的同时有没有系统级的思考。3. 进程调度与并发同步内核工程师的必修课3.1 CFS调度器背后的设计逻辑进程调度在笔试里几乎是必考。我记得有一道问答题是CFS调度器的基本原理是什么和O(1)调度器相比有哪些改进如果你只背了“CFS用红黑树维护进程运行队列vruntime最小的进程优先运行”那这道题只能拿一半分。它真正想考察的是你能否理解CFS的设计目标——公平。O(1)调度器用优先级数组高优先级进程可能一直占据CPU低优先级进程饿死CFS引入vruntime的概念每次调度选择vruntime最小的进程让每个进程都能按权重公平获得CPU时间。这里有个很容易被忽略的细节nice值如何影响调度它的本质是通过权重数组改变vruntime的增长速率。nice值越小、权重越大vruntime增长得越慢进程占用CPU的时间就越长。笔试题里给了两个进程一个nice0一个nice5问你哪个进程优先被调度、为什么。答案不是“nice5的先跑”而是“nice值的差异会导致vruntime增长速度不同调度器选的是vruntime最小的这不是简单的优先级高低”。我当时还扩展写了处理器负载均衡多核系统里调度器会通过load_balance机制把任务从忙的CPU迁移到闲的CPU。这个点本来不在题目里但写上去之后会让答案更有层次也让面试官觉得你有全局视野。3.2 自旋锁、信号量、互斥锁与RCU锁的选择是门学问并发同步的题是全场最硬核的部分。原题大概是在Linux内核中自旋锁、信号量、互斥锁、RCU分别适用于什么场景请简要说明理由。这题的答题框架应该是自旋锁忙等待不睡眠适合临界区极短、且可能在中断上下文使用的场景。在单核CPU上需要配合关闭抢占使用在多核上本质是原子操作加循环检测。信号量允许睡眠适合临界区较长的进程上下文。但要注意在中断上下文使用信号量会产生睡眠这是非法操作。互斥锁mutex比信号量更严格的互斥语义只有拥有者才能释放支持优先级继承能避免优先级反转。内核里推荐优先使用mutex。RCU读写场景中读者远多于写者时使用。读者侧几乎无锁开销写者通过延迟回收机制保证数据安全。但RCU对数据结构有要求通常针对链表、数组等场景。这道题你光列四种锁的用途还不够最好补一个反例。我当时写的是“在一个中断处理函数里如果需要保护一个被进程上下文共享的数据结构禁止使用信号量可能睡眠正确做法是使用自旋锁并禁用本地中断spin_lock_irqsave防止死锁。”这个反例很重要它把一个“概念题”变成了“你踩过坑才能写出来的答案”。内核开发里锁选错导致的死锁、睡眠异常问题非常多笔试考这种题就是在筛选有实战意识的人。3.3 高并发场景的常见问法多核性能抖动如何排查有一道场景题我印象很深一个多核系统在高并发下出现性能抖动top看CPU使用率并不高但应用RT明显增大如何排查这题其实考的是系统级排查思路不完全是内核源码知识。我当时的回答分几步先看CPU调度情况cat /proc/softirqs看软中断分布mpstat -P ALL看每个CPU的利用率是否均衡。如果软中断集中在一个CPU上说明网卡中断没有走RPS/RFS或irqbalance没配好导致单CPU过载。看上下文切换次数vmstat 1观察cs列如果context switch很高可能是锁竞争激烈也可能是线程数太多导致调度频繁。看锁竞争perf lock或perf sched可以抓取锁的等待时间找到热点锁。看内存分配/proc/slabinfo和perf kmem可以看是不是某些对象的分配导致缓存行颠簸。这个排查链路在笔试里能写出来绝对是一个大大的加分项。因为出题人不是要你背命令而是要看你会不会用这些工具去定位一个真实的内核性能问题。4. 文件系统与I/O路径从系统调用到块设备的一次完整旅行4.1 一个read()系统调用在文件系统里经历了什么文件系统部分是笔试题里最考验“链路感”的内容。有一道画图/描述题当一个进程调用read(fd, buf, count)时数据是怎么从磁盘到用户空间的完整链路是这样的用户态调用read通过sys_read现在是ksys_read进入内核找到文件描述符对应的struct file通过file-f_op-read_iter调用具体文件系统比如ext4的读操作。ext4先查页缓存page cache如果缓存命中直接拷贝到用户空间如果不命中则发起I/O请求通过通用块层提交到I/O调度队列最终由块设备驱动通过DMA读取磁盘数据然后把数据填充到页缓存再拷贝到用户空间缓冲区。这道题有个隐含考点数据拷贝了几次从磁盘到页缓存一次DMA页缓存到用户空间一次CPU拷贝。这也就是为什么sendfile和mmap能提升I/O性能——它们省去了一次用户态和内核态之间的数据拷贝。我当时画了链路图还标注了各层的关键结构体struct file、struct inode、struct address_space、struct bio。笔试阅卷时这种答案信息密度高、逻辑清晰很容易拿高分。4.2 页缓存、I/O调度器与脏页回写和文件系统紧密相关的是页缓存和I/O调度器。有一道选择题大概是I/O调度器的目的是什么选项包括“减少磁盘寻道时间”、“保证读写公平”、“尽量合并连续请求”等。正确答案是都有关但核心是减少寻道时间和合并请求。内核里的I/O调度器主要有三种Noop不做调度直接FIFO适合SSD和纯随机访问场景Deadline为每个请求设置截止时间避免某个请求饿死适合读写混合的数据库场景CFQ/MQ-DEADLINE按进程公平分配I/O带宽适合普通服务器多进程场景。笔试里我最怕这种多选因为每个选项看起来都有道理。要拿分必须准确理解“I/O调度器工作在块层它面对的是已经生成好的bio请求而不是文件系统层面的读写”。所以它管不到进程怎么发请求只能在队列里做重排。脏页回写的机制也是高频考点。笔试问的是sysctl -w vm.dirty_ratio10这个参数作用是什么答案是当脏页占内存的比例超过10%时内核会触发pdflush/flush线程开始异步写回。这种题已经有点运维的味道了说明笔试并不排斥实践操作知识。4.3 文件系统部分的典型笔试答题套路文件系统的问答题最容易出现“高手低分”的情况因为很多同学知道结构体名称但不知道它们之间的逻辑关系。我总结一个答题套路笔试时真的管用先开一个图用户态→系统调用→VFS→具体文件系统→页缓存→通用块层→I/O调度→驱动图中标出关键结构体file、dentry、inode、super_block、bio用“读/写一次数据”为例子顺着链路把每个结构体讲一遍最后补充说明哪些路径会被缓存命中优化掉。这个答题套路在内核岗面试的“讲一下文件系统”这类问题中也适用。笔试和面试本质是一样的——出题人看的不是你知道多少知识点而是你能不能把知识点串成一个系统。这个链路图要记牢。5. 设备驱动与中断上下文拉开差距的进阶题5.1 字符设备驱动的编写框架滴滴这场笔试的最后一道问答题是驱动相关的简述Linux字符设备驱动的编写步骤。这是个看起来基础、但想拿高分不容易的题。标准的回答模板是设备号注册register_chrdev_region或alloc_chrdev_region→ 初始化cdev并用cdev_add添加到内核 → 用class_create创建设备类 → 用device_create创建设备节点 → 实现file_operations里的open/read/write/release→ 在exit函数里依次撤销。但如果你只写这些分数只能算中等。我当时加了两点并发控制驱动里几乎必然面对多线程访问所以file_operations的实现里必须加锁保护共享资源常见选择是mutex或spinlock内存屏障如果涉及DMA和硬件寄存器需要用到wmb()/rmb()等内存屏障函数防止编译器或CPU重排导致硬件通信出错。这两点一写答案就从“背模板”变成了“真写过驱动”。内核工程师面试官最反感的是只会背API不会考虑并发和硬件约束的候选人。5.2 中断上下文里不能做什么tasklet与workqueue的分工中断相关题目出现了两道。一道是选择以下哪些函数可以在中断上下文安全调用选项里有kmalloc(GFP_KERNEL)、mutex_lock、printk、spin_lock。答案是spin_lock和printk前两个都会睡眠或可能睡眠在中断上下文非法。另一道问答题是中断处理函数为什么要拆分上下半部tasklet和workqueue的区别是什么拆分的核心原因中断处理函数运行时当前中断优先级被屏蔽取决于内核配置其他中断无法及时响应所以必须让上半部尽快结束。上半部只做必要的硬件确认和寄存器读写耗时工作比如协议处理、数据拷贝放到下半部执行。tasklet和workqueue的区别在于tasklet运行在软中断上下文不能睡眠用tasklet_schedule调度适合较轻量的下半部处理workqueue运行在进程上下文可以睡眠用queue_work调度适合需要阻塞等待I/O的下半部处理。我当时还补充了一个驱动开发中的常见坑tasklet回调里如果调用msleep内核直接报BUG: sleeping function called from invalid context。这个bug我在实验里踩过写进答案里很加分。5.3 驱动题的隐藏考点中断共享与设备树笔试里还涉及一个更细的考点中断共享。当两个设备共享同一根IRQ线时驱动程序在中断处理函数中必须先判断是否属于自己的设备产生的中断不是就返回IRQ_NONE否则返回IRQ_HANDLED。这个机制是为了支持旧式PCI设备的中断共享而存在的现代驱动里仍然要看request_irq时传的IRQF_SHARED标志。如果岗位偏嵌入式还会考设备树。题目问的是设备树中interrupt-parent属性的作用。答案是它指定了设备连接的中断控制器节点。这个知识点我在试卷里写了一句“通过设备树内核可以不经过硬编码就把硬件资源信息传递给驱动这让同一个内核镜像支持多种板卡”。嵌入式方向的同学建议把设备树基础概念和常用属性reg、interrupts、compatible都过一遍性价比很高。6. 备考复盘我的路线图和笔试现场的时间分配6.1 从《Linux内核设计的艺术》到源码验证三个月备考路线很多人问我备考应该看什么书我的建议是分层推进不要一上来就啃《深入理解Linux内核》这种大部头。我当时的路线是这样的第一个月看《Linux内核设计与实现》第三版这本书比较薄讲的是设计思路适合搭框架。重点看进程管理、内存管理、文件系统、设备驱动这四章。第二个月看《深入理解Linux内核》里内存管理和进程调度部分这时候你已经有了框架再看细节就不容易迷失。同时开始跑Linux内核实验比如写一个简单的字符驱动、用ftrace跟踪do_sys_open。第三个月刷题复盘。把历年内核岗笔试面试题整理成自己的答案库每天晚上花一小时练手写链表和内存相关代码。《Linux内核设计的艺术》这本书争议挺大但我个人觉得它偏重启动过程从BIOS到start_kernel对准备校招笔试帮助有限。笔试更关注运行期的机制而不是启动流程。当然如果你是零基础想建立整体认知快速翻阅一遍也不错。6.2 笔试现场答题顺序和时间分配实战策略亲身经历过这场笔试后我总结了一套答题顺序策略先快速过一遍全卷3分钟然后按“单选→编程题→问答题→多选”的顺序做。很多人会问为什么不先做分值高的问答题因为问答题需要调用大量知识如果时间不够写到一半答不完整反而拿不到分。先做单选的目的是快速进入状态把简单题的分稳稳拿到手。编程题放在第二位是因为它不需要太多上下文切换趁大脑还清醒的时候写代码效率和正确率都更高。时间分配上120分钟的大致安排阶段内容时间第一轮快速浏览全卷3分钟第二轮单选题15分钟第三轮编程题25分钟第四轮问答题50分钟第五轮多选题20分钟第六轮检查遗漏7分钟这个分配的核心思路是把最充裕的时间留给问答题因为它的答案需要组织结构、画链路图、举反例不是一两句话能写完的。6.3 几个容易翻车的细节和我的应对心得校招笔试里有些细节问题不一定会直接送命但能影响你的整体分数第一卷面表达一定要分点。内核相关的问答题阅卷人通常是内核工程师他们习惯看结构化答案。如果写成一大段流水账哪怕知识点全对也可能因为“表达能力不足”被扣印象分。第二不会的题不要空着。比如多选题拿不准时可以选一个最有把握的采用“宁可少选不可错选”的策略。如果时间够在答案旁边写上你的推理过程也能体现思路。第三命令题不要眼高手低。笔试里可能会有“用一条命令查看某进程打开了哪些文件”这种题答案是ls -l /proc/pid/fd/。这类题没有技巧平时真的要动手敲。备考期间建议每天花10分钟看man proc把/proc下的关键节点都过一遍。第四算法和数据结构不能丢。编程题喜欢用链表和哈希表当载体但考点仍然是基本的插入、删除、反转操作。考前把单链表、双链表、哈希冲突处理这三种基本操作各写一遍基本够了。回看这次笔试我最深的感受是内核岗笔试筛掉的不是不会背书的人而是没有形成“系统思维”的人。单一的知识点谁都能背但面对一道“数据从磁盘到用户空间经历了什么”这种题只有真正理解模块之间协作关系的人才能答得完整。这也是我在之后每一次面试、每一个项目里反复受益的能力。希望这份复盘能帮到准备投内核方向的你也欢迎在评论区交流你在这场笔试里遇到的坑。