百度音视频面试——一面

百度视频云音视频高级研发工程师——面经

自学音视频技术差不多1年,有点飘了。在bos s上挂了简历,有幸被百 度的HR看到。我跟HR说:我只能达到初/中级水平,达不到高级水平。HR说没事:投个简历吧。 我猜她是为了完成指 标,那就成 全她。投了简历,然后安排了面试。特此凭着记忆,记录一下面试过程。

首先自我介绍:上学、工作、项目。 对于自己特别熟悉的,拿手的,一定要重点多说一些,其他的,不熟悉的,一带而过。我是傻傻的,没有区分重点难点,一溜烟介绍了。而且自己做的项目,一定要特别熟悉,内部啥原理,甚至代码细节,都会被问到。 我这个人有个习惯:碰到不懂的,当时查清楚了,并记录了笔记CSDN/ github。结果东西就没有记在脑子里,脑子里记的,只有问题以及这个问题去哪里找答案。 看来,脑子只存储了指针。 

 

技术基础:

1、多线程间的通信方式:

1、全局变量,需要volatile关键字修饰。每次从内存中去读这个值。 

定一个全局变量,通过改变全局变量,通知线程做相应的动作,比如:bool类型的,就是通知线程是否停止退出。

如果不加volatile 关键字,直接使用全局变量,会有什么问题?

 volatile 关键字声明变量,可以用于两个线程通信。当两个线程都要用到某一个变量且该变量的值会被改变时,应该用 volatile 声明,该关键字的作用是防止优化编译器把变量从内存装入 CPU 寄存器中如果变量被装入寄存器,那么两个线程有可能一个使用内存中的变量,一个使用寄存器中的变量,这会造成程序的错误执行volatile 的意思是让编译器每次操作该变量时一定要从内存中真正取出,而不是使用已经存在寄存器中的值

2、临界区域

CRITICAL_SECTION section;// 临界区对象

InitializeCriticalSection(&section);// 用之前,必须初始化

EnterCriticalSection(&section);// 进入临界区,获取所有权

LeaveCriticalSection(&section);// 释放所有权

需要了解自动锁,C++11的新标准。

3、互斥量

HANDLE hMutex; // 声明一个互斥量

hMutex = CreateMutex(NULL, FALSE, NULL);//创建,并设置为false,没有线程拥有它

WaitForSingleObject(hMutex, INFINITE);// 某线程,拿到钥匙的使用权。

ReleaseMutex(hMutex);// 使用完之后,要释放线程的使用权

4、事件

HANDLE hEvent; // 事件对象

// 第二个参数:TRUE,表明人工重置对象, FALSE,非人工,即自动重置对象

// 第三个参数:FALSE,表明一开始没有线程拥有这个hEvent;无信号状态

hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

SetEvent(hEvent);// 使得hEvent为有信号状态,其他线程可以取到

WaitForSingleObject(hEvent, INFINITE);// 请求事件对象,将hEvent设置为非信号状态

SetEvent(hEvent);// 将hEvent设置为有信号状态,其他线程可拿去使用

详细描述连接

 

2、H264内部结构

在H.264/AVC视频编码标准中,整个系统框架被分为了两个层面:

1.VCL (VideoCoding Layer,视频编码层)。核心算法引擎,块,宏块及片的语法级别的定义,负责高效的视频内容表示,通俗的讲就是编码器直接编码之后的数据,这部分数据还不能直接用于保存和网络传输,否则在解析上存在困难。

2.NAL(NetworkAbstraction Layer,网络抽象层)。负责格式化数据并提供头信息,以保证数据适合各种信道和存储介质上的传输,通俗的讲NAL就是将上面的VCL加了一些头部信息封装了一下

现实中的传输系统是多样化的,其可靠性,服务质量,封装方式等特征各不相同,NAL这一概念的提出提供了一个视频编码器和传输系统的友好接口,使得编码后的视频数据能够有效地在各种不同的网络环境中传输。

最后所有的数据逻辑关系总结如下:

SODB  + RBSP trailing bits = RBSP  (原始字节序列载荷)

RBSP 将0x0000替换为0x000003 = EBSP

NAL header(1 byte) + EBSP = NALU

Start Code Prefix(3 bytes) + NALU + Start Code Prefix(3 bytes) + NALU + … + = H.264BitsStream

start code 是3位0x000001或4位0x00000001, 3字节的只有一种场合下使用,就是一个完整的帧被编为多个slice的时候。

nalu header =   1个字节

https://blog.csdn.net/qq_34732729/article/details/104969107

https://blog.csdn.net/qq214517703/article/details/80359911

 

3、MP4内部结构

查看工具:UltraEdit , mp4reader, 查看MP4文件的详细格式。

https://www.cnblogs.com/boonya/p/8572052.html  // 从代码层次的分析

https://blog.csdn.net/yue_huang/article/details/72812109   // 从结构方面,文字分析。并且,最后还会有各种计算样例。

 

4 、进程间的通信

进程是系统动态执行的基本单位,也是系统分配资源的基本单位;

线程是进程中执行的最小单位,它可以访问进程的共享资源。

进程之间对共享内存等进行读写操作,需要使用互斥机制,常使用Mutex;进程的同步机制包括Event、Semaphore,常使用Semaphore。进程间的通信不仅包括进程的同步互斥,还包括进程间数据的传输。

进程间常用的通信方式:共享内存、管道、信号量Semaphore、端口,其中Mutex和Event放在共享内存中使用。

Shared Memory称为共享内存,它是进程间数据传输最快的通信方式。由于共享内存是所有进程都可以访问,因此共享内存的操作需要加锁

pipe称为管道,其分为命名管道、匿名管道。

 

5、C++ 11的新特性

毕竟音视频是离不开C++的,而且现在C++11的新特性,都是常用的。

6、C++ 11的智能指针

C++11的智能指针,比之前的智能指针好在哪里。

7 、C++ 11的print(...), 变参是如何实现的

这部分就需要去看C++内部是如何构造和实现了。大厂就是问得深!

8 、浏览器是如何呈献的,比如:输入www.baidu.com ,到这个页面呈献,中间经历了什么?

https://www.dazhuanlan.com/2019/12/05/5de8187dcb7b9/

① url 是资源的地址。www.baidu.com, 域名,相当于一个服务器的别名,而服务器真正的地址是一个ip地址:182.61.200.6。 

②任何一个域名首先都会去DNS服务器中 转换一个ip, 只有转换了ip, 才能准确的找到这个服务器。本地有一个hosts文档,内部会存储一些常用的Ip和域名。本地访问的时候,会先去hosts里面找找,没有的话,再去DNS中转换,将转换回来的ip和域名,记录仅hosts文件(注意:hosts文档不是永久存储的,它会存储一段时间之后,里面的存储信息就会失效了。)。

③浏览器向服务器发送请求之前,会先建立一个可靠的TCP/IP连接(三次握手)

  • client ----syn----> server
  • client <----syn ack------- server
  • client -----ack------> server

④ 浏览器向web服务器发送请求

⑤ web服务器接收并处理请求

⑥ 服务器将数据返回给浏览器

⑧解析HTML、渲染页面(这一块内容较多,暂不记录)

⑦ 断开连接,4次挥手

  • client ----FIN----> server
  • client <----ack------- server
  • client <----FIN------- server
  • client -----ack------> server
  • server先close, 然后2msl时间后,client  close。

 

9 、如何录制的内部声音:

自己开发了一个录音机,可以录制内部声音和外部声音,所以介绍这个项目的时候,就被问到了。解答: 先安装一个screen capture recorder.exe 的文件,然后在cmd框,输入:ffmpeg -list_devices true -f dshow -i dummy,  就可以看到了virtual-audio-capture。然后写代码的时候,在 avformat_open_input(&pFmtCtx_Audio_in, psDevName, ifmt_audio, NULL),中,用virtual-audio-capture 替换“麦克风阵列”, 就可以采集内部声音了,也就是直接采集声卡。https://blog.csdn.net/qq_34732729/article/details/106573048

 

10 、mp2与AAC的区别,AAC更适合android

mp2: 有损压缩的音频格式。MP2主要应用在标准化数字广播和数字电视广播(DAB,DMB,DVB)的数字音频和视频编码。MP2文件格式通常用于广播电视行业,所以在普通音频播放器上的支持率不高。音质比mp3好。

mp3: 有损压缩的音频格式。压缩比例比MP2大,所以更适合网络传播。

 

11 、在Linux系统下,做过什么

因为简历上写了熟悉Linux,就被问到,在Linux下做过什么。

主要是在本地虚拟机VMware workstation15.5下,安装Ubuntu16.04系统。  通过shell进行操作的。  练习C++编程,学习nodejs,搭建简单的https服务。  编译ffmpeg, 适合android的arm32, arm64, 适合Linux的动态库。  搭建coturn服务,并测试。  搭建nginx服务,作为rtmp推流的服务器   。编译webRTC的android版

 

12、RTP/RTMP的区别

 RTPRTMP
概念Real- time Transport Protocol(实时传输协议)Real Time Message Protocol(实时信息传输协议)
协议UDPTCP
用途

在Internet上处理多媒体数据流的传输层协议,

单播(1V1),多播(组播1V多)

用来解决多媒体数据传输流的多路复用(Multiplexing)

和分包(packetizing)的问题

格式RTP header + payload

  RTMP在收发数据的时候并不是以Message为单位的,

而是把Message拆分成Chunk发送,而且必须在一个

Chunk发送完成之后才能开始发送下一个Chunk。

每个Chunk中带有MessageID代表属于哪个Message,

接受端也会按照这个id来将chunk组装成Message。

   

RTSP发起/终结流媒体、RTP传输流媒体数据 、RTCP对RTP进行控制,同步。

RTSP可以对流媒体提供诸如播放、暂停、快进等操作,它负责定义具体的控制消息、操作方法、状态码等,此外还描述了与RTP间的交互操作(RFC2326)。

 

13、qt的多线程

1、继承QThread方式:

  • 定义MyThread类,MyThread::QThread{}
  • 在MyThread类中,重载run(), 将耗时的程序,可以写在run中。
  • 开始和结束线程。在主窗口类中,定义MyThread类对象指针,用于启动run, 与停止run。

2、moveToThread方式

  • 创建一个MyClass的类,并继承QObject类, MyClass::QObject{}. 把 [要在线程中执行的工作] 作为 [类的槽函数]。
  •   在work.cpp中,实现do_something()的方法。
  • 创建一个线程对象, 把work1对象移到新线程下,
  • mainwindow.cpp  实例化
  • 把work1对象 移动到 新线程下
  • 绑定线程:
  • 启动线程:(在两个connect函数的下面)
  • 结束后,清理工作: (第一行,位于第一个connect的下面)

完整的:

 参考链接

 

14、opencv都怎么用的

因为2016年用过opencv,打开摄像头,采集图像,然后对图像进行处理:滤波,去除噪点、阈值分割、candy算法提取边缘。 通过像素与实际标定距离的转换,获得实际距离。其实opencv这些年发展应用领域挺广泛的:人机互动、物体识别、图像分割、人脸识别、动作识别、运动跟踪、机器人、运动分析、机器视觉、结构分析、汽车安全驾驶等。

 

15、说说自己开发的项目,项目难点是什么,怎么解决的。

这里介绍项目的时候,一定要熟悉到每一行代码。不然很容易被问懵。千万不要说:就是这样解决的呀,不觉得难呀。。。

16、编写一段代码

二叉树的插入。 我说:这个好难啊。 考官说:那写个双链表的插入和删除吧。 我以为我记得怎么写。 提笔忘字。 没写出来。 还是准备的不够充分。 面试前,一定要写写代码,找找手感,而不是看看代码,背一下。

 

面试时间70分钟。整个过程满满当当。面试官是一个特别和蔼的技术男。这里的每一个问题,都可以整理一篇博客了。果然是大厂,面试就是认真!

 

 

 

  • 5
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值