Skip to content

OPPO 多媒体开发 C++ 线上笔试复盘 ​

面试官提问清单 ​

单选题(一)(现有材料可完整复核的第 9~20 题) ​

  1. 跨网络发送数据时,网络层承担什么职责?
  2. 两个线程对共享计数器执行“读—加一—写回”时,如何避免更新丢失?
  3. 对带相同键值的记录执行一轮稳定冒泡排序后,序列如何变化?
  4. 开放寻址哈希表容量不变、键值对增多时,平均查找槽位为什么变多?
  5. 带缓冲的标准 I/O 写日志成功返回后,为什么另一个进程暂时看不到文件尾部的新内容?
  6. 两个事务基于同一个旧余额计算并写回绝对值,为什么会得到错误余额,应该怎样加锁?
  7. 两个线程无同步地各执行 1000 次自增,为什么结果可能小于 2000?
  8. SQL 如何统计每个用户的已支付订单,并只保留数量不少于 3 的用户?
  9. 同一服务器的 443 与 8443 两个 TCP 服务中,IP 地址与端口号分别起什么作用?
  10. RAG 系统将向量模型从 E1 升级到维度不同的 E2 时,怎样不停机迁移索引并保留回滚能力?
  11. 检索资料与模型回答发生事实冲突时,怎样评价回答的事实一致性与引用覆盖?
  12. 移动端编辑器的撤销功能应该使用哪种数据结构?

单选题(二)(图像判断) ​

  1. 从彩色碎片图中辨认数字。
  2. 将三张相同内容的图片按对比度从低到高排序。
  3. 从色觉测试图中辨认两位数字。
  4. 从色觉测试图中辨认动物。
  5. 从色觉测试图中辨认数字。
  6. 从彩色碎片图中辨认几何形状。
  7. 从色觉测试图中辨认数字。
  8. 从彩色碎片图中辨认物体。
  9. 比较两张图片,判断哪张整体白平衡与氛围更冷。

编程题 ​

  1. “没有闰月”:某人误把平年当成闰年,保留了 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 保证复合操作
16SQL 统计已支付订单且数量不少于 3WHERE、GROUP BY、HAVING 的位置组合WHERE status='paid' GROUP BY user_id HAVING COUNT(*)>=3
17同一服务器不同 TCP 服务的 IP/端口IP 定位主机,目标端口选择服务,源端口通常是临时端口IP 相同、目标端口不同
18向量模型换维度时无停机迁移原索引直接混写、停机重建、E2 新索引双写回填灰度、删除旧索引等新索引 + 双写回填 + 灰度切换 + 回滚
19RAG 资料与回答冲突的评价只看引用标签、逐句支持/缺失/冲突、只看相似度等区分支持、缺失和事实冲突
20编辑器撤销数据结构队列、栈、哈希表、堆等栈(LIFO)

单选题(二)图像判断 ​

图像题的选项本身是图片或图案,关键帧只适合记录最终识别结果,无法把图像选项转成可靠文本。现有材料可复核的参考答案为:数字 816、对比度 (3)(1)(2)、数字 66、动物“牛”、数字 6、形状“圆形”、数字 5、物体“杯子”、冷色图“图(1)”。

明确错题 ​

分区与题号最终选择建议答案错因
单选题(一)第 9 题B:DNS 根据域名查询 IPD:根据目标 IP 选择转发路径并逐跳转发DNS 属于应用层服务。网络层的核心对象是 IP 分组和跨网络路由;端口属于传输层,MAC 地址与数据帧属于数据链路层。
单选题(一)第 14 题D:把普通读取和写回放入同一事务即可A:读取余额时锁定目标行,并持锁到计算、写回和提交完成这是丢失更新。普通 SELECT 即使位于事务内也可能读取快照,不能保护后续“基于旧值计算再写回”的完整链路。
单选题(二)第 7 题B:不知道D:5图中异色圆点组成数字 5。选择“不知道”不是知识性错误,但在图案可辨认时会直接丢分。

已核对的正确选项 ​

单选题(一) ​

题号最终选择核对结果关键依据
10A正确必须使用同一把互斥锁保护完整的“读—改—写”,原执行序列会丢失一次自增。
11C正确一轮比较得到 [(2,B),(3,A),(1,D),(3,C)];相等键不交换,因此保持稳定。
12C正确容量不变而元素增多会提高装载因子,冲突和探测序列通常变长。
13D正确新内容仍在用户态标准 I/O 缓冲区中,尚未刷新到文件。
15D正确自增是读—改—写复合操作,线程交错会造成更新丢失。
16A正确WHERE status = 'paid' 先筛行,GROUP BY user_id 再分组,HAVING COUNT(*) >= 3 最后筛组。
17A正确目标 IP 定位主机,目标端口区分该主机上的服务;客户端源端口无需等于目标端口。
18A正确新建 E2 版本索引、双写、全量回填、校验、灰度切流,并保留 E1 回滚。
19C正确第一、三句有资料支持,第二句与“17:00 后下一工作日开始处理”冲突,检索标签本身不能消除事实冲突。
20D正确撤销按最近一次尚未撤销的操作逆序执行,符合栈的 LIFO。

单选题(二) ​

题号最终选择建议答案核对结果
1D:816D:816正确
2B:(3)(1)(2)B:(3)(1)(2)正确;对比度由低到高。
3D:66D:66正确
4A:牛A:牛正确
5C:6C:6正确
6A:圆形A:圆形正确
7B:不知道D:5错误
8C:杯子C:杯子正确
9A:图(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 回答要验证“支持、缺失、冲突” ​

检索标签只表示系统把某段资料关联给某句话,不代表资料真的支持该断言。逐句检查时应分成三类:

  1. 支持:资料能够直接推出回答。
  2. 缺失:资料没有说明,不能把回答当成已证实事实。
  3. 冲突:资料明确给出相反规则,回答事实不一致。

第 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 分损失。

编程题作答建议 ​

“没有闰月”在现有材料中没有实际作答,因此不能评价代码正确性。若继续完成,建议先做两件事:

  1. 用题目样例明确“三月及以后偏移一天”对应日期序号应加一还是减一,禁止只凭中文语感决定方向。
  2. 把 MM/DD 转为平年的年内序号,完成一天偏移后再按各月天数转换回 MM/DD,统一使用两位补零输出。

由于样例输入输出没有展示,当前不写死偏移方向,也不声称已有可通过的实现。

本次回答中需要改进的地方 ​

网络分层 ​

  • 问题:单选题(一)第 9 题把 DNS 解析选成网络层职责,混淆了应用层服务与 IP 路由。
  • 改进:看到“域名”先归到 DNS/应用层;看到“目标 IP、跨网络、逐跳、路由”再归到网络层。用地址类型和处理对象判断,不靠模糊记忆。

并发事务 ​

  • 问题:第 14 题认为把读取和写回放入同一事务就能避免丢失更新,忽略了普通快照读不会自动锁住目标行。
  • 改进:遇到“先读旧值—应用层计算—写回绝对值”,固定检查锁是否从读取阶段开始并持续到提交;若流程允许,再考虑原子相对更新或乐观锁版本号。

图像题 ​

  • 问题:单选题(二)第 7 题在目标数字可辨认时选择了“不知道”。
  • 改进:先按颜色分组看整体轮廓,分别检查上横、左竖、中横、右下和下横;这些结构能组成 5。给图像题预留一次整体复查,避免因第一眼不清晰直接放弃。

编程题进度 ​

  • 问题:材料结束时,编程题第 1 题仍停留在默认两数求和模板,未展示任何实现或测试;后续编程题和 AI Coding 也未展示。
  • 改进:进入编程题后先在 2~3 分钟内写出日期序号转换框架,并立即用月底、02/28、03/01、12/31 等边界构造自测。当前实现与正确性均未验证。

使用 Markdown 与 VitePress 构建