from 邏輯教育
第一部分:iOS面試題(上)
1: 談?wù)勀銓?duì)KVC的理解
2: iOS項(xiàng)目中引用多個(gè)第三方庫(kù)引發(fā)沖突的解決方法
3: GCD實(shí)現(xiàn)多讀單寫
4: 講一下atomic的實(shí)現(xiàn)機(jī)制;為什么不能保證絕對(duì)的線程安全?
5: Autoreleasepool所使用的數(shù)據(jù)結(jié)構(gòu)是什么?
6: AutoreleasePoolPage結(jié)構(gòu)體了解么?
7: iOS中內(nèi)省的幾個(gè)方法?
8: class方法和objc_getClass方法有什么區(qū)別?
9: 分類和擴(kuò)展有什么區(qū)別?可以分別用來(lái)做什么?
10: 分類有哪些局限性?分類的結(jié)構(gòu)體里面有哪些成員?
11: 能不能簡(jiǎn)述一下Dealloc的實(shí)現(xiàn)機(jī)制第二部分:iOS面試題(中)
12: HTTPS和HTTP的區(qū)別
13: TCP為什么要三次握手,四次揮手?
14: 對(duì)稱加密和非對(duì)稱加密的區(qū)別?分別有哪些算法的實(shí)現(xiàn)?
15: HTTPS的握手流程?為什么密鑰的傳遞需要使用非對(duì)稱加密?雙向認(rèn)證了解么?
16: 如何用Charles抓HTTPS的包?其中原理和流程是什么?
17: 什么是中間人攻擊?如何避免?
18: 了解編譯的過(guò)程么?分為哪幾個(gè)步驟?
19: 靜態(tài)鏈接了解么?靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的區(qū)別?
20: App網(wǎng)絡(luò)層有哪些優(yōu)化策略?
21: 排序題︰冒泡排序,選擇排序,插入排序,快速排序(二路,三路)能寫出那些?
22: iOS開發(fā)中的加密方式
23: App安全,數(shù)字簽名,App簽名,重簽名第三部分:iOS面試題(下)
24: OC數(shù)據(jù)類型
25: property和屬性修飾符
26: 成員變量ivar和屬性property的區(qū)別,以及不同關(guān)鍵字的作用
27: 類簇的優(yōu)缺點(diǎn)
28: 談?wù)勗O(shè)計(jì)模式
29: 談?wù)劶軜?gòu)設(shè)計(jì)
30: ReactiveCocoa的使用及優(yōu)缺點(diǎn)
31: 類的繼承,類能否多繼承,協(xié)議能不能做繼承?
32: 分類(category)和類擴(kuò)展(extension)的區(qū)別
33: 如何實(shí)現(xiàn)week
34: 字典注意事項(xiàng):setvalue和setobject的區(qū)別
35: 多線程和鎖
36: WebSocket與TCP Socket的區(qū)別
37: 事件傳遞和響應(yīng)機(jī)制
以下答案為本人自己查找資料整理回答
答案:
第一部分:
1: 談?wù)勀銓?duì)KVC的理解
答:key-value- coding 鍵值編碼,通過(guò)屬性字符串名稱訪問(wèn)或修改屬性機(jī)制,api為:valueForKey: 、 setValue:、 valueForKeyPath: 、setValue:
setValue原理為:

valueForKey原理為:

2: iOS項(xiàng)目中引用多個(gè)第三方庫(kù)引發(fā)沖突的解決方法
答:表現(xiàn)為編譯報(bào)dumplicate symbols錯(cuò)誤。
解決方式
一、使用命令將 .a 庫(kù)中相同的包
二、在編譯鏈接項(xiàng)中添加-dead_strip項(xiàng)
一、使用命令將 .a 庫(kù)中相同的包
1、創(chuàng)建臨時(shí)文件夾,用于存放armv7平臺(tái)解壓后的.o文件:mkdir armv7
2、取出armv7平臺(tái)的包:lipo libx.a -thin armv7 -output armv7/libx-armv7.a
3、查看庫(kù)中所包含的文件列表:ar -t armv7/libx-armv7.a
4、解壓出object file(即.o后綴文件):cd armv7 && ar xv libx-armv7.a
5、找到?jīng)_突的包(AFHTTPSessionManager),刪除掉rm AFHTTPSessionManager.o
6、重新打包object file:cd .. && ar rcs libx-armv7.a armv7/*.o,可以再次使用[2]中命令確認(rèn)是否已成功將文件去除
7、將其他幾個(gè)平臺(tái)(armv7s, i386, arm64, x86_64)包逐一做上述[1-6]操作
8、重新合并為fat file的.a文件:
lipo -create libx-armv7.a libx-armv7s.a libx-i386.a -output libSDK-new.a
9、拷貝到項(xiàng)目中覆蓋源文件:
cp libSDK-new.a /Users/tony/Desktop/XXXProject/Lib/libSDK.a
解決二
二、在編譯鏈接項(xiàng)中添加-dead_strip項(xiàng)
在Build Settings->Other link flags中添加-dead_strip,如果Other link flags中有-all_load與-force_load則刪掉,只填-dead_strip
3: GCD實(shí)現(xiàn)多讀單寫
- (void)viewDidLoad {
[super viewDidLoad];
_syncQueue = dispatch_queue_create("ioQueue", DISPATCH_QUEUE_CONCURRENT);
for (int i = 0; i < 100; i ++) {
[self setSomeString:[NSString stringWithFormat:@"%d",i]];
NSLog(@"someString:%@",[self someString]);
}
}
-(NSString *)someString {
__block NSString *localSomeString;
dispatch_sync(_syncQueue, ^{
sleep(1);
localSomeString = self.string;
});
return localSomeString;
}
- (void)setSomeString:(NSString *)someString {
dispatch_barrier_async(_syncQueue, ^{
sleep(1);
self.string = someString;
});
}
4: 講一下atomic的實(shí)現(xiàn)機(jī)制;為什么不能保證絕對(duì)的線程安
全?
答:
- atomic用于保證屬性setter、getter的原子性操作,相當(dāng)于在getter和setter內(nèi)部加了線程同步的鎖
- 這個(gè)鎖只能保證單獨(dú)的讀或者單獨(dú)的寫詩(shī)線程安全,如果同時(shí)讀和寫,就不是線程安全。
- 解決的方法就是讀和寫用同一把鎖。
5: Autoreleasepool所使用的數(shù)據(jù)結(jié)構(gòu)是什么?
答:雙向鏈表
6: AutoreleasePoolPage結(jié)構(gòu)體了解么?

7: iOS中內(nèi)省的幾個(gè)方法?
答:四個(gè)方法,判斷類,判斷方法
-(BOOL) isKindOfClass: 判斷是否是這個(gè)類或者這個(gè)類的子類的實(shí)例
-(BOOL) isMemberOfClass: 判斷是否是這個(gè)類的實(shí)例
-(BOOL) respondsToSelector: 判讀實(shí)例是否有這樣方法
+(BOOL) instancesRespondToSelector: 判斷類是否有這個(gè)方法
8: class方法和objc_getClass方法有什么區(qū)別?
答:
1.object_getClass(obj)
返回的是obj的isa指針;
-
[obj class]
obj為實(shí)例對(duì)象
調(diào)用的是實(shí)例方法:- (Class)class,返回的obj對(duì)象中的isa指針;
obj為類對(duì)象(包括元類和根類以及根元類)
調(diào)用的是類方法:+ (Class)class,返回的結(jié)果為調(diào)用者本身。
再回顧一下經(jīng)典圖:
image.png
9: 分類和擴(kuò)展有什么區(qū)別?可以分別用來(lái)做什么?
- Class Extension在編譯的時(shí)候,它的數(shù)據(jù)就已經(jīng)包含在類信息中
- Category是在運(yùn)行時(shí),才會(huì)將數(shù)據(jù)合并到類信息中
- 擴(kuò)展作用:為一個(gè)類添加額外的原來(lái)沒(méi)有變量,方法和屬性
一般的類擴(kuò)展寫到.m文件中
一般的私有屬性寫到.m文件中的類擴(kuò)展中
10: 分類有哪些局限性?分類的結(jié)構(gòu)體里面有哪些成員?
答:不能直接添加屬性,需要通過(guò)Runtime動(dòng)態(tài)添加get、set方法達(dá)到添加屬性目的,注意,只能通過(guò)get、set方法獲取,不能通過(guò)成員變量獲取,除非用runtime添加成員變量。
struct category_t {
const char *name;
classref_t cls;
WrappedPtr<method_list_t, PtrauthStrip> instanceMethods;
WrappedPtr<method_list_t, PtrauthStrip> classMethods;
struct protocol_list_t *protocols;
struct property_list_t *instanceProperties;
// Fields below this point are not always present on disk.
struct property_list_t *_classProperties;
method_list_t *methodsForMeta(bool isMeta) {
if (isMeta) return classMethods;
else return instanceMethods;
}
property_list_t *propertiesForMeta(bool isMeta, struct header_info *hi);
protocol_list_t *protocolsForMeta(bool isMeta) {
if (isMeta) return nullptr;
else return protocols;
}
};
11: 能不能簡(jiǎn)述一下Dealloc的實(shí)現(xiàn)機(jī)制
答:
- 當(dāng)一個(gè)對(duì)象要釋放時(shí),會(huì)自動(dòng)調(diào)用dealloc,接下的調(diào)用軌跡是
- dealloc
- _objc_rootDealloc
- rootDealloc
- object_dispose
- objc_destructInstance、free
第二部分:
12: HTTPS和HTTP的區(qū)別
答:
- HTTP:超文本傳輸協(xié)議,明文傳輸
- HTTPS:在HTTP基礎(chǔ)上增加SSL/TLS加密層,密文傳輸
- HTTP端口號(hào)為8080,HTTPS端口號(hào)為443
- HTTPS需要證書認(rèn)證,一般需要申請(qǐng)證書的費(fèi)用
- HTTP 頁(yè)面響應(yīng)速度比 HTTPS 快,主要是因?yàn)?HTTP 使用 TCP 三次握手建立連接,客戶端和服務(wù)器需要交換 3 個(gè)包,而 HTTPS除了 TCP 的三個(gè)包,還要加上 ssl 握手需要的 9 個(gè)包,所以一共是 12 個(gè)包。
13: TCP為什么要三次握手,四次揮手?
答:為了確保TCP正確地建立連接和斷開連接
詳情請(qǐng)看: 這一次,徹底搞懂TCP3次握手、4次揮手好嗎?
14: 對(duì)稱加密和非對(duì)稱加密的區(qū)別?分別有哪些算法的實(shí)現(xiàn)?
答:
- 對(duì)稱加密:使用同一個(gè)秘鑰,非對(duì)稱加密使用2把密鑰加密和解密,即公鑰、私鑰
- 常見(jiàn)的加密方式:
- 不可逆
- 單向散列函數(shù):MD5、SHA
- 可逆
- 對(duì)稱加密:DES、3DES、AES
- 非對(duì)稱加密:RSA
- 其他
- 混合密碼系統(tǒng)
- 數(shù)字簽名
- 證書
- 不可逆
15: HTTPS的握手流程?為什么密鑰的傳遞需要使用非對(duì)稱加密?雙向認(rèn)證了解么?
答:
- 為什么密鑰的傳遞需要使用非對(duì)稱加密?因?yàn)榉乐姑荑€被竊取、篡改。
16: 如何用Charles抓HTTPS的包?其中原理和流程是什么?
答:客戶端安裝證書。原理就是利用代理網(wǎng)絡(luò)對(duì)客戶端的網(wǎng)絡(luò)請(qǐng)求進(jìn)行代理轉(zhuǎn)發(fā)。
17: 什么是中間人攻擊?如何避免?
答:
- 指攻擊者與通訊的兩端分別創(chuàng)建獨(dú)立的聯(lián)系,并交換其所收到的數(shù)據(jù),使通訊的兩端認(rèn)為他們正在通過(guò)一個(gè)私密的連接與對(duì)方直接對(duì)話,但事實(shí)上整個(gè)會(huì)話都被攻擊者完全控制。
- 使用HTTPS
18: 了解編譯的過(guò)程么?分為哪幾個(gè)步驟?
- 預(yù)處理:處理以#開頭的命令,刪除注釋,解開宏定義等
- 編譯:詞法分析、語(yǔ)法分析、語(yǔ)義分析、中間代碼生成與優(yōu)化,最終生成匯編代碼
- 匯編:將匯編代碼翻譯成機(jī)器碼,生成.o目標(biāo)文件
- 鏈接:將多個(gè).o目標(biāo)文件和其他函數(shù)庫(kù)鏈接成可執(zhí)行文件
19: 靜態(tài)鏈接了解么?靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的區(qū)別?
答:
- 靜態(tài)鏈接:將各個(gè)模塊之間互相引用的部分都處理好,使得各個(gè)模塊之間能夠正確的銜接
- 區(qū)別:靜態(tài)庫(kù)在程序鏈接成可執(zhí)行文件時(shí)就已經(jīng)鏈接完成,動(dòng)態(tài)庫(kù)是在程序啟動(dòng)、運(yùn)行時(shí)才進(jìn)行鏈接
20: App網(wǎng)絡(luò)層有哪些優(yōu)化策略?
1、優(yōu)化DNS解析和緩存
2、網(wǎng)絡(luò)質(zhì)量檢測(cè)(根據(jù)網(wǎng)絡(luò)質(zhì)量來(lái)改變策略)
3、提供網(wǎng)絡(luò)服務(wù)優(yōu)先級(jí)和依賴機(jī)制
4、提供網(wǎng)絡(luò)服務(wù)重發(fā)機(jī)制
5、減少數(shù)據(jù)傳輸量
6、優(yōu)化海外網(wǎng)絡(luò)性能
7、購(gòu)買配置CDN網(wǎng)絡(luò)加速服務(wù)
21: 排序題︰冒泡排序,選擇排序,插入排序,快速排序(二路,三路)能寫出那些?
22: iOS開發(fā)中的加密方式
- base64加密
- Token值加密:服務(wù)端生成token,客戶端保存后每次請(qǐng)求發(fā)送token到服務(wù)端,用來(lái)判斷登陸狀態(tài)。
- MD5加密--(信息-摘要算法) 哈希算法之一、
- 時(shí)間戳密碼以及指紋識(shí)、人臉識(shí)別
- keychain保存
23: App安全,數(shù)字簽名,App簽名,重簽名
- iOS應(yīng)用程序在上傳App Store后,蘋果會(huì)對(duì)ipa包進(jìn)行數(shù)字簽名,用來(lái)保證app包的安全性
第三部分
24: OC數(shù)據(jù)類型
略
25: property和屬性修飾符
略
26: 成員變量ivar和屬性property的區(qū)別,以及不同關(guān)鍵字的作用
- ivar是ARC之前的產(chǎn)物,對(duì)象內(nèi)存需要自己管理
- ARC之后新增property特性,編譯器自動(dòng)生成ivar成員變量、get方法、set方法。
- 分類中的property不會(huì)生成ivar成員變量、get方法、set方法,需要自己通過(guò)runtime生成。
27: 類簇的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
- 可以將抽象基類背后的復(fù)雜細(xì)節(jié)隱藏起來(lái)。
- 程序員不會(huì)需要記住各種創(chuàng)建對(duì)象的具體類實(shí)現(xiàn),簡(jiǎn) 化了開發(fā)成本,提高了開發(fā)效率。
- 便于進(jìn)行封裝和組件化。
- 減少了 if-else 這樣缺乏擴(kuò)展性的代碼。
- 增加新功能支持不影響其他代碼。
缺點(diǎn)=
- 已有的類簇非常不好擴(kuò)展。
28: 談?wù)勗O(shè)計(jì)模式
29: 談?wù)劶軜?gòu)設(shè)計(jì)
- 組件化
- MVVM
30: ReactiveCocoa的使用及優(yōu)缺點(diǎn)
31: 類的繼承,類能否多繼承,協(xié)議能不能做繼承?
不能
32: 分類(category)和類擴(kuò)展(extension)的區(qū)別
略
33: weak實(shí)現(xiàn)原理
- weak的原理在于底層維護(hù)了一張weak_table_t結(jié)構(gòu)的hash表,key是所指對(duì)象的地址,value是weak指針的地址數(shù)組。
- weak 關(guān)鍵字的作用是弱引用,所引用對(duì)象的計(jì)數(shù)器不會(huì)加1,并在引用對(duì)象被釋放的時(shí)候自動(dòng)被設(shè)置為 nil。
- 對(duì)象釋放時(shí),調(diào)用clearDeallocating函數(shù)根據(jù)對(duì)象地址獲取所有weak指針地址的數(shù)組,然后遍歷這個(gè)數(shù)組把其中的數(shù)據(jù)設(shè)為nil,最后把這個(gè)entry從weak表中刪除,最后清理對(duì)象的記錄。
-
SideTable、weak_table_t、weak_entry_t這樣三個(gè)結(jié)構(gòu),它們之間的關(guān)系如下圖所示。
image.png
34: 字典注意事項(xiàng):setvalue和setobject的區(qū)別
setvalue需要注意對(duì)象為nil情況,為nil會(huì)導(dǎo)致崩潰,setobject不會(huì)
35: 多線程和鎖
- 多線程:利用cpu多核特性,同時(shí)執(zhí)行多個(gè)任務(wù),單核cpu通過(guò)任務(wù)調(diào)度模擬多線程。
- 鎖,為了防止多線程對(duì)讀和寫操作數(shù)據(jù)不一致問(wèn)題,和多線程安全問(wèn)題,有必要進(jìn)行加鎖操作
36: WebSocket與TCP Socket的區(qū)別
- WebSocket protocol 是HTML5一種新的協(xié)議。它實(shí)現(xiàn)了瀏覽器與服務(wù)器全雙工通信(full-duplex)。一開始的握手需要借助HTTP請(qǐng)求完成。
- TCP Socket不是協(xié)議,是一套API,是對(duì)TCP、UDP復(fù)雜傳輸方法的一套封裝。位于應(yīng)用層和傳輸層之間。
37: 事件傳遞和響應(yīng)機(jī)制
- 事件的產(chǎn)生
- 發(fā)生觸摸事件后,系統(tǒng)會(huì)將該事件加入到一個(gè)由UIApplication管理的事件隊(duì)列中,為什么是隊(duì)列而不是棧?因?yàn)殛?duì)列的特點(diǎn)是FIFO,即先進(jìn)先出,先產(chǎn)生的事件先處理才符合常理,所以把事件添加到隊(duì)列。
- UIApplication會(huì)從事件隊(duì)列中取出最前面的事件,并將事件分發(fā)下去以便處理,通常,先發(fā)送事件給應(yīng)用程序的主窗口(keyWindow)。
- 主窗口會(huì)在視圖層次結(jié)構(gòu)中找到一個(gè)最合適的視圖來(lái)處理觸摸事件,這也是整個(gè)事件處理過(guò)程的第一步。
- 找到合適的視圖控件后,就會(huì)調(diào)用視圖控件的touches方法來(lái)作具體的事件處理。
- 事件的傳遞
- 觸摸事件的傳遞是從父控件傳遞到子控件
- 也就是UIApplication->window->尋找處理事件最合適的view
- 注 意: 如果父控件不能接受觸摸事件,那么子控件就不可能接收到觸摸事件

