### 設計模式
#### 1、你所知道的設計模式有哪些?
> * 參考回答:
> * **創建型模式,共五種**:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。
> * **結構型模式,共七種**:適配器模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。
> * **行為型模式,共十一種**:策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄 模式、狀態模式、訪問者模式、中介者模式、解釋器模式。
#### 2、談談MVC、MVP和MVVM,好在哪里,不好在哪里 ?
> * 參考回答:
> * **MVC**:
> * 視圖層(View) 對應于xml布局文件和java代碼動態view部分
> * 控制層(Controller) MVC中Android的控制層是由Activity來承擔的,Activity本來主要是作為初始化頁面,展示數據的操作,但是因為XML視圖功能太弱,所以Activity既要負責視圖的顯示又要加入控制邏輯,承擔的功能過多。
> * 模型層(Model) 針對業務模型,建立數據結構和相關的類,它主要負責網絡請求,數據庫處理,I/O的操作。
> * 總結
> * 具有一定的分層,model徹底解耦,controller和view并沒有解耦層與層之間的交互盡量使用回調或者去使用消息機制去完成,盡量避免直接持有 controller和view在android中無法做到徹底分離,但在代碼邏輯層面一定要分清業務邏輯被放置在model層,能夠更好的復用和修改增加業務。
> * **MVP**
> * 通過引入接口BaseView,讓相應的視圖組件如Activity,Fragment去實現BaseView,實現了視圖層的獨立,通過中間層Preseter實現了Model和View的完全解耦。MVP**徹底解決**了MVC中View和Controller傻傻分不清楚的問題,但是隨著業務邏輯的增加,一個頁面可能會非常復雜,UI的改變是非常多,會有非常多的case,這樣就會造成View的接口會很龐大。
> * **MVVM**
> * MVP中我們說過隨著業務邏輯的增加,UI的改變多的情況下,會有非常多的跟UI相關的case,這樣就會造成View的接口會很龐大。而MVVM就解決了這個問題,通過雙向綁定的機制,實現數據和UI內容,只要想改其中一方,另一方都能夠及時更新的一種設計理念,這樣就省去了很多在View層中寫很多case的情況,只需要改變數據就行。
> * 三者如何選擇?
> * 如果項目簡單,沒什么復雜性,未來改動也不大的話,那就不要用設計模式或者架構方法,只需要將每個模塊封裝好,方便調用即可,不要為了使用設計模式或架構方法而使用。
> * 對于偏向展示型的app,絕大多數業務邏輯都在后端,app主要功能就是展示數據,交互等,建議使用mvvm。
> * 對于工具類或者需要寫很多業務邏輯app,使用mvp或者mvvm都可。
> * 推薦文章:[MVC、MVP、MVVM,我到底該怎么選?](https://juejin.im/post/5b3a3a44f265da630e27a7e6)
#### 3、封裝p層之后.如果p層數據過大,如何解決?
> * 參考回答:
> * 對于MVP模式來說,P層如果數據邏輯過于臃腫,建議引入**RxJava**或則**Dagger**,越是復雜的邏輯,越能體現RxJava的優越性
> * 推薦文章:[(仿有道精品課)RxJava+OkHttp+Retrofit+Dagger2+MVP框架(kotlin版本)](https://juejin.im/post/5c6e601cf265da2dc675b69e#comment)
#### 4、是否能從Android中舉幾個例子說說用到了什么設計模式 ?
> * 參考回答:
> * **AlertDialog、Notification源碼中使用了Builder(建造者)模式完成參數的初始化**
> * **Okhttp內部使用了責任鏈模式來完成每個Interceptor攔截器的調用**
> * **RxJava的觀察者模式;單例模式;GridView的適配器模式;Intent的原型模式**
> * **日常開發的BaseActivity抽象工廠模式**
#### 5、裝飾模式和代理模式有哪些區別 ?
> * 參考回答:
> * 裝飾器模式與代理模式的區別就在于
> * 兩者都是對類的方法進行**擴展**,但**裝飾器模式**強調的是增強自身,在被裝飾之后你能夠在被增強的類上使用增強后的功能。
> * 而**代理模式**則強調要讓別人幫你去做一些本身與你業務沒有太多關系的職責(記錄日志、設置緩存)代理模式是為了實現對象的控制,因為被代理的對象往往難以直接獲得或者是其內部不想暴露出來。
#### 6、實現單例模式有幾種方法 ?懶漢式中雙層鎖的目的是什么 ?兩次判空的目的又是什么 ?
> * 參考回答:
> * 單例模式實現方法有多種:**餓漢,懶漢(線程安全,線程非安全),雙重檢查(DCL),內部類,以及枚舉**
> * 所謂**雙層檢驗鎖(在加鎖前后對實例對象進行兩次判空的檢驗)**:加鎖是為了第一次對象實例化的線程同步,而鎖內還要有第二層判空是因為可能會有多個線程進入第一層if判斷內部,而在加鎖代碼塊外排隊等候,如果鎖內不進行第二次檢驗,仍然會出現實例化多個對象的情況。
> * 推薦文章:[單例模式的總結](https://xxxblank.github.io/2017/09/14/singleTon/)
#### 7、用到的一些開源框架,介紹一個看過源碼的,內部實現過程。
> * 參考回答:
> * 面試常客:Okhttp,Retrofit,Glide,RxJava,GreenDao,Dagger等
> * 推薦文章:
> * [Android OkHttp源碼解析入門教程(一)](https://juejin.im/post/5c46822c6fb9a049ea394510)
> * [Android OkHttp源碼解析入門教程(二)](https://juejin.im/post/5c4682d2f265da6130752a1d)
#### 8、Fragment如果在Adapter中使用應該如何解耦?
> * 參考回答:
> * 接口回調
> * 廣播