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 条评论
 下一页
  
   
   
   
   
  
  
  
  
  
  
  
  
  
  
 