1. 程式人生 > >IOS 面試總結(2)

IOS 面試總結(2)

        在這個公司待了三年,雖然我有足夠的危機感,但是並沒有讓我提升多少,所以我迫切的想換個工作環境,於是去了幾個公司面試,有個自稱是使用者在三億左右的公司,且不說使用者量是真是假。問了很多混合開發的東西,弱項,可想而知有多狼狽了吧。綜合幾家公司的面試,寫了這篇文集,有問題可以留言。謝謝。

1. 開發框架的選擇:原生開發?混合開發?

1.1原生開發:在應用的效能上以及使用者體驗上是最好的,但是原生的可移植性較差,所以相對來說開發成本會稍微高點。

1.2H5與原生混合開發,主要的就用利用WKWebView,實現原生與H5的混合,主要利用的就是JS做一些互動(JSBridge的橋接)。如果頁面需要變化量很快 或者是活動啥的,建議混合開發,可以節約成本(IOS+Android 共用一個h5介面),部署更新,升級都比較快。但是使用者體驗及效能上就稍微差些,而且有的也比較消耗資源。但是企業級的app 因為需要使用基礎元件,如推送通知,管理,安全,分析資料同步和連線到企業的資料庫,訂閱等等,不同的場景下要視情況而定。

1.3其他的可以學習下RN,Flutter,我也打算學習fluter

2.如何保證app的穩定性?

在網上找了個圖,大家可以參考下

2.1 app穩定性首先考慮程式碼的邏輯,設計模式的選擇等等。

記憶體問題:體現在記憶體洩露,記憶體警告方面。開發中學會使用instrument 檢測記憶體洩露,cpu使用率(Instruments的time profile來定位並解決問題)以及啟動時間(可以參考我的關於啟動優化的文章)等指標,迴圈引用等問題。迴圈引用容易引起記憶體洩露,記憶體激增,進而導致Crash。常見的有Delegate,Block,NStimer

2.2 單元測試

可藉助Xcode自帶的單元測試,也可使用第三方框架OCMock

2.3.Crash 的監控

3.開發中如何解決耦合性?

3.1建議看下MVVM+RAC開發

3.2目前最常見的有router 這個解決方案。viewmodel 吧展示層的資料 view /model 的業務處理隔離開。中間層的業務邏輯耦合性就很高,可以通過router 解決。

4. jsbridge 橋接h5

基本就是依賴於 WKWebView,實現其代理,使用js 與OC的互動就能完成

5.音視訊開發這塊,音視訊播放的原理是什麼?

視音訊技術主要是:音訊技術,主要包括音視訊的壓縮編碼技術,如果考慮到網路傳輸的話還要考慮到流媒體協議技術。

播放網上的視訊檔案,需要經過以下幾個步驟:解協議,解封裝,解碼音視訊,音視訊同步;如果是解碼本地檔案則不需要解協議。

解協議:因為播放視訊的時候需要遵循各種流媒體協議技術(http,RTMP,MMS等),需要解析為標準的相應的封裝格式資料。可以簡單的理解為不同廠家對應不同的音視訊格式。

解封裝:就是將輸入的封裝格式(MP3,MP4,FLv等)的資料,分離為音訊流壓縮編碼資料或者視訊流壓縮編碼資料。

解碼:可以簡單理解為就是對資料視訊進行壓縮/解壓縮的過程。常見的有H.26X(H.264,H.265等),MPEG等。

音視訊同步:就是將解碼好的是音視訊通過音效卡/顯示卡 播放出來。

6. weak 與assign 的區別?代理是什麼修飾?

6.1.在ARC,weak 只能修飾物件,如果修飾基礎資料型別,編譯器會報錯。在MRC時還沒有weak 這個修飾符

6.2 assign 可以修飾物件也可以修飾基本資料型別,assign 修飾物件時會導致導致野指標問題,因為被assign修飾的物件在物件釋放後,指標不會被置為nil,所以在次向物件發訊息就會崩潰。但是被weak 修飾的物件則不會出現野指標的問題,當weak修飾的物件被系統回收時指標會被置為nil。再次向其發訊息,不會崩潰。

6.3 通過以上我們知道代理為什麼經常使用weak修飾,一是為了解決迴圈引用問題,二是為了防止野指標的出現。

7.分類能否新增屬性?能否新增成員變數?為什麼?

7.1在{ } 內直接宣告 成員變數,編譯器會直接報錯。所以分類不能直接新增成員變數。

7.2分類是可以宣告屬性的,可以通過clang 編譯器檢視他的底層結構

struct _category_t {

const char *name;

struct _class_t *cls;

const struct _method_list_t *instance_methods;

const struct _method_list_t *class_methods;

const struct _protocol_list_t *protocols;

const struct _prop_list_t *properties;

};

但是他只能生成set/get的宣告,不能生成 set/get 方法的實現 ,所以在外部引用的時候,執行會報錯。經典錯誤unrecognized selector sent to instance

可以使用runtime的動態新增關聯物件 objc_setAssociatedObject(obj, &MyKey, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC) objc_getAssociatedObject實現。

8. 成員變數與例項變數的區別是什麼?屬性是什麼?

9. 可變陣列你經常使用什麼修飾,能否使用copy?

可變陣列使用strong修飾,不可變陣列使用copy修飾

可變陣列如果使用copy修飾的話,然後使其變成不可變陣列,如果對陣列進入增刪改操作,然後發現carsh

這裡涉及到 深/淺拷貝,深拷貝copy 拷貝其記憶體地址,淺拷貝strong 拷貝物件。

10.block 使用什麼關鍵字修飾,為什麼?block 想再其內部修改外部變數,需要怎麼做,原因是什麼?

10.1在MRC 下建議使用copy 修飾block,在ARC下建議使用copy/strong 修飾block

在MRC下block 的記憶體地址是在棧區,棧區的物件隨時都會被系統回收,所以需要使用copy把它複製到堆區。

在ARC下,使用copy/strong 修飾block時,系統會對block 自動進行一個拷貝到堆區。

10.2 在ARC 下__block修飾外部變數,會將其包裝成一個forwarding 指標指向自己。通過forwarding 修改內部變數的值。

11,OC Swift 混合開發,包的體積大嗎?如何瘦身?

11.1 OC與Swift 混編會讓你的ipa包體積增大,比如OC專案用到Swift的第三方,pod匯入到工程時,會把Swift的整個庫包也匯入進來,導致專案至少會增加20兆左右。好在上傳到appstore ,商城會進行一定的瘦身。

11.2 如何瘦身? 使用純OC 程式碼代替混編。

12.  GCD原理

 大家都知道蘋果的大部分東西都是不開源的,網上有大牛寫了個GCD的原始碼,供參考,奉獻上鍊接如下:https://github.com/apple/swift-corelibs-libdispatch 

另外GNUstep 是GNU計劃之一,他們將Cocoa 的OC庫重新寫了一遍,雖然不是蘋果正兒八經的原始碼但是可以作為參考,以下連結是:http://www.gnustep.org/resources/downloads.php

// 程式碼片段摘自libdispatch

//typedef void (^dispatch_block_t)(void);
void
dispatch_async(dispatch_queue_t dq, dispatch_block_t work)
{
/*_dispatch_continuation_alloc 的實現
	 static inline dispatch_continuation_t
	 _dispatch_continuation_alloc(void)
	 {
	 dispatch_continuation_t dc =
	 _dispatch_continuation_alloc_cacheonly();
	 if (unlikely(!dc)) {
	 return _dispatch_continuation_alloc_from_heap();
	 }
	 return dc;
	 }
	 從(執行緒的私有儲存,執行緒都是有自己的私有儲存的,這些私有儲存不會被其他執行緒所使用)中提取出一個 dispatch_continuation_t 結構
	 */

	dispatch_continuation_t dc = _dispatch_continuation_alloc();
	uintptr_t dc_flags = DISPATCH_OBJ_CONSUME_BIT;

	_dispatch_continuation_init(dc, dq, work, 0, 0, dc_flags);
	_dispatch_continuation_async(dq, dc);
}

以上我只寫了GCD的dispatch_async 非同步執行的入口,大家可以下載看看原始碼

總結:dispatch_async用連結串列儲存所有提交的 block,然後在底層執行緒池(p_thread 建立)中,依次取出 block 並執行;

 dispatch_sync同步方法的實現相對來說更簡單,只需要將任務壓入響應的佇列,並用訊號量做等待;

13.http 與 https的區別?sotocket 通訊的實現原理以及其返回response的資料格式?

http:網路上使用最廣泛的一種協議,是一個客戶端與伺服器端請求和應答的標準。用於向www伺服器傳輸超文字到本地瀏覽器的一個傳輸協議。以明文傳輸,不安全。

https:簡單的來說是http的安全版。在http的基礎上嵌入了SSL協議。SSL是依靠證書來驗證伺服器的身份,併為瀏覽器與伺服器之間的通訊進行加密。

加密解密等等三次握手自行腦補吧

socket: Socket是應用層與TCP/IP協議族通訊的中間軟體抽象層,它是一組介面,可以理解為是程式設計介面,是對tcp/ip的封裝。網路上的兩個程式之間想要實現資料的雙向傳輸交換(網路上的兩個程式通過一個雙向的通訊連線實現資料的交換,這個連線的一端稱為一個socket)。

socket:開->讀,寫->關閉。socket即是一種特殊的檔案。 網路層的“ip地址”可以唯一標識網路中的主機,而傳輸層的“協議+埠”可以唯一標識主機中的應用程式(程序)。這樣利用三元組(ip地址,協議,埠)就可以標識網路的程序了,網路中的程序通訊就可以利用這個標誌與其它程序進行互動。

14.weak的實現原理?

weak 本身是個hash 表。key 是所指物件的地址,Value是weak 指標的地址陣列(一個物件可能被多個弱指標指向)。runtime維護了一個weak表,用於儲存一個物件的所有的weak指標。

1、初始化時:runtime會呼叫objc_initWeak函式,初始化一個新的weak指標指向物件的地址。

2、新增引用時:objc_initWeak函式會呼叫 objc_storeWeak() 函式, objc_storeWeak() 的作用是更新指標指向,建立對應的弱引用表。

3、釋放時,呼叫clearDeallocating函式 首先根據物件地址獲取所有weak指標地址的陣列,然後遍歷這個陣列把其中的資料設為nil,最後把這個entry從weak表中刪除,最後清理物件的記錄。