自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 Netty原理及高性能

Netty的NioEventLoop读取到消息之后,直接调用ChannelPipeline的fireChannelRead,只要用户不主动切换线程,一直会由NioEventLoop调用到用户的Handler,期间不进行线程切换,这种串行化处理方式避免了多线程操作导致的锁的竞争,从性能角度看是最优的。在Netty中,零拷贝技术被广泛应用以提高网络数据传输的效率,零拷贝指的是在数据传输过程中,减少或者避免CPU的拷贝次数,从而加快数据传输速度,降低CPU负载。主要涉及到的是TCP的NAGLE算法。

2024-08-08 19:41:16 629

原创 Java面试题——第五篇(Java基础)

如果线程A希望立即结束线程B,则可以对线程B对应的Thread实例调用interrupt方法,如果此刻线程B正在wait、sleep、join,则线程B会立刻抛出InterruptedException,在catch中直接return即可安全的结束线程。当new时,他们的执行顺序为:父类静态变量、父类静态代码块、子类静态变量、子类静态代码块、父类非静态变量、父类非静态代码块、父类构造函数、子类非静态变量、子类非静态代码块、子类构造函数。final 修饰的变量是引用不可变,但是引用的对象还是可以发生改变。

2024-08-07 10:36:25 650

原创 Java面试题——第四篇(多线程)

AQS即队列同步器,是用来构建锁或者其他同步组件的基础框架,使用了一个int成员变量表示同步状态,通过内置的FIFO队列来完成资源获取线程的排队工作。AQS使用一个int成员变量state来表示同步状态,当state>0时表示已经获取了锁,当state=0时表示释放了锁。他提供了三个方法getState()、setState(int newState)、compareAndSetState(int expect,int update)来对同步状态state进行操作,当然AQS对state的操作是安全的。

2024-08-06 19:40:12 1178

原创 Java面试题——第三篇(JVM)

完整GC流程GC开始时,对象只存在于Eden区和From Survivor区域,To Survivor是空白的保留区域。GC进行时,Eden中所有存活的对象会被复制到To Survivor区域,而在From Survivor区域的对象,根据年龄决定去向,如果年龄+1大于15,则晋升到老年代,否则,进入To Survivor区域。接着,清空Eden区域和From Survivor区域。

2024-08-05 21:01:29 938

原创 Java面试题——第二篇(设计模式)

当希望将一个对象转换成满足另一个新接口的对象时,可以创建一个Wrapper类,持有原类的一个实例,在Wrapper类的方法中,调用实例方法即可。工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象,所谓复合对象就是指某个类具有不同的属性。对一个原型对象进行复制、克隆产生类似的新对象:将一个对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对象。给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例。

2024-08-01 19:53:10 987

原创 计算机网络面试题——第一篇

浏览器发送302跳转主要涉及HTTP协议中的重定向机制。具体来说,当服务器收到一个请求后,如果发现请求的资源暂时不在当前位置。而是位于另一个URL,服务器就会向浏览器发送一个302状态码,并在响应头中指定新的资源位置(即Location字段)。浏览器收到这个状态码和Location字段后,会自动向新的URL发送请求,从而实现页面跳转。Rest是一种软件架构风格,HTTP是一种文本传输协议。

2024-07-31 21:03:35 918

原创 Netty面试题——第一篇

要发送的数据大于TCP发送缓冲区剩余空间大小,将会发生拆包。待发送数据大于MSS(最大报文长度),TCP在传输前将进行拆包。要发送的数据小于TCP发送缓冲区大小,TCP将多次写入缓冲区的数据一次发送出去,将会发生粘包。接收数据端的应用层没有及时读取接受缓冲区的数据,将发生粘包。

2024-07-31 19:43:24 649

原创 Spring面试题——第一篇

总结:Spring事务底层原理是一个基于AOP和数据库事务机制的高效过程,他通过代理对象拦截方法调用,在事务上下文中执行业务逻辑,并在适当的时候提交或者回滚事务。SpringMVC的启动是一个负责但是有序的过程,主要涉及Tomcat的启动、Spring容器的创建和初始化、以及DispatcherServlet的初始化与配置。Spring事务的传播行为在Spring框架中是一个重要的概念,他定义了当一个事务方法被另一个事务方法调用时,事务应该如何进行。Spring提供了七种事务传播行为。

2024-07-31 16:11:04 262

原创 JDK高并发——锁的优化

锁膨胀后,为了避免线程真实的在操作系统层面挂起,虚拟机还会做最后的努力——自旋锁,当前线程暂时无法获得锁,而且什么时候可以获得锁是一个未知数,系统会假设在不久的将来,线程就可以得到这把锁。轻量级锁的操作,只是将对象头部作为指针指向持有锁的线程堆栈的内部,来判断一个线程是否持有对象锁,如果线程获得轻量级锁成功,则可以顺利进入临界区,如果轻量级锁加锁失败,则表示其他线程优先抢到了锁,那么当前线程的锁请求就会膨胀为重量级锁。但是,减小锁粒度会带来一个新的问题,即当系统需要取得全局锁时,消耗的资源会比较多。

2024-07-30 20:54:43 821

原创 Java高并发理论基础

在CPU1和CPU2上各运行一个线程,他们共享变量t,由于编译器优化或者硬件优化的缘故,在CPU1上的线程将变量t缓存到cache或者寄存器中,在这种情况下,CPU2上的线程对共享变量做了修改,CPU1上的线程无法意识到这种改动,依然会读取缓存值。两个线程无障碍的执行,那么不会因为临界区的问题导致一方被挂起,对于无障碍的线程来说,双方共同修改临界区的资源,如果一方把资源修改坏,会立即对自己所做的修改进行回滚,确保数据安全。如果线程之间是有优先级的,那么线程调度的时候总是倾向于满足高优先级的线程。

2024-07-25 16:37:50 987

原创 MySQL 数据表

分区功能并不是在存储引擎层完成的,MySQL数据库在5.1版本时添加了对于分区的支持,这个过程是将一个表或者索引物理的分为多个更小、更可管理的部分。就应用而言,从逻辑上讲,只有一个表或者一个索引,但是在物理上这个表或者索引可能由数十个物理分区组成。每个分区都是独立的对象,可以独自处理,也可以作为一个更大对象的一部分进行处理。MySQL数据库支持的分区类型为水平分区,并不支持垂直分区。此外,MySQL数据库的分区是局部分区索引,一个分区中既存放了数据又存放了索引。

2024-07-24 11:11:02 909

原创 MySQL 事务

事务是数据库区别于文件系统的重要特性之一。事务用来保证数据库的完整性——要么都做修改,要么都不做。同时,事务有严格的定义,必须同时满足四个特性。原子性:原子性指数据库事务是不可分割的工作单位。只有使事务中所有的数据库操作执行都成功,才算整个事务成功。如果事务中任何一个SQL语句执行失败,那么已经执行成功的SQL语句必须撤销。数据库状态应该退回到执行事务前的状态。一致性:一致性指事务将数据库从一种状态转变为下一种一致的状态。在事务开始之前和结束以后,数据库的完整性约束没有被破坏。

2024-07-23 13:50:38 1204

原创 MySQL 锁

首先,对于有自增长值的列的并发插入性能较差,事务必须等待前一个插入的完成。其次,对于insert…InnoDb存储引擎不存在锁升级的问题,因为其不是根据记录来产生行锁的,相反,其根据每个事务访问的每个页对锁进行管理的,采用的是位图的方式,因此,不管事务锁住页中的一个记录还是多个记录,其开销通常是一致的。此时事务T1并没有提交,返回结果5,与此同时,允许事务T2执行插入操作,插入值为4,则T1再次执行会返回记录 4和5的两个结果,与第一次得到的结果不同,违反了事务的隔离性,即当前事务能看到其他事务的结果。

2024-07-18 11:33:35 706

原创 InnoDB存储引擎

InnoDb存储引擎的插入缓冲是一种优化技术,旨在提高对非聚集索引插入操作的效率。在InnoDB中,数据存储在一个聚集索引中,同时可以有多个非聚集索引(也称为辅助索引)。当向表中插入数据时,除了要修改聚集索引外,还可能需要更新多个非聚集索引。

2024-07-11 15:06:21 1081

原创 Redis过期策略

淘汰池是一个数组,他的大小是maxmemory_samples,在每次淘汰循环中,新随机出来的key列表会和淘汰池中的key列表进行融合,淘汰掉最旧的一个key之后,保留剩余较旧的key列表放入淘汰池中等待下一个循环。因为指令同步是异步进行的,所以从库过期的key的del指令没有及时同步到从库的话,会出现主从数据的不一致,主库没有的数据从库里还存在,比如集群环境分布式锁的算法漏洞就是因为这个同步延迟产生的。删除指令del会直接释放对象的内存,大部分情况下,这个指令非常快,没有明显延迟。

2024-07-09 20:07:40 835

原创 Mysql 高性能索引

InnoDB引擎有一个特殊的功能叫做“自适应哈希索引”,当InnoDB注意到某些索引值被使用的非常频繁时,他会在内存中基于B-Tree索引之上在创建一个哈希索引,这样就让B-Tree索引也具有哈希索引的一些优点,比如快速的哈希查找,这是一个完全自动的、内部的行为,用户无法控制或者配置,不过如果有必要,可以关闭该功能。如果存储引擎不支持哈希索引,可以模拟创建一个自定义哈希索引,具体思路如下。

2024-07-09 13:47:59 1184

原创 Redis 分布式集群方案 Cluster

如果一个节点收到了某个节点失联的数量已经达到了集群的大多数,就可以标记该节点为确定下线状态,然后向整个集群广播,强迫其他节点也接受该节点已经下线的事实,并立即对该失联节点进行主从切换。当客户端向一个错误的节点发出了指令,该节点会发现指令的key所在的槽位并不归自己管理,这时他会向客户端发送一个特殊的跳转指令携带目标操作的节点地址,告诉客户端去连这个节点去获取数据。这里的迁移过程是同步的,在目标节点执行restore指令到原节点删除key之间,原节点的主线程会处于阻塞状态,直到key删除成功。

2024-07-08 14:32:34 755

原创 Redis分布式解决方案 codis

Codis要负责将特定的key转发到特定的Redis实例,Codis将所有的key默认划分为1024个槽位(slot),他首先将客户端传来的key进行crc32运算计算哈希值,再将hash后的整数值对1024这个整数进行取模得到一个余数,这个余数就是对应key的槽位,每个槽位都会唯一映射到后面的多个Redis实例之一,Codis会在内存维护槽位和Redis实例的映射关系。当 Codis接收到位于正在迁移槽位中的key后,会立即强制对当前的单个key进行迁移,迁移完成后,再将请求转发到新的Redis实例。

2024-07-08 10:36:31 952 1

原创 MySQL 基础概念

对于Select语句,在解析查询之前,服务器会先检查查询缓存,如果能够在其中找到对应的查询,服务器就不必再次执行查询解析、优化和执行的整个过程,而是直接返回查询缓存中的结果集。他会锁定整张表,一个用户在对表进行写操作前,需要先获得写锁,这会阻塞其他用户对该表的所有读写操作,只有没有写锁时,其他读取的用户才能获取到锁,读锁之间不相互阻塞。问题是加锁也需要消耗资源,锁的各种操作,包括获得锁、检查锁是否已经解除,释放锁等,如果系统花费大量的时间来管理锁,而不是存取数据,那么系统的性能反而受到影响。

2024-06-26 11:09:18 1032

原创 RabbitMQ 消息传递

mandatory参数:告诉服务器至少将该消息路由到一个队列中,否则将消息返回给生产者。immediate参数:告诉服务器,如果该消息关联的队列上有消费者,则立刻投递;如果所有匹配的队列上都没有消费者,则直接将消息返还给生产者,不用将消息存入队列等待消费者了。

2024-06-25 19:40:27 1092

原创 RabbitMQ 开发指南

每个Channel都拥有自己独立的线程,最常用的做法是一个Channel对应一个消费者,也就意味着消费者彼此之间没有关联,也可以在Channel中维持多个消费者,但是,如果Channel中一个消费者一直在运行,那其他消费者的callback会被耽搁。getReason可以获取Cause相关的信息。上面创建了一个持久化的、非自动删除的、绑定类型为direct的交换器,同时也创建了一个非持久化的、排他的、自动删除的队列(队列名称由RabbitMQ自动生成),这里的交换器和队列都没有设置特殊的参数。

2024-06-20 16:27:56 1145 1

原创 Redis 高可用 sentinel

Sentinel提供了一种高可用方案来抵抗节点故障,当故障发生时Redis集群可以自动进行主从切换,程序可以不用重启。Redis Sentinel集群可以看成是一个Zookeeper集群,他是Redis集群高可用的心脏,一般由3-5个节点组成,这样即使挂了个别节点集群还可以正常运转。他负责持续监控主从节点的健康,当主节点挂掉时,自动选择一个最优的从节点切换为主节点。具体流程如下客户端连接集群时,首先连接sentinel,通过sentinel查询主节点的地址客户端再去连接主节点进行数据交互。

2024-06-19 11:23:06 683

原创 Redis 主从同步

如果因为网络状况不好,从节点在短时间内无法和主节点进行同步,那么当网络状况恢复时,Redis的主节点中那些没有同步的指令在buffer中有可能已经被后续的指令覆盖掉了,从节点将无法直接通过指令流来进行同步,这个时候就需要用到更加复杂的同步机制——快照同步。有了主从,当master挂掉的时候,运维让从库过来接管,服务就可以继续,否则master需要经过数据恢复和重启的过程,可能会拖很长时间,影响业务持续服务。,从节点会努力追赶主节点,最终从节点的状态会和主节点的状态保持一致。

2024-06-19 10:50:56 931

原创 Redis小对象压缩

如果当前Redis内存有10G,当删除了1GB的key后,再去观察内存,会发现内存变化不会太大,原因是操作系统回收内存是以页为单位,如果这个页上只要有一个key还在使用,那么他就不能被回收。如果整数可以用uint16表示,那么intset的元素就是16位的数组,如果新加入的整数超过了uint16的表示范围,那么就使用uint32表示,如果新加入的元素超过了uint32,那么就使用了uint64。Redis的intset是一个紧凑的整数数组结构,他用于存放元素都是整数的并且元素个数较少的set集合。

2024-06-18 21:40:46 627

原创 Java并发编程之线程基础

在多线程编程中,线程个数一般大于CPU个数,而每个CPU同一时刻只能被一个线程使用,为了让用户感觉多个线程是在同时执行的,CPU资源的分配采用了时间片轮转的策略,也就是给每个线程分配一个时间片,线程在时间片内占用CPU执行任务。修改以后,发现当main线程运行结束以后,JVM进程也已经终止了,在这个例子中,main函数是唯一的用户线程,thread线程是守护线程,当main线程运行结束后,JVM发现当前已经没有用户线程了,就会终止JVM进程。也说明了在用户线程还存在的情况下JVM进程并不会终止。

2024-06-18 20:57:24 801

原创 RabbitMQ 相关概念

消息是指在应用间传送的数据,包含文本字符串、JSON等。消息队列中间件(MQ)指利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息排队模型,他可以在分布式环境下扩展进程间的通信。消息队列中间件,也称为消息队列或者消息中间件,一般有两种传递模式:点对点(P2P)以及发布/订阅(Pub/Sub)模式.点对点模式是基于队列的,消息生产者发送消息到队列,消息消费者从队列中接收消息,队列的存在使得消息的异步传输成为可能。

2024-06-18 14:55:24 1201

原创 Java多线程设计模式之保护性暂挂模式

多线程编程中,为了提高并发性,往往将一个任务分解为不同的部分。将其交由不同的线程来执行。这些线程间相互协作时,仍然可能会出现一个线程等待另一个线程完成一定的操作,其自身才能继续运行的情形。保护性暂挂模式(Guarded Suspension)可以帮助我们解决上述的等待问题。该模式的核心思想是如果某个线程执行特定的操作前需要满足一定的条件,则在该条件未满足时将该线程暂停运行(即暂挂线程,使其处于waiting状态,直到该条件满足时才继续运行)。

2024-06-17 19:29:38 1150

原创 Redis 事务

为了确保连读多个操作的原子性,一个成熟的数据库通常都会有事务支持。Redis事务也不例外,Redis的事务使用非常简单,不同于关系数据库,我们无需理解那么多复杂的事务模型,就可以直接使用。不过也正是因为这种简单性,他的事务模型很不严格。要求我们不能像使用关系型数据库的事务一样来使用Redis。

2024-06-17 15:32:12 970

原创 Redis 管道

此外,客户端read操作只负责将数据从本地recv buffer中取出来就完事了,但是如果接收缓冲是空的,那么就需要等待数据到来,这个就是读IO操作真正耗时。当我们使用客户端对Redis进行一次操作时,如下图所示,客户端将请求传送给服务器,服务器处理完毕后,再将响应回复给客户端,这要花费一个网络数据包来回的时间。剩下的事全部交给操作系统内核异步将数据送到目标机器,但是如果发送缓冲满了,那么就需要等待缓冲空出空闲时间,这个就是写操作IO的真正耗时。后续的read操作直接就可以从缓冲拿到结果,瞬间就返回了。

2024-06-17 14:38:07 1088

原创 Java面试题——第一篇

字节码就是(.class文件),他不面向任何特定的处理器,只面向虚拟机。Java语言通过字节码的形式,在一定程度上解决了传统解释型语言执行效率低的问题。同时保留了解释型语言可移植特性。所以,Java程序运行时相对高效(但是和C、C++、Go相比仍有差距)。而且,由于字节码并不针对一种特定的机器,因此Java程序无需重新编译便可在多种 不同操作系统上运行。

2024-06-14 16:50:04 947 1

原创 Redis 持久化

子进程因为数据没有变化,他能看到的内存里的数据在进程产生的一瞬间就凝固了,再也不会改变,这也是为什么Redis的持久化叫【快照】的原因,接下来子进程就可以非常安心的遍历数据进行序列化写磁盘。这种写入机制提供了较高的性能,因为写入内存通常比写入硬盘快得多,同时,这种方法也可能带来数据丢失的风险,如果在数据被持久化到硬盘之前系统发生崩溃,那么内存中的脏数据可能会丢失。于是,在Redis重启的时候,可以先加载rdb内容,然后在重放增量AOF日志就可以完全替代之前的AOF全量文件重放,重启效率因此大幅提升。

2024-06-14 14:12:28 1263

原创 Java I/O模型

文章主要介绍了NIO的核心组件以及零拷贝。如果需要使用NIO构建网络程序的话,不建议直接使用NIO,编程模型过于复杂,可以使用Netty,Netty在NIO的基础上进行了进一步优化和扩展。

2024-06-13 22:19:44 1188

原创 Redis之线程IO模型

Redis单线程,利用IO多路复用技术,单线程监听多个文件描述符,并进行事件轮询(单线程循环),轮询期间如果发生可读事件,从缓冲区中读取事件并进行处理,处理完后再将数据发送到写缓冲区写回给客户端。轮询通过select(read_fds, write_fds, timeout) 函数进行,其中timeout为轮询阻塞时间。

2024-06-13 19:11:09 1149

原创 Java 代理模式

代理模式简单来说就是使用代理对象来代替对真实对象的访问,这样就可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能。代理模式的主要作用是扩展目标对象的功能,比如说在目标对象的某个方法执行前后可以增加一些自定义操作。代理模式有静态代理和动态代理两种实现方式。

2024-06-13 14:22:04 1249 1

原创 设计模式之策略模式

策略模式是一种常用的设计模式,属于行为型模式的一种,他定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

2024-06-12 22:18:42 719

原创 设计模式之工厂模式

我们将创建一个Shape接口和实现Shape接口的实现类。FactoryPatternDemo类使用ShapeFactory来获取Shape对象,他将向ShapeFactory传递信息(circle/rectangle/square),以便获取他所需对象的类型。工厂模式是Java中最常用的设计模式之一,他提供了一种创建对象的方式,使得创建对象的过程和使用对象的过程分离。,而不是在客户端代码中直接实例化对象,这样可以提高代码的可维护性和可扩展性。工厂模式提供了一种创建对象的方式,而无需指定要创建的具体类。

2024-06-12 21:49:53 138

原创 SpringBoot自动装配

当提到自动装配的时候,一般会和Spring Boot联系在一起,但是,实际上Spring Framework早就实现了这个功能。Spring Boot只是在其基础上,通过SPI的方式,做了进一步优化。SpringBoot定义了一套规范,这套规范规定:SpringBoot再启动时会扫描外部引用jar包中的META-INF/spring.factories文件,将文件中配置的类型信息加载到spring容器(此处涉及到JVM 类加载机制与Spring容器知识),并执行类中定义的各种操作。

2024-06-12 20:29:31 820

原创 Redis 键空间迭代 Scan

如果不考虑字典的扩容缩容,直接按数组下标挨个遍历即可。limit参数表示需要遍历的槽位数,之所以返回的结果可多可少,是因为不是所有的槽位上都会挂接链表,有些槽位可能是空的,还有些槽位挂接的链表上的元素可能有多个。假设当前即将遍历110这个位置,那么扩容后,当前槽位上的所有元素对应的新槽位是0110,1110,也就是在槽位的二进制数增加一个高位0或者1.这时,我们可以直接从0110这个槽位开始往后继续遍历,0110槽位之前的所有槽位都是已经遍历过的,这样就可以避免扩容后对已经遍历过的槽位进行重复遍历。

2024-06-12 15:17:25 1019

原创 Redis 地理散列GeoHash

在一个地图应用中,车的数据、餐馆的数据、人的数据可能会有百万千万条,如果使用Redis的Geo数据结构,他们将全部放在一个zset集合中,在Redis的集群环境中,集合可能会从一个节点迁移到另一个节点,如果单个key的数据过大,会对集群的迁移工作造成较大的影响,在集群环境中单个key对应的数据量不宜超过1Mb,否则会导致集群迁移出现卡顿现象,影响线上业务正常运行。所以,建议Geo的数据使用单独的Redis实例部署,不使用集群环境。

2024-06-12 10:44:04 977

原创 Spring IOC以及AOP

IOC即控制反转/反转控制,他是一种思想不是一个技术实现。描述的是:Java开发领域对象的创建以及管理问题。例如:现有类A依赖于类B传统开发方式:往往是在类A中手动通过new关键字来new一个对象B。使用IOC思想的开发方式:不通过new关键字来创建对象,而是通过IOC容器来帮助我们实例化对象,我们需要哪个对象,直接从IOC容器里面去取即可。从以上两种开发方式的对比来看:我们“丧失了一个权力”(创建、管理对象的权利),从而也得到了一个好处(不用在考虑对象的创建、管理等一系列事情)。为什么叫控制反转。

2024-06-11 21:54:31 871

空空如也

空空如也

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

TA关注的人

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