面经|社招 快手|一面 二面 已凉
3565
2024.01.22
2024.02.03
发布于 未知归属地

一面

今天上午 11:00 面试了近 1 个半小时,最后一道算法题 121.买卖股票最佳时机 最后只写了一个 O(n^2) 的算法,之前虽然做过但是当时没有想起来思路,然后下楼吃饭突然又有了思路,真的是。。。,如下是解法:

#include <iostream>
#include <vector>

int main() {
  std::vector<int> prices = {7, 1, 5, 2, 6, 4};
  int res = 0;
  int buymin = prices[0];
  for (int i = 1; i < prices.size(); ++i) {
    res = std::max(res, prices[i] - buymin);
    buymin = std::min(buymin, prices[i]);
  }
  std::cout << res << std::endl;
  return 0;
}

之后就是问在工作中的项目经历,问得也很细致,具体到了某个协议的具体字段,具体内容是:

  1. rtc 中 rtp 协议转 rtmp 协议,具体 rtc 中的数据包是如何组合成 rtmp 的每一帧的数据呢。
  2. I 帧、P 帧和 B 帧有什么区别。
  3. 当第三方的 cdn 接收数据很慢时,推流机器人能对此做什么优化(一开始回答 jitter buffer,面试官说不对,因为 jb 作用更多的是对抗弱网,代价是延迟高,之后我又回答说增加一个缓冲区,用于缓存实时的音视频流数据)。
  4. 如果缓冲区满了,你会怎么做。丢音视频的数据你又会怎么丢呢?比如像 P 帧的前一帧丢了,该 P 帧岂不是没法前向参考了。
  5. 推流机器人的线程模型是怎么样的。控制侧一共有多少个线程注册到 Event Loop 中呢。
  6. 控制侧和媒体侧是如何交互的,回调函数是通过媒体侧调用控制侧的函数将流状态信息告诉控制侧的吗。
  7. 关于 SEI,控制侧做了什么事情,MetaData 和 DataStream 即通过塞到 H264 格式的头部和信令的方式发送到第三方 cdn 也是 ServerSDK2 做的吧(控制侧更多的是对请求要订阅信息插到 SEI 和组合 SEI 信息传回 ServerSDK2)。
  8. rtmp 协议是如何将数据从 rtc 拉流推到 cdn 呢,从协议的角度讲下。
  9. 一个 http 请求是如何到最终的边缘节点呢,可以讲下从 RESTFul API -> 调度器 -> wm -> worker 的完整流程。
  10. 调度器分配边缘节点的策略是什么。
  11. Engine 有固定的 12 个线程数,为什么是固定呢?以及每个线程干了什么(引擎的逻辑没看过,都是大前端做的,回答不上来)。
  12. 智能指针有用过吗,unique_ptr 的作用是什么。
  13. 栈的大小是多少,关于一个局部对象,是用 unique_ptr 的方式好还是局部变量方式好,当如果出现对象频繁的创建和销毁你会怎么做。
  14. 如何获取一个完整的 http 响应信息。

面试的岗位是录制系统开发,之后讨论下 srs 的内容,整体面下来更偏媒体侧,这还没问 ffmpeg 和编解码相关的问题,因为之前在声网是做控制侧开发,SDK 以库的形式提供给我们,所以导致音视频方面的知识有些欠缺,没有办法,只能补了。

虽然面试了 1 个半小时,但过得可能性不是很大。

二面

我主动询问 hr,才被通知一面过了,约的今天上午 11:00 的二面,关于二面问了很多关于优化方面的问题,无论是媒体侧还是 webserver:

  1. 自我介绍。
  2. 讲一下旁路推流的工作模式、线程模型以及 rtp 协议是如何转 rtmp 协议的。
  3. rtc 中使用 rtp 协议,因为基于 udp 会产生丢包,但 rtmp 是基于 tcp 的,要求数据连续,而在 rtp 转 rtmp 之前产生了丢包,推流侧是如何去处理的(rtmp 要求帧之间是连续的,因为帧与帧之间是具备参考信息的)。
  4. 你有做过媒体侧相关的开发吗?还是主要做的是信令。
  5. 我见过很多 webserver 的项目,你这个项目相比其他人做的亮点是什么,或者有做过什么优化。
  6. 上万 qps 中的 qps 是指什么。
  7. 关于定时器,epoll_wait 设置的阻塞时长为最先要超时节点的超时时间,当考虑上十万个 client 端连接进来,如果最新超时时间只有几十微秒,epoll_wait 岂不是会被反复触发,也就会造成频繁的用户态和内核态的切换,消耗 cpu 的资源,关于这种情况你会如何优化呢。
  8. 关于 reactor 模式下的线程池你是如何去做的。
  9. 关于任务队列有锁的机制,你有统计过一个线程最多能处理多少个消息吗(在 2 核 4G 6 个线程的情况下)。
  10. webbench 是如何进行压测的,使用的是长连接还是短连接(webbench 默认使用的是长连接,即不需要频繁的 tcp 建立连接和断开的开销,qps 是短连接的 3-4 倍)。

算法题:盛水最多的容器,因为很长时间没刷了,单调栈的做法没有写出来,就写了一个 O(n^2) 的暴力做法,正确解法如下:

#include <iostream>
#include <vector>

int main() {
  std::vector<int> v = {1, 8, 6, 2, 5, 4, 8, 3, 7};
  int n = v.size();
  int i = 0, j = n - 1, res = 0;
  while (i != j) {
    res = std::max(res, std::min(v[i], v[j]) * (j - i));
    if (v[i] > v[j]) {
      --j;
    } else {
      ++i;
    }
  }
  std::cout << res << std::endl;
  return 0;
}

最后问了下团队那边是否愿意培养控制侧转媒体侧,因为这个岗位更多涉及到媒体方面的技术栈比如 rtp / rtcp / hls / rtmp 协议、srs 以及音视频方面的知识等,面试官给的反馈是需要招有经验的开发人员,该岗位也是急招,能基于现有的录制系统快速做优化改进和架构升级,同时这个项目也是 24 年公司的一个大项目。所以听到这过的可能性也就不是很大,有点遗憾在声网没多看看 ServerSDK2 的源码,掌握一些媒体侧相关的知识。

评论 (7)