前端技术栈
1. MRN(Mobile React Native)
- 定义:基于React Native的移动端开发框架,支持跨平台(iOS/Android)开发,通过JavaScript编写原生组件。
- 特点:
- 高性能:直接调用原生API,接近原生应用的体验。
- 热更新:无需应用商店审核即可推送更新。
- 生态丰富:兼容React生态(如Redux、React Router)。
- 示例:Facebook、Instagram等应用的部分模块采用MRN开发。
2. H5框架
- 定义:基于HTML5技术的跨平台开发框架,如Ionic、Framework7,用于构建移动端Web应用或混合应用
- 特点:
- 跨平台:一套代码适配多端(Web/iOS/Android)。
- 开发效率高:利用Web技术栈(HTML/CSS/JS)。
- 依赖WebView:性能略低于原生应用25。
- 示例:Ionic开发的医疗管理应用,支持离线数据同步。
3. MachPro
- 定义:企业级全栈前端框架,整合UI组件库、状态管理和构建工具,适用于复杂后台系统1。
- 特点:
- 模块化:支持微前端架构,便于团队协作。
- 内置工具链:集成代码生成、自动化测试。
- 高性能:虚拟DOM优化和懒加载1。
- 示例:某金融系统的风控管理平台采用MachPro实现动态表单和实时图表。
4. MMP(Mini Program Platform)
- 定义:小程序开发框架(如微信、支付宝小程序),提供封闭的运行时环境和API2。
- 特点:
- 轻量化:无需安装,即用即走。
- 平台限制:依赖宿主App(如微信)的API能力。
- 快速迭代:支持灰度发布和A/B测试2。
- 示例:美团外卖小程序使用MMP框架实现订单实时跟踪。
对比总结
框架 | 技术栈 | 适用场景 | 性能 |
---|---|---|---|
MRN | React Native | 高性能跨平台App | 接近原生 |
H5 | HTML5/JS/CSS | 轻量级Web应用或混合App | 中等 |
MachPro | 全栈整合 | 复杂企业级后台系统 | 高 |
MMP | 小程序语法 | 平台内轻应用(如微信生态) | 依赖宿主环境 |
插件
Wappalyzer
用途:分析网站使用的技术栈。它可以检测出服务器类型、编程语言、JavaScript 框架、数据库、CMS 系统等。
对 Java 开发者的用途:当你看到一个网站时,可以用它来快速判断其后台是否是 Java 技术(如 Tomcat, Jetty, Spring)驱动的,用于技术调研和学习。
Octotree
- •用途:当你浏览 GitHub 上的 Java 项目时,这个插件会在左侧提供一个类似 IDE 的文件树视图,让你可以轻松地浏览项目结构,跳转文件,而无需不停地点击进入文件夹。
- •**为什么需手机开发者选项/工程模式:
Android: 启用开发者选项,可以看到实时网速、Wi-Fi查看信号强度(RSSI)。
iOS: 拨号盘输入*3001#12345#*进入Field Test模式,可以查看RSRP等真实信号值。要**:极大地提升了在 GitHub 上阅读和探索开源 Java 项目源码的效率。
杂记
正向测试 (Positive Testing)
目标:验证系统在正常、有效的输入和条件下,是否能够按照需求规格正确工作。
思想:“Happy Path” —— 用户按照预期的方式使用功能。
关注点:功能是否实现,业务逻辑是否正确。
逆向测试 (Negative Testing)
目标:验证系统在无效、异常的输入或用户操作下,是否能够优雅地失败,而不是崩溃或产生不可预知的行为。
思想:用户会以各种意想不到的错误方式使用系统。
关注点:系统的健壮性、错误处理能力、用户体验(友好的错误提示)。
异常测试 (Edge/Corner Case Testing)
目标:验证系统在边界条件或极端情况下的行为。
思想: bugs 最喜欢藏在边界附近。
关注点:系统的稳定性和逻辑完整性。它通常是逆向测试的一个子集,但更侧重于“边界”。
具体示例:用户登录功能
假设我们有一个简单的用户登录功能,要求如下:
用户名:6-20位字符(只能使用字母、数字、下划线)
密码:8-16位字符(至少包含字母和数字)
登录成功则跳转到首页,失败则提示具体错误信息。
- 正向测试用例 (Positive Test Cases)
用例编号
测试描述
输入数据
预期结果
POS-LOGIN-001
使用正确的用户名和密码登录
用户名: test_user123密码: pass123word
登录成功,跳转到首页
- 逆向测试用例 (Negative Test Cases)
用例编号
测试描述
输入数据
预期结果
NEG-LOGIN-001
用户名为空
用户名: `` (空) 密码: pass123word
提示“用户名不能为空”
NEG-LOGIN-002
密码为空
用户名: test_user123密码: `` (空)
提示“密码不能为空”
NEG-LOGIN-003
用户名不存在
用户名: non_existent_user密码: anypassword
提示“用户名或密码错误” (不明确提示是用户名错误,出于安全考虑)
NEG-LOGIN-004
密码错误
用户名: test_user123密码: wrongpassword
提示“用户名或密码错误”
NEG-LOGIN-005
用户名格式错误(包含特殊字符)
用户名: test-user@密码: pass123word
提示“用户名格式不正确,只能使用字母、数字、下划线”
NEG-LOGIN-006
密码格式错误(纯数字)
用户名: test_user123密码: 12345678
提示“密码强度不足,需包含字母和数字”
- 异常/边界测试用例 (Edge Case Test Cases)
用例编号
测试描述
输入数据
预期结果
EDGE-LOGIN-001
用户名长度在边界上(6位)
用户名: abc123(6位) 密码: pass123word
登录成功
EDGE-LOGIN-002
用户名长度在边界上(20位)
用户名: abcdefghij1234567890(20位) 密码: pass123word
登录成功
EDGE-LOGIN-003
用户名长度刚超过边界(21位)
用户名: abcdefghij12345678901(21位) 密码: pass123word
提示“用户名长度需在6-20位之间”
EDGE-LOGIN-004
密码长度在边界上(8位)
用户名: test_user123密码: pass1234(8位,含字母和数字)
登录成功
EDGE-LOGIN-005
密码长度刚超过边界(17位)
用户名: test_user123密码: thisisaverylongpass1(17位)
提示“密码长度需在8-16位之间”
EDGE-LOGIN-006
SQL注入攻击尝试
用户名: ‘ OR ‘1’=’1’–密码: anything
登录失败,提示“用户名或密码错误”,且后端数据库不应报错或被执行
EDGE-LOGIN-007
XSS攻击尝试
用户名: `` 密码: anything
输入应被过滤或转义,页面不弹出警告框
三、设计技巧与总结
需求分析是基础:彻底理解业务需求和功能规格说明(SRS),从中提取出所有的规则、约束和条件。
等价类划分和边界值分析:这是设计正向、逆向、异常用例最核心的技术。
等价类:将输入域划分为若干集合,从每个集合中选取一个有代表性的数据进行测试。
有效等价类:用于正向测试(如:符合格式的用户名)。
无效等价类:用于逆向测试(如:为空、格式错误、类型错误)。
边界值分析:重点关注输入条件的边界(如:长度字段的“最小-1”、“最小”、“最大”、“最大+1”),用于异常测试。
考虑用户行为和异常流程:想象一个“调皮”的用户会怎么做?
快速连续点击提交按钮。
输入超长字符串。
复制粘贴特殊字符。
在网络提交过程中突然断开连接。
错误提示信息:逆向和异常测试不仅要验证系统不崩溃,更要验证错误提示是否准确、友好、安全。
自动化:正向用例通常是自动化回归测试的重点。而一些复杂的逆向和异常场景(如安全测试、性能测试)也可能需要自动化
两个标准都属于国家军用标准(Guójiā Jūnyòng Biāozhǔn, GJB),简称“国军标”。它们共同构成了中国军用软件开发和文档编制的强制性规范体系。
GJB 2786A: 关注的是软件开发过程的管理和要求。它规定了“做什么”和“做到什么程度”。
GJB 438B/C: 关注的是软件开发过程的输出物。它规定了“要写什么文档”和“文档里要写什么内容”。
可以做一个形象的比喻:
GJB 2786A 像是 “烹饪指南”,它详细规定了做一道菜(开发软件)需要经历哪些步骤(如需求分析、设计、编码、测试),每个步骤要注意什么卫生和安全标准(管理要求)。
GJB 438B/C 像是 “菜谱模板” 和 “食材清单格式”,它规定了每个烹饪步骤完成后,需要记录下什么样的文档(如需求规格说明书、设计文档、测试用例报告),并且给出了这些文档的标准格式和必须包含的内容。
分项详解
- GJB 2786A《军用软件开发通用要求》
含义:
它的前身是GJB 2786-96,A代表第一次修订版。
这个标准全面采纳了国际公认的软件工程最佳实践,并将其应用于军用领域。
它明确规定了军用软件在整个生命周期(从概念到退役)中必须遵循的过程、活动和任务。其核心是确保软件开发是受控的、可追溯的、高质量的。
核心内容(运用):
过程管理: 要求建立一套规范的软件开发流程,包括系统要求分析、软件需求分析、设计、编码与调试、测试、集成、验收与交付等阶段。
风险管理: 强调在整个生命周期中必须进行风险识别、分析和 mitigation(缓解)。
评审与审计: 规定在关键阶段节点(如需求评审、设计评审)必须进行正式的技术和管理评审,以确保质量。
配置管理: 要求对软件代码、文档等所有产出物进行严格的版本控制和变更管理。
质量保证: 要求有独立于开发团队的QA人员对过程和产品进行监督和检查。
可追溯性: 要求从系统需求->软件需求->设计->代码->测试用例之间建立双向可追溯矩阵,确保任何需求都被实现和测试,任何代码都有据可依。
谁在用?怎么用?
运用对象: 承担军用软件研制的总体单位、承研单位(软件开发方)。
如何运用:
根据GJB 2786A的要求,建立本单位的军用软件质量管理体系。
在具体项目中,严格遵循标准规定的流程开展活动。
项目管理和质量部门依据该标准对项目进行监督和审查。
它是军方(甲方)对承研单位(乙方)进行监督和验收的重要依据。
- GJB 438B《军用软件开发文档通用要求》 和 GJB 438C
含义:
这是中国军用领域最著名的文档标准之一,常被直接称为 “438文档”。
B版是较早的版本,C版(2019年发布)是最新版本。目前新项目普遍要求遵循GJB 438C。
该标准规定了在GJB 2786A定义的软件开发过程中,需要产生的各类文档的种类、内容要求和编写规范。
核心内容(运用):
文档体系: 标准定义了一套完整的文档体系,通常包括但不限于:
《软件需求规格说明》(SRS)
《软件设计文档》(SDD): 包括概要设计和详细设计。
《软件测试计划》
《软件测试说明》
《软件测试报告》
《软件用户手册》
《软件配置管理计划》
《软件质量保证计划》
内容模板: 对每一种文档,标准都提供了非常详细的章节结构和内容要求,告诉编写者每一章应该写什么。例如,《软件需求规格说明》中必须包含功能需求、性能需求、接口需求、安全性需求等。
谁在用?怎么用?
运用对象: 软件开发人员、系统工程师、测试工程师、技术文档工程师。
如何运用:
在项目启动时,根据项目类型和合同要求,从GJB 438C中剪裁出本项目需要编写的文档清单(不是所有文档都是必须的)。
在开发过程中,相关人员按照标准提供的模板和要求编写相应的文档。
这些文档是开发过程的记录,是阶段评审的输入,也是最终交付物的重要组成部分。软件交付时,必须同时交付全套符合要求的文档。
军方验收时,“文实相符”(文档与软件实际功能相符) 是一项极其重要的检查项。
两个标准的关系与协同运用
过程与产物的关系: GJB 2786A规定了“做”的过程,GJB 438B/C规定了“记”的要求。2786A的每一个关键活动,其输出通常都对应着一份或多份438文档。
例如:完成了“软件需求分析”活动(2786A要求),就要产出《软件需求规格说明》(438要求)。
项目实践中的流程:
依据 GJB 2786A 管理项目流程。
在流程的每个阶段,依据 GJB 438C 编写相应的文档。
用文档来证明流程得到了有效执行,并作为下一阶段活动的输入。
最终,通过完整的文档包来证明软件是按要求、按流程开发的,是可靠、可信的。
总结
GJB 2786A 和 GJB 438B/C 是中国军用软件研制领域的基石性标准,具有强制性。
它们的目的是确保军用软件的高质量、高可靠性和高安全性,满足国防装备的严苛要求。
对于军工行业从业者来说,理解和熟练运用这两个标准是基本要求。整个项目的管理和技术活动基本都是围绕着满足这两个标准的要求来展开的。
GJB 438C 相比B版,更加灵活,支持迭代开发模型,并优化了文档结构,是现代军用软件开发的首选
广告召回流程
1:用户打开页面-》业务方系统-》2:请求广告-》网关-》3:流量分发-》业务层-》4:检索广告-》检索层-》5:广告召回-》业务层-》返回业务层结果-》网关-》返回广告-》业务方系统-》8:加载广告-》用户手机-》9:打点计费-》计费系统-》10:投放上下线-》广告数据-》引擎索引-》索引层
客户端测试责任范围
客户端(广告侧+自然侧):
核心逻辑:
广告请求:请求时机(首次、刷新、翻页等),请求内容(参数)
展示/渲染:广告标(时候展示、展示样式),样式,交互
计费埋点:上报时机,上报内容(计费上报字段)
灵犀埋点:上报时机,上报内容(uuid,dpid等)
页面跳转:schema链接,跳转锚点
服务端(自然侧):
广告请求:广告请求(参数),翻页请求(第二页,最后一页),请求个数(一页个数)
自然与广告merge逻辑:合并代码逻辑,位次代码逻辑(纯广告,固定位,灵活位次,浮动位),位次实验逻辑(不仅仅位次实验,有其他实验进行补充),刷新代码逻辑(页面刷新广告请求),计费字段拼接
QCPS是一种以“按实际销售效果付费”为核心的广告计费模式,强调广告主仅需为实际达成的有效销售(如订单成交)支付费用,通常与转化质量挂钩
与CPA(按行动付费)类似,但更聚焦于“高质量转化”(如剔除无效订单)
oCPX是“优化版按X付费”的统称,其中“X”代表传统计费模式(如CPC、CPM、CPA等),通过算法动态优化广告投放,以达成预设的转化成本目标
客户端测试 &服务端测试区别
测试对象
用户直接交互的界面和逻辑
- Web: 浏览器中的网页 (HTML, CSS, JavaScript)
- App: 安装在手机上的应用程序 (Android, iOS)
- 桌面应用: 如PC软件
应用程序的后台核心
- 服务器程序 (如用Java, Python, Go等编写的API)
- 数据库 (MySQL, Redis等)
- 其他中间件和服务
核心目标
确保用户体验良好
- 功能符合预期
- 界面美观易用
- 运行流畅稳定
确保业务逻辑正确、数据安全、服务稳定
- 数据处理准确
- 性能高效可靠
- 系统安全无漏洞
主要关注点
1. UI测试: 布局、字体、颜色、元素对齐等是否与设计稿一致。
2. 功能测试: 页面上的按钮、链接、表单、滑动等交互是否正常工作。
3. 兼容性测试:
- 浏览器兼容性 (Chrome, Firefox, Safari, Edge等)
- 操作系统兼容性 (Windows, macOS, Linux)
- 设备兼容性 (不同型号手机、平板、屏幕尺寸、分辨率)
- APP还需关注系统版本(Android/iOS版本)和硬件(摄像头、GPS等)兼容。
4. 性能测试: 前端性能,如页面加载速度、渲染速度、帧率(FPS)、内存占用等。
5. 交互体验: 动画是否流畅,操作反馈是否及时。
1. API接口测试: 核心中的核心。测试接口能否正确接收请求、返回预期响应、处理异常参数、遵守协议(如RESTful)。
2. 业务逻辑测试: 验证后台处理的业务规则是否正确。例如,支付流程的计算、订单状态的流转。
3. 数据库测试:
- 数据是否被正确增删改查 (CRUD)。
- 数据库 schema 设计是否合理。
- 查询语句是否高效,有无慢查询。
4. 性能测试: 后端性能,如接口响应时间、吞吐量(每秒处理请求数)、并发用户支持能力、系统资源消耗(CPU、内存)。
5. 安全测试: - SQL注入
- 身份认证和授权漏洞
- 数据泄露
- 加密机制
- 防重放攻击等。
6. 集成测试: 测试与其他第三方服务(如支付网关、短信服务、地图服务)的集成是否稳定。
常用工具
自动化: Selenium, Cypress, Playwright, Appium, Jest, Puppeteer
性能: Lighthouse, Chrome DevTools
兼容性: BrowserStack, Sauce Labs
API测试: Postman, JMeter, Rest-Assured
性能/压力测试: JMeter, LoadRunner, Gatling
安全测试: OWASP ZAP, SQLMap
单元测试: JUnit, TestNG, Pytest
测试环境
依赖多种浏览器、操作系统和真机设备。
依赖服务器环境(测试服、预发布服),需要配置数据库和网络。
三、一个例子来说明(以电商“加入购物车”功能为例)
客户端测试关注:
点击“加入购物车”按钮,按钮颜色是否会变化?是否有“已加入”的动画或提示?
购物车图标上的数字是否立即更新?
在不同手机浏览器上(如iPhone的Safari和安卓的Chrome),这个功能是否都正常?
页面加载慢吗?是因为图片太大还是JS文件加载慢?
服务端测试关注:
客户端点击按钮后,发出的 API请求 格式是否正确?(例如:POST /api/cart {item_id: 123, quantity: 1})
服务端是否正确接收了请求?是否正确地将商品ID和用户ID关联起来并存入数据库?
如果用户没登录,是否返回了正确的错误码(如401)?
如果库存为0,是否返回了“库存不足”的提示?
这个“加入购物车”的API接口,能否在1秒内处理1000个并发请求?
请求参数中尝试传入item_id: ‘ OR 1=1 –,是否会引发SQL注入漏洞?
总结与核心要点
分工不同:客户端测试是面向用户的,服务端测试是面向逻辑和数据的。
技能侧重:
客户端测试需要更了解前端技术(HTML/JS)、用户体验和多环境兼容。
服务端测试需要更深入的业务逻辑理解、数据库操作知识、API测试技巧和安全/性能测试能力。
一、音视频编解码(Codec)核心知识
1. 为什么需要编解码?
原始的音视频数据量巨大,无法直接存储和网络传输。
示例:一首3分钟的无压缩立体声音频,文件大小约 30MB。一秒未压缩的1080p/30fps视频,数据量可达 100MB。直接存一部电影需要几百个G,根本无法流畅在线观看。
2. 编解码是什么?
编码(Encode):利用特定的压缩算法,将原始音视频数据转换为体积小得多的码流(Bitstream)的过程。为了传输和存储。
解码(Decode):将压缩后的码流重新解压缩,转换为可以播放的原始数据的过程。为了播放和编辑。
“Codec” 一词就是 Coder(编码器) + Decoder(解码器) 的合成词。
3. 压缩的两种基本方式
无损压缩:压缩后可以100%还原原始数据。压缩率较低。常用于专业领域,如音频的FLAC,视频的Apple ProRes。
有损压缩:通过丢弃人眼/人耳不敏感的信息,获得极高的压缩率。绝大多数网络视频和流媒体都采用有损压缩,如H.264, AAC。
4. 视频编码原理(简要)
视频压缩的核心是消除冗余。
空间冗余:一帧图像内,相邻的像素往往很相似(如蓝色的天空)。利用算法(如DCT变换)记录这些相似块,而不是每个像素点。
时间冗余:相邻帧之间,大部分内容是基本不变的(如背景)。只需记录运动物体的变化部分和运动矢量即可,这就是 P帧 和 B帧 的原理,它们参考前面的 I帧(关键帧,完整画面)。
I帧(Intra-frame):关键帧,包含完整的图像信息,不参考其他帧。是解码的起点和参考点。
P帧(Predicted-frame):预测帧,只记录与前一帧(I帧或P帧)的差异信息。体积比I帧小。
B帧(Bidirectional-frame):双向预测帧,记录与前后帧的差异,压缩率最高。
二、常见的视频编码格式(Codec)
编码格式
发布方/性质
特点与应用
备注
H.264 / AVC
MPEG, ITU-T
目前最通用、兼容性最好的编码。在保证良好画质下,压缩率高。广泛应用于在线视频、蓝光碟、广播电视、视频会议等。
王者级别,几乎所有设备都支持。
H.265 / HEVC
MPEG, ITU-T
H.264的继任者,压缩效率比H.264高约50%(同等画质下体积减半)。支持4K/8K超高清。但专利授权复杂,兼容性略差于H.264。
需要更强的硬件解码能力。
AV1
开放媒体联盟 (AOM)
开源、免版权费的下一代编码格式。压缩效率与H.265相当甚至更好。被YouTube、Netflix、Facebook等巨头大力推广,用于节省带宽成本。
未来趋势,但需要新硬件支持才能流畅解码。
VP9
开源、免版权费的下一代编码格式。压缩效率与H.265相当甚至更好。被YouTube、Netflix、Facebook等巨头大力推广,用于节省带宽成本。
主要用于Web端,是AV1的前身。
MPEG-4
MPEG
早期编码,压缩效率不如H.264,但现在较少见。
常见于一些老旧设备和视频。
三、常见的音频编码格式(Codec)
编码格式
特点与应用
备注
AAC
目前最主流的音频编码。相比MP3,在相同码率下音质更好。是H.264视频的“标准搭档”。
苹果 iTunes、YouTube、各大流媒体平台都在用。
MP3
最著名的有损音频编码。极大地推动了数字音乐的发展,但现在逐渐被AAC取代。
Opus
非常高效的开源编码,专为网络交互设计(如语音聊天、直播)。在低延迟和低码率下表现极佳。
是WebRTC技术的默认音频编码。
FLAC
无损音频压缩。可以完全还原CD音质,但体积比原始WAV小。
音乐发烧友首选。
AC-3 (Dolby Digital)
多声道环绕声编码,常用于电影、家庭影院(5.1声道)。
四、常见的容器格式(Container)
重要:容器 ≠ 编码格式!
容器是一个“盒子”,里面可以包裹着视频流、音频流、字幕、元数据等。一个容器可以容纳多种不同编码的视频和音频。
容器格式
常见编码组合
特点与应用
MP4
视频:H.264, H.265, MPEG-4
音频:AAC, AC-3
万金油容器,兼容性极好。适用于网络传播和存储。
MKV
几乎支持所有编码格式
功能强大的开源容器。支持多音轨、多字幕、章节信息等。常用于收藏高清电影。
AVI
比较老旧,兼容性虽好但效率低
微软早期的容器格式,现在已不常用。
MOV
专业编辑常用编码(ProRes, DNxHD)
苹果公司的容器格式。常用于专业视频编辑和Mac生态系统。
WebM
视频:VP8, VP9, AV1
音频:Opus, Vorbis
为Web而生的开放容器格式。由Google主导,旨在提供高质量、免版税的网络视频。
TS
视频:H.264, H.265
音频:AAC, AC-3
传输流容器。常用于数字广播电视和实时流媒体(如直播),抗误码能力强。
五、分辨率(Resolution)
分辨率指视频画面包含的像素数量,通常表示为 宽度像素数 × 高度像素数。分辨率越高,画面越清晰细腻。
名称
分辨率 (宽x高)
常见叫法/应用
SD
720 × 480 (NTSC) 或 720 × 576 (PAL)
标清,早期DVD标准。
HD
1280 × 720
高清,是高清的入门标准。
Full HD (FHD)
1920 × 1080
全高清,目前最主流的标准。蓝光碟、大多数网络视频的标准。
2K
2560 × 1440
Quad HD (QHD),常见于高端手机和显示器。
4K / UHD
3840 × 2160
超高清,主流高端标准。电视、电影、专业视频领域普及。
8K / FUHD
7680 × 4320
8K超高清,是4K的4倍。目前处于前沿阶段,主要用于专业拍摄和顶级显示设备。
注:电影行业的2K(2048×1080)和4K(4096×2160)与消费电子领域的标准略有不同。
六、帧率(Frame Rate, FPS)
帧率指每秒显示的图像帧数,单位是FPS(Frames Per Second)。帧率越高,画面越流畅,动态细节越清晰。
帧率 (FPS)
常见应用场景
24 fps
电影感的标准帧率。人眼感觉最自然、有艺术感的帧率。
25 fps
PAL制式广播电视标准(中国、欧洲等地区)。
30 fps
NTSC制式广播电视标准(美国、日本等地区),也是早期网络视频的常见标准。
60 fps
高帧率。非常适合拍摄高速运动场景(体育赛事、游戏录像),能提供极其流畅的观感。
90/120/144 fps+
超高帧率。主要用于高端游戏(电竞显示器)和部分超高规格的视频拍摄,追求极致的流畅性。
总结与关联
选择编码格式是在文件体积和视频质量之间做权衡。
选择容器是为了兼容性和功能(如多字幕)。
分辨率决定了画面的清晰度。
帧率决定了画面的流畅度。
一个典型的视频文件可能是:一个MP4容器(.mp4),里面封装了用H.264编码的视频流和用AAC编码的音频流,分辨率是1920x1080(Full HD),帧率为30fps。
当然,准备音视频测试面试时,面试官会从基础概念、测试方法论、工具使用、问题排查和编程能力等多个维度进行考察。以下是分类整理的高频面试题及回答思路,可以帮助你更好地准备。
一、基础概念与原理题
这类问题考察你对音视频领域核心知识的理解深度。
解释一下视频编解码的基本原理。为什么要编码?
答:核心目的是压缩。原始视频数据量巨大(举例:一幅1920x1080的未压缩图像约6MB,一秒30帧就是180MB/s)。编码通过消除空间冗余(如一帧内的蓝天)和时间冗余(如相邻帧之间不变的背景)来大幅减小体积,使其便于存储和网络传输。解码则是逆过程。
说说你熟悉的视频编码格式(Codec)和容器格式(Container),并说明它们的区别。
答:
编码格式:H.264/AVC(最通用)、H.265/HEVC(更高压缩率)、AV1(开源免版税)。作用是压缩数据。
容器格式:MP4(通用)、MKV(功能多,多用于本地)、TS(流媒体常用)。作用是打包,将视频流、音频流、字幕、元数据等封装在一起。
关键区别:Codec是压缩算法,Container是包装盒。一个MP4文件里的视频可以是H.264编码,音频可以是AAC编码。
解释一下分辨率、帧率(FPS)、码率(Bitrate)的含义和它们之间的关系。
答:
分辨率:像素数量(如1920x1080),决定清晰度。
帧率(FPS):每秒帧数(如30fps),决定流畅度。
码率:每秒数据传输的比特数(如1Mbps),决定体积和整体质量。
关系:在编码器设置中,分辨率 ↑ + 帧率 ↑ = 所需码率 ↑。为在有限带宽下获得最佳体验,需要在三者间做权衡(即码率分配策略)。
什么是I帧、P帧、B帧?
答:
I帧:关键帧,包含完整图像信息,是解码的基准点。
P帧:参考前面的I帧或P帧,只存储与参考帧的差异信息,体积更小。
B帧:双向参考帧,参考前后帧,压缩率最高,但编解码更复杂,延迟稍高。
常见的音频编码格式有哪些?
答:AAC(最主流,用于在线视频)、MP3(经典)、Opus(低延迟,WebRTC默认)、FLAC(无损)。
二、测试方法论与思维题
这类问题考察你如何系统性地设计和执行测试。
你会从哪些维度来测试一个视频播放器/视频通话App?
答:这是一个经典问题,考察测试思维的全面性。可以从以下维度展开:
功能测试:基础播放/暂停/seek、音量调节、全屏切换、不同格式/编码的视频文件兼容性、网络切换(Wi-Fi/4G/5G)、后台播放、耳机插拔、来电中断等。
性能测试:
启动速度:首次启动、冷启动、热启动时间。
首帧时间/首帧渲染时间:点击播放到看到第一画面的时间。
播放成功率。
卡顿率:播放过程中卡顿的次数和时长。
耗电量、CPU/内存占用、发热情况。
兼容性测试:不同机型(品牌、芯片)、不同OS版本、不同分辨率/屏幕比例。
网络测试:
弱网测试:高延迟、高丢包、低带宽下的表现(是否卡顿、花屏、自动降级清晰度)。
码率自适应:网络变好时是否能无缝切换回更高清晰度。
用户体验测试:主观感受下的画质清晰度、音画同步、色彩是否正常等。
安全与稳定性:长时间播放是否崩溃、恶意文件测试等。
如何测试音画同步问题?
答:
主观测试:使用有规律口型或拍手声的测试视频,人眼观察和耳听。
客观测试:使用专业工具或开发插桩代码,在特定时间点(如拍手瞬间)在视频和音频流中打上相同的时间戳日志,分析日志计算差值。
测试点: seek后、网络抖动后、长时间播放后、不同机型上是否同步。
如何模拟和测试弱网络环境?
答:
工具:使用网络模拟工具,如Charles、Network Link Conditioner (macOS)、Facebook的ATC、Wireshark等。
模拟场景:设置不同的带宽(带宽)、延迟(latency)、丢包率(packet loss)、抖动(jitter) 参数组合。
观察指标:App是否卡顿、花屏、自动降级清晰度、延迟升高、或给出友好提示(如“网络不佳”)。
如果用户反馈“看视频很卡”,你会如何排查定位问题?
答:这考察问题排查思路。遵循从外到内、从大到小的原则:
确认现象:是某个视频卡还是所有视频卡?是特定网络下卡?是特定机型卡?
检查网络:用户网络环境如何?是否在弱网下?
查看服务端:检查CDN带宽、服务器负载是否正常。
查看客户端数据:拉取该用户的播放日志,重点关注:
卡顿日志:卡顿时长、次数。
播放器状态:当前缓冲大小、下载速度、设定的码率和实际码率。
播放策略:是否因为网络差一直在切换低清晰度?
最终定位:综合日志判断是网络原因、服务端下发策略原因还是播放器本地策略/bug。
三、工具与编程题
这类问题考察你的实践能力和自动化水平。
你用过哪些音视频测试工具?
答:
分析工具:FFmpeg/FFprobe(分析文件信息、编码格式、码率等)、Elecard StreamEye(分析视频码流,看I/P/B帧分布)、VQAnalyzer(客观画质分析)。
性能工具:Perfetto/Systrace(分析Android性能)、Instruments(分析iOS性能)、adb命令。
网络模拟工具:Charles、Wireshark、ATC。
自动化测试:Appium、Airtest。
如何用FFmpeg做一个简单的视频转码?
答:ffmpeg -i input.mp4 -c:v libx264 -c:a aac output.mp4
-i input.mp4: 指定输入文件。
-c:v libx264: 指定视频编码器为libx264(H.264)。
-c:a aac: 指定音频编码器为AAC。
output.mp4: 输出文件名。
如何用ADB命令获取Android应用的CPU占用?
答:adb shell top -n 1 | grep com.package.name
写一段Python脚本,遍历目录下的所有视频文件,并用FFprobe输出它们的时长和编码格式。
答:考察基本的脚本能力和对FFprobejson输出的解析。
import json
import subprocess
import os
video_dir = “/path/to/your/videos”
for filename in os.listdir(video_dir):
if filename.endswith((“.mp4”, “.mkv”)):
filepath = os.path.join(video_dir, filename)
cmd = f”ffprobe -v quiet -print_format json -show_format -show_streams {filepath}”
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
info = json.loads(result.stdout)
# 获取时长
duration = info['format']['duration']
# 获取视频流编码
video_codec = None
for stream in info['streams']:
if stream['codec_type'] == 'video':
video_codec = stream['codec_name']
break
print(f"File: {filename}, Duration: {duration}s, Video Codec: {video_codec}")
四、开放与项目经验题
你过去在音视频测试项目中遇到的最大挑战是什么?如何解决的?
答:(结合自身经历)示例:遇到低端机上播放4K视频卡顿严重。解决方法:通过Systrace分析发现解码器线程耗时过长。定位原因是播放器策略问题,没有根据设备性能主动降级到1080P。推动开发增加了设备性能白名单和动态降级逻辑,问题得以解决。
STAR法则:描述情境(Situation)、任务(Task)、行动(Action)、结果(Result)。
你对未来音视频技术趋势有什么了解?(如AV1、WebRTC、低延迟直播)
答:展示你的学习能力。可以聊AV1的开源和压缩效率优势及其对测试的挑战(CPU解码开销大);WebRTC在实时互动场景(视频会议、教育)的应用;HLS/DASH在点播和直播中的原理等。
一、 视频类页面详细测试点
视频页面通常用于播放课程录像、动画讲解、配音短片等。
1. 功能测试
- 核心播放功能:
- 播放/暂停、进度条拖拽、快进/快退(如双击/滑动)、音量调节、全屏/退出全屏切换是否正常。
- 清晰度切换(如720P, 1080P)、播放速度切换(0.5x, 1.0x, 1.5x, 2.0x)功能是否有效。
- 交互功能:
- 横竖屏切换时,画面是否自适应,有无黑边、拉伸或卡顿。
- 全屏模式下,手势调节音量和亮度是否生效。
- 锁屏或切换到后台,音频是否继续播放(画中画功能是否支持)。
- 视频播放时,来电、通知中断,处理是否正常(暂停播放,结束后可恢复)。
- UI与状态:
- 播放器控制栏是否自动显示/隐藏。
- 播放开始、播放中、播放结束、加载缓冲、播放错误等不同状态下的UI提示是否正确(如加载旋转图标、缓冲进度、错误重试按钮)。
- 视频标题、时长、当前播放时间显示是否正确。
- 附加功能:
- 字幕切换:如果有字幕,切换不同语言或关闭字幕是否正常。
- 弹幕功能:发送和接收弹幕是否实时,有无遮挡重要内容。
- 收藏/点赞:操作后状态是否立即更新并同步到服务器。
- 关联推荐:视频播放结束或暂停时,推荐的关联视频列表是否正确。
2. 兼容性测试
- 操作系统:覆盖主流iOS和Android版本(如iOS 14-17, Android 10-13)。
- 设备型号:不同屏幕尺寸和分辨率(刘海屏、折叠屏、平板)的适配,控制栏是否被遮挡。
- 硬件差异:不同芯片(如高通、联发科)、不同性能的设备上播放是否流畅,解码能力如何。
- 网络类型:在Wi-Fi、4G/5G、弱网(高延迟、低带宽)环境下,视频的加载速度、自动降级清晰度、卡顿处理是否合理。
3. H5 (WebView) 测试
如果视频页面是内嵌的H5:
- 内核兼容:测试不同系统WebView内核和浏览器内核(如Chrome)下的表现是否一致。
- JS接口:H5页面与Native App的通信(JSBridge)是否正常,例如全屏切换、获取设备网络状态等。
- 混合交互:H5页面内的按钮、链接调用Native功能(如登录、支付)是否正常工作。
4. 接口测试
- 视频信息接口:请求视频的元数据(标题、时长、清晰度列表、播放URL)是否正确。
- 播放地址接口:返回的M3U8或MP4地址是否有效,是否有防盗链机制(如Token、Referer校验)。
- 状态上报接口:播放、暂停、结束、卡顿、退出等行为的上报时机和数据(如播放进度)是否准确。
- 心跳/进度上报接口:是否定时向服务器发送心跳包或播放进度,用于记录学习时长和进度同步。
- 弹幕/评论接口:获取和发送弹幕/评论的API是否正常,实时性如何。
- 安全与性能:接口是否有防刷机制,响应时间是否在要求范围内。
5. 数据库测试
- 播放记录存储:观看进度、观看时长是否准确记录到本地数据库,并在不同设备间通过账号同步。
- 缓存管理:视频缓存文件是否有效存储和清理(根据App设置),避免占用过多存储空间。
- 资源关联性:视频与作业、课程、用户数据的关联关系在数据库中是否正确。
二、 音频类页面详细测试点
音频页面通常用于英语听力、课文朗读、单词发音等。
1. 功能测试
- 核心播放功能:
- 播放/暂停、进度条拖拽、快进/快退、播放速度切换(对英语学习尤其重要)。
- 后台播放:App切到后台或锁屏后,音频能否持续播放。
- 音频中断处理:来电、其他App播放音频、插入耳机等场景下,行为是否符合预期(暂停、压低音量、切换声道)。
- 交互与UI:
- 桌面控件(通知栏/锁屏界面)的播放控制是否有效。
- 播放页面的波形图或频谱显示是否正常(如果有)。
- 学习功能:
- AB循环复读:设置起点和终点进行循环播放的功能是否精准。
- 跟读模式:播放一句后自动暂停,等待用户跟读,录音并播放对比,该流程是否顺畅。
- 显示字幕(听力原文)并高亮当前播放的句子,同步是否准确。
2. 兼容性测试
- 音频通道:在蓝牙耳机、有线耳机、外放等不同输出设备间切换时,音频能否无缝切换,无爆音或延迟。
- 系统音频冲突:与系统其他音频App(如音乐播放器、地图导航)共存时,音量调节和焦点处理是否正常。
- 操作系统:同样需要覆盖主流OS版本,重点关注后台播放策略差异(如iOS和Android的后台省电限制)。
3. H5 (WebView) 测试
- 与视频类似,主要测试H5音频播放器与Native的交互,例如在后台播放时,H5能否保持活动状态(通常需要Native支持)。
4. 接口测试
- 音频信息接口:获取音频元数据(标题、原文文本、分段时间戳)是否正确。
- 音频文件接口:获取MP3等音频文件的URL是否有效。
- 跟读录音接口:上传用户录音文件的接口是否稳定,耗电量如何。
- 进度同步接口:音频播放进度的上报和同步是否准确,用于记录学习进度。
5. 数据库测试
- 播放进度:音频播放位置的本地存储和同步是否准确。
- 录音文件管理:用户跟读产生的录音文件在本地和服务器端的存储、索引和管理是否正确。
- 离线下载:如果支持下载音频离线学习,下载任务管理、文件完整性校验和存储路径是否正确。
总结与核心关注点
测试类型 | 视频类页面核心关注点 | 音频类页面核心关注点 |
---|---|---|
功能 | 播放控制、清晰度、全屏、中断恢复 | 播放控制、速度、后台播放、跟读复读 |
兼容性 | 设备适配、网络适配、解码能力 | 音频通道适配、后台策略、OS差异 |
H5 | JSBridge通信、全屏切换 | 后台播放保活、与Native交互 |
接口 | 播放地址、状态上报、防盗链 | 音频地址、录音上传、进度同步 |
数据库 | 播放记录、缓存管理 | 播放进度、录音文件管理 |
性能与体验专项测试:
- 启动速度:点击后到第一帧画面/声音出现的时间。
- 能耗:长时间播放视频/音频的电量消耗和发热情况。
- 流量:在不同清晰度下播放的流量消耗是否符合预期。
- 卡顿率:播放过程中卡顿的次数和时长。
- 崩溃率:播放器相关功能的崩溃情况。
在 Java 中反转整数数字
public class ReverseInteger {
public static int reverse(int x) {
int reversed = 0;
while (x != 0) {
// 检查是否溢出
if (reversed > Integer.MAX_VALUE / 10 ||
reversed < Integer.MIN_VALUE / 10) {
return 0; // 溢出时返回0
}
// 反转数字
int digit = x % 10;
reversed = reversed * 10 + digit;
x /= 10;
}
return reversed;
}
public static void main(String[] args) {
System.out.println(reverse(123)); // 321
System.out.println(reverse(-456)); // -654
System.out.println(reverse(120)); // 21 (前导零被忽略)
System.out.println(reverse(1534236469)); // 0 (溢出)
}
}
public class ReverseInteger {
public static int reverse(int x) {
// 处理特殊情况
if (x == 0) return 0;
// 转换为字符串并反转
String str = String.valueOf(x);
String reversedStr = new StringBuilder(str).reverse().toString();
// 处理负号
if (x < 0) {
reversedStr = reversedStr.substring(0, reversedStr.length() - 1);
}
// 处理前导零
while (reversedStr.startsWith("0")) {
reversedStr = reversedStr.substring(1);
}
// 转换回整数并处理溢出
try {
int result = Integer.parseInt(reversedStr);
return x < 0 ? -result : result;
} catch (NumberFormatException e) {
return 0; // 溢出时返回0
}
}
public static void main(String[] args) {
System.out.println(reverse(123)); // 321
System.out.println(reverse(-456)); // -654
System.out.println(reverse(120)); // 21
System.out.println(reverse(1534236469)); // 0
}
}
Java 实现数组拼接最大整数
将[234,65,9,1111]数组中的数字,拼接成最大整数,为9652341111
import java.util.Arrays;
import java.util.Comparator;
public class LargestNumber {
public static void main(String[] args) {
int[] nums = {234, 65, 9, 1111};
System.out.println(largestNumber(nums)); // 输出: 9652341111
}
public static String largestNumber(int[] nums) {
// 1. 将整数数组转换为字符串数组
String[] strArr = new String[nums.length];
for (int i = 0; i < nums.length; i++) {
strArr[i] = String.valueOf(nums[i]);
}
// 2. 自定义排序规则:比较两个字符串拼接后的结果
Arrays.sort(strArr, new Comparator<String>() {
@Override
public int compare(String a, String b) {
String order1 = a + b;
String order2 = b + a;
return order2.compareTo(order1); // 降序排序
}
});
// 3. 处理特殊情况:如果最大数字是0,则直接返回"0"
if (strArr[0].equals("0")) {
return "0";
}
// 4. 拼接排序后的字符串数组
StringBuilder sb = new StringBuilder();
for (String str : strArr) {
sb.append(str);
}
return sb.toString();
}
}
方法二:
public static String largestNumber(int[] nums) {
// 转换为字符串数组
String[] strArr = Arrays.stream(nums)
.mapToObj(String::valueOf)
.toArray(String[]::new);
// 使用Lambda表达式自定义排序
Arrays.sort(strArr, (a, b) -> (b + a).compareTo(a + b));
// 处理全0情况
if ("0".equals(strArr[0])) {
return "0";
}
// 拼接结果
return String.join("", strArr);
}