![](https://img-blog.csdnimg.cn/20190918140145169.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
Java基础篇
Java基础篇
L.2626
仅记录我的学习,注明出处按需转载
展开
-
Deque常用方法详细
【代码】Deque常用方法详细。原创 2024-08-20 16:44:13 · 477 阅读 · 0 评论 -
Mysql索引的基本原理
MySQL数据库使用多种类型的索引来优化查询性能,其中最常用的索引类型是B-Tree索引。原创 2024-07-05 14:13:08 · 270 阅读 · 0 评论 -
Mybatis#{}和${}的区别是什么?
在MyBatis中,#{}和${}#{}原创 2024-07-05 14:06:36 · 312 阅读 · 0 评论 -
Spring Boot中配置⽂件的加载顺序是怎样的?
Spring Boot 配置文件的加载顺序会影响配置属性的覆盖,因为可能会在多个地方定义相同的属性。Spring Boot 会按照特定的顺序加载配置文件,以便正确地合并属性值。的支持,这可能会影响配置文件的加载顺序。此外,Spring Cloud Config 和其他外部配置源可能会进一步影响配置属性的加载和覆盖。配置文件的加载顺序允许你在一个地方定义默认值,然后在其他地方(如环境变量或命令行参数)覆盖这些值。需要注意的是,Spring Boot 2.4 版本引入了新的配置文件加载机制,包括对。原创 2024-07-04 14:11:09 · 339 阅读 · 0 评论 -
Spring Boot是如何启动Tomcat的?
Spring Boot 内置了 Tomcat,使得你可以非常容易地创建和运行独立的 Spring 应用程序。Spring Boot 通过自动配置和启动嵌入式的 Tomcat 来简化 Web 应用程序的部署。原创 2024-07-04 14:07:33 · 329 阅读 · 0 评论 -
Spring Boot中常⽤的十二个注解及其底层实现,你知道几个?
Spring Boot 是一个用于快速开发、运行和管理 Spring 应用程序的框架。它简化了基于 Spring 的应用程序的配置和部署。这些注解大大简化了 Spring 应用的配置和开发过程,使得开发者能够更加专注于业务逻辑的实现。原创 2024-07-04 13:28:18 · 498 阅读 · 0 评论 -
如何理解 Spring Boot 中的 Starter
在Spring Boot中,"Starter"是一个重要的概念,它代表了一系列的依赖项管理,这些依赖项被组合在一起,以便于开发者能够快速地启动一个特定的项目或者使用一个特定的功能。依赖管理:自动配置:命名约定:模块化:自定义Starter:例如,如果你想开发一个Web应用,你可以添加到你的项目中。这个Starter会包含所有构建一个Spring Web应用所需的依赖,如Spring MVC和内嵌的Tomcat服务器。这样,你就可以快速地启动一个Web项目,而无需手动添加和管理多个依赖项。总之,Starter原创 2024-07-02 14:05:01 · 457 阅读 · 1 评论 -
Spring Boot ⾃动配置原理?
Spring Boot的自动配置是其核心特性之一,它能够极大地简化Spring应用程序的配置。自动配置的主要原理是利用Spring的条件化配置和Bean的条件注册,以及一系列的“启动器(Starters)”来实现的。启动器(Starters):条件化注解(@Conditional):自动配置类(@EnableAutoConfiguration):配置属性(application.properties/yml):Bean的定义和条件装配:配置属性类(@ConfigurationProperties):通过这种原创 2024-07-02 13:27:20 · 275 阅读 · 0 评论 -
Set和HashSet的区别
都是Java集合框架(Java Collections Framework)中的一部分,它们都用来存储无序且不重复的元素。接口提供了更广泛的操作集合的方法,不同的实现会有不同的性能和特性。在使用时,应根据实际需要选择合适的实现。接口的一个具体实现,它以哈希表的形式存储元素,提供了快速的访问和操作方法,但不保证元素的顺序。原创 2024-07-01 10:08:52 · 319 阅读 · 0 评论 -
Mybatis的优缺点
基于 SQL 语句编程,相当灵活,不会对应⽤程序或者数据库的现有设计造成任何影响,SQL 写在XML ⾥,解除 sql 与程序代码的耦合,便于统⼀管理;很好的与各种数据库兼容( 因为 MyBatis 使⽤ JDBC 来连接数据库,所以只要JDBC ⽀持的数据库 MyBatis 都⽀持)。SQL 语句的编写⼯作量较⼤, 尤其当字段多、关联表多时, 对开发⼈员编写SQL 语句的功底有⼀定要求。与 JDBC 相⽐,减少了 50%以上的代码量,消除了 JDBC ⼤量冗余的代码,不需要⼿动开关连。原创 2024-06-30 15:23:57 · 89 阅读 · 0 评论 -
Spring MVC的主要组件
作为前端控制器,负责接收所有的HTTP请求,并负责将请求分发给相应的处理器。:将请求体或响应体转换为Java对象或从Java对象转换为请求体或响应体。:包含模型数据和视图信息,用于从Controller传递数据到视图。:将HTTP请求映射到Controller的具体处理方法。:处理用户的请求,调用业务逻辑,并返回模型数据和视图。:解析用户的主题偏好,如不同的样式或布局。:解析视图,将模型数据渲染到视图模板中。:自动将请求参数绑定到Java对象上。:处理应用程序中的异常。原创 2024-06-29 13:38:15 · 352 阅读 · 0 评论 -
Spring MVC ⼯作流程
在整个流程中,Spring MVC还提供了许多其他的功能,如异常处理、数据验证、国际化、文件上传等。此外,Spring MVC的高度可配置性和灵活性使得开发者可以根据具体需求自定义各个组件的行为。Spring MVC(Model-View-Controller)是Spring框架中用于开发Web应用的核心模块。原创 2024-06-27 14:05:40 · 299 阅读 · 0 评论 -
Spring Boot、Spring MVC 和 Spring 有什么区别
Spring Boot: Spring Boot 是一个基于 Spring 的应用程序开发框架,它旨在简化 Spring 应用的创建和部署过程。Spring MVC: Spring MVC 是 Spring 框架中用于Web应用开发的一个模块,它是一个全功能的MVC(模型-视图-控制器)框架。Spring Boot、Spring MVC 和 Spring 这三个框架之间有密切的关系,它们都是 Spring 生态圈的一部分,但是它们各自有不同的定位和功能。原创 2024-06-27 13:24:29 · 414 阅读 · 0 评论 -
Spring⽤到了哪些设计模式
6. 模板模式:Spring中的JdbcTemplate、RestTemplate等模板类使用了模板模式,定义了一组固定的算法流程,子类可以对其中的某些步骤进行定制化。7. 策略模式:Spring中的BeanPostProcessor和BeanFactoryPostProcessor接口使用了策略模式,通过不同的策略进行相应的处理。8. 适配器模式:Spring中的适配器模式常用于兼容不同接口的实现方式,如Spring MVC中的HandlerAdapter适配不同类型的Controller。原创 2024-06-25 13:43:17 · 211 阅读 · 0 评论 -
Spring容器启动流程是怎样的
3. 注册BeanDefinition:将实例化的BeanDefinition注册到容器中,形成BeanDefinitionRegistry,同时对BeanDefinition进行相应的处理,如初始化、依赖注入等。7. 发布容器事件:在容器启动过程中会触发各种事件,如容器启动事件、Bean初始化事件等,Spring容器会发布这些事件,可以注册监听器对事件进行处理。4. 实例化Bean:根据BeanDefinition中的信息,Spring容器开始实例化各个Bean,并为它们注入依赖项。原创 2024-06-25 13:40:18 · 308 阅读 · 0 评论 -
ApplicationContext和BeanFactory有什么区别
**ApplicationContext**:ApplicationContext是BeanFactory的扩展,提供了更多的功能。- **BeanFactory**:BeanFactory是Spring IoC容器的基本实现,提供了最基本的IoC功能,如Bean的创建、管理、依赖注入等。- **ApplicationContext**:ApplicationContext在启动时会预先实例化所有的Bean,即在容器启动时就会加载所有的Bean对象。它们之间的主要区别在于功能和性能。原创 2024-06-24 13:31:55 · 130 阅读 · 0 评论 -
Spring中Bean是线程安全的吗
但是,如果一个Bean是有状态的,即包含可变数据(如实例变量),那么多个线程同时访问该Bean的状态可能会引发线程安全问题。2. **使用原型Bean**:对于有状态的Bean,可以将其配置为原型(prototype),即每次获取Bean时都会创建一个新的实例,从而避免多个线程共享同一个实例。1. **使用单例Bean**:如果Bean的状态对整个应用是共享的,并且需要被多个并发线程访问,可以将该Bean配置为单例并保证Bean本身是线程安全的。原创 2024-06-24 13:28:13 · 232 阅读 · 0 评论 -
Spring中的Bean创建的⽣命周期有哪些步骤
3. **BeanPostProcessor前置处理(BeanPostProcessor pre-processing)**:在Bean对象实例化完成后,容器会调用BeanPostProcessor接口的postProcessBeforeInitialization方法进行一些操作,如对Bean进行定制化的配置。2. **设置属性(Population)**:容器将Bean的属性值或引用注入到Bean中,包括通过构造函数注入、setter方法注入或自动装配。原创 2024-06-24 13:26:17 · 178 阅读 · 0 评论 -
什么是bean的⾃动装配,有哪些⽅式?
1. **根据类型自动装配(byType)**:Spring会自动将bean定义的属性与容器中同类型的bean进行匹配,如果只有一个匹配的依赖,就将其注入;2. **根据名称自动装配(byName)**:Spring会根据属性名称与容器中同名的bean进行匹配,如果有匹配的依赖就注入;3. **构造函数自动装配**:当一个bean的构造函数参数与其他bean的定义匹配时,Spring会自动将这些匹配的bean注入到构造函数中。通过合理选择自动装配的方式,可以简化bean之间的依赖注入,提高开发效率。原创 2024-06-24 13:13:27 · 126 阅读 · 0 评论 -
spring事务的实现过程
5. 并且修改数据库连接的autocommit属性为false,禁⽌此连接的⾃动提交,这是实现Spring事务⾮。11. Spring事务的传播机制是基于数据库连接来做的,⼀个数据库连接⼀个事务,如果传播机制配置为。10. Spring事务的传播机制是Spring事务⾃⼰实现的,也是Spring事务中最复杂的。需要新开⼀个事务,那么实际上就是先建⽴⼀个数据库连接,在此新数据库连接上执⾏sql。8. 如果出现了异常,并且这个异常是需要回滚的就会回滚事务,否则仍然提交事务。原创 2024-06-21 22:48:14 · 168 阅读 · 0 评论 -
spring中的事物是如何实现的
在编程式事务管理中,开发人员通过编写事务管理代码来控制事务的开始、提交、回滚等操作。在Spring中,可以使用`TransactionTemplate`或`PlatformTransactionManager`来实现编程式事务管理。在声明式事务管理中,开发人员通过注解或XML配置来定义事务规则,Spring框架会根据这些规则自动管理事务的开始、提交、回滚等操作。总的来说,Spring的事务管理实现提供了灵活、易用的方式来管理应用中的事务,提高了开发人员的开发效率和代码质量。原创 2024-06-21 22:45:24 · 231 阅读 · 0 评论 -
Spring事务什么时候会失效?
1. 方法未被@Transactional注解标记:在Spring中,只有被@Transactional注解标记的方法才会被事务管理器所管理,如果一个方法没有被@Transactional注解标记,那么其中的数据库操作将不会受到事务管理的影响,事务也将失效。2. 异常未被捕获并处理:如果在一个被@Transactional注解标记的方法中抛出了未被捕获的异常,并且异常被上层代码捕获并处理(而不是在方法中进行处理),那么事务就会因为异常未被传播至事务管理器而失效。原创 2024-06-20 14:10:20 · 441 阅读 · 0 评论 -
Spring事务传播机制
Spring事务传播机制是指在多个事务方法相互调用或嵌套调用的情况下,如何管理这些事务的行为。Spring提供了七种事务传播级别,通过设置不同的传播级别可以控制事务方法之间的关系,以确保事务的一致性和隔离性。需要注意的是,在设置事务传播级别时,要根据具体业务需求和数据库支持选择适合的传播级别,以确保事务的正确性和性能。5. NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,则挂起该事务。2. SUPPORTS:支持当前事务,如果当前没有事务,则以非事务方式执行。原创 2024-06-20 13:51:22 · 416 阅读 · 0 评论 -
Spring事务的实现⽅式和原理以及隔离级别?
在⼀个⽅法上加了@Transactional注解后,Spring会基于这个类⽣成⼀个代理对象,会将这个代理对象作为bean,当在使⽤这个代理对象的⽅法时,如果这个⽅法上存在@Transactional注解,那么代理逻辑会先把事务的⾃动提交设置为false,然后再去执⾏原本的业务逻辑⽅法,如果执⾏业务逻辑⽅法没有出现异常,那么代理逻辑中就会将事务进⾏提交,如果执⾏业务逻辑⽅法出现了异常,那么则会将事务进⾏回滚。通过设置@Transactional注解或配置文件中的隔禅级别属性,可以实现对事务的隔离级别控制。原创 2024-06-19 13:54:32 · 173 阅读 · 0 评论 -
对Spring框架的IOC的理解
全部对象的控制权全部上缴给“第三⽅”IOC容器,所以,IOC容器成了整个系统的关键核⼼,它起到了⼀种类似“粘合剂”的作⽤,把系统中的所有对象粘合在⼀起发挥作⽤,如果没有这个“粘合剂”,对象与对象之间会彼此失去联系,这就是有⼈把IOC容器⽐喻成“粘合剂”的由来。引⼊IOC容器之后,对象A与对象B之间失去了直接联系,当对象A运⾏到需要对象B的时候,IOC容器会主动创建⼀个对象B注⼊到对象A需要的地⽅。ioc容器:实际上就是个map(key,value),⾥⾯存的是各种对象(在xml⾥配置的bean节点、原创 2024-06-19 13:32:28 · 265 阅读 · 0 评论 -
解释下Spring⽀持的⼏种bean的作⽤域
单例作用域适合那些全局使用且状态无关的Bean,而原型作用域适合那些需要频繁创建和销毁的Bean,而请求和会话作用域适合Web应用中需要根据请求和会话创建和销毁Bean的情况。默认情况下,Spring中的Bean都是单例的,可以通过配置来实现。4. 会话(session)作用域:会话作用域也是在Web应用中有效的,会在每个HTTP会话中创建一个新的Bean实例。5. 全局会话(global session)作用域:全局会话作用域只在portlet环境中有效,它在整个应用的全局会话中共享一个Bean实例。原创 2024-06-19 13:40:58 · 182 阅读 · 0 评论 -
AOP基础
3. **通知(Advice)**:通知是切面在连接点执行的具体操作,包括前置通知(在连接点前执行)、后置通知(连接点正常执行后执行)、环绕通知(在连接点前后执行)、异常通知(连接点抛出异常时执行)等。1. **切面(Aspect)**:切面是一个模块化的横切关注点,它定义了在何处执行哪些特定的行为。通过切点可以精确地定义在哪些连接点应用特定的通知。2. **连接点(Join Point)**:连接点是在应用程序执行过程中的某个特定点,比如方法执行前、方法执行后、方法抛出异常等。原创 2024-06-18 13:30:02 · 287 阅读 · 1 评论 -
Spring是什么?
2. **面向切面编程(AOP)**:Spring框架提供了AOP功能,允许将横切关注点(如事务管理、日志记录等)从业务逻辑中分离出来,提高了代码的复用性和模块化。4. **MVC框架**:Spring框架提供了一个可扩展的MVC框架,用于构建Web应用程序,并且可以与其他框架(如Hibernate、MyBatis等)集成。1. **依赖注入(DI)**:Spring框架通过依赖注入实现了对象之间的松耦合,减少了组件之间的依赖关系,使得代码更加灵活、可维护。原创 2024-06-18 13:26:39 · 137 阅读 · 0 评论 -
谈谈你对AQS的理解,AQS如何实现可重⼊锁?
当state为0时表示没有线程持有锁,当state大于0时表示有一个线程持有锁,当state小于0时表示有多个线程正在竞争锁。AQS实现可重入锁的方式主要通过内置的同步队列(CLH队列)来实现。当一个线程持有锁时,可以多次调用lock()方法来获取锁,AQS会根据当前线程是否为锁的持有者来实现多次获取锁的判断。同时,AQS也会在锁的释放上做出对应的处理,确保线程释放锁的顺序正确。总的来说,AQS实现可重入锁的关键在于对线程的持有状态进行判断和处理,同时参考内置的同步队列来实现线程的排队和等待。原创 2024-06-18 13:19:07 · 171 阅读 · 1 评论 -
Sychronized和ReentrantLock的对比
根据具体的需求和场景选择合适的线程同步机制。Synchronized和ReentrantLock都是Java中用于实现线程同步的机制,它们都可以确保多个线程之间的互斥访问临界资源。sychronized锁的是对象,锁信息保存在对象头中,ReentrantLock通过代码中int类型的state标识来标识锁的状态。3. sychronized的底层是JVM层⾯的锁,ReentrantLock是API层⾯的锁。4. sychronized是⾮公平锁,ReentrantLock可以选择公平锁或⾮公平锁。原创 2024-06-18 13:16:02 · 212 阅读 · 0 评论 -
CountDownLatch和Semaphore的区别和底层原理
Semaphore底层也是基于AQS实现,Semaphore维护着一个许可数量,当线程获取许可时,会尝试获取许可,如果许可数量不足则会进入等待队列。- Semaphore有一个指定的许可数量,当线程请求许可时,会分配一个许可,当许可数量为0时,其他线程需要等待。- CountDownLatch是一次性的,一旦计数值减为0,就不能重新设置计数值,它是一种单向的等待机制。- Semaphore是可以重复使用的,线程获取到许可可以继续使用,使用完毕后可以释放许可。原创 2024-06-17 15:26:25 · 174 阅读 · 0 评论 -
ReentrantLock中tryLock()和lock()⽅法的区别
总的来说,tryLock()方法是一种非阻塞的尝试获取锁的方法,可以根据返回结果进行处理;而lock()方法是一种阻塞获取锁的方法,会一直等待直到获取到锁。如果锁是可用的,tryLock()方法会立即获取锁并返回true;- 如果使用lock()方法时锁不能被获取,线程将会阻塞在获取锁的位置,直到锁可用或者如果线程被中断则抛出InterruptedException。- tryLock()方法可以设置超时时间,即在尝试获取锁时可以指定等待的时间,如果在指定时间内无法获取锁,则返回false。原创 2024-06-17 15:19:42 · 269 阅读 · 0 评论 -
Sychronized的偏向锁、轻量级锁、重量级锁
偏向锁假设锁通常不会有竞争,因此会在第一次使用的时候,将对象头的标志位设置为偏向,然后将持有线程的ID复制到对象头中,以后如果有其它线程要获取锁,会先检查对象头的线程ID和当前线程ID是否一致。偏向锁的撤销发生在其他线程尝试获取偏向锁的时候,且会将锁升级为轻量级锁。当一个锁升级为重量级锁时,表示锁已经有多个线程来竞争,于是它会将持有锁的线程挂起,并将锁的对象维护在一个等待队列中。当其它线程想要获取锁时,会进入阻塞状态,被放到等待队列中,直到持有锁的线程释放锁,后续线程才会被唤醒竞争锁。原创 2024-06-16 09:00:00 · 408 阅读 · 0 评论 -
Sychronized和ReentrantLock的区别
ReentrantLock提供了更多的功能,性能更佳,支持更丰富的加锁特性,支持可中断操作,但使用上较为复杂。但在性能上,Synchronized的开销比较大,因为每次使用它进行同步时,都会涉及到大量的线程上下文切换和内核态和用户态之间的切换。- ReentrantLock提供了更多的功能,如支持公平锁和非公平锁、尝试获取锁的定时功能、可中断的获取锁等。- ReentrantLock支持中断操作,可以让一个线程尝试去获取锁,在获取锁的过程中,如果判断不合适,可以中断该操作。这种中断能力提高了程序的健壮性。原创 2024-06-16 09:00:00 · 278 阅读 · 0 评论 -
线程池中线程复⽤原理
4. 如果线程池的总线程数已经达到最大线程数,线程池会根据拒绝策略(RejectedExecutionHandler)来处理无法执行的任务,例如抛出异常、丢弃任务等。3. 如果任务队列已满,但线程池的总线程数没有达到最大线程数(maximumPoolSize),线程池会创建新的线程来执行任务。2. 如果核心线程池中的线程都在执行任务,并且任务队列没有达到最大容量,线程池会将任务放入任务队列中等待执行。线程池将线程和任务进⾏解耦,线程是线程,任务是任务,摆脱了之前通过 Thread 创建线程时的。原创 2024-06-15 08:30:00 · 151 阅读 · 0 评论 -
为什么是先添加列队⽽不是先创建最⼤线程?
当有任务提交到线程池时,线程池会先尝试将任务添加到阻塞队列中,如果队列已满,则会考虑创建新的线程来执行任务。通过先将任务添加到队列中,可以先尽可能地利用现有的线程来处理任务,避免无谓地创建新的线程。3. 避免线程爆炸:如果一开始就创建大量的线程,可能会导致线程数量过多,处理不过来,接着就会导致系统负载过重,甚至引发“线程爆炸”现象。综上所述,通过先添加任务到队列而不是立即创建最大线程数,可以更有效地利用系统资源,控制线程数量,避免系统负载过重,从而提高系统的性能和稳定性。原创 2024-06-14 15:36:05 · 163 阅读 · 0 评论 -
线程池中阻塞队列的作⽤?
1. 缓冲任务:当线程池中的线程数量达到设定的最大线程数时,新提交的任务会被放入阻塞队列中等待执行,以避免线程数量过多导致系统资源的浪费和性能下降。2. 控制任务提交速率:阻塞队列的容量限制了可以提交的任务数量,通过控制队列的大小可以限制任务的提交速率,避免任务过多导致系统负载过重。总的来说,线程池中的阻塞队列起到了缓冲、调度和控制任务提交速率的作用,能够提高线程池的效率和性能,保证系统的稳定性和可靠性。阻塞队列可以保证任务队列中没有任务时阻塞获取任务的线程,使得线程进⼊wait状态,释放cpu资源。原创 2024-06-14 15:33:46 · 243 阅读 · 0 评论 -
线程池的底层⼯作原理
如果此时线程池中的线程数量⼤于等于corePoolSize,缓冲队列workQueue满,并且线程池中的数量⼩于maximumPoolSize,建新的线程来处理被添加的任务。这样,线程池可以动态的调整池中的线程数。4. 线程管理:线程池会根据实际情况动态调整线程的数量,包括创建新线程、销毁空闲线程和调整空闲线程存活时间等操作,以确保线程池的资源利用率和性能。如果此时线程池中的线程数量⼩于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。原创 2024-06-13 15:51:23 · 196 阅读 · 0 评论 -
为什么⽤线程池?解释下线程池参数?
线程池可以在系统启动时创建一定数量的线程,并将它们保存在池中,当有任务需要处理时,直接从线程池中获取空闲线程来执行任务,避免了频繁地创建和销毁线程,从而降低了系统开销,提高了系统的响应速度和性能。2. 最大线程数(maximumPoolSize):线程池中最大允许的线程数量,当任务数量超过核心线程数且任务队列已满时,线程池会创建新的线程来执行任务,直到达到最大线程数限制。1. 核心线程数(corePoolSize):线程池中始终保留的线程数量,即使这些线程处于空闲状态。在没有任务时,核心线程也不会被销毁。原创 2024-06-13 15:46:28 · 265 阅读 · 0 评论 -
如何理解volatile关键字
假设有一个共享的boolean变量flag,在一个线程中修改了flag的值,而另外一个线程需要不断地读取flag的值来执行相应的逻辑。2. 有序性:volatile变量修饰的变量的读写操作是有序的,即在写入volatile变量之前的操作都会被执行,而在读取volatile变量之后的操作会被延迟执行,确保了访问顺序的一致性。总之,volatile关键字主要用于保证变量的可见性和有序性,适用于只有一个线程在写入变量,而多个线程在读取变量的场景。如何理解volatile关键字。原创 2024-06-07 13:29:57 · 351 阅读 · 0 评论