答卓同學的iOS面試題


卓同學昨天寫了一篇文章《4道過濾菜鳥的iOS面試題》。我手癢決定默寫一個參考答案。后來發現不認真回答被大家噴成狗,所以決定積極改造,重新做人。下面就是修編之后的答案。

1. struct和class的區別

swift中,class是引用類型,struct是值類型。值類型在傳遞和賦值時將進行復制,而引用類型則只會使用引用對象的一個"指向"。所以他們兩者之間的區別就是兩個類型的區別。

class有這幾個功能struct沒有的:

  • class可以繼承,這樣子類可以使用父類的特性和方法
  • 類型轉換可以在runtime的時候檢查和解釋一個實例的類型
  • 可以用deinit來釋放資源
  • 一個類可以被多次引用

struct也有這樣幾個優勢:

  • 結構較小,適用于復制操作,相比于一個class的實例被多次引用更加安全。
  • 無須擔心內存memory leak或者多線程沖突問題

順便提一下,array在swift中是用struct實現的。Apple重寫過一次array,然后復制就是深度拷貝了。猜測復制是類似參照那樣,通過棧上指向堆上位置的指針來實現的。而對于它的復制操作,也是在相對空間較為寬裕的堆上來完成的,所以性能上還是不錯的。

下面引用貓神OneV的博客:

var arr = [0,0,0]
var newArr = arr
arr[0] = 1
//Check arr and newArr
arr //[1, 0, 0]
newArr // before beta3:[1, 0, 0], after beta3:[0, 0, 0]

所以可以猜測其實在背后 Array和 Dictionary的行為并不是像其他 struct 那樣簡單的在棧上分配,而是類似參照那樣,通過棧上指向堆上位置的指針來實現的。而對于它的復制操作,也是在相對空間較為寬裕的堆上來完成的。當然,現在還無法(或者說很難)拿到最后的匯編碼,所以這只是一個猜測而已。

補充:
C語言中,struct與的class的區別:
struct只是作為一種復雜數據類型定義,不能用于面向對象編程。

C++中,struct和class的區別:
對于成員訪問權限以及繼承方式,class中默認的是private的,而struct中則是public的。class還可以用于表示模板類型,struct則不行。

2. 介紹一下觀察者模式

觀察者模式(Observer Pattern):定義對象間的一種一對多依賴關系,使得每當一個對象狀態發生改變時,其相關依賴對象皆得到通知并被自動更新。
在IOS中典型的推模型實現方式為NSNotificationCenter和KVO。

NSNotificationCenter

NSNotificationCenter
  1. 觀察者Observer,通過NSNotificationCenter的addObserver:selector:name:object接口來注冊對某一類型通知感興趣。在注冊時候一定要注意,NSNotificationCenter不會對觀察者進行引用計數+1的操作,我們在程序中釋放觀察者的時候,一定要去報從center中將其注銷了。
  2. 通知中心NSNotificationCenter,通知的樞紐。
  3. 被觀察的對象,通過postNotificationName:object:userInfo:發送某一類型通知,廣播改變。
  4. 通知對象NSNotification,當有通知來的時候,Center會調用觀察者注冊的接口來廣播通知,同時傳遞存儲著更改內容的NSNotification對象。

KVO

KVO的全稱是Key-Value Observer,即鍵值觀察。是一種沒有中心樞紐的觀察者模式的實現方式。一個主題對象管理所有依賴于它的觀察者對象,并且在自身狀態發生改變的時候主動通知觀察者對象。

  1. 注冊觀察者
    [object addObserver:self forKeyPath:property options:NSKeyValueObservingOptionNew context:]。
  2. 更改主題對象屬性的值,即觸發發送更改的通知。
  3. 在制定的回調函數中,處理收到的更改通知。
  4. 注銷觀察者 [object removeObserver:self forKeyPath:property]。

3.在一個HTTPS連接的網站里,輸入賬號密碼點擊登錄后,到服務器返回這個請求前,中間經歷了什么

這個非常得深非常得廣,我來大概說一下。


HTTPS加密流程
  1. 客戶端打包請求。包括url,端口啊,你的賬號密碼等等。賬號密碼登陸應該用的是Post方式,所以相關的用戶信息會被加載到body里面。這個請求應該包含三個方面:網絡地址,協議,資源路徑。注意,這里是HTTPS,就是HTTP + SSL / TLS,在HTTP上又加了一層處理加密信息的模塊(相當于是個鎖)。這個過程相當于是客戶端請求鑰匙。

  2. 服務器接受請求。一般客戶端的請求會先發送到DNS服務器。 DNS服務器負責將你的網絡地址解析成IP地址,這個IP地址對應網上一臺機器。這其中可能發生Hosts Hijack和ISP failure的問題。過了DNS這一關,信息就到了服務器端,此時客戶端會和服務器的端口之間建立一個socket連接,socket一般都是以file descriptor的方式解析請求。這個過程相當于是服務器端分析是否要向客戶端發送鑰匙模板。

  3. 服務器端返回數字證書。服務器端會有一套數字證書(相當于是個鑰匙模板),這個證書會先發送給客戶端。這個過程相當于是服務器端向客戶端發送鑰匙模板。

  4. 客戶端生成加密信息。根據收到的數字證書(鑰匙模板),客戶端會生成鑰匙,并把內容鎖上,此時信息已經加密。這個過程相當于客戶端生成鑰匙并鎖上請求。

  5. 客戶端發送加密信息。服務器端會收到由自己發送出去的數字證書加鎖的信息。 這個時候生成的鑰匙也一并被發送到服務器端。這個過程是相當于客戶端發送請求。

  6. 服務器端解鎖加密信息。服務器端收到加密信息后,會根據得到的鑰匙進行解密,并把要返回的數據進行對稱加密。這個過程相當于服務器端解鎖請求、生成、加鎖回應信息。

  7. 服務器端向客戶端返回信息。客戶端會收到相應的加密信息。這個過程相當于服務器端向客戶端發送回應。

  8. 客戶端解鎖返回信息。客戶端會用剛剛生成的鑰匙進行解密,將內容顯示在瀏覽器上。

HTTPS加密過程詳解請去https原理:證書傳遞、驗證和數據加密、解密過程解析

4.在一個app中間有一個button,在你手觸摸屏幕點擊后,到這個button收到點擊事件,中間發生了什么

響應鏈大概有以下幾個步驟

  1. 設備將touch到的UITouch和UIEvent對象打包, 放到當前活動的Application的事件隊列中
  2. 單例的UIApplication會從事件隊列中取出觸摸事件并傳遞給單例UIWindow
  3. UIWindow使用hitTest:withEvent:方法查找touch操作的所在的視圖view

RunLoop這邊我大概講一下

  1. 主線程的RunLoop被喚醒
  2. 通知Observer,處理Timer和Source 0
  3. Springboard接受touch event之后轉給App進程中
  4. RunLoop處理Source 1,Source1 就會觸發回調,并調用_UIApplicationHandleEventQueue() 進行應用內部的分發。
  5. RunLoop處理完畢進入睡眠,此前會釋放舊的autorelease pool并新建一個autorelease pool

深挖請去深入理解RunLoop

UIResponder是UIView的父類,UIView是UIControl的父類。

聲明一下,第3題依然有很大缺陷,不過因為深挖的地方太多,本文不可能完全兼顧,只能拋磚引玉。另外文章的目的是以面試題為引進行學習,所以寫得有點多,可能與面試技巧和時間有沖突。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,923評論 18 139
  • 國家電網公司企業標準(Q/GDW)- 面向對象的用電信息數據交換協議 - 報批稿:20170802 前言: 排版 ...
    庭說閱讀 11,149評論 6 13
  • OC的理解與特性 OC作為一門面向對象的語言,自然具有面向對象的語言特性:封裝、繼承、多態。它既具有靜態語言的特性...
    克魯德李閱讀 458評論 0 0
  • OC的理解與特性OC作為一門面向對象的語言,自然具有面向對象的語言特性:封裝、繼承、多態。它既具有靜態語言的特性(...
    LIANMING_LI閱讀 535評論 0 0
  • 紀我高中:相聚離開 三年前,我們穿著迷彩服在細雨中嘶喊,軍訓的六天生活,我至今仍然歷歷在目。 三年后的今天,禮堂外...
    慶州山人閱讀 155評論 0 0