尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

京东校招运维笔试考点复盘:从Linux到Kubernetes

京东校招运维笔试考点复盘:从Linux到Kubernetes 前阵子整理面试资料时翻到网上流传的2019年京东校招运维工程师笔试回忆版当时不少准备秋招的朋友都在刷这套题。我看完一个很直观的感受是这套笔试题的面铺得很宽但每道题都踩在运维日常真正会用到的地方Linux、网络、脚本、数据库、容器、故障排查全覆盖几乎没出偏题怪题。对准备运维岗位笔试的人来说这份卷子的参考价值不在于背答案而在于透过题目看清楚大厂校招笔试到底在考察什么。这篇文章我按这套题给我的整体印象把考点拆成几条主线来讲每类题目背后的命题逻辑、典型题目的解题思路、以及我踩过和见过别人踩过的坑。无论你是正在准备校招笔试还是刚入行想系统补运维基础应该都能从中找到点有用的东西。1. 试卷结构与命题逻辑校招笔试到底在筛什么1.1 我记忆中的题型分布虽然2019年到现在题型可能有些调整但据论坛回忆帖和身边入职同学的说法这套卷子大致是这样的笔试时长约120分钟满分100分。前半部分是单选题和多选题覆盖Linux基础命令、网络协议、数据库基本概念、进程与权限管理中间是几道简答题涉及系统启动流程、负载排查、常见服务原理最后是两道编程实操题通常是一道Shell脚本一道SQL查询再往后有一道综合场景设计题比如从零搭建一套线上Web系统给出你的整体方案。题型上最大的特点是选择题并不难难的是后面动手写的部分。很多同学选择题轻松过了倒在Shell和SQL上。这个分布其实是有意为之的——单选多选只能筛掉完全没基础的人真正区分度高的题目全在需要动笔写、需要讲清思路的部分。1.2 为什么大厂校招笔试爱考广而不深校招和社招不一样。社招笔试考的是你在某个领域的深度比如你负责的这套数据库集群怎么调优而校招候选人有那么多大多没有生产环境经验所以笔试的首要目标是快速过滤掉基本功不扎实的人。于是命题策略就变成了在有限的卷面上铺开尽量多的知识点每个点考得不深但覆盖面足够广广到能暴露你是否真正动手用过这些技术还是只在简历上写过。举个例子命令ss -lntp和netstat -lntp的区别背过的人可能都知道ss更快但为什么快因为ss直接读取内核socket信息而netstat依赖/proc文件系统。这种题在卷面上可能只是一道选择但它能区分出你是背过命令还是理解过原理。同理awk、sed、grep这三兄弟不是让你写复杂脚本而是考你遇到实际日志能不能快速提取信息——这是运维每天的日常。1.3 时间分配策略这套卷子120分钟我的建议是选择题和简答题控制在60到70分钟以内不要反复纠结后面Shell、SQL和场景设计题至少留50分钟因为这类题需要组织语言、捋清楚逻辑得分点也在这里。我见过不少同学前面选择题花了将近90分钟结果后面Shell题只写了半行、SQL表结构都没看明白非常可惜。选择题其实就那么几类复习到位了一眼就能出答案反复纠结只会压缩真正拉分题的时间。2. Linux与网络基础题看着简单丢分最多的恰恰是这里2.1 高频考点分布Linux和网络部分占的分量不小我复盘下来大概集中在这么几个方向进程管理ps、top、kill、僵尸进程、孤儿进程文件与权限文件权限位、SUID/SGID、软硬链接、inode文本处理grep、awk、sed、sort、uniq网络排查端口查看、TCP三次握手与四次挥手、HTTP状态码系统启动BIOS/Bootloader/Kernel/Systemd启动链路每个方向考得都不深但几乎都对应一个非常具体的运维场景。比如问某端口被占用怎么查是哪个进程这就是线上部署服务时每天都会遇到的真实问题。2.2 典型题目与答题要点我挑几道有代表性的题目说说答题思路。题目方向查看当前系统监听的所有TCP端口并显示对应的进程名。这道题本质考的是ss或netstat命令的掌握但细节在于参数。完整的答法是ss -lntp需要解释每个参数的含义-l 只看监听状态的socket-n 不解析域名直接显示IP-t 只看TCP-p 显示进程信息。如果不用-p参数普通用户看不到进程名需要root权限。这个细节很多人会忽略。为什么用ss而不用netstat因为ss直接解析内核socket表速度快而且在新版Linux中netstat命令可能没装ss属于iproute2包在多数发行版里是标配。这种题答的时候最好顺带解释一下选择理由会显得你真的理解而不是背命令。题目方向查看某进程的CPU使用率并找到它内部线程的CPU占用。答题链路是先用top确认高CPU进程PID再执行top -Hp PID-H表示按线程维度展示。如果要看线程名可以查看/proc/PID/task/下的线程目录。这道题背后对应的是Java应用CPU飙高的排查场景答的时候如果能提到当怀疑某个线程异常时还可以结合jstack导出线程栈分析会明显加分。题目方向解释502、503、504的区别。这道简答题在运维笔试里出现频率极高。502是网关从上游收到了无效响应503是服务暂时不可用如过载504是网关在超时时间内没等到上游响应。三者有相似点但一个明显区别是502意味着上游服务进程还在但返回数据有问题504则通常是上游处理太慢导致网关超时503常见于主动摘除或限流。2.3 做题时容易忽略的细节基础题丢分往往不是因为不会而是因为以为自己会。第一个坑是审题。题目让写查看所有TCP连接状态有人写成netstat -lntp只看了listen漏掉了established。所以答题前先圈出关键词是监听还是连接是TCP还是所有是否要求显示进程名。第二个坑是命令参数张冠李戴。比如ps aux的USER、PID、%CPU、%MEM、VSZ、RSS、TTY、STAT、START、TIME、COMMAND这些字段笔试可能会让你写出某一列的含义。很多人都能脱口说PID是进程号但对STAT字段的S、R、Z、D等状态容易混淆。STAT这里有个很重要的点S代表可中断睡眠R是运行中Z是僵尸D是不可中断睡眠。D状态其实在面试里经常被追问因为线上经常遇到大量D状态的进程那通常意味着磁盘或IO出问题了。第三个坑是只看命令不解释输出。不少同学能写出ss -lntp但笔试如果要求说明每列输出的含义需要知道State、Recv-Q、Send-Q、Local Address等字段代表什么Recv-Q和Send-Q在LISTEN状态下是连接队列长度在ESTABLISHED状态下是网络收发的排队数据量这两者含义不同是个很细的考点。3. Shell与SQL实操题手写代码题考察的不只是语法3.1 Shell脚本题从日志里提取信息是基本盘运维笔试的Shell题几乎不可能考你写个复杂的算法它考的就是日志分析、文件批量处理、系统状态统计这类日常操作。典型题目统计access.log中每个小时的请求数量并按请求量从高到低排序。这道题的常规解是组合awk、sort、uniq三个命令awk {print $4} access.log | cut -c14-15 | sort | uniq -c | sort -rn拆解一下假设日志默认格式是127.0.0.1 - - [10/Oct/2019:13:55:36 0800] GET /index.html HTTP/1.1 200 2326时间字段是第4列形如[10/Oct/2019:13:55:36 0800]前面两位是小时。先取第4列然后用cut取出第14-15个字符拿到小时值sort排序后uniq -c统计次数最后sort -rn按数字倒序。这里要求列数、字符位置准确如果格式变形用awk的match或gsub处理会更稳。答题还有一个加分细节写出可以用awk内置函数直接处理时间格式避免cut的字符位置依赖固定格式比如用awk {split($4, arr, /[:[]/); print arr[4]}这样对不同行格式变化更鲁棒。另一类常见的Shell题找出/var/log下7天前修改过的.log日志文件并打包。需要用到find的-mtime参数find /var/log -name *.log -mtime 7 -exec tar czf old_logs.tar.gz {} \;-mtime 7是修改时间在7天之前如果写成-7就是7天以内这是坑。还有一位同学在笔试时把-exec后面漏了{}和\;直接导致命令报错这种基础语法在写字操作时必须检查一遍。3.2 SQL题多表关联与聚合SQL题通常给两张或三张表考察join、group by、having、子查询。记住一个原则先写骨架SELECT...FROM...JOIN...ON...再补条件WHERE...GROUP BY...HAVING...ORDER BY...。典型题目有三张表用户表users(id, name)、订单表orders(id, user_id, amount, created_at)、商品表products(id, name, price)查每个用户消费总金额且只统计金额大于1000的用户按金额降序排列。SELECT u.name, SUM(o.amount) AS total_amount FROM users u JOIN orders o ON u.id o.user_id GROUP BY u.id, u.name HAVING SUM(o.amount) 1000 ORDER BY total_amount DESC;这道题有几个细节容易被扣分GROUP BY后面字段要完整MySQL sql_mode不同允许的写法不一样稳妥一点把u.id和u.name都写上过滤聚合条件要用HAVING而不是WHEREORDER BY可以用别名但最保险是写完整表达式。还有一类SQL题考取每个分类下的最新一条记录这种需要用子查询或者窗口函数。窗口函数在笔试里写ROW_NUMBER() OVER (PARTITION BY...)是很加分的做法但要注意如果题目环境默认不支持窗口函数比如只写MySQL 5.7子查询方案更保险SELECT p.* FROM products p JOIN ( SELECT category_id, MAX(created_at) AS max_time FROM products GROUP BY category_id ) t ON p.category_id t.category_id AND p.created_at t.max_time3.3 阅卷人想看到的答题习惯笔试阅卷不只看结果对不对更看思考过程。结合我看到过的高分卷和低分卷的差别有这么几个习惯很加分先写思路再写代码。在Shell题旁边简单写一句先取时间字段--截取小时--排序统计能让阅卷人一眼看出你思路清晰即使代码有小错也至少给过程分。考虑边界条件。比如处理日志文件时考虑文件不存在、权限不足、时间字段为空的情况或者在SQL里用COALESCE处理NULL。注意变量命名和可读性。写Shell脚本时用有意义的变量名而不是一长串magic截取。字符串截取要注意cut -c的位置从1开始按字节还是字符在中文环境有坑能主动说一句生产环境要注意编码会显得经验更足。很多同学把Shell和SQL当成会写就行但笔试阅卷恰恰能从代码风格里看出你平时写没写过真正的脚本。一个写过多页脚本的运维代码里天然会有错误判断、日志输出、退出码处理一个只背过命令的考生很难装出这种习惯。4. 容器与Kubernetes原理题从k8s如何调用containerd看命题深度4.1 为什么校招笔试会出现容器原理题2019年那会儿京东内部容器化已经推进得很深了它家的运维JD里明确写了Kubernetes容器编排经验优先。所以笔试出现容器题目一点都不意外。而且这类题目恰恰是最能区分只听过大名和真正接触过的。当时的考题方向有docker和虚拟机的区别、镜像和容器的关系、Dockerfile常见指令、Pod与容器的区别、Kubernetes的主要组件。但如果你只背了这些大概率栽在一道追问上kubelet是怎么把一个Pod跑起来的这背后就是kubernetes如何调用containerd的完整链路。4.2 容器调用链从kubelet到容器进程的每一跳把这条链路梳理清楚我可以负责任地说容器方向的大部分面试题都能应对。完整链路是这样的kubelet │ 通过 gRPC 调用 CRI 接口 ▼ containerd内置 CRI plugin │ 根据需要创建/停止容器管理镜像解压与快照 ▼ containerd-shim每个容器一个 │ 保持容器 1 号进程的父进程身份 ▼ runc符合 OCI 规范的运行时 │ 使用 namespaces/cgroups 创建容器 ▼ Linux kernel逐层解释第一层kubelet与CRI。kubelet是每个节点上的代理进程负责Pod的生命周期管理。但kubelet本身不直接操作容器它通过CRIContainer Runtime Interface这个统一接口来与运行时打交道。CRI是Kubernetes在1.5版本之后引入的接口标准它定义了kubelet如何创建、删除、查询容器运行时只要实现了这套gRPC接口就能作为k8s的容器运行时。这是一个解耦设计——kubelet不需要关心底层是containerd还是别的符合CRI的运行时。第二层containerd与CRI plugin。containerd最初是从Docker里拆分出来的核心容器运行时专管镜像管理、容器生命周期、存储快照。早期版本中Kubernetes要通过cri-containerd这个独立进程对接containerd后来containerd直接内置了CRI pluginkubelet的gRPC请求可以直接打到containerd的CRI服务上。1.0版本之后containerd内置的CRI插件就稳定了这也是containerd成为主流容器运行时的重要原因。第三层containerd-shim。这一步非常关键。runc把容器进程拉起来之后它的任务就结束了通常应该退出。但容器主进程不能没有父进程否则会被PID 1进程收养失去信号转发和退出状态传递的通道。所以containerd在每个容器启动前会拉起一个containerd-shim进程让shim成为容器内1号进程的父进程持续接管这个容器的标准输入输出、信号转发、退出状态收集并把这些信息回报给containerd。这个设计最大的好处是containerd本身即使重启已经运行的容器也不受影响因为shim还活着还在管理着容器进程。第四层runc与OCI。runc是一个独立的CLI工具它的职责是真正去和内核交互创建容器所需的namespacePID、网络、挂载等和cgroup然后启动容器进程。runc实现的是OCIOpen Container Initiative规范底层对应的是Linux内核提供的容器能力。镜像在被containerd取出并解压好之后会整理成一个bundle包含rootfs和config.jsonrunc根据bundle内容启动容器。第五层内核。这一层就是namespaces资源和cgroup资源限制的物理实现。每个容器实际上就是一个以普通进程为载体的隔离环境并没有所谓的容器内核——所有容器共享同一个宿主内核。这也是容器相对虚拟机轻量的根因同时也意味着容器隔离不如虚拟机彻底。4.3 原理背后的设计思路这套链路里的每一步都对应一个特定的设计意图kubelet和CRI的解耦让Kubernetes不绑定任何容器运行时用户可以选择CRI-O、containerd甚至自定义运行时。containerd再往下通过shim和runc隔离让容器运行时可以参与OCI运行时更换比如换成gVisor这类安全容器技术演进不会被锁死。shim的存在是父进程常驻、运行时短暂这一架构的支点它承担了信号通道、退出码传递、日志转发等脏活。笔试如果出一道选择题runc退出后容器为什么不会停止答案就是有containerd-shim在维持容器主进程。如果出一道简答containerd和dockerd有什么区别核心就一句containerd定位为容器运行时管理核心而dockerd曾经在内部嵌了containerd并额外提供镜像构建、API等上层能力两者是包含与被包含关系不是平级。4.4 笔试中常见的容器题目方向汇总根据这套题的风格容器方向的高频考点基本是这些题目方向答题要点CRI与OCI的区别CRI是kubelet与运行时之间的接口标准OCI是容器运行时的具体规范二者层次不同镜像和容器的关系镜像是静态模板只读层容器是运行实例可写层进程Pod与容器关系Pod是k8s最小调度单位可以包含1个或多个容器共享网络和存储containerd vs dockercontainerd是核心组件docker是上层工具docker内部使用containerdcontainerd-shim的作用作为容器主进程的父进程负责信号转发、退出码收集、日志IOcgroup与namespacenamespace做隔离cgroup做资源限制如果这些点你都能不看资料讲明白容器这块的笔试基本就稳了。5. 故障排查与系统维护场景题纸上谈兵也能看出实战经验5.1 典型场景题线上CPU飙高怎么排查这套题后面的简答或场景题基本是某天晚上线上主机的CPU使用率突然飙到90%你怎么排查和处理。这种题没有唯一标准答案但得分高低一眼能看出来。我的答题框架是四个步骤确认现象、定位进程、深挖线程/堆栈、结合上下文定预案。第一步先确认现象不能凭想象答题。用top或uptime查看系统整体负载记录CPU是user态高还是sys态高。这两者方向完全不同user态高通常说明业务代码在大量计算sys态高往往意味着系统调用过于频繁或内核态出了问题比如IO调度、网络栈、锁竞争。第二步定位到具体进程。top输出里找到CPU占用最高的PID然后进到线程维度top -Hp PID或者用ps命令ps -Lp PID -o pid,tid,pcpu,comm第三步如果进程是Java应用用jstack导出线程栈找到CPU高的那个tid换算成16进制分析它在执行什么代码如果是普通C/C服务可以用perf top或gdb attach看热点。第四步结合日志和监控判断是资源不足、代码Bug、外部流量突增还是依赖方超时。每种情况处理方式都不一样代码问题要回滚或限流流量问题要扩容依赖问题要降级。这种题目答得完整且链条清晰即使没有生产环境经验阅卷人也能从框架里看出你接受过系统训练。切忌一上来就答重启服务器——有些时候重启能解决但掩盖了问题处理方式里缺失分析过程就暴露了没实际排过障。5.2 另一类必考从零搭建一套生产系统并维护这道题在热搜词如何在生产环境从零搭建一个系统并做好后续维护里就是对应题目。答题的思路是覆盖完整生命周期而不是只讲装个Nginx、跑个Java进程。我的答题提纲大致是需求确认与容量评估预估QPS、数据量、日活确定机器规格和规模。基础环境安装与初始化选择操作系统版本配置yum/apt源、时间同步chrony、hosts解析、DNS、内网源、内核参数调优文件描述符、TCP缓冲区、swappiness。安全加固创建专用运行用户、配置SSH密钥登录禁用密码、防火墙iptables/firewalld、最小化开放端口、定期安全更新。应用部署用systemd管理服务配置环境变量、启动脚本、日志目录、数据目录配合配置中心做版本管理。高可用与负载均衡前面挂Nginx或SLB多实例部署预留健康检查接口数据层做主从或集群。监控告警部署node_exporter、Prometheus、Grafana覆盖CPU、内存、磁盘、网络、TCP状态、进程存活、业务接口RT/错误率。日志与审计文件日志采集上报日志切割轮转防止磁盘写满。备份与容灾数据库定期全备binlog增量备份文件异地存储定期演练恢复。日常巡检与变更规范从手动巡检磁盘空间、僵尸进程、证书过期、日志报错到逐步自动化变更要有回滚预案。这种题就是典型的看框架给分。你每多写一层阅卷人对你的成熟度评价就会高一级。比如大多数人只想到部署和监控你写了备份策略和回滚预案就明显属于有生产意识的人。5.3 答题的框架化思维无论是CPU排查还是系统搭建我发现这类场景题拿高分的共同点是框架化从现象到结论、从点到面、从故障到预案每一步都有逻辑链条。很多同学知道命令但答题时想到一个写一个结构松散。建议平时练习时就养成习惯先画主框架现象-定位-根因-处理-恢复-复盘再往框架里填细节。笔试试卷上是纸面你无法现场操作清晰的框架就是对经验和知识最好的替代展示。6. 复盘这套题之后我给备考者的几点建议6.1 知识体系搭建顺序如果你准备的是运维岗位校招我建议按这样的顺序补知识而不是东一榔头西一棒子第一步吃透Linux基础和网络基础。这是安身立命的根本也是笔试选择题的主要来源。文件权限、进程管理、文本处理三剑客、TCP状态、HTTP协议这些是每天都要用的必须形成条件反射。第二步掌握Shell和Python脚本能力。笔试的Shell题和后续工作中的自动化都依赖这个能力。不用写得多高级能完成日志统计、文件批量处理、服务启停脚本就够。第三步理解虚拟化/容器/编排原理。从虚拟机到容器到Kubernetes重点是搞懂原理和组件之间的关系尤其是我上面讲的那条调用链理解透彻之后可以应对很多问题。第四步了解监控、CI/CD、发布流程。这部分笔试考得不多但面试和工作中会遇到。会部署Prometheus和自己看Grafana的仪表盘能说清持续集成的流程是基本门槛。6.2 刷题之外更重要的动手复现这道题很多人看解析觉得我都会但实际笔试时写不完整。原因很简单看答案和自己动手写完全是两码事。我的建议是把上面每类题目都在自己的环境里跑一遍。装个虚拟机或随便买台便宜云服务器把统计access.log每小时请求量这个脚本真的写到文件里执行一遍把从零搭建系统这个方案真的在自己服务器上实施一次把kubelet调用containerd这条链路的每一层用命令验证一遍——比如在安装了containerd的节点上通过crictl pods看Pod状态用ctr namespace list看命名空间用runc list看容器状态用ps -ef | grep containerd-shim看shim进程在不在。验证过一遍后你对这套体系的理解深度完全不一样。我面过不少候选人简历上写熟悉Kubernetes但问到底层调用链很快就含糊了。反而是那些自己有空实验环境、把原理验证过的同学聊起来有底气得多。6.3 过来人的一些体会最后再分享点实在的体会。这套2019年的笔试题放到今天核心考点并没有过时Linux、网络、脚本、容器、故障排查永远是运维的基本功。技术的表象一直在变——比如现在云原生、Serverless、可观测性成了热词但底层那套排查链路和运维思想是稳定的。所以备考时不必纠结于题目是否原封不动再出现而是要透过这些题意识到大厂判断一个校招候选人能否胜任运维岗位看的不是你会多少新潮名词而是你是否具备扎实的基础、清晰的排查思路、主动补全体系的意识。我给准备笔试的朋友复习建议就三个字动手写。把命令敲出来、把脚本跑起来、把请求链路看一遍比你背一百道解析有用得多。这套笔试最真实的价值也正是帮你提前把这一整套思维和方法论打磨了一遍。
返回列表