在本文中,您將找到針對高級開發人員的iOS面試問題和解答。 當您準備進行技術性的iOS面試時,重要的是要瞭解您可能會被問到的話題以及經驗豐富的iOS開發人員的期望。這些問題被許多公司用來衡量iOS候選人的經驗水平。它們涵蓋了iOS開發的各個方面,旨在接觸對該平臺的廣泛瞭解。畢竟,高級開發人員有望能夠 ...
在本文中,您將找到針對高級開發人員的iOS面試問題和解答。
當您準備進行技術性的iOS面試時,重要的是要瞭解您可能會被問到的話題以及經驗豐富的iOS開發人員的期望。這些問題被許多公司用來衡量iOS候選人的經驗水平。它們涵蓋了iOS開發的各個方面,旨在接觸對該平臺的廣泛瞭解。畢竟,高級開發人員有望能夠從頭到尾交付完整的iOS產品。但是,在擁有大型iOS開發團隊(可容納25人以上)的大型公司中,也會進行專業化並且專註於對特定問題(例如網路)的深入瞭解。這絕不是詳盡的清單,但可以幫助您為即將進行的iOS技術面試做準備。
1. 個Swift的主要特征和優缺點是什麼?
這聽起來像是一個初學者的問題,但事實並非如此。有時可能會要求您評估您在使用其他語言方面的經驗,以及對所使用語言為您提供的語言及其優點,缺點和局限性的更廣泛理解。
預期答案:
TLDR:Swift的主要功能-靜態類型,協議,引用類型,值類型,可選,泛型。
Swift是一種強類型語言,它可能同時是其最大的功能,優點和缺點。靜態類型允許協議,泛型和可選項存在,並有助於您進行開發。靜態類型為您提供了許多編譯時警告和編譯錯誤,但提供了更高的運行時安全性和確定性(可選,var / let,泛型或具體類型等)。這是該語言提供的最大優勢之一。在以下情況下,具有嚴格的類型安全性是最有幫助的:
- 在構建客戶端應用程式時,您需要更嚴格的顯式性,而不是動態性和靈活性
- 當您要在一個環境中工作時,希望限制經驗不足的開發人員(初學者和初級人員)不要擁有過多的能力並自行射擊
- 當您需要重構代碼時,編譯器將幫助您正確正確地編寫代碼
所有這些恰好是iOS開發人員構建的大多數面向客戶的應用程式。
同時,當您構建需要更多靈活性的內容(如構建庫或框架)時,靜態類型可能會過於嚴格。在這方面,Objective-C可能是一個更好的選擇,因為它比Swift具有更好的元編程功能。(儘管可以說,此時Objective-C已過時,並且Apple平臺的所有開發都應在Swift中完成)
回答註意點:
只要您能闡明每個功能所提供的功能(即協議和泛型實際上允許您在代碼中執行什麼操作),就可以了?但是同樣,與嚴格類型系統相比,那些語言可以說是次要的語言功能。
2. 什麼是iOS應用程式,您的代碼適合哪裡?
這是一個大問題,以一種或另一種形式提出,以評估您對iOS應用程式的理解,以及您編寫的代碼在其中以及在iOS系統中的適用位置。
預期答案:
我們可能會認為我們構建的應用程式很特別,因為它們涵蓋了獨特的用例。但是您典型的iOS應用程式只是一個巨大的榮耀運行迴圈。它等待用戶輸入,並被外部信號打斷,例如電話,推送通知,首頁手勢/按鈕按下以及其他應用程式生命周期事件。唯一的區別在於,它不僅是每次用戶點擊您的應用程式圖標時都會啟動的簡單主迴圈函數,它還具有開發人員可以使用的更高級別的抽象,UIApplication,AppDelegate和SceneDelegate。
您編寫的用於實現應用程式業務邏輯的其餘代碼位於該主迴圈通過AppDelegate
或委托給我們應用程式的“觸發點”中SceneDelegate
。在iOS 13 AppDelegate
負責接收應用程式的所有外部事件並擴展UI之前,但從iOS 13開始,所有與UI相關的邏輯都移至SceneDelegate。
而已。簡單。您為應用程式編寫的代碼可以像方法/函數調用一樣簡單,也可以像VIPER體繫結構一樣複雜。這是你的選擇。
回答註意點:
通常,開發人員將iOS應用視為他們編寫的MVC代碼以及實現的複雜細節,這是事實。但是,如果退後一步,放眼大局,您可以看到真正的iOS應用程式-運行迴圈。
3. iOS中的記憶體管理如何處理?
記憶體管理在任何應用程式中都非常重要,尤其是在具有記憶體以及其他硬體和系統約束的iOS應用程式中。此問題涉及ARC,MRC,引用類型和值類型。
預期答案:
Swift使用自動引用計數(ARC)。從概念上講,這在Swift中與在Objective-C中是相同的。ARC會跟蹤對類實例的強引用,併在您將類實例(引用類型)的實例分配或取消分配給常量,屬性和變數時相應地增加或減少其引用計數。它釋放由引用計數降至零的對象使用的記憶體。ARC不會增加或減少值類型的引用計數,因為在分配值時,它們會被覆制。預設情況下,如果沒有另外指定,則所有引用都是強引用。
回答註意點:
這是每個iOS開發人員都必須知道的!由於iOS應用程式中的記憶體管理不善,記憶體泄漏和應用程式崩潰非常普遍。
4. 什麼是MVC?
哦,老MVC不錯。這是Apple不斷推向iOS開發人員的基本設計模式。無論您是申請高級職位還是初級職位,每位面試官都極有可能會問這個問題。不過,您作為大四學生的答案會有所不同。
預期答案:
MVC
代表模型視圖控制器。這是Apple選擇作為iOS應用程式開發的主要方法的軟體設計模式。模型代表應用程式數據;視圖在屏幕上繪製事物;控制器管理模型和視圖之間的數據流。模型和視圖從不直接相互通信,而依賴於控制器來協調通信。蘋果公司從最初的SmallTalk實現中將這種設計模式轉變為其他形式 。
iOS應用程式中每個Apple MVC層的典型表示為:
- UIView子類(可可觸摸或自定義)是視圖
- UIViewControllers及其子類是控制器
- 任何數據對象,NSManagedObject子類等都是模型
MVC是一種很棒的通用設計模式,但是作為高級開發人員,您應該知道它只是視圖層的設計模式,單獨使用它會限制您的體繫結構,並經常導致臭名昭著的“大型視圖控制器”問題。
Massive View Controller是代碼庫的狀態,在該狀態下,大量邏輯和職責被推到不屬於該代碼庫的View Controller中。這種做法會使您的代碼僵化、,腫且難以更改。還有其他設計模式可以幫助您解決這一問題,例如 MVVM, MVP和 Coordinator。還有一些架構,例如VIPER和 RIB是專門為擴展iOS代碼和避免Massive View Controller問題而設計的。
即使Apple一直告訴我們MVC就是一切,但請多瞭解並堅持SOLID原則。
回答註意點:
您絕對必須知道MVC是什麼,因為它是任何iOS開發的基礎。但是,請探索替代產品和附加產品,例如MVVM,MVP,VIPER和RIB。
5. 您對單身人士瞭解多少?您將在哪裡使用哪一個?
Singleton是許多OOP語言中常用的設計模式,可可認為它是“可可核心能力”之一。面試中會出現這個問題,以評估您對單身人士的體驗,或者瞭解您是否具有iOS以外的背景知識。
預期答案:
Singleton是一個類,無論您請求多少次,它都只返回一個實例。
有時將單例視為反模式。使用單例有多個缺點。主要參數是全局狀態,對象生命周期和依賴項註入。當您只有某個事物的一個實例時,很想直接在任何地方引用和使用它,而不是將其註入到對象中。這導致代碼中具體實現的不必要耦合,而不是使用介面抽象。
“方便”單例的另一個惡意副作用是全局狀態。通常,單例啟用全局狀態共用,並扮演每個對象用來存儲狀態的“公共包”的角色。當這種不受控制的狀態被某人覆蓋或刪除時,這將導致不可預測的結果,錯誤或崩潰。
回答註意點:
即使在某些語言和平臺中,單例被認為是不錯的選擇,但實際上它們是一種反模式,應不惜一切代價避免這種情況。
6. 代表和KVO有什麼區別?
有了這個問題,面試官正在評估您對iOS中使用的不同消息傳遞模式的瞭解。
預期答案:
兩者都是在對象之間建立關係的方式。委托是一對一關係,其中一個對象實現委托協議。另一個使用協議定義的方法向其發送消息。KVO是一種多對多關係,其中一個對象廣播一條消息,而一個或多個其他對象偵聽該消息並做出反應。KVO不依賴協議。KVO是反應式編程(RxSwift,ReactiveCocoa等)的 第一步和基本步驟
回答註意點:
經驗豐富的開發人員應該知道兩者之間的差異,以及在哪裡可以相互使用。
7. iOS應用程式通常使用哪些設計模式?
除初級職位外,所有級別的面試中都會出現這個問題。使用iOS平臺,開發人員應該熟悉iOS上常用的技術,體繫結構和設計模式。
預期答案:
構建iOS應用程式時,通常使用的典型模式是Apple在其Cocoa,Cocoa Touch,Objective-C和Swift文檔中所倡導的模式。這些是每個iOS開發人員都可以學習的模式。蘋果將它們稱為“核心競爭力”設計模式。它們包括MVC,Singleton,Delegate和Observer。
回答註意點:
當面試官(以一種或另一種形式)問這個問題時,他正在尋找MVC以外的東西。因為MVC是首選設計模式,所以期望每個iOS開發人員都知道這一點。但是,他們想從您那裡得到的消息是我們通常開箱即用的其他信息。
8. 除了您知道的常見可可圖案以外,還有哪些設計圖案?
這是一個高級問題,當您面試高級職位或建築師職位時,面試官會提出這個問題。期望的是,您將瞭解iOS應用程式中使用的更實用的設計模式,而不僅僅是前面問題中涵蓋的基本設計模式。準備召回一堆“ 四人幫”模式和其他類似模式。
設計模式本身就是一個巨大的話題(在我的書中有更好的介紹),因此在這裡,我將僅總結我在iOS代碼庫中常見的模式。
預期答案:
除了常用的MVC,Singleton,Delegate和Observer模式外,還有許多其他完全適用於iOS應用程式的模式:Factory Method,Adapter,Decorator,Command和Template。
Factory Method用於替換類構造函數,以抽象和隱藏對象的初始化,以便可以在運行時確定類型,並隱藏和包含switch/if
確定要實例化的對象類型的語句。
適配器是一種設計模式,顧名思義,它可以幫助您使一個對象的界面適應另一個對象的界面。當您嘗試適應無法更改為代碼的第三方代碼時,或者當您需要使用不方便或不相容的API時,通常會使用此模式。
裝飾器是另一個類的包裝,可以增強其功能。它包裝了您要裝飾的東西,實現了它的介面,並將發送給它的消息委托給基礎對象,或者增強了它們或提供了自己的實現。
命令是一種設計模式,您將在其中實現一個對象,該對象表示您想要執行的操作。該操作可以具有其自己的狀態和邏輯來執行它所執行的任務。這種設計模式的主要優點是,您可以向用戶隱藏操作的內部實現,可以向其添加撤消/重做功能,並且可以在以後的某個時間點(或根本不執行)而不是執行操作。立即創建操作的位置。
模板是一種設計模式,其主要概念是擁有一個基類,該基類概述了需要完成的演算法。基類有一些抽象方法,這些方法必須由其具體子類實現。這些方法稱為掛鉤方法。Template Method類的用戶只能使用實現演算法步驟的基類進行交互;這些步驟的具體實現由子類提供。
回答註意點:
當您剛從iOS平臺開始時,僅堅持使用MVC,Singleton,Delegate和Observer模式是很好的,但是對於高級功能,您需要更深入地研究更抽象和更高級的內容,例如“四個OOP設計模式的幫派”。它們非常有用,可以使您的代碼庫更加靈活和可維護。
9. 解釋並顯示SOLID原理示例?
SOLID原則相對較舊,但適用於任何語言的任何OOP代碼庫的概念都非常有用。觀看Bob叔叔關於該主題的一些演講,以充分理解其背後的歷史。
在YouTube上:Bob Martin面向對象和敏捷設計的SOLID原理。
不幸的是,SOLID原則本身就是一個巨大的話題(在我的書中也有更好的介紹),因此在這裡我僅對它們進行概述。
預期答案:
SOLID代表單一責任原則,開放/封閉原則,Liskov替代原則,介面隔離原則和依賴倒置原則。這些原則相互融合併相互支持,是您可以為代碼採用的最佳常規設計方法之一。讓我們逐一介紹一下。
單一責任原則(SRP)是該小組最重要的原則。它指出,每個模塊都應該只有一個責任和變更理由。SRP從小的具體情況開始,例如類和/或對象僅具有一個目的,並且僅用於一件事。
打開/關閉原則(OCP)指出,您的模塊應打開以進行擴展,但應關閉以進行修改。這是聽起來很容易的事情之一,但是當您開始思考它的含義時,很難把頭纏起來。實際上,這意味著在編寫代碼時,您應該能夠通過使用介面,抽象和依賴註入實現對象,從而通過繼承,多態和組合來擴展對象的行為。
Liskov替換原理(LSP)指出,程式中的對象應該可以用其子類型的實例替換,而不會改變該程式的正確性。這意味著當您從類或抽象類繼承或實現介面(協議)時,無論使用了您的子類介面或類,您的對象都應該是可替換和可註入的。這項原則通常被稱為按合同設計,或者在Swift社區中最近被稱為面向協議的編程。該原則的主要信息是,您不應違反從子類承諾繼承的介面要履行的約定,並且通過子類化,這些子類可以在以前使用超類的任何地方使用。
介面隔離原理(ISP)表示,許多特定於客戶端的介面比一種通用介面要好。它還指出,不應強迫任何客戶端依賴和實現不使用的方法。這就是說,當您創建類要實現的介面(協議)時,您應該努力並依賴於抽象性而不是特異性,但是直到浪費掉您必須實現一堆新類的方法時,這種浪費才成為現實。甚至使用。
依賴倒置原則(DIP)指出:“依賴抽象,而不依賴具體。” 展示此原理的最佳示例是依賴註入(DI)技術。使用依賴註入技術,在創建對象時,您將在其初始化或配置時提供並註入其所有依賴關係,而不是讓對象自行創建或獲取/查找其依賴關係。
回答註意點:
SOLID原則是良好的OOP設計的基礎。應用這些原則將幫助您構建更好,更可維護的軟體。如果您要申請iOS的高級職位,強烈建議您精通它們。
10. 您在iOS上實現存儲和持久性有哪些選擇?
採訪者會問這個問題,以瞭解您對可用於在iOS上存儲和保存數據的工具和方式的理解。
預期答案:
通常,有以下幾種按簡單到複雜的順序存儲數據的方式:
- 記憶體中的數組,字典,集合和其他數據結構
- NSUserDefaults /鑰匙串
- 文件/磁碟存儲
- 核心數據,領域
- SQLite的
記憶體中的數組,字典,集合和其他數據結構非常適合用於中間存儲數據或無需持久存儲數據。
NSUserDefaults / Keychain是簡單的鍵值存儲。一個是不安全的,另一個是安全的。
文件/磁碟存儲是一種使用NSFileManager向磁碟寫入數據或從磁碟寫入數據的方法。
核心數據和領域是簡化資料庫工作的框架。
SQLite是一個關係資料庫,當您需要實現複雜的查詢機制而Core Data或Realm不會削減它時,它是一個很好的選擇。
回答註意點:
您應該知道在iOS上存儲數據的不同方式以及它們的優缺點。不要將自己僅限於您習慣的一種解決方案(例如,Core Data)。知道何時一個比另一個更可取。
11. iOS上的網路和HTTP有哪些可用選項?
如今,每個應用程式都使用網路來從API和其他外部資源獲取數據。如果未連接到互聯網,許多應用程式將無用。每個iOS開發人員都應該知道他們可以使用什麼來構建其應用程式的服務/網路層。
預期答案:
在iOS中,有幾種實現HTTP網路的選項。您可以使用舊的NSURLSession,但是除非您對其進行足夠好的抽象,否則使用它可能會令人生畏。另一種選擇是在其周圍使用包裝器庫。iOS上最受歡迎的解決方案是Alamofire。
通常,如果您的團隊很小,則可能需要依靠開源解決方案,例如Alamofire,它可以為您抽象出許多樣板代碼。但是如果您的團隊很大,並且可以節省資源,那麼您將希望更好地控制數據與伺服器之間的傳遞以及使用NSURLSession自己實現數據的方式。
高級開發人員應記住,在iOS應用程式中構建網路層不僅意味著處理HTTP請求,而且意味著實現代碼所涉及的整套任務:HTTP網路,數據序列化和數據映射。
回答註意點:
如今,NSURLSession和Codable是用於在iOS上聯網的兩種主要技術,但瞭解Alamofire之類的開源解決方案也是有益的。
12. 如何以及何時在iOS上序列化和映射數據?
生成iOS應用程式時,數據序列化是一項常見任務。採訪者會問這個問題,以瞭解您是否認識到合適的位置,並知道在處理數據時(無論是網路數據還是存儲數據)所需的任務。
預期答案:
有兩種最常見的情況,您需要在iOS應用程式中序列化和映射數據:在網路層中接收或發送數據(例如JSON或XML或其他東西),以及在存儲層中持久化或檢索模型(NSData) ,NSManagedObject)。
每次您從後端API收到JSON或XML或任何其他響應類型的響應時,您很可能會以JSON或二進位或其他“不便”格式獲取它。要處理收到的數據,您需要做的第一件事就是將其序列化為您的應用可以理解的格式。最簡單和最基本的級別是字典或包含該響應中其他字典,數組和基元的對象數組。NSJSONSerialization會解決這個問題。下一步是將數據映射到應用程式的域模型中。這些將是應用程式其餘部分要使用的模型對象或結構。您可以手動執行此操作,也可以使用Codable
Apple提供的協議,也可以使用Mantle或SwiftyJSON之類的庫。數據流和序列化/映射為:binary data
->json
- > NSDictionary/NSArray
- > your domain model objects
。
同樣,在存儲層中,您將需要序列化數據並將其與自定義域模型對象之間的數據映射到存儲所能理解的格式。用於讀取數據的“映射”鏈:db
-> raw data format
-> custom domain models
; 編寫:custom domain models
-> raw data format
-> db
。您可以在此處使用NSManagedObject或NSCoding或Codable協議來實現。
回答註意點:
這裡的主要危險信號是沒有意識到與iOS應用程式的網路和存儲層一起使用時,需要進行這些數據操作。事情不會“自動地”發生,並且與原始的NSDictionaries合作也不是適當和可維護的。
13. 在iOS上佈置UI有哪些選項?
當您需要解決iOS上不同的UI挑戰時,瞭解在屏幕上佈置內容的選項至關重要。該問題有助於評估您有關如何在屏幕上放置和對齊視圖的知識。在回答這個問題時,您至少應提及CGRect,Fframes和AutoLayout和SwiftUI,但最好提及其他選項,例如Texture(ASDK),ComponentKit以及iOS上的其他Flexbox和React實現。
預期答案:
舊的CGRect框架和自動版式是在屏幕上顯示視圖的理想選擇。框架以及自動調整大小的蒙版在iOS 6之前就已使用過,如今已不再是首選。框架太容易出錯並且難以使用,因為很難為各種設備計算精確的坐標和視圖大小。
從iOS 6開始,我們有了AutoLayout,這是當今流行的解決方案,也是Apple首選的解決方案。AutoLayout是一項技術,可幫助您以聲明性的方式定義視圖之間的關係(稱為約束),使框架可以計算出精確的框架和UI元素的位置。
在iOS 13中,Apple引入了一種新的視圖佈局方法-SwiftUI,這是一種聲明性方法,它支持通過Combine進行FRP(函數式反應性編程)數據綁定。FRP和聲明性UI並不是新概念,但是SwiftUI和Combine是Apple支持的新框架。SwiftUI的聲明性質使您可以非常簡潔地聲明UI元素,然後通過數據綁定聲明UI的哪些部分(例如文本標簽)來更新什麼數據模型發生了變化。實際上,它允許您使用RxSwift進行以前但現在可以使用Apple框架進行的操作。
還有其他佈局視圖的選項,例如ASDK(紋理),ComponentKit和LayoutKit,其中一些或多或少受React啟發,而其他解決方案則不同。在某些情況下,例如,當您需要構建高度動態和快速的表視圖和集合視圖時,這些替代方法非常有用。AutoLayout並非總是那麼完美,知道其他選項總是一件好事。
註意:我們將看到SwiftUI將來如何證明自己能夠解決複雜的UI問題和複雜的非同步UI佈局問題,在撰寫本文時,這是一項非常新的技術。
回答註意點:
至少沒有提到自動版式以及框架很難正確放置的事實對於您的面試官來說是一個危險信號。如今,除非有必要,否則沒有理智的人會進行CGRect框架計算(例如,當您進行瘋狂的繪製時)。
它不會是一個危險信號,但是要提到SwiftUI,這很可能將成為蘋果在未來幾年內對我們的推動。
14. 如何優化動態大小的表或集合視圖的滾動性能?
與UITableView問題一起,訪談中的重要問題之一是滾動性能。
預期答案:
滾動性能是UITableViews的一個大問題,而且通常很難正確實現。主要困難是像元高度的計算。當用戶滾動時,每個下一個單元格需要先計算其內容,然後計算高度,然後才能顯示它。如果您手動進行“框架”視圖佈局,則性能會更高,但面臨的挑戰是正確計算高度和尺寸。如果使用自動版式,那麼面臨的挑戰就是正確設置所有約束。但是,即使AutoLayout本身也可能需要一些時間來計算單元格高度,並且滾動性能會受到影響。
滾動性能問題的潛在解決方案可能是:
- 自己計算像元高度
- 保留一個您填充了內容的原型單元,並使用它來計算單元的高度
或者,您可以採用一種完全激進的方法,即使用諸如ASDK(紋理)之類的不同技術。ASDK(紋理)是專門為具有動態內容大小的列表視圖製作的,並且經過優化以計算後臺線程中的單元格高度,從而使其具有超強的性能。
15. 您將如何在iOS上執行非同步任務?
如今,多線程是任何客戶端,面向用戶應用程式的重要組成部分。該問題可以在網路環境中提出,也可以作為有關GCD或非同步開發的獨立問題提出。
預期答案:
在iOS上,如今,非同步任務的首選解決方案是NSOperations和GCD塊。Grand Central Dispatch是一項可以與多個後臺隊列一起使用的技術,該後臺隊列又可以找出哪個後臺線程來處理工作。最主要的是,它是從您那裡抽象出來的,因此您不必擔心它。NSOperation是GCD之上的OOP抽象,它允許您執行更複雜的非同步操作,但是使用NSOperation可以實現的一切都可以與GCD一起實現。許多可可框架在後臺使用GCD和/或NSOperation(例如,NSURLSession)。
使用第三方庫的幫助還有其他處理非同步工作的方法。最著名的是Promises(PromiseKit),RxSwift和ReactiveCocoa。RxSwift和ReactiveCocoa特別擅長建模時間和工作的非同步特性,這些工作需要在後臺完成併在線程之間進行協調。
回答註意點:
每個iOS開發人員應瞭解的有關非同步工作的基礎知識是GCD和NSOperations。RxSwift和Promises是高級概念,但是高級開發人員應該瞭解它們。
16. 您如何管理依賴關係?
依賴管理是每個iOS項目中的重要任務。這個問題可以衡量您對問題及其解決方案的理解。
預期答案:
幾年前,我們在iOS上還沒有任何依賴項管理器,因此不得不將第三方代碼複製粘貼和拖放到我們的項目中或使用Git子模塊。隨著我們的代碼庫和依賴關係的增長,這些方法變得難以管理。
如今,我們還有其他依賴項管理器可供選擇:CocoaPods,Carthage和Swift Package Manager。
到目前為止,最主要和最強大的功能是CocoaPods。我本著Ruby Bundler寶石的精神建造的,本身就是Ruby寶石。它的工作方式是安裝gem,Podfile
在項目的根目錄中創建,聲明要使用的pod(庫)並運行pod install
。而已。
使用Carthage,您可以創建一個名為的依賴項聲明文件,Cartfile
但與Cocoapods不同,您需要進行Xcode項目設置才能使其工作。
Swift軟體包管理器是任何Swift項目依賴管理的未來,但它僅支持庫和框架,並且不能用於生成iOS目標,儘管iOS目標可以依賴於SPM構建的模塊。
回答註意點:
每個iOS開發人員都應該理解,當多個庫可能依賴於另一個庫的兩個不同版本時,將第三方庫複製粘貼到您的代碼庫中會導致維護的噩夢,從而導致不匹配以及編譯和運行時問題。
17. 您如何在iOS上調試和分析代碼?
沒有人編寫完美的代碼,開發人員需要調試其代碼和配置文件應用程式,以提高性能和記憶體泄漏。
預期答案:
iOS應用程式中 總是存在
NSLog
ging和
您可以使用進行更高級的調試和分析Instruments
。Instruments是一種性能分析工具,可幫助您分析應用程式併在運行時查找記憶體泄漏和性能問題。
18. 您有TDD經驗嗎?您如何在iOS上進行單元和UI測試?
儘管從歷史上看,iOS社區在TDD上並不占優勢,但由於工具的改進和來自其他社區(如Ruby)的影響(早在TDD之前就加入了TDD),它現在變得越來越流行。
預期答案:
TDD是一種技術和學科,在編寫使測試通過的生產代碼之前,您首先要編寫失敗的測試。測試推動了生產代碼的實現和設計,從而幫助您僅編寫通過測試實現所必需的代碼,沒有更多,更少。一開始的紀律可能令人望而生畏,您不會立即看到這種方法的收益,但是如果堅持下去,從長遠來看,它可以幫助您更快地採取行動。它在幫助您進行重構和代碼更改方面特別有效,因為在任何給定的時間,您都可以通過測試的安全網來告訴您是否發生了故障,或者在進行更改時一切仍然正常。
最近,Apple對XCTest框架進行了改進,使我們的測試變得更加容易。他們還通過Xcode(XCUITest)中的UI測試進行了很多改進,因此現在我們有了一個不錯的程式化界面來與我們的應用程式交互並查詢我們在屏幕上看到的內容。或者,您可以使用KIF,iOSSnapshotTestCase,EarlGrey等框架。
關於單元測試,也有幾種選擇,但是兩個最受歡迎的選擇是XCTest和Quick and Nimble。
XCTest是Apple構建的類似於xUnit的測試框架。這是他們建議使用的方法,它與Xcode的集成最佳。
Quick是一種類似於RSpec的BDD框架,可幫助您用行為而不是“測試”來描述規格/測試。RSpec的粉絲非常喜歡。
Nimble是一個匹配程式庫,可以與XCTest或Quick一起使用,以斷言測試/規範中的期望。
回答註意點:
越來越多的團隊和公司採用TDD,它已成為iOS開發過程中至關重要的一部分。如果您不想被拋在後面,請繼續學習並學習如何測試驅動您的代碼。
19. 模擬,存根和假貨之間有何不同?
隨著測試成為iOS世界中越來越重要的實踐,重要的是要在編寫測試時知道自己在做什麼。測試代碼與應用程式代碼一樣重要。這個問題可以幫助您瞭解對用於單元測試的對象的測試術語的理解。
預期答案:
不同的人可以通過多種方式對測試對象進行調用和分類,但是最常見的測試對象可以通過以下方式進行分類:偽造,存根和模擬。
偽造品是任何種類的模擬,偽造,存根,雙精度等的通用總稱。它們自己通常沒有實現,僅滿足它們所替代類型的介面API要求。
存根是偽造品,它們執行一些有意義的工作,這些工作對於測試所涉及的對象進行操作是必需的,但僅用於其他用途。它們不能代替實際的生產對象,但可以返回存根值。無法斷言它們。
cks是可以斷言的假貨。偽造用來代替偽造的其他對象,但是它們本身會記錄一些數據,例如方法調用的數量或傳遞給您的測試以供以後聲明的變數。
回答註意點:
許多開發人員將任何測試對象稱為模擬都是錯誤的,但是測試對象有一個特定的獨特命名法,用於指示每個對象的用途。作為高級開發人員,您不僅要編寫測試,還應該知道如何維護測試以及應用程式代碼庫。
20. 您是否編寫評論和/或配對程式的代碼?
即使那裡有許多由獨立開發人員構建的應用程式,但應用程式執行的複雜性仍在不斷增加,要求由一組開發人員來進行處理。團隊合作在代碼維護,協作和知識共用方面提出了不同的挑戰。
預期答案:
結對編程是一種實踐,其中兩個開發人員在同一臺電腦上共同完成同一任務(希望不會共用相同的屏幕和鍵盤,而是擁有兩組自己的屏幕和鍵盤)。目的是在代碼產生的地方促進協作,討論,代碼審閱和質量檢查。這個過程使知識轉移和架構討論成為日常的日常事務,從而防止人們在代碼的某些部分孤立或成為“專家”(當這個人離開或生病時會發生什麼?)。這也提高了代碼質量,因為兩組眼睛在編寫代碼時都在看代碼。這個過程同時發生在兩個開發人員之間,有時也稱為同步。
結對編程並不適合每個人,如果人們的個性不匹配,結對編程可能會很累人。但是,它仍然是軟體開發中最有效的協作技術之一。
代碼審查是協作和知識轉移的類似過程,但是與結對編程不同,它不會同時發生,因此是非同步的。通過代碼審查,在開發人員編寫了一段代碼或功能之後,團隊中的其他人就會對其進行查看。審閱者檢查代碼是否有意義,並建議進行更改和重構以進行改進。這就打開了有關該代碼的線上或離線討論,這很棒。這樣可以將有關該代碼段的知識轉移給其他隊友,並幫助及早發現錯誤和設計異味。
代碼審查是一種較少參與的協作類型,可以實現與結對編程相同的結果。這也是一種換位思考的練習,您可以在此向他人提供有關他們工作的反饋。
21. 什麼是FRP(功能性反應式編程)及其在iOS平臺中的位置?
函數式反應式編程(FRP)是iOS / Swift,JavaScript和其他開發者社區中的新熱點。除了它實際上不是那麼新。無論是Swift功能還是更大的體繫結構和概念性討論問題,都可以期待這個問題。
預期答案:
功能響應式編程(FRP)是一種聲明式編程範例,它結合了功能編程和響應式(非同步數據流編程)範例。這是一種聲明式的編程風格,您可以聲明代碼的工作方式,而不是聲明代碼的工作方式。FRP的反應性組件使我們能夠引入和描述時間的概念,這在純函數式編程中很難使用。FRP通常可以幫助我們處理用戶輸入和iOS應用程式的非同步特性;用戶輸入發生在某個時間點,聯網將在將來的某個時間結束,等等。
FP和FRP依賴於將函數作為參數並返回其他函數的高階函數(例如map,reduce和filter),這使它們具有很高的可組合性。
Swift沒有對FRP的本機支持,但是有兩個出色的庫實現了功能性反應式編程概念並使它們易於我們使用:ReactiveCocoa和RxSwift。
在iOS 13中,蘋果公司還宣佈了iOS內置的名為F合併的新FRP框架。組合實際上是類似於RxSwift的FRP框架實現。它具有兩個優點:它與SwiftUI集成在一起,從而可以將UI元素綁定到數據更改,並且它是Apple內置和支持的。缺點是:它不如RxSwift成熟,Apple對其進行更改和添加將很慢。
回答註意點:
FRP在iOS應用程式中正變得越來越普遍,並且將在Apple官方對Combine編程範例的官方支持下使用更多FRP。iOS開發人員應該開始擁抱它。
22. 您知道哪種iOS架構可擴展嗎?
可能會問這個問題,採訪一家擁有大型iOS開發團隊的大公司。iOS應用程式變得越來越複雜,MVC設計模式不能像大型應用程式架構那樣很好。對於前輩,主管,建築師等,這是一個非常高級的問題。
預期答案:
MVC,MVVM,MVP和類似的設計模式很棒,並且在彼此上都是一個改進,但是對於10人或20人以上的團隊,它們仍然無法很好地擴展。如果您超出了團隊規模,則需要使用更通用且可擴展的體繫結構方法。有一種概念性方法,稱為“乾凈架構”。
清潔體繫結構是用於規模化的概念性應用程式體繫結構,可以簡單地描述為“洋蔥分層體繫結構”。主要思想是使依賴關係向內指向您的域邏輯和域模型,並使其他所有內容都是可插拔的和可選的(存儲數據,呈現ui,接收或發送網路請求的方式等)。對於擁有100多個開發人員的大型團隊而言,此架構的擴展性特別好。
iOS上有兩種“清潔體繫結構”的具體實現:VIPER和RIB。
毒蛇代表View,Interactor,Presenter,Entity和Router。這些是該體繫結構的基石。在這種架構中,一切都始於路由器,並以視圖結束。每個VIPER堆棧(意味著一組View,Interactor,Presenter,Entity和Router)都是應用程式的一個屏幕或一個邏輯UI部分。要導航和使用VIPER堆棧,請實例化其路由器,然後要求其創建其視圖控制器。路由器創建視圖控制器,格式化視圖數據並接收視圖用戶輸入的相應演示者,保存業務邏輯並與演示者進行通信的交互器,以及使交互器工作所需的實體。然後,VC擁有演示者,演示者擁有交互者,而交互者擁有實體和路由器。結果視圖控制器將在視圖層次結構中使用,並根據需要插入,推送或顯示。由於您的應用程式的每個部分現在都是VIPER堆棧,因此該體繫結構可以為團隊規模提供強大的邏輯封裝和可伸縮性。
RIB代表路由器,交互器,構建器。RIB是Clean Architecture的另一種實現,它是VIPER的改進。在RIBs體繫結構中,主要構建塊是RIB,一組一個路由器,一個交互器和一個帶有可選視圖和演示者的構建器。沒有視圖的RIB稱為無頭RIB。就像在VIPER架構中一樣,您使用路由器從一個RIB路由到另一個RIB,這將應用程式的整個運行時結構化為帶有父RIB和子RIB的樹形結構。由於視圖是可選的,因此與VIPER不同,您的應用程式樹結構可能會或可能不會模仿您的視圖層次結構。
Builder負責為交互器,路由器以及視圖和演示者組裝或初始化它們而獲取或創建依賴關係。
路由器負責導航到特定的子RIB。
Interactor負責所有業務邏輯並使用路由器啟動路由。
演示者和視圖通常組合在視圖控制器中,其中演示者負責按摩和格式化要在視圖中顯示的數據。
View負責在屏幕上顯示數據並收集用戶輸入。
結論
本文中涉及的問題涉及iOS開發人員應瞭解的廣泛主題。這絕不是一個全面的清單。