今年9月中下旬因?yàn)閭€(gè)人原因正卧,換了一份工作蠢熄,期間面試了有4跪解,5家,基本都是D輪或者上市公司,也從他們的面試筆試中看到了自己的一些不足叉讥,于是就想寫出來和大家分享一下窘行,如果能幫到正在面試的同學(xué)更好。從面試題中图仓,其實(shí)可以看到一些行業(yè)的發(fā)展罐盔,以及總體人才需求是怎樣的了。
小編給大家推薦一個(gè)iOS技術(shù)交流群:551346706救崔!群內(nèi)提供數(shù)據(jù)結(jié)構(gòu)與算法惶看、底層進(jìn)階、swift六孵、逆向纬黎、底層面試題整合文檔等免費(fèi)資料!
一.筆試題
筆試基本都有一兩道基礎(chǔ)題劫窒,比如說UITableView的重用機(jī)制本今,ARC的基本原理,如何避免retain cycle主巍,談?wù)剬VC的理解冠息,iOS內(nèi)存管理機(jī)制。這些大家應(yīng)該都很清楚了孕索。筆試的內(nèi)容有幾種有選擇題逛艰,問答題,難一點(diǎn)的就是多選題了檬果。我面試了一家就是給了10道多選題瓮孙,多選,少選选脊,錯(cuò)選都不行杭抠,當(dāng)時(shí)做完以后就感覺不是很好,有些題目題干就是一下哪些是對的恳啥,然后ABCD依次給4個(gè)不同的概念偏灿,這種一道題相當(dāng)于考了4個(gè)點(diǎn)《鄣模總之遇到這種“惡心”的多選題也不要太慌翁垂,靜下心來一一甄別應(yīng)該能拿到不錯(cuò)的成績。
接下來我說幾個(gè)我當(dāng)時(shí)答的不怎么好的題目硝桩,我當(dāng)時(shí)記了一下沿猜,和大家分享一下。
1.進(jìn)程和線程的區(qū)別和聯(lián)系
這個(gè)其實(shí)是操作系統(tǒng)的問題碗脊,當(dāng)時(shí)一下子把我問的懵了啼肩,后來仔細(xì)回想了一下,加上自己的理解就答了,下面說說稍微完整的答案祈坠,大家可以準(zhǔn)備準(zhǔn)備害碾,再問這種問題就可以完美作答了。
進(jìn)程是具有一定獨(dú)立功能的程序關(guān)于某個(gè)數(shù)據(jù)集合上的一次運(yùn)行活動(dòng),進(jìn)程是系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位. 線程是進(jìn)程的一個(gè)實(shí)體,是CPU調(diào)度和分派的基本單位,它是比進(jìn)程更小的能獨(dú)立運(yùn)行的基本單位.線程自己基本上不擁有系統(tǒng)資源,只擁有一點(diǎn)在運(yùn)行中必不可少的資源(如程序計(jì)數(shù)器,一組寄存器和棧),但是它可與同屬一個(gè)進(jìn)程的其他的線程共享進(jìn)程所擁有的全部資源.
一個(gè)線程可以創(chuàng)建和撤銷另一個(gè)線程;同一個(gè)進(jìn)程中的多個(gè)線程之間可以并發(fā)執(zhí)行.
2.并行和并發(fā)的區(qū)別
并行是指兩個(gè)或者多個(gè)事件在同一時(shí)刻發(fā)生赦拘;
并發(fā)是指兩個(gè)或多個(gè)事件在同一時(shí)間間隔內(nèi)發(fā)生慌随。
3.談?wù)勀銓lock和delegate的理解
我當(dāng)時(shí)是這么答的,delegate的回調(diào)更多的面向過程躺同,而block則是面向結(jié)果的阁猜。如果你需要得到一條多步進(jìn)程的通知,你應(yīng)該使用delegation蹋艺。而當(dāng)你只是希望得到你請求的信息(或者獲取信息時(shí)的錯(cuò)誤提示)蹦漠,你應(yīng)該使用block。(如果你結(jié)合之前的3個(gè)結(jié)論车海,你會(huì)發(fā)現(xiàn)delegate可以在所有事件中維持state笛园,而多個(gè)獨(dú)立的block卻不能)
4.談?wù)刬nstancetype和id的異同
1、相同點(diǎn)
都可以作為方法的返回類型
2侍芝、不同點(diǎn)
①instancetype可以返回和方法所在類相同類型的對象研铆,id只能返回未知類型的對象;
②instancetype只能作為返回值州叠,不能像id那樣作為參數(shù)
5.category中能不能使用聲明屬性棵红?為什么?如果能咧栗,怎么實(shí)現(xiàn)逆甜?
這種問題一問,我當(dāng)時(shí)就感覺肯定能實(shí)現(xiàn)的致板,但是實(shí)在不知道怎么做交煞,后來回來查了一下,才知道是用到了Runtime的知識(shí)了斟或。貼一下答案
給分類(Category)添加屬性
利用Runtime實(shí)現(xiàn)getter/setter 方法
@interface ClassName (CategoryName)@property (nonatomic, strong) NSString *str;@end//實(shí)現(xiàn)文件#import "ClassName + CategoryName.h"#importstatic void *strKey = &strKey;
@implementation ClassName (CategoryName)
-(void)setStr:(NSString *)str
{
objc_setAssociatedObject(self, & strKey, str, OBJC_ASSOCIATION_COPY);
}
-(NSString *)str
{
return objc_getAssociatedObject(self, &strKey);
}
@end
6.isKindOfClass和isMemberOfClass的區(qū)別
這個(gè)題目簡單素征,但是就是當(dāng)時(shí)緊張的情況下,別答反了萝挤。
isKindOfClass來確定一個(gè)對象是否是一個(gè)類的成員御毅,或者是派生自該類的成員
isMemberOfClass只能確定一個(gè)對象是否是當(dāng)前類的成員
7.block里面的如何防止retain cycle
使用弱引用打斷block里面的retain cycle
MRC中 _block 是不會(huì)引起retain;但在ARC中 _block 則會(huì)引起retain怜珍。ARC中應(yīng)該使用 _weak或__unsafe_unretained弱引用
8.iOS多線程有哪幾種實(shí)現(xiàn)方法端蛆?GCD中有哪些隊(duì)列?分別是并行還是串行酥泛?
iOS中多線程編程工具主要3有:
1.NSThread
2.NSOperation
3.GCD
dispatch queue分為下面3種:而系統(tǒng)默認(rèn)就有一串行隊(duì)列main_queue和并行隊(duì)列g(shù)lobal_queue:
GCD中有三種隊(duì)列類型:
The main queue: 與主線程功能相同今豆。實(shí)際上侈沪,提交至main queue的任務(wù)會(huì)在主線程中執(zhí)行。main queue可以調(diào)用dispatch_get_main_queue()來獲得晚凿。因?yàn)閙ain queue是與主線程相關(guān)的,所以這是一個(gè)串行隊(duì)列瘦馍。
Global queues: 全局隊(duì)列是并發(fā)隊(duì)列歼秽,并由整個(gè)進(jìn)程共享。進(jìn)程中存在三個(gè)全局隊(duì)列:高情组、中(默認(rèn))燥筷、低三個(gè)優(yōu)先級隊(duì)列≡撼纾可以調(diào)用dispatch_get_global_queue函數(shù)傳入優(yōu)先級來訪問隊(duì)列肆氓。
用戶隊(duì)列: 用戶隊(duì)列 (GCD并不這樣稱呼這種隊(duì)列, 但是沒有一個(gè)特定的名字來形容這種隊(duì)列,所以我們稱其為用戶隊(duì)列) 是用函數(shù) dispatch_queue_create
創(chuàng)建的隊(duì)列. 這些隊(duì)列是串行的底瓣。正因?yàn)槿绱诵痪荆鼈兛梢杂脕硗瓿赏綑C(jī)制, 有點(diǎn)像傳統(tǒng)線程中的mutex。
9.談?wù)刲oad和initialize的區(qū)別
這個(gè)題目當(dāng)時(shí)問出來捐凭,真的是一下子就傻了拨扶,平時(shí)雖然用的多,但是真的沒有注意比較過他們倆茁肠,看來平時(shí)學(xué)習(xí)還是多要問問所以然患民!
10.Core Data是數(shù)據(jù)庫么?有哪些重要的類垦梆?
我當(dāng)時(shí)一看問到是不是的問題匹颤,我就留神,感覺應(yīng)該不是常理的托猩,當(dāng)時(shí)仔細(xì)想了想印蓖,Core Data確實(shí)不是一個(gè)數(shù)據(jù)庫,只是把表和OC對象進(jìn)行的映射京腥,當(dāng)時(shí)并不是進(jìn)進(jìn)映射那么簡單另伍,底層還是用的Sqlite3進(jìn)行存儲(chǔ)的,所以Core Data不是數(shù)據(jù)庫绞旅。
有以下6個(gè)重要的類:
(1)NSManagedObjectContext(被管理的數(shù)據(jù)上下文)
操作實(shí)際內(nèi)容(操作持久層)
作用:插入數(shù)據(jù)摆尝,查詢數(shù)據(jù),刪除數(shù)據(jù)
(2)NSManagedObjectModel(被管理的數(shù)據(jù)模型)
數(shù)據(jù)庫所有表格或數(shù)據(jù)結(jié)構(gòu)因悲,包含各實(shí)體的定義信息
作用:添加實(shí)體的屬性堕汞,建立屬性之間的關(guān)系
操作方法:視圖編輯器,或代碼
(3)NSPersistentStoreCoordinator(持久化存儲(chǔ)助理)
相當(dāng)于數(shù)據(jù)庫的連接器
作用:設(shè)置數(shù)據(jù)存儲(chǔ)的名字晃琳,位置讯检,存儲(chǔ)方式琐鲁,和存儲(chǔ)時(shí)機(jī)
(4)NSManagedObject(被管理的數(shù)據(jù)記錄)
相當(dāng)于數(shù)據(jù)庫中的表格記錄
(5)NSFetchRequest(獲取數(shù)據(jù)的請求)
相當(dāng)于查詢語句
(6)NSEntityDescription(實(shí)體結(jié)構(gòu))
相當(dāng)于表格結(jié)構(gòu)
以上是我9月份面試遇到的問到的我一下子沒有答全或者沒答好的問題,大神全部都會(huì)的話請忽略哈人灼。然后還有2個(gè)開放性的問題围段,那基本就是完全考驗(yàn)實(shí)力和自己理解的深度了。一個(gè)是談?wù)勀銓untime的理解投放,另一個(gè)是談?wù)勀銓unloop的理解奈泪,由于我個(gè)人這兩個(gè)理解都不是很深,這里就不貼我的理解了灸芳。大家如果也感覺欠缺的涝桅,就趕緊去網(wǎng)上多看看吧!
11烙样,sprintf,strcpy,memcpy使用上有什么要注意的地方
二.機(jī)試
這個(gè)環(huán)節(jié)基本都是大公司冯遂,或者是復(fù)試的時(shí)候會(huì)出現(xiàn),因?yàn)樯蠙C(jī)打代碼確實(shí)很很快區(qū)分出誰好誰壞谒获,當(dāng)然我也面了一家這樣的公司蛤肌,就給一張白紙,全程都是手寫代碼批狱,這就完全是考驗(yàn)基本功了寻定,因?yàn)闆]了代碼補(bǔ)全,沒有了編譯器告訴你哪里錯(cuò)了精耐,一切都要靠自己的基本功來了狼速。
機(jī)試基本就是靠靠算法題了。當(dāng)然也有算法題在筆試的最后幾道題出現(xiàn)卦停,那就看公司面試怎么安排的向胡。
2年前我也是面試iOS,當(dāng)時(shí)對算法和 數(shù)據(jù)結(jié)構(gòu)要求很低的惊完,很多面試基本都不問這些僵芹,今年面試多了這些問題,也讓我眼前一亮小槐,也感嘆拇派,2年技術(shù)發(fā)展之快,面試如今都會(huì)涉及到算法凿跳,不會(huì)算法和數(shù)據(jù)結(jié)構(gòu)的程序員的道路會(huì)越走越窄件豌。
算法題,我遇到的都不難控嗜,畢竟不是BAT那種公司茧彤,簡單的就是直接要你寫一個(gè)算法出來,稍微高級點(diǎn)的就是有一個(gè)背景疆栏,然后要你解決問題曾掂,其實(shí)就是和ACM題目一樣的惫谤,不過就是沒有那么復(fù)雜。我貼幾段問的最多的算法珠洗,太難的題只能考自己的算法功底了溜歪。
二分查找 θ(logn)
遞歸方法
int binarySearch1(int a[] , int low , int high , int findNum)
{
int mid = ( low + high ) / 2;
if (low > high)
return -1;
else
{
if (a[mid] > findNum)
return binarySearch1(a, low, mid - 1, findNum);
else if (a[mid] < findNum)
return binarySearch1(a, mid + 1, high, findNum);
else
return mid;
}
}
非遞歸方法
int binarySearch2(int a[] , int low , int high , int findNum)
{
while (low <= high)
{
int mid = ( low + high) / 2; //此處一定要放在while里面
if (a[mid] < findNum)
low = mid + 1;
else if (a[mid] > findNum)
high = mid - 1;
else
return mid;
}
return -1;
}
冒泡排序 θ(n^2)
void bubble_sort(int a[], int n)
{
int i, j, temp;
for (j = 0; j < n - 1; j++)
for (i = 0; i < n - 1 - j; i++) //外層循環(huán)每循環(huán)一次就能確定出一個(gè)泡泡(最大或者最小)许蓖,所以內(nèi)層循環(huán)不用再計(jì)算已經(jīng)排好的部分
{
if(a[i] > a[i + 1])
{
temp = a[i];
a[i] = a[i + 1];
a[i + 1] = temp;
}
}
}
快速排序 調(diào)用方法 quickSort(a,0,n); θ(nlogn)
void quickSort (int a[] , int low , int high)
{
if (high < low + 2)
return;
int start = low;
int end = high;
int temp;
while (start < end)
{
while ( ++start < high && a[start] <= a[low]);//找到第一個(gè)比a[low]數(shù)值大的位子start
while ( --end > low && a[end] >= a[low]);//找到第一個(gè)比a[low]數(shù)值小的位子end
//進(jìn)行到此蝴猪,a[end] < a[low] < a[start],但是物理位置上還是low < start < end,因此接下來交換a[start]和a[end],于是[low,start]這個(gè)區(qū)間里面全部比a[low]小的蛔糯,[end,hight]這個(gè)區(qū)間里面全部都是比a[low]大的
if (start < end)
{
temp = a[start];
a[start]=a[end];
a[end]=temp;
}
//在GCC編譯器下,該寫法無法達(dá)到交換的目的窖式,a[start] ^= a[end] ^= a[start] ^= a[end];編譯器的問題
}
//進(jìn)行到此蚁飒,[low,end]區(qū)間里面的數(shù)都比a[low]小的,[end,higt]區(qū)間里面都是比a[low]大的,把a(bǔ)[low]放到中間即可
//在GCC編譯器下萝喘,該寫法無法達(dá)到交換的目的淮逻,a[low] ^= a[end] ^= a[low] ^= a[end];編譯器的問題
temp = a[low];
a[low]=a[end];
a[end]=temp;
//現(xiàn)在就分成了3段了,由最初的a[low]樞紐分開的
quickSort(a, low, end);
quickSort(a, start, high);
}
注釋我也寫上了阁簸,這些算法基本上簡單的算法題都能應(yīng)對了爬早。
數(shù)據(jù)結(jié)構(gòu)的題目我就遇到了鏈表翻轉(zhuǎn),實(shí)現(xiàn)一個(gè)棧的結(jié)構(gòu)启妹,先進(jìn)后出的筛严,樹先跟,中跟饶米,后跟遍歷桨啃,圖的DFS和BFS。代碼就不貼了檬输,太長了照瘾。如果有忘記的,可以再去翻翻回顧一下丧慈。
三.面試
面試基本都是問你之前做過什么項(xiàng)目啦析命,遇到了哪些問題了,自己如何解決的逃默。談?wù)剬XX的看法等等這些問題鹃愤,只要平時(shí)認(rèn)真完成項(xiàng)目,其實(shí)面試反而問的東西更好答完域,因?yàn)槎际顷P(guān)于你項(xiàng)目的昼浦,這些你最了解和清楚了。
好了筒主,到此就是2018年9月上海地區(qū)除了BAT公司关噪,招聘iOS開發(fā)工程師的行情了鸟蟹,比2年前,最大的體會(huì)就是面試面更廣了使兔,要求更高了〗ㄔ浚現(xiàn)在要求除了會(huì)OC,還要懂算法和數(shù)據(jù)結(jié)構(gòu)虐沥,還有要么會(huì)ReactNative熊经,或者PhoneGap一系列混合開發(fā)的框架,或者熟悉Swift欲险,程序員要一直跟上主流才能不能被時(shí)代淘汰镐依。才能具有競爭力。這也是我面試了這些公司的感悟天试,活到老學(xué)到老槐壳!最后希望大家都和我交流交流,請大家多多指教!
小編給大家推薦一個(gè)iOS技術(shù)交流群:551346706!群內(nèi)提供數(shù)據(jù)結(jié)構(gòu)與算法白筹、底層進(jìn)階、swift枫笛、逆向、底層面試題整合文檔等免費(fèi)資料刚照!