SpringCode
  1. Spring 是如何默认开启循环依赖的?如何关闭支持循环依赖?

  2. @Autowired和@Resource区别

    @Autowired由AutowiredAnnotationBeanPostProcessor后置处理器解析,@Resource由CommonAnnotationBeanPostProcessor解析

  3. 循环依赖的实现

    /** Cache of singleton objects: bean name to bean instance. */
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

    /** Cache of singleton factories: bean name to ObjectFactory. */
    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

    /** Cache of early singleton objects: bean name to bean instance. */
    private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

    singletonObjects 单例池 Spring容器 一级缓存 存储的是bean

    singletonFactories 工厂 二级缓存 存储的是对象(半成品的bean)

    earlySingletonObjects 三级缓存

    三级缓存put一个从二级缓存中生产出来的一个对象

    为什么需要三级缓存?因为防止重复创建,提高效率

Read more
Lcof22

Lcof 22.链表中倒数第k个节点

输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如,一个链表有6个节点,从头节点开始,它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个节点是值为4的节点。

示例:

​ 给定一个链表: 1->2->3->4->5, 和 k = 2.

​ 返回链表 4->5.

class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
if (head == null || k < 0) {
return null;
}
ListNode right = head;
while (right != null && k > 0) {
right = right.next;
k--;
}
if (k > 0) {
return null;
}
ListNode left = head;
while (right != null) {
left = left.next;
right = right.next;
}
return left;
}
}

优化

class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
ListNode fast = head;
while (fast != null) {
if (k == 0) {
head = head.next;
} else {
k--;
}
fast = fast.next;
}
return head;
}
}

Lcof21

Lcof 21.调整数组顺序使奇数位于偶数前面

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。

示例:

​ 输入:nums = [1,2,3,4]
​ 输出:[1,3,2,4]
​ 注:[3,1,2,4] 也是正确的答案之一。

Read more
RedisDistributedLock

分布式锁

CAP理论:任何一个分布式系统都无法同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance),最多只能同时满足两项。

特点

  • 互斥性: 同一时刻只能有一个线程持有锁;
  • 可重入性: 同一节点上的同一个线程如果获取了锁之后能够再次获取锁;
  • 锁超时:和J.U.C中的锁一样支持锁超时,防止死锁;
  • 高性能和高可用: 加锁和解锁需要高效,同时也需要保证高可用,防止分布式锁失效;
  • 具备阻塞和非阻塞性:能够及时从阻塞状态中被唤醒;

实现方式

  • 基于数据库
  • 基于Redis
  • 基于zookeeper
Read more
CAS

原理

CAS通过调用JNI的代码实现的。而compareAndSwapInt就是借助C来调用CPU底层指令实现的。

public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);

缺点:

  1. ABA问题

    解决1:使用版本号或者时间戳;

    解决2:Java1.5开始在atomic包中提供一个类AtomicStampedReference来解决ABA问题,这个类的compareAndSet方法中首先检查当前引用是否等于预期引用,并且当前标志是否等于预期标志,如果全部相等,则以原子方式将该引用和该标志的值设置为给定的更新值。

  2. 循环时间长开销大

  3. 只能保证一个共享变量的原子操作

    可以使用Java1.5开始提供的AtomicReference来包装多个变量,或者使用Synchronized。


Lcof18

Lcof 18.删除链表的节点

给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。

返回删除后的链表的头节点。

注意:此题对比原题有改动

示例 1:

​ 输入: head = [4,5,1,9], val = 5
​ 输出: [4,1,9]
​ 解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.
示例 2:

​ 输入: head = [4,5,1,9], val = 1
​ 输出: [4,5,9]
​ 解释: 给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9.

Read more