Java高级面试题及答案宝典(19道常见必考题图解)

Java高级面试题及答案宝典(19道常见必考题图解)-mikechen

Java高级面试经常问到Java集合Java多线程 、JVM开发框架等,今天就给大家总结了一份Java高级面试题及答案@mikechen

Java虚拟机垃圾回收算法?

Java高级面试题及答案宝典(19道常见必考题图解)-mikechen

1.标记-清除: 这是垃圾收集算法中最基础的,根据名字就可以知道,它的思想就是标记哪些要被回收的对象,然后统一回收。这种方法很简单,但是会有两个主要问题:1.效率不高,标记和清除的效率都很低;2.会产生大量不连续的内存碎片,导致以后程序在分配较大的对象时,由于没有充足的连续内存而提前触发一次GC动作。

2.复制算法: 为了解决效率问题,复制算法将可用内存按容量划分为相等的两部分,然后每次只使用其中的一块,当一块内存用完时,就将还存活的对象复制到第二块内存上,然后一次性清楚完第一块内存,再将第二块上的对象复制到第一块。但是这种方式,内存的代价太高,每次基本上都要浪费一般的内存。 于是将该算法进行了改进,内存区域不再是按照1:1去划分,而是将内存划分为8:1:1三部分,较大那份内存交Eden区,其余是两块较小的内存区叫Survior区。每次都会优先使用Eden区,若Eden区满,就将对象复制到第二块内存区上,然后清除Eden区,如果此时存活的对象太多,以至于Survivor不够时,会将这些对象通过分配担保机制复制到老年代中。(java堆又分为新生代和老年代)

3. 标记-整理 该算法主要是为了解决标记-清除,产生大量内存碎片的问题;当对象存活率较高时,也解决了复制算法的效率问题。它的不同之处就是在清除对象的时候现将可回收对象移动到一端,然后清除掉端边界以外的对象,这样就不会产生内存碎片了。

4.分代收集 现在的虚拟机垃圾收集大多采用这种方式,它根据对象的生存周期,将堆分为新生代和老年代。在新生代中,由于对象生存期短,每次回收都会有大量对象死去,那么这时就采用复制算法。老年代里的对象存活率较高,没有额外的空间进行分配担保,所以可以使用标记-整理 或者 标记-清除。

 

JVM内存模型组成结构?

JVM内容模型如下图所示,主要分为4部分:

Java高级面试题及答案宝典(19道常见必考题图解)-mikechen

Java高级面试题及答案宝典(19道常见必考题图解)-mikechen

Java高级面试题及答案宝典(19道常见必考题图解)-mikechen1.堆:存放对象实例,几乎所有的对象实例都在这里分配内存

  •  堆得内存由-Xms指定,默认是物理内存的1/64;最大的内存由-Xmx指定,默认是物理内存的1/4。
  •  默认空余的堆内存小于40%时,就会增大,直到-Xmx设置的内存。具体的比例可以由-XX:MinHeapFreeRatio指定
  •  空余的内存大于70%时,就会减少内存,直到-Xms设置的大小。具体由-XX:MaxHeapFreeRatio指定。

2.虚拟机栈

虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息本地方法栈:本地方法栈则是为虚拟机使用到的Native方法服务。

3.方法区:存储已被虚拟机加载的类元数据信息(元空间)

1)有时候也成为永久代,在该区内很少发生垃圾回收,但是并不代表不发生GC,在这里进行的GC主要是对方法区里的常量池和对类型的卸载
2)方法区主要用来存储已被虚拟机加载的类的信息、常量、静态变量和即时编译器编译后的代码等数据。
该区域是被线程共享的。
3)方法区里有一个运行时常量池,用于存放静态编译产生的字面量和符号引用。该常量池具有动态性,也就是说常量并不一定是编译时确定,运行时生成的常量也会存在这个常量池中。

4.程序计数器:当前线程所执行的字节码的行号指示器

 

常用的JVM调优工具有哪些?

Java高级面试题及答案宝典(19道常见必考题图解)-mikechen

  1.  Jconsole : jdk自带,功能简单,但是可以在系统有一定负荷的情况下使用。对垃圾回收算法有很详细的跟踪。
  2.  JProfiler:商业软件,功能强大。
  3.  VisualVM:JDK自带,功能强大,与JProfiler类似。
  4.  MAT:MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具。

 

怎么理解Spring IOC?

IOC是Inversion of Control的缩写,多数书籍翻译成“控制反转”。

IOC不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。

传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试,有了IoC容器后,把创建和查找依赖对象的控制权交给了容器,如下图所示:
Java高级面试题及答案宝典(19道常见必考题图解)-mikechen

上图引入了IOC容器,使得A、B、C、D这4个对象没有了耦合关系,齿轮之间的传动全部依靠“第三方”了,全部对象的控制权全部上缴给“第三方”IOC容器。

所以,IOC借助于“第三方”实现具有依赖关系的对象之间的解耦,使程序更优良。

 

Spring IOC的实现原理

IOC容器其实就是一个大工厂,它用来管理我们所有的对象以及依赖关系。

  • 原理就是通过 Java 的反射技术来实现的,通过反射我们可以获取类的所有信息(成员变量、类名等等等);
  • 再通过配置文件(xml)或者注解来描述类与类之间的关系。

这样我们就可以通过这些配置信息和反射技术来构建出对应的对象和依赖关系了,如下图所示:

Java高级面试题及答案宝典(19道常见必考题图解)-mikechen

 

SpringBean的生命周期?

Spring中每个Bean的生命周期如下,主要分为以下8大步骤:

Java高级面试题及答案宝典(19道常见必考题图解)-mikechen

 

Java线程池有哪些参数?

Java线程池主要有如下7个核心参数:

public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue < Runnable > workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)

Java高级面试题及答案宝典(19道常见必考题图解)-mikechen

  • corePoolSize:核心线程数。也就是最少的线程数,即使空闲也要维护的线程数。
  • maximumPoolSize:池里最大线程数量。
  • keepAliveTime:线程最大活跃时间
  • unit:时间单位
  • workQueue:阻塞队列。线程用完时,任务放进的队列。
  • threadFactory:线程工厂
  • handler:丢弃策略。当队列也满的时候,如何处理的策略。

 

如何设计一个Java线程池?

设计一个Java线程池至少需要4个结构:

1、线程池管理:Manger,处理线程生命周期,执行任务;

2、工作线程:Worker,执行具体的任务;

3、任务:Task,任务接口,供业务实现;

4、任务队列:Queue,暂存没有资源执行的任务。

Java实现线程有哪几种方式?

1、继承Thread类实现多线程
2、实现Runnable接口方式实现多线程
3、使用ExecutorService、Callable、Future实现有返回结果的多线程

 

HashMap1.7与1.8底层如何实现(Put方法底层实现)(重点)

Java高级面试题及答案宝典(19道常见必考题图解)-mikechen
1.7底层实现基于数组+链表实现(Key和value封装成Entry对象)1.根据key的hash值,计算该key存放在数组的index位置

2.如果发生index冲突,则会使用单向链表存放

同一个链表中存放的都是hashCode值相同,但是内容值却不同

如果index发生冲突,采用链表存放查询的时间复杂度是为O(n),效率非常低,

所以在JDK1.8开始优化改为红黑树

3. 使用头插入法(并发下扩容可能会发生死循环问题)

1.8底层实现

基于数组+链表+红黑树实现(Key和value封装成Entry对象)

1.根据key的hash值,计算该key存放在数组的index位置

2.如果发生index冲突,则会使用单向链表存放

当数组的容量大于=64且链表长度大于8则会将链表转化成红黑树。

红黑树查询的时间复杂度是为O(logN)

当红黑树的节点个数<6则将红黑树转换成链表

3.使用尾插法 解决了HashMap1.7版本并发扩容引发扩容死循环问题。

 

SpringMVC执行流程是什么?

Java高级面试题及答案宝典(19道常见必考题图解)-mikechen

(1)用户发送请求发送给前端控制器

(2)前端控制器收到请求调用处理器映射器

(3)处理器映射器找到具体得处理器,生成处理器对象以及处理器拦截器并返回给前端控制器

(4)前端控制器调用处理器适配器

(5)处理器适配器经过适配调用具体得处理器

(6)处理器执行完成并返回结果给前端控制器

(7)前端控制器接受到结果,并讲结果传给视图解析器

(8)视图解析器解析后返回具体得view

(9)前端根据view进行渲染视图,并且响应用户

 

Spring  MVC 模型怎么理解?

可以用如下的图形来表示MVC三者之间的关系:
Java高级面试题及答案宝典(19道常见必考题图解)-mikechen

1.模型(Model)

模型封装了数据及对数据的操作,可以直接对数据库进行访问,不依赖视图和控制器,也就是说模型并不关注数据如何展示,只负责提供数据。GUI 程序模型中数据的变化一般会通过观察者模式通知视图,而在 web 中则不会这样。

2.视图(View)

视图从模型中拉取数据,只负责展示,没有具体的程序逻辑。

3.控制器(Controller)

控制器用于控制程序的流程,将模型中的数据展示到视图中。

 

为什么HashMap1.8需要引入红黑树(重点)

1.7HashMap集合中,当我们发生了Hash冲突,则会存放在同一个链表中,当链表的查询长度过长,查询效率非常低,因为采用链表存放查询的时间复杂度是为O(n),从头查询到尾部、在JDK1.8开始优化当数组容量>=64且链表长度>8则会将链表转化为改为红黑树,红黑树的时间复杂度为O(logn),性能有所提升。

 

HashMap1.8链表在什么时候转化成红黑树

当数组的容量大于=64且链表长度大于8则会将链表转化成红黑树。

红黑树查询的时间复杂度是为O(logN)

当红黑树的节点个数<6则将红黑树转换成链表

 

SpringMVC有哪些核心组件?

Java高级面试题及答案宝典(19道常见必考题图解)-mikechen

1)前端控制器(DispatcherServlet)

用户请求到达前端控制器,它就相当于 mvc 模式中的 c,DispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求,DispatcherServlet 的存在降低了组件之间的耦合性。

 

2)处理器映射器(HandlerMapping)

HandlerMapping 负责根据用户请求找到 Handler 即处理器,springmvc 提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。

 

3)处理器(Handler)

Handler 是继 DispatcherServlet 前端控制器的后端控制器,在 DispatcherServlet 的控制下 Handler 对具体的用户请求进行处理。

由于 Handler 涉及到具体的用户业务请求,所以一般情况需要程序员根据业务需求开发 Handler。

 

4)处理器适配器(HandlAdapter)

通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。

 

5)视图解析器(ViewResolver)

ViewResolver 负责将处理结果生成 View 视图,ViewResolver 首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。

 

6)视图(View)

SpringMVC 框架提供了很多的 View 视图类型的支持,包括:jstlView、freemarkerView、pdfView 等。

 

RabbitMQ的技术架构?

RabbitMQ的技术架构如下图所示:

Java高级面试题及答案宝典(19道常见必考题图解)-mikechen

1.生产者(Publisher)

发消息到RabbitMQ中的(Exchange)交换机上。

2.交换机(Exchange)

和生产者建立连接并接收生产者发来的消息

3.消费者(Consumer)

监听RabbitMQ中的(Queue)队列中的消息

4.队列(Queue)

Exchange将消息发送到指定的Queue中,Queue和消费者进行交互

5.路由(Routes)

交换机转发消息到队列的规则

 

Java哪些常用的线程池?

1、ThreadpoolExecutor.newCachedThreadPool:线程池无限大,当执行上一个任务已经完成,会复用上一个任务的线程,而不是每次都新建线程。适合执行时间短的任务。

Java高级面试题及答案宝典(19道常见必考题图解)-mikechen

2、ThreadpoolExecutor.newSingleThreadExecutor:单线程运行的线程池。适合需要顺序执行的任务。

Java高级面试题及答案宝典(19道常见必考题图解)-mikechen

3、ThreadpoolExecutor.newFixedThreadPool:固定线程数量的线程池

Java高级面试题及答案宝典(19道常见必考题图解)-mikechen

4、ThreadpoolExecutor.newScheduleThreadPool:定时线程池。适合周期性执行的任务。

Java高级面试题及答案宝典(19道常见必考题图解)-mikechen

5、Executors.newWorkStealingPool:并发线程池(JDK 1.8)动态调整线程数,并且使用多个队列,以支持给定的并发级别。不保证任务执行顺序。

Java高级面试题及答案宝典(19道常见必考题图解)-mikechen

 

Spring AOP的实现原理

Spring的AOP实现原理其实很简单,就是通过动态代理实现的。

Spring AOP 采用了两种混合的实现方式:JDK 动态代理和 CGLib 动态代理。

  • JDK动态代理:Spring AOP的首选方法。 每当目标对象实现一个接口时,就会使用JDK动态代理。目标对象必须实现接口
  • CGLIB代理:如果目标对象没有实现接口,则可以使用CGLIB代理。

 

SpringBoot、Spring MVC和Spring有什么区别?

1)Spring

Spring最重要的特征是依赖注入。所有Spring Modules不是依赖注入就是IOC控制反转,当我们恰当的使用DI或者是IOC的时候,可以开发松耦合应用。

2)Spring MVC

Spring MVC提供了一种分离式的方法来开发Web应用。通过运用像DispatcherServelet,MoudlAndView 和 ViewResolver 等一些简单的概念,开发 Web 应用将会变的非常简单。

3)SpringBoot

Spring和Spring MVC的问题在于需要配置大量的参数,SpringBoot通过一个自动配置和启动的项来解决这个问题。

 

SpringBoot 与 SpringCloud 区别?

SpringBoot 是快速开发的 Spring 框架,SpringCloud 是完整的微服务框架,SpringCloud 依赖于 SpringBoot。

作者简介

陈睿|mikechen,10年+大厂架构经验,BAT资深面试官,就职于阿里巴巴、淘宝、百度等一线互联网大厂。

👇阅读更多mikechen架构文章👇

阿里架构 |双11秒杀 |分布式架构 |负载均衡 |单点登录 |微服务 |云原生 |高并发 |架构师

以上

关注作者「mikechen」公众号,获取更多技术干货!

后台回复架构,即可获取《阿里架构师进阶专题全部合集》,后台回复面试即可获取《史上最全阿里Java面试题总结

评论交流
    说说你的看法