在這個公司待了三年,雖然我有足夠的危機感,但是並沒有讓我提升多少,所以我迫切的想換個工作環境,於是去了幾個公司面試,有個自稱是使用者在三億左右的公司,且不說使用者量是真是假。問了很多混合開發的東西,弱項,可想而知有多狼狽了吧。綜合幾家公司的面試,寫了這篇文集,有問題可以留言。謝謝。
- 開發框架的選擇:原生開發?混合開發?
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 解決。
- jsbridge 橋接h5
基本就是依賴於 WKWebView,實現其代理,使用js 與OC的互動就能完成
5.音視訊開發這塊,音視訊播放的原理是什麼?
視音訊技術主要是:音訊技術,主要包括音視訊的壓縮編碼技術,如果考慮到網路傳輸的話還要考慮到流媒體協議技術。
播放網上的視訊檔案,需要經過以下幾個步驟:解協議,解封裝,解碼音視訊,音視訊同步;如果是解碼本地檔案則不需要解協議。
解協議:因為播放視訊的時候需要遵循各種流媒體協議技術(http,RTMP,MMS等),需要解析為標準的相應的封裝格式資料。可以簡單的理解為不同廠家對應不同的音視訊格式。
解封裝:就是將輸入的封裝格式(MP3,MP4,FLv等)的資料,分離為音訊流壓縮編碼資料或者視訊流壓縮編碼資料。
解碼:可以簡單理解為就是對資料視訊進行壓縮/解壓縮的過程。常見的有H.26X(H.264,H.265等),MPEG等。
音視訊同步:就是將解碼好的是音視訊通過音效卡/顯示卡 播放出來。
- 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實現。
-
成員變數與例項變數的區別是什麼?屬性是什麼?
-
可變陣列你經常使用什麼修飾,能否使用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 程式碼代替混編。
- GCD原理
大家都知道蘋果的大部分東西都是不開源的,網上有大牛寫了個GCD的原始碼,供參考,奉獻上鍊接如下:github.com/apple/swift…
另外GNUstep 是GNU計劃之一,他們將Cocoa 的OC庫重新寫了一遍,雖然不是蘋果正兒八經的原始碼但是可以作為參考,以下連結是:www.gnustep.org/resources/d…
// 程式碼片段摘自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表中刪除,最後清理物件的記錄。
本文源自第三方轉載。