面试

关于一些通用性面试问题的思考

对一些面试问题的思考

你如何理解 Spring IOC / AOP 呢?

在面试中我们可能会被问到怎么理解 Spring IOC(或者说 Spring IOC 是什么?为什么Spring要使用IOC,IOC 和 DI 有什么不同吗?等等),那么面试官到底是要考察什么呢?

可能大部分人的回答都是类似这样:IOC 是控制反转,就是将创建对象的动作交给一个第三方容器去维护,并且由容器来管理对象间的依赖关系,可以在运行时动态注入(比如有构造函数注入、set注入、属性注入等),好处是我们不用使用new的方式来创建对象,将不同对象间的耦合降低到最低...

这样的回答是没有问题,但是不够出彩,因为你和大部分人理解的维度和高度是一样的;但是我理解,这个问题并不是那么的简单,在一个更高的认知高度和思考维度之后,会发现,这是一个和设计相关的问题,考察的是程序员最基本的系统设计能力、编程能力、设计思想、设计原则、设计思考等

  1. 从设计的角度看,在系统设计领域,有一个非常有名的设计原则:依赖反转原则 DIP,大致是讲:高层模块不要依赖低层模块,他们之间应该使用抽象来相互依赖;同时,抽象不要依赖具体实现细节,实现细节要依赖抽象。所谓高层模块和低层模块,可以简单理解为调用链上的调用者属于高层,被调用者属于低层;DIP 主要用来指导框架层面的设计。举个例子:Tomcat、Servlet 规范、Servlet 应用之间的关系,Servlet 应用部署在 Tomcat 容器中,Tomcat 容器可以执行 Servlet 应用,也就是 Tomcat 调用 Servlet 应用,所以 Tomcat 是高层模块,Servlet 应用是底层模块,但是他们两个不互相依赖,都只依赖于 Servlet 规范,Servlet 规范就是一个抽象,Tomcat 和 Servlet 应用都是具体的实现。可见它带来的好处是解耦合。和 DIP 类似,IoC 表示控制反转,我们可以降维到编码设计层面,通常情况下我们控制代码的方式是自己管理,如对象创建、对象依赖的组装等,但是在复杂的业务中,各种对象之间的关系可能会非常复杂,而且带有一定的重复性,我们可以把这些对象创建、依赖管理等这类重复工作做抽象,做成一个框架并留出必要的扩展点,这个时候,对象创建和依赖管理等的控制权就移交给框架来处理,程序员更多的精力放在业务开发上、类的设计上,至于对象之间的创建与编排工作交给框架来处理;所以IoC框架就是那个抽象(主要对对象创建和对象编排做抽象),业务代码和IoC容器都遵循我们的抽象去实现。再来说一下 IoC容器,其他它的实现方式有多种,比如依赖注入、模版设计模式等,

  2. 从简化编程的角度看,IoC 的运用简化编程过程,不用人工维护对象的编排过程

  3. 从代码可测性和可维护性上看,如果不使用 IoC 的方式,我们就需要使用大量的 new 操作,在对象内部new另外一个对象,是非常影响写单元测试的,最好的做法是使用构造函数传入,或者使用set函数传入,并且最好依赖于接口去编程,这样能提供更好的灵活性,然而这些事情就是 IoC 可以做到的,为什么不实用 IoC 的设计思想去设计一个更加通用的框架呢?

最后更新于