
笔记
文章平均质量分 81
一只小P熊
这个作者很懒,什么都没留下…
展开
-
Dubbo扩展点加载机制
概述Dubbo的扩展性除了和它恰到好处的使用了各种设计模式有关之外,还与它的扩展点机制有关(Dubbo SPI),Dubbo SPI在Java SPI的思想基础上进行了一定的改进。Java SPISPI全称Service Provider Interface,是Java提供的一套用来被第三方实现或者扩展的接口,它可以用来启用框架扩展和替换组件。SPI的作用就是为这些被扩展的API寻找服务实现。SPI和APIAPI (Application Programming Interface)在大多数情况下原创 2021-09-18 09:00:43 · 375 阅读 · 0 评论 -
Dubbo注册中心
注册中心概述假如我们在服务消费者端维护了一个服务提供者的列表,在没有注册中心的情况下,假如新增了一个服务提供者或者某一个提供者下线了,都要去更新服务消费者的配置文件。引入注册中心之后,就可以实现分布式服务的注册与发现,注册中心是分布式系统的枢纽,其主要作用有如下几点:动态加入。 一个服务提供者通过注册中心可以动态地把自己暴露给其他消费者, 无须消费者逐个去更新配置文件。动态发现。 一个消费者可以动态地感知新的配置、 路由规则和新的服务提供者, 无须重启服务使之生效。动态调整。 注册中心支持参数的原创 2021-09-18 09:00:30 · 2305 阅读 · 0 评论 -
计算机网络-传输层
传输层概述通过网络层、数据链路层和物理层可以建立起主机和主机之间的连接,但是实际上网络上的通讯都是主机应用程序和应用程序之间的通讯,IP数据报达到目的地之后要分发给不同的应用程序,这就是传输层的工作。SocketSocket套接字位于应用层和传输层之间,作为应用层和传输层通讯的通道。多路复用和多路分解多路复用:应用层产生的应用报文通过传输层的TCP/UDP协议会被封装成为应用数据报(UDP)、报文段(TCP),之后通过网络层的IP协议进一步封装成为IP数据报,IP数据报头部的协议字段会标记这原创 2021-09-07 20:29:17 · 2809 阅读 · 0 评论 -
计算机网络-DNS
什么是DNS域名系统DNS(Domain Name System)是互联网使用的命名系统,用来把便于人们使用的机器名字转换为IP地址。为什么不直接用域名,而要用IPIP长度是固定的,而域名的长度是不固定的,对于计算机来说处理IP会更加方便简单,而对于人来说,使用域名比使用IP更加方便简单。简单的工作原理在浏览器中输入www.baidu.com。浏览器从上述URL中抽取出主机名www.baidu.com,并将这台主机名传给DNS应用的客户端,每个计算机都有DNS客户端,用来与DNS服务器通讯。原创 2021-08-28 00:33:52 · 1374 阅读 · 2 评论 -
计算机网络-基础知识
协议在因特网中,凡是涉及两个或多个远程通信实体的所有活动都受协议的制约。例如,在两台物理上连接的计算机中,硬件实现的协议控制了在两块网络接口卡间的“线上”的比特流;在端系统中,拥塞控制协议控制了在发送方和接收方之间传输的分组发送的速率。协议在因特网中到处运行。什么是协议?一个协议定义了在两个或多个通信实体之间交换的报文格式和次序,以及报文发送和/或接收一条报文或其他事件所采取的动作。举一个列子来说:人与人之间进行交流,语言就可以当做协议,比如一个人说中文,一个人说英文,那么他们的协议不同,没办法正原创 2021-08-28 00:33:33 · 442 阅读 · 0 评论 -
Java并发-同步器原理
CountDownLatch在我们实际做开发的时候可能会遇到这样的需求,主线程需要等待所有子线程完成任务之后再执行操作,我们可以用join来实现这个功能,但是join不够灵活,主线程只能等子线程完全执行完毕才能从join返回,而不能在子线程某个位置就执行返回。为了解决这个问题,JDK开发组提供了CountDownLatch这个类,这样的需求通过CountDownLatch来实现会更加优雅、灵活。CountDownLatch的使用public static final CountDownLatch c原创 2021-08-25 00:06:01 · 249 阅读 · 0 评论 -
Java并发-ThreadPoolExecutor
线程池线程池与连接池的概念非常相似,所谓线程池就是在一个容器中装着提前准备好的线程,在我们需要用到线程的时候可以直接从池子中获取,使用完之后返回容器中。线程池解决的主要问题执行大量异步任务时线程池能够提供较好的性能,如果不使用线程池,每次去新建和销毁线程都需要额外的开销。线程池可以进行资源限制和管理,比如可以限制线程的个数,动态新增线程等。根据不同的场景进行参数的定制化可以适应不同的场景要求。ctlctl是一个原子整形AtomicInteger,它用来表示线程池状态和线程池中线程的个数,其原创 2021-08-25 00:05:43 · 196 阅读 · 0 评论 -
Java并发-队列原理剖析
JDK中提供的并发安全队列总的来说可以分为阻塞队列和非阻塞队列,前者使用锁实现,而后者则使用CAS非阻塞算法实现。根据队列是否有长度限制还可以分为有界队列和无界队列。LinkedBlockingQueueLinkedBlockingQueue是由链表实现的一个阻塞队列,其内部通过锁来保证多线程的并发安全性,根据使用的构造函数不同,LinkedBlockingQueue可以是有界队列,也可以是无界队列。// 使用无参构造函数的时候,默认会传入Integer.MAX_VALUE,此时队列是无界的publ原创 2021-08-25 00:05:12 · 461 阅读 · 0 评论 -
Java并发-锁相关知识
LockSupport工具类LockSupport是个工具类,是使用Unsafe类实现的,它的主要作用是挂起和唤醒线程,该工具类是创建锁和其他同步类的基础。LockSupport类与每个使用它的线程都会关联一个许可证,在默认情况下调用LockSupport类的方法的线程是不持有许可证的。park()方法如果调用park方法的线程已经拿到了与LockSupport关联的许可证,则调用LockSupport.park()时会马上返回,否则调用线程会被禁止参与线程的调度,也就是会被阻塞挂起。什么时候才p原创 2021-08-22 16:37:45 · 173 阅读 · 0 评论 -
Java并发-CopyOnWriteArrayList
简述ArrayList不是一个线程安全的类,在我们开发中要让List线程安全可能会用到Vector,而Vector是直接在方法上用synchronized关键字实现线程同步的的,性能有比较大的问题,并发包中提供了CopyOnWriteArrayList,CopyOnWriteArrayList是一个线程安全的ArrayList,对其进行的修改操作都是在底层的一个复制的数组(快照)上进行的,也就是使用了写时复制策略。性能会更好。public class CopyOnWriteArrayList<E&原创 2021-08-20 00:11:47 · 224 阅读 · 1 评论 -
Java并发-原子操作类
简述在Java中我们要保证一个共享变量在多线程环境下的安全问题,最容易想到的就是用锁进行操作的同步,但是用锁的话对性能有非常大的影响,于是Java提供了许多基于CAS的原子操作类来提高性能。原子变量操作类JUC 并发包中包含有AtomicInteger、AtomicLong 和 AtomicBoolean等原子性操作类,它们的原理类似。我们通过学习AtomicLong来一举反三即可,原子变量操作类其内部使用Unsafe来实现。public class AtomicLong extends Numbe原创 2021-08-20 00:11:39 · 261 阅读 · 0 评论 -
Java并发ThreadLocalRandom
简述ThreadLocalRandom类是JDK 7在JUC包下新增的随机数生成器,它弥补了Random类在多线程下的缺陷。Random以及局限性以前我们生成随机数都是用的Random类,如以下代码:public static void main(String[] args) { Random random = new Random(); System.out.println(random.nextInt(5)); //生成0-5的随机数,包含0,不包含5}nextInt内部原原创 2021-08-17 22:56:17 · 209 阅读 · 0 评论 -
JAVA并发基础
线程创建与运行继承Thread类public class ThreadTest { //继承Thread类并重写run方法 public static class MyThread extends Thread { override public void run ( ) { system.out.println ( "I am a child thread" ) ; } } public sta原创 2021-08-17 22:56:01 · 240 阅读 · 0 评论 -
Redis Cluster
简述Redis集群是Redis提供的分布式数据库方案,集群通过分片(sharding)来进行数据共享,每一个分片由一个主从架构负责,提供了复制和故障转移功能。启动集群节点一个集群节点其实就是运行在一个运行在集群模式下的Redis服务器,通过以下配置开启Redis服务器的集群模式:cluster-enabled yes开启集群模式之后,Redis服务器会继续使用单机模式下的服务器功能,会继续使用redisServer来保存服务器的运行状态,与集群相关的数据则会保存到clusterState和clu原创 2021-08-17 22:55:44 · 136 阅读 · 0 评论 -
Redis Sentinel
简介Sentinel(哨兵)模式是Redis的一种高可用解决方案,通过启动多个Sentinel实例对主从结构进行监视,可以做到在主节点宕机的时候自动把从节点提升为主节点,达到高可用的目的。Sentinel节点本身不可以用来处理存储数据,它是一个特殊的Redis服务器。监视主从架构中的各个节点。通过PING,长时间没有响应,Sentinel就会察觉到主节点宕机。通过筛选,从原本从节点中选出一个从节点作为新的主节点。把原本的其他的从节点改为复制新的主节点。监视旧的主节点,如果节点恢复,把原创 2021-08-13 18:52:55 · 224 阅读 · 0 评论 -
JVM-内存模型与线程
硬件效率与一致性CPU在处理任务的时候经常需要用到各种数据,这些数据来自内存,但是内存的IO速度和CPU的计算速度有着几个数量级的差距,如果不进行优化就无法高效的利用好CPU。为了解决这个问题,现代计算机在内存和CPU之间增加了一层高速缓存,这些CPU就可以高速的读写数据而不用等待缓慢的内存读写。缓存一致性缓存一致性问题,在多路处理器系统中,每一路处理器都有自己的高速缓存,他们共用同一主内存。当多路处理器涉及同一主内存区域的操作时,就会有缓存一致性的问题,这种情况下,要同步给主内存的数据到底应该以谁原创 2021-08-12 07:55:53 · 293 阅读 · 0 评论 -
JVM-虚拟机性能监控工具
简述在解决一个问题的时候,知识、经验是关键基础,数据是依据,工具是运用知识处理数据的手段。jpsjps绝对是使用最高频的工具,它可以列出正在运行的Java进程显示它们的PID,PID是使用其他工具的一个重要参数。命令格式如下:jps [options]jstat通过jstat命令了我们可以监控本地或者远程的Java进程的类加载、JVM内存区域的使用情况等运行数据。命令格式:jstat [options] [pid] [interval ms] [count]interval ms:多原创 2021-08-07 10:19:36 · 234 阅读 · 0 评论 -
JVM-垃圾收集器
经典垃圾收集器直接的关系图中连线表示它们可以搭配使用,Serial-CMS组合以及ParNew-Serial Old组合在JDK 9时已经被取消了。CMS与Serial Old直接也有连线,这是因为在CMS发生并发失败的时候(Concurrent Mode Failure)就会用备用方案Serial Old来进行收集SerialSerial是一个单线程工作的收集器,在它开始收集的时候需要暂停全部的用户线程,直到它收集结束。迄今为止,它依旧时Hotspot虚拟机运行在客户端模式下的默认新生代收集原创 2021-08-05 23:14:41 · 690 阅读 · 0 评论 -
JVM-进阶知识
记忆集与卡表JVM通过可达性分析来实现对象死亡和存活的判断,当我们发生年轻代回收时,要枚举年轻代的GC Roots对象,只要在这些引用链上的对象,我们就认为是存活的对象。但是,也有可能一些年轻代的对象会被老年代的对象引用。如果没有记忆集,我们需要遍历所有老年代的GC Roots,这样我们才能正确的标记年轻代的对象是否是存活的,由于跨代引用其实只存在少数,所以这样的操作是非常浪费性能的。为了解决这个问题于是有了记忆集的概念,记忆集就是记录了老年代中那一块区域存在跨代的引用,这样我们就不需要遍历全部的老年原创 2021-08-05 08:30:44 · 229 阅读 · 0 评论 -
MySQL-锁
锁的结构锁在内存中的结构如图所示:当我们去拿锁的时候,就会在内存中创建一个这样的结构,像上图的结构的产生流程如下:事务id为T1的事务,通过sql获取记录的X锁,在内存中就会生成一个锁的结构,结构中记录了事务的信息,并把is_waiting设置为false。事务id为T2的事务,通过sql想要获取记录的X锁,发现内存中已经有锁的结构了,于是生成另一个锁的结构,结构中记录了事务的信息,并把is_waiting设置为true。当事务id为T1的事务执行完成执行,会把内存中指向该记录的其他内存结构的原创 2021-07-30 07:55:56 · 176 阅读 · 0 评论 -
MySQL-redo日志
为什么要有redo日志?MySQL以页作为磁盘和内存的交互单位,在需要对数据进行增删改查的时候,会先把记录所在的页面读取到内存中的缓冲区Buffer Pool内,发生增删改都是在缓冲区中进行操作,然后由后台线程定时的把脏页刷新到磁盘中。因为是异步刷新,数据就可能存在丢失的情况,如何保证数据的持久性呢?最简单的方法,在对缓冲区的也进行增删改之后,事务一提交,就同步把页面刷新到磁盘中,这样可以保证数据百分之百不会丢失,但是却带来以下问题:每个页16KB,如果我们只是修改了一个字节的数据,还是要刷新一整原创 2021-07-28 00:31:37 · 250 阅读 · 0 评论 -
MySQL-Buffer Pool
简述MySQL中磁盘和内存的交互是以页来做单位,对记录进行操作的时候,需要把记录所在的页加载到内存中,页从磁盘到内存加载是要消耗性能的(IO代价),如果每一次对记录的操作都要进行这些的加载,那么对MySQL的整体性能来说是非常不利的,因此MySQL在把页加载到内存操作后并不会立刻释放,而是把页缓存在一个缓存区中,如果又有请求需要操作这个页中的数据,就可以省去加载的IO代价。Buffer Pool我们说了MySQL会把页缓存在一个缓存区中,这个缓存区就是Buffer Pool,MySQL在启动的时候会向原创 2021-07-24 15:42:04 · 412 阅读 · 2 评论 -
MySQL-执行计划
简述一条MySQL的语句,在到优化器的时候,会生成执行计划,我们可以通过执行计划显示的东西来对我们的SQL进行优化。EXPLAIN通过EXPLAIN命令可以查看sql的执行计划。各列解析我们只看最常关注的列。typetype显示该sql对存储引擎的访问方式system:表中只有一条记录,并且使用的存储引擎对数据的统计是精准的(InnoDB不精准,MyIsam或者Memory可以)。const:单表查询,条件是主键或者非NULL唯一索引的等值判断就是const(常数级别)。eq_ref原创 2021-07-23 21:41:15 · 234 阅读 · 0 评论 -
MySQL-优化器如何估算sql成本
sql成本MySQL以以下两个指标来估算一个sql的执行成本IO成本:磁盘与内存进行交互是以页作为单位,读取一次页进内存就计算一次IO成本,MySQL规定一次IO操作的成本是1.0。CPU成本:MySQL查询出来的所有记录,还要计算是否满足条件,MySQL规定一次CPU操作的成本是0.2。优化器在sql达到优化器的时候就会生成执行计划,计算执行这条sql的多个方式,最后会采用分值最低的访问方式。全表扫描分值计算MySQL可以很快计算出全表扫描的分值,因为MySQL有多少记录条数以及记录占用原创 2021-07-22 23:14:33 · 508 阅读 · 0 评论 -
MySQL-连接的原理
on和where在内连接中on和where作用相同,在外连接的时候,on这个子句的语义是“外连接驱动表的记录在被驱动表中找不到匹配记录时是否要加入到结果集中”。连接分类内连接: INNER JOIN外连接:LEFT JOIN, RIGHT JOIN连接的原理嵌套循环连接通过在驱动表中查询到匹配的记录,之后把驱动表的记录作为条件去被驱动表中查询数据。假如我们有以下两张表:执行以下语句:SELECT * FROM t1,t2 WHERE t1.m1 > 1 AND t1.m1原创 2021-07-22 23:14:03 · 363 阅读 · 6 评论 -
MySQL-单表访问方法
条条大路通罗马我们执行一条查询sql,MySQL有多种查询方式可以获取到结果,比如全表扫描、走聚簇索引,如果有二级索引可以先查二级索引再回表查聚簇索引,就跟我们要去一个地方一样,可以现在走路、骑车、驾车等方式,各种方法性能各不相同。访问方法const假如我们有主键id,以及唯一索引列col1,执行以下sql:SELECT * FROM TABLE id = 1;SELECT * FROM TABLE col1 = 'a'; //先从二级索引树定位到一个主键id,在通过该主键id去聚簇索引中原创 2021-07-22 23:13:35 · 259 阅读 · 1 评论 -
MySQL-段、区、组
区如果我们有大量的记录,那么表空间中页的数量就会非常的多,为了更好的管理这些页,设计者又提出了区的概念。对于16KB的页来说,连续的64个页(连续的)就是一个区,也就是说一个区的大小为1MB。(256个区被划分成一个组)为什么需要区通过页其实已经形成了完整的功能,我们查询数据时这样沿着双向链表就可以查到数据,但是页与页之间在物理位置上可能不是连续的,如果相隔太远,那么我们从一个页移动到另一个页的时候,磁盘就要重新定义磁头的位置,产生随机IO,影响性能,所以我们才要引入区的概念,一个区就是物理位置连续的原创 2021-07-21 20:47:05 · 2018 阅读 · 1 评论 -
MySQL-索引结构
查询页内查询为了方便理解,我们简化一下行结构,只保存记录头部信息的record_type和next_record。现在假设我们有一个数据页,如下:可以看到,页内的数据行是形成单列表的结构,同时,页有一个Page Dirctury区域,会把页中所有行数据进行分槽处理,这样就可以通过二分法快速的定位到数据。页分裂页与页之间会形成双向链表,并且上一页的数据行主键一定现在该页的最小主键,因为有着这样的特性,所以每次插入的时候,需要通过必要的移动来保证这个特性,现在我们假设一个页只能存三个数据行(实际原创 2021-07-21 20:46:35 · 291 阅读 · 1 评论 -
Redis慢查询
简述Redis的慢查询功能是一条Redis命令假如执行时间超过了我们设置的时间,Reids就会把这条命令的信息给写到慢查询log中,慢查询log是保存在内存中的,开启慢查询会消耗一定的内存空间。配置项slowlog-log-slower-than:该选项用来指定一个时长,超过该时长的命令就会被记录,单位为微秒(1秒 = 1000 000微秒)。slowlog-max-len:慢查询是保存在队列中的,该参数用来指定队列的长度,长度达到最大值时,队列会移除最旧的log。运行时设置:CONFIG原创 2021-07-14 23:42:23 · 244 阅读 · 0 评论 -
Redis二进制数组(Bit arrays or simply bitmaps)
简述Redis提供了二进制数组(Bit arrays、simply bitmaps)的功能,并使用SETBIT、GETBIT、BITCOUNT、BITOP四个命令来操作二进制数组。二进制数组的结构二进制数组底层是通过SDS简单动态字符串来实现的,因为SDS是二进制安全的结构,SDS buf数组中的每一个元素可以存储8个bit,如一下结构,可以存储16个bit的操作数据。操作命令SETBIT :把bit array的第bit位设置为value的值,value只能是0或者1。GETBIT原创 2021-07-14 23:42:12 · 855 阅读 · 0 评论 -
Redis事务
简述Redis通过MULTI、EXEC、WATCH、DISCARD等命令来实现“事务”,说是事务,其实更像是命令的打包执行。MULTI通过命令MULTI可以开启事务,之后执行Redis命令,除非是事务相关的命令会立刻被执行,其他的命令会被存放到一个队列中,等等后续操作。EXEC遍历执行队列中的命令,执行过程中发生错误不会回滚,会继续执行后续命令。WATCHWATCH是一个乐观锁,要在MULTI命令之前执行,用来监视某一个key,如果key在事务期间被修改,EXEC的时候就会报错,命令队列不会被原创 2021-07-14 23:42:00 · 86 阅读 · 0 评论 -
Redis发布与订阅
命令介绍Redis的发布与订阅由PUBLISH、SUBSCRIBE、UNSUBSCRIBE、PSUBSCRIBE、PUNSUBSCRIBE。PUBLISH:往频道发送一条消息。PUBLISH <channel> <msg>SUBSCRIBE:订阅某一个频道的消息。UNSUBSCRIBE:取消订阅某一个频道。PSUBSCRIBE:通过模式订阅频道。PUNSUBSCRIBE:取消某一个模式。概念解释:频道:类似消息中间件中topic的概念,订阅频道之后可以收到在原创 2021-07-14 23:41:27 · 293 阅读 · 0 评论 -
Redis主从复制
成为从节点通过SLAVEOF命令,可以让执行命令的Redis服务器成为一个目标服务器的从节点。SLAVEOF 127.0.0.1 6379 //执行该命令的服务器将成为127.0.0.1:6379的从服务器新旧版本对于主从数据的复制Redis 2.8版本是新旧版本的分割线,在Redis 2.8及之后的版本,Redis采用了新版本的复制功能,主要是解决旧版本部分复制时存在的效率低下的问题。2.8以前的复制全量复制在执行SLAVEOF命令成为某一个服务器的从节点之后,从节点要同步主节点的数据内容原创 2021-07-13 22:51:13 · 87 阅读 · 0 评论 -
Redis单机模式下命令执行过程
简述Redis是一个事件驱动的程序,Redis基于Reactor模式开发了自己的网络事件处理器,通过IO多路复用程序来同时监听多个套接字,并通过队列排队传输给事件分派器进行处理,事件分派器通过套接字准备执行的操作(accept、read、write、close)关联对应的事件处理器来处理这些事件。事件分派器只有处理完一个事件之后,才会处理队列中的下一个数据。客户端客户端连接到服务器之后,服务器对象redisServer中的list *clients链表会加入一个新的代表客户端的redisClien原创 2021-07-13 00:38:51 · 170 阅读 · 2 评论 -
Redis Ziplist(压缩列表)
简述ziplist是Redis list、hash、zset的底层实现结构之一,当list、hash、zset中节点数量较少,并且存储的大多节点为小整数型,较短的字符串时,Redis就会使用ziplist作为list、hash、zset的底层实现。牺牲时间换取空间拿list来说,实现有双向链表、ziplist。当实现为双向链表时,节点会有pre和next指针,每一个指针占8个字节。而ziplist的entry中,用previous_entry_length保存上一个entry的长度,当上一个entry原创 2021-07-06 23:05:31 · 3261 阅读 · 3 评论