1. 程式人生 > >大資料工程師面試題—5

大資料工程師面試題—5

2)HashMap和HashTable,ArrayList和Vector,ArrayList和LinkedList的區別

1 HashMap不是執行緒安全的
hashmap是一個介面 是map介面的子介面,是將鍵對映到值的物件,其中鍵和值都是物件,並且不能包含重複鍵,但可以包含重複值。
HashMap允許null key和null value,而hashtable不允許。
2  HashTable是執行緒安全的一個Collection。
HashMap是Hashtable的輕量級實現(非執行緒安全的實現),他們都完成了Map介面,主要區別在於HashMap允許空(null)鍵值(key),
由於非執行緒安全,效率上可能高於Hashtable。 HashMap允許將null作為一個entry的key或者value,而Hashtable不允許。 HashMap把
Hashtable的contains方法去掉了,改成containsvalue和containsKey。因為contains方法容易讓人引起誤解。 Hashtable繼承自
Dictionary類,而HashMap是Java1.2引進的Map interface的一個實現。 最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,
在多個執行緒訪問Hashtable時,不需要自己為它的方法實現同步,而HashMap 就必須為之提供外同步。 Hashtable和HashMap採用的
hash/rehash演算法都大概一樣,所以效能不會有很大的差別。
public static void main(String args[]) { HashTable h=new HashTable(); h.put("使用者1",new Integer(90)); 
h.put("使用者2",new Integer(50)); h.put("使用者3",new Integer(60)); h.put("使用者4",new Integer(70)); 
h.put("使用者5",new Integer(80)); Enumeration e=h.elements(); while(e.hasMoreElements()){ System.out.println(e.nextElement()); }

總結:

hashmap 執行緒不安全 允許有null的鍵和值 效率高一點、 方法不是Synchronize的要提供外同步 有containsvalue和containsKey方法 HashMap 是Java1.2引進的Map interface的一個實現 HashMap是Hashtable的輕量級實現
hashtable 執行緒安全 不允許有null的鍵和值 效率稍低、 方法是是Synchronize的 有contains方法方法 Hashtable 繼承於Dictionary類 Hashtable 比HashMap要舊

Vector & ArrayList 
1)  Vector的方法都是同步的(Synchronized),是執行緒安全的(thread-safe),而ArrayList的方法不是,由於執行緒的同步必然要影響效能,
因此,ArrayList的效能比Vector好。 
2) 當Vector或ArrayList中的元素超過它的初始大小時,Vector會將它的容量翻倍,而ArrayList只增加50%的大小,這樣,ArrayList就有利
於節約記憶體空間。
 linkedlist & ArrayList 
ArrayList 採用的是陣列形式來儲存物件的,這種方式將物件放在連續的位置中,所以最大的缺點就是插入刪除時非常麻煩
LinkedList 採用的將物件存放在獨立的空間中,而且在每個空間中還儲存下一個連結的索引  但是缺點就是查詢非常麻煩 要叢第一個索引
開始
Hashtable和HashMap類有三個重要的不同之處。第一個不同主要是歷史原因。Hashtable是基於陳舊的Dictionary類的,HashMap是Java 1.2
引進的Map介面的一個實現。 
也許最重要的不同是Hashtable的方法是同步的,而HashMap的方法不是。這就意味著,雖然你可以不用採取任何特殊的行為就可以在一個多
執行緒的應用程式中用一個Hashtable,但你必須同樣地為一個HashMap提供外同步。一個方便的方法就是利用Collections類的靜態的
synchronizedMap()方法,它建立一個執行緒安全的Map物件,並把它作為一個封裝的物件來返回。這個物件的方法可以讓你同步訪問潛在的
HashMap。這麼做的結果就是當你不需要同步時,你不能切斷Hashtable中的同步(比如在一個單執行緒的應用程式中),而且同步增加了很多
處理費用。 
第三點不同是,只有HashMap可以讓你將空值作為一個表的條目的key或value。HashMap中只有一條記錄可以是一個空的key,但任意數量的
條目可以是空的value。這就是說,如果在表中沒有發現搜尋鍵,或者如果發現了搜尋鍵,但它是一個空的值,那麼get()將返回null。
如果有必要,用containKey()方法來區別這兩種情況。 
一些資料建議,當需要同步時,用Hashtable,反之用HashMap。但是,因為在需要時,HashMap可以被同步,HashMap的功能比Hashtable的
功能更多,而且它不是基於一個陳舊的類的,所以有人認為,在各種情況下,HashMap都優先於Hashtable。 
關於Properties 
有時侯,你可能想用一個hashtable來對映key的字串到value的字串。DOS、Windows和Unix中的環境字串就有一些例子,如key的字串
PATH被對映到value的字串C:\WINDOWS;C:\WINDOWS\SYSTEM。Hashtables是表示這些的一個簡單的方法,但Java提供了另外一種方法。 
Java.util.Properties類是Hashtable的一個子類,設計用於String keys和values。Properties物件的用法同Hashtable的用法相象,但是類
增加了兩個節省時間的方法,你應該知道。 
Store()方法把一個Properties物件的內容以一種可讀的形式儲存到一個檔案中。Load()方法正好相反,用來讀取檔案,並設定Properties
物件來包含keys和values。 
注意,因為Properties擴充套件了Hashtable,你可以用超類的put()方法來新增不是String物件的keys和values。這是不可取的。另外,如果你將
store()用於一個不包含String物件的Properties物件,store()將失敗。作為put()和get()的替代,你應該用setProperty()和getProperty(),它們用String引數。

3)多執行緒實現方式Thread和Runnable的區別?
在java中可有兩種方式實現多執行緒,一種是繼承Thread類,一種是實現Runnable介面;Thread類是在java.lang包中定義的。一個類只要繼承
了Thread類同時覆寫了本類中的run()方法就可以實現多執行緒操作了,但是一個類只能繼承一個父類,這是此方法的侷限。
在java中可有兩種方式實現多執行緒,一種是繼承Thread類,一種是實現Runnable介面;Thread類是在java.lang包中定義的。一個類只要繼承
了Thread類同時覆寫了本類中的run()方法就可以實現多執行緒操作了,但是一個類只能繼承一個父類,這是此方法的侷限。
下面看例子:

但是,此時結果很有規律,先第一個物件執行,然後第二個物件執行,並沒有相互執行。在JDK的文件中可以發現,一旦呼叫start()方法,則會通過JVM找到run()方法。下面啟動start()方法啟動執行緒:

這樣程式可以正常完成互動式執行。那麼為啥非要使用start();方法啟動多執行緒呢?
在JDK的安裝路徑下,src.zip是全部的java源程式,通過此程式碼找到Thread中的start()方法的定義,可以發現此方法中使用了private native void start0();其中native關鍵字表示可以呼叫作業系統的底層函式,那麼這樣的技術成為JNI技術(java Native Interface)Runnable介面在實際開發中一個多執行緒的操作很少使用Thread類,而是通過Runnable介面完成。

例子:

但是在使用Runnable定義的子類中沒有start()方法,只有Thread類中才有。此時觀察Thread類,
有一個構造方法:public Thread(Runnable targer)此構造方法接受Runnable的子類例項,也就是說可以通過Thread類來啟動Runnable實現的多執行緒。(start()可以協調系統的資源):

兩種實現方式的區別和聯絡:
在程式開發中只要是多執行緒肯定永遠以實現Runnable介面為主,因為實現Runnable介面相比繼承Thread類有如下好處:
避免點繼承的侷限,一個類可以繼承多個介面。
適合於資源的共享
以賣票程式為例,通過Thread類完成:

 

下面通過三個執行緒物件,同時賣票:

 

如果用Runnable就可以實現資源共享,下面看例子:

雖然現在程式中有三個執行緒,但是一共賣了10張票,也就是說使用Runnable實現多執行緒可以達到資源共享目的。