面试小知识点整合

发布时间:2024年01月13日

程序员必备的面试技巧

“程序员必备的面试技巧,就像是编写一段完美的代码一样重要。在面试战场上,我们需要像忍者一样灵活,像侦探一样聪明,还要像无敌铁金刚一样坚定。只有掌握了这些技巧,我们才能在面试的舞台上闪耀光芒,成为那个令HR们心动的程序猿!”
> 提醒:在发布作品前,请把不需要的内容删掉。
?

方向1:面试知识点

一、Spring、SpringMVC:Spring常用注解、IOC、DI、AOP、事务管理、mybatis整合 springboot启动原理,多数据源

Spring框架

Spring常用注解

?以下是Spring的常用注解及其作用、使用场景和所在位置:
??
?1. @Component:修饰类,当扫描到该注解时,会将该类的对象注册到IOC容器当中;
? ? ? ? ? ? ? 等同于bean标签,默认的id为首字母小写的类名 添加位置:类定义之前。
??
?2. @ResponseBody:加了这个注解的类会将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML。添加位置:方法定义之前。
??
?3. @Retention:决定了注解的生命周期,用于创建自定义注解时使用。添加位置:自定义注解上。
??
?4. @Target:决定了自定义注解的使用范围(可以加在哪些成份上,比如接口、方法或者属性上)。添加位置:自定义注解上。
??
?5. @PostConstruct:在spring初始化bean时会调用加了该注解的方法,一般用于给bean属性赋值。添加位置:bean中初始化要spring执行的方法上。
??
?6. @Autowired:一般用来修饰成员变量,会将IOC容器当中合适的对象注入给该成员变量 ? ? 默认是ByType
??
?7. @Resource:注入bean,先根据name后根据type扫描注入,jdk自带的注解。添加位置:变量定义之前或方法  定义之前。
??
?8. @Controller:子注解只是让@Component见名知义,功能和@Component是一样的
? ? ? ? ? ? ? ? ? ? ? @Controller、@Service、@Repository等等
??
?10.@Repository:用于标注数据访问组件,通常用于处理数据访问操作。添加位置:类定义之前。
??
?11.@RestController:用于标注控制层组件,通常用于处理用户请求并返回数据对象。添加位置:类定义之前。
??
?12.@RequestMapping:用于映射请求URL到处理方法,可以标注在类或方法上。添加位置:类或方法定义之前。
??
?13.@GetMapping:用于映射GET请求到处理方法。添加位置:方法定义之前。
??
?14.@PostMapping:用于映射POST请求到处理方法。添加位置:方法定义之前。
??
?15.@PutMapping:用于映射PUT请求到处理方法。添加位置:方法定义之前。
??
?16.@DeleteMapping:用于映射DELETE请求到处理方法。添加位置:方法定义之前。
??
?17.@PathVariable:用于绑定URL路径参数到方法参数。添加位置:方法参数定义之前。
??
?18.@RequestParam:用于绑定请求参数到方法参数。添加位置:方法参数定义之前。
??
?19.@RequestBody:用于绑定请求体到方法参数。添加位置:方法参数定义之前。
??
?20.@ResponseBody:用于将方法返回值直接写入HTTP响应体。添加位置:方法定义之前。
??
?21.@ComponentScan:用于指定Spring扫描组件的包路径。添加位置:类定义之前。
??
?22.@Configuration:用于标注配置类,该类包含Spring容器的配置信息。添加位置:类定义之前。
??
?23.@Bean:用于声明将一个方法的返回值注册为Spring容器中的Bean。添加位置:方法定义之前。
??
?25.@Qualifier:按照byName来注入,value:IOC中已注册对象的id值,按照value去获取对象注入进来添加位置:变量定义之前或方法参数定义之前。
??
?26.@Value:用于注入属性值,可以从配置文件或注解中获取值。添加位置:变量定义之前或方法参数定义之前。
??
?27.@Profile:用于指定某个Bean只在特定的环境下生效,例如开发环境、测试环境或生产环境。添加位置:类定义之前或方法定义之前。

IOC: 将控制权从应用程序的代码转移到框架或容器中,框架或容器负责创建和管理对象,并在需要时将它们注入到应用程序中

控制反转,Spring框架中其它功能都是依赖于IOC来实现,将对象交给spring来管理 ? 1.对象生命周期的管理:对象的创建、对象的初始化、对象的销毁等等。对象通常被称为bean ? 2.对象之间依赖关系管理:DI

DI:

依赖注入:容器动态的将某个依赖关系注入到组件之中。为了提升组件重用率。

属性注入(settter注入):property(属性是类或对象的成员变量)、ref(引用) 一个对象或变量对另一个对象的指向或引用

?<!-- 配置UserRepository Bean -->
?<bean id="userRepository" class="com.example.UserRepository" />
??
?<!-- 配置UserService Bean,并使用属性注入注入UserRepository依赖 -->
?<bean id="userService" class="com.example.UserService">
? ? ?<property name="userRepository" ref="userRepository" />
?</bean>
? ? ?
? ? ?public class UserService {
? ? ?private UserRepository userRepository;
??
? ? ?public void setUserRepository(UserRepository userRepository) {
? ? ? ? ?this.userRepository = userRepository;
? ?  }
?}
??

构造器注入:constructor-arg 肯死抓可特儿

?<!-- 配置UserRepository Bean -->
?<bean id="userRepository" class="com.example.UserRepository" />
??
?<!-- 配置UserService Bean,并使用构造器注入注入UserRepository依赖 -->
?<bean id="userService" class="com.example.UserService全限定类名">
? ? ?<constructor-arg name="名称" ref="userRepository引用" />
?</bean>
??
??
?public class UserService {
? ? ?private UserRepository userRepository;
??
? ? ?public UserService(UserRepository userRepository) {
? ? ? ? ?this.userRepository = userRepository;
? ?  }
?}
??

构造函数注入和setter注入的区别:

注:构造函数注入是构造器注入的一种,setter注入就是属性注入

构造函数注入setter注入
没有部分注入有部分注入
不会覆盖srtter属性会覆盖setter属性
任意修改都会创建一个新的实例任意修改不会创建一个新实例
适用于设置很多属性适用于设置少量属性

部分注入:

部分注入是指只注入某个类的部分属性或依赖对象,而不是全部属性或依赖对象。在Spring框架中,可以通过配置<property>元素的name属性来指定需要注入的属性名称,从而实现部分注入。此外,也可以使用@Autowired注解和@Qualifier注解结合使用,实现更精细的部分注入。部分注入可以满足更加灵活的需求,例如在某些情况下,只需要注入部分属性或依赖对象就可以完成某个操作。

自动装配:

  1. 按名称自动装配(byName): 按名称自动装配是通过Bean的名称与属性名称匹配来进行依赖注入的方式。如果目标Bean的属性名称与另一个Bean的名称相匹配,Spring容器将自动将这个Bean注入到目标Bean中。 示例:

?<!-- 配置两个Bean,其中userRepository的名称匹配了userService中的userRepository属性 -->
?<bean id="userRepository" class="com.example.UserRepository" />
?<bean id="userService" class="com.example.UserService" autowire="byName">
? ? ?<!-- userRepository属性会自动装配 -->
?</bean>
  1. 按类型自动装配(byType): 按类型自动装配是通过Bean的类型与属性类型匹配来进行依赖注入的方式。如果目标Bean的属性类型与另一个Bean的类型相匹配,Spring容器将自动将这个Bean注入到目标Bean中。 示例:

? <!-- 配置两个Bean,其中userRepository的类型匹配了userService中的UserRepository属性的类型 -->
?<bean id="userRepository" class="com.example.UserRepository" />
?<bean id="userService" class="com.example.UserService" autowire="byType">
? <!-- userRepository属性会自动装配 -->
?</bean>

  1. 构造器自动装配(constructor): 构造器自动装配是通过构造函数的参数类型与Bean的类型匹配来进行依赖注入的方式。如果目标Bean的构造函数参数类型与另一个Bean的类型相匹配,Spring容器将自动将这个Bean注入到目标Bean的构造函数中。 示例:

? <!-- 配置两个Bean,其中userRepository的类型匹配了userService的构造函数参数类型 -->
?<bean id="userRepository" class="com.example.UserRepository" />
?<bean id="userService" class="com.example.UserService" autowire="constructor">
? <!-- userService的构造函数参数会自动装配 -->
?</bean>

mybatis整合:

配置Spring的数据源、mybatis的会话工厂、和事务管理器

1. Spring整合MyBatis示例:

示例代码:

  • DataSourceConfig.java:配置数据源。

?@Configuration
?public class DataSourceConfig {
? ? ?@Bean
? ? ?public DataSource dataSource() {
? ? ? ? ?DriverManagerDataSource dataSource = new DriverManagerDataSource();
? ? ? ? ?dataSource.setDriverClassName("com.mysql.jdbc.Driver");
? ? ? ? ?dataSource.setUrl("jdbc:mysql://localhost:3306/mydatabase");
? ? ? ? ?dataSource.setUsername("username");
? ? ? ? ?dataSource.setPassword("password");
? ? ? ? ?return dataSource;
? ?  }
?}

MyBatisConfig.java:配置MyBatis。

?@Configuration
?@MapperScan("com.example.dao")
?public class MyBatisConfig {
? ? ?@Autowired
? ? ?private DataSource dataSource;
??
? ? ?@Bean
? ? ?public SqlSessionFactory sqlSessionFactory() throws Exception {
? ? ? ? ?SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
? ? ? ? ?sessionFactory.setDataSource(dataSource);
? ? ? ? ?sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
? ? ? ? ? ?  .getResources("classpath:mybatis/*Mapper.xml"));
? ? ? ? ?return sessionFactory.getObject();
? ?  }
??
? ? ?@Bean
? ? ?public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
? ? ? ? ?return new SqlSessionTemplate(sqlSessionFactory);
? ?  }
?}

application.properties:Spring配置文件,用于配置数据库连接、MyBatis会话工厂、Mapper扫描以及Service注册。

?<!--导入属性文件-->
? ? ?<context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
?<!-- 数据源配置 -->
?<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
? ? ?<property name="driverClassName" value="com.mysql.jdbc.Driver" />
? ? ?<property name="url" value="jdbc:mysql://localhost:3306/mydatabase" />
? ? ?<property name="username" value="username" />
? ? ?<property name="password" value="password" />
?</bean>
??
?<!-- 配置MyBatis的SqlSessionFactory ?指定数据源和Mapper文件位置-->
?<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
? ? ?<property name="dataSource" ref="dataSource" />
? ? ?<property name="mapperLocations" value="classpath:mapper/*Mapper.xml" />
?</bean>
??
?<!-- 配置MyBatis的Mapper扫描器
?将dao接口的代理对象注册到IOC容器中;
?本质上就是将getMapper方法得到的对象注册
?注册的dao对象的id默认为首字母小写dao接口的名称
?-->
?<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
? ? ?<property name="basePackage" value="com.example.dao" />
?</bean>
??
?<!-- 配置事务管理器 -->
?<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
? ? ?<property name="dataSource" ref="dataSource" />
?</bean>
??
?<!-- 开启注解驱动 -->
?<context:component-scan base-package="com.example" />
?<tx:annotation-driven />
??

AOP:

面向切面编程,可以将某些功能在运行期间织入到需要该功能的对象中

面向切面编程,它的底层是通过动态代理来实现的,通过生成目标对象的代理对象,将系统功能和对象功能在代理对象中进行有效结合。它包括以下几点:

目标对象:要被添加额外功能的对象

代理对象:根据目标对象生成的对象

连接点:需要被添加额外功能的方法

切点:本质是一个表达式,满足该表达式的方法,参会被添加额外功能

通知:定义额外功能的方法

  1. 前置通知(Before Advice): 在目标方法执行之前执行。前置通知通常用于执行一些预处理操作,例如身份验证、日志记录等。

  2. 后置通知(After Advice): 在目标方法执行之后执行,无论方法是否成功执行。后置通知通常用于执行清理或资源释放操作。

  3. 返回通知(After Returning Advice): 在目标方法成功执行并返回结果后执行。返回通知通常用于处理目标方法的返回值,例如日志记录、结果转换等。

  4. 异常通知(After Throwing Advice): 在目标方法抛出异常时执行。异常通知通常用于处理异常情况,例如发送警报或执行回滚操作。

  5. 环绕通知(Around Advice): 在目标方法之前和之后执行,并控制目标方法的执行流程。环绕通知具有最大的灵活性,可以完全替代目标方法的执行,也可以在执行前后添加额外的逻辑。

切面:Aspect,本质是一个java类,在类中定义了通知,有时也会定义切点

织入:根据目标对象和切面生成代理对象的过程

AOP可以用来进行日志和异常处理,使用通知进行处理。

AOP实现方式有:

静态代理: 编译期间确定的代理关系,代理类在编译时已经存在。

·编译时编织(特殊编译器实现)

·类加载时编织(特殊的类加载器实现)

动态代理: 动态代理是在运行时动态生成代理类的方式,通常使用Java的反射机制。

JDK动态代理:通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口

CGLIB动态代理:如果目标类没有接口,他会动态代理目标类

注册对象:

spring中

xml配置:可以使用bean元素配置id和class

注解:使用@Service、Component、@Repository等

Java配置:使用Java配置类注册Bean,创建一个Java类,并使用@Configuration和@Bean注解,可以将Bean定义在Java类中

SpringMVC中使用@Controller:标识控制器类和@RequestMapping:用于指定请求的映射路径

Service层用@Service

Spring事务管理

Spring事务是Spring框架提供的一种机制,用于管理数据库操作或其他资源的事务性操作。事务是一组操作,要么全部成功执行并提交,要么全部失败并回滚,以确保数据的一致性和可靠性。以下是与Spring事务相关的一些重要知识点、其定义、作用和实现场景:

1. 事务(Transaction):

  • 定义: 事务是一组相关的数据库操作,这些操作要么全部成功执行,要么全部失败并回滚,以维护数据的一致性和完整性。

  • 作用: 确保数据库操作的一致性,当发生故障或错误时,保证数据库的数据状态不被破坏。

  • 实现场景: 数据库操作、文件操作、消息队列操作等任何需要一致性和可靠性的场景。

2. 事务管理器(Transaction Manager):

  • 定义: 事务管理器是Spring框架提供的接口,用于管理事务的生命周期,它负责事务的开始、提交和回滚。

  • 作用: 管理事务的状态,决定何时开始、提交或回滚事务,以确保事务的完整性。

  • 实现场景: 与不同的数据源(如数据库、消息队列)集成,管理各种资源的事务。

3. 事务传播行为(Transaction Propagation):

  • 定义: 事务传播行为定义了在多个事务之间调用方法时,如何处理事务的行为。

  • 作用: 控制方法之间事务的嵌套和交互,确保在方法调用期间事务的一致性。

  • 实现场景: 当一个方法调用另一个方法,并且这些方法涉及事务操作时,定义事务传播行为以确保事务的正确管理。

4. 事务隔离级别(Isolation Level):

  • 定义: 事务隔离级别定义了多个并发事务之间的相互影响程度。常见的隔离级别包括读未提交、读已提交、可重复读和串行化。

  • 作用: 控制事务之间的隔离程度,以防止并发访问数据时出现问题,如脏读、不可重复读和幻读。

  • 实现场景: 需要在高并发环境下维护数据的一致性。

5. 声明式事务管理(Declarative Transaction Management):

  • 定义: 声明式事务管理是一种使用注解或XML配置的方式来定义事务行为,而无需在代码中编程式管理事务。

  • 作用: 简化事务管理,将事务逻辑与业务逻辑分离,提高代码的可读性和可维护性。

  • 实现场景: 大多数业务场景,特别是使用Spring框架的应用程序。

6. 编程式事务管理(Programmatic Transaction Management):

  • 定义: 编程式事务管理是通过编写代码来显式管理事务的方式,使用编程接口如TransactionTemplate

  • 作用: 提供更精细的控制,允许在代码中编写自定义的事务逻辑。

  • 实现场景: 需要复杂的事务逻辑或与不支持注解的框架集成的情况。

7. 本地事务(Local Transaction):

  • 定义: 本地事务是指只涉及单个数据源(如单个数据库)的事务,由本地事务管理器管理。

  • 作用: 管理与单个数据源相关的事务,确保数据的一致性。

  • 实现场景: 单个数据库操作的业务逻辑。

8. 分布式事务(Distributed Transaction):

  • 定义: 分布式事务是指涉及多个数据源的事务,例如在不同的数据库或系统之间进行操作。

  • 作用: 管理多个数据源之间的事务,确保多个系统之间的操作的一致性和可靠性。

  • 实现场景: 跨越多个系统或数据库的业务逻辑,如微服务架构中的事务管理。

Spring事务管理是构建可靠和高性能应用程序的关键组成部分,它可以根据不同的场景和需求提供不同的配置选项和控制级别。通过适当地选择和配置事务管理机制,可以确保应用程序的数据一致性,并提供高度可维护的代码。

Spring的工厂模式

Spring框架中的工厂模式是一种设计模式,它用于创建和管理对象实例,从而将对象的创建和使用分离开,以提高代码的松耦合性和可维护性。Spring中的工厂模式主要体现在以下两种方式:

  1. BeanFactory(工厂模式): Spring的BeanFactory 是一种工厂模式的实现。它是Spring IoC容器的核心,负责创建、配置和管理Bean对象的实例。开发者通过配置文件或注解来定义Bean,然后通过BeanFactory来获取这些Bean的实例。这种方式将对象的创建和管理交给了Spring容器,从而实现了对象的解耦和可维护性。

    ?BeanFactory factory = new XmlBeanFactory(new ClassPathResource("beans.xml"));
    ?MyBean myBean = (MyBean) factory.getBean("myBean");
  2. ApplicationContext(应用上下文): ApplicationContextBeanFactory 的扩展,它是一种更高级的工厂模式实现。除了BeanFactory的功能外,ApplicationContext 还提供了更多的高级功能,如AOP、事务管理、国际化、事件发布等。它也是Spring框架中广泛使用的工厂模式的体现。

    ?ApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
    ?MyBean myBean = context.getBean("myBean", MyBean.class);

在Spring中,工厂模式的使用使得开发者可以将对象的创建和配置集中管理,从而降低了代码的复杂性,提高了可维护性和可扩展性。这也符合Spring框架的核心理念之一,即控制反转(IoC)和依赖注入(DI),其中工厂模式是IoC的一个关键实现方式。通过工厂模式,开发者将对象的创建交给了容器,从而更好地管理了应用程序的组件。

BeanFactory和ApplicationContext的区别

BeanFactoryApplicationContext
它使用懒加载它使用即时加载
它使用语法显示提供资源对象它自己创建和管理资源对象
不支持国际化支持国际化
不支持基于依赖的注解支持基于依赖的注解

BeanFactory:

优点:应用启动时占用资源少,对资源要求较高的应用,比较有优势

缺点:运行速度较慢。可能会有空指针异常错误。通过Bean工厂创建的Bean生命周期会简单一些

ApplicationContext:

优点:所有Bean在启动时都进行了加载,系统运行的速度快;在启动的时候,可以发现系统中的配置问题

缺点:把费时的操作放在系统启动中完成,所有的对象都可以预加载,缺点就是内存占用较大

SpringMvc文件上传

MultipartFile 读作:moteipartFile

在Spring MVC中,要实现文件上传功能,你可以通过以下步骤来操作:

  1. 添加文件上传配置:首先,确保你的Spring MVC项目已正确配置multipartResolver以支持文件上传。通常,Spring Boot应用程序已经自动配置了MultipartAutoConfiguration,因此你只需确保添加了spring-boot-starter-web依赖。

    ?<dependency>
    ? ? ?<groupId>org.springframework.boot</groupId>
    ? ? ?<artifactId>spring-boot-starter-web</artifactId>
    ?</dependency>

    如果你在Spring MVC中手动配置,确保在Spring配置文件中添加以下配置:

    ?<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    ? ? ?<!-- 配置上传文件大小限制 -->
    ? ? ?<property name="maxUploadSize" value="10000000"/> <!-- 10MB -->
    ?</bean>
  2. 创建上传表单:在你的HTML表单中添加文件上传字段,通常使用<input type="file">标签。例如:

    ?<form action="/upload" method="POST" enctype="multipart/form-data">
    ? ? ?<input type="file" name="file">
    ? ? ?<input type="submit" value="上传文件">
    ?</form>

    注意,表单的enctype属性必须设置为multipart/form-data,以支持文件上传。

  3. 编写Controller处理文件上传:在你的Spring MVC控制器中编写方法来处理文件上传请求。使用@RequestParam注解来接收上传的文件,并将其保存到服务器或进行其他操作。例如:

    ?import org.springframework.stereotype.Controller;
    ?import org.springframework.web.bind.annotation.*;
    ?import org.springframework.web.multipart.MultipartFile;
    ??
    ?@Controller
    ?public class FileUploadController {
    ??
    ? ? ?@PostMapping("/upload")
    ? ? ?public String handleFileUpload(@RequestParam("file") MultipartFile file) {
    ? ? ? ? ?if (!file.isEmpty()) {
    ? ? ? ? ? ? ?try {
    ? ? ? ? ? ? ? ? ?// 获取文件名
    ? ? ? ? ? ? ? ? ?String fileName = file.getOriginalFilename();
    ? ? ? ? ? ? ? ? ?// 文件保存路径,你可以根据需求自定义
    ? ? ? ? ? ? ? ? ?String filePath = "/path/to/save/uploads/" + fileName;
    ? ? ? ? ? ? ? ? ?// 保存文件
    ? ? ? ? ? ? ? ? ?file.transferTo(new File(filePath));
    ? ? ? ? ? ? ? ? ?// 文件上传成功,执行其他操作
    ? ? ? ? ? ? ? ? ?return "redirect:/success"; // 重定向到成功页面
    ? ? ? ? ? ?  } catch (Exception e) {
    ? ? ? ? ? ? ? ? ?e.printStackTrace();
    ? ? ? ? ? ? ? ? ?// 处理文件上传异常
    ? ? ? ? ? ? ? ? ?return "redirect:/error"; // 重定向到错误页面
    ? ? ? ? ? ?  }
    ? ? ? ?  } else {
    ? ? ? ? ? ? ?// 文件为空
    ? ? ? ? ? ? ?return "redirect:/error"; // 重定向到错误页面
    ? ? ? ?  }
    ? ?  }
    ?}

    上述代码中,handleFileUpload方法接收名为"file"的上传文件,并将其保存到服务器上指定的路径。你可以根据需要修改文件保存路径和处理逻辑。

  4. 配置上传文件大小限制:如果需要限制上传文件的大小,可以在multipartResolver的配置中设置maxUploadSize属性,以限制文件的最大大小。

  5. 创建成功和错误页面:根据上传结果,你可以创建成功和错误页面,以提供给用户相应的反馈信息。

  6. 测试文件上传:最后,启动你的Spring MVC应用程序,并访问包含文件上传表单的页面,测试文件上传功能。

这些是在Spring MVC中实现文件上传的基本步骤。根据你的项目需求,你可以进一步定制文件上传的行为,如检查文件类型、生成文件名、处理多个文件上传等。请根据实际情况进行适当的调整和扩展。

文章来源:https://blog.csdn.net/Xhycz9/article/details/135551592
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。