Swift 面試題及其答案

大風(fēng)車(chē)考試網(wǎng)

雖然Swift出生才一年,但是它已經(jīng)成為最流行的編程語(yǔ)言之一了。它的語(yǔ)法很簡(jiǎn)單,以至于當(dāng)它發(fā)布的時(shí)候,java script開(kāi)發(fā)者感覺(jué)就像下圖一樣。

事實(shí)上,Swift是一種復(fù)雜的語(yǔ)言。它包含面向?qū)ο蠛秃瘮?shù)方法這兩個(gè)方面,并且隨著新版本的發(fā)布在一直進(jìn)化。

你可以用這些問(wèn)題來(lái)測(cè)試應(yīng)聘者關(guān)于Swift方面的知識(shí)水平,或者測(cè)試一下你自己。如果你不知道答案,沒(méi)關(guān)系,沒(méi)一個(gè)問(wèn)題下面都有答案供你學(xué)習(xí)。

這些問(wèn)題包含兩個(gè)方面:

筆試問(wèn)題:通過(guò)電子郵件做一個(gè)編程測(cè)試是極好的,因?yàn)檫@涉及到寫(xiě)大量的代碼,從代碼質(zhì)量上可以看出一個(gè)人的水平。

面試問(wèn)題:電話面試或者面對(duì)面面試也是很好的,因?yàn)閷?duì)面試者來(lái)說(shuō)口頭交流會(huì)更方面。

每個(gè)方面有分成三個(gè)等級(jí):

初級(jí):適合讀了一到兩本有關(guān)Swift的書(shū),并且已經(jīng)開(kāi)始用Swift開(kāi)發(fā)應(yīng)用程序的初學(xué)者。

中級(jí):適合那些對(duì)Swift語(yǔ)言的概念有深刻理解和強(qiáng)烈興趣的,并且一直在閱讀大量有關(guān)Swift的博客文章并進(jìn)行實(shí)踐的中級(jí)工程師。

高級(jí):適合那些以探索Swift語(yǔ)言知識(shí)為樂(lè)趣,挑戰(zhàn)自己,使用前言技術(shù)的人們。

假如你想回答這些問(wèn)題,我建議你在回答這些問(wèn)題之前,打開(kāi)Playground運(yùn)行一下這些問(wèn)題的代碼。這些問(wèn)題的答案都在Xcode7.0Beta6版本中測(cè)試過(guò)。

準(zhǔn)備好了嗎?系好安全帶,現(xiàn)在就開(kāi)始!

筆試問(wèn)題

初學(xué)者

問(wèn)題1、(Swift1.0及其之后的版本的問(wèn)題)有什么更好的方法來(lái)寫(xiě)下面的for循環(huán)?

forvari=0;i<5;i++{

print("Hello!")

}

答案:

for_in0...4{

print("Hello!")

}

Swift實(shí)現(xiàn)了兩個(gè)數(shù)組運(yùn)算符closedoperator和half-operator.前者包含數(shù)組中得所有值。例如:下面的例子包含從0到4得所有整數(shù)

0...4

half-operator不包含數(shù)組中的最后一個(gè)元素,下面的例子會(huì)得到的結(jié)果和上面的一樣:

0..<5

問(wèn)題2?Swift1.0orlater

思考下面的問(wèn)題:

structTutorial{

vardifficulty:Int=1

}

vartutorial1=Tutorial()

vartutorial2=tutorial1

tutorial2.difficulty=2

tutorial1.difficulty和tutorial2.difficulty的值分別是多少?假如Tutorial是一個(gè)類(lèi),會(huì)有什么不同?并說(shuō)明原因。

答案:tutorial1.difficulty的值是1,然而tutorial2.difficulty的值是2.

在Swift中結(jié)構(gòu)體是值類(lèi)型,他們的值是復(fù)制的而不是引用的。下面的一行代碼意思是復(fù)制了tutorial1的值并把它賦值給tutorial2:

vartutorial2=tutorial1

從這一行開(kāi)始,tutorial2值得改變并不影響tutorial1的值。

假如Tutorial是一個(gè)類(lèi),tutorial1.difficulty和tutorial2.difficulty的值將都會(huì)是2.在Swift中類(lèi)對(duì)象都是引用類(lèi)型。tutorial1屬性的任何改變將會(huì)反應(yīng)到tutorial2上,反之亦然。

問(wèn)題3?Swift1.0orlater

view1聲明成var類(lèi)型,view2聲明let類(lèi)型。這里有什么區(qū)別嗎?下面的最后一行代碼能編譯嗎?

importUIKit

varview1=UIView()

view1.alpha=0.5

letview2=UIView()

view2.alpha=0.5//Willthislinecompile?

答案:view1是個(gè)變量可以重新賦值給一個(gè)新的實(shí)例化的UIView對(duì)象。使用let你只賦值一次,所以下面的代碼是不能編譯的:

view2=view1//Error:view2isimmutable

但是UIView是一個(gè)引用類(lèi)型的類(lèi),所以你可以改變view2的屬性,也就是說(shuō)最后一行代碼是可以編譯的:

letview2=UIView()

view2.alpha=0.5//Yes!

問(wèn)題4?Swift1.0orlater

下面的代碼是把數(shù)組里面的名字按字母的順序排序,看上去比較復(fù)雜。盡最大的可能簡(jiǎn)化閉包里的代碼。

letanimals=["fish","cat","chicken","dog"]

letsortedAnimals=animals.sort{(one:String,two:String)->Boolin

returnone<two

}

答案:

第一個(gè)簡(jiǎn)化的是參數(shù)。系統(tǒng)的參數(shù)類(lèi)型推斷功能,可以計(jì)算出閉包里面參數(shù)的類(lèi)型,所以你不必定義參數(shù)的類(lèi)型:

letsortedAnimals=animals.sort{(one,two)->Boolinreturnone<two}

函數(shù)返回值也可以被推斷出來(lái),所以簡(jiǎn)化掉,代碼變?yōu)椋?/p>

letsortedAnimals=animals.sort{(one,two)inreturnone<two}

這個(gè)$i符號(hào)可以代替參數(shù)名字,代碼進(jìn)一步簡(jiǎn)化為:

letsortedAnimals=animals.sort{return$0<$1}

在一個(gè)獨(dú)立的閉包內(nèi),return這個(gè)關(guān)鍵字是可以省略的。最后聲明的返回值就是閉包的返回值:

letsortedAnimals=animals.sort{$0<$1}

這簡(jiǎn)化很多了,但是我們不能止步于此!

對(duì)于字符串,有一個(gè)定義如下的比較函數(shù):

funcBool

這個(gè)簡(jiǎn)單的小函數(shù)可以使你的代碼簡(jiǎn)潔如下:

letsortedAnimals=animals.sort(<)

注意每一步的編譯結(jié)果都相同,但是最后一步你的閉包里只有一個(gè)字符。

問(wèn)題5?Swift1.0orlater

下面的代碼創(chuàng)建了兩個(gè)類(lèi)Address和Person,并且創(chuàng)建了兩個(gè)實(shí)例對(duì)象分別代表Ray和Brain.

classAddress{

varfullAddress:String

varcity:String

init(fullAddress:String,city:String){

self.fullAddress=fullAddress

self.city=city

}

}

classPerson{

varname:String

varaddress:Address

init(name:String,address:Address){

self.name=name

self.address=address

}

}

varheadquarters=Address(fullAddress:"123TutorialStreet",city:"Appletown")

varray=Person(name:"Ray",address:headquarters)

varbrian=Person(name:"Brian",address:headquarters)

假設(shè)Brain搬家到街對(duì)面的建筑物里,那么你會(huì)這樣更新他的地址:

brian.address.fullAddress="148TutorialStreet"

這樣做將會(huì)發(fā)生什么?錯(cuò)誤出在什么地方呢?

答案:Ray同樣會(huì)搬家到新的建筑物里面。Address是一個(gè)引用類(lèi)型類(lèi),所以無(wú)論你是通過(guò)ray或者brain訪問(wèn)headquarters,訪問(wèn)都是同一個(gè)實(shí)例化對(duì)象。headquarters對(duì)象的變化也會(huì)引起ray和brain的變化。你能想象如果Brain收到Ray的郵件或者相反Ray收到Brain的郵件,將會(huì)發(fā)生什么?解決方案是創(chuàng)建一個(gè)新的Address對(duì)象賦值給Brain或者把Address聲明成為結(jié)構(gòu)體而不是一個(gè)類(lèi)。

中級(jí)

問(wèn)題1?Swift2.0orlater

思考下面的代碼:

varoptional1:String?=nil

varoptional2:String?=.None

答案:兩者沒(méi)有什么不同。Optional.None(簡(jiǎn)稱(chēng).None)是optional變量值初始化的標(biāo)準(zhǔn)方法,而nil只是.None語(yǔ)法的一種修飾。事實(shí)上下面語(yǔ)句輸出是正確的:

nil==.None//OnSwift1.xthisdoesn'tcompile.YouneedOptional

.None

記住枚舉類(lèi)型的Optional下的None:

enumOptional{

caseNone

caseSome(T)

}

問(wèn)題2-Swift1.0orlater

下面是thermometer作為類(lèi)和結(jié)構(gòu)體的例子:

publicclassThermometerClass{

private(set)vartemperature:Double=0.0

publicfuncregisterTemperature(temperature:Double){

self.temperature=temperature

}

}

letthermometerClass=ThermometerClass()

thermometerClass.registerTemperature(56.0)

publicstructThermometerStruct{

private(set)vartemperature:Double=0.0

publicmutatingfuncregisterTemperature(temperature:Double){

self.temperature=temperature

}

}

letthermometerStruct=ThermometerStruct()

thermometerStruct.registerTemperature(56.0)

但是這段代碼編譯失敗了,請(qǐng)問(wèn)哪里報(bào)錯(cuò),出錯(cuò)的原因是什么。

建議:在使用Playground之前,認(rèn)真閱讀代碼并思考。

答案:代碼的最后一行不會(huì)被編譯通過(guò)。ThermometerStruct結(jié)構(gòu)體中正確的聲明了一個(gè)mutating屬性函數(shù),它是用來(lái)改變結(jié)構(gòu)體內(nèi)部temperature屬性的值的,但是編譯器不通過(guò)的原因是,通過(guò)let創(chuàng)建的不可變的registerTemperature結(jié)構(gòu)體調(diào)用了registerTemperature函數(shù)。

問(wèn)題3?Swift1.0orlater

下面的代碼輸出是什么?并說(shuō)明理由。

varthing="cars"

letclosure={[thing]in

print("Ilove\(thing)")

}

thing="airplanes"

closure()

答案:輸出的是:Ilovecars。當(dāng)閉包被聲明的時(shí)候,抓捕列表就復(fù)制一份thing變量,所以被捕捉的值并沒(méi)有改變,即使你給thing賦了一個(gè)新值。

如果你要忽視閉包中捕捉列表的值,那么編譯器引用那個(gè)值而不是復(fù)制。這種情況下,被引用變量的值的變化將會(huì)反映到閉包中,正如下面的代碼所示:

varthing="cars"

letclosure={

print("Ilove\(thing)")

}

thing="airplanes"

closure()//Prints"Iloveairplanes"

問(wèn)題4?Swift2.0orlater

下面是一個(gè)全局函數(shù),這個(gè)函數(shù)的功能是計(jì)算數(shù)組中特殊值得個(gè)數(shù)。(待校驗(yàn))

funccountUniques(array:Array)->Int{

letsorted=array.sort(<)

letinitial:(T?,Int)=(.None,0)

letreduced=sorted.reduce(initial){($1,$0.0==$1?$0.1:$0.1+1)}

returnreduced.1

}

它使用了<和==運(yùn)算符,他們限制著T(占位類(lèi)型)的實(shí)際類(lèi)型,也就是說(shuō)T必須遵循Comparable協(xié)議。你可以這樣使用它:

countUniques([1,2,3,3])//resultis3

現(xiàn)在要求你重寫(xiě)上面的方法作為Array的擴(kuò)展方法,然后你就可以這樣寫(xiě)代碼:

[1,2,3,3].countUniques()//shouldprint3

如何實(shí)現(xiàn)?

答案:在Swift2.0中,泛類(lèi)型可以使用類(lèi)型約束條件被強(qiáng)制擴(kuò)展。但是假如這個(gè)泛類(lèi)型不滿(mǎn)足這個(gè)類(lèi)型的約束條件,那么這個(gè)擴(kuò)展方法既不可見(jiàn)也無(wú)法調(diào)用。

所以countUniques全局函數(shù)可以作為Array的擴(kuò)展方法被重寫(xiě)如下:

extensionArraywhereElement:Comparable{

funccountUniques()->Int{

letsorted=sort(<)

letinitial:(Element?,Int)=(.None,0)

letreduced=sorted.reduce(initial){($1,$0.0==$1?$0.1:$0.1+1)}

returnreduced.1

}

}

注意:只有元類(lèi)型實(shí)現(xiàn)了Comparable協(xié)議新的方法才可以被使用。例如,如果你在全部是UIView對(duì)象的數(shù)組中調(diào)用countUniques,編譯器將會(huì)報(bào)錯(cuò)。

importUIKit

leta=[UIView(),UIView()]

a.countUniques()//compilererrorherebecauseUIViewdoesn'timplementComparable

問(wèn)題5-Swift2.0orlater

下面一個(gè)函數(shù)的功能是計(jì)算兩個(gè)double(optional)類(lèi)型的數(shù)的相除的結(jié)果。在執(zhí)行除法之前,必須提前滿(mǎn)足三個(gè)條件:

被除數(shù)必須包含nil值

除數(shù)必須為包含nil值

除數(shù)不能為零

funcpide(pidend:Double?,bypisor:Double?)->Double?{

ifpidend==.None{

return.None

}

ifpisor==.None{

return.None

}

ifpisor==0{

return.None

}

returnpidend!/pisor!

}

上面的函數(shù)可以正常使用,但是會(huì)存在兩個(gè)問(wèn)題:


  • 相關(guān)文章
  • 揭秘鮮為人知的高盛面試題揭秘鮮為人知的高盛面試題

    與高盛facetoface?在經(jīng)歷了四年大學(xué)學(xué)習(xí)、CFA的全級(jí)考試、復(fù)雜的網(wǎng)申之后,恭喜你到達(dá)了面試的環(huán)節(jié)。對(duì)于全球前三的投資銀行,高盛來(lái)說(shuō)。如何才能應(yīng)對(duì)自如的做好面試..

  • HTML前端開(kāi)發(fā)面試題及前端知識(shí)HTML前端開(kāi)發(fā)面試題及前端知識(shí)

    本文收集并總結(jié)了一些優(yōu)質(zhì)的前端面試題,初學(xué)者看后也要用心鉆研其中的原理,重要知識(shí)需要系統(tǒng)學(xué)習(xí),透徹學(xué)習(xí),形成自己的知識(shí)鏈。萬(wàn)不可投機(jī)取巧,只求面試過(guò)關(guān)是錯(cuò)..

  • 大數(shù)據(jù)技術(shù)Hadoop面試題大數(shù)據(jù)技術(shù)Hadoop面試題

    17.ClouderaCDH是需要付費(fèi)使用的。()18.Hadoop是Java開(kāi)發(fā)的,所以MapReduce只支持Java語(yǔ)言編寫(xiě)。()19.Hadoop支持?jǐn)?shù)據(jù)的隨機(jī)讀寫(xiě)。()20.NameNode負(fù)責(zé)管理metadata,cli..

  • 揭秘鮮為人知的高盛面試題揭秘鮮為人知的高盛面試題

    與高盛facetoface?在經(jīng)歷了四年大學(xué)學(xué)習(xí)、CFA的全級(jí)考試、復(fù)雜的網(wǎng)申之后,恭喜你到達(dá)了面試的環(huán)節(jié)。對(duì)于全球前三的投資銀行,高盛來(lái)說(shuō)。如何才能應(yīng)對(duì)自如的做好面試..

  • HTML前端開(kāi)發(fā)面試題及前端知識(shí)HTML前端開(kāi)發(fā)面試題及前端知識(shí)

    本文收集并總結(jié)了一些優(yōu)質(zhì)的前端面試題,初學(xué)者看后也要用心鉆研其中的原理,重要知識(shí)需要系統(tǒng)學(xué)習(xí),透徹學(xué)習(xí),形成自己的知識(shí)鏈。萬(wàn)不可投機(jī)取巧,只求面試過(guò)關(guān)是錯(cuò)..

  • 大數(shù)據(jù)技術(shù)Hadoop面試題大數(shù)據(jù)技術(shù)Hadoop面試題

    17.ClouderaCDH是需要付費(fèi)使用的。()18.Hadoop是Java開(kāi)發(fā)的,所以MapReduce只支持Java語(yǔ)言編寫(xiě)。()19.Hadoop支持?jǐn)?shù)據(jù)的隨機(jī)讀寫(xiě)。()20.NameNode負(fù)責(zé)管理metadata,cli..

  • 軍校面試體檢如何輕松過(guò)關(guān) 軍檢面試內(nèi)容及技巧軍校面試體檢如何輕松過(guò)關(guān) 軍檢面試內(nèi)容及技巧

    軍校面試主要是對(duì)報(bào)考軍校人員的政治思想的考核,所以提問(wèn)的內(nèi)容大都與政治方向有關(guān),當(dāng)然了因?yàn)槊鎸?duì)的是高中學(xué)生,一般不會(huì)提過(guò)難的問(wèn)題。以下是小編整理的相關(guān)內(nèi)容..

  • 大學(xué)社團(tuán)宣傳部經(jīng)典的面試問(wèn)題大學(xué)社團(tuán)宣傳部經(jīng)典的面試問(wèn)題

    1.你對(duì)學(xué)生會(huì)是怎么看的?對(duì)于學(xué)生會(huì)你有什么想法?“學(xué)生會(huì)是一個(gè)集體,我們學(xué)生會(huì)每一個(gè)成員都要時(shí)刻維護(hù)學(xué)生會(huì)的優(yōu)良形象,做好模范帶好頭。要時(shí)時(shí)以身作則,處處..

  • 大學(xué)學(xué)生會(huì)宣傳部的面試問(wèn)題模板大學(xué)學(xué)生會(huì)宣傳部的面試問(wèn)題模板

    學(xué)生會(huì)宣傳部社團(tuán)面試問(wèn)題回答11,你認(rèn)為宣傳部應(yīng)該是怎樣的一個(gè)部門(mén)?2,怎樣發(fā)揮宣傳部的作用?比如舉辦什么活動(dòng)。

  • 學(xué)生會(huì)宣傳部面試的簡(jiǎn)短問(wèn)題學(xué)生會(huì)宣傳部面試的簡(jiǎn)短問(wèn)題

    學(xué)生會(huì)宣傳部社團(tuán)面試問(wèn)題回答11,你認(rèn)為宣傳部應(yīng)該是怎樣的一個(gè)部門(mén)?2,怎樣發(fā)揮宣傳部的作用?比如舉辦什么活動(dòng)。