> For the complete documentation index, see [llms.txt](https://shniu.gitbook.io/cs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://shniu.gitbook.io/cs/other/interview.md).

# 面试

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

对一些面试问题的思考

#### 你如何理解 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 的设计思想去设计一个更加通用的框架呢？
