- 博客(142)
- 收藏
- 关注
原创 【Redis】-- key的过期策略
我们假设key已经到了过期时间了,但是并不会删除它,它还存在,知道一次访问,正好用到了这个已经过期了的key,此时就会让redis服务器出发删除该key的操作,同时给客户端返回一个nil。因为redis是单线程的程序,主要的任务就是处理每个命令,如果key的数量太大,就会消耗太多时间,导致正常处理命令被阻塞住了。所以redis采用每次抽取一部分,来验证时候到达过期时间,来保证这个抽取检查的过程足够快。惰性删除就比较符合懒人的心理了,用我妈的话来说就是“早了不动,晚了挠腚”🤦♀️。
2026-01-08 22:15:48
224
原创 【Redis】-- 单线程模型
redis 只使用一个线程来处理所有的命令请求,微观上来讲,redis服务器是串行/顺序执行多个命令的。并不是说一个redis服务器内部真的只有一个线程,redis服务器内部的多个线程是在处理网络IO。redis并不会出现多线程中 两个线程尝试同时对一个变量进行自增操作,表面上是进行了两次自增,结果却是自增一次的结果 的问题。redis之所以使用单线程模型可以很好的工作,主要原因是在于redis的核心业务逻辑都是扁平快的,不太消耗cpu资源,自然就不太吃多核了。但是如果redis中的某个操作占用时间长,就会
2026-01-08 09:49:33
226
原创 【多线程】-- JUC的常见类
通过信号量可以限制系统中并发执行的线程个数,对于计算机而言管理的是有效的资源数,如果在资源有限的场景下,都可以使用信号量去处理。但是方法没有返回值;:表示这是一个函数式接口,接口中有且只有一个未实现的方法,也就意味着可以使用lambda表达式简化创建写法。在创建ReentrantLock类时设置该锁是否是一个公平锁,默认是非公平锁,传入true为公平锁。实现公平锁时,会有一个队列来组织排队的进程,获取锁的顺序就按照线程先来后到的顺序。信号量是用来表示“可用资源的个数的”,本质上是一个计数器。
2026-01-06 10:40:26
796
原创 【多线程】-- 死锁
线程在获取锁资源的时候,由于获取不到导致线程卡死,多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。哲学家吃面的时候会拿起左右两边的筷子(一边一根),要求先那左边的,再拿右边的;如果桌子上的哲学家同时拿起自己左手边的筷子,这样大家就都拿不到右手边的筷子了,只能都阻塞等待,形成了死锁。只有在线程主动释放锁的时候,其他线程才有可能会获取到锁,别的线程不能直接抢。线程1等待线程2释放锁,线程2等待线程3释放锁,线程3等待线程1释放锁…就这样,锁A在等待锁B,锁B在等待锁A,循环等待造成死锁。
2026-01-05 19:04:07
492
原创 【多线程】-- synchronized原理
自旋锁:如果持有锁的线程能在很短时间内释放锁资源,那么那些等待竞争锁的线程就不需要做内核态和用户态之间的切换进入阻塞挂起状态,它们只需要等一等(自旋,一直让CPU空转,比较浪费CPU资源,因此自旋并不会一直持续进行,而是达到一定的时间/重试次数就不再自旋了,就是所谓的“自适应”),等持有锁的线程释放锁后即可立即获取锁,这样就避免用户线程和内核的切换的消耗。一旦涉及到其他的线程竞争锁(根据锁对象的对象头中记录的信息,很容易姐可以识别当前线程是不是之前记录的线程),再取消偏向锁状态,进入轻量级锁状态。
2026-01-05 17:31:07
370
原创 多线程 -- 常见的锁策略
轻量级锁:加锁的过程比较简单,用到的资源比较少,典型的就是用户态的一些操作(Java层面就可以加锁)。优缺点:内核态的操作,会生成对应的加锁指令,要等待被唤醒,在等待的过程中会释放CPU资源。写锁:写操作的时候加写锁(排它锁),只允许一个写锁执行任务,和其他锁是冲突的。重量级锁:加锁的过程比较复杂,用到的资源比较多,典型的就是内核态的一些操作。悲观锁是无论任何时候都加锁,消耗的资源多,所以可以说悲观锁是一种重量级锁。乐观锁是能不加锁就不加锁,消耗的资源少,所以说乐观锁是一种轻量级锁。
2026-01-03 19:35:37
407
原创 【JavaEE初阶】-- 网络原理(网络层)
街道的这个路由器最终是连接到了运营商的网络服务,运营商会提供一个公网IP,给到连接它的路由器,此时街道级别的路由器就可以通过公网IP访问网络上的任何主机了。是分⽚相对于原始IP报⽂开始处的偏移. 其实就是在表⽰当前分⽚在原报⽂中处在哪个位置. 实际偏移的字节数是这个值 * 8 得到的. 因此, 除了最后⼀个报⽂之外, 其他报⽂的⻓度必须是8的整数倍(否则报⽂就不连续了).不同的网络管理的网络范围是不同的,广域网是全世界,局域网只是一部分,一个网络内的IP地址不能重复,不管是公网还是局域网;
2025-12-01 20:52:51
564
原创 【JavaEE初阶】-- 网络原理(传输层)
定义一个分隔符来界定消息之间的边界如果是换行符:\r\n你好啊,一会儿去吃火锅\r\n行不行呀\r\n是不是在忙\r\nadflsjflsfj;lk;ds\r\n系统会回收进程的资源,包括文件描述符表,回收时相当于调用socket的close(),触发FIN操作。
2025-12-01 13:47:35
700
原创 【JavaEE】-- 网络编程套接字
网络编程是指网络上的主机通过不同的进程,以编程的方式实现网络通信(或称为网络数据传输)。当然,只需要满足进程不同就行,即便是在同一个主机,只要是不同进程基于网络来传输数据也属于网络编程。操作系统为用用提供了一组实现传输协议的接口–Socket API。JDK为系统API进行了封装,Java程序员使用JDK提供的API。ServerSocket是创建TCP服务端Socket的API.主要用于服务器端,创建一个TCP服务。方法签名方法说明创建⼀个服务端流套接字Socket,并绑定到指定端⼝方法签名。
2025-11-24 08:43:30
1007
原创 【JavaEE】-- Spring Web MVC入门
该注解是用来注册接口的的。路由映射:当用户访问一个URL时,将用户的请求对应到程序中的某个类的某个方法的过程。
2025-11-17 08:32:21
531
原创 【JavaEE】-- IoC & DI
Spring MVC 和 Spring Boot 都属于Spring ,Spring MVC是基于Spring的一个MVC框架,而Spring Boot 是基于Spring 的一套快速开发整合包。这三者专注的领域不同,解决的问题也不一样。总的来说,Spring就像一个大家族,有众多衍生产品,但他们的基础都是Spring。@Bean@Bean定义多个对象的时候我们就不能通过类型来获取对象了,需要使用Bean的名称来获取。IoC: 控制反转。也就是说Spring是一个“控制反转”的容器。
2025-11-13 19:56:54
962
1
原创 为什么封装第三方组件
有可能多个第三方的工具提供相似的功能,但是它的API和用法都是各不相同的,这个时候,我们对其封装,为我们当前项目提供一个统一的接口,这对于我们后续业务代码的开发是大有益处的,我们无需关心底层的具体实现的差异,直接调用我们封装的统一service.项目中使用第三方组件实现一些功能时,有时直接就能满足我们项目中的功能需求,但是有时我们需要使用第三方组件通过一个比较复杂的过程才能打到我们的需要,这个时候我们可以把这个复杂的过程封装成一个方法的,在项目的使用中将会更加简便。代码可读性与可维护性。
2025-11-13 12:57:37
217
原创 【JavaEE进阶】-- 加密算法
在数据库中通常存放一些用户的隐私信息,这些隐私信息通常不可以将其明文存放:1. 代码角度:代码bug漏洞可能会导致数据泄漏。2. 管理角度:管理员有权限查看数据表的数据,有可能会直接泄漏表数据。
2025-11-11 21:39:40
386
原创 【Spring Cloud 微服务】-- 服务拆分原则
以上面的电商系统为例,每一个微服务应该有自己的存储,配置,在进行开发,构建,部署,运行和测试时,并不需要过多关注其他微服务的状态和数据。在微服务架构中,一个微服务也应该只负责一个功能或业务领域,每个服务应该有清晰的定义和边界,只关注自己的特定业务领域。服务自治是指每个微服务都应该具备高度自治的能力,即每个服务要能做到独立开发,独立测试,独立构建,独立部署,独立运行.如果一些场景确实无法避免循环依赖或者双向依赖,可以考虑使用消息队列等其他方式实现。微服务之间需要做到单向依赖,严禁循环依赖,双向依赖。
2025-11-07 14:09:02
248
原创 【Spring Cloud微服务】-- DependencyManagement 和 Dependencies
如果子项目中没有对依赖指定版本,会从父项目中读取版本;如果子项目中指定了版本,就会使用子项目中指定的版本。只是对依赖进了声明,并没有实现jar包的引入,如果子项目需要用到相关依赖,需要进行显式声明。将所依赖的jar直接加到项目中,子项目也会继承该依赖。父工程的打包方式应该是pom,不是jar。
2025-11-07 12:29:50
289
原创 【JavaEE】-- Cookie &&Session
HTTP协议自身是属于“无状态”协议。无状态:默认情况下HTTP协议的客户端与服务器之间的这次通信,和下次通信之间没有直接关系。但是在实际开发中,我们很多时候是需要知道请求之间的关联关系的,比如:保存登陆状态。上图中的“令牌”,通常就存储在Cookie字段中。
2025-11-04 21:04:19
577
原创 【JavaEE】-- B/S && C/S 架构
1. 必须要安装客户端程序。不同的应用需要安装不同的客户端程序。2. 大部分业务都可以在客户端完成,包括客户端可以直接操作数据库等服务。充分利用本地的计算机资源。3. 由于客户端承担了更多的业务,所以其响应速度快。
2025-11-04 16:38:34
115
原创 【Redis】-- 分布式锁
在一个分布式系统中,也会涉及到多个节点访问统一公共资源的情况。此时就需要通过锁来做互斥控制,避免出现类似于“线程安全”的问题。而Java的synchronized或者C++的std::mutex,这样的锁都是只能在当前进程中生效,在分布式锁的这种多个进程多个主机之间就很难产生制约,分布式系统中多个进程之间的执行顺序也是不确定的。此时就需要分布式锁。
2025-09-17 17:45:46
1028
1
原创 【Redis】-- 缓存
缓存是一个相对的概念,访问速度快的设备可以作为访问速度慢的设备的缓存。CPU寄存器 > 内存 > 硬盘 > 网络。缓存速度虽然快,但是空间小,缓存之所以有意义,是由于二八定律(20%的数据能够应对80%的请求)。
2025-09-17 16:07:44
812
原创 【Redis】--集群
节点之间通过心跳包通信,心跳包中包含了该节点持有哪些slots.这个是使⽤位图这样的数据结构表示的. 表示 16384 (16k) 个 slots, 需要的位图大小是 2KB. 如果给定的 slots 数更多了, 比如 65536 个了, 此时就需要消耗更多的空间, 8 KB 位图表示了. 8 KB, 对于内存来说不算什么, 但是在频繁的网络心跳包中, 还是⼀个不小的开销的.
2025-09-16 19:49:44
904
原创 【Redis】-- 哨兵
再控制其他节点,执行slave of,让这些其他节点,作为新的主节点的从节点。多个哨兵进行投票,一个哨兵节点一票,多个Redis都认为这个Redis服务节点挂了(达到了法定票数)就认为这个Redis服务节点挂了。哨兵节点通过心跳包,判断Redis服务器是否正在正常工作,如果心跳包没有如期而至,就认为该Redis节点主观下线了。哨兵节点会自动的通知客户端程序,告知新的主节点是谁,并且后续客户端再进行写操作,就会针对新的主节点来进行操作。哨兵节点不负责存储数据,只是对其他的redis服务节点起到监控的作用。
2025-09-16 12:44:13
326
原创 【Redis】-- 主从复制
主节点将从生成RDB到接收完成期间主节点执行的写命令,写入到复制缓冲区中,等从节点保存完RDB文件之后,主节点再将缓冲区中的数据不发给从节点,不发的文件仍按以rdb的二进制格式追加写入到收到的rdb文件中,保持主从一致性。主节点可以进行读操作和写操作。本来在主节点上保存一堆数据,引入从节点之后,就是要把主节点上的数据复制到从节点上,后续如果主节点的数据有修改,也会同步到从节点上。主节点只需要同步部分从节点,剩下的节点交给从节点慢慢的去向从节点的从节点进行同步,这样主节点就不需要那么高的网络带宽了。
2025-09-15 20:16:51
1152
原创 【Redis】-- 事务
Redis的事务是否保证了原子性,这件事是存在争议的。原子性原本的含义:把多个操作打包在一起,要么 全部执行,要么全都不执行。Redis是做到了上述的原子性的含义的,但是Redis事务中的若干个操作,如果存在有操作失败,不会有回滚操作,错就错了。
2025-09-14 10:09:07
643
原创 【Redis】-- 持久化
所以子进程中的数据状态时父进程fork之间的数据状态,那fork之后父进程依旧在处理请求,这期间对内存的修改,子进程是不知道的。子进程并不需要读取 硬盘上哪个庞大的旧的AOF文件,而是遍历当前内存数据库中的所有数据,为每个键值对生成一条最精简的命令,并将其写入一个新的临时的AOF文件。在两次生成快照的中间,redis接收接收到了大量的key变化的请求,生成下一次快照之前,redis服务器挂了,那么中间这些key的变化就全丢了。写硬盘的时候,写入硬盘的数据的多少,对性能没有很大的影响。
2025-09-13 16:31:32
668
原创 【JavaEE初阶】-- JVM
当我们创建一个类时,先从应用程序加载器开始向上转发,一直转发到启动类加载器。类启动加载器在自己的路径下找,看有没有要创建的这个类,有则加载,没有就继续向下转发到扩展加载器。扩展加载器在自己的路径下找,看有没有要创建的这个类,有则加载,没有就继续向下转发到应用程序加载器。应用程序加载器在自己的路径中找到类并加载。
2025-09-12 20:54:39
1166
原创 【Spring Cloud】-- Nacos
如果设置了权重时候,发现该权重配置并没有生效,原因时我们当前使用的应用框架(Spring Cloud LoadBalancer)有自身的负载均衡配置方法,并没有使用nacos的权重属性进行负载均衡。由于成本和跨区访问是通过网络进行传输的,会出现延迟的现象,所以当微服务进行访问时,是尽量访问同机房的实例的,如果同机房的实例不可用时,才会去访问其他机房的实例。环境隔离就是这几个环境之间是不能相互通信的,Nacos提供了namespace来实现环境的隔离,不同的namespace的服务之间是不可见的。
2025-08-07 00:27:23
1322
原创 【Spring Cloud】-- 注册中心
服务提供者会在启动时向注册中心注册服务,并且会定时向注册中心发送心跳汇报存活状态。服务消费者会从注册中心中获取服务提供者提供的地址,并通过获取的地址调用服务提供者的接口。服务发现就是给服务消费者提供一个可用的服务列表。
2025-08-05 23:56:52
365
原创 【Spring Cloud】-- RestTeplate实现远程调用
但是这种风格的接口,只能从接口上定义其资源,但是无法通过接口了解具体对资源进行了什么操作。定义bean可以使用五大注解或者@Bean的方式来定义,但是RestTemplate是第三方的类,五大注解只能修饰自己的类,所以我们使用@Bean来进行修饰。: 是Spring提供的,用来封装HTTP调用,并强制使用RESTful风格,它会处理HTTP连接和关闭,只需要使用者童工资源的地址和参数即可。:表现层资源状态转移(资源在网络中以某种表现形式进行状态转移),是一种软件架构风格,表现层:资源的表现形式。
2025-08-05 22:06:16
305
原创 Linux基本命令
对于目录,该命令列出该目录下的所有子目录与文件。:用于显示指定文件末尾内容,不指定文件时,作为输入信息进行处理。:将文件重命名(第二个参数是文件)或 将其移至一个新的目录中(第二个参数是目录)。将当前工作目录改变到指定的目录下。:cp 源文件或目录 目标文件或目录。:mv 源文件或目录 目标文件或目录。:tail [参数] [文件]。:grep [参数] [文件]:ls[选项][目录或文件]:cat [选项] [文件]:用于查看系统上运行的进程。:查看系统上的网络状态。:查看目标文件的内容。
2025-08-05 00:17:38
268
原创 Redis基本介绍
如果在分布式系统中采用定义变量来存储数据的话是不能满足我们的需求的,定义的变量是只能在当前的服务器的进程的内部可以进行通信的。硬盘相当于对内存的数据备份了一下,如果redis重启了,就会在重启时加载硬盘中的备份数据,使Redis的内存恢复到重启前的状态。一个Redis能存储的数据是有限的,如果想存储更多的数据,就可以引入多个主机,部署多个Redis节点,每个Redis存储数据的一部分。Redis是在分布式系统中,才能发挥威力的,如果只是单机程序,直接通过变量存储数据的方式是比使用Redis更优的选择。
2025-06-23 20:53:55
755
原创 分布式系统
此时就可能会导致某个硬件资源不够用,无论是哪方面的资源不够用了,都可能会导致服务器处理请求的时间变长,甚至会处理出错,这极大的降低了用户的体验感。数据库服务器,就需要更大的硬盘空间,更快的数据访问速度,,就可以配置更大硬盘的服务器,甚至可以使用SSD硬盘。为了更方便代码的维护,就可以把一个复杂的服务器拆分成多个的,功能更单一,但是更小的服务器。通过增加应用服务器的方式,解决了处理更高请求量的问题,但是随着请求量的增加,对应的存储服务器要承担的请求量也会更多,此时就引入了读写分离,这种方式会比较麻烦。
2025-06-13 16:13:27
1092
原创 【JavaEE】-- HTTP
HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上的应用程序进程之间如何相互通信的规则和标准。简单来说,应用层协议就是应用程序用来”对话”的语言和约定。
2025-06-10 17:00:39
956
原创 【JavaEE初阶】-- 网络原理
我们在使用QQ时都是需要登录的,登陆的时候等于向QQ服务器发送了一个请求,然后QQ服务器给了有一个响应,此时QQ服务器就会记录登陆方的信息类似于key value的形式,比如:(key:QQ123456, value:IP:端口号)。发送方通过某种算法(CRC–对每个byte进行累加操作,最终得一个值)对载荷进行运算,得到一个值并保存起来,接收方在收到数据之后,取出载荷以相同的算法进行计算,如果得到的结果与校验和相同,就表示接收到的载荷与发送的载荷一致,中途没有被篡改,否则载荷就是无效的。
2025-05-28 16:06:38
1084
原创 【JavaEE】-- 文件操作和IO
文件是操作系统中的概念,Java为不同的操作系统做了封装,提供了一个File类,来让Java程序员操作文件。修饰符及返回值类型方法签名说明intread()一次读取一个字节的数据,返回-1代表已经完全读完了int最多读取b.length字节的数据到b中,返回实际读到的数量;-1代表已经读完了int最多读取len-off字节的数据到b中,放在从off开始,返回实际读到的数量;-1代表以及读完了voidclose()关闭字节流签名说明利用File构造文件输入流。
2025-05-27 16:31:24
974
原创 【MySQL】-- 事务
事务把一组SQL语句打包成为一个整体,在这组SQL的执行过程中,要么全部成功,要么全部失败。这组SQL语句可以是一条也可以是多条。来看一个转账的例子,如图:转账之前和转账之后张三和李四的总额都是2000-> );mysql> insert into bank_account(name, balance) values ('张三', 1000), ('李四', 1000);
2025-05-09 19:55:54
1338
原创 【MySQL】-- 索引(面试必问)
MySQL的索引是⼀种数据结构,它可以帮助数据库⾼效地查询、更新数据表中的数据。索引通过⼀定的规则排列数据表中的记录,使得对表的查询可以通过对索引的搜索来加快速度。不同的数据结构有自己的实现规则,不同的规则导致不同的数据结构的效率不同,最终时间复杂度和空间复杂度也不同。数据库最重要的功能是存储数据,在保证数据安全的基础上尽可能的提升效率。
2025-05-08 21:19:17
1826
原创 【MySQL】-- 视图
视图是一个虚拟的表,它是基于一个或多个基本表或其他视图的查询结果集。视图本身不存储数据,而是通过执行查询来动态生成数据。用户可以像操作普通表一样使用视图进行查询、更新和管理。视图本身并不占用物理存储空间,它仅仅是一个查询的逻辑表示,物理上它依赖于基础表中的数据。
2025-05-08 09:31:40
1449
原创 【MySQL】-- 联合查询
在数据库设计时由于范式的要求,数据被拆分到多个表中,那么要查询一个条数据的完整信息,就要从多个表中获取数据,如下图所示:要获取学生的基本信息和班级信息就要从学生表和班级表中获取,这时就需要使用联合查询,这里的联合指的是多个表的组合。参与查询的所有表取笛卡尔积(全排列),结果集存放在临时表中。观察哪些记录是有效数据,根据两个表的关联关系过滤掉无效数据。通过指定列查询,精简查询结果通过给表起别名的方式来精简查询sql语句2. 内连接2.1 语法简写:规范写法:
2025-05-07 17:37:50
1216
空空如也
在VS上运行代码时,出现这个,是什么意思,应该怎么解决?
2023-12-17
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅