上次寫過的《微軟 面試 心得》很意外的得到了很多朋友的關注和討論,再次表示很是感激。雖說上次微軟折戟而還,但也收穫良多,很多面試之內和面試之外的討論和反思,“完美”就是我上次收穫的最多的東西。上次已經與各位探討一番,鄙人最近又有幸參加了IBM面試,也是收穫頗豐,願與各位繼續討論,希望能帶給諸位一些反思和借鑒。此次收穫的最多的東西就是:“底蘊”。
這個底蘊不是誇IBM本身是一個非常有底蘊的公司,而是他們更加註重個人的底蘊。公司不會管你某個語言用的有多麼多麼精通,某項技術有多麼多麼熟悉,公司所看重的是你的綜合的知識面和基礎。性格是一方面,IBM更加看重的是個人知識的底蘊,尤其是對於一個小小的本科生來說(其實最近一個月來經過各種筆試面試,再加上是在異地作戰,身體有種虛脫的感覺,真想等這陣子過去之後好好休息一下)。下面列舉的是今天我面試的時候兩位面試官所提的問題,我特意做了一些題目和答案上的整理,便於日後回顧,也供諸位回顧一下基本知識。其實有些列舉出來的問題只是面試的時候所問的第一問,更深入的討論限於篇幅就沒有再列舉出來。
(一)java物件導向四個特點,重寫和重載區分。
封裝、繼承、多態、抽象
1.重寫的概念是在繼承中產生的,子類中有和父類相同的函式宣告,則該函數被重寫,子類對象無法訪問父類中的這個函數
2.重載是指若干函數有相似的函式宣告,參數列表不同,但是功能類似
(二)java容器的概念。linkedlist和arraylist的區別。
Java容器類包含List、ArrayList、Vector及map、HashTable、HashMap
(三)hashmap、hashtable的區別。hash的底層的兩種實現方式。
1.HashMap
1) hashmap的資料結構
Hashmap是一個數組和鏈表的結合體(在資料結構稱“鏈表散列“),如示:
當我們往hashmap中put元素的時候,先根據key的hash值得到這個元素在數組中的位置(即下標),然後就可以把這個元素放到對應的位置中了。如果這個元素所在的位子上已經存放有其他元素了,那麼在同一個位子上的元素將以鏈表的形式存放,新加入的放在鏈頭,最先加入的放在鏈尾。
2)使用
Map map =new HashMap();
map.put("RajibSarma","100");
map.put("RajibSarma","200");//The value "100" is replaced by"200".
map.put("SazidAhmed","200");
Iteratoriter = map.entrySet().iterator();
while(iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
Object key = entry.getKey();
Object val = entry.getValue();
}
2.HashTable和HashMap區別
第一,繼承不同。
public classHashtable extends Dictionary implements Map
public classHashMap extends AbstractMap implementsMap
第二
Hashtable中的方法是同步的,而HashMap中的方法在預設情況下是非同步的。在多線程並發的環境下,可以直接使用Hashtable,但是要使用HashMap的話就要自己增加同步處理了。
第三
Hashtable中,key和value都不允許出現null值。
在HashMap中,null可以作為鍵,這樣的鍵只有一個;可以有一個或多個鍵所對應的值為null。當get()方法返回null值時,即可以表示 HashMap中沒有該鍵,也可以表示該鍵所對應的值為null。因此,在HashMap中不能由get()方法來判斷HashMap中是否存在某個鍵, 而應該用containsKey()方法來判斷。
第四,兩個遍曆方式的內部實現上不同。
Hashtable、HashMap都使用了 Iterator。而由於曆史原因,Hashtable還使用了Enumeration的方式 。
第五
雜湊值的使用不同,HashTable直接使用對象的hashCode。而HashMap重新計算hash值。
第六
Hashtable和HashMap它們兩個內部實現方式的數組的初始大小和擴容的方式。HashTable中hash數組預設大小是11,增加的方式是 old*2+1。HashMap中hash數組的預設大小是16,而且一定是2的指數。
(四)Java中String是否可以被繼承
不可以。String 是final的,不能被繼承。
基本類型的類都是final類,無法被繼承或修改,比如:Integer,Float,Boolean,Byte,Character,Long,Short等等。
(五)抽象類別和介面的區別。
1、抽象類別裡面可以有非抽象方法
但介面裡只能有抽象方法
聲明方法的存在而不去實現它的類被叫做抽像類(abstract class),它用於要建立一個體現某些基本行為的類,並為該類聲明方法,但不能在該類中實現該類的情況。不能建立abstract 類的執行個體。然而可以建立一個變數,其類型是一個抽像類,並讓它指向具體子類的一個執行個體。不能有抽像建構函式或抽像靜態方法。Abstract 類的子類為它們父類中的所有抽像方法提供實現,否則它們也是抽像類為。取而代之,在子類中實現該方法。知道其行為的其它類可以在類中實現這些方法。
2、介面(interface)是抽像類的變體。在介面中,所有方法都是抽像的。多繼承性可通過實現這樣的介面而獲得。介面中的所有方法都是抽像的,沒有一個有程式體。介面只可以定義static final成員變數。介面的實現與子類相似,除了該實作類別不能從介面定義中繼承行為。當類實現特殊介面時,它定義(即將程式體給予)所有這種介面的方法。然後,它可以在實現了該介面的類的任何對像上調用介面的方法。由於有抽像類,它允許使用介面名作為引用變數的類型。通常的動態聯編將生效。引用可以轉換到介面類型或從介面類型轉換,instanceof
運算子可以用來決定某對象的類是否實現了介面。
(六)java多線程兩種實現方式。
java多線程的的兩種方法,要注意也有細微的差別!
繼承Thread類
實現Runnable介面 (注意:共用資料的時候實現Runnable介面,Thread類不支援)
Threadt1=new Thread()
{
public void run()
{
System.out.println("第一種方法");
}
};
t1.start();
Threadt2=new Thread(new Runnable()
{
public voidrun()
{
System.out.println("第二種方法,可實現同類下各線程資料共用");
}
});
t2.start();
(七)線程、進程區別,進程的好處。
簡而言之,一個程式至少有一個進程,一個進程至少有一個線程.
線程的劃分尺度小於進程,使得多線程程式的並發性高。
另外,進程在執行過程中擁有獨立的記憶體單元,而多個線程共用記憶體,從而極大地提高了程式的運行效率。
線程在執行過程中與進程還是有區別的。每個獨立的線程有一個程式啟動並執行入口、順序執行序列和程式的出口。但是線程不能夠獨立執行,必須依存在應用程式中,由應用程式提供多個線程執行控制。
從邏輯角度來看,多線程的意義在於一個應用程式中,有多個執行部分可以同時執行。但作業系統並沒有將多個線程看做多個獨立的應用,來實現進程的調度和管理以及資源分派。這就是進程和線程的重要區別。
進程是具有一定獨立功能的程式關於某個資料集合上的一次運行活動,進程是系統進行資源分派和調度的一個獨立單位.
線程是進程的一個實體,是CPU調度和指派的基本單位,它是比進程更小的能獨立啟動並執行基本單位.線程自己基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程式計數器,一組寄存器和棧),但是它可與同屬一個進程的其他的線程共用進程所擁有的全部資源.
一個線程可以建立和撤銷另一個線程;同一個進程中的多個線程之間可以並發執行.
進程和線程的主要差別在於它們是不同的作業系統資源管理方式。進程有獨立的地址空間,一個進程崩潰後,在保護模式下不會對其它進程產生影響,而線程只是一個進程中的不同執行路徑。線程有自己的堆棧和局部變數,但線程之間沒有單獨的地址空間,一個線程死掉就等於整個進程死掉,所以多進程的程式要比多線程的程式健壯,但在進程切換時,耗費資源較大,效率要差一些。但對於一些要求同時進行並且又要共用某些變數的並行作業,只能用線程,不能用進程。
(註:這個地方剛剛學長指出了有點問題,原話如下:
很多時候,一個現場阻塞死掉,其他線程還是可以繼續跑
如果一個程式,一般不需要用多進程,就不會用。不是健壯的問題,是效能的問題
死掉,如果你的線程沒有影響到臨界區的資料
也不會對其他線程造成影響
因為是並行的
)
(八)32位機器,什麼是32位,是怎麼起作用的。
(九)虛擬記憶體和記憶體的區別。
(十)快速排序是否是穩定的,什麼叫穩定的。
1.穩定的排序
冒泡排序(bubble sort) — O(n2)
雞尾酒排序 (Cocktail sort, 雙向的冒泡排序) — O(n2)
插入排序 (insertion sort)— O(n2)
桶排序 (bucket sort)— O(n); 需要 O(k) 額外 記憶體
計數排序 (counting sort) — O(n+k); 需要 O(n+k) 額外 記憶體
歸併排序 (merge sort)— O(n log n); 需要 O(n) 額外記憶體
原地歸併排序 — O(n2)
二叉樹排序(Binary treesort) — O(n log n); 需要 O(n) 額外記憶體
基數排序 (radix sort)— O(n·k); 需要 O(n) 額外記憶體
2.不穩定的排序
選擇排序 (selection sort)— O(n2)
希爾排序 (shell sort)— O(n log n) 如果使用最佳的現在版本
堆排序 (heapsort)— O(n log n)
快速排序 (quicksort)— O(n log n) 期望時間, O(n2) 最壞情況; 對於大的、亂數串列一般相信是最快的已知排序
詳見:http://fei-cool.blog.sohu.com/152000311.html
(十一)kmp尋找
(十二)紅/黑樹狀結構的實現
(十三)設計模式
設計模式主要分三個類型:建立型、結構型和行為型。 其中建立型有: 一、Singleton,單例模式:保證一個類只有一個執行個體,並提供一個訪問它的全域訪問點 二、Abstract Factory,抽象工廠:提供一個建立一系列相關或相互依賴對象的介面,而無須指定它們的具體類。 三、Factory Method,Factory 方法:定義一個用於建立對象的介面,讓子類決定執行個體化哪一個類,Factory Method使一個類的執行個體化延遲到了子類。 四、Builder,建造模式:將一個複雜物件的構建與他的表示相分離,使得同樣的構建過程可以建立不同的表示。 五、Prototype,原型模式:用原型執行個體指定建立對象的種類,並且通過拷貝這些原型來建立新的對象。 行為型有: 六、Iterator,迭代器模式:提供一個方法順序訪問一個彙總對象的各個元素,而又不需要暴露該對象的內部表示。 七、Observer,觀察者模式:定義對象間一對多的依賴關係,當一個對象的狀態發生改變時,所有依賴於它的對象都得到通知自動更新。 八、Template Method,模板方法:定義一個操作中的演算法的骨架,而將一些步驟延遲到子類中,TemplateMethod使得子類可以不改變一個演算法的結構即可以重定義該演算法得某些特定步驟。 九、Command,命令模式:將一個請求封裝為一個對象,從而使你可以用不同的請求對客戶進行參數化,對請求排隊和記錄請求日誌,以及支援可撤銷的操作。 十、State,狀態模式:允許對象在其內部狀態改變時改變他的行為。對象看起來似乎改變了他的類。 十一、Strategy,策略模式:定義一系列的演算法,把他們一個個封裝起來,並使他們可以互相替換,本模式使得演算法可以獨立於使用它們的客戶。 十二、China of Responsibility,職責鏈模式:使多個對象都有機會處理請求,從而避免請求的送發者和接收者之間的耦合關係 十三、Mediator,中介者模式:用一個中介對象封裝一些列的對象互動。 十四、Visitor,訪問者模式:表示一個作用於某對象結構中的各元素的操作,它使你可以在不改變各元素類的前提下定義作用於這個元素的新操作。 十五、Interpreter,解譯器模式:給定一個語言,定義他的文法的一個表示,並定義一個解譯器,這個解譯器使用該表示來解釋語言中的句子。 十六、Memento,備忘錄模式:在不破壞對象的前提下,捕獲一個對象的內部狀態,並在該對象之外儲存這個狀態。 結構型有: 十七、Composite,組合模式:將對象組合成樹形結構以表示部分整體的關係,Composite使得使用者對單個對象和組合對象的使用具有一致性。 十八、Facade,面板模式:為子系統中的一組介面提供一致的介面,fa?ade提供了一高層介面,這個介面使得子系統更容易使用。 十九、Proxy,代理模式:為其他對象提供一種代理以控制對這個對象的訪問 二十、Adapter,適配器模式:將一類的介面轉換成客戶希望的另外一個介面,Adapter模式使得原本由於介面不相容而不能一起工作那些類可以一起工作。 二十一、Decrator,裝飾模式:動態地給一個對象增加一些額外的職責,就增加的功能來說,Decorator模式相比產生子類更加靈活。 二十二、Bridge,橋模式:將抽象部分與它的實現部分相分離,使他們可以獨立的變化。 二十三、Flyweight,享元模式
(十四)英文自我敘述,非自我介紹。
(歡迎朋友們留言討論,共同進步。)