- 博客(84)
- 收藏
- 关注
原创 传统Web应用和RESTful API模式
为什么我需要搞清楚这个呢,是由于学习Spring MVC的时候,Spring MVC的执行流程中的DispatcherServlet去解析Controller的返回值这个步骤困惑住了我,如果是RESTful API模式,其实就没有这个流程,如果是传统Web模式,就会又这个步骤。1. DispatcherServlet接收请求2. HandlerMapping找到Controller3. HandlerAdapter调用Controller方法。
2025-06-12 00:04:25
189
原创 深入理解二叉树遍历:递归与栈的双重视角
读者可以根据前序遍历的思路自行去理解中序遍历和后序遍历。重点就是理解系统的线程栈是怎么运作的,以及手动实现的栈是如何保存节点的。搞清楚了这两点,对二叉树的遍历的理解就会更上一层了。
2025-04-26 21:33:49
855
原创 Java 并行快速排序:Fork/Join 框架的高效应用与性能对比
本篇文章介绍了快速排序的原理,并通过Fork/Join 框架实现了 并行快速排序。通过实验对比,我们发现并行计算在大规模数据集上具有显著优势,是高性能数据处理中的重要优化手段。
2025-04-01 00:32:37
772
原创 装饰器模式:如何用Java打扮一个对象?
装饰器模式通过“动态增强”而非“本质改变”的设计理念,为软件设计提供了高度的灵活性和可扩展性。本文以生活中“换装打扮”的生动场景为引,巧妙类比了装饰器模式的核心思想——在不修改对象自身的基础上,通过层层叠加装饰器来扩展功能。核心价值体现:灵活组合,动态扩展如同男孩可根据场合自由切换妆容和服饰,装饰器模式允许在运行时动态添加或替换功能。例如,先穿简约服装,再化妆,最后换宴会礼服,每一步装饰都独立且可逆,避免继承带来的僵化性。职责分离,结构清晰。
2025-03-30 01:45:10
1008
原创 Java为什么要使用线程池?
之前对于Java线程池的理解,一直停留在:对于Java中的多线程机制来说,如果不使用线程池的话,线程的使用就会变得杂乱无章。这一步。一直没有深入去理解为什么其更深层次的原因,今天来仔细思考一下,并记录我自己的理解。
2025-03-26 23:03:45
484
原创 Java实现死锁
(Circular Wait): 线程形成环状等待。小明等勺子 -> 小红等叉子 -> 小明等勺子(循环了!(Mutual Exclusion): 资源一次只能被一个线程占用。只有一个叉子或者叉子,不能两个人同时用。(Hold and Wait): 线程持有资源的同时,还在等待其他资源。小明拿着勺子,还在等叉子。学习并发编程的死锁,之前在408的操作系统也学习过相关概念,今天使用Java代码自己实现了一下。(No Preemption): 线程持有的资源不能被强行拿走。勺子被小红拿了,不能抢。
2025-03-11 23:45:30
418
原创 匿名内部类
在日常编写代码的过程中,总是会遇到匿名内部类的使用,但是对这一块一直不是很熟,所以这里总结记录一下。可以看到,不需要额外写一个子类去重写父类Kp中的show方法,而是直接在匿名内部类中重写就行。使用了匿名内部类,我们就只需要知道该接口和要实现的方法就行了。可以发现,要想使用Kp这个接口,还要先为他写一个实现类。
2025-02-24 16:43:23
167
原创 全局唯一ID
时间戳就是获取当前时间的秒数,在redis中保存的键是根据当前日期存储的,然后值是自增的。每次获取一个全局ID,就是获取当前的秒数然后左移32位,最后再用或运算拼接自增的id。2.在一些分布式系统中,数据库要分库分表,如果不适用全局ID,会导致两个库中两个不同的东西拥有同一个ID,这就会产生逻辑上的错误。1.如果不用全局ID,只使用数据库自增的方式的话,这样自增出来的id规律性太明显,很容易被人得到一些敏感信息。3.使用雪花算法,雪花算法和使用Redis自增生成的全局ID思路类似。
2025-02-23 18:38:35
206
原创 Redis作为缓存和数据库的数据一致性问题
因为对数据库操作是很慢的,而对缓存操作是很快的,所以很容易出现下面一个情景:线程A先更新数据,线程B再读取数据,线程A删除了缓存,但是由于更新数据库的速度很慢,事务还未提交,线程B又进来了,它读取缓存但是缓存被删了就去读数据库,读取到了数据库中的数据返回给了客户端,同时将数据写到了缓存中,最后线程A更新数据库的操作终于完成了。那么此时就会进行1000次数据库的修改和缓存的修改,但是缓存的前999次修改都是无效的,造成了大量的时间和空间浪费,删除操作又比修改操作快,而且无数据时删除操作是不执行的。
2025-02-22 16:19:36
712
原创 对计算机中缓存的理解和使用Redis作为缓存
客户端在获取数据的时候,不会直接访问数据库,而是先去访问Redis缓存,看看Redis中是否有想要的数据,如果有就从Redis中获取并直接返回,如果没有才会再去数据库中获取并保存到缓存中,以便下次使用,这与CPU和Cache缓存之间的思路是一样的。下面两张图分别对应缓存命中和缓存不命中的情况,可以看到,添加了缓存之后,将常用数据保存到Redis中,确实可以让数据的获取多次从内存中获取而不是硬盘中,提高了不少性能。 而Redis作为非结构型数据库,它的数据是保存在内存中的,读写速度很快。
2025-02-22 13:51:05
441
原创 JAVA使用Scanner类的nextLint()方法无法正确读取中文。
在练习的时候,我发现我使用Scanner类的nextLint()方法无法正确读取到中文了。检查了我的idea编辑器,用的编码格式也是”utf-8“。所以编码格式没有问题。问题如下棉两张图所示,我输入宝马后,控制台不打印出来显示还是空的。微软自带输入法,idea2024.2,jdk21。当我使用复制的中文输入进去时候,就又可以了。还是idea版本太高的原因?并且当我在最后打印的时候,出现的也是空的。
2024-09-27 17:16:56
453
4
原创 JAVA后端程序拉取私人仓库的npm包并将该程序打包成jar包
你可以通过在你的 pom.xml 文件里的 标签中增加像下面这样的片段来完成这个整合。创建了一个测试程序,在其中的pom.xml文件中引入已经打包好的jar包(引入的仓库地址配置在settings.xml中,在这里也不过多赘述。程序会自动创建该文件夹,根据该路径将拉取下来的npm包存储到该目标文件夹中,如果该文件夹里已有内容,程序会依据同名覆盖的原则进行覆盖。当前有一个系统用于导出项目,而每次导出的项目并不可以直接使用,需要手动从npm私人。私有仓库中去,这样可以在pom.xml中引入即可使用。
2024-08-23 17:19:44
565
原创 JAVA后端拉取gitee仓库代码并打包成jar包
当前有一个系统用于导出项目,而每次导出的项目并不可以直接使用,需要手动从gitee代码仓库中获取一个模板代码然后将他们整合到一起它才是一个完整的项目,所以目前我的任务就是编写一个java程序可以自动地从gitee仓库拉取下来那个模板代码到指定地路径上去。即可看见在目标文件夹中拉取到了目标gitee仓库中的代码,这里要注意,在设置localPath的时候,所存的目标文件夹可以不存在,系统会自动创建,但是要保证所存的目标文件夹为空,否则会拉取失败。有很多种方式可以让 JGit 连接你的项目,并依靠它去写代码。
2024-08-23 17:16:37
484
原创 删除二叉搜索树中的节点,力扣405题
这种情况下,按照二叉搜索树的删除的官方做法,是找到它的前驱节点(左子树中最右边的结点),或者是找到它的后继结点(右子树中的最左边的结点)。将它作为根节点,然后原来的左子树作为新的左子树,原来的右子树作为新的右子树。// 同时,网上还有另外一种做法,就是将左子树整个的挂在右子树的最左边的结点的左孩子下,返回右子树的根作为新的根节点,这样也可以,但是这样好像会不断地增加树地高度,最终这个树会变成一个链表。// 2.左孩子为空,右孩子不为空,直接删除根结点,返回右孩子结点作为删除之后的树。
2024-08-22 13:41:39
232
1
原创 JAVA中的ArrayDeque和LinkedList实现Deque,前者不能存NULL结点,后者可以存放NULL。
在刷力扣的时候,在进行二叉树的题目训练时,需要用队列来存储二叉树的结点。因为使用ArrayDeque实现Deque习惯了,所以默认使用ArrayDeque来实现Deque。但是在运行的时候,发现这个dq中无法存入null空结点,会报空指针异常。于是尝试了使用LinkedList来实现Deque。可以看到在ArrayDeque会对加入的值进行判断,如果为空就会报出异常,而LinkedList不会。具体原因我也不清楚。这样再将null空结点存入这个队列就不会报错了,我分别查看了一下两者的源码。
2024-08-13 10:41:15
478
原创 下载安装ansible后,缺失pyyaml,pip安装时又出错,升级时又由于时Python2.7,不好升级遇到的一系列问题。
经过上一篇文章,我虽然误删了CentOs自带的python和yum,但是我重新将他们恢复了。这里记住默认的python版本是2.7.5。我使用yum安装好ansible后,检查我的ansible版本的时候,发生了错误,提示没有yaml模块。
2024-08-06 17:45:41
1153
原创 CentOS版本的Linux系统误删了自带的python和yum,恢复过程
在进行别的操作的时候,一不小心将我的系统自带的Python2.7.5和yum删除掉了。后来我尝试重新安装yum,但是安装yum必须要有python。我又去重新安装了python,但是我一开始选择了安装3.8版本,所安装的yum又是需要python2版本的,所以还是不行。最后通过网上找的一个办法,只需要在一个网站里将所有需要的包都下载安装下来就行了。下面我记录一下。
2024-08-06 13:42:59
874
1
原创 Docker的可用源
首先Dokcer的源大部分现在都用不了,于是我上网查询,终于找到了一个可用的镜像。然后重启一下docker服务就可以使用正常使用docker了。
2024-08-05 10:53:10
1199
原创 JAVA中的PriorityQueue优先队列的使用和比较器。
下面这段代码摘自廖雪峰老师的java教程中。// 添加3个元素到队列:// Boss/V1// Bob/A1// null,因为队列为空// 如果两人的号都是A开头或者都是V开头,比较号的大小:// u1的号码是V开头,优先级高:return -1;看到User类,这是我们存入这个优先队列中的元素。
2024-08-05 10:41:36
394
原创 Java中字符串的==和equals方法。力扣150题。逆波兰表达式求值。
至于为什么使用“==”在idea中也能实现比较字符串内容的原因,大概是因为idea内置了优化把,自动将它识别成了equals?可以看到错误是,最后将尝试将“*”转换成int类型而报错,这就证明栈顶的元素是“*”,整个栈只进行了入栈操作,而并没有出栈。字符串比较的时候使用的是“==”运算符,结果运行通过,测验也能得到正确的结果。通过了解,我得知,在Java中,String的“==”运算符是用来。使用到了字符串内容的比较。但是我将它复制到力扣中去,编译就不通过了。在IDEA中我编写的代码是这样的。
2024-08-02 15:38:40
293
原创 JAVA中实现队列和栈(Deque接口和ArrayDeque类)
首先JAVA中有一个Queue接口,用来实现队列。Deque其实就是双端队列,代表两端都可进可出的队列。ArrayDeque就是用数组来实现这个双端队列。(Deque由于是接口,只可以用于声明对象,但是没办法实例化,实例化还是要使用ArrayDeque类)这时可能就会产生疑惑,队列有了,那么栈用什么来实现呢,其实在Java中栈也是用这个Deque来实现,具体实现下面会写,现在先放在一边,思考那么Java中的Stack类不就是栈吗,为什么不使用Stack来作为栈呢?
2024-08-02 14:07:11
924
原创 JAVA中List不能创建实例。结合ArrayList的理解。
后来我查看了List源码,和ArrayList源码,我发现。List是一个接口,而ArrayList是一个类继承自AbstrctList,而AbstractList实现了List接口。所以List是没法创建实例的。今天在使用List的时候,我以为List是一个父类,ArrayList继承自List,所以我想着干脆直接就创建一个List实例。结果发现程序报错了。
2024-08-02 09:35:11
270
原创 JAVA的String类的contains方法,Indexof方法不使用KMP算法
然后我又去看了Indexof的源码,发现他就是简单的暴力匹配,没有使用KMP算法,我们直到暴力匹配的算法的时间复杂度是O(m*n),而KMP算法的时间复杂度可以达到O(m+n)。为什么JDK官方没有使用更加优秀的KMP算法呢?今天做力扣的一道题目,在一个字符串中找出字符串的时候,想到了JAVA有一个contains方法,于是我去看了一下源码,发现他就是简单地调用了一下java的indexof方法,
2024-08-01 15:04:09
281
原创 对JAVA的包package的理解
一直理解不了java中的包,包括下图中的这种在几乎每个java程序的开头都有的import和package。今天在实际应用中突然理解了。
2024-07-31 15:19:06
474
原创 JAVA后端拉取gitee仓库代码项目并将该工程打包成jar包
公司当前有一个系统用于导出项目,而每次导出的项目并不可以直接使用,需要手动从gitee代码仓库中获取一个模板代码然后将他们整合到一起它才是一个完整的项目,所以目前我的任务就是编写一个java程序可以自动地从gitee仓库拉取下来那个模板代码到指定地路径上去。并且我还要将这个java程序打包成jar包上传到先前创建好的私有仓库中去,这样可以在pom.xml中引入即可使用。
2024-07-30 15:48:22
1050
原创 优化算法性能
从一组交叉验证集中获取错误分类的示例,然后将这些示例按照所属的共同的特征、共同的属性或者共同的主题进行分类。然后根据错误出现的比例有针对地去优化算法性能。
2024-07-29 13:11:15
204
原创 docker一些常用的命令
查看当前正在运行的容器,使用docker ps命令,使用这个命令可以展示出容器列表,记住其中需要的容器id。docker ps使用命令进入容器。。。当完成容器内部的操作后,可以使用exit命令退出容器exit。
2024-07-29 11:38:15
438
转载 Linux中的查找命令。which、whereis、和find。
which命令的作用是,也就是说,使用which命令,就可以看到某个系统命令是否存在,以及执行的到底是哪一个位置的命令。
2024-07-29 09:37:16
90
原创 对链表的头结点和各个指向结点的引用的理解。力扣24题,两两交换链表中的结点。
其实是知道在链表前面添加一个没有实际存储内容的头结点是有利于程序运行的,但是在实际编程中总是会忘记或者不知道到底起到什么样的作用,或许这就是纸上得来终觉浅,绝知此事要躬行吧。力扣24题要求我们两两交换链表中的结点。在这种情况就很需要有一个头结点,因为考虑到交换两个头结点的时候往往不单单会只用到被交换的两个结点,往往还需要考虑被交换的第一个结点的前一个结点,因为也需要把它的next指针改变。如果设置待被交换的两个结点按顺序分别是cur和next,那么cur前面的结点就是叫pre。
2024-07-23 17:29:27
470
原创 对递归的一些理解。力扣206题:翻转链表
在最后检测到cur是null之时,pre所指向的链表是我们最后要得到的答案,在这个时候执行return,但是return到的是上一个reverse函数栈,在该函数中,pre链表的结果还不是最终答案,就这样一步步回退回去之后,直到恢复成了原样,并从最后的“}}”退出,此时pre又变成了原来的空值,所以这就导致了无论我的输入是什么,输出都是空值的原因。将代码修改如下,在最后找到目标答案值得时候,一层层返回这个答案值,而不是返回空值得回退,这样可以将最后得答案值返回给进入循环时的pre,修改后的代码如下所示。
2024-07-23 15:21:43
424
原创 服务器上使用Docker部署sonarQube,并集成到Jenkins实现自动化。
目标是要在目标服务器上使用docker工具部署好sonar环境,然后再集成到Jenkins中实现自动化的代码审查工作。
2024-07-22 18:07:23
749
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人