同元软控 C++ 开发实习面经:多态、智能指针与 LRU
- 轮次
- 一面+HR面
- 结果
- 等待结果
- 时间
- 2026-10
- 来源
- 牛客网
《面试题目》
一面(技术面)
- 请做一下自我介绍。
- 谈谈你对多态的理解。
- 谈谈你对指针的认识。
- 智能指针的大小是多少?
- 迭代器失效的场景有哪些?
- C 语言的编译流程是怎样的?
- 你用过哪些 STL 容器?各自适用什么场景?
- 虚函数表存放在哪里?动态多态是如何通过虚函数表实现的?
- 分析一段智能指针实例代码,指出其中存在的问题。
- 手写 LRU 缓存的实现。
二面(HR 面)
- 请做一下自我介绍。
- 请介绍你的实习经历及主要收获。
- 你什么时候可以入职?
- 未来 3—5 年的职业发展方向是什么?
- 你的期望薪资是多少?
- 你有什么想问的?
《参考解析》
多态要分编译期和运行期。 函数重载、模板、CRTP 属于静态多态,编译器在编译期决定调用哪个实现,没有运行期开销;虚函数属于动态多态,对象里通常有一个 vptr 指向类的虚函数表,调用时通过表项间接跳转。虚函数表通常放在只读数据段,每个类一份,不是每个对象一份;对象里存的是指向表的指针。构造函数不能是虚函数,因为对象还没构造完、vptr 还没建立;基类析构必须是虚函数,否则通过基类指针删除派生对象时,派生类的析构不会执行。回答时可以把“虚表在哪里、vptr 什么时候设置、多继承怎么调整 this 指针”一起讲,深度就出来了。
智能指针的大小取决于实现。 unique_ptr 通常和一个裸指针一样大,但如果带自定义删除器,可能更大;shared_ptr 通常是两个指针(对象指针 + 控制块指针),控制块里放强引用计数、弱引用计数、删除器和分配器。make_shared 可以把对象和控制块一次分配,减少一次内存分配,但会让弱引用延长整块内存的生命周期。常见代码问题包括循环引用导致泄漏、用同一个裸指针构造两个 shared_ptr 导致二次释放、把 this 直接交给 shared_ptr、以及自定义删除器与数组类型不匹配。排查时先画所有权图,再决定用 unique_ptr、shared_ptr 还是 weak_ptr。
迭代器失效要按容器和操作分别记。 vector 在扩容时所有迭代器、指针、引用失效,erase 会让被删位置之后的迭代器失效;deque 在中间插入删除时失效规则更复杂;list/map/set 的插入通常不影响其他迭代器,但 erase 只让被删元素的迭代器失效。map 的 operator[] 可能插入新元素,erase 后要继续遍历要用返回的迭代器。回答时不要只背“vector 会失效”,要说明为什么:连续存储 + 重新分配。
LRU 的标准实现是哈希表 + 双向链表。 哈希表存 key 到链表节点的映射,链表头放最近使用、尾放最久未使用;get 命中后把节点移到头部,put 新键时如果超容量就删尾节点并同步删哈希表,更新已有键也要移到头部。所有操作 O(1)。边界要处理容量为 0、重复 put、get 未命中;线程安全版本要加锁,或者用分片降低锁竞争。手写时先定义节点结构,再写 remove/insertFront/moveToFront 三个辅助函数,代码会清楚很多。
HR 面重点确认稳定性和到岗时间。 实习经历讲清你做了什么、学到什么、为什么适合 C++ 开发;职业规划可以说短期补齐工程能力、中期独立负责模块、长期往系统设计或性能优化走。薪资先了解当地实习行情,给一个合理区间,别把实习薪资当成正式薪资来谈。反问可以问团队的技术栈、新人培养和转正机制。