面试真实问题

面试问题

1、OOP面向对象编程思想

  • 先有过程,后得结果。
  • 过程指得是现实客观得内容变为虚拟抽象得内容得过程——过程得步骤是:先归纳出类–>类中加属性(特征)和方法(行为动作)
  • 结果指得是根据过程中得类(属性+方法)来创造可以完成任务得个体(对象)

2、抽象类和接口的区别

​ 抽象类和接口都不能够实例化,但可以定义抽象类和接口类型的引用。一个类如果继承了某个抽象类或者实现了某个接口都需要对其中的抽象方法全部进行实现,否则该类仍然需要被声明为抽象类。

​ 接口比抽象类更加抽象,因为抽象类中可以定义构造器,可以有抽象方法和具体方法,而接口中不能定义构造器而且其中的方法全部都是抽象方法。抽象类中的成员可以是private、默认、protected、public的,而接口中的成员全都是public的。Java接口中声明的变量默认都是final的。抽象类可以包含非final的变量。类可以实现很多个接口,但是只能继承一个抽象类。

3、&和&&的区别

&和&&都是两个都为true才为true,区别:&&只要判断了前面为false则为false不用判断后面的

4、String、String Butter、 String Builder的区别

String :不可变对象,每当修改时都会生成一个新对象占用空间,效率最低

String Butter: 可变长字符串 、效率低、 安全 、多线程、 被synchronized修饰

String Builder: 可边长字符串 、效率高、 不安全 、单线程

5、创建线程有哪些方式

(1)继承thread类

  • 自定义线程类继承Thread
  • 重写run()方法,编写线程执行体
  • 创建线程对象,调用start()方法启动线程

(2)实现Runnable接口(推荐使用Runnable对象,因为Java单继承的局限性

  • 自定义线程类实现Runnable接口
  • 实现run()方法,编写线程执行体
  • 创建线程对象,调用start()方法启动对象

(3)实现Callable接口(了解)

  • 实现Callable接口,需要返回值类型

    重写call方法,需要抛出异常

    创建目标对象

    创建执行服务:ExecutorService ser = Executors.newFixedThreadPool(1);

    提交执行:Future result1 = ser.submit(11);

    获取结果:boolean r1 = result1.get()

    关闭服务:ser.shutdownNow();

6、jdk和jre

  1. JDK:java 开发工具包,提供了 java 的开发环境和运行环境。
  2. JRE:java 运行环境,为 java 的运行提供了所需环境。

具体来说 JDK 其实包含了 JRE,同时还包含了编译 java 源码的编译器 javac,还包含了很多 java 程序调试和分析的工具。简单来说:如果你需要运行 java 程序,只需安装 JRE 就可以了,如果你需要编写 java 程序,需要安装 JDK。

7、分组查询

group by …having

8、查询出成绩排名前十的学生

select sname from student order by subject desc limit 10;

9、mysql常用的关键字

select delete insert having group by join in left/right join order by from where distinct(去重)

union limit as like between and count arc desc both char with values to update

table true false then when or if index int key ignore double add all alter drop…

10、Java基本数据类型

byte short int long float double boolean char

11、list、set、map区别

  • List:有序集合,元素可重复
  • Set:不重复集合,LinkedHashSet按照插入排序,SortedSet可排序,HashSet无序
  • Map:键值对集合,存储键、值和之间的映射;Key无序,唯一;value 不要求有序,允许重复

12、面向对象的特征有哪些方面

(1)继承:继承:子类继承父类的非私有的属性和方法,并且只能单重继承(只能有一个父类),关键词extends.
1. 子类对象与父类对象共用同一空间,所有子类可以使用父类的属性和方法。(思考父类使用子类的属性和方法可以吗?)
2. 子类重写父类的方法,为了增加或改写父类的功能(行为动作),而特征没有被重写覆盖,因为属性特征是用来做标识对象使用的,和方法的作用以及意义不同。
(2)封装:就是类的私有化。将代码及处理数据绑定在一起的一种编程机制,该机制保证程序和数据不受外部干扰。

作用:

  1. 提高程序的安全性,保护数据
  2. 隐藏代码的实现细节
  3. 统一接口
  4. 系统可维护性增加了

(3)多态:同一方法可根据不同发送对象而采用不同的行为方式,多态分静态多态和动态多态,静态多态是编译时多态(重载):同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同),动态多态是运行时多态(重写):重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的返回类型,重载对返回类型没有特殊的要求。

13、数据结构的排序

选择排序、插入排序、冒泡排序、快速排序、希尔排序、堆排序(大根堆和小根堆)、归并排序

//归并--优化
public static void main(String[] args) {
		int[] x = new int[] {5, 1, 3, 7, 11, 4, 6, 2, 0, 13, -3};
		System.out.println(Arrays.toString(x));
		mergeSort(x);
		System.out.println(Arrays.toString(x));
	}
	
	public static void mergeSort(int[] nums) {
		// 避免生成大量的临时对象,声明等大数组存储空间
		int[] tmp = new int[nums.length];
		doSort(nums, tmp, 1, nums.length);
	}
 
	// 注:数组下标0开始,所有取值都-1
	public static void doSort(int[] nums, int[] tmp, int begin, int end) {
		if (begin == end) {
			tmp[begin - 1] = nums[begin - 1];
		} else {
			int middle = (begin + end) / 2;
			doSort(nums, tmp, begin, middle);
			doSort(nums, tmp, middle + 1, end);
			doMerge(tmp, nums, begin, middle, end);
			System.arraycopy(nums, begin - 1, tmp, begin - 1, (end - begin) + 1);
		}
	}

14、==和equals的区别

== 对于基本类型来说是值比较,对于引用类型来说是比较的是引用;而 equals 默认情况下是引用比较,只是很多类重新了 equals 方法,比如 String、Integer 等把它变成了值比较,所以一般情况下 equals 比较的是值是否相等。

15、Java中的IO都有哪些

  • 按方向:输入流和输出流

  • 按功能:节点流和过滤流

  • 按单位:字符流和字节流

16、String 类的常用方法都有那些

equals toUpperCase tolowCase endswith startswith trim length charAt tocharArray indexof

lastindexof replace split compare substring

17、分页查询

select * from emp limit 10,10;

18、mybatis的namespace映射

用于绑定Dao接口的,即面向接口编程

19、springboot的优势

  • 无代码生成和xml配置
  • 可以独立运行spring项目
  • 简化了maven配置
  • 自带应用监控
  • 内嵌 Servlet 容器
  • 提供了大量自动配置

20、前端三大框架

Angular、React、Vue

21、上传文件和导入数据的区别是什么

文件上传一般不会把图片或文件直接保存数据库,而是先保存文件的路径或者名称到硬盘上,再将这个名称或者路径保存到数据库。以文件形式放在服务器上,作为数据中转操作

导入:将事先准备好的模板导入

22、分组函数和聚合函数必须一起用么

no

23、list、arraylist的区别

  • List是一个接口,而ArrayList是List接口的一个实现类。
  • ArrayList类继承并实现了List接口。
  • 因此,List接口不能被构造,也就是不能创建实例对象,但是我们可以像下面那样为List接口创建一个指向自己的对象引用,而ArrayList实现类创建的实例对象就在此处充当了这个指向List接口的对象引用。

24、mysql触发器

CREATE <触发器名> < BEFORE | AFTER >
<INSERT | UPDATE | DELETE >
ON <表名> FOR EACH Row<触发器主体>

25、线程的状态

创建、就绪、运行、堵塞、死亡

26、list的三种排序方法

  1. 使用 Comparable 进行排序;类继承接口
  2. 使用 Comparator 进行排序;创建对象时用匿名内部类
  3. 如果是 JDK 8 以上的环境,也可以使用 Stream 流进行排序。

list = list.stream().sorted(Comparator.comparing(Person::getAge).reversed()).collect(Collectors.toList());

27、继承的特性

a、子类对象与父类对象共用同一空间,所有子类可以使用父类的属性和方法。(思考父类使用子类的属性和方法可以吗?)
b、子类重写父类的方法,为了增加或改写父类的功能(行为动作),而特征没有被重写覆盖,因为属性特征是用来做标识对象使用的,和方法的作用以及意义不同。

28、子类重写父类方法,调用时会调用子类重写之后的方法

会,调用后不在使用父类方法内定义的方法,而使用子类重写的方法

29、list<>可以加什么类型,可以加object么

不加的话默认为object类型

30、jdk 8的Lambda表达式

函数式接口( 任何接口,如果只包含唯一一个抽象方法,那么它就是一个函数式接口)

runnable

new Thread (()->System.out.println(“多线程学习。。。。”)).start();

31、值传递(java是值传递)和引用传递的区别

值传递(pass by value):在调用函数时,将实际参数复制一份传递到函数中,这样在函数中对参数进行修改,就不会影响到原来的实际参数;

引用传递(pass by reference):在调用函数时,将实际参数的地址直接传递到函数中。这样在函数中对参数进行的修改,就会影响到实际参数;

32、方法重载的规则:

  • 方法名称必须相同
  • 参数列表必须不同(个数、参数类型、或排序不同)
  • 返回类型可以相同也可以不相同
  • 仅仅返回类型不同不足以成为方法的重载

32、java和Javac

javac称为java编译程序,java称为java运行程序

33、不使用中间值,怎么使两个数值交换?

        int a =2,b=8;
        a=b-a;  //a=6
        b=b-a;  //b=2
        a=a+b;  //a=8

34、面向对象的本质及特征

本质:以类的方式组织代码,以对象的形式封装程序

特征:封装、继承、多态

35、Spring boot的注解(举例)

@SpringBootApplication:申明让spring boot自动给程序进行必要的配置,这个配置等同于:@Configuration ,@EnableAutoConfiguration 和 @ComponentScan 三个配置。

@ComponentScan:让spring Boot扫描到Configuration类并把它加入到程序上下文。

@Configuration :等同于spring的XML配置文件;使用Java代码可以检查类型安全。

@EnableAutoConfiguration :自动配置。

@Controller:用于定义控制器类,在spring项目中由控制器负责将用户发来的URL请求转发到对应的服务接口(service层),一般这个注解在类中,通常方法需要配合注解@RequestMapping。

@RestController=@ResponseBody+@Controller。注解可以直接返回一个对象,可以将对象转换为json字符串返回给前端

@RequestBody前端传过来的json转化为后台的Java对象

@RequestMapping:提供路由信息,负责URL到Controller中的具体函数的映射。

@Import:用来导入其他配置类。

@Autowired和@Resource注解都是作为bean对象注入的时候使用的,两者都可以声明在字段和setter方法上,引入mapper里UserMapper定义的接口
@Autowired注解默认通过byType方式注入,而@Resource注解默认通过byName方式注入;byName就是变量名去匹配bean的id属性,而byType则是变量类型去匹配bean的class属性

@Service:一般用于修饰service层的组件

@Bean:用@Bean标注方法等价于XML中配置的bean。

@Value:注入Spring boot application.properties配置的属性的值。

@Inject:等价于默认的@Autowired,只是没有required属性;

@Component:泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。

@Transactional //在代码执行出错的时候能够进行事务的回滚(回复到上一次正确的状态)

36、Thread和Runnable对比

继承Thread类:

子类继承Thread类具备多线程能力
启动线程:子类对象.start()
不建议使用:避免OOP单继承局限性

实现Runnable接口

实现接口Runnable具有多线程能力
启动线程:传入目标对象+Thread对象.start()
推荐使用:避免单继承局限性,灵活方便,方便同一个对象被多个线程使用

37、集合和数组的区别

  • 数组长度固定,集合长度不固定。

  • 数组可以存储基本类型和引用类型,集合只能存储引用类型。

38、java有什么特点

  1. 面向对象
  2. 平台无关性
  3. 简单性
  4. 可移植
  5. 多线程
  6. 分布式
  7. 健壮性
  8. 高性能
  9. 安全性

39、请简述session和cookie区别。

(1)存储位置不同

cookie的数据信息存放在客户端浏览器上。session的数据信息存放在服务器上。

(2)存储容量不同

cookie存储容量有限,session没有上限

(3)存储方式不同

cookie中只能保管ASCII字符串,并需要通过编码方式存储为Unicode字符或者二进制数据。session中能够存储任何类型的数据。

(4)隐藏性不同

cookie对客户端是可见的,session存储在服务器上是隐藏的

(5)有效期不同

cookie可以设置有效期,session关闭页面就失效。

(6)跨域

cookie支持跨域名访问。session不支持跨域名访问。

40、继承和接口的区别

1、不同的修饰符修饰(interface),(extends)

2、在面向对象编程中可以有多继承!但是只支持接口的多继承,不支持’继承’的多继承,而继承在java中具有单根性,子类只能继承一个父类。
3、在接口中只能定义全局常量,和抽象方法,而在继承中可以定义属性方法,变量,常量等。

4、某个接口被类实现时,在类中一定要实现接口中的抽象方法,而继承想调用那个方法就调用那个方法。

5、JAVA中不支持多重继承,但是可以用接口来实现,这样就要用到implements

6、继承只能继承一个类,但implements可以实现多个接口,用逗号分开就行了 。

41、mybatis-plus

  1. service层(接口方法)可以继承IService<>

  2. mapper层(接口定义层)可以用BaseMapper<>

  3. 逻辑删除@TableLogic(value =“0”,deval =“1”)

  4. 代码生成器

  5. 分页插件

42、Mybatis获取参数值的两种方式

${} 和 #{}

43、获取异常的方式

throw:

表示方法内抛出某种异常对象
执行到 throw 语句则后面的语句块不再执行
throw语句用来明确地抛出一个”异常”。

throws:

方法的定义上使用 throws 表示这个方法可能抛出某种异常
需要由方法的调用者进行异常处理
throws用来标明一个成员函数可能抛出的各种”异常”。

try/catch

用try来指定一块预防所有”异常”的程序。紧跟在try程序后面,应包含一个catch子句来指定你想要捕捉的”异常”的类型。

44、vue子父类传值

  • 父传子

    • 子组件(接收方)在vue对象中,通过props属性声明,声明他期待获得的数据
      • props:[“commentId”],
    • 父组件(发送方)注册子组件,在使用子组件的时候,以键值对的方式传递给子组件,
      • :commentId=“commentId”
      • 然后再data里面定义commentId的值
  • 子传父

    子组件(发送方)以某种方式触发一个自定义事件,在事件中通过
    $emit(“listToChild”,this.value)
    父组件(接收方)在引用子组件标签中监听该自定义事件,并添加一个响应该事件的方法
    v-on:listToChild=“showMsgFun”
    在方法中调用此方法 showMsgFun(val){ console.log(val); }

45、java什么是生命周期(生老病死),vue的声明周期,vue的钩子函数有哪些

一个java类的完整的生命周期会经历:加载、连接、初始化、使用、和卸载五个阶段

vue中的生命周期分3个阶段:初始阶段,更新阶段,销毁阶段,

具体开始创建、初始化数据、编译模版、挂载Dom -> 渲染、更新 -> 渲染、卸载

钩子函数:

  • beforeCreate
  • created
  • beforeMount
  • mounted
  • beforeUpdate
  • updated
  • beforeDestroy
  • destroyed
  • activated
  • deactivated 新增的钩子函数
  • errorCaptured

46、spring是什么

​ 1:是一个轻量级的开源框架,是为解决企业应用开发的复杂性而创建的;

 2:是一个三层架构,也为J2EE应用程序开发提供集成的框架;

    Web层:Spring MVC;

    业务层 :Spring的IoC;

    持久层 :Spring的JDBC、ORM、等持久层框架;

​ 3: IoC :控制反转

​ 4 :DI:依赖注入

​ 5: AOP :面向切面编程

47、spring注解(举例)

1.声明bean的注解

*@Component* 组件,没有明确的角色

@Service 在业务逻辑层使用(service层)

*@Repository* 在数据访问层使用(dao层)

@Controller 在展现层使用,控制器的声明(C)

2.注入bean的注解

@Autowired

@Inject

@Resource

3.java配置类相关注解

@Configuration 声明当前类为配置类,相当于xml形式的Spring配置(类上)

@Bean 注解在方法上,声明当前方法的返回值为一个bean,替代xml中的方式(方法上)

@Configuration 声明当前类为配置类,其中内部组合了@Component注解,表明这个类是一个bean(类上)

@ComponentScan 用于对Component进行扫描,相当于xml中的(类上)

@WishlyConfiguration 为@Configuration与@ComponentScan的组合注解,可以替代这两个注解

50、线程和进程的区别

​ 简而言之,进程是程序运行和资源分配的基本单位,一个程序至少有一个进程,一个进程至少有一个线程。进程在执行过程中拥有独立的内存单元,而多个线程共享内存资源,减少切换次数,从而效率更高。线程是进程的一个实体,是cpu调度和分派的基本单位,是比程序更小的能独立运行的基本单位。同一进程中的多个线程之间可以并发执行。

51、什么是事物及其特性

事务(Transaction),一般是指要做的或所做的事情

● 原子性(Atomicity)**:**操作这些指令时,要么全部执行成功,要么全部不执行。只要其中一个指令执行失败,所有的指令都执行失败,数据进行回滚,回到执行指令前的数据状态。

● 一致性(Consistency)**:**事务的执行使数据从一个状态转换为另一个状态,但是对于整个数据的完整性保持稳定。

● 隔离性(Isolation)**:**隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。

● 持久性(Durability)**:**当事务正确完成后,它对于数据的改变是永久性的。

52、static修饰符:
a、static主要有4中使用情况:成员变量、成员方法、代码块和内部类
b、不用创建对象可以直接调用
c、static关键字修饰的内容都是静态的
d、在static方法内部不能调用非静态方法
e、static修饰符修饰的类变量和静态语句块都只会运行一次。
f、可以使用静态变量作为应用级别的全局变量,被所有类和对象共用。

53、深拷贝和浅拷贝区别是什么?

  • 浅拷贝只是复制了对象的引用地址,两个对象指向同一个内存地址,所以修改其中任意的值,另一个值都会随之变化,这就是浅拷贝(例:assign())
  • 深拷贝是将对象及值复制过来,两个对象修改其中任意的值另一个值不会改变,这就是深拷贝(例:JSON.parse()和JSON.stringify(),但是此方法无法复制函数类型)

54、防止SQL注入的五种方法

  1. (简单又有效的方法)PreparedStatement…
  2. 使用正则表达式过滤传入的参数
  3. 字符串过滤
  4. jsp中调用该函数检查是否包函非法字符
  5. JSP页面判断代码:

55、前后端分离必备的接口规范
命名规范、参数规范、响应规范、错误处理规范、安全规范和文档规范
命名规范
良好的接口命名规范可以提高代码的可读性和可维护性,减少团队成员之间的理解差异。以下是一些常见的接口命名规范:

  1. 使用统一的URL路径规范
    URL路径应该使用小写字母,并采用短横线分隔单词。例如,/api/user/login。

  2. 使用动词来表示操作
    接口名应该使用动词来表示操作,而不是使用名词。例如,/api/user/login中的login表示登录操作。

  3. 使用名词复数形式表示资源集合
    当接口涉及到资源集合时,应该使用名词的复数形式。例如,/api/users表示获取所有用户的接口。

  4. 避免使用动词短语
    在命名接口时,应避免使用过长的动词短语。接口名应该简洁明了,能够清晰表达操作的含义。

参数规范
良好的参数规范可以确保前后端之间的数据交互准确无误。以下是一些常见的参数规范:

  1. 使用合适的HTTP方法
    根据操作的性质,选择合适的HTTP方法。例如,使用GET方法获取资源,使用POST方法创建资源,使用PUT方法更新资源,使用DELETE方法删除资源。

  2. 使用合适的参数位置
    根据操作的需要,将参数放置在合适的位置。通常,GET请求的参数可以放置在URL的查询字符串中,而POST和PUT请求的参数可以放置在请求体中。

  3. 使用合适的数据格式
    根据具体需求,选择合适的数据格式,如JSON、XML等。确保前后端之间的数据交换格式一致,以避免解析错误。

  4. 参数校验和合法性检查
    在接口中进行必要的参数校验和合法性检查,确保输入的数据满足要求和约束条件。这包括验证参数是否为必填项、参数格式是否正确、参数范围是否合法等。在接口层面进行参数校验可以有效地防止无效数据的传入,提高系统的安全性和稳定性。

响应规范
良好的响应规范可以确保前端能够正确地解析和处理后端返回的数据。以下是一些常见的响应规范:

  1. 使用统一的响应格式
    定义统一的响应格式,包括状态码、消息和数据。例如,可以使用JSON格式的响应,包含status、message和data字段。

  2. 使用合适的状态码
    根据不同的场景和操作结果,选择合适的状态码进行返回。常见的状态码包括200表示成功、400表示请求错误、401表示未授权、500表示服务器错误等。确保前端能够根据状态码进行相应的处理。

  3. 返回有意义的错误消息
    在发生错误时,返回有意义的错误消息,帮助前端定位和解决问题。错误消息应该清晰、准确,并包含足够的信息,以便于调试和排查错误。

  4. 分页和排序支持
    当接口返回大量数据时,应提供分页和排序的支持。通过使用page和pageSize参数来指定分页信息,并使用sort参数来指定排序字段和方式。这样,前端可以灵活地控制返回数据的数量和排序方式。

错误处理规范
良好的错误处理规范可以确保前后端在发生异常或错误时能够正确地处理和恢复。以下是一些常见的错误处理规范:

  1. 统一的错误码和错误消息
    定义统一的错误码和错误消息,以便前后端能够统一处理和解析错误。错误码可以作为标识,帮助定位问题,而错误消息可以作为给用户展示的友好提示。

  2. 异常处理和异常返回
    在后端接口中,对于异常情况应该进行适当的异常处理,并返回相应的错误信息。可以使用全局异常处理器来捕获和处理异常,确保错误信息能够正确返回给前端。

  3. 日志记录和错误追踪
    在发生异常时,应记录相关的日志信息,包括异常类型、堆栈追踪等。这有助于后续的错误追踪和排查。同时,可以使用错误追踪工具来记录和跟踪错误,以便及时发现和解决问题。

安全规范
在前后端分离的架构中,安全性尤为重要。以下是一些常见的安全规范:

  1. 接口鉴权和身份验证
    为了确保接口的安全性,应该实施鉴权和身份验证机制。前端在发送请求时需要提供有效的身份认证信息,后端则需要验证该信息的合法性。常见的身份验证方式包括基于令牌(Token)的身份验证和基于会话(Session)的身份验证。

  2. 参数加密和防篡改
    对于敏感数据或需要保密的参数,应该采用加密算法对其进行加密处理。这可以确保数据在传输过程中的安全性,防止被恶意窃取或篡改。

  3. 防止SQL注入和XSS攻击
    在处理用户输入数据时,应该进行合适的输入验证和过滤,以防止SQL注入和跨站脚本(XSS)攻击。使用参数绑定或预编译语句可以有效防止SQL注入,而对用户输入的内容进行转义或过滤可以防止XSS攻击。

  4. 接口访问控制
    根据用户的角色和权限,对接口进行访问控制。在后端实现身份验证后,可以根据用户的身份和权限判断其是否有权访问特定的接口或执行特定的操作。

文档规范
为了确保前后端团队之间的顺畅沟通和协作,接口规范的文档化非常重要。以下是一些常见的文档规范:

  1. 接口文档详细描述
    接口文档应包含接口的详细描述、输入参数、输出参数、异常情况等信息。描述应该清晰明了,便于理解和使用。

  2. 示例请求和响应
    为了帮助前端理解接口的使用方式,可以提供示例请求和响应。示例应涵盖各种常见情况,以便前端开发人员能够准确地理解接口的预期行为和返回结果。

  3. 更新记录和版本管理
    对于接口的更新和改动,应该及时记录和维护更新记录和版本管理。这样,前后端团队可以清楚地了解接口的变动,并进行相应的适配和调整。

56、VM中的五大内存区域划分详解
堆、方法区、虚拟机栈、本地方法栈、程序计数器

57、Spring三种注入对象的方式对比
1、属性注入 使⽤ @Autowired 实现的,将 Service 类注⼊到 Controller 类中
2、构造方法注入
3、Setter 注入

对比
属性注⼊的优点是简洁,使用方便;缺点是只能用于 IoC 容器,如果是非 IoC 容器不可用,并且只有在使用的时候才会出现 NPE(空指针异常)。
构造方法注入是 Spring 推荐的注入方式,它的缺点是如果有多个注⼊会显得比较臃肿,但出现这种情况你应该考虑⼀下当前类是否符合程序的单⼀职责的设计模式了。它的优点是通用性较强,不管是什么语言,构造方法的写法基本是类似的,而setter的写法很可能就不一样了,且在使用之前⼀定能把保证注⼊的类不为空。
Setter 方式是 Spring 前期版本推荐的注入方式,但通用性不如构造方法,所有 Spring 现版本已经推荐使用构造方法注入的方式来进行类注⼊了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值