spring 生命周期
实例化-设置参数(set)-三个aware接口(beanName、beanfactory、application)-后置处理器-
init-后置处理器-获取bean的事例-destory方法
mvc 生命周期
ee中的servelet域里存放一个容器,能够分发请求
过滤器拦截器,
过滤器
实现filter接口,webfilter注解配置拦截路径,dofiter放行
过滤器是基于方法回调,是以tomcat维度针对url进行的过滤行为
而拦截器是基于动态代理的行为,是spring进行bean初始化的时候给予的拦截能力
spring 初始化流程 空参处理器+set+后置处理器+init+后置处理器+destory方法
针对的对象不同
:原理,使用范围,拦截范围,触发时机,执行顺序,bean注入时间不同
redis消息队列消费 :
1:weblistnener imp servletcontextlisten init启动监听
2:(通过配置文件修改)
系统初始化 bean注解给redis监听器 ,
注解condition redis实例化时加载 ,开线程池
进行监听
是否存在锁:
无锁的时候 随机消费,
有锁的时候 比对uuid不一致 就一直自旋不消费
滑动窗口,找字符串内最大不重复子串
private String checkLenth(String s) {
int right;
int max;
HashMap<Integer, String> map = new HashMap<>();
char[] chars = s.toCharArray();
for (int i = 0; i < chars.length; i++) {
right=i+1;
for (int j = right; j < chars.length; j++) {
if (chars[i]==chars[j]){
//出现重复
max = j - i ;
String substring = s.substring(i, j);
map.put(max,substring);
break;
}
}
}
Integer integer = map.keySet().stream().sorted().collect(Collectors.toList()).get(0);
String s1 = map.get(integer);
return s1;
}
线程池
线程配置类,bean注入
7个参数:核心线程+最大线程+存活时间+单位时间+队列+线程工厂+拒绝策略
大于核心线程 进入阻塞队列 阻塞队列满了 再创建线程 ,超过最大线程 进行拒绝策略
callable接口与runnable接口
completefuture 方法 supplyAsync //runAsync 线程池入参
Future的局限性
并发执行多任务:Future只提供了get()方法来获取结果,并且是阻塞的。所以,除了等待你别无他法;
无法对多个任务进行链式调用:如果你希望在计算任务完成后执行特定动作,比如发邮件,但Future却没有提供这样的能力;
无法组合多个任务:如果你运行了10个任务,并期望在它们全部执行结束后执行特定动作,那么在Future中这是无能为力的;
没有异常处理:Future接口中没有关于异常处理的方法;
所以,我们还需要CompletionService来帮助我们完成这些需求。
completablefuture是future的加强版,可以并发多线程执行,可以抛异常,实现任务编排 == countdownlatch加线程池也行
CountDownLatch
根据任务数量初始化
开线程池执行
(子线程的bug捕获)
finally countdownlatch.countdown
countdownlatch.await()
redis 快照
RDB AOF
RDB会fork一个子线程接替主线程进行工作,主线程不再进行其他的io操作,快照的方式存储kv
到内存中(通常存放在一个别的机器上),恢复的时候移动文件就行。保存策略:x时间内进行y次操作,
会丢失再快照之前的最后一次修改的数据
AOF将操作的写命令记录到日志文件中,恢复时适用命令恢复数据,效率低 一般适用一秒一次
一般对并发要求高,敏感要求低的数据可以存储,是可以保证做到不丢失数据的,但是建议存储到关系型数据库中
回调函数
某个方法执行结束之后,以该方法的结果作为入参传递到回调方法中
CountDownLatch
根据任务数量初始化
开线程池执行
(子线程的bug捕获)
finally countdownlatch.countdown
countdownlatch.await()
线程池
线程配置类,bean注入
7个参数:核心线程+最大线程+存活时间+单位时间+队列+线程工厂+拒绝策略
大于核心线程 进入阻塞队列 阻塞队列满了 再创建线程 ,超过最大线程 进行拒绝策略
内网接口暴露:
外部接口会经过网关,网关过滤加上标识,内网接口aop,判断是外部接口禁止访问。
分布式事务
事务 acid 原子+一致+隔离+持久
cap理论,一致性+可用性+分区容忍性
强一致性,刚性事务 : xa/2pc 事务管理器,
事务一阶段执行所有的sql,全部执行成功开始执行二阶段
最终一致性:tcc,本地消息表,mq
mq事务
nameserver broker 提供&&消费
消息存放在broker中 各自topic的queue中
心跳机制:
broker 与 nameserver 每隔30s brocker传递心跳,两分钟内nameserver搜不到
broker的信息那么就断开连接(name与broker的连接)
生产者也每隔30s从nameserve获取broker的信息,这意味着如果broker宕机生产者需要30秒时间感知,
这期间消息将会失败
生产者每隔30s会给所有broker发送心跳信息,如果broker2分钟没有收到消息会断开连接
刷盘策略,同步&&异步,生产者与broker的通信,刷盘成功返回也返回再进行刷盘
事务流程:
上游投递一个half半事务消息,下游收到消息回传一个半事务消息。上游开始执行事务操作,
并将执行结果进行投递,失败->下游丢弃事务消息,成功->下游消费事务消息 , 消息丢失->下游因为拿到了
半事务消息,会按照消息进行回查事务状态(回查15次,如果15次都回查失败默认事务失败),根据事务状态再发送执行状态给下游。
执行成功的情况,下游尝试执行事务,执行16次,四个小时,来保证消息一致性。
16次执行都没有成功,mq将消息丢入死信队列,预警或者手动干预进行消费成功,成功后从队列中删除。
jwt
解决的问题:服务间调用的相互信任问题
1.nginx的hash_ip映射,健壮性,与负载均衡问题
2.session风暴
3.session共享
4.jwt
jwt的注销问题,
1.存储过期时间。2删除token,
3存在一个存储token注销的redis存储(黑名单机制),token有一些存活时间
4(白名单机制,不推荐)
会话技术
cookie 存储于浏览器,默认为会话级别,客户端技术,可以通过响应报文传送给客户端,
如果希望可以持久化保存,设置时间=正数
session 浏览器记录sessionId,实际数据存储于服务器,浏览器关闭会抹除sessionId,默认存在30分钟
redis
数据机构+持久化+分布式+穿透+内存淘汰策略+缓存一致性问题
进程:运行的程序或软件,操作系统进行资源调度的基本单位;
线程:进程中的子任务,进程中有多个线程,CPU进行资源调度的基本单位;
interrup
新建状态,就绪状态,执行状态,阻塞状态,死亡状态
mysql
存储引擎:mysam innodb
隔离级别:
索引失效情况:or查询,最左前缀,左like,where后有索引计算,索引有函数,类型转换,全表更快
与bio不同的是,bio是同步阻塞io,在服务端处理客户端请求时一个请求会有一个线程,在这个线程进行io操作时是阻塞的,
只有在完成这次操作后,才能继续接受请求。
nio同步非阻塞,是一种面向缓冲区基于通道的io操作,在接受客户端请求时生成的一个线程,即客户端发送的连接请求都会注册到多路复用器上
而Selector(选择器)用于监听多个通道的事件(比如:连接请求,数据到达等),每个channel都会对应一个 Buffer
一个线程对应Selector ,一个Selector对应多个channel(连接)程序
切换到哪个channel是由事件决定的
Selector 会根据不同的事件,在各个通道上切换
Buffer 就是一个内存块,底层是一个数组
栈帧:局部变量表、操作栈、动态连接、方法出口
ygc:根据根搜索算法(方法区和栈指向)确定垃圾,标记清除算法进行回收,(朝生夕死),从伊甸区与幸存者0区到幸存者1区
GC:大多数的对象都是在新生代生成。1.对象申请空间,新生代伊甸园是否能够存放,否->ygc,如果依然放不下,就去
老年代生成,如果还是不行进行fgc
抽象类与接口的区别
工厂类 作为容器,从容器种取出实现类,实现类调用方法。抽象方法必须实现,公共方法在抽象类中进行