得物测试开发面经
得物测开一面(2024)
- 自我介绍
- 为什么找测试岗位
- 讲一下测试的一般流程
- 设计测试用例的常用方法
- 如果需要测试一个接口,去测试一个并发场景,应该如何去做
- 如何去设置多线程
- 10万级别的接口访问量,如何去模拟
- 数据库了解如何
- 2000万中有2万条数据是热数据,需要经常使用的,如何实现
- Socket和HTTP的区别
- 现场直播或者打游戏,在线视频,使用HTTP还是Socket
- 如果你负责一个项目,需要多个团队或者业务组合作,作为项目负责人,你会怎么去推动进度以及避免项目中的风险
- 如果推进过程中临时加入新需求,你会如何处理
得物测开一面(2023)
- 自我介绍
- 为什么选择测试工程师
- 优秀的测试工程师应该具备什么素质
- 测试工具的使用
- 编程用的什么语言
- SQL的排序、分页
- 测试从哪几个方面进行测试
- 登录用到什么协议
- 对Web测试怎么测
- 有哪些请求
- 测试框架
- 测试流程
- 会不会接口测试
- 最近还有在学什么吗
得物测开一面(国际部Poizon项目)
- 自我介绍
- 简单介绍一下项目内容
- 介绍一下测试公司网络设备的原理(通过API配置产品的Web页面,测试接口是否连通,以及相应的网络协议)
- TCP/IP的四层分别是?
- 什么是L2,可以分别说说L2和L3的区别吗?
- 知道怎么测试服务端吗?
- 对Python熟悉吗?如果让你判断一个字符串是否为回文,怎么写?
得物测开一面(社招方向)
- 自我介绍
- 介绍最近做过的一个项目
- 小程序项目的重点、难点
- 实际过程中是否会使用微信支付?支付费用如何处理?
- 两周迭代一次的频率对你有什么压力?
- 手机App测试项目的重点和难点
- 如何验证庞大的数据集(50万数据的迁移工作)
- 共有多少种不同类型的券以及多少种不同类型的状态?
- 微信朋友圈评论功能你会怎么进行测试?
- 工作一两年的时间里谁给你的帮助是最大的?
- 本来计划要上线,但是在五点四十八分出现很严重的功能性bug,你会怎么处理
- 你对得物有什么了解?
得物测开一面(青训营,已OC)
- 自我介绍
- 你最擅长的计算机语言是什么
- 之前实习期间做CI/CD,具体工作是什么
- 数据可视化和数据报表你具体做了什么
- 实习经历简单表述
得物测开二面
- 自我介绍
- 实习介绍
- 怎么实现的自动检测
- 简单介绍一下Zookeeper,主要是解决了什么问题,有什么特性
- 介绍下ZNode的相关概念
- 项目在CAP里面是符合了哪两个要素,介绍下CAP理论
- Zookeeper怎么实现分布式锁
- 介绍一下RPC调用的流程
- Redis除了用在缓存的场景外还有什么场景可以使用
- 介绍下Java内部保证线程安全的方法有哪些
- 场景题:在一个很大并发情况下对类中的字段进行累加处理,怎么保证线程安全并保证结果正确
- 说一下死锁怎么产生的,简单介绍一个经典的死锁问题
- 说一下在Java里面怎么会造成死锁
- 说一下这种死锁问题如何避免
- 说一下MySQL里面的隔离级别
- 读已提交和可重复读的区别
- 简单介绍一下OAuth2,有什么核心概念
得物测开三面(项目拷打型)
- 自我介绍(约4分钟)
- 拷打项目(约10分钟)
- 职业规划
- 为什么选择这份工作
- 反问:部门的工作对标、求职建议、后续有什么安排
高频题目汇总
必问八股
- 测试流程
- 测试用例设计方法(等价类、边界值、场景法等)
- TCP/IP四层模型
- L2和L3的区别
- Socket vs HTTP
- 并发测试方案
- 多线程设置
- 线程安全(Java内部保证线程安全的方法)
- 死锁(产生原因、经典问题、如何避免)
- 数据库隔离级别(读已提交 vs 可重复读)
- 分布式锁(Zookeeper实现)
- CAP理论
- Redis应用场景(缓存以外)
- OAuth2核心概念
- RPC调用流程
- Zookeeper(ZNode概念、分布式锁)
- 数据库(热数据处理、SQL排序分页)
常考场景题
- 微信朋友圈评论功能测试
- App测试重点难点
- 50万数据迁移验证
- 严重Bug上线前发现如何处理
- 高并发下字段累加的线程安全
- 项目推动/风险管理
- 临时加需求如何处理
常考问题
- 为什么找测试岗位
- 优秀的测试工程师应具备的素质
- 对公司的了解
- 职业规划
- 为什么选择这份工作
得物暑期 AI 面面经
特点:开始先选熟悉的语言;题目偏综合,有追问
1. 网络不同层级的分工以及协议如何合作
参考回答:
OSI 七层 / TCP/IP 四层模型,每层各司其职:
| 层级 | 代表协议 | 职责 |
|---|---|---|
| 应用层 | HTTP/HTTPS、DNS | 用户数据格式化 |
| 传输层 | TCP/UDP | 端到端可靠传输、流量控制 |
| 网络层 | IP、ICMP | 路由寻址 |
| 数据链路层 | Ethernet、ARP | 相邻节点传输 |
| 物理层 | 光纤、网线 | 比特流传输 |
追问:举实际场景说明各层如何配合解决网络拥塞
场景:HTTP 请求下载大文件时发生网络拥塞
- 传输层(TCP):拥塞控制算法(慢启动、拥塞避免、快重传、快恢复),检测到丢包后降低发送窗口
- 网络层(IP/路由器):RED(随机早期检测)主动丢包,提前通知发送方降速;ECMP 多路径负载均衡
- 应用层(HTTP/2):多路复用,避免队头阻塞;HTTP/3(QUIC)在 UDP 上自己实现拥塞控制,绕过 TCP 限制
- 数据链路层:流量整形(Token Bucket),限制突发流量
2. 数据库锁机制
核心作用: 解决并发操作下的数据一致性问题(脏读、不可重复读、幻读、丢失更新)
常见类别:
| 锁类型 | 说明 | 适用场景 |
|---|---|---|
| 共享锁(S锁/读锁) | 多个事务可同时读,不能写 | 读多写少,数据查询 |
| 排他锁(X锁/写锁) | 只有一个事务可读写,其他全阻塞 | 写操作,需要强一致性 |
| 意向锁 | 表级锁,标记行锁意图 | InnoDB 内部使用 |
| 行锁 | 锁定单行 | 高并发,精细控制 |
| 表锁 | 锁定整张表 | 批量操作,MyISAM |
| 间隙锁(Gap Lock) | 锁定索引间隙,防止幻读 | RR 隔离级别 |
| 乐观锁 | 不加锁,提交时校验版本号 | 读多写少,冲突概率低 |
追问1:排他锁在并发中的作用 + 电商库存扣减如何选锁避免超卖
超卖问题本质: 并发读到同一库存值,各自扣减,导致库存变负
方案对比:
sql
-- 方案1:悲观锁(SELECT FOR UPDATE)
BEGIN;
SELECT stock FROM goods WHERE id=1 FOR UPDATE; -- 加排他锁
UPDATE goods SET stock=stock-1 WHERE id=1 AND stock>0;
COMMIT;
-- 优点:强一致,不会超卖
-- 缺点:高并发下锁竞争严重,吞吐量低
-- 方案2:乐观锁(版本号/CAS)
UPDATE goods SET stock=stock-1, version=version+1
WHERE id=1 AND stock>0 AND version=#{version};
-- 优点:无锁,高并发性能好
-- 缺点:失败需重试,冲突多时重试风暴
-- 方案3:Redis 原子操作(推荐高并发场景)
-- DECR stock_key(原子操作,天然防超卖)
-- 库存预热到 Redis,异步落库实际选择:
- 并发量低 → 悲观锁(简单可靠)
- 并发量高、冲突少 → 乐观锁
- 秒杀/大促 → Redis 原子操作 + 消息队列异步落库
追问2:排他锁的性能问题
- 锁等待:其他事务全部阻塞,响应时间增加
- 死锁:多个事务互相等待对方释放锁
- 锁升级:行锁升级为表锁(大量行锁时 MySQL 可能升级)
- 吞吐量下降:高并发下串行化执行,QPS 骤降
- 长事务风险:持锁时间长,阻塞其他事务
3. Python 深浅拷贝
核心区别:
| 浅拷贝 | 深拷贝 | |
|---|---|---|
| 方式 | copy.copy() / list[:] | copy.deepcopy() |
| 顶层对象 | 新建 | 新建 |
| 嵌套对象 | 共享引用(同一内存地址) | 完全独立(递归复制) |
python
import copy
original = [[1, 2], [3, 4]]
shallow = copy.copy(original)
deep = copy.deepcopy(original)
original[0].append(99)
print(shallow) # [[1, 2, 99], [3, 4]] ← 受影响!
print(deep) # [[1, 2], [3, 4]] ← 不受影响必须用深拷贝的场景:
- 嵌套数据结构(列表套列表、字典套列表)需要独立修改
- 测试框架中复用测试数据,防止用例间互相污染
- 多线程/多进程中传递可变对象
浅拷贝会出的问题:
- 修改嵌套对象时,原对象和拷贝对象同时被修改
- 测试数据污染:前一条用例修改了数据,后一条用例读到脏数据
4. 冒烟测试
定义: 对新版本/新构建进行的快速基础功能验证,判断是否值得进行完整测试
优点:
- 快速(通常 10-30 分钟)
- 早期发现严重问题,节省测试资源
- 作为 CI/CD 流水线的门禁
缺点:
- 覆盖率低,只验证核心路径
- 无法发现深层 Bug
- 用例维护成本(需随功能更新)
冒烟测试没通过怎么处理:
- 立即打回:通知开发该版本不可测,附上失败截图/日志
- 定位失败原因:是新功能引入的 Bug,还是环境问题,还是用例本身问题
- 记录缺陷:提 Bug,标注严重级别(P0/P1)
- 等待修复后重新冒烟:不在不稳定版本上继续测试(避免浪费时间)
- 复盘:冒烟频繁失败说明开发自测不足,推动开发先做 UT
5. 测试环境不稳定、问题复现困难
处理思路:
- 记录现场:截图、日志、请求/响应报文、时间戳,第一时间保留证据
- 环境排查:
- 是否是环境本身问题(服务挂了、数据库连接池满、依赖服务异常)
- 用监控工具(Prometheus/Grafana)查看资源使用情况
- 复现策略:
- 增加日志埋点,记录关键路径
- 固定测试数据,排除数据随机性
- 降低并发,单步执行,缩小问题范围
- 使用 Mock 隔离不稳定的外部依赖
- 沟通协作:
- 与运维确认环境稳定性
- 与开发确认是否有近期变更
- 长期方案:
- 推动搭建稳定的专用测试环境
- 关键服务加健康检查和自动重启
- 测试数据工厂,每次用例前初始化数据
6. 项目介绍(通用框架)
根据自己项目填写,以下为参考结构
项目:接口自动化测试框架
- 技术栈:Python + pytest + requests + Allure
- 负责模块:断言模块、数据提取模块、日志模块
追问1:断言如何实现
python
# 支持多种断言类型:状态码、字段值、包含关系、数据库验证
def assert_response(response, assert_rules):
for rule in assert_rules:
if rule['type'] == 'status_code':
assert response.status_code == rule['expected']
elif rule['type'] == 'json_path':
actual = jsonpath.jsonpath(response.json(), rule['path'])[0]
assert actual == rule['expected']
elif rule['type'] == 'contains':
assert rule['expected'] in response.text
elif rule['type'] == 'db':
actual = db.query(rule['sql'])
assert actual == rule['expected']追问2:正则/JSONPath/动态提取
python
import re, jsonpath
# 正则提取
def extract_by_regex(text, pattern):
match = re.search(pattern, text)
return match.group(1) if match else None
# JSONPath 提取
def extract_by_jsonpath(response_json, path):
result = jsonpath.jsonpath(response_json, path)
return result[0] if result else None
# 动态提取(关联上下文,如 token)
class ContextManager:
_store = {}
@classmethod
def set(cls, key, value):
cls._store[key] = value
@classmethod
def get(cls, key):
return cls._store.get(key)
# 用例中:登录后提取 token,后续用例自动使用
token = extract_by_jsonpath(login_response, '$.data.token')
ContextManager.set('token', token)追问3:日志设计
python
import logging
def setup_logger(name, log_file, level=logging.INFO):
formatter = logging.Formatter(
'%(asctime)s | %(levelname)s | %(name)s | %(message)s'
)
handler = logging.FileHandler(log_file, encoding='utf-8')
handler.setFormatter(formatter)
logger = logging.getLogger(name)
logger.setLevel(level)
logger.addHandler(handler)
return logger
# 关键节点记录:请求URL、请求体、响应状态码、响应体、断言结果7. 最近新学到的知识/工具
结合自身实际,参考方向:
- AI 辅助测试工具(如 Cursor、GitHub Copilot 写用例)
- k8s 基础(kubectl 命令、Pod 日志查看)
- 性能测试新工具(Locust、k6)
- 可观测性(OpenTelemetry、链路追踪)
8. JMeter 如何进行压测
基本步骤:
- 创建测试计划
- 线程组:设置并发用户数、Ramp-Up 时间、循环次数
- 添加 Sampler:HTTP Request,配置接口地址、方法、参数
- 添加配置元件:
- HTTP Header Manager(设置 token 等)
- CSV Data Set Config(参数化测试数据)
- 添加监听器:聚合报告(Aggregate Report)、响应时间图
- 执行压测:
- 先做基准测试(1 用户)
- 逐步加压(10→50→100→500)
- 观察 TPS、响应时间(P99)、错误率
- 分析结果:
- TPS 拐点 = 系统瓶颈
- 错误率 > 1% 需排查
- 结合服务器监控(CPU、内存、GC)定位瓶颈
9. 高并发场景下多项目压测如何高效切换
核心思路:隔离 + 文档化 + 优先级管理
- 环境隔离:每个项目独立的 JMeter 脚本、测试数据、监控看板
- 文档化:每个项目维护一份"压测快速上手文档"(环境地址、关键参数、历史基线)
- 时间分片:按项目阶段错开压测窗口,避免资源竞争
- 自动化脚本:一键切换环境配置(不同项目的 config 文件)
- 状态记录:每次切换前记录当前项目进度,防止遗漏
10. 环境/数据隔离不完善导致测试结果异常,如何沟通推动解决
沟通策略:
- 先定位,再沟通:带着证据(日志、数据对比、影响范围)去找开发,不要只说"有问题"
- 量化影响:说明哪些用例受影响、影响了几个项目、是否影响上线节点
- 提出方案:不只是提问题,同时给出建议方案(如:加环境标识字段、数据库 schema 隔离)
- 升级机制:若开发响应慢,及时同步测试 lead 或项目经理,推动优先级
- 事后复盘:问题解决后推动写入规范,防止复发
11. 发现更优的隔离方案,如何评估可行性并推动落地
评估维度:
- 技术可行性:现有技术栈是否支持,改造成本多大
- 收益:能解决哪些现有痛点,量化收益(减少多少 Bug、节省多少时间)
- 风险:引入新方案的风险点,是否有回滚方案
- 成本:人力、时间、学习曲线
推动落地:
- 先做 POC(小范围验证),用数据说话
- 写方案文档,对比新旧方案
- 找盟友(先说服 1-2 个关键人)
- 从低风险项目试点,成功后推广
- 定期同步进展,保持透明
12. 如何保证覆盖率和准确性
覆盖率:
- 需求覆盖:每条需求对应至少一条用例(需求追踪矩阵)
- 代码覆盖:单元测试用 coverage.py 统计行覆盖率(目标 80%+)
- 接口覆盖:所有接口、所有参数组合(等价类、边界值)
- 场景覆盖:正常流、异常流、边界场景
准确性:
- 断言要精准:不只断言状态码,还要断言业务字段
- 测试数据隔离:每条用例独立数据,避免互相干扰
- 环境一致性:测试环境与生产环境配置对齐
- 定期 Review 用例:随需求变更及时更新用例
13. Bug 优先级
常见分级(P0-P3):
| 级别 | 定义 | 示例 | 处理时限 |
|---|---|---|---|
| P0(Blocker) | 系统崩溃、核心功能完全不可用 | 登录失败、支付崩溃 | 立即修复,阻塞上线 |
| P1(Critical) | 核心功能严重受损,无 workaround | 下单成功但库存不扣减 | 当天修复 |
| P2(Major) | 功能部分受损,有 workaround | 搜索结果排序错误 | 本迭代修复 |
| P3(Minor) | 体验问题、UI 瑕疵 | 按钮颜色偏差、文案错别字 | 下个迭代或酌情处理 |
定级依据:
- 影响范围(多少用户受影响)
- 业务损失(是否涉及资金、数据安全)
- 是否有 workaround
- 出现频率(必现 vs 偶现)
