- 博客(71)
- 收藏
- 关注
原创 selenium自动化测试
Web 自动化测试的操作核心是能够找到页面对应的元素,然后才能对元素进行具体的操作。常见的元素定位方式非常多,如idclassnametagnamexpath。常用的主要由和xpath。
2026-03-08 16:08:06
386
原创 测试方法篇
不同的版本(软件,系统),浏览器的兼容性(同一个浏览器上不同版本打开我写的系统)不同浏览器(不同浏览器上打开我的系统),(比如谷歌浏览器是否能在苹果,联想,win10,win11...上打开),还有数据的兼容性(场景 : 可以进行手机号注册,可以进行微信注册,邮箱注册...邮箱注册之后,个人手机号是否可以登录)常见的测试方法有黑盒测试、白盒测试和灰盒测试。但是,灰盒测试没有白盒测试详细和完整,黑盒测试是覆盖产品范围最广的测试,因此灰盒测试基本是不能够替代黑盒测试,否则需要很大的代价,设计非常多的用例。
2025-12-19 19:13:19
705
原创 RabbitMQ:应用问题
不过其实在很多场景下是不需要保证消息的顺序性的,除非是一些对顺序性要求严格的操作,比如银行转帐的顺序,或者同一用户短时间内进行大量的个人信息修改操作,这种就要求以最后一次修改为准。幂等性关注的是对资源的影响,而非返回结果。当有消息成功发送到MQ后,此时因为网络问题生产者宕机,导致MQ对生产者的应答失败,如果之后生产者意识到消息发送失败并且尝试重新发送,那么消费者就会收到两条相同的消息了并且ID一致。MQ的幂等性是指,同一条消息被多次消费,对系统的影响是相同的,一般MQ的消息传输分为三个层级。
2025-11-23 20:00:57
648
原创 JAVA微服务脚手架项目详解(四)
就好比我们的身份证,之所以能标识一个人的身份,是因为它不能被篡改,而不是因为内容加密。在本项目中,C端用户的CRUD操作主要放在fw-admin模块下,而fw-portal里主要写一些用户行为的接口,比如登录注册,退出等用户操作的功能。还有一点需要注意,在涉及到一些敏感的信息时,比如用户电话或者账号密码之类的,肯定是不能明文传输的,所以我们就需要对这些字段进行加密。字典服务:通常是管理员在后台配置好,用户去读取,可以方便对⼀些内容进行分类查询,⼀般会是名词。AuthFilter 网关拦截器。
2025-11-22 15:31:59
991
原创 JAVA微服务脚手架项目详解(三)
与传统文件系统(如块存储或文件存储)不同,对象存储将数据存储为独立的“对象”,每个对象包含数据本身、元数据以及唯一的全局标识符(如对象ID),结合元数据和唯一的标识符可以进行数据检索。对象存储通常用于存储大量非结构化数据,如图片、视频、日志文件、备份数据等。这种方式提供一个独立的文件微服务,文件微服务向业务微服务提供统一的上传、下载、查看接口,不同的业务微服务调用方式相同,并且屏蔽了底层调用OSS服务(或其他厂商所提供对象存储服务的)的接口,即使以后迁移OSS服务商,业务微服务层面的系统也不需要变动。
2025-11-22 15:31:16
688
原创 JAVA微服务脚手架项目详解(二)
/ 问题3:A线程释放了B线程的锁,可能当t1线程获取锁proKey后这种执行减库操作时卡住了,然后时间超过了锁过期时间,此时t2线程也过来成功拿到锁,结果还没执行完任务,t1线程恢复了并执行了finally里的解锁操作,就把t2线程的锁给解开了。redis相关配置,这里要对redisTemplate进行序列化配置,不然redisTemplate会以16进制存储key-value,虽然对于redisTemplate来说可以认识,但是对于开发者来说并不友好而且内存占用较大,所以这里要进行序列化配置。
2025-11-22 15:30:32
1110
原创 RabbitMQ:持久化和发送方确认
一个快递,从商家发到买家手里,这个快递在运输途中任何时候都可能出问题,比如在运输路上可能会搞丢,或者在对应分拣栈站也可能被搞丢,就像是消息一样,可能在传输途中丢失,也可能在交换机或队列丢失,所以我们需要对消息进行持久化处理,来保证消息的持久性。RabbitMQ的持久化分为三个部分,交换机持久化,队列持久化,消息持久化。
2025-11-22 13:55:44
1005
原创 JAVA泛型擦除问题
在java中的泛型是伪泛型,在编译器编译泛型代码时,会移除泛型类型参数的相关信息,使得字节码中不包含泛型类型信息,让java泛型在运行时表现为原始类型。比如List<Object>和List<String>,对于JVM来说,都是list,里面的Object和String类型信息,JVM是看不到的。下面举个例子。这段代码的结果为true,这里定义了两个ArrayList,但是他们的类型参数信息不一样,一个是String,一个是Integer。
2025-11-22 13:54:50
1286
原创 RabbitMQ:消息确认
消息的唯一标识,它是一个单调递增的64位长整型值。手动确认时可以将队列中的信息分为两个部分,一时等待发送给消费者的,二是以及发送,正在等待确认的,如果RabbitMQ一直没有收到确认信号,并且消费这条消息的消费者已经断开链接了,那么RabbitMQ就会重新安排这条消息入队列,等待下一个消费者。在RabbitMQ的管理界面里也可以看到,这里的get message其实也可以看作是一个消费者,从队列中拿取数据,自上而下分别是,不确认拿完后放回队列,自动确认拿完后不放会队列,拒绝并重新入队,拒绝但不重新入队。
2025-11-20 15:54:55
1205
原创 JAVA微服务脚手架项目详解(一)
为了满足业务需求,Java提供了一些内置的异常类,但是它们并不一定能够满足我们的具体业务需求,所以我们需要自定义异常类。核心设计给出一份自定义异常模板,项目可按自身需求扩展更多异常类型。继承自 RuntimeException,异常一般在运行阶段抛出。核心字段:状态码 + 提示信息,具体可随项目调整。提供异常捕获:微服务和网关全局异常处理中应该应该分别提供自定义异常的捕获和处理三种构造方式:传入标准状态码,自动取用对应的 code 与 msg。仅传入提示信息,code 使用默认状态码。
2025-11-20 15:52:51
849
原创 SpringCloud:Eureka和负载均衡
在最初的架构体系中,集群的概念还不那么流行,且机器数量也比较少,此时直接使用 DNS + Nginx 就可以满足几乎所有服务的发现。相关的注册信息直接配置在 Nginx。但是随着微服务的流行与流量的激增,机器规模逐渐变大,并且机器会有频繁的上下线行为,这种时候需要运维手动地去维护这个配置信息是一个很麻烦的操作。所以开发者们开始希望有这么一个东西,它能维护一个服务列表,哪个机器上线了,哪个机器宕机了,这些信息都会自动更新到服务列表上,客户端拿到这个列表,直接进行服务调用即可。这个就是注册中心。注册中心主要有三
2025-11-15 20:31:36
1898
3
原创 Rabbit MQ:概述
MQ就是Message Queue的缩写,本质上就是一个队列只不过队列里存放的元素是一些消息而已,消息的类型可以很简单比如一个数字或者一个字符串,也可以是一些内嵌对象等等。MQ一般用于分布式系统之间的通信数据直接由一端到达另一端数据由一端发送到一个容器存储起来,之后达到某个条件后再由这个容器发送给另外另一端。
2025-11-15 20:30:32
1017
原创 深入探讨redis:分布式锁
分布式锁,也就是在分布式系统中用的锁,在分布式系统中也会遇见像多个节点访问同一个公共资源的情况,随机产生类似线程安全资源这样的问题,和java中的synchronized以及C++中的std::mutex这种锁不同的是,分布式系统中竞争的公共资源的从线程升级为进程。
2025-11-10 16:15:24
1555
1
原创 深入探讨redis:缓存
缓存的核新思路就是把⼀些常用的数据放到触手可及(访问速度更快)的地方,方便随时读取。比如我们一般都把钱存在银行,并且会拿出一部分出来放在自己的钱包里用来日常开销,那么这个钱包就相当于银行的缓存,我们为了不每次用钱的时候都去银行取,所以用个钱包在钱包里放一部分钱要使用的时候直接从钱包里拿(不考虑电子支付)。对计算机来说,速度往往和存储空间是成反比的,访问速度越快存储空间越小,redis是读内存的访问速度要比Mysql快但空间也比mysql小很多,所以一般缓存里只会放一些(热点数据)会频繁访问的数据。
2025-06-02 11:25:06
1126
20
原创 深入探讨redis:万字讲解集群
首先做完准备工作后,生成每个redis节点的配置文件接着使用docker创建出11个redis节点,并启动容器最后使用redis-cli 执行构建集群命令。
2025-06-01 10:06:36
1010
15
原创 深入探讨redis:主从复制
在若干个redis节点(物理服务器)中,有的节点被作为主节点,有的则作为从节点分别部署在redis-server进程中,从节点上的数据跟随主节点上的数据变化并保持一致。也就是说如果主节点上保存了一些数据,那么就要将这些数据复制一份出来给从节点,当主节点对这些数据有修改时,从节点也要进行对应的修改,并且从节点上的数据是不能主动或直接修改的,只能读取数据。//从节点也可以看作是主节点的副本。
2025-05-31 14:41:11
1433
11
原创 深入浅出:Spring IOC&DI
IOC(Inversion of Control),是一种设计思想,在之前的里就在类上添加@RestController和@Controller注解就是使用了IOC,这两个注解IOC的意思就是,在之前我们的面向对象编程中,我们要使用一个对象需要自己new出来,但是现在使用IOC思想后,我们创建对象的时候,是通过容器来创建的,。控制反转这个词听起来很高大上其实就是一个很简单的思想,比如之前我们需要什么工具都要自己去找,这个工具可能在车库可能在卧室。
2025-05-30 17:44:42
1811
21
原创 深入探讨redis:哨兵模式
本文介绍了Redis主从复制和哨兵机制的基本概念、手动与自动恢复主从复制的方法,以及使用Docker搭建哨兵环境的步骤。主从复制在主节点故障时,从节点无法自动接替主节点功能,需手动恢复。哨兵机制通过监控Redis节点,自动在主节点故障时选举新的主节点,确保系统的高可用性。文章详细描述了使用Docker和Docker-compose编排主从节点和哨兵节点的过程,包括配置文件的编写和容器的启动。此外,还介绍了哨兵节点重新选举主节点的流程,包括主观下线、客观下线、选举leader和选择新主节点的步骤。最后,文章强
2025-05-20 16:30:14
1154
原创 一篇解决Redis:持久化机制
Redis持久化方案主要包括RDB(Redis DataBase)和AOF(Append-Only File)两种方式。RDB通过定期生成数据快照进行持久化,适合备份和全量复制,但可能因未及时保存导致数据丢失。AOF则记录每次写操作,通过重写机制优化文件大小,提高数据恢复效率。AOF支持多种缓冲区刷新策略,以平衡数据可靠性和性能。此外,Redis还引入了混合持久化,结合RDB和AOF的优点,以二进制格式存储快照,同时追加文本格式的写操作,进一步提升性能和可靠性。
2025-05-14 23:01:40
1000
12
原创 关于我在实现用户头像更换时遇到的图片上传和保存的问题
最近在实现一个用户头像更换的功能,但是因为之前并没有处理过图片的上传和保存,所以就开始到处查阅资料。整个流程涉及到三个路径(实际上是两个,一个数据库存储的要被映射的路径,一个实际存储图片的路径)图片的存储路径:这个路径因为transferTo的原因只能使用绝对路径,所以需要提前选择一个文件用来存储图片。
2025-05-11 15:06:07
877
8
原创 Spring Web MVC基础理论和使用
MVC是一种架构模式,全称是Model(模型) View(视图) Controller(控制)Model(模型):是应用程序的主体,用来存储数据和处理用户请求的业务逻辑。View(视图):用来和浏览器交互的部分,展示模型中的数据,比如jsp和htmlController(控制) 用来接收视图发来的请求,将数据交给Model处理,并且将处理后的结果返回给视图。
2025-05-09 23:06:51
1267
原创 数据结构--红黑树
RED,BLACK//创建的新节点要是红色//新增的节点必须是红色的,如果是黑色的就会破坏每条路径黑节点个数相同,导致需要再新增节点以至于引起其他问题,如果插入红节点导致有两个连续的红节点,也只需要通过改变节点颜色或者旋转就可以恢复平衡。红黑树的插入主要会遇到三种需要调整的情况cur为红,parent为红,granderFather为黑,uncle存在且为红解决方法:将叔叔和双亲节点改为黑色,祖父节点改为红色如果祖父的双亲节点的颜色是红色,需要继续往上调整。
2025-05-08 20:03:47
859
1
原创 数据结构--AVL树
二叉搜索树可以帮助我们以极高的效率查找(理想情况下是logn),但是当在极端情况下,比如当树中的节点值是有序的时,二叉搜索树会变成一个单枝树,相当于一个链表,于是乎为了让树更接近与一个完全二叉树,想着当向二叉搜索树中插入新节点后,让每个节点的左右子树高度差的绝对值不超过1就可以降低树的高度从而提高效率,于是就有了AVL树。//平衡因子//平衡因子=右子树高度-左子树高度当新节点插入后如果树不平衡,既parent的平衡因子为-2或者21.parent的平衡因子为2,说明右树高。
2025-05-06 22:18:22
1208
17
原创 算法刷题篇
/目标数组设定为arr[n+1][m+1],注意题目数组是从1下标开始如果我们使用暴力解法,每次前缀和都遍历数组那么时间复杂度就是O(m*n*q)这样的时间复杂度必然是会超时的所以我们必须转换思路,首先创建一个前缀和数组dp[n+1][m+1],这个数组里的每个元素都是arr[1][1]到arr[i][j]这个范围的矩阵的所有元素的和,比如以上图输入为例。dp[2][2]就是arr数组的arr[1][1]到arr[2][2]的矩阵的和,即1+2+3+2=8。
2025-05-05 15:49:58
1285
1
原创 详细PostMan的安装和基本使用方法
选择Body为form-data,这种格式通常用于提交图片或者文件,对应Content-Type: multipart/form-data。
2025-04-27 15:11:52
621
1
原创 创建第一个Spring Boot项目
随着Spring的快速发展,项目中的XML文件越来越多,繁琐的配置以及,整合第三方框架的配置问题,导致大大增加了开发和部署的效率,使开发者无法专心于业务的开发。Spring Boot就相当于使Spring框架的脚手架,它的产生就是为了提高Spring的开发效率。Spring Boot继承了大量常用的第三方库,在Spring Boot项目里这些第三方库可以直接使用,简化了大量的配置过程,使开发者可以将更多精力放在业务逻辑上。
2025-04-23 20:47:27
1070
1
原创 HTTPS加密原理详解
HTTPS的工作流程主要用到了三次加密,一次对称加密和两次非对称加密用于校验证书是否被篡改,公钥在客户端系统中内置,私钥由公证机构给服务器,服务器用私钥对签名加密,客户端用公钥对签名解密来确认证书的合法性用于协商生成对称加密的密钥,公钥私钥都由服务器生成,公钥通过证书传递给客户端,客户端用这个公钥给对称密钥加密,服务器用私钥给对称密钥解密其实前两次的非对称加密都是为了解决对称加密遇到的问题,因为对称加密的运行效率要比非对称加密快得多,所以后于业务请求都用对称加密,
2025-03-08 21:12:52
2655
29
原创 leetcode刷题--超详解
在排序数组中查找元素的第⼀个和最后⼀个位置看到这道题我们首先想到的肯定是直接遍历,找到target然后定位左右位置,但是这样显然是行不通的,因为题上明确规定要求时间复杂度为O(logN)。所以我们要换个思路,既然是要查找,那么我们就可以想到使用二分查找。//找到区间中点//分析情况return mid;
2025-03-08 21:12:16
1029
7
原创 MyBatia详解-下
动态SQL是Mybatis的强大特性之一,能够完成不同条件下不同的sql拼接,以下的动态sql均使用XML的方式举例使用的类数据库信息。
2025-03-07 18:51:53
702
2
原创 Mybatis详解-上
Mybatis是一个优秀的ORM持久层框架,几乎支持所有的JDBC语句,以及设置其参数和获取结果集持久层:指的就是持久化操作的层,通常指数据访问层(dao),是⽤来操作数据库的。ORM:就是OBject Relation Mapping对象映射关系,可以通俗来将就是讲数据库里的表关系映射成,java里的对象mybatis的持久层代码一般写在mapper包里,使用接口来编写相应代码,命名方式一般在最后加上**Mapper使用@Mapper来交给Spring管理。
2025-03-07 18:51:05
1115
1
原创 Spring原理
我们先创建一个student类并把它交给Spring管理@Component接着通过直接注入ApplicationContext来获取Spring容器拿到两个student对象@Autowired@Test运行结果可以看到这两个对象的地址是一样的,说明我们从Spring容器里取出来的对象是同一个这也是一个单例模式(确保一个类只有一个实例),在默认情况下,Spring容器中的bean都是单例的,这种行为模式被称之为,bean的作用域,就是指,Bean在Spring框架中的某种行为模式。
2025-03-04 20:44:33
6283
29
原创 HTTP协议详解
也是一种一问一答的结构模型的协议,HTTP的请求的响应格式是有所差别的,HTTP大多是基于传输层的TCP协议实现(HTTP1.0 1.1 2.0都是基于TCP实现,HTTP3.0是基于UDP实现),目前应用应用比较广泛的是1.1和2.0版本。HTTP协议是文本格式的协议,内容都是以字符串的形式展现,而TCP,UDP,IP...协议都是二进制格式,HTTP响应也是文本格式,但是直接查看往往能看到二进制的数据,因为HTTP响应经常会被压缩,压缩之后,体积变小,传输的时候就可以节省带宽。
2025-03-04 20:44:15
817
5
原创 TCP协议
不过随着窗口大小不停的增大,达到一定程度,可能中间节点就出现问题了,发送方就要调小窗口大小,如果依然丢包就继续调小窗口直到不丢包,就再次尝试阔大窗口,在这个过程中,发送方不断调整窗口大小,逐渐达成‘动态平衡’(这种做法就相当于把中间节点都视为整体,通过实验的方式,来找到中间节点的瓶颈在哪里,然后确定最后的窗口大小,大概就类似于木桶原理,水面与取决于最低的那块木板)不过时间变长也不是无限的,当重传若干次后,时间已经拉长到一定程度,就会认为数据已经传不过去了,就会放弃tcp连接(会触发tcp的重置连接)。
2025-03-03 20:20:43
1085
8
原创 JVM详解
一个运行起来的Java进程就是一个JVM虚拟机,当进程运行起来时,就需要像操作系统申请一大块内存,JVM就会把这些内存化分成不同的区域,每个区域有不同的作用。这里存储的内容就是类对象(.class文件,加载到内存之后,就成了类对象)这里存储的是,代码中new的对象(占据的空间最大)这里储存的就是在代码执行过程中,方法之间的调用关系,储存结构和数据结构里的栈类似,这里的每一个元素,称为“栈帧”,每个栈帧就代表一个方法调用,栈帧里就包含方法的入口,方法返回的位置,方法的形参,方法的返回值,局部变量。。。
2025-03-03 20:18:28
1290
1
原创 UDP协议
把当前要计算校验和的数据,每个字节,都进行累加,把结果保存到这两个字节的变量(校验和)中,过程中溢出也没关系,如果中间某个数据,出现传输错误,第二次计算的校验和就会和第一次不同(CRC这个算法其实不是特别靠谱,比如如果前一个字节大小少1,后一个字节大小多1,那么最后得到的校验和任然相同,但是数据可能已经不同了)。描绘这个数据报的报文长度(包含报头),这里的长度是指该报文有多少个字节,因为只有16位比特位的大小,因为数据传输可能会出错,所以需要一定的方法知道所传输的数据是否正确传输。
2024-09-04 20:36:45
1115
31
原创 网络编程详解
socket是文件描述符表里的一个表项,每打开一个文件,就会占用里面的一个位置,文件描述符表是再pcb上的(跟随进程),这个socket在整个程序运行中都是需要使用的,不能提前关闭,当socket不再使用的时候,就意味着程序就要结束了,进程结束此时文件描述符表,就随着pcb销毁了,随着销毁的过程中,socket就被系统回收了。
2024-09-04 20:34:49
1922
40
原创 常见的锁策略
顾名思义就是比较悲观的锁策略,在每次拿数据时总感觉会有其他人会对数据进行修改导致自己拿到一个无效数据,所以每次拿数据时都会进行加锁,这样别人想修改就会阻塞等待。认为数据一般情况下不会发生并发突变,在数据进行提交更新的时候,才会对数据是否产生并发冲突进行检测,如果发现并发冲突了,就返回用户错误的信息,让用户决定如何去做。假如有两个朋友要找你出去玩,友人A比较悲观,认为你可能比较忙,会先发个消息“今天下午三点有空吗,出来玩”(将相当于要给你加锁),如果你有空他就可以来找你,如果没有他就会等待你有空之后再来找你。
2024-08-26 18:46:50
1020
18
原创 工厂模式详解
现在这个快餐店为了更好的销售产品,推出了一系列的套餐。抽象工厂模式提供了一个接口,用于创建一系列相关对象,而不是一个单一的对象。它允许客户端使用抽象接口来创建一整套相关的对象,而不必指定具体类抽象产品//抽象食物接口具体产品//薯条@OverrideSystem.out.println("做了一个薯条");//炸鸡@OverrideSystem.out.println("做了一个炸鸡");//汉堡@OverrideSystem.out.println("做了一个汉堡");//可乐。
2024-08-25 22:13:01
1211
21
原创 《javaEE篇》--线程池
线程的诞生是因为进程创建和销毁的成本太大,但是也是相对而言,如果频繁的创建和销毁线程那么这个成本就不能忽略了。一般有两种方法来进一步提高效率,一种是协程(这里不多做讨论),另一种就是线程池假如说有一个学校食堂窗口的老板想到给学生提供外卖服务,而且有一个奇妙的想法,每当需要送外卖就现场雇一个学生来送,然后解雇。(就相当于平时的有一个任务就创建一个线程来处理),但是老板还是觉得频繁的雇佣和解雇学生的成本太大,于是老板又有一个点子。指定一个指标,外卖员的人数扩张到3个人,但还是随着外卖的数量逐步雇人。
2024-08-25 09:58:45
2638
16
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅