# 面向对象编程的四大特性:封装、抽象、继承、多态。
封装是指把一些类的属性和实现细节隐藏起来,只暴露有限的访问接口,让外部调用这些接口来操控封装内部的类的属性。封装可以让内部类更安全。 抽象就是指封装这些属性时,具体所使用的方法,抽象可以让使用者知道方法可以达到的功能,而不用去知道这些方法是怎么实现的。一般在java中使用interface关键字或abstract关键字来实现抽象。 继承是指一个类可以使用另一个类的方法,使用方法的这个类叫子类,被使用方法的这个类叫父类,继承最大的优点是代码可以复用,一个父类的方法或属性可以给多个子类用,不用再重复写代码。 多态指在子类中可以替换父类其中的方法,达到方法重写的效果。
重写是指子类定义了一个父类中具有相同名称、相同参数列表、相同返回类型的的方法,从而达到子类可以根据需求的不同重新定义父类中方法的功能。(外壳不表,核心重写)。
# HashMap的底层原理是什么?
HashMap它是java中基于哈希表的Map接口的实现,它使用键值对的形式来存储数据(key value)核心优势是它的拆查询效率非常的快(因为使用key-value,类似字典中的使用拼音找汉字)
HashMap的底层数据结构是“数组+链表+红黑树”的组合,数组是HashMap的主干,数组的每一个位置被称为一个桶,它的作用是可以快速定位数据的位置,查询效率高。
当不同的键通过计算落到同一个数组下标的时候,就会发生哈希碰撞,如果这种情况出现的话,hashmap就会在这个桶下面形成一个链表,后面进来的新的元素就会按顺序放在链表里,这叫拉链法。
如果有不断的元素进来,会导致链表过长,会导致元素查询过慢,这时候当链表的长度超过8,并且当前数组的总长度超过或等于64时,这个链表就会自动转化为红黑树,当树中的元素减少到6个时,又会退化为链表。
# 创建线程有哪几种方式?
主要有四种,一种是继承thread类,重写run()方法,然后new一个对象调用start()方法使用。
一种是实现Runnable接口。
一种是实现Callable接口:这个与Runnable接口的区别是它会有返回值,即可以抛出异常。
一种是使用线程池创建:通过ExecutorService线程池来管理和调度线程,更节省资源,提高响应速度。
# 线程的生命周期/状态有哪些?
有六种:首先是NEW新建状态,当线程对象被新建出来后,但没有启动(start())方法之前,就处于这个状态。
之后是RUNNABLE可运行状态,当调用了start()方法后线程就会进入runnable状态,这个状态有一个正在cpu上运行和在队列中等待cpu调用的分别。
如果此时有一个线程在等待获取一个synchronized同步锁,那么此时线程的状态就是阻塞(BLOCKED)。
还有一个状态是WAITING(等待状态),此状态需要被其他线程唤醒。
TIMED_WAITING(超时等待),这种状态和WAITING类似,但区别在于它有一个等待的时间,等待时间一到就会自动被系统唤醒过来。
TERMINATED(终止),当线程的run()方法执行完毕或者出现异常时,线程就进入TERMNATED状态。意味着线程的生命周期已经结束。
SpringBean的生命周期?
Bean的定义和加载-Bean实例化-依赖注入-BeanPostProcessor前置处理-Bean初始化-BeanPostProcessor后置处理-Bean就绪-销毁
synchronized的底层原理?
synchronized的底层原理是JVM通过monitorenter和monitorexit指令来操作对象的Monitor,并通过对象头的Mark Word来记录锁的状态。后期为了优化锁的性能,JVM采用了锁升级的策略,无锁-偏向锁-轻量级锁-重量级锁。
什么是CAS?有什么缺点?
CAS全称是compare-and-swap,意思是比较并交换。它是一种无锁的、乐观的(乐观锁核心),用于实现多线程环境下的变量同步,原理就是先比较预期值,只有内存中的当前值和预期值一样的时候,处理器才会自动把新值更新进来,否则不进行操作。
如果长时间CAS操作不成功,则线程会一直进行自旋,所以CPU的性能消耗会增大。 CAS只能同时保证一个变量进行操作(可以将多个变量封装为一个对象)
Spring 事务传播机制和隔离级别?
传播机制和隔离级别首先是事务的两个核心点,对于事务传播机制Spring定义了七种,但常用的有三种:REQUIRED,REQUIRED_NEW,SUPPORTS。
REQUIRED指的是如果当前存在事务就加入该事务;如果当前没有事务就创建一个事务;这是最常用的。
REQUIRED_NEW就是无论如何都要创建一个新事务,如果已经有事务了,那就把当前事务挂起。适用于希望两个事务独立的情况
SUPPORTS指如果当前有事务就加入该事务,如果当前没事务就以非事务方式执行。
事务隔离级别有四种:READ_UNCOMMITTED(读未提交),READ_COMMITTED(读已提交),REPEATABLE_READ(可重复读),SERIALIZABLE(串行化)
隔离级别从低到高:读未提交-读已提交-可重复读-串行化
读未提交(允许读取其他事务未提交的更改)会导致脏读,不可重复读,幻读
读已提交(保证一个事务只能读取到其他事务已经提交的更改)解决了脏读,但仍会导致不可重复读和幻读
可重复读(保证在同一个事务中,多次读取同一数据的结果是一致的)可以避免脏读和不可重复读,但还是会出现幻读问题。
串行化解决了所有问题,但性能消耗最大,并发性最差。
Spring AOP 的实现原理?
Spring AOP的实现核心是基于动态代理技术
主要是JDK动态代理和CGLIB字节码增强
JDK动态代理是Spring的默认策略,要求目标类必须实现一个或多个接口,代理对象会实现与目标类相同的接口,客户端通过接口来调用方法。
Spring Boot 的核心优势是什么?
SpringBoot本质上是Spring框架的一个扩展,核心设计目标是简化基于Spring的程序的初始搭建和开发过程。
核心优势主要体现在三个方面:自动配置,起步依赖,内置容器与独立运行。
自动配置指SpringBoot会基于应用所声明的依赖(如运行需要的jar包),自动配置Spring应用所需的绝大部分组件,这样可以不用再编写大量的xml配置。
起步依赖指SpringBoot提供了一个预定义好的依赖描述符,只需要引入一个起步依赖,就可以得到你需要的开发某个功能所需的所有相关库的优化集合。
内置容器与独立运行是指SpringBoot应用内嵌了Tomcat、Jetty等Servlet容器,就是可以把应用打包成一个独立的jar包,且通过java-jar命令直接运行,不用额外部署服务器。
MyBatis 的一级缓存和二级缓存?
Mybatis是一个持久层框架,主要通过XML或者注解来配置和映射原始数据和Java对象。核心优势是可以编写原生的SQL。
Mybatis的一级缓存是默认开启的,它的作用域是SqlSession级别的,在同一个SqlSession中执行相同的查询,Mybatis会直接返回缓存中的内容而不会再次访问数据库。
Mybatis的二级缓存作用域是Mapper级别的,意思是缓存在多个SqlSession之间是共享的。
总结 一级缓存作用范围小 默认开启 SqlSession级别 二级缓存作用范围大 Mapper级别 手动开启
Redis 有哪些数据类型?分别的应用场景?
String Hash List Set ZSet
String作用于缓存 计数器 分布式锁
Hash作用于存储用户信息
List作用于消息队列
Set作用于共同好友(交集) 随即推荐
ZSet作用于排行榜