iOS之2016面試題一 -开发者知识库

iOS之2016面試題一 -开发者知识库,第1张

序言

招聘高峰期來了,大家都非常積極地准備着跳槽,那么去一家公司面試就會有一堆新鮮的問題,可能不會,也可能會,但是了解不夠深。本篇文章為群里的小伙伴們去寶庫公司的筆試題,由筆者整理並提供筆者個人參考答案。注意,僅供參考,不代表絕對正確。

參考答案不唯一,大家可以根據自己的理解回答,沒有必要跟筆者的一樣。參考筆者的答案,也許給你帶來靈感!

1、對數組中的元素去重復

例如:

 
123  NSArray *array = @[@"12-11", @"12-11", @"12-11", @"12-12", @"12-13", @"12-14"]; 

參考答案:

  • 第一種方法:開辟新的內存空間,然后判斷是否存在,若不存在則添加到數組中,得到最終結果的順序不發生變化。效率分析:時間復雜度為O ( n2 ):

 

 
123456789101112  NSMutableArray *resultArray = [[NSMutableArray alloc] initWithCapacity:array.count];// 外層一個循環for (NSString *item in array) {   // 調用-containsObject:本質也是要循環去判斷,因此本質上是雙層遍歷   // 時間復雜度為O ( n^2 )而不是O (n)    if (![resultArray containsObject:item]) {      [resultArray addObject:item];    }}NSLog(@"resultArray: %@", resultArray); 

補充:原來集合操作可以通過valueForKeyPath來實現的,去重可以一行代碼實現:

 
1234  array = [array valueForKeyPath:@"@distinctUnionOfObjects.self"];NSLog(@"%@", array); 

但是返回的結果是無序的,與原來的順序不同。大家可以閱讀:Collection Operators

  • 第二種方法:利用NSDictionary去重,字典在設置key-value時,若已存在則更新值,若不存在則插入值,然后獲取allValues。若不要求有序,則可以采用此種方法。若要求有序,還得進行排序。效率分析:只需要一個循環就可以完成放入字典,若不要求有序,時間復雜度為O(n)。若要求排序,則效率與排序算法有關:

 

 
12345678  NSMutableDictionary *resultDict = [[NSMutableDictionary alloc] initWithCapacity:array.count];for (NSString *item in array) {    [resultDict setObject:item forKey:item];}NSArray *resultArray = resultDict.allValues;NSLog(@"%@", resultArray); 

如果需要按照原來的升序排序,可以這樣:

 
12345678  resultArray = [resultArray sortedArrayUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {  NSString *item1 = obj1;  NSString *item2 = obj2;  return [item1 compare:item2 options:NSLiteralSearch];}];NSLog(@"%@", resultArray); 

 

  • 第三種方法:利用集合NSSet的特性(確定性、無序性、互異性),放入集合就自動去重了。但是它與字典擁有同樣的無序性,所得結果順序不再與原來一樣。如果不要求有序,使用此方法與字典的效率應該是差不多的。效率分析:時間復雜度為O (n):

 

 
12345  NSSet *set = [NSSet setWithArray:array];NSArray *resultArray = [set allObjects];NSLog(@"%@", resultArray); 

如果要求有序,那就得排序,比如這里要升序排序:

 
12345678  resultArray = [resultArray sortedArrayUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {  NSString *item1 = obj1;  NSString *item2 = obj2;  return [item1 compare:item2 options:NSLiteralSearch];}];NSLog(@"%@", resultArray); 

補充:

一直沒有使用過有序集合,網友們反饋到可以直接使用有序集合,感謝大家:

 
1234  NSOrderedSet *set = [NSOrderedSet orderedSetWithArray:array];NSLog(@"%@", set.array); 

以上三種方法是筆者所能想到的辦法。如果大家有更好的辦法,歡迎在評論中指出。

2、說說以下元素的特性和作用

 

 
123  NSArray、NSSet、NSDictionary與NSMutableArray、NSMutableSet、NSMutableDictionary 

參考答案:

特性:

  • NSArray表示不可變數組,是有序元素集,只能存儲對象類型,可通過索引直接訪問元素,而且元素類型可以不一樣,但是不能進行增、刪、改操作;NSMutableArray是可變數組,能進行增、刪、改操作。通過索引查詢值很快,但是插入、刪除等效率很低。
  • NSSet表示不可變集合,具有確定性、互異性、無序性的特點,只能訪問而不能修改集合;NSMutableSet表示可變集合,可以對集合進行增、刪、改操作。集合通過值查詢很快,插入、刪除操作極快。
  • NSDictionary表示不可變字典,具有無序性的特點,每個key對應的值是唯一的,可通過key直接獲取值;NSMutableDictionary表示可變字典,能對字典進行增、刪、改操作。通過key查詢值、插入、刪除值都很快。

作用:

  • 數組用於處理一組有序的數據集,比如常用的列表的dataSource要求有序,可通過索引直接訪問,效率高。
  • 集合要求具有確定性、互異性、無序性,在iOS開發中是比較少使用到的,筆者也不清楚如何說明其作用
  • 字典是鍵值對數據集,操作字典效率極高,時間復雜度為常量,但是值是無序的。在ios中,常見的JSON轉字典,字典轉模型就是其中一種應用。

3、簡單描述一下XIB與Storyboards,說一下他們的優缺點。

參考答案:

筆者傾向於純代碼開發,所以所提供的參考答案可能具有一定的個人感情,不過還是給大家說說筆者的想法。

優點:

  • XIB:在編譯前就提供了可視化界面,可以直接拖控件,也可以直接給控件添加約束,更直觀一些,而且類文件中就少了創建控件的代碼,確實簡化不少,通常每個XIB對應一個類。
  • Storyboard:在編譯前提供了可視化界面,可拖控件,可加約束,在開發時比較直觀,而且一個storyboard可以有很多的界面,每個界面對應一個類文件,通過storybard,可以直觀地看出整個App的結構。

缺點:

  • XIB:需求變動時,需要修改XIB很大,有時候甚至需要重新添加約束,導致開發周期變長。XIB載入相比純代碼自然要慢一些。對於比較復雜邏輯控制不同狀態下顯示不同內容時,使用XIB是比較困難的。當多人團隊或者多團隊開發時,如果XIB文件被發動,極易導致沖突,而且解決沖突相對要困難很多。
  • Storyboard:需求變動時,需要修改storyboard上對應的界面的約束,與XIB一樣可能要重新添加約束,或者添加約束會造成大量的沖突,尤其是多團隊開發。對於復雜邏輯控制不同顯示內容時,比較困難。當多人團隊或者多團隊開發時,大家會同時修改一個storyboard,導致大量沖突,解決起來相當困難。

4、請把字符串2015-04-10格式化日期轉為NSDate類型

參考答案:

 
123456789  NSString *timeStr = @"2015-04-10";NSDateFormatter *formatter = [[NSDateFormatter alloc] init];formatter.dateFormat = @"yyyy-MM-dd";formatter.timeZone = [NSTimeZone defaultTimeZone];NSDate *date = [formatter dateFromString:timeStr];// 2015-04-09 16:00:00 0000NSLog(@"%@", date); 

 

5、在App中混合HTML5開發App如何實現的。在App中使用HTML5的優缺點是什么?

參考答案:

在iOS中,通常是通常UIWebView來實現,當然在iOS8以后可以使用WKWebView來實現.有以下幾種實現方法:

  • 通過實現UIWebView的代理方法來攔截,判斷scheme是否是約定好的,然后iOS調用本地相關API來實現:

 

 
123  - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType; 

 

優缺點:

  • iOS加入H5響應比原生要慢很多,體驗不太好,這是缺點。
  • iOS加入H5可以實現嵌入別的功能入口,可隨時更改,不用更新版本就可以上線,這是最大的優點

6、請描述一下同步和異步,說說它們之間的區別。

參考答案:

首先,我們要明確一點,同步和異步都是在線程中使用的。在iOS開發中,比如網絡請求數據時,若使用同步請求,則只有請求成功或者請求失敗得到響應返回后,才能繼續往下走,也就是才能訪問其它資源(會阻塞了線程)。網絡請求數據異步請求時,不會阻塞線程,在調用請求后,可以繼續往下執行,而不用等請求有結果才能繼續。

區別:

  • 線程同步:是多個線程訪問同一資源時,只有當前正在訪問的線程訪問結束之后,其他線程才能開始訪問(被阻塞)。
  • 線程異步:是多個線程在訪問競爭資源時,可以在空閑等待時去訪問其它資源(不被阻塞)。

7、請簡單描述一下隊列和多線程的使用原理。

 

參考答案:

在iOS中隊列分為以下幾種:

  • 串行隊列:隊列中的任務只會順序執行

 

 
123  dispatch_queue_t q = dispatch_queue_create("...", DISPATCH_QUEUE_SERIAL); 

 

  • 並行隊列: 隊列中的任務通常會並發執行

 

 
123  dispatch_queue_t q = dispatch_queue_create("......", DISPATCH_QUEUE_CONCURRENT); 

 

  • 全局隊列:是系統的,直接拿過來(GET)用就可以;與並行隊列類似

 

 
123  dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 

 

  • 主隊列:每一個應用程序對應唯一一個主隊列,直接GET即可;在多線程開發中,使用主隊列更新UI

 

 
123  dispatch_queue_t q = dispatch_get_main_queue(); 

上面這四種是針對GCD來講的,串行隊列中的任務只能一個個地執行,在前一個沒有執行完畢之前,下一個只能等待。並行隊列可以並發地執行任務,因此多個任務之間執行的順序不能確定,當添加一個新的任務時,交由GCD來判斷是否要創建新的新的線程。

大家可以閱讀圖片多線程,也許更明了:

8、描述一下iOS的內存管理,在開發中對於內存的使用和優化包含哪些方面。我們在開發中應該注意哪些問題。

參考答案:

內存管理准則:誰強引用過,誰就在不再使用時使引用計數減一。

對於內存的使用和優化常見的有以下方面:

  • 重用問題:如UITableViewCells、UICollectionViewCells、UITableViewHeaderFooterViews設置正確的reuseIdentifier,充分重用。
  • 盡量把views設置為不透明:當opque為NO的時候,圖層的半透明取決於圖片和其本身合成的圖層為結果,可提高性能。
  • 不要使用太復雜的XIB/Storyboard:載入時就會將XIB/storyboard需要的所有資源,包括圖片全部載入內存,即使未來很久才會使用。那些相比純代碼寫的延遲加載,性能及內存就差了很多。
  • 選擇正確的數據結構:學會選擇對業務場景最合適的數組結構是寫出高效代碼的基礎。比如,數組: 有序的一組值。使用索引來查詢很快,使用值查詢很慢,插入/刪除很慢。字典: 存儲鍵值對,用鍵來查找比較快。集合: 無序的一組值,用值來查找很快,插入/刪除很快。
  • gzip/zip壓縮:當從服務端下載相關附件時,可以通過gzip/zip壓縮后再下載,使得內存更小,下載速度也更快。
  • 延遲加載:對於不應該使用的數據,使用延遲加載方式。對於不需要馬上顯示的視圖,使用延遲加載方式。比如,網絡請求失敗時顯示的提示界面,可能一直都不會使用到,因此應該使用延遲加載。
  • 數據緩存:對於cell的行高要緩存起來,使得reload數據時,效率也極高。而對於那些網絡數據,不需要每次都請求的,應該緩存起來,可以寫入數據庫,也可以通過plist文件存儲。
  • 處理內存警告:一般在基類統一處理內存警告,將相關不用資源立即釋放掉
  • 重用大開銷對象:一些objects的初始化很慢,比如NSDateFormatter和NSCalendar,但又不可避免地需要使用它們。通常是作為屬性存儲起來,防止反復創建。
  • 避免反復處理數據:許多應用需要從服務器加載功能所需的常為JSON或者XML格式的數據。在服務器端和客戶端使用相同的數據結構很重要。
  • 使用Autorelease Pool:在某些循環創建臨時變量處理數據時,自動釋放池以保證能及時釋放內存。
  • 正確選擇圖片加載方式:詳情閱讀細讀UIImage加載方式

9、plist文件是用來做什么的。一般用它來處理一些什么方面的問題。

參考答案:

plist是iOS系統中特有的文件格式。我們常用的NSUserDefaults偏好設置實質上就是plist文件操作。plist文件是用來持久化存儲數據的。

我們通常使用它來存儲偏好設置,以及那些少量的、數組結構比較復雜的不適合存儲數據庫的數據。比如,我們要存儲全國城市名稱和id,那么我們要優先選擇plist直接持久化存儲,因為更簡單。

10、iOS中緩存一定量的數據以便下次可以快速執行,那么數據會存儲在什么地方,有多少種存儲方式?

參考答案:

  • 偏好設置(NSUserDefaults)
  • plist文件存儲
  • 歸檔
  • SQLite3
  • Core Data

詳情請閱讀:iOS常用的持久化存儲方式

11、請簡單寫出增、刪、改、查的SQL語句。

參考答案:

數據庫的簡單操作,還是會的,大學可沒白學。

增:

 
123  insert into tb_blogs(name, url) values('標哥的技術博客','http://www.henishuo.com'); 

刪:

 
123  delete from tb_blogs where blogid = 1; 

改:

 
123  update tb_blogs set url = 'www.henishuo.com' where blogid = 1; 

查:

 
123  select name, url from tb_blogs where blogid = 1; 

12、在提交蘋果審核時,遇到哪些問題被拒絕,對於被拒絕的問題是如何處理的。

參考答案:

對於筆者而言,所提交過的app還沒有被拒絕過。不過在筆者所維護的幾個群里經常有朋友們問到相關被拒絕的解決辦法。幸好還懂一點點英文,還能幫助他們翻譯翻譯蘋果反饋的被拒原因及所擔的建議。

這里只列出幾種最常見的被拒原因:

  • 最常見到的就是app中有虛擬物品交易,但是不是走內購導致被拒。
  • 音頻類App或者使用到音頻相關的app,因為版權問題而被拒
  • App出現必閃退而被拒

最后

在這個夜晚,所有答案都是筆者花了大量的時間來整理出來的,且看且珍惜吧!

最佳答案:

本文经用户投稿或网站收集转载,如有侵权请联系本站。

发表评论

0条回复