- 博客(73)
- 收藏
- 关注
原创 工厂模式和策略模式
相较于简单工厂模式,不再是只有单一的一个工厂,而是一种汽车对应一个工厂,一个工厂专门只负责一种汽车的生产。优点是后续增加新的汽车种类,只需要新增一个汽车类和对应的汽车工厂类。可以看出,根据传入的不同的类型,得到不同的策略类,执行的也是不同的代码。缺点就是代码中有大量的ifelse,后续若是新增一个汽车,就需要对这个工厂类进行修改,这显然不符合设计模式的开闭原则。工厂模式加策略模式是一种在软件开发中常用的设计模式组合,它结合了工厂模式的创建型特点和策略模式的行为型特点,以提供更为灵活和可扩展的系统设计。
2024-08-14 10:00:00
1900
3
原创 netapp内网穿透使用指南
点击回车后处出现一个弹框,如下界面则启动成功。主要设置你想通过公网访问你的本地端口号。(等号后跟你的authtoken)接下来开启你的内网穿透之旅。公网能访问到我本地的。
2024-08-04 00:13:08
1267
原创 git的基本使用
git是一种分布式版本控制工具,git本地有三个工作区域:工作目录(Working Directory),暂存区(Stage/index),本地仓库(Repository),除此之外,还有一个远程仓库(Remote Directory),总的来说可以分为四个工作区域。解决合并冲突(原因是在创建分支之后,新的分支做了修改,并且原分支也进行了修改),需要手动解决(手动找到修改的地方,并根据情况是删除哪部分,保留哪部分),并进行一次提交(add+commit)操作。这次再查看git的状态,文件已经提交到。
2024-06-02 18:14:05
917
原创 Redis的使用和原理,事务操作,乐观锁,持久化策略等
通过源码观察,RedisTemplate的序列化器是jdk序列化,会将键值对转为字节形式存储,可读性差,并且内存占用也大。当value值为对象时,该实体类还必须实现Serializable接口,否则报错。由于传入的值都为Object类型,所以还需要类型强转。除了jdk序列化,观察源码发现还有其他类型的序列化,如json序列化等等。那如果我们想使用其他的序列化方式,可以自己定义一个RedisTemplate。
2024-05-06 17:53:12
1099
1
原创 【JUC】线程安全的集合类
我们知道ArrayList以及HashSet,HashMap都是线程不安全的,并发执行的时候会报并发修改异常错误。使其线程安全的方法有如下几种:1.使用java.util包下提供的Collections工具类,使其变成一个线程安全的集合类2.使用JUC并发编程包下提供的线程安全的集合类 CopyOnWriteArrayList那Vector也是线程安全的,Vector和CopyOnWriteArrayList有什么区别?HashSet也是线程不安全的,HashSet的底层是HashMap,其底层是new了一
2024-05-06 10:00:00
959
原创 什么是死锁?代码演示,死锁如何排查和解决
死锁是指在多线程或多进程中,两个或两个以上的线程或进程在执行过程中,因抢夺资源而造成的一种相互等待的现象。简单来说,就是两个或两个以上的线程或进程都在等待对方释放资源,从而导致所有线程或进程都无法继续执行的情况。有两个线程A,B,线程A占用了锁A,线程B占用了锁B,在这种情况下线程A又想获取锁B,线程B也想获取锁A,自己不释放锁,却又都在等待对象释放锁资源,相互僵持,就会造成死锁。jstack 线程id。
2024-05-02 16:58:05
489
1
原创 Java8新特性--lambda表达式
lambda表达式本质上是一个匿名函数,在lambda表达式中我们只需要关心。基本语法:(参数)->表达式 或 (参数) -> {语句;使用该接口,可以看出使用lambda表达式代码量会减少许多。优点是可以减少代码量。
2024-04-08 20:02:28
536
原创 Spring两大核心思想:IOC和AOP
1.先自定义一个注解@Target(ElementType.METHOD) //作用范围 此处是方法@Retention(RetentionPolicy.RUNTIME) //生命周期 此处是运行时2.在切点表达式中加入该注解@Aspect@Component@Slf4j@Around("@annotation(com.example.demo.aspect.TestAnnotation)") //此处加自定义注解log.info("around继续");try {
2024-02-19 17:34:45
2289
原创 统一数据格式返回,统一异常处理
由于我设置了统一返回类(code,msg,data),String类型的数据在上面第一步(返回的body中)就已经被包装成一个对象了,后续传参也都是泛型,直到调用 addDefaultHeaders 方法,接收却是String类型的。对象是不能自动转成String类型的。接口返回String类型的数据时,需要转Json格式。所以尽量少用,直接将String类型的数据包装在对象中返回即可。解决办法就是使用SpringBoot提供的Jackson库,可以将对象转成Json格式的字符串。
2024-02-09 18:24:49
1140
原创 MyBatis中#和$符的区别,sql注入问题,动态sql语句
#{}和${}都是MyBatis提供的sql参数替换。区别是:#{}是预编译处理,${}是字符串直接替换。#{}可以防止SQL注入,${}存在SQL注入的风险,例如 “' or 1='1”虽然存在SQL注入风险,但也有自己的适用场景,比如排序功能,表名,字段名等作为参数传入时。#{}模糊查询要搭配使用mysql内置的拼接函数concat,安全性高。模糊查询虽然${}可以完成,但是存在SQL注入,不安全。
2024-02-06 18:40:13
1827
2
原创 解决Xshell连接远程linux服务器,关闭Xshell程序对应的运行程序也相应关闭的问题
【代码】解决Xshell连接远程linux服务器,关闭Xshell程序对应的运行程序也相应关闭的问题。
2024-01-28 17:47:29
735
原创 解决Linux部署报错No main manifest attribute, in XXX.jar
这是我近期遇到的一个问题,报错原因就是没找到主类,首先你在你本地运行,本地运行ok的话,解压生成的jar包,里面有个META-INF文件,打开MANIFEST.MF文件,该文件是一个清单文件。该文件包含有关JAR文件中的内容的信息,包括入口点,。找主类(main方法的类)就是去这个文件中找的。
2024-01-28 03:00:32
4724
4
原创 Mysql 索引 、事务、隔离级别
一个有效的解决方法是:另外在弄一台机器,在这台机器上部署mysql服务器,并且创建一张同样的表,然后创建好索引,最后再将原服务器上的数据导入到新的mysql服务器上。而红黑树虽然既可以精确查询,又可以范围查询,还可以模糊匹配(但是%开头的这种模糊查询不支持),缺点是红黑树是一个二叉树,树的高度可能会很高,会导致IO操作频繁。索引是一种为了加快数据库查询(操作)速度而引入的一种手段,需要占用额外的磁盘空间,我们之前所学的主键,唯一键,外键都是自带了索引的。此时隔离性是最高的,效率是最低的,数据是最准确的。
2024-01-19 17:18:45
1030
原创 JVM的内存区域划分,类加载过程,GC垃圾回收机制总结
从一些特定的对象出发,尽可能的遍历所有能够访问到的对象,并标记成"可达",那些在扫描之后未被标记的对象,就是垃圾了。特定的出发点,比如,局部变量,常量池中引用的对象,方法区中的stack变量。最开始对象都是在新生代区里,当一个对象经过一次GC扫描后,还是有效,就会被拷贝到幸存区,当在幸存区中经过GC多次扫描还是有效对象后,就会被拷贝到老年代。在栈里,一个一个的元素被称为栈帧,每个栈帧就代表了一个方法调用,栈帧里就包含着这个方法的入口,方法返回的位置,方法的形参,方法的返回值,局部变量等等。
2024-01-15 14:36:22
1204
原创 使用阿里云镜像创建一个Spring Boot项目
由于现在的idea在创建项目时已经不支持Java8版本了,如果我们还想用8版本,可以使用阿里云镜像创建。springboot版本选择2开头的任意版本的。
2024-01-12 02:51:07
5113
原创 【常用的简单功能及算法】拦截器 加盐算法 深克隆 时间日期格式化 加盐算法 sql分页算法 验证码
先是生成盐值,再拼接盐值和密码,将拼接后的整体用md5加密。最后将盐值拼接$符拼接md5加密后的密文形成最终存储在数据库中的密文。再和用户登录时输入的密码一起重复上面加密操作。最终也会得到一个65个字符的密文,两个进行比较。用java自带的UUID生成一个随机数再拼接上用户的密码,就是最终的密码。以上两种分页是完全不同的。第一种涉及分页算法,分页常用第一种。有插件在插件中搜索,没插件去Maven仓库中搜索。首先获取盐值,拿到数据库中的密文,进行截断。2.2 设置拦截规则。1. 全局日期格式化。
2024-01-12 01:00:46
998
原创 Cookie和Session的工作流程、区别及如何使用
Cookie在生成时,就会被指定一个Expire值,这就是Cookie的生存周期,在这个周期内Cookie有效,超出周期Cookie就会被清除。有些页面将Cookie的生存周期设置为0或者负值,这样在关闭浏览器时,就会马上消除Cookie,不会记录用户的信息,更加安全。举个例子,如果设为10分钟的话,当你登录一个服务器,登陆成功的话,服务器会返回一个sessionId,登陆成功之后的10分钟内没有客户端这边进行任何HTTP请求,10分钟后你再发送一个HTTP请求,就会提示你需要重新登陆。
2023-11-08 21:15:59
258
原创 JS定时器实现页面N秒后跳转 实现每隔 1s 自动刷新页面并格式化的显示当前时间
1. 通过 setInterval 函数,来周期性的更新倒计时间,同时更新到页面。即通过设置页面可以显示 3 2 1,然后跳转。1000指的是每隔1秒执行一次。2. 通过 setTimeout 执行一个延迟函数来达到跳转的目的。
2023-11-06 20:21:16
1083
原创 Servlet的生命周期
加载成功后,容器会通过反射对Servlet进行实例化,这里反射的本质就是调用Servlet的无参构造方法。在Servlet的整个生命周期内,对于Servlet的每一次请求,Servlet容器都会调用一次service()方法,并创建新的ServletRequest和ServletResponse对象。Servlet实例化之后,Servlet容器调用Servlet的init()方法,初始化的目的是为了让Servlet在处理请求之前完成一些初始化的工作,比如建立与数据库的连接,获取配置信息等。
2023-11-05 20:17:40
218
原创 【Linux】Linux文件与目录操作、用户权限与组操作、shell脚本以及在Linux上搭建jdk,mysql环境,近万字总结
比如左边这个操作,本来是想删test.txt文件的,但是第一个斜杠和后面的root之间多了个空格,完蛋,这种不经意的操作。如果vim打开了因某种原因没有正常关闭,如断网等,那么下次再次启动的时候会提醒输入命令,输入D是删除上次编辑还未保存的内容,输入R是恢复之前的编辑页面,继续编辑。vim是vi的升级版本。1.从官网下载我们需要的tomcat版本的压缩包,可以先在xshell中创建一个目录,然后把压缩包直接拖拽到这个目录里。这里的 / 表示根目录,相当于windows中的此电脑,linux中没有盘符。
2023-11-01 21:11:12
504
原创 【计算机网络】三次握手 四次挥手
确认应答是可靠性传输的核心,而三次握手是有连接中的步骤,有连接包含连接的建立(三次握手),断开(四次挥手),维护等等。以上面图为例,如果客户端这边等待了2MSL,还没收到服务器那边传来的FIN,就会认为服务器那边已经成功接收到自己的ack,进行close了,客户端这边也就不等待了,也会进行close。B向A发送回复收到,A收到后,A就知道,B已经收到自己发送的信息了,,所以A就知道自己的发送和B的发送和接收功能是好的,但是B这这边还不知道A有没有收到自己的回复也就是不知道A的接收功能是否完好。
2023-10-30 13:06:38
653
原创 【计算机网络】从输入URL到页面都显示经历了什么??
① DNS 解析:当用户输入一个网址并按下回车键的时候,浏览器获得一个域名,而在实际通信过程中,我们需要的是一个 IP 地址,因此我们需要先把域名转换成相应 IP 地址。浏览器会首先从缓存中找是否存在域名,如果存在就直接取出对应的ip地址,如果没有就开启一个DNS域名解析器。DNS域名解析器会首先访问顶级域名服务器,将对应的ip发给客户端;然后访问根域名解析器,将对应的ip发给客户端;最后访问本地域名服务器,得到最终的ip地址。② TCP 连接。
2023-10-26 21:49:11
441
原创 【计算机网络】什么是HTTPS?HTTPS为什么是安全的?
HTTP最初的设计就是用于数据的共享和传输,并没有考虑到数据的安全性,如窃听风险,篡改风险和冒充风险。HTTPS是在 HTTP 的基础上引入了一个加密层。HTTPS通过数据加密,数据完整性检验和身份认证有效的保证了数据传输的安全性。HTTP默认端口号40,HTTPS默认端口号是443。是接下来说说这些方法具体是咋实现的。
2023-10-26 20:39:30
4215
15
原创 【计算机网络】应用层协议--HTTP协议及HTTP报文格式
HTTP 是一个简单的请求/响应协议,通常运行在 TCP(Transmission Control Protocol 的简称,是一种面向连接的、可靠的、基于字节流的传输层通信协议)之上。因为HTTP也是基于TCP的,TCP是以字节为单位传输的,传过去之后,接收方数据包都紧挨在一起,接收方也识别不出哪到哪是body,这样就需要用空行来区分body,再用content-Length来区分body中数据的长度。响应,来自服务器的应答。状态码:服务器的响应,表示了这次请求对应的响应是啥样的状态。
2023-10-23 13:34:12
574
原创 【计算机网络】网络编程 Socket
基于UCP协议的话:服务器和客户端之间的来回receive和send都是以数据包形式传递数据 所以要经常创建数据包。数据包中可包含数据 发送的目的地。充当发送的数据包中是要有发送的地址的,充当接收的数据包要预先创建一个空的数据包。这就是两种方式下数据包的不同的用法。
2023-10-20 09:56:04
1116
原创 【计算机网络】网络原理
由于通信网络很复杂,拆分就拆分出来太多的小的协议,小的协议太多,不好管理,这时候就需要分层了。在应用层中就会把这个输入的"hello"打包成一个应用层的数据报(格式:字符串拼接)数据报中是二进制形式,这个数据报的内容格式由开发QQ的人员自定义的。就是要对刚才的应用层数据再进行打包,变成传输层的数据报,打包过程即字符串拼接。把刚才的应用层数据的基础上再拼接传输层的报头。这个地址也是用来描述一个设备在网络上的地址的。通过IP协议进一步针对网络层的数据报进行解析,去掉报头,拿到载荷,再把载荷交给传输层。
2023-10-17 08:21:11
1074
原创 【文件IO】文件系统的操作 流对象 字节流(Reader/Writer)和字符流 (InputStream/OutputStream)的用法
文件是一个广义的概念。操作系统里会把很多的硬件设备和软件资源都抽象成"文件",统一进行管理。大部分情况下,谈到的文件都是指硬盘的文件。文件就相当于是针对"硬盘"数据的一种抽象。
2023-10-17 08:21:05
1357
19
原创 【多线程案例】Java实现简单定时器(Timer)
在日常生活中,如果我们想要在 t 时间 后去做一件重要的事情,那么为了防止忘记,我们就可以使用闹钟的计时器功能,它会在t时间后执行任务(响铃)提醒我们去执行这件事情. — 这就是Java定时器的简单功能。它作为一种日常开发组件。约定一个时间,时间到达之后,执行某个任务。常被用于网络通信。
2023-10-10 12:56:01
604
原创 【多线程案例】阻塞队列,实现生产者消费者模型
比如服务器和客户端之间的请求与响应,当用户量请求增大时,服务器也会受牵连,甚至于 将服务器弄崩溃给挂了,耦合性较高,如果两者之间用一种数据结构如队列存储请求,就不论客户 端用户量请求有多大时,服务器仍然可以按照自己的速度去处理请求。:当把阻塞队列封装成单独的服务器程序,部署到特定的机器上,这个时候就把这个队列称为"消息队列"。阻塞队列是多线程代码中比较常用的一种数据结构。是一种特殊的队列,带有阻塞特性。并发协作的模型,在分布式系统里非常常见。
2023-10-09 19:48:30
572
原创 【多线程安全】线程的调度顺序 wait和notify
但是使用join方法,只能等调用方法的线程结束,我们所希望的是一种既能实现线程之间的顺序执行,也能让调用线程不结束。活锁:是指线程1可以使用资源,但它很礼貌,让其他线程先使用资源,线程2也可以使用资源,但它很绅士,也让其他线程先使用资源。活锁:马路中间有条小桥,只能容纳一辆车经过,桥两头开来两辆车A和B,A比较礼貌,示意B先过,B也比较礼貌,示意A先过,结果两人一直谦让谁也过不去。我们都知道多线程的调度顺序是随机的,系统随机调度,抢占式执行,很多时候,也是希望能够通过一定的手段进行顺序执行的。
2023-10-08 14:56:58
208
原创 【多线程安全】死锁 锁竞争总结
或者,不加 volatile ,给循环里加个 sleep 也行,原因是加了sleep之后,while循环的执行速度变慢了,这样load操作的开销就不大了。为了解决这个变慢问题,提高效率,此时编译器就可能会对代码做出优化,即把一些本来要度内存的操作,优化成读取寄存器了,这样就会减少读内存的操作,也就会提高整体程序的效率了。此时就是发生内存可见性问题,即编译器通过优化读取操作,把读内存优化成都寄存器了,而改变后的值在却内存中,虽然是读速度变快了,但是有可能也就不准了,这样的优化操作也无疑会使预期结果出错。
2023-10-06 14:42:39
1644
23
原创 【简单的留言墙】HTML+CSS+JavaScript
4.位置居中问题已经解决,但是会发现输入框及文字排列还并不整齐。这是因为我们并未对span标签里的文字及input标签设置各自宽度及高度,一旦设置就会各自居左排布。3.文字已经居中,但是下面的输入框,按钮等还没居中,由于他们都被设置在div标签中,接下来可以对所有在div标签中的属性使用。以下代码有所省略,突出了重点,还是利用CSS选择器设置属性。1.首先我们用HTML的一些标签,初步构造区域 样式。5. 设置button按钮的宽度,文字颜色,按钮颜色。6.4.设置高度,使整体高居中度。
2023-10-03 19:18:47
5678
2
原创 Java大数 -- BigInteger类 小数 -- BigDecimal类
在java语言中,每一种整数类型都有自己的上限和下限,如果要想对非常大的整数做运算,就需要使用。例如这样一道进制转换题:十进制数有30位,对于java语言来说,int,long 都超出范围了。因为BigInteger所创建的是对象,所以不能使用传统的加减乘除。特别的,求余会返回一个大数数组,数组0索引位置是除数,1索引位置是余数。4.将大数转换为基本数据类型。BigInteger类。
2023-09-30 23:45:18
788
原创 653. 两数之和 IV - 输入二叉搜索树
先深度优先搜索遍历整棵二叉树,在遍历的同时在哈希表中存储当前结点的值。对于一个值为 x 的节点,首先检查哈希表中是否存在 k−x 。如果存在对应的元素,则遍历结束返回true;否则,将 x放入到哈希表中,接着进行往下遍历。如果遍历完整棵树都不存在对应的元素,那么该树上不存在两个和为 kkk 的节点。检查哈希表中是否存在 k−x,和将值放入到哈希表中是有先后顺序的。
2023-09-30 23:41:17
217
原创 【前端】CSS
包括大小,位置,颜色,形状,边距,边框,特殊滤镜,过渡效果,动画等等。html页面中的每个元素,都是可以设置成一个唯一的ID的,作为元素的身份标识。就是把多个简单的基础选择器组合一下(可以是标签,类,id,选择器的任意组合)也是把多个简单的基础选择器组合一下(可以是标签,类,id,选择器的任意组合)而ID选择器,则只能针对唯一的元素生效,且一个页面里的,只能有唯一的ID。引用这个id的时候,通过 id = "id名" 即可,不需要带#。一个类,可以被一个元素引用,也可以被多个元素引用。
2023-09-23 18:57:17
238
原创 【多线程练习】· 累加count 顺序打印 死锁
所谓的死锁就是线程一拥有锁1,线程二拥有锁2,双方在拥有自身锁的同时尝试获取对方的锁,最终两个线程就会进入无线等待的状态,这就是死锁。每个线程循环 1w 次,累加变量 count 的值,count 默认值为 0,注意线程安全问题。需要让他们同时启动,并按 c,b,a的顺序打印。有三个线程,线程名称分别为:a,b,c。使用两个线程来累加 count 的值。有三个线程,分别只能打印A,B和C。要求按顺序打印ABC,打印10次。每个线程打印自己的名称。
2023-09-19 20:45:07
135
软件生命周期.docx
2023-06-17
基于数据库的购物管理系统
2023-06-17
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人