java核心面试题解析(持续更新)

目录

1.索引

1.1创建索引:

1.2索引优化

基本概念

Index Nested-Loop Join的工作原理

优点和考虑因素

实际应用

2.spring

2.1 spring容器初始化

2.1.1 Spring容器 有哪些

2.2#{ }和${ }区别

2.3 AOP通知

2.4 AOP术语

2.5 IOC

2.5.1什么是IOC

2.5.2 ioc过程

2.5.3 IOC接口(重点)

2.5.4 IoC 的工作原理

2.5.5 IoC 容器的两种实现

2.5.5.1BeanFactory

2.5.5.2 ApplicationContext

2.6 依赖注入(DI)

2.7 Bean容器的生命周期

2.8 springMVC工作流程

3.多线程

3.1并发、并行和多线程

3.1.1mysql并发和java多线程并发有什么区别和联系?

3.2死锁

死锁发生的四个必要条件:

如何避免死锁:

死锁检测:

死锁解决:

示例:

3.3 sleep 与wait的区别?

3.4线程的同步

3.5守护线程

3.6 join方 法

3.7中断线程

3.8 synchronized 关键字的底层原理是什么?

3.8.1 synchronized基本使用

3.9Java多线程的生命周期

3.9.1前言

3.9.2 线程五种状态

3.10 多线程同步机制和redis分布式锁有什么区别 该使用哪个?

4.集合

4.1 list集合接口

4.1.1 ArrayList:实现原理

4.1.2 LinkedList实现原理

4.3 Vector实现原理

4.4 Map集合接口实现类

4.4.1 HashMap的实现原理

4.4.2 LinkedHashMap 实现原理

4.4.3 TreeMap实现原理

4.4.4 HashMap和HashTable 区别

4.5 Set集合接口实现类

4.5.1 HashSet实现原理

4.5.2 LinkedHashSet实现原理

4.5.3 TreeSet实现原理

5.修饰符

5.1 static关键字

5.2 abstract关键字

5.3 什么是多态

5.4包与修饰符关系

5.5 final关键字

5.6 this关键字

6.包装类

6.1 String

6.2 StringBuffer

6.3 StringBuilder

7.java基础

7.1 clone克隆

7.2代码块

7.3修饰符的作用域

7.4位运算

8.springboot

8.1 @Configuration注解

8.2 @ConfigurationProperties注解

8.3 AutowireCapableBeanFactory

9.mysql

9.1多表查询概述:

9.2子查询

9.2.1标量子查询

9.2.2 表子查询

9.2.3列子查询

9.2.4 行子查询

9.3 mysql事务

9.3.1事务的传播行为

9.3.2事务的隔离性

9.3.3 MySQL事务的隔离性

9.3.4 事务的四大特性

9.4联合查询

9.4.1 union和union all的区别

10.Redis

10.1保证mysql数据一致性

11.网络协议

11.1 HTTP与TCP区别

12.微服务

12.1 RESTFul与RPC比较

13.编程题

13.1用java编写判断101-200之间有多少个素数,并输出所有素数

14.JVM

14.1java虚拟机与计算机内存是如何协同工作的

14.1.1 jvm内存分配结构

14.1.2 多核并发缓存架构

14.1.3 java内存模型

14.2 JVM的组成

14.2.11. JVM由那些部分组成,运行流程是什么?

14.3 垃圾回收算法解析

14.4  什么是oom ?什么是栈溢出?

1. OOM(Out Of Memory)

2. 栈溢出(Stack Overflow)

总结


1.索引

1.1创建索引:

create index  索引名称 on 某张表 (列名)

示例:

create index  index_name on table (Column names)

1.2索引优化

MySQL数据库索引优化是提高查询性能的重要手段。以下是一些关键的索引优化策略:

  1. 选择正确的索引列
    • 经常需要排序、分组和联合操作的字段,如使用ORDER BYGROUP BYDISTINCTUNION等操作的字段,应该建立索引。
    • 常作为查询条件的字段也应该建立索引,因为查询速度会受到影响。
  2. 限制索引数量
    • 每个索引都需要占用磁盘空间,并且当表的内容发生变化时,索引也需要更新,有时还需要重构。因此,过多的索引会导致更新表的时间增长,并且MySQL在生成执行计划时也要考虑更多的索引,这会增加额外的开销。
  3. 使用数据量少的索引
    • 如果索引的值很长,查询速度会受到影响。因此,尽量使用数据量少的索引。
  4. 考虑覆盖索引
    • 覆盖索引是指SQL查询只需要通过遍历索引树就可以返回所需数据,无需回表操作。这可以显著提高查询性能。
  5. 遵循最左前缀匹配
    • 联合索引命中必须遵循最左前缀法则。即SQL查询的WHERE条件字段必须从索引的最左前列开始匹配,不能跳过索引中的列。
  6. JOIN优化
    • 在进行联表操作时,考虑使用Index Nested-Loop Join优化。这种优化方式主要为了减少内层表数据的匹配次数,当用来进行JOIN的字段在被驱动表中建立了索引时,匹配次数会显著减少。
  7. 使用前缀索引
    • 对于较长的字符串字段,如果前缀已经足够区分数据,可以考虑使用前缀索引,以减少索引的大小和查询时间。
  8. 避免不必要的索引操作
    • 不对索引字段进行逻辑操作,尽量全值匹配,避免使用不等于操作,字符类型查询时务必加上引号,OR关键字左右尽量都为索引列等,这些都能提高索引的使用效率。
  9. 数据量小的表优化
    • 对于数据量小的表,索引可能不会产生优化效果,因为查询花费的时间可能比遍历索引的时间还要短。因此,在这些情况下,最好不要使用索引。
  10. 定期审查和优化索引
    • 随着数据库的使用和数据的变化,之前有效的索引可能不再是最优的。因此,定期审查和优化索引是很重要的。可以使用EXPLAIN命令来查看查询的执行计划,了解索引的使用情况,并根据需要进行调整。

注释:

ORDER BY、GROUP BY、DISTINCT和UNION这些操作在处理数据库查询时可能会导致大量的磁盘I/O操作和CPU计算,特别是当涉及到大量数据时。为这些操作的字段建立索引可以显著提高查询效率,原因如下:

1. **ORDER BY**: 当对一个字段执行ORDER BY操作以进行排序时,如果该字段上有索引,数据库系统可以直接利用索引来快速定位和排序数据,而无需全表扫描。这在数据量大时特别有效,能够减少排序操作所需的资源和时间。

2. **GROUP BY**: GROUP BY操作用于将数据分组,通常与聚合函数(如COUNT(), SUM(), AVG()等)一起使用。如果对分组字段建立了索引,数据库可以更快地找到并组织相关的记录,减少分组操作的复杂度和时间。没有索引的话,数据库可能需要扫描整个表来完成分组。

3. **DISTINCT**: 使用DISTINCT关键字从结果集中去除重复行时,数据库需要检查每一行的唯一性。如果对DISTINCT涉及的列建立了索引,数据库可以通过索引来直接定位和去重,避免了全表扫描和额外的比较操作。

4. **UNION**: UNION操作用于合并两个或多个SELECT语句的结果集,并自动去除重复行。虽然直接对UNION操作的字段建立索引可能不直接影响UNION本身(因为这是在结果合并后的行为),但对参与UNION的每个查询涉及的列建立索引,可以加快每个单独查询的速度,从而间接提升整体UNION操作的性能。

综上所述,为这些操作涉及到的字段创建索引,主要是为了减少查询过程中不必要的数据读取、排序和比较,从而提升查询效率。然而,需要注意的是,虽然索引带来了查询性能的提升,但它也会占用额外的存储空间,并可能略微减慢写入操作(如INSERT、UPDATE、DELETE)的速度,因为索引也需要维护。因此,在决定是否为特定字段创建索引时,需要权衡查询性能和存储及维护成本。

如果创建的索引字段值长度较大,这可能会影响到查询速度,尤其是在索引被用来加速查询操作(如上述ORDER BY, GROUP BY, DISTINCT, UNION等)时。具体来说,影响包括:

1. **索引存储空间增加**:较长的索引值会导致索引文件更大,占用更多的存储空间。这不仅消耗存储资源,还可能影响到索引的搜索效率,因为数据库在查找索引时可能需要处理更多的数据块。

2. **索引遍历速度下降**:在内存中,较长的索引项意味着更少的索引项可以同时加载,这可能导致数据库系统在查找匹配项时需要更多次的磁盘I/O操作,从而降低了查询效率。

3. **索引选择性降低**:索引的选择性是指索引区分数据行的能力,高选择性意味着索引能更有效地缩小查询范围。对于长文本字段,如果其内容变化不大或者有很多相似值,索引的选择性可能会较低,这样在执行查询时,即使使用了索引也可能需要检查大量记录,无法充分发挥索引的优势。

因此,建议在设计索引时,尽量考虑使用较短的、区分度高的字段作为索引,或者对长字段进行适当的处理后再创建索引,比如只索引字段的部分内容(前缀索引)、使用哈希值作为索引等策略,以达到平衡存储空间、提高查询速度的目的。当然,这些策略需根据实际的数据特性和查询需求来灵活选择。

覆盖索引(也称为索引覆盖)是计算机领域中的一个术语,它指的是在数据库查询中,select的数据列只需要从索引中就能够取得,而无需读取数据行。换句话说,查询列被所建的索引覆盖。这种索引优化方式可以显著提高查询性能,因为它减少了不必要的磁盘I/O操作、数据传输和CPU消耗。

覆盖索引的好处主要体现在以下几个方面:

  1. 减少磁盘I/O:当使用覆盖索引时,查询所需的数据可以直接从索引中获取,无需额外的磁盘I/O操作,从而减少对磁盘的访问,提高查询速度。
  2. 减少数据传输:使用覆盖索引时,只需要传输索引所包含的字段数据,而不需要传输整行数据,从而减少了数据传输的量,节省了网络带宽和传输时间。
  3. 减少CPU消耗:覆盖索引可以减少对数据页的访问和解析,降低CPU的消耗,这在大型查询和高并发环境中的数据库性能提升尤为重要。

为了充分利用覆盖索引的优势,需要注意以下几点:

  • 选择合适的列:确保索引包含了查询中用到的所有列,这样查询可以完全通过索引来满足,而无需回表查询。
  • 减少索引列的宽度:尽量使用数据类型小的列,或者通过散列(如MD5)等方法减小列数据的宽度,这有助于减少索引的存储空间和查询时的内存消耗。
  • 避免函数操作和计算表达式:在索引列上使用函数或运算可能导致索引失效,因此在设计查询和索引时要避免这种情况。
  • 维护和分析索引:定期对索引进行维护(如重建和重新组织)和分析(更新统计信息),以保持其性能。

总之,覆盖索引是一种有效的数据库优化手段,通过合理的设计和使用,可以显著提高查询性能并降低系统开销。然而,需要注意的是,并不是所有情况都适合使用覆盖索引,因此在实际应用中需要根据具体情况进行权衡和选择。

Index Nested-Loop Join(索引嵌套循环连接)是数据库查询优化中的一种策略,主要用于减少在连接操作中的数据匹配次数。这种优化方式在联接操作中特别有效,特别是当联接的字段在被驱动表(通常是内层循环的表)上建立了索引时。

以下是一些关于Index Nested-Loop Join的基本概念和如何工作的解释:

基本概念

  • 嵌套循环连接(Nested-Loop Join):一种基本的连接算法,其中外部循环遍历一个表(通常称为驱动表),而内部循环遍历另一个表(通常称为被驱动表或内层表)。对于驱动表中的每一行,都会在被驱动表中查找匹配的行。
  • 索引:一种数据结构,可以加快数据的检索速度。当对一个字段建立索引时,数据库系统可以使用该索引快速找到该字段的值,而不是扫描整个表。

Index Nested-Loop Join的工作原理

  1. 选择驱动表:数据库优化器会选择一个表作为驱动表,通常基于表的大小、索引的存在以及其他因素。
  2. 遍历驱动表:对于驱动表中的每一行,优化器会检查是否需要与内层表进行连接。
  3. 使用索引查找:如果连接条件中的字段在被驱动表上建立了索引,那么优化器将使用索引来查找匹配的行,而不是扫描整个表。这大大减少了需要检查的行数,从而提高了查询性能。
  4. 返回结果:一旦找到匹配的行,优化器就会将它们作为查询结果返回。

优点和考虑因素

  • 优点:当被驱动表上有合适的索引时,Index Nested-Loop Join可以显著提高查询性能。
  • 考虑因素
    • 索引的选择性:索引的选择性越高(即不同值的比例越高),使用索引进行查找的效率就越高。
    • 表的大小:通常,较小的表更适合作为驱动表,因为这样可以减少需要遍历的行数。
    • 缓存效果:如果驱动表的数据能够很好地适应数据库的缓存(如内存缓冲区),那么性能可能会进一步提高。
    • 维护成本:索引虽然可以提高查询性能,但也会增加插入、更新和删除操作的开销,因为索引结构需要维护。

实际应用

在实际应用中,数据库优化器通常会自动选择是否使用Index Nested-Loop Join,并确定哪个表应该作为驱动表。然而,数据库管理员和开发人员也可以通过查询执行计划、调整索引和查询语句等方式来影响优化器的决策,以实现更好的性能。

总之,Index Nested-Loop Join是一种有效的连接优化策略,特别适用于在被驱动表上建立了合适索引的情况。通过减少内层表数据的匹配次数,它可以显著提高查询性能。

2.spring

2.1 spring容器初始化

Spring容器的初始化过程包括以下主要步骤:

  1. 加载配置文件Spring容器会从XML文件、Java注解或者Java Config等方式加载配置信息。这些配置信息定义了应用中的bean、依赖关系、切面等内容。
  2. 创建容器实例:一旦配置文件被加载,Spring容器会实例化并初始化容器对象。这意味着容器开始了解应用的组件和它们之间的关系。
  3. 实例化Bean:容器根据配置信息实例化各个Bean对象,这可能涉及到构造函数的调用或者工厂方法的调用。
  4. Bean的初始化:如果Bean实现了InitializingBean接口或者定义了初始化方法,容器会在依赖注入完成后调用这些初始化方法,以进行一些额外的初始化工作。
  5. 注册Bean:容器将实例化并初始化的Bean注册到自己的内部数据结构中,以便后续的管理和使用。

在这个过程中,还会涉及到依赖注入的过程,即Spring容器会自动地将Bean之间的依赖关系注入到相应的属性中,以确保Bean能够正常工作。

需要注意的是,Spring容器的初始化过程是一个复杂的过程,涉及到多个组件和机制的协同工作。为了确保Spring容器的正确初始化,需要仔细配置和检查配置文件,并确保所有的Bean都正确地定义和依赖注入。

此外,Spring容器还提供了许多扩展点和配置选项,可以根据具体的应用需求进行定制和优化。例如,可以通过Java Config或者注解的方式更加灵活地配置Bean,也可以使用AOP(面向切面编程)等功能来增强应用的功能和性能。

总之,Spring容器的初始化是Spring框架的核心功能之一,它使得开发者能够更加方便地管理和组织应用中的组件和依赖关系,提高了应用的可维护性和可扩展性。

2.1.1 Spring容器 有哪些

Spring容器主要提供了两种类型的容器:BeanFactoryApplicationContext

  1. BeanFactory:是基础类型的IoC容器,提供完整的IoC服务支持。如果没有特殊指定,默认采用延迟初始化策略。只有当客户端对象需要访问容器中的某个受管对象的时候,才对该受管对象进行初始化以及依赖注入操作。对于资源有限,并且功能要求不是很严格的场景,BeanFactory是比较合适的IoC容器选择。
  2. ApplicationContext:它是在BeanFactory的基础上构建的,是相对比较高级的容器实现。除了拥有BeanFactory的所有支持,ApplicationContext还提供了其他高级特性,比如事件发布、国际化信息支持等。ApplicationContext所管理的对象,在该类型容器启动之后,默认全部初始化并绑定完成。

除了上述两种主要的容器类型,Spring容器还有一些其他的特性,例如支持父级容器和子容器的概念,以及提供了多种方式来获取和管理容器中的Bean,如静态工具类方式等。

总的来说,Spring容器是Spring框架的核心组成部分,通过它,我们可以实现依赖注入、管理Bean的生命周期等功能,从而简化应用的开发和维护。

2.2#{ }和${ }区别

(1)$(key)表示获取参数,先获取参数的值拼接到SQL语句中,再编译执行SQL,可能会引起SQL注入的问题

(2)#(key)表示获取参数,先完成SQL编译(预编译),预编译之后再将获取的参数设置到SQL语句中,可以避免SQL注入问题

2.3 AOP通知

增强的部分叫通知

2.4 AOP术语

AOP术语:

1、连接点

类里面哪些方法可以被增强,这些方法称为连接点

2、切入点

实际被真正增强的方法,称为切入点

3、通知(增强)

(1)实际增强的逻辑部分称为通知(增强)

(2)通知有多种类型

*前置通知

*后置通知

*环绕通知

*异常通知

*最终通知 finnlly

4、切面(是动作)

把通知应用到切入点过程

2.5 IOC

2.5.1什么是IOC

IoC 是 Inversion of Control 的简写,译为“控制反转”,它不是一门技术,而是一种设计思想,是一个重要的面向对象编程法则,能够指导我们如何设计出松耦合、更优良的程序。

Spring 通过 IoC 容器来管理所有 Java 对象的实例化和初始化,控制对象与对象之间的依赖关系。我们将由 IoC 容器管理的 Java 对象称为 Spring Bean,它与使用关键字 new 创建的 Java 对象没有任何区别。

在 Spring 应用中,Java 对象创建的控制权是掌握在 IoC 容器手里的,其大致步骤如下。

  1. 开发人员通过 XML 配置文件、注解、Java 配置类等方式,对 Java 对象进行定义,例如在 XML 配置文件中使用 <bean> 标签、在 Java 类上使用 @Component 注解等。
  2. Spring 启动时,IoC 容器会自动根据对象定义,将这些对象创建并管理起来。这些被 IoC 容器创建并管理的对象被称为 Spring Bean。
  3. 当我们想要使用某个 Bean 时,可以直接从 IoC 容器中获取(例如通过 ApplicationContext 的 getBean() 方法),而不需要手动通过代码(例如 new Obejct() 的方式)创建。

IoC 带来的最大改变不是代码层面的,而是从思想层面上发生了“主从换位”的改变。原本调用者是主动的一方,它想要使用什么资源就会主动出击,自己创建;但在 Spring 应用中,IoC 容器掌握着主动权,调用者则变成了被动的一方,被动的等待 IoC 容器创建它所需要的对象(Bean)。

这个过程在职责层面发生了控制权的反转,把原本调用者通过代码实现的对象的创建,反转给 IoC 容器来帮忙实现,因此我们将这个过程称为 Spring 的“控制反转”。

2.5.2 ioc过程

IOC过程
//第一步 xm1配置文件,配置创建的对象
<bean id="dao” class="com. At. UserDao"></bean>  进一步降低耦合度
//第二步 有service类和dao类 ,创建工厂类
class UserFactory {
public static UserDao getDao() {
String classValue = class属性值: //1 xml解析
Class clazz= Class.forName(classValue): //2 通过反射创建对象
return(UserDao)clazz. Newinstance() ;
 }
}

2.5.3 IOC接口(重点)

  1. IOC思基于 i0C容器完成,IOC容器底层就是对象工厂

2、Spring 提供IOC容器实现两种方式: (两个接口)

(1) BeanFactory: IOC容器基本实现,是Spring 内部的使用接口,不提供开发人员进行使用

*加载配置文件时候不会创建对象,在获取对象(使用)才去创建对象

(2)ApplicationContext: BeanFactory 接口的子接口,提供更多更强大的功能,一般由开发人

员进行使用,

*加载配置文件时候就会把在配置文件对象进行创建

2.5.4 IoC 的工作原理

我们在程序设计时,所秉承的思想一般都是在不影响系统功能的前提下,最大限度的降低耦合度。

IoC 底层通过工厂模式、Java 的反射机制XML 解析等技术,将代码的耦合度降低到最低限度,其主要步骤如下。

  1. 在配置文件(例如 Bean.xml)中,对各个对象以及它们之间的依赖关系进行配置;
  2. 我们可以把 IoC 容器当做一个工厂,这个工厂的产品就是 Spring Bean;
  3. 容器启动时会加载并解析这些配置文件,得到对象的基本信息以及它们之间的依赖关系;
  4. IoC 利用 Java 的反射机制,根据类名生成相应的对象(即 Spring Bean),并根据依赖关系将这个对象注入到依赖它的对象中。


由于对象的基本信息、对象之间的依赖关系都是在配置文件中定义的,并没有在代码中紧密耦合,因此即使对象发生改变,我们也只需要在配置文件中进行修改即可,而无须对 Java 代码进行修改,这就是 Spring IoC 实现解耦的原理

2.5.5 IoC 容器的两种实现

IoC 思想基于 IoC 容器实现的,IoC 容器底层其实就是一个 Bean 工厂。Spring 框架为我们提供了两种不同类型 IoC 容器,它们分别是 BeanFactory 和 ApplicationContext。

2.5.5.1BeanFactory

BeanFactory 是 IoC 容器的基本实现,也是 Spring 提供的最简单的 IoC 容器,它提供了 IoC 容器最基本的功能,由 org.springframework.beans.factory.BeanFactory 接口定义。

BeanFactory 采用懒加载(lazy-load)机制,容器在加载配置文件时并不会立刻创建 Java 对象,只有程序中获取(使用)这个对对象时才会创建。

示例 1

下面我们通过一个实例演示,来演示下 BeanFactory 的使用。

1. 在 HelloSpring 项目中,将 MainApp 的代码修改为使用 BeanFactory 获取 HelloWorld 的对象,具体代码如下。

public static void main(String[] args) {
    BeanFactory context = new ClassPathXmlApplicationContext("Beans.xml");
    HelloWorld obj = context.getBean("helloWorld", HelloWorld.class);
    obj.getMessage();
}


2. 运行 MainApp.java,控制台输出如下。

message : Hello World!

注意:BeanFactory 是 Spring 内部使用接口,通常情况下不提供给开发人员使用。 

2.5.5.2 ApplicationContext

ApplicationContext 是 BeanFactory 接口的子接口,是对 BeanFactory 的扩展。ApplicationContext 在 BeanFactory 的基础上增加了许多企业级的功能,例如 AOP(面向切面编程)、国际化、事务支持等。

ApplicationContext 接口有两个常用的实现类,具体如下表。

实现类

描述

示例代码

ClassPathXmlApplicationContext

加载类路径 ClassPath 下指定的 XML 配置文件,并完成 ApplicationContext 的实例化工作

ApplicationContext applicationContext = new ClassPathXmlApplicationContext(String configLocation);

FileSystemXmlApplicationContext

加载指定的文件系统路径中指定的 XML 配置文件,并完成 ApplicationContext 的实例化工作

ApplicationContext applicationContext = new FileSystemXmlApplicationContext(String configLocation);

在上表的示例代码中,参数 configLocation 用于指定 Spring 配置文件的名称和位置,如 Beans.xml。

示例 2

下面我们就通过一个实例,来演示 ApplicationContext 的使用。

1. 修改 HelloSpring 项目 MainApp 类中 main() 方法的代码,具体代码如下。

public static void main(String[] args) {
    //使用 FileSystemXmlApplicationContext 加载指定路径下的配置文件 Bean.xml
    BeanFactory context = new FileSystemXmlApplicationContext("D:\\eclipe workspace\\spring workspace\\HelloSpring\\src\\Beans.xml");
    HelloWorld obj = context.getBean("helloWorld", HelloWorld.class);
    obj.getMessage();
}


2. 运行 MainApp.java,控制台输出如下。

message : Hello World!

2.6 依赖注入(DI)

在了解了 IoC 之后,我们还需要了解另外一个非常重要的概念:依赖注入。

依赖注入(Denpendency Injection,简写为 DI)是 Martin Fowler 在 2004 年在对“控制反转”进行解释时提出的。Martin Fowler 认为“控制反转”一词很晦涩,无法让人很直接的理解“到底是哪里反转了”,因此他建议使用“依赖注入”来代替“控制反转”。

在面向对象中,对象和对象之间是存在一种叫做“依赖”的关系。简单来说,依赖关系就是在一个对象中需要用到另外一个对象,即对象中存在一个属性,该属性是另外一个类的对象。
 

例如,有一个名为 B 的 Java 类,它的代码如下。

  1. public class B {
  2.     String bid;
  3.     A a;
  4. }


从代码可以看出,B 中存在一个 A 类型的对象属性 a,此时我们就可以说 B 的对象依赖于对象 a。而依赖注入就是就是基于这种“依赖关系”而产生的。

我们知道,控制反转核心思想就是由 Spring 负责对象的创建。在对象创建过程中,Spring 会自动根据依赖关系,将它依赖的对象注入到当前对象中,这就是所谓的“依赖注入”。

依赖注入本质上是 Spring Bean 属性注入的一种,只不过这个属性是一个对象属性而已。

2.7 Bean容器的生命周期

IOC 操作 Bean 管理 (bean 生命周期)

1、生命周期

(1) 从对象创建到对象销毁的过程

2、bean 生命周期

(1) 通过构造器创建 bean 实例 (无参数构造)

(2)为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)

(3)调用 bean 的初始化的方法(需要进行配置初始化的方法)

(4)bean 可以使用了 (对象获取到了)

(5)当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)。

2.8 springMVC工作流程

Spring MVC的工作流程主要包括以下几个步骤:

  1. 用户向服务端发送一次请求,这个请求会先到前端控制器DispatcherServlet(也叫中央控制器)。DispatcherServlet是整个请求响应的控制中心,组件的调用由它统一调度。
  2. DispatcherServlet接收到请求后会调用HandlerMapping处理器映射器。处理器映射器会根据用户访问的URL映射到对应的后端处理器Handler(一般来讲是Controller)。这个映射过程可以根据XML配置或注解进行查找,并生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
  3. DispatcherServlet调用HandlerAdapter处理器适配器。处理器适配器会根据映射器找到的处理器Handler信息,按照特定的规则去执行相关的处理器Handler。
  4. Handler(Controller)执行完成返回ModelAndView。ModelAndView包含了模型数据和视图信息。
  5. HandlerAdapter将Controller执行结果ModelAndView返回给DispatcherServlet。
  6. DispatcherServlet将ModelAndView传给ViewResolver视图解析器。
  7. 视图解析器会根据ModelAndView中的视图信息来解析对应的视图资源(通常是JSP页面)。
  8. 视图解析器将解析到的视图进行渲染,并把模型数据填充到视图中。
  9. DispatcherServlet将结果响应给用户。

以上就是Spring MVC的基本工作流程。这个流程通过DispatcherServlet作为中心控制器,将用户请求分发到不同的处理器进行处理,并通过视图解析器将处理结果渲染成视图返回给用户,实现了MVC的设计模式。

2.9 @PostConstruct、init-method和afterPropertiesSet执行顺序?

在Spring框架中,@PostConstructinit-methodafterPropertiesSet这三个元素或注解都与bean的初始化过程相关,但它们具有不同的执行顺序和用途。以下是它们之间的执行顺序和简要说明:

  1. @PostConstruct

    • 这是Java EE 5引入的一个注解,用于在依赖注入完成后立即执行某个方法。
    • 在Spring框架中,当bean的所有属性被设置并且依赖注入完成后,会调用标有@PostConstruct注解的方法。
    • 在bean的生命周期中,@PostConstruct注解的方法是在BeanPostProcessorpostProcessBeforeInitialization方法执行后,以及InitializingBeanafterPropertiesSet方法执行前调用的。
  2. afterPropertiesSet()

    • 这是InitializingBean接口中的一个方法。
    • 当一个bean实现了InitializingBean接口后,Spring容器会在bean的所有属性被设置完毕后自动调用这个方法。
    • 这确保了当afterPropertiesSet()方法被调用时,所有依赖的属性都已经被注入到bean中了。
    • 在Spring的生命周期中,afterPropertiesSet()方法在@PostConstruct注解的方法之后执行。
  3. init-method

    • 这是一个在Spring框架中使用的XML属性(通常与<bean>标签一起使用),用于指定bean初始化后要调用的方法。
    • 你可以在bean的定义中指定一个init-method,然后在bean实例化后自动执行该方法。
    • 在Spring的生命周期中,init-method指定的方法是在@PostConstruct注解的方法和afterPropertiesSet()方法之后执行的。

因此,总的执行顺序是:

  1. 构造函数
  2. 依赖注入(如使用@Autowired
  3. @PostConstruct注解的方法
  4. afterPropertiesSet()方法(如果bean实现了InitializingBean接口)
  5. init-method指定的方法(如果在bean定义中指定了)

注意:在一个bean中,通常不会同时使用@PostConstructafterPropertiesSet()init-method,因为这可能会导致代码重复或不必要的复杂性。选择最适合你需求的方法即可。

2.10 Spring Boot 有哪些优点?

Spring Boot 是一个基于 Spring 的框架,旨在简化新 Spring 应用的初始搭建以及开发过程。它提供了一系列开箱即用的插件和特性,使得开发者可以快速构建和运行 Spring 应用程序。以下是 Spring Boot 的一些主要优点:

  1. 快速开发
    • Spring Boot 提供了许多自动配置(Auto-configuration)的功能,能够自动配置项目所需要的组件,减少了手动配置的工作量。
    • 它还提供了大量的“starter”依赖,这些依赖集成了各种常用的库和框架,通过简单的添加依赖就能快速集成这些功能。
  2. 简化配置
    • Spring Boot 提供了许多默认的配置,开发者只需在需要时覆盖这些配置,无需从头开始配置。
    • 它还提供了外部化配置的支持,如通过 application.properties 或 application.yml 文件来配置应用,使得配置更加灵活和易于管理。
  3. 内嵌服务器
    • Spring Boot 可以内嵌 Tomcat、Jetty 或 Undertow 等服务器,使得开发者无需安装和配置外部服务器就能运行应用。
    • 这样可以简化应用的部署流程,使得应用更加轻量级和易于维护。
  4. 监控和管理
    • Spring Boot Actuator 提供了对应用的监控和管理功能,如健康检查、环境信息、度量指标等。
    • 这些功能可以帮助开发者更好地了解应用的运行状态和性能,以便及时发现问题并进行优化。
  5. 微服务支持
    • Spring Boot 与 Spring Cloud 集成良好,非常适合用于构建微服务架构的应用。
    • 它提供了许多微服务相关的组件和工具,如服务发现、配置中心、负载均衡等,使得构建微服务应用更加简单和高效。
  6. 社区支持
    • Spring Boot 有着庞大的用户社区和活跃的开发者群体,这意味着你可以很容易地找到解决方案、示例代码和教程。
    • 同时,Spring Boot 的更新和维护也非常及时,保证了技术的先进性和稳定性。
  7. 易于测试
    • Spring Boot 支持多种测试框架,如 JUnit、Mockito 等,使得编写和运行单元测试变得简单快捷。
    • 它还提供了内嵌的测试环境,可以在不启动完整应用的情况下测试应用的某些部分。
  8. 集成安全
    • Spring Boot 集成了 Spring Security,使得添加安全控制(如身份验证、授权等)变得简单方便。
    • 通过简单的配置和注解,就可以实现复杂的安全控制逻辑。
  9. 生产就绪
    • Spring Boot 提供了许多用于生产环境的特性,如日志记录、外部化配置、健康检查等。
    • 这些特性可以帮助你构建更加健壮和可靠的应用。
  10. 兼容性
    • Spring Boot 很好地兼容了 Spring 生态系统中的其他组件和库,如 Spring Data、Spring Security 等。
    • 这使得你可以在 Spring Boot 应用中无缝地使用这些组件和库,提高开发效率。

3.多线程

3.1并发、并行和多线程

  • 57
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

糯米小麻花啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值