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. Docker 学习5 Docker容器网络

    一.内核网络名称空间 1.可通过ip netns进行操作 [root@localhost /]# ip netns help Usage: ip netns list ip netns add NAM ...

  2. jedis keys和scan操作

    关于redis的keys命令的性能问题 KEYS pattern 查找所有符合给定模式 pattern 的 key . KEYS * 匹配数据库中所有 key . KEYS h?llo 匹配 hell ...

  3. MVC简单的增删改查

    最近的学习了一下mvc,现在做一个mvc的CRUD例子. 1.创建实体模型 2.创建一个UserInfo的控制器 3.查询数据 code public IList<UserInfo> us ...

  4. 磁共振成像SENSE 并行加速重建 g-factor计算方法(待更新)

    MRI SENSE 并行图像加速重建 g-factor计算方法: Matlab代码如下: function g=gfactor_noise(map,LOSS,Rx,Ry) % map -> se ...

  5. windows server 远程桌面连接问题。

    远程桌面连接相当于 linux 服务器root权限连接 mstsc /admin /v:目标IP mstsc /admin /

  6. Egret的按钮事件处理

    首先要在exml内要设置有对应按钮的ID 2,编写TypeScript脚本: public mybutton:eui.Button; 函数内部:this.mybutton.addEventListen ...

  7. Textarea设置自动高度

    $.fn.extend({ autoHeight: function() { return this.each(function() { var $this = jQuery(this); if(!$ ...

  8. java中的HMAC-SHA1加密

    public class Sha1Util { private static final String MAC_NAME = "HmacSHA1"; private static ...

  9. ios开发中的深拷贝和浅拷贝

    这是一个老生常谈的话题,面试中也经常被问到,下面总结一下自己的一些心得. 一句话总结: 浅拷贝就是指针拷贝: 深拷贝是对象本身的拷贝: 下面一张抽象的图可以直观的表述出两句话的内涵 其实这里还引申出了 ...

  10. vim 常用指令

    其他命令 <c-L> 重绘屏幕 <c-z> 挂起vim回到shell,想继续vim只需要输入 fg <c-x-f> 文件路径提示 <c-N> 当前文件中 ...