在游戏大厂的Java后端面试中,除了多线程与JVM调优外,Spring框架、集合机制、语言特性 也是必考内容。本文将结合真实面试题,深入讲解这些核心知识点。 编辑
编辑
一、Spring Bean 的生命周期 编辑
编辑
Spring Bean 的生命周期大致分为 七个阶段:
- 实例化(Instantiation)
 通过反射创建Bean实例。
- 属性赋值(Populate Properties)
 Spring将配置文件或注解中的属性注入到Bean中。
- 实现 BeanNameAware接口(可选)
 获取Bean的名称。
- 实现 BeanFactoryAware/ApplicationContextAware接口(可选)
 获取容器引用。
- 初始化前(BeanPostProcessor 前置处理)
 调用自定义的前置处理逻辑。
- 初始化(InitializingBean.afterPropertiesSet() 或 @PostConstruct)
 完成自定义初始化逻辑。
- 销毁(DisposableBean.destroy() 或 @PreDestroy)
 容器关闭时销毁Bean。
👉 一句话总结 :
Spring Bean 从"创建 → 依赖注入 → 初始化 → 使用 → 销毁"经历完整生命周期,由容器全程管理。
二、Spring 单例 Bean 是否线程安全? 编辑
编辑
不一定线程安全。
Spring 的单例 Bean 默认是 全局唯一的实例 ,如果该 Bean 内部存在可变状态(如成员变量),多个线程同时访问可能会导致 并发问题。
- 无状态 Bean(如 DAO、Service 层的逻辑类) → 线程安全
- 有状态 Bean(内部保存用户会话、缓存等数据) → 非线程安全
✅ 解决方式:
- 使用 ThreadLocal 存储线程独立变量。
- 将 Bean 设计为 无状态。
- 对关键代码块加锁(不推荐,会影响性能)。
三、有状态 Bean 和无状态 Bean 的区别 编辑
编辑
| 类型 | 特征 | 是否线程安全 | 示例 | |
|---|---|---|---|---|
| 有状态 Bean | 保存用户或请求相关数据 | 否 | 保存Session信息的Bean | |
| 无状态 Bean | 不保存状态,仅执行逻辑 | 是 | Service、DAO类 |  编辑 | 
四、Spring 事务机制 编辑
编辑
Spring 的事务管理基于 AOP(面向切面编程) 实现,通过动态代理在方法执行前后添加事务逻辑。
常见的事务传播行为:
- REQUIRED(默认):有事务则加入,没有则创建新事务
- REQUIRES_NEW:总是新建事务
- NESTED:嵌套事务
- SUPPORTS:如果存在事务就加入,否则不使用事务
事务隔离级别(防止脏读、不可重复读、幻读):
- READ_UNCOMMITTED
- READ_COMMITTED
- REPEATABLE_READ
- SERIALIZABLE
常用注解:
            
            
              java
              
              
            
          
          @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)  五、如何实现 HashMap 取出顺序与放入顺序一致?
使用 LinkedHashMap。
LinkedHashMap 继承自 HashMap,但通过 双向链表 维护插入顺序或访问顺序:
            
            
              java
              
              
            
          
          Map<String, String> map = new LinkedHashMap<>();  
map.put("A", "1");  
map.put("B", "2");  
map.put("C", "3");  
System.out.println(map.keySet()); // [A, B, C]  六、HashMap 的扩容时间复杂度及优化
- 扩容机制 :当元素数量超过容量 × 负载因子(默认0.75)时,进行 rehash。
- 时间复杂度:O(n)(每次扩容需要重新计算哈希并移动元素)
✅ 优化策略:
- 预估容量 ,在初始化时设置合适的容量:
 java new HashMap<>(expectedSize * 2);
- 使用ConcurrentHashMap 避免多线程频繁扩容。
- 避免过多小容量Map,可重用实例。
七、JDK8 添加的主要特性
- Lambda 表达式 (函数式编程)
 java list.forEach(item -> System.out.println(item));
- Stream API (集合流式操作)
 java list.stream().filter(x -> x > 10).forEach(System.out::println);
- 接口默认方法(default method)
- Optional 类(避免NullPointerException)
- 新的日期时间API(java.time)
- Nashorn JavaScript 引擎
- ConcurrentHashMap 改进
- 类型推断增强
八、Java 为什么既是解释型语言,又是编译型语言?
- Java 源代码(.java)首先被 编译器编译为字节码(.class) ------ 这是编译型语言特征。
- 然后由 JVM解释执行 ,将字节码翻译为机器指令 ------ 这是解释型语言特征。
- JIT(Just-In-Time)即时编译器结合了两者的优点,使性能接近本地代码。
👉 一句话总结 :
Java 是"先编译再解释"的混合型语言。
九、面向对象与面向过程的区别
| 对比项 | 面向过程 | 面向对象 | 
|---|---|---|
| 核心思想 | 以过程为中心,按步骤解决问题 | 以对象为中心,封装数据与行为 | 
| 代码复用 | 函数复用 | 继承与多态复用 | 
| 适用场景 | 简单逻辑、算法密集型 | 复杂系统、模块化开发 | 
| 示例 | C语言 | Java、C++ | 
十、Java 的类与 C++ 的类区别
| 对比项 | Java | C++ | 
|---|---|---|
| 内存管理 | 自动垃圾回收(GC) | 手动释放内存 | 
| 多继承 | 不支持类多继承(通过接口实现) | 支持类多继承 | 
| 指针 | 无显式指针 | 可直接操作指针 | 
| 平台相关性 | 跨平台 | 平台相关 | 
| 封装性 | 严格访问控制符 | 相对灵活 | 
十一、Java 语言的三大特性
- 
封装(Encapsulation) - 
隐藏内部实现,仅暴露接口。 
- 
提高代码安全性与复用性。 
 java private int health; public void setHealth(int h) { this.health = h; }
 
- 
- 
继承(Inheritance) - 子类继承父类属性与方法,增强可扩展性。
 java class Hero extends Character {}
 
- 子类继承父类属性与方法,增强可扩展性。
- 
多态(Polymorphism) - 同一方法,不同对象有不同实现。
 java Character c = new Mage(); c.attack(); // 动态绑定
 
- 同一方法,不同对象有不同实现。
✨总结
这份面试指南涵盖了游戏大厂常问的Spring、集合与Java语言特性。
面试中,除了死记答案,更重要的是结合实际项目去理解"为什么这么设计"------这正是优秀工程师与普通开发者的分界线。