0820-小厂一面面经,音视频岗(上)
- 引用与指针的区别?最主要是作为函数参数时,引用用来解决什么问题?
- 虚函数的机制?虚函数表是否全局唯一?虚函数表存在那内存那个区域?
- 堆和栈的区别?分配效率为什么栈快?
- 堆的内存管理机制?new 1个G的数组,什么情况下会报错?
- 怎么查看项目进程中是否存在内存泄露问题?
- 内存池的设计?
- TCP中socket编程中客户端与服务端调用的API?
- 为什么TCP可靠?讲述下TCP中的拥塞控制原理?滑动窗口?
- 线程同步的机制?信号量的底层实现原理?
- 怎么实现UDP可靠,可靠UDP与TCP的本质区别?可靠UDP的场景?
- HTTP3.0是否了解,简单讲下?
- 讲下HDR原理?
- H264的底层原理?SEI是什么?
- H264和H265的区别是什么?
- AAC的数据结构?adts头的详细信息?
答案(自我总结)
- (1)定义与初始化的区别(指针是变量,存储另一个变量的内存地址,可以被初始化nullptr;引用变量的别名,必须在定义时初始化且不能指向空值);(2)内存地址;(3)可修改性与多级间接访问区别;避免不必要的内存拷贝,也比指针更安全;指针传递参数本质上是值传递,所传递的是一个地址值;在引用传递时,也会在栈中开辟内存空间,但存放的是由主调函数放进来的实参变量的地址,在操作时需要间接访问;
- 虚函数表存放在常量区,虚函数存放在代码区;虚函数表是一个存储类中所有虚函数地址的数组,只要类中声明了virtual函数(包括继承自父类的虚函数),编译器就会该类生成唯一的vtable,属于类级别的数据结构;当子类重写父类的虚函数时,子类的虚函数表中会用自身的虚函数地址覆盖父类对应虚函数的地址;调用虚函数时,程序通过对象的 vptr 找到所属类的 vtable,再根据函数在表中的索引找到具体函数地址并调用,从而实现 “运行时绑定”。
- (1) 申请速度快:栈是运行前就已经分配好的空间,堆是运行时动态申请的;(2)存储寻址速度快:栈的物理地址空间是连续的,而堆未必,查找堆的链表也会耗费较多时间,所以存储寻址速度慢;(3)CPU硬件操作系统快:cpu有专门的寄存器(esp, ebp)来操作栈,堆是使用间接寻址的;
- 堆内存的分配和释放是动态且无序的,为了跟踪哪些内存块是空闲的,操作系统内核会维护一个空闲内存块链表;访问堆内存时需要通过调用指针(起始物理地址);内存空间不足或没有连续的1G内存块会导致分配失败;
- 使用free-m 或top命令,查看进程占用的内存是否随时间在推移持续增长;使用valgrind --tool=memcheck --leak-check=full ./xxx,memcheck(二进制插桩和影子内存)会跟踪所有动态分配的内存块,并在程序退出时检查哪些快未被释放;
- 使用循序buffer,并维护wptr和rptr指针;
- 客户端:socket、connect、read/write、close;服务端:socket、bind、listen、accept、read/write、close;
- (1)确认与重传机制;序号与确认号;(2)流量控制(使用滑动窗口机制实现流量控制,防止发送方数据过快,导致接受方缓冲区溢出);(3)连接管理(三次握手(确保发送方和接受方的发送、接受能力均正常)和四次挥手(双方数据已发送));(4)数据经验(报文首部包含一个经验和);(5)拥塞控制(通过拥塞控制机制避免网络引数据量过大而拥塞(网络链路或路由器不堪重负,导致数据丢失)):核心包括慢启动(连接刚建立时,发送窗口从较小值开始,指数级增长,逐步试探网络承载能力)、拥塞避免(当窗口增长到阈值后,改为线性增长,避免突然增加大量数据导致拥塞)、拥塞发生时(如果检测到网络拥塞(如超时重传),会减小发送窗口,降低发送速率,等待网络恢复)
- 信号量、锁、条件变量、原子变量;底层会维护一个引用计数,当大于1的时候可以访问临界资源,=0时会进行阻塞;
- 可以使用序号机制(为每个UDP数据包分配唯一序号,接收方通过判断数据包是否乱序或重复);确认与重传机制;可靠UDP是在UDP基础上模拟TCP的可靠性,通过应用层自定义机制实现;音视频通话、游戏
- 基于QUIC(quick udp internet connect)协议,是一种是一种基于 UDP 的新型传输协议,融合了 TCP 的可靠性和 UDP 的灵活性同时解决了 TCP 的固有缺陷:解决(1).队头阻塞问题(TCP 是字节流协议,单个数据包丢失会阻塞整个整个连接的传输(队头阻塞);而 QUIC 基于数据包传输,不同数据流的丢失互不影响(如视频流和文字流可独立传输)); (2)更快的连接建立(QUIC 把 TCP 的 “三次握手” 和 TLS 握手合并,仅需 1-RTT(往返时间) 即可建立加密连接)
- 扩展亮度范围,增加色彩细节(数据是10bit、12bit);HDR10+,支持动态元数据(每帧视频可单独设置亮度参数)
- 0000 0001 0000 01作为每帧的起始标志,I、B、P、IDR帧,I帧会利用空间相关性进行压缩,将图像分成16x16宏块,对于每个块,从周围已编码的像素选择最佳预测模式;而对于B、P帧是利用时间相关性进行压缩;SPS是序列参数集,存储整个视频序列的全局属性(分辨率、宏块信息),PPS是图像参数集,用于描述单帧或一组帧的编码参数;SEI是补充的增强信息
- H.264使用面向宏块(16x16/32x32)进行编解码;HEVC在编解码过程使用编码树单元(CTU),它的大小或形状不一定相同,小至4x4像素,大至64x64像素,可以更有效地压缩数据;使用更先进的帧类/帧间运动预测模式,另外H265在需要的带宽是H.264的一半;但是所需的硬件需更先进,目前还没普及开,如果电脑显卡不支持硬件解码H.265,单靠CPU运算是不够的;比特率(每秒钟需要多少数据来描述这段视频),码率是比特率的另一种叫法,码率越高,画质/音质越好,但文件越大、网络占用越宽
- AAC帧通过ADTS头+payload audio data transport stream;ADTS头部大小一般为7字节(分为fixed和variable);有12bit 0xFFF用于表示一个AAC帧的开始;音频的采样率(4bit);声道数(3bit);AAC帧的总长度
- 视频封装格式:将已经编码压缩好的视频流、音频流以及字幕按照一定的方式放到一个文件中,方便播放软件播放;常见格式有MKV、MOV、MP4、AVI、FLV;mp4格式是一个box的格式,box容器套box子容器,box子容器再套box子容器;box由box header和box body组成;mov类似mp4