iOS面試題摘要

  1. http的post和get啥區(qū)別?(區(qū)別挺多的,麻煩多說點(diǎn))
    ==

1.GET請(qǐng)求的數(shù)據(jù)會(huì)附在URL之后(就是把數(shù)據(jù)放置在HTTP協(xié)議頭中),以?分割URL和傳輸數(shù)據(jù),參數(shù)之間以&相連,如:login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0%E5%A5%BD。如果數(shù)據(jù)是英文字母/數(shù)字,原樣發(fā)送,如果是空格,轉(zhuǎn)換為+,如果是中文/其他字符,則直接把字符串用BASE64加密,得出如:%E4%BD%A0%E5%A5%BD,其中%XX中的XX為該符號(hào)以16進(jìn)制表示的ASCII。
  POST把提交的數(shù)據(jù)則放置在是HTTP包的包體中。

(1).首先是"GET方式提交的數(shù)據(jù)最多只能是1024字節(jié)",因?yàn)镚ET是通過URL提交數(shù)據(jù),那么GET可提交的數(shù)據(jù)量就跟URL的長(zhǎng)度有直接關(guān)系了。而實(shí)際上,URL不存在參數(shù)上限的問題,HTTP協(xié)議規(guī)范沒有對(duì)URL長(zhǎng)度進(jìn)行限制。這個(gè)限制是特定的瀏覽器及服務(wù)器對(duì)它的限制。IE對(duì)URL長(zhǎng)度的限制是2083字節(jié)(2K+35)。對(duì)于其他瀏覽器,如Netscape、FireFox等,理論上沒有長(zhǎng)度限制,其限制取決于操作系統(tǒng)的支持。

注意這是限制是整個(gè)URL長(zhǎng)度,而不僅僅是你的參數(shù)值數(shù)據(jù)長(zhǎng)度。[見參考資料5]

(2).理論上講,POST是沒有大小限制的,HTTP協(xié)議規(guī)范也沒有進(jìn)行大小限制,說“POST數(shù)據(jù)量存在80K/100K的大小限制”是不準(zhǔn)確的,POST數(shù)據(jù)是沒有限制的,起限制作用的是服務(wù)器的處理程序的處理能力。

3.在ASP中,服務(wù)端獲取GET請(qǐng)求參數(shù)用Request.QueryString,獲取POST請(qǐng)求參數(shù)用Request.Form。在JSP中,用request.getParameter("XXXX")來獲取,雖然jsp中也有request.getQueryString()方法,但使用起來比較麻煩,比如:傳一個(gè)test.jsp?name=hyddd&password=hyddd,用request.getQueryString()得到的是:name=hyddd&password=hyddd。在PHP中,可以用$_GET和$_POST分別獲取GET和POST中的數(shù)據(jù),而$_REQUEST則可以獲取GET和POST兩種請(qǐng)求中的數(shù)據(jù)。值得注意的是,JSP中使用request和PHP中使用$_REQUEST都會(huì)有隱患,這個(gè)下次再寫個(gè)文章總結(jié)。

4.POST的安全性要比GET的安全性高。注意:這里所說的安全性和上面GET提到的“安全”不是同個(gè)概念。上面“安全”的含義僅僅是不作數(shù)據(jù)修改,而這里安全的含義是真正的Security的含義,比如:通過GET提交數(shù)據(jù),用戶名和密碼將明文出現(xiàn)在URL上,因?yàn)?1)登錄頁面有可能被瀏覽器緩存,(2)其他人查看瀏覽器的歷史紀(jì)錄,那么別人就可以拿到你的賬號(hào)和密碼了,除此之外,使用GET提交數(shù)據(jù)還可能會(huì)造成Cross-site request forgery攻擊。

總結(jié)一下,Get是向服務(wù)器發(fā)索取數(shù)據(jù)的一種請(qǐng)求,而Post是向服務(wù)器提交數(shù)據(jù)的一種請(qǐng)求,在FORM(表單)中,Method默認(rèn)為"GET",實(shí)質(zhì)上,GET和POST只是發(fā)送機(jī)制不同,并不是一個(gè)取一個(gè)發(fā)!

  1. 我知道你大學(xué)畢業(yè)過后就沒接觸過算法數(shù)據(jù)結(jié)構(gòu)了,但是請(qǐng)你一定告訴我什么是Binary search tree? search的時(shí)間復(fù)雜度是多少?
    ==

Binary search tree:二叉搜索樹。
主要由四個(gè)方法:(用C語言實(shí)現(xiàn)或者Python)
1.search:時(shí)間復(fù)雜度為O(h),h為樹的高度

2.traversal:時(shí)間復(fù)雜度為O(n),n為樹的總結(jié)點(diǎn)數(shù)。

3.insert:時(shí)間復(fù)雜度為O(h),h為樹的高度。

4.delete:最壞情況下,時(shí)間復(fù)雜度為O(h)+指針的移動(dòng)開銷。

可以看到,二叉搜索樹的dictionary operation的時(shí)間復(fù)雜度與樹的高度h相關(guān)。所以需要盡可能的降低樹的高度,由此引出平衡二叉樹Balanced binary tree。它要求左右兩個(gè)子樹的高度差的絕對(duì)值不超過1,并且左右兩個(gè)子樹都是一棵平衡二叉樹。這樣就可以將搜索樹的高度盡量減小。常用算法有紅黑樹、AVL、Treap、伸展樹等。

  1. GCD里面有哪幾種Queue?你自己建立過串行queue嗎?背后的線程模型是什么樣的?
    ==

1.主隊(duì)列 dispatch_main_queue(); 串行 ,更新UI
2.全局隊(duì)列 dispatch_global_queue(); 并行,四個(gè)優(yōu)先級(jí):background,low,default,high
3.自定義隊(duì)列 dispatch_queue_t queue ; 可以自定義是并行:DISPATCH_QUEUE_CONCURRENT或者串行DISPATCH_QUEUE_SERIAL

  1. 用過coredata或者sqlite嗎?讀寫是分線程的嗎?遇到過死鎖沒?咋解決的?
    ==

  2. 講講你用Instrument優(yōu)化動(dòng)畫性能的經(jīng)歷吧(別問我什么是Instrument)
    ==

  3. 如何高性能的給UIImageView加個(gè)圓角?(不準(zhǔn)說layer.cornerRadius!)
    ==

我覺得應(yīng)該是使用Quartz2D直接繪制圖片,得把這個(gè)看看。
步驟:
  a、創(chuàng)建目標(biāo)大小(cropWidth,cropHeight)的畫布。

b、使用UIImage的drawInRect方法進(jìn)行繪制的時(shí)候,指定rect為(-x,-y,width,height)。

c、從畫布中得到裁剪后的圖像。

(UIImage)cropImageWithRect:(CGRect)cropRect
{
CGRect drawRect = CGRectMake(-cropRect.origin.x , -cropRect.origin.y, self.size.width self.scale, self.size.height * self.scale);

UIGraphicsBeginImageContext(cropRect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClearRect(context, CGRectMake(0, 0, cropRect.size.width, cropRect.size.height));

[self drawInRect:drawRect];

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

return image;
}
@end

第二種是使用貝塞爾曲線來切割圖片:

UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];  
imageView.center = CGPointMake(200, 300);  
UIImage *anotherImage = [UIImage imageNamed:@"image"];  
UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 1.0);  
[[UIBezierPath bezierPathWithRoundedRect:imageView.bounds
                         cornerRadius:50] addClip];
[anotherImage drawInRect:imageView.bounds];
imageView.image = UIGraphicsGetImageFromCurrentImageContext();  
UIGraphicsEndImageContext();  
[self.view addSubview:imageView];
  1. 使用drawRect有什么影響?(這個(gè)可深可淺,你至少得用過。。)
    ==
    drawRect方法依賴Core Graphics框架來進(jìn)行自定義的繪制,但這種方法主要的缺點(diǎn)就是它處理touch事件的方式:每次按鈕被點(diǎn)擊后,都會(huì)用setNeddsDisplay進(jìn)行強(qiáng)制重繪;而且不止一次,每次單點(diǎn)事件觸發(fā)兩次執(zhí)行。這樣的話從性能的角度來說,對(duì)CPU和內(nèi)存來說都是欠佳的。特別是如果在我們的界面上有多個(gè)這樣的UIButton實(shí)例。

  2. loadView是干嘛用的?
    ==

當(dāng)你訪問一個(gè)ViewController的view屬性時(shí),如果此時(shí)view的值是nil,那么,ViewController就會(huì)自動(dòng)調(diào)用loadView這個(gè)方法。這個(gè)方法就會(huì)加載或者創(chuàng)建一個(gè)view對(duì)象,賦值給view屬性。
loadView默認(rèn)做的事情是:如果此ViewController存在一個(gè)對(duì)應(yīng)的nib文件,那么就加載這個(gè)nib。否則,就創(chuàng)建一個(gè)UIView對(duì)象。

如果你用Interface Builder來創(chuàng)建界面,那么不應(yīng)該重載這個(gè)方法。

如果你想自己創(chuàng)建view對(duì)象,那么可以重載這個(gè)方法。此時(shí)你需要自己給view屬性賦值。你自定義的方法不應(yīng)該調(diào)用super。如果你需要對(duì)view做一些其他的定制操作,在viewDidLoad里面去做。

=========================================

根據(jù)上面的文檔可以知道,有兩種情況:

1、如果你用了nib文件,重載這個(gè)方法就沒有太大意義。因?yàn)閘oadView的作用就是加載nib。如果你重載了這個(gè)方法不調(diào)用super,那么nib文件就不會(huì)被加載。如果調(diào)用了super,那么view已經(jīng)加載完了,你需要做的其他事情在viewDidLoad里面做更合適。

2、如果你沒有用nib,這個(gè)方法默認(rèn)就是創(chuàng)建一個(gè)空的view對(duì)象。如果你想自己控制view對(duì)象的創(chuàng)建,例如創(chuàng)建一個(gè)特殊尺寸的view,那么可以重載這個(gè)方法,自己創(chuàng)建一個(gè)UIView對(duì)象,然后指定 self.view = myView; 但這種情況也沒有必要調(diào)用super,因?yàn)榉凑阋膊恍枰趕uper方法里面創(chuàng)建的view對(duì)象。如果調(diào)用了super,那么就是浪費(fèi)了一些資源而已

9.7.為什么其他語言里叫函數(shù)調(diào)用, objective c里則是給對(duì)象發(fā)消息(或者談下對(duì)runtime的理解)

[receiver message]會(huì)被編譯器轉(zhuǎn)化為:
objc_msgSend(receiver, selector)
如果消息含有參數(shù),則為:
objc_msgSend(receiver, selector, arg1, arg2, ...)
如果消息的接收者能夠找到對(duì)應(yīng)的selector,那么就相當(dāng)于直接執(zhí)行了接收者這個(gè)對(duì)象的特定方法;否則,消息要么被轉(zhuǎn)發(fā),或是臨時(shí)向接收者動(dòng)態(tài)添加這個(gè)selector對(duì)應(yīng)的實(shí)現(xiàn)內(nèi)容,要么就干脆玩完崩潰掉。

現(xiàn)在可以看出[receiver message]真的不是一個(gè)簡(jiǎn)簡(jiǎn)單單的方法調(diào)用。因?yàn)檫@只是在編譯階段確定了要向接收者發(fā)送message這條消息,而receive將要如何響應(yīng)這條消息,那就要看運(yùn)行時(shí)發(fā)生的情況來決定了。

Objective-C 的 Runtime 鑄就了它動(dòng)態(tài)語言的特性,這些深層次的知識(shí)雖然平時(shí)寫代碼用的少一些,但是卻是每個(gè) Objc 程序員需要了解的。

Objc Runtime使得C具有了面向?qū)ο竽芰?,在程序運(yùn)行時(shí)創(chuàng)建,檢查,修改類、對(duì)象和它們的方法??梢允褂胷untime的一系列方法實(shí)現(xiàn)。

向object發(fā)送消息時(shí),Runtime庫會(huì)根據(jù)object的isa指針找到這個(gè)實(shí)例object所屬于的類,然后在類的方法列表以及父類方法列表尋找對(duì)應(yīng)的方法運(yùn)行。id是一個(gè)objc_object結(jié)構(gòu)類型的指針,這個(gè)類型的對(duì)象能夠轉(zhuǎn)換成任何一種對(duì)象。

然后再來看看消息發(fā)送的函數(shù):objc_msgSend函數(shù)

在引言中已經(jīng)對(duì)objc_msgSend進(jìn)行了一點(diǎn)介紹,看起來像是objc_msgSend返回了數(shù)據(jù),其實(shí)objc_msgSend從不返回?cái)?shù)據(jù)而是你的方法被調(diào)用后返回了數(shù)據(jù)。下面詳細(xì)敘述下消息發(fā)送步驟:

檢測(cè)這個(gè) selector 是不是要忽略的。比如 Mac OS X 開發(fā),有了垃圾回收就不理會(huì) retain,release 這些函數(shù)了。
檢測(cè)這個(gè) target 是不是 nil 對(duì)象。ObjC 的特性是允許對(duì)一個(gè) nil 對(duì)象執(zhí)行任何一個(gè)方法不會(huì) Crash,因?yàn)闀?huì)被忽略掉。
如果上面兩個(gè)都過了,那就開始查找這個(gè)類的 IMP,先從 cache 里面找,完了找得到就跳到對(duì)應(yīng)的函數(shù)去執(zhí)行。
如果 cache 找不到就找一下方法分發(fā)表。
如果分發(fā)表找不到就到超類的分發(fā)表去找,一直找,直到找到NSObject類為止。
如果還找不到就要開始進(jìn)入動(dòng)態(tài)方法解析了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容