XPath查找父元素的常用写法
1. 直接父元素定位
parent::
轴:直接定位当前节点的父元素//子元素表达式/parent::父元素标签名
//input[@id=”submit”]/parent::div # 定位input的直接父div
..
简写:等同于parent::
//input[@id=”submit”]/.. # 定位input的父元素
2. 多级祖先定位
ancestor::
轴:定位所有祖先元素(包括父、祖父等)//input[@id=”submit”]/ancestor::form # 定位input所在的最外层form标签
3. 条件筛选父元素
结合属性过滤:通过子元素属性反推父元素特征
//*[@class=”container”]/child::div[input/@value=”搜索”]
说明:查找包含value=”搜索”的input元素的父级div,且该div有class=”container”
对动态生成的类名(如class="btn-12345"
),使用contains()
函数:
//button[contains(@class, ‘submit’)]/parent::div
迭代器(Iterator)
定义与使用
迭代器需实现__iter__
和__next__
方法,用于逐个生成数据。
class CountDown:
def __init__(self, start):
self.current = start
def __iter__(self):
return self
def __next__(self):
if self.current <= 0:
raise StopIteration
self.current -= 1
return self.current + 1
for num in CountDown(3):
print(num) # 输出: 3, 2, 1
应用场景:处理大数据流时节省内存
生成器(Generator)
定义与使用
生成器用yield
替代return
,自动实现迭代器协议。
def fibonacci():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
fib = fibonacci()
print([next(fib) for _ in range(5)]) # 输出: [0, 1, 1, 2, 3]
生成器表达式(惰性计算):
squares = (x**2 for x in range(10))
print(list(squares)) # 输出: [0, 1, 4, 9, ..., 81]
优势:内存效率高,适合处理无限序列
装饰器(Decorator)
基础装饰器
装饰器用于增强函数功能,不修改原函数代码。
def timer(func):
def wrapper(*args, **kwargs):
import time
start = time.time()
result = func(*args, **kwargs)
print(f"{func.__name__}耗时: {time.time()-start:.2f}秒")
return result
return wrapper
@timer
def slow_function():
time.sleep(1)
slow_function() # 输出: slow_function耗时: 1.00秒
带参数的装饰器:
def prefix_log(prefix):
def decorator(func):
def wrapper(*args, **kwargs):
print(f"[{prefix}] 执行函数: {func.__name__}")
return func(*args, **kwargs)
return wrapper
return decorator
@prefix_log("DEBUG")
def greet():
print("Hello!")
greet() # 输出: [DEBUG] 执行函数: greet → Hello!
应用场景:日志记录、权限校验、性能监控
dotenv(环境变量管理)
安装与使用
pip install python-dotenv
.env文件:
DB_HOST=localhost
DB_USER=root
DB_PASS=secret
Python代码:
from dotenv import load_dotenv
import os
load_dotenv() # 加载.env文件
print(os.getenv("DB_HOST")) # 输出: localhost
优势:避免硬编码敏感信息,支持多环境配置
match高级语法(模式匹配)
基本用法
Python 3.10+支持类似Rust的模式匹配。
def http_status(code):
match code:
case 200 | 201:
return "Success"
case 404:
return "Not Found"
case _:
return "Unknown"
print(http_status(404)) # 输出: Not Found
解构与守卫:
point = (3, 5)
match point:
case (0, y):
print(f"Y轴坐标: {y}")
case (x, 0) if x > 0:
print(f"正X轴坐标: {x}")
类匹配:
class User:
def __init__(self, name, age):
self.name = name
self.age = age
user = User("Alice", 30)
match user:
case User(name="Alice", age=age):
print(f"Alice的年龄是{age}")
应用场景:复杂数据解析、状态机
匿名函数(Lambda)
基础用法
# 排序列表中的字典
students = [{"name": "Bob", "age": 20}, {"name": "Alice", "age": 18}]
sorted_students = sorted(students, key=lambda x: x["age"])
print(sorted_students) # 按年龄升序
高阶函数结合:
# 过滤偶数
numbers = [1,2,3,4,5]
evens = list(filter(lambda x: x%2==0, numbers)) # [2,4]
优势:简洁定义一次性逻辑
魔法函数(Magic Methods)
常用魔法函数
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def __str__(self):
return f"Vector({self.x}, {self.y})"
v1 = Vector(1,2)
v2 = Vector(3,4)
print(v1 + v2) # 输出: Vector(4,6)
其他常用方法:
__len__
: 定义长度(如len(obj)
)__getitem__
: 支持索引访问(如obj[0]
)- eq: 定义相等比较(如obj1 == obj2)
自定义魔法函数
案例:实现可迭代对象
class MyRange:
def __init__(self, start, end):
self.start = start
self.end = end
def __iter__(self):
return iter(range(self.start, self.end))
for i in MyRange(1,5):
print(i) # 输出: 1,2,3,4
运算符重载:
class Complex:
def __init__(self, real, imag):
self.real = real
self.imag = imag
def __mul__(self, other):
return Complex(
self.real*other.real - self.imag*other.imag,
self.real*other.imag + self.imag*other.real
)
def __repr__(self):
return f"Complex({self.real}, {self.imag})"
c1 = Complex(1,2)
c2 = Complex(3,4)
print(c1 * c2) # 输出: Complex(-5,10)
应用场景:自定义数据类型、运算符行为
总结
特性 | 核心用途 | 典型场景 |
---|---|---|
迭代器 | 惰性遍历数据 | 大文件读取、无限序列 |
生成器 | 按需生成数据 | 斐波那契数列、实时数据流 |
装饰器 | 无侵入式扩展函数功能 | 日志、权限、性能监控 |
dotenv | 管理环境变量 | 配置分离、敏感信息保护 |
match | 复杂模式匹配与解构 | 状态码处理、数据解析 |
匿名函数 | 简短的一次性函数逻辑 | 排序、过滤、映射 |
魔法函数 | 自定义类行为,模拟内置类型 | 运算符重载、可迭代对象 |
通过合理组合这些特性,可显著提升代码的可读性和灵活性。
以下是服务端数据库测试的核心步骤、注意事项及实战案例解析,结合数据库测试的全生命周期管理:
数据库测试核心步骤
1. 测试规划与策略设计
目标:明确测试范围(功能/性能/安全)、选择工具(如JMeter、DbUnit)、搭建测试环境(与生产环境一致)
示例:使用SQL*Plus或JDBC编写连接脚本验证数据库连通性,配置测试数据生成工具(如DataFactory)模拟百万级数据
2. 功能测试
验证点:
CRUD操作:插入、查询、更新、删除数据是否符合预期
约束验证:主键唯一性、外键关联、非空约束
事务完整性:验证ACID特性(如转账事务的原子性)
-- 测试唯一约束 INSERT INTO users (email) VALUES ('test@example.com'); -- 成功 INSERT INTO users (email) VALUES ('test@example.com'); -- 应抛出唯一约束错误
3. 性能测试
方法,压力测试:模拟高并发查询(如1000线程同时查询订单表)
负载测试:逐步增加数据量(如从10万到1亿条记录),观察响应时间变化
指标:响应时间(如95%请求<200ms)、吞吐量(TPS)、资源占用(CPU/内存)
工具:JMeter、SysBench、Vitess(分库分表性能测试)
4. 安全测试
重点
SQL注入防护:验证参数化查询是否有效
SELECT * FROM users WHERE id=1 OR 1=1
应被拦截)
权限控制:测试未授权用户是否无法执行敏感操作(如DROP TABLE
# 模拟SQL注入攻击测试 malicious_input = "1' OR '1'='1" cursor.execute("SELECT * FROM users WHERE username='%s'" % malicious_input) # 应返回空结果
5. 数据一致性验证
场景
分布式事务:验证跨库操作的数据同步(如订单库与库存库的最终一致性)
备份恢复:测试数据库崩溃后数据恢复的完整性
工具:DbUnit(数据比对)、Vitess(分片数据一致性检查)
6. 测试报告与优化
输出:记录缺陷(如索引缺失导致查询慢)、性能瓶颈分析(如慢查询日志解析)
优化示例
-- 为高频查询字段添加索引 CREATE INDEX idx_user_email ON users(email);
关键注意事项
- 环境一致性
- 测试环境需与生产环境一致(如MySQL版本、硬件配置),避免“测试通过,线上报错”
- 使用Docker容器化部署数据库,确保环境可重复
- 数据隔离与清理
- 每个测试用例使用独立数据集,避免相互干扰
- 测试后自动回滚事务或清空测试表(如使用@Transactional注解)
- 覆盖全面性
- 功能测试需覆盖所有SQL操作(增删改查、存储过程、触发器)
- 性能测试需模拟真实场景(如电商秒杀的突发流量)
- 安全防护
- 禁止测试环境暴露公网,防止恶意注入
- 定期扫描数据库漏洞(如使用Nessus)
- 性能监控
- 监控慢查询(如MySQL的slow_query_log)、锁竞争(如死锁检测)
- 使用APM工具(如SkyWalking)分析数据库调用链路
实战案例:电商订单库测试
场景:验证订单创建接口的性能与一致性
- 功能测试
- 输入验证:订单金额必须>0,商品ID必须存在。
- 事务测试:订单创建成功后,库存扣减同步完成。
- 性能测试
- 脚本:使用JMeter模拟1000用户同时下单。
- 指标:响应时间<500ms,数据库CPU<70%。
- 安全测试
- SQL注入:尝试通过订单号字段注入
' OR 1=1 --
,验证是否拦截。 - 权限控制:未登录用户无法调用下单接口。
- SQL注入:尝试通过订单号字段注入
- 数据验证
- 一致性:订单表、库存表、支付表数据同步(使用DbUnit比对)。
- 备份恢复:模拟数据库宕机后,从备份恢复数据并验证订单完整性。
工具推荐
测试类型 | 工具示例 | 用途 |
---|---|---|
功能测试 | JUnit、Pytest | 编写单元测试用例 |
性能测试 | JMeter、SysBench | 模拟高并发与压力测试 |
安全测试 | SQLMap、OWASP ZAP | 检测SQL注入漏洞 |
数据比对 | DbUnit、Vitess | 验证数据一致性 |
监控分析 | MySQL Slow Query Log、Prometheus | 分析慢查询与资源使用情况 |
禅道/TAPD
对比维度 TAPD平台 禅道
功能全面性 更全面,集成了项目管理和DevOps工具链,适合大型团队和复杂项目。 功能相对简单,专注于项目管理,适合中小型团队和简单项目。
用户体验 界面现代,操作流畅,但功能较多,需要一定的学习成本。 界面简洁,操作直观,简单易学。
集成能力 支持多种开发和运维工具,提供完整的工具链集成。 主要是项目管理功能,支持扩展插件,但整体集成能力不如TAPD。
适用规模 适合大型团队、企业级项目。 适合中小型团队、项目管理需求较简单的场景。
自动化支持 提供丰富的自动化功能,支持自动化工作流和CI/CD。 自动化功能较少,主要依靠插件扩展。
开源与否 TAPD是商业平台,提供免费和付费版本。 禅道是开源软件,可以免费使用和自行修改。
如何选择
选择TAPD平台:当您的团队较大,项目复杂,需要完整的DevOps工具链和自动化流程时,TAPD是一个更好的选择。它能够帮助团队实现高效的协作和快速的迭代开发。
选择禅道:当您的团队规模较小,项目管理需求相对简单,只需要基础的任务管理和缺陷跟踪功能时,禅道非常适合。它简单易用,成本低廉,能够快速上手。
无论选择哪个平台,清楚了解自己的项目需求和团队规模,将有助于做出最佳选择,提高工作效率和项目的成功率。
TAPD 的主要用途
全生命周期项目管理
支持需求管理、任务分配、缺陷跟踪、测试管理、文档协作等全流程,覆盖从需求提出到产品上线的完整研发周期
提供自定义工作流和看板视图,适配敏捷开发、瀑布模型等多种项目管理模式
团队协作与效率提升
通过自动化小助手实现逾期预警、状态联动、字段变更通知等功能,减少人工干预
集成第三方工具(如 Git、Jira)和即时通讯平台(如企业微信、飞书),提升跨团队协作效率
数据驱动决策
生成缺陷密度、任务进度等可视化报表,辅助管理层优化资源配置和流程设计
使用方式示例:
需求管理:在 TAPD 中创建需求池,按优先级排序并关联到迭代计划
缺陷跟踪:提交缺陷单时自动关联需求或任务,通过状态流转(如“待修复→已验证”)跟进处理进度
Trello/JIRA
对比维度 Trello JIRA
项目管理方法 基于Kanban,使用板块、列表和卡片管理任务。 支持Scrum和Kanban,适用于敏捷开发,功能更全面。
复杂度 简单易用,适合小型项目。 功能复杂,适合大型项目和复杂需求。
定制化 灵活性高,支持自定义工作流和字段。 高度可定制,适合有特定需求的团队。
集成能力 支持第三方集成,如Power-Up。 与多种开发和协作工具集成,如GitHub、Slack等。
成本 提供免费版本,付费版本费用较低。 提供免费试用,付费版本费用较高,适合企业和大型团队。
适用规模 适合中小型团队和简单项目。 适用于大型团队和复杂项目,尤其是软件开发领域。
svn
SVN 的主要用途
代码与文件版本控制
集中管理代码、文档的版本历史,支持多人协作开发时同步更新和冲突解决
通过分支(Branch)管理不同功能开发或版本迭代,合并(Merge)后统一提交到主干(Trunk)
历史追溯与回滚
查看任意版本的修改记录,快速定位问题代码或恢复误删文件
支持标签(Tag)功能标记重要版本(如正式发布版)
使用方式示例:
基础操作:
检出仓库到本地
svn checkout http://svn.example.com/repo
提交修改到仓库
svn commit -m “修复登录页面样式问题”
冲突处理:本地修改与服务器版本冲突时,使用 svn update 合并差异或手动解决冲突后提交34。
TAPD 与 SVN 的协同场景
需求与代码关联
TAPD 中的需求单可关联 SVN 提交记录,实现需求→代码的可追溯性68。
自动化流水线
SVN 代码提交触发 TAPD 需求状态自动变更(如“开发中→待测试”)
Testbed
Testbed(测试平台)
Testbed 就像是一个“实验台”或“安全区”,专门用来对软件、硬件、系统(比如手机APP、网站、机器人等)做各种测试,验证它们能不能正常工作。
核心作用:提前发现问题,避免用户遇到bug。
验证功能
比如:你做了一个“自动计算工资”的软件,Testbed就是用来模拟各种员工数据(正常、异常、极端情况),看看软件算得对不对。
测试稳定性
比如:让一个APP连续运行24小时,看它会不会卡死、闪退、耗光内存。
兼容性测试
比如:你的网站在iPhone、安卓手机、Windows电脑上显示正常吗?用Testbed可以快速切换不同设备测试。
性能压测
比如:1万人同时抢购商品,你的服务器会不会崩溃?Testbed能模拟大量用户“围攻”系统。
模拟特殊环境
比如:测试自动驾驶系统在暴雨天的反应,现实中难实现,Testbed可以用虚拟环境模拟雨天、车祸等场景。
Playwright
Playwright 是一个自动化测试工具,可以控制浏览器(如 Chrome、Firefox、Edge)自动执行操作,比如打开网页、点击按钮、填写表单等。它支持多种编程语言(Python、JavaScript、Java、C#),适合做网页自动化测试或爬虫。
优势:
支持所有主流浏览器。
自动等待元素加载(减少代码中的等待时间)。
可以录制操作生成代码。
能处理弹窗、文件上传下载等复杂场景。
常用例子(Python版)
- 启动浏览器,打开网页
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
#启动 Chrome 浏览器
browser = p.chromium.launch(headless=False) # headless=False 表示显示浏览器界面
page = browser.new_page()
# 打开网页
page.goto("https://www.baidu.com")
print(page.title()) # 输出页面标题
# 关闭浏览器
browser.close()
- 点击按钮和填写表单
场景:在百度搜索框输入关键词并搜索。
page.goto("https://www.baidu.com") #输入文字
page.fill("#kw", "Playwright教程") #kw 是百度搜索框的 CSS 选择器
page.click("#su")
page.wait_for_timeout(2000) # 等待 2 秒(实际项目建议用更智能的等待方式)
- 处理弹窗
场景:点击按钮后出现弹窗,点击确认。
监听弹窗事件
page.on("dialog", lambda dialog: dialog.accept())
触发弹窗的操作(例如点击一个按钮)
page.click(“button#show-alert”)
4. 截图和录屏
截取页面截图
page.screenshot(path=”screenshot.png”)
录制视频(需要在启动浏览器时配置)
browser = p.chromium.launch(headless=False)
context = browser.new_context(record_video_dir="video/")
page = context.new_page()
page.goto("https://example.com")
关闭时会自动保存视频
- 模拟手机浏览器
使用 iPhone 11 的模拟设备
iphone_11 = p.devices["iPhone 11"]
browser = p.chromium.launch()
context = browser.new_context(**iphone_11)
page = context.new_page()
page.goto("https://m.baidu.com")
- 文件下载
监听下载事件
with page.expect_download() as download_info:
page.click("a#download-link") # 触发下载的链接
download = download_info.value
#保存文件到本地
download.save_as(download.suggested_filename)
- 文件上传
上传本地文件
page.set_input_files(“input#file-upload”, “myfile.txt”)
8. 等待元素出现
自动等待元素加载(Playwright 默认行为)
page.click(“#submit-button”)
显式等待某个元素出现
page.wait_for_selector(“.success-message”, timeout=5000) # 最多等 5
css元素选择
一、逻辑“与”(AND)
通过 连续书写多个属性选择器 或 组合选择器 实现多条件同时满足的定位。
示例:
同时满足两个属性条件
/* 选择同时具有 alt=”div1-img1” 和 href=”https://www.sogou.com/" 属性的 img 元素 */img[alt="div1-img1"][href="https://www.sogou.com/"]
此方式要求元素同时满足所有属性条件。
组合类名与属性
/* 选择 class 为 “spread” 且 type 为 “submit” 的 input 元素 */
input.spread[type=”submit”]
通过类选择器(.)与属性选择器([])组合实现
二、逻辑“或”(OR)
通过 逗号分隔选择器 实现任一条件满足的定位。
示例:
匹配多个选择器
/* 选择 class 为 “btn” 的按钮,或 type 为 “submit” 的 input 元素 */
.btn, input[type=”submit”]
逗号分隔的选择器表示“或”关系,任一匹配的元素都会被选中
部分属性值匹配
/* 选择 href 属性以 “https://www.sogou" 开头,或以 “sogou.com/“ 结尾,或包含 “sogou” 的 a 元素 /
a[href^=”https://www.sogou"], a[href$=”sogou.com/“], a[href=”sogou”]
通过 ^=(开头匹配)、$=(结尾匹配)、*=(包含匹配)实现不同条件
三、逻辑“非”(NOT)
通过 :not() 伪类 排除特定条件的元素。
示例:
排除指定属性
/* 选择所有 input 元素,但排除 type 为 “text” 的元素 */
input:not([type=”text”])
使用 :not() 伪类过滤不符合条件的元素
排除特定类名
/* 选择 class 为 “box” 但非 “disabled” 的元素 */
.box:not(.disabled)
结合类选择器与 :not() 实现反向筛选
PerfDog
PerfDog 主要用途
全平台性能测试与分析
支持 iOS/Android 设备、H5、小程序、游戏及后台进程的性能测试,覆盖 CPU、内存、GPU、帧率(FPS)、电量、网络流量等核心指标13。
无需 Root(Android)或越狱(iOS),即插即用,且不修改应用代码15。
跨平台兼容性
支持 Windows 和 Mac OS 系统,单台 PC 可同时测试多台设备16。
兼容云真机、Android 模拟器等测试场景13。
数据可视化与团队协作
提供本地数据保存及云端分析功能,支持生成可视化图表、版本对比及测试报告46。
可结合自动化脚本或中台系统构建性能监控平台78。
PerfDog 入门使用步骤
- 下载与启动
访问官网 PerfDog | 全平台性能测试分析专家 ,按系统选择 Windows 或 Mac 版本下载12。
解压后直接运行 PerfDog.exe(Windows)或 .dmg(Mac),无需安装12。 - 连接设备
USB 模式:通过数据线连接设备(需开启 USB 调试模式),选择设备列表中的 USB 图标68。
Wi-Fi 模式(推荐测试功耗):
确保 PC 与设备处于同一 Wi-Fi 网络。
先用 USB 连接设备,选择 Wi-Fi 图标完成检测后拔掉数据线 - 选择被测应用
在 PerfDog 界面选择目标应用(如游戏或 App),设备端将显示悬浮窗实时展示性能数据(如 FPS、CPU 使用率) - 配置监控指标
点击界面右下角加号(+),勾选需监控的指标(如内存、帧时间、流量等)
支持截图功能(需数据线模式)记录关键场景 - 开始测试与标记
点击 播放按钮 启动测试,实时查看性能曲线
通过 标签功能 标记测试阶段(如“登录页面”、“战斗场景”),便于后续分析 - 保存与导出数据
测试结束后,数据可 本地保存(CSV 格式)或 上传云端 生成可视化报告
云平台支持多维数据对比(如版本迭代性能差异)
注意事项
账号登录:需使用 TAPD 账号登录 PerfDog
iOS 设备:推荐使用 Wi-Fi 模式,部分场景需外置无线网卡优化连接稳定性8。
功耗测试:仅 Wi-Fi 模式可准确测量电量消耗
总结
服务端数据库测试需覆盖功能、性能、安全、一致性四大维度,结合自动化工具提升效率,并通过持续优化保障系统稳定性。实际项目中,建议采用分层测试策略(单元测试→集成测试→压力测试),并建立数据库测试知识库(记录常见缺陷与解决方案
一、参数校验(功能性测试)
1. 必填字段缺失
- 问题:未传递接口文档定义的必填参数,导致业务逻辑异常。
- 示例:用户注册接口缺少
username
字段,但接口返回”参数校验失败”而未明确缺失项。 - 验证方法:使用OpenAPI规范生成参数校验模板,结合Postman脚本动态检测
2. 参数类型/格式错误
- 问题:参数类型与定义不符(如字符串传数值),或日期格式非法。
- 示例:传入
age="abc"
导致数值解析异常,或birthday="2024/02/30"
(非闰年)。 - 验证方法:在网关层实施JSON Schema校验,正则约束日期格式(如^\d{4}-\d{2}-\d{2}$
3. 边界值与组合逻辑
- 问题:未覆盖参数边界(如最大值、空值)或组合逻辑冲突。
- 示例:分页参数
page_size=0
导致数据库查询异常,或优惠券有效期与使用时间冲突。 - 验证方法:等价类划分+Pairwise工具生成最优用例组合
二、业务逻辑验证(场景完整性)
1. 数据状态同步
- 问题:接口操作后数据库/缓存未同步更新。
- 示例:用户修改头像后CDN缓存未刷新,导致新旧头像交替显示。
- 验证方法:通过数据库事务日志分析工具(如Debezium)验证数据变更,设置缓存过期策略
2. 分布式事务与幂等性
- 问题:分布式环境下事务未原子化,或重复请求导致数据异常。
- 示例:支付接口未实现幂等性,用户重复点击引发多次扣款。
- 验证方法:设计唯一请求ID(如Idempotency-Key),数据库使用唯一索引防重
三、异常场景处理(容错性测试)
1. 服务不可用与超时
- 问题:下游服务故障时未触发降级策略,导致线程池耗尽。
- 示例:支付网关超时未返回结果,订单接口线程阻塞引发雪崩。
- 验证方法:使用熔断器(如Hystrix)模拟服务降级,验证备用数据返回逻辑
2. 异常输入过滤
- 问题:未过滤非法字符(如SQL注入、XSS),引发安全漏洞。
- 示例:搜索关键词含
' OR 1=1 --
导致数据库注入攻击。 - 验证方法:OWASP Sanitization库过滤输入,设置字段长度限制
四、安全测试(防护性验证)
1. 鉴权与权限控制
- 问题:未校验Token/API Key,导致越权访问。
- 示例:修改JWT Payload字段提升用户权限,或普通用户访问管理员接口。
- 验证方法:实施RBAC权限模型,定期轮换密钥并审计日志
2. 敏感数据泄露
- 问题:密码、手机号等敏感信息明文传输。
- 示例:用户注册接口返回的Token包含明文密码。
- 验证方法:拦截响应数据,检查敏感字段是否加密(如AES加密)
五、性能测试(稳定性验证)
1. 高并发与资源瓶颈
- 问题:未做压力测试导致接口崩溃。
- 示例:秒杀接口1000并发请求引发MySQL连接池耗尽。
- 验证方法:JMeter阶梯加压测试,监控QPS、响应时间及资源占用(CPU/内存)
2. 缓存与锁机制
- 问题:缓存穿透/雪崩或锁竞争导致性能劣化。
- 示例:热点商品库存查询未使用本地缓存,引发频繁数据库访问。
- 验证方法:使用Redis布隆过滤器防穿透,分布式锁优化并发控制
六、数据一致性(最终一致性)
1. 异步任务与补偿机制
问题:异步任务失败未触发补偿,导致数据不一致。
示例:订单批量删除接口异步任务失败,但前端显示已删除。
验证方法:模拟任务失败场景(如数据库主键冲突),验证重试与补偿逻辑
存与数据库同步**
问题:缓存未及时更新,导致脏数据。
示例:用户信息修改后,缓存中仍保留旧数据。
验证方法:通过Cache Aside
模式验证读写策略,设置缓存过期时间
七、测试工具与实践建议
测试类型 | 工具示例 | 应用场景 |
---|---|---|
功能测试 | Postman、Swagger | 接口参数校验、状态码断言 |
性能测试 | JMeter、Gatling | 压力测试、吞吐量分析 |
安全测试 | OWASP ZAP、SQLMap | 注入攻击检测、权限漏洞扫描 |
数据校验 | DbUnit、DeepDiff | 响应数据结构比对、数据库一致性验证 |
混沌工程 | Chaos Monkey、Netflix Chaos | 服务容错性测试、故障注入 |
八、典型缺陷案例
- 案例1:未处理空指针异常
- 场景:用户信息接口未校验
address
字段存在性,返回NullPointerException
。 - 修复:增加空值判断,返回标准化错误码(如
400 Bad Request
)。
- 场景:用户信息接口未校验
- 案例2:缓存雪崩
- 场景:所有用户同时访问时,缓存集中过期导致数据库崩溃。
- 修复:为缓存设置随机过期时间,引入二级缓存(本地+Redis)。
面试题
自动化测试的好处:加快测试进度,发现bug的时间
视频和文章测试流程:视频,以时间轴为主,视频播放前加载,刷新页面,视频封面是否正常加载,视频播放中,正常拖拉进度条,横屏竖屏,小窗播放,切后台冷启动,杀进程热启动等;视频结束后,横屏竖屏,播放状态是否正常;
广告测试流程:测试广告曝光和点击打点中的计费串,是否能被广告平台正常解析出来,保证计费成功和时效性正常
搭建测试环境的流程:分为前端和后端,搭建环境使用的是xstp+cnap平台的多路复用技术,具体测试环境参考前端和后端的开发环境的部署CICD流程,需要先申请机器,然后在堡垒机跳转开发机,搭建数据库mysql,安装测试需要的库request,appium,playwright等等,搭建集成部署集成开发CICD流水线在平台上,每次部署新的测试环境就需要运行CICD流水线即可。
共享单车扫码功能如何进行测试:
1:端内外扫码测试,端外扫码有提示请到端内app中扫码
2:明暗灯光测试,黑暗情况下,开启灯光,正常扫码
3:弱网环境下,能够正常扫码
4:扫码距离测试,远距离也能扫码
5:二维码的时效性,3分钟后失效,需要在刷新生成
6:扫码后跳转页面加载正常
接口测试如何进行
一、代码题(Python/Java)
列表元素平方
# Python实现 ListA = [1,3,5,7,9,11] squared = [x**2 for x in ListA] # 列表推导式 print(squared) # [1,9,25,49,81,121]
Python日志装饰器
def log_decorator(func): def wrapper(*args, **kwargs): print(f"调用函数 {func.__name__},参数:{args}, {kwargs}") result = func(*args, **kwargs) print(f"函数 {func.__name__} 返回:{result}") return result return wrapper @log_decorator def add(a, b): return a + b
合并两个有序数组(无额外空间)
def merge_sorted_arrays(nums1, m, nums2, n): p1, p2, p = m-1, n-1, m+n-1 while p1 >= 0 and p2 >= 0: if nums1[p1] > nums2[p2]: nums1[p] = nums1[p1] p1 -= 1 else: nums1[p] = nums2[p2] p2 -= 1 p -= 1 nums1[:p2+1] = nums2[:p2+1]
二、核心概念题
- 进程、线程、协程区别
- 进程:操作系统资源分配的基本单位,独立内存空间,开销大。
- 线程:CPU调度的基本单位,共享进程资源,轻量级。
- 协程:用户态的轻量级线程,由程序控制调度,适合高并发IO场景
- Selenium框架工作原理
- 驱动层:WebDriver(如ChromeDriver)与浏览器交互。
- 操作层:封装浏览器操作(如点击、输入)。
- 业务层:测试用例逻辑。
- 持续集成:结合TestNG/Jenkins实现自动化测试流程
- WSGI/uWSGI/Nginx关系
- WSGI:Python Web应用与服务器的协议接口(如Django通过WSGI运行)。
- uWSGI:高性能应用服务器,实现WSGI协议。
- Nginx:反向代理服务器,处理静态资源、负载均衡,与uWSGI通过TCP连接
三、框架与工具
Django中间件方法
class CustomMiddleware: def process_request(self, request): # 请求到达视图前 pass def process_view(self, request, view_func): # 视图函数调用前 pass def process_response(self, request, response): # 响应返回前 pass
应用场景:日志记录、权限校验、请求缓存
MySQL存储引擎对比
引擎 事务支持 锁粒度 适用场景 InnoDB 支持 行级锁 事务型系统(OLTP) MyISAM 不支持 表级锁 读密集型(OLAP) Memory 不支持 表级锁 临时数据缓存
四、Docker操作题
创建Volume
docker volume create kuma
启动容器并挂载
docker run -d --name yapi -p 5000:3000 -v kuma:/data/db yapi-image
五、高频场景题
- 自动化测试关键节点
- 环境搭建:容器化部署(Docker)、CI/CD集成(Jenkins)。
- 用例设计:数据驱动、参数化测试。
- 结果验证:断言机制、日志监控。
- 维护优化:用例版本管理、失败用例自动重试
- 性能测试瓶颈排查
- 服务器资源:CPU/内存/磁盘IO监控(
top
、iostat
)。 - 接口响应:慢查询优化(索引、SQL语句)。
- 网络延迟:抓包分析(Wireshark)、CDN加速
- 服务器资源:CPU/内存/磁盘IO监控(
六、开放性问题
如何定位前端/后端Bug?
前端:检查元素状态、网络请求是否发送、控制台报错。
后端:日志分析(异常堆栈)、接口返回数据校验
测试与开发的协作模式
- 敏捷开发:参与需求评审、每日站会同步进度。
- 自动化覆盖:核心功能用例集成到CI流水线,减少回归成本
一、TypeScript 代码题
1. 类型推导与泛型
题目:实现一个泛型深拷贝函数 deepClone<T>
,支持嵌套对象和数组。
function deepClone<T>(obj: T): T {
if (obj === null || typeof obj !== 'object') return obj;
if (Array.isArray(obj)) return obj.map(item => deepClone(item)) as unknown as T;
const clone: Partial<T> = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
clone[key] = deepClone(obj[key]);
}
}
return clone as T;
}
// 测试用例
const nested = { a: 1, b: { c: [2, 3] } };
const cloned = deepClone(nested);
console.log(cloned); // { a:1, b: { c: [2,3] } }
考点:递归、类型守卫、泛型约束
2. 接口与类型别名
题目:定义一个接口 Animal
,包含 name
属性和 speak()
方法;再定义一个类型别名 Dog
,继承 Animal
并添加 breed
属性。
interface Animal {
name: string;
speak(): void;
}
type Dog = Animal & {
breed: string;
};
const dog: Dog = {
name: "Buddy",
breed: "Golden Retriever",
speak() {
console.log("Woof!");
}
};
考点:接口继承、类型组合
3. 函数实现
题目:实现 mergeArray
函数,合并两个有序数组并保持有序。
function mergeArray(arr1: number[], arr2: number[]): number[] {
const result: number[] = [];
let i = 0, j = 0;
while (i < arr1.length && j < arr2.length) {
if (arr1[i] < arr2[j]) {
result.push(arr1[i++]);
} else {
result.push(arr2[j++]);
}
}
return result.concat(arr1.slice(i)).concat(arr2.slice(j));
}
// 测试用例
console.log(mergeArray([1,3,5], [2,4,6])); // [1,2,3,4,5,6]
考点:双指针、数组操作
二、Java 代码题
1. 单例模式(线程安全)
题目:实现线程安全的懒汉式单例模式。
public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
考点:双重检查锁、volatile
关键字
2. 集合与泛型
题目:编写一个方法,找出两个 List<Integer>
的交集(去重)。
public List<Integer> intersection(List<Integer> list1, List<Integer> list2) {
Set<Integer> set1 = new HashSet<>(list1);
Set<Integer> set2 = new HashSet<>(list2);
set1.retainAll(set2);
return new ArrayList<>(set1);
}
// 测试用例
List<Integer> list1 = Arrays.asList(1,2,3,4);
List<Integer> list2 = Arrays.asList(3,4,5,6);
System.out.println(intersection(list1, list2)); // [3,4]
考点:集合操作、泛型约束
3. 多线程与同步
题目:编写多线程程序,主线程打印奇数,子线程打印偶数,交替输出 1-10。
public class OddEvenPrinter {
private int count = 1;
private final Object lock = new Object();
public void printOdd() {
while (count <= 10) {
synchronized (lock) {
if (count % 2 != 0) {
System.out.println("Odd: " + count++);
lock.notify();
} else {
try { lock.wait(); } catch (InterruptedException e) { }
}
}
}
}
public void printEven() {
while (count <= 10) {
synchronized (lock) {
if (count % 2 == 0) {
System.out.println("Even: " + count++);
lock.notify();
} else {
try { lock.wait(); } catch (InterruptedException e) { }
}
}
}
}
}
考点:线程同步、wait/notify
机制
三、高频综合题
1. TypeScript 类型系统
题目:用 TypeScript 实现一个函数,判断变量是否为数组。
function isArray<T>(value: unknown): value is T[] {
return Array.isArray(value);
}
// 使用示例
const arr = [1,2,3];
console.log(isArray(arr)); // true
考点:类型守卫、泛型类型谓词
2. Java 异常处理
题目:自定义一个受检异常 InvalidInputException
,并在方法中抛出。
public class InvalidInputException extends Exception {
public InvalidInputException(String message) {
super(message);
}
}
public class Validator {
public static void validateInput(String input) throws InvalidInputException {
if (input == null || input.isEmpty()) {
throw new InvalidInputException("Input cannot be empty");
}
}
}
考点:异常分类、自定义异常
四、面试技巧
TypeScript:
强调类型安全、接口设计、泛型应用。
熟悉tsconfig.json配置(如严格模式、模块解析)
掌握 JVM 原理(内存模型、GC 算法)、集合框架源码。
熟悉设计模式(单例、工厂、观察者)的实际应用
可变与不可变类型
题目:解释 Python 中可变与不可变类型的区别,并举例说明。
参考答案:
不可变类型:对象创建后内容不可修改(如 int, str, tuple)。修改时会生成新对象。
a = 10
a += 5 # 实际创建新对象,原对象不变
可变类型:对象内容可修改(如 list, dict, set)。
lst = [1,2,3]
lst.append(4) # 直接修改原对象
考点:内存管理、对象特性 。
装饰器实现
题目:编写一个装饰器,统计函数执行时间。
参考答案:
import time
def timer(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f”{func.name} 执行时间:{end - start:.2f}秒”)
return result
return wrapper
@timer
def example_function():
time.sleep(1)
考点:装饰器原理、闭包应用 。
测试框架相关
- unittest 测试用例
题目:使用 unittest 编写测试类,验证字符串反转函数。
参考答案:
import unittest
def reverse_string(s):
return s[::-1]
class TestStringMethods(unittest.TestCase):
def test_reverse(self):
self.assertEqual(reverse_string(“hello”), “olleh”)
self.assertNotEqual(reverse_string(“world”), “word”)
if name == ‘main‘:
unittest.main()
考点:断言方法、测试类结构 。
- pytest 参数化测试
题目:使用 pytest 对登录接口进行多组参数测试。
参考答案:
import pytest
test_data = [
(“user1”, “pass123”, True),
(“user2”, “wrongpass”, False)
]
@pytest.mark.parametrize(“username,password,expected”, test_data)
def test_login(username, password, expected):
result = login(username, password) # 假设 login 是待测函数
assert result == expected
考点:参数化、断言逻辑 。
数据结构与算法
- 快速排序实现
题目:用 Python 实现快速排序算法。
参考答案:
def quicksort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quicksort(left) + middle + quicksort(right)
考点:分治思想、递归实现 。
- 链表环检测
题目:判断链表是否有环(Floyd 判圈算法)。
参考答案:
class ListNode:
def init(self, val=0, next=None):
self.val = val
self.next = next
def has_cycle(head):
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
return True
return False
考点:双指针、链表操作 。
自动化测试场景题
- Selenium 元素定位
题目:编写代码点击页面上的动态加载按钮。
参考答案:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get(“https://example.com")
try:
button = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, “//button[@id=’dynamic-btn’]”))
)
button.click()
except Exception as e:
print(f”元素未找到或无法点击: {e}”)
考点:显式等待、异常处理 。
接口测试断言
题目:验证接口返回的 JSON 数据中 status 字段为 200。
参考答案:
import requests
def test_api():
response = requests.get(“https://api.example.com/data")
assert response.status_code == 200
data = response.json()
assert data.get(“status”) == 200
考点:HTTP 请求、JSON 解析、断言 。
综合应用题
- 文件处理与统计
题目:统计文本文件中每个单词的出现次数,按频率降序输出。
参考答案:
from collections import defaultdict
def count_words(file_path):
word_count = defaultdict(int)
with open(file_path, ‘r’) as f:
for line in f:
words = line.strip().split()
for word in words:
word_count[word.lower()] += 1
return sorted(word_count.items(), key=lambda x: x[1], reverse=True)
考点:文件 I/O、字典操作、排序 。
- 日志分析工具
题目:编写脚本分析日志文件,提取错误日志行数及高频错误类型。
参考答案:
def analyze_logs(log_path):
error_count = 0
error_types = defaultdict(int)
with open(log_path, ‘r’) as f:
for line in f:
if “ERROR” in line:
error_count += 1
error_type = line.split(“ERROR: “)[1].split()[0]
error_types[error_type] += 1
return {“total_errors”: error_count, “top_errors”: dict(error_types)}
考点:正则表达式(可选)、数据处理 。
高频考点总结
框架应用:unittest/pytest 测试用例设计、Selenium 自动化操作。
性能优化:生成器处理大数据、避免内存泄漏。
异常处理:合理使用 try-except 保障测试稳定性。
代码质量:单元测试覆盖率、Mock 技术(如 unittest.mock)
何时选择 Express
虽然 Next.js API Routes 很方便,但在以下情况建议使用独立 Express 服务:
需要大量第三方中间件(如 Passport.js 复杂鉴权)
需要长连接(WebSocket)
已有成熟的 Express 代码库
需要独立扩展后端服务
Neo4j 是一个专门处理“关系”的数据库,就像一个超级厉害的“人际关系侦探”,能快速找到数据之间的复杂联系。
为什么需要 Neo4j?
生活中很多问题都是关于“关系”的:
社交网络(谁认识谁?)
推荐系统(喜欢A的人也可能喜欢B)
欺诈检测(异常转账关系网)
知识图谱(新冠病毒和哪些药物相关?)
Neo4j 的三大特点:
用“图”存数据
数据用 节点(比如人、商品)和 关系(比如朋友、购买)表示,像画思维导图。
例如:
text
Copy Code
[小明] → (朋友) → [小红] → (买了) → [手机]
关系查询极快
比如找“小明的朋友的朋友的朋友”,传统数据库要查好几层,Neo4j一步到位。
直观易懂
数据之间的关系一目了然,像看地图,适合分析复杂网络。
实际用途:
社交网络
推荐你可能认识的人(比如 LinkedIn)。
电商推荐
“买了手机的人还买了耳机”(亚马逊常用)。
金融风控
发现洗钱团伙的异常转账网络。
知识图谱
谷歌搜索背后的“关联信息”引擎。
其他
一、FastAPI
用途:快速搭建后端接口(数据出入口)
类比:像快餐店的点餐系统,快速接受订单、处理请求、返回结果。
例子:
你点外卖时,APP后端用 FastAPI 接收你的请求 → 通知厨房做菜 → 返回“订单已接单”
优势:开发速度比传统框架(如Django)快3倍,适合快速迭代的项目。
二、OAuth2 —— 万能钥匙管家
用途:安全授权登录(不用暴露密码)
类比:像酒店房卡,授权第三方临时使用你的权限,但不给密码。
例子:
用微信登录其他APP时,微信通过OAuth2告诉APP:“这用户没问题,但别问我密码”
优势:避免密码泄露,支持微信/谷歌/苹果等第三方登录。
三、Dify —— 乐高式AI搭建工具
用途:低代码开发AI应用(不用写代码训练模型)
类比:像用乐高积木拼装机器人,拖拽就能创建智能应用。
例子:
小白用Dify:上传数据 → 选预训练模型(如GPT-3) → 生成一个智能客服聊天机器人
优势:10分钟搭建一个AI应用,不用学机器学习。
四、OpenWebUI —— 智能家居控制面板
用途:管理AI模型的Web界面(可视化操作)
类比:像智能家居APP,用按钮控制灯光、空调,而不是敲代码。
例子:
用OpenWebUI管理本地部署的AI模型:上传图片 → 点按钮生成描述 → 下载结果
优势:非技术人员也能操作复杂AI模型。
五、OpenAPI —— 万能插座标准
用途:统一接口规范(不同系统能互相通信)
类比:像电源插座标准,所有电器插头都能匹配。
例子:
银行提供OpenAPI → 支付宝调用它实现转账功能 → 微信支付也能用同一套接口
优势:不同公司系统能无缝对接,避免重复开发。
接口测试
功能正确性验证
检查接口请求与返回数据的格式、字段类型、默认值、非空校验及业务逻辑准确性
验证接口对异常输入(特殊字符、边界值、非法长度)的容错处理能力
兼容性验证:确保新版本接口兼容历史版本功能23
异常场景覆盖
操作异常:非法业务流程(如未授权操作、越权访问)
依赖异常:第三方服务超时、服务宕机时的降级策略验证24
性能与安全
响应时间、吞吐量等性能指标测试
敏感数据传输加密验证,防御SQL注入、XSS攻击等安全漏洞47
二、后端系统测试
数据库与缓存
数据一致性:事务处理、脏读/幻读等场景验证
缓存更新策略(如缓存穿透、雪崩防护机制)35
中间件与分布式系统
负载均衡策略有效性验证
分布式事务完整性(如两阶段提交、回滚机制)
消息队列的可靠性(消息重试、死信队列处理)58
三、性能测试
负载与压力测试
模拟高并发场景(如秒杀活动),验证系统最大承载能力
资源监控:CPU、内存、线程池使用率等指标分析47
稳定性验证
7*24小时持续运行测试,观察内存泄漏、资源回收等问题
故障恢复能力:服务中断后数据恢复速度和完整性48
四、安全测试
渗透测试
模拟攻击手段:如暴力破解、DDoS攻击验证防御机制
权限漏洞检测:越权操作、敏感信息暴露风险78
敏感数据处理
日志脱敏、密钥管理合规性检查
输入输出数据加密算法强度验证58
五、兼容性测试
环境适配
不同操作系统(Linux/Windows)、JDK版本的适配性
浏览器兼容性:Chrome/Firefox等主流浏览器接口调用验证78
六、持续测试策略
自动化与工具链
集成CI/CD流程(如Jenkins、GitLab CI),实现测试脚本自动化执行
使用Docker/Kubernetes模拟真实环境进行灰度发布验证
功能正确性验证核心要点
一、基础数据格式与字段校验
请求/响应格式验证
验证接口返回数据的格式(如JSON/XML)是否符合规范,使用JSON Schema或XML Schema工具进行结构化校验27。
检查字段类型是否匹配预期(如数值类型是否为int而非string)
示例:
// 接口返回数据示例
{
“user_id”: 1001, // 应为数值类型,非字符串
“status”: “active”
}
若user_id返回为”1001”(字符串),则判定为字段类型错误
默认值与空值处理
非必填参数需验证默认值是否生效(如分页参数page_size未传时默认返回10条数据)
必填字段缺失时,接口应返回明确错误码(如400 Bad Request)及错误描述
二、业务逻辑准确性验证
业务规则覆盖
根据业务场景验证数据关联性,例如:
用户积分变更后,账户余额需同步更新15。
订单状态流转需符合预设流程(如“待支付”→“已支付”不可逆)
关联性校验:调用依赖接口验证数据一致性(如支付成功后查询订单状态是否更新)
数据完整性校验
检查返回结果是否包含所有必要字段(如用户信息接口必须包含id、name、mobile字段)
列表数据需验证分页逻辑(如total_count与实际返回条目数一致)
三、异常输入容错处理
特殊字符与非法输入
输入含SQL敏感字符(如’、;)时,接口应过滤或转义,而非直接报错或引发注入漏洞
示例:
GET /search?keyword=test’;DROP TABLE users–
若接口未处理特殊字符,可能导致数据库异常
边界值与非法长度校验
数值型参数需验证合法范围(如年龄字段age传入-1或200时返回错误)
字符串长度超限时,接口应截断或返回错误(如用户名长度超过50字符限制)
非法流程拦截
验证未授权操作(如普通用户越权访问管理员接口)返回403 Forbidden
四、兼容性验证
历史版本兼容性
新增接口字段时,需确保旧版本客户端调用不受影响(如新字段设为可选,或默认值兼容旧逻辑)
灰度验证:通过版本号控制(如/v1/api和/v2/api),逐步切换流量验证兼容性
数据结构兼容
修改响应数据结构时,需保留旧字段或提供迁移过渡期(如新增new_price字段时暂不删除old_price)
验证方法与工具推荐
验证类型 工具/方法 适用场景
格式校验 Postman + JSON Schema Validator 结构化数据格式验证
异常输入覆盖 JMeter参数化测试 批量测试边界值、特殊字符场景
业务逻辑自动化 Python + Pytest框架 高频接口回归测试
兼容性验证 Docker多环境部署 + 流量回放 新旧版本并行验证
DB2数据库管理命令
实例与数据库启停
启动服务:db2start15
停止服务:db2stop [force]15
激活数据库实例:db2 activate database
查看活跃数据库:db2 list active databases15
数据库创建与连接
创建数据库:
db2 create database
连接数据库:
db2 connect to
数据导入/导出
导出数据:
db2 “export to path/file.del of del select * from
导入数据:
db2 “import from path/file.del of del insert into
指定编码导出:
db2 “export to data.del modified by codepage=1208…”
二、常用查询与数据操作
表与视图操作
创建表:
CREATE TABLE
创建视图:
CREATE VIEW
插入数据:
INSERT INTO
索引与触发器
创建唯一索引:
CREATE UNIQUE INDEX
创建触发器示例:
CREATE TRIGGER
三、监控与优化
锁与性能监控
查看锁信息:
db2 get snapshot for locks on
db2pd -d
动态SQL监控:
db2 get snapshot for dynamic sql on
事务管理与快照
开启事务:
BEGIN TRANSACTION
查看数据库快照:
db2 get snapshot for database on
四、高级功能示例
跨平台支持与编码设置
创建数据库时指定编码和国家:
db2 create database mydb codeset utf-8
表空间管理
监控表空间状态:
db2 list tablespaces show detail
一、Java基础
集合框架
HashMap vs Hashtable
- 线程安全:Hashtable 线程安全,HashMap 非线程安全。
- null值:HashMap 允许 key 和 value 为 null,Hashtable 不允许。
- 性能:HashMap 默认初始容量 16,负载因子 0.75;Hashtable 初始容量 11,扩容时容量翻倍+1。
// HashMap 扩容示例 Map<String, String> map = new HashMap<>(16, 0.75f);
多线程与并发
线程池参数:
corePoolSize
(核心线程数)、maximumPoolSize
(最大线程数)、keepAliveTime
(空闲线程存活时间)、workQueue
(任务队列)、threadFactory
(线程工厂)、handler
(拒绝策略)。锁机制
:
- 偏向锁 → 轻量级锁 → 重量级锁:根据竞争情况升级,减少锁开销。
- ReentrantLock vs synchronized:ReentrantLock 支持公平锁、可中断、条件变量,灵活性更高。
JVM调优
垃圾回收器对比:
回收器 适用场景 特点 Serial 单线程、小型应用 串行回收,低停顿 G1 大内存、低延迟需求 分区回收,可预测停顿时间 调优方向:调整堆大小(
-Xms
、-Xmx
)、选择合适垃圾回收器、监控 GC 日志。
二、测试基础
测试类型
- 单元测试:验证单个方法/类逻辑(JUnit/TestNG)。
- 接口测试:验证接口功能、性能(Postman/JMeter)。
- 性能测试:关注 TPS(每秒事务数)、QPS(每秒查询数)、响应时间。
- 自动化测试:Selenium(UI)、Appium(移动端)、Cucumber(BDD)。
测试用例设计
- 等价类划分:将输入分为有效/无效等价类。
- 边界值分析:测试输入范围的边界值(如 0、最大值)。
- 场景法:模拟用户操作流程(如登录→下单→支付)。
性能测试
- TPS与QPS的区别:
TPS(Transaction Per Second):每秒事务数,适用于完整业务流程。
QPS(Query Per Second):每秒查询数,适用于单一接口。
压测工具:JMeter(HTTP接口)、Locust(分布式压测)。
三、测试开发进阶
持续集成/持续部署(CI/CD)
- Jenkins Pipeline:通过 Groovy 脚本定义流水线任务。
- 代码质量检查:SonarQube(代码异味、漏洞扫描)。
自动化框架设计
- 数据驱动:通过 Excel/CSV 参数化测试用例。
- Page Object 模式:封装页面元素,提升代码复用性。
// Page Object 示例 public class LoginPage { private By username = By.id("username"); public void login(String user) { driver.findElement(username).sendKeys(user); } }
数据库测试
事务隔离级别:
隔离级别 脏读 不可重复读 幻读 READ UNCOMMITTED ✔️ ✔️ ✔️ READ COMMITTED ❌ ✔️ ✔️ REPEATABLE READ ❌ ❌ ✔️ SERIALIZABLE ❌ ❌ ❌ SQL优化:避免
SELECT *
、添加索引、拆分大表。
四、高频面试题
- HashMap 的底层实现
- JDK 1.8 前:数组 + 链表。
- JDK 1.8 后:数组 + 链表 + 红黑树(链表长度 >8 时转换)。
- 如何设计一个秒杀系统
- 限流:令牌桶算法(Guava RateLimiter)。
- 库存扣减:Redis 原子操作(
DECR
)。 - 异步处理:消息队列(Kafka/RocketMQ)削峰填谷。
- 全链路压测的步骤
- 环境准备:模拟生产环境配置。
- 流量建模:根据业务场景生成请求比例。
- 监控指标:CPU、内存、数据库连接池、接口响应时间。
五、实战代码示例
单例模式(双重检查锁)
public class Singleton { private static volatile Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
JMeter 参数化测试
- CSV Data Set Config:从 CSV 文件读取参数。
- 用户参数(User Parameters):每个线程独立参数。
六、面试准备建议
- 结合项目经验:重点描述性能优化、自动化框架设计等实际案例。
- 原理深入:如 JVM 内存模型、线程池状态流转。
- 编码能力:刷 LeetCode(数组、字符串、链表)。
- 工具链掌握:Jenkins Pipeline 编写、Arthas 线上诊断。
一、网络协议与基础
1. HTTP/HTTPS 协议
Q1:HTTP 1.0 与 HTTP 1.1 的主要区别?
参考答案:
HTTP 1.0 默认短连接(无 Keep-Alive),每次请求需建立新 TCP 连接;HTTP 1.1 默认长连接(Keep-Alive),支持复用 TCP 通道
HTTP 1.1 新增分块传输(Chunked)、缓存控制(Cache-Control)、Host 头字段支持虚拟主机
考察点:对协议演进的理解。
Q2:HTTPS 如何保证安全性?
使用 SSL/TLS 协议加密通信,通过证书验证服务器身份(防止中间人攻击)。
握手过程:客户端发起请求 → 服务器返回证书 → 客户端验证证书并生成密钥 → 双向加密传输
- 考察点:加密机制与握手流程。
2. TCP 与 Socket
Q3:TCP 如何保证可靠传输?
- 确认应答(ACK)、超时重传、滑动窗口(流量控制)、拥塞控制(慢启动、拥塞避免)
考察点:TCP 可靠性机制。
Q4:TCP 三次握手与四次挥手的意义?
三次握手:确保双方均具备发送和接收能力,避免无效连接。
四次挥手:确保双方均确认数据传输完成,防止残留数据干扰
- 考察点:连接建立与终止的细节。
二、接口测试
1. 接口测试流程
Q1:接口测试的完整流程是什么?
需求分析 → 2. 接口文档确认 → 3. 用例设计(等价类、边界值) → 4. 搭建测试环境 → 5. 使用工具(Postman/JMeter)执行 → 6. 结果验证(状态码、响应数据) → 7. 生成报告
考察点:流程规范性。
Q2:如何验证接口的安全性?
- 检查参数过滤(如 SQL 注入、XSS 攻击)、身份认证(JWT/OAuth)、HTTPS 加密、敏感数据脱敏
- 考察点:安全测试思维。
2. 工具与实战
Q3:JMeter 如何实现参数化?
- CSV 数据文件设置 → 添加 CSV Data Set Config → 引用变量(如${username}
考察点:工具使用熟练度。
Q4:接口返回 504 如何定位问题?
- 检查网关/反向代理超时配置 → 查看服务端日志(如 Nginx error.log) → 确认后端处理耗时(数据库查询、外部调用)
- 考察点:问题排查能力。
三、性能测试
1. 指标与场景
Q1:TPS 与 QPS 的区别?
TPS(Transaction Per Second):每秒事务数,适用于完整业务流程(如登录→下单)。
QPS(Query Per Second):每秒查询数,适用于单一接口(如查询用户信息)
考察点:性能指标理解。
Q2:如何设计高并发场景的测试方案?
参考答案
- 确定业务峰值(如双十一订单量) → 2. 使用 JMeter 模拟多线程 → 3. 监控服务器资源(CPU、内存、磁盘 I/O) → 4. 分析瓶颈(数据库锁、缓存穿透)
考察点:场景设计能力。
2. 瓶颈分析
Q3:TPS 上不去的可能原因?
- 数据库连接池不足 → 未使用索引 → 代码逻辑低效(如循环嵌套) → 外部服务调用延迟
- 考察点:问题定位思路。
四、数据库测试
1. 索引与优化
Q1:索引的底层实现(B+树 vs B树)?
B+树:非叶子节点不存储数据,叶子节点形成链表,适合范围查询;
B树:每个节点存储数据,适合随机查询
- 考察点:数据库原理。
Q2:如何优化慢查询?
使用EXPLAIN
分析执行计划 → 添加合适索引 → 避免SELECT *→ 拆分大表
- 考察点:SQL 调优能力。
五、系统设计与分布式
1. 架构设计
Q1:如何设计一个高可用服务?
- 负载均衡(Nginx/HAProxy) → 服务熔断(Hystrix/Sentinel) → 数据库主从复制 → 缓存(Redis 集群)
考察点:架构设计能力。
Q2:分布式事务如何保证一致性?
参考答案
:
两阶段提交(2PC)、TCC(Try-Confirm-Cancel)、消息队列最终一致性(如 RocketMQ)
5
。
考察点:分布式事务解决方案。
六、自动化测试
1. 框架设计
Q1:如何搭建接口自动化测试框架?
- 技术栈:Python + Requests + Pytest + Allure → 数据驱动(YAML/Excel) → 断言封装 → Jenkins 持续集成
考察点:框架设计经验。
Q2:如何处理接口依赖(如 Token 传递)?
- 使用全局变量存储 Token → 通过中间件(如 Redis)缓存 → 关联提取(正则/JSONPath)
- 考察点:实际问题解决能力。
七、安全测试
1. 常见漏洞
Q1:如何防御 SQL 注入?
- 使用预编译语句(PreparedStatement) → 输入过滤(黑名单/白名单) → 最小权限原则
考察点:安全防护意识。
Q2:CSRF 攻击的防范措施?
- 验证码 → SameSite Cookie → CSRF Token
- 考察点:安全攻防知识。
八、综合论述题
1. 如何设计一个秒杀系统的测试方案?
功能测试:库存扣减、并发下单、超卖防护(Redis 分布式锁)。
性能测试:模拟 10 万用户并发,监控响应时间与系统吞吐量。
安全测试:防刷单(IP 限流)、身份认证(JWT)。
容灾测试:数据库主从切换、服务降级(Hystrix)
- 考察点:复杂场景的综合设计能力。
附:高频考点总结
类别 | 高频考点 |
---|---|
网络协议 | HTTP/HTTPS、TCP 三次握手、RESTful API 设计原则 |
接口测试 | 参数校验、状态码验证、安全防护(XSS/CSRF) |
性能测试 | TPS/QPS 区别、瓶颈分析(数据库/缓存)、JMeter 脚本编写 |
数据库 | 索引优化、事务隔离级别、慢查询排查 |
系统设计 | 高并发方案(负载均衡/缓存)、分布式事务(TCC/消息队列) |
自动化 | 框架设计(Pytest+Requests)、持续集成(Jenkins)、数据驱动 |