零、概述
架構/框架問題主要用於考察中高級、資深工程師。
1、爲什麼要在APP中引入框架?他有什麼好處呢?
1)、模塊化
2)、分層
3)、解耦
4)、降低代碼重合度
一、圖片緩存
1、怎麼設計一個圖片緩存框架?
2、圖片通過什麼樣的方式進行讀寫,過程是怎樣的?
以圖片URL的單向Hash值作爲key進行存儲。讀取流程其實就是瀏覽器的緩存讀取流程,如下:
3、內存的設計上需要考慮哪些問題?
1)、存儲的size
2)、淘汰策略
有兩種策略:以隊列先進先出的方式淘汰、LRU算法(即最近最久未使用算法)。
淘汰的時機有兩種:定時檢查(非常low,非常損耗性能)、提高檢查觸發頻率(每次進行讀寫時檢查、前後臺切換時檢查,這兩種檢查相對性能比較好)。
4、磁盤的設計上需要考慮哪些問題?
1)、存儲的size
2)、淘汰策略
3)、存儲方式
5、網絡部分的設計上需要考慮哪些問題?
1)、圖片請求最大併發量
2)、請求超時策略
3)、請求優先級:用戶當前緊急使用的優先級高一些。
6、對於不同格式的圖片,解碼採用什麼方式來做?
應用策略模式對不同的格式進行解碼
7、在哪個階段做圖片解碼處理?
在磁盤讀取後和網絡請求返回後進行解碼處理,因爲將圖片解碼後放到內存中可以減少顯示時CPU的壓力。
8、圖片緩存框架時序圖
二、閱讀時長統計
1、怎樣設計一個時長統計框架?
2、爲何要有不同類型的記錄器,你的考慮是什麼?
基於不同分類場景提供提供關於記錄的封裝、適配。
3、記錄的數據會由於某種原因丟失,如何降低丟失呢?
1)、定時寫磁盤
2)、限定內存緩存條數(如10條),超過該條數就寫磁盤
4、上傳器關於延時上傳的具體場景有哪些?
實時上傳太消耗性能,所以需要使用延時上傳,常用場景如下:
1)、前後臺切換
2)、從無網到有網的變化
3)、通過輕量接口捎帶。這條不符合企業級實現。
三、複雜頁面架構(一般的頁面MVC就夠了)
1、怎樣的頁面算複雜頁面呢?
比如微博APP的正文頁、去哪網航班列表頁今日頭條等資訊類APP的多籤首頁。
2、複雜頁面設計要考察的內容
1)、整體架構
視圖層View中的操作:控件初始化、設置數據、交互事件通過代理控制
視圖層VC中的操作:視圖創建、組合;邏輯協調;View事件代理/回調的處理。
業務邏輯層ViewModel操作:業務邏輯處理,如將數據預排版;封裝數據的增刪改查(只是封裝,並不是增刪改查的實現);線程安全處理。
數據層Engine操作:網絡請求、數據解析、增刪改查(我認爲一般用不到,只有向數據庫存儲時涉及)、本地邏輯處理(如Sever數據的適配)。
我的理解:大公司的話人員多要求質量,會用到Engine,小公司一般沒有,一般圖中Engine的層級都已經是網絡層了。分層帶來代碼結構清晰易於維護,但是增加複雜度和成本,所以有些小公司連ViewModel層都不實現,直接都在VC中實現。
2)、數據流
網絡數據我理解的就是網絡傳輸過來的數據,一般爲json;業務數據一般是json轉化出來的model;UI數據比較複雜,是一個對象,對象包括frame和value兩個屬性。
3)、反向更新
很簡單,就是頁面初始的網絡刷新、用戶交互行爲去通過VC->ViewModel->Engine加載數據,數據加載完後刷新頁面。
作者所講的反向更新是先給ViewModel數據打髒標記,數據更新回來後由ViewModel去遍歷髒標記更新。用到了系統UIView更新機打髒標記思想和ReactNative的數據流思想。但是我覺得這樣太繁瑣,還是我的好。
3、複雜頁面架構用到的思想
1)、MVVM框架思想
2)、ReactNative的數據流思想
子節點沒有決定自己更新的權利,必須交給根節點遍歷決定(根據各節點是否有髒標記遍歷節點是否需要更細),即數據流是單向的。
3)、系統UIView更新機制思想==我不覺得反向更新用到視圖更新時打髒標記的思想
4)、FaceBook的開源框架AsyncDisplayKit關於預排版的設計思想
四、客戶端整體架構
1、客戶端的整體架構是怎樣的?
中間層:起到協調和解耦上層業務層各個業務的作用。
通用業務層(即當下App通用的組件,該App的各個業務線都需要用,但是另一個App不一定能用):自定義的步進控件、UIImageView的封裝。
獨立於App的通用層(即各個App通用功能):時長統計、日誌統計、網絡請求封裝。
架構如上設計的話比較有彈性,很容易把某個/某些業務單拎出來稱爲新的App。
2、業務層各業務之間如何解耦?
1)、OpenURL
2)、依賴注入
需求:業務A需要調用業務C的某個功能。
解決:業務C注入中間層(中間層存儲各業務遵守的業務代理協議,業務C啓動時將自身註冊爲中間層的代理,其他業務需求業務C時通過中間層調用代理實現的方法),然後業務A去中間層獲取它所依賴的數據。