Java中高级面试题及答案收集(一)

(一)Java基础

1、线程池的原理

预先启动一些线程,线程无限循环从任务队列中获取一个任务进行执行,直到线程池被关闭。如果某个线程因为执行某个任务发生异常而终止,那么重新创建一个新的线程而已。如此反复。

2、为什么要创建线程池?

线程池为线程生命周期开销问题和资源不足问题提供了解决方案。

(1)通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上。其好处是,因为在请求到达时线程已经存在,所以无意中也消除了线程创建所带来的延迟。这样,就可以立即为请求服务,使应用程序响应更快。

(2)而且,通过适当地调整线程池中的线程数目,也就是当请求的数目超过某个阈值时,就强制其它任何新到的请求一直等待,直到获得一个线程来处理为止,从而可以防止资源不足。

3、线程的生命周期

(1)新建 New

当创建Thread类的一个实例(对象)时,此线程进入新建状态(未被启动)。例如:Thread t1=new Thread();

(2)就绪 Runnable

调用Thread类的start方法,线程已经被启动,进入就绪状态,正在等待被分配给CPU时间片,也就是说此时线程正在就绪队列中排队等候得到CPU资源。

(3)运行 Running

线程获得CPU资源正在执行任务(执行run()方法),此时除非此线程自动放弃CPU资源或者有优先级更高的线程进入,线程将一直运行到结束或者时间片结束。

(4)阻塞 Blocked

由于某种原因导致正在运行的线程让出CPU并暂停自己的执行,即进入堵塞状态。阻塞结束后线程进入就绪状态。
堵塞的情况分三种:

(一)等待堵塞:执行的线程执行wait()方法,JVM会把该线程放入等待池中。

(二)同步堵塞:执行的线程在获取对象的同步锁时,若该同步锁被别的线程占用。则JVM会把该线程放入锁池中。

(三)其它堵塞:执行的线程执行sleep()或join()方法,或者发出了I/O请求时。JVM会把该线程置为堵塞状态。
当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完成时。线程又一次转入就绪状态。

(5)死亡 Dead

当线程执行完毕(run方法运行结束)或被其它线程杀死,线程就进入死亡状态,这时线程不可能再进入就绪状态等待执行。

4、什么是线程安全,如何实现线程安全?

(1)当多个线程访问某个方法时,不管你通过怎样的调用方式或者说这些线程如何交替的执行,我们在主程序中不需要去做任何的同步,这个类的结果行为都是我们设想的正确行为,那么我们就可以说这个类时线程安全的。

 (2)一般来说,基本上所有的并发模式在解决线程安全问题时,采用的操作都是序列化访问共享资源。在java中,提供了两种方式,synchronized和Lock。

9、wait()与 sleep()的区别?
sleep()来自 Thread 类,wait()来自 Object 类;

调用 sleep()方法,线程不会释放对象锁。而调用 wait 方法线程会释放对象锁;

sleep()睡眠后不出让系统资源,wait 让其他线程可以占用 CPU;

sleep(milliseconds)需要指定一个睡眠时间,时间一到会自动唤醒。而 wait()需要配合 notify()

或者 notifyAll()使用。

5、synchronized、volatile区别

  1. volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取; synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。
  2. volatile仅能使用在变量级别;synchronized则可以使用在变量、方法、和类级别的
  3. volatile仅能实现变量的修改可见性,不能保证原子性;而synchronized则可以保证变量的修改可见性和原子性
  4. volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。
  5. volatile标记的变量不会被编译器优化;synchronized标记的变量可以被编译器优化

6、Java9比Java8改进了什么;

modularity System 模块系统、HTTP/2、JShell、不可变集合工厂方法、私有接口方法、HTML5风格的Java帮助文档、多版本兼容 JAR、统一 JVM 日志、I/O 流新特性

7、HashMap内部的数据结构是什么?底层是怎么实现的?

8、说说反射的用途及实现,反射是不是很慢,我们在项目中是否要避免使用反射;

9、说说自定义注解的场景及实现;

10、List和Map区别,Arraylist与LinkedList区别,ArrayList与Vector 区别;

(1)List,Set都是继承自Collection接口,Map则不是

(2)ArrayList和LinkedList的大致区别如下:

  1. ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 
  2. 对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。 
  3. 对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。

(3)ArrayList与Vector 区别:

  1. Vector的方法都是同步的(Synchronized),是线程安全的(thread-safe),而ArrayList的方法不是,由于线程的同步必然要影响性能,因此,ArrayList的性能比Vector好。  
  2. 当Vector或ArrayList中的元素超过它的初始大小时,Vector会将它的容量翻倍,而ArrayList只增加50%的大小,这样,ArrayList就有利于节约内存空间。

(二)JVM相关

1、JVM内存模型,GC机制和原理;GC分哪两种;什么时候会触发Full GC?

2、JVM里的有几种classloader,为什么会有多种?

3、什么是双亲委派机制?介绍一些运作过程,双亲委派模型的好处;(这个我真的不会…)

4、什么情况下我们需要破坏双亲委派模型;

5、常见的JVM调优方法有哪些?可以具体到调整哪个参数,调成什么值?

6、JVM虚拟机内存划分、类加载器、垃圾收集算法、垃圾收集器、class文件结构是如何解析的;
 

(三)Java多线程

1、什么是 ThreadLocal?ThreadLocal 和 Synchonized 的区别?
线程局部变量。是局限于线程内部的变量,属于线程自身所有,不在多个线程间共享。Java提供 ThreadLocal 类来支持线程局部变量,是一种实现线程安全的方式。

synchronized 是利用锁的机制,使变量或代码块在某一时该只能被一个线程访问。而 ThreadLocal 为每一个线程都提供了变量的副本,使得每个线程在某一时间访问到的并不是同一个对象,这样就隔离了多个线程对数据的数据共享。

2、创建线程的方式?

继承 Thread 类、实现 Runnable 接口、使用 Executor 框架

(四)Spring专栏

1、Spring AOP的实现原理和场景;(应用场景很重要)

实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。

具体可以在下面的场景中使用:

  • Authentication 权限
  • Caching 缓存
  • Context passing 内容传递
  • Error handling 错误处理
  • Lazy loading 懒加载
  • Debugging  调试
  • logging, tracing, profiling and monitoring 记录 跟踪 优化 校准
  • Performance optimization 性能优化
  • Persistence  持久化
  • Resource pooling 资源池
  • Synchronization 同步
  • Transactions 事务

2、Spring bean的作用域和生命周期

SpringBean的作用域

  • scope:设置bean的作用范围
  • singleton:单例(创建只有一个实例)
  • prototype:原型(创建多个实例)
  • request:对request请求创建新的bean
  • session:一次会话中创建同一个bean
  • global-session:所有会话共享一个bean

Bean实例生命周期的执行过程如下:

  1. Spring对bean进行实例化,默认bean是单例;
  2. Spring对bean进行依赖注入;
  3. 如果bean实现了BeanNameAware接口,spring将bean的id传给setBeanName()方法;
  4. 如果bean实现了BeanFactoryAware接口,spring将调用setBeanFactory方法,将BeanFactory实例传进来;
  5. 如果bean实现了ApplicationContextAware接口,它的setApplicationContext()方法将被调用,将应用上下文的引用传入到bean中;
  6. 如果bean实现了BeanPostProcessor接口,它的postProcessBeforeInitialization方法将被调用;
  7. 如果bean实现了InitializingBean接口,spring将调用它的afterPropertiesSet接口方法,类似的如果bean使用了init-method属性声明了初始化方法,该方法也会被调用;
  8. 如果bean实现了BeanPostProcessor接口,它的postProcessAfterInitialization接口方法将被调用;
  9. 此时bean已经准备就绪,可以被应用程序使用了,他们将一直驻留在应用上下文中,直到该应用上下文被销毁;
  10. 若bean实现了DisposableBean接口,spring将调用它的distroy()接口方法。同样的,如果bean使用了destroy-method属性声明了销毁方法,则该方法被调用;

3、Spring Boot比Spring做了哪些改进?

Spring Boot 基本上是 Spring 框架的扩展,它消除了设置 Spring 应用程序所需的 XML配置,为更快,更高效的开发生态系统铺平了道路。以下是 Spring Boot 中的一些特点:

  1. 创建独立的 spring 应用。
  2. 嵌入 Tomcat , Jetty Undertow 而且不需要部署他们。
  3. 提供的“starters” poms来简化 Maven 配置
  4. 尽可能自动配置 spring 应用。
  5. 提供生产指标,健壮检查和外部化配置
  6. 绝对没有代码生成和 XML 配置要求

4、Spring IOC是什么?优点是什么?

5、SpringMVC、动态代理、反射、AOP原理、事务隔离级别;
 

(五)Java框架技术

(六)中间件

1、了解几种消息中间件产品?各产品的优缺点介绍;

2、消息中间件如何保证消息的一致性和如何进行消息的重试机制(幂等性)?

产生消息的业务动作和消息发送的一致: 如果业务动作执行成功了,那么这个动作产生的消息一定要发送出去。另一方面,如果这个业务没有发生或者失败,就不应该把消息发送出去。

3、怎么避免消息队列中的消息丢失和消息重复?

消息重复:

(1)在发送端和消费端都建立消息记录表,当发送端操作成功后,在发送端的消息记录表中建立一条记录,状态标识成uncomfirm(未确认),将消息投递到消息队列

(2)消费端从消息队列中获取消息后,根据消息操作成功后,在消费端的记录表中建立一条记录,状态标识为confirmed

在支付宝端和余额宝端同时建立消息表

(3)消费端将响应消息投递到响应队列, 发送端获得响应后, 查询发送端的消息表, 如果其中没有消费记录, 则插入新的消息。如果查询有消费的消息, 就停止插入, 并返回已经消费的消息。这样可以避免消息重复消费的问题。

(4)发送端端会有一个定时任务, 相隔一段时间就从消息表中将unconfirm的消息拉取并重新发送, 这样可以避免消息丢失的问题 

4、RabbitMQ 工作模式
简单模式:一个生产者发送消息到队列,一个消费者接收。

工作队列模式:一个生产者,多个消费者,每个消费者获取到的消息唯一,多个消费者只有一个队列。

发布/订阅模式:一个生产者发送的消息会被多个消费者获取,每个消费者只能从自己订阅的队列中获取。

路由模式:生产者发布消息的时候添加路由键,消费者绑定队列到交换机时添加键值,这样就可以接收到需要接收的消息。

通配符模式:基本思想和路由模式是一样的,只不过路由键支持模糊匹配,符号“#”匹配一个或多个词,符号“*”只匹配一个词。

(七)关系型数据库

1、锁机制介绍:行锁、表锁、排他锁、共享锁;

2、乐观锁的业务场景及实现方式;

3、事务介绍,分布式事物的理解,常见的解决方案有哪些,什么事两阶段提交、三阶段提交;

4、MySQL记录binlog的方式主要包括三种模式?每种模式的优缺点是什么?

5、MySQL锁,悲观锁、乐观锁、排它锁、共享锁、表级锁、行级锁;

6、分布式事务的原理2阶段提交,同步异步阻塞非阻塞;

7、数据库事务隔离级别,MySQL默认的隔离级别、Spring如何实现事务、

8、JDBC如何实现事务、嵌套事务实现、分布式事务实现;

9、SQL的整个解析、执行过程原理、SQL行转列;

(八)非关系型数据库

1、Redis为什么这么快?redis采用多线程会有哪些问题?

2、Redis支持哪几种数据结构;

3、Redis跳跃表的问题;

4、Redis单进程单线程的Redis如何能够高并发?

5、Redis如何使用Redis实现分布式锁?

6、Redis分布式锁操作的原子性,Redis内部是如何实现的?

(九)分布式和微服务

1、Dubbo完整的一次调用链路介绍;

2、Dubbo支持几种负载均衡策略?

3、Dubbo Provider服务提供者要控制执行并发请求上限,具体怎么做?

4、Dubbo启动的时候支持几种配置方式?

5、了解几种消息中间件产品?各产品的优缺点介绍;

6、消息中间件如何保证消息的一致性和如何进行消息的重试机制?

7、Spring Cloud熔断机制介绍;

8、Spring Cloud对比下Dubbo,什么场景下该使用Spring Cloud?

(十)拓展或算法

1、红黑树的实现原理和应用场景;

2、NIO是什么?适用于何种场景?

发布了65 篇原创文章 · 获赞 85 · 访问量 27万+

猜你喜欢

转载自blog.csdn.net/u013521220/article/details/103660039