(字节飞书、哈啰、谷歌中国、美团)面试:如何成功转型为Java开发者并找到理想工作的真实经历与分享

我来自一所名气不大的双非一本院校,学习计算机科学与技术。大二时,由于家庭的一些影响和对未来的迷茫,我选择了考研这条路。
去年,因为备战考研而错过了秋季招聘,走出考场的那一刻,我意识到自己在研究生之路上已无法继续。经过一年半的刻苦准备,最终因某校复试线上涨45分而无奈落败。我感到失落和痛苦,但我明白,沉溺于失落并不能为我带来美好的未来,也无法实现我早已规划的梦想。因此,我毅然加入了成千上万的春招大军,尽管我并不知道未来等待我的是什么。

起初,我的专业课程中只涉及了两门Java相关的内容,而且因为当时不够重视,导致我对Java的理解仅停留在面向对象的基础知识上,能做的只是一些简单的条件判断和循环控制。

在准备过程中,我通过各种招聘网站和前辈的建议,逐渐了解到封装、继承、多态,以及企业开发中使用的框架、分布式和微服务等相关知识。看着那些学习路线图,我感到害怕,但时间却不允许我继续犹豫,咬紧牙关,开始了我的学习旅程!

备战面试

以下是我从开始学习到现在的时间表。

  • 一月中上旬,我开始根据马士兵的Java SE视频学习。我知道基础知识的重要性,因此在每天听完几个小节后,**我会在晚上复盘当天学习的知识,并将其记录在博客上,同时在第二天找时间进行复习。**这样的学习方式持续到二月中旬。
  • 二月中旬到二月底,我开始学习前端(HTML、CSS、JavaScript、Vue、ElementUI)。这一阶段我仅仅掌握了一些基础语法,完成了几个Demo和两个项目作业,这是为了后续项目的铺垫。由于学习相对简单,我也经常复习SE的相关知识。
  • 三月初,我开始关注牛客网、Boss直聘和携程的招聘信息,同时学习Java EE知识并不断迭代自己的项目。从最基本的SSM到后来的SpringBoot,我意识到亲自动手实现想法才是最佳学习方法。
  • 到三月二十号,我基本完成了项目的核心功能,虽然还有一些功能停留在想法阶段,考虑到时间的关系,我没有继续完善。从这个时间段起直到五月中旬,我参与了多场笔试和面试,准备了面试中的常见问题。

我的面经

以下是我在字节飞书、哈啰、谷歌中国、美团及其他中小企业面试中被问到的一些知识点,供大家参考。

Java基础知识

  • JDK、JVM与JRE的区别
  • 包装类型的常量池技术
  • 接口与抽象类的区别
  • String、StringBuffer、StringBuilder的区别
  • 泛型擦除的原理
  • 反射的应用场景
  • 异常类型及示例
  • 常用容器及其特点
  • ArrayList的扩容机制
  • HashMap源代码实现
  • ConcurrentHashMap的底层实现
  • Lambda表达式的优缺点及应用场景

Java并发

  • 多线程的优势及具体场景
  • 线程生命周期及其状态标志
  • 避免死锁的三个必要条件
  • 简述哲学家就餐问题与银行家算法
  • 为什么调用start()时执行run(),而不能直接调用run()?
  • 场景题:如何实现实时排序的游戏战力榜单?
  • 场景题:如何实现高并发的竞技场挑战功能?
  • volatile的用法
  • synchronized与ReentrantLock的区别
  • 乐观锁与悲观锁的底层实现
  • 如何在不加锁的情况下保证线程安全?
  • synchronized是可重入锁吗?
  • 使用vector就一定能保证线程安全吗?
  • 多线程实现方式
  • 场景题:如何在高并发情况下保证数据一致性?
  • 场景题:10个线程对i=0做10次自增,最后i的值是多少,为什么?
  • ThreadLocal的原理
  • 场景题:在生产者消费者问题中如何保证当消费者用完产品后,生产者能及时得知?
  • Java线程池类型及参数含义
  • 线程池的拒绝策略

JVM相关知识

  • JVM的基本结构
  • 双亲委派模型的优点
  • 运行时数据区的基本结构及用途
  • 垃圾回收策略
  • 垃圾回收器种类
  • 如何判断一个类是否无用
  • 查看JVM状态的方法
  • G1回收器与旧版的不同
  • 类加载过程及其每个阶段的功能
  • JVM常用参数及调优手段

Spring框架

  • Spring的特性与优势
  • Spring的组件种类
  • 场景题:如何实现一个简单的Spring框架?
  • Spring MVC的底层实现原理
  • IOC与AOP的具体介绍
  • Spring Bean是什么?
  • IOC与DI的关系
  • IOC配置的三种方式
  • 依赖注入的三种方式及构造器注入的优势
  • 场景题:构造器注入类过多时的解决方案
  • AspectJ注解特性及不足
  • Spring如何处理非单例属性的循环依赖?
  • Spring中Bean的生命周期
  • 场景题:自定义一个starter的实现方式

MyBatis知识点

  • 接口层与数据库交互的方式
  • MyBatis的层次结构
  • sqlSessionFactory与SqlSession的介绍
  • Excutor的概念
  • 动态SQL的种类及用途
  • 连接池的必要性
  • $与#之间的区别

计算机网络

  • OSI与TCP/IP模型
  • HTTP与HTTPS的区别
  • HTTPS的加密方式
  • TCP三次握手的过程及作用
  • 四次挥手的过程及作用
  • TCP流量控制的作用
  • ARQ协议介绍
  • 从输入URL到页面加载的过程
  • HTTP如何管理用户状态
  • Cookie的作用及与Session的区别
  • HTTP状态码种类

数据库知识

  • 数据库设计的步骤
  • MySQL的分页方法
  • MyISAM与InnoDB的区别
  • MySQL日志种类及作用
  • 读锁与写锁的底层实现
  • 表级锁与行级锁的实现原理
  • 事务特性
  • 并发事务的常见问题
  • 事务隔离级别的种类
  • 场景题:MySQL应对千万级数据库的策略
  • MVCC的作用
  • 索引的功能及其底层数据结构
  • 为什么InnoDB使用B+树作为索引结构
  • 索引的种类
  • 如何避免回表查询
  • 最左前缀法则
  • 覆盖索引的定义
  • MySQL读写分离方案
  • MySQL主从复制的概念及延迟问题解决方案

Redis知识

  • Redis为何是单线程的
  • Redis的使用场景
  • Redis支持的数据类型及其应用
  • SDS的存在意义
  • Redis Stream的设计初衷
  • Redis Stream中的消费者崩溃及消息丢失问题
  • Redis Stream中的坏消息与死信问题
  • Redis的持久化机制
  • AOF是写前日志还是写后日志?
  • Redis过期键的删除策略
  • Redis内存淘汰算法
  • Redis如何优化内存使用
  • Redis事务命令及错误处理
  • Redis为何不支持回滚
  • Redis缓存问题及解决方案
  • Redis 6.0之前为何不支持多线程