今天下午去面試去面試一家初創(chuàng)公司,然后又接到到了丁香園的電話面試,這篇blog記錄一下面試的一些問(wèn)題,有的回答的還行,有點(diǎn)感覺(jué)不太好,主要是有些英文單詞說(shuō)的太low了估計(jì)被鄙視了吧,下面給大家總結(jié)一下面試的一些問(wèn)題,有些回答是摘要一些大神blog的出處,都有給原鏈接,希望見(jiàn)諒~~
簡(jiǎn)單講解一下http請(qǐng)求,以及GET POST的區(qū)別
這個(gè)問(wèn)得其實(shí)不是很難,主要看你了不了解了,我因?yàn)榱私庖恍┖笈_(tái)的東西,所以回答的還行,下面我給大家看兩幅圖片大家就基本了解了:
- 請(qǐng)求Request的原數(shù)據(jù)
- 返回Resonse的原數(shù)據(jù)
總結(jié)一下,其實(shí)http請(qǐng)求就是發(fā)送和接受報(bào)文,報(bào)文的具體格式就如上圖所示,具體由三部分構(gòu)成,GET 和 POST比較明顯的不同就是請(qǐng)求方式和參數(shù)的位置不同,其他原理的不同大家可以去下面的鏈接去看:
- 請(qǐng)求的方法URL協(xié)議/版本
- 請(qǐng)求頭(Request Header)
- 請(qǐng)求正文(Content)
其中請(qǐng)求頭里面可以放很多參數(shù),比如報(bào)文的大小啊,啥的一些參數(shù),具體可以百度,這里就不展開(kāi)了。
下面給兩個(gè)大神們推薦的鏈接,大家可以自行查看:
https的加密方式和幾次握手
這個(gè)問(wèn)題回答的就比較菜了,程序比較復(fù)制,當(dāng)時(shí)特意記了一下,沒(méi)想到面試的時(shí)候還是有點(diǎn)蒙,回答的非常菜,現(xiàn)在在普及一下,下面是一篇講的很詳細(xì)的blog地址,大家可以去原地址去看,我下面也簡(jiǎn)單總結(jié)一下:
https的加密方式
- 對(duì)稱加密
? 對(duì)稱加密是指加密和解密使用相同密鑰的加密算法。它要求發(fā)送方和接收方在安全通信之前,商定一個(gè)密鑰。對(duì)稱算法的安全性依賴于密鑰,泄漏密鑰就意味著任何人都可以對(duì)他們發(fā)送或接收的消息解密,所以密鑰的保密性對(duì)通信至關(guān)重要。
對(duì)稱加密算法的優(yōu)、缺點(diǎn):
優(yōu)點(diǎn):算法公開(kāi)、計(jì)算量小、加密速度快、加密效率高。
缺點(diǎn):
1)交易雙方都使用同樣鑰匙,安全性得不到保證;
2)每對(duì)用戶每次使用對(duì)稱加密算法時(shí),都需要使用其他人不知道的惟一鑰匙,這會(huì)使得發(fā)收信雙方所擁有的鑰匙數(shù)量呈幾何級(jí)數(shù)增長(zhǎng),密鑰管理成為用戶的負(fù)擔(dān)。
3)能提供機(jī)密性,但是不能提供驗(yàn)證和不可否認(rèn)性。
- 非對(duì)稱加密
? 這種加密或許理解起來(lái)比較困難,這種加密指的是可以生成公鑰和私鑰。凡是公鑰加密的數(shù)據(jù),公鑰自身不能解密,而需要私鑰才能解密;凡是私鑰加密的數(shù)據(jù),私鑰不能解密,需要公鑰才能解密。這種算法事實(shí)上有很多,常用的是RSA,其基于的數(shù)學(xué)原理是兩個(gè)大素?cái)?shù)的乘積很容易算,而拿到這個(gè)乘積去算出是哪兩個(gè)素?cái)?shù)相乘就很復(fù)雜了,具體原理有興趣可以自行研究。
非對(duì)稱加密相比對(duì)稱加密更加安全,但也存在兩個(gè)明顯缺點(diǎn):
? 1)CPU計(jì)算資源消耗非常大。一次完全TLS握手,密鑰交換時(shí)的非對(duì)稱解密計(jì)算量占整個(gè)握手過(guò)程的90%以上。而對(duì)稱加密的計(jì)算量只相當(dāng)于非對(duì)稱加密的0.1%,如果應(yīng)用層數(shù)據(jù)也使用非對(duì)稱加解密,性能開(kāi)銷太大,無(wú)法承受。
? 2)非對(duì)稱加密算法對(duì)加密內(nèi)容的長(zhǎng)度有限制,不能超過(guò)公鑰長(zhǎng)度。比如現(xiàn)在常用的公鑰長(zhǎng)度是2048位,意味著待加密內(nèi)容不能超過(guò)256個(gè)字節(jié)。
所以公鑰加密目前只能用來(lái)作密鑰交換或者內(nèi)容簽名,不適合用來(lái)做應(yīng)用層傳輸內(nèi)容的加解密。
加密的詳細(xì)過(guò)程
? 首先服務(wù)器端用非對(duì)稱加密(RSA)產(chǎn)生公鑰和私鑰。然后把公鑰發(fā)給客 戶端,路徑或許有人會(huì)截取,但是沒(méi)有用,因?yàn)橛霉€加密的文件只有私鑰可以解密,而私鑰永遠(yuǎn)都不會(huì)離開(kāi)服務(wù)器的。當(dāng)公鑰到達(dá)客戶端之后,客戶端會(huì)用對(duì)稱加密產(chǎn)生一個(gè)秘鑰并且用公鑰來(lái)加密發(fā)送給服務(wù)器端,這個(gè)秘鑰就是以后用來(lái)通信的鑰匙。這樣服務(wù)器端收到公鑰加密的秘鑰時(shí)就可以用私鑰來(lái)解公鑰從而獲得秘鑰。這樣的話客戶端和服務(wù)器端都獲得了秘鑰,信息交流相對(duì)是安全的。流程圖如下:
? 聽(tīng)起來(lái)確實(shí)是挺安全的,但實(shí)際上,還有一種更惡劣的攻擊是這種方法無(wú) 法防范的,這就是傳說(shuō)中的“中間人攻擊”。在身份認(rèn)證的過(guò)程中,出現(xiàn)了一個(gè)“中間人”攔截我們的信息,他有意想要知道你們的消息。我們將這個(gè)中間人稱為M。當(dāng)服務(wù)器第一次給客戶端發(fā)送公鑰的時(shí)候,途徑M。M知道你要進(jìn)行密鑰交換了,它把公鑰扣了下來(lái),假裝自己是客戶端,偽造了一個(gè)偽秘鑰(對(duì)稱加密產(chǎn)生的),然后用服務(wù)器發(fā)來(lái)的公鑰加密了偽秘鑰發(fā)還給服務(wù)器,這樣服務(wù)器以為和客戶端完成了密鑰交換,實(shí)際上服務(wù)器是和M完成了密鑰交換(獲得了偽秘鑰)。同時(shí)M假扮成服務(wù)器自行用非對(duì)稱加密產(chǎn)生偽公鑰和偽私鑰,與客戶端進(jìn)行秘鑰交換,拿到客戶端發(fā)送過(guò)來(lái)的秘鑰。現(xiàn)在客戶端拿著秘鑰,M拿著秘鑰和為偽秘鑰,服務(wù)器拿著偽秘鑰,整個(gè)交流的過(guò)程就是:
還有很多大家直接去大神的blog去看吧,寫的很詳細(xì),我這就點(diǎn)到為止了~~
在不知道二進(jìn)制文件格式的情況下如何區(qū)分文件
當(dāng)聽(tīng)到這么問(wèn)題的時(shí)候還是有點(diǎn)倉(cāng)促的,隱約記得是通過(guò)二進(jìn)制的頭部的標(biāo)識(shí)來(lái)區(qū)分的,當(dāng)時(shí)也不太確定就含糊的回答了一下,說(shuō)是通過(guò)二進(jìn)制文件的頭部標(biāo)識(shí)來(lái)區(qū)分的,看面試官的樣子不是很滿意,回答百度學(xué)習(xí)一波,百度結(jié)果如下所示,附帶原鏈接:
可以通過(guò)二進(jìn)制頭識(shí)別文件類型,可以使用UE或者WinHex軟件打開(kāi):
1). JPEG/JPG
- 文件頭標(biāo)識(shí) (2 bytes): $ff, $d8 (SOI) (JPEG文件標(biāo)識(shí))
- 文件結(jié)束標(biāo)識(shí) (2 bytes): $ff, $d9 (EOI)
2). TGA
- 未壓縮的前5字節(jié) 00 00 02 0000
- RLE壓縮的前5字節(jié) 00 00 10 0000
3). PNG
- 文件頭標(biāo)識(shí) (8 bytes) 89 50 4E 470D 0A 1A 0A
4). GIF
- 文件頭標(biāo)識(shí) (6 bytes) 47 49 46 3839(37) 61
? G I F 8 9 (7) a
5). BMP
- 文件頭標(biāo)識(shí) (2 bytes) 424D
? B M
6). PCX
- 文件頭標(biāo)識(shí) (1 bytes) 0A
7). TIFF
- 文件頭標(biāo)識(shí) (2 bytes) 4D 4D 或 4949
8). ICO
- 文件頭標(biāo)識(shí) (8 bytes) 00 00 01 0001 00 20 20
9). CUR
- 文件頭標(biāo)識(shí) (8 bytes) 00 00 02 0001 00 20 20
10). IFF
- 文件頭標(biāo)識(shí) (4 bytes) 46 4F 524D
? F O R M
11). ANI
- 文件頭標(biāo)識(shí) (4 bytes) 52 49 4646
? R I F F
以上是一些文件的區(qū)別方式,回答的總方向還是對(duì)的,可能回答的不夠好,下次就知道了。
常見(jiàn)的幾種線程鎖
這個(gè)問(wèn)題比較尷尬,因?yàn)橛⑽牟惶茫由掀綍r(shí)用的也不多,回答的比較吞吞吐吐,就說(shuō)了NSLock
、@synchronized
和dispatch的semaphore
,其中有些單詞的讀法還不太準(zhǔn),想想就很尷尬,下面大概總結(jié)一下,有一下幾種:
- NSLock
- @synchronized
- dispatch的semaphore
- 條件鎖NSCondition
- 條件鎖NSConditionLock
- NSDistributedLock
- 互斥鎖POSIX
- 自旋鎖OSSpinLock
下面總結(jié)一下,說(shuō)實(shí)話太多有點(diǎn)記不過(guò)來(lái)了 - . -,附帶詳細(xì)的原文地址:
各種線程鎖 | 使用場(chǎng)景和簡(jiǎn)單介紹 |
---|---|
@synchronized |
適用線程不多,任務(wù)量不大的多線程加鎖 |
NSLock |
比較常用的一種鎖,性能一般 |
dispatch_semaphore_t |
使用信號(hào)來(lái)做加鎖,性能很好 |
NSCondition |
使用其做多線程之間的通信調(diào)用不是線程安全的 |
NSConditionLock |
單純加鎖性能非常低,比NSLock低很多,但是可以用來(lái)做多線程處理不同任務(wù)的通信調(diào)用 |
NSRecursiveLock |
遞歸鎖的性能出奇的高,但是只能作為遞歸使用,所以限制了使用場(chǎng)景 |
NSDistributedLock |
因?yàn)槭荕AC開(kāi)發(fā)的,就不討論了 |
POSIX(pthread_mutex) |
底層的api,復(fù)雜的多線程處理建議使用,并且可以封裝自己的多線程 |
OSSpinLock |
性能也非常高,可惜出現(xiàn)了線程問(wèn)題 |
再總結(jié)一下,總的意思就是一般用dispatch_semaphore_t
就行了,再簡(jiǎn)單點(diǎn)用
NSLock
,另外帶一個(gè)swift
出的一個(gè)線程鎖的方式:
func synchronized(lock: AnyObject, closure: () -> ()) {
objc_sync_enter(lock)
closure()
objc_sync_exit(lock)
}
怎么保證線程安全
這個(gè)問(wèn)題我是接著上一個(gè)問(wèn)題之后回答的,感覺(jué)線程安全主要是數(shù)據(jù)競(jìng)爭(zhēng)帶來(lái)的,下面簡(jiǎn)單講解一下:
線程安全的代碼可以從多個(gè)線程或并發(fā)任務(wù)安全地調(diào)用,而不會(huì)造成任何問(wèn)題(數(shù)據(jù)損壞,系統(tǒng)崩潰等)。例如當(dāng)你多線程編程時(shí),你用let定義一個(gè)數(shù)組,因?yàn)樗侵蛔x的,你能在同一時(shí)間不同線程去使用它,而不會(huì)造成線程安全的問(wèn)題,然而當(dāng)你用var定義一個(gè)數(shù)組時(shí)就不一樣了,它不是線程安全的,當(dāng)多個(gè)線程在同一時(shí)間訪問(wèn)和修改數(shù)組時(shí)會(huì)產(chǎn)生不可預(yù)知的結(jié)果。
SDWebImage具體實(shí)現(xiàn)和具體類
這個(gè)問(wèn)題回答的一般般吧,說(shuō)了一下簡(jiǎn)單的構(gòu)造和實(shí)現(xiàn),然后讓我說(shuō)具體類的時(shí)候有點(diǎn)心累了,因?yàn)榇_實(shí)記得不是很清楚了,下面簡(jiǎn)單總結(jié)一下一些主要的類:
SDWebImageManager
SDWebImageCombinedOperation
SDImageCache
SDWebImageDownloader
- 各種類目
這是一些簡(jiǎn)單的類,大家想要詳細(xì)了解可以去這篇文章去看,非常詳細(xì)!!!
Alamofire實(shí)現(xiàn)原理和主要的類
跟上個(gè)問(wèn)題一樣,簡(jiǎn)單的回答了一下,都怪自己沒(méi)仔細(xì)專研過(guò)這些,只是簡(jiǎn)單看過(guò),停留在應(yīng)用層面上,下面同樣簡(jiǎn)單介紹一下,附帶大神blog地址吧:
Manager
SessionDelegate
ResponseSerialization
URLStringConvertible
這是一些簡(jiǎn)單的類,大家想要詳細(xì)了解可以去這篇文章去看,非常詳細(xì)!!!
RxSwift的原理使用和主要類?
這個(gè)幸好用過(guò)了,不過(guò)也沒(méi)深入過(guò),就簡(jiǎn)單抽象的講了一下響應(yīng)式編程的思想,然后從應(yīng)用使用方面講解了一下:RxSwift
的目的是讓讓數(shù)據(jù)/事件流和異步任務(wù)能夠更方便的序列化處理,能夠使用swift
進(jìn)行響應(yīng)式編程;讓后讓我說(shuō)一下RxSwift
里面有哪些Subjects
,這個(gè)就比較尷尬了,這讓我只用過(guò)PublishSubject
和Driver
的人情何以堪,下面同樣列一下Subjects
列表和大神地址:
PublishSubject
ReplaySubject
BehaviorSubject
Variable
Driver
下面是大神blog,有詳細(xì)介紹大家可以去閱讀~~~
realm的簡(jiǎn)單介紹和使用時(shí)的線程問(wèn)題
這個(gè)也簡(jiǎn)單用過(guò),也是沒(méi)往深入研究,也是大概說(shuō)了一下使用過(guò)程,和多線程數(shù)據(jù)共享的坑,首先realm
是一個(gè)跨平臺(tái)移動(dòng)數(shù)據(jù)庫(kù)引擎,支持iOS
、OS X
(Objective-C
和Swift
)以及Android
,核心數(shù)據(jù)引擎C++
打造,并不是建立在SQLite
之上的ORM
。
跨線程時(shí)的使用
廢話不多說(shuō),直接上代碼:
let person = Person(name: "Jane")
try! realm.write {
realm.add(person)
}
// 以下是跨線程必要的操作,先建一個(gè)Reference
let personRef = ThreadSafeReference(to: person)
// 然后在需要返回?cái)?shù)據(jù)的線程里面去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"
}
}
這里是官方中文文檔,大家可以去看看,非常詳細(xì)~~~
簡(jiǎn)單講一講RunTime和RunLoop
runtimer
和runloop
因?yàn)榭催^(guò)一篇文章寫的特別好,有一定了解,說(shuō)了runtime
的一些主要功能和應(yīng)用的地方,下面簡(jiǎn)單介紹一下:
RunTime
-
RunTime
簡(jiǎn)稱運(yùn)行時(shí); - OC就是運(yùn)行時(shí)機(jī)制,就是在運(yùn)行的時(shí)候調(diào)用一些機(jī)制;
- 對(duì)于C語(yǔ)言,在編譯的時(shí)候會(huì)決定調(diào)用哪個(gè)函數(shù);
- 對(duì)于OC,在編譯的時(shí)候并不能決定調(diào)用哪個(gè)函數(shù),只有在真正運(yùn)行的時(shí)候才會(huì)根據(jù)函數(shù)的SEL來(lái)調(diào)用對(duì)應(yīng)的函數(shù)。
RunTime 應(yīng)用范圍
- 發(fā)送消息
- 交換方法
- 動(dòng)態(tài)添加方法
- 動(dòng)態(tài)添加屬性
其中用的比較多的就是用類目給某個(gè)類動(dòng)態(tài)添加屬性。
RunLoop
RunLoop
簡(jiǎn)單來(lái)說(shuō)就是事件循環(huán),保持APP一直處于存活方式的一種機(jī)制,讓線程能隨時(shí)處理事件但并不退出,下面有一篇超級(jí)棒的RunLoop
文章給大家介紹一下,我這就不展開(kāi)說(shuō)了,了解RunLoop
看那篇文章足夠了。
簡(jiǎn)單說(shuō)一下iOS的幾種持續(xù)化存儲(chǔ)方式
這個(gè)回答的就比較輕松了,下面隨便列幾個(gè)吧,大家有其他的可以補(bǔ)充一下:
NSUserDefaults
plist
NSKeyedArchiver
SQL
coredata
realm
WKWebView緩存和清理緩存的方法
WKWebView緩存的使用
主要通過(guò)NSURLCache
對(duì)請(qǐng)求的數(shù)據(jù)進(jìn)行緩存,具體實(shí)現(xiàn)可以去這個(gè)github上去查看~~~~
清楚緩存的方法
詳情看這篇blog,這里簡(jiǎn)單陳述一下,其實(shí)在iOS9
出了一個(gè)方法,調(diào)用一下就清除了:
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的實(shí)現(xiàn),以及autorelease對(duì)象什么時(shí)候會(huì)被release
這個(gè)問(wèn)題回答的不太好,說(shuō)實(shí)話當(dāng)時(shí)連續(xù)面試了兩家,鬧著已經(jīng)有點(diǎn)蒙了,這里借用喵神翻譯的一本書上的原話來(lái)描述一下:
? autorelease
它會(huì)將接受該消息的對(duì)象放到一個(gè)預(yù)先建立的自動(dòng)釋放池 (auto release pool
) 中,并在 自動(dòng)釋放池收到 drain
消息時(shí)將這些對(duì)象的引用計(jì)數(shù)減一,然后將它們從池子中移除 (這一過(guò)程形象地稱為“抽干池子”)。”
【摘錄來(lái)自: 王巍 (onevcat). “Swifter - Swift 必備 Tips (第三版)”。 iBooks. 】
實(shí)現(xiàn)原理的話大概就是被autorelease
標(biāo)記的類會(huì)被加入一個(gè)池子,當(dāng)這個(gè)池子drain
時(shí)里面的引用計(jì)數(shù)會(huì)減1。
談?wù)剬?duì)swift中extension的理解
說(shuō)實(shí)話其實(shí)這個(gè)問(wèn)題當(dāng)時(shí)比較吵,聽(tīng)的不是很清楚,問(wèn)了好幾遍問(wèn)題,挺尷尬的,下面簡(jiǎn)單介紹一下吧,因?yàn)檫@個(gè)在swift
中用的比較多:
- 首先
extension
在swift
中類似oc
的類目,可以擴(kuò)展方法,計(jì)算屬性,不能添加存儲(chǔ)屬性; - 可以通過(guò)
extension
讓類實(shí)現(xiàn)某個(gè)協(xié)議,一般這個(gè)用的也比較多,比如實(shí)現(xiàn)Comparable
這個(gè)協(xié)議; - 還有一個(gè)很重要的,就是可以通過(guò)
extension
對(duì)協(xié)議進(jìn)行擴(kuò)展,添加默認(rèn)實(shí)現(xiàn),屬于黑魔法吧,非常好用。
前兩點(diǎn)在面試的時(shí)候都又提到,最后一點(diǎn)壓根忘了,自己的面試發(fā)揮真不是一般的差- . -
swift寫時(shí)復(fù)制,自己的結(jié)構(gòu)體怎么實(shí)現(xiàn)寫時(shí)復(fù)制
幸好之前看了喵神翻譯的【Swift進(jìn)階】 ,受益頗深,下面同樣借用喵神的話給大家簡(jiǎn)單描述一下,大家可以去買這本書,還是挺劃算的,下面大量復(fù)制喵神書里面的內(nèi)容,請(qǐng)見(jiàn)諒:
在 Swift 標(biāo)準(zhǔn)庫(kù)中,像是 Array,Dictionary 和 Set 這樣的集合類型是通過(guò)一種叫做寫時(shí)復(fù)制 (copy-on-write) 的技術(shù)實(shí)現(xiàn)的。我們這里有一個(gè)整數(shù)數(shù)組:
var x = [1,2,3]
var y = x
如果我們創(chuàng)建了一個(gè)新的變量 y,并且把 x 賦值給它時(shí),會(huì)發(fā)生復(fù)制,現(xiàn)在 x 和 y 含有的是獨(dú)立的結(jié)構(gòu)體。在內(nèi)部,這些 Array 結(jié)構(gòu)體含有指向某個(gè)內(nèi)存的引用。這個(gè)內(nèi)存就是數(shù)組中元素所存儲(chǔ)的位置,它們位于堆 (heap) 上。在這個(gè)時(shí)候,兩個(gè)數(shù)組的引用指向的是內(nèi)存中同一個(gè)位置,這兩個(gè)數(shù)組共享了它們的存儲(chǔ)部分。不過(guò),當(dāng)我們改變 x 的時(shí)候,這個(gè)共享會(huì)被檢測(cè)到,內(nèi)存將會(huì)被復(fù)制。這樣一來(lái),我們得以獨(dú)立地改變兩個(gè)變量。昂貴的元素復(fù)制操作只在必要的時(shí)候發(fā)生,也就是我們改變這兩個(gè)變量的時(shí)候發(fā)生復(fù)制:
x.append(5)
y.removeLast()
x // [1, 2, 3, 5]
y // [1, 2]
如果 Array 結(jié)構(gòu)體中的引用在數(shù)組被改變的一瞬間時(shí)是唯一的話 (比如,沒(méi)有聲明 y),那么也不會(huì)有復(fù)制發(fā)生,內(nèi)存的改變將在原地進(jìn)行。這種行為就是寫時(shí)復(fù)制,作為一個(gè)結(jié)構(gòu)體的作者,你并不能免費(fèi)獲得這種特性,你需要自己進(jìn)行實(shí)現(xiàn)。當(dāng)你自己的類型內(nèi)部含有一個(gè)或多個(gè)可變引用,同時(shí)你想要保持值語(yǔ)義,并且避免不必要的復(fù)制時(shí),為你的類型實(shí)現(xiàn)寫時(shí)復(fù)制是有意義的。
下面看看通過(guò)簡(jiǎn)單的例子看一下:
var array = [COWStruct()]
array[0].change() // No copy
var otherArray = [COWStruct()]
var x = array[0]
x.change() // Copy
然而自己去實(shí)現(xiàn)一個(gè)寫時(shí)復(fù)制的話,首先你要判斷引用的唯一性,不是唯一的話進(jìn)行寫時(shí)復(fù)制,唯一的話直接改變需要改變的值。
結(jié)構(gòu)體和類以及它們的使用時(shí)機(jī)
結(jié)構(gòu)體和類主要的區(qū)別就是一個(gè)是值類型,一個(gè)是引用類型;值類型是寫時(shí)復(fù)制的,引用類型是不會(huì)發(fā)生寫時(shí)復(fù)制的;當(dāng)我們需要一個(gè)簡(jiǎn)單不需要繼承、不多變的數(shù)據(jù)時(shí)候我們首選結(jié)構(gòu)體,因?yàn)樵跀?shù)據(jù)結(jié)構(gòu)上來(lái)說(shuō)結(jié)構(gòu)體的存取效率是高于類的,反之當(dāng)我們需要一個(gè)數(shù)據(jù)結(jié)構(gòu)比較大,需要繼承,變化比較多的時(shí)候我們選擇類,因?yàn)樵谧兓倪^(guò)程中結(jié)構(gòu)體可能會(huì)發(fā)生寫時(shí)復(fù)制,而類不會(huì);下面舉一個(gè)簡(jiǎn)單的例子:
以Array
和NSMutableArray
來(lái)說(shuō):
當(dāng)有一個(gè)數(shù)組,數(shù)據(jù)量相對(duì)比較小,也不用去經(jīng)常改變它,只是用來(lái)存數(shù)據(jù)和取數(shù)據(jù),我們首先Array
當(dāng)數(shù)組的數(shù)據(jù)量很大的時(shí)候,并且經(jīng)常要去對(duì)他進(jìn)行添加,刪除等操作,并且經(jīng)常賦值給其他變量的話就推薦使用NSMutableArray
讓你實(shí)現(xiàn)一個(gè)數(shù)據(jù)存儲(chǔ)的框架的具體思路
這個(gè)是一個(gè)比較開(kāi)發(fā)性的問(wèn)題了,我想到的是用策略模式的方式來(lái)簡(jiǎn)單實(shí)現(xiàn)一下,使用策略模式的好處是方便文件類型的擴(kuò)展,下面我簡(jiǎn)單畫個(gè)簡(jiǎn)單的UML圖大家看一看吧:
當(dāng)然這只是一個(gè)初步的模型,還有很多細(xì)節(jié)待考慮,比如文件緩存什么的,是存本地還是磁盤,這都得去考慮,小弟只是拋磚引玉給個(gè)簡(jiǎn)單的思路。
寫完已經(jīng)是深夜了,以上是我丁香園電話面試的一些問(wèn)題,和之前面試一些回答不好的問(wèn)題,最后面試完我問(wèn)了一下丁香園的面試官對(duì)我感覺(jué)怎樣,他說(shuō)廣度還行深度不夠,我確實(shí)又有這點(diǎn)問(wèn)題,想學(xué)的知識(shí)比較多,有時(shí)候也沒(méi)來(lái)得及去看實(shí)現(xiàn)原理,只是簡(jiǎn)單的過(guò)一下,沒(méi)深入研究透徹,這是我需要加強(qiáng)的地方,之后如果有二面的話我會(huì)在繼續(xù)更新的,最后謝謝大家的閱讀~~我是WCL,大家可以去我github關(guān)注一波