OPPO后端开发秋招一面面经(已秒过)

OPPO后端开发秋招一面面经(已秒过)
最新回答
干净好听的昵称

2026-10-23 12:11:37

OPPO后端开发秋招一面整体以基础知识考察为主,涵盖多线程、数据库、分布式、Java集合与框架等内容,项目与实习经历询问较少,以下为详细解析:

考察内容与解析
  • 自我介绍

    需简洁清晰阐述个人教育背景、技术栈、项目经历(简要提及核心项目与成果)、技术热情方向等,让面试官快速了解你的基本情况与技术优势。

  • ReentrantLock

    是Java中可重入互斥锁,基于AQS(AbstractQueuedSynchronizer)实现。

    可重入性:同一线程可多次获取同一把锁,每获取一次锁计数器加1,释放一次减1,计数器为0时锁真正释放。

    公平锁与非公平锁:公平锁按请求锁顺序获取,非公平锁可能插队获取,非公平锁吞吐量更高。

    与synchronized区别:ReentrantLock功能更灵活,如可响应中断、可设置超时、可公平锁等;synchronized是Java关键字,使用简单,由JVM实现,在JDK1.6后性能大幅提升。

  • 线程池类型与核心参数

    线程池类型:

    newFixedThreadPool:固定大小线程池,核心线程数与最大线程数相同,可控制并发数,适用于任务量较稳定场景。

    newCachedThreadPool:可缓存线程池,核心线程数为0,最大线程数为Integer.MAX_VALUE,线程空闲60秒后回收,适用于任务多且执行时间短场景。

    newSingleThreadExecutor:单线程线程池,只有一个核心线程,保证任务按顺序执行,适用于需要顺序执行任务场景。

    newScheduledThreadPool:定时任务线程池,支持定时与周期性任务执行。

    核心参数:

    corePoolSize:核心线程数,线程池保持的最小线程数。

    maximumPoolSize:最大线程数,线程池允许创建的最大线程数。

    keepAliveTime:线程空闲时间,超过该时间未任务则回收线程(核心线程除外)。

    unit:时间单位,与keepAliveTime配合使用。

    workQueue:任务队列,用于存放等待执行的任务。

    threadFactory:线程工厂,用于创建新线程。

    handler:拒绝策略,当任务队列满且线程数达到最大线程数时采取的策略,如AbortPolicy(抛异常)、CallerRunsPolicy(调用者执行)等。

  • Mysql索引数据结构与选择原因

    数据结构:主要采用B+树。

    选择原因:

    磁盘IO友好:B+树是平衡多路搜索树,树高度较低,可减少磁盘IO次数,提高查询效率。

    范围查询高效:B+树叶子节点通过指针连接,范围查询时只需定位到起始节点,然后顺序遍历叶子节点即可,无需回溯上层节点。

    查询稳定性高:B+树所有查询都需从根节点到叶子节点,查询路径长度相同,查询效率稳定。

  • 建索引注意事项

    选择合适列:选择经常用于查询条件、排序、分组的列,如WHERE子句、ORDER BY子句、GROUP BY子句中的列。

    避免过多索引:索引会占用存储空间,且插入、更新、删除操作需维护索引,过多索引会影响写入性能。

    考虑列选择性:列选择性越高,索引效果越好,如性别列选择性低,不适合建索引。

    复合索引顺序:遵循最左前缀原则,将选择性高、区分度大的列放在前面。

    避免索引失效:如使用函数、运算符、模糊查询(以%开头)等可能导致索引失效。

  • 项目介绍与问题解决

    选择一个核心项目,介绍项目背景、目标、技术栈、架构设计等。

    重点阐述项目中遇到的最大问题,如性能瓶颈、数据一致性问题、并发问题等,并说明解决方案,体现问题分析与解决能力。

  • 技术学习方式

    可提及阅读经典技术书籍(如《Java编程思想》《深入理解Java虚拟机》等)、在线课程(如慕课网、极客时间等)、技术博客(如CSDN、掘金等)、开源项目学习、参与技术社区讨论等。

  • Mysql四个隔离级别

    读未提交(Read Uncommitted):一个事务可读取另一个事务未提交的数据,存在脏读、不可重复读、幻读问题。

    读已提交(Read Committed):一个事务只能读取另一个事务已提交的数据,解决了脏读问题,但存在不可重复读、幻读问题。

    可重复读(Repeatable Read):同一事务内多次读取同一数据结果一致,解决了脏读、不可重复读问题,但存在幻读问题(InnoDB引擎通过MVCC与间隙锁解决幻读问题)。

    串行化(Serializable):所有事务串行执行,避免了脏读、不可重复读、幻读问题,但并发性能最低。

  • Mysql的MVCC机制

    多版本并发控制:通过保存数据在某个时间点的快照来实现并发控制,读操作不加锁,提高并发性能。

    实现原理:

    隐藏字段:每行记录有创建版本号(创建事务ID)、删除版本号(删除事务ID)。

    ReadView:事务在某一时刻生成的读视图,包含事务ID、活跃事务列表等信息,用于判断记录对当前事务是否可见。

    可见性判断:根据记录的创建版本号、删除版本号与ReadView中的事务ID、活跃事务列表比较,判断记录是否可见。

  • raft主节点挂了选从节点过程

    选举触发:当主节点挂了或网络分区导致其他节点无法与主节点通信时,触发选举。

    候选人发起选举:节点等待随机超时时间后,若未收到主节点心跳,则自增任期号,转为候选人,发起投票请求。

    投票规则:每个节点在一个任期内只能投一票,且优先投给收到请求中任期号最大且日志更完整的候选人。

    选举成功:候选人获得多数节点投票后成为新主节点,开始发送心跳通知其他节点。

  • Redis基本数据类型

    String:最基本数据类型,可存储字符串、整数、浮点数,支持增删改查等操作。

    Hash:键值对集合,适合存储对象,如用户信息。

    List:链表结构,支持两端插入与弹出操作,可用于消息队列、最新消息排行等。

    Set:无序集合,元素唯一,支持交并差等集合操作。

    Zset(Sorted Set):有序集合,元素唯一,每个元素关联一个分数,根据分数排序,可用于排行榜等场景。

  • 双写一致性保证

    方案一:先更新数据库,再删除缓存:可能存在更新数据库成功但删除缓存失败情况,导致数据不一致。可通过重试机制、消息队列保证最终一致性。

    方案二:先删除缓存,再更新数据库:可能存在删除缓存后更新数据库前有读请求将旧数据写入缓存,导致数据不一致。可通过延迟双删(删除缓存、更新数据库、延迟一段时间再删除缓存)解决。

  • 缓存穿透、击穿、雪崩解决

    缓存穿透:查询不存在的数据,导致请求直接访问数据库。可通过布隆过滤器、缓存空对象解决。

    缓存击穿:热点数据缓存过期时,大量请求同时访问数据库。可通过设置热点数据永不过期、加互斥锁解决。

    缓存雪崩:大量缓存同时过期或缓存服务器宕机,导致大量请求直接访问数据库。可通过均匀设置缓存过期时间、多级缓存、限流降级等解决。

  • ConcurrentHashMap实现原理

    JDK1.7:采用分段锁技术,将数据分成多个段,每个段是一个独立的哈希表,段与段之间互不影响,提高并发性能。

    JDK1.8:取消分段锁,采用CAS+synchronized实现,通过节点数组+链表+红黑树结构存储数据,当链表长度超过阈值时转为红黑树,提高查询效率。

  • Spring Bean生命周期

    实例化:通过反射创建Bean实例。

    属性赋值:为Bean实例设置属性值。

    BeanPostProcessor前置处理:调用BeanPostProcessor的postProcessBeforeInitialization方法。

    初始化:调用Bean的初始化方法(如实现InitializingBean接口的afterPropertiesSet方法、自定义init-method方法)。

    BeanPostProcessor后置处理:调用BeanPostProcessor的postProcessAfterInitialization方法。

    使用:Bean实例可供应用程序使用。

    销毁:调用Bean的销毁方法(如实现DisposableBean接口的destroy方法、自定义destroy-method方法)。

  • Spring事务传播机制

    REQUIRED:默认传播行为,若当前存在事务,则加入该事务;若不存在,则创建新事务。

    SUPPORTS:若当前存在事务,则加入该事务;若不存在,则以非事务方式执行。

    MANDATORY:必须在事务中执行,若当前不存在事务,则抛出异常。

    REQUIRES_NEW:创建新事务,若当前存在事务,则挂起当前事务。

    NOT_SUPPORTED:以非事务方式执行,若当前存在事务,则挂起当前事务。

    NEVER:不能在事务中执行,若当前存在事务,则抛出异常。

    NESTED:若当前存在事务,则在嵌套事务中执行;若不存在,则创建新事务。

总结
  • 本次面试主要考察Java基础、数据库、分布式、框架等知识,需对这些知识有深入理解与掌握。
  • 项目与实习经历虽询问不多,但也是展示个人能力的重要部分,需提前准备好相关内容。
  • 面试过程中要保持清晰思路,准确回答问题,对于不确定的问题可表达自己的思考方向。