自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 RabbitMQ七种工作模式

Topics和Routing的基本原理相同,即:生产者将消息发给交换机,交换机根据RoutingKey将消息转发给与RoutingKey匹配的队列. 类似于正则表达式的方式来定义Routingkey的模式.2. 当消息被RabbitMQ服务器接收并处理后,服务器会异步地向生产者发送一个确认(ACK)给生产者(包含消息的唯一ID),表明消息已经送达.Routing 模式是发布订阅模式的变种,加了key,作用就是过滤,就是根据Routing Key来进行筛选,将筛选后的消息发给对应的消息队列。

2025-06-18 19:06:14 982

原创 Redis缓存-数据淘汰策略

数据淘汰策略就是,当redis内存满的时候,此时在向redis添加新的key,那么redis会按照某一种规则将内存中的数据删掉,这种删除数据的规则成为内存的淘汰策略。1.如果有明显的冷热区分,建议使用allkeys-lru,为什么使用lfu呢,如果某个数据仅仅是在某个时间段内访问量比较高,其他时间就很少,所以就不能用lfu。3.如果业务中有置顶需求,可以使用volatile-lru,同时置顶数据不设置过期时间,这些数据就不会被删除,会淘汰其他过期时间的数据。下面就说一下LRU和LFU。

2025-06-04 00:12:35 377

原创 redis数据过期策略

定期删除:定期检查一定量的key是否过期,有两种模式,一种是slow,另一种是fast,这里面的参数都可以在配置文件中修改。所以这种模式解决了惰性删除的问题,限制频率,不仅可以对cpu友好,对内存也友好,唯一的缺点就是:不好控制频率和操作执行时长。首先说惰性删除,对于已经过期的数据,访问这个key的时候判断key是否过期,如果过期则删除,这种方式对cpu友好,只有使用key的时候才会进行过期检查,用不到的时候不用浪费时间进行过期检查。缺点就是,已经过期的key仍然会占用内存。

2025-06-03 23:37:16 329

原创 Redis缓存-双写一致性

共享锁:读锁readLock,加锁之后,其他线程可以共享读操作。排他锁,writeLock,枷锁之后阻塞其他线程读写操作。这种方式性能会第一点。还有一种传统的做法就是,延迟双删。这里为什么要双删和延迟呢,双删就是防止脏数据,延迟是因为数据库是中从模式,主节点要向从节点同步数据。所以就有了下面这种操作,就是通过异步通知,使用MQ作为中间件,更新数据后,通知缓存删除。有两种方式,起到的效果也不同,只种是不要求一致性这么高,另一种则是一致性高。这个双写一致性就问题其实就是数据库与redis数据进行同步的问题.

2025-06-03 11:35:07 214

原创 Redis缓存-穿透,击穿,雪崩问题及解决方案

就是当一个请求来时,发现逻辑时间过期了,这是他会创建一个线程并上锁,用重建数据库与缓存的连接,再将最新的数据写入缓存。方案一:就是当一直访问的数据不存在的时候,数据库生成一个空数据,就相当于null,并存储到redis中,这样请求就不会到达数据库,也就解决了问题,但是这种方案会有比较大的内存开销。什么是缓存击穿,就是在高并发的场景下,某个热点数据在缓存中瞬间过期,大量的请求直接打到数据库中,从而导致数据库挂掉。这两种方案要根据具体的业务场景来进行选择,方案一体现的强一致性,方案二则体现的是高可用。

2025-06-03 11:01:58 172

原创 怎么实现pid隔离

还要注意一点就是:当我们进行隔离的时候,是感受不到父进程的,也就是说我们要创建一个进程来分配这个挂载的文件系统的资源.既然要实现进程的隔离,我们还要将/proc这个文件目录里面的东西先挂载出去,就有了下面的命令.在进行pid隔离之前我们要有一块可以存储文件的磁盘,我们怎么来得到这块磁盘呢,其实很简单.我们将一个文件进行挂载,不就相当于一个磁盘了吗.就是将这个文件进行挂载,挂载之后就相当于磁盘了.挂载的意思就是可以理解为,我们的电脑插了一个U盘.这就是挂载.这样就将文件挂载上去了,我们可以使用一个命令。

2025-05-27 21:06:21 212

原创 Redis持久化存储

fork是linux系统提供的创建子进程的api(系统调用),这也就说明了redis只支持linux系统,在windows系统下是不支持的(我说的是以前,现在已经支持,但是linux更稳定,所以一般都是再linux使用redis).fork子进程的时候会将文件描述符表,pcb,虚拟地址空间(内存中的数据).我们从上面的流程图思考一个问题.就是父进程fork完毕之后,就已经让子进程写新的aof文件了,并且随着时间的推移,很快就写完了新的文件,让新文件替换旧文件,父进程还要继续写这个即将消亡的旧文件吗?

2025-05-14 20:16:06 708

原创 Nacos刚下载启动的时候启动不了?

我们在学习SpringCloud的时候,都会碰到我提到的问题,我们直接看解决方案.我们将启动的可执行程序,用编辑器打开,改成我上面26行的样子就可以运行了.我们从官网下载Nacos,当启动的时候发现直接闪退,问题是什么呢?其实很简单,就是Nacos默认是集群模式,我们要把它改成单机模式.上面这个图片是修改后的.就是26.

2025-04-22 21:21:15 242

原创 Tcp/IP五层模型

4.数据链路层收到数据包,数据链路层典型的协议是:以太网(电脑,通过有线网,传输数据走的就是"以太网协议",以太网也有自己的数据包格式,将拿到的数据链路层的数据包进一步封装,也就是在数据包的前面加上"以太网头部"也可以说是帧头,在数据包的后面加上"以太网尾部"也可以说是帧尾,这样就封装好了,我们将封装好的数据叫以太网帧.然后将数据发送到物理层.网络层的作用就是规划消息传输的路径,数据链路层则是端到端的传输,也就是网络接口,可以是不同机器之间,也可以是同一台机器.同一台机器很好理解,就比如说,文件传输助手.

2025-04-22 16:01:33 387

原创 序列化时,怎么写不用多次写try-catch

看这些方法,执行顺序是,先调用tryParse这个方法,将lambda里面的表达式作为参数传递进去,在内部调用parser.call(),再执行表达式里面的代码,tryParse里面写了try-catch,写一次就不用写了.这个有很多方法,我只是截取了部分的代码,我们会看到一个lambda表达式,都调用了tryParse这个方法,我们进去这个方法里面看看。我们看到这个方法里面使用了try-catch,当其他发方法对他进行调用的时候,就不用写了,我们直接将源码里面的代码拿过来,修改一下.

2025-04-21 20:12:09 186

原创 RabbitMQ:工作流程

我们明白,RabbitMQ是一个生产者消费者模型,生产者和消费者都是客户端.生产者是发送消息,消费者是接收消息.生产者创建消息通常是一个带有一定业务逻辑解构的数据.消费者只会收到消息,不知道生产者是谁,生产者,也不知道消费者是谁.有了上面这些话,我们来看下图,即RabbitMQ的工作流程.Queue:队列,这个才是来存储消息的,exchange只是起到转发的作用,这里说一下,多个消费者可以订阅一个队列,一个消费者也可以订阅多个队列.Broker就相当于RabbitMQ服务器.

2025-04-21 14:06:24 253

原创 Redis事务

还有一个命令就是WATCH,这个命令是用来监控某个key在事务执行前,是否发生变化,就比如说,我开起了事务,设置了一个键值对,还没有执行事务,另一个客户端也设置了一个相同的key,值不一样,那么就可以说这个key在执行事务之前发生了变化,如果发生变化,事务执行的结果就是nil.Redis是有原子性的,但是和Redis有一些不同,原子性是将操作打包到一起来执行,在MySQL中,会保证要么全执行成功,要么全不执行,但是在Redis中,没有这么做,而是要么全执行要么全不执行,没有保证成功.

2025-04-21 13:38:18 273

原创 软件测试-概念篇

一般在软件开发开发初期需求不是很明确的时候,采用渐进式的开发模式.螺旋模式是渐进式开发模式的代表之一,这对那些规模庞大,复杂程度高,风险大的项目尤其适合.这种迭代开发的模式给软件测试带来了新的需求,它不允许有一段独立的测试时间和阶段,测试必须跟随开发迭代而迭代.因此回归测试的重要性不言而喻了.原型--->风险分析--->需求分析--->风险分析--->原型1--->计划--->风险分析--->原型2--->设计--->测试模型我主要介绍两个模型,一个是V模型,一个是W模型,而W模型其实也是双V模型.

2025-04-13 18:26:15 862

原创 个人论坛系统测试报告

论坛系统基于前后端分离实现,同时使用了数据库来存储数据,同时将其部署到云服务器上,项目的主要功能有,注册,登录,发布帖子,查看帖子详情,对帖子点赞,个人可以删除和编辑帖子,用户对个人信息的修改,支持站内信.测试用例执行测试操作(只展示部分测试):1 注册注册成功,所有列举的功能都试了,没有异常.2登录登录成功,没有出现异常情况.3.发布博客发布功能也没有问题,发布后成功跳转到主页页面显示出发布的帖子.4 个人中心每种情况都试了一下没有问题,密码修改后会跳转到登录界面5 站内信测试通过发私信可以看到小铃铛有红

2025-03-23 19:57:04 432

原创 java面试题01

JDK:Java开发工具包,提供给Java程序员使用,包含JRE,同时还包含了Java自带的调试工具(首先说一下三者的包含关系:JDK包含JRE,JRE包含JVM,这里可以看出JDK也包含JVM看下图。jstack等),同时还包含了Java编译器javac和java工具。JRE:Java的运行时的环境,包含了Java基础类库和JVM.Java JDK,JRE,JVM三者之间的关系。总结一下就是:jdk=jre+jvm。JVM:就是用来运行java代码的。

2024-08-20 16:06:42 181

原创 java IO 读写(字节流和字符流)

mport java.io.*;import java.util.Scanner;public class IO { //文件操作 字节流和字符流 //字节流 // InputStream和 OutputStream 他们两个都是抽象类,不能实例化 //实例化 FileInputstream FileOutputStream //构造方法填写参数:绝对路径,

2024-08-09 11:07:02 396

原创 多线程(基础知识)

多线程,字面意思就是多个线程(多个线程执行程序),我们在之前学习的都是单线程,多线程我们在以后的开发中会经常使用到,举个例子,就比如说一个音乐播放器,我们在搜索的时候,同时还可以播放歌曲,这就是多线程.

2024-07-26 09:31:44 977

原创 线程和进程的区别

进程相对于线程比较大,如果我们频繁创建进程,效率就会大大降低,所以在Java中我们都是以线程为重点.效率低是因为每次创建进程系统都会分配资源.而线程就不会,这里就出现了包含关系,线程包含于进程之中.也就是说在创建线程时系统就不再需要分配资源了,线程会直接拿系统为进程分配好的资源.线程不是越多越好,线程多了就会出现,一个任务,其他线程抢不到的现象,这也就浪费了线程.应该合理分配线程.多个线程一般会相互影响,如果有一个线程出现崩溃,可能会导致其他线程出现问题,最终导致程序崩溃.同一个进程的线程共用同一份资源。

2024-07-01 15:43:59 238

原创 StringBufffer和StringBuilder

我们知道String的内容不能修改,而StringBuffer和StringBuilder可以修改.在String的源码中他的对象被private修饰同时又被final修饰,这就意味着我们拿不到字符串的引用.也就无法修改字符串.而StringBuffer和StringBuilder他们两个可以实例化对象,对象里面可以存储字符串,这也就意味着,我们拿到了字符串的引用可以进行修改.当然,这两个类还有很多方法,具体可以查阅官方文档.

2024-05-04 16:31:16 191 1

原创 static 总结

2.static代码块:在加载类的时候,会优先加载到内存中,会被优先执行,如果一个类继承了另一个类,父类中也有静态代码块,会优先被执行,接着就是执行子类中的静态代码块,再执行构造方法.这里注意,在执行构造方法时,会优先执行父类的构造方法,接着才是子类的构造方法.1.要调用static修饰的变量和方法,最好用类名来调用,当然用实例化的对象调用也可以,但不推荐.4.被static修饰的变量和方法只被执行一次.2.static 修饰的成员变量从属于类。上面就是static常用的一些结论.

2024-05-04 14:04:31 264 1

原创 Java类与对象

在我们刚开始接触编程时,我们是面向过程编程。面向对象是一种编程思想,主要是依靠对象之间的交互来解决问题,也就说我们没有必要关注具体怎么实现。举个例子来说:洗衣服,要是按照我们以前的想法就是,洗衣服要先拿个盆将衣服放到里面,放入洗衣粉,手搓.....最后晾晒。这个过程十分十分复杂,这就是面向过程编程。如果我们是面向对象的思想,我们要做的就是将衣服放入洗衣机,倒入洗衣粉,剩下的交给洗衣机,这就是面向对象,处理问题起来十分简便。

2024-03-02 16:06:59 860

原创 java基本数据类型和运算符

无论在C语言中还是java中byte都是占1个字节,short占个字节,但是在java中int 永远占4个字节,long永远占8个字节。同样在Java中double在任和系统下都占8个字节。同时注意浮点数在内存中的储存和整型不同,比较麻烦所以在计算浮点数的时候要小心。浮点数计算时都是一个近似值,不是精确值。

2024-02-14 11:11:24 379 1

原创 C语言的编译和链接

首先在执行代码的时候分为两个大部分:翻译环境和运行环境。其中翻译环境又可分为编译和链接两个部分,运行环境又包括可执行程序和输出结果两个部分。画图象如下:那么下面具体说一下编译和链接的过程。

2024-01-16 10:56:56 399 1

原创 柔性数组的使用

c99中规定,结构体中最后一个元素允许是未知大小的数组,叫做柔性数组.从这里看出柔性数组只会出现在结构体当中.下面写一个简单的代码认识一下柔性数组struct stuint i;int a[0];上面代码中a就是一个柔性数组,当然a后面的[ ],里面的0;可写可不写,取决于编译器.当一个结构体中存在柔性数组时,不会计算柔性数组的大小,上面这个结构体大小为4个字节.

2023-12-07 23:52:00 111

原创 C语言动态内存管理常用的函数

1.当你在开辟一块空间的时候,一定要判断,这个空间是否开辟成功,上面三个函数开辟空间如果开辟不成功,会返回空指针,也就是判断返回的是不是空指针.在介绍calloc函数那一段代码有体现.2.原空间后面的空间,不够你想要的空间的大小,这是realloc函数会重新开辟一块空间,并将原空间的值拷贝回来,这时函数的返回值为开辟新的空间的起始位置.2.当你在释放一块空间的时候,那块空间是被释放了,但是指向起始位置的指针还在,如果不将该指针置为空指针,那它就成了野指针,野指针是非常危险的.calloc函数语法如下。

2023-12-06 22:45:59 106 1

原创 判断当前机器是大端存储还是小端存储

可以用两种方法来实现.

2023-12-05 18:10:22 90

原创 C语言联合体大小的计算

我们用计算结构体的方法推算一下,arr是是一个char类型的数组,每个元素占1个字节,总共有7个元素,也就是要占7个字节,但是在对齐规则里,总大小要为最大对齐数的整数倍,在该联合体中最大对齐数为4,也就是int 的大小,所以该联合体的大小为8个字节.有人说联合体的大小就是联合体成员变量类型中最大的那个,这个说法是不对的.当然上面这个联合体的大小就为4个字节.但是如果在联合体内有数组呢,结果就不一样了,看下面这段代码。上面这段代码就是联合体的创建.结果为8,也就是8个字节,

2023-12-04 19:05:05 199

原创 结构体所占空间大小的计算

先看第一个结构体,首成员变量为char s1,大小为1个字节,即在0的前面放s1,与0对齐对齐数即为1(我是在编译器为VS的情况下来说的),第二个成员变量为 int i 大小为4个字节,这时 i 的对齐数为4,也就是说 i 的数据要在4那个位置开始放数据,大小为4个字节,会占4个格子,最后一个也是一个char类型,占一个1格子,计算一下此时已经用了9个格子,也就是9个字节(但是结构体的总大小为最大对齐数的整数倍,同时还要比9大,因为12是4的倍数,且比9大,所以该结构体的大大小为12个字节.

2023-12-03 20:45:37 206 1

原创 大端字节序和小端字节序

这是因为在计算机系统中我们是以字节为单位为的,每个字节都对应一个内存地址,一个字节相当于8个bit位,但是在C语言中我们有short类型占两个字节16个比特位,int类型占4个字节32个比特位等各种数据类型,对于大于8个字节的处理器,比如16位,32位或者64位等机器,寄存器大于一个字节,这就存在着如何将多字节安排的问题,也就有了大小端之分.数据在内存中存储时,超过一个字节时就有存储顺序的问题,按照不同的顺序我们分为大端字节序和小端字节序.上面就是大小端的介绍.

2023-11-29 19:08:05 121 1

原创 C语言的内存函数

那么下面对该函数进行简单的实现。

2023-11-28 21:00:45 82

原创 C语言指针内容概括

要说指针首先要说什么是指针,在C语言中指针可以理解为地址,即指针==地址,而我们口头上说的指针实际上是指针变量.接着我们还要介绍一点前言就是,也就是最简单的一些代码.那么看下面这段代码首先看&操作符,这是取地址操作符,就是把a的地址取出来,放到指针变量p里面,p左边的int*,其中 * 在说明p是指针变量,int说面p指向整型类型的对象.那么要是char类型的要怎么写呢?代码如下charch ='w';pc = &ch;ok,有了前面的铺垫,那么下面开始介绍指针的其他内容指针的分类。

2023-11-22 20:04:13 43 1

原创 C语言的分支与循环

那么介绍一下怎么用,switch后面的表达式,必须是整型表达式,当满足表达式的时候,程序会接着往下走,当走到第一个满足case后面的值是开始依次往下执行.如果遇到break,则会跳出循环.当然循环也可以嵌套,可以while嵌套if,也可以if嵌套while,总之,就是一句换循环可以嵌套.还拿上面的例子来说如果这个数是奇数执行语句1,不是奇数则走语句2,代码如下。if else 语句如果表达式成立,则执行语句1,不成立,执行语句2.for循环是最常使用的循环,语法如下。判断输入的数是0,整数还是负数.

2023-11-13 22:49:54 51

原创 原码,反码,补码

一个整数二进制最高位为符号位,0表示正,1表示负.比如-10的原码(原码就是将对应的数转换成二进制序列)为10000000000000000000000000001010,而10的原码为 00000000000000000000000000001010.原码--------------------------------------->反码------------------------------------->补码。首先,先说一下,整数的的二进制表示方法有三种,即原码,反码,补码.

2023-11-05 23:09:39 60 1

原创 进制的转换

十六进制转二进制和八进制转换成二进制相似,不同之处是十六进制的每一个数要用4个二进制数表示.比如一个十六进制数0x365,5用四个二进制数表示为0101,6可表示为0110,3可以表示为0011,即十六进制数0x365,转换成二进制为001101100101,二进制转16进制反过来即可.二进制转十进制:拿一个二进制数1010,转成十进制:0*2^0+1*2^1+0*2^2+1*2^3=10。实质就是拿二进制数的每一个数,乘以2^n-1,再将每一个乘积加起来就转换成了十进制.2.八进制转二进制.

2023-11-05 22:47:53 104 1

原创 C语言编译和项目创建

C语言是一种编译型计算机语言,C语言源文件是文本文件,需要经过编译器翻译和链接器链接,生成二进制可执行文件,可执行文件才可以被执行.具体过程为下图。

2023-11-03 23:10:31 78

原创 java类型转换

byte, short,char可进行计算,但计算时要转换为int类型.否则会报错.也就是说在进行运算的时候要将结果存到int类型或者更大类型,比如float,double类型.char和short所占大小相同,但任然会报错,从byte转换为char任然会报错.java的自动转换是将是由大向小的转换,也就是大的数据类型可以转换为小的数据类型。java类型转换比python复杂,下面我整理了java类型转换的细节。强制转换是将大的数据类型转换为小的数据类型.char c2=m;上面数据类型从左到右依次增大。

2023-10-05 16:24:05 42

空空如也

空空如也

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

TA关注的人

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