Java之父James Gosling:你需要的軟件可靠性越高,靜態類型語言的幫助就越大

{"type":"doc","content":[{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"James Gosling,通常被稱爲“Java博士”,是一名加拿大計算機科學家,以"},{"type":"link","attrs":{"href":"https:\/\/www.java.com\/zh-CN\/","title":"xxx","type":null},"content":[{"type":"text","text":"Java"}]},{"type":"text","text":"編程語言之父聞名。他完成了Java的最初設計,實現了Java最初的編譯器和虛擬機。日前,Evrone 的DevRel、Grigory Petrov對James Gosling進行了採訪。InfoQ 對訪談內容進行了翻譯,以饗讀者。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"記者:有些語言,比如Go,省略了類和繼承,而另一些語言則嘗試使用諸如Rust中的traits之類的特性。作爲一名語言設計師,您認爲一種現代的、通用的、合理的編程語言是怎樣的?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"James:"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"我想我不會放棄類的。事實上,我發現類對於創作很有效。C語言中有宏,這幾乎是一場災難,因爲宏不是語言的一部分,它們是語言之外的東西。Rust設計師嘗試在語言中很好地適配宏。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"其它語言,例如Lisp家族的所有語言,設法更優雅地適配宏,但它們有一種定義語法的方法,其中語法完全沒有語義。在大多數語言中,語法和語義是緊密相連的。作爲一個在過去寫了很多Lisp代碼的人,我對使用Lisp程序來操縱Lisp程序的技術非常着迷。這是我非常非常想念的一點。有些語言允許你用不同的方式來實現這一點,例如在Groovy中,你可以直接使用AST,而Rust則有一些語法集成的宏。但我總覺得這裏有一個有意思的研究問題:你能做得更多嗎?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"我能體會到Lisp對代碼片段進行計算來生成新代碼的感覺嗎?在Java世界裏,人們就是這樣做的。這是一個更受歡迎的功能,儘管它的層級很低。因爲人們將註解和可以使用某些不同語言生成字節碼結合使用,這是超級強大的。它會在你意想不到的地方使用,例如Jackson,並通過計算序列化程序獲得了很多性能。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"一方面,這是一種非常強大的技術。另一方面,它非常難用。事實證明它是可行的,但你能走多遠?它們可能是有限制的。所以,你可以看看像Lombok這樣的東西,它添加了一系列非常好的Java特性,但另一方面,它也顯示出了弱點,因爲這是一組應該內置的功能。而Java Community Process喪失了部分本應該有的社區性。我已經不在社區好幾年了,但到處都有一些你可以做的事情。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"記者: 這就是爲什麼我們準備了關於您創建語言的奇妙體驗的問題,而不是現代Java增強提案。我承認,五年前,我操縱了一些Java字節碼。當然,這是好事,但是用它來創建特定領域的語言有點棘手。對於Ruby,這就容易得多了。我們在Evrone的團隊精通Ruby,我們有幾十個Ruby開發人員。Ruby開發人員都很棒,但是他們需要進行很多年的培訓來學習所有的DSL“魔法”。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"James:"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"像計算代碼片段這樣的特性,在Java中很難用的原因是,Java試圖做編譯到機器代碼的所有過程,而Ruby總是被解釋執行的。當你這樣做,但你不想盡你可能獲得所有的性能時,事情就會變得很容易。但是如果你想同時獲得強大的功能和終極性能,事情就會變得困難得多。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"記者:最近,我們採訪了Ruby的作者Yukihiro Matsumoto,他提到他用最新的Ruby 3.0主版本進行了一個實驗。他試圖在不進行破壞性變更的情況下發布這個版本,看看會發生什麼。我知道Java對於破壞性更新很謹慎,所有語言在沒有不兼容的情況下演化是一個好主意嗎?或者,這是一種只能用於特定語言(如Ruby或Java)的有限制的方法?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"James:"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"這幾乎完全取決於開發者社區的規模,每一次破壞性的更新都會給開發者社區帶來痛苦。如果你沒有太多開發者,那麼破壞性更新並不是一個大問題,但你必須考慮成本效益的平衡。如果你做了一個破壞性更新,它會增加一些痛苦,但也會帶來一些好處。如果你將下標運算符從方括號改爲圓括號,則它可能完全不會爲你帶來任何好處,而是會帶來巨大的痛苦。因爲這是一個愚蠢的主意。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"在"},{"type":"link","attrs":{"href":"https:\/\/www.infoq.cn\/article\/ROKRwdAVLz9pDq2YdcQ8","title":"xxx","type":null},"content":[{"type":"text","text":"JDK 9"}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"中,存在一個變化,這是引入的爲數不多的破壞性更新之一,它造成的破壞是:如果你使用一些隱藏的API,封裝機制就會混亂,那些打破封裝邊界,並以不正確的方式使用工具的人,從8遷移到9就會很痛苦。但一旦我們克服這些,平臺就有了更多創新自由。在8到9轉換的特殊情況下,這意味着可以對平臺進行分割,你實際上可以進行定製打包,從而使Java運行時環境更小。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"另一個經常讓人感到不適的地方是:如果某個功能存在bug,人們爲這個bug採取了變通方法,如果你修復了bug,你可能會打破這些變通方法。在Java世界中,確實有過這樣的例子,我們要麼決定不修復bug,要麼引入一種正確的方法,這甚至體現在硬件上。sin和cos有一個問題,它們有些錯誤的地方,因此你必須有正確和錯誤的指導說明。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"記者:二十五年前,當我開始自己的軟件開發生涯時,我寫了很多C和C++代碼。我還記得那些每月發生一次的神祕指針錯誤。調試這些bug是一種痛苦。但現在,作爲一名軟件開發者,我看到許多工具集成到我們的工作流中,例如靜態類型檢查器。現代開發者使用集成開發工具,例如NetBeans、Intellij IDEA或者Visual Studio Code。他們編寫源代碼,一個靜態類型檢查器解析程序,構建一個抽象語法樹,並檢查所有它能檢查的東西,然後在文本編輯器中高亮顯示可能的錯誤。這些技巧不僅適用於靜態類型語言,也適用於Python、Ruby和TypeScript等動態類型語言。您對我們今天使用的這些靜態類型檢查器有什麼看法?它們是我們向編寫更好的軟件邁出的一步嗎?還是我們需要在語言語法中加入更多這樣的功能?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"James:"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"嗯,兩者都有。我非常喜歡使用靜態類型系統的語言,因爲它們爲靜態類型檢查器和IDE提供了一個框架。我一生的大部分時間都是作爲一名軟件工程師度過的,對我來說,最不滿意的消磨時間的方式就是尋找那些在奇怪時間點發生的模糊bug。在bug浪費我的時間之前,我能做的任何能夠使bug消失的事情都是極好的。所以,我非常喜歡IDE可以做的任何能夠減少bug可能性的事情。因此,當我們研究動態類型語言(如JavaScript和Python)時,它們的推理框架比較少,因爲它們不一定知道任何東西的類型,它們只是猜測而已。強類型語言(如Java)爲類型檢查器提供了更嚴格的框架。在另一個層次上,有些東西可以進行全自動的定理證明。所以像Dafny這樣的系統,它有一個非常複雜的定理證明器。因此,如果你想構建一個加密算法,你將能夠從數學上證明屬性。對於某些代碼來說,這確實非常有用。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"而且這在很大程度上取決於你的目的到底是什麼。如果你是一名大學生,你正在努力完成作業,或者你是一名博士生,你正在努力畢業,那麼當你寫程序時,你的目標是它工作一次就行了,至少一次。因爲你必須做一個演示,能夠展示它,看看它是否有效。如果你在一個工業環境中,就像我大部分生涯所在的環境一樣,那麼它需要每次都能工作。一次工作和每次工作的區別是巨大的。因此,如果它只需要工作一次,那麼更具動態性的語言就可以相當好地工作。如果你必須確保它能一次又一次地工作,那麼所有的靜態類型工具能夠幫助你建立信心。但是如果你正在做的事情是,比如你是一名物理學家,你想算出一些計算的結果,它只需要運行一次。這取決於你所工作的背景。你所需要的軟件可靠性越高,靜態類型語言就越有幫助。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"記者:談一談企業和產業發展。我自己從來沒有爲機器人編程過,但我在爲數百萬人開發軟件的公司工作過,我可以比較下今天和20-25年前的情況。現在,像GitHub這樣的社交編碼平臺得到了大公司的支持,它們幫助個人開發者和企業\/行業軟件開發者進行開源開發。那麼,我們可以稱今天爲開源軟件的黃金時代嗎?您對此怎麼看?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"James:"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"我對此沒有什麼想法,你在問一個關於未來的問題。“今天是黃金時代嗎”,這個問題暗示:“它從今天走下坡路嗎?”如果今天是黃金時代,那麼明天就不會是黃金時代了。我認爲,我們正在走向黃金時代,無論黃金時代是什麼。我認爲有很多有趣的改進可以發生。目前,我們有各種各樣安全方面的危機,比如應該如何應對網絡恐怖主義等。當這種事情發生時,我不認爲現在是黃金時代。如果有某種方式,人們通過社區合作可以讓網絡恐怖主義終結——那將是黃金時代。我們拭目以待。總的來說,這確實是一個偉大的時代,但它可以變得更好。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"記者:您使用JIT(just-in-time compilation,即時編譯)創建了Java和JVM(Java Virtual Machine,Java虛擬機)。JIT提供了驚人的速度,同時保持了語言語法的功能和高級特性。許多語言都跟隨你的腳步,比如C#和JavaScript。在熱路徑上編譯和重新編譯代碼的速度接近C和C++。但許多其它語言,如Python、Ruby、PHP,都有可選的JIT,但並不流行。爲什麼不是所有語言都使用JIT來爲開發人員提供驚人的速度?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"James:"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"要想真正獲得性能提升,使用靜態類型語言會有很大幫助。對於動態類型語言,比如Python,這樣的性能提升非常困難。通常,人們要做的就是在語言中添加註解,這樣就可以得到TypeScript這樣的語言,它本質上是帶有類型註解的JavaScript。這真的很有趣,因爲JavaScript本質上是Java刪除了類型聲明。因此,TypeScript本質上是具有置換語法的Java。它們有Pascal風格的聲明。但是,如果你只是用Python快速編寫腳本,那麼很多人都會覺得聲明很煩人,因爲考慮它們的變量類型是很煩人的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"在Python和許多其它語言中,通常只有一種數字,那就是雙精度浮點數。不存在真正的整數,不存在字節和16位整數等概念上增加複雜性的東西,但這些複雜概念能提高性能。如果你有一個雙精度浮點數和一個單精度浮點數,就會存在一個認知負擔。要想做出明智的權衡,你必須瞭解一些數值分析。軟件工程師普遍對數值分析一無所知,所以他們寧願不去想它。如果你是一位使用Python的物理學家,你可能總是想要獲取所有精度。當然,除非你需要在內存中放入一個非常大的數組,其中單精度和雙精度或一個8位整數之間的差異才會非常重要。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"在我有生之年,我修了太多數值分析課程,被劣質的數值分析搞崩潰的次數太多了,因此我很在乎精度。這取決於你在這個領域的位置,而腳本語言世界中的大多數人並不關心這類問題,他們的關注點是完全不同的。而且很多人實際上並不關心性能和數字的細節,他們關心的是:“速度夠快嗎”?性能有點兒像布爾值:速度夠快,還是不夠快。對於一些人來說,這更像是調整賽車。如果你能讓一輛車每小時多跑兩三英里,那麼你更有可能贏得比賽。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"記者:我記得幾個月前,Ruby on Rails(廣受歡迎的Web框架之一)的作者David Heinemeier Hansson提到,他的雲預算中只有15%用於語言本身。其餘的是一些緩存、消息隊列、存儲等等。他告訴我們,無論Ruby有多“慢”,這都不是很重要,因爲即使Ruby快100倍,15%變成了1%,這也不會有多大變化。現代語言已經“足夠快”。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"James:"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"這很大程度上取決於你的任務在程序空間中的位置。如果你想要完成的事情實際上是由網絡和數據庫以及其它所有東西所主導,如果你一直在做RPCs,那麼你應該做的第一件事是質疑這些RPCs是否都有價值。當人們談論微服務時,它們是一件好事,但要明白它們至少比方法調用慢一百萬倍。仔細想想這其中的含義。對於很多人來說,所有的低級細節都很重要。如果你知道高併發很重要,能夠同時驅動數千個進程,進行主要的計算,如果你正在做數據庫本身或一個主要的存儲服務,那麼你真的要非常關心。因此,這完全取決於手頭的任務。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"記者:最近,我們看到很多語言都採用了協程和async\/await方案來處理網絡之類比較慢的事情。它被添加到Python、Ruby、JavaScript以及很多其他語言中。但是async\/await、協程和線程中的調度器並不是萬能的。他們也有自身的複雜性,有時它們會使軟件速度變得更慢。那麼,你如何看待這種現代的async\/await炒作?這是處理網絡的一種好方法嗎?還是我們誤用了它?我們需要看看Erlang和其它解決方案嗎?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"James:"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"這類問題的上下文很重要。協程非常好,它們從60年代就開始被採用了。最早採用協程的語言是Simula 67。Simula是一種可愛的語言。我仍然懷念它。它沒有線程,有協程,但它們執行協程的方式看起來很像線程。協程在真正的並行中神奇地避開了一些問題。對我來說,協程的一個問題是它們實際上不允許讓你利用多個處理器,這就是我很長時間沒有采用協程的原因。採用協程,你不能做真正的並行。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"因此,人們看向具有真正並行的語言(比如Erlang和Java)中的東西。你必須做的事情增加了另一層複雜性。通常情況下,處理這種複雜性的方法是非常仔細地策劃原語。在Java中,你可以用ConcurrentHashMap做的事情非常神奇。一旦你使用了一種基於協程的語言,並且你試圖利用多個處理器,如果你做了大量協程操作,而你並沒有足夠的處理器,那麼你只會使一個處理器飽和。你真的很想使用多個處理器,因爲世界上已經沒有單核處理器了,對吧?每樣東西都有很多內核,如果你真的想在一個問題上同時使用你所有的計算機處理器,你只需要克服和處理真正多線程所固有的複雜性。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"然後是風格問題。想象你可以說“await這”和“await那”的環境,它們做了這個透明的控制反轉,你只能被動屈服。雖然能使你的語法看起來非常像真正的線程。但這意味着,在真正的線程中,有許多棘手的問題需要避免。所以,如果你說“a = a + 1”,你知道這是在運算的中間,你不會被打斷,所以你不必做同步。但還有一些其它地方,它不再採用這種風格,而是變成了一種事件導向的風格,你做你自己的事情,然後你把一個事件處理器插入到某個東西中來處理事情完成後發生的事情。這往往是JavaScript的主要風格。這很好用,但可能有點笨重。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"當我在70年代初發現Simula時,它有一種自然的風格。你只需要編程,你可以把你的計算看做是獨立的東西,而其他事物是否與之交織對你來說是透明的。我發現,作爲一種概念模型,它比事件編程要乾淨地多。它很難在幕後實現,但通常更容易思考。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"記者:Simula畢竟是第一個面向對象的語言。我從沒有機會使用過它,但我看過文檔,它看起來很有特色。然而,如果我們查看一些現代語言,比如Ruby,併發模型是複雜的:我們有進程,進程中有單獨的解釋器,單獨的解釋器中有線程,線程中有核心例程——就像一個俄羅斯套娃。如果你允許的話,現在問一個非技術性問題。當我們談論不同的語言時,在你個人看來,現在哪一種語言是適合研究生院或大學教授軟件開發新手作爲他們第一語言的最佳語言?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"James:"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"我顯然會有偏見。很長一段時間,"},{"type":"link","attrs":{"href":"https:\/\/www.infoq.cn\/article\/wayrJRwdR8Gkvh4rZMqM","title":"xxx","type":null},"content":[{"type":"text","text":"Java"}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"一直成功地作爲軟件開發新手的第一語言。但我學的第一種編程語言是PDP-8彙編代碼,大致與Fortran並行使用。你可以教人們任何東西。其中一些語言比其它語言更容易理解,但這很大程度上取決於一個人最終的職業道路。如果你想成爲一名全面的軟件開發人員,構建大型的高性能的系統,那麼其它語言很難打敗在JVM上運行的語言。實際上,我不在乎你在JVM上使用哪種語言。我的意思是,Scala和Kotlin都很好。Clojure真的很有趣,但你必須用不同的方式思考。如果你是一名物理系學生,Python就可以了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"我認爲你選擇哪一種語言並沒什麼大不了的。雖然很多人堅持他們所學的第一語言,並從事相關的工作,但如果你能讓人們學習多種語言並反覆切換是更好的。我認爲,每個大學都應該爲學生開設的一門課程是編程語言比較課程。在這學期裏,你有五個不同編程語言的作業,讓學生們能夠習慣快速學習它們,並思考哪一種編程語言更好。很久以前,我參加了其中一門課程,每次作業我都用了最糟糕的語言,用COBOL進行數值計算。那只是娛樂!甚至我還用Fortran進行符號操作。令人驚訝的是,我仍得了個A。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"記者:下一個問題是關於模式匹配。最近,它在Python和Ruby中大放異彩,許多提案都有不同的語言版本。我們查看了開發者白皮書,他們並不完全確定模式匹配在現代高級語言中的角色。這種模式匹配思想,您認爲它如何適合那些使用Java、Python、Ruby或某種高級語言的普通現代開發人員?我們真的需要模式匹配嗎,或者它只是針對特定用例的特定語法?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"James:"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"首先,我認爲編程語言中的術語“模式匹配”有點誤導。因爲當我聽到“模式匹配”這個短語,我想到的是正則表達式,無論是字符串上的正則表達式,還是樹上的正則表達式。也許模式與樹的形狀匹配,隨便什麼。但是回到Simula。Simula有一個inspect語句,這個inspect語句幾乎完全與許多模式匹配語句相同。也就是說,inspect語句是一個case語句,其中case標籤是類型名,你可以說:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"Inspect P\n When Image do Show;\n When Vector do Draw;"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"你可以將其視爲一個case語句,基於類型的cases。大多數模式匹配語言提案都是這種類似的東西。就我個人而言,我很懷念這一點,我真的很喜歡。特別是如果發生的事情有點像C語言中的隱式轉換,如果你說“inspect P When Image P do P”,那麼case語句中的P現在就是switch標籤的類型。在一種類似C的語法的語言中,你總是以強制轉換結束。它看起來像:“如果a是x的實例,否則如果a是y的實例,那麼……”Simula中的“inspect”語句非常漂亮,我喜歡它,而這些模式匹配提案和語言特性中許多都是這樣的。你可以稱它爲“類型實例(type case)”,但是如果你稱它爲“模式匹配”,並且它的功能比正則表達式小,那麼它就會讓人產生誤解,有點像虛假廣告。但是,作爲一種功能,我認爲它很棒。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"記者:Kotlin和許多其它語言,例如Clojure或者Scala,在您創建的現有Java虛擬機、庫和框架的生態系統,以及現有代碼的基礎上蓬勃發展。這些語言都面臨什麼挑戰?有什麼東西能把它們團結起來嗎?這對它們來說有困難嗎?當它們試圖用某種不同的語法熱轉換Java語法時,它們面臨哪些困難?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"James:"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"這取決於你想要做什麼。Java虛擬機的一個特點是它內置了許多安全性和可靠性的概念。它們主要與內存模型的完整性有關,所以你不能構造一個指針。像C這樣的語言,如果你沒有構造指針的能力,你就不能實現C。有些虛擬機沒有嚴格的安全模型。如果你有一個安全的虛擬機,有些地方你就無法實現。但是有些人已經建立了不嚴格安全的虛擬機,沒有內存分配模型。如果您想在C和Kotlin之間實現互操作性,您必須放棄一些安全性和可靠性。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"所以,這取決於你想要到哪裏。當然,在Java誕生之初,我的個人規則之一是:我不想調試另一個可怕的內存損壞bug。我已經浪費了太多時間在晦澀難懂的內存損壞bug上。而且這是循環中的一個逐次錯誤,恰好從數組末尾的一個條目中刪除,直到數百萬次操作之後你纔會找出問題。所以這取決於你對什麼感到舒服。你知道,有些人認爲花時間做這些事很有男子氣概。也有人喜歡使用vi,它在70年代是一個偉大的編輯器,在80年代也是一個出色的編輯器。"},{"type":"text","text":"加油,夥計們!"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"原文鏈接:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/evrone.com\/james-gosling-interview","title":null,"type":null},"content":[{"type":"text","text":"https:\/\/evrone.com\/james-gosling-interview"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章