靜網PWA視頻評論

iOS工程師面試筆試題

2023年09月25日

- txt下載

前言:以下iOS工程師面試筆試題,部分來源於網絡,筆者在此處收集起來,既是要鞏固自我,也希望能夠幫助到同樣需要的人!參考答案均為筆者所寫,其有疑問或者出錯之處,請在評論中提出,謝謝!不喜勿噴!


1. #import和#include的區別?


參考答案:


#import是Objective-C導入頭文件的語法,可保證不會重複導入。
#include是C/C++導入頭文件的語法,如果是Objective-C與C/C++混編碼,對於C/C++類型的文件,還是使用#include來引入,這種寫法需要添加防重複導入的語法。


2. @class的作用


參考答案:


@class一般用於頭文件中通過前向聲明,就可以聲明了,但是在.m文件中還是需要使用#import進來的。它的作用只是前向聲明。


3. 用NSLog函數輸出一個浮點類型,結果四捨五入,並保留一位小數


參考答案:


float money = 1.011;
NSLog(@"%.1f", money);


使用%f來格式化,其中要保留一位小數,因此再用%.1f就是保留一位。


4.property屬性的修飾符有什麼樣的作用


參考答案:


property是屬性訪問聲明,擴號內支持以下幾個屬性:
getter=getName、setter=setName:設置setter與getter的方法名
readwrite、readonly:設置可供訪問級別
assign:方法直接賦值,不進行任何retain操作,為了解決原類型與環循引用問題
retain:其setter方法對參數進行release舊值再retain新值,所有實現都是這個順序
copy:其setter方法進行copy操作,與retain處理流程一樣,先對舊值release,再copy出新的對象,retainCount為1。這是為了減少對上下文的依賴而引入的機制。
nonatomic:非原子性訪問,不加同步, 多線程並發訪問會提高性能。注意,如果不加此屬性,則默認是兩個訪問方法都為原子型事務訪問。


5. self.name=@object和name=@object有什麼不同?


參考答案:


self.name =」object」:會調用對象的setName()方法;name = 「object」:會直接把"object"字符串賦值給當前對象的name屬性。


6. viewDidLoad、loadView和viewDidUnload何時調用


參考答案:


viewDidLoad在view加載完成時調用,loadView在controller的view為nil時調用。對於viewDidUnload現在已經不能直接調用了。


7. objective-c中的可變與不可變詞典


參考答案:


可變字典就是可以增、刪、改操作的字典,對應於NSMutableDictionary類型。
不可變字典就是不能執行增、刪、改操作的字典,對應於NSDictionary類型。


8.Objective-C的內存管理


參考答案:


現在內存管理幾乎都採用ARC,也就是Automatic Reference Counting,意思是自動引用計數。由編譯器在編譯時自動為添加retain、release等代碼。


如果問的MRC,也就是Manual Reference Counting,意思是手動內存管理。


黃金法則:誰使對象的引用計數+1,不再使用該對象時,誰就應該使該對象的引用計數-1。


9. 自動生成getter/setter方法


參考答案:


對於以前的代碼,那時還沒有property,使用這樣的方法來創建:


- (void)setName:(NSString *)aName;
- (NSString *)name;


在後面有了property,直接使用@property (nonatomic, copy) NSString *name這樣的方法來聲明,編譯器會自動生成getter/setter方法並生成一個_name成員變量。


10. 什麼是MVC


參考答案:


我相信大部分人在被問到這個問題時,都會回答M就是Model,V就是View,C就是Controller。這都是停留在概念上的回答,明顯沒有什麼工作經驗。對於一個對框架和架構有一定的思想的人,回答時會從項目的耦合度、團隊開發如何減少衝突、如何降低團隊與團隊之間的溝通成本、如何將M、V、C之間按照既定的標準建立溝通的橋樑。


Model用於處理數據,通常來說,Model中會包含多個欄位,用於存儲數據。但是,Model還會有一部分邏輯,比如說:


@interface TestModel: HYBBaseModel
// 這個是接口返回的欄位,1表示XXX,2表示YYY,3表示ZZZ
@property (nonatomic, assign) NSUInteger type;
// 這個不是接口返回的欄位,但是由於`type`欄位是一個數值,不是`view`需要顯示的數據
// 所以我們最好將邏輯統一放到這裡來,外部只管獲取最終顯示需要的值即可。即使哪天接口
// 返回的欄位變化或者增加什麼新的值,只需要處理這個模型內部就好了。
@property (nonatomic, copy, readonly) NSString relationship;
@end


對於View,不應該包含邏輯,應該根據模型直接獲取數據。


對於Controller,大部分交互邏輯都集中到了這裡,所有View需要的數據,都是通過Controller提取Model然後交給view去顯示數據。


11. 重寫getter/setter方法


假設聲明屬性:


@property (nonatomic, copy) NSString *blogName;
重寫這個屬性的getter/setter方法:


參考答案:


這裡一旦連getter方法也重寫,編譯器不會給我們自動生成成員變量_blogName,因此我們需要在類的聲明中添加一個成員變量_blogName:


@interface Demo () {
NSString *_blogName;
}
@end


在自動內存管理下(ARC):


- (void)setBlogName:(NSString *)aName {
if (_blogName != aName) {
_blogName = nil;
_blogName = [aName copy];
}
}
- (NSString *)blogName {
return _blogName;
}
對於手動內存管理(MRC):
- (void)setBlogName:(NSString *)aName {
if (_blogName != aName) {
[_blogName release];
_blogName = nil;
_blogName = [aName copy];
}
}
- (NSString *)blogName {
return _blogName;
}




12. obj在編譯時和運行時分別時什麼類型的對象


如下面的代碼,obj在編譯時和運行時分別時什麼類型的對象:
NSString *obj = [[NSData alloc] init];


參考答案:


在編譯時,我們所聲明的obj是NSString *類型,因此是NSString類型對象。在運行時,由於指針obj所指向的是NSData類型對象的內存,因此實際上是NSData類型的對象。在編譯時,這一行代碼會轉換成類似這樣:


NSString *obj = ((id (*)(id, SEL))objc_msgSend)([NSData class], @selector(alloc));
obj = ((id (*)(id, SEL))objc_msgSend)((id)obj, @selector(init));


由於在編譯時,轉換成id,因此可以用NSString *指向NSData對象,而id是具備運行時特性的,因此在連結時,通過id的isa指針可以找到其所屬的類,因此最終類型還是通過isa確定其所屬類型。


13. id聲明的對象有什麼特性?


id類型可以指向任何類型的對象。


參考答案:
我們先看看其定義:


/// Represents an instance of a class.
struct objc_object {
Class isa OBJC_ISA_AVAILABILITY;
};
/// A pointer to an instance of a class.
typedef struct objc_object *id;


可其定義可知id類型是一個指向objc_object結構體類型的指針,這個結構體只有一個指向對象無類的指針isa,因此id可以指向任何類型的對象,故其具備運行時特性。


14. iOS設備性能測試


在實際開發中,我們經常需要對應用瘦身,因此對性能的檢測是很重要的。


參考答案:
使用Profile-> Instruments ->Time Profiler可以檢測性能。


15. Objective-C中有私有方法、私有變量麼?


我記得曾經我就被這麼問過,不知道大家有沒有遇到過。


參考答案:


在類的.m實現文件內聲明,就可以作為私有方法、私有變量。但是,並不是絕對的私有,如果外部知道有這麼個方法,一樣可以調用,而且不會報錯。就像蘋果公司沒有公開出來的API,只要我們通過其它方式了解到api就可以調用。於是蘋果審核時經常由於使用了私有api而打回來了。


16. 簡述tableview的重用機制


曾經筆者面試時,也被問到這個問題。


參考答案:
[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]


這個方法就是重用機制的核心了。比如,有一個介面可顯示10個cell,那麼創建10次cell,並給cell指定同樣的重用標識(當然,可以為不同顯示類型的cell指定不同的標識)並且10個cell將全部都加入到visiableCells數組,reusableTableCells為空.


滾動tableView,當有一個cell完全移出螢幕時,這個cell就會被加入到reusableTableCells。而新出現的那個cell將加入到visiableCells,而這個cell就是被重用的。
如果要讓tableview不重用,不設置reuseIdentifier就可以了。


17. nil與NULL的區別


參考答案:


nil和C語言的NULL相同,在objc/objc.h中定義。nil表示Objective-C對象的值為空。在C語言中,指針的空值用NULL表示。在Objective-C中,nil對象調用任何方法表示什麼也不執行,也不會崩潰。


18. Category是什麼,何時使用?


參考答案:


Category就是所謂的擴展。


有時我們需要在一個已經定義好的類中增加一些方法,而不想去重寫該類,這時候使用擴展就很好。比如,當工程已經很大,代碼量比較多,或者類中已經有很多方法,已經有其他代碼調用了該類創建對象並使用該類的方法時,可以使用類別對該類擴充新的方法。


筆者所到公司之處,都會根據公司的UI風格定製一套UI組件,統一全局的風格。本人向來不喜歡用xib/storyboard開發,因為維護成本太高了。我們不能通過繼承的方式定製各種組件吧?所以這個時候使用擴展是最佳時期.


19. 什麼是Delegate?常用場景?


參考答案:


Delegate就是所謂的代理,代理是一種設計模式。在iOS開發中,會使用到大量的代理,而代理設計模式是蘋果中的標準設置模式。


常用場景有反向傳值。比如:蘋果的藍牙,我們進入到下一個介面去打開或者關閉藍牙,當操作之後需要將狀態反饋到前一個介面,並更新顯示。對於這種狀態,使用代理設計模式是很標準的模式。


20. 什麼是單例,如何設計單例?


參考答案:


單例就是全局都只有一個對象存在,而且是在整個App運行過程中都存在。每個App都會有單例,比如UIApplication。而我們在做用戶數據存儲時,通常都會用單例存儲,因為應用在所有操作中,經常要求先登錄。


下面這種寫法是最常用的寫法,這個是線程安全的。


+ (instancetype)shared {
static HYBUserManager *sg_userManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (sg_userManager == nil) {
sg_userManager = [[HYBUserManager alloc] init];
}
});
return sg_userManager;
}


21. 什麼是通知?


參考答案:


在iOS中,通知是非常常用的設計模式。它是多對多的關係。關於通知,由於這一節比較重要,單獨寫成一篇文章,後續發出!

收藏

相關推薦

清純唯美圖片大全

字典網 - 試題庫 - 元問答 - 简体 - 頂部

Copyright © cnj8 All Rights Reserved.