下文轉載自:http://www.henishuo.com/objc-interview-two/ios
一、即時聊天App不會採用的網絡傳輸方式設計模式
A. UDP網絡
B. TCP 數據結構
C. HTTP 多線程
D. FTP架構
FTP:是文件傳輸協議,是File Transfer Protocol的簡稱,它的做用是用於控制互聯網上文件的雙向傳輸,所以必定不會是即時聊天使用的;併發
UDP:是面向無鏈接的傳輸層協議,數據傳輸是不可靠的,它只管發,無論收不收穫得;socket
TCP:是面向鏈接的,可靠的傳輸層協議;ide
HTTP:是超文本傳輸協議,對應於應用層,而HTTP是基於TCP的。函數
關於socket理論基礎知識,更詳細可閱讀下面的文章:Socket理論知識
參考答案:D
-----------------可愛的分割線------------------
二、下列技術不屬於多線程的是
A Block
B NSThread
C NSOperation
D GCD
蘋果提供了NSThread、NSOperation、GCD這三種技術用於處理多線程。
對於NSThread是須要本身管理其生命週期的;
對於NSOpeartion也是經常使用的技術之一,一般與NSOperationQueue一塊兒配合使用;
對於GCD是平時見到最多的,使用起來很方便,而它與block配合起來使用,簡單並且簡潔。
Block不是一項技術,只是代碼段,可是具有自動捕獲上下文信息的功能,與函數指針有點相似,其實全局函數就是特殊的block。
關於NSOperation/NSOperationQueue,可閱讀筆者的文章:多線程之NSOperatoin/NSOperationQueue;
參考答案:A
-----------------可愛的分割線------------------
三、線程和進程的區別不正確的是
A 進程和線程都是由操做系統所提供的程序運行的基本單元
B 線程之間有單獨的地址空間
C 進程和線程的主要差異在於它們是不一樣的操做系統資源管理方式
D 線程有本身的堆棧和局部變量
這是學習操做系統知識的時候常常會考試的內容,可是在工做中常常會遇到多線程處理問題。一般來講,一個進程就表明着一個應用程序,而操做系統爲了更好的利用資源,提供了線程用於處理併發。線程之間沒有有單獨的地址空間,處理完成以後還得回到主線程,因此,一個線程死掉就等於整個進程死掉。進程和線程都是操做系統的基本單元,只是分工不一樣,是兩種不一樣的資源管理方式。線程所須要的資源都來自於進程,它沒有本身獨立的資源,也就沒有本身的堆棧和局部變量。
修正:這裏參考答案與描述不符合的問題。
參考答案:B
-----------------可愛的分割線------------------
四、堆和棧的區別正確的是
A 對於棧來說,咱們須要手工控制,容易產生memory leak
B 對於堆來講,釋放工做由編譯器自動管理,無需咱們手工控制
C 在Windows下,棧是向高地址擴展的數據結構,是連續的內存區域,棧頂的地址和棧的最大容量是系統預先規定好的
D 對於堆來說,頻繁的new/delete勢必會形成內存空間的不連續,從而形成大量的碎片,使程序效率下降
棧是由編譯器管理的,不是咱們手動控制,可是棧所能分配的內存是比較少的,若是要處理大數據,則須要在堆上分配,所以在棧上比較容易出現Memory Leak;
對於堆,須要咱們本身申請內存,同時也須要咱們本身手動釋放,不然會形成內存泄露;對於堆,若是過多地申請內存空間,會致使內存空間不鏈接,從而形成內存碎片,使程序效率下降。
參考答案:D
-----------------可愛的分割線------------------
五、下列回調機制的理解不正確的是
A target-action:當兩個對象之間有⽐較緊密的關係時,如視圖控制器與其下的某個視圖。
B delegate:當某個對象收到多個事件,並要求同一個對象來處理全部事件時。委託機制必須依賴於某個協議定義的⽅法來發送消息。
C NSNotification:當須要多個對象或兩個無關對象處理同一個事件時。
D Block:適⽤於回調只發⽣生一次的簡單任務。
對於Target-Action機制,要求兩個對象之間有比較緊密的聯繫,好比在控制器與cell之間,可經過設置target爲控制器對象,而action則爲控制器中的某個回調方法;
對於Delegator機制,它是蘋果提供的標準回調機制,一般會提供一個標準的協議,而後由代理類遵照協議,最經常使用的用法是反向傳值,好比打開藍牙後要反饋給前一個界面藍牙的開關狀態;
對於通知,一般是多對多的關係,它並不關心是誰要處理消息,任意對象均可以註冊通知到通知中心,當發送通知時,全部註冊了該通知的對象均可以收到消息。最經常使用的場景是跨模塊,好比登陸模塊與其它模塊有着很是緊密的聯繫,可是登陸成功後各個地方可能須要作一些處理,所以一般會在登陸成功或者登出成功後發送通知,以便各個須要處理的模塊獲得正確的處理;
對於Block是至關簡單的,它只適用於一對一的關係,好比在作某個操做成功或者失敗後回調。
參考答案:B
-----------------可愛的分割線------------------
六、對於runloop的理解不正確的是
A 每個線程都有其對應的RunLoop
B 默認非主線程的RunLoop是沒有運行的
C 在一個單獨的線程中沒有必要去啓用RunLoop
D 能夠將NSTimer添加到runloop中
說到RunLoop,它但是多線程的法寶。一般來講,一個線程一次只能執行一個任務,執行完任務後就會退出線程。可是,對於主線程是不能退出的,所以咱們須要讓主線程即時任務執行完畢,也能夠繼續等待接收事件而不退出,那麼RunLoop就是關鍵法寶了。可是非主線程一般來講就是爲了執行某一任務的,執行完畢就須要歸還資源,所以默認是不運行RunLoop的。
每個線程都有其對應的RunLoop的,只是默認只有主線程的RunLoop是啓動的,其它子線程的RunLoop默認是不啓動的,若要啓動則須要手動啓動。
在一個單獨的線程中,若是須要在處理完某個任務後不退出,繼續等待接收事件,則須要啓用RunLoop。
NSRunLoop提供了一個添加NSTimer的方法,能夠指定Mode,若是要讓任何狀況下都回調,則須要設置Mode爲Common模式。
實質上,對於子線程的runloop默認是不存在的,由於蘋果採用了懶加載的方式。若是咱們沒有手動調用[NSRunLoop currentRunLoop],就不會去查詢是否存在當前線程的RunLoop,也就不會去加載,更不會建立。
下面是CFRunLoop的部分源碼:
// should only be called by Foundation
// t==0 is a synonym for "main thread" that always works
CF_EXPORT CFRunLoopRef _CFRunLoopGet0(pthread_t t) {
if (pthread_equal(t, kNilPthreadT)) {
t = pthread_main_thread_np();
}
__CFSpinLock(&loopsLock);
if (!__CFRunLoops) {
__CFSpinUnlock(&loopsLock);
CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks);
CFRunLoopRef mainLoop = __CFRunLoopCreate(pthread_main_thread_np());
CFDictionarySetValue(dict, pthreadPointer(pthread_main_thread_np()), mainLoop);
if (!OSAtomicCompareAndSwapPtrBarrier(NULL, dict, (void * volatile *)&__CFRunLoops)) {
CFRelease(dict);
}
CFRelease(mainLoop);
__CFSpinLock(&loopsLock);
}
CFRunLoopRef loop = (CFRunLoopRef)CFDictionaryGetValue(__CFRunLoops, pthreadPointer(t));
__CFSpinUnlock(&loopsLock);
if (!loop) {
CFRunLoopRef newLoop = __CFRunLoopCreate(t);
__CFSpinLock(&loopsLock);
loop = (CFRunLoopRef)CFDictionaryGetValue(__CFRunLoops, pthreadPointer(t));
if (!loop) {
CFDictionarySetValue(__CFRunLoops, pthreadPointer(t), newLoop);
loop = newLoop;
}
// don't release run loops inside the loopsLock, because CFRunLoopDeallocate may end up taking it
__CFSpinUnlock(&loopsLock);
CFRelease(newLoop);
}
if (pthread_equal(t, pthread_self())) {
_CFSetTSD(__CFTSDKeyRunLoop, (void *)loop, NULL);
if (0 == _CFGetTSD(__CFTSDKeyRunLoopCntr)) {
_CFSetTSD(__CFTSDKeyRunLoopCntr, (void *)(PTHREAD_DESTRUCTOR_ITERATIONS-1), (void (*)(void *))__CFFinalizeRunLoop);
}
}
return loop;
關鍵加載過程以下:
檢查全局字典裏是否存在該線程的runLoop,若是有則退出,不然
建立一個新的runLoop放到全局字典中
參考答案:C
-----------------可愛的分割線------------------
七、斷點續傳須要在請求頭中添加的控制續傳最重要的關鍵字
A range
B length
C type
D size
理由:對於實現文件的斷點續傳和斷點下載,須要設置請求頭中的Range實體頭,指定第一個字節的位置和最後一個字節的位置,而與之對應的響應頭有Content-Range,指示了整個實體的長度及部分插入位置,如Content-Range: bytes 0-500/801,指定了範圍爲當前範圍與文件總大小。
參考答案:A
-----------------可愛的分割線------------------
八、MVC優勢不正確的是
A 低耦合性
B 高重用性和可適用性
C 較低的生命週期成本
D 代碼高效率
理由:MVC只是一種構架設計模式,它的出現有比較久的歷史了。Model-Controller-View是在開發中最多見到的架構設計模式,經過將Model、View、Controller三者相互聯繫,以Model做爲數據加工廠,以Controller做爲橋樑,處理業務,而View只是數據展現層,理應與業務無關。MVC設計模式下降了耦合性,提供了重用性和適用性,可有效地提升開發效率。
參考答案:D
-----------------可愛的分割線------------------
九、混編ObjC和C++的源碼文件須要將文件格式的後綴改成
A .c
B .cpp
C .mm
D .m
理由:ObjC要想與C++源代碼文件混編,那麼就須要將文件後綴改成.mm。這個沒有什麼可細說了,記住就行了!
參考答案:C
-----------------可愛的分割線------------------
十、ObjC聲明一個類所要用到的編譯指令是
A @interface SomeClass
B @protocol SomeClass
C @implementation SomeClass
D @autorelease SomeClass
理由:A是聲明類的指令;B是聲明協議的指令;C是實現類的定義的指令;D是聲明自動釋放池的指令。
參考答案:A
-----------------可愛的分割線------------------
十一、MRC文件在ARC工程混合編譯時,須要在文件的Compiler Flags上添加什麼參數
A -shared
B -fno-objc-arc
C -fobjc-arc
D -dynamic
理由:對於ARC工程中,若是要混編MRC文件,須要在工程的Compiler Flags添加-fno-bojc-arc;對於MRC工程中,若是要混編ARC文件,須要設置爲-fobjc-arc。
參考答案:B
-----------------可愛的分割線------------------
十二、下面關於Objective-C內存管理的描述錯誤的是
A 當使用ARC來管理內存時,代碼中不能夠出現autorelease
B autoreleasepool 在 drain 的時候會釋放在其中分配的對象
C 當使用ARC來管理內存時,在線程中大量分配對象而不用autoreleasepool則可能會形成內存泄露
D 在使用ARC的項目中不能使用NSZone
理由:ARC只是在大多時候編譯自動爲咱們添加上內存管理的代碼,只是咱們的源代碼看不到而已,可是在編譯時,編譯器會添加上相關內存管理代碼。對於自動釋放池,在drain時會將自動釋放池中的全部對象的引用計數減一,若引用計數爲0,則會自動釋放掉其內存。若是在線程中須要大量分配內存,咱們理應添加上自動釋放池,以防內存泄露。好比在for循環中要分配大量的內存處理數據,那麼咱們應該在for循環內添加自動釋放池,在每一個循環後就將內存釋放掉,防止內存泄露。在ARC項目中,天然不能手動使用NSZone,也不能調用父類的dealloc。
參考答案:A
-----------------可愛的分割線------------------
1三、下面哪一個不屬於對象數據序列化方法
A JSON
B Property List
C XML
D HTTP
理由:數據序列化是將對象的數據轉化成某一種格式的數據,在ios開發中最經常使用的就是JSON,部分公司會採用XML,筆者從未遇到過使用Property List來傳輸數據的,可是咱們經過會將一些小量的數據存儲到Property List中,好比NSUserDefaults就是操做plist文件的。而HTTP是超文件傳輸協議,只是一種協議。
參考答案:D
-----------------可愛的分割線------------------
1四、在UIKit中,frame與bounds的區別是
A. frame 是 bounds 的別名
B. frame 是 bounds 的繼承類
C. frame 的參考系是父視圖座標,bounds 的參考系是自身的座標
D. frame 的參考系是自身座標,bounds 的參考系是父視圖的座標
理由:frame的參考系是父視圖的座標系,而bounds是參考自個人座標系。修改父視圖的bounds能夠移動子視圖。不過一般不會這麼幹法,若是父視圖不須要移動,沒有必要修改bounds,直接修改子視圖的frame就能夠實現了。
參考答案:C
-----------------可愛的分割線------------------
1五、下面關於線程管理錯誤的是
A. GCD所用的開銷要比NSThread大
B. 能夠在子線程中修改UI元素
C. NSOperationQueue是比NSthread更高層的封裝
D. GCD能夠根據不一樣優先級分配線程
理由:首先,UI元素的更新必須在主線程。GCD與Block配合使用,block須要自動捕獲上下文變量信息等,所以須要更多的資源,故比NSThread開銷要大一些。NSOperationQueue與NSOperation配合使用,比NSThread更易於操做線程。GCD提供了多個優先級,咱們能夠根據設置優先級,讓其自動爲咱們分配線程。
關係NSOperationQueue,請閱讀文章:NSOperationQueue
參考答案:B
-----------------可愛的分割線------------------
最後
文章中不免有說得不合理的地方,若是您認爲說法不正確或者哪裏有錯誤的地方,請在評論中留言,筆者會在第一時間修正!!!