面经 csig_0309
面经
C++的智能指针你用过吗?(主要使用过shared_ptr、weak_ptr、unique_ptr)C++里面总共有多少种智能指针?每一种的用法和应用场景是什么?(三种)unique_ptr:- 定义:表示对所拥有的对象的独占权,一个对象只能被一个
unique_ptr拥有 - 特点:只可以移动,不可以被复制,经常配合
std::move来使用;
- 定义:表示对所拥有的对象的独占权,一个对象只能被一个
shared_ptr:- 定义:表示对所拥有的对象的共享权,一个对象可以被多个
shared_ptr拥有; - 特点:需要维持一个控制块,来进行引用计数;
- 定义:表示对所拥有的对象的共享权,一个对象可以被多个
weak_ptr:- 定义:不拥有对象,但是
weak_ptr可以观察shared_ptr所拥有的对象; - 特点:解决循环依赖问题;作为缓存对象;
- 定义:不拥有对象,但是
C++在main函数执行之前,还有哪些函数会先执行?main之前通常会先执行运行时启动代码,然后完成 全局变量、静态变量的初始化。- 如果这些对象是 类类型,就会 先调用它们的构造函数;
- 如果它们的初始化表达式里调用了普通函数,这些函数也会在
main前执行。 - 程序真正的入口一般不是
main,而是像_start这样的运行时入口函数。 static局部变量不属于这个阶段,它是在第一次执行到时才初始化。
如果
const加在成员函数后面,它的作用是什么?- 防止成员函数修改成员变量的状态,也不能调用非
const成员函数 - 本质上是把
this指针变成了指向const对象的指针。这样既能保证函数是只读操作,也能让const对象调用这个函数。
- 防止成员函数修改成员变量的状态,也不能调用非
如果一个链表里有环,怎么判断它有没有环?(通过快慢指针)
UDP你了解吗?(UDP是一种无连接、不可靠、面向数据报、开销小、传输效率高的传输层协议)
UDP相比TCP主要是不可靠传输,如果让UDP尽量保证可靠,你觉得可以怎么做?- 如果想让
UDP尽量可靠,本质上就是在应用层自己实现一套可靠传输机制。通常会加上 序列号、ACK确认、超时重传、乱序重排、重复包去重,再进一步配合 滑动窗口、流量控制 和 拥塞控制。这样虽然底层还是UDP,但上层可以做出类似TCP的可靠效果。
- 如果想让
为什么不直接用
TCP?- 因为有些场景更看重 低延迟和灵活控制。
TCP虽然可靠,但它的 超时重传、拥塞控制、队头阻塞 等机制有时会影响实时性。基于UDP在应用层自己实现可靠传输,可以按业务需求选择 “全可靠” 还是 “部分可靠”,更灵活。
- 因为有些场景更看重 低延迟和灵活控制。
某些场景里不要求完全可靠,只要求一两秒内能到,超过时间就算了,这种 半可靠场景 你有了解吗?
- 这类场景我理解为半可靠或者时效性优先的传输。它不是要求所有数据最终都到,而是要求数据在有效时间窗口内到达,超时就没有价值了,比如 音视频、直播、游戏状态同步。
- 实现上 一般会给数据加 序列号 和 时间戳,只在
deadline内做有限重传,过期包直接丢弃;同时对不同类型的数据分级,关键控制消息走可靠传输,高频状态消息走半可靠传输。
FEC了解吗?FEC是指 前向纠错(Forward Error Correction),发送方在原始数据之外,额外发送一些冗余校验数据,这样接收方即使丢了一部分包,也有机会自己恢复出来,而不用等重传。
P2P打洞这块,如果两端都是对称NAT,应该怎么处理?- 使用中继服务器
平时用过抓包工具吗?
Linux服务器上我一般用tcpdump抓包,因为它轻量、命令行方便;- 抓下来的
pcap文件再放到Wireshark里做详细分析,进行排查相关问题;
自旋锁是怎么实现的?(
spinlock)- 用 原子操作 去竞争一个锁变量,比如通过
CAS或exchange把锁状态从 未加锁 改成 已加锁; - 如果修改成功,线程进入临界区;
- 如果修改失败,说明锁被其他线程持有,当前线程不会睡眠,而是一直循环重试,直到锁被释放;
- 优点:避免线程阻塞和上下文切换,适合临界区非常短的场景;
- 缺点:持续占用
CPU,如果锁持有时间长或者竞争激烈,就会浪费很多CPU资源;
- 用 原子操作 去竞争一个锁变量,比如通过
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 GYu的妙妙屋!
