2016-03-30 82 views
1

在我最近的軟件工程師職位面試中,有人問我這個問題:散列表和散列表之間有什麼區別?我詢問了面試官他是否具體關於Java,因爲在Java中,hashtable是同步的,而hashmap不是(實際上,google搜索後用Java比較hashtable和hashmap的信息很多,所以這不是我正在尋找的答案)我想解釋一下這兩者的區別。散列表和散列表之間有什麼區別? (並不特定於Java)

我對這個問題感到非常困惑和震驚(實際上現在仍然感到困惑)。國際海事組織,hastable或hashmap只是一個術語問題。實際上,只有Java有C++這樣的術語和其他語言,他們甚至沒有術語hashtable。在採訪中,我只是解釋了哈希的原理,並說hashmap和hashtable都應該基於這個原則來實現,我不知道這兩者之間是否有區別。面試官絕對不相信,並且正在尋找其他答案,當然在那輪之後我被拒絕了。

因此,回到主題,如果有什麼可能是散列表和散列表(通常不是特定於Java)的區別?

+0

爲了跟進,看起來像C#中的字典和散列表有所不同,但這又不是我正在尋找的。 –

回答

2

在計算機科學中,由於措辭的不同,

HashTable是某種查找表,它使用密鑰哈希來查找表中的對應值,如數據結構。那只是一種鍵值映射。你可能知道有不同的實現。不同的哈希,哈希合謀解決方案和表增長策略以及更多內容。如果你無論出於何種原因需要製作你自己的哈希表,那隻會很有趣。

HashMap是某種鍵值對與散列鍵的映射。映射是抽象的,它可能不是一張表。平衡樹或嘗試或其他數據結構/映射也是可能的。

您可以簡化並說HashTable是底層數據結構,HashMap可能會使用HashTable。

字典是另一個抽象層次,因爲它可能根本不使用散列 - 例如全文二分查找查找或其他比較方法。無需考慮某些編程語言,這就是所有你可以從單詞中獲得的。

- 在考慮太多之前。你能否肯定地說 - 你的面試官對他/她所談論的事情有了線索?你有沒有討論技術細節,或者他們只是聽/提問,有時會發表評論?有時候,面試官只是拿出最嘲笑的答案來回答他們首先不瞭解的問題。像你自己寫的,一般來說它只是術語。軟件開發人員經常使用這些術語可互換,除了那些真正與Java差異的人。

+0

感謝您的回覆。我認爲你的回答非常好,但我現在還不能將其標記爲正確答案。爲了澄清事情,這個問題是一個孤立的問題,沒有任何背景,面試官只是把它扔給我。另外,我非常有信心,他沒有提出這個問題,因爲其他人提到了爲同一家公司採訪過的這個問題。正如我在我的文章中提到的,我向他解釋了哈希原理,並說哈希表和哈希表都可以這樣實現(我知道你也可以使用二叉搜索樹來實現hasmap,但我沒有提到)... –

+0

(繼續),並詢問面試官他是否可以給我任何關於他正在尋找的答案的暗示。他沒有給我任何提示,而是問我另一個問題。由於我採訪的公司是業內知名公司,他們以這種方式進行了採訪,因此我對結果感到非常失望。 –

+0

我明白了。 [Here](http://stackoverflow.com/a/32367030/3828957)是另一個 - 較老的 - 在普通數據結構級別上的回答,[this](http://stackoverflow.com/q/30110252/3828957)涵蓋它的答案更多一點。好運找到你的答案。如果你所能做的只是假設什麼是正確的或者是否有足夠的複雜性/深度來作爲答案,那將是很難的。 – makadev

0

面試官可能一直在尋找這樣的認識......

  • 一個哈希表是一個低級別的概念,並不暗示或一定支持任何區分或隔離鍵和值(即可以實現散列設定使用散列表)的值,而
  • 一個哈希映射必須支持不同的鍵和值,作爲有可從鍵到值的映射/關聯;兩者是不同的,即使在一些實現中它們總是並排存儲在存儲器中,例如,相同結構的成員/ std::pair<>

實例:(壞)哈希表實現防止用作哈希映射。

考慮:

template <typename T> 
class Hash_Table 
{ 
    ... 
    bool insert(const T& t) 
    { 
     // work out which bucket t hashes to... 
     size_t bucket = hash_bytes((void*)&t, sizeof t) % num_buckets_; 

     // see if t is already stored in the bucket... 
     if (memcmp((void*)&t, (void*)&buckets_[bucket], sizeof t) == 0) 
      ... 
     ... handle collisions etc. ... 
    } 
    ... 
}; 

以上,硬編碼調用的是把插入爲二進制的blob值的散列函數,以及整個tmemcmp,意味着你不能做T說一個std::pair<int, std::string>並且使用散列表作爲從ints到strings的散列圖。所以,這是一個散列表的例子,其而不是可用作散列映射。


可能會或可能不會還要考慮一個哈希表,根本沒有用作哈希表不是一個哈希表提供任何便利功能。例如,如果API被設計爲就好像只處理值 - h.insert(t); h.erase(t); auto i = h.find(t); - 但它允許調用者指定任意自定義比較和散列函數,這些函數可能會將其操作僅限於t的關鍵部分,那麼散列表可能會將(ab)用作功能哈希映射。


爲了闡明如何涉及makadev現有答案,我不同意:

  • 「A哈希表[用途]鍵散列來查找對應的值」;因爲它假設一個鍵 - >值映射。

  • 「一個HashMap [...]。映射是抽象的,它可能不是一個表,平衡樹或嘗試或其他數據結構/映射也是可能的。錯誤,因爲哈希映射的主要機制仍然是對錶/數組中桶(索引)的哈希:某些哈希表/映射可能使用其他數據結構(數組,鏈表,樹......)來存儲在同一個桶中發生衝突的元素,但這是一個不同的問題,而不是散列表和散列映射之間區別的一部分。

+0

有效的觀點,但回到「......它只是術語」。你的HashTable不是我所說的[數據結構HashTable](https://en.wikipedia.org/wiki/Hash_table)。同樣,你的HashMap並不是我通過散列鍵進行抽象映射的意思,但更多的是我知道的HashTable,除了「不暗示支持鍵和值的區分或分離」。順便說一句。這對我來說實際上沒有意義。爲什麼你想要一個像HashTable或HashSet一樣的查找數據結構 - f.e.爲存在檢查 - 的關鍵? – makadev

+0

@makadev:「它只是術語」 - 對數據結構,設計模式等有了共同的理解。術語使我們能夠簡潔和有意義地描述和討論系統。編碼系統越多,其他人必須幫助維護,發展或使用,它就越重要。無論如何,*「爲什麼你會希望像HashTable或HashSet這樣的查找數據結構沒有區別 - 用於存在檢查 - 密鑰?」 - 一個哈希集可能會存儲在文本文件中看到的單詞:沒有獨特的關鍵字與價值 - 每個詞都是關鍵*和*值。不要說word1與word2不太一樣。 –

0

實際上HashTable成爲廢棄物,HasHMap是最好的方法來使用,因爲Hashtable是同步的。如果不需要線程安全的實現,建議使用HashMap來代替Hashtable。如果需要線程安全的高度並行實現,則建議使用java.util.concurrent.ConcurrentHashMap來代替Hashtable。

第二個區別是HashMap extends Map Interface和HashSet Dictionary接口。

相關問題