scala演算法
㈠ 大數據要學哪些課程
《大數據實訓課程資料》網路網盤資源免費下載
鏈接:https://pan..com/s/1RiGvjn2DlL5pPISCG_O0Sw
大數據實訓課程資料|雲計算與虛擬化課程資源|課程實驗指導書綜合版|機器學習與演算法分析課程資源|Spark課程資源|Python課程資源|Hadoop技術課程資源|雲計算課程資料.zip|微課.zip|演算法建模與程序示例.zip|spark課程資源.zip|hadoop課程資源.zip|實驗指導書|教學視頻|教學PPT
㈡ scala的map存儲散列演算法是字典順序嗎
不是,那個效率太低了
一、 使用 拉鏈式存儲
這個以 java 中的 HashMap 為例進行講解。 HashMap 的內部有個數組 Entry[] table, 這個數組就是存放數據的。
Entry 類的定義大致是 :
class Entry {
Object key
Object value
Entry next;
}
所以, Entry[] table 的每個元素都是一個鏈表,即 HashMap 的內部存儲是 數組 + 鏈表,即拉鏈式存儲。
當往 HaspMap 中 put(key, value) 數據時,先進行 key.hashCode() & (table.length() - 1) ,得到一個小於 table.length() 的值, 稱為 index, 則這個新的 Entry 就屬於 table[index] 這個鏈表了 ( 如果鏈表還不存在,則把這個新的 Entry 作為鏈表的頭部了 ); 然後開始從前往後遍歷 table[index] 這個鏈表,如果 key.equals( entry.key ), 那麼表示這個 key 已經有了舊值,則替換 value 的值即可;
否則,把這個新的 Entry 插入到 table[index] 鏈表的最前面.
以上就是 HashMap 的存儲方式介紹了, 而且可以知道,作為 HashMap 的 Key, 它的 hashCode() 和 equals() 方法都被使用了
二、數組存儲
1.分散的數組存儲
這個以 ThreadLocal 和 ThreadLocal.Values 類為例進行講解。 Values 類裡面有兩個變數, Object[] table, 和 mask , table 就是存儲數據的數組了,table 的長度是 2 的倍數 , mask 的值就是 table.length - 1 ; 這一點和 HashMap 的內部存儲很像。 不過 table 中的每個元素就不是鏈表了。
當往 Values 中進行 put(key, value) 時,先進行 key.hashCode & mask ,得到一個小於 table.length 的值,稱為 index (與上面的 HashMap 好像,哈哈), 然後去檢查 table[index] 的值,如果不存在,則在 table[index] 處放入 key, table[index + 1] 處放入 value; 如果已經存在了,且 key.equals( oldKey ) 不成立,即發生了沖突,那麼 index = index + 2 ( 此處是 + 2,因為 key ,value 兩個是挨著放的,一個元素占倆坑 ) ; 往下一地方找找,如果再沖突,再找,直到找到一個可插入的地方,把 table[index] = key, table[index + 1] = value;
有兩處需要注意:
key.hashCode() 必須是 2 的倍數, 否則 index 的值有可能為奇數,如此就可能發生沖突了. 可參考 ThreadLocal.hash 這個成員變數
table 內部的數據是分散著存儲的.
2.連續的數組存儲
這個以 Android 中新增的 ArrayMap 為例進行分析( 據說沒 ArrayMap 是用來替換 HashMap 的哈 ), ArrayMap 中有兩個主要變數, int[] mHashes, Object[] mArrays.
mHashes 主要是存放 key 的 hash 值的, mArrays 是用來存放數據的,它也是奇數存放 key ,偶數存放 value , key 和 value 順序排列( 這個和 TheadLocal.value 中的 table 存儲方式很像 )。 mArrays 的長度是 mHashes 的 2 倍,畢竟 mArrays 是 key, value 都要存嘛~
mHashes 中存放 key 的 hash 值,是從小到大排列的,如果有多個 key 的 hash 值有一樣的,那麼就挨著排列
當往 ArrayMap 中進行 put(key, value) 時,先 int hash = key.hashCode, 然後通過二分查找在 mHashes 中查找 hash 的位置( 如果裡面有,就返回,如果無,就先找到最接近的位置,然後進行取反操作並返回 ) index,如果 index > 0 ,那麼再去 mArrays 中 2 * index 處獲取 key 值,比對兩個 key 是否 equals(), 如果不相等,那麼再分別向上、向下查找附近相同 hash 值的 key ,看是否有 equals() 的 key, 若有,則替換,若無,則插入; 如果 index < 0 ,表示之前沒有相等 hash 的 key 插入過,那麼 index = ~index( 再次取反,就是個正數了,代辦要插入的位置), 再在 mHashes 的 index 處插入 hash, 在 mArrays 的 2 * index 處插入 key, 在 (2 * index ) + 1 處,插入 value .
注意:
mHashes 和 mArrays 在插入新數據時,都需要把插入位置後面的數據向後移動一個單位,這個對於頻繁插入、刪除的動作來說消耗比較大.
key 的 hash 大小決定了插入的順序
3.以數字為 key 的數組存儲
這類的 map 比較特殊,key 是數字類型。 這個以 Android 中新增的 SparseArray 進行分析。 SparseArray 中有兩個主要變數, int[] mKeys 和 Object[] mValues , mKeys 是存放 key 的,是個有序數組,從小到大排列; mValues 是與 mKeys 一一對應的 value 值集合. mKeys 和 mValues 的長度是相等的。
當往 SparseArray 中 put(key, value) 時,先用二分查找在 mKeys 中查找 key 所在的位置 (如果找到,返回; 如果沒有找到,則找到它應該插入的位置,取反並返回) ,記為 index, index > 0 ,則直接在 mValues[index] 處替換 value; 如果 index < 0 ,則 index = ~index, 即取反, 然後在 mKeys 的 index 處插入 key , 在 mValues[index] 處插入 value ,之前的數據自 index 處後移一個單位。
注意:
mKeys 和 mArrays 的數據插入時,都是要進行數據移動的,對頻繁插入、刪除的 map 來說消耗很大.
最後了,對它們的優缺點做些對比。
HashMap : 內存佔用較大,增、刪的效率較高,改、查的效率一般
ThreadLocal.Values : 內存佔用一般,當數據量比較小時,增刪改查的效率高;數據量大時,增刪改查效率一般
ArrayMap: 內存佔用較小,改、查的效率高,增、刪的效率較低
SparseArray : 內存佔用較小,改、查的效率高,增、刪的效率低,且主鍵是數字
最後,我們不評判哪種存儲方式好,一切都要以實際情況實際分析,找出最符合的那種存儲,哈哈~
㈢ Murmur哈希演算法
說到哈希演算法,可能大部分人都會不自覺得想到 md 和 sha 系列,在這之前,我就是這樣的,因為他們意味著流行安全和穩定。但是,最近我知道了一款另類的流行的哈希函數, 這款哈希函數廣泛應用於分布式系統-Hadoop/Lucence等等,原因就是因為它速度快而且散列效果好 ,這個哈希演算法就是 MurmurHash。
哈希系列比較流行的有三個系列,分別是 MD/SHA 和 MAC 系列,但是這些系列都是比較安全,雖然 MD5 和 SHA-1 已經被王小雲教授碰撞了,但是相對我們平時使用的直接簡單求模這種還是比較安全的,相對安全帶來的負面效果就是 計算量還是挺大的,而且不保證哈希結果的均勻 。而在分布式環境下,為了資源的合理利用,我們需要的更多是均勻,因為是內部散列的作用,所以哈希安全我們並不那麼在乎,所以在這種情境下,2008 才被發明的 MurmurHash 成為了分布式中的寵兒,深受 Google 系的喜愛。
MurmurHash 當前最新的版本是 MurmurHash3,它能夠產生出32-bit或128-bit哈希值。除了我們能夠猜到的不再使用的 mmh1 以及 還在使用的 mmh2 之外,還有好些變種,不過都是針對平台優化的。
Murmur哈希的演算法確實比較簡單,它的計算過程其實就是它的名字,MUltiply and Rotate,因為它在哈希的過程要經過多次MUltiply and Rotate,所以就叫 MurMur 了。
演算法原理可參考維基網路: https://zh.wikipedia.org/wiki/Murmur%E5%93%88%E5%B8%8C
Scala API自身是有MurmurHash演算法的實現的( scala.util.hashing.MurmurHash3 ),返回值是int,32位。
spark也廣泛採用了Murmur哈希演算法,可以看一個在sparksql中的例子,在TreeNode類中有:
之所以調用 proctHash 方法是因為TreeNode繼承自scala的 Proct 特質(有興趣的同學可以通過反編譯查看到,scala 的Case class類實現了scala.Proct和scala.Serializable介面(Proct和Serializable都是Traits)),而且有很多case class 類繼承TreeNode類。
參考:
https://liqiang.io/post/murmurhash-introction
https://leibnizhu.github.io/2017/01/19/Scala%E5%AE%9E%E7%8E%B064%E4%BD%8D%E7%9A%84MurmurHash%E5%87%BD%E6%95%B0/index.html
㈣ Scala 使用MD5加密演算法
}
㈤ 我也已經25歲其實就有轉行的打算了,想轉數據分析大數據行業,我大學本科是和這個專業相關的,
讀研期間多跟著導師做項目,有些導師手上有很多橫向項目,是參與實踐的良好途徑,其實有人讀研期間跟上班一樣忙,不要讓學校時光虛度。另外,你年齡不小了,可以在讀書期間思考以後就業的問題,讀書時成家政策也支持,當然有合適的結婚對象才行。
㈥ 做大數據分析一般用什麼工具呢
Java :只要了解一些基礎即可,做大數據不需要很深的Java 技術,學java SE 就相當於有學習大數據。基礎
Linux:因為大數據相關軟體都是在Linux上運行的,所以Linux要學習的扎實一些,學好Linux對你快速掌握大數據相關技術會有很大的幫助,能讓你更好的理解hadoop、hive、hbase、spark等大數據軟體的運行環境和網路環境配置,能少踩很多坑,學會shell就能看懂腳本這樣能更容易理解和配置大數據集群。還能讓你對以後新出的大數據技術學習起來更快。
好說完基礎了,再說說還需要學習哪些大數據技術,可以按我寫的順序學下去。
Hadoop:這是現在流行的大數據處理平台幾乎已經成為大數據的代名詞,所以這個是必學的。Hadoop裡麵包括幾個組件HDFS、MapRece和YARN,HDFS是存儲數據的地方就像我們電腦的硬碟一樣文件都存儲在這個上面,MapRece是對數據進行處理計算的,它有個特點就是不管多大的數據只要給它時間它就能把數據跑完,但是時間可能不是很快所以它叫數據的批處理。
記住學到這里可以作為你學大數據的一個節點。
Zookeeper:這是個萬金油,安裝Hadoop的HA的時候就會用到它,以後的Hbase也會用到它。它一般用來存放一些相互協作的信息,這些信息比較小一般不會超過1M,都是使用它的軟體對它有依賴,對於我們個人來講只需要把它安裝正確,讓它正常的run起來就可以了。
Mysql:我們學習完大數據的處理了,接下來學習學習小數據的處理工具mysql資料庫,因為一會裝hive的時候要用到,mysql需要掌握到什麼層度那?你能在Linux上把它安裝好,運行起來,會配置簡單的許可權,修改root的密碼,創建資料庫。這里主要的是學習SQL的語法,因為hive的語法和這個非常相似。
Sqoop:這個是用於把Mysql里的數據導入到Hadoop里的。當然你也可以不用這個,直接把Mysql數據表導出成文件再放到HDFS上也是一樣的,當然生產環境中使用要注意Mysql的壓力。
Hive:這個東西對於會SQL語法的來說就是神器,它能讓你處理大數據變的很簡單,不會再費勁的編寫MapRece程序。有的人說Pig那?它和Pig差不多掌握一個就可以了。
Oozie:既然學會Hive了,我相信你一定需要這個東西,它可以幫你管理你的Hive或者MapRece、Spark腳本,還能檢查你的程序是否執行正確,出錯了給你發報警並能幫你重試程序,最重要的是還能幫你配置任務的依賴關系。我相信你一定會喜歡上它的,不然你看著那一大堆腳本,和密密麻麻的crond是不是有種想屎的感覺。
Hbase:這是Hadoop生態體系中的NOSQL資料庫,他的數據是按照key和value的形式存儲的並且key是唯一的,所以它能用來做數據的排重,它與MYSQL相比能存儲的數據量大很多。所以他常被用於大數據處理完成之後的存儲目的地。
Kafka:這是個比較好用的隊列工具,隊列是干嗎的?排隊買票你知道不?數據多了同樣也需要排隊處理,這樣與你協作的其它同學不會叫起來,你干嗎給我這么多的數據(比如好幾百G的文件)我怎麼處理得過來,你別怪他因為他不是搞大數據的,你可以跟他講我把數據放在隊列里你使用的時候一個個拿,這樣他就不在抱怨了馬上灰流流的去優化他的程序去了,因為處理不過來就是他的事情。而不是你給的問題。當然我們也可以利用這個工具來做線上實時數據的入庫或入HDFS,這時你可以與一個叫Flume的工具配合使用,它是專門用來提供對數據進行簡單處理,並寫到各種數據接受方(比如Kafka)的。
Spark:它是用來彌補基於MapRece處理數據速度上的缺點,它的特點是把數據裝載到內存中計算而不是去讀慢的要死進化還特別慢的硬碟。特別適合做迭代運算,所以演算法流們特別稀飯它。它是用scala編寫的。Java語言或者Scala都可以操作它,因為它們都是用JVM的。
㈦ 如何將普通演算法改為支持scala out
Java 和 Scala 都支持變參方法, 寫在最後的位置上,最基本的調用方式也都是一樣的,一個個羅列過去。也可以傳入數組參數,因為變參本質上就是一個數組,就是把 ... 開始位置到最後一個參數都收納到數組中去,所以變參之所以要放在最後的位置上,且一個方法中最多隻能有一個變參類型。這里主要是對比 Scala 對變參方法的調用,基本調用法當然是沒問題的,但是在傳入數組作為變參的參數列表與 Java 相對時就稍有變化了。
另外提一下,如果想傳入 List 作為變參列表,而不是整體作為變參的第一個元素就是調用集合的 toArray() 方法轉換成一個數組傳入。
下面看 Java 中對變參方法的調用,參數列表和數組
public class JavaVarArgs {
public static void main(String[] args) {
foo("a", "b", "c");
foo(new String[]{"d", "e"});
}
public static void foo(String...params) {
System.out.println(params + " : " + params.length);
for(String s: params) {
System.out.println(s);
}
}
}
從輸出結果能夠很明白的看出變參 params 實際上就是一個數組
[Ljava.lang.String;@3f91beef : 3
a
b
c
[Ljava.lang.String;@1a6c5a9e : 2
d
e
我們知道 Scala 和 Java 之間可以互相調用,現在寫一段 Scala 代碼來調用 foo() 方法
object ScalaVarArgs {
def main(args: Array[String]) {
JavaVarArgs.foo("a", "b", "c")
// JavaVarArgs.foo(Array[String]("d", "e"))
}
}