面试积累
spring面试积累
springmvc中为什么需要用到父子容器?
父容器是使用了ContextLoaderListener加载并实例化的ioc容器为父容器;
子容器是使用了DispatcherServerlet加载并实例化的ioc容器为子容器
通;
常我们使用springmvc的时候,采用3层结构,controller层,service层,dao层;父容器中会包含dao层和service层,而子容器中包含的只有controller层;这2个容器组成了父子容器的关系,controller层通常会注入service层的bean。
采用父子容器可以避免有些人在service层去注入controller层的bean,导致整个依赖层次是比较混乱的。
父容器和子容器的需求也是不一样的,比如父容器中需要有事务的支持,会注入一些支持事务的扩展组件,而子容器中controller完全用不到这些,对这些并不关心,子容器中需要注入一下springmvc相关的bean,而这些bean父容器中同样是不会用到的。
@configuration是什么,有什么作用?
标注当前类为配置类;
用于定义配置类(java配置类),被注解的类内部中的@Bean将被(ApplicationConfigApplicationContext或ApplicationConfigWebApplicationContext)扫描用于构建Bean定义,初始化spring容器。
@Conditional注解是什么?条件判断在什么时候执行?
是从spring4.0才有的,可以用在任何类型或者方法上面,通过@Conditional注解可以配置一些条件判断,当所有条件都满足的时候,被@Conditional标注的目标才会被spring容器处理。
Spring对配置类的处理主要分为2个阶段:
配置类解析阶段
会得到一批配置类的信息,和一些需要注册的bean
bean注册阶段
将配置类解析阶段得到的配置类和需要注册的bean注册到spring容器中;
@Conditional中判断条件会对两个阶段都有效,此时通过Condition是无法精细的控制某个阶段的,如果想控制某个阶段需要用到另外一个接口了:ConfigurationCondition
相对于Condition接口多了一个getConfigurationPhase方法,用来指定条件判断的阶段,是在解析配置类的时候过滤还是在创建bean的时候过滤。(详细及使用,见下方链接)
conditional注解转自:
原文链接:https://blog.csdn.net/likun557/article/details/105108901
什么是配置类
类中有下面任意注解之一的就属于配置类:
类上有**@Compontent注解
类上有@Configuration注解
类上有@CompontentScan注解
类上有@Import注解
类上有@ImportResource注解
类中有@Bean**标注的方法
spring的ImportSelector接口有什么作用?
(@EnabledAutoConfiguration:自动化配置注解,是SpringBootAppliction核心注解之一;
代码核心:最重要是@Import(AutoConfigurationImportSelector.class))
@Import作用是将bean注册到Spring IOC容器中;
public interface ImportSelector {
/**
* Select and return the names of which class(es) should be imported based on
* the {@link AnnotationMetadata} of the importing @{@link Configuration} class.
*/
String[] selectImports(**AnnotationMetadata importingClassMetadata)**;
}
收集需要导入的配置类
一般和@Import一起使用,@Import引入@ImportSelector的实现类后会把实现类中bean class数组注册到Spring容器中;
spring@EnableXXX注解的原理
例如:@EnableAutoConfiguration,@EnableAsync,@EnableSwagger等。
@Enable起到了开关的作用,底层使用到ImprotSelector实现。
Eureka
注册慢
1、 eureka注册慢的根本原因在于eureka的AP特性。
(CAP理论,一致性consistency(C)可用性Avaliability(A)分区容错性Partition tolerance(P))
2、eureka client延迟注册,默认30秒
eureka server的响应缓存,默认30秒
eureka server的缓存刷新,默认30秒
与zk比较
分布式基础:CAP理论
eureka保证AP特性
zk是典型的CP特性
自我保护
Eureka server 会自动更新续约更新阈值。
eureka server 续约更新频率低于阈值则进入保护模式。
自我保护模式下eureka server不会剔除任何注册信息。
JAVA面试积累
weekHashMap
WeakHashMap继承Map,key的类型是弱引用WeakReference(弱引用:如果对应的key被回收,则这个key指向的对象会被从Map容器中移除)。
public class WeakHashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>
WeakHashMap跟普通的HashMap不同,WeakHashMap一定程度上基于垃圾收集器的行为,因此一些Map数据结构对应的常识在WeakHashMap上会失效——size()方法的返回值会随着程序的运行变小,isEmpty()方法的返回值会从false变成true等等。
典型使用场景: tomcat两级缓存
tomcat在这里是使用ConcurrentHashMap和WeakHashMap做了分代的缓存。
package org.apache.tomcat.util.collections;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
public final class ConcurrentCache<K,V> {
private final int size;
private final Map<K,V> eden;
private final Map<K,V> longterm;
public ConcurrentCache(int size) {
this.size = size;
this.eden = new ConcurrentHashMap<>(size);
this.longterm = new WeakHashMap<>(size);
}
/*
优先从eden中找对应的v,如果没有则进入longterm缓存中查找,找到后就加入eden缓存并返回。
*/
public V get(K k) {
V v = this.eden.get(k);
if (v == null) {
synchronized (longterm) {
v = this.longterm.get(k);
}
if (v != null) {
this.eden.put(k, v);
}
}
return v;
}
/*
在插入一个k-v时,先检查eden缓存的容量是不是超了。没有超就直接放入eden缓存,如果超了则锁定longterm将eden中所有的k-v都放入longterm。再将eden清空并插入k-v。
*/
public void put(K k, V v) {
if (this.eden.size() >= size) {
synchronized (longterm) {
this.longterm.putAll(this.eden);
}
this.eden.clear();
}
this.eden.put(k, v);
}
}
分布式锁与分布式事务
Dubbo面试相关
设计原则
- “微内核+插件”的设计模式,内核只负责组装插件(扩展点),Dubbo的功能都是由插件实现的,也就是Dubbo的所有功能点都可被用户自定义扩展类所替换。
- 一致性, 采用URL作为配置信息的统一格式,所有扩展点都通过url携带配置信息。
三大领域模型
- protocol服务领域:是invoker暴露和引用的主要功能入口,它负责invoker的生命周期管理。
- invoker实体域:是Dubbo的核心模型,它代表一个可执行体,可向它发起invoke调用,它有可能是一个本地的实现,也可能是个远程的实现,也可能是个集群实现。
- Invocation 是会话域:它持有调用过程中的变量,比如方法名,参数等。
四大组件
-
Registry 注册中心
-
Monitor 监控中心(dubbo自己的监控项目,直接解压在tomcat下就能启动了,可以查看消费者,生产者)
-
Provider 提供者
-
Consumer 消费者
十层架构
- Business层
- RPC层
- Remotting层