关于 OOP 和设计模式的面试题
这部分包含 Java 面试过程中关于 SOLID 的设计原则,OOP 基础,如类,对象, 接口,继承,多态,封装,抽象以及更高级的一些概念,如组合、聚合及关联。 也包含了 GOF 设计模式的问题。
103、接口是什么?为什么要使用接口而不是直接使用具体类?
接口用于定义 API。它定义了类必须得遵循的规则。同时,它提供了一种抽象, 因为客户端只使用接口,这样可以有多重实现,如 List 接口,你可以使用可随机 访问的 ArrayList,也可以使用方便插入和删除的 LinkedList。接口中不允许写 代码,以此来保证抽象,但是 Java 8 中你可以在接口声明静态的默认方法,这 种方法是具体的。
104、Java 中,抽象类与接口之间有什么不同?
Java 中,抽象类和接口有很多不同之处,但是最重要的一个是 Java 中限制一个 类只能继承一个类,但是可以实现多个接口。抽象类可以很好的定义一个家族类 的默认行为,而接口能更好的定义类型,有助于后面实现多态机制。
105、除了单例模式,你在生产环境中还用过什么设计模式?
这需要根据你的经验来回答。一般情况下,你可以说依赖注入,工厂模式,装饰 模式或者观察者模式,随意选择你使用过的一种即可。不过你要准备回答接下的 基于你选择的模式的问题。
106、你能解释一下里氏替换原则吗?
答案 https://blog.csdn.net/pu_xubo565599455/article/details/51488323
107、什么情况下会违反迪米特法则?为什么会有这个问题?
迪米特法则建议“只和朋友说话,不要陌生人说话”,以此来减少类之间的耦合。
108、适配器模式是什么?什么时候使用?
适配器模式提供对接口的转换。如果你的客户端使用某些接口,但是你有另外一 些接口,你就可以写一个适配去来连接这些接口。
109、什么是“依赖注入”和“控制反转”?为什么有人使用?
控制反转(IOC)是 Spring 框架的核心思想,用我自己的话说,就是你要做一件 事,别自己可劲 new 了,你就说你要干啥,然后外包出去就好~
依赖注入(DI) 在我浅薄的想法中,就是通过接口的引用和构造方法的表达,将 一些事情整好了反过来传给需要用到的地方~
110、抽象类是什么?它与接口有什么区别?你为什么要使用过 抽象类?
接口用于规范,抽象类用于共性.
声明方法的存在而不去实现它的类被叫做抽象类
接口(interface)是抽象类的变体。在接口中,所有方法都是抽象的。
111、构造器注入和 setter 依赖注入,那种方式更好?
每种方式都有它的缺点和优点。构造器注入保证所有的注入都被初始化,但是 setter 注入提供更好的灵活性来设置可选依赖。如果使用 XML 来描述依赖, Setter 注入的可读写会更强。经验法则是强制依赖使用构造器注入,可选依赖使 用 setter 注入。
112、依赖注入和工程模式之间有什么不同?
虽然两种模式都是将对象的创建从应用的逻辑中分离,但是依赖注入比工程模式 更清晰。通过依赖注入,你的类就是 POJO,它只知道依赖而不关心它们怎么获 取。使用工厂模式,你的类需要通过工厂来获取依赖。因此,使用 DI 会比使用 工厂模式更容易测试。
113、适配器模式和装饰器模式有什么区别?
虽然适配器模式和装饰器模式的结构类似,但是每种模式的出现意图不同。适配 器模式被用于桥接两个接口,而装饰模式的目的是在不修改类的情况下给类增加 新的功能。
114、适配器模式和代理模式之前有什么不同?
这个问题与前面的类似,适配器模式和代理模式的区别在于他们的意图不同。由 于适配器模式和代理模式都是封装真正执行动作的类,因此结构是一致的,但适配器模式用于接口之间的转换,而代理模式则是增加一个额外的中间层,以便 支持分配、控制或智能访问
115、什么是模板方法模式?
模板方法提供算法的框架,你可以自己去配置或定义步骤。例如,你可以将排序 算法看做是一个模板。它定义了排序的步骤,但是具体的比较,可以使用 Comparable 或者其语言中类似东西,具体策略由你去配置。列出算法概要的方 法就是众所周知的模板方法
116、什么时候使用访问者模式?
访问者模式用于解决在类的继承层次上增加操作,但是不直接与之关联。这种模 式采用双派发的形式来增加中间层。
117、什么时候使用组合模式?
组合模式使用树结构来展示部分与整体继承关系。它允许客户端采用统一的形式 来对待单个对象和对象容器。当你想要展示对象这种部分与整体的继承关系时采 用组合模式。
118、继承和组合之间有什么不同?
虽然两种都可以实现代码复用,但是组合比继承共灵活,因为组合允许你在运行 时选择不同的实现。用组合实现的代码也比继承测试起来更加简单。
119、描述 Java 中的重载和重写?
重载和重写都允许你用相同的名称来实现不同的功能,但是重载是编译时活动, 而重写是运行时活动。你可以在同一个类中重载方法,但是只能在子类中重写方 法。重写必须要有继承。
120、Java 中,嵌套公共静态类与顶级类有什么不同?
类的内部可以有多个嵌套公共静态类,但是一个 Java 源文件只能有一个顶级公 共类,并且顶级公共类的名称与源文件名称必须一致。
121、 OOP 中的 组合、聚合和关联有什么区别?
如果两个对象彼此有关系,就说他们是彼此相关联的。组合和聚合是面向对象中 的两种形式的关联。组合是一种比聚合更强力的关联。组合中,一个对象是另一 个的拥有者,而聚合则是指一个对象使用另一个对象。如果对象 A 是由对象 B组合的,则 A 不存在的话,B 一定不存在,但是如果 A 对象聚合了一个对象 B, 则即使 A 不存在了,B 也可以单独存在。
122、给我一个符合开闭原则的设计模式的例子?
开闭原则要求你的代码对扩展开放,对修改关闭。这个意思就是说,如果你想增 加一个新的功能,你可以很容易的在不改变已测试过的代码的前提下增加新的码。有好几个设计模式是基于开闭原则的,如策略模式,如果你需要一个新的策 略,只需要实现接口,增加配置,不需要改变核心逻辑。一个正在工作的例子是 Collections.sort() 方法,这就是基于策略模式,遵循开闭原则的,你不需为新的 对象修改 sort() 方法,你需要做的仅仅是实现你自己的 Comparator 接口。
123、抽象工厂模式和原型模式之间的区别?
抽象工厂模式:通常由工厂方法模式来实现。但一个工厂中往往含有多个工厂方 法生成一系列的产品。这个模式强调的是客户代码一次保证只使用一个系列的产 品。当要切换为另一个系列的产品,换一个工厂类即可。
原型模式:工厂方法的最大缺点就是,对应一个继承体系的产品类,要有一个同 样复杂的工厂类的继承体系。我们可以把工厂类中的工厂方法放到产品类自身中吗?如果这样的话,就可以将两个继承体系为一个。这也就是原型模式的思想, 原型模式中的工厂方法为 clone,它会返回一个拷贝(可以是浅拷贝,也可以是深 拷贝,由设计者决定)。为了保证用户代码中到时可以通过指针调用 clone 来动 态绑定地生成所需的具体的类。这些原型对象必须事先构造好。
原型模式想对工厂方法模式的另一个好处是,拷贝的效率一般对构造的效率要高。
124、什么时候使用享元模式?
享元模式通过共享对象来避免创建太多的对象。为了使用享元模式,你需要确保 你的对象是不可变的,这样你才能安全的共享。JDK 中 String 池、Integer 池 以及 Long 池都是很好的使用了享元模式的例子。
Java 面试中其他各式各样的问题
这部分包含 Java 中关于 XML 的面试题,正则表达式面试题,Java 错误和异常 及序列化面试题
125、嵌套静态类与顶级类有什么区别?
一个公共的顶级类的源文件名称与类名相同,而嵌套静态类没有这个要求。一个 嵌套类位于顶级类内部,需要使用顶级类的名称来引用嵌套静态类,如 HashMap.Entry 是一个嵌套静态类,HashMap 是一个顶级类,Entry 是一个嵌 套静态类。
126、你能写出一个正则表达式来判断一个字符串是否是一个数 字吗?
一个数字字符串,只能包含数字,如 0 到 9 以及 +、- 开头,通过这个信息, 你可以下一个如下的正则表达式来判断给定的字符串是不是数字。
1首先要 import java.util.regex.Pattern 和 java.util.regex.Matcher
2public boolean isNumeric(String str){
3Pattern pattern = Pattern.compile("[0-9]*");
4Matcher isNum = pattern.matcher(str);
5if( !isNum.matches() ){
6return false;
7}
8return true;
9}
127、Java 中,受检查异常 和 不受检查异常的区别?
受检查异常编译器在编译期间检查。对于这种异常,方法强制处理或者通过 throws 子句声明。其中一种情况是 Exception 的子类但不是 RuntimeException 的子类。非受检查是 RuntimeException 的子类,在编译阶 段不受编译器的检查。
128、Java 中,throw 和 throws 有什么区别
throw 用于抛出 java.lang.Throwable 类的一个实例化对象,意思是说你可以通 过关键字 throw 抛出一个 Error 或者 一个 Exception,如: throw new IllegalArgumentException(“size must be multiple of 2″ )
而 throws 的作用是作为方法声明和签名的一部分,方法被抛出相应的异常以便 调用者能处理。Java 中,任何未处理的受检查异常强制在 throws 子句中声明。
129、Java 中,Serializable 与 Externalizable 的区别?
Serializable 接口是一个序列化 Java 类的接口,以便于它们可以在网络上传输 或者可以将它们的状态保存在磁盘上,是 JVM 内嵌的默认序列化方式,成本高、 脆弱而且不安全。Externalizable 允许你控制整个序列化过程,指定特定的二进 制格式,增加安全机制。
130、Java 中,DOM 和 SAX 解析器有什么不同?
DOM 解析器将整个 XML 文档加载到内存来创建一棵 DOM 模型树,这样可以 更快的查找节点和修改 XML 结构,而 SAX 解析器是一个基于事件的解析器, 不会将整个 XML 文档加载到内存。由于这个原因,DOM 比 SAX 更快,也要 求更多的内存,不适合于解析大 XML 文件。
131、说出 JDK 1.7 中的三个新特性?
虽然 JDK 1.7 不像 JDK 5 和 8 一样的大版本,但是,还是有很多新的特性, 如 try-with-resource 语句,这样你在使用流或者资源的时候,就不需要手动关 闭,Java 会自动关闭。Fork-Join 池某种程度上实现 Java 版的 Map-reduce。 允许 Switch 中有 String 变量和文本。菱形操作符(<>)用于类型推断,不再需 要在变量声明的右边申明泛型,因此可以写出可读写更强、更简洁的代码。另个值得一提的特性是改善异常处理,如允许在同一个 catch 块中捕获多个异常。
132、说出 5 个 JDK 1.8 引入的新特性?
Java 8 在 Java 历史上是一个开创新的版本,下面 JDK 8 中 5 个主要的特性: Lambda 表达式,允许像对象一样传递匿名函数 Stream API,充分利用现代多核 CPU,可以写出很简洁的代码 Date 与 Time API,最终,有一个稳定、简单的日期和时间库可供你使用 扩展方法,现在,接口中可以有静态、默认方法。 重复注解,现在你可以将相同的注解在同一类型上使用多次。
133、Java 中,Maven 和 ANT 有什么区别?
虽然两者都是构建工具,都用于创建 Java 应用,但是 Maven 做的事情更多, 在基于“约定优于配置”的概念下,提供标准的 Java 项目结构,同时能为应用自 动管理依赖(应用中所依赖的 JAR 文件),Maven 与 ANT 工具更多的不同之 处请参见答案。
后续
这就是所有的面试题,如此之多,是不是?我可以保证,如果你能回答列表中的 所有问题,你就可以很轻松的应付任何核心 Java 或者高级 Java 面试。虽然, 这里没有涵盖 Servlet、JSP、JSF、JPA,JMS,EJB 及其它 Java EE 技术,也 没有包含主流的框架如 Spring MVC,Struts 2.0,Hibernate,也没有包含 SOAP 和 RESTful web service,但是这份列表对做 Java 开发的、准备应聘 Java web 开发职位的人还是同样有用的,因为所有的 Java 面试,开始的问题都是 Java 基 础和 JDK API 相关的。如果你认为我这里有任何应该在这份列表中而被我遗漏了 的 Java 流行的问题,你可以自由的给我建议。我的目的是从最近的面试中创建一份最新的、最优的 Java 面试问题列表。