- 博客(49)
- 收藏
- 关注
原创 Java面试高频八股
Java异常处理体系基于Throwable类,分为Error(不可恢复错误)和Exception(可处理异常)。Exception又分为检查性异常(必须处理)和非检查性异常(RuntimeException及其子类)。处理异常使用try-catch-finally块,通过throw手动抛出异常,throws声明方法可能抛出的异常类型。 面向对象编程通过封装、继承和多态实现代码复用和扩展。多态允许同一方法在不同对象中表现不同行为,通过父类引用指向子类对象实现。 集合框架中,ArrayList基于动态数组,查询
2025-12-29 22:23:58
1048
原创 初识消息队列的世界
摘要:MQ(消息队列)是基于FIFO原则的通信机制,用于系统间数据传输。RabbitMQ作为主流MQ实现,支持AMQP协议,具有异步解耦、流量削峰等功能。相较于Kafka和RocketMQ,RabbitMQ功能完备且社区活跃。在Ubuntu安装需先装Erlang,通过命令完成RabbitMQ服务部署和管理界面配置,添加用户后可通过web界面(默认15672端口)进行管理。安装过程涉及软件包更新、服务状态检查及日志排查等步骤。
2025-09-21 11:29:57
1706
原创 微服务统一入口——Gateway
定义工厂类:继承,泛型为配置类(存储断言参数)。实现方法:重写apply方法(生成 Predicate)和方法(指定参数顺序)。注册为 Bean:通过@Component注解注册。代码示例:自定义 “请求 IP 在白名单中” 的断言工厂// 配置类:存储白名单参数@Data// 允许的IP列表// 自定义断言工厂@Component// 构造方法:指定配置类// 生成Predicate:判断请求IP是否在白名单中@Override// 获取客户端IP。
2025-08-23 13:16:09
1624
原创 告别 RestTemplate,OpenFeign 才是微服务通信的正确姿势
是 Spring Cloud 提供的一种。它的核心作用是,让我们,不用自己写的请求代码。当前代码功能上没有问题,但是存在一些细节上的问题:1.封装比较臃肿,URL复杂时可能容易出错。2.代码可读性比较差,风格不统一。
2025-08-22 08:57:46
1139
原创 Spring Cloud——功能丰富的Nacos
注意: Spring Boot 和Spring Cloud的版本是有⼀定对应关系的,Spring Cloud Alibaba也遵循Spring Cloud 的标准, 在引⼊依赖时,⼀定要确认各个版本的对应关系。配置中心就是对这些配置项进行统⼀管理,通过配置中心,可以集中查看,修改和删除配置,无需再逐个修改配置文件,提高效率的同时, 也降低了出错的风险。生产环境相对是比较恶劣的,我们需要对服务的流量进行更加精细的控制,Nacos支持多种负载均衡策略,包括权重,同机房,同地域,同环境等。
2025-08-21 09:21:20
1439
原创 微服务流量分发核心:Spring Cloud 负载均衡解析
Bean注意: 该类需要满足:不用 @Configuration 注释在组件扫描范围内@Bean在 RestTemplate 配置类上方, 使用 @LoadBalancerClient 或 @LoadBalancerClients 注解, 可以对不同的服务提供方配置不同的客户端负载均衡算法策略,这样就把默认的轮询策略替换成了随机策略@LoadBalancerClient 注解说明name: 该负载均衡策略对哪个服务生效(服务提供方)。
2025-08-20 09:17:04
1311
原创 Spring Cloud——服务注册与服务发现原理与实现
在idea下搭建了一个通过pom.xml构建的父子工程项目,子模包含订单模块,产品信息模块,每个模块都存在根据id查找对应的信息(例如根据订单id查询订单信息,根据产品id查找对应的产品信息)。现在的需求是根据服务注册中心,能够实现通过网络远程调用其他模块的信息,在订单数据表中包含对应的产品id,因此下面是实现在访问订单模块的时候能同时获取到对应产品的信息。,系统间的网络不能100%保证健康,服务又必须对外保证服务,因此分区容错性不可避免,那就只能在C和A中选择⼀个,也就是CP或者AP架构。
2025-08-19 13:40:34
1389
原创 认识微服务与SpringCloud
服务越小,微服务的独立性就会越来越高,但同时,微服务的数量也会越多,管理这些微服务的难度也会提高,所以服务拆分也要考虑场景。,它整合了一系列组件,用于解决微服务架构落地时的共性问题(如服务注册发现、负载均衡、服务调用、熔断降级、集中配置管理、API网关等),简化了微服务系统的开发和运维。服务自治原则:服务自治是指每个微服务都应该具备高度自治的能力,即每个服务要能做到独立开发,独立测试,独立构建,独立部署,独立运行。软件架构的演变始终围绕着。从最初的单体架构到如今的微服务架构,每一次演进都是对前一种架构。
2025-08-11 11:54:59
1928
原创 Redis分布式锁的核心逻辑与原理
Redis 分布式锁的设计核心,是在多节点并发场景下确保共享资源的互斥访问,避免数据不一致和逻辑混乱。基础实现依赖过期时间防止死锁,结合唯一标识避免误删他人锁,并通过Lua 脚本保证释放锁的原子性;在业务耗时不可预测时,引入看门狗机制自动续租,提升锁的稳定性;在对高可用性要求极高的场景,可采用Redlock跨多 Redis 节点实现容错。根据业务特点合理组合这些机制,才能在性能与安全性之间取得最佳平衡。
2025-08-10 11:32:07
1029
原创 Redis缓存详解:内存淘汰和缓存的预热、击穿、雪崩、穿透的原理与策略
指的是,由于在短时间内,redis上大规模的key失效,导致缓存命中率直线下降,打到mysql的请求激增压力迅速上升,引发mysql宕机。设置好缓存的容量上限,在接收用户请求的过程中,存在缓存的数据就直接返回给用户,如果不存在则去数据库中查,再将结果写到redis缓存中。引入缓存,在缓存中保存访问频繁的热点数据,降低直接对数据量访问的请求量(“二八定律”,20%的热点数据能满足80%的访问需求)。引入布隆过滤器,将合法的key预装到布隆过滤器中,请求先询问布隆过滤器,不存在就直接返回,不去访问mysql。
2025-08-09 11:58:55
1336
原创 Redis的集群模式
节点之间通过心跳包通信,心跳包中包含了持有的槽位,通过位图需要2kb来存储该,如果槽位过大位图所占的空间越大,对网络资源开销较大。Redis 集群选择 16384 个槽位是经过性能与实现复杂度权衡的结果,计算高效、分片粒度细,有利于均衡负载和灵活迁移。
2025-08-08 14:43:43
1096
原创 Redis的哨兵机制
了解哨兵机制前可以先再回顾一遍。在redis的主从结构中,还存在两个问题:问题1:主节点宕机后,需要进行主节点切换,这个过程由人工完成将会费事费力。问题2:从节点保存的数据和主节点相同,写压力与存储压力无法被分担。本篇所讲的redis的哨兵机制将会解决问题1,哨兵 + 主从复制解决的问题是 "提高可用性",而另一篇redis的集群模式则会解决问题2。
2025-08-08 14:43:11
831
原创 Redis的主从复制
Redis的主从复制是在解决单个redis节点,的问题。Redis 主从复制是指一个 Redis 服务器(主节点 Master)可以将数据同步到一个或多个 Redis 服务器(从节点 Slave)。从节点可以接收主节点的写操作更新,并保持与主节点数据的一致性。构成主从架构的模型中,负责请求,而只负责请求。
2025-08-05 22:01:30
1281
原创 Redis的事务
概念:Redis 事务就是让多条命令打包在一起,再执行时顺序运行,中途不会被其他命令插入,但不提供传统数据库(例如MySQL)的回滚能力。
2025-08-03 14:05:34
403
原创 Redis的持久化
对于redis来说,他的数据中,其实在份。一般来说在像redis中插入数据的时候,redis会将数据既写到内存中又写入硬盘中,当查询某个数据的时候,是直接从内存中读取。redis的持久化能够将数据恢复到内存中,避免redis服务重启的时候数据丢失。针对redis的持久化,存在不同的策略。
2025-08-02 23:20:23
1710
原创 万字讲清Redis中常见数据类型
Redis数据库提供丰富的数据类型和操作命令,主要包括5种核心数据类型及扩展类型。String类型支持SET/GET/MSET等基本操作,以及INCR/DECR等数值运算,应用场景包括缓存、计数和会话共享。Hash类型用于存储结构化数据,提供HSET/HGET等字段级操作。List作为双向链表实现消息队列功能。Set提供不重复元素的集合运算,ZSet是有序集合支持分数排序。此外还包含Stream、GEO、HyperLogLog等扩展类型。每种类型都有特定的内部编码优化存储效率,如int/embstr/raw
2025-07-30 14:06:05
1380
原创 Redis单线程模型的特点
redis对于所有请求的处理时只使用一个线程,但是会在处理网络IO时使用多个线程。redis能够使用单线程模型很好的工作,原因主要在于redis的核心业务逻辑,都是“短平快”的,不太消耗cpu资源,自然而然处理请求时就不太需要吃多核。单线程弊端:必须特别小心,某个操作占用时间长,就会阻塞其他命令的执行。
2025-07-24 16:32:34
425
原创 Redis数据类型与内部编码
在Redis中通常普遍认为,使用redis的能进行查询,插入,删除,修改操作都是O(1)是因为他是利用hash表实现的,但是,背后的实现不一定是一个标准的hash表,它,不过仍然能保证时间复杂度符合承诺。在面对不同的场景,redis会进行特定的优化,不同的数据类型(value值)的实现会有不同的内部编码格式,如下表所示。最基本的字符串。(底层就是一个C++的char数组,或者Java的byte数组)当value是整数的时候,此时redis可能会直接使用int来保存。针对短字符串进行的特殊优化。
2025-07-24 16:31:36
398
原创 Redis通用常见命令及过期策略
Redis基础命令包括:get/set操作键值(key固定为字符串,value支持多种类型);全局命令keys(O(N)复杂度,生产环境禁用)、exists/del(O(N))、expire(设置过期时间)、ttl(查看剩余时间)、type(查看数据类型)。Redis采用定期删除+惰性删除的过期策略:定期抽样检查过期key并删除,访问时触发过期key删除。还支持优先级队列和时间轮等高效定时器设计,但Redis未采用。内存淘汰机制用于处理残留过期key问题。
2025-07-20 12:22:24
400
原创 认识redis
真实的演化过程都是和业务发展密切相关的,业务是更重要的,技术只是给业务提供支持的。因为进程具有隔离性的特点,所以Redis可以通过网络通信,基于网络,把自己的内存中的数据给别进程或者给别的主机的进程进行使用。Redis是将数据存储在内存中的一种数据库,因其相较于传统数据库(MySQL)速度很快的特点成为当前热门的数据库。MySQL是一个客户端服务器结构的程序,本体是MySQL服务器(存储和组织数据的部分)。从业务功能的角度,把应用服务器,拆分成更多功能更单一,更简单,更小的服务器。
2025-07-19 18:16:45
828
原创 Git用法—掌握企业级多人协同开发
gti是一个版本控制器,记录每次修改以及版本迭代的一个管理系统可以控制电脑上所有格式的文档项目中的源代码文档---对于开发人员来说。
2025-07-13 09:30:23
553
原创 JVM的内存区域划分,类加载器和GC
在写代码的过程中,会定义很多变量,比如栈上的局部变量,方法区的静态类型的变量等,因此就可以从这些变量作为起点,出发,尝试去进行“遍历”,所谓的遍历就是会沿着这些变量中持有的引用类型的成员,再进一步的往下进行访问。所有能被访问到的对象,自然就不是垃圾了,剩下的遍历一圈也访问不到的对象,自然也就是垃圾了。当每次增加一个引用指向内存里的对象,该对象的计数器就会+1,当减少一个引用指向该对象,该对象的计数器就会-1,当计数器到达0时,此时被专门的扫描线程给发现,就会被认为是垃圾说明这个对象可以被释放了。
2025-07-06 20:42:51
1144
原创 HTTPS的工作过程
HTTPS通过引入加密层(SSL/TLS)解决了HTTP明文传输的安全问题。其核心机制是:先用非对称加密安全传输对称密钥,再用对称加密高效加密数据。具体流程包括:服务器生成公钥私钥对,公钥通过数字证书由权威机构认证,客户端验证证书真实性后,用公钥加密对称密钥传输,服务器用私钥解密获取密钥,后续通信使用对称加密。这种混合加密方案既保证了密钥传输安全,又兼顾了加密效率。证书验证环节通过比对校验和确保公钥未被篡改,有效防止中间人攻击。
2025-07-04 22:22:41
1147
原创 锁策略、CAS与synchronized原理
1.对于”悲观乐观“,”重量轻量“,”自旋 挂起等待“是自适应的,初始情况下,synchronized会预测当前锁的锁冲突概率不大,此时以乐观锁模式来运行(此时也是轻量级锁,基于自旋方式实现的),在实际过程中,如果发现锁冲突的情况比较多,synchronized就升级成悲观锁(也就是重量级锁,基于挂起等待实现的)假设我去ATM取钱,我本身账户1000,我想取500,但在取钱的过程中,出现bug了,我按下取钱按钮没反应,我就又按了一下,此时,就产生了两个线程进行扣款操作!
2025-04-30 10:10:35
1135
1
原创 线程—代码案例
在第一个结构中,一旦客户端这把发送的请求多了,每个A收到的请求,都会立即发给B,A抗多少访问量,B就和A完全一样,不同的服务器跑的业务不一样,虽然访问量一样,但是单个访问消耗的硬件资源是不一样的,可能A能承担这些并发量,但是B就不行然后就之间挂了(比如B操作数据库,数据库本身就是分布式系统中相对脆弱的环节)假设一个线程的所有代码都是cpu密集型,这个时候,线程池的数量不应该超过N (设置N就是极限了),设置比N更大,这个时候,也没法提高效率了,cpu已经吃满了,此时更多的线程反而会增加调度的开销。
2025-04-28 08:15:10
1276
1
原创 线程—volatile、wait和notify关键字
假设这里是按照1,3,2来执行,当第一个线程(t1)调用此方法执行完1和3时,instance已经非空了,此t1还没执行完,cpu调度器就调度到第二个线程(t2),t2就开始执行,此时t判断instance为非空,就直接return instance了,进一步t2就有可能访问到instance里的属性和方法了,这时就容易出现bug了,这个执行顺序可以是1,2,3 也可以是1,3,2来执(1一定是先执行),不管什么顺序,单线程下都是无所谓的,但是在多线程下,可能就会出问题。结论:保证有序性是禁止指令重排序。
2025-04-27 10:53:52
1018
原创 线程—死锁
那么对于上面代码这种情况就会产生“死锁”,导致线程卡死,第二个想要加锁成功就需要第一次释放锁,需要执行到程序“1号”位置,但是想要到“1号”位置 就需要 第二次能成功加锁让程序继续往下走,由于第二次加锁处在“阻塞等待“状态,也就执不了代码,最终到不了2号位置,也就无法释放锁,因此线程就直接被卡死了。对于4来说,可以约定加锁的顺序,就可以避免循环等待 (例如针对锁进行编号,加多把锁的时候,先加编号小的锁,再加编号大的锁,所有线程都要遵循这个规则)但C++中std::mutex就是不可重入锁,就会出现死锁。
2025-04-23 20:16:17
744
原创 线程—线程安全
解决上诉问题的办法是上枷锁,利用关键字synchronized,在使用synchronized的时候,需要搭配一给代码块{},进入{}就会枷锁,{}里的内容执行完毕就会解锁,在已经加锁的状态中,另一个线程也对此同样进行加锁时,就会产生“锁竞争/锁冲突”,后一个线程就会阻塞等待,一直等到前一个线程解锁为止。但如果t线程一直不结束,join默认就会"死等" ,但是一般开发中不建议死等,可以用join(xxx)带参数进行等待,带一个超时时间,超时时间到了t线程还没结束,就会不在等待,继续执行主线程的剩余代码。
2025-04-23 15:00:52
968
原创 认识线程与进程
谈到并发编程,c++鼓励多使用多进程编程,而java更鼓励引入多个进程 是为了 实现并发编程 => 因为目前是多核cpu时代多进程,实现并发编程,效果也是非常理想但是,多进程编程模型,也有明显缺点。进程太重量,效率不高创建一个进程,销毁一个进程,调度一个进程, 消耗时间都比较多,消耗在资源申请上。为了解决上诉问题,就引入了“线程”(Thread)线程也叫做"轻量级进程",创建,销毁,调度都比线程更快。线程不能独立存在,而是要依附于进程(进程包含线程),进程可以包含一个线程,也可以包含多个线程。
2025-04-21 15:50:11
204
原创 C++入门基础
定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员。zpp是命名空间的名字,一般开发中是用项目名字做命名空间名。①命名空间中可以定义变量/函数/类型//变量//函数//类型int val;②命名空间可以嵌套//test.cppint a;int b;//N2为嵌套的命名空间int c;int d;③同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。//test.h。
2024-09-19 19:08:45
2260
7
原创 排序算法-归并排序
1. 归并的缺点在于需要O(N)的空间复杂度,归并排序的思考更多的是解决在磁盘中的外排序问题。2. 时间复杂度:O(N*logN)3. 空间复杂度:O(N)4. 稳定性:稳定我的主页还有其他排序算法欢迎大家前往阅读!
2024-09-17 16:59:29
532
原创 排序算法-交换排序
1. 快速排序整体的综合性能和使用场景都是比较好的,所以才敢叫快速排序2. 时间复杂度:O(N*logN)如果还想了解更多排序欢迎大家前往我的主页。
2024-09-16 09:59:01
1238
1
原创 排序算法-选择排序
直接选择排序的特性总结1. 直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用2. 时间复杂度:O(N^2)3. 空间复杂度:O(1)4. 稳定性:不稳定堆排序的特性总结1. 堆排序使用堆来选数,效率就高了很多。2. 时间复杂度:O(N*logN)3. 空间复杂度:O(1)4. 稳定性:不稳定。
2024-09-14 14:29:28
1002
1
原创 排序算法-插入排序
2.如果要插入的数比前一个数更小则需将前面大的数依次向后移动一次,当遇到的数比插入 的数小时则停下来进行插入。3. 希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在好些树中给出的希尔排序的时间复杂度都不固定。把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列。实际中我们玩扑克牌时,就用了插入排序的思想,从左往右将每一张牌插入到前面排好序的合适的位置。最坏时间复杂度:O(N^2)
2024-09-13 21:24:43
586
3
原创 数据结构-二叉树
在上一篇文章中我们初步认识了一下二叉树,我们主要讲解了一些关于树的概念和堆的结构与实现,详细请看,接下来我们主要讲解普通二叉树的实现。
2024-09-04 14:03:51
1206
6
原创 leetcode-设计循环队列
设计你的循环队列实现。循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。FrontReardeQueue()isEmpty()isFull()// 设置长度为 3// 返回 true// 返回 true// 返回 true。
2024-09-01 20:30:00
1221
2
原创 数据结构-栈和队列
栈(Stack)是一种特殊的线性表,其只允许在表的进行插入和删除操作。栈顶:进行插入数据和删除数据的一端。栈底:相对于栈顶的另一端。原则:栈的数据元素遵循LIFO( Last In First Out )的原则通过图也能明显看出栈的特点只有当栈顶元素出栈后,才能出后面的元素,有点类似于手枪的弹夹,用的时候先一个一个把子弹压进去,最后压进去的子弹最先打出,所以有的进栈也称为压栈。
2024-08-30 17:41:00
1375
4
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅