iOS快手面經(已拿offer)

背景

過完年來北京之後,有準備看看機會,也是想了解下市場行情。簡歷沒有投太多,只定向投了頭條教育部門、抖音、快手、阿里,這些公司。

頭條和阿里的簡歷都沒過,肯定是亮點太少吧。只有快手簡歷過了,快手是三輪技術面+一輪HR面,前兩輪技術都比較順利,到第三輪卻栽了,很痛心o(╥﹏╥)o。目前就不考慮換工作了,等下半年再說了,接下來的時間再好好精煉一下。

快手是視頻面試,不支持週末,但是可以選擇晚上時間,我這幾次都是定在了晚上九點。視頻面試是通過牛客網進行的,以下是我還記得下來的各輪面試題,對於一些iOS基礎知識就不做解答了。

一面

1、用遞歸寫一個算法,計算從1到100的和。

func sum(value: Int) -> Int {
    if value <= 0 {
        return 0
    }
    var number = value
    return value + sum(value: number - 1)
}
// 計算過程
let result = sum(value: 100)
print(result)

作爲一個開發者,有一個學習的氛圍跟一個交流圈子特別重要,這是一個我的iOS交流羣:413038000,不管你是大牛還是小白都歡迎入駐 ,分享BAT,阿里面試題、面試經驗,討論技術, 大家一起交流學習成長!

寫完算法之後又圍繞着問了幾個問題,都是算法基礎:

  • 算法的時間複雜度是多少
  • 遞歸會有什麼缺點
  • 不用遞歸能否實現,複雜度能否降到O(1)

2、property的作用是什麼,有哪些關鍵詞,分別是什麼含義?

3、父類的property是如何查找的?

4、NSArrayNSDictionary應該如何選關鍵詞?

5、copymuteCopy有什麼區別,深複製和淺複製是什麼意思,如何實現深複製?

6、用runtime做過什麼事情?runtime中的方法交換是如何實現的?

7、講一下對KVC合KVO的瞭解,KVC是否會調用setter方法?

8、__block有什麼作用

9、說一下對GCD的瞭解,它有那些方法,分別是做什麼用的?

10、對二叉樹是否瞭解?

面試官是想接着問這方面的問題的。我當時說了不瞭解,然後就沒有後續了。

二面

1、ARC和MRC的區別,iOS是如何管理引用計數的,什麼情況下引用計數加1什麼情況引用計數減一?

2、在MRC下執行[object autorelease]會發生什麼,autorelease是如何實現的?

3、CoreAnimation是如何繪製圖像的,動畫過程中的frame能否獲取到?

4、談一下對Runlop的瞭解?

5、OC如何實現多繼承?

這個當時沒有答好。其實藉助於消息轉發,protocol和類別都可以間接實現多繼承。

6、對設計模式有什麼瞭解,講一下其中一種是如何使用的。

7、有沒有哪個開源庫讓你用的很舒服,講一下讓你舒服的地方。
我這裏說了RxSwift中的觀察者模式,和響應式編程。然後面試官問,如果要用OC實現一套RxSwift那樣的邏輯應該怎麼做。我回答的是結合KVO,將一些需要觀察的屬性,通過KVO進行監聽,然後通過block回調出來。

8、一張100*100,RGBA的png圖像解壓之後佔多大內存空間。
RGBA > FFFFFFFF > 4字節
所以會佔用:(100 100 4) / 1024 = 39KB

9、算法題

題目:給定一個個數字arr,判斷數組arr中是否所有的數字都只出現過一次。

這個並沒有要求寫出來,說是提供思路就行了。我當時給的方案是在便利數組的時候,用一個字典把便利的元素存起來,如果在後面的便利過程中新元素在字典中存在過就說明,有重複數字出現。時間複雜度是O(n)。

當時也問了有沒有辦法進行優化,我當時想到了將數組轉成Set,然後和原數組比較,兩個集合的數量是否變化。

10、因爲我跟他介紹自己Swift用的多一些,然後問了些Swift跟OC的區別,各自的優缺點。

11、爲什麼離職,有什麼職業規劃。

三面

1、給定一個Int型數組,用裏面的元素組成一個最大數,因爲數字可能非常大,用字符串輸出。


輸入: [3,30,34,5,9]
輸出: 9534330

這個是leetcode的179題,難度中等。面試官讓先說思路,再去做題。事先說一下這個題我沒有做過。當時的思路是用冒泡法進行排序,排序的前提是將較少位數的數字進行循環補齊,例如3和30的比較,變成33和30的比較,34和4的比較變成34和44的比較,然後將結果從大到小整合成字符串輸出。

但是做題是卻發現沒那麼簡單,位數的補齊對於2位和3位數的比較還需要求位數的最小公倍數,將他們都轉成6位數才能比較。在掙扎了5分鐘做了就做罷了。

後來再去做這道題,其實這就是一個排序而已,只不過他的規則是按高位優先級更高的原則,而這一點跟字符串的比較保持一致,如果再加一些Swift的高階函數,就可以寫成:

func largestNumber(_ nums: [Int]) -> String {
    let sort = nums.map {"\($0)"}.sorted { (lStr, rStr) -> Bool in
        return lStr + rStr > rStr + lStr
    }
    let result = sort.joined()
    if result.prefix(1) == "0" {
        return "0"
    } else {
        return result
    }
}

2、項目中有這麼一個方法func findfile(dir: String suffix: String) -> [String] ,可以通過輸入文件夾目錄,和後綴檢索出所需的文件。

例如需要在某個文件中檢索txt文件或者mp4文件,那就傳入dir和suffix就行了。現在又有一些需求,例如需要檢索utf8格式的txt或者h264編碼的mp4,也會有一些例如查找最近一週更新過的文件這樣的需求,你如何優化這個類,讓它滿足這些情況?

我首先想到的是這麼多需求不可能一個方法就完成,需要根據不同場景拆出不同的方法,但是這些同屬於文件操作,會有一個共同使用的方法就是檢索文件。這個方法需要傳入文件目錄,然後遞歸的返回當前目錄所有文件路徑。外部不同場景的調用邏輯就用一個enum完成,不同值對應相同範圍的不同種類。

面試官比較關注內部共用的文件檢索怎麼寫,他說子文件如果過多怎麼辦,如何優化。我有點懵,查找文件至少是要遍歷一遍的,子文件過多,這個應該是沒法優化的啊。中間卡了一段時間,後來他給了提示說是不是可以用block實現,將文件路徑返回出去,由外部決定當前文件是否可用,最終外部的調用類是這個樣子。


max-width: 100%;">//我的方案
//func findDir(_ dir: String) -> [String]
//block方案
func findDir(_ dir: String, block: ((String) -> Bool))

我想來確實沒毛病,用block返回內容至少不會將該目錄的所有文件都由一個對象持有,而前面一堆的鋪墊其實也都是爲驗證block方案的好處。

其實事後想下這個問題沒啥難的,這種寫法自己也有寫過,但當時就是沒想起來,可能前面一圈的鋪墊給我帶偏了吧,說虧也不虧,以後多多努力吧。

總結

整體來看,快手的面試題跟我在別處看到的iOS面試題對比要簡單些,一面主要是基礎知識,二面考察更全面一些,更多讓自己談一些對技術的理解,三面則是更偏實踐一些。

算法雖然三輪都有,但相對比較簡單,即使寫不出來,有思路也是可以的。當然寫出來肯定是加分項,所以大家準備面試時,應該都看一下。算法相關的,排序,數組,二叉樹,這幾類是重點。

作爲一個開發者,有一個學習的氛圍跟一個交流圈子特別重要,這是一個我的iOS交流羣:413038000,不管你是大牛還是小白都歡迎入駐 ,分享BAT,阿里面試題、面試經驗,討論技術, 大家一起交流學習成長!

推薦閱讀

iOS開發——最新 BAT面試題合集(持續更新中)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章