news 2026/9/3 6:23:16

基本功练习-9月

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基本功练习-9月

20260901练习

题目1 如何测试一个大模型推理服务

假设服务提供如下接口:

POST /v1/chat/completions

请求示例:

{"model":"xxx","messages":[{"role":"user","content":"你好"}],"stream":true}

请整理一份 3~5 分钟的面试回答,至少覆盖以下内容:

  1. 功能测试需要覆盖哪些场景?
  2. 如何测试流式输出?客户端中途断开连接时如何验证?
  3. 如何设计并发测试和压力测试?
  4. 什么是 TTFT、TPOT、E2E Latency、吞吐量和 P99 延迟?
  5. 输入长度、输出长度和并发数分别会怎样影响性能?
  6. 如果 P99 延迟突然升高,如何定位问题?
  7. 如何测试服务重启、GPU 不可用、请求超时和下游异常?

回答
q1. 功能测试需要覆盖的基本场景如下,按照优先级排序:
p0 基本功能,如不同的模型id,构造不同的message类型,stream的true or false,是否返回预期内容,比如传入1+1 =? 模型是否正确的返回了答案等
p0 逻辑部分,是否依赖于其他前置接口,如auth等
p1 异常边界测试,如异常场景,参数异常等
p1 安全测试cookie token等认证

q2. 流式接口测试的核心理念是响应是否持续到大以及每个event是否都正确,因此要测试流式接口主要从以下步骤入手
s1. 确定流式接口的传输形式:
SSE: 标志为header中的Content-Type为text/event-stream
HTTP-Chunked:标志为 header中字段为transfer-encoding为chunked
WebScoket:连接建立后双向收发形式。
如果是前两种,则可以直接使用curl进行验证,如果是websocket,则需要编写代码或者专用客户端
s2. 应该验证断言内容如下:
- 状态码
- 首包及其响应时间
- 事件格式是否符合要求
- 事件顺序
- 事件是否正确结束
- 持续性与完整性
- 连接是否正常关闭
- 事件延迟,间隔,总耗时
- 事件结束后,服务端是否正确停止和生成资源
s3. 异常与压力测试

q3. 相较于传统的应答式接口,流式接口的测试应该从两个角度或者说测试模型入手。
a. 固定并发模型
能稳定维持多少个流式连接
b. 到达率模型
每秒能承受多少个新建请求,比如不去管先前的模型,而是固定的按时间启动固定数量的流
活跃并发数 = 每秒新请求 * 平均流请求时间
基于上述模型,需要进行以下阶段的测试
s1.基线测试,少量并发请求,确认接口和客户端逻辑基本正确
s2. 阶段性的加压测试:持续增加并发数量,每档保持一定量级的时间
s3. 临界点: 找到开始出现异常的时间点
s4. 突发异常流量测试: 短时间内从0至大并发,观察连接与服务器负载
s5. 稳定性测试:正常负载下持续并发请求与测试
s6. 取消与重试测试:随机中断连接,验证服务器资源是否正常

q4. TTFT: time to fisrt token,从请求发出到收到的第一个token,首token时间
TPOT:time per output token,首token后生成每个token所需要的平均时间,持续生成速度,Decode效率,流式输出是否顺畅的主要衡量项
E2E Latency: end-to-end latency 从请求开始到完整请求的总耗时
吞吐量:单位时间内处理的请求数,Token数和字节数
p99延迟:延迟分布的第99百分位,同样的p95和p50分别是95和50百分位,他们保证的分别是大多数用户,一般用户的体验

q5.
a. 输入长度对性能的影响主要体现在 TTFT 显存与最大并发等指标上,这是因为输入的内容在经过模型计算后,需要去建立KV Cache,都是些需要去消耗资源去做的事
输入长度越长<通常意义上来讲也就是说模型需要去理解的事情越复杂>,也就是模型需要去思考的事情变得更多了,那么思考阶段的成本也就变高了。
因此就会导致TTFT增大,E2E的延迟也会增大,模型思考阶段的KV Cache增加,显存需求量更大,输入阶段的注意力计算量也需要更大,此外,更长的输入也意味着,后续每个输入的token需要关注的上下文也越来越长,因此Decode阶段的计算和显存访问也会显存增加。

b. 输出长度主要会导致E2E的延迟变长,以及连接占用的时间变久,同时输出变长,每一个输出的token都需要调用一次decoder,所以decode阶段对显存的需求也会增长

c. 并发长度:并发数量则直观的影响系统资源,无需多言
三者情况组合的话,大概是如下组合:
长输入 + 高并发,容易显存不足;
长输出 + 高并发,容易连接堆积和排队;
长输入 + 长输出 + 高并发,P99超时 OOM等,最不健康的状态

q6. 定位途径 当前请求数量/负载 -> 系统资源<cpu/内存/显存> -> 服务状态 -> 网络状态

q7:
a. 预期流程重启,检查原请求是否正确路由或者说负载到了备用服务上,检查是否有新请求进来
b. 强制重启,预料外的断开,检查入口是否正确启动了负载,客户端是否正确发送了重试请求,是否正确路由到了新的服务器,原有长链接是否被正确关闭, 服务器重启后是否存在僵尸进程,残留进程,协议栈中连接是否正确释放
c. GPU异常应测试GPU调度异常,CUDA设备无法识别,GPU OOM,模型失败,GPU实例负载失败
具体方法有:
- 修改GPU配置以模拟调度异常
- 暂时屏蔽或者短线GPU模拟CUDA无法识别
- 减小GPU可用内存模拟显存OOM
- 模拟模型的返回给下游,返回异常
d. 请求超时,需要模拟的异常情况主要有首token超时,流中超时,E2E超时
f. 下游异常返回,mock异常返回即可

20260902练习

假设你需要用 Go 编写一个简单的大模型推理服务压测工具,要求如下:

  • 总共发送 1000 个请求
  • 最大并发数为 20
  • 每个请求超时时间为 5 秒
  • 支持通过Ctrl+C取消测试
  • 统计成功数、失败数、超时数、平均延迟和 P99 延迟
  • 程序退出时不能遗留 goroutine 或 HTTP 连接

请整理一份 3~5 分钟的面试回答,至少覆盖以下内容:

  1. 如何使用 goroutine 和 channel 组织并发请求?
  2. 如何限制最大并发数?有哪些实现方式?
  3. 全局取消、单请求超时和程序退出之间是什么关系?
  4. 多个 goroutine 如何安全地统计测试结果?
  5. 如果收到Ctrl+C,应该如何停止新请求并处理正在执行的请求?
  6. 如何验证程序没有 goroutine 泄漏?
  7. “固定并发”与“固定每秒请求数”两种压测模型有什么区别?
  8. 如果 P99 延迟升高,你会优先查看哪些指标?

回答

q1. 如何使用 goroutine 和 channel 组织并发请求?

任务队列 + 固定数量 worker模型:
主 goroutine 将请求任务写入jobschannel,启动不超过最大并发数的 worker;
每个 worker 循环读取任务、执行请求,并将结果写入resultschannel。

这样做的好处是可以复用固定数量的 goroutine,不需要为 1000 个请求一次性创建 1000 个 goroutine。
jobschannel 负责分发任务,resultschannel 负责传递结果;

q2. 如何限制最大并发数?有哪些实现方式?

常见实现方式有三种:

  1. 固定数量 worker:直接启动concurrency个 worker,每个 worker 同时只处理一个任务。
  2. 带缓冲 channel 作为信号:启动任务前向容量为concurrency的 channel 写入一个令牌,任务结束后取出令牌。
  3. semaphore:使用golang.org/x/sync/semaphore管理并发许可。

同时,并发实现时需要配合sync waitgroup,锁等机制来配合使用并保证并发安全,防止出现脏数据

q3. 全局取消、单请求超时和程序退出之间是什么关系?

  • 全局取消:任务整体被停止,比如收到操作系统层面的SIGINT信号后调用context 的cancel()
    实现全局取消的前提是所有任务、worker 和请求都应该监听这个 context。
  • 单请求超时:在context 下为某个请求创建context.WithTimeout子 context,只影响该请求;
    超时后应记录为超时结果并释放资源。
  • 程序退出:程序预期中的退出,任务完成,优雅的退出并清理释放资源

q4. 多个 goroutine 如何安全地统计测试结果?

有三种可行方案:

  • worker 只负责发送Result,由一个 collector goroutine 串行更新计数器和延迟数组;
  • 对共享计数器或切片使用sync.Mutex保护;这也是最简单和常用的方法
  • 对简单的成功数、失败数使用sync/atomic,延迟明细仍由单独 collector 收集。

q5. 如果收到 Ctrl+C,应该如何停止新请求并处理正在执行的请求?

收到Ctrl+C后调用根 context 的cancel()。任务生产者在投递任务前监听ctx.Done(),取消后不再投递新任务;worker 在取任务和执行任务时也监听ctx.Done()

q6. 如何验证程序没有 goroutine 泄漏?

可以采用以下方法:

  • 在测试前后记录runtime.NumGoroutine(),重复执行多轮取消测试,观察数量是否持续增长;
  • 使用pprof.Lookup("goroutine")runtime/trace查看 goroutine 的调用栈和生命周期;
  • 使用go.uber.org/goleak等测试工具辅助检测;
  • 为 jobs、results 和 worker 的退出路径设置明确的关闭和等待逻辑;
  • 使用go test -race检查数据竞争,但要明确:-race不能替代 goroutine 泄漏检测。

q7. “固定并发”与“固定每秒请求数”两种压测模型有什么区别?

  • 固定并发:始终维持固定数量的活跃请求。一个请求完成后,才补充下一个请求。它形式上比较类似于并发测试
  • 固定请求:按照固定速率产生新请求,例如每秒启动 20 个请求,不等待之前的请求完成。形式上比较类似于新建测试

q8. 如果 P99 延迟升高,你会优先查看哪些指标?

“确认现象 → 拆分链路 → 关联资源 → 验证根因”的顺序定位:

  1. 确认时间窗口、样本量和统计口径,对比 P50、P95、P99、错误率和吞吐量,判断是整体变慢还是少量长尾变慢。
  2. 查看最近是否发生版本发布、模型切换、配置修改、扩缩容或流量结构变化,特别关注输入和输出 Token 长度分布。
  3. 将端到端延迟拆成网关、排队、Prefill、Decode、网络传输和下游依赖耗时。
  4. 查看推理服务的排队长度、batch 大小、TTFT、TPOT、GPU 利用率、显存和 KV Cache 占用,以及 OOM 和重试情况。
  5. 查看 CPU、内存、GC、连接数、负载均衡是否倾斜、网络丢包/重传和下游服务状态。
  6. 根据 request ID 抽取 P99 慢请求,关联日志和 Trace,最后通过回滚、降低流量、隔离实例或复现实验验证根因。

不能因为只有 P99 升高就直接排除网络问题;网络抖动、连接复用异常和负载均衡倾斜都可能主要表现为长尾延迟。

题目2 Go 小型工程练习:实现一个可取消、限并发的任务执行器

请实现下面的函数,暂时不要求真正调用 HTTP 接口:

typeResultstruct{SuccessboolLatencyMsint64Errerror}funcRunLoadTest(ctx context.Context,totalint,concurrencyint,)[]Result

要求如下:

  1. 使用context.Context支持任务取消。
  2. 最大并发数不能超过concurrency
  3. 每个任务随机模拟 10~100 毫秒的执行耗时。
  4. 收集每个任务的执行结果。
  5. ctx取消后,不再启动新任务。
  6. 已经开始执行的任务应能够感知取消并尽快退出。
  7. 结果收集不能产生数据竞争。
  8. 使用go test -race检查并发安全性。
  9. 思考如何验证程序没有 goroutine 泄漏。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/3 6:22:02

多层折叠标签:小包装信息承载的工程化解决方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/3 6:21:35

AI编程实战:Vibe Coding理念与Claude Code、Cursor、Codex工具全解析

这次我们来看一套完整的AI编程实战教程&#xff0c;重点解决零基础开发者如何快速上手Vibe Coding、Claude Code、Cursor、Codex等主流AI编程工具。如果你正在寻找一套从环境配置到项目实战的完整指南&#xff0c;这篇文章可以直接收藏备用。Vibe Coding&#xff08;氛围编程&a…

作者头像 李华
网站建设 2026/9/3 6:18:27

融合语义与平面约束:攻克低纹理环境的单目视觉SLAM实战

简介&#xff1a;本资源是一个面向机器人与计算机视觉方向研究者及高阶开发者的优质SLAM实战项目&#xff0c;聚焦低纹理环境下传统单目SLAM失效的核心痛点&#xff0c;创新融合语义理解、单目视觉与平面几何约束&#xff0c;显著提升特征贫乏场景&#xff08;如白墙、走廊、天…

作者头像 李华
网站建设 2026/9/3 6:17:52

OpenStamp:为开源大模型添加隐形水印的本地化部署与实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/3 6:17:28

text-to-cAD:自然语言生成CAD模型的技术原理与实践指南

你有没有遇到过这样的场景&#xff1a;手里有一份产品描述、设计草图甚至只是一段文字需求&#xff0c;却要花上大半天时间在 CAD 软件里一点一点画出三维模型&#xff1f;或者作为一个硬件开发者&#xff0c;明明知道机器人部件应该长什么样&#xff0c;却卡在了从概念到具体 …

作者头像 李华
网站建设 2026/9/3 6:16:35

STM32智能小车驱动板设计全解析:从原理图到PCB实战指南

简介&#xff1a;本资源是一套基于STM32F103ZET6主控的智能小车驱动板完整硬件设计资料&#xff0c;面向嵌入式初学者、课程设计学生及智能车竞赛爱好者&#xff0c;解决电机驱动电路设计、PCB布局布线与模块化接口集成等实践难点。压缩包共34个文件&#xff0c;包含Altium Des…

作者头像 李华