Java基础知识记录-20220317

Java基础知识记录-20220317

spring Bean的生命周期

1.实例化Bean实例

2.设置对象属性

3.检查Aware的相关接口并设置相关依赖

4.BeanPostProcessor前置处理

5.是否实现InitializingBean接口

6.是否配置自定义的init-method

7.BeanPostProcessor后置处理

8.注册Destruction相关回调接口

9.是否实现DisposableBean接口

10.是否配置自定义的destory-method

spring中都用到了哪些设计模式

1.简单工厂: BeanFactory

2.工厂方法: FactoryBean

3.单例模式: DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)

4.适配器模式: HandlerAdapter

5.装饰器模式

6.代理模式

7.观察者模式 spring中的事件驱动

8.策略模式 Resource

9.模版方法 JdbcTemplate

spring中的单例是如何实现的

相关方法

org.springframework.beans.factory.BeanFactory#getBean(java.lang.String)
org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String)
  
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)

单例获取方法

@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
  Object singletonObject = this.singletonObjects.get(beanName);
  if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
    synchronized (this.singletonObjects) {
      singletonObject = this.earlySingletonObjects.get(beanName);
      if (singletonObject == null && allowEarlyReference) {
        ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
        if (singletonFactory != null) {
          singletonObject = singletonFactory.getObject();
          this.earlySingletonObjects.put(beanName, singletonObject);
          this.singletonFactories.remove(beanName);
        }
      }
    }
  }
  return singletonObject;
}

BeanFactory和FactoryBean的区别

  1. BeanFactory:负责生产和管理Bean的一个工厂接口,提供一个Spring Ioc容器规范,
  2. FactoryBean: 一种Bean创建的一种方式,对Bean的一种扩展。对于复杂的Bean对象初始化创建使用其可封装对象的创建细节。

阻塞队列是线程安全的吗

阻塞队列是线程安全的,因为在它的实现类中获取数据和插入数据都是加ReentrantLock锁的

//以ArrayBlockingQueue 的take和put方法为例
public E take() throws InterruptedException {
  final ReentrantLock lock = this.lock;
  lock.lockInterruptibly();
  try {
    while (count == 0)
      notEmpty.await();
    return dequeue();
  } finally {
    lock.unlock();
  }
}
    
public void put(E e) throws InterruptedException {
  checkNotNull(e);
  final ReentrantLock lock = this.lock;
  lock.lockInterruptibly();
  try {
    while (count == items.length)
      notFull.await();
    enqueue(e);
  } finally {
    lock.unlock();
  }
}

ReentrantLock底层都用到了哪些东西

AQS 、CLH 、CAS

ReentrantLock 是可重入锁吗

ReentrantLock是可重入锁

ReentrantLock中的公平锁和非公平锁的区别

公平锁和非公平锁,主要是在方法 tryAcquire 中,是否 有 !hasQueuedPredecessors() 判断

//公平锁
protected final boolean tryAcquire(int acquires) {
  final Thread current = Thread.currentThread();
  int c = getState();
  if (c == 0) {
    //公平锁和非公平锁的区别,公平锁会判断当前队列中没有其他线程在等待锁资源
    if (!hasQueuedPredecessors() &&
        compareAndSetState(0, acquires)) {
      setExclusiveOwnerThread(current);
      return true;
    }
  }
  else if (current == getExclusiveOwnerThread()) {
    int nextc = c + acquires;
    if (nextc < 0)
      throw new Error("Maximum lock count exceeded");
    setState(nextc);
    return true;
  }
  return false;
}
}

//非公平锁
final boolean nonfairTryAcquire(int acquires) {
  final Thread current = Thread.currentThread();
  int c = getState();
  if (c == 0) {
    if (compareAndSetState(0, acquires)) {
      setExclusiveOwnerThread(current);
      return true;
    }
  }
  else if (current == getExclusiveOwnerThread()) {
    int nextc = c + acquires;
    if (nextc < 0) // overflow
      throw new Error("Maximum lock count exceeded");
    setState(nextc);
    return true;
  }
  return false;
}

ReentrantLock中的Sync重写了AQS的哪两个方法

//这是独占式释放同步状态的方法,让那些等待获取同步状态的线程能够有机会获取同步状态
java.util.concurrent.locks.AbstractQueuedSynchronizer#tryRelease
//这个方法用来判断当前同步器是否在独占模式下被线程占用,它会取出占用的线程和当前线程做个比较,看下是否相等。
java.util.concurrent.locks.AbstractQueuedSynchronizer#isHeldExclusively

ReentrantLock中的状态变量为什么不使用AtomicInteger

代码漏洞

1.以下代码有什么目的? 有什么严重的bug?
private int sumSubString(String a, String b){
    int sub = 0;
    while (a.contains(b)) {
          sub++;
          a = a.replaceFirst(b, " ");
    }
    return sub;
}

解惑
1.上面的代码为了统计字符串a包含多少个字符串b
2.上面的代码执行,会在以下两种情况下死循环

public class CountStringTest {
	private int sumSubString(String a, String b){
		int sub = 0;
		while (a.contains(b)) {
			sub++;
			a = a.replaceFirst(b, " ");
		}
		return sub;
	}
        
       //1.第一种情况a中有空格,b中也有空格
	@Test(timeout = 5L)
	public void testSumSubString(){
		String a = "hello world";
		String b = " ";
		int i = new CountStringTest().sumSubString(a, b);
		System.out.println(i);
	}
        
        //碰到了转义字符
	@Test
	public void testSumSubString2(){
		String a = "hello\\rworld";
		String b = "\\r";
		int i = new CountStringTest().sumSubString(a, b);
		System.out.println(i);
	}

}
posted @ 2022-03-17 21:50  crazy-zz5536  阅读(36)  评论(0编辑  收藏  举报