Appearance
OPPO 多媒体开发 C++ 线上笔试复盘
面试官提问清单
单选题(一)(现有材料可完整复核的第 9~20 题)
- 跨网络发送数据时,网络层承担什么职责?
- 两个线程对共享计数器执行“读—加一—写回”时,如何避免更新丢失?
- 对带相同键值的记录执行一轮稳定冒泡排序后,序列如何变化?
- 开放寻址哈希表容量不变、键值对增多时,平均查找槽位为什么变多?
- 带缓冲的标准 I/O 写日志成功返回后,为什么另一个进程暂时看不到文件尾部的新内容?
- 两个事务基于同一个旧余额计算并写回绝对值,为什么会得到错误余额,应该怎样加锁?
- 两个线程无同步地各执行 1000 次自增,为什么结果可能小于 2000?
- SQL 如何统计每个用户的已支付订单,并只保留数量不少于 3 的用户?
- 同一服务器的
443与8443两个 TCP 服务中,IP 地址与端口号分别起什么作用? - RAG 系统将向量模型从 E1 升级到维度不同的 E2 时,怎样不停机迁移索引并保留回滚能力?
- 检索资料与模型回答发生事实冲突时,怎样评价回答的事实一致性与引用覆盖?
- 移动端编辑器的撤销功能应该使用哪种数据结构?
单选题(二)(图像判断)
- 从彩色碎片图中辨认数字。
- 将三张相同内容的图片按对比度从低到高排序。
- 从色觉测试图中辨认两位数字。
- 从色觉测试图中辨认动物。
- 从色觉测试图中辨认数字。
- 从彩色碎片图中辨认几何形状。
- 从色觉测试图中辨认数字。
- 从彩色碎片图中辨认物体。
- 比较两张图片,判断哪张整体白平衡与氛围更冷。
编程题
- “没有闰月”:某人误把平年当成闰年,保留了
02/29,使三月及以后的日期偏移一天。输入若干个MM/DD日期,输出修正后的日期。
判定范围与结论
统一复核口径:本页现在以题干、选项含义和知识点为主;录屏中的勾选过程只作证据附注。原视频当前不在工作区,无法从关键帧恢复的选项会明确标注,不以悬停或瞬时高亮推断答案。
试卷由 20 道单选题(一)(40 分)、9 道单选题(二)(9 分)、2 道编程题(28 分)和 1 道 AI Coding(23 分)组成。现有材料存在以下边界:
- 单选题(一)的第 1~8 题只有“已答”状态,没有题干和最终选项画面,无法复核。
- 单选题(一)的第 9~20 题以及单选题(二)的 9 题均能确认最终提交选项。
- 没有展示官方答案、得分页或整卷交卷结果,以下答案是按题干和基础定义独立推导的高把握结论。
- 编程题只打开了第 1 题,编辑器仍是默认的两数求和模板;没有展示代码编写、运行或提交。第 2 道编程题和 AI Coding 未展示。
在 21 道可确认最终选项的题目中,发现 3 道明确错误:单选题(一)第 9、14 题,以及单选题(二)第 7 题;其余 18 题未发现错误。按题面分值估算,这 3 题共损失 5 分,但这不是整场笔试得分。
题目与选项复核清单
单选题(一)第 9~20 题
| 题号 | 题干目标 | 选项判断要点 | 参考答案 |
|---|---|---|---|
| 9 | 跨网络发送数据时网络层职责 | DNS 解析、线程调度、IP 路由、文件写入等选项区分层次 | 根据目标 IP 选择路径并逐跳转发 |
| 10 | 共享计数器避免丢失更新 | 无锁、不同 mutex、同一 mutex 覆盖读改写、只加 volatile 等 | 同一把锁保护完整读—改—写 |
| 11 | 一轮稳定冒泡排序后的序列 | 相等键是否交换决定稳定性;其余选项为不稳定交换或错误序列 | [(2,B),(3,A),(1,D),(3,C)] |
| 12 | 开放寻址查找槽位变多的原因 | 扩容、装载因子上升、删除标记、哈希函数变化等 | 装载因子升高导致探测变长 |
| 13 | 标准 I/O 写成功但他进程看不到 | 内核缓存、用户态 stdio 缓冲、权限、文件锁等 | 数据仍在用户态缓冲,需刷新 |
| 14 | 两事务余额丢失更新 | 普通事务、锁定读、写锁、乐观版本等 | SELECT ... FOR UPDATE 持锁到提交 |
| 15 | 无同步自增结果小于预期 | 原子自增、读改写竞态、volatile、线程创建失败等 | 使用 mutex/atomic 保证复合操作 |
| 16 | SQL 统计已支付订单且数量不少于 3 | WHERE、GROUP BY、HAVING 的位置组合 | WHERE status='paid' GROUP BY user_id HAVING COUNT(*)>=3 |
| 17 | 同一服务器不同 TCP 服务的 IP/端口 | IP 定位主机,目标端口选择服务,源端口通常是临时端口 | IP 相同、目标端口不同 |
| 18 | 向量模型换维度时无停机迁移 | 原索引直接混写、停机重建、E2 新索引双写回填灰度、删除旧索引等 | 新索引 + 双写回填 + 灰度切换 + 回滚 |
| 19 | RAG 资料与回答冲突的评价 | 只看引用标签、逐句支持/缺失/冲突、只看相似度等 | 区分支持、缺失和事实冲突 |
| 20 | 编辑器撤销数据结构 | 队列、栈、哈希表、堆等 | 栈(LIFO) |
单选题(二)图像判断
图像题的选项本身是图片或图案,关键帧只适合记录最终识别结果,无法把图像选项转成可靠文本。现有材料可复核的参考答案为:数字 816、对比度 (3)(1)(2)、数字 66、动物“牛”、数字 6、形状“圆形”、数字 5、物体“杯子”、冷色图“图(1)”。
明确错题
| 分区与题号 | 最终选择 | 建议答案 | 错因 |
|---|---|---|---|
| 单选题(一)第 9 题 | B:DNS 根据域名查询 IP | D:根据目标 IP 选择转发路径并逐跳转发 | DNS 属于应用层服务。网络层的核心对象是 IP 分组和跨网络路由;端口属于传输层,MAC 地址与数据帧属于数据链路层。 |
| 单选题(一)第 14 题 | D:把普通读取和写回放入同一事务即可 | A:读取余额时锁定目标行,并持锁到计算、写回和提交完成 | 这是丢失更新。普通 SELECT 即使位于事务内也可能读取快照,不能保护后续“基于旧值计算再写回”的完整链路。 |
| 单选题(二)第 7 题 | B:不知道 | D:5 | 图中异色圆点组成数字 5。选择“不知道”不是知识性错误,但在图案可辨认时会直接丢分。 |
已核对的正确选项
单选题(一)
| 题号 | 最终选择 | 核对结果 | 关键依据 |
|---|---|---|---|
| 10 | A | 正确 | 必须使用同一把互斥锁保护完整的“读—改—写”,原执行序列会丢失一次自增。 |
| 11 | C | 正确 | 一轮比较得到 [(2,B),(3,A),(1,D),(3,C)];相等键不交换,因此保持稳定。 |
| 12 | C | 正确 | 容量不变而元素增多会提高装载因子,冲突和探测序列通常变长。 |
| 13 | D | 正确 | 新内容仍在用户态标准 I/O 缓冲区中,尚未刷新到文件。 |
| 15 | D | 正确 | 自增是读—改—写复合操作,线程交错会造成更新丢失。 |
| 16 | A | 正确 | WHERE status = 'paid' 先筛行,GROUP BY user_id 再分组,HAVING COUNT(*) >= 3 最后筛组。 |
| 17 | A | 正确 | 目标 IP 定位主机,目标端口区分该主机上的服务;客户端源端口无需等于目标端口。 |
| 18 | A | 正确 | 新建 E2 版本索引、双写、全量回填、校验、灰度切流,并保留 E1 回滚。 |
| 19 | C | 正确 | 第一、三句有资料支持,第二句与“17:00 后下一工作日开始处理”冲突,检索标签本身不能消除事实冲突。 |
| 20 | D | 正确 | 撤销按最近一次尚未撤销的操作逆序执行,符合栈的 LIFO。 |
单选题(二)
| 题号 | 最终选择 | 建议答案 | 核对结果 |
|---|---|---|---|
| 1 | D:816 | D:816 | 正确 |
| 2 | B:(3)(1)(2) | B:(3)(1)(2) | 正确;对比度由低到高。 |
| 3 | D:66 | D:66 | 正确 |
| 4 | A:牛 | A:牛 | 正确 |
| 5 | C:6 | C:6 | 正确 |
| 6 | A:圆形 | A:圆形 | 正确 |
| 7 | B:不知道 | D:5 | 错误 |
| 8 | C:杯子 | C:杯子 | 正确 |
| 9 | A:图(1) | A:图(1) | 正确;图(1)整体色温更冷。 |
知识点回顾
网络分层:先判断“地址属于哪一层”
| 关键词 | 层次 | 作用 |
|---|---|---|
| 域名、DNS | 应用层 | 把名称解析为 IP 地址 |
| 端口、TCP/UDP | 传输层 | 区分主机上的通信端点或应用进程 |
| IP、路由、逐跳转发 | 网络层 | 在不同网络之间传送分组 |
| MAC、帧、同一链路 | 数据链路层 | 在一段本地链路上传送帧 |
第 9 题不需要背整套 OSI 模型,只要抓住“跨网络”“目标 IP”“转发路径”三个信号即可确定网络层职责。
临界区必须覆盖完整的读—改—写
错误做法是分别保护读取或写回:
text
T1 read 0
T2 read 0
T1 write 1
T2 write 1两次自增最终只留下 1。正确临界区必须由所有线程使用同一把锁,并覆盖共享值从读取到写回的全过程:
cpp
{
std::lock_guard<std::mutex> lock(count_mutex);
++count;
}不同互斥锁无法建立线程间互斥;只保证可见性也不能把复合操作变成原子操作。
一轮稳定冒泡排序
初始序列:
text
[(3,A), (2,B), (3,C), (1,D)]从左到右依次比较:
text
(3,A) 与 (2,B) 交换 → [(2,B), (3,A), (3,C), (1,D)]
(3,A) 与 (3,C) 不交换 → [(2,B), (3,A), (3,C), (1,D)]
(3,C) 与 (1,D) 交换 → [(2,B), (3,A), (1,D), (3,C)]“相等不交换”同时说明该排序在这个比较规则下保持稳定。
开放寻址哈希表与装载因子
装载因子为:
text
alpha = 已使用槽位数 / 槽位总数容量不变而元素增加时,空槽位减少,冲突后的探测更容易连续命中已占用槽位,所以成功和失败查找的平均探测次数都会上升。工程上应在装载因子达到阈值时扩容并重新散列,而不是接受不断增长的探测链。
标准 I/O 缓冲、刷新与持久化
fwrite、fprintf 等带缓冲接口成功返回,只说明数据已被标准 I/O 流接受;缓冲区未满且文件未关闭时,数据可能仍在用户态缓冲区。fflush(stream) 会把该流尚未写出的数据送到文件,定义可参考 POSIX fflush。
还要区分两个目标:
- 让其他进程能够读取新内容:刷新用户态缓冲是关键步骤。
- 保证掉电后仍然存在:还需要按系统语义调用
fsync等持久化接口;fflush本身不等于落盘保证。
数据库丢失更新与锁定读
第 14 题的错误链路是:两个事务都读取余额 100,分别计算 120 和 90,后提交的绝对值 90 覆盖了先提交的 120。单条 UPDATE 的行锁只能保护写语句执行期间,无法倒推保护此前的普通读取。
在必须保留“读取—业务计算—绝对值写回”流程时,应使用锁定读:
sql
START TRANSACTION;
SELECT balance
FROM account
WHERE id = ?
FOR UPDATE;
-- 使用读到的余额计算新值
UPDATE account SET balance = ? WHERE id = ?;
COMMIT;锁必须从读取一直持有到提交。MySQL 文档也明确说明:普通 SELECT 对“先查再改”保护不足,SELECT ... FOR UPDATE 会锁住读取到的记录,锁在提交或回滚时释放,见 InnoDB Locking Reads。如果业务允许改写处理方式,单条相对更新 UPDATE account SET balance = balance + ? 通常更简单;本题明确要求保留绝对值写回流程,因此应选锁定读。
SQL 的行级过滤、分组与组级过滤
目标 SQL 是:
sql
SELECT user_id, COUNT(*)
FROM orders
WHERE status = 'paid'
GROUP BY user_id
HAVING COUNT(*) >= 3;记忆执行意图即可:WHERE 过滤原始行,GROUP BY 形成分组,HAVING 根据聚合结果过滤组。聚合条件不能放在本题的 WHERE 中。
TCP 的主机、服务与连接标识
访问 203.0.113.10:443 和 203.0.113.10:8443 时:
- 两个连接的目标 IP 相同,因为服务器主机相同;
- 目标端口不同,用于选择服务器上的不同服务;
- 客户端通常为每条连接选择可用的临时源端口,无需使用
443或8443作为源端口。
TCP 首部独立包含源端口和目标端口,定义见 RFC 9293。判断此类题时不要把“客户端源端口”和“服务器监听端口”混为一谈。
向量模型升级:不同向量空间不能混查
E1 与 E2 的维度不同,向量既不能放进同一固定维度字段,也不能直接比较跨模型余弦相似度。安全迁移链路是:
text
建立 E2 版本索引
→ 新增/修改文档双写 E1 与 E2
→ 全量回填历史文档的 E2 向量
→ 校验数量、失败项和抽样检索质量
→ 按版本灰度切换查询流量
→ 观察稳定后停止 E1 写入
→ 保留 E1 一段时间用于快速回滚查询必须在单一向量空间内完成。若底层检索引擎支持索引别名,可用一次原子别名变更完成无停机切换;Elasticsearch 官方文档给出了 通过别名实时切换和无停机重建索引 的机制。
RAG 回答要验证“支持、缺失、冲突”
检索标签只表示系统把某段资料关联给某句话,不代表资料真的支持该断言。逐句检查时应分成三类:
- 支持:资料能够直接推出回答。
- 缺失:资料没有说明,不能把回答当成已证实事实。
- 冲突:资料明确给出相反规则,回答事实不一致。
第 19 题第二句声称“18:00 前提交都会当天开始处理”,而资料明确规定 17:00 后提交的常规请求到下一工作日才开始处理,因此属于冲突,不只是引用覆盖不足。
撤销功能使用栈
每次操作入栈,撤销时弹出最近一次尚未撤销的操作:
text
执行 A → push(A)
执行 B → push(B)
执行 C → push(C)
撤销 → pop() 得到 C如果题目继续要求“重做”,通常再增加一个 redo 栈;但本题只问撤销,选择栈即可,不需要引入双栈设计。
图像判断题的应试方法
- 对比度看同一画面中亮部与暗部的差值,不要只比较整体亮度;本题顺序为
(3)(1)(2)。 - 白平衡偏冷通常表现为蓝、青成分更明显,偏暖则更黄、橙;本题图(1)更冷。
- 碎片图和色觉图先寻找同色或近色区域的连续轮廓,再匹配数字、形状或物体,不要逐个碎片识别。
- 只有确实无法形成稳定轮廓时才选择“不知道”。第 7 题的异色点可以连成数字 5,过早放弃造成了 1 分损失。
编程题作答建议
“没有闰月”在现有材料中没有实际作答,因此不能评价代码正确性。若继续完成,建议先做两件事:
- 用题目样例明确“三月及以后偏移一天”对应日期序号应加一还是减一,禁止只凭中文语感决定方向。
- 把
MM/DD转为平年的年内序号,完成一天偏移后再按各月天数转换回MM/DD,统一使用两位补零输出。
由于样例输入输出没有展示,当前不写死偏移方向,也不声称已有可通过的实现。
本次回答中需要改进的地方
网络分层
- 问题:单选题(一)第 9 题把 DNS 解析选成网络层职责,混淆了应用层服务与 IP 路由。
- 改进:看到“域名”先归到 DNS/应用层;看到“目标 IP、跨网络、逐跳、路由”再归到网络层。用地址类型和处理对象判断,不靠模糊记忆。
并发事务
- 问题:第 14 题认为把读取和写回放入同一事务就能避免丢失更新,忽略了普通快照读不会自动锁住目标行。
- 改进:遇到“先读旧值—应用层计算—写回绝对值”,固定检查锁是否从读取阶段开始并持续到提交;若流程允许,再考虑原子相对更新或乐观锁版本号。
图像题
- 问题:单选题(二)第 7 题在目标数字可辨认时选择了“不知道”。
- 改进:先按颜色分组看整体轮廓,分别检查上横、左竖、中横、右下和下横;这些结构能组成 5。给图像题预留一次整体复查,避免因第一眼不清晰直接放弃。
编程题进度
- 问题:材料结束时,编程题第 1 题仍停留在默认两数求和模板,未展示任何实现或测试;后续编程题和 AI Coding 也未展示。
- 改进:进入编程题后先在 2~3 分钟内写出日期序号转换框架,并立即用月底、
02/28、03/01、12/31等边界构造自测。当前实现与正确性均未验证。