Skip to content

蚂蚁集团测试开发面经(按一二三面拆分 · 可背诵标准回答版)


一、一面(45~60 分钟 · 项目 + 基础 + 手撕代码)

1. 自我介绍

面试官好,我叫 XXX,XX 学校 XX 专业硕士/本科在读。

我有 X 段测试相关经历:
- 在 XX 公司实习期间,负责 XX 模块的功能测试和接口自动化测试

技术栈方面,我熟悉 Python/Java、MySQL、Redis,能独立编写测试脚本。
蚂蚁集团的业务技术含量高,测试涉及支付安全,对质量要求极高,我很认可,也希望能加入这样的团队。

2. 接口和抽象类的区别

1. 抽象类:可以有抽象方法和具体方法
   接口:JDK 8 后可以有 default 和 static 方法

2. 抽象类:单继承
   接口:多实现

3. 抽象类:可以有构造方法
   接口:不能有构造方法

4. 抽象类:可以有成员变量(各种权限)
   接口:成员变量默认是 public static final(常量)

选择:表示"是什么"用抽象类,表示"能做什么"用接口

3. Redis 做分布式锁怎么实现?

SET key value NX PX timeout

- NX:只有 key 不存在时才设置(保证原子性)
- PX:设置过期时间,防止死锁
- value:设置唯一标识,释放锁时验证是否是自己的锁

释放:用 Lua 脚本保证释放锁的原子性
if redis.call("get", KEYS[1]) == ARGV[1] then
    return redis.call("del", KEYS[1])
else
    return 0
end

问题:过期了但业务还没执行完?
→ 可以开一个续期线程,定期延长过期时间(Redisson 的看门狗机制)

4. 接口幂等性是什么?如何保证?

幂等性:同一操作执行多次,结果和执行一次相同。

场景:支付/下单/退款接口必须幂等

保证方案:
1. 数据库唯一索引:插入时用唯一约束防止重复
2. 分布式锁:SETNX 防止并发
3. Token 机制:提交前获取 Token,提交时验证并删除
4. 状态机:只有特定状态才能流转(待支付→已支付→完成)

5. RabbitMQ 用来做什么?

我用过 RabbitMQ 实现定时关单功能。

原理:
1. 用户下单后,发送一条延迟消息到死信队列
2. 等待 15 分钟,检查订单状态
3. 如果未支付,关闭订单,释放库存

RabbitMQ 还可以做什么:
1. 异步处理:用户注册后发邮件/短信,不阻塞主流程
2. 流量削峰:高峰期请求进入队列,后端慢慢处理
3. 分布式事务:用消息队列实现最终一致性

6. Spring AOP 怎么实现?

1. AOP = Aspect Oriented Programming,面向切面编程
2. 核心概念:
   - Join Point:连接点(方法执行)
   - Pointcut:切点(要拦截的方法)
   - Advice:通知(拦截后的处理逻辑:前置/后置/环绕/异常)
   - Aspect:切面(切点 + 通知)

实现方式:
1. JDK 动态代理:只能代理接口
2. CGLIB 代理:可以代理类(通过继承)
3. Spring 默认:接口用 JDK 代理,类用 CGLIB

7. Java 中的锁机制

1. synchronized:
   - 修饰实例方法:锁当前对象
   - 修饰静态方法:锁整个类
   - 修饰代码块:锁指定对象

2. synchronized 锁升级:
   无锁 → 偏向锁 → 轻量级锁 → 重量级锁
   (JDK 6 之后做了优化,锁可以升级但不能降级)

3. ReentrantLock:
   - 可重入锁
   - 支持公平锁/非公平锁
   - 支持 tryLock 尝试获取锁
   - 需要手动释放

4. 死锁:
   多个线程互相等待对方持有的资源。
   避免:按顺序加锁、设置超时、使用锁顺序检测

8. 设计模式:单例怎么写?

python
# Python 单例:懒汉式(线程安全)
class Singleton:
    _instance = None
    _lock = threading.Lock()

    def __new__(cls):
        if cls._instance is None:
            with cls._lock:
                if cls._instance is None:
                    cls._instance = super().__new__(cls)
        return cls._instance

9. Java 运行时数据区

1. 堆(Heap):对象实例、数组,GC 管理
2. 栈(Stack):方法调用、局部变量,每个线程独立
3. 方法区(Method Area):类信息、静态变量
4. 本地方法栈:Native 方法
5. 程序计数器:记录当前执行位置

堆的分区:
- 新生代:Eden + Survivor(From + To)
- 老年代:长期存活对象

10. 线程池参数和工作流程

线程池参数:
1. corePoolSize:核心线程数
2. maximumPoolSize:最大线程数
3. keepAliveTime:空闲线程存活时间
4. unit:时间单位
5. workQueue:任务队列
6. threadFactory:线程工厂
7. handler:拒绝策略

工作流程:
1. 任务进来,先看核心线程池有没有空闲线程
2. 满了就加入队列
3. 队列满了就创建新线程,直到最大线程数
4. 满了就执行拒绝策略

拒绝策略:
1. AbortPolicy:抛异常(默认)
2. DiscardPolicy:丢弃任务
3. DiscardOldestPolicy:丢弃最老的任务
4. CallerRunsPolicy:由调用线程执行

11. 手撕代码:连续子数组最大和

python
def maxSubArray(nums):
    max_sum = nums[0]
    cur_sum = nums[0]
    for i in range(1, len(nums)):
        cur_sum = max(nums[i], cur_sum + nums[i])
        max_sum = max(max_sum, cur_sum)
    return max_sum

12. 手撕代码:找出有序数组中两个重复元素

python
def findDuplicate(nums):
    # 二分查找
    left, right = 1, len(nums) - 1
    while left < right:
        mid = (left + right) // 2
        count = 0
        for num in nums:
            if num <= mid:
                count += 1
        if count > mid:
            right = mid
        else:
            left = mid + 1
    return left

二、二面(60 分钟 · 架构深挖 + 项目)

1. 项目架构相关问题

面试官会深挖:
1. 系统整体架构:画图讲解
2. 微服务拆分:按什么维度拆分,服务间如何通信
3. 数据一致性:分布式事务如何处理
4. 性能瓶颈:哪些地方做了优化
5. 监控告警:如何发现线上问题

2. 职业规划

1. 短期(1~2 年):扎实测试技术,能独立负责模块
2. 中期(3~5 年):深入测试开发,能设计测试平台和方案
3. 长期:测试架构师 / 测试团队负责人

3. 手撕代码:给定字符串删除特定字符(O(1) 空间)

python
def removeChars(s, chars):
    # 用双指针,O(1) 空间
    char_set = set(chars)
    p = 0
    for c in s:
        if c not in char_set:
            s[p] = c
            p += 1
    return ''.join(s[:p])

4. 手撕代码:stringToInt 实现

python
def stringToInt(s):
    s = s.strip()
    if not s:
        return 0

    sign = 1
    if s[0] == '-':
        sign = -1
        s = s[1:]
    elif s[0] == '+':
        s = s[1:]

    result = 0
    for c in s:
        if not c.isdigit():
            break
        result = result * 10 + int(c)

    result *= sign
    result = min(result, 2**31 - 1)
    result = max(result, -2**31)
    return result

三、三面(HR 面 · 稳定性 + 动机)

1. 为什么选择蚂蚁?

1. 蚂蚁是金融科技领域的头部公司,技术实力强
2. 支付业务对质量要求极高,测试工程师能学到很多东西
3. 蚂蚁的分布式系统、大数据等技术都是我感兴趣的方向
4. 团队氛围好,技术分享多

2. 对加班的看法

我认为加班要分情况:
1. 项目紧急时,加班是必要的,可以接受
2. 长期来看,应该通过提高效率来减少不必要的加班
3. 我会尽量在工作时间内高效完成任务

3. 老家在哪里?父母支持吗?

如实回答,并表示家人支持自己在外地工作。

4. 能接受工作地点吗?

如实回答,可以说对杭州/上海等工作地点没有限制。

四、蚂蚁集团面试特点总结

蚂蚁一面:Java 基础(集合/锁/线程池)+ Redis + 项目 + 手撕代码
重点:Java 八股要深入,Redis 分布式锁要掌握

蚂蚁二面:架构深度 + 项目深挖
重点:项目要能讲清楚架构设计,技术选型理由

蚂蚁三面:HR 面
重点:稳定性、动机、对蚂蚁的了解

Powered by VitePress

🔒 需要口令解锁

关注微信公众号
回复关键词 「」 获取口令

解锁后本浏览器长期有效