8.6.4.1请实现一个线程安全的单例模式。

1      public class MailListReader {

2          private static MailListReader reader = null;

3          private MailListReader(){}//构造函数私有

4           public static MailListReader getInstance() {

5              if(singleton == null){

6                 synchronized (Singleton.class){

7                   if(singleton == null){

8                            singleton = new Singleton();

9                    }

10                  }

11               }

12               return reader;

13          }

14          //省略提供邮件列表的方法

15      }

8.6.4.2工厂模式有哪几类?使用工厂模式最主要的好处是什么?你在项目里是怎么使用工厂模式的?

工厂模式(Factory Method)是用来向使用者屏蔽创建对象的细节。之前我们在讲SAX解析XML文件时,已经用到过工厂模式,当时我们是通过如下代码用SAXParserFacotry这个工厂对象来创建用于解析的parse对象,代码如下所示。

1      SAXParserFactory factory = SAXParserFactory.newInstance();

2      SAXParser parser = factory.newSAXParser();

作为使用者,我们只要能得到parser对象进行后继的解析动作,至于parser对象是如何创建的,我们不需要,也不应管。如果不用工厂模式,那么我们还得亲自关注如何创建parser对象,比如得考虑创建时传入的参数,以及是否改用“池”的方式来创建从而提升效率。

这样亲力亲为的后果是,会让使用和创建parser对象的代码耦合度很高,这样一旦创建parser的方法发生改变,比如日后需要传入不同的参数,那么使用parser的代码也需要对应修改。

大家别以为增加修改量没什么大不了,如果我们在某个模块里修改了代码,哪怕这个修改点再小,也得经过完整的测试才能把这段代码放入生产环境,这是需要工作量的。如果我们把“使用”和“创建”对象放在一个模块里,那么“使用”部分的代码也得测试(虽然没改),但我们通过了工厂模式分离了两者,那么只需要测“创建”模块,就可以减少工作量了。

更多内容请看本书8.2.2到8.2.4部分

8.6.4.3 你在平时的开发过程中用过哪些设计模式?

在本书的第8章里,已经列了关于观察者等模式的说辞,下面,我们进一步给出讲述设计模式(乃至设计思想)的说辞。

我们在8.5.3讲述里氏替换原则时,已经给出了“在面试中不露痕迹引出设计模式话题“的一些方法,这里我们将给出展示自己 设计模式能力的方法,大家一定得在面试前,根据这里给出的四个关键说明点做好充分的准备,临时准备一定是达不到好的效果的。

说明点一,通过案例场景引出你准备说的模式。

这里可以从你简历中的最近做的一个项目里提炼一个例子,比如就拿观察者模式里的“牛人发文章邮件通知粉丝”为例,大家可以先描述下项目的场景(也就是要解决的实际问题)。

说明点二,引出待使用的设计模式。

这里需要说出你引用的场景和设计模式的切合点,比如这里需求的关键点在于“状态改变后需通知依赖对象”,这和观察者模式的适用场景一致。

说明点三,结合项目实际,通过代码等方式说明设计模式。

比如这里可以通过项目里的相关类,以及类之间的继承和调用关系来说明你是怎么实现观察者模式的,比如通知类、文章管理类和调用类分别是如何实现的,同时说明它们之间的调用关系。

说明点四,结合设计原则,说出自己对设计模式的理解。

最好再说下自己对设计模式的理解,否则你的层次可能只停留在“会用设计模式解决实际问题”(当然这也已经不错了),而不是“具有一定的架构设计和优化能力”(这是更好的评价)。

这里给出一些“出彩”的语句给大家参考。

1 其实我们使用设计模式的根本原因是提升项目的可维护性。(大家都知道,但你得说)

2 我们在解决这个(你举的例子)问题时,除了用到设计模式之外,还会尽量注意设计模式背后蕴含的思想,比如在设计观察者类时,我们不在其中放其它种类的业务代码,这符合单一职责模式,而且我们定义类之间的关系时,会遵循“合成复用原则“,只在具有从属关系的类之间才使用继承,否则会使用聚合或组合。(最好再通过实例说明,如果可以,再结合项目实例引入其它的原则)

3 在项目里,我们经常会收到需求变更,当我们引入设计模式(或原则)后,发现能让项目拥抱修改。

随后举个例子说明,比如之前的代码没有很好遵循单一职责模式,在一些重要方法里放了多种逻辑,在几次修改后,我们痛定思痛决定重构代码,重构后的方法里只包含了一类逻辑,之后再修改的时候,我们的测试工作量就能大幅度降低了。

4 我现在感觉是,设计模式不仅能给出具体的解决方案,还能提供优化系统架构的思路,所以在项目里,我们一般不会只用其中某个,而会根据一些原则来优化我们的代码。

比如在定义模块和方法时,根据单一职责原则,我们尽量只在其中引入一类逻辑,在定义子类方法时,根据里氏替换原则,如果子类要扩展功能,我们是会在其中添加新的方法,而不是覆盖父类的非抽象方法,又如,根据合成复用原则,我们只把具有逻辑从属关系的类定义成父子类,否则是用组合或聚合来定义类之间的耦合关系。

总之,大家如果能在面试中按上述四个“说明点”层层递进地展示自己设计模式方面的能力,就一定能得到“精通设计模式”乃至“有一定的系统架构设计和优化经验”之类的评价,这类评语在同等条件下能很大程度地帮助大家成功地在竞争者中脱颖而出,从而得到心仪的岗位。

Java核心技术及面试指南 设计模式部分的面试题总结以及答案的更多相关文章

  1. Java核心技术及面试指南 JDBC部分的面试题总结以及答案

    5.5.1 你最近的项目里用到的是哪个数据?或你用过哪些数据库?或你对哪个数据库最熟悉? 通过这个问题,我们将会确认候选人是否在项目里用过数据库或JDBC. 5.5.2 你有没有建过表?或修改表里的字 ...

  2. Java核心技术及面试指南 集合部分总的面试题归纳以及答案

    3.6.1ArrayList和LinkedList有什么差别?在哪种场景里应当用ArrayList(或LinkedList)? 大家如果学过数据结构,这个问题不难回答:前者是基于数组,数组比较擅长索引 ...

  3. Java核心技术及面试指南 IO部分的面试题归纳以及答案

    4.6.1 java中有几种类型的流? Java中的流分为两种,一种是字节流,另一种是字符流,分别由四个抽象类来表示(每种流包括输入和输出两种所以一共四个):InputStream,OutputStr ...

  4. Java核心技术及面试指南 面向对象部分的面试题总结以及答案

    问题2.7.1,开放性问题,说一下你对面向对象思想的了解. 要点1,先说基础概念,比如面向对象思想包括封装.继承.多态,然后说些语法,比如可以通过extends继承类.通过implement来实现接口 ...

  5. Java核心技术及面试指南 多线程部分的基本面试题总结以及答案

    7.1.5 (1) 如果某个类已经继承(extends)了一个类,那么让这个类具有多线程的特性? implements runnable类或通过线程池 7.1.5  (2)启动一个线程是用run()还 ...

  6. Java核心技术及面试指南 异常部分的面试题归纳以及答案

    4.2.4.1 throw和throws有什么差别?异常(Exception)和错误(Error)有什么差别? throw语句表示抛出异常,由方法体内的语句处理.throws语句用在方法声明后面,表示 ...

  7. Java核心技术及面试指南 数据库方面的面试题归纳以及总结

    5.1.7.1 事务的四大特性是什么? ⑴ 原子性(Atomicity) 原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚. ⑵ 一致性(Consistency) 一致性是指事务必须使数据库 ...

  8. Java核心技术及面试指南的视频讲解和代码下载位置

    都是百度云盘,均无密码 代码下载位置: https://pan.baidu.com/s/1I44ob0vygMxvmj2BoNioAQ 视频讲解位置: https://pan.baidu.com/s/ ...

  9. Java核心技术及面试指南:视频列表

    如下是本书相关内容的视频列表,会动态更新 第一章 1 视频1.1  JDK和JRE和JVM的区别,安装Java开发环境    1.1.1  第2页 2 视频1.2  编写第一个HelloWorld程序 ...

随机推荐

  1. 关于Hbase开启snappy压缩

    版本:自己编译的hbase-1.2.0-cdh5.14.0 默认情况下,Hbase不开启snappy压缩 , 所以在hbase的lib/native目录下什么也没有(我的前提是执行hadoop che ...

  2. 分布式缓存技术之Redis_04Redis的应用实战

    目录 1 Redis Java客户端的使用 Jedis 单点连接 Jedis sentinel连接哨兵集群 Jedis sentinel源码分析 Jedis Cluster分片环境连接 Jedis C ...

  3. HTML5+CSS3 1

    html5标准模板 <!DOCTYPE html>   //<!DOCTYPE>标签 向浏览器声明当前文档使用的HTML版本,<!DOCTYPE html>适用于所 ...

  4. Java 扫描实现 Ioc 动态注入,过滤器根据访问url调用自定义注解标记的类及其方法

    扫描实现 Ioc 动态注入 参考: http://www.private-blog.com/2017/11/16/java-%e6%89%ab%e6%8f%8f%e5%ae%9e%e7%8e%b0-i ...

  5. ABC113 AK失败记

    众所周知, ABC是一场水题盛宴, 也是一场AK盛宴. 但是我却没能AK. 原因也十分可笑: 我在一开始觉得题目太简单, 颓废了.直到我看了第4题之后才找到状态并A了此题...最后时间来不及第三题最后 ...

  6. matplotlia应用

    一.简单使用 使用函数 plt.polt(x,y,label,color,width) 根据x,y 数组 绘制直,曲线 import numpy as np #引用numpy库,从新命名它为np(以后 ...

  7. tar解压到指定目录

    对于tar.gz的压缩包,压缩参数是tar xvzf 指定解压路径为/tmp则为: tar xzvf xxx.tar.gz -C /tmp 注意/文件夹必须存在.

  8. thrift小试--C++

    [转自]http://blog.csdn.net/poechant/article/details/6618284# Thrift可以实现C++.Java.Python等多种语言的自动生成,此处以C+ ...

  9. vue基于webpack说明

    1.文件build里的check-versions.js:检查node和npm版本, 此文件里的 (1)require('chalk')引入一个模块,定义输入终端样式 (2) require('sem ...

  10. 请问浏览器访问www.baidu.com经历了怎样的过程?

    1.查找浏览器缓存 首先会查找浏览器缓存,浏览器会保存一段时间你之前访问过的网址的DNS信息,不同的浏览器保存的时长不等. 2.查找系统缓存 如果上面的步骤没有找到对应的DNS信息,这个时候浏览器会尝 ...