校招 未知部门 / 后端-C++ / 一面
[面试日期] 2026-09-08 [面试时长] 未知
[学校背景] 浙江大学 | 985 [学历背景] 未知
[发布人] 面试之星官方收录
<h2>百度 C++后端开发 一面面经</h2>
<h1>1. 虚函数表在单继承下如何布局?通过基类指针调用虚函数的完整过程是什么?</h1>
<ol>
<li>对象里通常有一个虚表指针,指向该类的虚函数表。</li>
<li>虚表里按声明顺序存放虚函数地址;派生类重写时,对应表项替换为派生类函数。</li>
<li>通过基类指针调用时,先取对象的虚表指针,再按偏移取函数地址并调用。</li>
<li>因此实际调用取决于对象的动态类型,而不是指针的静态类型。</li>
<li>构造期间虚表可能尚未切到最派生类,构造函数里调虚函数通常不会落到派生类实现。</li>
</ol>
<h1>2. 右值引用和移动构造解决什么问题?什么情况下移动不会发生?</h1>
<ol>
<li>右值引用绑定即将销毁的临时对象,允许资源“偷走”而不是深拷贝。</li>
<li>移动构造/移动赋值通常转移指针所有权,并把源对象置空,降低大对象传递成本。</li>
<li><code>std::move</code> 只是转换成右值引用,真正移动取决于是否有可用的移动函数。</li>
<li>源类型无移动构造、移动被删除,或成员不可移动时,会退化为拷贝。</li>
<li>const 对象、需要保留原对象有效状态的场景,也不该依赖移动语义。</li>
</ol>
<h1>3. <code>std::mutex</code>、<code>std::recursive_mutex</code>、<code>std::shared_mutex</code> 怎么选?</h1>
<ol>
<li><code>mutex</code> 适合绝大多数互斥临界区,同一线程不可重复加锁。</li>
<li><code>recursive_mutex</code> 允许同一线程重入加锁,但容易掩盖调用栈设计问题,优先重构避免。</li>
<li><code>shared_mutex</code> 适合读多写少:共享锁并行读,独占锁串行写。</li>
<li>锁粒度要小,持锁时间要短,避免在锁内做耗时 IO。</li>
<li>多锁时固定加锁顺序,降低死锁概率。</li>
</ol>
<h1>4. 内存序里 <code>memory_order_relaxed</code> 和 <code>acquire/release</code> 差异是什么?什么时候必须更强?</h1>
<ol>
<li><code>relaxed</code> 只保证原子变量自身读写原子性,不提供跨线程同步关系。</li>
<li><code>release</code> 与配对的 <code>acquire</code> 能建立 happens-before,让释放前的写对获取后可见。</li>
<li>做“发布指针/标志位,另一边读取后使用其指向数据”时,常用 release/acquire。</li>
<li>只做计数、统计且不依赖周围数据可见性时,可用 <code>relaxed</code>。</li>
<li>需要双向同步或更强全局顺序时,才考虑 <code>seq_cst</code>,但它通常更贵。</li>
</ol>
<h1>5. 用户态线程切换和进程切换,开销差在哪里?</h1>
<ol>
<li>线程切换主要换寄存器、栈、线程私有状态,地址空间通常不变。</li>
<li>进程切换还要切换页表/地址空间,TLB 失效成本更高。</li>
<li>同进程线程共享堆、全局数据、文件描述符表等,通信更轻,但同步更复杂。</li>
<li>高并发网络服务常用多线程或线程池,减少进程切换与 IPC 成本。</li>
<li>隔离性、崩溃互不影响、权限边界更强时,才更倾向多进程。</li>
</ol>
<h1>6. 页面故障(page fault)分哪几类?对后端服务延迟意味着什么?</h1>
<ol>
<li>缺页可能是首次访问未映射页、换出页调入,或非法访问导致信号/崩溃。</li>
<li>匿名页第一次写时常触发写时分配;文件映射可能从磁盘读入。</li>
<li>频繁 majfault 往往伴随磁盘 IO,尾延迟会明显变差。</li>
<li>服务启动后预热、控</li>
</ol>
AI 推荐面试题
