面灵AI→

北京华玉通软软件测试实习面经

结果
已oc
时间
2026-10
来源
牛客网

《面试题目》

  1. 自我介绍。
  2. AI 是如何辅助你之前的工作的?
  3. 注册成功登录失败怎么排查?
  4. 你提到了死锁,怎么理解死锁?
  5. 怎么确定是死锁造成的问题?
  6. C++ 学过吗?
  7. mock 解决什么问题?
  8. 了解单元测试吗?
  9. 一个接口让你进行单元测试怎么做?
  10. 怎样让代码逻辑满足分支覆盖率?
  11. 动态库和静态库了解吗?
  12. 给一个程序,少给了依赖,在 Linux 上执行报错,怎么解决?
  13. 给你足够的 git 代码权限,怎样设计自动化执行和手动执行并汇报到 Jira 上的流水线?
  14. 一些产品在内网中不能使用 AI 能接受吗?

《参考解析》

「注册成功登录失败」怎么排查。这道题考的是排查方法论,按「先分层、再收窄」答。客户端层:确认登录请求是否真的发出(抓包或看前端日志)、请求体字段是否完整(密码是否被前端做了意外处理)、时间与时区是否正确(验证码或 token 过期)、缓存与 Cookie 是否残留旧态(清缓存再试)。网络层:状态码是超时还是 4xx/5xx,超时看网关与后端连通性,4xx 看参数与鉴权。服务端层:查登录接口日志与 trace id,确认是否收到请求、在哪个分支返回失败;核对数据库里用户记录是否真的写入(注册事务是否提交、是否写到了分库分表的另一个库)、密码哈希与盐是否一致、账号状态是否被置为未激活或锁定。链路层:如果登录依赖缓存或消息,检查缓存是否写成功、是否有异步任务把状态覆盖回去了。最后做对照实验收窄:用同一份数据走注册接口再走登录接口、用工具直接查库比对字段。答题时把「先确认现象→再分层排除→最后定位根因→补回归用例」这条顺序讲出来,比直接猜原因得分高。

死锁与定位。死锁的四个必要条件要能背:互斥、持有并等待、不可剥夺、循环等待;破坏任意一个条件就能避免。常见成因:两把锁加锁顺序不一致、在持有锁的情况下调用可能阻塞的外部接口(回调回来又拿同一把锁)、递归加锁未用可重入锁、资源池耗尽后互相等待。怎么确定是死锁造成的:先看现象特征——进程卡死不退出、CPU 占用为 0(不是死循环)、相关线程都在等待状态;然后取证,Linux 下用 pstack/gdb attach 打印各线程的栈与当前持有的锁(thread apply all bt、info threads),Java 用 jstack 看 Found one Java-level deadlock 与等待环,或者用 pstack/gcore 抓两份快照比对;日志里如果打了「acquiring lock X」这类信息,能直接还原等待环。把「谁持有谁等待」的环形依赖画出来,就是死锁成立的确凿证据。定位之后修法:统一加锁顺序、用 try_lock 加超时、缩小锁粒度、避免持锁调用外部代码、用无锁队列或单线程化访问共享资源。

mock 与单元测试。mock 解决的是「被测代码依赖了不可控或不存在的部分」:外部 HTTP、数据库、消息队列、时间、随机数、第三方 SDK。它的价值是让单元测试只验证被测单元自身的逻辑,跑得快、结果稳定、不依赖环境。要能说出 mock 的类型:桩(stub)提供固定返回值、伪造(fake)提供简化实现(比如内存数据库)、mock 还能断言「有没有被调用、调用了几次、参数是什么」,spy 在真实对象上记录调用。单元测试的写法(以「给一个接口写单元测试」为例):先明确接口契约(输入、输出、异常、边界),列出等价类与边界值,覆盖正常路径、参数非法、依赖失败(超时、返回错误码)、并发或重复调用;用断言验证返回值与副作用(被依赖对象收到了什么调用);测试要独立可重复,不依赖执行顺序,外部依赖全部 mock。再补一句工程实践:测试函数命名体现被测场景、失败信息要能直接看出期望与实际、尽量一个测试只验证一件事。

分支覆盖率怎么做到。先分清指标:语句覆盖率看每行是否执行,分支(判定)覆盖率看每个条件的真/假两个方向是否都走到,条件覆盖看复合条件里每个子条件的取值,路径覆盖最难也最贵,实践里通常盯分支覆盖率。提升手段很具体:为每个 if/else 补齐真与假两个用例;把 &&/|| 的短路分支拆成独立用例;异常分支(catch、错误码返回)要通过 mock 让依赖返回错误来触发;switch 的每个 case 与 default 都要有用例;不可达的防御分支要么删掉、要么用注释说明不可达,别为凑覆盖率写无意义用例。要提醒一句:覆盖率是手段不是目标,100% 覆盖率不等于没有 bug,关键看用例的断言是否真的在验证行为。

动态库与静态库。静态库(.a)在链接期被整体或按需拷贝进可执行文件,产物大、运行时无外部依赖、升级要重新编译链接;动态库(.so)在运行时按需加载,多进程共享同一份内存、体积小、可单独升级,但要处理版本与路径问题(LD_LIBRARY_PATH、rpath、ldconfig 缓存、符号冲突)。测试视角的差异:静态库测试要关注链接时的重复符号与体积;动态库要额外测加载失败、版本不匹配、多版本共存、延迟绑定(dlopen/dlsym)与卸载后的句柄有效性。

Linux 上缺依赖报错怎么排查。先看报错本身:error while loading shared libraries: libxxx.so.N: cannot open shared object file,拿库名去定位。步骤是:ldd ./program 列出所有依赖及其解析结果,缺失的会显示 not found;用 find / -name 'libxxx.so*' 或 ldconfig -p | grep libxxx 确认系统里有没有;确认架构与位数是否匹配(file、uname -m,32 位程序找不到 64 位库);如果库在但找不到,把它所在目录加进 LD_LIBRARY_PATH,或者在链接时用 -Wl,-rpath,或者写进 /etc/ld.so.conf.d/ 后跑 ldconfig;如果是版本号对不上(需要 libxxx.so.1 但只有 libxxx.so.2),先确认 ABI 兼容性,再考虑装对应版本的包或用兼容层,别直接软链了事。回答时把「ldd 定位 → 是否存在 → 架构与路径 → 版本与 ABI → 修法」这条链路讲完整。

CI 流水线与 Jira 汇报的设计。要点是「触发条件、执行内容、结果回写」三段。触发:提交或合并请求时自动跑(编译、单元测试、静态检查、打包、部署到测试环境),同时保留一个手动触发的入口用于「指定版本 / 指定环境 / 只跑冒烟」这类场景,两者用同一套脚本避免行为漂移。执行:用流水线配置文件(Jenkinsfile / GitHub Actions workflow / GitLab CI)定义阶段与失败策略(失败即阻断合并、允许重试但记录次数),产物归档、日志留存。汇报:把结果回写到 Jira——提交信息里带 issue key,或在流水线里调 Jira REST API 在对应 issue 下留言(成功/失败、构建号、日志链接、覆盖率),失败时更新 issue 状态或打标签并通知负责人;更完善的做法是把测试用例与需求/缺陷双向关联,让「这个缺陷是被哪次构建的哪个用例发现的」可追溯。要主动提到两个工程细节:凭据用 secret 管理而不是写进脚本、流水线要幂等且可重跑。

「内网不能用 AI 能接受吗」。这是筛意愿与合规意识的问题,别有怨气地答。可以说清:能接受,同时会把效率手段换成合规的替代方案(内网知识库、代码规范与静态检查工具、本地部署的模型能力),并且理解这类限制通常源于数据安全与交付要求。