记我的第一次视频面试

  最近参加一个据说是创业公司的视频面试,其中波折趣味一言难尽,在此分享一下我做的两道算法类题目这是其中一道,初看这道题,第一感觉是只要考虑每个数的个位即可,因为只有个位上的乘法才有可能产生0,于是乎好办了,每隔10个数能产生一个10的倍数,个位上的1……9又能产生一个0,于是只要算出有多少个10即可,每隔十个数能产生2个0,再看看m%10是否大于5,如果大于5,也能产生一个0,好,问题似乎是解决了,有点想当然了,写程序验证,验证当m = 20正确;m = 25时,按照我的算法,结果应该是2 * 25/10 + 1 = 5,但是看了一下,25!结尾是有6个0,不对,哪出了问题了呢?原来在于25这里,25可以分解为5*5,而20后的21,22,23,24,25五个数的个位为:1,2,3,4,5,只能产1个0,但是21,22,23,24,25这五个数相乘是能产生两个0的,原因就在于25这里,5*5,原来,0的产生其实是跟5有关的,从1开始,每隔5个数,能产生一个0,因为每隔5个数,就能产生一个因子5,比如1……5,有一个5,6……10,10=2 * 5,那是不是结果就是m/5呢,还是不,当m=25时还是不对,这是怎么回事?因为到25这里,产生了2个5,那125是5*5*5,625 = 5*5*5*5要把这些情况都考虑进去才对,也就是每隔5的一个幂次级,就多产生一个5,比如到25这里,要多一个5,也就是说每隔25,就多产生一个5(如50,75,100)也就会多产生一个0,125这里会多产生一个0……这下问题理清楚了,可以写程序了。

int count = 0;
for (int i = 5; i <= m; i *= 5)
{
	count += m / i;
}

道题的时间复杂度为Log5(m),看起来也挺靠谱的,像是一个算法的时间复杂度,嘿嘿,验证也无误。写程序也就是这么一点点,但是想的过程却是曲曲折折的简约而不简单

再来看看另外一道,我认为更难了。


也就是比如一个35矩阵:

                                              1 2 3 4 5       1 1 1

                                              1 2 3 4 5 => 2 2 2

                                               1 2 3 4 5       3 3 3

                                                                    4 4 4

                                                                    5 5 5

在一维数组中是按照[1 2 3 4 5 1 2 3 4 5 1 2 3 4 5]存的,现在要将它转置,那么它在数组中应该是:[1 1 1 2 2 2 3 3 3 4 4 4 5 5 5],当年到这道时,真是有点犯难,按以前求二维数组的矩阵来转置得了,多省事,非得弄这么一茬,不好弄了,想了好久没什么进展,直到最后才发现了一点点眉目:不是要转置么,我一个一个移,先将原矩阵的第0(按照C语言中的习惯,从0开始)列的第1个1保存,然后将它之前的5,4,3,2后移一位,再将1插入到数组的第1个位置,一维数组变成:11 2 3 4 5 2 3 4 5 1 2 3 4 5按这个方法,移另个一个1,数组变成:1 1 12 3 4 5 2 3 4 5
2 3 4 5,好了,转置后的第一行完成了,原来当我进行移位的时候,数组中的其它元素的相对位置是不变的。再看数组中,因为1 已经排好序,不用管了,剩下3组2 3 4 5 ,怎么办呢,对了,把2 3 4 5 2 3 4 5 2 3 4 5 当成是一个新3的行4列矩阵,像刚才一样进行移位变换,于是数组变成:1 1 1 2 2 2 3 4 5 3 4 5 3 4 5,好了, 1、2都排好序了,剩下3组3 4 5 3 4 5 3 4 5,依此类推,结果就出来了。于是我们可以看到,对于m*n行的矩阵,把转置分为n - 1轮,每轮过后就会完成一列的转置,当完成n-1轮后,原矩阵已经有n-1列完成了转置,最后列由于算法的设计,自动转置了。照这个算法,交换的次数就要多了,但是可以实现空间复杂度为O(1),也算是满足要求了。想起来有点点复杂,贴程序,用Python写的

#-*-coding:utf8-*-  
#a:数组,m:行,n:列  
def fun(a,m,n):  
    #这个运算需要进行的次数  
    for c in range(n - 1):#表示[0,n-1)  
        #每次的起始位置  
        frm = c * m  
        for i in range(1,m):  
            '''''下一个要确定位置的元素位置,并保存其值, 
            每次运算过后 ,剩下的元素组成的的m行数组列数减1 
            '''  
            pos = i * (n - c) + frm  
            temp = a[pos]  
            #pos的前n-1个数整体前移一位  
            for j in range(pos - 1,frm + i -1,-1):  
                a[j + 1] = a[j]  
            #找到位置并赋值  
            a[frm + i] = temp  
#测试           
a = [1,1,1,1,1,2,2,2,2,2,3,3,3,3,3]  
b = [1,1,2,2,3,3,4,4,5,5,6,6,7,7]  
c = [1,1,1,2,2,2,3,3,3]  
fun(a,3,5)  
fun(b,7,2)  
fun(c,3,3)  
print a,'\n',b,'\n',c

这个算法想的时候很不顺利,写程序的时候到也有点小小的波折所以想记录自己在解这两道题的时候思维过程,通过建立清晰的思维模型,严谨的分析与验证,才能得出正确的答案,在解题的过程中,如何想的真的很重要,它反映了我平时的一些不好的思维习惯,这些习惯定势还有很多地方需要改进。其实在视频面试的时候由于网络不太好,我完全有机会作弊,但是我知道,看到答案时那一声惊呼:“原来是这样“,对我来说没有任何作用,只有自己慢慢想出来的经历了这个思维过程,至少对自己是有用的,还好,面试那人比较耐心,也比较相信我,嘿嘿大笑



### C++音视频处理面试常见问题及经验 #### 常见问题分析 在C++音视频开发领域,常见的面试问题通常围绕以下几个方面展开:基础理论知识、实际应用能力以及解决问题的经验。以下是几个典型的面试问题及其解答。 --- #### 1. **音视频数据传输中的丢包容忍机制** 音视频数据在网络传输过程中可能会遇到丢包的情况。由于音视频流具有较强的实时性需求,在某些场景下允许一定程度的丢包以换取更好的用户体验[^3]。 - 解决方案通常是通过前向纠错(FEC, Forward Error Correction)或重传请求(NACK, Negative Acknowledgement)来应对丢包问题。 - FEC 的原理是在发送端增加冗余信息,接收端即使丢失部分数据也能恢复原始信号。 - NACK 则依赖于反馈机制,当接收方检测到丢包时会通知发送方重新发送丢失的数据包。 --- #### 2. **TCP 和 UDP 在音视频传输中的选择** 音视频传输对延迟非常敏感,因此通常优先考虑使用 UDP 协议而非 TCP。这是因为: - TCP 是面向连接的协议,提供可靠的数据传输服务,但在出现丢包时会触发重传机制,从而引入额外的延迟。 - UDP 不保证可靠性,但其无连接特性使其更适合低延时的应用场景,如在线直播或视频通话。 然而,在一些特殊情况下(如文件下载),也可以采用 TCP 来确保数据完整性。 --- #### 3. **如何排查 C++ 程序运行期间发生的崩溃问题?** 对于 C++ 开发者来说,程序崩溃是一个常见的挑战。以下是一些有效的排查方法: - 使用调试工具(如 Windbg 或 GDB)附加到目标进程中,捕获异常并定位问题根源[^1]。 - 如果未生成 dump 文件,则可以通过设置自定义 crash handler 来录详细的错误日志。 - 对于多线程环境下的死锁或竞争条件问题,建议启用静态代码分析工具(如 Clang-Tidy 或 Visual Studio Code Analysis)提前发现潜在隐患。 --- #### 4. **音视频编码解码的基础概念** 音视频编解码是该领域的核心技术之一。开发者应熟悉主流标准(H.264/H.265、AAC/MP3 等)的工作原理及相关 API 库(FFmpeg、GStreamer)。具体而言: - 编码器的作用是对原始媒体数据进行压缩以便存储和传输;而解码器则负责将其还原成可播放的形式。 - 实际项目中可能还需要实现自适应比特率调整功能,即根据当前网络状况动态改变输出质量参数以优化观看体验[^2]。 --- #### 5. **建立 TCP 连接的过程描述** 尽管大多数现代音视频通信倾向于基于 UDP 构建,但仍有必要掌握传统 TCP 握手过程的知识点——这是计算机网络课程中最基本的内容之一: 1. 客户端发起 SYN 请求; 2. 服务器回应带有同步标志位确认号字段值加一后的 ACK 报文段同时附带自己的初始序列号形成第二次握手; 3. 最终由客户端再次返回一个仅含 ACK 字段更新过的报文完成整个三次握手机制确立正式双向通讯链路。 --- ### 示例代码片段 下面展示了一个简单的 FFmpeg 初始化函数用于加载外部库资源: ```cpp extern "C" { #include <libavcodec/avcodec.h> } void initialize_ffmpeg() { av_register_all(); // 注册所有可用的编解码器和支持格式 } ``` 上述代码展示了如何调用 `av_register_all` 函数注册所有的多媒体容器格式与对应的音频视频编解码组件实例化操作步骤说明文档链接地址如下所示。 --- ####
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值