1. 计算机网络
- OSI七层架构和TCP五层架构
- OSI:应用、表示、会话、传输、网络、数据链路、物理
- TCP:应用(报文)、传输(报文段)、网络(分组)、数据链路(帧)、物理(比特)
- TCP五层对应的协议
- 应用层:为用户提供交互应用服务。DNS、HTTP、STMP
- 传输层:在两台主机之间进行通信传输数据。TCP、UDP
- 网络层:选择合适的路由和交换节点。IP
- 数据链路层:在两个相邻节点传输帧
- 物理层:在相邻节点间传输比特
- TCP和UDP的区别
-
TCP是面向连接的、可靠的、传输字节流、传输效率慢
- TCP通过三次握手建立连接,确保双方能正常收发数据
- TCP通过四次挥手断开连接,确保双方都已经完成收发并且数据已经被成功接收后才断开连接
- 可靠性:通过确认、超时重传、流量控制、拥塞控制等机制确保传输数据的可靠性,即数据传输不丢包、数据无错误、数据顺序正确、不重传
- 应用:文件传输(FTP)、发送邮件(STMP)
-
UDP是无连接、不可靠的、传输数据报文段、传输效率高
- 不需要建立连接也不需要断开连接
- 传输数据只管发送不管是否成功接收,效率高
- 应用:发送语音、直播、视频
-
- TCP如何保证可靠传输
确认:接收方的确认报文ack约定发送方下一个报文的头部。比如发送方发送报文123,接收方回应ack报文约定发送方下一个报文的头部必须是4。如果发送方的下一个报文的头部不为4,接收方可以要求发送方重发报文
超时重传:发送方发送了一个报文后,如果超过一段时间都没有收到接收方的确认报文,会重发这个报文
流量控制:如果发送方发送数据太快,会导致接收方来不及接收数据导致数据丢包。通过滑动窗口进行流量控制,接收方收到数据后,根据自身缓冲区的大小,将剩余窗口的大小通过确认报文返回给发送方,发送方根据这个窗口大小确定下一次发送数据的长度
-
拥塞控制:也是基于滑动窗口实现,但是是发送方根据当前网络环境自己估算窗口大小
- 慢开始:一开始窗口大小为1,如果网络好,大小呈指数增长
- 拥塞避免:因为是呈指数增长,当窗口大小达到阈值时,开始呈线性增长。当出现网络拥塞时,窗口大小降为1,重新开始慢开始
- 快重传:当发送方接收到三个重复的确认报文后,无需等待,直接重传下一个报文
- 快恢复:窗口大小降为快重传发生时的1/2
- 三次握手、四次挥手
-
三次握手:假设发送方为客户端,接收方为服务端
- 客户端向服务端发起建立连接请求,客户端生成一个序列号seq=x,将标志位SYN=1和序列号seq=x发送给服务器端。此时客户端状态为SYN_SENT,服务端状态为LISTEN
- 服务端收到客户端的报文后,服务端生成一个序列号seq=y,将标志位SYN=1,序列号seq=y,确认报文ACK=1,确认号ack=x+1发送给客户端。此时客户端状态为SYN_SENT,服务端状态为SYN_RECV
- 客户端收到服务端的报文后,客户端生成序列号seq=x+1,将标志位ACK=1,序列号seq=x+1,确认号ack=y+1发送给服务端。此时客户端状态为ESTABLISHED,服务器收到报文后,状态也为ESTABLISHED
-
四次挥手
- 当客户端发送完报文后,客户端向服务端发送终止报文(标志位FIN=1,序列号seq=u),客户端进入FIN_WAIT1状态
- 服务端收到终止报文,服务端向客户端发送确认报文(标志位ACK=1,序列号seq=v,确认号ack=u+1),服务端进入CLOSE_WAIT状态
- 服务端此时还会继续发送剩余的未发送的数据,当数据发送完后,服务端向客户端发送终止报文(标志位FIN=1,标志位ACK=1,序列号seq=w,确认号ack=u+1),服务端进入LAST_ACK状态
- 客户端收到服务端的终止报文后,向服务端发送确认报文(标志位ACK=1,序列号seq=u+1,确认号ack=w+1),客户端进入TIME_WAIT状态,等待2MSL时间后,客户端进入CLOSE状态,当服务端收到客户端的确认报文后,服务端也进入CLOSE状态,服务端早于客户端进入CLOSE状态
-
- 为什么是三次握手,两次是否可以
- 假设只有两次握手,那么如果第二次握手的时候,服务端返回给客户端的确认报文丢失了,客户端没有收到确认报文,认为没有建立连接,但是服务端把报文发送出去了,认为已经建立了连接,但是实际连接是没有成功建立
- 假设只有两次握手,那么第一次客户端发送的请求建立连接的报文没有丢失,而是因为超时重传,后面又发送了一次,如果只有两次握手,当服务端收到请求建立连接的报文后,又会建立另一个连接,但是这个连接不会进行数据传输
- 为什么连接的时候是三次,断开连接却要四次
- 当服务端收到客户端的终止报文后,回复确认报文之后,服务端要将剩余的数据继续发送完才会发送终止报文给客户端,这样能保证数据传输的完整
- 为什么第四次挥手时发出的确认报文要等到2MSL时间才能释放TCP连接
- 因为MSL是报文在传输时存活的最长时间,当第四次挥手时客户端发送的确认报文达到服务端,服务端再返回确认报文,最长时间就是2MSL,如果超过2MSL还没有收到服务端返回的确认报文,就说明客户端发送的报文丢失了,要重传,否则服务端无法关闭连接
- HTTP和HTTPS
- HTTP端口80,HTTPS端口443
- HTTP无加密,HTTPS通过数字证书进行加密
- HTTP基于TCP协议,传输明文内容。HTTPS基于SSL协议,传输加密数据
- HTTP的请求有哪些:GET、POST、DELETE、PUT
- PUT:上传文件
- DELETE:删除文件
- POST:提交数据,修改
- GET:获取数据,查询
- HTTP状态码:200——成功、404——找不到、500——服务端错误
- HTTP1.0、HTTP1.1、HTTP2.0(长连接和短连接)
- 1.0默认采用短连接,每次传输数据都要通过三次握手建立TCP连接,数据传输完毕后就通过四次挥手断开连接
- 1.1采用长连接,在一个TCP连接存活的keepAlive时间里,可以多次使用该连接传输数据
- HTTP请求过程(从网址栏输入URL到显示主页的过程)
- 对输入的url进行DNS解析,将域名转换为IP地址
- 和目标服务器建立TCP连接
- 向目标服务器发送HTTP请求
- 目标服务器处理请求并返回HTTP报文
- 浏览器解析并渲染页面
- HTTPS请求过程(HTTPS加密过程)
- 客户端和服务端经过三次握手建立连接后,客户端会发送一个请求给服务端,告诉服务端,客户端支持的SSL版本、加密算法和密钥长度
- 服务端将公钥发给数字证书机构,得到公钥证书,服务端将公钥证书发给客户端
- 客户端收到证书后先校验证书是否有效,然后生成对称密钥,将对称密钥发送给服务端
- 服务端收到对称密钥后,使用私钥进行解密
- 然后客户端跟服务端就可以通过对称加密进行通信
- 对称加密和非对称加密
- 对称加密:加密和解密使用同一个密钥,运算快,但是要安全将密钥传输给另一方,DES、AES
- 非对称加密:公钥加密的信息只能用私钥解密,私钥加密的信息只能用公钥解密。RSA
- 重定向和转发
- 重定向,是客户端行为,浏览器根据服务端返回的状态码(3xx),对重定向的URL重新发起HTTP请求,URL会发生变化,不能共享数据。可以用于用户注销后重定向到登录页面
- 转发,是服务端行为,URL不会发生变化,转发和被转发页面可以共享request请求头的数据。可以用于用户登录后将user数据转发到指定页面
- session、cookie、token
因为HTTP协议是无状态的,也就是客户端每次想要和服务端通信,都要重新建立连接。cookie、session、token都是为了校验用户
-
cookie:
- 流程:客户端请求服务端,服务端生成一个session,将sessionid设置到cookie,返回给客户端浏览器保存。
- 特点:大小在4KB左右,浏览器每次请求都会在请求头携带cookie
- 缺点:不安全,存放在浏览器,可以被查看
-
session
- 流程:客户端请求服务端,服务端生成一个session,保存到数据库,然后将sessionid设置到cookie,返回给客户端浏览器。下一次请求时,通过cookie存放的sessionid校验
- 特点:存放在服务端,存储空间大
- 优点:安全,存放在服务端
- 缺点:session相当于存了整个用户信息
-
token
- 流程:客户端请求服务端,服务端校验通过后,将用户id和其他一些信息进行加密,生成token,保存到缓存或者数据库,然后将token返回给客户端,客户端下一次请求时把token带上,服务端校验token是否通过
- 特点:体积小,是一段加密的字符
- 优点:安全,存放在服务端,且只存了用户id,可以通过缓存层实现不需要去数据库查询用户
- 如果客户端禁止cookie,session还能用吗
- 也可以,虽然session一般是通过将sessionid存放在cookie中实现的,但是如果cookie被禁用了,也可以将sessionid通过url传递,也能实现校验
- ping命令做了什么,是基于哪一层
- ping命令主要用来测试两台主机之间的连通性
- 原理:向目的主机发送请求报文,目的主机收到后发送回应报文,根据收发时间和成功响应的次数计算往返时间和丢包率
- 工作在网络层
2. 操作系统
- CPU占用过高排查
- top命令查看当前服务器的cpu、内存占用情况
- 输入P命令,查看CPU占用最高的进程
- top -H -p [进程id]:查看进程的线程
- printf "%x\n" [进程id],得到线程的16进制id
- jstack [进程id] | grep -A100 [线程id]
- 常用的Linux命令
- 查看目录:ls
- 当前路径:pwd
- 查看文件:cat
- 查看前50行:cat xx.log | head -n 50
- 查看后50行:cat xx.log | tail -n 50
- 查询文件:grep
- grep --c "xxx" xx.log
3. Spring:https://zhuanlan.zhihu.com/p/551246463
- Spring特点
- 轻量级:jar包
- 控制反转:通过IOC机制,将一个对象依赖的其他对象也会通过被动的方式加载到IOC容器,不需要对象自己创建或查找依赖对象
- 面向切面:AOP
- 容器:IOC容器管理IocBean
- Spring核心模块
- Spring-core核心包
- Spring-context上下文
- Spring-aop
- Spring-dao
- Spring-orm
- Spring-web
- Spring-mvc
- Spring注解
-
标记Bean相关注解
- @Component
- @Controller:控制层,标记一个类作为mvc控制器
- @Service:业务层,标记一个类作为服务类
- @Repository:持久层,标记一个类作为数据访问对象
- @Bean:在方法上使用,该方法要注册为上下文context中的bean
-
注入Bean相关注解
- @Autowired:由bean提供,按类型匹配,如果存在多个,再按名称匹配
- @Inject:由JSR-330提供,按类型匹配
- @Resource:由JSR-250提供,按名称匹配,如果存在多个,再按类型匹配
-
Java配置相关注解
- @Configuration:标记一个类为配置类
-
AOP相关注解
- @Aspect:标记一个类为切面类
- @Before:标记在方法上,在该方法执行之前执行
- @After:标记在方法上,在该方法执行之后执行
- @Around:标记在方法上,在该方法执行之前和执行之后执行
-
- Spring与第三方框架结合
- 权限:Shiro
- 缓存:Redis
- 持久化:Mybatis
- 什么是SpringIoc
- 也就是控制反转。我们可以把这个词拆开,分别看看控制什么,反转了什么
- 控制:控制对象的创建、管理、销毁,也就是控制了对象的生命周期
- 反转:传统方式下对象是通过new创建的,然后我们再通过使用实例对象操作,而Spring是通过一个Ioc容器,将对象初始化出来放到容器里,我们使用的时候不需要new对象,可以直接从容器中拿出即可使用
- 也就是控制反转。我们可以把这个词拆开,分别看看控制什么,反转了什么
- 什么是DI依赖注入
- 当bean之间存在依赖关系,ioc容器也会自动将依赖对象的实例进行注入,基于反射实现(newInstance、invoke method)
- 接口注入
- setter注入
- 构造器注入
- 当bean之间存在依赖关系,ioc容器也会自动将依赖对象的实例进行注入,基于反射实现(newInstance、invoke method)
- 什么是Bean:被Ioc容器管理的对象,一般可以通过application.xml配置文件或者使用注解将一个类标注为Bean
- 将一个类声明为bean的注解
- @Component:通用注解,如果一个类不知道被标记为哪个层,可以使用这个注解
- @Service:业务层,业务逻辑代码
- @Repository:持久层dao,操作数据库
- @Controller:mvc控制层,用于接收客户端请求并调度Service业务逻辑
- @Component和@Bean的区别
- @Component用于类,@Bean用在方法
- @Component是通过@ComponentScan注解扫描类路径自动装配到ioc容器的,@Bean则是告诉Spring这是某个类的实例,在需要使用时给我
- 当使用第三方库的类需要装配到Spring容器时,只能使用@Bean
- 注入Bean的注解有哪些
- @Autowired:spring提供
- @Inject:JSR-250
- @Resource:JSR-330
- @Autowired和@Resource的区别是什么
- @Autowired是spring内置的注解,默认根据bean的类型匹配,可配置@Qualifier指定bean的name根据名称匹配
- @Resource是JDK的JSR-330,默认根据bean的名称匹配,有name和type两个参数可以指定
- Bean的作用域
- Singleton:单例模式,在整个IOC容器中,只有一个Bean实例
- protoType:原型模式,也就是多例,每次通过getBean()获取Bean都会创建一个新的Bean实例
- request:每次HTTP请求,都会创建不同的Bean实例
- session:每次HTTP Session请求,都会创建不同的Bean实例
- global session:使用HTTP Session的都只有一个Bean实例
- Controller是singleton,因为一般不会在controller定义属性
- Bean的生命周期
- 实例化:对应传统方式的构造函数。通过XML配置文件、注解等方式,将定义好的Bean对象转换为BeanDefination对象,完成对Bean对象的解析和加载,通过反射机制newInstance()创建Bean对象
- 属性设置:对应传统方式的getter和setter方法。这阶段会进行依赖注入,将Bean对象依赖的其他Bean对象也加载到Ioc容器
- 初始化:AOP
- 调用aware接口相关方法,invokeAwareMethod()
- 调用BeanPostProcessor的前置处理方法
- 调用initMethod方法
- 调用BeanPostProcessor的后置处理方法
- 使用
- 销毁:调用destoryMethod()方法
- 什么是SpringAop
- 在传统方式下,进行事务管理,比如try/catch/finaly这些代码,或者在业务逻辑前后输出日志,要写重复的代码。aop就是为了简化这些重复代码而出现的概念
- 通过横向抽取的概念,把这些重复的代码抽取到一个切面,通过切面的切入,实现在不同类的方法中加入事务管理、日志打印等功能
- 业务场景
- 在CRUD操作中打印每个操作的开始和结束日志:@Before、@After
- 在CRUD操作出现报错时回滚操作:@AfterThrowing
- 在CRUD操作后关闭数据库连接:@After
- 统计CRUD操作的执行时长:@Around
- aop的两种代理方式:通过动态代理,使得在程序运行时可以动态添加新的逻辑和功能
JDK动态代理:当目标对象实现了一个接口时,使用JDK动态代理。通过newInstance()方法创建代理对象,通过invoke()方法插入额外的逻辑和功能,基于反射机制
CGLIB代理:当目标对象没有实现接口,使用CGLIB代理,基于字节码文件实现
- 什么是SpringMVC
- Model模型:负责数据的读取、操作、存储
- View视图:负责数据的展示,web页面
- Controller控制器:负责在Model和View之间进行数据传递
- SpringMvc核心组件
- DispatchServlet:前端控制器,负责统一处理前端的请求和将请求转发分配
- HandleMapping:将请求路径映射到对应的处理请求的控制器,使用@RequestMapping注解定义路径
- Controller:实际处理请求的控制器,对请求进行业务逻辑处理
- HanldeAdapter:负责将请求分派给控制器进行处理
- ViewResolver:负责将逻辑视图解析为实际的视图对象
- View:视图,负责渲染并展示最终的响应内容
- SpringMvc工作流程
- 前端请求发送到前端控制器DispatcherServlet
- DispatcherServlet收到请求后调用处理映射器HandlerMapping
- HandlerMapping根据映射的url路径找到对应的后端处理控制器Controller,将处理器对象返回给前端控制器DispatcherServlet
- DispatcherServlet再调用处理适配器HandlerAdapter调用对应的后端控制器Controller(这里才是真正执行后端的业务逻辑)
- Controller处理完之后,将ModelAndView结果返回给处理适配器HandlerAdapter
- HandleAdapter把ModelAndView返回给前端控制器DispatcherServlet
- DispatcherServlet再调用视图解析器ViewResolver解析ModelAndView
- ViewResolver将ModelAndView的解析结果返回给View
- View渲染并展示响应结果
-
SpringBoot的优点
- properties配置文件和yml配置文件使得项目的配置更简便
- 内置了TOMCAT
SpringBoot配置文件:properties文件和yml文件
-
SpringBoot核心注解
- @SpringBootConfiguration:启动类的注解
- @EnableAutoConfiguration:打开自动配置的功能
- @ComponentScan:Spring组件扫描。
4. Mybatis:(https://www.zhihu.com/people/zhao-yin-jing/posts)
- 注解实现动态SQL:(https://blog.csdn.net/qq_43494025/article/details/89791321)
- @Select(SQL)、@Insert(SQL)、@Update(SQL)、@Delete(SQL)
- 动态SQL:@SelectProvider(type="SQLProviderClass",method="SQLProviderMethod")
-
优点:
- 相比于JDBC,简化了代码,通过配置文件实现数据库连接,封装了JDBC加载驱动、创建连接等繁琐的复杂操作,只需要关注如何编写SQL语句
- 可以通过XML或者注解的方式来配置mapper映射
-
{}和${}的区别
-
{}是预处理,可以防止SQL注入,安全性高
- ${}是字符串替换
-
4. Nutz框架
- (Nutz的mvc流程)项目中如何通过type协议号,定位到对应的执行方法的(底层还是根据反射,先将facade方法注册到一个map里,key是type协议号,value是method方法,然后根据前端请求的参数type,从map中拿到对应的method,然后反射invoke执行方法,将方法执行结构的res返回)
起服时,在MessageDispatcher类中,扫包,检测使用了@Packet注解标注的Facade方法,都其标注的type协议号作为key,Method方法作为value,存入map中
当前端发送请求时,在MessageDispatcher类中,根据请求参数协议号type,从map拿到对应的Method,new MessageFacadeInvoker(msg, callback),将msg请求参数和Method方法交给MessageFacadeInvoker反射执行类
MessageFacadeInvoker类的run方法执行,调用handleMessage(reqMsg,MethodCallback)
在handleMessage()方法中,先执行methodCallback.handle()通过this.method.invoke()执行方法
根据方法执行返回的Res,填充本次请求的返回
-
NutzMvc
后台请求处理:https://blog.csdn.net/weixin_43358075/article/details/93999678-
OperModule后台web操作类
@IocBean
@At("/opt")
@Fail("void")
@Filters({ @By(type = DESDecryptFilter.class), @By(type = InvokeTimeFilter.class) })
public class OperateModule {@At("/recharge")
@Ok("json")
public WebResult recharge() {
...
}
} @IocBean:表明该类是IOC,会被解析到IOC容器,可通过@Inject注入其他IOC
@At:指定URL,类似@RequestMapping
@Fail:请求失败的返回
@Filters:指定过滤器,每个请求都要经过@By(type=filterClass)的过滤
@OK:请求成功后返回给客户端的数据类型
-
DESDecryptFilter过滤器:
- 客户端发送的param参数是一个用密钥加密后的参数
- 通过DESCoder解密后才能得到请求的参数
-
InvokeTimeFilter过滤器:
- 计算方法从执行到完毕的时间,打印日志
-
8. Web主模块
/**
* web主模块
*
* @author yaowenhao
* @date 2014年7月12日 下午4:44:02
*/
@Fail("void")
@IocBy(type = GameWebMain.class, args = { "" })
@Modules({ OperateModule.class, SystemModule.class })
public class MainModule {
}
9. @Modules:主模块
10. @IocBy:指定通过xxx反转注入
- NutDao
- AbsConfig:抽象配置解析类,所有系统的配置解析类都要继承这个抽象类
- load()时,注册NutDao为IocBean
- 子类在setValue()时,通过拼接的表名_小表名,dao从配置数据库中读取对应的表(dao.query(tableName)),将表数据转换为List<Record>,然后根据各个字段的@Config和对应的解析方法,通过反射机制调用解析方法解析表字段配置
- AbsConfig:抽象配置解析类,所有系统的配置解析类都要继承这个抽象类
- NutIoc
@IocBean:AnnotationIocLoader根据这个注解来判断哪些类应该被自己加载
@Inject:AnnotationIocLoader根据这个注解来了解类中的字段,具体的注入方式
使用了@IocBean注解标注的class类,在服务器启动时,通过AnnotationIocLoader将其转换为IocBean,放到GameWebContext的全局Ioc容器中
@Inject
Json文件:JsonLoader加载server.js配置文件
- NutAop
- @Aop注解