iOS面試技巧及問題最全梳理,讓BAT的Offer不再難拿!

序言

目前形勢,參加到iOS隊伍的人是越來越多,甚至已經到供過於求了。今年,找過工作人可能會更深刻地體會到今年的就業形勢不容樂觀,隨著各大公司秋招的開始,很多小夥伴都行動起來了,我也有幸獲得了一份不錯的offer並和大家分享自己的經驗心得。由於我面試公司比較多,所以自然也是做了這方面的準備,因此這篇總結並不一定適合想去創業公司的同學。另外,由於經驗本來就是主觀性極強的東西,加之筆者水平有限,所以如果有不認可的地方,萬望諸君呵呵一笑,拋之腦後。

接下來,我就斗膽分享一下自己在準備和參加面試的過程中的收穫、對面試的思考,以及一些可能對大家有用的建議。希望能助大家一臂之力!!

首先我要問大家幾個問題

什麼是面試

有些人可能會把面試看的太重,覺得面試過了就能進入大廠,技術和財富兼得……

我倒是覺得,面試沒有這麼誇張(抱歉做了一回標題黨),它其實是一次你和麵試官互相瞭解的絕佳機會,藉此機會你還可以對未來的工作有初步的瞭解。

面試本身並不能完全評價一個人的實力。面試透過的人,也許只是恰好在面試時遇到了自己熟悉的問題,面試不透過,也有可能是面試官自身的問題,並非每個面試官都具備客觀評價別人的能力。

換句話說,面試沒透過也許是面試官沒有發現你的才華,面試通過了也並不代表你就能勝任工作,因為進入企業之後可不是每天負責回答面試題!

所以從這一點來看,面試有點像相親。你滿意我,我滿意你,王八對綠豆——看上眼了,那就一拍即合,否則就分道揚鑣。我本人非常希望能夠多幾輪面試(實際並不總是能做到),這樣大家都有充足的時間互相瞭解,決定去留。

網上某些面經中,介紹了一些“裝逼”的方法,還有所謂的“面試技巧”,我是不太認可的。技巧需要有,這是為了讓你更好的展示自己,而非坑蒙拐騙,無理取鬧,無中生有。我更想展現一個真實的自己,如果面試官不認可,說明我們沒有緣分,或者說自己的能力還不夠。

面試要準備什麼

有一位小夥伴面試阿里被拒後,面試官給出了這樣的評價:“……計算機基礎,以及程式設計基礎能力上都有所欠缺……”。但這種籠統的回答並非是我們希望的答案,所謂的基礎到底指的是什麼?

作為一名 iOS 開發者,我所理解的基礎是 作業系統、網路和演算法這三大塊,不同的開發方向可能有不同的側重,但基礎總的來說就是這些。我不推薦透過去網上看教程來學習這些基礎知識,因為能用短短几篇文章講明白的事情不叫基礎,至少我沒見過寫得這麼深入淺出的文章。

不知道有多少讀者和我一樣有過這樣的困擾:“我知道某些東西很重要,所以去百度查了資料,但是查到的文章質量很差,正確率沒有保證”。這其實是正常的,優秀的文章一般都放在優秀的作者的個人部落格上,這恰恰是搜尋引擎的盲區,所以一般只能搜到 CSDN、部落格園這種地方的文章。自然就無法保證文章質量。所以擁有一個自己的iOS交際圈子就很重要。

在這裡歡迎大家加入我的iOS交流群659170228,不管是小白還是大牛,歡迎大家入駐,一起交流成長!

除了準備通用的基礎知識以外,簡歷也是一個很重要的環節。一直很仰慕唐巧老師的猿題庫,無奈簡歷太差,都沒有收到面試邀請。後來好好改了簡歷以後,就沒有這種問題了。關於簡歷的書寫,推薦兩篇文章:如何寫面向網際網路公司的求職簡歷、程式猿簡歷模板。你也可以參考我的簡歷,沒有亮點,就當是拋磚引玉。

最後,當然是準備好相關崗位的基礎知識了。作為 iOS 開發者,雖然 Swift 已經發布了快兩年,但是大公司轉向 Swift 的動作還不明顯,所以 Objective-C 幾乎是必備項,Swift 都不一定能算是加分項。iOS 方面的知識也必不可少,雖然招聘資訊上寫著如果基礎紮實,零 iOS 基礎也可以,但是現實往往是比較殘酷的。

iOS面試技巧及問題最全梳理,讓BAT的Offer不再難拿!

659170228

在這裡有一些試探性的面試問題不知道大家會答的怎麼樣呢?

您在工程中遇到過什麼很難的問題?不論是特殊的互動方式、複雜動畫、效能、安全問題…… 最後怎麼解決的?

展示您做過最複雜的一個介面 / 自己封裝得比較好的元件,介紹它的結構和為什麼這麼做;

您在工程中做過哪些重構?做出了哪些改變,最後的效果如何?

平常工程中用到哪些第三方開源庫?您讀過它們的原始碼嗎?講講自己最熟悉的一個開源庫的原始碼結構;

這些問題的好處是顯而易見的,每個人都能多少說上幾句。回答大部分是“沒有”、“沒什麼”的基本可以 pass 了,而優秀的工程師往往有很多內容可聊。

下面給您看的這幾張圖是我上一期剛開發完的需求,如果讓您開發的話,您能給出一個估時嗎?其中有什麼難點和風險點嗎?

一些面試技巧

一般HR開場都會讓大家介紹一下自己的基本情況,說一說自己做過的專案以及負責過的模組。在這個環節,我覺得各位應該把之前所有的緊張不安的情緒全部穩定下來,因為我相信這個問題,大家應該已經做好了充分的準備,並且應該要有足夠的勇氣跟自信來回答這些問題。這個階段就有人被淘汰了,有的人表達得結結巴巴,不懂如何描述,或者前後不連貫,想到哪算哪,甚至對他的專案表述的都是一頭霧水。這樣的人在HR眼裡就會覺得他產品需求人員溝通一定會出大問題,誤會和返工少不了,因為他沒法表達清楚他做的專案的業務。

在這裡我給各位小夥伴一些建議,開場白非常重要!

從iOS的基礎,底層,到音影片編碼,逆向還有新的AR,coreML,大家對這些技術瞭解多少?

此外我覺得大家擴充一下自己的知識廣度是非常有必要的!

也許應聘者很多關於各種技術的回答是錯的,但是HR能看出來你是想過還是沒想過,是有自己的一套認知還是胡說八道。你說錯沒關係,我們團隊裡有懂的人,他以後會給你把觀點改正過來,但是想都沒想過,差距就顯而易見。如果你能瞭解一些AR,coreML的知識 那麼你就會在HR那裡加分不少!

iOS面試技巧及問題最全梳理,讓BAT的Offer不再難拿!

扯了這麼多,讓我們進入重頭戲

也許因為專案經歷所限,你沒機會用過這些技術,但是隨便上一些技術網站,都能瞭解到現在流行什麼,這些技術是為了解決什麼問題存在的,你看這些技術也說明你注意到了一些問題的存在。視野開闊的人,說明他的求知慾強。

先來梳理一下iOS面試中經常會遇到的一些問題吧!

OC作為一門面向物件的語言,自然具有面向物件的語言特性:封裝、繼承、多型。它既具有靜態語言的特性(如C++),又有動態語言的效率(動態繫結、動態載入等)。總體來講,OC確實是一門不錯的程式語言。

Objective-C具有相當多的動態特性,表現為三方面:動態型別(Dynamic typing)、動態繫結(Dynamic binding)和動態載入(Dynamic loading)。動態——必須到執行時(run time)才會做的一些事情。

OC的理解與特性

之前:OC記憶體管理遵循“誰建立,誰釋放,誰引用,誰管理”的機制,當建立或引用一個物件的時候,需要向她傳送alloc、copy、retain訊息,當釋放該物件時需要傳送release訊息,當物件引用計數為0時,系統將釋放該物件,這是OC的手動管理機制(MRC)。

目前:iOS 5。0之後引用自動管理機制——自動引用計數(ARC),管理機制與手動機制一樣,只是不再需要呼叫retain、release、autorelease;它編譯時的特性,當你使用ARC時,在適當位置插入release和autorelease;它引用strong和weak關鍵字,strong修飾的指標變數指向物件時,當指標指向新值或者指標不復存在,相關聯的物件就會自動釋放,而weak修飾的指標變數指向物件,當物件的擁有者指向新值或者不存在時weak修飾的指標會自動置為nil。

簡述記憶體管理基本原則

MVC是一種架構模式,M表示MOdel,V表示檢視View,C表示控制器Controller:

Model負責儲存、定義、操作資料;

View用來展示書給使用者,和使用者進行操作互動;

Controller是Model和View的協調者,Controller把Model中的資料拿過來給View用。Controller可以直接與Model和View進行通訊,而View不能和Controller直接通訊。View與Controller通訊需要利用代理協議的方式,當有資料更新時,MOdel也要與Controller進行通訊,這個時候就要用Notification和KVO,這個方式就像一個廣播一樣,MOdel發訊號,Controller設定監聽接受訊號,當有資料更新時就發訊號給Controller,Model和View不能直接進行通訊,這樣會違背MVC設計模式。

如何理解MVC設計模式

ViewModel層,就是View和Model層的粘合劑,他是一個放置使用者輸入驗證邏輯,檢視顯示邏輯,發起網路請求和其他各種各樣的程式碼的極好的地方。說白了,就是把原來ViewController層的業務邏輯和頁面邏輯等剝離出來放到ViewModel層。

View層,就是ViewController層,他的任務就是從ViewModel層獲取資料,然後顯示。

如何理解MVVM設計模式

代理是一種回撥機制,且是一對一的關係,通知是一對多的關係,一個對向所有的觀察者提供變更通知;

效率:Delegate比NSNOtification高;

Delegate和Block一般是一對一的通訊;

Delegate需要定義協議方法,代理物件實現協議方法,並且需要建立代理關係才可以實現通訊;

Block : Block更加簡潔,不需要定義繁瑣的協議方法,但通訊事件比較多的話,建議使用Delegate;

NSNotification、Block、Delegate和KVO的區別

程式碼緊湊,傳值、回撥都很方便,省去了寫代理的很多程式碼。

NSTimer封裝成的block,具體實現

實現方法:

iOS面試技巧及問題最全梳理,讓BAT的Offer不再難拿!

有2種方法解決:一個view已經初始化完畢,view上面添加了n個button,除用view的tag之外,還可以採用什麼辦法來找到自己想要的button來修改button的值

第一種:如果是點選某個按鈕後,才會重新整理它的值,其它不用修改,那麼不用引用任何按鈕,直接在回撥時,就已經將接收響應的按鈕給傳過來了,直接透過它修改即可。

第二種:點選某個按鈕後,所有與之同類型的按鈕都要修改值,那麼可以透過在建立按鈕時將按鈕存入到陣列中,在需要的時候遍歷查詢。

使用block有什麼好處?使用NSTimer寫出一個使用block顯示(在UILabel上)秒錶的程式碼

一個程式至少要有進城,一個程序至少要有一個執行緒。

程序:資源分配的最小獨立單元,程序是具有一定獨立功能的程式關於某個資料集合上的一次執行活動,程序是系統進行資源分配和排程的一個獨立單位。

執行緒:程序下的一個分支,是程序的實體,是CPU排程和分派的基本單元,它是比程序更小的能獨立執行的基本單位,執行緒自己基本不擁有系統資源,只擁有一點在執行中必不可少的資源(程式計數器、一組暫存器、棧),但是它可與同屬一個程序的其他執行緒共享程序所擁有的全部資源。

程序和執行緒都是由作業系統所體會的程式執行的基本單元,系統利用該基本單元實現系統對應用的併發性。

程序和執行緒的主要差別在於它們是不同的作業系統資源管理方式。程序有獨立的地址空間,一個程序崩潰後,在保護模式下不會對其它程序產生影響,而執行緒只是一個程序中的不同執行路徑。執行緒有自己的堆疊和區域性變數,但執行緒之間沒有單獨的地址空間,一個執行緒死掉就等於整個程序死掉,所以多程序的程式要比多執行緒的程式健壯,但在程序切換時,耗費資源較大,效率要差一些。

但對於一些要求同時進行並且又要共享某些變數的併發操作,只能用執行緒,不能用程序。

執行緒與程序的區別和聯絡?

NSThread:當需要進行一些耗時操作時會把耗時的操作放到執行緒中。執行緒同步:多個執行緒同時訪問一個數據會出問題,NSlock、執行緒同步塊、@synchronized(self){}。

NSOperationQueue操作佇列(不需考慮執行緒同步問題)。程式設計的重點都放在main裡面,NSInvocationOperation、BSBlockOperation、自定義Operation。建立一個操作繫結相應的方法,當把操作新增到操作佇列中時,操作繫結的方法就會自動執行了,當把操作新增到操作佇列中時,預設會呼叫main方法。

GCD(`Grand Central Dispatch)宏大的中央排程,序列佇列、併發佇列、主執行緒佇列;

同步和非同步:同步指第一個任務不執行完,不會開始第二個,非同步是不管第一個有沒有執行完,都開始第二個。

序列和並行:序列是多個任務按一定順序執行,並行是多個任務同時執行;

程式碼是在分執行緒執行,在主執行緒嘟列中重新整理UI。

多執行緒程式設計是防止主執行緒堵塞、增加執行效率的最佳方法。

Apple提供了NSOperation這個類,提供了一個優秀的多執行緒程式設計方法;

一個NSOperationQueue操作佇列,相當於一個執行緒管理器,而非一個執行緒,因為你可以設定這個執行緒管理器內可以並行執行的執行緒數量等。

多執行緒是一個比較輕量級的方法來實現單個應用程式內多個程式碼執行路徑。

iPhoneOS下的主執行緒的堆疊大小是1M。第二個執行緒開始就是512KB,並且該值不能透過編譯器開關或執行緒API函式來更改,只有主執行緒有直接修改UI的能力。

定時器與執行緒的區別;

定時器;可以執行多次,預設在主執行緒中。

執行緒:只能執行一次。

多執行緒程式設計

這裡就列舉我的兩次面試經歷吧

關於面試問題方面就先梳理到這,當然這肯定不是全部只是一部分,接下來我給大家分享一下我的經歷吧!

公司一

一面:約 1。5 小時

首先是四個演算法題:

不用臨時變數怎麼實現 swap(a, b)——用加法或者異或都可以

二維有序陣列查詢數字——劍指 offer 第 3題

億級日誌中,查詢登陸次數最多的十個使用者——(不確定對不對,我的思路是)先用雜湊表儲存登陸次數和ID,然後用紅黑樹儲存最大的十個數。劍指 offer 第 30題

簡述排序演算法——快排partion函式的原理,堆排(不穩定),歸併排序,基數排序。

最後是 iOS 相關,面試官問的很開放,都是談談自己的理解

說說你對 block 的理解。—— 三種 block,棧上的自動複製到堆上,block 的屬性修飾符是 copy,迴圈引用的原理和解決方案。

說說你對 runtime 的理解。——主要是方法呼叫時如何查詢快取,如何找到方法,找不到方法時怎麼轉發,物件的記憶體佈局。

說說你對 MVC 和 MVVM 的理解。—— MVC 的 C 太臃腫,可以和 V 合併,變成 MVVM 中的 V,而 VM 用來將 M 轉化成 V 能用的資料。

說說 UITableView 的調優。——一方面是透過 instruments 檢查影響效能的地方,另一方面是估算高度並在 runloop 空閒時快取。

談談你對 ARC 的理解。ARC 是編譯器完成的,依靠引用計數,談談幾個屬性修飾符的記憶體管理策略,什麼情況下會記憶體洩露。

一面的問題非常基礎,主要是演算法和 Objective-C,因為準備比較充分,基本上答出來 80% 吧。大約一週後突然二面。

二面:約 0。5 小時

二面比較突然,顯示簡單的自我介紹,然後問了三個問題:

野指標是什麼,iOS 開發中什麼情況下會有野指標?——野指標是不為 nil,但是指向已經被釋放的記憶體的指標,不知道什麼時候會有,如果有知道的讀者還望提醒。

介紹 block。—— (接第一問) 我讓面試官提示我一下什麼時候會有野指標,他說用 block 時,我表示還是不知道,只知道 block 會有迴圈引用。於是就扯回了一面的問題。

說說你是怎麼最佳化 UITableView 的。——還是一面的問題……。。。。。

雖然通過了,但是幾乎又問了一遍一面的問題讓我感覺對方不太認真。

公司二

主要是計算機方面的大雜燴,涉及作業系統,網路,移動開發,演算法等。難度不大,目測是為了淘汰渾水摸魚的人,就不列出題目了,演算法有三題,直接線上寫(木有 IDE 表示很憂傷):

很長一道題,讀了很久才讀懂,目測是 DFS,但是最後沒時間了,寫了個思路。

把 “www。zhidao。baidu。com” 這樣的字串改成 “com/baidu/zhidao/www”。——老題目了,劍指 offer 的,兩次逆序排列即可。

求陣列中和為某個值的所有子陣列,比如陣列是

[5,5,10,2,3]

一共有四個子陣列的和是 15,比如

[5,10]

[5,10]

[10,2,3]

[5,5,2,3]

。這個就是簡單的遞迴了,分兩種情況,當前位置的數字在子陣列中,以及不在子陣列中。

筆試

全部是 iOS 題,可能是覺得演算法已經面過了

介紹 block。——我提到棧上的 block 在 ARC 下會自動複製到堆上,面試官問我從 iOS 4 還是 5 開始支援這一特性,表示不知道,我又不是學 OC 歷史的,後來想想可能是公司內部老專案有這個坑

介紹一下 MVVM 和 RAC。——可能是我簡歷的某個角落寫了用過 RAC,被挖出來了,大概談了一下,結果面試官問我資料的雙向繫結怎麼做,bind函數了解過麼,果斷說已經忘了

介紹自己用過哪些開源庫。——Masonry 和 SnapKit,AFNetWorking,MKNetworkKit,Alamofire,Mantle,SDWebImage

SDWebImage 下載了圖片後為什麼要解碼?——當時矇住了,面試官很 nice 的解釋了一下,說是要把 png 檔案建立一個什麼記憶體對映,目前還不太懂,有空研究一下。

面試

面試收穫,注意看!!非常重要!!

1.

我的建議是,如果你想增加自己的入選機會,那最好還是花點錢製作一份專業的簡歷。相較於你將來可能得到的巨大收穫,這真的只是一個小小的投資。

給自己寫一份非常專業的簡歷

2.

當HR聯絡程式設計師來面試的時候,他總是會事先發電子郵件給他,並附上他的名字和部落格地址。但是讓我驚訝的是,當很多小夥伴去面試的時候,他竟然對HR還是一無所知。

舉個正面的例子,當HR在面試時遇到一位開發人員,甚至能對他以前寫的一篇部落格或者做的教學影片上面的內容侃侃而談。

你說HR會推薦哪個?

研究面試官

不管這種方法是否有欠公正,但是如果你想面試成功,那麼我建議你事先最好先好好研究一下你應聘的這家公司和麵試官(如果知道的話)。

當今社會的資訊是如此的發達,我們完全可以在貼吧、論壇、微博、部落格上找到任何人的資料。即使你只是大致瀏覽一番,也會讓你受益良多。

面試官也是人,也會有人性的弱點和特點。Dale Carnegie曾說過,要讓別人對你感興趣,最簡單的方法就是你先表達出對對方的興趣。

3.

知道找工作最簡單的方法是什麼嗎?那就是獲得內部推薦。

這不但可以增加面試機會,還能提升40%的錄用機率。

講一下我以前的一次經歷吧,我找到了一家心儀的公司。然後直接投簡歷?NONO,猜猜我是怎麼做的吧?

首先我找到一名和我有共同想法和意見的開發人員,然後開始關注他的部落格。

接著我在他的部落格中留言、發表建議,並且表現出對他的工作和公司非常感興趣的想法。最後我成功拿到了這個寶貴的內部推薦資格。

很多程式設計師會說,“可是,某某某公司裡面的人我一個也不認識啊”。如果你想就此放棄,那當我什麼也沒說,如果你願意試試,我敢打賭,你總能想出一種方法達到你的目的。

不過這有個秘訣,那就是首先你得在網上建立自己的“名片”——讓別人有了解你的機會,所以do it now吧。

獲得內部推薦

4.

這是每一個開發人員都應該具備的重要技能,而且真要掌握起來也並非那麼難。

在很多面試中,都會有這樣的問題,要求你在白板或者電腦上解決程式設計問題,但是許多程式設計師,即使是那些非常優秀的程式設計師,都會一下子大腦一片空白,完全理不出思路來。

如果你能花時間學會如何解決這種型別的面試問題,那麼下次再碰到這種場景,就不會這麼緊張了。

我們會緊張其實和怯場無關,主要是因為我們不熟悉這些問題,也沒有自信能解決這種問題。

在這方面建立起自信之後,你就再也不會緊張了。

學會解決演算法問題

5.

只用一個字或者一句話,照本宣科平平無奇地回答問題,或許在技術上是正確的,但是你忘了應該藉此機會好好展示自己的激情——這才是一個開發人員能帶給團隊的最大正能量。

舉個例子說,如果我問你什麼是多型性,我不是要你按照課本中的定義重複給我聽,我希望你能就這個主題闡述一下,然後我們可以更深入地聊一聊。

活力洋溢地回答問題

6.

小心

陷阱

你為什麼換工作?

說說你最大的優點和缺點。

最近一次你是如何解決和同事之間發生的技術分歧的?

在回答問題之前,你最好明白麵試官問這些問題的目的,掌握如何回答這類問題的技巧。

就先說說第一個問題吧“你為什麼換工作?”

在大多數情況下,面試官想知道的是你是否是一個愛說三道四、慣於誹謗抨擊僱主的人。所以千萬不要上當。

問題

遇到不會的問題果斷承認啊。如果是基本問題,比如問你雜湊表怎麼實現,你說不會,那麼這次面試可能就懸了。如果是有一定難度的問題,那麼你承認不會,也是一種明智之舉,畢竟人無完人,一個問題不會並不能全盤否定一個人的能力。

但是比較糟糕的一種情況是,面試者由於過分緊張,擔心答不上面試官的問題會有嚴重後果,所以嘗試著去敷衍面試官。比如:“我猜是 xxx 吧”,“我覺得可能是 ……”,更有甚者直接裝逼:“這個我試過,不就是 xxx 麼”。要知道,此時的你,由於緊張,在心態上已經輸給了面試官,更何況面試官問你的問題一定是他有把握的,你覺得這時候你負隅頑抗會有幾成勝算呢?

所以,面試官問我“堆排序”的細節時,由於我當時忘了堆排序是怎麼實現的,所以我直接告訴他我記不清了。另一個主動認輸的例子是面試官問我 RAC 如何實現雙向繫結,我告訴他這個是我當時學習的時候寫過的 demo,因為不常用,已經只記得一些簡單的概念了。

最後,還需要保持一個平穩的心態:“面試時盡力就好,遇到自己不會的問題也是正常情況”。如果面試者順利答對了所有問題,難免會讓面試官感到一絲尷尬,面試者也有可能會產生一些別的情緒。所以,我們要做的只是把自己的能力展示給面試官,做到不驕不躁。

7. 遇到真的不會的問題怎麼處理

iOS面試技巧及問題最全梳理,讓BAT的Offer不再難拿!