Java面试题总结(持续更新中)

97 阅读10分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

hashmap底层:

hash算法散列-->hash冲突-->单向链表-->长度增加到8-->红黑树  特点:快速查找,快速存储,可伸缩
		长度大于8时红黑树整体插入效率高于链表

ConcurrentHashMap

MYSQL index索引底层

采用B+树的数据结构,所有记录的节点都是按照键值大小顺序存档到叶子节点上,B+树的查找效率高,支持排序和范围查找
	B+树适合随机索引和顺序检索,空间利用率高,叶子节点连在一起可以范围查找,顺序查找方便
	中大型表创建索引可以提高查找效率,超大型表创建和维护索引代价变大,考虑分区分表技术

​ 索引建立的场景

对于增删改比较多而查询较少的数据表不需要建立索引,因为维护索引代价也很高
		对于在where条件中不出现的字段没必要建立索引
		多字段联合查询可以用联合索引,字段多且字段值没有重复的可以考虑创建唯一索引,字段多且有重复的可以考虑创建普通索引

​ 索引的设计原则

最适合索引的列是在where后面出现的列或连接条件的列

​ 索引失效情况

使用like,有函数运算,有比较运算,为空判断,进行计算,有or语句

jvm调优

针对的时新生代和老年代的调优,尽量把新生代设置大点,减少程序的Full GC

redis持久化:

AOF:日志追加模式,上次更新时间和redis宕机时间段内的数据会丢失,存储快,一直向文件里追加内容,默认时间1s
	RDB: 默认方式,生成某个时间点的快照文件,效率低

消息队列的几种模式:

主题模式、发布订阅模式、简单队列模式、路由模式、工作模式

docker制作镜像制作原则:

镜像最小化:选择最精简的docker基础镜像,清理构建的中间产物,尽可能减少分层
构建速度最快:注意网络优化等

object有哪些方法:

getClass、hashCode、equals、clone、toString、wait、notify、notifyAll、finalize

如何对sql进行优化,慢查询:

Explain sql语句 查看sql执行计划,查询结果会有type一列,如果是All那就是全文检索,没有使用索引,一般都是all index ref等
	还有一列Extra,显示查询的附加信息 using whereusing index等

session,cookie有哪些属性:

session是保存在server端,关闭浏览器就消失了,过多会造成内存溢出,cookie保存在客户端
	cookie主要有MaxAge、path、name、domain、createTime、lastAccessTime、secure(如果是https或者SSL传输必须为true,默认是false)等属性
	session主要是建立通信后创建一个sessionid的编号给客户端,客户端每次请求都带着这个sessionid

并发锁有哪些,分布式锁 sso单点登录 springboot跨域:

1、重写WebMvcConfigurer 2、使用@CrossOrigin 3、定义新的CrossFilter 前端:JSONP 

消息队列模式 springmvc注解 递归和迭代

递归自己调用自己,迭代可以转化为递归,但是递归不一定能转为迭代,递归浪费空间容易造成堆栈溢出

spingboot声明两个kafka

声明两个yaml配置;创建两个kafka配置类,两个配置类获取两套配置内容;配置类里面生命两套kafka的bean,名字区分

堆和栈异常 堆溢出原因 :

    JVM中堆是存储对象的地方,如果不断的new新对象会造成堆空间溢出
    是否有大量的static修饰的变量,是否有大量的递归或者无限递归,是否使用了大量的循环或者死循环
    是否使用了大量的字符串+的操作造成堆内存中有大量的string对象,没有被jvm及时回收
    是否数据库查询结果返回数据量过大

​ 栈溢出原因:

	JVM中栈是存储方法和局部变量的地方,如果方法调用的深度超过虚拟机允许的最大深度,将会抛出StackOverflowError异常
    最有可能的就是递归调用的时候产生这个结果
    是否有递归调用、是否有大量循环或者死循环、全局变量是否过多、数组 list map是否过大

SQL数据库中把一个表中的数据复制到另一个表中

	1、create table A as selcet * from B; 复制表结构和数据
	2、create table A as selcet * from B where 1=2; 只复制表结构
	dump 导入导出数据文件

redis数据类型和使用场景

StringHashSetListZset

springboot自动配置原理

主动启动类中有@SpringbootApplication的注解,这是一个组合注解,里面又包含了三个比较重要的注解:
@SpringbootConfiguration 作用就是支持javaconfig的方式进行配置,使用configuration类替代xml文件
@EnableAutoConfiguration 开启自动配置
@ComponentScan 扫面当前主启动类下的包包含注解的类进入IOC容器
关于@EnableAutoConfiguration
	自动载入应用程序需要的默认配置,包含两个重要的注解
	@AutoConfigurationPackage 自动配置包
	@Import 给IOC容器导入组件
		里面包含了@AutoConfigurationImportSeclector.class,该类里面的方法会扫面所有jar包下的META_INF/spring.factories
		文件,将里面的EnableConfiguration的数据下面的全类名数组加载到IOC容器中

springboot启动时运行代码:

实现CommandLinerRunner或ApplicationRunner,重写run方法,run方法参数不一样

stringbuilder 和 stringbuffer区别:

stringbuffer线程安全,stringbuilder线程不安全

spring事务的传播行为:是指当一个事务方法被另一个事务方法调用,这个事务方法该如何进行。

	propagation=required、supports、mandatory、requires_new、not_supported
	required:默认,表示当前方法必须在事务中,如果当前事务存在,方法将在当前事务中进行,否则就创建一个新的事务执行
	supports:表示当前方法不需要事务上下文,如果当前存在事务就在当前事务中执行
	mandatory:表示当前方法必须在事务中执行,如果没有抛出异常
	required_new:表示当前方法必须运行在它自己的事务中,执行前如果存在其他事务,则将其他事务挂起
	not_supported:表示当前方法不需要在事务中执行,如果存在事务则挂起事务

数据库的隔离级别

read uncommitted、 read committed、 repeated read、 serializable 

设计模式 mybatis resultMap和resultType区别

	resultType更简单,只有满足ORM时,即数据库表中的字段和实体类的属性完全一致能够使用,或者基本属性,String int等
	resultMap可以灵活定义数据表中字段和实体类属性的关系

Java中list去重

1、使用两层for循环 2、遍历list,然后使用contains方法 3、先将list转为hashset,再将set转为list(无序)
	4、先将list转为TreeSet再将set转为list(有序) 5、使用Java8 stream stream().distinct().collcet(Collctors.toList())

springboot 循环依赖: @Lazy lazy-init 分布式事务

alibaba seata:由3个部分组成:
	主要控制全局事务(TM,事务的发起方),维护全局和分支事务的状态(TC,SEATA服务器)和分支事务处理资源(RM,各个微服务)。
		过程:
		1、Seata拦截业务SQL,在业务数据更新前,保存为before image,执行业务SQL,更新数据后将其保存为after image,生成行锁;
		在一个数据库事务内完成,保证操作的原子性,业务库里默认由undo_log表
		主要在Seata系统库的global、branch和lock表里,image包含的是json串信息,回滚
		2、如果整体业务没有异常,则将第一步保存的快照数据和行锁信息删除即可

java线程池 种类:

	1、newCachedThreadPool 可缓冲的无界的线程池,可灵活处理回收空线程,无可回收,则新建线程。
    2、newFixedThreadPool 指定大小的线程池,可以控制线程的最大并发数,超出线程会被阻塞
    3、newScheduledThreadPool 定长的线程池,可指定核心线程数,支持定时和周期性执行任务
    4、newSingleThreadExcutor 单线程化的线程池,仅有一个线程,按照指定顺序执行任务

​ 参数

		1corePoolSize(线程池的基本大小):当向一个线程池提交任务后,如线程池已创建的线程数量小于corePoolSize,即使存在空闲
			线程,也会创建新的线程执行任务,直到创建的线程数量大于或者等于corePoolSize,才会根据是否存在空闲线程决定是否创建			  新的线程。
		2maxPoolSize(线程池最大大小):线程池允许的最大线程数。当队列满了,且已创建的线程数小于maxPoolSize,则线程池会创建			新的线程执行任务,无界队列可忽略该参数
		3keepAliveTime(线程存活保持时间):当线程池的线程个数多于corePoolSize时,线程的空闲时间超过keepAliveTime会终				止。
		4unit(存活时间的单位):纳秒--天
		5workQueue(任务队列):
			如果运行的线程数少于corePoolSize,则Excutor首选创建新的线程,不进行排队
			如果运行的线程数等于或多余corePoolSize,则Excutor首选加入队列,不添加新的线程
			如果无法请求加入队列则创建新的线程,如果创建线程数量超过了maxPoolSize,任务将被拒绝
		6ThreadFactory(线程工厂):用于创建新的线程

​ java锁

mybatis association:一对一 collection:一对多

springcloud config动态刷新配置文件:

nacos动态获取配置文件

客户端长轮询:
		客户端发送一个http的post请求,超时时间30秒

ArrayList: 默认初始容量为10,每次扩容为上次的1.5倍,扩容的本质就是创建新长度的ArrayList并将就数据复制到新的里面 HashMap扩容: hashmap扩容后,原有数据的Hash值不需要重新计算,因为数组长度变为2倍,需要判断是最高位是1还是0即可 如果是0,则在原位置,如果是1,则是原位置+原长度 java有哪些类型的锁 Synchronize:非公平,悲观,独享,互斥,可重入锁 ReentrantLock

创建线程的三种方式

	1、继承Thread 2、实现Runnable接口,重写run方法 3、实现Callable接口,重现call方法
	Runable和Callable
        Callable可以在任务结束时候提供一个返回值,Runnable无法提供
        Callable的call方法可以抛出异常,而Runnable的run方法不能

Java8 Options 少写if 使用策略模式

设计模式 策略模式 门面模式 AOP和IOC

	AOP:
    由pointcut和advice组成,包含横切逻辑的定义,也包含了连接点的定义。
    通过pointcut和advice定义到特定的joinpoint,然后在advice上编写切面代码

​ spring注解 基于token的鉴权机制

	1、用户使用账号密码请求服务器
	2、服务器验证用户信息
	3、服务器验证通过给用户发送一个token
	4、客户端存储token,每次请求都带着这个token
	5、服务的验证token并返回数据

jwt token

分为三个部分:1、头部 2、载荷 3、签证

spring security

自定义注解

	包含四个元注解:@Rentention @Target @Document @Inherited
	@Retention 定义注解的保留策略,source:仅源码,不在字节码 class:字节码,运行时无法获得  runtime:同时在class和运行时
	@Target 定义注解的作用目标 TYPE:作用于类上,Method:作用在方法上,Parameter:作用于方法参数 Field:作用于字段

​ ​

​ ​ ​