摘要:的解法程序猿的世界,代碼說明一切,我們直接上代碼吧,算法的入口是一個名為函數不知道能完全看懂上面代碼的人有多少。程序猿的語言世界真的好復雜
首先聲明一點,這篇短文不是要挑起語言之間的關于孰優孰劣的論戰,只是希望通過一個小需求,讓大家能夠對比體會一下函數式編程和面向對象編程的差異(包括理念和語法上的)。
要解決一個什么問題
Clojure 是什么?
Clojure 是運行在 Java 虛擬機(JVM)上的一種 Lisp 方言,她比 Common Lisp 更強調純函數式編程,同時擁有復雜的「宏」。具體可以看 CSDN 上的一篇介紹文章 現實世界的LISP:Clojure語言初探 和知乎上的討論 請評價一下Clojure語言的設計
我們在開發過程中經常會碰到這個需求,要對一個字符串進行哈希,然后當成 key 存入 redis。我們準備使用 Java 的 SHA-512 哈希算子來做第一步運算,并且把結果再做一次 Base64 編碼轉換。
好的,那我們接下來就看看在兩種語言中如何做到這一點吧。
Clojure 的解法程序猿的世界,代碼說明一切,我們直接上代碼吧,算法的入口是一個名為 hash-name 函數:
(defonce ^:private hash-key "universal_redis_hash_key") (defn hash-name [k] (.substring ^String (:password (digest hash-key k)) 0 4)) (defn digest ([salt passwd] (digest "SHA-512" 512 salt passwd)) ([hashalg iterations salt passwd] (let [jhash (MessageDigest/getInstance hashalg) new-pass (b64-encode (digester jhash salt passwd iterations))] {:salt salt :password new-pass}))) (defn- digester [^MessageDigest hasher ^String salt ^String pw-clear iter] {:tag String} (letfn [(hashme [hv] (letfn [(oneround [hv] (do (.reset hasher) (.digest hasher hv)))] (nth (iterate oneround hv) iter)))] (.reset hasher) (.update ^MessageDigest hasher (.getBytes salt)) (.update ^MessageDigest hasher (.getBytes pw-clear)) (hashme (.digest hasher)))) (defn b64-encode [^bytes b] {:tag String} (Base64/encodeBase64String b))
不知道能完全看懂上面代碼的人有多少。要是我們用Java寫出來的話,相信很多人會拍著腦袋:原來如此!
Java 的解法還是一樣,直接上代碼,這里只有一個函數 hashName:
private final static String hashKey = “universal_redis_hash_key"; public static String hashName(String salt, String pw, int iter) { try { MessageDigest digest = MessageDigest.getInstance("SHA-512"); digest.reset(); digest.update(salt.getBytes()); digest.update(pw.getBytes()); byte[] temp = digest.digest(); for (int i = 0; i < iter; i++) { digest.reset(); temp = digest.digest(temp); } String result = Base64.encodeBase64String(temp); return result.substring(0, 4); } catch (Exception ex) { ex.printStackTrace(); } return ""; }結論
對這兩門語言的看法,或許有人會從通俗易懂上進行比較,有人會從優雅嚴謹性上進行批判,我沒有任何傾向性,這就是一個仁者見仁智者見智的問題。
我只想補充說一下這種對比的由來。我司的程序員中 Clojure 粉較多,很多程序都是用 Clojure 寫的。最近要跟其他公司的小伙伴合作搭一個服務,兩邊都需要采用同樣的關鍵字哈希算法。我找到一塊我們的實現片段,發了過去。但是對方不懂 Clojure,他們使用的是 Ruby;我懂 Clojure 但是不懂 Ruby,兩個人都快沒法交流了。最后我們一商量,大家都能懂 Java,所以我先把 Clojure 代碼翻譯成 Java 代碼,然后他再轉換成 Ruby 代碼,這樣兩邊的系統就對接上了。程序猿的語言世界真的好復雜!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/64123.html
摘要:我們的目標是建立對每一種語言的認識,它們是如何進化的,未來將走向何方。有點的味道是堅持使用動態類型,但唯一還收到合理擁泵的編程語言,然而一些在企業的大型團隊中工作的開發者擇認為這會是的一個缺陷。 為什么我們需要如此多的JVM語言? 在2013年你可以有50中JVM語言的選擇來用于你的下一個項目。盡管你可以說出一大打的名字,你會準備為你的下一個項目選擇一種新的JVM語言么? 如今借助來自...
摘要:如果應用發生了內存泄漏問題,就會進行檢測生成報告,并且提供切實可行的方案去掉這個問題。主要特性實時的內存泄漏檢測和告警一份包含時間,內存大小,速度以及泄漏事件的重要級別的報告。 在這篇文章中我們決定收集制作一個關于這類工具的簡略名單,他們中的大多數工具只是最近推出的。其中一些工具是為Java定制的,但也有一些是支持其他語言。但對于Java項目而言,他們都是非常好的,并且擁有同一個愿景:...
摘要:根據對社區和新特性的深刻理解,他創作了函數式編程一書。問你在倫敦社區的經歷是否幫助你創作了函數式編程這本書絕對是這樣。我認為引入函數式編程會為很多編程任務提供方便。問之前的是面向對象的,現在全面支持函數式編程。 非商業轉載請注明作譯者、出處,并保留本文的原始鏈接:http://www.ituring.com.cn/article/199271 Richard Warburto...
摘要:而且這種現象在德國的法定節假日里更加突出。所以本文提到的這些東西都是在德國節假日里無聊的產物,對于顧問的實際工作可能幫助不大。這也是在這篇文章里介紹的眾多用搞出來的無聊的東西里唯一被官方認可的工具,囧。直接用執行里的事務碼或者函數。 國慶大假馬上就要來臨了,我們聊點輕松的話題,關于假期。 Jerry的成都同事李貝寧(Li Ben), 《SAP成都研究院李三郎:SCP Applicati...
摘要:第一節函數式范式什么是函數式編程函數式編程英語或稱函數程序設計,又稱泛函編程,是一種編程范型,它將電腦運算視為數學上的函數計算,并且避免使用程序狀態以及易變對象。 第一節 函數式范式 1. 什么是函數式編程 函數式編程(英語:functional programming)或稱函數程序設計,又稱泛函編程,是一種編程范型,它將電腦運算視為數學上的函數計算,并且避免使用程序狀態以及易變對...
閱讀 3870·2021-09-10 11:22
閱讀 2325·2021-09-03 10:30
閱讀 3660·2019-08-30 15:55
閱讀 1873·2019-08-30 15:44
閱讀 840·2019-08-30 15:44
閱讀 581·2019-08-30 14:04
閱讀 3041·2019-08-29 17:18
閱讀 1262·2019-08-29 15:04