JAVA 面试题精选

集合篇:

1、ArrayList和LinkedList区别是什么

①数据结构:ArrayList:连续空间存储相同类型的线性数据结构;LinkedList:双向链表结构
②操作数据效率:ArrayList根据下标查找,时间复杂度是O(1),LinkedList不支持下标查找
③内存空间占用:ArrayList连续空间省内存,LinkedList更占用内存
④线程是否安全:都不安全,一般都是局部变量,局部变量不涉及线程安全问题

2、HashMap的实现原理?

①数据结构:数组+链表或红黑树
②添加数据时,计算key的值确定元素在数组的下标,key相同就替换,不同就插入到链表中
③获取数据是,计算key 的下标,来获取元素
④JDK1.8之前用的是 数组+链表;1.8用的是数组+链表/红黑树,链表长度大于8并且数组长度超过64自动转换成红黑树。

Spring篇:

1、Spring中的单例bean线程是安全的吗?

①不是线程安全的,Spring中有一个@scope 注解,默认的值就是singleton,单例的。
②bean是无状态注入的,所以不涉及线程安全问题,如果在bean中定义了可修改的变量,是要考虑线程安全问题的,可是使用枷锁或者多例来解决。

2、什么是AOP?

①面向切面编程,用于把那些于业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取公共模块复用,降低耦合
②AOP使用的场合,统一异常,统一日志,Spring实现的事务

3、Spring的事务是如何实现的?

①其本质是通过AOP功能,对方法的前后进行拦截,在执行方法之前开始事务,在执行目标结束后根据执行情况,进行提交或者回滚

4、Spring的事务失效的原因有哪些?

①异常捕获处理,自己处理了异常,没有抛出
②非public方法导致事务失效,改为public

5、Spring bean 的生命周期?

①首先获取bean的定义信息
②通过构造函数实例化bean
③bean的依赖注入
④处理三个Aware接口
⑤Bean的后置处理器-前置
⑥初始化方法
⑦Bean的后置处理器-后置

6、Spring的循环依赖怎么解决?

①Spring的三级缓存解决了大部分循环依赖
②如果使用了构造方法导致了循环依赖,可以使用@lazy注解解决

7、Spring MVC 的执行流程?

①用户发送请求给前端控制器
②前端控制器收到请求后调用处理器映射器
③处理器映射器找到对应的处理器,生成处理器对象和拦截器,返回给前端控制器
④前端处理器调用处理器适配器
⑤处理器适配器经过适配调用具体的处理器
⑥方法上添加了 @responsebody
⑦返回结果转换成json

8、Spring boot 的自动配置的原理?

①在启动类上有一个注解 @SpringbootApplication,这个注解分别对三个注解进行了封装分别是
@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan
②其中@EnableAutoConfiguration是 实现自动配置类的核心注解,其中通过@Import注解导入了对应的配置选择器
内部读取了META-INF/spring.factories文件中所配置的全类名,这些配置类会根据所定义的bean根据注解来决定是否导入其Spring容器中。

8、springboot项目启动后执行代码?

①在Spring Boot中,可以通过编写一个类并使用@PostConstruct注解来指定该类的初始化方法。当应用程序启动时,这些被标记为@PostConstruct的方法将会自动执行。

Spring-cloud篇:

1、SpringCloud的组件有哪些?

①注册中心-Eureka
②负载均衡-Ribbon
③远程调用-Feign
④服务熔断-Hystrix
⑤网关-gateway

2、服务注册和发现是什么意思?

①服务注册:服务者需要把自己的信息注册到eureka,由eureka来保管这些信息,比如服务名称、IP、端口
②服务发现:消费者向eureka拉取服务列表信息,如果服务者有集群,则消费者利用负载均衡算法,发起一个调用
③服务监控:服务提供者会每隔30秒向eureka发送心跳,报告状态,如果超过90秒没有发送,从eureka剔除

3、Ribbon负载均衡有哪些?

①RoundRobinRule:轮询服务列表来选择服务器
②WeightedRespnseTimeRule:按照权重来选择服务器,响应越长,权重越小
③RandomRule:随机选择一个可用服务器
④ZoneAvoidanceRule:区域敏感策略

4、如果想自定义负载均衡该如何实现?

①创建IRule接口,可以指定负载均衡策略
②在客户端的配置文件中,可以配置某一个服务调用的负载均衡策略

5、什么叫做服务雪崩?

①服务雪崩:一条服务失败,导致整个链路服务都失败的情况
②服务降级:服务自我保护的一种机制,或者保护下游服务的一种方式,确保服务不会崩溃,一般与Feign接口整合,编写降级逻辑
③服务熔断:默认关闭,需要手动打开,如果检测10秒内请求失败率超过50%,就触发熔断机制,之后每过5秒重新尝试请求微服务,如果微服务不能响应,则继续走熔断机制,如果微服务恢复,就关闭。

6、分布式系统理论?

①CAP定理:
分布式系统节点通过网络连接,一定会出现分区问题(p),
当分区问题出现时,系统的一致性(c)和可用性(a)就无法同时满足
②base理论:基本可用、软状态、最终一致
③解决分布式事务的思想和模型:
最终一致思想:各个分支事务分别提交,如果有数据不一致的情况,再想办法恢复(ap),
强一致思想:各分支事务执行完业务不要提交,等待彼此结束,然后统一提交或回滚(cp)

7、分布式事务解决方案?

①MQ方式实现分布式事务,在A服务写数据的时候,需要在同一个事务内发送到另一个事务,异步,性能最好

8、分布式服务的幂等性如何设计?

①幂等:多次调用接口或方法不会改变业务状态,可以保证重复调用和单次调用的结果一致
②如果是新增数据,可以使用数据库唯一索引
③如果是新增或修改数据可以使用 分布式锁 或者使用 token+redis来实现

MySql篇:

1、如何定位慢查询?

①在MySQL中开启了慢日志查询,我们设置的值是2秒,一旦SQL超过2秒就会记录到日志中

2、SQL执行很慢怎么定位?

①一般会使用explan去查看这条SQL的执行情况,可以通过key和lkey_len检查是否命中了索引,也可以判断索引是否失效

3、什么是索引?索引的底层数据结构了解过吗?

①索引是帮助Mysql高效获取数据的数据结构,提高了数据检索的效率,通过索引对数据进行排序,降低CPU的消耗
②Mysql的innerDB引擎用的B+树的数据结构来存储索引,非叶子结点只存储指针,叶子结点存储数据

4、什么是聚簇索引?什么是非聚簇索引?什么是回表查询?

①聚簇索引:数据和索引放到一起,叶子结点保存了整行数据,有且只有一个
②非聚簇索引:数据于索引分开存储,叶子节点保存对应的主键,可以有多个
③回表查询:通过二级索引找到对应的主键值,到聚集索引中查找整行数据,整个过程就是回表

5、索引创建的原则?

①针对数据量大,且查询比较频繁的表建立索引
②针对常作为查询条件,排序,分组操作的字段建立索引
③尽量选择区分度较高的列作为索引,尽量建立唯一索引,区分度越高,使用索引的效率越高
④尽量使用联合索引

6、什么情况下索引会失效?

①违反最左原则,会失效
②范围查询最右边的列
③用函数
④模糊查询%在前面会失效,%在后面不会

7、SQL优化的经验?

①表的设计优化
②索引优化
③SQL语句优化,比如必要select *
④主从复制,读写分离
⑤分库分表

8、事务的特性?

①原子性:要么成功,要么失败
②一致性:事务完成时,所有数据全部一致
③隔离性:事务在不收外部并发操作的影响下独立运行
④持久性:事务一旦提交或者回滚,对数据影响是永久的

9、并发事务的问题?如何对事务进行隔离

①脏读:一个事务读到另一个事务还没有提交的数据
②不可重复读:一个事务先读取同一条记录,但两次读取的数据不同
③幻读:一个事务按条件查询数据时,没有对应的数据,但是插入的时候,又发现这行存在
④隔离级别:①未提交读,②读已提交,③可重复读

10、事务的隔离性是如何控制的?

①隐藏字段:事务ID,回滚指针
②undo log :回滚日志,版本链

11、主从同步的原理?

①主从复制的核心是DDL语句和DML语句
②主库在事务提交后,会把数据变更到二进制文件中
③从库读取主库的二进制文件,写入到中继日志
④然后从中继日志,写入到自己的数据库

Mybatis篇:

1、Mybatis的执行流程?

①读取Mybatis配置文件:mybatis-config.xml 加载运行环境和映射文件
②构造会话工厂sqlsessionfactory
③会话工厂创建sqlsession对象
④操作数据库的接口,executor执行器,同时负责缓存的维护
⑤executor接口的执行方法中,有一个MapperdStatement类型的参数,封装了映射信息
⑥输入参数映射
⑦输入结果映射

2、Mybatis是否支持延迟加载?

①支持,需要用到数据时才进行加载,不需要时就不用加载(一对一、一对多)
②默认是关闭的,在mybatis配置文件中可以启用

3、Mybatis的一二级缓存?

①一级缓存作用域是session,当session进行flush或close之后,将被清空,默认开启
②二级缓存作用域是namespace和mapper,不依赖于sqlsession,需要单独开启,修改mybatis配置并且mapper文件中加上标签。当某一个作用域进行了增删改之后,所有缓存会被清空。

Redis篇:

1、什么是缓存穿透,怎么解决?
①查询到一个不存在的数据,mysql查询不到也不会写入缓存,导致每次请求都是查询数据库
②解决一,缓存空数据
③解决二,加入过滤器

2、什么是缓存击穿,怎么解决?
①给某个key设置了过期时间,在多个请求的时候,key刚好过期,导致大量请求访问数据库可能吧数据库压垮
②解决一,设置互斥锁 (强一致性,性能差)
③解决二,不设置过期时间 (性能高,数据可能不一致)

3、什么是缓存雪崩,怎么解决?
①缓存雪崩指的是设置的缓存设置了同样的过期时间,导致缓存在某一时刻同时失效,将请求转发到DB,导致DB宕机,和击穿的区别是,击穿是 一个key,雪崩是 多个key
②解决,将缓存的过期时间分散开,在原有的过期时间上加一个随机值

4、Redis作为缓存,如何于mysql进行数据同步?
①为了保证数据的强一致性,可以使用redisson 提供的读写锁来保证数据同步,共享锁readlock,加锁之后,其他线程可以共享读操作,排他锁,writelock,加锁之后,阻塞其他线程写操作
②可以使用MQ中间件,更新数据后,发送消息通知缓存删除

5、Redis持久化
RDB:
持久化方式:定时对整个内存做快照
数据完整性:不完整,两次备份之间会丢失
文件大小:会有压缩,文件体积小
宕机恢复速度:很快
数据恢复优先级:低
系统资源占用:高
使用场景:允许容忍几分钟的数据丢失,追求更快的启动速度
AOF:
持久化方式:记录每一次执行的命令
数据完整性:相对完整,取决于刷盘策略
文件大小:记录命令,文件体积很大
宕机恢复速度:漫
数据恢复优先级:高
系统资源占用:低
使用场景:对数据安全性要求较高常见

Rabbit-MQ篇:

1、如何保证消息不丢失?

①开启生产者确认机制,确保生产者的消息能到达队列
②开启持久化,确保消息未消费前在队列不会丢失
③开启消费者确认机制为auto,由spring确认消息处理成功后完成ACK
④开启消费者失败重试机制,多次重试失败后将消息提交到异常交换机,人工处理

2、重复消息如何避免?

①加一个唯一id
②加锁

3、RabbitMQ 死信交换机 和 延迟队列?

①如果消息超时未消费就会变成死信,RabbitMQ可以绑定一个死信交换机,在死信交换机上绑定其他队列,这样就可以消费了

4、RabbitMQ 高可用机制?

①镜像集群:镜像模式搭建集群,一主多从,所有操作都是主节点完成,然后同步给镜像节点,主节点宕机后,镜像节点就会替代主节点
②仲裁队列:主从同步基于RAFT协议,强一致。

5、RabbitMQ和RocketMQ的区别?

①RabbitMQ是基于AMQP(Advanced Message Queuing Protocol)协议的消息中间件,采用的是经典的消息队列模型。它使用Erlang语言编写,具有高可用性和可靠性。
RocketMQ是基于分布式消息协议的消息中间件,采用的是主题(Topic)和队列(Queue)的组合模型。它使用Java语言编写,具有高吞吐量和低延迟的特点。
②RabbitMQ保证消息的顺序性,即按照发送的顺序进行消息的接收和处理。
RocketMQ也可以保证消息的顺序性,但需要在发送消息时指定消息的顺序标识,以便接收者按照指定的顺序进行处理。

并发编程篇:

1、线程和进程的区别?

①进程是正在运行的实例,进程包含了线程,每个线程执行不同的任务
②不同的进程使用不同的内存空间,当前进程下所有线程共享内存空间

2、并行和并发的区别?

①并发是同一时间应对多件事情的能力
②并行是同一时间动手做多件事情的能力

3、创建线程的方式?runnable和callable的区别?线程run方法和start方法的区别?

①继承Thread类;实现runnable接口;实现callable接口;使用线程池
②runnable没有返回值、不能抛异常,callable有返回值、可以抛异常
③start是用来启动线程的,该线程调用run方法里面的逻辑,该方法只能调用一次;run方法封装了要被执行的逻辑,可以被调用多次

4、线程包括那些状态?线程状态之间是如何变化的?

①新建;可运行;等待;阻塞;终止
②创建线程是新建状态,调用了start方法变为可运行状态,如果抢到了CPU的执行权,执行结束后变为终止状态,如果没有抢到CPU的执行权,可能会切换到其他状态

5、新建T1、T2、T3三个线程,如何保证他们按顺序执行?notify和notifyall有什么区别?

①使用join方法解决
②notifyall 是唤醒所有wait方法,notify是唤醒某个wait方法

6、wait方法和sleep方法 的区别?

①共同点:都能让线程暂时放弃当前CPU的使用权,进入阻塞状态
②不同点:
方法归属不同:sleep是thread的静态方法,wart是object的成员方法,每个对象都有
醒来时机不同:sleep会在等待响应毫秒后醒来,wait需要通过notify唤醒
锁的特性不同:wait方法的调用必须先获取wait的对象锁,而sleep不需要

7、如何停止一个正在运行的线程?

①使用退出标志,使线程正常退出,当run方法完成后线程终止。
②使用interrupt方法中断线程

8、死锁产生的条件是什么?

①一个线程同时获取多把锁就容易发生死锁

9、synchronized和lock锁有什么区别?

①语法:synchronized是关键字,使用时退出同步代码块回自动释放锁,lock是接口,需要手动调用unlock方法才能释放
②功能:都是悲观锁,Lock提供了许多synchronized不具备的功能,比如公平锁,可打断,可超时
③性能:没有竞争,synchronized好一点,有竞争力,lock好一点

10、谈谈对volatile的理解?

①是一个关键字,能够防止编译器等优化的发声,让一个线程对共享变量的修改让另一个线程可见,保证了线程之间的可见性

11、导致并发程序出现的原因是什么?

①原子性
②内存可见性
③有序性

12、线程池的核心参数?线程池的执行原理?

①corePoolsize 核心线程数目
②maximumPoolSize 最大线程数目
③keepAliveTime 生存时间
④workQueue 当没有空闲核心线程时,新来的任务会加入到此队列,队列满会创建救急线程
在这里插入图片描述

13、线程池的种类?

①newFixedThreadPool:创建一个长线程池,可控制线程最大并发数,超出的线程会在队列中等待
②newSingleThreadExecutor:创建一个单线程化的线程池,只会用唯一的工作线程来执行任务
③newCachedThreadPool:创建一个可缓存的线程池,如果线程长度超过处理需要,可灵活收回线程
④newScheduledThreadPool:可以执行延迟任务的线程池,支持定时及周期性任务执行

14、谈谈对ThreadLocal的理解?

①可以实现资源隔离,让每个线程各自用各自的资源,避免争用引发线程安全问题
②threadlocal 同时实现了线程内的资源共享

JVM篇:

1、什么是程序计数器?

①线程私有的,每个线程一份,内部保存的字节码行号,用于记录正在执行的字节码指令的地址。

2、什么是虚拟机栈?

①什么是虚拟机栈?
每个线程运行时所需要的内存,叫做虚拟机栈,每个栈由多个栈帧组成,对应着每次调用方法时所占用的内存
②垃圾回收机制是否设计栈内存?
垃圾回收机制主要涉及堆内存,当栈帧弹栈之后,内存会自动释放
③栈和堆的区别是什么?
栈内存一般存储局部变量和方法调用,堆内存存储java对象和数组。堆会垃圾回收,栈不会;
栈的内存是线程私有的,堆内存是线程共有的

3、什么是类加载器?什么是双亲委派模型

①JVM只会运行二级制文件,类加载器作用就是将字节码文件加载到JVM中,从而让java程序可以运行
②双亲委派模型指的是,加载某一个类,先委托上一级的加载器加载,如果上级加载器也有上一级会继续向上委托,如果该类委托上级没有被加载,子加载器尝试加载

4、对象什么时候被垃圾回收?

①如果一个或过个对象没有任何的引用指向他了,就会被垃圾回收。

5、强引用,软引用,弱引用,虚引用的区别?

①强引用 只要所有的GC root 能找到,就不会被回收
②软引用 当垃圾多次回收,内存依然不够的时候,就会被回收
③弱引用 只要垃圾进行回收,就会把弱引用对象回收
④虚引用 必须配合引用队列使用,被引用对象回收时,会将虚引用入队,线程调用虚引用方法释放内存

6、JVM调优参数有哪些?

①设置堆空间大小
②虚拟机栈的设置
③年轻代中伊甸区和两个S区的比例
④设置垃圾回收器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值