
简介本资源为腾讯测试开发工程师岗位笔试题回忆版整理文档面向准备大厂测试/测开校招或社招的求职者聚焦Linux系统操作、Web前端基础、数据库SQL实战、中间件日志机制及软件测试用例设计等核心考点助力快速查漏补缺与高频题型突击。文档以单个Word.docx文件形式呈现内容结构清晰涵盖5大知识模块Linux进程监控与目录管理命令详解、HTML/JS基础语法与浏览器兼容性要点、MySQL三范式与事务优化策略、Apache日志重定向原理分析以及三角形判定函数的等价类划分法完整测试用例设计。文件大小仅18KB轻量易读适合作为随身复习资料或面试前速览提纲。目前已有1549人学习下载内容源自真实笔试场景知识点覆盖全面、答案解析务实可直接用于模拟自测与答题思路训练。1. 腾讯测试开发工程师笔试题回忆版不是考“背题”而是考你系统性拆解问题的肌肉记忆你有没有过这种经历刷了几十套“大厂面试题”一到真实笔试现场看到第一道free -m和crontab -l并列出现的题脑子突然卡住——“等等free看的是物理内存还是虚拟内存crontab查的是当前用户的还是系统的”这不是记不住命令而是没在真实 Linux 终端里“摸爬滚打”过free显示的available列到底代表什么为什么top里看的 CPU 占用和ps算出来的总和对不上/proc目录明明是“文件”却连ls -l都看不到大小它到底存的是啥这份《腾讯测试开发工程师笔试题回忆版》表面是一堆零散知识点——Linux 命令、HTML 标签、SQL 更新、Cookie 大小、等价类划分……但背后藏着一条清晰主线测试开发不是“点鼠标的人”而是能一眼看穿系统分层OS → Web → DB → 中间件 → 测试逻辑并快速定位断点的“系统侦探”。它不考你会不会写冒泡排序而考你看到mv access_log access_log.bak后能不能立刻反应出“Apache 进程还拿着旧文件句柄日志照写不误”这个关键事实。搞懂它不是为了押中题而是把零散知识拧成一股绳——下次遇到新系统、新中间件、新数据库报错你脑子里自动弹出的不再是“百度一下”而是“先看进程、再查日志、接着验数据、最后推逻辑”的条件反射。2. Linux 基础别再死记命令先搞懂“系统怎么想”测试开发天天和服务器打交道但很多人对 Linux 的理解还停留在“命令行黑盒子”阶段敲top就出个表敲free就出个数至于这些数字从哪来、为什么这么设计、哪里容易踩坑——全靠玄学。其实Linux 的设计逻辑非常朴素一切皆文件一切可追溯。/proc是内核给你的“实时监控面板”/etc是你亲手写的“系统说明书”而free和top只是不同角度读取同一份数据的“翻译器”。2.1free -m看内存为什么available比free大这根本不是 bug很多人第一次看到free -m输出时会懵$ free -m total used free shared buffers cache available Mem: 15927 4230 2180 123 245 9048 11200“free才 2180MBavailable却有 11200MB内存凭空多出来 9GB”打个比方你租了一整层写字楼total自己工位占了 3 间used空着的 5 间free谁都能用但还有 10 间是“共享会议室”buffers/cache平时没人用但你临时要开大会管理员内核马上就能腾出来给你——这部分就是available。它代表此刻系统能立刻分配给新进程的内存总量包括真正空闲的 可快速回收的缓存。提示available是 Linux 3.14 引入的关键指标比free更真实反映系统余量。老版本没有这一列得靠free buffers cached估算但新版直接给你算好了。2.2top动态看进程为什么 CPU% 加起来超过 100%因为你在看“时间切片”top是测试开发最常开的窗口但很多人没注意右上角那行小字%Cpu(s): 23.5 us, 1.2 sy, 0.0 ni, 75.0 id, 0.3 wa, 0.0 hi, 0.0 si, 0.0 st。ususer用户态程序占用 CPU 时间sysystem内核态系统调用占用时间ididleCPU 空闲时间wawait等待 I/O如磁盘、网络的时间关键点top默认按CPU 时间占比排序而现代服务器都是多核比如 8 核。如果一个 Java 进程单线程跑满 1 个核它显示99.9%另一个 Python 进程开了 4 个线程每个占 20%加起来就80%——所有进程 CPU% 总和远超 100%这完全正常。注意ps aux --sort-%cpu看的是瞬时快照top是动态刷新。ps的%CPU是自进程启动以来的平均值top是最近几秒的实时值两者数值天然不同别拿它们直接对比。2.3/etcvs/proc一个是你写的“说明书”一个是内核直播的“监控屏”这是笔试高频混淆点也是理解 Linux 架构的分水岭维度/etc目录/proc目录本质普通文件系统硬盘存储虚拟文件系统内存映射无真实磁盘文件内容你手动编辑的配置文件如nginx.conf内核实时生成的进程/内存/设备状态如/proc/1/status修改方式vim /etc/hosts直接编辑echo 1 /proc/sys/net/ipv4/ip_forward写入即生效删除风险删了passwd用户登录直接挂掉rm -rf /proc/1删不掉/proc下所有“文件”都是只读或特殊接口通俗地说/etc是你给系统写的“操作手册”/proc是系统正在运行时内核主动向你“直播”的后台画面。find /usr/proc -name *test*这种题本质是在考你是否意识到/usr/proc这个路径本身就很可疑——标准 Linux 根目录下只有/proc/usr/proc通常不存在除非你手动建了个空目录。真正的查找应该针对/proc下的进程名ps aux | grep test或ls /proc/*/comm 2/dev/null | xargs -I{} sh -c echo {}; cat {} | grep test。2.4crontab和find周期任务不是“定时闹钟”而是“系统级服务契约”crontab -l查当前用户定时任务这谁都懂。但笔试问“Linux 下查看周期执行的任务”陷阱在不止一个地方能设用户级crontab -e个人任务如每天备份家目录系统级/etc/crontab全局任务如 logrotate 日志轮转固定目录/etc/cron.d/第三方软件放的 cron 文件、/etc/cron.hourly/每小时执行的脚本find /usr/proc -name *test*这题除了路径错误更深层是考你是否理解find的适用场景find适合查静态文件名而/proc下的进程是动态的进程名存在/proc/[pid]/comm里PID 每次启动都变。真要找含test的进程该用pgrep test或ps aux | grep test。血泪经验某次线上服务异常运维说“cron 没跑”结果发现他只查了crontab -l却忘了cat /etc/cron.d/myapp里还有一条被注释掉的旧任务——测试开发必须养成“查全链路”的习惯不能只盯一个入口。3. Web 与数据库前端、后端、数据层每一层都在“说人话”测试开发不是纯前端也不是纯后端而是要听懂三端“方言”HTML/CSS 是页面的“骨骼和皮肤”JavaScript 是客户端的“小脑”HTTP 是前后端对话的“普通话”SQL 是和数据库“讲道理”的逻辑语言。笔试里那些看似零碎的问题其实在考你能否把这三层语言串成一句完整的话。3.1 HTML 标签块级和行内本质是“浏览器渲染时的换行权”div和span的区别教科书说“块级独占一行行内不换行”。但这只是现象本质是 CSS 的display属性默认值不同块级元素p,h1,divdisplay: block→ 自动换行 可设宽高 默认 100% 宽行内元素span,a,strongdisplay: inline→ 不换行 宽高无效 宽度由内容撑开为什么重要测试时遇到样式错乱第一反应不该是“CSS 写错了”而是“这个标签是不是用错了类型”。比如把a行内当成按钮塞进div里又强行display: block不如直接用button天生块级语义化。注意HTML5 新增了display: inline-block如img它既有行内元素的“不换行”特性又能设宽高——这是很多 UI Bug 的隐藏根源。3.2 JavaScript 执行位置客户端不是“浏览器”而是“用户设备上的 JS 引擎”“JavaScript 运行在客户端”这句话90% 的人理解为“在浏览器里跑”。但严格说客户端 用户设备上执行 JS 的运行时环境。传统场景Chrome 的 V8 引擎新场景Node.js服务端 JS、微信小程序WebView 内嵌 JSCore、Electron桌面应用所以document.getElementById().style.fontSize1.5em这行代码只能在有document对象的环境运行即浏览器或 WebView。放到 Node.js 里直接报错ReferenceError: document is not defined。提示测试开发写自动化脚本时若用 Puppeteer 控制浏览器这段代码在page.evaluate()里执行若用 Node.js 直接发 HTTP 请求就得换思路——用 API 返回的数据校验而不是操作 DOM。3.3 Cookie vs Session不是“客户端 vs 服务器”而是“钥匙 vs 保险柜”笔试常问区别但很多人答成“Cookie 存客户端Session 存服务器”。这没错但漏了最关键的一环它们如何协同工作Cookie 是浏览器保存的一小段字符串如sessionidabc123每次请求自动带上Session 是服务器内存/数据库里的一块数据如{userid: 1001, login_time: 2024-05-01}关联方式服务器用 Cookie 里的sessionid作为 key去查自己的 Session 存储所以 Cookie 最大 4KB限制的是“钥匙串长度”不是“保险柜容量”。Session 数据可以很大如用户购物车但钥匙Cookie必须小巧。易混点localStorage也是客户端存储但它不随 HTTP 请求自动发送需 JS 主动读写适合存用户偏好如主题色不适合做登录态。3.4 SQL 三范式不是“教条”而是“避免数据扯皮的宪法”三范式听起来抽象其实全是生活常识1NF第一范式字段不可再分。比如“地址”字段不能存北京市朝阳区建国路1号而应拆成province北京,city朝阳区,street建国路1号。否则按城市统计人数时LIKE %朝阳%会误匹配“朝阳门”。2NF第二范式非主键字段必须完全依赖主键。反例订单表order(id, product_id, product_name, qty)product_name只依赖product_id不依赖(id, product_id)联合主键 → 应拆出products(product_id, product_name)表。3NF第三范式非主键字段不能相互依赖。反例员工表emp(id, dept_id, dept_name, salary)dept_name依赖dept_id而dept_id又依赖id→ 应拆出depts(dept_id, dept_name)。为什么测试开发要懂你写 SQL 查询时如果SELECT * FROM user_visit JOIN user ON ...而user表没建索引JOIN会全表扫描响应时间从 10ms 涨到 2s——这比写错WHERE条件更致命。优化 MySQL核心就三条**加索引覆盖查询字段、避免 SELECT *、用EXPLAIN看执行计划。4. 常见误区与易混概念这些坑90% 的人毕业三年还在踩笔试题里埋的雷往往不是知识点冷门而是几个概念长得太像稍不留神就掉坑里。下面这 5 组是腾讯笔试回忆版里反复出现的“孪生兄弟”必须掰开揉碎讲清楚。4.1GETvsPOST不是“传参方式不同”而是“HTTP 方法语义不同”易混点为什么混怎么区分认为 GET 不能传敏感数据POST 就安全混淆了“传输方式”和“安全性”。GET 参数在 URL 里会被浏览器历史、代理服务器、Web 服务器日志明文记录POST 参数在请求体日志默认不记——但两者在网络上传输时都是明文未加密真要安全必须上 HTTPS。记住口诀GET 是“查”POST 是“改”。RFC 规定 GET 必须是安全的无副作用可被缓存、可被收藏POST 是不安全的可能修改数据不可缓存。登录用 POST搜索用 GET。认为 GET 有长度限制POST 没有混淆了协议限制和实现限制。HTTP 协议本身对 URL 长度无限制但浏览器Chrome 限制约 2MB、服务器Nginx 默认 4K、代理如 Squid都有各自限制。POST 请求体理论上无上限但服务器会设client_max_body_size。实际开发中传参超 2KB 就该用 POST不是因为协议不允许而是兼容性风险太高。曾经有项目用 GET 传 Base64 图片Chrome 正常Safari 直接 414 错误。认为 POST 比 GET 慢混淆了网络传输和服务器处理。一次 HTTP 请求耗时 DNS 解析 TCP 握手 TLS 握手 发送请求 服务器处理 返回响应。GET 和 POST 的差异仅在请求头POST 多Content-Length和请求体GET 为空服务器处理逻辑相同的情况下耗时几乎一样。性能瓶颈永远在服务器处理如数据库查询或网络延迟不在 GET/POST 选择上。压测时发现 POST 慢99% 是后端代码问题不是方法选错了。4.2cookie.maxAgevscookie.expires不是“两个名字”而是“两种时间体系”易混点为什么混怎么区分认为两者完全等价都是控制 Cookie 过期时间初学者自然觉得“换个写法而已”。maxAge是相对时间秒数如maxAge3600表示 1 小时后过期expires是绝对时间GMT 时间字符串如expiresWed, 21 Oct 2025 07:28:00 GMT。maxAge优先级更高如果同时设置浏览器以maxAge为准。在 JS 中设置时混淆Date.now()和new Date().toUTCString()document.cookie a1; max-age3600正确document.cookie a1; expires Date.now() 3600000错误Date.now()返回毫秒数expires要 GMT 字符串。JS 设置expires必须用new Date().toUTCString()设置max-age直接写数字。Node.js 的res.cookie(a, 1, { maxAge: 3600000 })用的是毫秒和 JS 的Date.now()单位一致——跨端开发时单位陷阱最多。4.3crontabvsat不是“定时工具”而是“调度粒度不同”易混点为什么混怎么区分认为crontab能执行一次性任务crontab语法支持reboot看起来像能“只跑一次”。crontab是周期性调度器最小粒度是分钟* * * * *。reboot是特例只在开机时触发一次。真要执行“今天下午 3 点发邮件”该用at 15:00它专为一次性任务设计。混淆用户 crontab 和系统 crontabcrontab -e编辑的是当前用户任务/etc/crontab是系统级任务格式多一列user指定以谁身份运行。crontab -e里写0 2 * * * backup.sh是以当前用户执行/etc/crontab里写0 2 * * * root backup.sh明确指定root用户。测试开发部署定时任务时权限错误如普通用户写/etc/crontab是常见翻车点。4.4INNER JOINvsLEFT JOIN不是“左右之分”而是“主表立场不同”易混点为什么混怎么区分认为 LEFT JOIN 就是“左表全出来”忽略 ON 条件过滤SELECT * FROM A LEFT JOIN B ON A.id B.a_id WHERE B.status active这里WHERE会把B为 NULL 的行过滤掉实际效果等同INNER JOIN。LEFT JOIN 的核心是“保留左表所有行”但WHERE是在 JOIN 结果上二次过滤。要保留左表所有行且只取右表 active 记录必须把条件写进ONLEFT JOIN B ON A.id B.a_id AND B.status active。这是 SQL 查询最隐蔽的坑。用 JOIN 替代子查询时忽略性能SELECT * FROM user WHERE id IN (SELECT user_id FROM order WHERE amount 100)vsSELECT u.* FROM user u JOIN order o ON u.id o.user_id WHERE o.amount 100。后者可能产生笛卡尔积一个用户多笔订单返回多行。IN子查询适合“存在性判断”JOIN适合“关联取字段”。用EXPLAIN看执行计划IN可能走DEPENDENT SUBQUERYJOIN可能走ALL全表扫描。索引才是王道——order(user_id, amount)复合索引能让两者都飞起来。4.5 Apache 日志重命名不是“文件移动”而是“文件描述符fd的生死契约”易混点为什么混怎么区分认为mv access_log access_log.bak后新日志会写到access_log.bak把 Linux 文件系统理解成 Windows 的“资源管理器”以为移动文件就是“改名字”。Apache 进程启动时用open()打开access_log获得一个文件描述符fd。mv只是把目录项dentry指向变了原文件 inode 还在fd 依然有效。所以 Apache 继续往原 inode 写日志access_log.bak是个空文件。lsof -p apache_pid认为重启 Apache 后日志会写到新文件access_log忘了 Apache 配置里写的是CustomLog /path/access_log重启时会重新open()这个路径。正确做法是kill -USR1 apache_pid优雅重启日志它会通知 Apache 关闭旧 fd重新open()配置里的路径。mvkill -USR1是运维标准流程mvrestart是懒人做法但也能用——只要确保重启前旧进程已退出。5. 测试设计与中间件从“点按钮”到“推演系统行为”测试开发的核心能力不是会点自动化工具而是能基于系统原理预判边界和异常。比如三角形测试题考的不是“等价类划分”这个名词而是你能否想到输入0,0,0是“无效输入”1,1,100是“不满足三角形不等式”1.5,2.5,3.5是“浮点数精度陷阱”。Apache 日志题同理考的是你对“进程、文件、内核”三者关系的理解深度。5.1 等价类划分不是“分组填表”而是“用数学思维穷举系统状态”三角形函数测试标准答案是分三类有效等价类能构成三角形如3,4,5→ 验证“等边/等腰/普通”无效等价类不满足三角形不等式如1,2,5→ 验证“提示错误”边界等价类临界值如0,1,1、1,1,2、INT_MAX,INT_MAX,1→ 验证“溢出/精度”但真实项目中这远远不够。某次测试某图像处理 API输入参数是width100height200formatjpg我们按等价类设计有效width0,height0,format in [jpg,png]无效width0,height-1,formatexe边界width1,width65535,formatJPG大小写结果上线后大量500错误。排查发现API 内部用ImageMagick处理当width * height 1000000001 亿像素时会因内存不足崩溃。而我们的等价类只考虑了单个参数没考虑参数组合的隐式约束。教训等价类划分必须结合系统实现细节。测试前先问这个函数内部调用了什么库库的文档写了哪些限制有没有未公开的阈值否则就是闭着眼睛猜。5.2 Apache 日志重命名一次mv操作暴露整个 Unix I/O 模型回到那个经典题mv access_log access_log.bak后日志写哪第一步确认 Apache 进程是否还在运行# 查看 Apache 主进程 PID ps aux | grep apache | grep -v grep # 假设 PID 是 1234 # 查看它打开了哪些文件 lsof -p 1234 | grep access_log # 输出类似httpd 1234 root 12w REG 253,0 123456 1234567 /var/log/apache2/access_log (deleted) # 注意最后的 (deleted) —— 表示文件已被 unlink但进程还握着 fd第二步验证日志是否真在写# 实时监控原 inode即使文件名没了inode 还在 # 先找到 inode 号上一步 lsof 输出中的 1234567 # 用 find 查找该 inode 对应的文件通常在 /proc 下 find /proc/*/fd -lname *1234567 2/dev/null | xargs ls -la # 输出/proc/1234/fd/12 - /var/log/apache2/access_log (deleted) # 然后 tail -f 这个 fd 链接需要 root 权限 tail -f /proc/1234/fd/12 # 你会发现日志还在实时滚动第三步重启后的行为Apache 重启时主进程退出所有 fd 关闭原 inode 被内核释放。新进程启动读取配置CustomLog /var/log/apache2/access_log执行open(/var/log/apache2/access_log, O_APPEND|O_WRONLY)创建一个全新的文件新 inode日志开始写入新文件。关键认知Linux 中“文件” inode元数据数据块 dentry目录项即文件名。mv只改 dentryunlink如rm才减 inode 引用计数。进程持有 fd就等于给 inode 上了锁哪怕rm了数据还在直到进程退出。5.3 从笔试题到真实工作我如何把“回忆版”变成肌肉记忆去年我负责某支付网关的稳定性测试上线前压测发现 TPS 上不去。监控显示数据库 CPU 100%但慢查询日志一片空白。直觉告诉我问题不在 SQL而在连接池。我立刻打开终端执行# 查看 MySQL 当前连接 mysql -u root -p -e SHOW PROCESSLIST; | grep -E (Sleep|Query) | wc -l # 发现 200 Sleep 连接远超连接池配置的 50 # 再查 Apache 日志发现大量 504 Gateway Timeout # 于是执行lsof -i :80 | grep apache | wc -l # 查 Apache 工作进程数 # 结果是 200和 MySQL Sleep 连接数一致 # 推断Apache 子进程卡在等待数据库响应无法释放连接这时笔试里free -m的available、top的waI/O wait、lsof查文件描述符的知识全串起来了。我让开发检查数据库连接关闭逻辑果然发现一处try-catch里没写conn.close()异常时连接泄露。从那以后我每次压测前都强制走一遍“系统四连问”free -m看available是否充足内存瓶颈top看wa是否高I/O 瓶颈netstat -an | grep :80 | wc -l看连接数网络瓶颈lsof -p pid | wc -l看进程打开的 fd 数资源泄漏希望帮到你。本文还有配套的精品资源点击获取