iOS面試題合集(多線程篇)

目錄:

1.進(jìn)程與線程分別是什么意思?

2.什么是多線程?

3.多線程的優(yōu)點(diǎn)和缺點(diǎn)有哪些?

4.多線程的 并行 和 并發(fā) 有什么區(qū)別?

5.iOS中實(shí)現(xiàn)多線程的幾種方案,各自有什么特點(diǎn)?

6.多個(gè)網(wǎng)絡(luò)請求完成后如何執(zhí)行下一步?

7. 多個(gè)網(wǎng)絡(luò)請求順序執(zhí)行后如何執(zhí)行下一步?

8.如何理解多線程中的死鎖?

9.如何去理解GCD執(zhí)行原理?

1.進(jìn)程與線程分別是什么意思?

進(jìn)程:

1.進(jìn)程是一個(gè)具有一定獨(dú)立功能的程序關(guān)于某次數(shù)據(jù)集合的一次運(yùn)行活動(dòng),它是操作系統(tǒng)分配資源的基本單元.

2.進(jìn)程是指在系統(tǒng)中正在運(yùn)行的一個(gè)應(yīng)用程序,就是一段程序的執(zhí)行過程,我們可以理解為手機(jī)上的一個(gè)app.

3.每個(gè)進(jìn)程之間是獨(dú)立的,每個(gè)進(jìn)程均運(yùn)行在其專用且受保護(hù)的內(nèi)存空間內(nèi),擁有獨(dú)立運(yùn)行所需的全部資源

線程

1.程序執(zhí)行流的最小單元,線程是進(jìn)程中的一個(gè)實(shí)體.

2.一個(gè)進(jìn)程要想執(zhí)行任務(wù),必須至少有一條線程.應(yīng)用程序啟動(dòng)的時(shí)候,系統(tǒng)會(huì)默認(rèn)開啟一條線程,也就是主線程

進(jìn)程和線程的關(guān)系

1.線程是進(jìn)程的執(zhí)行單元,進(jìn)程的所有任務(wù)都在線程中執(zhí)行

2.線程是 CPU 分配資源和調(diào)度的最小單位

3.一個(gè)程序可以對應(yīng)多個(gè)進(jìn)程(多進(jìn)程),一個(gè)進(jìn)程中可有多個(gè)線程,但至少要有一條線程

4.同一個(gè)進(jìn)程內(nèi)的線程共享進(jìn)程資源

2.什么是多線程?

多線程的實(shí)現(xiàn)原理:事實(shí)上,同一時(shí)間內(nèi)單核的CPU只能執(zhí)行一個(gè)線程,多線程是CPU快速的在多個(gè)線程之間進(jìn)行切換(調(diào)度),造成了多個(gè)線程同時(shí)執(zhí)行的假象。

如果是多核CPU就真的可以同時(shí)處理多個(gè)線程了。

多線程的目的是為了同步完成多項(xiàng)任務(wù),通過提高系統(tǒng)的資源利用率來提高系統(tǒng)的效率。

3.多線程的優(yōu)點(diǎn)和缺點(diǎn)有哪些?

優(yōu)點(diǎn):

能適當(dāng)提高程序的執(zhí)行效率

能適當(dāng)提高資源利用率(CPU、內(nèi)存利用率)

缺點(diǎn):

開啟線程需要占用一定的內(nèi)存空間(默認(rèn)情況下,主線程占用1M,子線程占用512KB),如果開啟大量的線程,會(huì)占用大量的內(nèi)存空間,降低程序的性能

線程越多,CPU在調(diào)度線程上的開銷就越大

程序設(shè)計(jì)更加復(fù)雜:比如線程之間的通信、多線程的數(shù)據(jù)共享

4.多線程的 并行 和 并發(fā) 有什么區(qū)別?

并行:充分利用計(jì)算機(jī)的多核,在多個(gè)線程上同步進(jìn)行

并發(fā):在一條線程上通過快速切換,讓人感覺在同步進(jìn)行

5.iOS中實(shí)現(xiàn)多線程的幾種方案,各自有什么特點(diǎn)?

NSThread 面向?qū)ο蟮模枰绦騿T手動(dòng)創(chuàng)建線程,但不需要手動(dòng)銷毀。子線程間通信很難。

GCD c語言,充分利用了設(shè)備的多核,自動(dòng)管理線程生命周期。比NSOperation效率更高。

NSOperation 基于gcd封裝,更加面向?qū)ο螅萭cd多了一些功能。

6.多個(gè)網(wǎng)絡(luò)請求完成后如何執(zhí)行下一步?

使用GCD的dispatch_group_t

創(chuàng)建一個(gè)dispatch_group_t

每次網(wǎng)絡(luò)請求前先dispatch_group_enter,請求回調(diào)后再dispatch_group_leave,enter和leave必須配合使用,有幾次enter就要有幾次leave,否則group會(huì)一直存在。

當(dāng)所有enter的block都leave后,會(huì)執(zhí)行dispatch_group_notify的block。

NSString*str=@"http://xxxx.com/";

NSURL*url=[NSURL URLWithString:str];

NSURLRequest*request=[NSURLRequest requestWithURL:url];

NSURLSession*session=[NSURLSession sharedSession];

dispatch_group_t downloadGroup=dispatch_group_create();

for(inti=0;i<10;i++){

dispatch_group_enter(downloadGroup);

NSURLSessionDataTask*task=[session dataTaskWithRequest:request completionHandler:^(NSData*_Nullable data,NSURLResponse*_Nullable response,NSError*_Nullable error){

NSLog(@"%d---%d",i,i);

dispatch_group_leave(downloadGroup);

}];

[task resume];

}

dispatch_group_notify(downloadGroup,dispatch_get_main_queue(),^{

NSLog(@"end");

});

使用GCD的信號(hào)量dispatch_semaphore_t

dispatch_semaphore信號(hào)量為基于計(jì)數(shù)器的一種多線程同步機(jī)制。如果semaphore計(jì)數(shù)大于等于1,計(jì)數(shù)-1,返回,程序繼續(xù)運(yùn)行。如果計(jì)數(shù)為0,則等待。dispatch_semaphore_signal(semaphore)為計(jì)數(shù)+1操作,dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER)為設(shè)置等待時(shí)間,這里設(shè)置的等待時(shí)間是一直等待。

創(chuàng)建semaphore為0,等待,等10個(gè)網(wǎng)絡(luò)請求都完成了,dispatch_semaphore_signal(semaphore)為計(jì)數(shù)+1,然后計(jì)數(shù)-1返回

NSString*str=@"http://xxxx.com/";

NSURL*url=[NSURL URLWithString:str];

NSURLRequest*request=[NSURLRequest requestWithURL:url];

NSURLSession*session=[NSURLSession sharedSession];

dispatch_semaphore_t sem=dispatch_semaphore_create(0);

for(inti=0;i<10;i++){

NSURLSessionDataTask*task=[session dataTaskWithRequest:request completionHandler:^(NSData*_Nullable data,NSURLResponse*_Nullable response,NSError*_Nullable error){

NSLog(@"%d---%d",i,i);

count++;

if(count==10){

dispatch_semaphore_signal(sem);

count=0;

}

}];

[task resume];

}

dispatch_semaphore_wait(sem,DISPATCH_TIME_FOREVER);

dispatch_async(dispatch_get_main_queue(),^{

NSLog(@"end");

});

7.多個(gè)網(wǎng)絡(luò)請求順序執(zhí)行后如何執(zhí)行下一步?

使用信號(hào)量semaphore

每一次遍歷,都讓其dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER),這個(gè)時(shí)候線程會(huì)等待,阻塞當(dāng)前線程,直到dispatch_semaphore_signal(sem)調(diào)用之后

NSString*str=@"http://www.lxweimin.com/p/6930f335adba";

NSURL*url=[NSURL URLWithString:str];

NSURLRequest*request=[NSURLRequest requestWithURL:url];

NSURLSession*session=[NSURLSession sharedSession];

dispatch_semaphore_t sem=dispatch_semaphore_create(0);

for(inti=0;i<10;i++){

NSURLSessionDataTask*task=[session dataTaskWithRequest:request completionHandler:^(NSData*_Nullable data,NSURLResponse*_Nullable response,NSError*_Nullable error){

NSLog(@"%d---%d",i,i);

dispatch_semaphore_signal(sem);

}];

[task resume];

dispatch_semaphore_wait(sem,DISPATCH_TIME_FOREVER);

}

dispatch_async(dispatch_get_main_queue(),^{

NSLog(@"end");

});

8.如何理解多線程中的死鎖?

死鎖是由于多個(gè)線程(進(jìn)程)在執(zhí)行過程中,因?yàn)闋帄Z資源而造成的互相等待現(xiàn)象,你可以理解為卡主了。產(chǎn)生死鎖的必要條件有四個(gè):

互斥條件 :指進(jìn)程對所分配到的資源進(jìn)行排它性使用,即在一段時(shí)間內(nèi)某資源只由一個(gè)進(jìn)程占用。如果此時(shí)還有其它進(jìn)程請求資源,則請求者只能等待,直至占有資源的進(jìn)程用畢釋放。

請求和保持條件 :指進(jìn)程已經(jīng)保持至少一個(gè)資源,但又提出了新的資源請求,而該資源已被其它進(jìn)程占有,此時(shí)請求進(jìn)程阻塞,但又對自己已獲得的其它資源保持不放。

不可剝奪條件 :指進(jìn)程已獲得的資源,在未使用完之前,不能被剝奪,只能在使用完時(shí)由自己釋放。

環(huán)路等待條件 :指在發(fā)生死鎖時(shí),必然存在一個(gè)進(jìn)程——資源的環(huán)形鏈,即進(jìn)程集合{P0,P1,P2,···,Pn}中的P0正在等待一個(gè)P1占用的資源;P1正在等待P2占用的資源,……,Pn正在等待已被P0占用的資源。

最常見的就是 同步函數(shù) + 主隊(duì)列 的組合,本質(zhì)是隊(duì)列阻塞。

dispatch_sync(dispatch_get_main_queue(),^{

NSLog(@"2");

});

NSLog(@"1");

// 什么也不會(huì)打印,直接報(bào)錯(cuò)

9.如何去理解GCD執(zhí)行原理?

GCD有一個(gè)底層線程池,這個(gè)池中存放的是一個(gè)個(gè)的線程。之所以稱為“池”,很容易理解出這個(gè)“池”中的線程是可以重用的,當(dāng)一段時(shí)間后這個(gè)線程沒有被調(diào)用胡話,這個(gè)線程就會(huì)被銷毀。注意:開多少條線程是由底層線程池決定的(線程建議控制再3~5條),池是系統(tǒng)自動(dòng)來維護(hù),不需要我們程序員來維護(hù)(看到這句話是不是很開心?) 而我們程序員需要關(guān)心的是什么呢?我們只關(guān)心的是向隊(duì)列中添加任務(wù),隊(duì)列調(diào)度即可。

如果隊(duì)列中存放的是同步任務(wù),則任務(wù)出隊(duì)后,底層線程池中會(huì)提供一條線程供這個(gè)任務(wù)執(zhí)行,任務(wù)執(zhí)行完畢后這條線程再回到線程池。這樣隊(duì)列中的任務(wù)反復(fù)調(diào)度,因?yàn)槭峭降模援?dāng)我們用currentThread打印的時(shí)候,就是同一條線程。

如果隊(duì)列中存放的是異步的任務(wù),(注意異步可以開線程),當(dāng)任務(wù)出隊(duì)后,底層線程池會(huì)提供一個(gè)線程供任務(wù)執(zhí)行,因?yàn)槭钱惒綀?zhí)行,隊(duì)列中的任務(wù)不需等待當(dāng)前任務(wù)執(zhí)行完畢就可以調(diào)度下一個(gè)任務(wù),這時(shí)底層線程池中會(huì)再次提供一個(gè)線程供第二個(gè)任務(wù)執(zhí)行,執(zhí)行完畢后再回到底層線程池中。

這樣就對線程完成一個(gè)復(fù)用,而不需要每一個(gè)任務(wù)執(zhí)行都開啟新的線程,也就從而節(jié)約的系統(tǒng)的開銷,提高了效率。在iOS7.0的時(shí)候,使用GCD系統(tǒng)通常只能開58條線程,iOS8.0以后,系統(tǒng)可以開啟很多條線程,但是實(shí)在開發(fā)應(yīng)用中,建議開啟線程條數(shù):35條最為合理。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,460評論 6 538
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,067評論 3 423
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,467評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,468評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,184評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,582評論 1 325
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,616評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,794評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,343評論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,096評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,291評論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,863評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,513評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,941評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,190評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,026評論 3 396
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,253評論 2 375