某游戏大厂Java面试指南:Spring、集合与语言特性深度解析 (三)

在游戏大厂的Java后端面试中,除了多线程与JVM调优外,Spring框架、集合机制、语言特性 也是必考内容。本文将结合真实面试题,深入讲解这些核心知识点。​编辑


一、Spring Bean 的生命周期​编辑

Spring Bean 的生命周期大致分为 七个阶段

  1. 实例化(Instantiation)
    通过反射创建Bean实例。
  2. 属性赋值(Populate Properties)
    Spring将配置文件或注解中的属性注入到Bean中。
  3. 实现 BeanNameAware 接口(可选)
    获取Bean的名称。
  4. 实现 BeanFactoryAware / ApplicationContextAware 接口(可选)
    获取容器引用。
  5. 初始化前(BeanPostProcessor 前置处理)
    调用自定义的前置处理逻辑。
  6. 初始化(InitializingBean.afterPropertiesSet() 或 @PostConstruct)
    完成自定义初始化逻辑。
  7. 销毁(DisposableBean.destroy() 或 @PreDestroy)
    容器关闭时销毁Bean。

👉 一句话总结

Spring Bean 从"创建 → 依赖注入 → 初始化 → 使用 → 销毁"经历完整生命周期,由容器全程管理。


二、Spring 单例 Bean 是否线程安全?​编辑

不一定线程安全。

Spring 的单例 Bean 默认是 全局唯一的实例 ,如果该 Bean 内部存在可变状态(如成员变量),多个线程同时访问可能会导致 并发问题

  • 无状态 Bean(如 DAO、Service 层的逻辑类) → 线程安全
  • 有状态 Bean(内部保存用户会话、缓存等数据) → 非线程安全

解决方式:

  1. 使用 ThreadLocal 存储线程独立变量。
  2. 将 Bean 设计为 无状态
  3. 对关键代码块加锁(不推荐,会影响性能)。

三、有状态 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)(每次扩容需要重新计算哈希并移动元素)

优化策略:

  1. 预估容量 ,在初始化时设置合适的容量:
    java new HashMap<>(expectedSize * 2);
  2. 使用ConcurrentHashMap 避免多线程频繁扩容。
  3. 避免过多小容量Map,可重用实例。

七、JDK8 添加的主要特性

  1. Lambda 表达式 (函数式编程)
    java list.forEach(item -> System.out.println(item));
  2. Stream API (集合流式操作)
    java list.stream().filter(x -> x > 10).forEach(System.out::println);
  3. 接口默认方法(default method)
  4. Optional 类(避免NullPointerException)
  5. 新的日期时间API(java.time)
  6. Nashorn JavaScript 引擎
  7. ConcurrentHashMap 改进
  8. 类型推断增强

八、Java 为什么既是解释型语言,又是编译型语言?

  • Java 源代码(.java)首先被 编译器编译为字节码(.class) ------ 这是编译型语言特征。
  • 然后由 JVM解释执行 ,将字节码翻译为机器指令 ------ 这是解释型语言特征。
  • JIT(Just-In-Time)即时编译器结合了两者的优点,使性能接近本地代码。

👉 一句话总结

Java 是"先编译再解释"的混合型语言。


九、面向对象与面向过程的区别

对比项 面向过程 面向对象
核心思想 以过程为中心,按步骤解决问题 以对象为中心,封装数据与行为
代码复用 函数复用 继承与多态复用
适用场景 简单逻辑、算法密集型 复杂系统、模块化开发
示例 C语言 Java、C++

十、Java 的类与 C++ 的类区别

对比项 Java C++
内存管理 自动垃圾回收(GC) 手动释放内存
多继承 不支持类多继承(通过接口实现) 支持类多继承
指针 无显式指针 可直接操作指针
平台相关性 跨平台 平台相关
封装性 严格访问控制符 相对灵活

十一、Java 语言的三大特性

  1. 封装(Encapsulation)

    • 隐藏内部实现,仅暴露接口。

    • 提高代码安全性与复用性。
      java private int health; public void setHealth(int h) { this.health = h; }

  2. 继承(Inheritance)

    • 子类继承父类属性与方法,增强可扩展性。
      java class Hero extends Character {}
  3. 多态(Polymorphism)

    • 同一方法,不同对象有不同实现。
      java Character c = new Mage(); c.attack(); // 动态绑定

✨总结

这份面试指南涵盖了游戏大厂常问的Spring、集合与Java语言特性。

面试中,除了死记答案,更重要的是结合实际项目去理解"为什么这么设计"------这正是优秀工程师与普通开发者的分界线。

相关推荐
程序新视界6 小时前
数据库的分片与分区:有什么区别?
数据库·后端·mysql
IT_陈寒6 小时前
Java 17 新特性实战:这5个隐藏功能让你的代码效率提升50%
前端·人工智能·后端
程序员爱钓鱼6 小时前
Python编程实战 - 函数与模块化编程 - 创建自己的模块与包
后端
程序员爱钓鱼6 小时前
Python编程实战 - 函数与模块化编程 - Python内置模块(math、os、sys、random等)
后端·python·ipython
Victor3566 小时前
Redis(94)如何启用Redis的数据加密?
后端
Victor3566 小时前
Redis(95)Redis的防火墙配置如何设置?
后端
陪我一起学编程8 小时前
Rust 不可变借用:从规则约束到内存安全的深度思考
后端·rust·编程语言
今日说"法"12 小时前
Rust探秘:所有权转移在函数调用中的表现
开发语言·后端·rust
你的人类朋友14 小时前
设计模式的原则有哪些?
前端·后端·设计模式