JAVA技术栈
2024-11-09 12:16:03 26 举报
AI智能生成
java 技术栈
作者其他创作
大纲/内容
分布式消息中间件<br>
ROCKETMQ<br>
ROCKETMQ详细特性和场景<br>
消息类型
顺序消息
广播消息
延迟消息
批量消息
过滤消息
事务消息
消息存储<br>
刷盘机制
同步刷盘
异步刷盘
消息主从复制
同步复制
异步复制
RocketMQ消息的存储分为三个部分
CommitLog:存储消息的元数据。
ConsumerQueue:存储消息在CommitLog的索引。
IndexFile:为了消息查询提供了一种通过key或时间区间来查询消息的方法,
<br>
ROCKETMQ核心源码解析<br>
参考:https://note.youdao.com/ynoteshare/index.html?id=c91c232cb5052cc9917c35ff2aa62e49&type=note&_time=1726298216245
ROCKETMQ源码解读和实践问题<br>
参考:https://note.youdao.com/ynoteshare/index.html?id=34ee9fe19157c6f4f0ab416d69622c7a&type=note&_time=1726303554161
KAFKA
KAFKA快速实战和基本原理<br>
KAFKA发送接收消息核心参数配置与设计原理详解<br>
KAFKA生产问题总结和性能优化实战<br>
RABBITMQ
RABBITMQ集群及高级特性<br>
RABBITMQ如何作可靠消息的投递<br>
分布式技术MongDBSharding-Sphere<br>
MONGDB
MONGDB集群架构及高级特性<br>
MONGDB企业应用实战<br>
ShardingSphere<br>
ShardingSphere核心概念<br>
ShardingSphere内核原理及核心源码解析<br>
ShardingProxy分库分表实战及同类产品选型<br>
MYSQL主从架构分库分表
分布式通信netty框架<br>
JAVA BIO&NIO&AIO精讲<br>
netty核心功能与线程模型精讲<br>
netty编解码&粘包拆包及零拷贝精讲<br>
netty线程模型源码解析<br>
分布式技术apache Dubbo<br>
DUBBO基本应用和高级应用
负载均衡
随机负载均衡(Random Load Balance)
轮询负载均衡(Round Robin Load Balance)
最少活跃数负载均衡(Least Active Load Balance)
一致性哈希负载均衡(Consistent Hash Load Balance)
服务超时<br>
集群容错<br>
服务降级<br>
本地存根<br>
本地伪装<br>
参数回调
异步调用<br>
泛化调用<br>
DUBBO的可扩展SPI源码解析<br>
Spring与Dubbo整合原理<br>
DUBBO服务导出源码解析<br>
DUBBO服务导入源码解析
DUBBO服务调用源码解析
分布式ELK<br>
ElasticSearch核心语法与集群环境搭建<br>
ElasticSearch集群架构原理和搜索技术深入<br>
ElasticSearch底层原理与分组聚合查询<br>
ElasticSearch进阶与Java api整合ES<br>
微服务技术<br>
SpringBoot自动装配核心源码剖析<br>
<br>
<br>
为什么Springboot可以运行jar包?<br>
@SpringBootApplication
继承@Configuration,标注这是一个Spring Boot配置类:@SpringBootConfiguration<br>
启用Spring Boot的自动配置机制,尝试根据类路径设置、其他bean以及各种属性设置自动配置:@EnableAutoConfiguration<br>
启用组件扫描,允许Spring Boot查找其他组件、配置文件和服务。:@ComponentScan<br>
微服务架构Alibaba nacos 注册中心实战<br>
负载均衡组件RRibbon&LLoadBalancer实战<br>
JVM性能调优<br>
类加载机制<br>
引导类加载器<br>扩展类加载器<br>应用程序类加载器<br>自定义加载器<br>
类加载机制流程图
类加载的双亲委派机制
JVM<br>
JVM整体结构
JVM整体结构图
JVM内存分配<br>
对象内存分配图<br>
对象内存分配流程图
对象进入老年代几种机制<br>
<font color="#ec7270">大对象直接进入老年代<br></font>大对象就是需要大量连续内存空间的对象(比如:字符串、数组)。JVM参数 -XX:PretenureSizeThreshold 可以设置大对象的大小,如果对象超过设置大小会直接进入老年代,不会进入年轻代,这个参数只在 Serial 和ParNew两个收集器下有效。<br>
<font color="#ec7270">长期存活的对象将进入老年代<br></font>既然虚拟机采用了分代收集的思想来管理内存,那么内存回收时就必须能识别哪些对象应放在新生代,哪些对象应放在老年代中。为了做到这一点,虚拟机给每个对象一个对象年龄(Age)计数器。<br>
<font color="#ec7270">对象动态年龄判断<br></font>当前放对象的Survivor区域里(其中一块区域,放对象的那块s区),一批对象的总大小大于这块Survivor区域内存大小的50%(-XX:TargetSurvivorRatio可以指定),那么此时大于等于这批对象年龄最大值的对象,就可以直接进入老年代了,例如Survivor区域里现在有一批对象,年龄1+年龄2+年龄n的多个年龄对象总和超过了Survivor区域的50%,此时就会把年龄n(含)以上的对象都放入老年代。这个规则其实是希望那些可能是长期存活的对象,尽早进入老年代。对象动态年龄判断机制一般是在minor gc之后触发的。
<font color="#ec7270">老年代空间分配担保机制<br></font>年轻代每次minor gc之前JVM都会计算下老年代剩余可用空间<br>如果这个可用空间小于年轻代里现有的所有对象大小之和(包括垃圾对象)<br>就会看一个“-XX:-HandlePromotionFailure”(jdk1.8默认就设置了)的参数是否设置了<br>如果有这个参数,就会看看老年代的可用内存大小,是否大于之前每一次minor gc后进入老年代的对象的平均大小。<br>如果上一步结果是小于或者之前说的参数没有设置,那么就会触发一次Full gc,对老年代和年轻代一起回收一次垃圾,如果回收完还是没有足够空间存放新的对象就会发生"OOM"<br>当然,如果minor gc之后剩余存活的需要挪动到老年代的对象大小还是大于老年代可用空间,那么也会触发full gc,full gc完之后如果还是没有空间放minor gc之后的存活对象,则也会发生“OOM”<br>
老年代空间分配担保机制流程图
JVM字节码文件结构<br>
JVM调优工具<br>
调优流程<br>
对于还在正常运行的系统:<br>1.可以使用jmap来查看JVM中各个区域的使用情况<br>2.可以通过jstack来查看线程的运行情况,比如哪些线程阻塞、是否出现了死锁<br>3.可以通过jstat命令来查看垃圾回收的情况,特别是fullgc,如果发现fulgc比较频繁,那么就得进行调优了4.通过各个命令的结果,或者jvisualvm等工具来进行分析<br>5.首先,初步猜测频繁发生fullgc的原因,如果频繁发生fullgc但是又一直没有出现内存溢出,那么表示fullgc实际上是回收了很多对象了,所以这些对象最好能在younggc过程中就直接回收掉,避免这些对象进入到老年代,对于这种情况,就要考虑这些存活时间不长的对象是不是比较大,导致年轻代放不下,直接进入到了老年代,尝试加大年轻代的大小,如果改完之后,fullgc减少,则证明修改有效<br>6.同时,还可以找到占用CPU最多的线程,定位到具体的方法,优化这个方法的执行,看是否能避免某些对象的创建,从而节省内存<br>
对于已经发生了OOM的系统:<br>1.一般生产系统中都会设置当系统发生了OOM时,生成当时的dump文件(-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/local/base)<br>2.我们可以利用jsisualvm等工具来分析dump文件<br>3.根据dump文件找到异常的实例对象,和异常的线程(占用CPU高),定位到具体的代码<br>4.然后再进行详细的分析和调试<br>
调优工具
arthas工具<br>
jsisualvm工具
JVM调优实战<br>
垃圾收集器
Serial<br>
Serial收集器
parallel<br>
Parallel收集器
parNew<br>
ParNew收集器
CMS
CMS收集器
CMS收集器步骤图
CMS相关参数
垃圾回收器底层算法-三色标记
GC ROOTS算法
G1<br>
G1垃圾回收器
G1收集器参数设置<br>
ZGC<br>
垃圾回收器选择
MYSQL性能调优
MYSQL索引底层数据结构和算法<br>
底层数据结构
索引是帮助MySQL高效获取数据的排好序的数据结构
二叉树
红黑树
Hash表
B-Tree
B+Tree
存储引擎索引<br>
MyISAM存储引擎索引实现
<br>
InnoDB存储引擎索引实现
索引最左前缀原理<br>
<br>
explain详解与索引的最佳实践<br>
索引类型(type)
依次从最优到最差分别为:system>const>eq_ref>ref>range>index>ALL;<br>一般来说,得保证查询达到range级别,最好达到ref<br><br>
explain的sql字段说明
key_len计算规则如下:<br>字符串<br>char(n):n字节长度<br>varchar(n):如果是utf-8,则长度 3n+2 字节,加的2字节用来存储字符串长度0<br>数值类型<br>tinyint:1字节。<br>smallint:2字节<br>int:4字节<br>bigint:8字节<br>时间类型<br>date:3字节<br>timestamp:4字节。<br>dateime:8字节<br>如果字段允许为 NULL,需要1字节记录是否为 NULL索引最大长度是768字节,<br>当字符串过长时,mysql会做一个类似左前缀索引的处理,将前半部分的字符提取出来做索引。<br>
一条SQL怎么执行<br>
<br>
MYSQL索引优化实战<br>
trace工具<br>
开启trace
trace信息:预估成本<br>
trace信息:最优选择
关闭trace
order by和group by优化
<br>
<br>
<br>
<br>
<br>
<br>
<br>
总结
单路排序和双路排序
<br>
索引设计原则<br>
<br>
<br>
<br>
索引设计实战<br>
<br>
分页查询<br>
<br>
优化前:EXPLAIN select * from employees ORDER By name limit 90000,5;<br>优化后:EXPLAIN select * from employees inner join (select id from employees order by name limited 90000,5) ed on e.id = ed.id;<br>
join优化<br>
<br>
<br>
<br>
in和exsits优化<br>
<br>
<br>
count优化
字段类型优化<br>
MYSQL事务隔离级别和锁机制<br>
事务及其ACID属性
原子性(Atomicity):事务是一个原子操作单元,其对数据的修改,要么全都执行,要么全都不执行。
一致性(Consistent):在事务开始和完成时,数据都必须保持一致状态。这意味着所有相关的数据规则都必须应用于事务的修改,以保持数据的完整性。
隔离性(Isolation):数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的"独立“环境执行。这意味着事务处理过程中的中间状态对外部是不可见的,反之亦然。
持久性(Durable): 事务完成之后,它对于数据的修改是永久性的,即使出现系统故障也能够保持。<br>
并发事务带来问题<br>
脏读<br>
不可重复读<br>
幻读
事务隔离级别<br>
未提交读
提交读
可重复读:写时加锁
可串行化:读写加锁<br>
<br>
锁分类
乐观锁
悲观锁
读锁(共享锁,S锁(Shared)):针对同份数据,读操作可以同时进行而不会互相影响
写锁(排它锁,X锁(eXclusive)):当前写操作没有完成前,它会阻断其他写锁和读锁
行锁<br>每次操作锁住一行数据。开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度最高。InnoDB与MYISAM的最大不同有两点:<br>InnoDB支持事务(TRNSACTION)<br>InnoDB支持行级锁
表锁<br>每次操作锁住整张表。<br>开销小,加锁快;不会出现死锁:锁定粒度大,<br>发生锁冲突的概率最高,并发度最低:<br>一般用在整表数据迁移的场景<br>
<br>
间隙锁<br>
<br>
临键锁
<br>
无索引行锁会升级为表锁
<br>
查看锁情况
<br>
锁优化建议
<br>
概述
<br>
MVCC与BufferPool缓存机制<br>
MVCC
<br>
MVCC的判断规则<br>
可重复读事务:在一个事务中,第一个查询会生成一个readview,后面的查询都使用这个readview;<br>已提交读事务:在一个事务中,第一个查询会生成一个readview,后面的查询都会实时生成一个readview;
BufferPool
<br>
TOMCAT性能调优<br>
TOMCAT核心组件及应用架构详解<br>
TOMCAT核心组件源码解析<br>
TOMCAT源码之HTTP请求响应过程剖析<br>
TOMCAT源码之热加载热部署及类加载器剖析<br>
并发编程专题<br>
操作系统底层工作的底层认识<br>
JMM&volatile详解<br>
多线程下可见性<br>
可见性:当一个线程修改了一个被声明为 volatile 的共享变量时,其他线程能够立即看到这个变化,<br>而不是等待缓存失效或刷新。这意味着对 volatile 变量的写操作会强制刷入主内存,<br>并且读操作会从主内存中读取最新值。
多线程下有序性
禁止指令重排序:编译器和CPU不会对 volatile 变量进行指令重排序优化,<br>保证了程序执行的顺序与源代码中的顺序一致(即 happens-before 规则)。<br>这对于依赖于特定顺序执行的操作特别重要。
内存屏障:Java内存模型(JMM)通过插入内存屏障来实现 volatile 的语义。内存屏障是一种硬件层面的技术,<br>它可以确保一些内存操作按照指定顺序执行。对于 volatile 写操作,会在其后插入“写屏障”,<br>这样能确保所有之前的操作都完成并刷新到主内存;对于 volatile 读操作,则在其前插入“读屏障”,<br>确保在此之后的所有操作都能看到此变量的最新值。
缓存一致性协议:现代多核处理器使用缓存一致性协议(如Intel的MESI协议等)来维持不同CPU核心之间的缓存数据同步。<br>当一个CPU核心修改了 volatile 变量时,该协议会确保其他核心上的缓存副本失效,从而需要从主内存重新加载最新的值。
总结:<br>总结来说,volatile关键字是Java中用于简化并发编程的一种机制,它确保了多线程环境下的简单同步问题,但不能替代原子操作或解决复杂的互斥问题。在实际应用中,volatile 常用于状态标志、计数器等简单的并发场景,而更复杂的并发控制通常需要借助于 synchronized 或 java.util.concurrent 包中的工具类。<br>
JMM&MESI协议<br>
synchronized详解<br>
锁的状态总共有四种,无锁状态、偏向锁、轻量级锁和重量级锁。随着锁的竞争,锁可以从偏向锁升级到轻量级锁,再升级的重量级锁,但是锁的升级是单向的,也就是说只能从低到高升级,不会出现锁的降级。从JDK 1.6 中默认是开启偏向锁和轻量级锁的,可以通过-XX:-UseBiasedLocking来禁用偏向锁。<br>
AQS应用lock详解<br>
AQS核心:①自旋;②线程阻塞;③cas;④队列;
AQS应用阻塞队列(BlockingQueue)<br>
countDownLatch&SemaPhore应用<br>
底层是基于AQS实现的
countDownLatch
CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。<br>每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,<br>它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。
CountDownLatch.countDown()<br>CountDownLatch.await();
SemaPhore
Semaphore 字面意思是信号量的意思,它的作用是控制访问特定资源的线程数目
构造方法<br>public Semaphore(int permits)<br>public Semaphore(int permits, boolean fair)<br>permits 表示许可线程的数量<br>fair 表示公平性,如果这个设为 true 的话,下次执行的线程会是等待最久的线程<br>
重要方法<br>public void acquire() throws InterruptedException<br>public void release()<br>tryAcquire(int args,long timeout, TimeUnit unit)<br>acquire() 表示阻塞并获取许可<br>release() 表示释放许可<br>
atomic&Unsafe详解<br>
Map&List&Set详解<br>
ArrayList、LinkedList、Vector区别和实现原理
ArrayList和Vector是基于动态数组实现的,LinkedList是基于双向链表实现的(含有头结点)
ArrayList、LinkedList不具有有线程安全性,<br>如果在并发环境下使用它们,可以用Collections类中的静态方法synchronizedList()对ArrayList和LinkedList进行调用即可,即可达到线程安全问题。<br>Vector实现线程安全的,即他的方法大都包含关键字synchronized,但是Vector的效率没有ArraykList和LinkedList高。<br>
hashMap hashtable ConcurrentHashMap区别
hashMap内部存储结构是数组加链表,线程非安全<br>
hashtable内部存储结构是数组加链表,线程安全,在很多方法定义时都会加上 synchronized关键字<br>
ConcurrentHashMap底层采用分段的数组+链表实现,底层先调用lock(),lock是ReentrantLock类的一个方法,因此是线程安全<br>锁分段技术:首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。<br>
Excutor线程池原理和源码解读<br>
ThreadPoolExcutor七大参数说明
<br>
拒绝策略
线程数设置
定时任务线程池<br>
Future&ForkJoin框架<br>
无锁并发框架-Disruptor<br>
源码框架专题<br>
SpringIOC流程和源码<br>
流程1:<br><br>
流程2:<br><br>
流程3:<br><br>
SpringAOP流程和源码<br>
切面术语:
切面流程:
解析切面:<br><br>
创建动态代理:<br><br>
调用:<br><br>
aop的四种实现方式:<br>
一、BeanNameAutoProxyCreator
二、DefaultAdvisorAutoProxyCreator<br>
三 、aop:config 配置代理<br>
四 、注解方式实现AOP
链接:https://blog.csdn.net/d1451545368/article/details/127304500<br>声明式事务管理和编程式事务管理<br>
Spring事务流程和源码
声明性事务四大特性ACID<br>
A 原子性:原子性指的是 在一组业务操作下 要么都成功 要么都失败<br>在一组增删改查的业务下 要么都提交 要么都回滚<br>
C 一致性:事务前后的数据要保证数据的一致性<br> 在一组的查询业务下 必须要保证前后关联数据的一致性<br>
I 隔离性:在并发情况下 事物之间要相互隔离。<br>
D 持久性:数据一旦保存就是持久性的。<br>
@Transactional注解应该写在哪:<br>
@Transactional 可以标记在类上面(当前类所有的方法都运用上了事务)<br>
@Transactional 标记在方法则只是当前方法运用事务<br>
也可以类和方法上面同时都存在, 如果类和方法都存在@Transactional会以方法的为准。如果方法上面没有@Transactional会以类上面的为准<br>建议:@Transactional写在方法上面,控制粒度更细, 建议@Transactional写在业务逻辑层上,因为只有业务逻辑层才会有嵌套调用的情况。
子类继承父类事务,子类依然具有事务功能
事务配置属性<br>
isolation:设置事务的隔离级别<br>propagation:事务的传播行为<br>noRollbackFor:那些异常事务可以不回滚<br>noRollbackForClassName:填写的参数是全类名<br>rollbackFor:哪些异常事务需要回滚<br>rollbackForClassName:填写的参数是全类名<br>readOnly:设置事务是否为只读事务<br>timeout:事务超出指定执行时长后自动终止并回滚,单位是秒<br>
设置隔离级别(isolation)<br>
并发事务产生问题
脏读<br>
不可重复度<br>
幻影读
事务隔离级别<br>
并发安全:SERIALIZABLE>REPEATABLE_READ>READ_COMMITTED<br>运行效率:READ_COMMITTED>REPEATABLE_READ>SERIALIZABLE
事务的传播特性<br>
<br>
超时属性(timeout)
指定事务等待的最长时间(秒)<br>当前事务访问数据时,有可能访问的数据被别的数据进行加锁的处理,那么此时事务就必须等待,如果等待时间过长给用户造成的体验感差。<br>
设置事务只读(readOnly)<br>
<br>
异常属性<br>
<br>
在实战中事务的使用方式<br>
面试题<br>
面试题:<br>Spring事务的实现方式和实现原理<br>说一下Spring的事务传播行为<br>说一下 spring 的事务隔离?<br>Spring框架的事务管理有哪些优点?<br>操作!!<br>
事务实现流程
SpringMVC流程和源码<br>
SpringMVC流程<br>
MyBatis流程和源码<br>
Spring整合MyBatis的源码解析<br>
分布式缓存技术Redis<br>
Redis核心数据结构与高性能原理<br>
五种数据结构
高性能原理
<br>
Redis持久化<br>
RDB快照(snapshot)
AOF(append-only file)<br>
Redis 4.0 混合持久化<br>
Redis的主从、哨兵、集群架构<br>
主从架构<br>
<br>
主从、哨兵架构
集群架构
<br>
Redis分布式实战锁<br>
Redis缓存设计与性能优化
缓存穿透<br>
1、缓存空对象
2、布隆过滤器<br>
缓存失效(击穿)
由于大批量缓存在同一时间失效可能导致大量请求同时穿透缓存直达数据库,可能会造成数据库瞬间压力过大甚至挂掉,<br>对于这种情况我们在批量增加缓存时最好将这一批数据的缓存过期时间设置为一个时间段内的不同时间。<br>
缓存雪崩<br>
1) 保证缓存层服务高可用性,比如使用Redis Sentinel或Redis Cluster。
2) 依赖隔离组件为后端限流熔断并降级。比如使用Sentinel或Hystrix限流降级组件。<br>比如服务降级,我们可以针对不同的数据采取不同的处理方式。当业务应用访问的是非核心数据(例如电商商品属性,用户信息等)时,暂时停止从缓存中查询这些数据,而是直接返回预定义的默认降级信息、空值或是错误提示信息;当业务应用访问的是核心数据(例如电商商品库存)时,仍然允许查询缓存,如果缓存缺失,也可以继续通过数据库读取。<br>
3) 提前演练。 在项目上线前, 演练缓存层宕掉后, 应用以及后端的负载情况以及可能出现的问题, 在此基础上做一些预案设定。<br>
热点缓存key重建优化<br>
开发人员使用“缓存+过期时间”的策略既可以加速数据读写, 又保证数据的定期更新, 这种模式基本能够满足绝大部分需求。 但是有两个问题如果同时出现, 可能就会对应用造成致命的危害:<br>当前key是一个热点key(例如一个热门的娱乐新闻),并发量非常大。<br>重建缓存不能在短时间完成, 可能是一个复杂计算, 例如复杂的SQL、 多次IO、 多个依赖等。<br>在缓存失效的瞬间, 有大量线程来重建缓存, 造成后端负载加大, 甚至可能会让应用崩溃。<br>要解决这个问题主要就是要避免大量线程同时重建缓存。<br>我们可以利用互斥锁来解决,此方法只允许一个线程重建缓存, 其他线程等待重建缓存的线程执行完, 重新从缓存获取数据即可。<br>
redis的高并发
配置优化
配置文件优化:可以适当增加Redis的最大连接数(maxclients),设置合适的内存限制(maxmemory),根据实际情况设置合理的超时时间,确保Redis能够处理足够多的连接和请求
网络配置优化:调整操作系统的参数,如增加文件描述符限制、调整TCP连接参数等,以提高Redis的并发处理能力。
数据分片
分片横向扩展:将数据按照一定规则划分到多个Redis实例中,每个实例负责处理一部分数据。这样可以将负载均衡到多个实例上,提高整体并发能力。
分区键优化:合理选择分区键,避免某个键对应的数据集中在某个实例上,导致某个实例成为热点,影响整体性能。<br>
数据预加载和缓存预热
数据预加载:启动Redis时,可以通过导入rdb文件或者aof文件来提前将数据加载到内存中,避免数据一开始大量访问导致的性能瓶颈。
缓存预热:根据业务情况,在Redis启动前预先将热点数据加载到缓存中,可以提前将数据加载到内存中,避免大量请求的时候造成冷启动的性能问题。<br>
使用主从复制和哨兵模式
主从复制:通过搭建Redis主从复制架构,将读请求分发到从节点,减轻主节点的负载,提高并发能力。<br>
哨兵模式:通过引入Redis哨兵来实现自动的故障转移和主从切换,保证Redis的高可用性。<br>
使用集群模式<br>
Redis Cluster:Redis Cluster支持在多个节点上分布数据,自动进行数据分片和容错,实现高可用和高并发<br>
总结
综上所述,通过合理的配置优化、数据分片、数据预加载和缓存预热、主从复制和哨兵模式、使用集群模式等方法来解决Redis高并发问题。<br>
分布式协调服务zookeeper<br>
zookeeper特性和节点数据类型<br>
PERSISTENT-持久化目录节点<br>
客户端与zookeeper断开连接后,该节点依旧存在,只要不手动删除该节点,他将永远存在
PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点
客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号
EPHEMERAL-临时目录节点
客户端与zookeeper断开连接后,该节点被删除
EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点<br>
客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号<br>
Container 节点
Container 节点(3.5.3 版本新增,如果Container节点下面没有子节点,则Container节点在未来会被Zookeeper自动清除,定时任务默认60s 检查一次)
TTL 节点<br>
( 默认禁用,只能通过系统配置 zookeeper.extendedTypesEnabled=true 开启,不稳定)<br>
zookeeper客户端使用和集群特性<br>
zookeeper典型使用场景实战<br>
zookeeper典型核心源码解析<br>
<br>
zookeeper的ZAB原理和源码
设计模式
单例模式:懒汉与饿汉,使用饿汉模式,数据库连接池,创建一个单例对象,用于提供对数据库连接方法,还有在一些配值类中,声明一个配置读取单例用于配值类的读取。
原型模式:创建复杂对象时,如果每次都是从头初始化,可能会带来性能开销或者逻辑过于复杂,通过实现Cloneable()接口与实现Searializiable接口实现浅克隆与深克隆。
模板方法模式:主要特点是封装了不变的部分,扩展了可变的部分。它将不变的算法骨架封装在父类中,而将可变的步骤留给子类实现。<br>使用场景:当某个方法的实现需要多个步骤,其中有些步骤是固定的,而有些步骤可以变化时。
工厂方法模式:定义工厂接口,然后根据具体工厂类进行产品的管理,客户端直接与具体的工厂进行交互。
建造者模式:创建带参数的构造器对象的时候可以使用建造者模式,可以动态改变参数传递顺序,代码可读性也会更好。
代理模式:面向切面编程,日志处理,事务管理这些都可以用代理模式,有接口用jdk动态代理,无接口用cglib动态代理。
策略模式:在Java开发中,策略模式是一种行为设计模式,它使你能在运行时改变对象的行为。通过定义一系列可互换的算法(策略),并在上下文中使用这些策略来解决特定问题,就是定义抽象的策略接口,定义不同接口实现类实现不同的策略,比如:电商网站购卡的不同优惠策略。<br>
观察者模式:用于实现对象之间的依赖关系,当一个对象的状态改变时,所有依赖于它的对象都会得到通知并自动更新。比如:消息队列就是典型的观察者模式。
备忘录模式:用于在不违反封装性原则的前提下,捕获并存储对象的内部状态,以便将来可以恢复到之前的状态,用于在一些回滚的场景,用于还原状态。
装饰者模式:java.io` 包中的输入/输出流类如 `BufferedReader`、`BufferedWriter`、`DataInputStream` 和 `DataOutputStream` 等,这些类作为装饰器添加额外功能到基础的 `InputStream` 和 `OutputStream` 流上。
好的编程习惯
类名使用 UpperCamelCase 风格,以下情形例外 :DO / PO(持久对象) / DTO(数据传输对象 )/ BO(业务对象) / VO / UID 等。<br><br>使用版本控制:如Git,管理代码变更,便于追踪和协作。<br><br>编写清晰的注释:为复杂的逻辑、方法和类提供注释。<br><br>异常处理:妥善处理异常,并给出明确的错误信息。<br><br>遵循SOLID原则:编写可维护、可扩展和可测试的代码。<br><br>使用日志:记录关键信息和错误,便于调试和排查问题。<br><br>编写测试:包括单元测试、集成测试和功能测试。<br><br>避免硬编码:将常量、配置信息等放入配置文件或环境变量中。<br><br>遵循代码风格指南:保持代码风格一致。<br><br>使用合适的集合:根据需求选择合适的集合类型。<br><br>避免长方法:将长方法拆分为多个小方法。<br><br>使用设计模式:在适当的情况下使用设计模式。<br><br>考虑接口兼容性:修改老接口时,确保新旧接口的兼容性。<br><br>遵循依赖注入原则:通过依赖注入来解耦代码,提高代码的可测试性和可维护性。<br><br>使用接口隔离原则:为每个类定义明确的接口,并只让它们依赖于它们真正需要的接口。<br><br>使用设计模式:不仅限于常见的设计模式,也要根据具体场景选择合适的设计模式,如观察者模式、策略模式等。
自由主题
0 条评论
下一页