面試技巧攻克-多線程和網絡編程

一、iOS中多線程編程

1、自旋鎖和互斥鎖的區別?

先解釋一下鎖是因為什么產生的?在多核處理下,共享資源(臨界區)在同一時刻容易被多個線程或者進程同時訪問,為了解決臨界區的互斥訪問,即在某一時刻只能被一個線程或者進程訪問,鎖的概念應運而生。

自旋鎖和互斥鎖,都是為了解決多線程下臨界區互斥訪問的問題。保證一個時刻只有一個線程能訪問臨界區。臨界區指的是,一段能夠公共訪問的代碼。

互斥鎖是一種sleep-waiting鎖,對于臨界區的訪問,是先加鎖,如果臨界區已經被其他線程加鎖,則該線程進入休眠狀態,直到互斥鎖被釋放后喚醒。在執行完臨界區代碼后,需要釋放互斥量進行解鎖。
特點:互斥鎖的線程調度開銷較大,引起線程上下文切換,信號量發送,CPU搶占,一般用于不經常切換線程的執行耗時操作的任務。

自旋鎖是一種busy-waiting鎖,對于臨界區的訪問,線程不會進入休眠裝填,而是進入循環,不停嘗試獲取鎖,會一直處于忙等狀態,知道其他線程釋放了鎖。
特點:避免了線程切換的開銷,一般用于執行時間比較短的任務,或者需要頻繁訪問臨界區的任務,效率很高。(例如引用計數的操作)

2、iOS中線程間如何進行通信?

線程間通信只有三種方式:
(1)performSelector 選擇器方式
(2)NSMachPort/CFMachPort(基于port)方式
(3)GCD方式

performSelector方式

@interface NSObject (NSThreadPerformAdditions)

- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait modes:(nullable NSArray<NSString *> *)array;
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait;
    // equivalent to the first method with kCFRunLoopCommonModes

- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait modes:(nullable NSArray<NSString *> *)array API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
    // equivalent to the first method with kCFRunLoopCommonModes
- (void)performSelectorInBackground:(SEL)aSelector withObject:(nullable id)arg API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));

@end

NSMachPort/CFMachPort方式
看一下這篇文章基本就可以明白了

http://www.lxweimin.com/p/26acb4819fd2

GCD方式

dispatch_async(dispatch_get_main_queue(), ^{
       //主線程執行代碼
        
    });

3、項目中使用過多線程技術么?iOS中有哪些可以實現多線程?

實現多線程的常用方式有3中:
(1)NSThread
(2)GCD
(3)NSOpreation

還有一種是基于POSIX的封裝,pthread,C語言開發,很少使用。
在介紹 Cocoa 并發編程之前,我們先理清會提到的幾個術語:

線程:就是我們通常提到的線程,在進程中可以用線程去執行一些主進程之外的代碼。OS X 中線程的實現基于 POSIX 的 pthread API。
進程:也是我們通常意義上提到的進程,一個正在執行中的程序實體,可以產生多個線程
任務:一個抽象的概念,用于表示一系列需要完成的工作
Cocoa 中封裝了 NSThread, NSOperation, GCD 三種多線程編程方式,他們各有所長。

  • NSThread
    NSThread 是一個控制線程執行的對象,通過它我們可以方便的得到一個線程并控制它。NSThread 的線程之間的并發控制,是需要我們自己來控制的,可以通過 NSCondition 實現。它的缺點是需要自己維護線程的生命周期和線程的同步和互斥等,優點是輕量,靈活。

  • NSOperation
    NSOperation 是一個抽象類,它封裝了線程的細節實現,不需要自己管理線程的生命周期和線程的同步和互斥等。只是需要關注自己的業務邏輯處理,需要和 NSOperationQueue 一起使用。使用 NSOperation 時,你可以很方便的設置線程之間的依賴關系。這在略微復雜的業務需求中尤為重要。

  • GCD
    GCD(Grand Central Dispatch) 是 Apple 開發的一個多核編程的解決方法。在 iOS4.0 開始之后才能使用。GCD 是一個可以替代 NSThread 的很高效和強大的技術。當實現簡單的需求時,GCD 是一個不錯的選擇。

4、GCD和NSOpreation有什么區別?什么時候用GCD?什么時候用NSOpreation?

NSOperation是對GCD的面向對象的分裝,底層實現是一樣。
GCD的使用更為輕量,簡單,不需要復雜代碼就能實現線程創建和調度,試用簡單的場景,通常將耗時任務放入到子線程中執行,任務間不具備順序關系和依賴關系,而且一旦任務執行,不能終止,只能等待任務結束。
NSOperation通常配合NSOpreationQueue一起使用,通過面向對象的方式操作線程,不同于GCD的FIFO隊列,NSOpreationQueue不支持FIFO,而是通過設置線程之間的優先級和依賴關系來執行對應任務,并且能夠設置最大并發數。還可以通過cancel取消還沒有執行的線程。還可以通過KVO來監聽NSOPreation的狀態,來控制執行的任務。
更適合較為復雜的業務邏輯,根據業務之間的關系,實現線程間的依賴。

5、多線程安全問題的幾種解決方案?

多線程可能會在同一時間訪問共享資源(臨界區),導致數據錯誤或者數據不安全,為了避免這種資源爭奪而導致的安全問題,主要使用鎖來解決。同一時間只允許一個線程訪問臨界區。
(1)@synchronized關鍵字
(2)NSLock(NSRecusiveLock,NSConditinLock)有機會詳細理解一下。
(3)GCD信號量(有機會詳細理解一下)

二、iOS網絡編程

1、如何使用NSURLSession發送網絡請求?

網絡相關的看這篇文章就夠了,講的很明白。

https://objccn.io/issue-5-4/

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • NSThread 第一種:通過NSThread的對象方法 NSThread *thread = [[NSThrea...
    攻城獅GG閱讀 830評論 0 3
  • 多線程基本概念 單核CPU,同一時間cpu只能處理1個線程,只有1個線程在執行 。多線程同時執行:是CPU快速的在...
    WeiHing閱讀 720評論 1 5
  • 在這篇文章中,我將為你整理一下 iOS 開發中幾種多線程方案,以及其使用方法和注意事項。當然也會給出幾種多線程的案...
    張戰威ican閱讀 612評論 0 0
  • Swift1> Swift和OC的區別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,132評論 1 32
  • 多線程 你們項目中為什么多線程用GCD而不用NSOperation呢? 你有沒有發現國外的大牛他們多線程都是用NS...
    b485c88ab697閱讀 17,542評論 11 83