双非本华为OD:1年开发+1年空窗,从测试岗到Java开发面经

个人情况

深圳大学计算机本科(双非),1年小公司Java后端开发经验(主要做电商平台订单模块),后因家庭原因空窗1年。2025年3月首次华为OD机考未通过,5月通过内部推荐开始系统备战。8月成功通过机考(Java开发岗),但技术面被刷,转岗测试。10月测试岗面试通过,部门急需Java开发,直接转岗,11月拿到Offer,12月初入职。整个流程历时9个月,比常规长,但最终达成目标。

资格面(10/18)

  1. 自我介绍
    “我是深圳大学计算机专业,1年Java开发经验,专注电商平台订单系统。空窗期用于系统化学习,重点补足算法和分布式知识。这次面试希望能将积累落地到华为的业务中。”

  2. 离职原因与空窗期
    “离职因家庭事务需回老家处理,空窗期未放弃技术学习:每天2小时刷********、重学《Java并发编程实战》,并完成2个Spring Boot微服务项目(含Redis缓存、MySQL分库分表)。”

  3. 为什么选择华为OD?
    “华为的工程规范和技术深度吸引我,OD模式能快速接触真实业务,且部门对双非背景友好,符合我‘快速成长’的诉求。”

  4. 技术栈与学习准备
    “Java核心(集合、并发)、Spring Boot、MySQL优化、Redis缓存。学习路径:先刷《剑指Offer》算法,再重学JVM,最后实战项目。重点补了空窗期缺失的分布式知识。”

  5. 反问
    “部门目前主要技术栈是什么?是否有新人导师机制?”

技术一面(11/02)

测试相关

  1. 测试流程参与
    “开发视角:需求评审时提出边界条件(如‘订单金额为0’);编码阶段写单元测试;联调时用Postman验证接口。测试视角:编写测试用例覆盖异常场景(如超时、重复提交),参与回归测试。”

  2. 模块关联梳理
    “通过画时序图和数据库ER图理清关联。例如,订单模块依赖库存模块,我主动和库存组确认了‘库存扣减逻辑’和‘超卖兜底方案’,避免后期联调阻塞。”

  3. 接口测试方法
    “用Postman+Newman跑自动化脚本,覆盖正例/反例;用Arthas监控接口响应时间;模拟高并发用JMeter(如500并发下单测试TPS)。”

  4. 用户视角发现的问题
    “项目中发现‘用户用优惠券下单后,退款时优惠券未回滚’。原需求只考虑了订单状态,未覆盖优惠券状态。我建议增加‘优惠券状态机’,并推动产品补充需求文档。”

  5. Linux命令

    • export PATH=$PATH:/opt/myapp(配置环境变量)
    • df -h(查看磁盘空间)
    • sed -i 's/old/new/g' file.txt(全局替换)
    • find / -name "config.yml"(按文件名查找)

项目相关

  1. 核心模块
    “订单中心:支付回调、库存扣减;用户中心:优惠券核销;数据同步:订单数据异步同步到ES(非实时,因实时同步会拖慢主流程,仅在促销期间用实时方案)。”

  2. 实时同步场景
    “实时同步:支付状态同步(需秒级响应);非实时:订单日志同步(可容忍5分钟延迟,用RabbitMQ队列异步处理)。”

手撕代码

题目: 找出数组中最大的子集,满足任意两数 a % b == 0b % a == 0
示例: 输入 [3,6,9,12] → 输出 [3,6,12](或 [3,9,12])。
思路:

  1. 排序数组(从小到大,确保小数能整除大数)
  2. 动态规划:dp[i] 表示以 nums[i] 结尾的最大子集长度
  3. 遍历 j < i,若 nums[i] % nums[j] == 0,则 dp[i] = max(dp[i], dp[j]+1)
    代码(Java):
public List<Integer> largestDivisibleSubset(int[] nums) {
    Arrays.sort(nums);
    int n = nums.length;
    int[] dp = new int[n];
    int[] prev = new int[n];
    Arrays.fill(dp, 1);
    Arrays.fill(prev, -1);
    
    int maxIdx = 0;
    for (int i = 1; i < n; i++) {
        for (int j = 0; j < i; j++) {
            if (nums[i] % nums[j] == 0 && dp[i] < dp[j] + 1) {
                dp[i] = dp[j] + 1;
                prev[i] = j;
            }
        }
        if (dp[i] > dp[maxIdx]) maxIdx = i;
    }
    
    List<Integer> result = new ArrayList<>();
    while (maxIdx != -1) {
        result.add(nums[maxIdx]);
        maxIdx = prev[maxIdx];
    }
    Collections.reverse(result);
    return result;
}

技术二面(11/06)

项目相关

  1. 项目难点
    “高并发下单时库存超卖。解决方案:Redis+Lua原子扣减(DECR命令),并设置库存预警(低于阈值触发消息队列通知运维)。”

  2. 并发与数据量
    “日均订单10万,订单表2000万条。处理方案:按用户ID分库分表(ShardingSphere),查询用ES索引加速;并发用Redis分布式锁(RedissonRLock)。”

手撕算法

题目: 统计用户输入的单词数(含续行符\)。
输入示例:

3
Hello,world\ 
this is a test.
!@#$% 

输出: 4(单词:Hello, world, this, is)
思路:

  1. 逐行处理,用StringBuilder合并续行(如Hello,world\Hello,world
  2. 用正则[a-zA-Z]+匹配单词
    代码(Java):
import java.util.*;
import java.util.regex.*;

public class WordCounter {
    public static int countWords(String[] lines) {
        StringBuilder sb = new StringBuilder();
        int count = 0;
        Pattern pattern = Pattern.compile("[a-zA-Z]+");
        
        for (String line : lines) {
            if (line.endsWith("\\")) {
                sb.append(line, 0, line.length() - 1); // 去掉续行符
            } else {
                sb.append(line);
                Matcher matcher = pattern.matcher(sb.toString());
                while (matcher.find()) count++;
                sb.setLength(0); // 重置
            }
        }
        return count;
    }
}

测试相关

  1. 测试用例设计

    • 边界:输入空行、仅\、纯标点(如!@#
    • 异常:\独占一行(如line = "\\" → 应忽略)
    • 正常:Hello,world\ → 合并为Hello,world
  2. malloc接口测试

    • 边界:size=0(应返回NULL)
    • 异常:size=10^9(内存不足)
    • 功能:分配后写入数据,验证内容正确

Java八股

  1. Java锁
    synchronized(对象锁/类锁)、ReentrantLock(可中断、公平锁)、StampedLock(读写锁优化)

  2. 线程等待方法
    wait()(Object类)、join()(线程等待)、await()(Condition)

  3. sleep vs wait
    sleep不释放锁,wait释放锁并进入等待池

加面(11/10)

Java八股

  1. Redis使用
    “订单缓存(Redis String)、热点商品缓存(Redis Hash)、分布式锁(Redisson)。”

  2. 缓存一致性
    “先更新DB,再删除Redis(异步删除,防误删);双写一致性用MQ补偿(如RabbitMQ)。”

  3. SQL慢查询
    “原因:全表扫描、索引失效。处理:EXPLAIN分析,加索引(避免重复索引、覆盖索引)。”

  4. 索引注意事项
    “字段选择性高、避免索引过多、覆盖索引优化查询。”

  5. ArrayList vs LinkedList
    ArrayList随机访问快(数组),LinkedList插入删除快(链表)

  6. 线程安全集合
    HashMap不安全;HashtablesynchronizedConcurrentHashMap用分段锁(JDK8+ CAS+红黑树)

  7. 单例模式
    “双重检查锁(volatile保证可见性):private volatile static Singleton instance;
    工厂模式:在订单服务中用OrderFactory统一创建订单类型(如普通订单、优惠券订单)

  8. 接口 vs 抽象类
    接口:多继承、行为契约;抽象类:共性代码复用、状态维护

  9. static方法区别
    static方法不能访问非静态变量,不能重写

  10. 其他修饰符
    final(不可变)、private(封装)、protected(继承访问)

手撕算法

题目: 设计租房系统RoomManager

public class RoomManager {
    // 用HashMap存房源(key: id, value: Room对象)
    private Map<Integer, Room> rooms = new HashMap<>();
    
    public boolean addRoom(int id, int area, int price, int rooms) {
        if (rooms.containsKey(id)) {
            rooms.get(id).update(area, price, rooms);
            return false;
        } else {
            rooms.put(id, new Room(area, price, rooms));
            return true;
        }
    }
    
    public boolean deleteRoom(int id) {
        return rooms.remove(id) != null;
    }
    
    public int[] queryRoom(int area, int price, int rooms) {
        List<Room> list = rooms.values().stream()
            .filter(r -> r.area >= area && r.price <= price && r.rooms == rooms)
            .sorted(Comparator.comparingInt(Room::getPrice).thenComparingInt(r -> -r.area))
            .collect(Collectors.toList());
        return list.stream().mapToInt(r -> r.id).toArray();
    }
    
    static class Room {
        int id, area, price, rooms;
        Room(int area, int price, int rooms) {
            this.area = area; this.price = price; this.rooms = rooms;
        }
        void update(int area, int price, int rooms) {
            this.area = area; this.price = price; this.rooms = rooms;
        }
    }
}

主管面(11/11)

  1. 空窗期解释
    “家庭原因需回老家处理,但未放弃学习:系统重学JVM、刷了200+算法题。现在更清楚职业方向,华为是首选。”

  2. 开发工作细节
    “在上家公司,我主导了订单模块重构:从单体拆微服务,用Spring Cloud,性能提升3倍。”

  3. 印象深刻的Bug
    “支付回调重复触发。原因是没做幂等校验,用Redis+UUID解决(ORDER_ID作为唯一键)。”

  4. 学习方法
    “每天1小时深度学习(如JVM源码),周末实战项目。面试准备3个月,重点补足分布式和算法。”

  5. 学习项目
    “用Spring Boot+Redis实现了一个简易秒杀系统(含库存扣减、防超卖),代码已开源到GitHub。”

  6. 适应性
    “入职后会先熟悉代码库,参与Code Review;用Git分支管理,每天同步进度到团队。”

  7. 反问
    “团队目前技术栈是Spring Cloud Alibaba吗?新人有定期技术分享吗?”

关键经验总结

  • 空窗期不是劣势:用“系统性学习”和“实战项目”证明能力,避免模糊描述。
  • 转岗核心逻辑:测试岗面试时强调“开发技能”,主动提“能快速转Java开发”。
  • 算法准备:华为OD必考,重点练动态规划、字符串处理(如续行符)。
  • Java八股:锁、集合、JVM是高频考点,必须手写代码(如单例模式)。

最后建议:面试前务必用********模拟手撕题,避免现场卡壳。华为看重“工程能力”,回答时多结合项目细节!

#华为OD##深圳##东莞##华为##gap#
全部评论

相关推荐

不会做题的小熊:我感觉我就算是找不到工作,我也不会作弊进去,作弊进去感觉一方面是自己不踏实,其次就是都靠作弊了,那后面肯定工作的心态是不一样的,没有一种内驱力。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务