自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 算法排序算法

对于这种“第K个元素”的问题,可以用快速选择,它是对快速排序的一种简化。快速排序采用分治思想,将数组分为两个子数组,每次划分数组都随机选择一个元素,小于该元素的在一个数组,大于该元素的在另一个数组。递归执行划分数组操作,直到数组全部完成排序。而快速选择针对某个元素,它不要求对两个子数组排序,仅仅递归划分“第K个元素”在的那个子数组即可,直到获得“第K个元素”的位置。为了避免两个子数组,一个长度为1,一个长度为n-1的极端情况,每次划分数组时随机选择元素。通过递归实现快速排序。

2024-12-29 07:11:22 550

原创 SpringBoot ApplicationListener SpringApplicationRunListeners

自定义一个事件监听器和run方法监听器。并且将监听器写入/META/spring.factories文件。

2024-12-27 08:12:01 539

原创 SpringBoot 启动类 SpringApplication 三 配置IOC容器

是交给容器子类自定义初始化,web容器在此配置web环境并且启动tomcat。默认的初始化器有7个。从上到下它们的功能分别是。容器根据定义类创建容器。是容器实现类,它添加bean后处理器。最后将后处理器重新注册一遍。是bean的定义类,是对不同来源(,因为此时还没有创建bean。后处理器分2种,一种是。也是按照优先级进行处理。接口,其余的最后处理。处理结束后,删除缓存。方法也是按照优先级注册。

2024-12-27 06:25:14 751

原创 SpringBoot 启动类 SpringApplication 二 run方法

在。

2024-12-22 17:23:20 461

原创 算法 双指针技巧

那么左指针遍历到i时,如果右指针大于j,那么和偏大,右指针左移,不会出现左指针右移的情况。右指针遍历到j也是同理,因此不会出现左指针大于i,右指针小于j的情况。a表示头节点到入环点的距离,b表示入环点到相遇点的距离,c表示相遇点到入环点的距离。由于数组是有序的,因此两个指针,一个从前向后遍历,一个从后往前遍历,可以在O(n)时间复杂度完成查询。,这个等式意味着,分别从相遇点出发和从头结点出发的两个节点终会在入环点相遇。在环里相遇,它们速度又相同,因此它们在环里的每个位置都相遇,自然包括入环点。

2024-12-22 12:00:01 595

原创 SpringBoot Redis 消息队列

Redis在server端为每个消费者保留一块内存区域,存储该消费者订阅的数据。如果消费者处理速度慢,内存区域满了,那么Redis会断开消费者连接,这会导致消息丢失。完整项目在https://gitcode.com/zsss1/redis_mq/overview。发送者将消息发送到频道,订阅者订阅频道即可及时收到消息。消息队列可以实现消息解耦、消息路由、异步处理、流量削峰填谷。同时可以满足有序,消息去重。redis的list底层是链表,满足先进先出。它支持组生产者与消费者。Redis也可以实现消息队列。

2024-12-21 18:38:12 728

原创 贪心算法 greedy

先从左到右遍历孩子,如果当前孩子比左边孩子评分更高,则糖果数=左孩糖果数加1.完成遍历后,满足左邻条件。再从右往左遍历孩子,如果当前孩子比右边孩子评分更高,则糖果数=右孩糖果数加1。为了更多孩子能拿到饼干,对每个孩子的要求是“尽量给没拿到饼干的孩子留更多饼干”,换句话说就是“自己尽量拿更小的饼干”。题目要求:相邻两个孩子评分更高的孩子会获得更多的糖果。为了更少分配糖果,如果孩子评分更高,只比相邻1个糖果。因此按照区间的结束序号从小到大排序,每次都留下结束时间最早的,然后往后遍历,删去重叠的。

2024-12-21 11:37:13 593

原创 SpringBoot 启动类 SpringApplication 一 构造器方法

这两个上下文,前者是引导上下文,在IOC容器启动之前保存预先加载的类,IOC容器启动之后会销毁引导上下文。是资源加载器,它定义获取资源的策略。它加载各种来源的资源,比如文件资源(启动项目,加载的实现类中就包含自定义的实现类。参数获取实现类的全限定类名,之后实例化。方法查询类路径上是否存在某个类。静态方法实现加载工厂类并且保存在。的方法,该方法所在的类就是主类。对象是对各种资源的抽象,调用。用于实例化该接口的实现类,即。实现类,定义监听的事件。的实现类,用于监听启动。工厂类文件的加载器。

2024-12-20 07:52:55 502

原创 SpringBoot SPI

SPI将服务接口与服务实现解耦。调用者动态配置JDBC实现包,实现动态加载数据库连接,而不是在代码中显式定义。是服务提供者的接口,有接口,有实现。比如后端向前端提供的接口。是服务接口,它只有接口,没有接口的实现。具体实现由不同的包自己定义。目录下新增配置文件,文件名是接口全限定类名,文件内容是接口实现者的全限定类名。以JDBC为例,JDK提供JDBC接口,在包。修饰的配置类,使得配置类中定义的bean都进入IOC容器。接口的实现类,154个类就是这样放入。文件用一组键值对表示接口与实现。

2024-12-15 12:13:47 339

原创 [146 LRU缓存](https://leetcode.cn/problems/lru-cache/)

维护一个双向链表保存缓存中的元素。如果元素超过容量阈值,则删除最久未使用的元素。为了实现这个功能,将方法获取的元素添加到链表首部。为了在O(1)时间复杂度执行get()方法,再新建一个映射表,缓存key与链表节点。

2024-12-14 10:37:54 544

原创 JAVA 泛型

java脚本的编译分为两个阶段,一阶段是源码(.java文件)编译为字节码(.class文件),二阶段是字节码编译为JVM使用的二进制机器码。为了兼容早起版本,Java泛型在一阶段被擦除为原始类型,字节码文件里没有泛型参数。不能写的原因是上界通配符无法确定实际类型,如果2次写的实际类型不一致,如下代码,那就违背泛型的初衷了。这种指定接口的类型参数,实例方法的类型参数为接口指定的类型参数。是类型参数,在调用时才能确定具体类型。表示泛型类型的上界,泛型参数可以是。表示泛型类型的下界,泛型参数可以是。

2024-12-11 21:30:14 703

原创 JDK17 CompletableFuture 二 返回与回调

同步返回当前对象的计算结果,即result变量。T join()以为例分析源码。是当前线程的等待唤醒类。nanos表示距离超时还剩多少时间,deadline表示超时时间,表示是否响应中断,表示当前线程(就是thread变量)是否被设置中断。当前线程将Signaller放入对象的stack之后就进入等待。之后异步线程得到的结果并且执行方法,在stack里找到这个Signaller,并且执行方法唤醒当前线程。方法和get()方法类似,表示不响应中断。

2024-12-11 07:43:29 1042

原创 JDK17 CompletableFuture 一 调用

类有2个成员变量,volatile修饰符保证多线程环境下变量可见性。result表示当前任务的结果,可能是正常结果,可能是异常对象。stack是当前任务确定结果后接下来所有执行的任务栈。常用的创建方法中,有返回值,runAsync没有返回值(返回值类型为Voidasync表示异步,即runnable任务不由调用线程执行,而是由线程池执行。默认线程池是,这是一个全局唯一的线程池。为了管理任务,建议对不同类型任务分别分配线程池。

2024-12-08 18:15:16 715

原创 算法 并查集

因此将2节点和3节点的元素指向3节点。注意:1号节点指向2号节点,不是3节点。但是2号节点指向3号节点。初始化并查集数组,下标1-5代表节点编号,元素代表节点所属的集合。节点形成环,任意一条边都可以是多余边,删除任意一条边都能还原成树。例题:edges = [[1,2], [2,3], [3,4], [1,4], [1,5]]将1号节点和2号节点视为一个集合,因此它们的元素指向同一个节点。一种路径压缩的思路是每次计算节点所属集合时路径上每个节点的集合。边,由于1号节点和2号节点不属于一个集合,因此。

2024-12-07 11:21:12 1399

原创 JDK17 阻塞队列 LinkedBlockingQueue

生产者和消费者平时是互不干扰的,直到队列为空或者队列为满时才相互交互。节点是队列的内部类,目的是以单向链表(只有。唤醒某个生产者,那个生产者重新获取锁后从。唤醒某个消费者,那个消费者重新获取锁后从。独占锁才能添加元素,消费者先获取。,因此被称为无界队列,有。,取出元素的线程称为。独占锁才能取出元素。元素满时,生产者调用。元素空时,消费者调用。锁,直到生产者者调用。

2024-12-05 07:40:34 1097

原创 JDK17 线程池 ThreadPoolExecutor

TOC。

2024-12-03 20:10:06 660

原创 JDK17 共享锁 Semaphore和CountDownLatch

/ 定义非公平锁// 获取锁// 释放锁与类想同,Semaphore类也代理内部静态公平锁和非公平锁。permits是类的state,代表锁的状态。独占锁类的state从0开始,占锁的线程使state++,释放锁state--。而Semaphore共享锁类的state从非0开始,代表可利用的资源数量,state减少表示线程占锁,增加表示线程释放锁。

2024-12-01 12:23:10 443

原创 JDK17 ReentrantLock独占锁

它们的区别。

2024-12-01 08:45:18 910

原创 JDK17 AbstractQueuedSynchronizer 二 条件队列

同步队列中的线程是为了争抢锁,而条件队列中的线程是主动释放锁,挂起自己,等条件满足时被别的线程唤醒,继续工作。AQS里只有1个同步队列,但可以有多个等待队列,每个等待队列对应一个对象。同步队列的头尾节点是head和tail,等待队列的头尾节点是和lastWaiter。同步队列的头结点是哑节点,等待队列没有哑结点。线程想进入同步队列是没有条件的,线程想进入等待队列得先获取锁,而且还得是独占锁。同步队列的节点和等待队列的节点都是Node对象,线程离开等待队列后会进入同步队列,继续获取锁。

2024-11-29 16:58:00 631

原创 JDK17 AbstractQueuedSynchronizer 一 同步队列

抽象队列同步器是JDK提供的用于管理线程间同步状态的类。常见的同步器类ReentrantLock, CountDownLatch, Semaphore等都是AbstractQueuedSynchronizer的子类。AQS提供三个功能。

2024-11-28 08:01:27 1510

原创 springboot+redis+lua实现分布式锁

Java锁能保证一个JVM进程里多个线程交替使用资源。而分布式锁保证多个JVM进程有序交替使用资源,保证数据的完整性和一致性。分布式锁要求。

2024-11-26 08:17:58 683

原创 springboot+redis+lua脚本实现滑动窗口限流

为了维护系统稳定性和防止DDoS攻击,需要对系统请求量进行限制。

2024-11-24 16:53:59 764

原创 行为型设计模式-访问者模式

允许一个或者多个操作应用到一组对象上,解耦操作和对象本身。

2024-11-23 17:06:29 1021

原创 结构性设计模式-组合模式

将对象组合成树形结构 , 表示 " 部分-整体 "层次结构。

2024-11-21 20:12:14 725

原创 行为型设计模式-模板模式

0 定义定义一个操作的框架,一些步骤延迟到子类实现。子类不改变框架,改变具体步骤内容。1 经典模板方法模板类一般是抽象类。模板类的方法有2种,一种是抽象方法,由子类实现,模板类仅仅定义,一般用protected修饰。另一种是模板方法,由模板类定义,final修饰表示不允许修改。public abstract class Template { public final boolean execute() { String id = method1(); retu

2024-11-20 11:12:05 408

原创 行为型设计模式-责任链模式

将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为止。责任链模式与其他行为型设计模式最主要的区别是:处理器工厂类硬编码处理器类处理请求的先后顺序。而策略模式由运行时参数动态选择处理器类。

2024-11-20 10:40:36 342

原创 行为型设计模式-策略模式

定义一类算法,将每个算法分别封装起来,让它们可以互相替换。算法的变化独立于使用它们的客户端。策略模式的目的是将算法的创建与算法的使用独立开来。

2024-11-20 10:23:19 299

原创 结构性设计模式-代理模式

为某对象提供代理以控制对这个对象的访问。代理模式从简单到复杂可以分为静态代理,动态代理,面相切面变成。

2024-11-19 08:31:18 400

原创 创建型设计模式-原型模式

原型模式适合的场景:创建对象的成本比较高(不一定是内存开销高,可能是网络IO和磁盘IO开销高)。此时,复制已有对象来创建新对象达到节省时间的目的。这种创建对象的方式叫做原型模式。

2024-11-19 07:58:50 149

原创 结构性设计模式-装饰器模式

动态地给一个对象添加额外的职责,同时不改变其结构。

2024-11-19 07:57:41 910

原创 创建型设计模式-建造者模式

工厂模式和建造者模式同样是解耦生成对象和使用对象,它们的区别是:工厂模式是在一个类里创建多个对象,这些对象继承同一个父类或者接口。而建造者模式是专注于一个对象的生成,通过不同的参数,定制化创建不同对象。因此它们可以搭配使用。

2024-11-17 21:29:09 321

原创 创建型设计模式-工厂模式

工厂模式的目的是解耦创建对象和使用对象这两个操作。工厂模式可以分为简单工厂、工厂方法和抽象工厂。

2024-11-17 18:42:49 414

原创 创建型设计模式-单例模式

某个类只有1个实例,并且类自行实体化并且向系统提供这个实例。

2024-11-17 17:35:04 212

原创 六个设计模式原则

开闭原则是核心要求,其余五个原则是它的实现。单一职责原则是对单个实现类的要求:不要设计大而全的类。里氏替换原则是对继承和多态的要求:子类应当可以替换父类。依赖倒置原则是对依赖关系的实现要求:不依赖具体类,而是依赖接口/抽象类。接口隔离原则是对依赖倒置原则的补充:所依赖的接口应当进行细化,接口不提供非必须信息。迪米特法则是对依赖关系的逻辑要求:对依赖对象的了解尽量少。

2024-11-17 16:33:36 660

原创 算法题-删除数组中重复元素,只保留2个

给定一个数组,原地删除重复元素,使每个元素最多出现2次,并且返回删除后数组的长度。不用管数组中剩余的元素。例题:数组为,删除后数组为,长度为6.Leetcode有道类似的题,它的特点是每个元素只保留1个。而本题的特点是每个元素保留2个。

2024-11-17 12:13:03 363

原创 算法-字符串匹配KMP

而KMP算法不会,主串下标永远不会回退。再看子串下标,暴力算法会将子串下标重置为0,而KMP算法会利用成功匹配部分尽量保留匹配子串。接下来就来看看它是怎么做到的。从图中可以看出暴力算法与KMP算法中主串下标和子串下标移动规则的区别。首先看主串下标,暴力算法会将主串下标从。

2024-11-10 17:49:11 976

原创 算法-分治算法

分治算法由分和治组成。以归并排序为例,分就是将原数组递归分解为2个子数组,直到子数组的长度为1,不可再分。治就是将排好序的2个子数组合成1个排好序的新数组,合二为一。

2024-11-10 10:01:57 237

原创 算法-二分法

在一个有序数据集合中找目标元素,每次跟区间中间位置的元素进行对比,进而每次舍弃一半元素,在剩下一半区间中继续查找。直到找到目标元素或者区间长度为0.

2024-11-10 09:52:40 429

原创 windows机器上的postman 访问远程linux机器上的springboot服务

【代码】postman 访问linux机器上的springboot服务。

2024-11-08 17:18:43 227

原创 mysql复制表结构语句`create table select from`无法复制原表的索引

问题是复制表没有索引。复制原表,然后改表名。

2024-09-12 15:36:22 247

空空如也

空空如也

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

TA关注的人

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