丁香園iOS電話面試問題總結

今天下午去面試去面試一家初創公司,而後又接到到了丁香園的電話面試,這篇blog記錄一下面試的一些問題,有的回答的還行,有點感受不太好,主要是有些英文單詞說的太low了估計被鄙視了吧,下面給你們總結一下面試的一些問題,有些回答是摘要一些大神blog的出處,都有給原連接,但願見諒~~ios

簡單講解一下http請求,以及GET POST的區別

這個問得其實不是很難,主要看你了不瞭解了,我由於瞭解一些後臺的東西,因此回答的還行,下面我給你們看兩幅圖片你們就基本瞭解了:git

  • 請求Request的原數據

  • 返回Resonse的原數據

總結一下,其實http請求就是發送和接受報文,報文的具體格式就如上圖所示,具體由三部分構成,GET 和 POST比較明顯的不一樣就是請求方式和參數的位置不一樣,其餘原理的不一樣你們能夠去下面的連接去看:github

  • 請求的方法URL協議/版本
  • 請求頭(Request Header)
  • 請求正文(Content)

其中請求頭裏面能夠放不少參數,好比報文的大小啊,啥的一些參數,具體能夠百度,這裏就不展開了。web

下面給兩個大神們推薦的連接,你們能夠自行查看:面試

https的加密方式和幾回握手

這個問題回答的就比較菜了,程序比較複製,當時特地記了一下,沒想到面試的時候仍是有點蒙,回答的很是菜,如今在普及一下,下面是一篇講的很詳細的blog地址,你們能夠去原地址去看,我下面也簡單總結一下:objective-c

https的加密方式

  • 對稱加密

​ 對稱加密是指加密和解密使用相同密鑰的加密算法。它要求發送方和接收方在安全通訊以前,商定一個密鑰。對稱算法的安全性依賴於密鑰,泄漏密鑰就意味着任何人均可以對他們發送或接收的消息解密,因此密鑰的保密性對通訊相當重要。算法

對稱加密算法的優、缺點:數據庫

優勢:算法公開、計算量小、加密速度快、加密效率高。編程

缺點:
1)交易雙方都使用一樣鑰匙,安全性得不到保證;swift

2)每對用戶每次使用對稱加密算法時,都須要使用其餘人不知道的唯一鑰匙,這會使得發收信雙方所擁有的鑰匙數量呈幾何級數增加,密鑰管理成爲用戶的負擔。

3)能提供機密性,可是不能提供驗證和不能否認性。

  • 非對稱加密

​ 這種加密或許理解起來比較困難,這種加密指的是能夠生成公鑰和私鑰。凡是公鑰加密的數據,公鑰自身不能解密,而須要私鑰才能解密;凡是私鑰加密的數據,私鑰不能解密,須要公鑰才能解密。這種算法事實上有不少,經常使用的是RSA,其基於的數學原理是兩個大素數的乘積很容易算,而拿到這個乘積去算出是哪兩個素數相乘就很複雜了,具體原理有興趣能夠自行研究。

非對稱加密相比對稱加密更加安全,但也存在兩個明顯缺點:

​ 1)CPU計算資源消耗很是大。一次徹底TLS握手,密鑰交換時的非對稱解密計算量佔整個握手過程的90%以上。而對稱加密的計算量只至關於非對稱加密的0.1%,若是應用層數據也使用非對稱加解密,性能開銷太大,沒法承受。

​ 2)非對稱加密算法對加密內容的長度有限制,不能超過公鑰長度。好比如今經常使用的公鑰長度是2048位,意味着待加密內容不能超過256個字節。

因此公鑰加密目前只能用來做密鑰交換或者內容簽名,不適合用來作應用層傳輸內容的加解密。

加密的詳細過程

​ 首先服務器端用非對稱加密(RSA)產生公鑰和私鑰。而後把公鑰發給客 戶端,路徑或許有人會截取,可是沒有用,由於用公鑰加密的文件只有私鑰能夠解密,而私鑰永遠都不會離開服務器的。當公鑰到達客戶端以後,客戶端會用對稱加密產生一個祕鑰而且用公鑰來加密發送給服務器端,這個祕鑰就是之後用來通訊的鑰匙。這樣服務器端收到公鑰加密的祕鑰時就能夠用私鑰來解公鑰從而得到祕鑰。這樣的話客戶端和服務器端都得到了祕鑰,信息交流相對是安全的。流程圖以下:

​ 聽起來確實是挺安全的,但實際上,還有一種更惡劣的攻擊是這種方法無 法防範的,這就是傳說中的「中間人攻擊」。在身份認證的過程當中,出現了一個「中間人」攔截咱們的信息,他有意想要知道大家的消息。咱們將這個中間人稱爲M。當服務器第一次給客戶端發送公鑰的時候,途徑M。M知道你要進行密鑰交換了,它把公鑰扣了下來,僞裝本身是客戶端,僞造了一個僞祕鑰(對稱加密產生的),而後用服務器發來的公鑰加密了僞祕鑰發還給服務器,這樣服務器覺得和客戶端完成了密鑰交換,實際上服務器是和M完成了密鑰交換(得到了僞祕鑰)。同時M假扮成服務器自行用非對稱加密產生僞公鑰和僞私鑰,與客戶端進行祕鑰交換,拿到客戶端發送過來的祕鑰。如今客戶端拿着祕鑰,M拿着祕鑰和爲僞祕鑰,服務器拿着僞祕鑰,整個交流的過程就是:

還有不少你們直接去大神的blog去看吧,寫的很詳細,我這就點到爲止了~~

在不知道二進制文件格式的狀況下如何區分文件

當聽到這麼問題的時候仍是有點倉促的,隱約記得是經過二進制的頭部的標識來區分的,當時也不太肯定就含糊的回答了一下,說是經過二進制文件的頭部標識來區分的,看面試官的樣子不是很滿意,回答百度學習一波,百度結果以下所示,附帶原連接

能夠經過二進制頭識別文件類型,可使用UE或者WinHex軟件打開:

1). JPEG/JPG

  • 文件頭標識 (2 bytes): $ff, $d8 (SOI) (JPEG文件標識)
  • 文件結束標識 (2 bytes): $ff, $d9 (EOI)

2). TGA

  • 未壓縮的前5字節 00 00 02 0000
  • RLE壓縮的前5字節 00 00 10 0000

3). PNG

  • 文件頭標識 (8 bytes) 89 50 4E 470D 0A 1A 0A

4). GIF

  • 文件頭標識 (6 bytes) 47 49 46 3839(37) 61
    ​ G I F 8 9 (7) a

5). BMP

  • 文件頭標識 (2 bytes) 424D
    ​ B M

6). PCX

  • 文件頭標識 (1 bytes) 0A

7). TIFF

  • 文件頭標識 (2 bytes) 4D 4D 或 4949

8). ICO

  • 文件頭標識 (8 bytes) 00 00 01 0001 00 20 20

9). CUR

  • 文件頭標識 (8 bytes) 00 00 02 0001 00 20 20

10). IFF

  • 文件頭標識 (4 bytes) 46 4F 524D
    ​ F O R M

11). ANI

  • 文件頭標識 (4 bytes) 52 49 4646
    ​ R I F F

以上是一些文件的區別方式,回答的總方向仍是對的,可能回答的不夠好,下次就知道了。

常見的幾種線程鎖

這個問題比較尷尬,由於英文不太好,加上平時用的也很少,回答的比較吞吞吐吐,就說了NSLock@synchronizeddispatch的semaphore,其中有些單詞的讀法還不太準,想一想就很尷尬,下面大概總結一下,有一下幾種:

  • NSLock
  • @synchronized
  • dispatch的semaphore
  • 條件鎖NSCondition
  • 條件鎖NSConditionLock
  • NSDistributedLock
  • 互斥鎖POSIX
  • 自旋鎖OSSpinLock

下面總結一下,說實話太多有點記不過來了 - . -,附帶詳細的原文地址

各類線程鎖 使用場景和簡單介紹
@synchronized 適用線程很少,任務量不大的多線程加鎖
NSLock 比較經常使用的一種鎖,性能通常
dispatch_semaphore_t 使用信號來作加鎖,性能很好
NSCondition 使用其作多線程之間的通訊調用不是線程安全的
NSConditionLock 單純加鎖性能很是低,比NSLock低不少,可是能夠用來作多線程處理不一樣任務的通訊調用
NSRecursiveLock 遞歸鎖的性能出奇的高,可是隻能做爲遞歸使用,因此限制了使用場景
NSDistributedLock 由於是MAC開發的,就不討論了
POSIX(pthread_mutex) 底層的api,複雜的多線程處理建議使用,而且能夠封裝本身的多線程
OSSpinLock 性能也很是高,惋惜出現了線程問題

再總結一下,總的意思就是通常用dispatch_semaphore_t就好了,再簡單點用
NSLock,另外帶一個swift出的一個線程鎖的方式:

func synchronized(lock: AnyObject, closure: () -> ()) {
    objc_sync_enter(lock)
    closure()
    objc_sync_exit(lock)
}複製代碼

怎麼保證線程安全

這個問題我是接着上一個問題以後回答的,感受線程安全主要是數據競爭帶來的,下面簡單講解一下:

線程安全的代碼能夠從多個線程或併發任務安全地調用,而不會形成任何問題(數據損壞,系統崩潰等)。例如當你多線程編程時,你用let定義一個數組,由於它是隻讀的,你能在同一時間不一樣線程去使用它,而不會形成線程安全的問題,然而當你用var定義一個數組時就不同了,它不是線程安全的,當多個線程在同一時間訪問和修改數組時會產生不可預知的結果。

SDWebImage具體實現和具體類

這個問題回答的通常般吧,說了一下簡單的構造和實現,而後讓我說具體類的時候有點心累了,由於確實記得不是很清楚了,下面簡單總結一下一些主要的類:

  • SDWebImageManager
  • SDWebImageCombinedOperation
  • SDImageCache
  • SDWebImageDownloader
  • 各類類目

這是一些簡單的類,你們想要詳細瞭解能夠去這篇文章去看,很是詳細!!!

Alamofire實現原理和主要的類

跟上個問題同樣,簡單的回答了一下,都怪本身沒仔細專研過這些,只是簡單看過,停留在應用層面上,下面一樣簡單介紹一下,附帶大神blog地址吧:

  • Manager
  • SessionDelegate
  • ResponseSerialization
  • URLStringConvertible

這是一些簡單的類,你們想要詳細瞭解能夠去這篇文章去看,很是詳細!!!

RxSwift的原理使用和主要類?

這個幸虧用過了,不過也沒深刻過,就簡單抽象的講了一下響應式編程的思想,而後從應用使用方面講解了一下:RxSwift的目的是讓讓數據/事件流和異步任務可以更方便的序列化處理,可以使用swift進行響應式編程;讓後讓我說一下RxSwift裏面有哪些Subjects,這個就比較尷尬了,這讓我只用過PublishSubjectDriver的人情何以堪,下面一樣列一下Subjects列表和大神地址

  • PublishSubject

  • ReplaySubject

  • BehaviorSubject

  • Variable

  • Driver

    下面是大神blog,有詳細介紹你們能夠去閱讀~~~

realm的簡單介紹和使用時的線程問題

這個也簡單用過,也是沒往深刻研究,也是大概說了一下使用過程,和多線程數據共享的坑,首先realm是一個跨平臺移動數據庫引擎,支持iOSOS XObjective-CSwift)以及Android,核心數據引擎C++打造,並非創建在SQLite之上的ORM

跨線程時的使用

廢話很少說,直接上代碼:

let person = Person(name: "Jane")
try! realm.write {
  realm.add(person)
}
// 如下是跨線程必要的操做,先建一個Reference
let personRef = ThreadSafeReference(to: person)
// 而後在須要返回數據的線程裏面去resolve
DispatchQueue(label: "background").async {
    let realm = try! Realm()
    guard let person = realm.resolve(personRef) else {
    // person 已被刪除
      return 
    }
    try! realm.write {
      person.name = "Jane Doe"
    }
}複製代碼

這裏是官方中文文檔,你們能夠去看看,很是詳細~~~

簡單講一講RunTime和RunLoop

runtimerrunloop由於看過一篇文章寫的特別好,有必定了解,說了runtime的一些主要功能和應用的地方,下面簡單介紹一下:

RunTime

  • RunTime簡稱運行時;
  • OC就是運行時機制,就是在運行的時候調用一些機制;
  • 對於C語言,在編譯的時候會決定調用哪一個函數;
  • 對於OC,在編譯的時候並不能決定調用哪一個函數,只有在真正運行的時候纔會根據函數的SEL來調用對應的函數。

RunTime 應用範圍

  • 發送消息
  • 交換方法
  • 動態添加方法
  • 動態添加屬性

其中用的比較多的就是用類目給某個類動態添加屬性。

RunLoop

RunLoop簡單來講就是事件循環,保持APP一直處於存活方式的一種機制,讓線程能隨時處理事件但並不退出,下面有一篇超級棒的RunLoop文章給你們介紹一下,我這就不展開說了,瞭解RunLoop看那篇文章足夠了。

超級棒的文章地址

簡單說一下iOS的幾種持續化存儲方式

這個回答的就比較輕鬆了,下面隨便列幾個吧,你們有其餘的能夠補充一下:

  • NSUserDefaults
  • plist
  • NSKeyedArchiver
  • SQL
  • coredata
  • realm

WKWebView緩存和清理緩存的方法

WKWebView緩存的使用

主要經過NSURLCache對請求的數據進行緩存,具體實現能夠去這個github上去查看~~~~

清楚緩存的方法

詳情看這篇blog,這裏簡單陳述一下,其實在iOS9出了一個方法,調用一下就清除了:

NSSet *websiteDataTypes = [WKWebsiteDataStore allWebsiteDataTypes];
//// Date from
NSDate *dateFrom = [NSDate dateWithTimeIntervalSince1970:0];
//// Execute
[[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:websiteDataTypes modifiedSince:dateFrom completionHandler:^{
// Done
}];複製代碼

WKWebview的cookie的使用

主要用到的類有NSHTTPCookie,你們一樣也能夠去大神的blog去查看~~~~

autorelease的實現,以及autorelease對象何時會被release

這個問題回答的不太好,說實話當時連續面試了兩家,鬧着已經有點蒙了,這裏借用喵神翻譯的一本書上的原話來描述一下:

autorelease它會將接受該消息的對象放到一個預先創建的自動釋放池 (auto release pool) 中,並在 自動釋放池收到 drain 消息時將這些對象的引用計數減一,而後將它們從池子中移除 (這一過程形象地稱爲「抽乾池子」)。」

【摘錄來自: 王巍 (onevcat). 「Swifter - Swift 必備 Tips (第三版)」。 iBooks. 】

實現原理的話大概就是被autorelease標記的類會被加入一個池子,當這個池子drain時裏面的引用計數會減1。

談談對swift中extension的理解

說實話其實這個問題當時比較吵,聽的不是很清楚,問了好幾遍問題,挺尷尬的,下面簡單介紹一下吧,由於這個在swift中用的比較多:

  • 首先extensionswift中相似oc的類目,能夠擴展方法,計算屬性,不能添加存儲屬性;
  • 能夠經過extension讓類實現某個協議,通常這個用的也比較多,好比實現Comparable這個協議;
  • 還有一個很重要的,就是能夠經過extension對協議進行擴展,添加默認實現,屬於黑魔法吧,很是好用。

前兩點在面試的時候都又提到,最後一點壓根忘了,本身的面試發揮真不是通常的差- . -

swift寫時複製,本身的結構體怎麼實現寫時複製

幸虧以前看了喵神翻譯的【Swift進階】 ,受益頗深,下面一樣借用喵神的話給你們簡單描述一下,你們能夠去買這本書,仍是挺划算的,下面大量複製喵神書裏面的內容,請見諒:

在 Swift 標準庫中,像是 Array,Dictionary 和 Set 這樣的集合類型是經過一種叫作寫時複製 (copy-on-write) 的技術實現的。咱們這裏有一個整數數組:

var x = [1,2,3]
var y = x複製代碼

若是咱們建立了一個新的變量 y,而且把 x 賦值給它時,會發生複製,如今 x 和 y 含有的是獨立的結構體。在內部,這些 Array 結構體含有指向某個內存的引用。這個內存就是數組中元素所存儲的位置,它們位於堆 (heap) 上。在這個時候,兩個數組的引用指向的是內存中同一個位置,這兩個數組共享了它們的存儲部分。不過,當咱們改變 x 的時候,這個共享會被檢測到,內存將會被複制。這樣一來,咱們得以獨立地改變兩個變量。昂貴的元素複製操做只在必要的時候發生,也就是咱們改變這兩個變量的時候發生複製:

x.append(5)
y.removeLast()
x // [1, 2, 3, 5]
y // [1, 2]複製代碼

若是 Array 結構體中的引用在數組被改變的一瞬間時是惟一的話 (好比,沒有聲明 y),那麼也不會有複製發生,內存的改變將在原地進行。這種行爲就是寫時複製,做爲一個結構體的做者,你並不能免費得到這種特性,你須要本身進行實現。當你本身的類型內部含有一個或多個可變引用,同時你想要保持值語義,而且避免沒必要要的複製時,爲你的類型實現寫時複製是有意義的。

下面看看經過簡單的例子看一下:

var array = [COWStruct()]
array[0].change() // No copy

var otherArray = [COWStruct()]
var x = array[0]
x.change() // Copy複製代碼

然而本身去實現一個寫時複製的話,首先你要判斷引用的惟一性,不是惟一的話進行寫時複製,惟一的話直接改變須要改變的值。

結構體和類以及它們的使用時機

結構體和類主要的區別就是一個是值類型,一個是引用類型;值類型是寫時複製的,引用類型是不會發生寫時複製的;當咱們須要一個簡單不須要繼承、很少變的數據時候咱們首選結構體,由於在數據結構上來講結構體的存取效率是高於類的,反之當咱們須要一個數據結構比較大,須要繼承,變化比較多的時候咱們選擇類,由於在變化的過程當中結構體可能會發生寫時複製,而類不會;下面舉一個簡單的例子:

ArrayNSMutableArray來講:

當有一個數組,數據量相對比較小,也不用去常常改變它,只是用來存數據和取數據,咱們首先Array

當數組的數據量很大的時候,而且常常要去對他進行添加,刪除等操做,而且常常賦值給其餘變量的話就推薦使用NSMutableArray

讓你實現一個數據存儲的框架的具體思路

這個是一個比較開發性的問題了,我想到的是用策略模式的方式來簡單實現一下,使用策略模式的好處是方便文件類型的擴展,下面我簡單畫個簡單的UML圖你們看一看吧:

固然這只是一個初步的模型,還有不少細節待考慮,好比文件緩存什麼的,是存本地仍是磁盤,這都得去考慮,小弟只是拋磚引玉給個簡單的思路。

寫完已是深夜了,以上是我丁香園電話面試的一些問題,和以前面試一些回答很差的問題,最後面試完我問了一下丁香園的面試官對我感受怎樣,他說廣度還行深度不夠,我確實又有這點問題,想學的知識比較多,有時候也沒來得及去看實現原理,只是簡單的過一下,沒深刻研究透徹,這是我須要增強的地方,以後若是有二面的話我會在繼續更新的,最後謝謝你們的閱讀~~我是WCL,你們能夠去我github關注一波

相關文章
相關標籤/搜索