自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 数据结构——堆

你可以想象一下:如果选择了头插,容量不够的时候需要进一步扩容,况且我们使用的是数组模拟堆。如果头插,我们需要整体都向后移动一位,移动后的堆已经不是原来的堆了,此时我们还需要向下调整,光是想想就很麻烦吧。我们知道:堆其实就是优先级队列,很显然,区别于普通的队列二字,他多出了优先级三个字。由于向上调整和向下调整有很相似的逻辑,我就不赘述图了,可以自己尝试画画,加深一下印象。当我们补充offer 代码的时候,会发现一个问题,我们是选择头插还是尾差呢?方法的基本框架都写好了,下面就是建堆了。此时,堆就算是建好了。

2024-09-12 18:08:39 626 1

原创 接口中的方法到底能有具体实现吗?

这是我无意间发现的一个问题,有一天在写代码的时候突然发现,我实现了一个接口却没有将他的抽象方法重写完,这还不是问题,问题是他还不报错。这是怎么回事呢?按理说接口的定义不就是:一个类实现该接口就必须重写其所有方法吗,为啥我没有把他的抽象方法重写完,还不报错呢?难道是编译器出错了?

2024-08-11 18:03:26 797

原创 项目实战_图书管理系统(简易版)

此时我们只需要将用户传过来的用户名和密码和我们存储的用户名和密码对比,如果相同就返回true,反之,返回false。如果能正常显示就说明复制过来的前端代码没问题,不要计较前端加载的那些数据,那些都是假数据,后期那些代码是需要我们改的。简易版只实现上述两个功能,如有兴趣还请看下一期的升级版,升级版将会实现页面上的各个功能,以及解决统一事务的处理方式。接下来就是获取图书列表接口了,我们知道要想返回图书信息,我们得先有一个图书类啊,用来描述图书。后端的代码确保正确了以后,就该修改前端代码了。

2024-08-04 08:10:40 1129

原创 项目实战_表白墙(升级版)

如果我们想将数据存起来首先要有一个数据库吧,所以首先就是要创建一个数据库 ,由于直接在Mysql 小黑框里写有点麻烦,我们可以借助一些软件来更加简单的创建数据库,我使用的是Navicat Premium17,挺好用的,虽然它收费,但是搜搜教程,免费的就来了,懂我的意思吧。我们可以看到数据库里有很多属性,如果只靠我们之前定义的类中的属性肯定是不够的,所以我们要重新定义一个实体类和数据库里的属性对应。这是创建一个message_info表的代码,有兴趣的可以跟着敲一下,就当复习了,没兴趣的直接复制就行。

2024-07-31 21:20:50 6200 3

原创 项目实战_表白墙(简易版)

效果如下。

2024-07-29 12:25:37 3842 2

原创 我的创作纪念日

机缘不知不觉我在CSDN已经一年了,想到我写的第一篇博客时的费心尽力,到现在的手拿把掐。一对比,我明白我好像真的进步了。在最近的一个月我偶然看到了我之前的博客,发现阅读量已经破千了,心里默默感慨:这大概就是努力具象化的样子吧。真的,当时我的心里十分的激动,我迫切想要与别人分享,毕竟谁不想顺便去装个杯呢?一举两得。但是回首望去,我的身旁好像没有一人能真正懂我,我终于发现我们好像已经形同陌路了,此刻,我的身后一片虚无,举世茫茫,身旁只有大道相伴,唉,这难道就是强者独有的境界吗?哈哈哈,一不小心又被我装到了吧。

2024-07-18 08:39:34 649

原创 Spring MVC入门5

同样, 如果类上有 @RestController 注解时:表⽰所有的⽅法上添加了 @ResponseBody 注解, 也就是当前类下所有的⽅法返回值做为响应数据。如果⼀个类的⽅法⾥, 既有返回数据的, ⼜有返回⻚⾯的, 就把 @ResponseBody 注解添加到对应的⽅法上即可.也就是说: 在类上添加 @ResponseBody 就相当于在所有的⽅法上添加了 @ResponseBody 注解.如果作⽤在类上, 表⽰该类的所有⽅法, 返回的都是数据, 如果作⽤在⽅法上, 表⽰该⽅法返回的是数据.

2024-07-15 18:05:17 1078

原创 Spring MVC入门4

HttpServletResponse 对象代表服务器的响应. HTTP响应的信息都在这个对象中, ⽐如向客⼾端发送的数据, 响应头, 状态码等. 通过这个对象提供的⽅法, 可以获得服务器响应的所有内容。HttpServletRequest 对象代表客⼾端的请求, 当客⼾端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的⽅法,可以获得客⼾端请求的所有信息.Spring MVC在这两个对象的基础上进⾏了封装, 给我们提供更加简单的使⽤⽅法.

2024-07-15 10:06:40 786

原创 Spring MVC入门3

简单来说:JSON就是⼀种数据格式, 有⾃⼰的格式和语法, 使⽤⽂本表⽰⼀个对象或数组的信息, 因此JSON本质是字符串. 主要负责在不同的语⾔中数据传递和交换.接下里我们就要演示如何使用JSON来传递对象,详细回应上一篇文章末尾的问题。没有关系, 只是语法相似, js开发者能更快的上⼿⽽已, 但是他的语法本⾝⽐较简单, 所以也很好学。,2,编写代码,接收JSON对象, 需要使⽤ @RequestBody 注解。和字⾯表达的意思⼀样, 这个注解主要作⽤在请求URL路径上的数据绑定。• 国际通⽤语⾔-英语。

2024-07-12 20:16:20 715

原创 Spring MVC入门2

某些特殊的情况下,前端传递的参数 key 和我们后端接收的 key 可以不⼀致,⽐如前端传递了⼀个array2 给后端,⽽后端是使⽤ array 字段来接收的,这样就会出现参数接收不到的情况,如果出现。当有多个参数时,前后端进⾏参数匹配时,是以参数的名称进⾏匹配的,此时由于我们传递的参数的名称和形参是一致的,因此参数的位置是不影响后端获取参数的结果,所以我们将name和id交换位置也不会错。Postman里的KEY要和我们传递的参数要一致不然就会不匹配,相当于不能给这个参数赋值,于是他就默认为null了。

2024-07-11 21:16:51 1000

原创 Spring Web MVC入门

从标题我们就能看见一个很陌生的名词“”,这个名词听着很高大上,但它到底是啥呢?Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架,从⼀开始就包含在 Spring 框架中。它的正式名称“Spring Web MVC”来⾃其源模块的名称(Spring-webmvc),但它通常被称为 SpringMVCSpring Web MVC 是⼀个 Web 框架。

2024-07-11 15:42:19 1181

原创 将x减到0的最小操作(滑动窗口)

【代码】将x减到0的最小操作(滑动窗口)

2024-05-28 14:28:45 220 1

原创 最大连续1的个数(滑动窗口)

如果还没有看明白,没关系。详细解释一下:对比以前的滑动窗口,以前的判断条件是求某一段的和最大/求某一段含有不重复的字符最多……,只不过这次的判断条件是0的个数不能超过k,由于这个条件对我们子区间内还要进行操作,所以可能会使你下不去手,困惑。这道题大眼一看是关于翻转多少个0的问题,但是,如果你按照这种思维去做题,肯定不容易。所以我们要换一种思维去做,这种思维不是一下就能想到的,所以想不到也情有可原。但是只要抓住本质,按照那个模版来就能写对,这还需要平时多练。暴力解法就不展示了,就是两个for循环枚举。

2024-05-23 19:08:49 462

原创 无重复字符的最长子串(滑动窗口)

从一开始,我们就定义两个指针,同时指向0位置,让right指针向后走(进窗口),紧接着判断我们的hash表里是否有重复了(判断),如果重复了就出让left++(出窗口)直到hash表里重复的元素全出,再对个数进行更新(更新结果)。这种算法能极大减少指针移动的次数,我们不需要像暴力解法那样让right 每次都要从头再来,而是只需要向后移动一遍就行了。其实写这个暴力解法,写的还不熟,总是忘了下一步该咋写,那就是不熟练,多写写应该就行了。这也是一道滑动窗口的题,可以使用暴力解法,也能使用滑动窗口。

2024-05-18 15:48:36 310

原创 长度最小的子数组(滑动窗口)

他利用单调性,规避了很多没有必要的枚举行为,因此虽然他使用了两个循环,但是他的时间复杂度只有O(1)其实这种滑动窗口的题本质上还是用指针来写的。利用单调性,使用《同向指针》来优化。

2024-05-17 19:38:04 262

原创 四数之和(双指针)

【代码】四数之和(双指针)

2024-05-17 18:18:10 179

原创 三数之和(双指针)

我们通过示例一可以发现如果一个一个枚举的话有三种情况,但是看答案发现它又筛选掉了一种情况,因此需要进行去重。这道题的大体框架就是固定一个数,使三个数的和转换成另两个数的和。主要的难点其实就是去重了。当然还有很多小细节不能忽略。以上排完序再去重的方法很新颖,要好好体会。排序+暴力枚举+set去重。

2024-05-16 09:25:00 344

原创 查找总价格为目标值的两个商品(双指针)

定义两个指针,分别指向两端,然后拿两端值的和和target进行比较,如果target更大:则需要将left++,反之right- -,原理其实很简单:我们知道该数组是升序排列的,因此他的最左边肯定是最小的数,最右边肯定是最大的数,如果此时他们相加的和都要小于target了,肯定是要增大这个和的,而此时只有将left++才能增大这个和。其实啊一切算法的总结都是在暴力的基础上进行的,算法其实就是对暴力进一步的优化。其实我们首先想到的方法肯定是暴力,两个for循环嵌套就能找到,但肯定会超时。

2024-05-14 15:14:00 151

原创 有效三角形的个数(双指针)

然后我们定义一个标志位 pos 指向数组的最后,该标志位其实是代指了三角形的最大的那个边,然后定义两个指针分别表示另两条较小的边,一个指向数组最前,一个指向pos -1 ,然后判断如果此时nums[left]+nums[right] > nums[pos] 此时一定能构成三角形。我们知道数组是升序排列的,如果此时将left++ 一定能构成三角形,因此right~left这一段都能和pos构成三角形,ret+=right-left。

2024-05-14 08:30:00 248

原创 盛最多水的容器(双指针)

解题思路:1,暴力解法(超时)我们可以使用两层for循环进行遍历。找到那个最大的面积即可,这里我就不写代码了,因为写了也是超时。2,双指针法先定义两个指针一个在最左端,一个在最右端:矩形的体积是 底*高 ,我们将两个指针之间的距离当做底,当两个指针移动时底一定会减小,所以如果此时高还在减小,那么他的面积肯定会减小,所以我们就找高增大的作为矩形的两边,因此就有了height[left] > height[right] 这个判断条件,每次移动后都要比较,并取最大的体积,然后重复循环即可。此算法的

2024-05-13 22:00:26 272

原创 快乐数(双指针)

因此我们可以使用快慢指针法:使用这个方法有一个好处就是:当没有环的时候快慢指针一定不会相遇,有环的时候才会相遇,这样也符合我们的分析。上述两种情况是题目告诉我们的,但是假如没有了第二条题目,这道题的复杂的度就直接上来了,因为我们要考虑是否有那种无限循环且不重复的情况。此时我们可以由一个定理来证明一下:雀巢定理。雀巢定理的内容:有 n 个巣 ,有n + 1个鸽子,如果让所有鸽子都归巢,那至少有一个巣里面的鸽子的数量大于1。以上的两种情况其实我们可以归结成一种情况:都是无限循环但是第二种是对于1的无限循环。

2024-05-07 09:48:55 393

原创 移动零(双指针)

我们可以先分区域,将数组的左边都定义为非零区域,将数组的右边都定义为零区域。即【0,dest】是非零区域,【dest,length -1】为零的区域。让cur指针从前向后走,如果遇到0就继续走,遇到非零就停下并且将dest+1位置和cur位置的数据交换位置(注意dest的初始值是-1,cur 是0,这是这种算法的定义方式。你也可以寻找其他初始化的方式,不过相应的代码就要做出改变。不要纠结为啥dest初始值就是-1,这就是这种算法的写法,多写写就明白了)。

2024-05-07 08:35:03 166

原创 复写零(双指针)

下面的解法需要手动画图,举例去体会,只有自己手动去做了,才会有所收获。

2024-05-06 21:35:32 151

原创 网络中的基本概念

当我们刷一个视频时,手机(客户端)会向字节的服务器请求数据,此时就牵扯到了数据的发送和接收,而数据的包装正是用的我们前面用到的五层协议模型,先封装再发送。之后服务器就接收了客户端的数据,进行分用,像“ 拆快递 ”一样对数据进行解析。解析后的数据会在服务器内部进行一系列的业务代码,如:给你推荐你感性趣的内容。就这样经过两次发送,两次解析,客户端和服务器就能够通信了,你也能愉快的刷抖音了。如图所示:记住只要是用户使用的那一方就是客户端。为客户端提供资源的就是服务器。了解一下即可,我们重点掌握的是五层模型。

2024-04-23 18:22:34 815

原创 测试习题1

软件测试就是执行和运行软件的过程,其目的是为了发现软件功能和需求不相符的地方,或者寻找实际输出和预期之间的差异。

2024-04-22 11:01:49 163

原创 synchronized的优化策略^o^

此时每个 append 的调⽤都会涉及加锁和解锁. 但如果只是在单线程中执⾏这个代码, 那么这些加锁解锁操作是没有必要的, 白白浪费了⼀些资源开销.会根据情况,进行依次升级。如果你打三次电话,分三次汇报这三件事,我相信领导在接到你的第三次电话的时候,很可能就想亲切地问候你一下了。上诉案例,你将多次加锁完成的事,都堆加在一块只用一次加锁就完成,这样的操作我们称为。但是如果你一次电话就将这三件事汇报完,不仅能得到领导的表扬,还能节省自己的时间。我们知道两个人在通话中第三个人是不能插进来的,这也和加锁很相似。

2024-04-18 15:56:44 1604

原创 CAS ^o^

CAS: 全称Compare and swap,字⾯意思:”比较并交换“

2024-04-18 09:40:40 1731

原创 锁策略^o^

如果获取锁失败, ⽴即再尝试获取锁, ⽆限循环, 直到获取到锁为⽌. 第⼀次获取锁失败, 第⼆次的尝试会在极短的时间内到来.⼀旦锁被其他线程释放, 就能第⼀时间获取到锁.假设三个线程 A, B, C. A 先尝试获取锁, 获取成功. 然后 B 再尝试获取锁, 获取失败, 阻塞等待;这就好⽐⼀群男⽣追同⼀个⼥神. 当⼥神和前任分⼿之后, 先来追⼥神的男⽣上位, 这就是公平锁;这个锁其实和自旋锁是有点相反的,该锁在获取锁失败后会直接进入阻塞状态,放弃CPU,需要很久才能被调度,这也就是之前我们最常用到的锁。

2024-04-16 16:07:04 828

原创 线程池总结

通过上图可知:ThreadPoolExecutor有7个参数。

2024-04-12 11:58:40 922

原创 阻塞队列的模拟实现

【代码】阻塞队列的模拟实现。

2024-04-09 09:50:03 191

原创 单例程的写法总结

其实啊,单例程是一种设计模式。那啥是设计模式呢?设计模式就好比象棋中的棋谱。假如,红方当头炮,那么黑方就马来跳,这样就能有效应对红方的走棋。因此黑方应招的时候有一些固定的套路,按照套路走,局势就不会吃亏。在软件开发中也有很多常见的问题场景,针对这些问题场景,大佬们总结出了一些固定的套路,按照这个套路来实现代码,就不会吃亏。由此可见啊,那些大佬为了我们可谓是操碎了心。

2024-04-05 19:58:21 514

原创 线程安全问题的原因和解决方案

在t1 线程已经上了一把锁lock1 ,t2 线程已经上了一把锁 lock2 的前提下,t1 在阻塞等待t2将lock2 解锁了 ,而t2 在阻塞等待 t1 将lock1 解锁了,就这样他们就僵住了,结果毫无疑问,就是什么都不打印,都在阻塞等待。出现问题,我们要解决啊,所以我们引入了加锁操作,但是,我们会发现加锁也是有出错的风险的,因此我们又总结了常见的加锁操作,以及产生死锁的条件,以防我们之后写代码的时候写成死锁。但是,有线程之间是随机调度且抢占式执行 ,所以造成了线程不安全的问题。

2024-03-29 11:51:22 784 1

原创 Thread类中run和start的区别&&线程的状态

当李四、王五开始去窗⼝排队,等待服务,就进⼊到 RUNNABLE 状态。该状态并不表⽰已经被银⾏⼯作⼈员开始接待,排在队伍中也是属于该状态,即可被服务的状态,是否开始服务,则看调度器的调度;当李四、王五因为⼀些事情需要去忙,例如需要填写信息、回家取证件、发呆⼀会等等时,进⼊BLOCKED 、 WATING 、 TIMED_WAITING 状态;刚把李四、王五找来,还是给他们在安排任务,没让他们⾏动起来,就是 NEW 状态;如果李四、王五已经忙完,为 TERMINATED 状态。

2024-03-28 17:33:40 319 1

原创 Thread类的基本用法

这是因为currentThread()是静态的,想一下线程的真正启动,是不是在start的时候,而start是在调用这个线程之后的位置,说人话:也就是我们在这个线程启动之前就调用了这个线程,这样是不允许的,所以我们需要调用静态方法currentThread()来过渡一下,这样才能在启动线程之后直接拿到线程对象。)里加上3000之后,这意味着:我们只需要等待3秒,不管这三秒 t 线程是否执行的完,只要3秒一过,就不再等待,这中等待比死等要好的多,现实中用的大多数也是这种有限的等待。通过继承Thread对象。

2024-03-28 17:06:32 258 1

原创 进程和线程的区别&&线程的5种构造方法

从上面5种方法,我们不难看出,只有这个lambda表达式最为特殊,只有它没有重写run方法,其实我们可以认为它写成这个形式,就已经重写过了。

2024-03-25 15:59:46 444 1

原创 java的JDBC编程(详解)

JDBC的来源:那时有很多的数据库厂商,但是很多的数据库厂商的API都有所不同,此时的程序猿要想操作不同的数据库就要学习不同的API,这就大大增加了程序员的负担。此处有一个捷径:就是一些大佬觉得有些软件太分散了不好找的,于是就建立了一个第三方中央仓库,便于我们直接去下载,这个仓库的链接 https://mvnrepository.com/,在搜索框里直接搜MySQL 就行了,下载新版本还是旧版本,就看你用的MySQL是新版本还是旧版本了,如果是新的你就最好用新的,反之,亦是如此。,这是对一个好程序的要求。

2024-03-21 17:41:26 767 1

原创 事务(初阶)

举个例子:还是接着上面的例子说,我们将窗户关掉,等到做完课件的时候,再将它发出来,此时小明正在津津有味的读你的课件。所以,他可能会查询很多次,但是当他查到某一次的时候,发现内容竟然和之前的不一样,于是你再次靠实力让小明再一次带上了他的小丑面具,此时小明肯定不乐意了,于是他就来质问你。所以,此时,你又想了一个点子,我不能该原来的数据了,那我新建一个不就行了吗,于是通过事务D又新建了一个更先进的数据,此时的小明虽然读的是不变的数据,但是,当他某次查询后,发现又多出来了一个进阶版课件,这是怎么回事?

2024-03-19 16:04:35 461

原创 深入理解索引

那此时,如果我们创建一个普通索引的话,该普通索引的叶子结点储存的数据其实是我们主键索引的一个指针(目前可以理解成一个指向主键索引的一个指针),在查询的时候,假如你使用的是普通索引(即:你命中了普通索引),他会先使用普通索引找到普通索引的叶子结点,然后根据该叶子节点,找到主键的位置,然后再在主键的索引里找到的叶子节点,此时找到的叶子结点储存的数据才是,真正的表里的数据,我们也将这样的进行二次查找的叫做 “回表”。此时会默认一列,MySQL为我们创建一个隐藏索引,这个隐藏的索引和上诉的隐藏主键是差不多的。

2024-03-18 16:14:30 582

原创 回文数(含sprintf函数的详细解答)

上面是一道计算回文数的题:虽然这道题总体上来说很简单,但是对于那些没有掌握思路的人来说,其实也是挺难的,我在写的时候也总结了很多,下面就来分享给你们:今天我们主要从代码的思路以及写法 和 sprintf 的用法两个方面来说,其中我也是搜索了多关于这道题的信息,可以说这篇博客是干货满满,要认真看哦。

2023-12-11 11:52:14 432 1

原创 移除链表元素

上面是力扣上的一道题,主要是考察我们对单链表的理解和使用。

2023-12-04 17:54:00 328

空空如也

空空如也

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

TA关注的人

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