MVC
SpringWeb项目结构推荐
- model:模型
- po(entity):数据库表结构类
 - dao(mapper or orm):数据库单表访问类
 - dal(use multiple dao):数据库多表访问层
 - bo(business):业务数据类
 - co(common):通用数据类
 - vo(view):视图数据类(后端生成网页时使用)
 - dto(transfer):传输数据类(前后端交互时使用,分为请求和响应)
 
 - view:视图
 - controller:控制器
 - service:业务逻辑实例类
 - manager:通用逻辑实例类
 - helper:业务逻辑静态类
 - utils:通用逻辑静态类
 
请求处理模型
JavaWeb三大组件
- Servlet
 - Filter
 - Listener
 
Servlet
Filter
Listener
请求流程描述
- web容器接收到请求后解析成Request对象
 - web容器将所有请求交给DispatcherServlet处理
 - DispatcherServlet通过HandlerMapping获取Handler
 - 通过相应的适配类HandlerAdapter调用Handler的处理方法处理请求并返回ModelAndView
 - 根据返回的ModelAndView选择一个适合的ViewResolver
 - ViewResolver结合Model和View渲染视图
 - 将结果放到Response对象中返回给web容器
 
请求过滤拦截
- Filter(过滤器)和Interceptor(拦截器)对比入门
 - Filter(过滤器)和Interceptor(拦截器)对比进阶
 - Filter(过滤器)和Interceptor(拦截器)对比详解
 - Filter(过滤器)、Interceptor(拦截器)、AOP对比入门
 - Filter(过滤器)、Interceptor(拦截器)、AOP对比进阶
 - Filter(过滤器)、Interceptor(拦截器)、AOP对比详解
 - Filter(过滤器)、Interceptor(拦截器)、Advice、AOP执行顺序
 - Filter(过滤器)之多个Filter的顺序
 - Interceptor(拦截器)之多个Interceptor的顺序
 - Filter(过滤器)之如何正确的使用依赖注入
 - Interceptor(拦截器)之如何正确的使用依赖注入
 
主要区别如下
- 使用范围不同:Filter是Servlet规范,只能用于web应用,Interceptor是Spring的规范,还可以用于非web应用
 - 拦截时机不同:Filter在进入Servlet之前,Interceptor在进入Servlet之后且进入Controller之前
 
执行顺序如下
- Filter(过滤器)
 - Servlet(DispatcherServlet)
 - Interceptor(拦截器)
 - Advice(通知)
 - Aop(切面)
 - Controller(控制器)
 
使用场景如下
- 认证鉴权
 - 日志记录
 - 耗时统计
 
Filter(过滤器)
- init:容器启动的时候执行一次
 - doFilter:每次请求和响应时都会执行
 - destroy:容器停止的时候执行一次
 
ps:Filter可以访问request和response,不能访问controller
ps:FilterChain.doFilter之前的代码在请求的时候执行
ps:FilterChain.doFilter之后的代码在响应的时候执行
Interceptor(拦截器)
- preHandle:Controller调用之前执行
 - postHandle:Controller调用之后且视图渲染之前执行
 - afterCompletion:视图渲染之后执行
 
ps:Interceptor可以访问request和response,还可以访问controller和modelAndView
Advice(通知)
ps:切面可以通过RequestContextHolder访问request和response
AOP(切面)
ps:AOP可以通过RequestContextHolder访问request和response,还可以通过JoinPoint访问方法参数
Controller
Controller包含多个Handler,Controller里的每个方法都是一个Handler
Request
RequestEntity包含
- 请求头(@RequestHeader)
 - 请求体(@RequestBody)
 
Route
Param
- 参数名称
 - 参数个数
- 单个参数
 - 多个参数
 
 - 参数类型
- 基本类型
 - 对象类型
 - 容器类型
- Map
 - Array/List/Set
 
 
 
Pass
- Method
- GET
 - POST
 
 - MIME
- x-www-form-urlencoded(Post form type)
 - multipart/form-data(Post form type)
 - application/json(Post json type)
 
 - Type 
- 基本类型
 - 对象类型
 - 容器类型
- Map
 - Array/List/Set
 
 
 
Method
MIME
- SpringMVC之参数传递方式之MIME
 - SpringMVC之参数传递方式之MIME和Post请求
 - SpringMVC之参数传递方式之MIME的application/json
 - SpringMVC之参数传递方式之MIME的application/x-www-form-urlencoded
 - SpringMVC之参数传递方式之MIME的multipart/form-data
 - SpringMVC之参数传递方式之MIME的multipart/form-data与application/x-www-form-urlencoded的区别
 - SpringMVC之参数传递方式之MIME和form的enctype
 
Type
Fetch
- SpringMVC之参数获取来源入门
 - SpringMVC之参数获取来源详解
 - SpringMVC之参数使用方式入门
 - SpringMVC之参数使用方式详解
 - SpringMVC之参数名称
 - SpringMVC之参数默认值
 - SpringMVC之Attribute和Parameter的区别入门
 - SpringMVC之Attribute和Parameter的区别进阶
 - SpringMVC之Attribute和Parameter的区别详解
 - SpringMVC之Request和RequestScope的区别
 - SpringMVC之RequestScope和SessionScope入门
 - SpringMVC之RequestScope和SessionScope详解
 - SpringMVC之RequestScope和SessionScope原理
 - SpringMVC之forward和Redirect的区别
 - SpringMVC之request.setAttribute()和session.setAttribute()的区别
 - SpringMVC之request.setAttribute()和model.addAttribute()的区别
 
Attribute和Parameter的来源
- Request
 - Session
 - Model
 
Attribute和Parameter的获取
- HttpServletRequest:可以获取Parameter和Attribute
 - HttpSession:可以获取Attribute
 - Model:可以获取Attribute
 
Attribute和Parameter的区别
- Attribute:由后端生成,可以存在Request、Session和Model中
 - Parameter:由前端生成,只存在Request中,可以自行添加到Session和Model中
 
Attribute和Parameter的范围
- Request:Request范围
 - Session:Session范围
 - Model:Request范围
 
ps:Request范围的数据只能被该请求单独访问,Session范围的数据可以多个请求共享访问
ps:Model的Attribute是Request范围的,如果要在Session范围内使用Model的Attribute,可以使用@SessionAttributes注解将Model的Attribute转到Session的Attribute中
Attribute和Parameter的传递
- Attribute:转发后的页面可以访问Request和Session范围的,重定向后的页面可以访问Session范围的
 - Parameter:转发后的页面不可以访问,GET重定向的页面可以访问(因为浏览器会携带参数重新请求)
 
Parameter
Attribute
Attribute相关注解的作用
- @RequestAttribute:从HttpRequest中获取Attribute
 - @SessionAttribute:从HttpSession中获取Attribute
 - @ModelAttribute:从Model中获取Attribute或者将方法的返回值存入Model中
 - @SessionAttributes:将Model里面的Attribute存到Session域中(Model的有效范围默认是Request域的)
 
ps:@SessionAttributes和@SessionAttribute之间差一个
s,但作用不同
Model
Model的作用是将数据传递给视图进行渲染,比Request和Session更符合MVC规范
ps:视图获取参数时建议使用哪个Model,也可以使用Request和Session,因为在使用Model时可以更加优雅的通过
${param}的方式取值
Header
Cookie
Session
Response
ResponseEntity包含
- 响应头(ResponseHeader)
 - 响应体(@ResponseBody)
 - 响应状态(@ResponseStatus)
 
ps:ResponseEntity的优先级比@ResponseBody高
Result
Status
Header
Cookie
View
Exception
- 参数校验异常
 - 数据访问异常(mysql、redis)
 - 业务处理异常
 
Context
Invalid
Validation
Annotation
@Validated和@Valid的区别
- @Validated是spring的注解,@Valid是java的注解
 - @Validated不支持标注字段,@Valid支持标注字段
 - @Validated不支持嵌套校验,@Valid支持嵌套校验
 - @Validated支持分组校验,@Valid不支持分组校验
 
Exception
MethodArgumentNotValidException和ConstraintViolationException的区别
- BindException:表单请求数据绑定到参数出错时抛出的异常
 - MethodArgumentNotValidException:使用@Valid和@Validated注解标注的方法参数校验失败时抛出的异常
 - ConstraintViolationException:使用@NotNull等注解直接标注的方法参数校验失败时抛出的异常
 
Assertion
Converter
Date
Enum
Json
- Jackson详解
 - Jackson注解入门
 - Jackson注解详解
 - Jackson之字段映射
 - Jackson之依赖Getter-Setter反射方法
 - Jackson之配置为依赖字段反射
 - Jackson之处理is开头的字段
 - Jackson之@JsonProperty和@JsonAlias详解
 - Jackson之@JsonFormat处理date和enum
 - Jackson之@JsonValue处理enum
 - Jackson之TypeReference详解
 - Jackson之自定义序列化和反序列化
 - Spring之ResolvableType详解
 - Spring之Jackson配置
 - JsonPath详解
 - jq详解
 
CORS
CORS:CrossSite(跨域)
- 全局
- WebMvcConfigurer
 - CorsFilter
 - 自定义Filter添加响应头(Access-Control-Allow-Origin)
 
 - 局部
- @CrossOrigin
 - 手动在响应里面添加响应头(Access-Control-Allow-Origin)
 
 
Auth
登录跳转实现方案
- 后端实现
- 跳首页:返回302(浏览器负责实现跳转)
 - 跳当前页:返回302 + 前端将当前页地址存到sessionStorage中、返回302 + 前端请求时每次将当前页地址放到
自定义header或者参数中传给后端(不推荐这个方案) 
 - 前端实现
- 跳首页:返回401(前端负责实现跳转)
 - 跳当前页:返回401 + 前端将当前页地址存到sessionStorage中
 
 
Service
- Service:
业务逻辑实例类 - Manager:
通用逻辑实例类 - Helper:
业务逻辑静态类 - Utils:
通用逻辑静态类 
Model
POJO
*+ po(entity):数据库表结构类
- dao(mapper or orm):数据库单表访问类
 - dal(use multiple dao):数据库多表访问层
 - bo(business):业务数据类
 - co(common):通用数据类
 - do(domain):领域数据类
 - vo(view):视图数据类(后端生成网页时使用)
 - dto(transfer):传输数据类(前后端交互时使用,分为请求和响应)
 
Transform
View
Jsp
Thymeleaf
spel:Spring Expression Language
Freemarker
Web
Protocol
Http
RPC
RPC是远端过程调用,调用协议通常包含
- 序列化协议
- Xml
 - Json
 - Bin
- Hessian(比较早期的框架)
 - MessagePack(Json格式的优化版)
 - Protobuf(Google出品的框架)
 - Thrift(FaceBook出品的框架)
 - Avro(Hadoop的一个子项目)
 - Kyro(针对java的二进制协议)
 - Fct(针对java的二进制协议)
 
 
 - 传输协议
- TCP
 - HTTP
 
 
ps:RPC的传输协议可以使用TCP来实现,也可以使用Http来实现
RPC框架
- Dubbo(Ali)
 - Finagle(Twitter)
 - Thrift(Facebook)
 - grpc(Google)
 - brpc(Baidu)
 
WebSocket
WebSocket和Http对比
- 都是应用层协议
 - WebSocket支持双向通信,Http只支持单向通信
 
WebSocket和Socket对比
- WebSocket是应用层协议,Socket是传输层协议的封装
 - Socket比较原始,WebSocket则是在应用层面对于Socket的进一步封装
 
Specification
Restful(Web API)
SOAP(Web Service)
Reliability
Exception
Retry
Idempotent
幂等和去重的区别
- 幂等:是一种概念,操作执行多次的结构都是一样的
 - 去重:是一种方案,操作只会执行一次
 
ps:去重是实现幂等的一种方案(如果操作本身就是支持幂等的就不需要去重)
如何实现幂等
- 请求
- token令牌
 
 - 数据
- 插入操作
- 去重表(mysql)
- 直接插入 + 唯一约束:适合有唯一约束的
- 使用
insert into检测到插入失败(DuplicateKeyException)后换一个主键重试 - 使用
insert ignore into检测到插入失败后换一个主键重试 
 - 使用
 - 检测插入 + 加锁控制:适合没有唯一约束的
- 使用
select for update检测到重复后换一个主键重试 
 - 使用
 
 - 直接插入 + 唯一约束:适合有唯一约束的
 - 去重表(redis)
- setnx
 
 
 - 去重表(mysql)
 - 更新操作
- 状态机 + CAS思想
 - 版本号 + CAS思想
- 计数
 - 时间戳
 
 
 
 - 插入操作
 
ps:去重时还可以使用布隆过滤器来优化去重的效率
ps:数据库的插入和更新都会主动加锁,所以不需要额外加锁
幂等和去重都需要唯一标识
唯一标识来源
- 业务id(身份证号、手机号、设备指纹)
 - 逻辑id(发号器生成)
- 顺序id
 - 随机id
 
 
唯一标识实现
- 单机
- 顺序id
- mysql自增id
 - 时间戳
 
 - 随机id
- UUID
 
 
 - 顺序id
 - 分布式
- 顺序id
- mysql发号器
 - redis发号器
 
 - 随机id
- UUID
 - SnowflakeId
 - MongodbId
 
 
 - 顺序id
 
Repeat
如何防止重复提交
- 前端
- 进入页面时向后端请求一个去重token放入隐藏域中
 - 点击提交按钮后立即禁用提交按钮
 - 点击提交按钮后显示加载中或者跳转到其他页面
 
 - 后端
- 取出前端提交的去重token
 - 如果token存在,则执行正常逻辑,并销毁去重token
 - 如果token不存在,则执行去重逻辑,即丢弃重复的请求
 
 
防抖和节流的区别
- 防抖:debounce,延时后只执行一次,用于防止操作过快(操作的时间间隔短)
 - 截流:throttle,周期内只执行一次,用于防止操作过多(操作的触发频率高)
 
ps:防抖中再次触发时,会重置延时计时器和取消上一次的延时操作
ps:截流是限流的一种方式
Performance
- 缓存加速
- 本地缓存
 - 集中缓存
 
 - 异步处理
- 子线程(多线程)
 - 消息队列
 
 - 并行处理
- 分解任务并进行并行处理
 
 - 批量处理
- 聚合任务并进行批量处理
 
 - 池化技术
 
异步处理时获取任务结果
- 轮询
 - 回调(回调机制,耦合)
 - 监听(发布和订阅,不耦合)
 
系统三高
- 高性能:每次请求的处理时间越短越好
 - 高并发:同时支持的请求数量越多越好
 - 高可用:集群或分布式系统中部分服务节点故障也不影响整体服务(备份机制)
 
性能模型
- CPU密集型:需要CPU进行大量的处理,例如数学计算、加密解密、编码解码、压缩解压、正则表达式搜索
 - IO密集型:大部分的时间CPU都在等IO(内存、磁盘、网络),例如WEB服务、爬虫
 
性能指标
服务性能指标
关键概念
- RT:响应时间(Response Time),实际包含请求时间(Request Time)、处理时间(Handle Time)、响应时间(Response Time)
 - ART:平均响应时间(Average Response Time),描述的是响应时间的平均值
 - HPS:每秒点击量(Hit Per Second),描述的
客户端每秒点击量 - RPS:每秒请求量(Request Per Second),描述的
客户端每秒请求量 - QPS:每秒查询量(Query Per Second),描述的是
查询系统的每秒查询量 - TPS:每秒事务量(Transaction Per Second),描述的是
业务系统的每秒事务量 - Concurrency:并发量,描述的
后端能够同时处理的请求数量(不是单位时间能处理的数量) - Latency:延迟,用户等待请求或事务从开始到完成的时间(ART)
 - Throughput:吞吐量,系统单位时间内处理请求(QPS)和事务(TPS)的数量
 
ps:一个事务可能会包含多个请求或者请求链
ps:前台交互型应用追求的是最低延迟,比如Web服务应用
ps:后台计算型应用追求的是最大吞吐量,比如大数据计算应用
延迟和吞吐量之间的关系
- 延迟和吞吐量之间没有必然的关系
 - 延迟变低(比如提高处理速度)可以提高吞吐量
 - 但是延迟变高(比如进行批量处理)也可以提高吞吐量
 
核心指标
- 平均响应时间(ART)
 - 并发量(Concurrency)
 - QPS
 
QPS = Concurrency / ART(单位通常是毫秒,计算时需要换算成秒)
ps:QPS不是ART的倒数这种估算值,需要进行实测,因为处理请求时不止一个线程或进程
ps:而且ART不是一个固定的值,会受服务器资源(cpu、mem、disk、net)的状态影响
ps:因为ART不可调,所以可以不断增大Concurrency直到QPS开始下降来测出QPS的最大值
网络性能指标
- RTT:往返时间(Round-Trip Time),表示从发送端发送数据开始,到发送端收到来自接收端的确认(接收端收到数据后便立即发送确认,不包含数据传输时间)
 - Latency:时延,是一个描述
网络延迟时间的概念,包含RTT这个核心指标 
业务评价指标
- PV:单个页面访问量(Page View)
 - UV:独立用户访问量(Unique Visitor)
 - DAU:日活(Daily Active User)
 - MAU:月活(Month Active User)
 - GMV:总商品价值量(Gross Merchandise Volume)
 
Container
- Tomcat
 - Netty(WebFlux)
 - Jetty
 - Undertow
 
Tomcat
Client
- Http请求库选型
 - Http请求库演进
 - HttpClient详解
 - OkHttp入门
 - OkHttp进阶
 - OkHttp详解
 - Retrofit详解
 - Forest详解
 - RestTemplate详解
 - RestTemplate集成HttpClient和OkHttp
 - RestClient详解
 - WebClient详解
 - OkHttp和HttpClient对比
 - Retrofit和OkHttp对比
 - Forest和Retrofit对比
 - WebClient和RestClient和RestTemplate对比
 - Dubbo和OpenFeign和Feign对比
 - RestTemplate和Retrofit对比
 - Feign和Retrofit对比
 - Spring声明式HTTP Interface
 
客户端的分类
- 客户端的调用方式可以分为 
编程式调用和声明式调用 - 客户端的请求方式可以分为 
同步请求和异步请求 - 客户端的请求协议可以分为 
Http请求和RPC请求 
客户端的实现
- HttpClient:Apache组织出品的较早的Http请求库,支持
编程式调用 - OkHttp:Square公司出品的较新的Http请求库,支持
编程式调用 - Retrofit:Square公司出品的较新的Http请求库,基于OkHttp和RxJava,支持
声明式调用 - Forest:开源的轻量级Http请求库,基于OkHttp和RxJava,支持
声明式调用 - RestTemplate:Spring中使用,可以适配多种Http请求库,支持
编程式调用 - RestClient:Spring中使用,新一代的同步Http请求库,支持
编程式调用 - WebClient:Spring中使用,新一代的异步Http请求库,支持
编程式调用 - Feign:SpringCloud中使用,支持负载均衡的Http请求库,支持
声明式调用 - OpenFeign:SpringCloud中使用,支持负载均衡的Http请求库,支持
声明式调用 - Dubbo:SpringCloud中使用,支持负载均衡的RPC请求库,支持
声明式调用 
ps:OpenFeign是Spring对Feign支持SpringMVC的封装,可以使用SpringMVC的注解
Logging
Library
log4j2
logback
Optimize
Placeholder
Judgement
Question
Problem
Adapter
Specification
Category
Event
事件日志:程序的运行日志
- 事件信息(what)
 - 事件时间(when)
 - 事件来源(who)
 - 事件位置(where):比如线程名、记录器名称、模块名、方法名、代码行
 - 事件标签(tag):比如事件属性、输入参数
 
Action
操作日志:用户的行为日志
- 操作信息(what)
 - 操作时间(when)
 - 操作者(who)
 - 操作资源(resource):资源名称和资源id
 - 操作变化(change):资源变化前和变化后的状态
 
Trace
链路日志:服务的调用日志
Testing
Framework
Unit Test
- Junit5使用了Extend机制(@ExtendWith),可以支持多个Extend
 - Junit4使用了Runner机制(@RunWith),只能支持一个Runner