摘要:中使用那一套,線程的速度,你知道的而對于分布式數據流來說,本來就是并行的,這種參數意義就不大了。函數種類一般作用在數據流上的函數,會分為兩類。中的程序是實現在數據流上的。可以看作是的更新日志,數據流中的每一個記錄對應數據庫中的每一次更新。
最近入職一個有趣的年輕同事,提交了大量大量的代碼。翻開git記錄一看,原來是用了非常多的java8的語法特性,重構了代碼。用的最多的,就是map、flatMap之類的。 但是其他小伙伴不愿意了,雖然有的人感覺代碼變的容易懂了,但有更多的人感覺代碼變的很晦澀。 那感覺就像是:脫了褲子放屁,多此一舉。
這些函數的作用域,根據級別,我覺得可以分為三類。簡直是無所不在。
不要過分使用
我也不知道這些函數是從什么時候流行起來的,但它們與函數編程的關系肯定是非常密切的。好像是2004年的Scala開始的。
沒什么神奇的,它們全部是語法糖,作用是讓你的程序更簡潔。你要是想,完全可以用多一點的代碼去實現。不要為了炫技刻意去使用,物極必反,用不好的話,產生的效果會是非常負面的。比如java,它并不是一門函數編程語言,那么lambda就只是一種輔助;而你用java那一套去寫Lisp代碼的話,也只會不倫不類。
但語言還是要融合的,因為潮流就是這樣。不去看他們背后的設計,我們僅從api的語義表象,橫向看一下它們所表達的東西。
我們首先看一下其中的共性(注意:邏輯共性,并不適合所有場景),然后拿幾個典型的實現,看一下在這個星球上,程序員們的表演。
這些抽象的概念這些函數的作用對象,據說是一種稱之為流的東西。那流到底是一種什么東西呢?請原諒我用一些不專業的話去解釋。
不論是在語言層面還是分布式數據結構上,它其實是一個簡單的數組。它有時候真的是一個簡單的數組,有時候是存在于多臺機器的分布式數組。在下文中,我們統稱為數組流。
我們簡單分為兩類。
語言層面的:比如Java的Stream 分布式層面的:比如Spark的RDD
它們都有以下幾個比較重要的點。
函數可以作為參數C語言當然是沒問題的,可以把函數作為指針傳入。但在不久之前,在Java中,這還得繞著彎子去實現(使用java概念中的Class去模擬函數,你會見到很多Func1、Func0這樣奇怪的java類)。
函數作參數,是使得代碼變得簡潔的一個必要條件。我們通常的編程方法,大多是順序執行一些操作。
array = new Array()
array = func1(array)
if(func2(array)){
array = func3(array)
}
array = func4(array)
而如果函數能夠當參數,我就能夠盡量的將操作平鋪。最終,還是要翻譯成上面的語句進行執行的。
array = new Array() array.stream() .map(func1) .filter(func2) .flatMap(func3) .sorted(func4) ...
編程模式完全變了,函數也有了語義。
sequential & parallel如果我們的數組流太大,對于單機來說,就有順序處理和并行處理兩種方式。
通常,可以通過parallel函數進入并行處理模式。對于大多數本地操作,開了并行不見得一定會快。 java中使用ForkJoin那一套,線程的速度,你知道的...
而對于分布式數據流來說,本來就是并行的,這種參數意義就不大了。
函數種類一般作用在數據流上的函數,會分為兩類。
轉換。Transformation 動作。Action
轉換,典型的特點就是lazy。 只有action執行的時候,才會真正參與運算。所以,你可以認為這些轉換動作是一套被緩沖的操作。典型的函數如:map、flatMap等。它們就像烤串一樣被串在一起,等著被擼。
動作。真正觸發代碼的運行,上面的一系列轉換,也會像開了閘的洪水一樣,一瀉而下。典型的如reduce函數,就是這種。
map & reduce以上的描述也不盡然,比如python的map,執行后就可以輸出結果。這讓人很沒面子啊。
談到map和reduce,大家就不約而同的想到了hadoop。然而,它不僅僅是大數據中的概念。
對于它倆的概念,我們僅做下面兩行介紹。
將傳入的函數依次作用到序列的每個元素,并把結果作為新的數組流返回。
reduce類似于一個遞歸的概念。最終會歸約成一個值。看看這個公式:)
reduce([p1,p2,p3,p4],fn) = reduce([fn(p2,p4),fn(p1,p3)])
具體還是看谷歌的經典論文吧。
《MapReduce: Simplified Data Processing on Large Clusters》 ai.google/research/pu…
你能訪問么?:)
map & flatMap這兩個函數經常被使用。它們有如下區別:
把數組流中的每一個值,使用所提供的函數執行一遍,一一對應。得到元素個數相同的數組流。
flat是扁平的意思。它把數組流中的每一個值,使用所提供的函數執行一遍,一一對應。得到元素相同的數組流。只不過,里面的元素也是一個子數組流。把這些子數組合并成一個數組以后,元素個數大概率會和原數組流的個數不同。
程序員們的表演 java8種的Stream
java8開始,加入了一個新的抽象,一個稱之為流的東西:Stream。配合lambda語法,可以使代碼變的特別的清爽、干凈(有木有發現都快成了Scala了)。
一個非常好的向導: stackify.com/streams-gui…
Spark的RDD操作spark的核心數據模型就是RDD,是一個有向無環圖。它代表一個不可變、可分區、其內元素可并行計算的集合。 它是分布式的,但我們可以看下一個WordCount的例子。
JavaRDD textFile = sc.textFile("hdfs://...");
JavaPairRDD counts = textFile
.flatMap(s -> Arrays.asList(s.split(" ")).iterator())
.mapToPair(word -> new Tuple2<>(word, 1))
.reduceByKey((a, b) -> a + b);
counts.saveAsTextFile("hdfs://...");
多么熟悉的Api啊,你一定在Hadoop里見過。
Flink 的 DataStreamFlink程序是執行分布式集合轉換(例如,filtering, mapping, updating state, joining, grouping, defining windows, aggregating)的常規程序。Flink中的DataStream程序是實現在數據流上的transformation。
我們同樣看一下它的一段代碼。
DataStream> counts =
// split up the lines in pairs (2-tuples) containing: (word,1)
text.flatMap(new Tokenizer())
// group by the tuple field "0" and sum up tuple field "1"
.keyBy(0).sum(1);
kafka stream的操作
kafka已經變成了一個分布式的流式計算平臺。他抽象出一個KStream和KTable,與Spark的RDD類似,也有類似的操作。
KStream可以看作是KTable的更新日志(changlog),數據流中的每一個記錄對應數據庫中的每一次更新。
我們來看下它的一段代碼。
KTable wordCounts = textLines
.flatMapValues(value -> Arrays.asList(value.toLowerCase().split("W+")))
.groupBy((key, value) -> value)
.count();
wordCounts.toStream().to("streams-wordcount-output", Produced.with(stringSerde, longSerde));
RxJava
RxJava是一個基于觀察者模式的異步任務框架,經常看到會被用到Android開發中(服務端采用的也越來越多)。
RxJava再語言層面進行了一些創新,有一部分忠實的信徒。
語言層面的lambda當然,對Haskell這種天生的函數編程語言來說,是自帶光環的。但其他的一些語言,包括腳本語言,編譯性語言,也吸收了這些經驗。
它們統稱為lambda。
Python作為最流行的腳本語言,python同樣也有它的lambda語法。最基本的map、reduce、filter等函數同樣是存在的。
JavaScriptjs也不能拉下,比如Array.prototype.*()等。它該有的,也都有了。
End另外還有很多很多,就不一一羅列了。話說,這些函數可以申請專利么?我很喜歡,雖然我很少用。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/6824.html
摘要:中使用那一套,線程的速度,你知道的而對于分布式數據流來說,本來就是并行的,這種參數意義就不大了。函數種類一般作用在數據流上的函數,會分為兩類。中的程序是實現在數據流上的。可以看作是的更新日志,數據流中的每一個記錄對應數據庫中的每一次更新。最近入職一個有趣的年輕同事,提交了大量大量的代碼。翻開git記錄一看,原來是用了非常多的java8的語法特性,重構了代碼。用的最多的,就是map、flatM...
摘要:中使用那一套,線程的速度,你知道的而對于分布式數據流來說,本來就是并行的,這種參數意義就不大了。函數種類一般作用在數據流上的函數,會分為兩類。中的程序是實現在數據流上的。可以看作是的更新日志,數據流中的每一個記錄對應數據庫中的每一次更新。最近入職一個有趣的年輕同事,提交了大量大量的代碼。翻開git記錄一看,原來是用了非常多的java8的語法特性,重構了代碼。用的最多的,就是map、flatM...
摘要:來總結一下我遇到的坑,或者說我為什么不在推薦使用。但是功利的看,在解決異步處理這個問題上,的確是投入高,收獲少。這種在輕量級應用,或者一些小型異步處理比如數據埋點等等行為中,都顯得過于龐大。距離上一次更新也有一段時間了,其實這篇文章我早就想寫,礙于一直沒來得及總結(懶)。所以一直沒有成文。來總結一下我RxJava遇到的坑,或者說我為什么不在推薦使用RxJava。 相信熟悉或者關注我的朋友,絕...
摘要:前兩篇的使用一基本用法的使用二介紹了的基本用法,對還不了解的請先看以上兩篇。這篇為大家講解中和的使用。注意對這些發射的數據做的是合并操作,因此它們可能是交錯的。如果要保證順的的話,可以使用。其他操作符除了和之外,還有其他操作符以供使用。 前兩篇Android RxJava的使用(一)基本用法、Android RxJava的使用(二)Action介紹了RxJava的基本用法,對Rxjav...
閱讀 1267·2023-04-25 23:22
閱讀 1667·2023-04-25 20:04
閱讀 2643·2021-11-22 15:24
閱讀 2801·2021-11-11 16:54
閱讀 1878·2019-08-30 14:03
閱讀 1480·2019-08-29 16:35
閱讀 1699·2019-08-26 10:29
閱讀 2642·2019-08-23 18:01