Java技术复试面试:全面解析

在Java技术复试面试中,面试官通常会问一些涉及基础知识、框架原理以及系统设计等方面的问题。下面是针对常见面试问题的详细解答,帮助你高效准备面试。​编辑

1. 介绍集合

Java中的集合框架主要由三大部分组成:CollectionMapIterator 。每个部分提供了不同的数据存储结构和操作方法。​编辑

  • Collection :是所有集合的根接口,主要包括:ListSetQueueDeque等。

    • List :有序、可重复的集合(如ArrayListLinkedList)。

    • Set :无序、不允许重复元素的集合(如HashSetTreeSet)。

    • Queue :队列,先进先出(FIFO),如PriorityQueue

  • Map :映射接口,存储键值对(如HashMapTreeMap)。

    • HashMap :基于哈希表实现,允许null键和null值。

    • TreeMap:基于红黑树实现,按键值排序。

  • Iterator :用于遍历集合元素的接口,支持hasNext()next()等方法。​编辑

2. List的并发问题

List是一个常用的集合,尤其是ArrayList,但在多线程环境下使用List时会面临并发问题,常见的问题有:

  • ConcurrentModificationException :当多个线程同时修改List时,会导致该异常。
  • 数据不一致性:例如,线程A读取数据时,线程B修改了数据,导致读取到的内容不一致。

为了解决并发问题,可以使用:

  • CopyOnWriteArrayList:线程安全的List实现。
  • Vector:虽然是线程安全的,但性能较低,已经不推荐使用。
  • 使用外部锁(如synchronized)保证线程安全。

3. Set是否有序?去重原理?如何有序?

  • 是否有序Set本身并不保证有序性。具体实现中:

    • HashSet :无序,元素的顺序取决于哈希算法。

    • LinkedHashSet :有序,按照插入顺序保存元素。

    • TreeSet:有序,基于红黑树实现,按自然顺序或者自定义排序规则排序元素。

  • 去重原理Set通过哈希值判断元素是否重复。在HashSet中,通过hashCode()equals()方法判断元素是否相同。​编辑

4. 异常机制

Java的异常机制分为两类:

  • Checked Exception (检查型异常):需要显式捕获或声明的异常(如IOException)。
  • Unchecked Exception (非检查型异常):运行时异常,不需要显式捕获或声明(如NullPointerExceptionArithmeticException)。

Java通过try-catch语句来捕获异常,finally块用于执行清理工作。常见的异常处理流程包括:

java 复制代码
try {  
    // 可能引发异常的代码  
} catch (ExceptionType e) {  
    // 异常处理代码  
} finally {  
    // 清理代码,无论是否发生异常  
}  

5. 线程的5大状态

Java中的线程有五种状态:

  • 新建(New) :线程对象被创建,但尚未调用start()方法。
  • 就绪(Runnable):线程准备好运行,但尚未获得CPU的时间片。
  • 运行(Running):线程正在执行。
  • 阻塞(Blocked):线程等待获取锁资源。
  • 终止(Terminated):线程执行完毕或因异常退出。

6. 线程的创建方式

Java中创建线程有三种方式:

  1. 继承Thread :重写run()方法,调用start()启动线程。
    java class MyThread extends Thread { public void run() { System.out.println("Thread is running"); } } MyThread thread = new MyThread(); thread.start();

  2. 实现Runnable接口 :通过实现run()方法来定义线程的工作内容。
    java class MyRunnable implements Runnable { public void run() { System.out.println("Thread is running"); } } Thread thread = new Thread(new MyRunnable()); thread.start();

  3. 使用CallableExecutorService:返回值形式,适用于任务有返回结果时。

7. 线程池原理

线程池通过复用已有线程来执行任务,减少了频繁创建和销毁线程的开销。主要原理包括:

  • 核心线程数:始终存在的线程数。
  • 最大线程数:线程池能容纳的最大线程数。
  • 任务队列:用于存放待执行的任务。
  • 线程池的拒绝策略 :如ThreadPoolExecutor.AbortPolicyThreadPoolExecutor.DiscardPolicy等。

常见的线程池实现:

  • ExecutorService接口,常用实现为ThreadPoolExecutor

8. 谈谈双亲委派机制

双亲委派机制是类加载器的工作机制。在加载类时,Java的类加载器会遵循以下规则:

  • 委托机制 :每个类加载器都有一个父类加载器。当加载一个类时,当前加载器首先请求父类加载器加载该类,直到最顶层的Bootstrap ClassLoader
  • 好处 :保证了Java核心库(如rt.jar)的类不会被覆盖,确保了JVM的稳定性。

9. 垃圾回收算法介绍

Java的垃圾回收算法主要有以下几种:

  • 标记-清除算法:标记所有需要回收的对象,然后清除它们。缺点是可能产生内存碎片。
  • 复制算法:将内存分为两块,每次使用一块。回收时将活动对象复制到另一块内存中。
  • 标记-整理算法:标记需要回收的对象,然后将活动对象移到一块连续的内存区域,避免内存碎片。
  • 分代回收算法:将堆内存分为年轻代、老年代和永久代,不同代使用不同的回收策略。

10. 谈谈Spring

Spring是一个开源框架,广泛用于Java应用的开发。Spring的核心特性包括:

  • IoC(控制反转)容器:通过依赖注入(DI)管理对象的创建和生命周期。
  • AOP(面向切面编程):通过代理机制实现横切关注点的功能,如日志、事务等。
  • 事务管理:提供声明式事务管理,使得事务的处理变得简单。
  • Spring MVC:Web开发模块,通过分层架构实现MVC模式。

11. 前端发来一条请求,Spring是怎么处理的

当前端发来请求,Spring会按照以下流程进行处理:

  1. 前端请求:浏览器发起HTTP请求。
  2. DispatcherServlet :Spring的核心控制器,它接收到请求后,会根据配置文件(如web.xml)将请求转发给相应的Controller。
  3. HandlerMapping:查找合适的Controller处理请求。
  4. Controller :执行请求逻辑,返回Model和View(通过@RequestMapping映射)。
  5. ViewResolver:根据返回的View名称解析出具体的视图(如JSP页面)。
  6. 响应返回:将视图渲染后返回给前端浏览器。

12. Redis的OOM溢出原因和解决方案

  • 原因 :当Redis的内存使用超过配置的maxmemory限制时,会发生OOM(Out of Memory)错误。常见的原因包括数据过多、配置不合理或缓存策略不当。
  • 解决方案
    • 调整maxmemory配置 :限制Redis使用的最大内存。
    • 使用LRU策略 :根据最近最少使用(Least Recently Used)策略淘汰数据。
    • 定期清理过期数据:通过设置过期时间来防止缓存堆积。

13. Redis的缓存穿透

缓存穿透指的是请求的数据在缓存和数据库中都不存在,这种请求会直接到达数据库,造成数据库的压力。解决方案:

  • 使用布隆过滤器来过滤无效请求。
  • 对不存在的数据缓存一个空值,设置较短的过期时间,防止重复查询数据库。

14. 为什么用RocketMQ,为什么不用其他的MQ?

RocketMQ是一个分布式消息中间件,广泛用于高吞吐量和低延迟的消息传递。相比其他消息队列系统,RocketMQ具有以下优势:

  • 高吞吐量:RocketMQ支持高效的消息队列管理,能够处理大规模数据流动,且支持大批量的消息发送和接收。
  • 分布式事务支持:RocketMQ提供了分布式事务的支持,能够确保消息一致性,适合复杂的业务场景。
  • 灵活的消息消费方式:支持点对点、发布/订阅等多种消费模式,提供灵活的消息消费和传输机制。
  • 高可靠性和高可用性:RocketMQ设计了多副本机制,保证了消息的可靠性,即使部分节点宕机,系统仍能继续运行。

与其他消息中间件如Kafka、RabbitMQ等相比,RocketMQ在高吞吐量、低延迟以及分布式事务模型的支持上有一定优势。

15. RocketMQ的分布式事务模型

RocketMQ的分布式事务模型基于 "3-phase commit"(三阶段提交协议)。其基本流程如下:

  1. 事务消息发送阶段:生产者发送消息到RocketMQ的事务消息队列,并标记该消息为"半消息"。
  2. 事务消息执行阶段:消息生产者执行本地事务操作,并根据事务执行的结果提交或回滚消息。
  3. 事务消息确认阶段:如果本地事务成功,则提交消息;如果失败,则回滚消息。

这个机制确保了消息的可靠性和一致性,适用于分布式系统中的事务管理。

16. Dubbo的原理

Dubbo是一个高性能的Java RPC框架,用于实现分布式服务的通信。其核心原理包括:

  • 服务暴露和引用:Dubbo将服务暴露到网络中,客户端可以通过代理模式引用远程服务。
  • 协议与序列化:Dubbo使用高效的通信协议(如HTTP、Dubbo协议)和序列化机制(如Hessian)来传输数据。
  • 注册中心:Dubbo通过注册中心(如Zookeeper)进行服务发现和负载均衡,客户端可以动态发现可用的服务提供者。
  • 调用与返回:Dubbo的客户端通过代理发起RPC调用,服务端接收到请求后,执行业务逻辑并返回结果。

Dubbo的设计模式非常注重解耦,提供了高效的异步通信和负载均衡能力,适用于大规模分布式系统。


总结:

RocketMQ因其高吞吐量、低延迟以及对分布式事务的支持,特别适合需要高可靠性和可扩展性的场景。Dubbo作为一个轻量级的RPC框架,提供了简单而高效的分布式服务调用方式,广泛应用于微服务架构中。

相关推荐
用户297994363792 小时前
门户功能技术方案实战:搞定动态更新与高频访问的核心玩法
后端
我不是混子2 小时前
为什么不建议使用SELECT * ?
后端·mysql
NightDW2 小时前
amqp-client源码解析1:数据格式
java·后端·rabbitmq
程序员清风3 小时前
美团二面:KAFKA能保证顺序读顺序写吗?
java·后端·面试
风象南4 小时前
SpringBoot的零配置API文档工具的设计与实现
spring boot·后端
程序员爱钓鱼4 小时前
Go语言实战案例-项目实战篇:开发一个 IP 归属地查询接口
后端·google·go
追逐时光者4 小时前
C#/.NET/.NET Core推荐学习书籍(25年9月更新)
后端·.net
IT_陈寒4 小时前
Vue3性能优化:掌握这5个Composition API技巧让你的应用快30%
前端·人工智能·后端
canonical_entropy14 小时前
从同步范式到组合范式:作为双向/δ-lenses泛化的可逆计算理论
后端·低代码·领域驱动设计