Java面試題-算法篇十七

作者:阿木俠 
來源:公眾號Java知音

170,堆和棧在內存中的區別是什麼?

概念:

棧(stack)是為執行線程留出的內存空間。當函數被調用的時候,棧頂為局部變量和一些 bookkeeping 數據預留塊。當函數執行完畢,塊就沒有用了,可能在下次的函數調用的時候再被使用。棧通常用後進先出的方式預留空間;因此最近的保留塊通常最先被釋放。這麼做可以使跟蹤堆棧變的簡單;從棧中釋放塊只不過是指針的偏移而已。

堆(heap)是為動態分配預留的內存空間。和棧不一樣,從堆上分配和重新分配塊沒有固定模式;你可以在任何時候分配和釋放它。這樣使得跟蹤哪部分堆已經被分配和被釋放變的異常複雜;有許多定製的堆分配策略用來為不同的使用模式下調整堆的性能。

區別:

內存分配:

棧:由編譯器自動分配和釋放,存放函數的參數、局部變量、臨時變量、函數返回地址等。

堆:一般人為分配和釋放,對Java而言由系統釋放回收,但對於C++等,必須手動釋放,如果沒有手動釋放會引起內存洩漏。

系統響應:

棧:只要棧的剩餘空間大於所申請的空間,系統將為程序提供內存,否則將報異常提示棧溢出。

堆:在記錄空閒內存地址的鏈表中尋找一個空間大於所申請空間的堆結點,然後將該結點從空閒結點鏈表中刪除,並將該結點的空間分配給程序。

大小限制:

棧:在Windows下,棧是向低地址擴展的數據結構,是一塊連續的內存的區域。這句話的意思是棧頂的地址和棧的最大容量是系統預先規定好的,在 windows下,棧的大小是2M,如果申請的空間超過棧的剩餘空間時,將提示overflow。因此,能從棧獲得的空間較小。

堆:堆是向高地址擴展的數據結構,是不連續的內存區域。這是由於系統是用鏈表來存儲的空閒內存地址的,自然是不連續的,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限於計算機系統中有效的虛擬內存。

結論:堆獲得的空間比較靈活,也比較大。

分配效率:

棧:由系統自動分配,速度較快,無法人為控制。

堆:由new分配的內存,一般速度比較慢,而且容易產生內存碎片,不過用起來最方便。

存儲內容:

棧:在棧中,第一個進棧的是主函數下一條指令的地址,然後是函數的各個參數,在大多數編譯器中,參數是由右往左入棧,然後是函數中的局部變量。注意,靜態變量不入棧。出棧則剛好順序相反。

堆:一般在堆的頭部用一個字節存放堆的大小,具體內容受人為控制。

171,求出1000之內的所有水仙花數

概念:

水仙花數指的是一個三位整數,它的各位數字的立方和等於這個數本身.。

解法:

Java面試題-算法篇十七

172,比較一下幾種常用的排序算法,簡單的寫一下你知道的幾種排序算法?

比較:

1.穩定性比較

插入排序、冒泡排序、二叉樹排序、二路歸併排序及其他線形排序是穩定的

選擇排序、希爾排序、快速排序、堆排序是不穩定的

2.時間複雜性比較

插入排序、冒泡排序、選擇排序的時間複雜性為O(n2)

其它非線形排序的時間複雜性為O(nlog2n)

線形排序的時間複雜性為O(n);

3.輔助空間的比較

線形排序、二路歸併排序的輔助空間為O(n);

其它排序的輔助空間為O(1);

4.其它比較

*插入、冒泡排序的速度較慢,但參加排序的序列局部或整體有序時,這種排序能達到較快的速度,但是在這種情況下,快速排序反而慢了。

*當n較小時,對穩定性不作要求時宜用選擇排序,對穩定性有要求時宜用插入或冒泡排序。

*若待排序的記錄的關鍵字在一個明顯有限範圍內時,且空間允許是用桶排序。

*當n較大時,關鍵字元素比較隨機,對穩定性沒要求宜用快速排序。

*當n較大時,關鍵字元素可能出現本身是有序的,對穩定性有要求時,空間允許的情況下宜用歸併排序。

*當n較大時,關鍵字元素可能出現本身是有序的,對穩定性沒有要求時宜用堆排序。

常見的排序算法:

選擇排序

Java面試題-算法篇十七

插入排序

Java面試題-算法篇十七

快速排序

Java面試題-算法篇十七

希爾排序

Java面試題-算法篇十七

就先列到這裡了,誰還有其他算法的示例或者有這些算法的其他更優解,歡迎留言討論!

相關推薦

推薦中...