一
AVL排序树
AVL排序树是一种自平衡的二叉搜索树。
主要特点👇
- 平衡性:AVL树始终高度平衡,任何节点的左右子树高度差(平衡因子)不超过1。
- 排序性:作为二叉搜索树,AVL树满足左子树所有节点值小于根节点,右子树所有节点值大于根节点的性质。
- 高效操作:由于平衡性,查找、插入和删除操作的时间复杂度都是O(log n)。
平衡因子👇
平衡因子=左子树高度-右子树高度
平衡因子必须为-1、0或1,否则需要通过旋转来重新平衡。
平衡操作👇
当插入或删除操作导致树不平衡时,AVL树通过四种旋转操作来恢复平衡:
- 右旋(LL旋转):用于左子树比右子树高2,且新节点插入在左子树的左子树
- 左旋(RR旋转):用于右子树比左子树高2,且新节点插入在右子树的右子树
- 左右旋(LR旋转):先左旋再右旋,用于左子树比右子树高2,且新节点插入在左子树的右子树
- 右左旋(RL旋转):先右旋再左旋,用于右子树比左子树高2,且新节点插入在右子树的左子树
参考:
应用场景👇
AVL树适用于需要频繁查找但插入删除操作相对较少的场景,如数据库索引,文件系统等。
与红黑树相比,AVL树提供更严格的平衡,因此查找效率更高,但插入和删除操作可能需要更多的旋转操作。
红黑树
红黑树是一种自平衡的二叉搜索树(BST),它在插入和删除操作时通过特定的规则和旋转来保持树的平衡,从而确保最坏情况下的时间复杂度仍为O(log n)。
红黑树的五大性质👇
- 节点是红色或黑色
- 根节点是黑色
- 所有叶子节点(NIL节点,空节点)是黑色
- 红节点的两个子节点必须是黑色(即不能有连续的红色节点)
- 从任一节点到其他每个叶子节点的所有路径包含相同数量的黑色节点(黑高相同)
这些性质保证了红黑树的平衡性,最长路径不超过最短路径的两倍。
红黑树和AVL树对比👇

红黑树调整操作👇
当插入或删除节点后,红黑树可能违反其性质,需要通过以下方式调整:
1.旋转
- 左旋:用于处理右子树过重的情况。使父节点的右孩子成为新的父节点,原父节点成为其左孩子。
- 右旋:用于处理左子树过重的情况。使父节点的左孩子成为新的父节点,原父节点成为其右孩子。
2.重新着色
- 改变节点的颜色以满足红黑树的性质。
3.插入后的调整
插入的节点默认为红色(以减少黑高变化),可能导致以下情况:

4.删除后的调整


参考:
Spring的事务注解
Spring框架提供了强大的事务管理支持,主要通过注解方式来声明事务行为。
1.@Transactional(核心事务注解)
@Transactional是Spring事务管理的核心注解,可以应用于类或方法上。

2.@事务传播行为(Propagation)
定义事务如何传播

3.事务隔离级别(Isolation)


享元模式
享元模式是一种结构型设计模式 ,主要用于减少内存使用 ,通过共享对象来高效地支持大量细粒度对象。

代码实例:场景中的子弹对象(大量相似子弹,共享类型信息)
java
// 1. Flyweight 接口
interface Bullet {
void fire(int x, int y); // x,y 是外部状态(每颗子弹不同)
}
// 2. ConcreteFlyweight(可共享的子弹类型)
class ConcreteBullet implements Bullet {
private final String type; // 内部状态(共享的子弹类型)
public ConcreteBullet(String type) {
this.type = type;
}
@Override
public void fire(int x, int y) {
System.out.println("发射" + type + "子弹,位置: (" + x + "," + y + ")");
}
}
// 3. FlyweightFactory(享元工厂)
class BulletFactory {
private static final Map<String, Bullet> bullets = new HashMap<>();
public static Bullet getBullet(String type) {
if (!bullets.containsKey(type)) {
bullets.put(type, new ConcreteBullet(type));
}
return bullets.get(type);
}
}
// 4. Client(客户端)
public class Game {
public static void main(String[] args) {
Bullet bullet1 = BulletFactory.getBullet("AK47"); // 共享同一个AK47子弹对象
bullet1.fire(100, 200);
Bullet bullet2 = BulletFactory.getBullet("M4A1"); // 共享同一个M4A1子弹对象
bullet2.fire(150, 300);
Bullet bullet3 = BulletFactory.getBullet("AK47"); // 复用已存在的AK47子弹对象
bullet3.fire(200, 400);
}
}



多线程

Java多线程实现方式



场景问题👇

Java中public、protected、private、default使用范围
public所有情况都可访问
protected包内才可直接访问,本类和子类才可以访问
private本类访问
dafault同一包中的类可访问