Java知识
2023-06-05 11:01:03 0 举报
AI智能生成
java学习知识,包含设计模式,数据库,redis等等相关内容
作者其他创作
大纲/内容
ORM
MyBaties
二级缓存
一级缓存
SqlSession级别的缓存
二级缓存
mapper级别的缓存
自定义注解
实现原理
Maven
构建声明周期
验证validate
验证项目
编译compile
执行编译
测试test
测试
包装package
打包
检查verify
检查
安装install
安装
部署deploy
部署
设计模式
六大原则
开闭原则
对扩展开放,对修改关闭,多使用抽象类和接口。
里氏代换原则
基类可以被子类替换,使用抽象类继承,不使用具体类继承。
依赖倒转原则
要依赖于抽象,不要依赖于具体,针对接口编程,不针对实现编程。
接口隔离原则
使用多个隔离的接口,比使用单个接口好,建立最小的接口。
迪米特法则
一个软件实体应当尽可能少地与其他实体发生相互作用,通过中间类建立联系。
合成复用原则
尽量使用合成/聚合,而不是使用继承。
23种设计模式
创建型模式
工厂方法
抽象工厂
建造者
原型
单例
普通创建
懒汉式(不安全)
懒汉式(安全)
饿汉式
内部类
双重锁验证
CAS
枚举
结构型模式
适配器
桥接
组合
装饰
外观
享元
代理
行为模式
责任链
命令
迭代器
中介者
备忘录
观察者
状态
策略
模板方法
访问者
JVM
JVM结构概览图
分支主题
分支主题
垃圾回收
七种常见的垃圾回收器以及回收算法
分支主题
新生代
JDK1.8默认 Parallel Scavenge
复制算法
采用了GC的复制算法,速度快,因为新生代一般是新对象,都是瞬态的用了可能很快被释放的对象
老年代
JDK1.8默认 Parallel Old
标记/整理算法
GC后会执行压缩,整理到一个连续的空间,这样就维护着下一次分配对象的指针,下一次对象分配就可以采用碰撞指针技术,将新对象分配在第一个空闲的区域
Jvm调优
-Xss
-Xms
-Xmx
类加载
类加载过程
加载
链接
验证
准备
解析
初始化
使用
卸载
加载器
双亲委派机制
自定义加载器
应用加载器
扩展加载器
根加载器
子主题 5
内存泄露&内存溢出
内存溢出(Out Of Memory)
申请内存时,JVM没有可以申请的内存了
内存泄露 (Memory Leak)
一直不释放自己持有的内存,长时间会引起内存溢出
Java
基本知识
数据结构
Map
HashMap
扩容机制
长度16 加载因子0.75f
实现
jdk1.7
数组+链表
jdk1.8
数组+链表+红黑树
Collection
List序列
ArrayList
扩容机制
默认长度10,1.5倍扩容
LinkedList(不继承List)
Set集
HashSet
Queue队列
8种常见数据类型
整型
byte(1字节 8位,-128~127)
short(2字节 16位)
int(4字节 32位)
long(8字节 64位)
浮点型
float(4字节 32位)
double(8字节 64位)
字符型
char(2字节 16位)
布尔型
boolean (1字节)
多线程
创建方法
集成Thread类,实现run()方法
实现Runnable接口,实现run()方法
实现Calable接口,实现call()方法(有返回值)
状态
线程状态
新建(new)
可运行(Runnable)
运行中(Running)
阻塞(Blocking)
等待阻塞
同步阻塞
其他阻塞
死亡(Dead)
线程池状态
Running
ShutDown
Stop
Tidying
Terminated
线程池流程
分支主题
线程池
自定义线程池,new ThreadPoolExecutor
分支主题
缓存线程池,Executors.newCachedThreadPool()
分支主题
单线程线程池,Executors.newSingleThreadExecutor()
分支主题
固定线程数线程池,Executors.newFixedThreadPool(5)
分支主题
定时定长线程池,Executors.newScheduledThreadPool(5)
分支主题
锁
自旋锁(spinlock)
互斥锁(mutex)
读写锁(RWLock)
其他分类方式
悲观锁和乐观锁
悲观锁和乐观锁这个概念主要用于数据库高并发的场景
悲观锁
乐观锁
公平锁和非公平锁
公平锁和非公平锁主要在于线程的资源公平性
公平锁
非公平锁
共享变量
Volatile关键字是如果做到值改变后通知其他线程
线程内存
MESI机制:
ThreadLocal
异常
Throwable
Exception
IOException
FileNotFoundException
RuntimeException
ClassNotFoundException
NullPointerException
ArrayIndexOutOfBoundsException
UnKnownTypeException
IllegalArgumentException
Error
VirtuMachineError
StackOverFlowError
OutOfMemoryError
AWTError
Java框架
Spring
三大特性
DI(依赖注入)
IOC(控制反转)
AOP(切面拦截)
循环依赖
思想
Spring 解决循环依赖的核心就是提前暴露对象,而提前暴露的对象就是放置于第二级缓存中。缓存的底层都是Map,至于它们属于第几层是由Spring获取数据顺序以及其作用来表现的。
实现方式
三级缓存
singletonObjects
一级缓存,存放完整的 Bean。
earlySingletonObjects
二级缓存,存放提前暴露的Bean,Bean 是不完整的,未完成属性注入和执行 初始化(init) 方法。
singletonFactories
三级缓存,存放的是 Bean 工厂,主要是生产 Bean,存放到二级缓存中。
流程
A/B对象的迁移
1 A创建过程中需要B,于是A将自己放到三级缓存里面,去实例化B
2 B实例化的时候发现需要A,于是B先查一级缓存,没有,再查二级缓存,还是没有,再查三级缓存,找到了A然后把三级缓存里面的这个A放到二级缓存里面,并删除三级缓存里面的A
3 B顺利初始化完毕,将自己放到一级缓存里面(此时B里面的A依然是创建中状态)然后回来接着创建A,此时B已经创建结束,直接从一级缓存里面拿到B,然后完成创建,并将A自己放到一级缓存里面。
区分
实例化:堆内存中申请一块内存空间
初始化:完成属性的各种赋值
事务注解
@Transactional
事务隔离级别
Spring Bean作用域
1、singleton:单例,默认作用域。
2、prototype:原型,每次创建一个新对象。
3、request:请求,每次Http请求创建一个新对象,适用于WebApplicationContext环境下。
4、session:会话,同一个会话共享一个实例,不同会话使用不用的实例。
5、global-session:全局会话,所有会话共享一个实例
常见问题
Spring Bean是线程安全的么
https://www.cnblogs.com/myseries/p/11729800.html
SpringBoot
注解
核心注解有哪些
@SpringBootApplication
@EnableAutoConfiguration
@SpringBootConfiguration
@ComponentScan
@Configuration
常用注解
@RestController
@RequestMapping
@GetMapping
@PostMapping
自定义注解
声明方法
元注解
@Documented
@Retention
@Target
使用
AOP
启动流程
https://blog.csdn.net/weixin_44947701/article/details/124055713
怎么扫描的Bean
参考1
https://blog.csdn.net/LNView/article/details/93338432
SpringCloud Alibaba
组件
Nacos(服务注册配置中心)
Gateway(网关)
Sentinel(限流)
OpenFeign(接口调用)
Seata(分布式事务解决方案)
SkyWalking(链路追踪)
数据库
MySQL
事务
事务性
原子性(Atimicity)
一致性(Consistency)
隔离性(Isolation)
持久性(Durability)
事务并发的问题
脏读
不可重复读(侧重修改)
幻读(侧重新增删除)
不可重复读&幻读
事务隔离级别
读未提交(read-uncommitted)
读已提交(read-committed)
可重复读(repeatabel-read Innodb默认隔离级别)
串行化(serializable)
引擎
Innodb
MyISAM
索引
物理储存维度
聚集索引
非聚集索引
数据结构维度
B+数索引
哈希索引
全文索引
R-Tree索引
逻辑维度
主键索引
唯一索引
普通索引
联合索引
空间索引
执行计划
id
select查询的序列号,包含一组数字,表示查询中执行select子句或操作表的顺序
1、id相同:执行顺序由上至下 。
2、id不同:如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行 。
3、id相同又不同(两种情况同时存在):id如果相同,可以认为是一组,从上往下顺序执行;在所有组中,id值越大,优先级越高,越先执行
select_type
查询的类型,主要是用于区分普通查询、联合查询、子查询等复杂的查询
类型
SIMPLE
PRIMARY
UNION
SUBQUERY
说明
简单表,不使用表连接或子查询
主查询,即外层的查询
UNION中的第二个或者后面的查询语句
子查询中的第一个
table
输出结果集的表(表别名)
type
表示MySQL在表中找到所需行的方式,或者叫访问类型。
常见访问类型如下,从上到下,性能由差到最好:
差
ALL
全表扫描
一般是没有where条件或者where条件没有使用索引的查询语句
分支主题
index
索引全扫描
索引全扫描,MySQL遍历整个索引来查询匹配行,并不会扫描表。
一般是查询的字段都有索引的查询语句
分支主题
range
索引范围扫描
索引范围扫描,常用于<、<=、>、>=、between等操作
分支主题
ref
非唯一索引扫描
使用非唯一索引或唯一索引的前缀扫描,返回匹配某个单独值的记录行
分支主题
eq_ref
唯一索引扫描
类似ref,区别在于使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配
分支主题
const,system
单表最多有一个匹配行
单表中最多有一条匹配行,查询起来非常迅速,所以这个匹配行的其他列的值可以被优化器在当前查询中当作常量来处理
好
NULL
不用扫描表或索引
MySQL不用访问表或者索引,直接就能够得到结果
possible_keys
表示查询可能使用的索引
key
实际使用的索引
key_len
使用索引字段的长度
ref
使用哪个列或常数与key一起从表中选择行。
rows
扫描行的数量
Extra
执行情况的说明和描述,包含不适合在其他列中显示但是对执行计划非常重要的额外信息
子主题 1
Distinct
优化distinct操作,在找到第一个匹配的元素后即停止查找
子主题 2
Not exists
使用not exists来优化查询
MVVC
多版本并发控制(Innodb引擎下)
参考链接:
https://blog.csdn.net/huaishu/article/details/89924250
MVCC只在 READ COMMITTED 和 REPEATABLE READ 两个隔离级别下工作
MVVC的实现机制
InnoDB在每行数据都增加三个隐藏字段,
一个唯一行号,
一个记录创建的版本号,
一个记录回滚的版本号。
分支主题
在多版本并发控制中,为了保证数据操作在多线程过程中,保证事务隔离的机制,降低锁竞争的压力,保证较高的并发量。在每开启一个事务时,会生成一个事务的版本号,被操作的数据会生成一条新的数据行(临时),但是在提交前对其他事务是不可见的,对于数据的更新(包括增删改)操作成功,会将这个版本号更新到数据的行中,事务提交成功,将新的版本号更新到此数据行中,这样保证了每个事务操作的数据,都是互不影响的,也不存在锁的问题。
分支主题
undo-log
高可用方案
主从或主主半同步复制
说明
用双节点数据库,搭建单向或者双向的半同步复制。
通常会和proxy、keepalived等第三方软件同时使用,即可以用来监控数据库的健康,又可以执行一系列管理命令。如果主库发生故障,切换到备库后仍然可以继续使用数据库。
优缺点
优点
架构、部署比较简单,主机宕机直接切换即可
缺点
完全依赖于半同步复制,半同步复制退化为异步复制,无法保证数据一致性;另外,还需要额外考虑haproxy、keepalived的高可用机制
半同步复制优化
说明
半同步复制机制是可靠的,可以保证数据一致性的。但是如果网络发生波动,半同步复制发生超时会切换为异步复制,异复制是无法保证数据的一致性的。因此,可以在半同复制的基础上优化一下,尽可能保证半同复制。如双通道复制方案
优缺点
优点
这种方案架构、部署也比较简单,主机宕机也是直接切换即可。比方案1的半同步复制,更能保证数据的一致性。
缺点
需要修改内核源码或者使用mysql通信协议,没有从根本上解决数据一致性问题
高可用架构优化
说明
保证高可用,可以把主从双节点数据库扩展为数据库集群。Zookeeper可以作为集群管理,它使用分布式算法保证集群数据的一致性,可以较好的避免网络分区现象的产生。
优缺点
优点
保证了整个系统的高可用性,扩展性也较好,可以扩展为大规模集群
缺点
数据一致性仍然依赖于原生的mysql半同步复制;引入Zookeeper使系统逻辑更复杂
共享存储
说明
共享存储实现了数据库服务器和存储设备的解耦,不同数据库之间的数据同步不再依赖于MySQL的原生复制功能,而是通过磁盘数据同步的手段,来保证数据的一致性。
DRBD磁盘复制
DRBD是一个用软件实现的、无共享的、服务器之间镜像块设备内容的存储复制解决方案。主要用于对服务器之间的磁盘、分区、逻辑卷等进行数据镜像,当用户将数据写入本地磁盘时,还会将数据发送到网络中另一台主机的磁盘上,这样的本地主机(主节点)与远程主机(备节点)的数据就可以保证实时同步。
当本地主机出现问题,远程主机上还保留着一份相同的数据,即可以继续使用,保证了数据的安全。
优缺点
优点
部署简单,价格合适,保证数据的强一致性
缺点
对IO性能影响较大,从库不提供读操作
分布式协议
说明
分布式协议可以很好解决数据一致性问题。常见的部署方案就是MySQL cluster,它是官方集群的部署方案,通过使用NDB存储引擎实时备份冗余数据,实现数据库的高可用性和数据一致性。
优缺点
优点
不依赖于第三方软件,可以实现数据的强一致性;
缺点
配置较复杂;需要使用NDB储存引擎;至少三节点;
SQL优化
1、 加索引
2、避免返回不必要的数据
3、适当分批量进行
4、优化sql结构
5、分库分表
6、读写分离
三大范式
第一范式:
表中的每个字段都不能再拆分了
第二范式:
满足第一范式且非主键字段都依赖于主键字段
第三范式:
满足第二范式并且表中的非主键字段必须不传递依赖于主键字段,每一列 数据和主键直接相关。
中间件
Redis
基础知识
数据结构
&应用场景
String: 字符串
最大长度512M
场景:
缓存、计数器、分布式锁等。
数据编码
数字
int
字符串
长度<39:enbstr
长度>39:raw
List: 列表
最多存储元素
2^32-1
场景:
链表、队列、微博关注人时间轴列表等。
数据编码
列表的元素个数<512
& 列表的每个元素值都<64字节(默认)
使用ziplist
不满足上述
linkedlist
Hash: 散列
场景:
用户信息、Hash 表等。
数据编码
哈希类型元素个数<512个
&所有值都<64字节(默认)
ziplist
不满足上述
hashtable
Set: 集合
场景:
去重、赞、踩、共同好友等。
数据编码
元素都是整数
&元素个数<512个
intset
不满足上述
hashtable
ZSet: 有序集合
场景:
访问量排行榜、点击量排行榜等。
数据编码
有序集合元素个数<128个
&每个元素的值<64
ziplist
不满足上述
skiplist
持久化
RDB
AOF
分布式锁
击穿&穿透&雪崩
击穿
指单个key在缓存中查不到,去数据库查
‼️‼️这里指的是单个key发生高并发
解决方案
通过synchronized+双重检查机制:某个key只让一个线程查询,阻塞其它线程
设置value永不过期
使用互斥锁(mutex key)
穿透
一般是出现这种情况是因为恶意频繁查询才会对系统造成很大的问题: key缓存并且数据库不存在,所以每次查询都会查询数据库从而导致数据库崩溃。
解决方案
布隆过滤器
缓存及穿透的key
雪崩
描述
雪崩指的是多个key查询并且出现高并发,缓存中失效或者查不到,然后都去db查询,从而导致db压力突然飙升,从而崩溃。
原因
key同时失效
redis本身崩溃
解决方案
哨兵
集群
主从复制原理
1、设置主节点的地址和端口
2、建立套接字连接
3、发送PING命令
4、权限验证
5、同步
6、命令传播
分支主题
为什么快
纯内存操作
单线程操作,无锁竞争
C语言实现,更接近底层
多路I/O复用模型,非阻塞IO
数据结构简单,底层又做了优化
源码精湛,简短
过期策略和内存淘汰策略
过期策略
定时过期
惰性过期
定期过期
内存淘汰策略
volatile-lru
当内存不足以容纳新写入数据时,从设置了过期时间的key中使用LRU(最近最少使用)算法进行淘汰;
allkeys_lru
当内存不足以容纳新写入数据时,从所有key中使用LRU(最近最少使用)算法进行淘汰
volatile-lfu
4.0版本新增,当内存不足以容纳新写入数据时,在过期的key中,使用LFU算法进行删除key。
allkeys-lfu
4.0版本新增,当内存不足以容纳新写入数据时,从所有key中使用LFU算法进行淘汰
volatile-random
当内存不足以容纳新写入数据时,从设置了过期时间的key中,随机淘汰数据
allkeys_random
当内存不足以容纳新写入数据时,从所有key中随机淘汰数据
volatile-ttl
当内存不足以容纳新写入数据时,在设置了过期时间的key中,根据过期时间进行淘汰,越早过期的优先被淘汰
noeviction
默认策略,当内存不足以容纳新写入数据时,新写入操作会报错
RocketMQ
功能
解耦
削峰
异步处理
消息通讯
远程调用
消费模式
集群消费
示意图
分支主题
说明
当 consumer 使用集群消费时,每条消息只会被 consumer 集群内的任意一个 consumer 实例消费一次。举个例子,当一个 consumer 集群内有 3 个consumer 实例(假设为consumer 1、consumer 2、consumer 3)时,一条消息投递过来,只会被consumer 1、consumer 2、consumer 3中的一个消费。
同时记住一点,使用集群消费的时候,consumer 的消费进度是存储在 broker 上,consumer 自身是不存储消费进度的。消息进度存储在 broker 上的好处在于,当你 consumer 集群是扩大或者缩小时,由于消费进度统一在broker上,消息重复的概率会被大大降低了。
注意:在集群消费模式下,并不能保证每一次消息失败重投都投递到同一个 consumer 实例。
广播消费
示意图
分支主题
说明
当 consumer 使用广播消费时,每条消息都会被 consumer 集群内所有的 consumer 实例消费一次,也就是说每条消息至少被每一个 consumer 实例消费一次。举个例子,当一个 consumer 集群内有 3 个 consumer 实例(假设为 consumer 1、consumer 2、consumer 3)时,一条消息投递过来,会被 consumer 1、consumer 2、consumer 3都消费一次。
与集群消费不同的是,consumer 的消费进度是存储在各个 consumer 实例上,这就容易造成消息重复。还有很重要的一点,对于广播消费来说,是不会进行消费失败重投的,所以在 consumer 端消费逻辑处理时,需要额外关注消费失败的情况。
虽然广播消费能保证集群内每个 consumer 实例都能消费消息,但是消费进度的维护、不具备消息重投的机制大大影响了实际的使用。因此,在实际使用中,更推荐使用集群消费,因为集群消费不仅拥有消费进度存储的可靠性,还具有消息重投的机制。而且,我们通过集群消费也可以达到广播消费的效果。
如何保证消息不会丢失
处理过程图
分支主题
三个阶段
Producer发送消息阶段
1、提供SYNC的发送消息方式,等待broker处理结果
同步发送-默认
(丢失概率最低)
异步发送:
Oneway发送:
2、发送消息如果失败或者超时,则重新发送
3、broker提供多master模式,即使某台broker宕机了,保证消息可以投递到另外一台正常的broker上
Broker处理消息阶段
提供同步刷盘的策略
提供主从模式,同时主从支持同步双写
Consumer消费消息阶段
consumer默认提供的是At least Once机制
先提交后消费
先消费,消费成功后再提交
(RocketMQ默认方式)
消费消息重试机制
如何保证消息不被重复消费
消费端处理消息的业务逻辑保持幂等性
保证每条消息都有唯一编号且保证消息处理成功与去重表的日志同时出现
ElasticSearch
Kafka
k8s
rancher
垃圾回收GC算法
引用计数法&可达性分析
标记/清除算法
1、初始标记:独占CPU(STW),仅标记GCroots能直接关联的对象,速度比较快;
2、 并发标记:可以和用户线程并行执行,标记所有可达对象
3、 重新标记:独占CPU(STW),对并发标记期间用户线程运行产生的垃圾对象进行标记修正(用的是增量更新)---防止对象消失
4、 并发清理:可以和用户线程并行执行,清理垃圾
缺点:
递归效率低性能低;释放空间不连续容易导致内存碎片;会停止整个程序运行;
复制算法
把内存分成两块区域:空闲区域和活动区域,第一还是标记(标记谁是可达的对象),标记之后把可达的对象复制到空闲区,将空闲区变成活动区,同时把以前活动区对象1,4清除掉,变成空闲区。
缺点:
速度快但耗费空间,假定活动区域全部是活动对象,这个时候进行交换的时候就相当于多占用了一倍空间,但是没啥用。
标记整理算法
1、初始标记:独占CPU(STW),仅标记GCroots能直接关联的对象,速度比较快;
2、 并发标记:可以和用户线程并行执行,标记所有可达对象
3、最终标记:独占CPU(STW),对并发标记期间用户线程运行产生的垃圾对象进行标记修正(用的是原始快照)---防止对象消失
4、筛选回收:需要STW,但是也可以和用户线程并行执行,首先对各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿时间来制定回收计划
树
二叉树
平衡二叉树
红黑树
B树
图示
分支主题
B+树
图示
分支主题
数据库和缓存一致性
0 条评论
下一页