自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 Java堆中的年轻代为什么要设置Survivor区?为什么还要设置两个Survivor区?

1 年轻代只设置一个Eden区行不行?如果只设置一个Eden区,那么没进行一次MinorGC,存活的对象就会被送入老年代,老年代很快被填满,就会触发MajorGC,因为MajorGC之前会先进行一次MinorGC,所以也可以看做是发生了Full GC,Full GC消耗的时间要远远大于Minor GC,这样会增加系统停顿时间。那么,你们也许会想,可以增加老年代的空间,减少Full GC的频率,可以是频率虽然降低了,但是由于老年代存储的对象太多,一旦发生Full GC,单次GC的时间增加了,系统停顿时间依然

2021-03-06 23:54:27 863 2

原创 JVM垃圾收集器

介绍JVM堆内存主要分为新生代和老年代,其中新生代占用1/3堆空间,老年代占用2/3堆空间,其中新生代又细分为Eden区、Survivor区、SurvivorFrom区,分别是8:1:1。JVM针对新生代和老年代分别提供了不同的垃圾收集器。针对新生代的垃圾收集器有:Serial、ParNew、Parallel Scavenge;针对老年代的垃圾收集器有:Serial Old、Parallel Old、CMS;还有不分新生代和老年代的垃圾收集器G1,G1垃圾收集器是针对不同区域的G1分区收集算法。新生代

2021-02-08 16:45:40 94

原创 保证接口幂等性的4种方案

1 什么是接口幂等性接口幂等性是指一次和多次请求某一个资源对于资源本身应该具有相同的结果,即任意执行多次执行对资源本身所产生的影响与一次执行的影响相同。2 为什么需要实现幂等性前端重复提交表单;用户恶意进行刷单;接口超时重复提交;消息进行重复消费;3 引入幂等性对系统的影响引入幂等性后有如下影响:把并行执行的功能改为串行执行,降低了执行效率;增加了额外控制幂等性的业务逻辑,复杂了业务功能所以在使用的时候需要考虑是否需要幂等性,一般情况下不需要引入幂等性4 请求方法类型是否满足

2021-02-07 18:05:21 1198

原创 SpringBoot自动装配原理

SpringBoot项目无需各种配置文件,一个main方法,就能把项目启动起来。那么我们看看SpringBoot是如何进行自动配置和启动的。SpringBoot通过main方法启动SpringApplication类的静态方法run()来启动项目。根据注释的意思,run方法从一个使用了默认配置的指定资源启动一个SpringApplication并返回ApplicationContext对象,这个默认配置如何指定呢?这个默认配置来源于@SpringBootApplication注解,这个注解是个复

2020-07-21 15:22:12 38742 17

原创 一致性hash算法

1. ip_hash算法存在的问题如下图所示,一旦下标为2的服务器,即Tomcat 3发生宕机了,则服务器的数量发生了变化,由3变为2,最后hash算法的结果也发生更改,比如:5%3=2变为了5%2=1,所有的请求都要重新进行求模运算,最后导致用户在原来服务器里面的会话发生丢失,响应的数据缓存也丢失。2. 一致性hash算法如下图所示,将一组数字组装成一个环形,假设有一台服务器,它的ip地址经过hash算法计算后的结果放到环形中,随后,所有的服务器节点都顺时针的放在环形的特定位置中。然后,用户的ip

2020-05-27 16:39:04 179

原创 Redis和MySQL如何保证数据一致性

Redis用来作为应用和数据库之间的缓存层,主要目的是为了减少数据的IO,提升IO性能。当应用程序需要读取某个数据时,会先从Redis去查询,如果命中则把数据返回,否则再查询数据库,查询到数据后再把数据缓存到Redis中。在这样的架构中,数据会同时存储在Redis和数据库中,当数据发生变化时,Redis和数据库需要同步更新,由于更新数据是有先后的,所以会出现数据一致性问题。无论选择哪种方法,由于两个操作不是原子的,都会出现一方失败导致的数据不一致问题。

2023-06-24 00:01:34 454

原创 缓存雪崩和缓存穿透的解决方案

缓存雪崩是指存储在缓存里面的大量数据,在同一时刻全部过期,大部分流量直接到达了数据库,导致数据库压力增加,造成数据库崩溃的情况。

2023-06-23 22:27:06 509

原创 零拷贝原理分析

上述步骤中,数据是经磁盘->内核空间->用户空间->内核空间->网卡,其中内核到用户,再从用户到内核是多余的操作,零拷贝就是将这两个多余的操作省略掉,让程序可以直接把数据从磁盘经过内核空间传递给网卡,不需要再经过应用程序所在的用户空间,降低了拷贝以及CPU上下文切换所造成的资源占用。

2023-06-18 19:37:55 109

原创 如何保证线上MQ消息不丢失

要保证MQ消息不丢失,需要保证每一步的可靠性。

2023-06-18 12:29:05 174

原创 MVCC原理

数据库并发带来的问题数据库并发会带来脏读、不可重复读、幻读等问题。脏读:当前事务读取了其它事务未提交的数据;不可重复读:当前事务中,在相同的查询条件下前后读取的结果不一样,主要侧重于查询记录的某些列不一样;幻读:当前事务中,在相同的查询条件下前后读取的结果集不一样,主要侧重于查询记录的个数增加或减少;数据库隔离级别数据库采用了事务的隔离级别来解决这些问题。读未提交:当前事务可以读取其它事务未提交的数据,不解决脏读、不可重复读、幻读的问题;读已提交:当前事务可以读取其它事务已提交的数据,

2021-02-17 14:01:25 206 1

原创 Spring如何解决循环依赖

什么是循环依赖比如:在A类引入b对象,在B类引入A对象,创建a的时候需要依赖b,创建b的时候需要依赖a,而各自创建对象的时候,其互相依赖的对象还没有创建完成,就导致各自都无法成功创建对象。这就是循环依赖。class A { private B b;}class B { private B a;}解决循环依赖的方法很简单,如下所示,先实例化A和B,此时都没初始化,即都没有对各自对象里面的属性进行赋值,接下来可以通过set方法,把实例a和实例b set到各自的对象属性中去,这样一

2021-02-09 20:41:09 215

原创 Spring AOP的原理

1. Spring AOP介绍Spring AOP通过面向切面技术将与业务无关却为业务模块所共用的逻辑代码封装起来,以提高代码的复用率,降低模块之间的耦合度。Spring AOP将应用分为核心关注点和横切关注点两部分。业务处理流程为核心关注点,被业务所依赖的公共部分为横切关注点,比如:权限认证、日志、事务等。2. Spring AOP概念Spring AOP包含以下几个概念:横切关注点:定义对哪些方法进行拦截,拦截后执行哪些操作;切面(Aspect):横切关注点的抽象;连接点:被拦截到的方法(

2021-02-09 16:02:45 73

原创 Java中常用的垃圾回收算法

如何确定垃圾Java中采用可达性分析算法来确定对象是否应该被回收,可达性分析算法通过一系列的GC Roots的点作为起点向下搜索,GC Roots主要包括栈中的引用(当前正在调用的方法中局部变量的引用)、方法区中静态变量和常量的引用、本地方法栈中的引用。当一个对象到任意GC Roots都没有引用链的时候证明该对象可以回收。标记-清除算法(内存碎片多)标记-清除法首先会标记可回收的对象,在清理完对象后,并没有重新整理可用的内存空间,如果内存中回收的小对象比较多,会引起内存碎片化的问题,后期大对象则无法获

2021-02-08 13:33:40 165

原创 JVM堆

Java中常用的垃圾回收算法有复制法、标记-清除法、标记-整理法、分代收集算法。复制算法标记-清除算法标记-整理算法分代收集算法

2021-02-08 11:14:31 62

原创 SpringBoot启动流程

@SpringBootApplicationpublic class AdminApplication { public static void main(String[] args) { // 执行main方法 SpringApplication.run(AdminApplication.class, args); }} public static ConfigurableApplicationContext run(Class<?> prim

2021-02-08 09:45:36 141

原创 类加载器和双亲委派模型

类加载器JVM提供了三种类加载器:启动类加载器、扩展类加载器、应用程序类加载器。他们所加载的内容如下:启动类加载器:加载JAVA_HOME/lib下面的jar;扩展类加载器:加载JAVA_HOME/lib/ext下面的jar;应用程序类加载器:加载用户路径下的jar,比如我们自己写的代码,会加载classpath路径下的类;除了上述三种方式,我们可以继承ClassLoad类来自定义自己的类加载器。双亲委派模型双亲委派模型:当一个类加载器收到类加载请求的时候,不会自己去加载这个类,而是向上请

2021-02-07 15:35:57 93 1

原创 new一个对象的过程

如上图所示,在JVM创建一个对象的时候,首先判断当前类是否已经加载,如果类没有加载,需要先执行类加载机制,当加载完成后再为对象分配空间、初始化等等。类加载过程如下:加载:读取某个类的class文件到方法区内,并在堆中为这个类创建对应的Class对象,在加载时候可以通过类文件、jar、war包的形式读取;验证:验证class文件是否符合当前虚拟机的规范;准备:为类的静态变量(无final修饰)和常量(final修饰)赋默认初始值,放入到方法区中,值得注意的是,常量直接赋予初始值,设置为多少就赋予多.

2021-02-07 15:00:14 2784

原创 JVM的内存结构

JVM主要包含几个区域:堆:堆是JVM中线程共享的内存区域,堆上存储对象、数组、变量等信息。堆中细分为年轻代和老年代,其中年轻代又细分为Eden、SurvivorTo、SurvivorFrom等3个部分,默认比例是8:1:1。虚拟机栈:虚拟机栈是线程私有区域,每个方法执行的时候都会在栈中创建一个栈帧,方法的调用过程就对应了入栈和出栈的过程。每个栈帧包含局部变量表、操作数栈、动态链接、方法返回地址。局部变量表用于存储方法参数和局部变量,是一个数组结构;操作数栈用于保存计算过程中的中间结果,存储一些

2021-02-07 14:23:08 48

原创 什么是GC Root

1 GC ROOT的定义我们知道,JVM中判断一个对象是否标记为可回收的对象是根据可达性分析算法,顾名思义,可达性分析需要知道当前对象(是否需要回收的对象)的起点,而这个起点对象在当前时刻一定是存活的,才能保证对当前对象是否需要回收的判断是正确的,所以GC Root表示:当前时刻存活的对象。2 GC ROOT对象都有哪些?先说概念:当前正在被调用的方法里局部变量引用的对象,即虚拟机栈的局部变量表中引用的对象;方法区中静态变量引用的对象;方法区中常量引用的对象;本地方法栈中Native方法引用

2021-02-07 11:44:43 5820 1

原创 继承关系下构造方法执行顺序

public class Father { static { System.out.println("父类静态代码块"); } { System.out.println("父类代码块"); } public Father () { System.out.println("父类构造方法"); } public static void main(String[] args) { new Son(); }}class Son extends Father { stat

2021-02-03 17:38:04 279

原创 接口幂等性的四种方案

1 什么是接口幂等性接口幂等性是指一次和多次请求某一个资源对于资源本身应该具有相同的结果,即任意执行多次执行对资源本身所产生的影响与一次执行的影响相同。2 为什么需要实现幂等性前端重复提交表单;用户恶意进行刷单;接口超时重复提交;消息进行重复消费;3 引入幂等性对系统的影响引入幂等性后有如下影响:把并行执行的功能改为串行执行,降低了执行效率;增加了额外控制幂等性的业务逻辑,复杂了业务功能所以在使用的时候需要考虑是否需要幂等性,一般情况下不需要引入幂等性4 请求方法类型是否满足

2021-02-03 10:40:27 688

原创 Java中只有值传递

值传递:指在调用方法时将实际参数复制一份传递给方法中,这样在方法中如果对参数进行修改,将不会影响到实际参数。引用传递:指在调用方法时将实际参数的地址直接传递到方法中,那么在方法中对参数进行的修改,将影响到实际参数。所以值传递和引用传递的区别是:值传递会创建一个副本,方法中无法改变实际参数引用传递不会创建一个副本,方法中会改变实际参数值传递和引用传递的区别不是传递的内容,而是实参到底有没有被赋值一份传给形参所以,Java中只有值传递,只不过对于对象作为参数,值的内容是对象的引用地址的值..

2021-02-02 14:57:31 369 1

原创 接口与抽象类的区别

接口的方法默认是public,所有的方法在接口中不能有实现,Java8开始接口方法可以有默认实现,而抽象类中可以有非抽象方法接口中除了static、final变量,不能有其他变量,而抽象类不一定;一个类可以实现多个接口,但是只能实现一个抽象类;接口方法默认修饰是public,抽象方法可以有public、protected等修饰符,抽象方法就是为了被重写所有不能用private关键字修饰;从设计层面,抽象是对类的抽象,而接口是对行为的抽象;...

2021-02-02 14:18:29 66

原创 并发List、Map的一些问题

1. CopyOnWriteArrayList相关1.1 和ArrayList相比有哪些相同点和不同点?相同点:底层的数据结构相同,都是数组不同点:后者是线程安全的,在多线程环境下使用,无需加锁,可以直接使用1.2 CopyOnWriteArrayList通过哪些手段实现了线程安全?数组容器被volatile关键字修饰,保证了数组内存地址被任意线程修改后,都会通知到其他线程,保证了可见性;对数组的所有修改操作,都进行了加锁,保证了同一时刻只有一个线程对数组进行修改,比如在add时,无法re

2020-09-22 15:55:33 244

原创 Dockerfile语法梳理和最佳实践

Dockerfile里面定义了许多关键字,如FROM、RUN等等,通过这些关键字来定义Dockerfile。1. FROMFROM通常是Dockerfile最开头的语法,这个语法指定了base image是什么,即想在哪个base image之上build。如果不需要任何的base image,只是要从头build的话,那么写FROM scratch;更多的情况是利用已有的base image,在这基础之上进行build,比如在centos或者ubuntu等image之上进行build2.

2020-08-26 13:06:59 132

原创 关于Map的一些问题

1 Map数据结构类问题1.1 HashMap底层数据结构HashMap底层是数组+链表+红黑树的数据结构,数组的主要作用是方便快速查找,时间复杂度是O(1),默认大小是16,当数组容量不够时,扩容为原来的2倍。数组的下标索引是通过key的hashcode计算出来的,数组元素叫做Node,当多个key的hashcode一致,但是key值不同时,单个Node就会转化成链表,链表的查询复杂度是O(n),当链表的长度大于等于8并且数组的大小超过64时,链表就会转化成红黑树,红黑树的查询复杂度是O(log(n)

2020-08-24 11:07:13 529

原创 SpringMVC的原理

SpringMVC的MVC即模型-视图-控制器,该框架围绕一个DispatcherServlet设计,DispatcherServlet会把请求分发给各个处理器进行处理。SpringMVC的工作流程如下图所示。浏览器发起HTTP请求,发送给DS;DS寻找映射处理器HandlerMapping,这个对象是个Mapping对象,保存了URL->方法的映射关系,通过HandlerMapping找到对应的Controller;调用Controller;Controller调用Service;Co

2020-08-10 15:50:49 142

原创 关于List的一些问题

1 扩容类问题ArrayList无参构造器构造,现在add一个值进去,此时数组的大小是多少,下一次扩容前最大可用大小是多少?答:此时数组的大小是1,下一次最大可用大小是10,因为ArrayList第一次扩容时是有默认值的,默认值是10,在第一次add一个值进去时,数组的可用大小被扩容到10了。如果连续往list里面add值,增加到11个的时候,数组最大可用大小是多少?答: 因为ArrayList第一次扩容的最大容量是10,所以add到11个的时候,ArrayList第二次及其以后的扩容规则是原来容

2020-08-07 18:35:27 353

原创 Java集合类详解(二)

1.2 LinkedListLinkedList适用于集合元素先入先出和先入后出的场景,其底层是一个双向链表,整体结构如下图所示:

2020-07-31 17:54:20 154

原创 Java集合类详解(一)

Java的集合类被定义在Java.util包中,主要有四种集合,分别为List、Set、Map、Queue,如下图所示。1. ListList是有序的集合,一共有3个实现类ArrayList、Vector、LinkedList。1.1 ArrayList

2020-07-29 11:10:24 110

原创 Spring Bean的4种依赖注入方式

所谓依赖注入,其实就是给对象里的属性赋值,因为对象里有其他对象,因此就形成了依赖。Spring有4种方式来给属性赋值:1. 构造方法注入2. set方法注入3. 自动装配4. 注解1. 构造方法注入构造方法注入是指在构造方法中注入属性或者对象来实现依赖注入,如下所示,在标签中定义一个id为userDaoImpl的Bean,并通过注入了name为username,value为admin的值,注入完成后直接通过this.username获取到值admin。其中引用类型使用ref属性,基本类型使用v

2020-07-24 15:44:09 6102

原创 Spring Bean的生命周期

Spring Bean的生命周期如图所示,一共分为4个阶段:实例化Bean、依赖注入、初始化和销毁阶段。

2020-07-23 17:03:46 62

原创 Spring Bean的作用域

Spring为Bean定义了5种作用域,分别为Singleton(单例)、Prototype(原型)、Request(请求级别)、Session(会话级别)、和Global Session(全局会话)。Singleton:Singleton是单例模式,当实例类型为单例模式时,Spring IoC容器中只会存在一个共享的Bean实例,无论有多少个Bean引用它,都始终指向同一个Bean对象。该模式在多线程下是安全的。Singleton作用域是Spring中的默认作用域,也可以通过配置将Bean定义为Si

2020-07-22 17:50:40 86

原创 Spring Bean的装配流程

Spring在启动时会从XML配置文件或者注解中读取应用程序提供的Bean配置信息,并在Spring容器中生成一份相应的Bean配置注册表,然后根据这张注册表实例化Bean,装配好Bean之间的依赖关系。然后把实例化好的Bean放到Bean缓存池中,其中Bean缓存池为HashMap实现。Spring Bean的装配流程如图所示。...

2020-07-22 17:50:07 834

原创 MySQL数据库集群入门

1. 数据库集群能解决什么问题?单节点和集群哪个读写速度更快?在低并发情况下,单节点MySQL读写速度快;在高并发情况下,大量的读写请求会让单节点的MySQL硬盘无法承受,MySQL集群能把这些请求分发到不同的节点,所以此时集群的读写速度更快。所以数据库集群解决了高并发情况下单节点MySQL的性能瓶颈问题。2. MySQL集群的两种方案读写分离,就是把写操作和读操作分发给不同的节点执行,这样就提升了数据读写的效率。因为大部分系统都是读多写少的,所以可以把写操作发给DB1节点,然后把读操作发给DB2节

2020-07-15 11:31:53 576 1

原创 在CentOS 7下安装MySQL5.7

下载并安装MySQL的数据源并启动wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpmyum -y install mysql57-community-release-el7-10.noarch.rpmyum -y install mysql-community-serversystemctl start mysqld.service修改密码策略和字符编码并重启vim /e..

2020-07-14 17:58:49 88

原创 业界主流的分布式消息队列与技术选型

1. 分布式消息队列应用场景服务解耦:系统之间、服务之间作出必要的隔离,这是业务层面的划分,然后采用消息队列进行通信削峰填谷:比如说秒杀活动,如何对这个服务进行抗压,把流量的高峰和低谷的速率进行一个均衡,这是消息队列做的最核心的事情,就是说把消息缓存到一个地方,然后慢慢的去消费,这就是削峰填谷异步化缓冲:有些业务逻辑允许异步操作,只要做到最终一致性即可2. 分布式消息队列应用思考点生产端的可靠性投递,保证这条消息不能丢失消费端幂等,对于可能会重复的消息,如果都消费了,那数据肯定不一致的,所

2020-06-21 21:43:19 217

原创 缓存雪崩的解决方案

1. 什么是缓存雪崩?Redis里面会有大量的key,通常会设置过期时间,在某个时间点全部都失效了,恰巧同时有大量的请求过来,那么请求都直接涌向数据库,数据库支撑不住造成宕机,这种现象叫做缓存雪崩2. 雪崩预防永不过期过期时间错开多缓存结合,就是结合Memcache等其他的缓存,比如请求过来先去查询Redis,没有的话再去查询Memcache,这样就会多了一层保障...

2020-06-18 15:51:23 163

原创 缓存穿透的解决方案

1. 什么是缓存穿透?查询的key在redis中不存在对应的id在数据库也不存在此时被非法用户进行攻击,大量的请求直接打在db上,造成宕机,这种现象叫做缓存穿透2. 解决方案把空的数据也缓存起来,比如:空字符串、空对象、空数组等等...

2020-06-18 15:11:33 136

原创 Redis哨兵机制与实现

1. Redis哨兵机制Redis的读写分离、主从复制架构师针对读请求的一种横向扩展,可以形成一主多从的架构,但是有一个非常致命的问题:master节点挂了怎么办?slave节点只会提供读请求,用户没法执行写请求了为了解决这个问题,需要一个第三方来监视着master和slave的服务状态,一旦master挂掉,第三方还负责去切换其中一个slave为master,形成一个新的主从复制架构。这个第三方就是哨兵。2. Redis哨兵机制实现拷贝redis文件夹中的sentinel.conf 文件

2020-06-18 10:22:41 102

空空如也

空空如也

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

TA关注的人

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