Java体系总结
Java技术体系总结涵盖了Java基础(Java运行原理、运行环境、Java特性、集合、线程、JVM、SPI)、Netty框架、Https原理、Spring框架、SpringBoot框架的知识整理
目录
- Java体系总结
- 一、Java基础
- 1、Java运行原理
- 2、运行环境
- 3、Java特性
- 1)、封装
- 2)、继承
- 3)、多态
- 4、集合
- 4.1、List
- 1)、ArrayList
- 2)、Vector
- 3)、LinkedList
- 4)、Set
- 4.2、Map
- 1)、HashMap
- 2)、TreeMap
- 4.3、线程安全集合
- 5、线程
- 5.1 、线程与进程的关系
- 5.2、线程的状态
- 5.3、线程池
- 5.4、sleep与wait的区别
- 5.5、join与yield的区别
- 5.6、实现
- 5.7、异步
- 1)、继承Thread
- 2)、实现Runnable
- 3)、实现Callable,返回Future,获取线程任务返回结果
- 4)、使用CompletableFuture
- 5)、使用RxJava库,定义订阅处理逻辑和事件发布
- 6)、基于消息队列的订阅和发布实现
- 7)、基于Socket+协议/消息实现跨进程异步
- 6、JVM
- 6.1 内存模型
- 1)、程序计数器
- 2)、栈
- 3)、堆
- 4)、方法区
- 6.2 GC原理
- 7、高级特性
- 7.1 SPI-Service Provider Interface
- 二、Netty
- 1、IO原理
- 2、IO模型
- 2.1 BIO
- 2.2 NIO
- 2.3 IO多路复用
- 2.4 信号驱动IO
- 2.5 异步IO
- 3、Netty的IO模型
- 3.1 事件分发器
- 4、Netty的框架
- 4.1 网络通信层
- 4.2 事件调度层
- 4.3 服务编排层
- 5、Netty的原理
- 三、Https原理
- 1、7层协议
- 2、Https的概述
- 3、Https原理
- 3.1 握手阶段-非对称加密
- 3.2 数据传输-对称加密
- 四、Spring框架
- 1、特性
- 五、Springboot框架
- 1、Bean的注入
- 1.1、声明注入
- 1.2、手动注入
- 2、装配原理 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/125e5fc8fd3c46c0a3484ef570e4d89d.png#pic_center)
- 六、Mybatis框架
- 1、执行原理
- 七、微服体系
- 1、Api网关
- 2、注册中心
- 3、配置中心
- 4、服务调用
- 5、缓存
- 6、消息队列
- 7、全文索引库
- 8、安全框架
- 9、分布式事务管理框架
一、Java基础
1、Java运行原理
- 将.java文件通过javac编译器进行编译成字节码,字节码-存于.class文件;
- JVM加载字节码;
- JVM解释字节码,将字节码转化为机器码;
- 将机器码经OS交由CPU执行;
2、运行环境
Java运行环境包括JDK和JRE,JDK下有Java的SDK和jvisualvm、jconsole、jmap…工具;而JRE只有Java的SDK。
3、Java特性
1)、封装
2)、继承
3)、多态
1、多态类型:
- 有编译时多态:静态多态
- 运行时多态:动态多态
2、必要条件:
- 继承
- 重写
- 向上转型
3、实现方式:
- 方法重载
- 方法重写
- 接口实现
4、集合
4.1、List
1)、ArrayList
1、原理
- 底层是数组
- 默认容量=10
- 非线程安全
2、扩容算法
- JDK6: newCapacity=(oldCapacity*3)/2 +1
- JDK8: newCapacity=oldCapacity+(oldCapacity >> 1)
3、扩容原理
- 新创建一个数据,将旧数据中的数据复制到新数组中,做数据移动,效率低
2)、Vector
1、原理
- 底层是数组
- 线程安全,效率低
- 内部实现基本上与ArrayList相同,只是Vector内部方法上加上了synchronized
2、扩容算法
- 指定了扩容量:newCapacity=oldCapacity+ 扩容量
- 未指定扩容量:newCapacity=oldCapacity * 2
3、扩容原理
- 新创建一个数据,将旧数据中的数据复制到新数组中,做数据移动,效率低
3)、LinkedList
1、原理
- 底层是双向链表
- Add、Remove效率高
- 查询效率较低,需要遍历
4)、Set
Set接口的实现集合有HashSet和TreeSet
4.2、Map
1)、HashMap
1、原理
- JDK6: 数组+链表
- JDK8: 数组+链表+红黑树
1)、当链表长度>8时,将链表转换为红黑树,提升查询效率;
2)、当链表长度<=8时,仍是链表
3)、红黑树:自平衡二叉查找树,平衡二叉B-Tree- 初始容量=2^4,16
红黑树定义:
- 每一个结点都有一个颜色,要么为红色,要么为黑色
- 树的根结点为黑色
- 树中不存在两个相邻的红色结点
- 从任意一个结点(包括根结点)到其任何后代 NULL 结点(默认是黑色的)的每条路径都具有相同数量的黑色结点
2、扩容算法
- 装载因子=0.75,数组容量达到75%,就扩容。
- 根据维基百科解释:对于开放定址法,加载因子是特别重要因素,应严格限制在0.7-0.8以下。当超过0.8后,在查表时CPU缓存(cache missing)按照指数曲线上升。
3、扩容原理
- 创建一个新的数组,容量=旧数组容量的2倍
- 遍历原Entry数组,把所有的Entry重新Hash到新数组
2)、TreeMap
4.3、线程安全集合
- 常用的线程安全的集合有ConcurrentSkipList、ConcurrentHashMap
- 与Vector相比,Vector效率非常低,原因是Vector的锁颗粒度较大,是类级别的全局锁,而ConcurrentSkipList、ConcurrentHashMap是集合内元素级别的,效率更高;
5、线程
5.1 、线程与进程的关系
线程是由进程创建的,一个进程可以有一个或多个线程
5.2、线程的状态
- 新建
- 就绪
- 运行
- 阻塞
- 死亡
5.3、线程池
1)、ExecutorService
执行任务
1、execute(Runnable)
2、Future = submit(Callable)
3、String = invokeAny(List)
4、List<Future> = invokeAll(List)
停止线程池
shutdown:不会立即销毁线程池,而是停止接受新的任务了,直到线程池中的所有任务全部执行完成后才会关闭并销毁。
shutdownNow:尝试立即关闭并销毁线程池,并不能保证所有线程都停止。
2)、ScheduledExecutorService
- schedule
- scheduleAtFixedRate
- scheduleWithFixedDelay
3)、ForkJoinPool
- ForkJoinTask
- RecursiveAction - 不返回值
- RecursiveTask<返回值类型T> - 返回值
5.4、sleep与wait的区别
- sleep不会释放持有的锁
- wait会释放持有的锁,将线程放入队列池中,等notify()执行后从队列中弹出先入队列的一个线程,状态重新回到就绪状态;notifyAll()是将队列池中等待的所有线程全部回到就绪状态;所以wait必需配合synchronized对锁对象进行同步阻塞保护
5.5、join与yield的区别
- join是将其调用线程加入到当前线程中,当前线程执行完成后,再执行队列后面的线程,是一种串行排队执行的方式;
- yield是调用线程暂时交出cpu时间片给其它线程使用,线程状态重新回到就绪状态,当有空闲的CPU时间片就再次回到运行状态;
5.6、实现
- 继承Thread
- 实现Runnable
- 实现Callable: 会返回Future,获取返回结果时会阻塞当前线程
5.7、异步
1)、继承Thread
2)、实现Runnable
3)、实现Callable,返回Future,获取线程任务返回结果
4)、使用CompletableFuture
4.1)、此接口定义了可与异步计算步骤组合的异步计算步骤契约
4.2)、处理异步计算的结果
- completableFuture.thenApply:将completableFuture计算结果提供给下一个函数,并返回CompletableFuture
- completableFuture.thenAccept:将completableFuture计算结果提供给下一个函数,并返回CompletableFuture(不返回值)
- completableFuture.thenRun:不会将completableFuture计算结果提供给下一个函数,,并返回CompletableFuture(不返回值)
4.3)、组合Future
顺序
- CompletableFuture.supplyAsync().thenCompose()
合并
- CompletableFuture.supplyAsync(函数1).thenCombine(函数2, 合并函数)
- CompletableFuture.supplyAsync(函数1).thenAcceptBoth(函数2, 合并函数)
5)、使用RxJava库,定义订阅处理逻辑和事件发布
6)、基于消息队列的订阅和发布实现
7)、基于Socket+协议/消息实现跨进程异步
6、JVM
6.1 内存模型
- JVM内存模型包含程序计数器、栈、堆、方法区
- 栈分为本地方法栈和虚拟机栈
1)、程序计数器
- 记录着当前线程执行字节码的行号,指向下一个将要执行的指令代码,由执行引擎来读取下一条执令
- 一个线程的执行,由通过字节码解释器改变当前线程的计数器的值来获取下一条需要执行的字节码指令,来确保线程的正确执行
- 每个线程都有一 个独立的计数器,线程之间互不影响
- 计数器中记录的是正在执行的JVM字节码的指令地址; 如果执行的是Native方法,计数器的值为Undefined.
2)、栈
分类
- 虚拟机栈: JVM执行java方法服务
- 本地方法栈:JVM使用到的Native方法服务
定义
- 限定仅在表头进行插入和删除的线性表,入栈和出栈都是对栈顶元素操作的。
- 栈是线程私有的,生命周期与线程相同,每个线程都会分配一个栈空间,是独立的。
- 栈中存储是栈帧。每个方法在执行时都会创建一个栈帧。栈帧中存储了局部变量表、操作数、动态连接和方法出口等信息。方法在执行时栈帧入栈,方法执行结束时栈帧出栈。
3)、堆
下图为JVM内存结构模型(注意图中每个内存区域占用的比例y/x,y表示当前区域的分子,x表示堆内存分母)
根据内存模型,如果堆内存为3072MB,则堆内存分配情况如下:
NO | 内存区 | 内存大小 |
---|---|---|
1 | 堆内存 | 3072MB |
2 | Yong区(新生代) | 1024MB |
3 | Eden区 | 819.2MB |
4 | Survivor区 | 204.8MB |
5 | Old区(老年代) | 2048MB |
4)、方法区
- 类信息
- 常量
- 静态变量
- 运行时常量池,存储是编译器生成的信息
1、字面量=Java中的常量
- final 修饰的常量
- 基本数据类型的值
- 字符串
2、符号引用
- 类和接口的全类名
- 方法名和描述符
- 字段名和描述符
6.2 GC原理
普通GC - Minor GC
- 如果新生代内存不足时会触发一次普通GC(内存回收)
- 普通GC只释放Yong区的内存,通过扫描Eden区的对象
1)、如果对象还有被引用,就将对象移入S0或S1区
2)、如果Eden中的对象较大就会直接被移入老年代- 然后将Eden区中所有不在被引用的对象全部释放;
完全GC - Full GC
- 老年代内存区使用率达到90%时就会触发完全GC,完全GC时才会释放老年代内存区的内存
7、高级特性
7.1 SPI-Service Provider Interface
SPI是服务提供者接口,是一种服务发现的机制,通过ServiceLoader.load(Class)实现;
SPI-实现:
- 建立目录META-INF/services
- 建立文件cn.test.spi.HelloService(接口的全限定名)
- 内容是实现接口的类名:cn.test.spi.impl.HelloServiceImpl
- 自定义一个加载的类,并且通过ServiceLoader.load()方法进行加载
public class HelloServiceFactory {
public HelloService getHelloService() {
ServiceLoader<HelloService> load = ServiceLoader.load(HelloService.class);
return load.iterator().next();
}
}
二、Netty
1、IO原理
- 1、[用户进程] 向 [系统内核] 发出请求
- 2、[系统内核] 向 [IO设备] 发出请求
- 3、[IO设备] 将数据写入[系统内核] 缓存区
- 4、系统将数据从[系统内核] 缓存区写入[用户进程]可以访问的用户态缓存区
2、IO模型
2.1 BIO
同步阻塞
2.2 NIO
同步非阻塞
2.3 IO多路复用
1、Select
2、poll
3、epoll
2.4 信号驱动IO
1、[IO设备] 将数据写入[系统内核] 缓存区
2、系统向 [用户进程] 发送一个数据可以读取的信号
3、[用户进程]收到信号后向[系统内核] 缓存区读取数据
2.5 异步IO
1、[用户进程] 使用线程 向 [系统内核] 发出请求,不等[系统内核] 返回就立即返回
2、[系统内核] 向 [IO设备] 发出请求
3、[IO设备] 将数据写入[系统内核] 缓存区
4、系统异步的将数据从[系统内核] 缓存区写入[用户进程]可以访问的用户态缓存区
5、系统向[用户进程] 发送一个数据准备好的信号
6、[用户进程]收到信号后向[用户态] 缓存区读取数据
3、Netty的IO模型
Netty的IO模型采用NIO+IO多路复用
3.1 事件分发器
1)、Reactor-同步IO模式(EventLoopGroup)
1、单线程模型
2、多线程模型
3、主从Reactor模型
- Boss-主Reactor
- Worker-从Reactor
2)、Proactor-异步IO模式
4、Netty的框架
4.1 网络通信层
- BootStrap:客户端启动器
- ServerBootStrap:服务器启动器
- Channel:Socket通信通道
4.2 事件调度层
1)、EventLoopGroup
- EventLoopGroup本质上是一个线程池,负责接收IO请求,并分配线程处理IO请求
- 一个EventLoopGroup包含一个或多个EventLoop
- 每新建一个Channel时,EventLoopGroup会分配一个EventLoop与其绑定
2)、EventLoop
- EventLoop处理Channel内的所有IO事件,accept、connect、read、write等IO事件
- 每个EventLoop都是单线程,是通过Select进行事件循环的
4.3 服务编排层
- ChannelPipline
- ChannelHandler
- ChannelHandlerContext
5、Netty的原理
1、服务器启动时,会初始化BossEventLoopGroup和WorkerEventLoopGroup,BossEventLoopGroup负责网络连接事件,当有新的网络连接事件到达时,会将Channel注册到WorkerEventLoopGroup;
2、WorkerEventLoopGroup会分配一个EventLoop与Channel进行绑定,负责处理该Channel的读写事件;
3、当客户端发起IO读写事件时,服务器会通过EventLoop进行数据读取,然后通过pipline触发各种监听器进行数据加工处理;
4、客户端的数据被传递到ChannelPipeline中的第一个ChannelInboundleHandler,处理完后会将处理完的数据传递到下一个ChannelInboundleHandler;
5、当向客户端回写数据时,数据会在ChannelPipeline的ChannelOutboundleHandler中进行传播,直到到达客户端;
三、Https原理
1、7层协议
1、物理层
2、数据链接层
3、网络层
4、传输层
5、会话层
6、表示层
7、应用层
2、Https的概述
Http协议 + SSL/TLS协议
3、Https原理
3.1 握手阶段-非对称加密
1、客户端-发起握手请求
2、服务器-响应请求并回复证书
3、客户端-验证证书,并从证书中解析出公钥
4、客户端-生成私钥,并用公钥对私钥加密
5、客户端-将加密后的私钥发往服务器
6、服务器-用公钥解密,并保存私钥,回复握手完成
3.2 数据传输-对称加密
1、客户端-将要发送的数据采用私钥进行加密
2、服务器-对收到的数据采用私钥进行解密
四、Spring框架
1、特性
1)、依赖注入-DI
程序中所依赖的对象由Spring容器根据依赖关系通过构造方法、工厂方法或属性进行注入
2)、控制反转-IOC
原本是在程序中通过手动编写代码方式实现依赖,Spring框架是由Spring容器接手了
3)、面向切面-AOP
- 静态代理
- JDK动态代理
- CGLIB动态代理
五、Springboot框架
1、Bean的注入
1.1、声明注入
@Configuration - 类级别的声明,指明此对象是bean定义的源
@Bean - 方法级别的声明,用于Spring IOC容器管理时一个新对象的实例化,配置和初始化的方法
@Component - 以标识自动将该类的实例注册到 Spring IoC 容器中
@Controller/@RestController - 声明为Controller
@Service - 声明Servicee类
@Repository - 声明dao类
@Autowired - 自动注入
1.2、手动注入
1、GenericBeanDefinition - 借助 GenericBeanDefinition 完成 BeanDefinition 的注册
2、BeanDefinitionBuilder - 借助 BeanDefinitionBuilder 完成 BeanDefinition 的注册
3、BeanFactoryPostProcessor - 通过实现 BeanFactoryPostProcessor 接口注册 BeanDefinition
4、BeanDefinitionRegistryPostProcessor - 通过实现 BeanDefinitionRegistryPostProcessor 接口注册 BeanDefinition
2、装配原理
六、Mybatis框架
1、执行原理
1)、获取Mapper接口
- 通过SqlSession对象调用getMapper方法
- 调用configuration对象的getMapper方法
- 调用configuration对象的MapperRegistry的getMapper方法
- 从MapperRegistry中的knownMappers缓存中获取当前类型的代理工厂类MapperProxyFactory
- 然后通过代理工厂类生成当前类型的Mapper的代理类MapperProxy<>
- MapperProxy实现了InvokationHandler(JDK动态代理),会被代理调用invoke方法
2)、Mapper接口与映射文件关联
Mapper接口及其映射文件是在加载mybatis-config配置文件的时候存储进去的
3)、sql执行过程
- 1、寻找sql
- 2、执行sql语句
七、微服体系
1、Api网关
1、路由-Nacos
2、限流-sentinel
2、注册中心
Nacos
3、配置中心
Nacos
4、服务调用
Dubbo
- 微服务调用
- 微服务负载
- 异步调用
5、缓存
Redis
6、消息队列
- RocketMQ
- ActiveMQ
- Kafka
7、全文索引库
- ElasticSearch
- Apache Solr
8、安全框架
- Spring Security
- Apache Shiro
9、分布式事务管理框架
- Seata