設計模式相關面試題目

設計模式理論

1.什麼是設計模式?你是否在你的代碼裏面使用過任何設計模式?
在軟件工程中,設計模式(design pattern)是對軟件設計中廣泛存在(反覆出現)的各類問題,所提出的解決方案。
平時用的比較多有單例模式(在內存中僅實例化一個對象時使用),適配器模式(典型的就是ListView和GridView的適配器),建造者模式(AlertDialog.Builder),觀察者模式可能比較隱蔽,在Android源碼中BaseAdapater的NotifyDataSetChanged的實現(?)。java

2.你能夠說出幾個在JDK庫中使用的設計模式嗎?web

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
Birdge 橋接模式:
這個模式將抽象和抽象操做的實現進行了解耦,這樣使得抽象和實現能夠獨立地變化。
GOF在提出橋樑模式的時候指出,橋樑模式的用意是 "將抽象化(Abstraction)與實現化(Implementation)脫耦,使得兩者能夠獨立地變化" 。這句話有三個關鍵詞,也就是抽象化、實現化和脫耦。
在Java應用中,對於橋接模式有一個很是典型的例子,就是應用程序使用JDBC驅動程序進行開發的方式。所謂驅動程序,指的是按照預先約定好的接口來操做計算機系統或者是外圍設備的程序。
 
Adapter 適配器模式:
用來把一個接口轉化成另外一個接口。使得本來因爲接口不兼容而不能一塊兒工做的那些類能夠在一塊兒工做。
java.util.Arrays#asList()
java.io.InputStreamReader(InputStream)
java.io.OutputStreamWriter(OutputStream)
 
Composite 組合模式:
又叫作部分-總體模式,使得客戶端看來單個對象和對象的組合是同等的。換句話說,某個類型的方法同時也接受自身類型做爲參數。
avax.swing.JComponent#add(Component)
java.util.Map#putAll(Map)
java.util.List#addAll(Collection)
java.util.Set#addAll(Collection)
 
裝飾者模式:
動態的給一個對象附加額外的功能,這也是子類的一種替代方式。能夠看到,在建立一個類型的時候,同時也傳入同一類型的對象。這在JDK裏隨處可見,你會發現它無處不在,因此下面這個列表只是一小部分。
java.io.BufferedInputStream(InputStream)
java.io.DataInputStream(InputStream)
java.io.BufferedOutputStream(OutputStream)
java.util.zip.ZipOutputStream(OutputStream)
java.util.Collections#checkedList|Map|Set|SortedSet|SortedMap
 
Facade 門面模式,即外觀模式:
給一組組件,接口,抽象,或者子系統提供一個簡單的接口。
java.lang.Class
javax.faces.webapp.FacesServlet
 
Flyweight 享元模式:
使用緩存來加速大量小對象的訪問時間。
java.lang.Integer#valueOf( int )
java.lang.Boolean#valueOf( boolean )
java.lang.Byte#valueOf( byte )
java.lang.Character#valueOf( char )
 
Proxy 代理模式:
代理模式是用一個簡單的對象來代替一個複雜的或者建立耗時的對象。
java.lang.reflect.Proxy
RMI
 
Abstract Factory 抽象工廠模式:
抽象工廠模式提供了一個協議來生成一系列的相關或者獨立的對象,而不用指定具體對象的類型。它使得應用程序可以和使用的框架的具體實現進行解耦。這在JDK或者許多框架好比Spring中都隨處可見。它們也很容易識別,一個建立新對象的方法,返回的倒是接口或者抽象類的,就是抽象工廠模式了。
java.util.Calendar#getInstance()
java.util.Arrays#asList()
java.util.ResourceBundle#getBundle()
java.sql.DriverManager#getConnection()
java.sql.Connection#createStatement()
java.sql.Statement#executeQuery()
java.text.NumberFormat#getInstance()
javax.xml.transform.TransformerFactory#newInstance()
 
 
抽象工廠模式
抽象工廠模式提供了一個協議來生成一系列的相關或者獨立的對象,而不用指定具體對象的類型。它使得應用程序可以和使用的框架的具體實現進行解耦。這在JDK或者許多框架好比Spring中都隨處可見。它們也很容易識別,一個建立新對象的方法,返回的倒是接口或者抽象類的,就是抽象工廠模式了。
java.util.Calendar#getInstance()
java.util.Arrays#asList()
java.util.ResourceBundle#getBundle()
java.sql.DriverManager#getConnection()
java.sql.Connection#createStatement()
java.sql.Statement#executeQuery()
java.text.NumberFormat#getInstance()
javax.xml.transform.TransformerFactory#newInstance()
 
Builder 建造者模式:
定義了一個新的類來構建另外一個類的實例,以簡化複雜對象的建立。建造模式一般也使用方法連接來實現。
java.lang.StringBuilder#append()
java.lang.StringBuffer#append()
java.sql.PreparedStatement
javax.swing.GroupLayout.Group#addComponent()
 
工廠方法:
就是一個返回具體對象的方法。
java.lang.Proxy#newProxyInstance()
java.lang.Object#toString()
java.lang.Class#newInstance()
java.lang.reflect.Array#newInstance()
java.lang.reflect.Constructor#newInstance()
java.lang.Boolean#valueOf(String)
java.lang.Class#forName()
 
原型模式
使得類的實例可以生成自身的拷貝。若是建立一個對象的實例很是複雜且耗時時,就可使用這種模式,而不從新建立一個新的實例,你能夠拷貝一個對象並直接修改它。
java.lang.Object#clone()
java.lang.Cloneable
 
單例模式
用來確保類只有一個實例。Joshua Bloch在Effetive Java中建議到,還有一種方法就是使用枚舉。
java.lang.Runtime#getRuntime()
java.awt.Toolkit#getDefaultToolkit()
java.awt.GraphicsEnvironment#getLocalGraphicsEnvironment()
java.awt.Desktop#getDesktop()
 
 
責任鏈模式
經過把請求從一個對象傳遞到鏈條中下一個對象的方式,直到請求被處理完畢,以實現對象間的解耦。
 
java.util.logging.Logger#log()
javax.servlet.Filter#doFilter()
命令模式
將操做封裝到對象內,以便存儲,傳遞和返回。
 
java.lang.Runnable
javax.swing.Action
解釋器模式
這個模式一般定義了一個語言的語法,而後解析相應語法的語句。
 
java.util.Pattern
java.text.Normalizer
java.text.Format
迭代器模式
提供一個一致的方法來順序訪問集合中的對象,這個方法與底層的集合的具體實現無關。
 
java.util.Iterator
java.util.Enumeration
中介者模式
經過使用一箇中間對象來進行消息分發以及減小類之間的直接依賴。
 
java.util.Timer
java.util.concurrent.Executor#execute()
java.util.concurrent.ExecutorService#submit()
java.lang.reflect.Method#invoke()
備忘錄模式
生成對象狀態的一個快照,以便對象能夠恢復原始狀態而不用暴露自身的內容。Date對象經過自身內部的一個 long 值來實現備忘錄模式。
 
java.util.Date
java.io.Serializable
空對象模式
這個模式經過一個無心義的對象來代替沒有對象這個狀態。它使得你不用額外對空對象進行處理。
 
java.util.Collections#emptyList()
java.util.Collections#emptyMap()
java.util.Collections#emptySet()
觀察者模式
它使得一個對象能夠靈活的將消息發送給感興趣的對象。
 
java.util.EventListener
javax.servlet.http.HttpSessionBindingListener
javax.servlet.http.HttpSessionAttributeListener
javax.faces.event.PhaseListener
狀態模式
經過改變對象內部的狀態,使得你能夠在運行時動態改變一個對象的行爲。
 
java.util.Iterator
javax.faces.lifecycle.LifeCycle#execute()
策略模式
使用這個模式來將一組算法封裝成一系列對象。經過傳遞這些對象能夠靈活的改變程序的功能。
 
java.util.Comparator#compare()
javax.servlet.http.HttpServlet
javax.servlet.Filter#doFilter()
模板方法模式
讓子類能夠重寫方法的一部分,而不是整個重寫,你能夠控制子類須要重寫那些操做。
 
java.util.Collections#sort()
java.io.InputStream#skip()
java.io.InputStream#read()
java.util.AbstractList#indexOf()
訪問者模式
提供一個方便的可維護的方式來操做一組對象。它使得你在不改變操做的對象前提下,能夠修改或者擴展對象的行爲。
 
javax.lang.model.element.Element and javax.lang.model.element.ElementVisitor
javax.lang.model.type.TypeMirror and javax.lang.model.type.TypeVisitor

  

3.Java中什麼是單例設計模式?用Java寫出線程安全的單例。
保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。
使用單例模式最核心的一點是體現了面向對象封裝特性中的「單一職責」和「對象自治」原則。
而且能夠節省系統開銷。算法

4.使用工廠模式最主要的好處是什麼?你在哪裏使用?
各模式的理解: 
簡單工廠:把對象的建立放到一個工廠類中,經過參數來建立不一樣的對象。 
工廠方法:每種產品由一種工廠來建立。(不這樣會有什麼問題?) 
抽象工廠:子工廠有一些相同的功能,將這些功能抽象放在父工廠中,每一個子工廠有這些公共行爲,還有本身的功能。sql

面向接口編程:設計模式的一個重要原則是 針對接口編程,不要依賴實現類。工廠模式遵循了這一個原則。 
開閉原則(Open-Closed Principle,OCP) 「Software entities should be open for extension,but closed for modification」。翻譯過來就是:「軟件實體應當對擴展開放,對修改關閉」。這句話說得略微有點專業,咱們把它講得更通俗一點,也就是:軟件系統中包含的各類組件,例如模塊(Modules)、類(Classes)以及功能(Functions)等等,應該在不修改現有代碼的基礎上,引入新功能。開閉原則中「開」,是指對於組件功能的擴展是開放的,是容許對其進行功能擴展的;開閉原則中「閉」,是指對於原有代碼的修改是封閉的,即不該該修改原有的代碼。編程

使用工廠的理由: 使開發者和對象的建立隔離開來。同時不在關心對象建立的細節
A.把對象的建立集中在一個地方(工廠中),在增長新的對象類型的時候,只須要改變工廠方法;不然在應用中四處散佈對象建立邏輯,若是建立方法改變時則須要四處修改,維護量增長. 
B.應用的場合是新的對象類型極可能常常被添加進來. 
C.你所關心的僅僅是工廠方法返回的接口方法,沒必要關心實現細節設計模式

5.在Java中,什麼叫觀察者設計模式(observer design pattern)?
觀察者模式又叫作發佈-訂閱(Publish/Subscribe)模式、模型-視圖(Model/View)模式、源-監聽器(Source/Listener)模式或從屬者(Dependents)模式。
一個軟件系統經常要求在某一個對象的狀態發生變化的時候,某些其它的對象作出相應的改變。作到這一點的設計方案有不少,可是爲了使系統可以易於複用,應該選擇低耦合度的設計方案。減小對象之間的耦合有利於系統的複用,可是同時設計師須要使這些低耦合度的對象之間可以維持行動的協調一致,保證高度的協做。
緩存

6.舉一個用Java實現的裝飾模式(decorator design pattern)?它是做用於對象層次仍是類層次?
動態地給一個對象增長一些額外的職責,就增長對象功能來講,裝飾模式比生成子類實現更爲靈活。裝飾模式是一種對象結構型模式。裝飾模式是一種用於替代繼承的技術,使用對象之間的關聯關係取代類之間的繼承關係。在裝飾模式中引入了裝飾類,在裝飾類中既能夠調用待裝飾的原有類的方法,還能夠增長新的方法,以擴充原有類的功能。
裝飾原有對象、在不改變原有對象的狀況下擴展加強新功能/新特徵.。當不能採用繼承的方式對系統進行擴展或者採用繼承不利於系統擴展和維護時可使用裝飾模式。
安全

7.什麼是MVC設計模式?舉一個MVC設計模式的例子?
MVC是一個設計模式,它強制性的使應用程序的輸入、處理和輸出分開。使用MVC應用程序被分紅三個核心部件:模型、視圖、控制器。它們各自處理本身的任務。app

 

參考:https://yq.aliyun.com/articles/38175框架

相關文章
相關標籤/搜索