高标后端二面:一个实习项目被连问四十分钟,从拉流协议问到协程
- 轮次
- 二面
- 时间
- 2026-10
- 来源
- 牛客网
《面试题目》
- 自我介绍。
- 介绍一下这个项目?介绍一下软件架构?介绍一下系统架构?
- 你说的视频拉流用的是什么协议?这个是在 Web 端还是 Go 后端拉流的?怎么路由到某架无人机视频流的?
- 有没有遇到拉流卡顿的情况?怎么排查问题的?
- 你说的目标识别图片是存在哪里的?怎么显示在前端的?
- 你说的 DDS 是什么?是个消息队列吗?
- 你说的这个后台是部署在云上的还是本地?
- 你说的这个电台是什么?你们这个有接入互联网的环节吗?
- 你说这个软件是部署在终端上的,那它是怎么接入局域网的?
- 你在项目中遇到最难的技术难点是什么?这个技术难点具体是什么原因?你觉得你有什么优化策略能够减少这些 bug?
- 什么时候转的 Go?Go 和 Java 哪个更熟悉?这两者开发你觉得有啥区别?
- 你刚谈到协程,那协程和线程有什么区别?
- 你刚谈到 channel,那你们用全局变量吗?哪些应该用 channel、哪些应该用全局变量?
- 你平时有用 AI Agent 去辅助开发吗?你怎么评价 AI 辅助编码?你觉得人应该更多充当怎样的角色?
《参考解析》
按架构层次讲项目:这类追问的顺序其实是固定的——「软件架构(模块怎么分)→ 系统架构(部署在哪、怎么连通)→ 关键链路(数据怎么流)」。回答时先给一张图上的分层(终端侧采集、边缘服务、云端后台、Web 端),再讲每一层之间用什么协议、走什么网络(局域网 / 互联网 / 专网),最后挑一条最熟悉的链路讲细节。不要一上来就讲实现细节,否则后面每个问题都会把你拖进更细的层次,最后讲不清楚全局。
视频拉流的路由:要能说清三层——信令层怎么知道「要看哪架无人机的流」(设备注册与在线状态、按设备 ID 或通道号建立会话),媒体层用什么协议(RTSP/RTMP/WebRTC,WebRTC 延迟低但要处理 SDP 协商与 ICE,RTSP 更适合转封装到 HLS/FLV 做分发),以及转发在哪一侧(Web 端直接拉终端流通常不通,需要中间服务做转封装或中转)。「怎么路由到某架无人机」的答案要落到「设备 ID → 当前推流地址 / 中继节点」的映射表,以及设备 IP 变化时怎么更新(心跳上报、注册中心)。
拉流卡顿排查:按链路分段定位——终端侧看编码码率与帧率是否稳定、网络上行是否丢包;传输侧看丢包率、RTT、抖动(ping/mtr、服务端抓包看 RTP 序列号与时间戳是否有缺口);服务端看转封装是否积压(队列长度、CPU、GC 停顿);播放侧看缓冲区策略与解码能力。要能给出「怎么区分是网络问题还是服务端问题」的判据:抓包看关键帧间隔与丢包分布,服务端无积压但客户端卡 → 网络或解码;服务端转封装队列堆积 → 处理能力不足。
DDS 是什么:DDS(Data Distribution Service)是面向实时分布式系统的发布/订阅数据总线标准,不是传统意义的 MQ。它用 Topic 做数据分发,带 QoS(可靠性、时限、历史深度、寿命),典型用在机器人、自动驾驶、工业控制这类「同一份状态要低延迟广播给多个节点」的场景。和 Kafka/RabbitMQ 的区别要说得清:MQ 一般是「消息队列 + 服务端 broker + 持久化 + 消费确认」,DDS 是去中心的对等发现、以「最新值」为主、追求低延迟与确定性,不强调消息堆积与重放。
协程与线程:线程是内核调度单位,切换要走内核、保存寄存器与栈、可能触发 TLB 刷新,成本在微秒级;协程是用户态调度,切换只是保存少量寄存器和栈指针,成本在纳秒级,可以开到几十万个。Go 的 goroutine 是 M:N 模型(G 挂在 P 上由 M 执行),遇阻塞系统调用时 P 会交给其他 M 继续跑,所以不会被一个阻塞拖住全部。代价是:协程不能跨核并行(同一 G 同一时刻只在一个 M 上跑)、长时间阻塞的非协作式调用仍会占住线程、调度器需要处理抢占(Go 1.14 起有基于信号的异步抢占)。
channel 还是全局变量:判据是「所有权与同步语义」。channel 用于传递数据和转移所有权(生产者消费者、任务分发、结果聚合、退出信号),它把同步写进了通信本身,读代码的人一眼能看出谁给谁;全局变量(配 sync.Mutex/atomic)适合真正共享的状态——配置、计数器、连接池、缓存这类「多方读写同一份数据」的场景。经验规则:数据要「流动」用 channel,数据要「共享」用锁保护的结构体;不要用 channel 去模拟共享内存(那只是绕远的锁),也不要用全局变量去做任务传递(生命周期与所有权会失控)。
AI 辅助开发的评价:说得出边界比说态度重要。AI 擅长的:样板代码、单测、正则/SQL、读陌生代码、写文档、把报错翻译成排查方向;不擅长的:跨越多个模块的架构取舍、需要业务上下文与历史包袱的判断、以及「看起来对但边界错」的实现。人的角色从「写代码」上移到「定义问题、给约束、验收结果」——具体做法是把验收标准先写下来(测试用例、预期行为),让 AI 在可验证的范围内产出,人负责判断与兜底。这样答比空谈「AI 提效」更有说服力。
「最难的技术难点」怎么答:用「现象 → 定位过程 → 根因 → 修复 → 验证 → 后续预防」六段讲一个真实案例,重点放在定位过程(用了什么工具、排除了哪些可能)而不是结论。最后那段「后续预防」是加分项:把它变成一条规则、一个监控指标或一段自动检查,说明你不只是修了这一次。