耶,這些面試題有點(diǎn)歪,你會(huì)嗎?

這次給大家分享一些面試題,你知道答案嗎?

第一道面試題:

請(qǐng)看下面的代碼,請(qǐng)問(wèn)輸出的結(jié)果是什么?

第二道面試題:

請(qǐng)看下面的代碼,請(qǐng)問(wèn)輸出的結(jié)果是什么?

第三道面試題:

請(qǐng)看下面的代碼,請(qǐng)問(wèn)輸出的結(jié)果是什么?

第四道面試題:

請(qǐng)看下面的代碼,請(qǐng)問(wèn)著2塊代碼會(huì)發(fā)生什么事?

面試題答案

1.第一道:

相信我們心中都是已經(jīng)有答案了,現(xiàn)在我們一個(gè)一個(gè)來(lái)看看每一道面試題,其實(shí)考察的還是我們的基礎(chǔ)的問(wèn)題,涉及的都是某一個(gè)知識(shí)點(diǎn),首先第一道.這樣我們先看一下運(yùn)行結(jié)果:1和3

結(jié)果是1和3,而test2方法并沒(méi)有執(zhí)行,這時(shí)候我換一種寫法,如下:我們?cè)倏匆幌陆Y(jié)果.

afterDelay去掉以后立刻就會(huì)輸出1,2,3.首先我們要知道[self performSelector:@selector(test2) withObject:nil];這里的執(zhí)行本質(zhì)就是objc_msgSend(self,@selector(test2))就是這種,再說(shuō)白點(diǎn)就是[self test2];(這里可以查看objc源碼的實(shí)現(xiàn),直接查找performSelector的方法實(shí)現(xiàn)就能找到).

而[self performSelector:@selector(test2) withObject:nil afterDelay:.0];就有點(diǎn)不一樣的,大家可以把上面的異步線程的里面的代碼全部拿到主線程來(lái)操作,你會(huì)發(fā)現(xiàn)都是有輸出的.會(huì)輸出1,2,3(順序可能不一樣,但都會(huì)輸出).這時(shí)候你可以點(diǎn)擊進(jìn)去看里面的定義,你會(huì)發(fā)現(xiàn)它是屬于RunLoop里面的模塊,而且在objc里面你是找不到源碼的.這時(shí)候我們就可以參照上個(gè)博客說(shuō)的GNUstep的源碼(GNUstep上個(gè)博客有介紹),我們看源碼如下:

所以很明顯,它的底層是用了NSTimer定時(shí)器.比如時(shí)間我寫2.0就是2秒以后做事情.而我們知道定時(shí)器是要加在Runloop里面.這下就很清楚了,為什么主線程可以,因?yàn)槲覀冎乐骶€程的Runloop是默認(rèn)開(kāi)啟的,子線程是默認(rèn)沒(méi)有Runloop的,所以會(huì)出現(xiàn)這種情況.定時(shí)器沒(méi)法工作,它那段代碼是往runloop中添加了一個(gè)定時(shí)器任務(wù).如果想讓它工作,我們只要添加runloop即可.

2.第二道:

我們先看一下第二道面試題的輸出結(jié)果

輸出1以后,執(zhí)行performSelector任務(wù)的時(shí)候,直接崩潰了,因?yàn)槲覀冎?調(diào)用start,它就會(huì)執(zhí)行block任務(wù),執(zhí)行完以后,線程的任務(wù)就算完成了,線程自動(dòng)會(huì)退出,這時(shí)候你去讓一個(gè)已經(jīng)退出的線程安排任務(wù),肯定會(huì)出問(wèn)題.

3.第三道:

第三道也可以說(shuō)是第二道的升華,因?yàn)橛行┤丝赡軙?huì)想,既然thread會(huì)退出,那我就用一個(gè)強(qiáng)指針指著,不讓它退出,不就行了嗎?真的可以嗎?我們?cè)囋?

你會(huì)發(fā)現(xiàn)這樣寫還是一樣,還是會(huì)崩潰,這是為什么呢?

這是因?yàn)?強(qiáng)指針只是讓它不銷毀,讓這個(gè)線程對(duì)象還是在內(nèi)存中,但是它不能做事情了,它已經(jīng)沒(méi)有用了,而只有添加RunLoop才是保證線程處于激活的狀態(tài),保證它的生命周期不結(jié)束,還能繼續(xù)在這個(gè)線程中執(zhí)行線程任務(wù).所以必須使用RunLoop才能保住線程的生命周期.

而第三道面試題,我是加了runloop,所以就能正常執(zhí)行,而第三道面試題,第一塊是只執(zhí)行了1次performSelector,它是不會(huì)崩潰正常執(zhí)行的.這樣,我還是截圖代碼運(yùn)行結(jié)果吧,請(qǐng)看下面:

正常運(yùn)行
崩潰

為什么會(huì)有上面的結(jié)果呢?原因它還是關(guān)于Runloop的一個(gè)線程?;畹膯?wèn)題(也就是控制線程的生命周期),這里就不細(xì)說(shuō)了,之前的博客都有介紹,有興趣的可以看一下.你了解RunLoop線程?;顔?已封裝好,2句代碼直接使用里面詳細(xì)介紹run和runMode區(qū)別,知道這個(gè)就能很清楚解答這道面試題

4.第四道:

這個(gè)是涉及tagged pointer的知識(shí)點(diǎn),如果你了解,這道面試題就相對(duì)來(lái)說(shuō)簡(jiǎn)單些,這樣我們先看運(yùn)行結(jié)果:

有問(wèn)題的運(yùn)行崩潰
沒(méi)問(wèn)題的運(yùn)行

我們可以看到上面的2張圖,第一張直接崩潰了,第二張圖的運(yùn)行結(jié)果沒(méi)有什么問(wèn)題,要解答這個(gè)面試題,你要知道tagged pointer這個(gè)東西:(這里大致說(shuō)一下,因?yàn)槲液竺娴牟┛蜁?huì)詳細(xì)介紹這個(gè)tagged pointer)

tagged pointer:?從 64bit 開(kāi)始,蘋果引入了 tagged pointer 計(jì)數(shù),用于優(yōu)化 NSNumber , NSDate , NSString 等小對(duì)象的存儲(chǔ),沒(méi)有這個(gè)數(shù)據(jù)之前,NSNumber 等對(duì)象需要?jiǎng)討B(tài)分配內(nèi)存,維護(hù)引用計(jì)數(shù),NSNumber 指針存儲(chǔ)的是堆中NSNumber對(duì)象的地址值,而引入了這個(gè)計(jì)數(shù)之后,NSNumber 指針里面存儲(chǔ)的數(shù)據(jù)是 : tag + data ,也就是直接將數(shù)據(jù)存儲(chǔ)在指針中。這樣做特別節(jié)省空間。如果這個(gè)數(shù)據(jù)特別大,指針存儲(chǔ)不下這個(gè)數(shù),那么會(huì)恢復(fù)之前的方式,存儲(chǔ)在堆區(qū),然后指針存放堆區(qū)的地址。

我們知道存在堆區(qū)的話,給TestStr賦值內(nèi)部會(huì)類似下面的訪問(wèn):

-(void)setTestStr:(NSString *)TestStr{

? ? if (_TestStr != TestStr) {

? ? ? ? [_TestStr release];

? ? ? ? _TestStr = [TestStr copy];

? ? }

}

這樣的話就可能有多個(gè)線程同時(shí)去 ?[_TestStr release],如果_TestStr已經(jīng)釋放了,又去訪問(wèn)就會(huì)直接崩潰.為了避免這個(gè)問(wèn)題,我們可以使用線程同步技術(shù),我上個(gè)博客寫了好多種技術(shù),我們隨便用一個(gè)即可解決.

self.TestStr = [NSString stringWithFormat:@"abc"]這個(gè)就是使用了tagged pointer技術(shù),所以不會(huì)涉及到釋放,就不會(huì)出現(xiàn)崩潰的問(wèn)題.(tagged pointer后面的博客我會(huì)詳細(xì)介紹)

接下來(lái)我會(huì)繼續(xù)努力編寫其他博客,您的支持就是我最大的動(dòng)力!

如果覺(jué)得我寫得對(duì)您有所幫助,請(qǐng)點(diǎn)贊關(guān)注我,我會(huì)持續(xù)更新??

感謝支持??????!

我是GDCoder,我們下期見(jiàn)!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前言: 最近把 iOS 面試中可能會(huì)遇到的問(wèn)題整理了一番, 題目大部分是網(wǎng)上收錄的, 方便自己鞏固復(fù)習(xí), 也分享給...
    iOS猿_員閱讀 5,626評(píng)論 0 14
  • 屬性關(guān)鍵字的理解以及在MRC和ARC下的寫法的不同,對(duì)其要有深刻的理解和認(rèn)識(shí)。 assign和weak的區(qū)別? w...
    ROTK_lvzhenhua閱讀 888評(píng)論 0 1
  • 1.OC里用到集合類是什么? 基本類型為:NSArray,NSSet以及NSDictionary 可變類型為:NS...
    輕皺眉頭淺憂思閱讀 1,476評(píng)論 0 3
  • 目錄: 定時(shí)器 內(nèi)存區(qū)域、Tagged Pointer MRC Copy 引用計(jì)數(shù)、__weak原理 autore...
    Imkata閱讀 597評(píng)論 0 0
  • 如果你不知道你接下來(lái)需要補(bǔ)充學(xué)習(xí)哪一部分知識(shí),做點(diǎn)面試題吧。 基礎(chǔ)部分 1、線程和進(jìn)程有什么區(qū)別 那么,線程和進(jìn)程...
    就叫yang閱讀 4,727評(píng)論 8 56

友情鏈接更多精彩內(nèi)容