面灵AI→

清微智能 AI 测开一面面经

轮次
一面
时间
2026-10
来源
牛客网

《面试题目》

  1. 自我介绍。
  2. VLA 边端部署的硬件选型。
  3. 量化有哪些好处?量化的算法有哪些?量化的对象有哪些?
  4. RAG 是否是自己搭建的?
  5. flask 框架是用在测试项目上的吗?
  6. 有了解过什么测试框架吗,比如 pytest?有实际应用过吗?
  7. Python 八股:list、tuple、set 的区别。
  8. list 的切片的三个参数表示什么含义?
  9. is 关键字和 == 的区别?
  10. 浅拷贝和深拷贝的区别?
  11. 多线程修改同一个变量,有什么问题,如何规避?
  12. 有了解数据库中的锁吗?
  13. pytest fixture 的作用有哪些?
  14. 测试用例的公有配置,pytest 如何实现?
  15. Python 抛出异常的方式?
  16. C 语言:函数指针和指针函数的区别。
  17. 突然追加提问:接触陌生领域如何去学习相关技能?如何推进?

《参考解析》

量化对 AI 测试意味着什么。好处有三:显存与带宽占用下降(模型能塞进边端芯片)、推理延迟降低(整数运算更快)、功耗下降。常见算法:训练后量化(PTQ,直接对权重与激活做校准,成本低)与量化感知训练(QAT,训练时模拟量化误差,精度更好但贵);位宽上从 FP32 → FP16/BF16 → INT8 → INT4;校准方式有最大值、KL 散度、MSE、直方图等;还需处理异常值(per-channel 量化、outlier 分离)与算子融合。量化的对象包括权重、激活、KV Cache(大模型推理的关键)、以及算子实现本身。测试侧要验什么:精度(与浮点基准的余弦相似度、Top-1/Top-5 一致率、困惑度、任务指标)、性能(时延、吞吐、首 token 时间)、一致性(同一输入多次推理结果稳定)、边界(超长输入、空输入、极端数值)、以及部署链路的正确性(量化后的模型能否被目标推理引擎加载、算子是否落到了加速器而不是回退到 CPU)。

pytest 的 fixture 与公共配置。fixture 的作用是提供测试的前置/后置资源与数据,并按需注入:@pytest.fixture 定义,测试函数用同名参数声明即注入;支持作用域(function/class/module/session,作用域越大越省时间但状态更难隔离);支持 yield 写前置与清理(teardown);支持 autouse=True 自动生效、params 做参数化、fixture 之间互相依赖。公共配置的几种做法:把公共 fixture 放在 conftest.py 里(按目录层级自动生效、无需 import);用 pytest.ini/pyproject.toml/setup.cfg 配置运行参数(测试路径、标记、日志、插件);用独立的配置模块或 pytest_addoption 加自定义命令行参数,再用 fixture 读取命令行与环境变量;另外用 pytest_runtest_makereport 之类的钩子统一做失败截图、日志收集。要能提到几个常用插件:pytest-xdist(并行)、pytest-html/allure-pytest(报告)、pytest-cov(覆盖率)、pytest-mock。

Python 基础题的关键点。list/tuple/set:list 有序可变、允许重复、支持索引与切片;tuple 有序不可变(更省内存、可哈希因而能做字典键);set 无序、元素唯一、底层哈希、适合去重与集合运算,注意它不保证顺序且元素必须可哈希。切片 a[start:stop:step]:start 默认 0、stop 默认长度、step 默认 1,负数表示从末尾倒数,step 为负表示反向切片;切片越界不报错(这点和索引不同)。is 比较的是对象身份(内存地址),== 比较的是值(调用 __eq__);小整数缓存与字符串驻留会让 is 在小整数上「看起来像比较值」,但这是实现细节不可依赖,判断相等一律用 ==,判断 None 才用 is None。浅拷贝(copy.copy、切片、dict())只复制最外层容器,内部元素仍是同一对象;深拷贝(copy.deepcopy)递归复制,能避免改嵌套对象影响原对象,代价是性能与循环引用(deepcopy 用 memo 处理循环引用,但仍要留意不可拷贝的对象)。

多线程修改同一变量的风险与规避。风险来自「读—改—写」不是原子操作:count += 1 在字节码层面是多步,两个线程交错执行会丢失更新;即使单个操作原子,复合逻辑仍需要锁。Python 里还有 GIL:它保证同一时刻只有一个线程执行字节码,所以不少操作「碰巧」安全,但 GIL 可能在任何字节码边界切换,因此不能把它当成线程安全保证;而且 I/O 释放 GIL 时并发问题更明显。规避手段:用锁(threading.Lock/RLock,注意尽量缩小临界区、固定加锁顺序避免死锁)、用 queue.Queue 做线程间通信(内部已加锁)而不是共享变量、用不可变数据结构、用 threading.local 做线程私有状态、或者改用 multiprocessing/异步模型规避共享。要对「数据库锁」问题补充:MySQL 里有表锁与行锁(InnoDB 的行锁基于索引,索引缺失会退化成扫全表加锁)、共享锁与排他锁、意向锁、以及 MVCC 提供的一致性读;并发问题对应四类:脏读、不可重复读、幻读与丢失更新,分别由隔离级别与加锁/乐观锁解决。

C 语言的函数指针与指针函数。int (*f)(int, int) 是函数指针:变量 f 指向一个函数,调用 f(1,2) 或 (*f)(1,2) 都行;用途是回调(qsort 的比较函数、事件分发表)、函数表(用数组存一组处理函数替代长 switch)、以及运行时多态。int *f(int, int) 是指针函数:它是个函数,返回值是指针,注意不能返回局部变量的地址。要能说出二者在读法上的区别(从变量名出发,看它先和谁结合:先和 * 结合说明是指针,先和 () 结合说明是函数),以及更复杂的嵌套(返回函数指针的函数、函数指针数组)。嵌入式场景下函数指针还要提醒一句:跳转到错误地址是跑飞(HardFault)的常见原因,因此函数表中的指针要有范围校验,Flash 中存放的函数地址在重定位与升级时尤其要注意。

「接触陌生领域怎么学」这类开放题。给出可复用的方法而不是态度:先找到该领域的权威入口(官方文档、规范、经典教材)建立概念地图,再用一个最小可跑的例子打通闭环(跑起来比看懂更重要),然后带着具体问题去查(问题驱动比通读快),输出一份自己的笔记或最小 demo 用来检验理解。推进上要会拆里程碑并设置可验证的中间结果:例如一周内能把模型在目标芯片上跑通并给出时延与精度数据。最后补一句信息渠道:官方 issue、源码、以及同行社区,比零散博客更可靠。