自定义博客皮肤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)
  • 收藏
  • 关注

原创 线程的状态

使⽤多数据源时,需要根据数据源的名字切换数据源,假设⼀个线程设置了⼀个数据源,这个时候就有可能有另⼀个线程去修改 数据源,可以使⽤ ThreadLocal 维护这个数据源名字,使每个线程持有数据源名字的副本,避免线程安全问题。多线程环境下,每个线程都会被分配⼀个固定长度的 CPU 计算时间,每个线程运⾏⼀会⼉就会停⽌让其他线程运⾏,这样才能让每个线程 公平的运⾏。主要⽤途是为了保持线程⾃⾝对象和避免参数传递,主要适⽤场景是按线程多实例(每个线程对应⼀个实例)的对象的访问,并且这个对象很多地⽅都要⽤到。

2024-02-05 04:55:51 354

原创 简述CAS

在Java中,ABA问题是指在多线程环境下,一个值在某一时刻被线程A修改为B,然后又被修改为A,而线程B在这个过程中可能并不知情。这可能导致一些意外的行为,尤其是在使用CAS(Compare and Swap)操作时,因为CAS只检查值是否仍然是预期的值,而不考虑其在操作过程中是否发生过其他变化。CAS,Compare And Swap,是一种轻量级的同步机制,主要用于实现多线程环境下的无锁算法和数据结构,保证了并发安全性。这样,在进行CAS操作时,可以检查版本号或时间戳,而不仅仅是值是否匹配。

2024-01-31 00:30:15 250

原创 Synchronized和ReentrantLock的区别

ReentrantLock 是 Java 中用于实现可重入锁的一种机制。它提供了比传统的 synchronized 关键字更灵活的锁定方式。在上述例子中,整个方法被标记为 synchronized,这意味着只有一个线程能够同时执行这个方法。其他线程需要等待当前线程执行完毕后才能访问该方法。在Java中,synchronized 是一种用于实现线程同步的关键字。关键字Synchronized 与 ReentrantLock。ReentrantLock的可重入性。Java 常见的加锁方法。

2024-01-31 00:18:49 124

原创 缓存相关问题

在一个较短的时间内,缓存中较多的key过期,恰恰就是在较短的时间内,有很多请求访问过期key而未命中,让请求到达数据库,数据库同时接收大量的请求,而无法及时处理,导致数据库崩溃。同时重启应用服务、redis服务、数据库服务,重启以后,海量请求呼啸而至,缓存中是空的,继续崩溃。2.白名单策略:采用布隆过滤器,布隆过滤器的思想是,将所有可能存在的key哈希到一个足够大的 bitmap 中,一个一定不存在的数据会被这个 bitmap 拦截掉,从而避免了对底层存储系统的查询压力附加 对于空间的利用到达了一种极致。

2024-01-22 06:04:09 537

原创 Hash集合

每个段都有自己的锁,不同的段之间互相独立,这样不同的线程在访问不同的段时可以并行进行,提高了并发性能,并减少了锁竞争的概率。在1.8之后的ConcurrentHashMap中,获取锁的粒度变大了,相比于1.8之前的实现,降低了锁竞争的概率,提高了并发性能。而1.8之后的ConcurrentHashMap引入了分段锁机制,将整个集合分为多个段,每个段拥有独立的锁,提高了并发性能并降低了锁竞争的概率。无序性:HashSet集合中的元素是无序的,即元素的存储顺序与元素被添加到集合中的顺序不一致。

2024-01-22 05:58:43 441

原创 数据库常用锁 小记

3.可重复读(Repeatable Read):在一个事务中,多次读取同一数据的结果是一致的,即使其他事务对该数据进行了修改,当前事务读取到的仍然是事务开始时的值。1.读未提交(Read Uncommitted):最低的隔离级别,事务可以读取其他事务尚未提交的数据,可能导致脏读(Dirty Read),即读取到未提交的数据。用于提高并发性能,指示事务将要对资源的子资源进行锁定,例如在表级别存在一个独占锁时,其他事务可以获取该表的共享意向锁而不必遍历全表进行加锁。独占锁会阻塞其他事务的共享锁和独占锁。

2023-12-12 20:49:01 38

原创 CPU密集型和IO密集型对CPU内核之间的关系 小记

I/O密集型任务对CPU资源的需求并没有很大,其主要关注在输入/输出操作上,而CPU主要是在等待I/O操作完成然后处理相应的数据,并不需要大量密集的计算操作。CPU密集型任务会需要大量的CPU资源进行对任务的处理,多个CPU内核可以并行地处理这些计算任务,各个CPU内核可以同时进行计算操作互不干扰从而让任务更快的完成。总的来说,CPU密集型任务对于CPU内核之间的合作和协调非常重要,会需要大量的CPU资源,拥有更多的CPU内核可以提高计算性能;I/O密集型任务指的是那些对输入/输出操作的需求较高的任务。

2023-12-07 20:34:05 33

原创 ELK-日志解决方案

同时载入logback-spring.xml文件。2.springboot中使用logstash。重启容器并释放9600和5044端口即可。1.搭建ELK-logstash。

2023-12-06 20:39:41 25

原创 线程池 小记

常见的拒绝策略有:AbortPolicy(终止策略,抛出异常)、CallerRunsPolicy(调用者运行策略,由调用线程直接执行任务)、DiscardOldestPolicy(丢弃最旧任务策略,丢弃任务队列中最旧的任务)、DiscardPolicy(丢弃策略,直接丢弃新的任务)。该策略既不会抛弃任务,也不会抛出异常,而是将某些任务回退给提交任务的线程(调用线程),由调用者自己执行任务,从而降低新任务的流量。当线程池无法接受新任务时,该策略会直接丢弃新的任务,没有任何提示或处理,该策略不会执行任务操作。

2023-12-05 20:32:28 19

原创 java定时任务schedule quartz xxl-job 小记

Timer的缺点在于其是单线程,所有任务都在一个线程中串行执行,如果一个任务的执行时间超过了预期,会对后续任务的执行时间产生影响。因此Timer类只适合于简单的定时任务,不涉及复杂的任务调度需求或分布式环境。通过timer.schedule(task, delay, period)的方法将任务task安排在延迟delay毫秒后开始,每间隔period毫秒重复执行。通过spring task实现定时任务可见能更快速实现,但不支持动态调整,修改任务参数就需要重启项目。使用注解即可实现定时任务。

2023-12-04 20:52:49 131

原创 Docker

下载docker-compose文件并移动到Linux的/usr/loacl/bin文件中。搭建Redis一主二从结构 redis_6379为主 redis_6380和redis_6381为从。redis.conf为Redis配置文件,redis.log为Redis记录日志文件。先创建6379、6380、6381三个文件夹,分别作为每个redis的挂载文件用。配置bind端口→修改保护模式→修改日志文件配置→。配置完成后就可以运行redis-master。在创建日志文件时要修改文件权限。

2023-12-02 17:58:03 19

原创 sychronized 小记

关键字来修饰一段代码块,将其称为同步代码块。由于JKD早期Synchronized是重量级锁,通过切换操作系统运行态来申请锁会消耗大量资源,于是在JKD1.6中对Synchronized进行了大量优化,锁自旋、锁粗化、锁消除,锁膨胀等技术。在Java SE 1.6里Synchronied同步锁,一共有四种状态:无锁,偏向锁,轻量级锁,重量级锁,它会随着竞争情况逐渐升级。Synchronized关键字解决的是多个线程之间访问资源的同步性,synchronized 翻译为中文的意思是同步,也称之为”同步锁“。

2023-11-30 20:33:27 18

原创 过滤器,拦截器,aop之间差异

拦截器也是拦截请求,它是属于org.springframework.web.servlet包下的,依赖于spring,所以它可以获取到spring ioc容器中的bean,如其他的service等,而过滤器是不能的。AOP的描述为:面向切面编程,实现在不修改源代码的情况下给程序动态统一添加额外功能的一种技术,AOP可以拦截指定的方法并且对方法增强,而且无需侵入到业务代码中,使业务与非业务处理逻辑分离,这样可以提高代码的可维护性、可重用性和扩展性。由此可见,过滤器,拦截器拦截的是URL。

2023-11-29 18:55:46 24

原创 代理模式之静态代理、动态代理和CGLIB代理 小记

动态代理,即JDK动态代理,是一种在运行时创建代理类的机制,它允许在不提前知道代理类的具体类型的情况下,动态地创建一个代理对象来代替原始类。相比于静态代理,动态代理更加灵活,可以代理任意的接口类型,不需要为每个被代理的类编写专门的代理类,而是通过Java的反射机制在运行时动态生成代理类。静态代理在编译时就已经确定了要代理的类和方法,其需要定义一个代理类,该代理类实现了与目标对象相同的接口,并拥有目标对象的引用。类创建代理对象,我们首先设置要代理的目标对象的类为代理类的父类,然后设置拦截器为。

2023-11-28 20:12:30 22

原创 Spring是如何解决循环依赖的 小记

5.解决循环依赖:如果发现另一个正在创建的对象依赖于当前对象,并且当前对象已经在二级缓存中标记为未完成状态,Spring 将会从三级缓存中获取已经创建的对象实例(只是未完成状态),并注入到另一个对象的依赖属性中。二级缓存:早期的单例对象,beanName->Bean,其中存储的是实例化之后,属性未赋值的单例对象,执行了工厂方法生产出来的Bean,bean被放进去之后, 当bean在创建过程中,就可以通过getBean方法获取到早期单例对象。这样,其他对象在引用该对象时,可以获取到一个未完成的引用。

2023-11-27 20:38:20 15

原创 Rpc和http的区别

RPC服务主要是基于TCP/IP协议的,而HTTP服务主要是基于HTTP协议的,因此在传输层的RPC会比在应用层的HTTP效率更高。由于HTTP是无状态的,因此每次客户端发送请求到服务端时都需要携带大量信息去确保访问服务端的正确性,而RPC时会在客户端和服务端建立一个会话保持连接状态信息,从而实现更高效的状态信息,此外RPC还支持异步调用,可以在不阻塞主线程的情况下处理多个请求。HTTP协议是无状态的,每一次请求都是独立的,服务器不会保存之前的状态信息。因此每个请求都会携带足够的信息去确保传输的正确性。

2023-11-25 17:40:18 19

原创 设计模式-build 小记

建造者模式通过将复杂对象的构建过程和表示分离,使得构建过程可以更灵活、可配置,并且可以创建不同表示的对象。设计模式中的建造者模式(Build)是一种创建型设计模式,用于将一个复杂对象的构建过程与其表示分离,从而使同样的构建过程可以创建不同的表示。建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象 的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。4.指挥者(Director):负责调用合适的建造者方法,按照特定顺序组装产品,在隔离客户与对象的生产情况下创建复杂对象。

2023-11-24 10:15:19 16

原创 http协议和websocket协议之间的区别 小记

1.连接方式:HTTP协议是一种请求-响应模型的协议,每次请求都需要客户端发送一个完整的请求到服务器,服务器处理完请求后返回响应。而WebSocket协议是一种基于持久连接的协议,通过建立一次连接后,双方可以随时发送和接收数据。它是一种无状态的协议,每个请求都是独立的,服务器不会保留任何关于客户端的状态信息。HTTP协议即超文本传送协议(Hypertext Transfer Protocol ),是Web联网的基础,也是手机联网常用的协议之一,HTTP协议是建立在TCP协议之上的一种应用层协议。

2023-11-22 20:29:20 27

原创 ConcurrentHashMap和HashMap的区别 小记

在ConcurrentHashMap中,无论是读操作还是写操作都能保证很高的性能:在进行读操作时几乎不用加锁,而在写操作时通过锁分段技术,将整个哈希表分成多个(Segment),每个段都有自己的锁,不同的线程可以同时对不同的段进行操作,从而提高并发性能。这个映射函数叫做散列函数,存放记录的数组叫做散列表。由于散列表是通过散列函数来将key值映射到表中的某一个位置,散列函数能使对一个数据序列的访问过程更加迅速有效,通过散列函数,数据元素将被更快地定位,所以其查询的时间速度可以认为是O(1)。

2023-11-21 20:09:25 19

原创 计算机网络 小记

传输层属于是中间的桥梁,用于控制传输,传输层的端口号只具有本地意义,长度为16bit(65536个端口),其中0~1023是熟知端口号(给TCP/IP最重要的应用程序),1024~49151位登记端口号(为没有熟知端口号的应用程序使用),49152~65535给客户端使用,仅在客户进程运行时才动态选择。TCP/IP参考模型虽然不是规定的标准,但是由于OSI参考模型的功能划定不合理,因此使用了更为合理的更符合市场使用的TCP/IP模型,成为了事实标准。分为:链路层,网络层,传输层,应用层。

2023-11-20 20:33:39 16

原创 gitlab搭建小记

v /usr/local/software/gitlab/config:/etc/gitlab #挂载文件。-p 80:80 #将容器内80端口映射至宿主机80端口,这是访问gitlab的端口。-p 23:22 #将容器内22端口映射至宿主机23端口,这是访问ssh的端口。--name gitlab #设置容器名称为gitlab。之后访问hostname的地址即可进入gitlab界面。-p 443:443 #将容器内部端口向外映射。然后pull下载最新版本的gitlab。之后进入容器设置用户。

2023-11-18 14:07:05 24 1

原创 生产者消费者模型 小记

通过使用生产者消费者模型,能够提高系统的并发性和资源利用率,同时避免了数据竞争和死锁等并发编程中常见的问题。系统中有一组生产者进程和一组消费者进程,生产者每次生产一个产品放入缓冲区,消费者每次取出一个产品使用掉。生产者消费者模型能够降低生产者和消费者之间的依赖关系,通过增加一个缓存区的方式,将生产者和消费者变成两个独立的并发主体,互不干扰的运行。生产者模块产生的数据可以直接存放到缓冲区内等待消费者模块调用,将数据块放入缓冲区后可以继续生产而不需要等待消费者处理;消费者:处理数据的模块。

2023-10-30 20:07:07 46 1

原创 数据库分表分库 小记

当单表数据达到千万级别时,其查询等性能会严重下降,通过建立索引等方法我们已经无法实现对数据库性能的提升,所以需要通过分表分库的方法来提高系统的性能。是否需要进行分库分表应该根据实际业务需求和数据库性能瓶颈来决定,原则上是能不分就不分,数据库表之间的关系一定上映射了业务逻辑,分库分表的行为会增加业务逻辑的复杂度,会使得后续维护的成本上升。因为数据库的容量是固定的,随着数据量的增长,为了解决容量不够的问题,最简单的方法就是增加容量。除此之外,通过将不同的数据分散到不同的库和表中,可以增加数据的安全性。

2023-10-28 17:39:41 32 1

原创 Threadlocal对象的使用 小记

由于ThreadLocalMap 的生命周期跟 Thread 一样长,对于重复利用的线程来说,如果没有手动删除(remove()方法)对应 key 就会导致entry(null,value)的对象越来越多,从而导致内存泄漏.。当线程使用threadlocal 时,是将threadlocal当做当前线程thread的属性ThreadLocalMap 中的一个Entry的key值,实际上存放的变量是,Entry的value值,我们实际要使用的值是value值。T get(): 得到这个线程对应的 value。

2023-10-25 20:15:22 36 1

原创 CAS——Compare And Swap

CAS乐观锁机制的实现需要保证操作的原子性和可见性,同时要避免ABA问题的出现,因为CAS无法判断旧期望值A和内存V取值是同一个版本(无法确保内存数值未更改过还是已经进行更改又有操作将其变回了同样数值)悲观锁的实现方式就是Java中的synchronized等独占锁,乐观锁的实现方式是添加版本号字段或CAS算法等。乐观锁认为每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断—下是否被更新。如果相等则将变量的值更新为新值B。CAS是一种乐观锁,相对的那就要提到悲观锁。

2023-10-24 20:10:55 29

原创 搭建nexus私服部署项目

由于maven配置文件中已经设置好私服的连接地址,所以可以通过导入依赖直接导入仓库里的分装类。将两个仓库添加到配置文件中,同时mirror地址处也要添加,url为nexus的maven-public。1.先创建添加release和snapshot版本库,并添加到public仓库中。2.修改maven的setting.xml配置文件。3.在项目的pom文件中部署maven。4.新开发项目时要调用私服方法。点击deploy即部署完毕。还要配置profile。

2023-10-23 20:12:32 19

原创 RBAC-基于角色权限的模型 小记

RBAC认为权限授权的过程可以抽象地概括为:Who是否可以对What进行How的访问操作,并对这个逻辑表达式进行判断是否为True的求解过程,也即是将权限问题转换为Who、What、How的问题,Who、What、How构成了访问权限三元组。RBAC模型,role-based access control,基于角色的访问控制。通过角色的权限管理,简化了用户权限管理的复杂性,减少了管理工作的负担。一个用户有一个或多个角色。一个角色包含多个用户。一个权限属于多个角色。将用户对应到角色,通过角色来确定权限。

2023-10-21 18:01:47 51 1

原创 redis的五种常用类小记

zset集合和set集合非常相似,但不同在于zset是有序的,其每个元素都会通过关联一个 double 类型的分数来进行成员之间从小到大的排序。但由于是基于set所以添加,删除,查找的复杂度都是 O(1)。list是简单的字符串列表,按照插入顺序排序,其底层是一个双向链表结构,可以从列表头部或者尾部插入/取出数据(即左边(lpush)或右边(rpush))。当锁未释放时,setnx命令总不成功,当进程操作完或规定时间结束后释放block键值,之后再进行setnx命令能成功,从而实现锁的效果。

2023-10-19 20:07:48 42 1

原创 spring缓存注解Cache

Cacheable(value/cacheName=”name1”),这个注释的意思是,当调用这个方法的时候,会从一个名叫 name1的缓存中查询。如果没有,则执行实际的方法(即查询数据库),并将执行的结果存入缓存中,否则返回缓存中的对象。缓存的作用是提高系统的性能和响应速度,减少网络流量和数据库的负载。@CachePut这个注释可以确保方法被执行,同时方法的返回值也被记录到缓存中,实现缓存与数据库的同步更新。@CacheEvict 注释来标记要清空缓存的方法,当这个方法被调用后,即会清空缓存。

2023-10-18 20:10:01 31 1

原创 springmvc的工作流程

既然是 Web 框 架,那么当用户在浏览器中输入了 url 之后,我们的 Spring MVC 项目就可以感知到用户的请求。3.处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。9.DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。Controller(控制器)是应用程序中处理用户交互的部分。View(视图)是应用程序中处理数据显示的部分。

2023-10-17 20:34:02 24

原创 mysql数据库引擎-InnoDB,MyISAM

InnoDB引擎是MySQL默认的事务性存储引擎,也是最常用的引擎之一。提供行级锁定,可以处理高并发情况下的多个并行操作,支持外键约束和崩溃回滚能力,对于读写操作的性能表现较好,特别是对于大量并发的写操作。不支持事务,不能提供数据的完整性和一致性,也不支持外键约束和崩溃回滚能力,无法处理高并发情况下的多个并行操作。Archive引擎(只支持INSERT和SELECT操作),Blackhole引擎,CSV引擎(不支持索引),Memory引擎,Federated引擎等。

2023-10-16 20:34:11 19 1

原创 搭建企业maven私服小记

u nexus用户名 -p nexus密码 -r 仓库地址。再次配置maven的setting文件(忽略图片不一致问题)nexus-3.40.1 : 服务器文件夹,启动程序等。sonatype-work: 工作空间,数据文件。将nexus的压缩包上传到linux并解压安装。创建完成后添加到maven-public群组中。完成后就实现了私有仓库的上传到部署整个流程。配置maven默认使用的jdk环境。配置更便于连接的中央仓库的镜像仓库。导入本体仓库到nexus私有仓库。在idea中完成设置。

2023-10-12 20:18:06 30

原创 swagger小记

接口测试工具:swagger2(knife4j)/postman。配置完application文件后设置端口为9091。压力测试工具:JMetter。

2023-10-11 19:34:40 18

原创 springboot整合Dockerfile

通过已经建立的maven项目种的package来打包springboot项目。之后在springboot项目下创建dockerfile文件并加入配置。并引入之前打包的test1-0.0.1-SNAPSHOT.jar文件。同时要配置JAVA_HOME, PATH, CLASS_PATH。在/etc/profile文件下编辑添加。然后在linux上运行打包的jar文件。故需要先在linux上安装JDK。然后重新加载系统环境变量文件。然后创建容器并绑定端口即完成。安装完成后可以看到版本号。

2023-10-10 20:20:44 32 2

原创 docker搭建mysql主从数据库小结

创建完主从服务器后,在master容器创建用户用于主从关联。为了不让从(slave)服务器使用root用户登录写数据。然后在slave容器连接mysql从而实现主从关系。docker cp 容器名称:文件地址 目标地址。启动slave能看到YES则表示建立成功。先创建文件夹并拷贝my.cnf文件。然后也要修改配置文件my.cnf。用户名为sd 密码为123的用户。创建一个用户做从处理(只能读)如果连接不上则需要开启防火墙。测试成功说明搭建完成。

2023-10-09 19:39:18 25 1

原创 docker学习笔记

docker设计目的是提供一个简单的应用程序打包工具,就是从远程仓库中将已有的镜像拉取复制到自己的docker环境中,然后通过镜像启动容器来运行自己想要的软件和服务。docker images镜像是docker中最基础的部分,通过远程镜像仓库docker registry等下载获得镜像并在docker内安装。创建/运行docker容器:docker run -it --name xxx(自定义容器名称) -e xxxxx -d 镜像名称。删除镜像:docker rm/rmi 镜像id(rmi强制删除)

2023-10-08 20:35:55 19 1

原创 制作管理系统碎碎记

考虑到这个因素,建立两张表,一张表用于存放用户的登录账号密码员工等级,另一个表存放员工姓名等各种具体信息。除此之外,关于员工主管关系之间的设计,一开始的想法是将关系直接放入员工信息表中,但是考虑到在系统操作过程中,查询员工和上级的关系的频率肯定会比查询员工信息的频率多很多,但每次查询都要去查看员工信息表的话肯定会变得很慢,因此我选择单独建立一个关系表,用来记录员工和上级的关系,以存放id的方式记录,这样每次查看员工和上级关系的时候先通过查看表就可以直接获得员工自己上级主管是谁,或者主管自己下属员工有哪些。

2023-08-12 13:44:23 33 1

原创 索引的一些理解

通过设置索引能提高数据库检索数据的效率,但代价是需要构建索引列表来对数据进行排序,因此索引的设置也会占用一部分的空间,同时在更新数据进行增删改查操作时也需要对相应的索引文件进行维护。MySql的聚簇索引就是根据每张表通过定义一个自增的ID列为主键,来构造一个新的B+树,而且是对经典的B+树进行优化,叶子节点保存一行完整的数据,叶子节点之间以双向链表的形式存储。每个节点最多有两个子节点的树,同时在二叉树的基础上多定义一条:对所有节点其左子树所有的节点必须小于根节点,右子树所有的节点必须大于根节点。

2023-07-28 18:01:08 143 1

原创 树、map的理解

因此,相比数组查找的时间O(n),map查找的时间O(1)无疑是更快的。举例来说,如果设置的散列函数为V=K%7,因此如果K值依次为1,8,15,则获得的V值相同则会储存至同一块地方,为了避免同义词冲突,将会以数组或链表的结构存放。Map是一个接口类,该类没有继承自Collection,该类中存储的是结构的键值对,并且K一定是唯一的,不能重复。因此,若想使得map查询速度恢复,可以使用的方法为重新确立更优良合理的散列函数,或者在重复区域以树的结构存储等。

2023-07-05 10:38:26 47

原创 归并排序的理解

第二步进行两两归并,从递归最底下的两个单元素归并到递归最外面的最后两段有序表归并。在归并时建立一个临时数组用于存储归并排序完的数组,在整个数组归并完毕后赋值回原数组从而实现排序的目的。归并排序与其他基于交换、选择等排序的思想不一样,“归并”的思想是将两个或两个以上的有序表组合成一个新的有序表。假定待排序表含有n个记录,则可将其视为n个有序的子表,每个子表的长度为1,然后两两归并,得到。如此重复,直到合并成一个长度为n的有序表为止,这种两两归并的排序方法称为2路归并排序。趟归并,所以算法的时间复杂度为。

2023-07-04 11:23:50 31

空空如也

空空如也

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

TA关注的人

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