Spring事务传播行为
PROPAGATION_REQUIRED: 如果当前存在事务,则加入该事务;否则,创建一个新事务。
PROPAGATION_SUPPORTS: 如果当前存在事务,则加入该事务;否则,不使用事务。
PROPAGATION_MANDATORY: 如果当前存在事务,则加入该事务;否则,抛出异常。
PROPAGATION_REQUIRES_NEW: 创建一个新事务,并挂起当前事务(如果存在)。
PROPAGATION_NOT_SUPPORTED: 不使用事务;如果当前存在事务,则挂起该事务。
PROPAGATION_NEVER: 不使用事务;如果当前存在事务,则抛出异常。
PROPAGATION_NESTED: 如果当前存在事务,则在嵌套事务中执行;否则,创建一个新事务。
事务传播机制的默认值为 PROPAGATION_REQUIRED。这意味着如果一个方法在一个具有事务的上下文中执行,而该方法又调用另一个方法,则第二个方法将加入该事务。
Spring Boot
SpringBoot项目启动会扫描以下位置的application.properties或者application.yml文件作为SpringBoot的默认配置文件,
域的加载顺序
Java程序初始化顺序(一看就懂)
顺序:父类(静态域按顺序加载)–>子类(静态域按顺序加载) –>父类(非静态变量,非静态代码块,构造函数)–>子类(非静态变量,非静态代码块,构造函数)静态域:
类加载的几个过程:
加载、验证、准备、解析、初始化。然后是使用和卸载了
类的加载顺序
父类的静态代码块
子类的静态代码块
父类代码块
父类的构造方法
子类代码块
JVM 分为栈区、堆区和方法区
初始化的对象放在堆里面,引用放在栈里面, class 类信息:常量池(static 常量)放在方法区。
1. 栈:栈的结构是栈帧组成的,调用一个方法就压入一帧,帧上面存储局部变量,局部变量存放8大基础类型和指向引用类型的指针。
2. 堆:初始化的对象,成员变量 (那种非 static 的变量),所有的对象实例都在堆上分配。
3. 方法区:主要是存储类信息,常量池(static 常量),编译后的代码(字节码)等数据。
2. 堆里面的分区:Eden,survival (from+ to)
堆里面分为新生代和老生代(java8 取消了永久代,采用了 Metaspace)
新生代包含 Eden+Survivor 区,survivor 区里面分为 from 和 to 区,内存回收时,如果用的是复制算法,从 from 复制到 to,当经过一次或者多次 GC 之后,存活下来的对象会被移动到老年区,当 JVM 内存不够用的时候,会触发 Full GC,清理 JVM 老年区。当新生区满了之后会触发 YGC,先把存活的对象放到其中一个 Survice 区,然后进行垃圾清理。
3. GC 的两种判定方法
1. 引用计数法:指的是如果某个地方引用了这个对象就+1,如果失效了就-1,当为 0 就会回收但是 JVM没有用这种方式,因为无法判定相互循环引用(A 引用 B,B 引用 A) 的情况。
2. 引用链法: 通过一种 GC ROOT 来判断,如果有一条链不能到达 GC ROOT 就说明可以回收
多线程 锁
线程的4种创建方式
1. extend 继承Thread类
2. implement 实现Runnable接口
3. 使用Callable和Future创建线程
4. 通过线程池创建。
继承Thread和实现Runnable最大的区别在于数据是否容易共享. Runnable更容易实现数据共享.
线程之间如何通讯
1. 使用全局变量(共享变量)。
2. 使用事件对象。
3. 使用消息中间件。
线程安全解决方案
1. 同步代码块
2. 同步方法
3. 实现Lock锁
4. 使用分布式锁
死锁和解决方案
不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了死锁。死锁的四个条件:
1. 不可剥夺:资源被一个线程占用后,不能被另外一个线程剥夺使用权。
2. 资源互斥:资源在某一时刻只能被一个线程使用。
3. 请求保持:线程持有资源锁的时候,没处理完任务就不会释放锁。
4. 循环等待:多个线程互相循环等待。
解决方案:破坏四个条件中的一个或多个
1. 超时机制。
2. 避免嵌套同步。
wait()和 sleep()方法有什么区别
sleep 方法和 wait 方法都可以用来放弃 CPU 一定的时间,不同点在于如果线程持有某个对象的监视器,sleep 方法不会放弃这个对象的监视器,wait 方法会放弃这个对象的监视器。
wait需要等待被唤醒,而sleep睡眠一定时间之后自动苏醒。
#秋招##找工作##面经##应届生##大学生#