本文非原創(chuàng),是看到MrPeak大大出的題目
1.NSString如何計算字符的個數(shù)?
將一個NSString類型字符串獲取的長度轉(zhuǎn)換成類似ASCII編碼的長度,如漢字2個字節(jié),英文以及符號1個字節(jié)這個功能。由于使用[NSString length]方法調(diào)用獲取的長度是一個中文和一個英文都是一個字節(jié),而使用
[NSString lengthOfBytesUsingEncoding:NSASCIIStringEncoding] 方法無法識別中文編碼,真是令人揪心。于是想獲得一個char*類型的字符串,然后自己遍歷一遍,將它整理為類似ASCII編碼的格式,這里要用到[NSString cStringUsingEncoding:NSUnicodeStringEncoding]函數(shù)獲得一個const char*指針,然后對這個字符串進(jìn)行遍歷,遇/0就跳過,否則length+1,下面是代碼,拿出來與大家分享:
這里一定要使用gbk的編碼方式,網(wǎng)上有很多用Unicode的,但是部分漢字計算字節(jié)數(shù)錯誤;比如開使用unicode編碼計算出來為1個字節(jié)
NSString *text = @"Hello World! 你好,中國!";
計算以上string的長度:
NSLog(@"text.length = %lu",text.length);
得到的結(jié)果為19,明顯中文符號算為1的長度。
- (int)convertToInt:(NSString*)strtemp//判斷中英混合的的字符串長度
{
int strlength = 0;
char *p = (char *)[strtemp cStringUsingEncoding:NSUnicodeStringEncoding];
for (int i=0; i < [strtemp lengthOfBytesUsingEncoding:NSUnicodeStringEncoding]; i++) {
if (*p) {
p++;
strlength++;
}
else {
p++;
}
}
return strlength;
}
NSLog(@"len = %d",[self convertToInt:text]);
結(jié)算結(jié)果為:25字節(jié)。
2.PKI體系當(dāng)中加密和簽名有什么區(qū)別?
3.如何自己高效實(shí)現(xiàn)NSUserDefault?
數(shù)據(jù)量一大讀取成本就高,敏感數(shù)據(jù)容易被破解,因?yàn)镹SUserDefault實(shí)際上是明文存在 plist 中的,所以建議用戶安全相關(guān)的(如 token)盡量不要放在 UserDefault 中,即使要存也最好做一次加密再存,最好的方式是存在 Keychain 中。UserDefault 更適合存一些輕量的數(shù)據(jù),如當(dāng)前版本(可用來做檢測更新以及展示歡迎頁或其他邏輯)。建議使用 Sqlite 或其他數(shù)據(jù)存儲方式
4.解釋下tcp的慢啟動特性。
5.如何用HTTP實(shí)現(xiàn)長連接?
首先,http能實(shí)現(xiàn)長連接,是建立在tcp協(xié)議的基礎(chǔ)上的。但http中,其實(shí)沒有長連接這樣的類型。保持一個tcp連接是長連接。完全是通過程序員手動來控制的。
如果程序員,想讓一個http連接,比如該連接叫A,讓A成為一個長連接。
那么,就不調(diào)用該連接的close()方法。
直到,不再需要A連接的時候,才關(guān)閉該連接。
那么,A就叫做一個長連接
HTTP連接分為兩種:
HTTP短連接(非持久連接)是指,客戶端和服務(wù)端進(jìn)行一次HTTP請求/響應(yīng)之后,就關(guān)閉連接。所以,下一次的HTTP請求/響應(yīng)操作就需要重新建立連接。
HTTP長連接(持久連接)是指,客戶端和服務(wù)端建立一次連接之后,可以在這條連接上進(jìn)行多次請求/響應(yīng)操作。持久連接可以設(shè)置過期時間,也可以不設(shè)置。
HTTP短連接
在首部字段中設(shè)置Connection:close,則在一次請求/響應(yīng)之后,就會關(guān)閉連接。
HTTP長連接
在首部字段中設(shè)置Connection:keep-alive 和Keep-Alive: timeout=60,表明連接建立之后,空閑時間超過60秒之后,就會失效。如果在空閑第58秒時,再次使用此連接,則連接仍然有效,使用完之后,重新計數(shù),空閑60秒之后過期。
設(shè)置HTTP長連接,無過期時間
在首部字段中只設(shè)置Connection:keep-alive,表明連接永久有效。
實(shí)現(xiàn)原理:
了解怎么設(shè)置之后,就開始用起來。然而,問題來了。在請求頭中設(shè)置Connection:keep-alive,為什么連接空閑一段時間之后,還是斷開了呢?這是因?yàn)閏onnection字段只有服務(wù)端設(shè)置才有效。
HTTP操作是請求/響應(yīng)成對出現(xiàn)的,即先有客戶端發(fā)出請求,后有服務(wù)端處理請求。所以,一次HTTP操作的終點(diǎn)操作在服務(wù)端上,關(guān)閉也是由服務(wù)端發(fā)起的。
6.HTTP2.0針對同一個域名的多個請求,會建立多少個tcp連接?
7.數(shù)據(jù)庫建表的時候索引有什么用?
8.Full Text Search為什么快?
9.iOS下如何實(shí)現(xiàn)指定線程數(shù)目的線程池?
10.介紹下iOS設(shè)備獲取唯一設(shè)備號的歷史變遷。
iOS中獲取設(shè)備唯一標(biāo)示符的方法一直隨版本的更新而變化
但是,推薦大家用KeyChain來保存獲取到的UDID,因?yàn)锳PP刪了再裝回來,也可以從KeyChain中讀取回來,哈哈,公司的項(xiàng)目都是把UDID存在KeyChain。(SAMKeychain)

11.函數(shù)式編程當(dāng)中的 first-class function是什么意思呢?
12.如何使用runtime hook一個class的某個方法,又如何hook某個instance的方法?
首先要考慮 hook是否有公開頭文件的類
方法一,hook已有公開頭文件的類,寫一個Utility函數(shù).
方法二,hook沒有公開頭文件的類,需要另建一個類作為新函數(shù)載體,然后先為被hook的類增加函數(shù),再替換。
方法三,hook沒有公開頭文件的類,另建一個類作為新函數(shù)載體,用新函數(shù)替換舊函數(shù),并把舊函數(shù)保存到靜態(tài)變量里.
13.談下Objective C都有哪些鎖機(jī)制,你一般用哪個?
iOS開發(fā)中常用的鎖有如下幾種:
- @synchronized 同步鎖
- NSLock 對象鎖
- NSRecursiveLock 遞歸鎖
- NSConditionLock 條件鎖
- pthread_mutex 互斥鎖(C語言)
- dispatch_semaphore 信號量實(shí)現(xiàn)加鎖(GCD)
- OSSpinLock 參考YY
14.聊下HTTP post的body體使用form-urlencoded和multipart/form-data的區(qū)別。
http與服務(wù)器交互最常用的就是GET,POST兩個方法.
1.application/x-www-form-urlencoded:
這是標(biāo)準(zhǔn)且默認(rèn)的編碼格式。當(dāng)action為get時候,客戶端把form數(shù)據(jù)轉(zhuǎn)換成一個字串a(chǎn)ppend到url后面,用?分割。當(dāng)action為post時候,瀏覽器把form數(shù)據(jù)封裝到http body中,然后發(fā)送到server。
2.multipart/form-data:
multipart表示的意思是單個消息頭包含多個消息體的解決方案。multipart媒體類型對發(fā)送非文本的各媒體類型是有用的。一般多用于文件上傳。
15.讓你設(shè)計一種機(jī)制檢測UIViewController的內(nèi)存泄漏,你會怎么做?
一般都是用Instrument來測試的.
16.通過[UIImage imageNamed:]生成的對象什么時候被釋放?
為了方便,一開始讀取圖像資源的時候都是直接使用了[UIImage imageNamed:@""]方法,這個方法非常方便,一句話就可以從bundle中讀取圖片。而[UIImage imageNamed:]只適合與UI界面中小的貼圖的讀取,而一些比較大的資源文件應(yīng)該盡量避免使用這個接口。使用[UIImage imageWithContentsOfFile]替代.
類方法創(chuàng)建的會自動加入到自動釋放池中。
17.applicationWillEnterForeground和applicationDidBecomeActive都會在哪些場景下被調(diào)用?舉例越多越好。
當(dāng)程序進(jìn)入后臺狀態(tài)時,名為applicationWillEnterForeground委托方法會被調(diào)用:
-(void)applicationWillEnterForeground:(UIApplication *)application { }
當(dāng)程序復(fù)原時,applicationDidBecomeActive 委托方法會被調(diào)用
推送、支付、應(yīng)用跳轉(zhuǎn)、分享、退到后臺等.
18.如何終止正在運(yùn)行的工作線程?
一般來講網(wǎng)絡(luò)操作都是可以終止的,就 URLSession 來說,每個 task 都有 cancel 方法,直接 cancel 掉就好了。如果說是耗時的計算類線程,在恰當(dāng)?shù)牡胤郊觽€ flag,cancel 時把 flag 置 false,線程就能及時終止。但是,GCD本身是沒有提供這樣的API的。
終止一個線程中正在執(zhí)行的任務(wù):
設(shè)置一個標(biāo)識符,假如是BOOL類型的,當(dāng)它為NO的時候執(zhí)行任務(wù),當(dāng)它變?yōu)閅ES的時候終止執(zhí)行任務(wù)。
dispatch_async(dispatch_get_global_queue(0, 0), ^{
for (NSInteger i = 0; i < 10000; i++) {
NSLog(@"%lu",(long)i);
sleep(2);
if (flag == YES) {
NSLog(@"終止任務(wù)...");
}
}
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"回到主線程刷新UI");
});
});
19.窮舉iOS下所有的本地持久化方案。
所有的本地持久化數(shù)據(jù)存儲的本質(zhì)都是寫文件,而且只能存到沙盒中。
沙盒機(jī)制是蘋果的一項(xiàng)安全機(jī)制,本質(zhì)就是系統(tǒng)給每個應(yīng)用分配了一個文件夾來存儲數(shù)據(jù),而且每個應(yīng)用只能訪問分配給自己的那個文件夾,其他應(yīng)用的文件夾是不能訪問的。
數(shù)據(jù)存儲的核心都是寫文件。主要有四種持久化方式:屬性列表,對象序列化,SQLite 數(shù)據(jù)庫, CoreData