第19章 场景与业务实战
本章共收录 43 道题,覆盖:业务场景需求拆解、线上问题排查与优先级、协作沟通与质量、刁钻疑难排查(性能渲染/网络并发/资源工程)、系统设计与架构取舍、产品设计与玩家体验。
一、业务场景题:需求拆解与技术决策
1.1 设计一套限时活动系统,要求热配置、定时开放、奖励领取、跨端展示和防重复领取
★★ 中等考点: 活动系统设计、配置热更新、幂等、服务端权威
参考答案:
- 活动定义与玩家进度分离:配置(版本号、时间窗、奖励表、灰度范围)与玩家实例进度分开存储;
- 服务端权威:以服务端时间和领奖资格为权威,客户端只做展示与倒计时,规避时钟漂移;
- 领奖接口幂等:以(活动ID+奖励ID+角色ID)为唯一键记录发奖流水,重复请求返回相同结果;
- 配置热更新:配置带版本号、灰度范围与回滚能力,活动下线后仍保留历史存档数据;
- 异常路径:时钟漂移、断线补领与补偿发奖需有明确处理。
1.2 设计背包与道具系统,既支持堆叠、随机词条、过期时间,又要支持多人交易
★★★ 困难考点: 物品系统设计、数据模型、交易事务
参考答案:
- 静态 Item Definition 与 Item Instance 分离:定义保存模板(名称、图标、基础属性),实例保存唯一ID、堆叠数、随机词条、过期时间;
- 交易由服务端事务/状态机驱动:物品进入锁定态,不能相信客户端物品 ID;
- 须处理并发点击、断线重连、审计日志与数据迁移;
- 高分补充:容量/重量/索引设计、网络增量同步策略。
1.3 新手引导经常被跳过,产品希望"强引导直到完成",你怎么做?
★★ 中等考点: 新手引导设计、可恢复状态机、埋点
参考答案:
- 先确认目标是转化、留存还是功能理解,不能只堆强制弹窗;
- 引导应是可恢复状态机:事件驱动校验完成条件,支持跳过、重试、版本迁移;
- UE 层用 DataAsset 定义引导步骤,避免把流程硬编码进关卡蓝图;
- 加埋点漏斗验证引导效果,用数据判断强制是否带来负反馈。
1.4 设计赛季通行证和每日任务系统
★★★ 困难考点: 赛季系统、任务系统、奖励幂等、多端一致性
参考答案:
- 明确周期、时区、刷新规则、免费/付费轨道、奖励幂等与跨设备一致性;
- 任务事件归一化:原始事件上报后聚合成任务进度,再网络同步;
- 处理赛季切换、补领、付费退款与作弊刷任务等异常路径。
1.5 项目要从单机加入 4 人联机合作,如何评估改造成本?
★★★ 困难考点: 联机改造评估、权威状态、架构迁移
参考答案:
- 按"权威状态、输入、表现、存档、UI、关卡/任务、第三方服务"逐项盘点,而非只给 Actor 打开
Replicates;
- 区分可客户端表现与必须服务端裁决的逻辑;
- 先用原型验证一条核心循环与弱网体验,再分阶段迁移。
二、业务场景题:线上问题与优先级
2.1 上线后玩家反馈"偶尔丢档",但无法稳定复现。你的第一天怎么处理?
★★★ 困难考点: 数据安全、问题聚类、日志补全
参考答案:
- 先止血:保留旧存档、增加备份与写入校验,必要时暂停高风险迁移;
- 按版本、平台、网络、磁盘空间、存档大小聚类,缩小怀疑范围;
- 补齐写入结果、校验和、序列化版本、异常码等日志;
- 修复要做兼容读取与恢复工具,而不只是 try/catch。
2.2 新版本 DAU 未下降,但付费转化下降 15%,技术负责人要做什么?
★★★ 困难考点: 数据分析、埋点核对、灰度排查
参考答案:
- 不抢做业务结论,先核对埋点、支付回调、商品配置、地区/平台、漏斗分段与版本灰度;
- 排除 UI 不可点击、价格展示、网络请求、订单去重等技术故障;
- 提出可回滚的修复、对照组与监控阈值。
2.3 核心战斗功能延期两周,美术、策划、服务端都依赖它,怎么推进?
★★ 中等考点: 项目推进、依赖管理、MVP
参考答案:
- 暴露关键路径和不确定性,拆出可演示的 MVP;
- 冻结接口并提供 Mock/配置兜底,让下游并行开发;
- 按功能价值、风险、依赖重新排期;
- 每日以可验证里程碑同步,而不是只报"开发中"。
2.4 玩家说匹配很慢,但服务端监控显示 CPU 空闲。如何分析?
★★ 中等考点: 匹配系统、指标分析、决策权衡
参考答案:
- 匹配不是纯算力问题:检查队列分桶、段位/地区/队伍限制、超时策略、房间创建、网络握手和客户端展示;
- 按等待时长分位数与原因码拆分定位瓶颈;
- 方案可含逐步放宽规则、跨区策略、机器人兜底,但必须说明公平性代价。
2.5 线上热修复后崩溃率上升,但日志不完整,是否立即回滚?
★★ 中等考点: 发布决策、风险控制、回滚策略
参考答案:
- 以影响范围和严重度决策:启动崩溃、数据损坏、付费链路异常优先回滚/停服开关;
- 若仅小比例非关键崩溃,可灰度暂停、采集符号与最小样本再判断;
- 始终保留可逆开关、版本映射和对外沟通方案。
三、业务场景题:协作、质量与沟通
3.1 策划提出"改一个数值",实际会影响存档、网络和 UI,你如何沟通?
★★ 中等考点: 跨职能沟通、影响面评估
参考答案:
- 用影响面和选项沟通,而非只说"不能改";
- 说明即时改、版本兼容改、下版本改各自的成本/风险;
- 提供数据迁移、配置开关、灰度验证方案;
- 将决策和验收指标写入需求,避免反复。
3.2 你如何处理一次代码评审分歧:功能能跑,但你认为会造成未来性能问题?
★★ 中等考点: 代码评审、性能权衡、沟通
参考答案:
- 先用目标场景和基准数据说话,避免主观判断;
- 区分阻塞风险与可记录债务;
- 提出最小安全改动和后续优化 ticket;
- 不把个人风格当质量门槛,并说明如何防止同类问题再出现。
3.3 如何给非技术负责人解释"为什么要投入两周建设性能自动化"?
★★ 中等考点: 技术沟通、价值量化
参考答案:
- 用业务语言量化:卡顿影响留存/审核/延期,人工回归的频率与成本;
- 给出最小范围(核心地图、目标机、帧耗/内存阈值)、分阶段收益与不建设的风险;
- 不承诺不现实的"永不掉帧"。
3.4 需求临近上线才发现无障碍/本地化不合格,谁负责,怎么补救?
★★ 中等考点: 无障碍、本地化、流程改进
参考答案:
- 不推责,先按合规和上线风险定优先级;
- 把文本、字体、输入、字幕、色盲、可读性分别拆项补救;
- 建立伪本地化、自动截屏、键盘导航等前置检查,纳入 Definition of Done。
四、刁钻场景与疑难排查:性能与渲染
4.1 PC 版平均 60 FPS,但进入新区域必现 300ms 卡顿;GPU 轨迹正常。如何区分资源 IO、对象创建、GC、Shader/PSO 与同步等待?
★★★ 困难考点: 性能定位、trace 分析、实验验证
参考答案:
- 先以 trace 和指标区分各环节:文件 IO(Async Loading/IO 耗时)、对象创建(Spawn/构造)、GC(强制 GC 触发)、Shader/PSO 编译闪帧、同步等待(加载阻塞主线程);
- GPU 轨迹正常说明瓶颈在 CPU 侧,用 Unreal Insights/stat 抓时间切片,定位 300ms 集中在哪个阶段;
- 每项只做可逆实验(如预编译 PSO、改异步加载、调 GC 频率),最后用同路线跑 P95/P99 百分位验证。
4.2 同一场景在编辑器流畅、Shipping 包明显卡顿。列出构建配置、DDC、PSO、日志与统计差异的检查顺序
★★★ 困难考点: 打包差异排查、构建配置
参考答案:
- 对齐 Shipping 的 CVars(
r.* 质量开关、帧率限制)与 Cook 内容(排除 Debug 资产、纹理压缩差异);
- 检查 DDC/PSO 是否预编译、是否剥离调试符号、DeviceProfile 差异;
- 必须在打包目标机上以同样 CVars 与统计开关复现,而非推断。
4.3 美术要求"所有模型 Nanite、所有阴影 VSM、全部 Lumen"。你如何建立目标机上的质量/显存预算并提出降级矩阵?
★★★ 困难考点: 性能预算、质量分级、平台回退
参考答案:
- 为每平台建立 GPU/显存预算与功能矩阵(内存占用、帧耗、发热);
- 按可见距离、质量档、平台回退(如移动端用 SSR 替代 Lumen、阴影降档),而非全局全开;
- 用目标机实测数据说服,给出降级矩阵并约定默认档位。
4.4 角色换装后显存持续增长;UObject 数量正常。如何定位 Render Resource、流送纹理、材质实例和 Render Target 泄漏?
★★★ 困难考点: 显存泄漏排查、渲染资源生命周期
参考答案:
- 对比显存快照与 Render Resource/Streaming/RT 池:用
stat TextureMemory、stat Streaming、RenderTarget 追踪工具观察;
- 检查动态材质实例(替换时是否释放旧引用)与 Render Target 生命周期(帧结束后是否释放);
- UObject 数量正常不代表 GPU 资源正常,材质/纹理/RHI 资源可能独立泄漏。
4.5 CPU 帧耗 10ms、GPU 12ms,Frame 却稳定在 33ms。你会怀疑哪些帧同步、VSync、Present、限帧或队列问题?
★★★ 困难考点: 帧同步、Present、帧率限制
参考答案:
- 检查 VSync/帧率上限(
r.VSync、t.MaxFPS、平台帧率锁定 30/33ms);
- 检查 Swapchain Present 与 GPU queue 提交节奏、CPU 等待 fence(渲染线程是否等待前一帧 Present);
- Frame 可能被显示同步锁到 33ms(30FPS 档),需与平台显示刷新率对齐确认。
4.6 透明技能特效一放就掉帧,但 Draw Call 不高。如何证实是 overdraw、粒子更新、灯光还是后处理?
★★★ 困难考点: 渲染性能、overdraw、粒子
参考答案:
- 用 Quad Overdraw(
profilegpu/移动端 overdraw 视图)确认填充率压力;
- GPU pass 分析半透明渲染耗时,粒子统计看更新与发射量;
- 逐项禁用(关后处理、关粒子、关灯光)定位;Draw Call 低仍可因全屏透明混合与复杂像素着色慢。
4.7 使用 TSR 后远处植被抖动/拖影。请从运动矢量、材质、LOD、抖动采样与锐化参数提出验证方案
★★★ 困难考点: 时间超分辨率、运动矢量、TSR/TAA
参考答案:
- 检查 velocity(运动矢量)是否正确:WPO/材质扰动是否写入速度、骨骼网格是否输出速度;
- 检查材质设置与 LOD 切换导致的瞬时变化;
- 逐项固定变量:抖动采样(jitter)、锐化参数(
r.TSR.Sharpening),在运动镜头下 A/B 对比。
五、刁钻场景与疑难排查:网络与并发
5.1 玩家 A 看见自己开门,玩家 B 偶发看不见;重连后又正确。请设计日志字段和最小复现矩阵
★★★ 困难考点: 网络同步排查、日志设计、复现
参考答案:
- 记录 Actor NetId、角色、RPC 调用与参数、复制版本、Dormancy 状态、连接状态与时延;
- 两端日志对齐时间轴,按晚加入/弱网/重连矩阵复现;
- 重连后正确 → 怀疑复制条件(
bOnlyRelevantToOwner、NetUpdateFrequency)或 Dormancy 唤醒失败。
5.2 某个 Reliable RPC 每帧发送,测试网络没问题,线上弱网后所有交互延迟数秒。解释原因和改造路径
★★★ 困难考点: RPC 可靠性、网络队列、限流合并
参考答案:
- 原因:Reliable 按序可靠队列被每帧消息占满,后续事件只能排队,弱网丢包进一步放大延迟;
- 改造:改为状态复制(Actor 属性)、最新值用不可靠发送、限流与合帧(只发最新状态);
- 区分事件与状态:事件用可靠但低频,状态用不可靠最新值。
5.3 客户端预测冲刺手感很好,但在斜坡、移动平台和高 ping 下频繁回弹。你怎样切分可预测状态与服务端判定?
★★★ 困难考点: 移动预测、服务器校验、网络补偿
参考答案:
- 将可预测状态(输入驱动的速度/方向)与服务端权威判定(碰撞、平台状态)切分;
- 记录输入序列与时间戳,服务端回放校验;
- 对斜坡/移动平台定义一致的模拟规则,或加服务端校正策略,减少回弹。
5.4 客户端能伪造一次"拾取成功"事件。仅把 RPC 改为 Reliable 为什么无效?服务端要验证哪些事实?
★★★ 困难考点: 反作弊、服务端权威、安全设计
参考答案:
- Reliable 只保证送达与顺序,不保证请求合法;
- 服务器必须校验:物品存在、所有权、距离、状态(未拾取)、冷却时间与拾取锁,并限流;
- 关键判定逻辑放服务端,客户端只上报输入/意图。
5.5 异步加载回调偶发崩溃,堆栈指向已析构 Widget。除了 IsValid 外,生命周期、取消句柄和线程切换怎样设计?
★★★ 困难考点: 异步任务生命周期、弱引用、线程安全
参考答案:
- 任务持有取消句柄与世代号(generation),页面销毁时取消任务并递增世代号;
- 回调先验证弱引用(
TWeakObjectPtr)再切回 Game Thread 更新 UI;
- 明确线程归属:加载/IO 在后台线程,UI 更新必须回 Game Thread。
5.6 开发者用 `TSharedPtr<UObject>` 解决异步回调悬垂。为什么这是错误方向?
★★★ 困难考点: 智能指针与 UObject、GC、内存所有权
参考答案:
TSharedPtr 不参与 UObject GC 追踪,无法感知对象回收,可能造成双重所有权与悬垂;
- 应使用
TWeakObjectPtr/UPROPERTY 管理引用,配合明确的异步保活对象(任务上下文持有强引用);
- 规则:非 UObject 用
TSharedPtr,UObject 用 TWeakObjectPtr/UPROPERTY。
六、刁钻场景与疑难排查:资源、UObject 与工程
6.1 某 DataAsset 在 PIE 正常、Cook 后为 null。你如何检查引用方式、Asset Manager 扫描、Cook 规则和软路径?
★★★ 困难考点: 资源加载、Cook 规则、AssetManager
参考答案:
- 检查引用方式:硬引用还是软路径(
TSoftObjectPtr),路径是否失效;
- 检查 AssetManager 扫描规则与 Cook 规则(
CookAdditionalAssets、是否被打包);
- 在包内实际列出资产确认存在,不能只看 PIE 缓存;检查 bundle/关卡依赖。
6.2 一个 `UPROPERTY` 指针没有 GC,另一个裸指针"看起来一直能用"。为什么后者更危险?何时裸指针仍合理?
★★★ 困难考点: GC、指针安全、所有权
参考答案:
- UPROPERTY 能被 GC 追踪并自动置空;裸指针不会被 GC 清理,对象回收后即悬垂;
- 后者危险在于"看起来一直能用"可能实际已悬垂——悬垂未崩溃更隐蔽;
- 裸指针仅在短作用域、非拥有且对象生命周期确定(必然存活)时才合理。
6.3 重命名大量资产后,提交显示大量无意义改动且加载出现 Missing。如何恢复并建立团队迁移流程?
★★ 中等考点: 资产迁移、版本控制、流程
参考答案:
- 停止大规模重命名,先修复 Redirector(Fix Up Redirectors)、引用与提交范围;
- 恢复策略:用提交历史/备份回退,或批量修复被破坏的引用;
- 建立流程:Checkout 锁与通知机制、自动引用检查、分批小步迁移。
6.4 策划希望运行时修改 DataTable 并保存。你会直接修改资产吗?请设计运行态覆盖层与版本迁移
★★ 中等考点: 配置热更新、数据覆盖、版本迁移
参考答案:
- 不直接修改打包资产(只读、无版本控制、易被热更覆盖);
- 设计运行态配置覆盖层:记录"基础配置 + 覆盖项(delta)",保存到存档/服务器;
- 以版本化 schema 迁移,兼容旧版本数据并校验合法性。
6.5 只在某台构建机上 Shader 编译失败。如何从插件、目标平台、DDC、路径长度、工具链和最小工程排查?
★★★ 困难考点: 构建环境差异、Shader 编译、DDC
参考答案:
- 比较机器与目标平台:插件版本、工具链(编译器/SDK)、路径长度(Windows 长路径)、磁盘空间;
- 清 DDC 或用干净 DDC 排除缓存污染,对比 DDC key;
- 用最小工程或同代码换机器复现,验证是环境差异而非代码问题。
6.6 "用 `AddToRoot` 防止对象被 GC"为什么通常是坏修复?什么情况下可短期接受?
★★ 中等考点: GC、AddToRoot、内存泄漏
参考答案:
AddToRoot 绕过 GC 追踪,忘记 RemoveFromRoot 即永久泄漏;
- 通常应改为
UPROPERTY 强引用 + 明确生命周期管理;
- 仅在短时引擎级对象(如启动期)可短期接受,且必须有确定的
RemoveFromRoot 路径。
七、系统设计与架构取舍
7.1 设计一个支持单机与联机、可预测、可存档、可配置的投射物系统。请给出模块边界和数据所有权
★★★ 困难考点: 投射物系统设计、网络权威、存档
参考答案:
- 模块边界:数据(定义/配置)、运行实例、碰撞/表现、网络权威、存档;
- 本地预测发射,服务器生成与命中裁决,客户端做表现与预测;
- 实例 ID 支持恢复与存档还原,配置走 DataAsset 便于扩展。
7.2 设计可复用的交互系统,需覆盖射线检测、UI 提示、多人权限、长按、打断和扩展到 NPC/物体
★★★ 困难考点: 交互系统设计、接口抽象、权限
参考答案:
- 用接口描述可交互能力(
IInteractable),客户端负责检测(射线/形状)与提示展示;
- 服务器校验距离/状态/权限,客户端只上报意图;
- 交互状态机支持长按、取消/打断与冷却,通过接口扩展到 NPC/物体。
7.3 在不改动大量关卡蓝图的前提下,引入昼夜天气系统。如何处理环境参数、网络、保存、流送区和美术扩展?
★★★ 困难考点: 天气系统设计、Subsystem、网络同步
参考答案:
- 用 Subsystem 协调时间与天气,DataAsset 定义曲线(光照、雾、天空);
- 环境参数分层:全局权威时间/天气 + 本地过渡表现;
- 网络同步权威时间,流送区订阅状态,存档仅存必要状态,美术通过曲线扩展。
7.4 设计一套可在 10 万条配置下查询的道具/任务数据系统;如何避免启动全加载,又保持策划可编辑?
★★★ 困难考点: 数据系统设计、索引、异步加载
参考答案:
- 定义与实例分离,ID 唯一,配置按类型/标签组织;
- 建立索引/标签支持查询,按需异步加载,运行态缓存设有限额(如 LRU);
- 编辑侧有版本与校验(schema 校验、引用检查),避免启动全加载。
7.5 你需要支持 PC/主机/移动三端同内容。哪些系统必须抽象,哪些应明确分叉?如何落地?
★★★ 困难考点: 跨平台架构、抽象与分叉、能力检测
参考答案:
- 必须抽象:输入(Enhanced Input 统一映射)、存档、在线服务、质量档、UI(Anchors 布局、安全区域);
- 应明确分叉:渲染特性、内存策略、平台服务(手柄特性、审核要求)、物理与性能档位;
- 用 Device Profile 与能力检测选择默认质量,Scalability Settings 支持运行时分级:
#if PLATFORM_IOS || PLATFORM_ANDROID
bUseTouchControls = true;
#elif PLATFORM_PS5
bUseDualSenseFeatures = true;
#endif
void AdjustQualityForPlatform() {
if (IsMobilePlatform()) {
SetScalabilityQuality(EScalabilityQuality::Low);
} else if (IsConsolePlatform()) {
SetScalabilityQuality(EScalabilityQuality::Epic);
}
}
- 优先开发目标平台,定期在其他平台测试,考虑移动端存储限制。
八、产品设计与玩家体验
8.1 游戏设计中的"心流"理论是什么?
★★ 中等考点: 心流理论、难度设计、玩家体验
参考答案:
- 心流(Flow)由心理学家 Csikszentmihalyi 提出,指玩家完全沉浸在游戏中的体验,在挑战与技能平衡时产生;
- 心流通道:挑战过高→焦虑挫败,挑战过低→无聊,平衡区→心流;
- 设计原则:渐进式难度、即时反馈、明确目标、专注体验(减少干扰)、控制感;
- UE 实现:难度曲线系统、动态敌人 AI、多难度选择、教程系统引导。
8.2 如何设计良好的游戏反馈系统?
★★ 中等考点: 游戏反馈、视听触觉、即时性
参考答案:
- 反馈让玩家知道行动结果、增强沉浸感、提供成就感并引导行为;
- 类型:视觉(粒子、UI 动画、屏幕震动、角色动画)、听觉(音效、音乐变化、语音)、触觉(手柄震动)、数值(伤害数字、经验、成就解锁);
- 原则:即时性、清晰性、一致性、适度性、层次感;
- 代码示例:
UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), HitEffect, HitLocation);
GetWorld()->GetFirstPlayerController()->ClientPlayCameraShake(HitShake, 1.0f);
UGameplayStatics::PlaySoundAtLocation(GetWorld(), HitSound, HitLocation);
8.3 如何优化游戏的加载时间?
★★ 中等考点: 加载优化、异步加载、流送与缓存
参考答案:
- 加载时间影响第一印象与留存,目标控制在 5 秒内;
- 异步加载:Async Loading + 进度条 + 预加载关键资源;
- 资源优化:压缩纹理/网格、LOD、减少无用资源;
- 流式加载:World Partition 按需加载卸载;缓存:DDC 避免重复加载;
- 代码示例:
FLatentActionInfo LatentInfo;
LatentInfo.CallbackTarget = this;
LatentInfo.ExecutionFunction = "OnLevelLoaded";
UGameplayStatics::LoadStreamLevel(GetWorld(), "LevelName", true, LatentInfo, FLinearColor::White);
UAssetManager::Get().PreloadPrimaryAssets(AssetList, true, true);
- 使用加载画面掩盖过程,显示提示或故事,优化首屏加载。
8.4 如何设计良好的 UI/UX?
★★ 中等考点: UI/UX 设计、UMG、可访问性
参考答案:
- 原则:清晰性、一致性、反馈性、简洁性、可访问性;
- HUD 分层:重要信息(生命/护盾、弹药、小地图、任务目标)、次要信息(技能冷却、道具栏、队友状态)、动态信息(伤害数字、拾取提示、任务更新);
- UE 用 UMG/Widget Blueprint/Canvas Panel 实现,用动画增强交互;
- 测试不同屏幕尺寸,考虑色盲玩家、提供字幕与音量控制,支持手柄与键鼠。
8.5 如何优化移动端性能?
★★★ 困难考点: 移动端性能、渲染配置、内存优化
参考答案:
- 渲染:降低分辨率(720p 或更低)、Forward Rendering、减少 Draw Call、简化材质、减少后处理;
- 纹理:ASTC/ETC2 压缩、降低分辨率、使用纹理图集;
- 网格体:低多边形、LOD、合并静态网格体;
- 内存:及时卸载、对象池、减少纹理内存、音频压缩;
- CPU:减少 Tick、优化 AI、异步加载、减少物理模拟;
- 配置示例:
[/Script/Engine.RendererSettings]
r.MobileHDR=False
r.Mobile.MaxShadowmapResolution=512
r.Mobile.NumDynamicPointLights=2
r.Mobile.EnableStaticAndCSMShadowReceivers=False
[/Script/Engine.TextureEncodingProjectSettings]
FinalMobileRuntimeTextureFormat=ASTC
- 目标 30 FPS 稳定,用 Unreal Insights 分析,定期真机测试,用 Scalability 分级质量适配不同设备。