腾讯搜狗输入法秋招二面面经:智能指针、lambda 与字符串大整数乘法
- 轮次
- 二面
- 时间
- 2026-10
- 来源
- 牛客网
《面试题目》
- 智能指针的使用场景有哪些?
- lambda 表达式的使用场景有哪些?和函数指针相比性能怎么样?什么时候函数指针快、什么时候 lambda 表达式快?
- 手撕算法:字符串大整数乘法。
- 平时做需求时,怎么保证 AI 写代码的输出可靠?
- 怎么设计测试用例?
- 平时用 Agent 有遇到过什么问题?
- 你认为 AI 之后会不会完全取代程序员?人以后在什么场景能起作用?
《参考解析》
智能指针:三种语义对应三类所有权。 unique_ptr 表达独占所有权,不可拷贝只可移动,几乎零开销,是默认选择——工厂函数返回值、资源句柄(文件、socket、COM 对象)都该用它,并用自定义删除器适配非 delete 的释放方式。shared_ptr 表达共享所有权,靠控制块里的引用计数在最后一个持有者析构时释放,代价是控制块的内存与原子计数开销(多线程下是原子操作,单线程场景可能成为热点),而且要注意 make_shared 把对象和控制块一次分配、缓存更友好,但会延长对象内存的存活时间到弱引用清零。weak_ptr 用来打破循环引用(父子互指、观察者、缓存),使用前必须 lock() 提升为 shared_ptr 再判空,不能直接解引用。面试里可以补两个真实场景:回调注册用 weak_ptr 防止对象已销毁仍被回调(enable_shared_from_this 也是同一类问题);需要共享所有权但又要避免长生命周期泄漏时,weak_ptr 做缓存条目。注意智能指针只解决内存与所有权,不解决并发访问的数据竞争,也不该跨模块 ABI 边界随手传(shared_ptr 的实现细节会带来兼容问题)。
lambda 与函数指针:差在类型擦除与内联机会。 lambda 是一个匿名的闭包类型,捕获列表决定它持有什么状态、是否可拷贝,编译器为每个 lambda 生成独立的 operator(),因此调用点通常是直接调用并可被内联——这是它比函数指针快的根本原因(函数指针是间接调用,编译器一般无法内联跨指针的目标,也容易打断指令流水与优化)。lambda 的典型使用场景是标准算法的谓词、一次性回调、需要捕获上下文的异步任务、以及 sort 的自定义比较等;函数指针则适合无状态的简单回调、C 接口与跨语言边界、以及需要把回调存成统一类型注册进表里的场景。无捕获的 lambda 可以隐式转换为函数指针,代价是丢掉内联机会;而 std::function 是类型擦除容器,会带来一次间接调用与可能的堆分配(捕获大对象时),能在模板里直接用泛型参数就别为了统一类型过早包成 std::function。回答「什么时候函数指针更快」可以说清三个条件:调用点无法被内联(比如跨编译单元、通过外部注册表调用)、闭包捕获导致额外的间接寻址、以及需要把回调存进固定 ABI 的接口时省掉 std::function 的擦除开销。
字符串大整数乘法:竖式模拟,注意前导零与符号。 思路是把两个字符串转成数字数组(低位在前),用结果数组 res[i+j+1] 累加 a[i]*b[j],随后统一处理进位,最后去掉前导零并处理符号与零值。时间复杂度 O(n·m),空间 O(n+m)。写的时候有四个容易扣分的点:进位要在累加后统一处理(边乘边进位容易错位)、下标从后往前对齐、结果是 "0" 的边界(输入含 0 或全零)、负数与正负号规则。如果面试官追问优化,可以提 Karatsuba 分治(约 O(n^1.585))以及它的适用前提(位数足够大、常数因子才划算),但不要为了炫技在 20 分钟里手写一个容易错的 Karatsuba——先把竖式写对并自测几组用例(0×0、9×9、长度不等、带进位链)更实在。
怎么保证 AI 写出来的代码可靠:靠流程而不是靠自己多看两眼。 有效做法是先切小步:把需求拆成可独立验证的单元,一次只生成一小块,每块都有明确的验收条件;再用机器判据兜底——类型检查、lint、单测、真实数据的端到端跑通,尤其要覆盖边界与异常分支(空值、越界、并发、超时)。人工审查的重点放在 AI 容易出错的地方:不存在的 API 与库用法(幻觉调用)、错误处理被吞掉、循环边界与资源释放、以及「测试通过但业务语义错」这类问题,所以关键路径上的改动自己要能讲清每一行的意图。另外要把约束写进上下文(既有代码风格、禁止引入的依赖、必须复用哪个工具函数),并且在提交与回滚上留后路:小步提交、可回滚、改动可追溯。原帖问的其实是「你怎么防止 AI 把不稳定的东西带进主干」,把上面这套流程说成习惯而非口号,比表态「我会仔细检查」可信得多。
测试用例设计、Agent 使用中的问题、以及 AI 与程序员的关系。 设计用例的通用框架是:先按等价类划分有效与无效输入,再针对每个划分补边界值(最小、最大、刚好越界),加上场景与状态流转用例(正常路径、异常中断、重复操作、并发),最后按风险排优先级并说明哪些用自动化覆盖、哪些靠人工探索。用 Agent 过程中常见的问题可以照实说:上下文一长就开始遗忘前面的约束、会重复调用同一个工具、把没验证的结果报成完成、以及参数拼装层反复出错;对应的处理是缩小上下文、给工具调用加去重与最大步数、把「没观测到成功就记失败」写成硬规则、危险动作前加人工确认。关于「AI 会不会取代程序员」,比较有说服力的答法是分层看:明确的、可验证的、有大量先例的编码工作正在被压缩;难被替代的是三件事——把模糊的业务目标翻译成可验证的需求、在信息不全时做取舍与决策、以及对结果负责(上线、回滚、事故兜底)。所以人的位置会从「写代码」更多转向「定义问题、设计约束、验收结果」,这也是面试官真正想听的态度。