9.10日面试遇到问题总结

1.简历里面的处理400mb/s的数据是瞬时的还是普遍的?400mb/s还是很恐怖的,几秒钟就1个G了,你是怎么处理这个问题的?你们的频谱设备的屏幕能显示多少呢?

400MB/s 是 FPGA 通过udp发给上位机的IQ 数据的瞬时峰值速率,不是持续稳定的平均流量,正常的IQ数据量应该是40兆,400mb/s是因为硬件一次扫频(就是频谱设备在一段连续频率区间,从起始频率逐步扫描到终止频率,在每个频点采集无线电信号)短时间内高速吐出 IQ 原始采样数据,瞬时带宽(带宽是单位时间能够传输的数据量,代表传输通道的数据吞吐上限。我们项目 400MB/s 就是 UDP 传输瞬时带宽)达到这个水平,如果直接全部绘图、存盘,上位机会内存打满、卡顿。 处理方案,区分 IQ 时域和频谱模式,按需解析,不会保存全部原始大数据。 界面绘图点数受屏幕像素限制,最终送到 Qt 绘图只有几千个点,仅几十 KB,保证 UI 流畅。原始大数据只在缓冲区短暂存放,旧数据直接覆盖,不会长期保存。

①独立 UDP 子线程专门接收报文,预分配大缓冲区,我们一次只会接收在业务设置的这个缓冲区接收一帧数据,下一次新扫频的数据过来,直接覆盖缓冲区里上一帧的旧数据,不会缓存多帧。所以不需要 400MB 的内存。调大 socket 内核缓冲区减少丢包;

②做降采样抽帧,不把全部原始采样交给绘图,paint 函数区间取最大值,丢弃冗余帧;

③区分 IQ 时域和频谱模式,按需解析,不会保存全部原始大数据。 界面绘图点数受屏幕像素限制,最终送到 Qt 绘图只有几千个点,仅几十 KB,保证 UI 流畅。原始大数据只在缓冲区短暂存放,旧数据直接覆盖,不会长期保存。

我们上位机软件在用户配置扫频参数的时候,会提前校验,如果预估单帧数据会超过 40MB,就自动拆分频段,分多次扫频,保证单帧不会超过 40MB 缓冲区上限,防止溢出。

正常情况下我们做参数校验,不会出现溢出。极端场景下来不及处理,新数据包会丢弃,打上丢包标记,通知设备重扫。

2.你们使用的是udp,你们是怎么来降低丢包的概率的?

网卡收到 UDP 数据包,硬件通过中断通知操作系统,内核把数据包先放到 socket 的内核接收缓冲区排队。我们的上位机接收线程调用 recvfrom (),从内核缓冲区把数据包拷贝到我们用户态 40MB 业务环形缓冲区。 瞬时流量爆发的时候,内核缓冲区充当 "临时蓄水池"。如果没有调大,大量 UDP 小包瞬间涌入,内核缓冲区很快填满,新来的包直接丢弃;调大之后,内核可以短暂缓存更多报文,给应用线程争取时间去读取,从而降低丢包概率。

这是我们减少 UDP 丢包的手段之一:调大 socket 内核接收缓冲区,作为临时蓄水池,应对瞬时流量尖峰,给应用线程留出读取数据的时间,避免报文直接在内核层面被丢弃。 除此之外,我们还有其他配套丢包处理方案:

①调大 socket 内核接收缓冲区,缓存瞬间涌入的 UDP 小包,减少内核直接丢包;

②业务层开辟 40MB 环形缓冲区,接收线程把 recvfrom 读到的包存入,按包序号重组,拼接完整一帧;

③每个 UDP 数据包携带序列号,接收端检测是否出现丢包;一旦检测丢包,向上层上报,下发指令让 FPGA 重新执行一次扫频,重传这一帧分段数据;

④上位机提前做参数校验,超大频段自动拆分成多段扫频,控制单帧大小,避免一次性超大流量冲击网卡。

2.你说你是通过给UDP到的包进行排序来确认包的顺序的,请问具体是怎么实现的?udp有哪个字段可以确定包?比如时间戳什么的。

UDP 原生协议头没有序列号,我们在业务载荷前面自定义包头 ,自己添加包序列号 seq。 FPGA 打包时,给每个 UDP 包写入 seq 序号、帧编号、一帧总包数量。上位机收到包,解析出自定义包头里的 seq,根据序列号,在环形缓冲区对应位置存放数据包,完成重组。 接收完成后检查序列号是否连续,检测丢包;一旦丢包,通知设备重扫。不用时间戳排序,时间戳不能用来恢复数据包顺序

缓冲区底层是一块预先 malloc 的 40MB 连续一维数组,整体封装成环形缓冲区。 因为 UDP 包会乱序到达,不能简单 FIFO。我们依靠包里面的 seq 序列号,计算对应的字节偏移,直接写入数组对应位置;同时维护一个标记数组记录每个 seq 包是否收到,用来检测丢包。环形缓冲区的作用是复用这块内存,新的一帧到来直接覆盖旧帧。

4.你说为了给udp到的包设置了buffer,具体是怎么实现的

5.屏幕上显示的是多少数据量的数据?

6.知不知道udp和tcp的区别?既然你们的业务需要处理丢包情况,为什么不直接使用tcp协议?

拥塞控制的意思是一旦网络有轻微丢包,就会降低发送窗口,压低发包速率,我们这个项目需要短时间爆发式发送大量数据包,TCP 容易被限流,传输一帧耗时变长。

我们场景是短时间一次性推送一整帧几十 MB 的 IQ 数据,追求瞬时高速发包。TCP 拥塞控制会限制发包速度。当瞬间大量数据发送,TCP 检测到轻微丢包就主动降速,40MB 的数据发送时间会被拉长,达不到高速传输需求;TCP 协议栈本身开销更大,频繁的 ACK 报文会占用网卡带宽,拉低最大吞吐;我们的业务场景可以自己做简单的丢包处理:包带自定义 seq 序号,检测丢包之后,直接通知设备重扫整帧。 一次扫频是完整的一帧,一旦检测丢包,直接重发整帧,不需要 TCP 那种精细的单包重传。 权衡下来:UDP 在 FPGA 端实现简单,发包速率高;丢包由我们业务层检测 + 重扫机制处理,更适合频谱仪这种高速批量传输场景。

7.如果说在实际开发中给你一个你从来没有接触过的qt业务让你来开发,你接手到这个项目打算怎么做?你的具体的开发流程是什么?

①需求调研与熟悉代码 先看懂业务需求文档,明确功能、输入输出、测试指标;然后搭建编译环境,跑通现有工程,理解整体架构、模块划分、类之间的关系;看懂已有数据流转,比如数据接收、解析、绘图模块。梳理信号槽、多线程的边界,重点区分 UI 主线程和工作线程,防止 UI 阻塞。

②方案设计 梳理新功能的数据流,确定新代码放在哪个模块;明确和原有模块的交互接口;考虑边界场景,比如参数校验、异常处理、内存保护。 Qt 项目重点注意:耗时操作不能放在 UI 主线程,放到子线程,通过信号槽把结果传回 UI;还要考虑绘图性能、大数据降采样、缓冲区溢出等问题。

③编码开发 先写底层基础逻辑和接口,再写 UI 界面;尽量复用项目已有工具类、数据结构;严格区分 UI 业务和数据处理逻辑,减少耦合。开发过程写日志,方便排查。

④单元自测 + 联调写完模块先单元自测;再和后端 FPGA 设备联调,测试正常场景、边界场景(超大扫描范围、网络波动、断连);重点测试大数据流量尖峰、缓冲区溢出、丢包重扫场景;最后做 UI 界面测试,检查绘图、交互是否流畅。

⑤收尾 整理注释,提交代码,提交测试,修复 bug。

第一步,先读懂需求文档,搭建环境跑通工程,熟悉项目架构、模块划分、线程模型与数据流转;

第二步,做方案设计,确定接口和模块划分,重点保证耗时操作放在子线程,不阻塞 Qt 主线程,处理好边界异常;

第三步,编码实现,复用项目现有工具模块,分离 UI 与数据逻辑;

第四步,自测,再和硬件联调,测试正常场景、网络波动、大流量边界场景; 最后修复 bug,提交代码。

8.C的内存管理是什么?

C 语言没有垃圾回收,内存由程序员手动管理。

内存分为栈、全局静态区、堆、代码段。 栈:编译器自动分配释放,局部变量,容量小;

堆:手动管理,通过 malloc、calloc、realloc 申请,free 释放,用完必须释放,防止内存泄漏。 malloc 得到的内存不会自动清零,calloc 会初始化为 0。使用完不 free 造成内存泄漏;free 之后继续使用会出现野指针。我们项目 40MB 环形缓冲区就是 malloc 在堆上分配。

9.你的整个高并发服务器项目的实现逻辑是什么?

10.你不是科班计算机的,呢你是在哪里学习的这些?

我是通过线上网课自学起步的,B 站跟着课程学习 C 语言、数据结构。学完之后权衡方向,决定专注 C++,边听课边敲代码,代码都提交到 Gitee。后面发现只听课理解不够深入,又读侯捷老师的 C++ 书籍,同时参考 CSDN 技术博客,自己也写博客复盘知识点。 语言基础打好后,继续学习操作系统、计算机网络、Linux 系统编程。学网络编程后,发现简单通信无法支撑多用户并发,于是研读 muduo 库源码,动手实现高并发服务器项目。

11.你的高并发服务器项目是为什么想到会做这个呢?代码从始至终是你自己手搓的还是说会借鉴一些别的?

学习网络编程的时候,我写了简单 socket 程序,但只能单连接,无法处理并发。于是想学习高性能服务器的实现,了解到 muduo 库。 项目思路借鉴 muduo 的 Reactor 模型设计,核心代码是自己从零手写,不是直接复制源码。参考开源项目的优秀架构,是开发中很常用的方式;我自己实现事件循环、epoll 监听、收发缓冲区、粘包处理等逻辑,过程中独立调试 bug,代码放到 Gitee,同时写博客总结踩坑点。

12.你怎么看现在ai盛行对我们程序员来说是怎么样的,你有没有用ai实现过一些脚本?

我觉得 AI 是程序员的辅助工具,不会取代程序员。AI 可以快速写模板代码、简单脚本,减少重复工作;但 AI 代码经常缺少边界处理,存在隐藏 bug,必须人工审核自测。 我有用 AI 写过一些简单的 shell 测试脚本。不过我一定会读懂代码逻辑,验证正确性。项目里的核心底层逻辑,都是我自己独立编码实现的。

我用 AI 辅助写过两类 shell 脚本。一类是日志处理脚本,自动筛选、统计日志里网络异常报错,方便定位 bug;另一类是简易并发测试脚本,批量启动客户端连接服务器,做简单并发测试。这些只是辅助测试工具,项目核心代码是我自己写的。

14.扫描范围怎么确定?频谱设备作用是什么?

扫描范围由用户在上位机软件填写起始频率、终止频率、分辨率带宽等参数,软件通过网络下发参数给 FPGA 硬件,硬件按照这个区间执行扫频;设置的频段范围越大,采集采样点越多,单帧数据量越大。 频谱设备作用:捕获空间中的无线电电磁波信号。硬件采集原始 IQ 信号,可以直接上传 IQ 采样数据;也可以在 FPGA 内部做 FFT 快速傅里叶变换,算出各个频点信号功率,输出频谱数据。 我们 Qt 上位机接收数据,绘制频谱曲线,实现信号峰值检索、数据存储,用于电磁环境监测、无线信号排查。

17.如果给了你offer,你打算在去公司工作前做什么?

如果拿到 offer,入职前我会巩固 C++、Linux、网络编程这些基础;复习 Qt、数据库等项目用到的技术;复盘我之前的项目,梳理清楚项目原理;了解公司业务,同时保持算法刷题。争取入职之后可以快速上手业务,尽快投入开发。

18.你平常用的两个ai的区别是什么?

我用 AI 辅助写过两类 shell 脚本。一类是日志处理脚本,自动筛选、统计日志里网络异常报错,方便定位 bug;另一类是简易并发测试脚本,批量启动客户端连接服务器,做简单并发测试。这些只是辅助测试工具,项目核心代码是我自己写的。

成为一个独立的人究竟要吃多少苦。

----------2026.9.11 16:26

相关推荐
敲代码的嘎仔4 小时前
从零实现视频续播 + 学习进度统计:前端心跳、条件更新、GROUP BY 统计全链路拆解
java·前端·数据库·学习·面试·职场和发展·音视频
爱读源码的大都督20 小时前
DeepSeek面试官问:多租户 RAG 系统怎样实现细粒度权限控制?
后端·面试·架构
蒸蒸yyyyzwd20 小时前
机试和Redis学习笔记
c++·笔记·面试
一只叫煤球的猫21 小时前
Spring AI 2.0 源码解析(四):Prompt、Message、Options 的对象模型
后端·面试·ai编程
IT大白鼠1 天前
MySQL 分布式集群系列 · 第八篇(收官)——NDB 集群面试高频题 +架构总结与未来演进
分布式·mysql·面试
ShineWinsu1 天前
对于MySQL:内置函数的解析
linux·数据库·c++·mysql·面试·函数·查询
letisgo51 天前
JAVA 高级进阶02篇《并发编程三板斧:JMM、CAS与AQS的源码级拆解》
java·面试·并发编程·aqs·jmm
尾善爱看海1 天前
Vue 面试进阶篇:Composition API、插槽、自定义指令……8 个章节 + 高频面试题全解析
前端·javascript·vue.js·面试·vue