自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(48)
  • 收藏
  • 关注

原创 goland goroutine协程调度

协程调度线程与协程线程与协程我们以Java线程为例。熟悉Java的朋友肯定知道线程,一个Java JVM thread对应一个os thread,是1:1的关系。但是在goland中情况就不是这样的了,多个goroutine可以运行在一个os thread上,是1:n的关系。可以简单理解为goroutine是go对类Java中的thread进行了一层封装。线程与协程的运行基础都是os thread,最底层的任务调度都是基于os 本身的任务切换。线程调度:goroutine调度:...

2022-01-26 16:20:39 645

原创 Spring的BeanFactory和ApplicationContext

BeanFactory和ApplicationContextBeanFactory第一梯队第二梯队ListableBeanFactoryHierarchicalBeanFactory第三梯队ConfigurableBeanFactory第四梯队AutowireCapableBeanFactoryAbstractBeanFactory第五梯队ConfigurableListableBeanFactoryAbstractAutowireCapableBeanFactory第六梯队DefaultListableB

2021-02-24 17:44:50 773

原创 SpringBoot源码解析自动装配

自动加载BeanFactoryPostProcessor生成contextSpring刷新在SpringBoot下,我们并没有告诉Spring应该扫描那个xml配置,也没有告诉Spring是否需要开启自动注入。在SpringBoot下,我们只要使用了@Component 和@Autowired的组合标签即可实现Bean的自动注入。那Spring又是如何帮我们关联上Bean的呢?生成context要了解这个问题,我们还是需要从SpringBoot的启动过程说起。在Boot的run方法中,对帮我们创建

2021-02-21 22:39:01 436 1

原创 Spring 源码解析 Bean创建的主体流程

Bean 主体创建流程runrefreshprepareRefreshobtainFreshBeanFactoryprepareBeanFactorypostProcessBeanFactoryinvokeBeanFactoryPostProcessorsregisterBeanPostProcessorsinitApplicationEventMulticasteronRefreshregisterListenersfinishBeanFactoryInitialization这篇介绍的是Spring中

2021-02-21 15:49:03 354

原创 Spring Bean的创建过程概述

Bean构建总体流程图Bean解析BeanDefinition对象创建名词释义本篇仅简单介绍流程,具体的创建过程,由后续的源码解析部分进行详述。总体流程图简易版Spring Bean的创建过程如下图:简单来讲,Bean的创建有下面几个过程:解析Bean的定义构建BeanDefinition对BeanDefinition进行增强根据BeanDefinition创建Bean对象,其中包括对象的实例化和初始化两个阶段Bean解析我们可以使用XML,propertites,yam文件形式定义

2021-02-20 16:06:26 1495 1

原创 算法 - 栈/队列

栈/队列基于链表基于数组设计栈(队列),push,pop,getMin时间复杂度为O(1)如何仅使用队列实现栈的功能如何仅使用栈实现队列功能相信大家都清楚,栈是先进后出,队列是先进先出。具体该怎么实现这两种数据结构呢?我们可以基于双向链表,或者数组实现:基于链表基于双向链表也可以实现队列:使用链表的方式,可以实现队列的增强,不仅限于队列头添加节点,队尾弹出节点,在队列的任意节点都可以很方便的实现节点的添加和删除,进需要调整下当前节点的pre和next指针。栈的实现也是一样,只是栈从头部进,从头

2021-02-18 13:12:58 260

原创 算法 - 链表

链表单链表反转双向链表反转单链表删除某一个值的节点单链表,链表长度为基数则返回中点元素,偶数则返回上中点元素单链表,链表长度为基数则返回中点元素,偶数则返回下中点元素单链表,链表是否是回文结构单链表反转将链表的头结点变成尾结点/** * 翻转单链表 * * @param head * @return */ public static Node reverseLinkedList(Node head) { // 预存前节点

2021-02-18 13:10:51 544 1

原创 算法 -前缀树

前缀树假设我们现在有字符"a",“ab”,“ac”,“bc”,“123”,“35”,“73”,问:以"a" 开头的字符有多少个?是否有以"3"字符结尾的?是否存在"235"这样的字符?针对这种,我们可以根据所有字符,构建出一颗字符的前缀树:我们可以以每一个字符,构建出一个节点,每一个节点包含两条信息:through:通过该节点的数量,end:以该节点结尾的数量。我们先来处理字符"a":由于我们在当前的tree中还没有“a”这个字符,我们先创建出这一点一个节点:由于“a"经过root

2021-02-17 18:03:14 345

原创 算法 - 排序

排序选择排序冒泡排序插入排序归并排序快速排序选择排序什么是选择排序?选择排序,就是从一堆数中有选择的挑选出最小的那个数。算法核心思想:每一次遍历,找出所有数字中最小的那个,放到最前面去。假设现有数组:a[] = [6,3,4,2,1,5]数组总长度 n = 6;第一次:index=0,从a[]下标为 0 -> (n-1)中选出最小的数字,放到index处,即a[0]和a[4]数值交换a[]=[1,3,4,2,6,5],此时a[0]为所有数字的最小值第二次:index=1,从a[]下标

2021-02-17 16:53:21 106

原创 算法 - 运算符

运算符与 &保留右边第一个1,其他全部置为0计算二进制中1的个数异或^交换数值如何不借用第三方变量找到唯一出现奇数次的那个数找出出现奇数次的两个数与 &与操作,二进制位上如果不相同则记为0:1001 & 1101 =1001保留右边第一个1,其他全部置为0现有数字A = 100010001100100,需要保留右边第一个1,其他全部置为0:先对A进行取反: ~A=011101110011011取反后+1 :~A+1 = 011101110011100再与A: (~A

2021-02-16 23:49:26 392

原创 Tomcat源码解析如何支持NIO

Tomcat支持NIO我们前面介绍过了JDK里的NIO,那在实际生产环节又是如何使用的呢?目前公司实际业务使用的是Tomcat8,我们以Tomcat8为例简单介绍下。在Tomcat官网Advanced IO章节有介绍,based on NIO/NIO2,内容相当少。基于官方文档,我们尝试在tomcat源码中寻找NIO/NIO2相关的类信息:经过一番搜寻可以很明显的看到NIO相关的信息。channel,selector,pool经验告诉我们这些都不可能是业务处理的核心逻辑,剩下的就只有这个end

2021-02-10 17:11:19 255

原创 java多线程之间数据通信

线程数据通信使用共享变量/对象父子线程通信Exchanger管道我们知道Java每个线程之间是数据隔离的,那在多线程环境下,两个线程之间,如何进行数据传输呢下面我们以main线程中新起一个子线程的方式,来模拟两个线程之间数据通信的场景。使用共享变量/对象 private static String name = "张三"; public static void main(String[] args) { System.out.println("主线程:name :" +

2021-02-09 17:46:38 644 1

原创 基于netty实现自有协议的RPC

RPC场景引入RPC代码本章节我们介绍下如何使用netty实现RPC场景引入我们先来想象一下这样一幅场景:现在有一个用户A想买辆车,但是A对车子不是很熟悉,于是他打电话给他的朋友B进行咨询:A:兄弟,我想买辆车B:想买辆什么样的车啊A:我不是很懂车子,我说几个品牌你帮我参考下。法拉利怎么样?B:911,跑车啊,是好车!A:那兰博基尼呢?B:那是男人心中的梦想!A:那我大概知道了,那就兰博基尼好了,那我买什么颜色好呢?红色咋样?B:红色啊,红艳艳的,不错哦A:我看还有一辆紫色的,紫色

2021-02-09 13:01:56 264

原创 Redis击穿、穿透、雪崩

Redis击穿穿透雪崩我们前面讲过Redis可以做为DB使用,也也可以做为缓存使用。在做为缓存使用时有可能会遇到击穿、穿透、雪崩的情况。注:这些情况,只会在Redis做为缓存使用时才会出现,此时在我们应用的后端,必然还有一个物理DB存在击穿所谓击穿,就是在高并发的情况下,Redis某一个key,由于有效期到了,或者LRU策略导致被清理了,在某一个时间的瞬间,这个key不存在了,但是在高并发下此时由大量的请求同时到达,假设1w个请求,此时去查询Redis缓存,key不存在,必然导致这1w个请求都会

2021-02-09 00:58:40 681

原创 Java 代码如何支持多路复用

多路复用

2021-02-07 20:21:40 994 3

原创 IO多路复用模型

多路复用上一章节我们介绍了NIO模型,我们先来回顾一下NIO模型:

2021-01-27 15:40:13 911

原创 Java NIO模型

NIOBIO问题NIOBIO问题通过前面两个章节的介绍,相信大家已经对网络BIO模型已经有了不少了解了。那么BIO主要的问题点在哪里呢?我们来回顾下BIO模型的架构图:client与service经历三次握手之后,service在内核中开辟空间,分配FD,socket主线程bind到该FD后,clone出子线程来接收client传输的数据以及业务处理。如果简单的使用此模型,我们可以看到每一次接收到client连接,都需要创建出新线程,而我们也知道计算机创建新线程的代价是很大的,内存分配(每个线程约

2021-01-24 19:50:05 451 1

原创 Java BIO模型

网络IOBIO前面我们简单介绍了网络之间是service和client是如何建立通信的,这次我们来看下两方是如何交换数据的。使用的service和client代码和前一章一样。BIO首先我们先来看下基础的网络BIO模型是如何运作的,为了讲解清楚过程,我们还是以实际运行结果展示。注:环境以mac os 10.14.6位基础,部分命令以及展示结果与Linux会有不同,不过基本上大同小异。我们这次在service运行时,追踪一下service进程的系统调用情况:还记得我们Service中的代码逻辑

2021-01-23 17:05:34 217

原创 网络IO模型

TCP实际操作演示通信三次握手连接唯一性BackLog,TimeOut实际操作演示这章介绍下TCP网络通讯协议的工作原理。首先我们使用Java代码编写一个service端和一个client端,让两者建立通讯。注:使用环境适用于Linux/Unix环境我们先来看下Service端:我们再Service端定义一个9091端口,新建一个ServerSocket并且绑定9091端口。下面我们将Service 运行起来:现在我们已经在shell中将service run起来了,端口号是9091。请

2021-01-19 10:36:30 266

原创 文件IO

文件IO文件读取文件加载虚拟目录:文件描述符(FD)一切皆文件文件IOpageCahcedirty刷盘LRUbufferfile NIO在计算机中,IO有很多种,常见的文件IO,网络IO,我们常用的鼠标键盘这些也都是IO设备。今天主要介绍下文件IO文件读取先简单看下我们的应用是怎么读取到文件的:在我们的内存中,主要被分为了两块区域,一块OS内核的专有内存,另外一块是我们运行的其他程序的内存。文件的读与写,都是由kernel统一管理,针对文件这块,kernel会对文件虚拟出一个文件目录树,当需要读

2021-01-17 23:16:28 168 1

原创 java 常见GC

GC常见GCSerialSerial oldParallel Scavenge(PS)Parallel old(PO)ParNewCMS(concurrent mark sweep)G1RegionYoung GCMixed GCFull GCZGC概念并行并发card tableCSet(Collection Set)RSet(Remembered Set)GC和内存容量常见GCSerial随着JDK诞生,使用的垃圾回收器就是Serial这是一种单线程垃圾回收器,串行工作那么它是如何工作的呢?

2021-01-10 21:35:34 969

原创 Java GC - 分代

GC-分代垃圾对象识别垃圾引用计数(reference count)可达性分析(root searching)root节点垃圾清除标记清除拷贝标记-压缩GC种类内存分代对象生命流转垃圾对象在Java里面,什么样的对象,是垃圾对象呢?通俗来讲,就是没有任何引用指向的对象,即为垃圾对象,在内存中占着空间,但是没有任何引用会引用到它。Java中有专门的GC(垃圾收集器)来处理垃圾,一般情况下,开发人员不需要特别关注垃圾对象的处理。识别垃圾现在清楚了什么是垃圾对象,那GC又是如何判断这个对象是否是垃圾呢?

2021-01-10 02:13:50 288

原创 MySql 主从复制延迟

主从复制主从复制原理延迟原因数据一致性组提交查看同步延迟解决延迟问题主从复制原理我们先来看下主从复制的原理:当Master有数据改动之后,会将数据写入自己的bin log文件,Slave上会有一个I/O thread 线程,拉取Master的bin log文件,写入自己的Relay log(中继日志),再由Slave上的SQL thread来读取解析加载Relay log中的数据延迟原因我们按照上面原理图来分析下主从复制同步延迟耗时的原因:从Master写入bin log 耗时Slave的

2020-12-13 18:15:18 644 1

原创 RockmetMQ消息持久化

消息存储零拷贝文件存储零拷贝RockmetMQ的持久化,是基于文件系统的,采用零拷贝技术文件存储我们进入一个Broker,查看其内部是如何进行文件存储的。主要有以下几个文件:commitlog,config,consumequeue,indexcommitlog:存放每一条消息的消息实际内容,因采用零拷贝技术,其大小是由限制的,一般默认是1G。采用append方式,存储的每一条之间是无序的。如上图,有两个Producer,共产生6条消息,在commitlog中,6条消息的先后存储顺序是随机的

2020-11-19 19:54:03 142

原创 RocketMQ 拉取消息

start在上面的start章节,我们从源码中可以看到这么一行代码:

2020-10-25 20:49:05 1717

原创 RockmetMQ Consumer start(1)

Consumer代码结构代码start负载均衡继续startoffset继续start代码结构首先来一个直观了解:Consumer默认共有两种类型,分别是DefaultMQPullConsumer和DefaultMQPushConsumer两个默认Consumer分别有自己的实现:DefaultMQPullConsumerImpl和DefaultMQPushConsumerImpl。消息的消费方式也有两种,分别是ConsumeMessageConcurrentlyService和ConsumeM

2020-09-08 12:22:01 336

原创 RocketMQ 一

RocketMQFIFO (先进先出)事务消息消息重试FIFO (先进先出)当一个Producer连续发送了多条消息,彼此之间有顺序。要求Consumer在消费消息时也必须按照顺序进行消费,RocketMQ如何保证消息的顺序消费呢?Producer在发送消息时指定同一个topicProducer在发送消息时,需要将消息放入同一个QUEUE(类似于Kafka的Partition),通过实现MessageQueueSelector或者指定Queue。Producer发送消息时需要由一个线程去发送消

2020-09-06 13:47:26 106

原创 MySQL之日志

日志redoundobinlog事务MySQL日志有3种:redo官方文档:https://dev.mysql.com/doc/refman/8.0/en/innodb-redo-log.htmlredo log是重做日志,提供前滚操作。redo log是物理日志,记录的是数据行的物理修改,当数据需要恢复时,可以从redo log中恢复到数据最后一次的修改状态。redo log包含两块内容,一部分是日志缓冲(log buffer),在内存中;另一部分是日志重做文件(log file),在磁盘

2020-06-28 15:26:08 197

原创 MySQL之分区

分区分区类型工作过程注意项官网地址:https://dev.mysql.com/doc/refman/8.0/en/partitioning.html假设现在有提条业务线,需要用到100张表,每张表里面有100w条数据,我们现在需要遍历这些数据,从中取出一条符合条件的记录,最坏情况,可能需要遍历100*100w,这数据量是多么庞大。这时候我们就需要对表进行拆分了:垂直拆分:可以按照业务线维护进行聚合,如按照订单表,用户表,商品表等多种业务维度进行聚合到一个DB水平拆分:将每张表里面的100w条

2020-06-27 21:11:45 216

原创 MySQL之优化

优化慢因优化访问优化过程优化慢因罗列下执行效率变慢的几个原因:网络波动CPU过载I/O阻塞线程上下文切换调用系统资源阻塞锁等待优化访问优化为了减少I/O压力,查询时,可以通过减少访问数据量的方式进行优化。确认程序是否存在检索了大量超出需要的数据确认MySQL server是否存在分析大量超过需要的数据行向数据库请求了大量业务中不需要的数据case1举个栗子:使用order by默认是进行全表扫描的,但是如果我们能够使用索引进行order by,则不需要进行全表扫描,减少

2020-06-26 16:00:36 201

原创 MySQL调优之索引

索引

2020-06-15 22:59:34 351

原创 MySQL 调优之执行计划

执行计划概述idselect_typetabletypepossible_keyskeykey_lenrefrowsextra概述当我们写完了一条SQL语句给数据库执行,那数据库是如何执行的呢?这就涉及到SQL的执行计划了。现有需求:我们需要查看一年级有哪些学生:select * from student s join greade g on s.class=g.greadeCode where g.greadeCode =1;如何查看上面这条SQL的执行计划呢?很简单,加上explain命令

2020-06-07 20:00:09 377

原创 MySQL 调优之性能监控

性能监控MySQL基本架构:show profileperformance schemaMySQL基本架构:想要了解SQL的性能,我们需要先了解下MySQL是如何玩起来的:连接器:负责跟客户端建立连接,获取权限,维持和管理连接,包括用户名密码验证,权限的查询与分配,自动断开连接等,可分为长连接和短连接。查询缓存:当执行查询语句的时候,先去查询缓存中的数据,如果能找到结果则直接返回,如果没有,再去数据库中进行查询。如果数据更新比较频繁,只要表更新,缓存就会被清空,此时不建议使用缓存,命中率会比较低

2020-06-07 15:35:54 419

原创 分布式事务

分布式事务两段式提交(2PC)三段式提交(3PC)3PC vs 2PC基于消息的一致性假设现在客人下单成功了,我们需要落订单信息,调整库存信息,落订单快照信息等多项操作,但是这些信息在不同的数据库集群中,如何通过事务保证数据准确呢?两段式提交(2PC)何为两段式提交?两段式提交,即为通过一个中间者TM来协调所有数据库的动作,TM先发送预提交指令(第一阶段),再发送提交/回滚指令(第二阶段)具体过程如下:client提交事务请求到TMTM向每个数据库发送可以提交指令每个数据库处理自己的数据(增

2020-05-31 15:42:12 162

原创 分布式锁

分布式锁锁线程锁分布式锁Redis实现分布式锁简单讲述下Redis为什么可以做分布式锁:锁线程锁相信大家在写代码中遇到多线程有资源竞争关系时,第一反应是加锁,Synchronized,Lock,这种属于线程锁,只在单个JVM中有效。如果在分布式系统中又是个什么情况呢?分布式锁现在假设有这样一种场景,有3台服务器组成一个集群,有一个商品,库存数量为1。现在有6个客人都想购买这个商品,假设他们同时都发送预定请求。假设现在6个请求同时到达各自的服务器,同时假设每台服务器的每个线程处理速度一致,则6个

2020-05-29 20:34:03 158

原创 JVM之JMM

JMM内存分布MarkWord运行时数据区栈帧Frame在上面的Class加载章节中,我们讲解了JVM是如何将Class文件加载进内存的。那当我们对这个Class进行实例化之后,JVM又是如何处理这个实例化对象的呢?我们今天来了解下Java的内存模型JMM内存分布当我们在代码中写完 T t = new T(),我们知道这是这是将Class T实例化了一个t对象,那这个t对象,在内存中是如何体现的呢?主要分为普通对象和数组对象,差别不大,我们先看下普通对象的内存分布情况:实例化的普通对象t的组成主

2020-05-24 15:16:58 310

原创 硬件级多线程保障

硬件与多线程存储结构图数据一致性总线锁缓存一致性协议缓存行对齐小demoWCBuffer(write combining buffer)CPU乱序执行CPU 内存屏障JVM内存屏障存储结构图对于现代CPU,广告中我们经常可以听到一个三级缓存的概念。其中第一级和第二级缓存,为每个CPU核心独享,第三级缓存,是所有CPU核心共享,缓存集成在CPU内部,读取写入速度非常快,但是容量很小再往下一级便是我们的内存,容量大,读写速度相对较快,再往下便是我们的磁盘, 容量可以非常大,但是读写速度比较一般。那整

2020-05-21 20:43:16 959 1

原创 JVM之Class加载

Class Load我们编译后的.class文件是如何被JVM加载进入内存的呢,中间经过了哪些个步骤呢?如下图:主要是经过这么几个步骤:loading加载linking- verifiy验证阶段- prepare准备阶段- resolute解析阶段初始化...

2020-05-18 12:57:20 302

原创 JVM之Class文件

ClassLoader我们先看下我们的代码是如何在JVM层面跑起来:

2020-05-12 13:35:51 166

原创 读懂Java线程池

线程池Java容器线程池Executor、Future、FutureTaskExecutorFutureFutureTaskThreadPoolExecutor执行过程实现原理线程复用Java容器在Java中,容器共有2大类,一种是Collection,另一种是map。其中Collection下又有2中集合类型,一种是普通存储数据类的list以及set,还有一种是为高并发服务的queue。为...

2020-05-05 16:04:14 642

空空如也

空空如也

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

TA关注的人

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