面灵AI→

拼多多客户端提前批一面到HR面:Kotlin协程与C++内存

轮次
一面+二面+三面+HR面
时间
2026-10
来源
牛客网

《面试题目》

一面

  1. Kotlin 为什么好用?
  2. 协程和线程是什么关系?
  3. 两个线程对同一个数字分别执行若干次自增,最后的结果是否固定?如果希望结果固定,应该怎么处理?
  4. Feed 的数据加载、缓存与页面复用是怎么做的?
  5. 如何判断 UI 是否流畅?
  6. 如何查看后端接口返回的内容?
  7. HTTPS/TLS 是如何防止中间人攻击的?
  8. 手撕:给定一个只包含整数、加减符号和括号的数学表达式字符串及其长度,计算该表达式的结果。

二面 · C/C++ 与内存

  1. 写一个能得到 1 + 100 = 101 的简单程序或表达式。
  2. sum 变量存放在哪里?
  3. 可以在堆上再构造一个 int 吗?
  4. 指针的大小是多少?
  5. 1.1 + 2.1 == 3.2 是否成立?为什么?
  6. 动态库和静态库有什么区别?
  7. 堆和栈有什么区别?
  8. 线程拥有怎样的独立空间?

二面 · 操作系统与并发

  1. 线程栈是独立的吗?
  2. 多线程场景下怎样加锁?
  3. CPU 可以执行多线程吗?
  4. 单核 CPU 可以执行多线程吗?
  5. 中断是什么?

二面 · 网络与数据库

  1. HTTP 是怎样被劫持的?
  2. 光纤怎样传输信号?
  3. 事务是什么?

二面 · 算法

  1. 快速排序怎么实现?
  2. 最长回文子串怎么求?

二面 · AI 与项目开放题

  1. 什么是 AI 幻觉?
  2. 国内有哪些主要的 AI 公司或模型?
  3. 国外有哪些主要的 AI 公司或模型?
  4. 你自己做过的东西里,哪个项目最满意?
  5. 这个项目遇到了什么问题?你是怎样处理的?

三面

  1. 介绍一下你的实习经历,做了什么、有什么收获?
  2. 手撕:简单实现一个缓存框架。
  3. 你在项目里承担什么角色(ownership)?项目是怎么迭代的?
  4. 你了解 A/B 实验吗?该怎么设计和评估一次实验?

《参考解析》

Kotlin、协程与客户端基础。 Kotlin 的「好用」主要来自空安全(可空类型在编译期拦住 NPE 高发路径)、扩展函数、data class、默认参数与更简洁的 lambda,以及协程被做成一等公民;代价是产物要带上 kotlin-stdlib、与 Java 混编时有心智成本。协程不是线程的替代品,而是跑在线程之上的可挂起任务:suspend 函数在挂起点把状态存进 Continuation 后让出线程,恢复时再由调度器丢回某个线程执行,所以一个线程能承载成千上万个协程,而阻塞式 sleep 会真的占住线程。Feed 这类长列表通常按「分页拉取 + 内存 LRU 缓存 + 请求去重与随生命周期取消 + 视图复用与 diff 局部刷新 + 图片多级缓存和预取」来做,核心是别在主线程做重活、也别让离屏请求回来乱改数据。判断 UI 是否流畅,除了肉眼滑动,更要看帧耗时分布:Android 侧可以用 Choreographer/FrameMetrics、JankStats 或 Perfetto 抓掉帧,关注 P95/P99 帧耗时而不是平均值,超过帧预算(60Hz 约 16.6ms)就会掉帧。要看后端返回了什么,常见做法是 okhttp Interceptor 打日志、抓包代理(Charles/Fiddler 装证书)或 Studio 的 Network Inspector。

并发与内存:自增为什么不固定、堆栈与线程空间。 count++ 是「读—改—写」三步,不是原子操作,两个线程交叉执行就会丢更新,所以结果不固定且只会小于等于预期值;要固定就必须互斥或原子化——加锁(synchronized/ReentrantLock)、用 AtomicInteger 的 CAS,或在高竞争下换 LongAdder 分摊热点。只加 volatile 不够,它保证可见性和顺序但不保证复合操作原子,这是这道题埋的坑。内存那组题的关键是先分清作用域再回答:局部 sum 在栈上(也可能被优化进寄存器),全局/静态变量在数据段(.data/.bss),字符串字面量在只读段;堆上当然能再 new 一个 int,区别是生命周期要自己管、要配对释放。指针大小跟平台有关,32 位 4 字节、64 位 8 字节;1.1 + 2.1 == 3.2 不成立,因为 IEEE 754 二进制浮点无法精确表示 0.1 这类十进制小数,正确做法是用误差阈值比较或改用十进制类型。堆与栈的差别在分配方式、生命周期、大小上限和碎片;线程之间共享代码段、数据段和堆,各自私有栈、寄存器上下文和线程局部存储,这也解释了「线程栈独立吗」——独立,且栈大小限制了单线程的递归深度。

网络、数据库与手撕题。 HTTPS 防中间人的链条是:握手用非对称或 ECDHE 协商出对称密钥并做前向保密,客户端通过受信任 CA 的证书链和域名校验确认对面身份,之后的报文用 AEAD 校验,篡改会直接被发现;能解开的前提是客户端自己信任了攻击者的根证书(用户装了代理证书),所以 App 还会做证书固定。明文 HTTP 没有这层保护,常见劫持手段是 ARP/DNS 欺骗和链路侧的内容注入,HSTS 与 DoH/DoT 分别缓解这两类。光纤用全内反射把光信号约束在纤芯里传播,电信号先转成光、用强度或相位调制编码 0/1,接收端再由光电探测器还原,波分复用让一根纤里同时跑多个波长。事务是一组要么全成功要么全失败的操作,靠 undo log 回滚、redo log 保证持久、锁与 MVCC 提供隔离,答题时把 ACID 和隔离级别对应的并发异常串起来说更完整。手撕三题里,表达式求值的稳妥写法是递归下降或双栈:按「表达式 → 项 → 因子」分层,遇到左括号递归进去、右括号返回,别把嵌套括号拍平;快速排序要能口述分治与 pivot 分区,并主动提随机化 pivot 防有序输入退化成 O(n²);最长回文子串用中心扩展写起来最短(O(n²) 时间、O(1) 空间),补一句 Manacher 可以做到 O(n) 就够。

开放题、项目与流程环节。 AI 幻觉指模型生成读起来合理但没有事实依据的内容,成因是自回归按概率续写、训练数据噪声与知识过时、以及对齐带来的迎合倾向;答题时给一条缓解路径(检索增强并给出处、约束输出格式、关键结论人工复核)比只背定义更有说服力。被问「国内/国外有哪些模型」时,如实报出主流几家的名字和大致定位即可,不确定的别硬编。项目题按「背景—我的职责(ownership)—难点与取舍—量化结果—复盘」讲,面试官会顺着追问三层,重点是他听到你亲手做了什么、踩过什么坑。三面的缓存框架手撕除了 get/put,最好主动补容量上限与淘汰策略(LRU/LFU)、并发安全、TTL 和命中率统计,这些都是面试官会继续追的点;A/B 实验则要讲清分流与对照组、样本量与显著性、北极星指标与护栏指标,别偷看数据提前下结论。HR 面(原帖只记了 9.22 这个时间,没留问题)筛的是稳定性、动机匹配与薪资预期:准备好一句话自我介绍、为什么选这家、职业规划、期望薪资区间,以及在手 offer 的情况,口径一致就不会翻车。