目录
1.mysql使用innodb引擎,请简述mysql索引的最左前缀,如何优化order by语句
2.在JVM内存模型中,为什么要区分新生去和老年代,对于新生代为什么要区分eden区和survial区?
3.常见的远程调用有几种
4.对于外部衔接的方法需要注意那些问题?
5.关于@Transactional注解范围理解
6.SpringBoot如何管理版本依赖?什么是自动配置,起步依赖?
7.数据库索引原理
8.Integer和int的区别
9.数据库的三大范式
10.什么是Spring的依赖注入?有那些方法进行依赖注入
11.理解JVM
12.浅谈ReentrantLock的设计
13.说一下mysql中事务的实现原理
14.编写一个基于线程安全的懒加载单例模式
15.值传递和引用传递问题
16.异常中的return问题
17.Spring的AOP的时评场景有那些
18.列举Linux的常用命令
19.列举知道并使用过其他前沿技术
20.JVM运行时数据区域包含那几个部分
21.多线程中的start()方法和run()方法的区别时什么
22.简单写一个会导致死锁的程序
23.对于高并发问题的处理方式
24.高可用问题的常用处理方式
26.数据连接池的工作机制是什么
27.那一个List实现最快插入
28.存在i+1的数么<>
33.null问题
34.共享变量多线程可见性问题
35.synchronize锁对象竞争问题
36.高级回答方式 多线程有几种实现方式
37.高级同步有几种实现方式
38.Thread类的常用方法
39.Exception父类问题
40.String值对比问题
43.gc守护线程和volatile问题
1.mysql使用innodb引擎,请简述mysql索引的最左前缀,如何优化order by语句
解:
理解:索引建立和查询是在内存当中,当索引不存在则会在磁盘进行io,如果更新一个字段,会在所有的有关索引进行更新,浪费时间
关键字:
1.如果排序字段不在索引列上会有firesort两种算法,单路排序和双路排序
(单路排序:快速排序,是一种分支思想的排序算法。双路排序:快排优化。单路排序会比双路排序快一点)
2.无过滤不索引(where。limit属于限制条件不是锅炉条件)
3.order by 最左firesort(最好完全匹配,比如3个字段,没有使用第一个字段,后面两个字段使用了,虽然也可以走索引,但是从explain中的extra中会查看也会使用Using firesort。可以去掉后面,不能去掉中间和前面的)
4.顺序错了(where,group by)
5.方向反了firesort(在order by中统一顺序排序,顺序变化会导致firesort)
6.熟练使用explain,必要使用使用optimizer_trance
答案:
1.首先要对sql进行分析检查,过滤字段、排序字段是否按照顺序创建索引
2.如果查询字段不在索引中会导致回表,降低性能
3.一定要有多虑字段
4.多个字段排序字段方向不一致也会导致firesort,降低性能
5.排序字段和索引顺序不一致也会导致firesort,降低性能
6.使用explain关键字段和索引情况
7.尽可能减少没必要的firesort
2.在JVM内存模型中,为什么要区分新生去和老年代,对于新生代为什么要区分eden区和survial区?
关键点:
1.分清jvm标准与实现
2.分清收集算法在g1是逻辑上的划分之前的垃圾回收器可以理解是在物理上
3.标记算法
4.清楚算法
5.内存连续空间
答案:
1.主流垃圾回收器cms g1都使用分代手机算法
2.正常系统运行时候都会产生海量的临时对象,这些对象短时间会大量实现,我们把这个对象产生的区域叫新生代
3.新生代满了之后需要清理垃圾对象,把有用的对象存放到老年代,方法后续的使用
4.为了区分那些对象应该复制到老年代中,所以新生代划分出edun区s0,s1区域
5.细化后新生代的内容再次划分保障高速读写同时内存连续
1.新对象会被保存到eden区(开始是空的所以内存连续,eden区满了后会把有效休想复制到s0区(s0也是空的所以连续))
2.清楚eden区(再次写入连续空间)
3.s0和s1在命名上呼唤,远在的s1等待写入(空的)
4.eden区再次满了重复操作(15次后,进入老年代)
6. eden区通过复制/清楚算法保障了读写连续性
3.常见的远程调用有几种
关键点:
1.网络协议与封装所有的网络请求是基于Tcp和Udp协议的
2.常用框架(netty,restTemplate)
3.长连接(复用)
答案:
1.自定以协议实现c/s RPC调用(实现复杂,需解决问题多,serversocket,BIO,通过FileInputStream、FileOutPutStream,进行读写)
2.UDP广播类型(查用于通讯、速度快、但要二次确认)
3.基于http协议调用基于restful风格的api,springcloud就是使用http
4.dubbo协议(阿里出品,长连接,二进制传输数据,性能比较高)
5.soap协议(古老的webservice框架,基于xml实现数据封装,http请求)
6.异步响应式(webFlux,SpringBoot Data Reactive)
7.服务器堆(不主动调用,常见系统通知类,单工和双工通知,聊天室)
4.对于外部衔接的方法需要注意那些问题?
1.写好接口文档,方法系统维护和团队写作
2.统一报文结构
3.标准化的服务状态码 status_code=200//请求成功
4.统一化请求日志以及异常记录
5.GlobalExceptionHandler logger.error("服务器异常",exception)
6.请求延迟过高,可以快速失败
7.重试机制
8.事务问题可回滚(Seata类似框架实现)
9.数据一致性问题(加锁)
5.关于@Transactional注解范围理解
关键字:
1.数据库事务
2.编程式事务:beginTransaction,commit.rollback
3.声明式事务@Transaction
答:不能再类上声明事务,虽然可以开启但是效率慢,在单独的方法上添加@Transaction,
6.SpringBoot如何管理版本依赖?什么是自动配置,起步依赖?
关键点:
1.maven
2.springboot父子关系
3.spring-boot-starter
答案:
1.springboot底层使用maven管理依赖,通过控制pom.xml父子关系完成细节配置,在父pom中定义具体框架和版本号
2.提供很多场景的spring-boot-starter,来标准化引入依赖避免环境冲突
什么是自动配置
关键点:
1.看springboot的源码
2.@SpringBootAutoConfiguration开启自动配置功能,包含@EnableAutoConfiguration,@SpringBootConfiguration,@ComponentScan注解
3.@EnableAutoConiguration开启自动配置功能,包含@AutoConfigurationPackage,@import
1.@AutoConfigurationPackage中@import(AutoConfigurationPackages.class)引入Registart.class完成批量注册,默认扫描启动类的包@Bean或@Component注解
2.@import(AutoConfigurationImportSelector.class)
4.@ComponentScan扫描被@Component@Service@Controller注解的bean加载到容器中
5.@SpringBootConfiguration表示SpringBoot配置类
答案:
1.所加载使用的jar包比较常见的,spring默认默认配置
2.springboot通过在启动类添加@SoringBootApplication完成自动配置类
3.内部完成读取每个jar包下的MET-INF/Spring.factories和spring-boot-autoconfigure-版本.jar的默认配置
起步依赖:
答案:各种start重点是在pom,xml,其中包含框架所需要的其他依赖不需要我们配置。
7.数据库索引原理
关键点:
1.那种数据库
2.以mysql为例的b+树
3.索引的好处和代价
5.优化:
1.硬件层面
2.软件层面
数据库索引的原理?
1.以mysql为例,默认引擎InnoDB使用b+树实现索引,在索引查找时实现了log(n)的时间复杂度
b+树中每一个结点时固定大小的,一页默认表示16k
2.索引类型分为聚簇索引(记录完整数据)和非聚簇索引(索引字段+主键id)。
聚簇索引的叶子结点记录完整的值,比如一个表有id,name,age,主键为id,那么聚簇索引会默认生成,他是以id为主键,包含数据name,age的索引。创建索引为id,但默认包含该id的一行数据
非聚簇索引的叶子结点存放的是,当初创建索引的字段不包含其他字段。,比如一张表的字段为id(主键),name,age。我创建的索引为name,那么索引的只包含name和主键id,如果我需要通过name查询响应的age,则需要回表操作。但是聚簇索引就不需要回标操作。
3.索引的叶子结点以链表的形式存储,方便顺序查找和排序
索引的缺点是什么?
1.会占用空间(会建立各种复合索引,比如name一个索引,name和age索引)
2.更新时会练级更新索引
3.高并发影响性能(mvcc机制)
什么情况会导致索引失效?
1.select 使用函数
2.否定语句,比如where中的is not null,is null,!=或者<>
3.未使用最佳左匹配,比如索引三个字段,查询时未从第一个开始,先使用中间的
4.使用左模糊查询,like以%开头导致索引失效(阿里手册严谨左模糊和有模糊,如果需要使用es解决)
5.数据库优化器觉得不走索引比走索引快的时候,比如说数据量比较少的时候
6.类型转化导致索引失效
数据库优化的方法有那些?
1.硬件上优,主要在存储进行优化,申请单独的磁盘存储数据库
2.网络,优化网卡,现在比如千兆网卡,或者万兆网卡,提高带宽比如
3.操作系统调优,tcp/ip协议超时的优化
4.表结构的优化,1.比如表中添加冗余字段进行优化2.使用varchar(20)就不需要使用200,3.比较长的字段使用blob(能不再数据库上存就不要在数据库上存),字段比较小的直接使用char类型(最多存255)。4.存储时间优化datatime换成timestamp(timestamp比dattime存储少一半)。
5.sql的优化,select *不要用,where的等职比对,范围比对(等值匹配放到前面,范围匹配放到后面),order by按照最左匹配法则建好
6.减少函数的使用
7.索引优化,借助explain工具,减少多表查询,子查询,临时的中间表
8.大字段的以及全文检索优化,比如es,或者FastDFS
9.连接池优化,
10.事务优化,防止表锁或者行锁,少用select * ...for update,把事务的隔离级别调低
11.数据库集群的优化,单节点的优化,读写分离(会指数级的提成)集群方案:主从复制,多主复制(mmm:master+master+master)
12.加入缓存
13.冷热存储,按照查询的时间,分冰冷数据和热乎的数据,把冷数据存到别的库中,需要调用另外的接口进行擦汗寻
14.分库分表
8.Integer和int的区别
关键点:
1.堆栈存储基础数据类型与对象
2.值比对的时候注意java的自动拆箱
3.Integer值大小在-128到127之内,使用IntegerCache
答:
1.Integer是int包装类,int则是一个基本数据类型
2.Integer实际是对象的引用,当new一个integer,实际上胜场一个指针的对象,而int则直接存放数据
3.integer的默认值是null,而int的默认值是0
9.数据库的三大范式
第一范式:单表(字段),拆分到不可差分为止,,有主见有原子性,字段不再可拆分
第二范式:每一行数据唯一性
第三范式:表之间主键关联
10.什么是Spring的依赖注入?有那些方法进行依赖注入
关键字:
1.IOC inversion of Control 控制翻转
2.DI Dependency Injection 依赖注入(通过IOC来左DI这件事的)
答案:依赖注入是指将依赖的对象实例交给Spring帮我们注入管理,从而释放兑现搞得管理
1.set方法注入
2.构造方法注入
3.autowire自动注入
11.理解JVM
1.jvm标准与实现(各个厂商不一样)
2.解决跨平台问题
3.JMM内存模型
4.JVM模型
5.不同的垃圾回收器(g1,stw)
答案:jvm是java虚拟机,我们class文件运行在虚拟机上,通过虚拟机解决跨平台问题,jvm中有jmm来管理java内存访问问题,不同jvm实现性能关注有差异,现在主流是现实hotspot,垃圾回收器是G1,jvm运行时内存中分为方法去,堆,本地方法栈,执行代码时需要执行引引擎。
12.浅谈ReentrantLock的设计
答案:
1.ReentrantLock是多线程竞争资源时使用的锁,他是一个独占锁(只有一个线程可以进入),可重入锁(当前线程获取锁后,当这个线程又需要这个锁的其他业务逻辑的时候不需要再重新获取这一把锁头),悲观锁
2.ReentrantLock支持公平锁,对于公平和非公平锁又不同的实现逻辑
3.ReentrantLock使用aqs(AbstractQueuedSynchronizer)来实现获取锁的锁的线程队列等待过程
4.内部使用了原子类来操作cas(compareAndSetState(0,1),0表示没有上锁,1表示上锁了,判断当前是否获取锁,失败则会继续acpuire)比较线程与对应的锁关系
5.内部支持newCondition来灵活控制获取锁的线程的阻塞和释放
13.说一下mysql中事务的实现原理
依赖MVCC(Multi-version Concurrency Control)的版本控制。Mvcc实现依赖于隐藏字段、Read View、Undo Log
隐藏字段:
DB_TRX_ID:用来表示最近一次对数据修改(insert,update)的事务的标识符,即最后一次修改本行记录的事务id,再innDB存储引擎内部也属于一次update,即更新行中的一个特殊为,如果进行删除并非真正的删除。
DB_ROLL_PTR:回滚指针,该只想行的undo log,如果为被更新,则为空
DB_ROW_ID:如果没有主键的时候,则InnoDB会使用该id生成聚簇索引
Read View:
不同的事务隔离级别,当有事务再执行过程中修改了数据(更新了版本号),在并发事务时需要判断一下版本链中那个版本是当前事务可见。
undo log:
除了用来回滚出局,还可以读取可见版本数据,以此实现非锁定读
答案:
1.mysql是由mvcc实现事务控制
2.MVCC的实现依赖于:隐藏字段、Read View ,undo log(mysql中写输入的时候是先写日志,再写数据)
3.在不同的事务隔离级别下通过设置readview内容,控制了那些数据可见,那些不可见
14.编写一个基于线程安全的懒加载单例模式
public class Test03 {
private static Test03 instance=null;
private Test03(){
}
public static Test03 getInstance(){
// 多线程中,重复new了多个对象
if (instance==null){
// 第一次访问初始化的时候降低
synchronized (Test03.class){
if (instance==null){
return new Test03();
}else {
return instance;
}
}
}else {
return instance;
}
}
}
15.值传递和引用传递问题
16.异常中的return问题
catch()捕捉异常的return没有用,最后一定会走finally
17.Spring的AOP的时评场景有那些
关键点:
1.aop面向切面编程使用非常广泛,几乎适用于一切需要统一化处理的场景
答:
1.统一日志处理
2.统一异常处理
3.访问设置(权限、限流)sentinel组件
4.事务处理@Transactional
5.缓存管理等
6.aop是面向切面编程,通过代理方式(jdk或cglib),为程序统一添加功能,解决公共问题
18.列举Linux的常用命令
答:
1.find、rm、rmdir、mv、cp、cat、pwd、chmod、kill、ping、ifconfig
2.tail、ps、grep、nestat、echo、ssh、scp、top、mpstat、free、df
19.列举知道并使用过其他前沿技术
1.go语言
2.物联网LOT嵌入式开发,树莓派小车,摄像头
3.地带吗数据中心
4.jdk新特性,g1,zgc
5.区块链
6.容器化云原生与监控
7.java高性能游戏开发,jdk11之后可以会使用到硬件了
8.DDD
9.响应式编程与异步网络编程
10.推荐系统
11.高并发系统框架nginx+lua
12.chatgpt
20.JVM运行时数据区域包含那几个部分
答:
运行时区域就是new出来的对象和执行方法
1.堆:new出来的对象,会存储大量的对象,所以划分出新生区、老年代。共享数据区。对象的引用,
2.栈:方法内部需要运行的数据,包括局部变量,传参变量、class文件。在栈中他会存储栈针,在栈帧中包含指向具体的类输入和输出的一些参数。同样也会用到程序计数器。随着线程的产生而产生,随着线程的销毁而销毁,不需要垃圾回收。
3.本地方法栈:运行基础程序的也需要一些方法。网络驱动啊,一些输入输出的设备。
4.方法区:通过classloader的load上面就到方法区,jdk1.7和1.8有些区别
21.多线程中的start()方法和run()方法的区别时什么
1.start的方法是启动线程,改变的是线程的状态,由就绪进入执行
2.run方法中包含要执行的代码,在执行状态时运行里面的代码,方法返回的是void,无法得到结果,只能通过多线程返回访问共享变量获取结果。
22.简单写一个会导致死锁的程序
避免:1.不要使用嵌套锁。2.锁的顺序
23.对于高并发问题的处理方式
1.寻找平静
2.分治的思想,业务差分、流程拆分
3.限流
4.分流、cdn缓存
5.流量清洗。waf
6.多级缓存设计,后端缓存,客户端缓存
7.日志溯源
8.资源隔离
9.弹性扩缩容量
10.降级处理前后端兜底数据
24.高可用问题的常用处理方式
1.容器化管理
2.keepalived
25.简单描述一下JVM加载class文件的原理机制
关键字:
1.类加载器
2.魔数
3.元空间
负责加载class文件,class文件在口头由特定的文件表示,并且ClassLoader只负责class文件加载,至于是否能运行又Execution Engine决定
魔数:
class文件开头的四个字节的无符号称为魔数
魔数是Class文件标识。值是固定的为0xCAFEBABE
如果一个class文件的投自己字节不是0xCAFEBABE就会报错
双亲委派机制:
26.数据连接池的工作机制是什么
关键点:1.连接复用2.限制连接个数
1.连接池与线程池实现原理一样
2.限流与复用
3.数据库建立一个连接的开销要比客户都安大
4.数据库负责连接池分配、管理和释放数据连接,他允许应用床徐重复使用一个现有的数据库连接,而再不是重新建立一个
答案:
1.预先创建好一些数据,放到连接池中
2.连接池中设置最小连接数和最大连接数
3.最小连接不断开和数据库的连接
4.超过最小连接的那些线程,再长时间不使用会被回收,也就是断开数据库的连接
5.所有向数据库发送请求的业务必须通过连接池获得数据库连接
6.再连接使用,可以使用队列等待
27.那一个List实现最快插入
arrayList:十足实现,查询,修改比较快
linkedList:链表实现,扎入、删除比较快,直接再最后插入数据即可
vector:jdk1.0,线程安全但是效率比较低
28.存在i+1<i的数么
1.基本数据类型至大至+1会变成负数
Integer.Max_Value+1就会打印出附属
33.null问题
关键点:1.null可以被强转到任何类型的
输出结果haha
34.共享变量多线程可见性问题
运行无返回值,需要添加volatile,让线程共享变量。while代替if,否则会导致虚假唤醒。
35.synchronize锁对象竞争问题
synchronize修饰方法如果是静态默认的锁为class,如果非静态默认锁为当前对象
36.高级回答方式 多线程有几种实现方式
1.实现Runable接口void返回值,start,run
2.实现Callable接口可以指定返回值
FetureTask(new Callable()),start,get
37.高级同步有几种实现方式
非阻塞:
1.volatile(不能保障原子特性)
2.cas以及atomic系列实现(保障同步和数据一致性)
阻塞:
1.wait()
2.sleep
3.synchronized
4.Lock的实现 ReentrantLock、ReentrantReadWriteLock等、condition.await()
5.CountDownLatch
6.CylicBarrier
7.Semaphore
8.BlockingQueue
38.Thread类的常用方法
start,run,getPriority()获取优先级,interrupt()打断线程会抛出异常
结束线程最好是讲简称执行完毕
39.Exception父类问题
继承Throwable和Serialable
40.String值对比问题
false,不允许
43.gc守护线程和volatile问题
gc是守护线程,
volatile无法保证线程安全