自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(493)
  • 资源 (4)
  • 收藏
  • 关注

原创 netty源码阅读二(内存池之PoolChunk)

这个分享阅读的是4.1.52.Final-SNAPSHOT这个版本的源码jemalloc论文poolChunk表示的内存池中一整块的内存,也是内存池向java虚拟机申请和释放的最小单位,即内存池每次会向虚拟机申请一个PoolChunk内存来进行分配,并在PoolChunk空闲时将PoolChunk中的内存释放。内存池对于内存的分配其最终分配的是内存所处的PoolChunk以及PoolChunk下的句柄handle。重要术语在介绍PoolChunk代码之前先介绍几个比较重要的术语。.

2020-08-08 15:15:50 1333

原创 kafka源码分享----controller

整体架构下图是kafkaController的主要组件的架构图。KafkaController中ControllerEventManager维护一个单线程,维护一个队列接收其他组件产生的event在ControllerEventManager中顺序执行,handlers监听zk的相关节点变化,并在变化时加入相关ControllerEvent到ControllerEventManager中,各...

2020-04-13 11:15:00 425

原创 redis6源码阅读之九(stream)

stream是redis对消息队列比较完备的实现。下面图即为stream的主要的数据结构,可以看到下面的1-20即为其日志的数据,不过在stream中这些日志数据不是通过顺序表来存储的,而是通过rax这个基数树的数据结构来进行存储的。...

2021-05-27 10:59:33 410 1

原创 redis6源码阅读之八(rax)

阅读的版本为6.0.5rax是redis实现的基数树(前缀树),不过其进行了数据的压缩,即将只有一个子节点的子节点压缩到其自己的节点上。下面两张图即为其源码给的关于正常的前缀树和radis实现的前缀树的比较,可以看到其将一个节点的连续的节点都合并为一个节点,入[foo] [er],[ar]这些节点。这种的实现的方式比较节约内存,不过在插入新的节点时比较复杂,需要进行树的分裂操作。数据结构可以看到下面代码和图表示的数据结构,可以看到这个前缀树的单个节点只有iskey,isnull,iscom.

2021-05-14 21:34:14 349

原创 redis6源码阅读之七(rdb数据结构)

阅读的版本为6.0.5rdb时redis持久化的另一种形式,与aof存储执行过的命令形式不同,rdb的存储的是将当前的内存快照数据。redis生成rdb文件主要是有两种形式。一种是利用命令SAVE或者BGSAVE来让服务器生成rdb文件,这两个命令不同的是save命令会让服务器阻塞,而BGSAVE命令则是创建一个子进程,在子进程进行持久化,不会对服务器进行阻塞。另外一种方式则是save seconds changes 这种配置来让redis在seconds时间内有changes个写操作时就会进行.

2021-05-07 16:17:38 313

原创 redis源码阅读之六(aof)

aof和rdb是redis的持久化的两种方式,其中aof是通过将所有的redis数据库执行过的命令都存下来的方式来持久化的,而rdb则是存储的是redis的数据快照。aof的数据格式aof的数据实是文本格式,可以直接阅读的,看下图是set ttt 111 这条命令打印出的日志记录,可以看到它的数据之间是通过\n\r隔开的,然后主要是有两个特殊字符。*: 这个字符主要后接一个数字表示的是这个命令的数据条数$: 这个符号表示的是下面的这个这条数据的长度分析一下下面得到这串字符,可以看到首先的*2

2021-04-29 15:36:44 251

原创 redis源码阅读之五(淘汰机制)

redis在内存超过其配置的maxmemory时,则会通过配置maxmemory-policy的配置的不同策略来淘汰key。这些淘汰策略主要有下面8种配置说明volatile-lru从expires的dict中,利用近似的lru算法淘汰volatile-lfu在expires中找,利用近似的lfu算法淘汰volatile-ttl在expires中找,然后通过ttl计算淘汰volatile-random在expires中随机找节点淘汰allkeys-lru

2021-04-23 11:58:12 176

原创 redis源码阅读之四(zset)

zset是redis的有序集合对象,它是由skipList和dict这两种数据结构来实现的(在数据量较小的时候是用的zipList来实现的)。其中skipList主要是zrank,zrange 这些操作能在o(log(n))的复杂度内完成,而dict中存储的主要是<key,score>的键值对,他能是的zscore这种操作能在O(1)的复杂度内完成。数据结构下面的代码即为zset的数据结构//跳表每个节点的结构typedef struct zskiplistNode { sds

2021-04-21 22:50:39 183

原创 redis源码阅读之三(dict)

dict是redis中使用的很多的一种数据结构,redis中的一个数据库其实就是一个dict,而且redis的hash相关的命令都是通过dict来实现的。dict其实和java中的hashMap很像,他们最大的差异是rehash的操作不同,hashMap是直接对自己的table进行扩容,而dict是会维护两个table,在进行rehash的时候是会创建一个新的table,然后再慢慢地将旧地table中地数据转移到新地table中。数据结构下图展示了dict的数据结构,首先看一下dict的结构,下面代码

2021-04-21 10:43:55 135

原创 redis源码阅读之二(geo)

geo主要是用来获取地图附近的单位(美团的附近商家,共享单车的附近的单车等)。geo通过对地图上的一个一个位置描述用二维的经纬度来表示,经度范围为(-180,180),维度的范围为(-90,90)。而对于获取某个经纬度坐标(x,y)附近的其他的单位的问题,其实类似于下面图中找以坐标点(x,y)为中心的矩形中的单位。其实就是查找坐标点集合中横坐标坐标x1在范围[x-dx,x+dx],纵坐标在[y-dy,y+dy]的所有的位置集合。...

2021-04-16 15:32:34 392

原创 redis源码阅读之一(zipList)

zipList是redis为了节约内存开发而设计的,zipList是内存连续的。zipList的数据结构下面图即为zipLst的数据结构,其中:zlbytes: 记录整个压缩列表的内存的数量,主要是用来进行对这个压缩列表的内存重新分配zltail: 记录的是这个zipList的起始地址到尾节点的偏移量,通过这个偏移量能直接找到这个链表的尾节点zlen: 主要存储的是整个压缩列表的节点的数量,需要注意的是它是两个字节,当其字节超过65535(包括)时,则需要通过遍历才能找到这个zipLi

2021-04-16 15:31:45 218 1

原创 maven源码阅读之二(plexus-classworlds)

plexus本来是想构建一个IOC容器,但是现在这个IOC容器被eclipse-sisu代替了,eclipse-sisu是集成了google的guice和的IOC容器,这个在后面的文章中具体分享,而plexus为maven提供了很多的组件,其中plexus-classworlds就是很重要的一个,plexus-classworlds主要是对java的ClassLoader进行了扩展,提供了一个可以从其他的classLoader中导入class的有向图的依赖结构,并且提供了一个classLoader的加载器池

2021-03-15 22:27:21 1367

原创 maven源码阅读之一(Guice介绍)

阅读版本为4.0.0-alpha-1-SNAPSHOTguice文档guice是google开发的一个轻量级的IOC框架,

2021-03-15 22:26:27 928

原创 AbstractQueuedSynchronizer

节点状态:signal:表示其后续节点需要在其取消或者释放之后唤醒,再将后续节点唤醒时会将状态会切换为0 condition:表示当前节点需要等待condition,这是在condition队列中的 cancelled:表示当前节点已经被取消 propagate:这个状态是让唤醒传播下去,因为在共享模式下,可能会有多个节点出队,几个原则pre节点一定是当前节点对应的线程才会坐更改,所以对于其更新不需要用cas操作next为null的不一定是tail节点,next节点主要是提升...

2021-02-02 10:40:45 223

原创 aqs中关于propagate状态的思考

aqs中队列的节点有多个状态,signal,cancelled,condition,propagate,0这几个状态,其他的状态都很好理解,但是对于propagate这个状态很难理解,它只在doReleaseShared这个方法中会切换到这个状态。在jdk1.6之前是没有这个状态的,引入这个状态是因为一个jdk bug。这个bug展示的是四个线程中两个线程来acquireShared,两个线程来releaseShared,则有可能有一个线程会挂住,一直在等待其他线程的唤醒。下面是具体的代码实现。imp

2021-02-02 10:40:25 1896 2

原创 zookeeper源码阅读之八(数据同步)

zookeeper在经过选举之后,则是会进入恢复阶段,这个阶段leader会从候选的leader变成真正的leader,follower则会根据leader的数据完成自身的事务日志的同步,而同步的相关的代码则主要是zookeeper中的leader,follower和learnerHandler。zookeeper中内部的大部分的协议类型都是在这个阶段进行的。重要概念在具体介绍这个阶段之前,先介绍一下两个比较重要的概念:acceptedEpoch:表示的是NEWEPOCH消息接收的epoch.

2021-01-20 09:53:56 475

原创 zookeeper源码阅读之七(leader选举)

current_epoch:当前的epoch,表示的是真实用来选举的epoch,对于leader的epoch则是用过半的follower的lastAcceptedEppoch+1来确定的accepted_epoch:接受的epoch,表示的是收到的leaderInfo的epoch

2021-01-13 20:08:37 329

原创 Zookeeper源码阅读之六(Zookeeper网络IO架构)

zookeeper集群方式运行时,单个服务器会开启三个端口,分别负责和客户端连接,进行leader选举以及leader和Follower之间的广播操作。下面图主要的展示了在集群下zookeeper的网络IO情况。这张图主要展示了一个已经稳定了的三个节点的zookeeper集群的网络IO情况,其中主要包括一个Leader和两个Follower节点。可以看到每个节点都可以和客户端进行连接,客户端用ClientCnxn来处理对应的IO,而对于每个节点则是为每条客户端连接分配了一个ServerCnxn来与客

2021-01-04 21:23:03 268 1

原创 Zookeeper源码阅读之五(FileTxnSnapLog)

本次阅读的zookeeper的版本是3.4.19zookeeper的数据的持久化主要是依赖两种文件,第一种是snapshot快照文件,一种是log日志文件。对于snapshot文件存储的是这个DataTree和session内存的快照,对于log文件则是顺序存储的事务日志。下面图展示了这两种文件的格式,可以看到这两种文件的后缀都是一个16进制数,对于snapshot文件表示的是在开始这个快照时其对应的最后一个执行的事务id,这表示在做恢复时这个事务id之后的事务都需要重新执行,对于log文件来..

2020-10-26 14:00:20 304

原创 Zookeeper源码阅读之四(RequestProcessor)

本次阅读的zookeeper的版本是3.4.19RequestProcessor是zookeeper对用户请求的核心处理逻辑之处,RequestProccssor通过构建成不同的调用链来完成不同角色下对请求的处理的逻辑。下面图展示了Leader角色服务器下对事务消息的处理逻辑,其中黑色线条表示的是RequestProcessor的处理链。可以看到它的第一个处理器是PreRequestProcessor,这个处理器的主要作用有鉴权以及事务请求加上TxnHeader等信息。其后面接的是Pro...

2020-10-19 17:10:19 434

原创 mysql学习笔记

1.数据库语句的执行顺序(1) from:对左表left-table和右表right-table执行笛卡尔积(a*b),形成虚拟表VT1 (2) on: 对虚拟表VT1进行on条件进行筛选,只有符合条件的记录才会插入到虚拟表VT2中 (3) join: 指定out join会将未匹配行添加到VT2产生VT3,若有多张表,则会重复(1)~(3) (4) where: 对VT3进行条件过滤,形成VT4, where条件是从左向右执行的 (5) group by: 对VT4进行分组操作得到VT5 (

2020-10-16 10:14:36 181

原创 java问题笔记

1.jvm常用命令和作用jinfo:打印对应的虚拟机的参数和系统属性 jstat:命令可以查看堆内存各部分的使用量,以及加载类的数量。如jstat -gc 10000 jmap:dump对应的内存数据jmap -dump:live,format=b,file=myjmapfile.txt 19570 jstack:打印线程信息 jhat:分析内存信息以html形式打印出来 javap:将class文件转化为可读形式 javap -v a.class2.threadLocal的内部实现:T

2020-10-16 10:13:01 373

原创 Zookeeper源码阅读之三(SessionTrackerImpl)

本次阅读的zookeeper的版本是3.4.19SessionTrackerImpl主要是来维护客户端和服务器之间的session,它主要是利用一个轮询线程每次tick检查这一帧需要移除的session并将对应的session移除掉。下面是其对应的数据结构,其中白色底的序列表示的是tick的轮次,绿色底的是对应的session。下面代码是对应的轮询线程的代码,代码很简单,可以看到逻辑就是先等待时间达到下次超时检查时间,然后此次超时时间中需要移除的session标识位关闭,并进行相应的cl...

2020-09-25 16:51:58 249

原创 Zookeeper源码阅读之二(ServerCnxnFactory)

本次阅读的zookeeper的版本是3.4.19前面介绍了Zookeeper的客户端是通过ClientCnxn来与服务端进行交互,与之相对的服务端为每一个客户端连接维护了一个ServerCnxn来进行网络IO操作,而ServerCnxnFactory则是来创建和维护这些ServerCnxn的。ServerCnxnFactory根据其对应的实现方式分为NIOServerCnxnFactory和NettyServerCnxnFactory这两种形式,其中NioServerCnxnFactory是利用.

2020-09-25 13:22:50 252

原创 Zookeeper源码阅读之一(Zookeeper客户端)

本次阅读的zookeeper的版本是3.4.19下面的图展示了zookeeper的客户端的主要架构,可以看到用户是利用Zookeeper来进行相应的接口如(getData,getChildren等)的调用,zookeeper会将用户传入的参数包装成一个Packet,这个Packet中维护了Request,Response以及Watch等数据,它会被加入到outgoingQueue中。SendThread这个线程是一个轮询的线程,它的循环会进行IO操作,其中它的write操作会利用ClientCn.

2020-09-24 11:17:39 310

原创 netty源码阅读之十一(unsafe中的register,deregister,connect,bind等方法)

这个分享阅读的是4.1.52.Final-SNAPSHOT这个版本的源码unsafe是每个channel都会对应的一个对象,把它定义为Unasfe是因为用户是无法直接操作这个接口的,它是由netty内部进行调用的,这个接口主要是用来进行具体的IO的处理的。并且除了register,deregister等,其他方法都需要在eventLoop中完成操作的。下面表中列出了其主要的方法,并列出了由于这些方法可能会fire出的事件,其中红色的方法表示的是这些方法是outbound方法,即这些方法是从ch..

2020-09-16 17:22:08 918

原创 netty源码阅读之十(channel概述)

这个分享阅读的是4.1.52.Final-SNAPSHOT这个版本的源码channel主要是作为网络管道的包装类,对于不同类型的管道进行了抽象,并对它们进行了相应的包装,并对外提供了对应管道的状态,以及相应管道的IO等方法。Channel内部还提供了一个Unsafe接口,这个接口是用于netty内部对channel进行调用,而不由外部来进行操作。在具体介绍Channel之前,有不要介绍一下Channel,ChannelPipeline,ChannelHandlerContext,Chann..

2020-09-15 16:05:01 276

原创 netty源码阅读之九(ChannelOutboundBuffer)

这个分享阅读的是4.1.52.Final-SNAPSHOT这个版本的源码ChannelOutboundBuffer是作为channel写的缓存,即为channel.write(msg)不是将数据写入网络管道中,而是写到ChannelOutboundBuffer中,而是flush操作将channel中的数据从ChannelOutboundBuffer写入到管道中。下图为这个ChannelOutboundBuffer的数据结构,可以看到它主要是维护了一个链表用于存储数据,并且维护了三个节点位置:.

2020-09-10 13:39:49 227

原创 netty源码阅读之八(EventLoop)

这个分享阅读的是4.1.52.Final-SNAPSHOT这个版本的源码EventLoop是netty中很重要的一部分,netty的Reactor线程模型也主要是利用EventLoop来进行完成的,一个EventLoop主要是处理注册到这个EventLoop的Channel的IO操作。下面先来看一下NioEventLoop的继承树,可以看到是还是比较复杂的继承关系。途中的右边的蓝线则是其对应的类的继承,绿色实线则是接口继承关系,绿色虚线则是类实现接口关系。可以看到其最顶层基类是Abstra..

2020-09-07 19:45:56 305

原创 netty源码阅读之七(ByteBuf的方法分类)

这个分享阅读的是4.1.52.Final-SNAPSHOT这个版本的源码ByteBuf是netty自己实现的对byte[],ByteBuffer这两种从堆或者堆外分配的内存的访问和修改的抽象接口,并提供比ByteBuffer更丰富的操作的方法。下面图展示了ByteBuf三个比较重要的变量,分别为readIndex,writeIndex和capacity,它们三个的关系是: 其中read...

2020-08-31 13:25:12 1003

原创 netty源码阅读之六(Recycler)

Recycler是一个基于ThreadLocal的轻量级的对象池,其对象池中的对象都存在各个线程的对应的ThreadLocal中。下面图是一个Recycler对应的数据结构。Recycler为每个线程都绑定了一个Stack对象存储了当前线程下回收的对象,并且一个Map<Stack, WeakOrderQueue>存储一个其他线程创建的对象。可以看到下面的thread1绑定了一个stack1,而stack1在thread2和thread3的Map<Stack, WeakOrderQu

2020-08-27 15:37:23 186

原创 netty源码阅读五(内存池之PoolArena和PoolChunkList)

PoolArena是外部申请内存的主要入口,在多线程处理器中,每个线程都会对应一个DirectPoolArena和HeapArena,而其选取的策略则是轮询找出最少的thread的arena,这种轮询的方式能让每个PoolArena中的Thread更加的平均,下面图则是线程和PoolArena的对应图。这种线程模型保证的是同一个线程对应下分配的PooledByteBuf是在同一块的PoolArena中,但是同一个线程进行free的PooledByteBuf则不一定是同一个PoolArena。因为

2020-08-08 15:18:09 622

原创 netty源码阅读四(内存池之PoolChunkList)

这个分享阅读的是4.1.52.Final-SNAPSHOT这个版本的源码jemalloc论文PoolChunkList主要维护了一个双链表存储PoolArena中的PoolChunk。jemalloc按照内存的使用度将其划分为QInit,Q0,Q25,Q50,Q75 ,Q100这几个类型,下面入是jemalloc论文中的一张图,展示了每种类型的PoolChunkList内存的使用情况。其中的虚线表示一个PoolChunk从一个类别移动到另一个类别其对应的内存度。可以看到对于内存的内存的回收是.

2020-08-08 15:17:32 305

原创 netty源码阅读三(内存池之PoolSubpage)

这个分享阅读的是4.1.52.Final-SNAPSHOT这个版本的源码jemalloc论文PoolSubPage主要是对sizeClasses中isSubPage是1的内存的分配(即大小小于1<<(pageshift+LOG22_SIZE_CLASS_GROUP)的对应的内存)的分配。其主要是在PoolChunk将一页或者多页内存的数据分配为多个第一次请求的内存块,用PoolSubPage来维护。一个PoolArena的所有的可以被分配的PoolSubpage都由PoolAre.

2020-08-08 15:16:52 383

原创 netty源码阅读一(内存池之SizeClasses)

这个分享阅读的是4.1.52.Final-SNAPSHOT这个版本的源码jemalloc论文SizeClassessizeClasses是表示对于内存池中分配的内存大小需要对齐的size,在jemalloc论文中将其分为了三块,分别为Small,Large和Huge。其中Small和Large是在Arena中分配的,而Huge则是直接在Arena之外进行分配的。下面则是其对应的各个size的图。不过对于Netty来说其对应的sizeClasses是有所不同的。下面的表格展示了nett.

2020-08-08 15:14:58 1488 12

原创 spring源码分享之容器系列四(bean的实例化,LookupMethod,ReplaceMethod)

spring-beans中提供的注解主要是在annotation包下的,主要是下面的6个<code>@Autowired</code>

2020-07-28 13:56:41 383

原创 spring源码分享之容器系列三(spring的依赖注入)

spring的依赖注入是spring的依赖的一个很重要的特性,本文详细介绍了spring在进行属性注入的几种方式以及spring源码中是怎么完成这些属性注入的。AbstractAutowireCapableBeanFactory#populateBeanspring中对属性的赋值操作主要是在populateBean这个方法来完成的。可以看到这个populateBean主要做了四件事。调用InstantiationAwareBeanPostProcessor的afterInstantiation.

2020-07-22 20:24:10 367

原创 利用Instrumentation热更新

热更新一种方式是通过classLoader重新加载来进行,通过定义不同的classLoader,监听到文件变化时,卸载原来的classLoader,然后用新的classLoader加载新的jar包,tomcat采用的是这种方式。另外一种方式是利用AgentMain的方式来进行。其主要是利用tools包下的VirtualMachine将agent.jar方法。...

2020-07-14 19:57:19 668 1

原创 关于spring循环依赖的思考

spring主要处理的是属性注入的循环依赖,即beanA的属性中有beanB,beanB的属性中有beanA。而其主要的解决方式则是在创建beanA但是还有没有对beanA进行赋值之前先将beanA的索引注册到容器中,而在beanA进行属性赋值时会引起beanB的创建操作,而在beanB的创建过程中需要进行属性赋值,而其获取beanA的属性值则是获取的beanA先暴露到容器的对象。下面来详细描述一下上面那段解释,首先写一个循环依赖的例子:@Componentpublic class Circ

2020-07-13 10:49:59 160

原创 spring源码分享之容器系列二(类型转换)

spring的类型转换基本上是在TypeConverterDelegate来完成的,其首先是利用PropertyEditor来进行转换的,这个接口是在java.beans中定义的,主要是在GUI上操作的,其主要的转换方式是String类型与其他类型的转换。由于PropertyEditor的局限性,spring自己定义了一套类型转换器,这个类型转换器是定义在spring-core包下,对外接口主要是ConversionService来进行类型转换,而ConversionService则是将类型转换委托给注

2020-07-08 20:10:16 330

电子技术基础_模拟部分(第五版)_康华光_课后答案(无水印完整清洁版)

电子技术基础_模拟部分(第五版)_康华光_课后答案(无水印完整清洁版)

2015-10-30

Python学习手册

Python可移植、功能强大、易于使用,是编写独立应用程序和脚本应用程序的理想选择

2015-09-11

python基础教程(第二版)

python基础教程中文高清pdf【第二版】

2015-09-11

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除