ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

宇视科技软件岗笔试面试:C/C++内存、Linux与RTSP备战指南

宇视科技软件岗笔试面试:C/C++内存、Linux与RTSP备战指南 简介这份资料是宇视科技软件岗位笔试与面试的真题回忆整理面向准备投递嵌入式、C/C后端及系统软件开发方向的应届生与求职者用于在有限时间内把握企业考核的重点范围与题型分布。压缩包内共1个PDF文件约107KB内容按判断题、选择题、填空题、编程题与面试问答几个板块组织笔试部分覆盖逗号运算符优先级、结构体内存对齐与字节对齐、二维数组与数组指针的关系、常量表达式、自增自减、sizeof与传参方式值传递、指针传递、引用传递等高频基础考点编程题涉及任意长字符串求和、IP地址类型判定与枚举实现。面试部分则延伸到字符串逆置、最长回文子串、链表中间节点、快速排序、union内存布局、图书管理系统设计、C/S架构与多线程数据库交互以及socket、进程线程差异和IPC通信种类等进阶内容。目前已有190人学习适合用来对照自身知识盲区逐题梳理思路并复盘常见错误也可作为短期冲刺自测的题库参考。1. 宇视科技软件岗笔试面试先弄清它到底考什么投递宇视科技软件岗的人经常在笔试当天遇到两个意外卷子上没有刁钻的算法难题却有一半篇幅在问指针、字节序、Linux 命令面试官不急着让你手撕红黑树反而揪着简历里那个项目连问三层。这家做视频监控与 AIoT 的公司软件岗位大致分为嵌入式、平台后端、算法和应用开发几类公共底座都是 C/C、操作系统、计算机网络再往上叠加视频相关的协议常识与工程素养。准备的重心落在三件事上就够基础题不丢分、项目讲得清、场景题给得出方案。接下来的几章按笔试代码题、项目面、场景设计、自测复盘依次展开每一段都给出可以直接照抄的代码或命令方便你在有限时间里把复习变成可验证的动作。2. 宇视软件笔试的 C 语言与内存题手写代码怎么不丢分2.1 手写字符串与内存函数边界条件比算法更重要笔试里手写 strcpy、memcpy、strcat 这类题出现的频率不低。评分点不在算法多聪明而在你有没有处理空指针、有没有返回目标地址、有没有考虑源和目的内存重叠、有没有把结尾的\0算进去。很多人上来就写while (*s) *d *s;指针越界和返回值缺失各扣一半分。常见做法是先把参数检查写完再把重叠场景单独拆出来最后补上返回值。#include stddef.h /* 手写 memcpy兼顾返回值、空指针与内存重叠 */ void *my_memcpy(void *dst, const void *src, size_t n) { unsigned char *d (unsigned char *)dst; const unsigned char *s (const unsigned char *)src; if (d NULL || s NULL || n 0) { return dst; /* 空指针或零长度直接返回避免后续解引用 */ } if (d s) { /* 目标在源之前从前向后拷不会踩到未读数据 */ while (n--) { *d *s; } } else { /* 目标在源之后必须从后向前否则源会被提前写坏 */ d n - 1; s n - 1; while (n--) { *d-- *s--; } } return dst; }参数说明dst和src用void *接是为了兼容任意类型n的单位是字节而不是元素个数返回dst是为了支持链式调用。真正区分水平的是那个分支判断——标准库把带重叠处理的版本叫 memmove笔试里能主动提一句「这就是 memmove 的实现思路」比闷头写完更讨巧。2.2 大小端、位运算与结构体对齐一张表算清 sizeof大小端判断几乎年年出现写法有联合体和指针强转两种联合体更稳妥不会被编译器优化掉。位运算常考清零、置位、取反三件套以及用宏封装寄存器读写。这两类题属于送分题写不完整就太亏。#include stdint.h /* 用联合体判断大小端低地址存低字节即为小端 */ int is_little_endian(void) { union { uint32_t v; uint8_t b[4]; } u; u.v 0x01020304; return u.b[0] 0x04; } #define BIT_SET(x, n) ((x) | (1U (n))) /* 置位 */ #define BIT_CLR(x, n) ((x) ~(1U (n))) /* 清零 */ #define BIT_GET(x, n) (((x) (n)) 1U) /* 取值 */结构体对齐是另一类必考计算题规则只有两条每个成员的偏移必须是自身对齐数的整数倍结构体总大小必须是最大对齐数的整数倍。结构体定义64 位默认对齐sizeof原因struct A { char a; int b; };8a 占 1 字节后补 3 字节让 b 落在 4 的倍数上struct B { char a; double b; char c; };24b 必须 8 字节对齐整体还要补到 8 的倍数struct C { char a; char b; int c; };8两个 char 能挤进同一个 4 字节单元尾部再补 2 字节struct D { char a; int b; } __attribute__((packed));5取消填充按声明顺序紧排提示#pragma pack(1)会把结构体压紧代价是某些架构上访问未对齐地址会降速甚至触发异常。协议解析时常用业务结构体里别随手加。嵌入式方向的卷子偶尔会追问 SPI 的硬件片选与软件片选差别硬件片选由控制器在收发前后自动拉低拉高时序稳定、几乎不占 CPU软件片选要自己操作 GPIO一旦被中断打断就可能提前释放片选从机一多就更容易出错。2.3 指针与内存分析题的答题模板给一段有 bug 的代码让你找问题是笔试后半段的常客。错误类型其实很集中指针释放后继续使用、malloc 结果不判空、函数返回栈上数组地址、数组下标写成造成越界、结构体浅拷贝导致 double free。答题时按「定位行号、说明后果、给出改法」三步写比笼统说一句「这里有内存问题」拿分高得多。char *get_name(void) { char buf[16]; strcpy(buf, uniview); /* buf 在栈上函数返回后这段空间已经失效 */ return buf; /* 悬垂指针调用方拿到的是被回收的栈地址 */ }标准改法有两种改成static char buf[16];让生命周期延长或者由调用方传入缓冲区并附带长度参数。前者线程不安全后者更通用能说出这个取舍就是加分项。内存泄漏题则要能报出检测手段开发阶段用valgrind --leak-checkfull ./a.out线上用grep VmRSS /proc/pid/status观察常驻内存是否单调上涨。3. Linux 系统编程与网络协议笔试从 fork 到 RTSP 的落地复现3.1 fork/exec 与线程五个必考对比点进程和线程的区别几乎被答烂了面试官于是换角度问写时复制怎么发生的、子进程退出后资源谁回收、多线程里 errno 是不是共享、fork 之后父进程的锁是什么状态、线程栈默认多大。这几个点答得出来才说明真写过代码而不是背过八股。维度进程线程地址空间独立fork 后靠写时复制共享只读页共享一处越界全进程一起崩通信方式管道、共享内存、消息队列、socket全局变量加锁、条件变量创建开销大需要复制页表和文件描述符表小默认栈 8MB可用ulimit -s调调度单位资源分配单位CPU 调度单位崩溃影响通常只影响自身整个进程一起挂掉注意多线程程序里调 fork 之后子进程只能调用异步信号安全的函数。子进程里再去碰父进程持有的互斥锁很容易直接死锁。3.2 epoll 服务端的最小可跑骨架视频平台的接入服务基本是 epoll 加线程池的形态笔试让你写个 epoll 骨架一点也不奇怪。核心就三步epoll_create1建实例、epoll_ctl注册事件、epoll_wait收事件。把这三步写对再补一句水平触发和边缘触发的区别这道题就完整了。#include sys/epoll.h #include unistd.h #include stdio.h #define MAX_EVENTS 64 int main(void) { int epfd epoll_create1(0); /* 参数传 0语义上比老的 epoll_create(1) 更清楚 */ struct epoll_event ev, events[MAX_EVENTS]; ev.events EPOLLIN; /* 关注可读用边缘触发要加 EPOLLET 并把 fd 设成非阻塞 */ ev.data.fd 0; /* 这里用标准输入演示实际替换为 listen_fd */ epoll_ctl(epfd, EPOLL_CTL_ADD, 0, ev); for (;;) { int n epoll_wait(epfd, events, MAX_EVENTS, -1); /* -1 表示永久阻塞直到有事件 */ for (int i 0; i n; i) { if (events[i].data.fd 0) { char buf[128] {0}; ssize_t r read(0, buf, sizeof(buf) - 1); if (r 0) { /* 对端关闭或出错摘除并关闭 fd */ epoll_ctl(epfd, EPOLL_CTL_DEL, 0, NULL); continue; } printf(recv: %s, buf); } } } }参数说明epoll_wait第四个参数是毫秒超时0立即返回、-1永久阻塞events数组长度决定单次最多返回多少就绪事件生产环境按并发量给到 1024 以上EPOLL_CTL_DEL时旧版本内核要求传非空指针踩过这个坑的人不少。水平触发只要缓冲区有数据就一直通知写起来简单边缘触发只在状态变化时通知一次必须循环读到EAGAIN否则事件就丢了这是最常见的现场事故。3.3 TCP 与 RTSP视频岗特有的协议落点网络部分除了三次握手、四次挥手、TIME_WAIT 过多怎么调参数视频方向的岗位还会问 RTSP 的交互流程。RTSP 本身是文本协议负责控制真正传视频的是 RTP通常跑在 UDP 上丢包了靠上层重传或者干脆丢帧。把「控制面与数据面分离」这句话讲出来层次立刻就出来了。方法方向作用DESCRIBE客户端 → 服务端取回 SDP拿到编码格式、分辨率、媒体端口SETUP客户端 → 服务端建立会话协商 RTP/RTCP 走 TCP 还是 UDPPLAY客户端 → 服务端开始推流服务端回 RTP-Info 给出起始序列号PAUSE客户端 → 服务端暂停播放会话保持不断开TEARDOWN客户端 → 服务端结束会话释放服务端资源被追问 UDP 丢包怎么办时可以按代价从低到高说先靠 RTCP 反馈做丢包统计再让接收端发 NACK 请求重传关键帧丢失时发 PLI/FIR 请求编码器立刻出一帧 I 帧网络实在差就退回 TCP 隧道传输。这套答法比单说一句「UDP 不可靠」有说服力得多。4. 技术面项目环节用一张软件架构图把视频管理平台讲透4.1 项目讲述的三段式背景、我的模块、量化结果面试官手上不止你一份简历项目讲得散是最容易挂的原因。我一般建议按三段来一句话讲背景和系统规模三句话讲自己负责的模块和关键技术决策一句话给量化结果。比如「做一个接入两千路摄像机的视频管理平台我负责流媒体转发模块把单机转发能力从 200 路提到 600 路首帧延迟压到 500 毫秒以内」。数字不用多但每一个都要经得起追问否则宁可不报。4.2 软件架构图怎么分层设备接入到客户端的五层被要求画一张软件架构图时别一上来就堆组件名。视频管理平台有相对固定的分层从上到下讲一遍面试官立刻能判断你做过真实系统而不是课程设计。层次职责常见技术展示层实时预览、录像回放、告警弹窗Web 前端、C/S 客户端业务层设备管理、权限、录像计划、告警联动微服务或单体后端媒体层拉流、转封装、转发、按需分发信令RTSP/RTP、GB28181、WebRTC接入层设备注册、心跳保活、私有协议适配ONVIF、厂商 SDK、接入网关存储层录像切片、索引、磁盘配额与回收对象存储、块存储、本地文件系统讲的时候顺手点一下数据流向设备推流到接入层媒体层按订阅关系把流转发给客户端录像落盘走存储层业务层只碰信令不碰视频数据。这个「信令与媒体分离」的设计是明确的加分项可以顺势聊到扩容方式和故障隔离范围也能自然引出下一节的量化指标。4.3 遇到海康 VM 等同类软件的对比追问怎么接面试官有时会问「你用过海康 VM 吗和你们做的有什么区别」。这类问题的坑在于踩一捧一正确姿势是先承认对方产品的成熟度再从自己项目的约束出发讲差异客户规模、私有协议适配量、部署环境是否要求内网离线运行和国产操作系统适配、二次开发接口的开放程度。落到具体点上比如坦白「我们的优势是私有设备协议多、能对接老设备弱项是客户端体验和大规模级联」态度和判断力都在里面比硬吹安全。4.4 量化指标把「我参与了」换成可验证的数字项目里能报的指标就那么几类并发路数、端到端延迟、QPS、内存占用、CPU 占用、崩溃率、单机容量。报之前先想清楚口径被追问「这个数怎么测出来的」必须答得上。命令行统计是最容易复现的方式也最容易在现场演示。# 统计与 RTSP 默认端口处于 ESTABLISHED 的连接数粗略反映当前并发拉流路数 ss -tn state established ( sport :554 or dport :554 ) | tail -n 2 | wc -l # 采样进程常驻内存观察是否有持续上涨趋势 for i in $(seq 1 10); do grep VmRSS /proc/$(pgrep -n media_server)/status sleep 5 done第一条命令按源端口或目的端口过滤连接tail -n 2去掉表头行wc -l数行数由于 RTSP 的 RTP 数据会另开端口这个数字只能算下限面试时主动把这个局限说清楚反而显得可信。第二条每 5 秒采一次VmRSS连采十次能看出趋势比只报一个瞬时值有说服力得多。5. 场景设计与排错题双机热备软件、数据库同步软件与抓包定位5.1 双机热备的两种模式与心跳、VIP 设计场景题里高频出现的是「两台服务器怎么保证服务不中断」。先说结论主备模式实现简单、数据一致性容易保证适合数据库和录像索引这类有状态的组件双活模式资源利用率高但要求应用无状态或者能把状态外置到共享存储与分布式缓存。心跳最好用独立网线直连不要和业务流量挤同一条链路否则业务一拥堵心跳就误判主备来回切反而更糟。#!/bin/bash # 双机热备心跳探测连续 3 次失败才切换避免网络抖动导致主备反复漂移 FAIL0 for i in $(seq 1 3); do if ! curl -sf -m 2 http://10.10.10.10:8080/health /dev/null; then FAIL$((FAIL 1)) fi sleep 1 done if [ $FAIL -ge 3 ]; then echo switchover # 生产环境对接 keepalived 的 notify 脚本或自研仲裁模块 else echo keep fi参数说明-s是静默模式不打印进度和错误-f让 HTTP 4xx/5xx 也返回失败码否则接口挂了但返回 500curl依然认为成功-m 2是 2 秒超时防止探测本身被卡住。切换动作一般由 keepalived 或自研仲裁进程执行靠 VIP 漂移让客户端无感。脑裂场景必须靠第三方仲裁来判定谁是主常用手段是网关探测、共享存储锁或者一台独立的心跳节点。5.2 数据库同步软件的同步链路怎么讲被问到「两台机器的数据怎么同步」时答全量加增量是基本盘先做一次全量快照再用增量日志追平。MySQL 系用 binlogPostgreSQL 用逻辑复制槽文件类数据用 rsync 的增量算法或对象存储的版本号。回答里要主动提三个坑主键冲突、DDL 变更导致同步中断、延迟监控。延迟可以用SHOW SLAVE STATUS里的Seconds_Behind_Master看或者对比主从记录里的时间戳字段。提示跨机房同步别用强一致协议硬扛网络抖动会直接拖垮写入性能。按业务容忍度选异步或半同步并且给同步链路单独配监控和告警别等业务方发现数据不对才回头查。5.3 用科来抓包软件和 tcpdump 定位一次断流面试官描述「客户端看着看着黑屏了」这种故障让你说排查思路。标准路径是自下而上先确认是单路还是全部、再看服务端日志、然后抓包看链路。服务端用 tcpdump 抓最方便客户端侧用科来抓包软件看更直观因为它能把 RTSP 会话按流还原出来比逐包看十六进制舒服得多。# 抓取与指定客户端之间的 RTSP/RTP 流量限制文件大小避免写满磁盘 tcpdump -i eth0 -s 0 -w /tmp/rtsp.pcap \ host 192.168.1.50 and (port 554 or portrange 50000-50100) \ -C 20 -W 5 # 抓完先确认会话有没有正常收尾 tcpdump -r /tmp/rtsp.pcap -nn -A | grep -E DESCRIBE|SETUP|PLAY|TEARDOWN参数说明-s 0抓完整包长而不是默认截断-w写文件便于用 Wireshark 或科来打开分析-C 20 -W 5表示每个文件 20MB、最多轮转 5 个加起来封顶 100MB。判定思路很直接如果只有 RTP 断了而 RTSP 会话还在多半是丢包或者码率突增如果连 TEARDOWN 都没发、TCP 直接 FIN那就是进程崩了或链路断了下一步该去看服务端有没有 core 文件。5.4 银河麒麟安装软件命令与依赖排查国产化适配是这类公司绕不开的考点尤其是部署到银河麒麟等国产操作系统上的场景。包管理看着像 CentOS 那一套实际用 deb 还是 rpm 取决于具体发行版动手前先用命令确认别凭印象选包。cat /etc/os-release # 确认发行版和版本号 uname -m # 确认 CPU 架构aarch64 与 x86_64 的包不通用 sudo apt install -y ./pkg.deb # deb 系本地安装自动拉取依赖 sudo rpm -ivh pkg.rpm # rpm 系安装缺依赖时 --nodeps 只是绕过检查不解决问题 ldd ./media_server | grep not found # 查动态库缺失比翻报错日志快依赖问题的定位顺序是先ldd看缺哪个 so再用find / -name libxxx.so*确认库里到底有没有这个文件最后检查LD_LIBRARY_PATH和/etc/ld.so.conf.d/里有没有配上路径配完执行ldconfig刷新缓存。Windows 客户端还涉及驱动问题如果目标机器上提示驱动数字签名无法验证测试阶段可以临时开启测试模式正式交付必须换成签名过的驱动否则装不上就是装不上没有别的办法。6. 用软件设计师中级真题做自测三轮复盘的具体做法6.1 第一轮按模块限时刷题标注错因软件设计师中级真题的价值不在于和宇视笔试重合而在于它把数据结构、操作系统、网络、数据库、软件工程这几块铺得足够全适合用来查漏。做法是按模块限时刷每道错题只标一个错因概念不清、审题失误、计算错误、完全不会。四类错因对应完全不同的补救动作全混在一起看等于白刷。概念不清就回去翻教材对应章节审题失误就练圈关键词计算错误就专门练对齐、校验、信道这几个题型完全不会的题才值得抄进错题本。6.2 第二轮口述式自测把每道题讲出声笔试会做不等于面试会讲。第二轮把错题和项目相关的高频题拿出来掐表两分钟对着空气讲一遍讲不顺的地方就是没真懂的地方。下面这张表可以照着过一遍每一项都要能用三句话答完才算过关。考点自测问题合格标准C 内存memcpy 与 memmove 差在哪说清重叠处理与返回值的作用进程线程线程栈默认多大、怎么改提到 8MB 与ulimit -s网络TIME_WAIT 过多怎么处理从四次挥手原因讲到内核参数方向视频协议RTSP 与 RTP 各管什么控制面与数据面分开讲高可用主备切换怎么防脑裂提到第三方仲裁与独立心跳链路国产化麒麟上装包第一步做什么先确认发行版与 CPU 架构6.3 第三轮全真模拟与反问清单第三轮按真实时间做一整套笔试卷手写代码部分改用纸笔故意去掉编辑器的补全和报错提示看看自己能不能一次写对——这一步能暴露大量平时被 IDE 兜住的低级错误。面试部分准备三到五个反问问题要指向团队而不是福利比如这个岗位的软件主要跑在哪些形态的设备上、新人的代码评审流程是怎样的、团队现在用自研还是开源方案做媒体转发、录像存储是按项目定制还是统一组件。反问的质量往往比你答对最后一道算法题更能留下印象。简历里如果写过软件著作权、竞赛或开源贡献提前想好两句话说明自己具体做了哪一部分别让面试官追问出「这是你一个人做的吗」这种尴尬问题。本文还有配套的精品资源点击获取
返回列表