一.Thread 和 Runnable 的区别
(1)Thread 是实现类而Runnable 是接口,所以继承只能单一继承而接口实现可以多实现,如果已经有继承关系的类要实现多线程只能实现Runnable 接口
(2)Runnable 表示一个线程的顶级接口,Thread 类其实是实现了 Runnable 这个接口,我们在使用的时候都需要实现 run 方法。站在面向对象的思想来说,Runnable 相当于一个任务,而 Thread 才是真正处理的线程,所以我们只需要用 Runnable 去定义一个具体的任务,然后交给Thread 去处理就可以了,这样达到了松耦合的设计目的
(3)接口表示一种规范或者标准,而实现类表示对这个规范或者标准的实现,所以站在线程的角度来说,Thread 才是真正意义上的线程实现。Runnable 表示线程要执行的任务,因此在线程池里面,提交一个任务传递的类型是 Runnable。
二.可以讲一下 ArrayList 的自动扩容机制吗
ArrayList 是一个数组结构的存储器默认情况下数组的长度是10,当然我可以自己定义长度,当随着程序不断的增加数据到ArrayList 中达到最大长度的时候,ArrayList 就没有空间存储数据量,这时候数组会自动扩容,首先会创建一个新的数组是之前数组长度的1.5倍然后然后使用Arrays.copyOf 方法把之前数组的中的值传给新的数组,扩容完成后再把当前要添加的元素加入到新的数组里面,从而完成动态扩容的过程。
三,谈谈你对 Spring IOC 和 DI 的理解
(1)在传统的 Java 程序开发中,我们只能通过 new 关键字来创建对象,这种导致程
序中对象的依赖关系比较复杂,耦合度较高。
(2)而 IOC 的主要作用是实现了对象的管理,也就是我们把设计好的对象交给了 IOC
(3)容器控制,然后在需要用到目标对象的时候,直接从容器中去获取。
有了 IOC 容器来管理 Bean 以后,相当于把对象的创建和查找依赖对象的控制
权交给了容器,这种设计理念使得对象与对象之间是一种松耦合状态,极大提升
了程序的灵活性以及功能的复用性。
控制反转的核心是:将对象的创建权交出去,将对象和对象之间关系的管理权交出去,由第三方容器来负责创建与维护。
然后,DI 表示依赖注入,也就是对于 IOC 容器中管理的 Bean,如果 Bean 之间
存在依赖关系,那么 IOC 容器需要自动实现依赖对象的实例注入,通常有三种
方法来描述 Bean 之间的依赖关系。
接口注入
setter 注入
构造器注入
另外,为了更加灵活的实现 Bean 实例的依赖注入,Spring 还提供了@Resource
和@Autowired 这两个注解。
分别是根据 bean 的 id 和 bean 的类型来实现依赖注入
四.为什么要使用 Spring 框架?
Spring 是一个轻量级应用框架,它提供了 IoC 和 AOP 这两个核心的功能。它的核心目的是为了简化企业级应用程序的开发,使得开发者只需要关心业务需求,不需要关心 Bean 的管理,以及通过切面增强功能减少代码的侵入性。从 Spring 本身的特性来看,我认为有几个关键点是我们选择 Spring 框架的原因。轻量:Spring 是轻量的,基本的版本大约 2MB。
IOC/DI:Spring 通过 IOC 容器实现了 Bean 的生命周期的管理,以及通过 DI 实
现依赖注入,从而实现了对象依赖的松耦合管理。
面向切面的编程(AOP):Spring 支持面向切面的编程,从而把应用业务逻辑和系
统服务分开。
MVC 框架:Spring MVC 提供了功能更加强大且更加灵活的 Web 框架支持
事务管理:Spring 通过 AOP 实现了事务的统一管理,对应用开发中的事务处理
提供了非常灵活的支持
最后,Spring 从第一个版本发布到现在,它的生态已经非常庞大了。在业务开
发领域,Spring 生态几乎提供了
五.Spring 中,有两个 id 相同的 bean,会报错吗,如果会报错,在哪个阶段报错
首先,在同一个XML配制文件中,不能存在id相同的两个bean,否则spring容器启动时候会报错,因为id这个属性表示bean的唯一标志符号,所以spring在启动的时候会去验证id的唯一性,一旦发现重复就会报错,这个错误发生在spring对xml文件进行解析转化为BeanDefinition的阶段。但是在两个不同的spring配置文件中,可以存在两个相同id的bean。ioc容器在加载bean的时候默认会对多个相同id的bean进行覆盖。
在spring3.x版本后,这个问题发生了变化,我们知道spring3.x里面提供给Configuration注解去声明一个配置类,然后使用@Bean注解实现Bean的声明,这种方式完全取代了Xml.
在这种情况下,如果我们在同一个配置文件里面声明多个相同名字的bean,在SpringIoc容器中只会注册第一个声明的Bean的实例。后序重复的Bean就不会再注册了,
如果使用@Autowired 注解根据类型实现依赖注入,因为 IOC 容器只有UserService01的实例,所以启动的时候会提示找不到UserService02这个实例如果使用@Resource 注解根据名词实现依赖注入,在 IOC 容器里面得到的实例对象是 UserService01,于是 Spring 把 UserService01 这个实例赋值给 UserService02,就会提示类型不匹配错误。这个错误,是在 Spring IOC 容器里面的 Bean 初始化之后的依赖注入阶段发生的。