Open SummerXinBing opened 1 month ago
线程池的工作原理
最大线程数怎么设置?
6.三个线程,A、B线程同时运行,要求A、B中任意线程执行完毕后C线程继续执行,有哪些实现方案 ComplateFutrun 创建异步对象 计算完成时回调 线程串行化 两个任务组合,两个都要完成 两个任务组合,完成一个1
8.spring中注册 bean的方式有哪些 xml 代码 注解
注解扫描 通过打上一些注解@Service @Component @Bean等方式 @Component是 手动配置
想到bean,其实就要想到IOC容器,ioc的设计初衷就是提供bean的注册,和bean的定义
描述:Ioc容器的功能规范 功能:该接口提供一些基础的抽象方法,比如通过Bean的name获取Bean的实例,还有Bean类型等;该接口有3个子类(接口),比如AutowireCapableBeanFactory定义了将IOC容器的Bean按照某种规则(名字、类型)自动装配的方法;
描述:Bean的注册
描述:描述了各种Bean对象和它们之间的相互关系(Bean有相互循环依赖的问题),抓住3个要点去理解BeanDefinition a BeanDefinition 定义Bean对象和其相互关系 b BeanDefinitionReader BeanDefinition的解析器 Bean的解析过程比较复杂,主要针对Spring的配置文件进行解析,所以需要更多的扩展类去处理; c BeanDefinitionHolder 这是BeanDefination的包装类,用来存储BeanDefinition,name以及aliases等。
问1:怎么解决循环依赖的问题,通过3级缓存;
描述:Ioc容器的设计和实现
一级缓存:单例对象缓存池,已经实例化了,且已经赋值了的成品单例Bean; 二级缓存:单例对象缓存池,已经实例化了但是还没赋值的半成品单例Bean; 三级缓存:单例工厂缓存
private final Map<String, Object> singletonObjects = new CurrentHashMap<String, Object>(256);
private final Map<String, Object> earlyStringObjects = new HashMap<String, Object>(16);
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);
protected Object getBean(String beanName, boolean allowEarlyReference) {
// Spring尝试去一级缓存中获取
Object singletonObject = this.singletonObjects.get(beanName);
// 一级缓存取不到,并且对象正在建立中
if (singletonObjects == null && isSingletonCurrentlyInCreation(beanName))) {
// 去二级缓存中
synchronized(this.earlyStringObjects) {
Object singletonObject = this.earlyStringObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
}
}
}
}
return singletonObject;
}
上述代码只是描述如何从三级缓存中获取Bean,下面就是如何去模拟解决循环依赖的场景。 对象A依赖对B,对象B依赖对象A;当加载A的时候,在创建A的实例时会先放到BeanFcatort中,提前暴露给其他对象使用的,当创建A的过程中,发现需要创建B,那就去创建B,在创建B的过程中,发现需要依赖A,那就先从缓存中获取对象;
好比“A对象setter依赖B对象,B对象setter依赖A对象”,A首先完成了初始化的第一步,而且将本身提早曝光到singletonFactories中,此时进行初始化的第二步,发现本身依赖对象B,此时就尝试去get(B),发现B尚未被create,因此走create流程,B在初始化第一步的时候发现本身依赖了对象A,因而尝试get(A),尝试一级缓存singletonObjects(确定没有,由于A还没初始化彻底),尝试二级缓存earlySingletonObjects(也没有),尝试三级缓存singletonFactories,因为A经过ObjectFactory将本身提早曝光了,因此B可以经过ObjectFactory.getObject拿到A对象(半成品),B拿到A对象后顺利完成了初始化阶段一、二、三,彻底初始化以后将本身放入到一级缓存singletonObjects中。此时返回A中,A此时能拿到B的对象顺利完成本身的初始化阶段二、三,最终A也完成了初始化,进去了一级缓存singletonObjects中,并且更加幸运的是,因为B拿到了A的对象引用,因此B如今hold住的A对象完成了初始化。
Bean的作用域 单例 原型 请求request 会话session 全局作用域
类加载的过程 加载 、连接(验证、准备、解析)、初始化、使用、卸载;
加载有多种方式,网络加载、本地加载ets。加载就是将二进制流加载到jvm内存中; 验证:验证被加载类的正确性 准备:为类的静态变量分配内存,并初始化值 解析:把类的符号引用转化为直接引用 初始化:为类的成员变量分类内存,并初始化值 使用:jvm在方法去提供了一个接口,用来访问heap中的数据; 卸载:结束生命周期
类加载器的层次 启动类加载器:加载启动类相关,jdk/jre/lib 扩展类加载器:加载扩展类 jdk/jre/lib/ext 应用程序类加载器:加载用户路径java代码 自定义类加载器
类加载机制 全盘委托 父亲机制 双亲委派机制:如果jvm收到了一个类的加载请求,类加载器不会立即去加载,而是去父层加载器寻找(扩展类加载器、启动类加载器),找到就返回;如果找不到,依次往上找,找不到就下一层的类加载器去加载;
1.项目亮点难点处理方案,java服务容器中除了堆内堆外还有哪些内存占用 2.线程池工作原理 3.线程池线程数量设置依据 4.线程池中某个线程执行报异常了,该线程会怎么样,怎样在主线程中获取该异常 5.ThreadLocal原理、ThreadLocalMap原理、什么情况下会出现内存泄露、什么情况下会出现OOM 6.三个线程,A、B线程同时运行,要求A、B中任意线程执行完毕后C线程继续执行,有哪些实现方案 7.AQS原理,线程入队细节 8.spring中注册 bean的方式有哪些 9.nacos配置动态更新原理、nacos注册中心AP/ CP原理 10.mysql主键索引与唯一索引功能上的区别 11.mysql mvcc原理