iOS面試題

一、runtime的實現機制是什麼?實現的應用場景?相關函數?緩存

runtime是一套比較底層的純C語言API。 OC代碼在程序運行時, 其實最終都是轉成了runtime的C語言代碼, 它是OC的幕後工做者.
好比說,建立對象的方法中: 
[[Person alloc] init] 
-->
objc_msgSend(objc_msgSend("Person" , "alloc"), "init")

應用場景:能夠進行一些很是底層的操做(用OC是沒法現實的, 很差實現)

在程序運行過程當中, 動態建立一個類(好比KVO的底層實現);

在程序運行過程當中, 動態地爲某個類添加屬性\方法, 修改屬性值\方法的實現;

遍歷一個類的全部成員變量(屬性)\全部方法(例如:當歸檔解檔的時候屬性比較多時,可使用runtime動態設置,不須要寫不少的代碼);

用於封裝框架.當系統的方法不能知足邏輯需求的時候,能夠利用運行時替換系統的方法,好比AFNetworking框架.

相關函數:
objc_msgSend : 給對象發送消息
class_copyMethodList : 遍歷某個類全部的方法
class_copyIvarList : 遍歷某個類全部的成員變量
class_..... 這是咱們學習runtime必須知道的函數!

二、runloop的底層實現原理是什麼?應用場景?和線程的關係?服務器

其內部是一個 do-while 循環。當你調用CFRunLoopRun()時,線程就會一直停留在這個循環裏;直到超時或被手動中止,該函數纔會返回。
應用場景:
一、autoreleasePool

二、事件響應

三、手勢識別

四、界面更新

五、定時器

六、PerformSelecter(利用RunLoop常駐線程)

七、GCD
runloop和線程的關係:
每條線程都有惟一的一個 RunLoop 對象與之對應的
主線程的 RunLoop 是自動建立並啓動
子線程的 RunLoop 須要手動建立

三、kvo的底層實現網絡

3.一、KVO是基於runtime機制實現的

3.二、當某個類的屬性對象第一次被觀察時,系統就會在運行期動態地建立該類的一個派生類,在這個派生類中重寫基類中任何被觀察屬性的setter 方法。派生類在被重寫的setter方法內實現真正的通知機制

3.三、若是原類爲Person,那麼生成的派生類名爲NSKVONotifying_Person

3.四、每一個類對象中都有一個isa指針指向當前類,當一個類對象的第一次被觀察,那麼系統會偷偷將isa指針指向動態生成的派生類,從而在給被監控屬性賦值時執行的是派生類的setter方法

3.五、鍵值觀察通知依賴於NSObject 的兩個方法: willChangeValueForKey: 和 didChangevlueForKey:;在一個被觀察屬性發生改變以前, willChangeValueForKey:必定會被調用,這就 會記錄舊的值。而當改變發生後,didChangeValueForKey:會被調用,繼而 observeValueForKey:ofObject:change:context: 也會被調用。

補充:KVO的這套實現機制中蘋果還偷偷重寫了class方法,讓咱們誤認爲仍是使用的當前類,從而達到隱藏生成的派生類

四、APP 請求大量數據,致使服務器卡、返回數據慢,要如何進行優化多線程

4.一、減小radio活躍時間 ,也就是減小網絡數據獲取的頻次,從而也減小了radio的電量消耗,控制電量使用。

4.二、減小獲取數據包的大小,能夠減小流量消耗,也可讓每次請求更快,在網絡狀況很差的狀況下也有良好表現, 提高用戶體驗.

具體實現:

4.三、API設計,App與Server之間的API設計要考慮網絡請求的頻次, 資源的狀態等. 以便App能夠以較少的請求來完成業務需求和界面的展現.
例如, 註冊登陸. 正常會有兩個API, 註冊和登陸, 可是設計API時咱們應該給註冊接口包含一個隱式的登陸. 來避免App在註冊後還得請求一次登陸接口(有可能失敗, 從而致使業務流程失敗).

4.四、Gzip壓縮,使用Gzip來壓縮request和response, 減小傳輸數據量, 從而減小流量消耗.

4.五、網絡緩存,適當的緩存, 既可讓咱們的應用看起來更快, 也能避免一些沒必要要的流量消耗.

4.六、打包網絡請求,當接口設計不能知足咱們的業務需求時. 例如可能一個界面須要請求多個接口, 或是網絡良好, 處於Wifi狀態下時咱們想獲取更多的數據等.
這時就能夠打包一些網絡請求, 例如請求列表的同時, 獲取Header點擊率較高的的item項的詳情數據.
能夠經過一些統計數據來幫助咱們定位用戶接下來的操做是高几率的, 提早獲取這部分的數據.

五、你用過NSOperationQueue麼?若是用過或者瞭解的話,你爲何要使用NSOperationQueue,實現了什麼?請描述它和GCD的區別和相似的地方(提示:能夠從二者的實現機制和適用範圍來描述併發

5.一、 GCD是純C語言的API,NSOperationQueue是基於GCD的OC版本封裝

5.二、 GCD只支持FIFO的隊列,NSOperationQueue能夠很方便地調整執行順序、設置最大併發數量

5.三、 NSOperationQueue能夠在輕鬆在Operation間設置依賴關係,而GCD須要寫不少的代碼才能實現

5.四、 NSOperationQueue支持KVO,能夠監測operation是否正在執行(isExecuted)、是否結束(isFinished),是否取消(isCanceld)

5.五、 GCD的執行速度比NSOperationQueue快

任務之間不太互相依賴:GCD

任務之間有依賴\或者要監放任務的執行狀況:NSOperationQueue

六、你實現過多線程的Core Data麼?NSPersistentStoreCoordinator,NSManagedObjectContext和NSManagedObject中的哪些須要在線程中建立或者傳遞?你是用什麼樣的策略來實現的?框架

 

七、block的實現原理異步

建立block的時候,內部是建立了對應的函數;

在調用block的時候,是調用了以前封裝的函數。

八、你實現過一個框架或者庫以供別人使用麼?若是有,請談一談構建框架或者庫時候的經驗;若是沒有,請設想和設計框架的public的API,並指出大概須要如何作、須要注意一些什麼方面,來使別人容易地使用你的框架函數

抽象和封裝,方便使用。首先是對問題有充分的瞭解:
好比構建一個文件解壓壓縮框架,從使用者的角度出發,只需關注發送給框架一個解壓請求,框架完成複雜文件的解壓操做,而且在適當的時候通知給使用者,如解壓完成、解壓出錯等。
在框架內部去構建對象的關係,經過抽象讓其更爲健壯、便於更改。
其次是API的說明文檔。

九、NSNotificationCenter通知中心是同步操做仍是異步操做?oop

NSNotificationCenter消息的接受線程是基於發送消息的線程的,也就是同步的。
所以,有時候,你發送的消息可能不在主線程,而你們都知道操做UI必須在主線程,否則會出現不響應的狀況。
因此,在你收到消息通知的時候,注意選擇你要執行的線程。

十、消息機制的流程嗎/KVC的底層實現/weak的底層實現學習

 

十一、 sleep performal延遲操做默認在哪一個線程?

 

十二、GCD沒有取消以前,是怎麼取消已經派發的任務?

 

1三、以前開發項目實現過程,遇到過什麼問題,如何解決?

 

1四、怎麼處理死鎖

產生死鎖的四個必要條件:
(1) 互斥條件:一個資源每次只能被一個進程使用。
(2) 請求與保持條件:一個進程因請求資源而阻塞時,對已得到的資源保持不放。
(3) 不剝奪條件:進程已得到的資源,在末使用完以前,不能強行剝奪。
(4) 循環等待條件:若干進程之間造成一種頭尾相接的循環等待資源關係。
這四個條件是死鎖的必要條件,只要系統發生死鎖,這些條件必然成立,而只要上述條件之
一不知足,就不會發生死鎖。
相關文章
相關標籤/搜索