JVM内存区域
线程共享的是堆区和方法区
线程私有的是虚拟机栈,本地方法栈,程序计数器
full gc频繁的原因
1.系统并发高,执行耗时过长,或者数据量过大,导致young gc频繁,且gc后存活对象太多,但是survivor区存放不下,导致对象快速进入老年代,老年代迅速堆满
2.程序一次性加载过多对象到内存,导致频繁有大对象进入老年代,造成full gc
避免方法:
调整堆内存大小
合理设置新生代和老年代的比例
检查有无内存泄漏
static关键字的作用
修饰成员变量和成员方法,被static修饰的成员属于类,不属于单个这个类的某个对象,被类中所有对象共享,可以使用类名来调用,被static声明的成员变量属于静态成员变量,静态变量存放在java内存区域的方法区
静态代码块:静态代码块定义在类中方法外,静态代码块在非静态代码块之前执行
double和float的区别
double和float的精度损失是怎么导致的
redis为什么快
Redis的大部分操作都在内存中完成,并且采用了高效的数据结构
Redis采用IO多路复用机制处理大量的客户端socket请求,IO多路复用机制是指一个线程处理多个IO流,在Redis只运行单线程的情况下,该机制允许内核中,同时存在多个监听socket和已连接socket。内核会一直监听这些socket上的连接请求或数据请求。一旦有请求到达,就会交给Redis线程处理,,这就实现了一个Redis线程处理多个IO流的效果
线程安全指的是什么
线程安全指的是在多线程环境下,对于同一份数据,不管有多少个线程同时访问,都能保证这份数据的正确性和一致性
threadLocal原理
每个Thread中都具备一个ThreadLocalMap,而ThreadLocalMap可以存储以ThreaLocal为key,object对象为value的键值对
ThreadLoca存在内存泄漏问题,ThreadLocalMap中使用的key为ThreadLocal的弱引用,而value是强引用。所以如果ThreadLocal没有被外部强引用的情况下,在垃圾回收的时候,key会被清理掉,而value不会被清理掉。这样一来,ThreadLocalMap中就会出现key为null的Entry。假如我们不做任何措施的话,value永远无法被GC回收,就会出现内存泄漏,可以手动使用remove方法
内核空间和用户空间是什么,什么时候进入内核空间
操作系统的数据都是存放于内核空间的,用户进程的数据都是存放于用户空间的,分开来存放,就让系统的数据和用户的数据互不干扰,保证系统的稳定性
用户态的程序不能随意操作内核地址空间,对操作系统起到保护作用。
当发生软中断(即进程发生了异常事件),硬中断(如时钟周期,IO等)
linux里边进程和线程区别
进程是资源分配的单位,线程是CPU调度的单位
进程拥有一个完整的资源平台,而线程只是独享必不可少的资源,如寄存器和栈
线程同样具有就绪,阻塞和执行三种状态,同样具有状态之间的转换关系
线程能减少并发执行的时间和空间开销
三次握手和四次挥手
服务端主动监听某个端口,处于listen状态
客户端随机初始化序号,将此序号置于TCP首部的序号字段中,同时把SYN标志位置为1,表示SYN报文。接着把第一个SYN报文发送给服务端,表示向服务端发起连接,该报文不包含应用层数据,之后客户端处于SYN-SENT状态
服务端收到客户端的SYN报文后,首先服务端也随机初始化自己的序号,将此序号填入TCP首部的序号字段中,其次把TCP首部的确认应答号字段填入client+1,接着把SYN和ACK标志位置为1,最后把该报文发给客户端
客户端收到服务端报文后,还要向服务端回应最后一个应答报文,首先该应答报文TCP首部ACK标志为1,其次确认应答号字段填入server_isn+1,最后把报文发送给服务端,这次报文可以携带客户端到服务端的数据,之后客户端处于ESTABLISHED状态
客户端打算关闭连接,此时会发送一个TCP首部FIN标志位被置为1的报文,也即FIN报文,之后客户端进入FIN_WAIT_1状态
服务端收到该报文后,就向客户端发送ACK应答报文,接着服务端进入close_wait状态
客户端收到服务端的ACK应答报文后,之后进入FIN_WAIT_2状态
等待服务端处理完数据后,向客户端发送FIN报文,之后服务端进入LAST_ACK状态
客户端收到服务端的FIN报文后,回一个ACK报文,进入TIME_WAIT状态
服务端收到ACK应答报文后,就进入了Close状态,至此服务端已经完成连接的关闭
客户端在经过2msl一段时间后,自动进入close状态,至此客户端也完成连接的关闭
java实现代理的方式
JDK动态代理
CGLIB动态代理
JDK动态代理只能代理实现了接口的类或者直接代理接口,而CGLIB可以代理未实现任何接口的类
数据库执行一条select语句的过程
先连接mysql服务,连接的过程需要经过TCP三次握手。连接完成后要验证用户名和密码,获取用户的权限
词法分析,mysql会根据输入的字符串识别出关键字,例如select from关键字
语法分析,判断输入的SQL语句是否满足mysql语法,如果没问题回构建sql语法树
执行SQL
预处理器
检查sql查询语句中的表或者字段是否存在
将select*中的*符号,扩展为表上的所有列
优化器:负责将sql查询语句的执行方案确定下来,比如表中有多个索引,优化器会基于查询成本的考虑,来决定选择使用哪个索引
执行器:执行器就会和存储引擎交互
抽象类和接口的区别
接口主要用于对类的行为进行约束,实现了某个接口就具有了对应的行为。抽象类主要用于代码复用,强调的是所属关系
一个类只能继承一个类,但是可以实现多个接口
接口中的成员变量只能是public static final类型,不能被修改且必须有初始值,而抽象类的成员变量默认default,可在子类中被重新定义
bean的生命周期
创建Bean实例:Bean容器首先会找到配置文件中的Bean定义,然后使用java反射API来创建Bean的实例
Bean属性赋值/填充:为Bean设置相关属性和依赖,例如@Autowired等关键注入的对象,@Value注入的值,setter方法或构造函数注入依赖和值,@resource注入的各种资源
Bean初始化:如果Bean实现了Bean Name Aware接口,调用set Bean Name()方法,传入Bean的名字
如果Bean实现了Bean Class Loader Aware接口,调用setBeanClassLoader方法,传入Class Loader对象的实例
如果Bean实现了BeanFactoryAware接口,调用setBeanFactory方法,传入BeanFactory对象的实例
如果有和加载这个Bean的Spring容器相关的BeanPostProcessor对象,执行postProcessBeforeInitialization方法
如果Bean实现了InitializingBean接口,执行afterPropertiesSet方法
如果Bean在配置文件中的定义包含init-method属性,执行指定的方法
如果有和加载这个Bean的spring容器相关的BeanpostProcessor对象,执行postProcessAfterInititialzation()方法
销毁Bean:销毁并不是说要立马把Bean给销毁掉,而是把Bean的销毁方法先记录下来,将来需要销毁Bean或者销毁容器时,就调用这些方法去释放Bean所持有的资源
自动装配原理
@SpringBootApplication看作是@Configuration,@EnableAutoConfiguration,@ComponentScan注解的集合。@Configuration允许在上下文中注册额外的bean或者导入其他配置类,@EnableAutoConfiguration启用springboot的自动配置机制,@ComponentScan扫描被@component或者@Service注解的bean。
自动装配会通过配置选择器,去META-INF/spring.factories,获取需要自动装配的所有配置类
http状态码
2XX 成功,报文已经收到并被正确处理
3XX 重定向 资源位置发生变动,需要客户端重新发送请求
4XX客户端错误,请求报文有误,服务器无法处理
5XX 服务器错误,服务器在处理请求时内部发生了错误
http和https之间的区别
http是超文本传输协议,信息是明文传输,存在安全风险的问题。Https则解决http不安全的缺陷,在TCP和HTTP网络层之间加入了SSL/TLS安全协议,使得报文能够加密传输
http连接建立相对简单,tcp三次握手之后便可进行http的报文传输。而https在tcp三次握手之后,还需进行ssl/tls的握手过程,才可进行加密报文传输
http是80端口,https是443端口
https协议需要向证书权威机构申请数字证书,来保证服务器的身份是可信的
equals和==的区别
对于基本数据类型,==比较的是值
对于引用数据类型,==比较的是对象的内存地址
equals()不能用于判断基于数据类型的变量,只能用来判断两个对象是够相等
java异常
Exception:程序本身可以处理的异常,可以通过catch来进行捕获。Exception又可以分为checked exception受检查异常和Unchekced Exception不受检查异常
Error:属于程序无法处理的错误
Unchekced Exception不受检查异常,即使不处理不受检查异常也可以正常通过编译
RuntimeException及其子类都统称为非受检查异常,常见的有:
nullPointerException空指针错误
illegalArgument Exception参数错误比如方法入参类型错误
ArrayIndexOutOfBoundsException数组越界错误
ClassCastException类型转换错误
sleep和wait区别
sleep()方法没有释放锁,而wait()方法释放了锁
wait()通常被用于线程间交互/通信 sleep()通常被用于暂停执行
wait()方法被调用后,线程不会自动苏醒,需要别的线程调用同一个对象上的notify或者notifyAll()方法。sleep()方法执行完成后,线程会自动苏醒,或者也可以使用wait(long timeout)超时后线程会自动苏醒
autowired和resource两个注解的区别
@Autowired先根据类型查找,如果存在多个Bean再根据名称查找,支持属性注入,构造方法注入,setter注入
@Resource是先根据名称查找,如果根据名称查找不到,再根据类型进行查找。支持属性注入,setter注入
参考资料: