B站 测试开发工程师 一面

面试基本信息

  • 公司: B站(哔哩哔哩)
  • 职位: 测试开发工程师(日常实习)
  • 面试轮次: 一面(技术面)
  • 面试形式: 线上视频面试
  • 面试时长: 约65分钟
  • 面试官: 技术面试官

面试问题与回答

问题1:自我介绍

面试官问题

“首先欢迎你参加本次面试,先请你做一个自我介绍。”

我的回答

“你好,我是王宇哲,然后是一个研一的学生,现在就读于华东师范大学软件工程专业,研究方向是密码学方向。我现在主要的技术栈在Go语言这一块,但是也接触过一些测试相关的知识。我做过一些项目,比如说抖音商城,这是一个基于Go语言、gRPC,然后各种微服务组件组合起来构成的一个微服务框架的项目。然后还有一个是AI Nexus,是我自己做的一个小项目,是一个使用AI的分布式系统,多代理系统,差不多就这些。”

标准/建议回答

自我介绍要更加结构化一些,建议这样组织:

"您好,我是XXX,目前是华东师范大学软件工程专业的研一学生,研究方向是密码学。在技术栈方面,我主要专注于Go语言后端开发,同时也有测试相关的实践经验。

在项目经验方面,我参与了字节跳动青训营的抖音商城项目,这是一个基于Go语言的微服务架构项目,使用了gRPC、服务发现、消息队列等技术。另外我还独立开发了AI Native项目,这是一个多代理AI系统。

除了项目经验,我还有实际的实习经历,负责过CMS系统开发和CI/CD流水线搭建等工作。"

总结反思

  • 回答比较随意,结构性不强
  • 对项目的描述不够清晰
  • 应该突出与测试开发相关的经验

问题2:为什么选择Go语言

面试官问题

“为什么选择做Go语言呢?”

我的回答

“因为Go语言的话我觉得它第一它比较简洁,就是从我个人开发角度来说,我觉得它比较简洁。然后我自己做的时候也比较方便,能部署到我自己的服务器上面去会比较方便。因为它编译好运行以后可以直接部署上去。但Java的话,我服务器它可能会因为还要运行一个虚拟机,所以说它可能会有点慢。所以说从我个人开发角度来说,我倾向于使用Go。其次是Go的语法的话,我觉得是比较简单易懂的,因为它有点像是面向过程的那种语言,Java的话它可能看起来代码量会大一点,当然它不是真的大,基本上就是因为我个人感觉Go语言,对我自己的使用而言会更舒服一些。”

标准/建议回答

选择Go语言主要有几个原因:

首先是部署简单,Go是编译型语言,可以直接编译成二进制文件,部署时不需要额外的运行环境,这对个人项目和小团队特别友好。

其次是语法简洁清晰,Go的设计理念就是简单优雅,学习曲线相对平缓,代码可读性很好。

另外Go在并发编程方面有天然优势,goroutine和channel的设计让并发编程变得简单安全。

最后是性能表现,Go的执行效率比较高,内存占用也相对较小,特别适合云原生和微服务场景。

总结反思

  • 回答了基本想法,但表达不够专业
  • 可以更多从技术特性角度分析

问题3:实习经历介绍

面试官问题

“我看你之前还有一个实习经历是吧?这个是你们说一下你这个实习经历的主要工作有哪些?”

我的回答
描述了在实习期间主要做PHP官网系统重构、数据库迁移(SQLite到MySQL)、CI/CD流水线搭建等工作。

标准/建议回答

我的实习主要负责三个方面的工作:

第一是官网系统重构,使用PHP技术栈重新设计了模板渲染引擎,通过正则表达式实现变量提取和替换。

第二是数据库迁移,将原有的SQLite数据库迁移到MySQL,处理了数据类型兼容性问题,编写Python脚本完成了600多条新闻数据的迁移。

第三是搭建CI/CD流水线,使用阿里云效平台实现了自动化部署,建立了测试环境和生产环境的分离,将部署周期从两周缩短到3-4天。

这些工作让我了解了完整的项目开发流程,特别是质量保障和自动化部署的重要性。

总结反思

  • 项目经验比较完整
  • 体现了一定的工程化思维
  • 与测试开发岗位有一定关联性

问题4:抖音商城项目详解

面试官问题

“我看你去去从近期在做的一个项目是抖音商城这个项目。对,你能大概说一下这个项目的功能有哪些吗?”

我的回答
详细介绍了抖音商城项目的微服务架构,包括用户模块、授权模块、前端模块、订单模块、购物车模块、商品模块、结算和支付模块等。

标准/建议回答

抖音商城是一个基于微服务架构的电商系统,我主要负责以下几个核心模块:

  1. 用户认证授权:实现JWT令牌分发、权限校验和黑名单机制
  2. 前端网关:负责请求路由和权限验证,使用正则表达式进行路径匹配
  3. 订单系统:包括下单流程、库存校验、支付集成和订单超时处理
  4. 商品搜索:使用Elasticsearch实现商品的模糊搜索
  5. 消息队列:使用RocketMQ实现订单处理的削峰填谷

在技术架构上,我们使用了服务注册中心(Nacos)、分布式链路追踪、日志收集等可观测性组件,确保系统的稳定性和可维护性。

总结反思

  • 项目经验丰富,技术栈完整
  • 对微服务架构有实际理解
  • 体现了一定的架构设计能力

问题5:消息队列原理

面试官问题

“你能说一下这个消息队列的底层原理是什么样子的吗?”

我的回答

“消息队列底层的话应该是是我没有了解太多,但是我感觉他应该就是一个队列。因为他我部署的时候,我发现他有一个叫name server,还有一个叫他应该是一个主从结构的。然后他消息的话应该是他就是一个队列然后。它底层应该就是一个队列,直观上看上去就是一个队列。”

标准/建议回答

RocketMQ的底层原理可以从几个层面来说:

首先是架构组成,主要包括Name Server(服务发现)、Broker(消息存储)、Producer(生产者)和Consumer(消费者)。

存储机制上,RocketMQ使用CommitLog进行顺序写入,通过ConsumerQueue建立索引,这样既保证了写入性能,又支持高效的消息检索。

在高可用方面,Broker支持主从复制,Name Server采用无状态设计,避免了单点故障。

消息的可靠性通过同步/异步刷盘、主从同步等机制来保证。

在消费模式上,支持推拉两种模式,可以实现负载均衡和广播消费。

总结反思

  • 对消息队列的理解比较浅层
  • 需要深入学习中间件的底层原理
  • 实际使用经验有,但理论基础需要加强

问题6:数据库基础

面试官问题

“说一下基本的增删改的关键字,周善改查,增删改查四个。”

我的回答
介绍了SELECT、INSERT INTO、UPDATE、DELETE的基本语法。

标准/建议回答

MySQL的基本CRUD操作:

查询(SELECT):SELECT 字段 FROM 表名 WHERE 条件 GROUP BY 字段 HAVING 条件 ORDER BY 字段

插入(INSERT):

  • INSERT INTO 表名 VALUES (值列表)
  • INSERT INTO 表名 (字段列表) VALUES (值列表)

更新(UPDATE):UPDATE 表名 SET 字段=值 WHERE 条件

删除(DELETE):DELETE FROM 表名 WHERE 条件

需要注意的是WHERE条件的使用,避免误删误改数据。

总结反思

  • 基础语法掌握正确
  • 表达比较清晰

问题7:索引的作用

面试官问题

“说一下索引的作用。”

我的回答

“索引的话它主要是为了让这个字段能够提高查询的效率。它是对字段进行加索引的,然后索引的话就是你走这个字段索引完以后,它会再回过头去走主键的那个索引。然后这样的话就是能大大提高搜索效率。因为底层的B+树结构的话,它是支持就可以把查询的速度从O(n)降到O(log n),所以说可以大大提高查询的效率。但是索引有时候也会失效,就是可能会造成一些最终还是会变成全表扫描。然后我们系统优化,就是MySQL优化的话,也要去避免这些可能会造成全表扫描的情况。”

标准/建议回答

索引的作用主要是提高查询效率,具体原理是这样的:

首先,索引使用B+树数据结构,可以将查询时间复杂度从O(n)降低到O(log n)。

其次,索引的查询过程分为两步:先通过索引定位到主键,再通过主键回表获取完整数据,这叫做回表操作。

但是索引也有成本,包括:

  1. 占用额外存储空间
  2. 影响写入性能(每次写入都要维护索引)
  3. 可能失效的情况(如函数操作、类型转换、最左匹配原则等)

所以索引设计要考虑查询模式,避免过多无用索引。

总结反思

  • 基本概念理解正确
  • 对B+树和回表有认识
  • 但表达不够准确,术语使用有误

问题8:TCP和UDP的区别

面试官问题

“能说一下TCP和UDP的区别吗?”

我的回答
介绍了TCP面向连接、可靠性、三次握手四次挥手,UDP面向报文、不可靠但速度快等特点。

标准/建议回答

TCP和UDP的主要区别:

连接性:TCP是面向连接的,需要建立连接后才能传输;UDP是无连接的,直接发送数据。

可靠性:TCP通过序列号、确认应答、重传机制保证可靠传输;UDP不保证可靠性。

效率:TCP头部较大(20字节),有各种控制机制;UDP头部简单(8字节),传输效率高。

应用场景

  • TCP适用于对可靠性要求高的场景,如HTTP、HTTPS、文件传输
  • UDP适用于对实时性要求高的场景,如视频直播、在线游戏、DNS查询

总结反思

  • 基本概念掌握正确
  • 能够结合应用场景分析
  • 回答比较完整

问题9:HTTP和HTTPS的区别

面试官问题

“说一下HTTP和HTTPS的区别。”

我的回答
介绍了端口号区别(80 vs 443)、HTTPS的加密机制、证书验证过程等。

标准/建议回答

HTTP和HTTPS的主要区别:

安全性:HTTP是明文传输,容易被窃听;HTTPS在HTTP基础上加了SSL/TLS加密层。

端口:HTTP默认使用80端口,HTTPS使用443端口。

认证机制:HTTPS使用数字证书验证服务器身份,防止中间人攻击。

加密过程

  1. 客户端请求HTTPS连接
  2. 服务器返回数字证书(包含公钥)
  3. 客户端验证证书有效性
  4. 使用公钥加密随机生成的会话密钥
  5. 后续通信使用会话密钥进行对称加密

性能影响:HTTPS由于加密解密过程,性能略低于HTTP,但现在硬件性能足够,影响微乎其微。

总结反思

  • 对加密原理有基本理解
  • 能够说出具体的握手过程
  • 回答相对完整

问题10:HTTP请求类型

面试官问题

“HTTP的请求有哪些类型?”

我的回答

“主要有GET、POST这两个最常用。然后还有OPTIONS,它是请求方法的。然后PUT、DELETE好像也是比较新一些的类型,好像很少看到。然后还有一个TRACE它好像是用来链路跟踪的类型。还有一个我不太确定了,好像是一个关于HEAD的类型。”

标准/建议回答

HTTP的主要请求方法:

GET:获取资源,幂等且安全
POST:创建资源,非幂等
PUT:更新整个资源,幂等
DELETE:删除资源,幂等
PATCH:部分更新资源
HEAD:获取资源头信息,不返回消息体
OPTIONS:获取服务器支持的HTTP方法
TRACE:用于诊断,回显服务器收到的请求

其中GET、POST是最常用的,PUT、DELETE在RESTful API中使用较多。

总结反思

  • 基本方法都知道
  • 但对每个方法的具体作用不够清晰
  • 表达有些不准确

问题11:HTTP状态码

面试官问题

“HTTP的响应状态码,说一些你比较熟悉的。”

我的回答
介绍了200、301/302、404、403、401、502、503等常见状态码。

标准/建议回答

常见HTTP状态码:

2xx成功

  • 200 OK:请求成功
  • 201 Created:资源创建成功
  • 204 No Content:请求成功但无返回内容

3xx重定向

  • 301 Moved Permanently:永久重定向
  • 302 Found:临时重定向
  • 304 Not Modified:资源未修改,使用缓存

4xx客户端错误

  • 400 Bad Request:请求语法错误
  • 401 Unauthorized:未认证
  • 403 Forbidden:无权限
  • 404 Not Found:资源不存在

5xx服务器错误

  • 500 Internal Server Error:服务器内部错误
  • 502 Bad Gateway:网关错误
  • 503 Service Unavailable:服务不可用

总结反思

  • 常见状态码基本掌握
  • 能够分类说明
  • 个别状态码理解有偏差

问题12:编程题 - 第一个只出现一次的字符

面试官问题

“好,行,那我们来做一个编程的题目。好这个题目二,第一个只出现一次的字符OK。”

我的回答
实现了使用map统计字符出现次数,然后遍历字符串找到第一个出现次数为1的字符的解法。

标准/建议回答

这道题有两种主要解法:

方法一:哈希表(我使用的方法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
func firstUniqChar(s string) int {
count := make(map[rune]int)
// 统计每个字符出现次数
for _, char := range s {
count[char]++
}
// 找第一个出现次数为1的字符
for i, char := range s {
if count[char] == 1 {
return i
}
}
return -1
}

方法二:两次遍历优化
可以用数组代替map,因为字符范围有限,空间复杂度更优。

时间复杂度:O(n),空间复杂度:O(1)(字符集大小固定)

总结反思

  • 解法正确,思路清晰
  • 代码实现没有问题
  • 编程基础扎实

问题13:职业规划

面试官问题

“就是你自己的整体的职业规划大概是什么样子?”

我的回答

“我整体职业规划的话,其实我主要是想要接触一些更多的技术,就是先提升自己的技术能力,然后就是争取未来能走上一些更好的开发岗,测试开测试开发也在内。目前来说的话,主要是想要更多学习的技术,然后学习一些规范更规范的流程。因为我原本实习的公司,他的那个开发它不是它的核心职能部门。所以说我们我们的工作它没有其实是没有一个很规范的一些流程的。所以说我想知道真正的一个开发的规范流程应该是什么样子的,这是我目前想要做的事。然后接下来才是主要就是这些,就是目前来说是这些。”

标准/建议回答

我的职业规划分为几个阶段:

短期目标(1-2年)
通过实习机会深入了解大厂的开发流程和质量保障体系,学习规范的工程化实践,提升技术栈的深度和广度。

中期目标(3-5年)
成为一名优秀的测试开发工程师,能够独立设计和实施自动化测试体系,具备系统架构和性能优化的能力。

长期目标
向技术专家或技术管理方向发展,能够在技术决策和团队建设方面发挥更大作用。

选择测试开发是因为这个岗位既能发挥我的开发能力,又能让我深入了解质量保障体系,对技术的全面性要求更高。

总结反思

  • 表达了学习意愿
  • 对规范流程的渴望很真诚
  • 但规划不够具体和深入

问题14:对测试开发岗位的理解

面试官问题

“那你对测试开发岗位是有什么样的理,就是预期是什么样的,或者是说初步的了解是什么样的。”

我的回答

“测试开发岗位的话他其实就是感觉有点像是。有点像是一个一堵防火墙,它可以能保证最终那个软件上线是能能要尽量确保软件上线是正常的。因为实际上我们开发的时候,就是在开发的过程中,我们可能会因为注重业务的实现,导致忽略了很多忽略很多一些边界条件什么的。就导致最后上线的话,它可能会出现一些bug。然后测试的作用就是在中间给他做一个完整性的测试,然后就是尽可能的杜绝这些出现的问题。”

标准/建议回答

我对测试开发岗位的理解:

核心职责:测试开发不只是一道防火墙,更是质量保障体系的建设者。主要包括:

  1. 设计和实现自动化测试框架
  2. 建设CI/CD流水线中的质量卡点
  3. 进行性能测试和稳定性测试
  4. 开发测试工具和平台

技能要求

  • 扎实的编程能力(自动化测试开发)
  • 深入的业务理解(设计有效的测试策略)
  • 系统性思维(整体质量保障设计)
  • 工具开发能力(提升测试效率)

价值体现:通过技术手段提升研发效率,降低线上故障率,保障用户体验。

总结反思

  • 对岗位有基本认知
  • 理解了质量保障的重要性
  • 但对具体工作内容了解不够深入

面试整体感受

  • 难度评价: 适中偏难
  • 面试官风格: 专业友善,会逐步深入追问
  • 题目类型: 项目经验+基础知识+编程题,全面考察
  • 准备建议: 需要对项目经验进行深度总结,基础知识要扎实

面试结果

  • 当场反馈: 面试官没有明确表态
  • 后续流程: 等待HR通知
  • 个人感受: 整体发挥一般,项目经验较好,基础知识有待加强

经验总结

做得好的地方

  • 项目经验比较丰富,能够详细介绍技术细节
  • 编程题解答正确,代码实现没有问题
  • 对实习工作有深入思考

需要改进的地方

  • 语言表达需要更加专业和准确
  • 基础知识掌握不够深入,特别是中间件原理
  • 对目标岗位的理解还需要加深

准备建议

  1. 项目经验:准备STAR法则描述项目,突出技术难点和解决方案
  2. 基础知识:深入学习Go语言特性、数据库原理、网络协议等
  3. 测试开发:了解自动化测试框架、CI/CD、性能测试等相关知识
  4. 表达能力:多练习技术表达,使用准确的专业术语

知识点复习

  • Go语言并发编程(GMP模型、channel等)
  • 微服务架构设计和中间件原理
  • 数据库索引优化和SQL调优
  • HTTP/HTTPS协议详解
  • 自动化测试和质量保障体系