### 1. AOP是什么,说一下使用的场景
AOP全称Aspect Oriented Programming意为面向切面编程,也叫做面向方法编程,是通过预编译方式和运行期动态代理的方式实现不修改源代码的情况下给程序动态统一添加功能的技术。
使用场景:
1. 记录日志
2. 监控方法运行时间 (监控性能)
3. 权限控制
4. 次调用, 直接从内存对象返回,不需要查询数据库 )
5. 事务管理 (调用方法前开启事务, 调用方法后提交关闭事务 )
### 2. Spring Boot常用的注解及其作用
- @Autowired :自动导入对象到类中,被注入进的类同样要被 Spring 容器管理比如:Service 类注入到 Controller 类中。
- @Component :通用的注解,可标注任意类为 Spring 组件。如果一个 Bean 不知道属于哪个层,可以使用@Component 注解标注。
- @Repository : 对应持久层即 Dao 层,主要用于数据库相关操作。
- @Service : 对应服务层,主要涉及一些复杂的逻辑,需要用到 Dao 层。
- @Controller : 对应 Spring MVC 控制层,主要用户接受用户请求并调用 Service 层返回数据给前端页面。
- @RestController注解是@Controller和@ResponseBody的合集,表示这是个控制器 bean,并且是将函数的返回值直 接填入 HTTP 响应体中,是 REST 风格的控制器。
- @Configuration :一般用来声明配置类,可以使用 @Component注解替代,不过使用Configuration注解声明配置类更加语义化。
- @RequestBody
用于读取 Request 请求(可能是 POST,PUT,DELETE,GET 请求)的 body 部分并且Content-Type 为 application/json 格式的数据,接收到数据之后会自动将数据绑定到 Java 对象上去。系统会使用HttpMessageConverter或者自定义的HttpMessageConverter将请求的 body 中的 json 字符串转换为 java 对象。
### 3. 什么是死锁,手写一个例子
**死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去**。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。产生死锁的原因,主要包括:
- 系统资源不足;
- 程序执行的顺序有问题;
- 资源分配不当等。
如果系统资源充足,进程的资源请求都能够得到满足,那么死锁出现的可能性就很低;否则,就会因争夺有限的资源而陷入死锁。其次,程序执行的顺序与速度不同,也可能产生死锁。
产生死锁的四个必要条件:
- 互斥条件:一个资源每次只能被一个进程使用。
- 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
- 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
- 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。
简单的代码例子:
```
public class SimpleDeadLock {
private final Object left = new Object();
private final Object right = new Object();
public void leftRight() {
synchronized (left) {
synchronized (right) {
// doSomething()
}
}
}
public void rightLeft() {
synchronized (right) {
synchronized (left) {
// doSomething()
}
}
}
}
```
### 4. 数据库的 ACID 特性
**原子性、一致性、持久性、隔离性**
原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
一致性:一个事务可以封装状态改变(除非它是一个只读的)。事务必须始终保持系统处于一致的状态,不管在任何给定的时间并发事务有多少。
隔离性:隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。
持久性:在事务完成以后,该事务对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
### 5. 如何排查java应用中CPU使用率高或内存占用高的问题
>参考:https://my.oschina.net/xiaominmin/blog/3063548
一、在排查问题的过程中针对CPU的问题,使用以下命令组合来排查问题
1. 查看问题进程,得到进程PID:
```
top -c
```
2. 查看进程里的线程明细,并手动记下CPU异常的线程PID:
```
top -p PID -H
```
3. 使用jdk提供jstack命令打印出项目堆栈:
```
jstack pid > xxx.log
```
线程PID转成16进制,与堆栈中的nid对应,定位问题代码位置。
二、针对内存问题,使用以下命令组合来排查问题
1、查看内存中的存活对象统计,找出业务相关的类名:
```
jmap -histo:live PID > xxx.log
```
2、通过简单的统计还是没法定位问题的话,就输出内存明细来分析。这个命令会将内存里的所有信息都输出,输出的文件大小和内存大小基本一致。而且会导致应用暂时挂起,所以谨慎使用。
```
jmap -dump:live,format=b,file=xxx.hprof PID
```
3、 最后对dump出来的文件进行分析。文件大小不是很大的话,使用jdk自带的jhat命令即可:
```
jhat -J-mx2G -port 7170
```
4、dump文件太大的话,可以使用jprofiler工具来分析。jprofiler工具的使用,这里不做详细介绍,有兴趣可以搜索一下。
三、需要分析GC情况,可以使用以下命令:
```
jstat -gc PID
```
这里简单介绍一下java8里面这个命令得出的列表各个列的含义:
>S0C:第一个幸存区的大小
S1C:第二个幸存区的大小
S0U:第一个幸存区的使用大小
S1U:第二个幸存区的使用大小
EC:伊甸园区的大小
EU:伊甸园区的使用大小
OC:老年代大小
OU:老年代使用大小
MC:方法区大小
MU:方法区使用大小
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间
一般会比较关注YGC和FGC的次数。

0223-总结