技术总结
2022-04-14 07:41:03 1 举报
AI智能生成
java
作者其他创作
大纲/内容
spring
核心接口
DefaultListableBeanFactory
ConfigurableBeanFactory提供配置Factory的各种方法
ListableBeanFactory获取bean的配置清单
BeanDefinition
手动注册BeanDefinition
实现ImportBeanDefinitionRegistrar
实现BeanDefinitionRegistryPostProcessor
GenericBeanDefinition
RootBeanDefinition
BeanDefinitionRegistry
bean的注册器
BeanWrapper
对Bean的一种包装,动态获取和设置属性值
FactoryBean
ApplicationContext
与BeanFactory区别
提供支持国际化的文本消息
统一资源文件读取方式
支持事件传播
ApplicationContextInitializer
Spring ConfigurableApplicationContext调用的回调接口
ConfigurationClassPostProcessor,解析加了@Configuration的配置类
bean生命周期
Spring Bean元信息处理阶段
Spring Bean元信息解析阶段
常用Spring Bean元信息配置是注解,针对这种Spring Bean元信息配置的解析,在AnnotationConfigApplicationContext进行处理
AnnotationConfigApplicationContext一个构造器里会调用scan方法扫描指定包路径,会使用ClassPathBeanDefinitionScanner的scan能力扫描具有某些注解的类,把这些类加载为Spring Bean元信息
Spring BeanDefinition注册阶段
Spring具有一个数据结构BeanDefinitionRegistry,解析后的BeanDefinition会注册到BeanDefinitionRegistry,BeanDefinitionRegistry是一个接口,一个典型的实现类是DefaultListableBeanFactory,GenericApplicationContext里通过生成DefaultListableBeanFactory成员实现注册
Spring BeanDefinition合并阶段
在底层IoC容器通常会有两种BeanDefinition,一个是GenericBeanDefinition,一个是RootBeanDefinition,一个Bean在实例化前,对应BeanDefinition都要转化成RootBeanDefinition。
GenericBeanDefinition保存原始的Spring Bean元信息,可以指定父Bean的beanName,但是不会继承父Bean的属性,还不具备实例化的能力。
GenericBeanDefinition在合并之后会变成RootBeanDefinition,这时RootBeanDefinition不会保存父Bean的beanName,但是会从父Bean继承属性。
Spring Bean实例化阶段
Spring Bean Class加载阶段
Spring Bean Class加载方法是AbstractBeanFactory#resolveBeanClass, resolveBeanClass方法会使用RootBeanDefinition里记录的beanClassName加载对应类,保存到RootBeanDefinition
Spring Bean实例化前阶段
AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation方法提供一个扩展InstantiationAwareBeanPostProcessor可以让Spring Bean在实例化前做一些扩展
Spring Bean实例化后阶段
AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors方法是Spring提供的第一个Spring Bean实例化后扩展,实现MergedBeanDefinitionPostProcessor接口即可进行扩展
Spring提供的第二个实例化后扩展是InstantiationAwareBeanPostProcessor,在方法AbstractAutowireCapableBeanFactory#populateBean里有一段代码处理这个扩展
Spring Bean实例化阶段
如果通过InstantiationAwareBeanPostProcessor生成了代理类,则不会走AbstractAutowireCapableBeanFactory#doCreateBean,AbstractAutowireCapableBeanFactory#createBeanInstance方法处理Spring Bean实例化,给指定beanName创建一个新的实例,先后使用工厂方法、构造器自动注入、简单实例化方式创建
Spring Bean属性赋值前阶段
Spring Bean赋值前提供扩展是InstantiationAwareBeanPostProcessor#postProcessProperties和InstantiationAwareBeanPostProcessor#postProcessPropertyValues,在方法AbstractAutowireCapableBeanFactory#populateBean里有一段代码处理这两个扩展
Spring Bean赋值阶段
Spring Bean赋值方法是AbstractAutowireCapableBeanFactory#applyPropertyValues
Spring Bean初始化阶段
Spring Bean Aware接口回调阶段
AbstractAutowireCapableBeanFactory#invokeAwareMethods
Spring Bean初始化前阶段
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
这个方法会调用BeanPostProcessor#postProcessBeforeInitialization方法
Spring Bean初始化阶段
AbstractAutowireCapableBeanFactory#invokeInitMethods
Spring Bean初始化后阶段
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
这个方法回调用BeanPostProcessor#postProcessAfterInitialization方法
生命周期自定义处理方法
InstantiationAwareBeanPostProcessor
构造函数
依赖注入
BeanNameAware
BeanFactoryAware
ApplicationContextAware
BeanPostProcessor前置方法
InitializingBean
自定义init方法,使用@PostConstruct注解
BeanPostProcessor后置方法
DisposableBean
自定义destroy方法
bean缓存
三级缓存 singletonFactories
单例对象工厂的cache,存放 bean 工厂对象
二级缓存 earlySingletonObjects
存放了刚实例化好的,但是还未配置属性和初始化的bean
一级缓存 singletonObjects
存放初始化好的bean
为什么需要三级缓存解决循环依赖
如果bean被AOP代理的话,singletonFactory.getObject每次都会产生一个新的代理对象,所以二级缓存解决不了循环依赖问题
扩展接口
BeanFactoryPostProcessor
处理所有bean前,对bean factory进行预处理
springboot内置实现类
ConfigurationClassPostProcessor
解析了加了Configuration注解的类,同时解析出 @ComponentScan 和 @ComponentScans 扫描出的Bean,也会解析出加了 @Bean 注解的方法所注册的Bean,以及通过 @Import 注解注册的Bean和 @ImportResource 注解导入的配置文件中配置的Bean
利用CGLIB对加了@Configuration注解的类创建动态代理,进行增强。最后还会向spring容器中添加一个Bean后置处理器:ImportAwareBeanPostProcessor
AutowiredAnnotationBeanPostProcessor
RequiredAnnotationBeanPostProcessor
CommonAnnotationBeanPostProcessor
PersistenceAnnotationBeanPostProcessor
BeanDefinitionRegistryPostProcessor
可以添加自定义的bean
BeanPostProcessor
支持在bean初始化前、后对bean进行处理
InitalizingBean、@PostConstruct
bean创建完成,所有属性注入完成后执行
ApplicationListener
用来监听产生的应用事件
ApplicationContextInitializer
refresh上下文之前
springboot内置实现类
ConfigurationWarningsApplicationContextInitializer
对于一般配置错误在日志中作出警告
ContextIdApplicationContextInitializer
设置ApplicationContext#getId()所获取的ID值,默认取spring.application.name属性值,没有配置时默认为 application
DelegatingApplicationContextInitializer
使用环境属性context.initializer.classes指定的初始化器(initializers)进行初始化工作,如果没有指定则什么都不做
ServerPortInfoApplicationContextInitializer
将内置servlet容器实际使用的监听端口写入到Environment环境属性中。这样属性"local.server.port"就可以直接通过@Value注入到测试中,或者通过环境属性Environment获取
SharedMetadataReaderFactoryContextInitializer
创建一个SpringBoot和ConfigurationClassPostProcessor共用的CachingMetadataReaderFactory对象,实现类使用ConcurrentReferenceCachingMetadataReaderFactory
ConditionEvaluationReportLoggingListener
将ConditionEvaluationReport写入日志
springboot
URLStreamHandler
java中描述资源常使用URL,由于URL用于表达各种各样的资源,打开资源的具体动作由java.net.URLStreamHandler这个类的子类来完成
根据不同的协议,会有不同的handler实现,子类的类名必须是 Handler ,同时最后一级的包名必须是协议的名称
JVM 启动的时候,需要设置 java.protocol.handler.pkgs 系统属性,如果有多个实现类,那么中间用 | 隔开。因为JVM在尝试寻找Handler时,会从这个属性中获取包名前缀,最终使用包名前缀.协议名.Handler
通过maven插件将依赖包也打进最终的Jar,变成一个可运行的FatJar
META-INF文件夹:程序入口,其中MANIFEST.MF用于描述jar包的信息
lib目录:放置第三方依赖的jar包,比如springboot的一些jar包
spring boot loader相关的代码
模块自身的代码
jar启动过程
MANIFEST.MF文件中Main-Class是JarLauncher,Start-Class才是自定义应用的主类
JarLauncher继承于org.springframework.boot.loader.ExecutableArchiveLauncher。该类的无参构造方法最主要的功能就是构建了当前main方法所在的FatJar的JarFileArchive对象
以FatJar为file作为入参,构造JarFileArchive对象。获取其中所有的资源目标,取得其Url,利用org.springframework.boot.loader.jar.Handler(支持识别多层!/分隔符),加载资源
创建自定义 ClassLoader 实现类 LaunchedURLClassLoader,通过它来加载 BOOT-INF/classes 目录下的类,以及 BOOT-INF/lib 目录下的 jar 包中的类,引入自定义类加载器就是为了能解决jar包嵌套jar包的问题,系统自带的AppClassLoarder不支持读取嵌套jar包
LaunchedURLClassLoader加载MANIFEST.MF文件中Start-Class指向的业务类,并且执行静态方法main。进而启动整个程序
main方法启动过程
获取SpringApplicationRunListener监听器实现类,调用starting方法
加载环境变量,调用监听器的environmentPrepared方法
createApplicationContext创建应用上下文,默认是AnnotationConfigApplicationContext
prepareContext准备上下文,调用ApplicationContextInitializer实现类的initialize方法
refreshContext刷新上下文
prepareRefresh,加载ApplicationListener监听器
prepareBeanFactory,
ignoreDependencyInterface忽略指定接口的自动装配
registerResolvableDependency指定系统接口的实现类
添加一些系统自带的BeanPostProcessor,ApplicationContextAwareProcessor、ApplicationListenerDetector
postProcessBeanFactory
扫描有相应注解的类
invokeBeanFactoryPostProcessors
执行BeanDefinitionRegistryPostProcessor、BeanFactoryPostProcessor的实现类的方法
Servlet3.0
扫描jar包的META-INF/services/javax.servlet.ServletContainerInitializer
SPI机制加载SpringServletContainerInitializer
HandlesTypes注解可以将WebApplicationInitializer接口的实现类作为ServletContainerInitializer的onStartup方法的第一个入参里面
SpringBootServletInitializer实现了WebApplicationInitializer
war包部署时需继承SpringBootServletInitializer,实现configure方法
SpringApplicationRunListener接口回调来让用户在启动的各个流程中可以加入自己的逻辑
开始启动
Environment构建完成
ApplicationContext构建完成
ApplicationContext完成加载
ApplicationContext完成刷新并启动
启动完成
启动失败
CommandLineRunner、ApplicationRunner 接口是在容器启动成功后的最后一步回调
@Conditional注解原理
ConfigurationClassPostProcessor的processConfigBeanDefinitions对@configuration注解的bean进行创建解析
ConfigurationClassParser调用processConfigurationClass方法判断当前解析的配置bean是否包含Conditional注解,如果不包含则不需要跳过,包含了则进行match方法得到匹配结果
通过ConditionEvaluator中shouldSkip方法判断当前bean处于解析还是注册,如果处于解析阶段则跳过,如果处于注册阶段则不跳过
通过实现Condition接口,并重写其matches方法来构造判断条件
springmvc
流程
DispatcherServlet收到请求调用处理器映射器HandlerMapping。
处理器映射器HandlerMapping向前端控制器返回Handler,HandlerMapping会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象,多个HandlerInterceptor拦截器对象)一并返回给DispatcherServlet。
DispatcherServlet根据处理器Handler获取处理器适配器HandlerAdapter执行HandlerAdapter处理一系列的操作,如:参数封装,数据格式转换,数据验证等操作
执行处理器Handler(Controller,也叫页面控制器)。
Handler执行完成返回ModelAndView
HandlerAdapter将Handler执行结果ModelAndView返回到DispatcherServlet
DispatcherServlet将ModelAndView传给ViewReslover视图解析器
ViewReslover解析后返回具体View
DispatcherServlet对View进行渲染视图(即将模型数据model填充至视图中)。
分支主题
组件
HandlerMapping
处理器映射器默认:BeanNameUrlHandlerMapping
SimpleUrlHandlerMapping
HandlerAdapter
处理器适配器默认:HttpRequestHandlerAdapter
SimpleControllerHandlerAdapter
ViewResolver
视图解析器默认:InternalResourceViewResolver
事务
失效场景
注解@Transactional配置的方法非public权限修饰
注解@Transactional所在类非Spring容器管理的bean
注解@Transactional所在类中,注解修饰的方法被类内部方法调用
业务代码抛出异常类型非RuntimeException,事务失效
异步请求
webflux
异步非阻塞的web框架
适用于IO密集型的服务
一个线程可以处理更多的请求,springmvc一个请求会对应容器的一个线程
Callable
释放容器线程,spring使用TaskExecutor管理任务线程
Deferredresult
释放容器线程,用户自己管理任务执行线程
state machine
State:状态存储关于过去的信息,就是说它反映从系统开始到现在时刻的输入变化。
Actions & Transitions:转换指示状态变更,并且用必须满足来确使转移发生的条件来描述它。动作是在给定时刻要进行的活动的描述。
Guards:检测器出现的原因是为了检测是否满足从一个状态切换到另外一个状态的条件。
Event:事件
POI
HSSFWorkbook
支持excel 2003最多只允许存储65536条数据
XSSFWorkbook
支持excel2007以上版本,因为它采用ooxml格式,可以支持1048576条数据
SXSSFWorkbook
POI3.8之后新增,可以控制excel数据占用的内存,他通过控制在内存中的行数来实现资源管理,即当创建对象超过了设定的行数,它会自动刷新内存,将数据写入文件
权限
Shiro
核心组件
subject:主体,可以是用户也可以是程序,主体要访问系统,系统需要对主体进行认证、授权
securityManager:安全管理器,主体进行认证和授权都是通过securityManager进行,是shiro的心脏
realm:域,领域,相当于数据源,通俗意义的DAO层,通过realm存取认证、授权相关数据
Authentication: 认证。即验证是哪个用户登录
Authorization:也被称为访问控制,即决定当前登录用户是否有权限去访问受保护的资源
Spring Security
核心组件
SecurityContextHolder:提供对SecurityContext的访问
SecurityContext:持有Authentication对象和其他可能需要的信息
AuthenticationManager:其中可以包含多个AuthenticationProvider
ProviderManager对象:为AuthenticationManager接口的实现类
AuthenticationProvider:主要用来进行认证操作的类 调用其中的authenticate()方法去进行认证操作
Authentication:Spring Security方式的认证主体
GrantedAuthority:对认证主题的应用层面的授权,含当前用户的权限信息,通常使用角色表示
UserDetails:构建Authentication对象必须的信息,可以自定义,可能需要访问DB得到
UserDetailsService:通过username构建UserDetails对象,通过loadUserByUsername根据userName获取UserDetail对象
过滤器
WebAsyncManagerIntegrationFilter: 将 Security 上下文与 Spring Web 中用于处理异步请求映射的 WebAsyncManager 进行集成
SecurityContextPersistenceFilter:在每次请求处理之前将该请求相关的安全上下文信息加载到 SecurityContextHolder 中,然后在该次请求处理完成之后,将 SecurityContextHolder 中关于这次请求的信息存储到一个“仓储”中,然后将 SecurityContextHolder 中的信息清除,例如在Session中维护一个用户的安全信息就是这个过滤器处理的
HeaderWriterFilter: 用于将头信息加入响应中
CsrfFilter 用于处理跨站请求伪造
LogoutFilter用于处理退出登录
UsernamePasswordAuthenticationFilter用于处理基于表单的登录请求,从表单中获取用户名和密码。默认情况下处理来自 /login 的请求。从表单中获取用户名和密码时,默认使用的表单 name 值为 username 和 password,这两个值可以通过设置这个过滤器的usernameParameter 和 passwordParameter 两个参数的值进行修改
DefaultLoginPageGeneratingFilter如果没有配置登录页面,那系统初始化时就会配置这个过滤器,并且用于在需要进行登录时生成一个登录表单页面
BasicAuthenticationFilter检测和处理 http basic 认证
RequestCacheAwareFilter 用来处理请求的缓存
SecurityContextHolderAwareRequestFilter主要是包装请求对象request
AnonymousAuthenticationFilter:检测 SecurityContextHolder 中是否存在 Authentication 对象,如果不存在为其提供一个匿名 Authentication
SessionManagementFilter:管理 session 的过滤器
ExceptionTranslationFilter处理 AccessDeniedException 和 AuthenticationException 异常
FilterSecurityInterceptor可以看做是过滤器链的出口
RememberMeAuthenticationFilter当用户没有登录而直接访问资源时, 从 cookie 里找出用户的信息, 如果 Spring Security 能够识别出用户提供的remember me cookie, 用户将不必填写用户名和密码, 而是直接登录进入系统,该过滤器默认不开启
分支主题
mybatis
主要对象
SqlSessionFactory
SqlSession
Executor
SimpleExecutor:每执行一次 update 或 select,就开启一个 Statement 对象,用完立刻关闭 Statement 对象
ReuseExecutor:执行 update 或 select,以 sql 作为key 查找 Statement 对象,存在就使用,不存在就创建,用完后,不关闭 Statement 对象,而是放置于 Map
BatchExecutor:完成批处理
StatementHandler
ParameterHandler
ResultSetHandler
TypeHandler
完成从 javaType 至 jdbcType 的转换
完成 jdbcType 至 javaType 的转换
setParameter()和 getResult()两个方法,分别代表设置 sql 问号占位符参数和获取列查询结果
插件机制
拦截器实现
实现Interceptor 接口
使用@Intercepts注解完成插件签名,注解里描述指定拦截方法的签名 [type,method,args]
拦截器拦截接口
Executor
StatementHandler
ParameterHandler
ResultSetHandler
缓存
一级缓存
作用域是session
HashMap实现
默认开启
二级缓存
作用域是Mapper(namespace)
支持ehcache等缓存实现
可配置删除策略、刷新间隔、缓存数量等
mapper接口里的方法不能重载
事务
核心类
PlatformTransactionManager
事务管理器,获取事务,回顾事务,提交事务
TransactionDefiition
定义事务的类型,事务包含很多属性,是否可读,事务隔离级别,事务传播级别
TransactionStatus
事务运行的状态,事务是否完成,是否是新的事务,是不是只能回滚等
处理流程
mybatis 启动时根据xml、注解创建了 mapperedStatement,用于sql执行,创建了 SqlSessionFactory 用于创建 SqlSession 对象。
mybatis 启动时创建了 MapperProxyFactory 用于创建接口的代理对象 MapperProxy
在创建 MapperProxy 时,spring 为其注入了一个 sqlSession 用于 sql执行,但是这个 sqlSession 是一个代理对象,叫做 sqlSessionTemplate,它会自动选择我们该使用哪个 sqlSession 去执行
@Transactional 注解的方法通过TransactionInterceptor进行方法代理
在执行时,spring 切面在执行事务之前,会创建一个叫做 TransactionInfo 的对象,此对象会根据事务传播等级来控制是否创建新连接,是否挂起上一个连接,将信息保存在 TransactionSynchronizationManager
到了真正需要创建或者获取 sqlSession 时,spring 重写的 TransactionFactory 会优先去 TransactionSynchronizationManager 中拿连接对象。
编码
设计模式
创建型
单例
懒汉式
饿汉式
工厂
简单工厂
唯一工厂类,一个产品抽象类,工厂类的创建方法依据入参判断并创建具体产品对象
工厂方法
多个工厂类,一个产品抽象类,利用多态创建不同的产品对象,避免了大量的if-else判断
抽象工厂
多个工厂类,多个产品抽象类,产品子类分组,同一个工厂实现类创建同组中的不同产品,减少了工厂子类的数量
建造者
原型
对象克隆
结构型
适配器
slfj日志框架
类适配器
对象适配器
接口适配器
代理
享元
连接池
装饰器
实现接口,传入实例对象,接口方法前后调用改造
桥接
行为型
策略
模板方法
基于AQS的锁的实现
责任链
观察者
迭代
命令
备忘录
状态
solid设计原则
单一职责
开放封闭
通过扩展来实现变化而不是通过修改已有代码
里氏替换
父类出现的地方子类可以替换,反之则不可以
接口隔离
依赖倒置
依赖抽象和接口,模块间依赖抽象不与具体实现依赖
领域驱动设计
作用
统一思想:统一项目各方业务、产品、开发对问题的认知,而不是开发和产品统一,业务又和产品统一从而产生分歧
明确分工:域模型需要明确定义来解决方方面面的问题,而针对这些问题则形成了团队分钟的理解
反映变化:需求是不断变化的,因此我们的模型也是在不断的变化的。领域模型则可以真实的反映这些变化
边界分离:领域模型与数据模型分离,用领域模型来界定哪些需求在什么地方实现,保持结构清晰
概念
实体
有唯一标志的核心领域对象,且这个标志在整个软件生命周期中都不会发生变化。这个概念和我们平时软件模型中和数据库打交道的Model实例比较接近,唯一不同的是DDD中这些实体会包含与该实体相关的业务逻辑,它是操作行为的载体。
值对象
依附于实体存在,通过对象属性来识别的对象,它将一些相关的实体属性打包在一起处理,形成一个新的对象。
举个栗子:比如用户实体,包含用户名、密码、年龄、地址,地址又包含省市区等属性,而将省市区这些属性打包成一个属性集合就是值对象。
聚合
实体和值对象表现的是个体的能力,而我们的业务逻辑往往很复杂,依赖个体是无法完成的,这时候就需要多个实体和值对象一起协同工作,而这个协同的组织就是聚合。聚合是数据修改和持久化的基本单元,同一个聚合内要保证事务的一致性,所以在设计的时候要保证聚合的设计拆分到最小化以保证效率和性能。
划分原则
生命周期一致性
这个对象如果离开本聚合的上下文,是否还有单独存在的价值
问题域一致性
场景频率一致性
如果一个对象在不同场景下都会被使用,应该考虑把它们分到不同的聚合中
聚合内的元素尽可能少
聚合根
聚合中最重要的一个实体对象,它是聚合的管理者,代表聚合的入口,抓住聚合根可以抓住整个聚合。
领域服务
有些领域的操作是一些动词,并不能简单的把他们归类到某个实体或者值对象中。这样的行为从领域中识别出来之后应该将它声明成一个服务,它的作用仅仅是为领域提供相应的功能。
领域事件
在特定的领域由用户动作触发,表示发生在过去的事件。比如充值成功、充值失败的事件
界限上下文
一个单词或语句出现时确定其含义的设置”。简而言之,这意味着模型在边界内是有含义的,且每个上下文中都有不同的含义
属于解决方案空间,即我们将如何实施问题的解决方案
领域
代表组织所做的工作。例如零售或电子商务
子域
组织或组织内的业务部门。一个领域由多个子域组成
属于问题空间,即我们的业务要如何看待问题
模式
失血模型
模型中只有简单的get set方法,是对一个实体最简单的封装,其他所有的业务行为由服务类来完成
贫血模型
在失血模型基础之上聚合了业务领域行为,领域对象的状态变化停留在内存层面,不关心数据持久化
充血模型
在贫血模型基础上,负责数据的持久化
胀血模型
service都不需要,所有的业务逻辑、数据存储都放到一个类中
建模方法
用例分析
获取用例:提取领域规则描述
收集实体:定位实体,
添加关联:两个实体间用动词关联起来
添加属性:获取实体属性
模型精化:可选的步骤,可以用UML的泛华和组合来表达模型间的关系,同时可以做子领域的划分
四色建模
四色关注的是某个人的角色在某个地点的角色用某个东西的角色做了某件事情
事件风暴
简单来说就是谁在何时基于什么做了什么,产生了什么,影响了什么事情
架构分层
Application:包含事件注册、业务逻辑等
Domain:聚合、实体、值对象
InfraStructure:基础设施封装、数据库访问等
算法
分治
可以分解为子问题
子问题的解可以合并为原问题的解
子问题之间没有关联
动态规划
按顺序求解子问题
子问题之间有关联关系
最后一个子问题的解为原问题的解
解题步骤
穷举分析
确定边界
找出规律,确定最优子结构
写出状态转移方程
回溯
深度优先搜索
获取解空间的所有解
贪心
局部最优解能产生全局最优解
具备后无效性
分支界定
广度优先搜索
获取解空间的任意解
排序算法
冒泡排序
两两比较交换
选择排序
选一个数依次比较
插入排序
快速排序
选基准值,右边找比自己小的交换,再左边找比自己大的交换,直到两边相遇停止,然后相遇位置的值与基准值位置交换
堆排序
根据初始数组去构造初始堆(构建一个完全二叉树,保证所有的父结点都比它的孩子结点数值大)
每次交换第一个和最后一个元素,输出最后一个元素(最大值),然后把剩下元素重新调整为大根堆
归并排序
计数排序
分支主题
最短路径
dijkstra算法
Floyd算法
最小生成树
prim算法
kruskal算法
数据结构
bitmap
long数组进行存储,每个long是个word,分成lw直接存储数据和rlw存储跨度信息,低32存储跨了多少个空word,高32个存储后方有多少个连续lw
布隆过滤器
基于bitmap存储,通过计算多个hash值,通过比较多个hash值是否一致进行过滤,会出现误判,将实际不存在的值判定为已存在。
BST二叉搜索树
若左子树不空,则左子树上所有结点的值均小于它的根结点的值
若右子树不空,则右子树上所有结点的值均大于它的根结点的值
左、右子树也分别为二叉排序树
AVL平衡二叉树
左子树和右子树的深度之差(平衡因子)的绝对值不超过1,且它的左子树和右子树都是一颗平衡二叉树
红黑树
根节点是黑色
叶子节点是黑色
相邻节点不同为红色
从根节点到叶子节点的所有路径上的黑色节点数目相等
B树
非叶子节点的孩子个数超过 M-1 时要分裂,分裂时,将中间的key向上移植父节点
小于 M/2 - 1(向上取整) 时要合并,将最左边或者最右边的key向上移至父节点
B+树
B+树叶子结点保存数据节省空间,叶子结点形成有序链表范围查询更快
一致性hash
key跟hash值顺时针找到归属结点,通过虚拟结点解决不均衡问题,节点的增加退出只会影响部分数据
跳表
跳表是一个随机化的数据结构,实质是一种可以进行近似二分查找的有序链表。跳表在原有的有序链表上增加了多级索引,通过索引来实现快速查询
lsm树
类似于b树,LSM树原理把一棵大树拆分成N棵小树,它首先写入内存中,随着小树越来越大,内存中的小树会flush到磁盘中,磁盘中的树定期可以做merge操作,合并成一棵大树,以优化读性能
合并策略
size-tiered,每当某个尺寸的SSTable数量达到既定个数时,合并成一个大的SSTable
Leveled Compaction,将数据分成互不重叠的一系列固定大小的SSTable文件,再将其分层(level)管理,Level-L最多只能保存 10 L 个SSTable文件
函数式编程
特性
不可变数据、无副作用、引用透明
高阶函数
函数作为入参或返回值的函数
惰性求值
减少不必要的计算
柯里化
接受多个参数的函数转换成接受一个单一参数,并且返回接受余下参数的函数,参数可以复用,延迟运行
闭包
定义在一个函数内部的函数,外部函数调用内部函数的时候,内部函数叫做闭包
读取函数内部的变量、让变量始终保存在内存中
响应式编程
RxJava
Reactor
Flux 表示的是包含 0 到 N 个元素的异步序列
Mono 表示的是包含 0 或者 1 个元素的异步序列
CORS 请求
预检请求
预检请求是在发送实际的请求之前,客户端会先发送一个 OPTIONS 方法的请求向服务器确认,如果通过之后,浏览器才会发起真正的请求,这样可以避免跨域请求对服务器的用户数据造成影响
Origin 表示请求来自哪个源
Access-Control-Request-Method 告诉服务器实际请求方法
Access-Control-Request-Headers 告诉服务器使用header字段
服务端配置
Access-Control-Allow-Origin设置请求源是可以访问的
Access-Control-Allow-Methods 表示服务器允许客户端发起请求方法
Access-Control-Allow-Headers 表示服务器允许请求中携带header字段
Access-Control-Max-Age 表示该响应的有效期,单位为秒
Access-Control-Allow-Credentials支持跨域请求携带cookie
简单请求
GET、POST、HEAD,请求头 Content-Type 为:text/plain、multipart/form-data、application/x-www-form-urlencoded 的就属于 “简单请求” 不会触发 CORS 预检请求
非简单请求
Content-Type 为 application/json 就会触发 CORS 预检请求
安全
跨站攻击
CSRF
防御
Token 验证
Referer 验证
(Cross-site request forgery):跨站请求伪造
XSS
(Cross Site Scripting):跨域脚本攻击
防御
对用户输入的数据进行HTML Entity编码
过滤
使用DOM Parse转换,校正不配对的DOM标签
mica-xss
<dependency>
<groupId>net.dreamlu</groupId>
<artifactId>mica-core</artifactId>
<version>2.0.9-GA</version>
</dependency>
<dependency>
<groupId>net.dreamlu</groupId>
<artifactId>mica-xss</artifactId>
<version>2.0.9-GA</version>
</dependency>
HTTP协议
HTTP1.1
高延迟 — 队头阻塞(Head-Of-Line Blocking)
无状态特性 — 阻碍交互
明文传输 — 不安全性
不支持服务端推送
管线化
类似批量请求和相应
组成部分
请求行:包含请求方法、URI、HTTP版本信息
请求头
请求头和请求正文之间是一个空行,它表示请求头已经结束
请求内容实体
通用首部
Cache-Control 控制缓存的行为
Connection 逐跳首部、连接的管理
Date 创建报文的日期时间
Pragma 报文指令
Trailer 报文末端的首部一览
Transfer-Encoding 指定报文主体的传输编码方式
Upgrade 升级为其他协议
Via 代理服务器的相关信息
Warning 错误通知
请求首部
Accept 用户代理可处理的媒体类型
Accept-Charset 优先的字符集
Accept-Encoding 优先的内容编码
Accept-Language 优先的语言(自然语言)
Authorization Web认证信息
Expect 期待服务器的特定行为
From 用户的电子邮箱地址
Host 请求资源所在服务器
If-Match 比较实体标记(ETag)
If-Modified-Since 比较资源的更新时间
If-None-Match 比较实体标记(与 If-Match 相反)
If-Range 资源未更新时发送实体 Byte 的范围请求
If-Unmodified-Since 比较资源的更新时间(与If-Modified-Since相反)
Max-Forwards 最大传输逐跳数
Proxy-Authorization 代理服务器要求客户端的认证信息
Range 实体的字节范围请求
Referer 对请求中 URI 的原始获取方
TE 传输编码的优先级
User-Agent HTTP 客户端程序的信息
响应首部
Accept-Ranges 是否接受字节范围请求
Age 推算资源创建经过时间
ETag 资源的匹配信息
Location 令客户端重定向至指定URI
Proxy-Authenticate 代理服务器对客户端的认证信息
Retry-After 对再次发起请求的时机要求
Server HTTP服务器的安装信息
Vary 代理服务器缓存的管理信息
WWW-Authenticate 服务器对客户端的认证信息
实体首部
Allow 资源可支持的HTTP方法
Content-Encoding 实体主体适用的编码方式
Content-Language 实体主体的自然语言
Content-Length 实体主体的大小(单位:字节)
Content-Location 替代对应资源的URI
Content-MD5 实体主体的报文摘要
Content-Range 实体主体的位置范围
Content-Type 实体主体的媒体类型
Expires 实体主体过期的日期时间
Last-Modified 资源的最后修改日期时间
HTTP2
二进制分帧 - HTTP2 性能增强的核心
多路复用 - 解决串行的文件传输和连接数过多
多路复用 — 解决队头阻塞
头部压缩 — 解决巨大的 HTTP 头部
使用了HPACK(HTTP2头部压缩算法)压缩格式对传输的header进行编码,减少了header的大小。并在两端维护了索引表,用于记录出现过的header,后面在传输过程中就可以传输已经记录过的header的键名,对端收到数据后就可以通过键名找到对应的值
请求优先级 — 先获取重要数据
服务端推送 — 填补空缺
提高安全性
QUIC
改进的拥塞控制、可靠传输
快速握手
集成了 TLS 1.3 加密
多路复用
连接迁移
HTTPS
客户端:发送随机数A、协议版本、加密算法
服务端:确定加密算法、数字证书、随机数B
客户端:确认数字证书是否有效、生成随机数C、使用服务器的公钥加密随机数C
根据随机数A、B、C和相同的算法生成对称密钥进行加密通信
Server使用对称密钥加密“明文内容A”,发送给Client
Client使用对称密钥解密响应的密文,得到“明文内容A”
HTTP方法
HEAD
不返回报文主体部分,用于确认URI 的有效性及资源更新的日期时间等
OPTIONS
查询针对请求 URI 指定的资源支持的方法
CONNECT
实现用隧道协议进行 TCP 通信。主要使用 SSL(Secure Sockets Layer,安全套接层)和 TLS(Transport Layer Security,传输层安全)协议把通信内容加 密后经网络隧道传输
MQTT协议
结构
固定头
数据包类型
CONNECT:客户端连接到MQTT代理
CONNACK:连接确认
PUBLISH:新发布消息
PUBACK:新发布消息确认,是QoS 1给PUBLISH消息的回复
PUBREC:QoS 2消息流的第一部分,表示消息发布已记录
PUBREL:QoS 2消息流的第二部分,表示消息发布已释放
PUBCOMP:QoS 2消息流的第三部分,表示消息发布完成
SUBSCRIBE:客户端订阅某个主题
SUBACK:对于SUBSCRIBE消息的确认
UNSUBSCRIBE:客户端终止订阅的消息
UNSUBACK:对于UNSUBSCRIBE消息的确认
PINGREQ:心跳
PINGRESP:确认心跳
DISCONNECT:客户端终止连接前优雅地通知MQTT代理
标识位
DUP:发布消息的副本。用来在保证消息的可靠传输,如果设置为1,则在下面的变长中增加MessageId,并且需要回复确认,以保证消息传输完成
QoS:发布消息的服务质量
级别0:尽力而为。消息发送者会想尽办法发送消息,但是遇到意外并不会重试。
级别1:至少一次。消息接收者如果没有知会或者知会本身丢失,消息发送者会再次发送以保证消息接收者至少会收到一次,当然可能造成重复消息。
级别2:恰好一次。保证这种语义肯待会减少并发或者增加延时,不过丢失或者重复消息是不可接受的时候,级别2是最合适的。
RETAIN: 发布保留标识,表示服务器要保留这次推送的信息,如果有新的订阅者出现,就把这消息推送给它,如果设有那么推送至当前订阅者后释放
剩余长度
可变头
2字节的数据包标识字段
消息体
CONNECT,消息体内容主要是:客户端的ClientID、订阅的Topic、Message以及用户名和密码
SUBSCRIBE,消息体内容是一系列的要订阅的主题以及QoS
SUBACK,消息体内容是服务器对于SUBSCRIBE所申请的主题及QoS进行确认和回复
UNSUBSCRIBE,消息体内容是要订阅的主题
特点
精简,不添加可有可无的功能。
发布/订阅(Pub/Sub)模式,方便消息在传感器之间传递。
允许用户动态创建主题,零运维成本。
把传输量降到最低以提高传输效率。
把低带宽、高延迟、不稳定的网络等因素考虑在内。
支持连续的会话控制。
理解客户端计算能力可能很低。
提供服务质量管理。
假设数据不可知,不强求传输数据的类型与格式,保持灵活性。
json处理
fastjson
默认不会输出null值的属性
日期格式化注解
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
gson
默认不会输出null值的属性
日期格式代码
new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create()
jackson
默认会输出null值的属性
日期格式化注解
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
研发效能
需求交付路径
已确认并拆分的需求
排期
及时完成排期
超时完成排期
超时未排期
开发
及时完成开发并转测
超时完成开发并转测
开发已超时
测试
及时完成测试和缺陷修复
超时完成测试和缺陷修复
测试已超时
交付
按时交付
未按时交付
需求取消
分析模型
维度
A(Activity)需求的近期活跃度(相关事件频率)
I(Importance)需求的重要程度(优先级、距离计划完成的剩余时间)
W(Workload)需求关联的已投入开发工作量(譬如代码修改行数)
分支主题
0 条评论
下一页