自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 【Redis分析】(二) Sentinel

Sentinel 可以在被监视的主服务器进入下线状态时,自动将下线主服务器的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求。领头 Sentinel 在已下线主服务器的所有从服务器里面,选举一个从服务器,并将其升级为新的主服务器, 会将新的配置写到配置文件里。脑裂是指哨兵系统中的一个主节点没有下线, 只是和从节点之间的网络断开了, 从节点被选举为新的主节点, 从而出现了多个主节点;当哨兵监测到某个主节点客观下线之后 (从节点下线不会干啥) ,就会开始故障转移流程。

2024-08-19 17:50:25 1102

原创 【Redis分析】(一) 主从同步

到现在整个redis 主从复制的过程就讲解完成了,现在来做下总结。主从同步分为两个类型:全量同步全量同步redis 会执行bgsave 来生成rdb文件,然后发送给从库,从库接收之前会先清空从库的数据空,防止之前有数据造成数据的污染,接收完rdb文件之后,就会就加载rdb文件到内存,这时同步其实并没有完成,在进行生成rdb文件的时候,还会有新的写请求过来,此时这些写请求会缓存在一个缓冲区内,这个缓冲区叫做,当从库加载完rdb之后,就会接收这个缓冲区的所有写命令了,到此全量复制就结束了。

2024-08-19 16:57:08 1143

原创 【Java 并发编程】(大结局) 线程池常见八股与源码解读

本文略硬核, 但线程池作为后端服务器的基石, 不论是应付八股, 还是在真正工作中, 都是重中之重, 所以啃下这块硬骨头的收益还是很高的;废话不多说, 进入正题!

2024-08-17 09:48:16 1214

原创 【Java 并发编程】(五) ReentrantLock 源码解读

AQS,全称为 AbstractQueuedSynchronizer,是 Java 中 java.util.concurrent 包的一部分。作为构建锁或其他同步工具(如信号量、倒计时闸门等)的基础框架;

2024-08-17 09:47:38 957

原创 【Java 并发编程】(四) ThreadLocal 源码解读

每个Thread对象, 内部有一个ThreadLocalMap threadLocals, 这是一个哈希表, 底层是一个Node[ ] table;当在某个线程中调用ThreadLocal的set方法时, 会使用Thread.currentThread获取当前先线程的thread对象, 然后将ThreadLocal对象作为key, 将set方法的参数作为value, 构建一个Entry, 将此Entry保存到thead对象的ThreadLocalMap中;

2024-08-16 10:00:29 779

原创 【Java 并发编程】(三) 从CPU缓存开始聊 volatile 底层原理

前面讲过, 当一个 CPU 要读某个数据时, 会向其它 CPU 查询是否有该数据的缓存, 如果有, 拿过来, 如果没有, 去内存拿;CPU1 读变量a, 发现 CPU0 有变量a的缓存, 那么拿到自己的缓存里来, 并将缓存的最新值写入内存, 缓存的状态变为S, CPU0和1现在都有a的缓存, 且状态都是 S;所以, 新生代上 new 对象, 一般适用指针碰撞;由于指令重排, 有可能还没调用构造方法, 就放到局部变量表里了, 这时候去使用它, 用的是一个没有经过构造方法初始化的对象, 很危险;

2024-08-16 09:45:34 1066

原创 【Java 并发编程】(二) 从对象内存布局开始聊 synchronized

当一个线程第一次进入同步块时,会尝试获取对象的偏向锁, 本质就是通过 CAS(下文会有详细介绍) 的方式, 将指向本线程的指针, 写到对象头里;一个线程持有监视器锁时, 其它线程尝试获取锁时将被阻塞, 放到该锁的阻塞队列中;持有锁的线程释放锁后, 如果有其他线程正在等待获取同一个对象的监视器锁,那么其中的一个线程会被唤醒;它的基本思想是,要修改某个值时, 先读取当前值, 记为e, 计算出要修改为的值v, 写回之前再次读取当前值n, 如果n和e不相同, 说明修改失败, 放弃修改, 重新执行此过程。

2024-08-15 20:55:15 1404

原创 【Java 并发编程】(一) 线程状态, 线程创建, 线程销毁

- 操作系统的内核级线程, 是CPU资源调度的最小单位; - 以最简单的时间片轮转调度算法为例, 在定时中断的中断处理函数中, 操作系统的调度程序选出一个就绪线程, 让其上 CPU 运行;- 另外还有用户级线程, 由用户应用程序内部自己进行切换, 该过程对操作系统来说并不可见, 在操作系统眼里它就是在执行线程 A, 至于应用在线程内自己分离出来并自己负责切换的线程 A-a 和 线程 A-b, 操作系统是不知道的;

2024-08-15 20:41:12 791

原创 【ArrayList】JDK1.8源码详细注释 以及如何实现线程安全的链表

逻辑上来说, 你迭代一次, 当然只能判断当前的对象是不是需要被删除, 干嘛要多次删除?其次, 这样也能让迭代器的代码逻辑更简洁, 避免很多边界条件的判断, 也能避免很多潜在的错误;如果是无参构造创建的ArrayList,首次添加第一个元素时,扩容到10,如果首次直接使用 addAll 添加集合c,会有特殊判断, 扩容到 max { c.length , 10 }原理是: 创建 COWIterator 的时候, 会将底层数组的引用传进入, 这样, 即使有其他线程更换了底层数组, 也不会影响到当前的迭代器;

2024-08-10 22:08:01 825

原创 【ConcurrentHashMap】JDK1.8版本源码解读与分析

HashTable 是早期的线程安全的哈希表, 但是锁的范围太大了, 其 put, get 方法都有 synchronized 关键字修饰, 锁的范围是 hashtable 对象, 并发度太低;JDK1.7 的 ConcurrentHashMap ( 以下简称为 CHM ), 锁的范围是一个段, 段的数量可以在构造的时候指定, 又称并发级别;

2024-08-10 21:33:21 1328

原创 【ConcurrentHashMap】JDK1.7版本源码解读与分析

底层是一个Segment[]数组, 每个Segment对象内部又有一个Entry[ ]数组, 一个Entry[]数组就相当于一个HashMapEntry[ ]采用拉链法解决冲突, 但是没有红黑树,红黑树是1.8才引入的;一个Segment对象就是一个段;当往容器中添加元素调用 put 方法时, 锁的粒度就是一个段;调用 put 方法时, 先计算应该放到Segment[ ]中的哪个段, 然后调用方法将 Entry 插入到,可以看出, 一次插入有两次散列,一次选择段, 一次选择段内的位置;

2024-08-09 21:02:53 1590

原创 【最小生成树】(三) Prim 算法

在最小生成树的前两个章节中, 我们介绍了并查集以及基于并查集的 Kruskal 算法;不难看出, Kruskal 算法的时间复杂度主要来自于对所有边按权值排序;假设图中共有 E 条边, 那么 Kruskal 的时间复杂度为 ElogE;因为我们在并查集中使用了路径压缩算法, 其时间复杂度接近 O(1), 所以整个算法的时间复杂度和排序算法相当, 在使用快速排序的情况下, 就是 ElogE;

2024-08-09 10:18:50 517

原创 【最小生成树】(二) Kruskal 算法

假设图中有 1, 2, 3 三个顶点, 有 [1, 2], [1, 3] 两条边, 现在考虑加入 [2, 3] 这条边, 原本结点 2 和 结点 3 就已经处于连通状态, 现在加入 [2, 3] 必定导致图中出现环状结构;在无向图中, 如果一条边的两个端点本来就是连通的(处在同一集合中), 那么这个边的加入必然会使得图中产生 “环”当我们遍历到一条边, 这条边所连的两个顶点本身就已经连通时, 那么这条边是多余的, 如果加入, 会产生环;并查集的作用与代码在上一篇文章中有详细介绍, 可以到专栏中查看;

2024-08-08 15:04:13 337

原创 【最小生成树】(一) 预备知识 并查集

并查集的本质就是一个数组;表示元素 i 属于 集合 j;" 集合 j " 说明这个集合以元素 j 为根;只要一个元素 i 沿着 father 数组能往上找到 j , 那么 i 就属于根为 j 的集合;例如 father = {1, 3, 3, 5, 1, 5};我们希望找到 下标0 所属集合的根, father[0] = 1, father[1] = 3, father[3] = 5, father[5] = 5;于是我们沿着 father 数组找到了 下标0 所属集合的根, 即 下标5;

2024-08-08 14:46:38 352

原创 【SpringBoot 属性加载机制】

一个 SpringBoot 应用的配置属性可以有多种不同的来源, 比如可以来自操作系统的环境变量, 比如可以来自 application.yaml 文件;每一种不同的属性来源, 都会被 SpringBoot 封装成一个对象, 保存在对象的类型成员的中;一个对象中就通过一个 Map 保存了这个属性源下的所有属性配置;例如文件中的配置会被保存到一个对象中;这些属性源在 List 中的顺序决定了他们的优先级;因为无论是通过@Value注解还是注解去获取属性值, 其本质都是调用了方法;

2024-08-07 20:12:43 916

原创 【Nacos无压力源码领读】(三) Nacos 配置中心与热更新原理详解超详细解读

本文将从 Nacos 配置中心的基本使用入手, 详细介绍 Nacos 客户端发布配置, 拉取配置, 订阅配置的过程以及服务器对应的处理过程;配置订阅以及热更新原理相关的部分, 我看了主流的博客网站, 绝对没有比这更详细的讲解;

2024-08-07 17:18:48 1202

原创 【Nacos无压力源码领读】(二) 集成 LoadBalancer 与 OpenFeign

上一篇文章中, 详细介绍了 Nacos 注册中心的原理, 相信看完后, 大家应该完全掌握了 Nacos 客户端是如何自动进行服务注册的, 以及 Nacos 客户端是如何订阅服务实例信息的, 以及 Nacos 服务器是如何处理客户端的注册和订阅请求的;本文承上启下, 在订阅服务实例的基础上, 介绍如何在实例之间进行选择, 实现负载均衡;并详细介绍了负载均衡组件 LocaBanlancer 和函数式调用组件 OpenFeign 是如何与 Nacos 注册中心进行集成的;

2024-08-07 16:51:36 1314

原创 【Nacos无压力源码领读】(一) Nacos 服务注册与订阅原理

本文将详细介绍 Nacos 客户端在启动时进行自动注册原理, 以及Nacos服务器是如何处理客户端的注册与订阅请求的;本文会附带源码解读, 但不会死抠每一行代码, 主要是梳理整个流程, 过程中的关键步骤, 都会由思维导图的形式展现出来;

2024-08-07 16:18:11 794

原创 【限流与Sentinel超详细分析】

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统自适应保护等多个维度来保障微服务的稳定性。

2024-08-06 22:20:54 1123

原创 [ 分布式事务 ] (二) Seata 单机与集群部署及三种工作模式原理详解, 教你如何解决 TCC 空回滚, 业务悬挂问题

关于分布式事务的几种解决方案以及刚性事务和柔性事务的概念, 在上一篇文章中已经详细介绍过, 这里不再赘述, 大家自行查看;阿里巴巴有一个付费分布式事务框架, GTS;Seata基于阿里的GTS, 免费的开源分布式事务框架, 支持多种分布式事务模式;遵循 XA 规范, 采用 2PC 的方式实现分布式事务管理;是强一致性的事务;基于 TCC, 采用 TCC 的方式实现分布式事务管理;是柔性事务;基于 XA/2PC 协议的变种实现, 它支持事务的回滚,但是回滚本身是由SEATA实现,并非数据库的回滚;

2024-08-06 15:16:16 1345

原创 [ 分布式事务 ] (一) 分布式事务详解,秒杀项目必问

分布式环境下, 传统 MySQL 事务无法满足多个结点之间的原子性, 需要引入新的事务组件来实现分布式环境下跨节点的事务, 本文详细介绍了几种分布式事务的实现方案;

2024-08-05 23:03:02 1428

原创 [HashMap 源码详解] 阿里面经: 不要再说 hashCode 默认实现是取内存地址了, 必挂!

本文无废话, 全干货, 由 hashCode 方法开始讲起, 带你完全重新认识 hashCode 方法, 并囊括 HashMap 所有可能的八股文知识, 附带源码详细解读;然后将会讲解阿里面试问题, 进行知识提炼与提升, 希望大家都能认真看完;

2024-07-30 16:32:31 816

原创 SpringBoot启动流程与配置类处理机制详解, 附源码与思维导图

纯干货无废话, 附源码与思维导图

2024-07-29 21:56:16 834

原创 阿里: 了解@Autowired注解吗? 它是怎么实现依赖注入的?

@Autowired 注解可以说是每天都要用到, 但我们很少去想它底层实现依赖注入的原理到底是什么, 面试被问到这题大部分人也只能说出来 Autowired 注入的一些规则, 今天从SpringBoot 创建 Bean 的过程来给大家详细讲解 @Autowired 注解;看完后, 你将对 @Autowired 注解的注入原则, SpringBoot 属性加载机制, SpringBoot 创建Bean 的过程, @Value 注解的原理, Spring Bean 的生命周期有新的认识;

2024-07-29 21:46:26 795

原创 后端面试被问: 说说你对ThreadLocal的理解 [附源码解读]

每个Thread对象, 内部有一个ThreadLocalMap threadLocals, 这是一个哈希表, 底层是一个Node[ ] table;当在某个线程中调用ThreadLocal的set方法时, 会使用Thread.currentThread获取当前先线程的thread对象, 然后将ThreadLocal对象作为key, 将set方法的参数作为value, 构建一个Entry, 将此Entry保存到thead对象的ThreadLocalMap中;

2024-07-27 20:38:26 648

原创 [NIO系列]接IO多路复用, 详细介绍NIO与零拷贝

在 DirectByteBuffer 的构造方法中, 会创建一个 Cleaner 对象, 创建 Cleaner 对象的时候, 把当前的 DirectByteBuffer 传了进去, 同时还传递了一个 Deallocator 对象, 这个 Deallocator 将作为 Cleaner 的 thunk 成员;以 FileChannel 为例, 如果是 DBB, 直接进行写, 如果是 HeapByteBuffer, 则先构造一个 DBB, 拷贝到DBB, 再由DBB写到Channel;

2024-07-27 10:47:18 758 1

原创 面试必问: [NIO系列]从文件描述符开始教会你IO多路复用, 超多细节

文件描述符(File Descriptor,简称FD)是操作系统内核用于访问可以进行 I/O 的资源的一个抽象标识符。Linux 万物皆文件, 在操作系统看来, 一个 Socket 对象就是一个可以 IO 的资源, 发送数据就是对 Socket 进行写操作, 接收数据就是读 Socket;文件描述符是一个非负整数,代表一个已经打开的文件、管道、网络套接字或其他 I/O 资源;例如, 当一个程序通过系统调用(如opensocket等)打开一个文件或创建一个网络连接时,操作系统会返回一个文件描述符。

2024-07-26 19:29:02 998 1

原创 Spring为什么用三级缓存来解决循环依赖问题? 二级不行吗?

我在学习循环依赖的解决方案时, 一直有这样的疑惑: A, B 循环依赖的话, A 实例化以后直接放到二级缓存, B 注入的时候直接到二级缓存取 A 就可以了, 为什么 A 要先放到三级缓存, 被注入的时候再挪到二级缓存?一句话总结: 为了优雅地引入 AOP;

2024-07-26 18:40:00 450 1

空空如也

空空如也

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

TA关注的人

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