自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(51)
  • 资源 (2)
  • 收藏
  • 关注

原创 基于双向链表实现无锁队列

由于链表的特性,因此可以知道其进行添加元素或者删除元素只需要进行节点的改变即可,同时不需要考虑扩容和缩容的问题,比较方便。那实现队列,需要的是生产者和消费者的模型。其本质是执行进队和出队操作。 代码源于https://github.com/takumiCX/beautiful-concurrent。那么怎样才能实现一个并发无锁的队列呢?首先需要考虑队列是基于链表的,因此我们能操作它的前驱节点和后继节点,同时对数据需要存储到队列中,然后进行消费。为了解决并发问题,我们采用乐观锁+volatile的方式实现。

2021-03-23 15:46:35 661

原创 设计模式之装饰者模式

在前面我们看到了单例模式的使用,在dubbo中,同样有单例模式的使用,找到dubbo中的ExtensionLoader类可以看到这样的代码:/** * Find the extension with the given name. If the specified name is not found, then {@link IllegalStateException} * will be thrown. */@SuppressWarnings("unchecked")public T getE

2021-03-08 23:47:30 205

原创 设计模式之工厂模式

工厂模式工厂模式属于创建型模式,它是创建对象的最佳方式,它负责事项创建所有实例的内部逻辑。工厂类创建产品类的方法可以被外界直接调用,创建所需要的产品对象。它在spring中是非常常见的。工厂模式例子public interface Product{ void show();}创建接口实现类Moblie:public class Mobile implement Product{ @Override public void show(){ System.out.println("H

2021-03-08 23:39:27 217

原创 设计模式之单例模式

在前面中,我们知道如果一个bean需要被加载,首先需要获取资源的位置,然后根据资源位置获取xml文件,然后将其变成document,然后根据document对元素进行解析,然后放入beanDefintionMap中,然后通过getBean获取bean,而这个过程是bean加载的过程。而这里关注的重点是doGetBean。public class BeanFactoryTest { public static void main(String[] args) { //获取xml资源

2021-03-08 23:37:44 187

原创 设计模式之观察者模式

观察者模式观察者模式:Observer Pattern,又称为发布-订阅(Publish-Subscribe)模式,对象之间存在一对多或者一对一依赖,当一个对象改变状态,依赖它的对象会收到通知并自动更新。MQ其实就属于一致观察者模式,发布者发布消息,订阅者获取消息,订阅了就能收到信息,没有订阅的就收不到信息。其核心是将观察者和被观察者进行解耦,以类似消息/广播发送的机制联动两者,使被观察者的变动能通知到感兴趣的观察者们,从而做出响应。特点其优点是可以建立一对多的触发机制,但如果观察者的数量过多,则通知

2021-03-08 23:33:50 184

原创 设计模式之设计原则

1.消息的核心是什么?1) 消息发送publish =>MqClient.publish(topicName, "",new ProducerDataDto(String.valueOf(i)));=>ConsumerController#publish2)消息存储 saveMessage =>msgNotifyService.notify(request);=>MqQueueExcutorService#notifyMsg3)消息消费 doPullingData=>pu

2021-03-08 23:20:40 124

原创 RocketMQ的NameServer执行流程学习梳理

RocketMQ的NameServer执行流程学习梳理首先看流程图从流程图中,我们可以梳理如下信息:首先NamesrvStartUp启动,首先经过main()方法,也是我们常见的main方法进入到main0()执行创建controller操作与启动controller操作这两个操作。而创建controller的操作则首先需要拿到namesrvConfig的配置信息和NettyServerConfig的配置信息,此时会 创建这两个对象,并填充配置信息然后放入到创建的controller对象中的构造函数

2021-03-08 23:15:49 169

原创 RocketMQ的物理偏移量和逻辑偏移量

RocketMQ的物理偏移量和逻辑偏移量消息存储中CommitLog、ComsumeQueue、IndexFile之间的关系CommitLog 文件:消息存储文件,所有主题的消息随着到达 Broker 的顺序写入 CommitLog 文件,每个文件默认为1G,文件的命名也及其巧妙,使用该存储在消息文件中的第一个全局偏移量来命名文件,这样的设计主要是方便根据消息的物理偏移量,快速定位到消息所在的物理文件。RocketMQCommitLog 文件使用顺序写,极大提高了文件的写性能。ConsumeQue

2021-03-08 23:11:48 1393

原创 rocketmq学习2

rocketmq学习2前面我们已经通过quickstrat可以看到nameServer的启动:1.nameServer启动类/** * nameServer启动类 */public class NamesrvStartup { private static InternalLogger log; private static Properties properties = null; private static CommandLine commandLine = nu

2021-03-08 23:07:11 161

原创 Rocketmq学习1

首先从github中拉取Rocketmq的代码,进行运行。1.由于rocketmq需要依赖nameServer,类似于zookeeper。首先启动时,配置好NamesrvStartup的环境变量信息,也即rocketmq的ROCKEMQ_HOME与你的项目对应。接着就可以启动了。/** * nameServer启动类 */public class NamesrvStartup { private static InternalLogger log; private static

2020-08-01 20:35:17 312

原创 Netty学习三

前面我们已经知道Netty服务端启动的时候最重要的是进行bind操作,这个操作不仅进行了run()操作进行死循环,而且将线程任务添加到队列中,进行runAllTasks操作。首先,我们可以看Netty的架构图,图片来自即时通讯网:reactor线程模型图,图片来自即时通讯网:下面是跟踪源码的流程操作: AbstractBootstrap#bind(int inetPort)-> AbstractBootstrap# bind(SocketAddress localAddress)->

2020-08-01 20:33:08 196

原创 Netty学习二

前面我们已经了解了官方的Netty的example,知道要编写一个一个聊天demo或者一个简单的rpc,或者应答模式的demo,在Netty中通常需要写服务端和客户端的引导,而引导是启动服务用的,而服务端和客户端的Handler则是用于处理具体的业务逻辑。这个通常在RPC框架中比如Dubbo,通常会在服务进行暴露或者进行引用的时候,需要调用Netty服务进行启动,然后进行暴露或者调用的,此时采用协议适配的时候,采用适配器模式,而我们知道生产者端最重要的方法就是doBind方法,而在消费者端最重要的方法是do

2020-08-01 20:28:35 175

原创 Netty学习一

前面我们已经学习了NIO的简单知识,三大组件:ByteBuffer、Channel、Selector。知道ByteBufffer是数据,而Channel是数据的载体通道,selector为多路复用。如果说线程池为线程提供了重复利用的途径,而Selector则为起到了调度线程的目的,也即高效率的使用线程。下面我们开始Netty的学习。首先,我们来了解一下mmap、sendFile、零拷贝。在java中,由于传统的IO读写需要进行四次拷贝、四次切换(如图),因此效率上,通常在传输大文件的时候比较低。因此引入了

2020-08-01 20:15:30 453

原创 NIO学习四-Selector

前面我们已经简单的学习了channel,知道channel作为通道,可以在通道中进行读写操作,同时知道ByteChannel是双向的。对于NIO的优势在于多路复用选择器上,在Nginx、Redis、Netty中都有多路复用的体现。因此学习Selector是有必要的。1.使用多路复用选择器的方式/** * selector 选择器 多路复用,选择器结合selectable-channel实现非阻塞效果,提高效率 * 可以将通道注册进选择器中,其主要注意是使用一个线程来对多个通道中的已就绪进行选择,然后

2020-08-01 20:08:32 174

原创 NIO学习三-Channel

在学习NIO时,ByteBuffer、Channel、Selector三个组件是必须了解的。前面我们说到ByteBuffer是作为缓冲区进行数据的存放或者获取。通常我们需要进行flip翻转操作,但是这个在Netty中,有一个更为强大的类可以替代ByteBuf,其不需要进行翻转,也可以进行读写的双向操作。要将数据打包到缓冲区中,通常需要使用通道,而通道作为传输数据的载体,也即它可以使数据从一端到另一端,因此就必须进行了解。Channel中,我们也看到其子类有很多,通常都是用于读写操作的。其中ByteChan

2020-08-01 20:07:25 961

原创 NIO学习二-ByteBuffer

前面我们已经了解到Buffer中,0<=mark<=postion<=limit<=capacity。其中mark是标记,如果为-1时丢弃。postion是当前位置,limit是限制,也即上界。capacity是容量。同时了解了直接缓冲区与缓冲区的底层实现是不同的,缓冲区是基于数组的,而直接缓冲区是基于内存的。同时可以基于反射,拿到cleaner,进而拿到clean进行清理。同时clear是还原缓冲区的状态,flip是反转缓冲区的,rewind重绕缓冲区,标记清除。remianing

2020-08-01 20:06:02 341

原创 NIO学习一-Buffer

NIO相比普通IO提供了功能更为强大、处理数据更快的解决方案。常用于高性能服务器上。NIO实现高性能处理的原理是使用较少的线程来处理更多的任务常规io使用的byte[]、char[]进行封装,而NIO采用ByteBuffer类来操作数据,再结合针对File或socket技术的channel,采用同步非阻塞技术来实现高性能处理,而Netty正是采用ByteBuffer(缓冲区)、Channel(通道)、Selector(选择器)进行封装的。因此我们需要先了解NIO相关的知识。NIO相关知识:首先

2020-08-01 20:04:08 199

原创 CompletableFuture学习

​ 前面我们已经知道CompletionService是可以解决Future带来的阻塞问题的,同时我们除了前面我们看到的take方法之外,还可以使用poll方法,这样可以使你的程序免受阻塞之苦。因为poll方法也是无阻塞性的。同时在kafka的源码中,我们如果使用消费者的话,可以看到会使用一个基于future的poll方法。同时我们可以在dubbo的新版本2.7中,可以看到其异步编程采用的就是我们要介绍的CompletableFuture。因此,我们有必要了解CompletableFuture,同时

2020-08-01 20:01:46 193

原创 CompletionService学习

前面已经说到Future的默认实现是FutureTask,因此你可以看到其在jdk1.5的时候采用的是AQS去实现的,因此具有阻塞性,但jdk1.6之后,可以看到其基于CAS实现的。之所以学习Future,除了其具备异步功能,同时其采用的思想也是在设计模式中有体现的,也即Future模式,而且可以在kafka源码中看到基于Future构建的异步编程。前面说到其基于AQS具有阻塞性,但从源码中,可以看到在jdk1.6之后采用的是CAS:public V get(long timeout, TimeUnit

2020-08-01 19:58:46 214

原创 Future和Callable学习

我们知道使用多线程时,最初的Thread到线程池,此时对于线程的使用,提供了其使用的复用率。而实现多线程的三种方式:继承Thread;实现Runnable接口,重写run方法;实现Callable接口,同时重写call方法,同时通过Future获取执行的返回值。也就是说callable执行任务,而Future拿到执行的结果。Future具有阻塞性在于其get()方法具有阻塞性,而isDone()是不具有阻塞性的。通常使用线程池+Runnable的时候,会发现Runnable不能返回值,也就执行的结果情况,

2020-05-24 21:31:50 332

原创 java8学习整理二

java8不但可以提高代码的运行的性能,而且实现起来很优雅,因此学习它是不错的选择。今天写这篇文章,是因为看到我们部门大佬写的代码,因此将其还原成匿名内部类的时候发现这个retrun是不能省掉的,省去会报错。同时还可以学习到map如果在筛选条件中只有一行的时候,是可以不需要return的,这个是与中间有处理过程是不同的。因此就有了下面的学习:public List<CmPatientBasePO> listAll(Integer fkHospId, Integer fkTenantId) {

2020-05-24 08:22:56 181

原创 java8学习整理

由于项目中使用java8中的lambda表达式,因此想学习一下java8中的lambda表达式和stream流。Lambda表达式的格式:(匿名内部类被重写方法的形参列表)->{被重写方法的方法体代码}例如:public class LambdaDemo1 {public static void main(String[] args) {new Thread(new Runnable() {@Overridepublic void run() { System.out.print

2020-05-24 08:17:07 268

原创 对前端传入的json对象解析成多个对象

在我们的项目中可以看到很多类似的multiRequestBodyDemo(@MultiRequestBody(“dog”) Dog dog, @MultiRequestBody(“user”) User user)的注解,那么这些注解是Spring MVC自带的吗?当然不是,spring MVC中自带的是@RequestBody的注解,这个注解有什么作用呢?这个注解可以将前端传进来的json数据进行解析成json数据。而如果我们没有采样@MultiRequestBody时,通常的做法是将其首先转成json首

2020-05-24 07:59:54 3120

原创 Netty实现简单RPC调用

Netty实现简单RPC调用我们知道Dubbo是一个RPC框架,那RPC框架需要实现什么?需要实现的是调用远程服务和本地服务一样方便,同时提高调用远程服务的性能。而服务端和客户端之间的关系,其实就是一个生产和消费的关系。客户端与服务端交互关系图1.服务消费方以本地调用方式调用服务2.client stub 接收到调用后负责将方法、参数等封装成能够进行网络传输的消息体3.client s...

2020-04-16 17:47:08 453

原创 Dubbo源码学习五-服务消费者发现

首先思考服务消费者发现从类图中,我们可以看到ReferenceBean继承了Referenceconfig,同时实现了FactoryBean、DisposableBean、ApplicationContextAware、InitializingBean,因此可以看到里面会有相应的aware方法、相应的destroy方法、 AfterPropertiesSet方法,这里我们重点关注AfterPr...

2020-04-16 17:42:43 1700

原创 dubbo源码学习四

前面我们已经知道服务暴露分为本地服务暴露和远程服务暴露,同时远程服务暴露又分为:进行服务暴露、服务注册到注册中心、服务订阅。而服务暴露的过程中,其实是进行相关配置的完善,进行相关协议的适配,然后适配到服务器,从而进行createServer操作,而采用默认的dubbo协议时,走的就是NettyServer,进行bind操作之后,进入到NettyServer的创建包括两种线程池:boss和worke...

2020-04-16 17:40:28 540

原创 dubbo源码学习三—暴露服务exporter、invoker

前面我们知道通过自定义标签,我们可以定位到相关标签的解析,同时梳理出三个重要的bean:ServiceBean、ReferenceBean、ConfigCenterBean。通过Servicebean,可以看到ServiceConfig中有我们关注的export方法。通过export,我们可以看到其暴露服务,又分为本地暴露和远程暴露两种,而暴露之前,会进行配置的检查,然后进行url的组装操作,...

2020-04-16 17:38:03 1094

原创 dubbo源码学习二

前面已经知道dubbo的入口可以通过自定义标签找到DubboNamespaceHandler找到解析自定义标签的相关类了。还有4个我们需要关注:ConfigCenterBean、ServiceBean、ReferenceBean、new AnnotationBeanDefintionParser()。下面我们来逐一了解:1.ConfigCenterBean[外链图片转存失败,源站可能有防盗链...

2020-04-16 17:30:10 297

原创 dubbo源码学习一

​ 首先,我们知道dubbo在以前都是基于zookeeper作为配置中心的,同时是建立在spring基础之上的。因此,就需要思考一些问题:​ 首先dubbo是怎样和spring集成的,也即dubbo集成在spring上需要具备什么条件?接着dubbo作为一个服务治理的微服务框架,那它的生产者和消费者与注册中心怎样进行交互的。​ dubbo是基于spring的基础...

2020-04-16 17:25:08 232

原创 JVM学习三

1.类文件结构通常一个java文件,编译之后会变成字节码文件。根据jvm规范,类文件的结构如下:classFile{ u4 magic; #魔数,表示其是否是类文件,0-3字节,ca fe ba be u2 minor_version; #版本,4-7字节,表示类的版本,其中34表示java8,52表示java9 u2 major_version; #主版本, ...

2020-04-16 17:22:07 119

原创 JVM学习二

jvm监控排查问题相关工具:jps、jstat、jinfo、jhat、jstack、jconsole、jmap、MAT、Btrace、psi_probe监控tomcat,通过gceasy查看和GCViewer查看GC,从而解决问题。jps:查看所有的java进程jps -help #显示jps所有的命令参数信息jps #查看有哪些运行的java线程jps -l #输出主类的全名jps...

2020-04-16 17:21:12 118

原创 JVM学习一

JVM学习一jvm的内存结构、相关的垃圾算法、分代回收算法、相关溢出的问题排查思路jvm的内存结构:可以看到我们的java文件会首先编译成class文件,经过类加载器进行加载,然后经过jvm的相关区域:f方法区、堆、虚拟机栈、程序计数器、本地方法栈等地,可以进行本地方法接口进行调用,执行引擎,进行编译,执行程序。当中涉及到垃圾回收。1.程序计数器:Program Count Registe...

2020-04-16 17:18:52 228

原创 ThreadPoolExecutor源码学习

思考线程池的相关参数含义,以及32位的相关含义,拒绝策略以及运行状态?采用executorService创建线程,可以创建线程:newCahcheThreadPool、newFixedTheadPool、newSingleThreadExecutor、newScheduledThreadPool。但点进去看newSingleThreadExecutor可以看到其会调用ThreadPoolExe...

2020-04-16 17:13:47 130

原创 LinkedBlockingQueue源码学习

首先来看一个例子,例子来源于网上:/** * 多线程模拟实现生产者/消费者模型 * */public class BlockingQueueTest2 { /** * * 定义装苹果的篮子 * */ public class Basket { // 篮子,能够容纳3个苹果 BlockingQu...

2020-04-16 17:08:34 685 2

原创 ReentranLock源码学习

首先回答一个问题?线程的三大特性?什么时候我们需要锁?java中已经提供了synchronized,为什么还要使用ReentrantLock?AQS原理。​ 线程的三大特性:原子性、可见性、有序性。也就是说满足这个三个特性的操作都是可以保证安全的,如Atomic包、volatile、通过happensBefore原则可以进行线程的安全的判断,这个依据通常是为了避免jvm指令重排。比如通...

2020-04-16 17:07:16 303

原创 ConcurrentHashMap源码学习

首先思考一下:既然有了HashMap为什么还会出现ConcurrentHashMap?同时ConcurrentHashMap具有什么优势?ConcurrentHashMap与HashMap、HashTable有什么区别?ConcurrentHashMap中的sizeCtl有几种值,这些值代表的是什么状态?ConcurrentHashMap使用了哪些锁?DEFAULT_CONCURRENCY_LE...

2020-04-16 17:02:50 375

原创 HashMap源码学习

首先实现map的子类:HashMap、HashTable、TreeMap、LinkedHashMap。这几个类中HashMap与HashTable的区别:线程上:HashMap是线程不安全的,而HashTable是安全的。key、value的支持:HashMap的key、balue可以为空,而HashTable是key、value不可以为空的。底层数据结构:HashMap采用数组+链表+红黑树...

2020-04-16 16:58:28 120

原创 LinkedList源码学习

前面一文,我们知道ArrayList是给定初始化容量为10,后面进行扩容时是原来的1.5倍。采用位运算向右移一位+原来的容量。扩容的时候将原来的数组元素拷贝到新的数组中,采用arrayCopy复制到新的数组中。其最大容量是2^31-9。其扩容操作是在grow方法中进行的。LinkedList 继承 抽象SequentialList、实现list接口,双端队列Deque以及克隆,因此具备列表、队列...

2020-04-16 16:55:47 123

原创 ArrayList源码学习

ArrayList是一种以数组实现的列表,而数组的优势在于有角标,因此查询的速度较快,是一种可以动态扩容的数组。1.相关变量信息//默认初始化容量为10private static final int DEFAULT_CAPACITY = 10;//为空数组实例准备一个空数组{},如果传入的列表为0时使用private static final Object[] EMPTY_ELEME...

2020-04-16 16:45:18 78

原创 Kafka学习二

Kafka学习二一个正常的生产逻辑具备的步骤: 配置生产者参数及生产者实例 构建待发送消息 发送消息 关闭生产者实例回收资源需要设置的必要的三个参数: bootstrap.servers key.serializer value.serializer消息发送通常有三种方式: 发后既忘、同...

2019-06-06 14:09:03 169

程序员实用算法

2017-04-22

495个必须知道的C语言问题

C语言,495个必须知道的C语言问题!

2016-12-23

空空如也

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

TA关注的人

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