自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

為什么用 Java:一個(gè) Python 程序員告訴你

開(kāi)發(fā) 后端
這篇文章專(zhuān)門(mén)給程序員寫(xiě)的,普通讀者慎入。原作者:Kevin Sookocheff 譯者:Celia Zhen,原文點(diǎn)擊文末鏈接。

每當(dāng)我告訴別人我一直在用Java工作時(shí),大家的反應(yīng)都是:

“納尼!Java?為啥是Java?”

說(shuō)實(shí)話,本人剛開(kāi)始的時(shí)候也是同樣的反應(yīng)。但是由于Java的類(lèi)型安全,執(zhí)行性能和堅(jiān)如磐石的工具,我漸漸地開(kāi)始欣賞Java。同時(shí)我注意到,現(xiàn)在的Java已今非昔比——它在過(guò)去的10年間穩(wěn)健地改善著。

 

[[164274]]

緣何是Java?

假 設(shè)每天都用Java的想法還沒(méi)有讓君惡心到食不下咽,我在此重申Java已非你所了解的“吳下阿蒙”了。當(dāng)Python, Ruby, 和Javascript在“動(dòng)態(tài)類(lèi)型語(yǔ)言革命”™(我自己造的名詞)中大放異彩時(shí),Java已經(jīng)悄悄地借鑒了動(dòng)態(tài)語(yǔ)言和函數(shù)式語(yǔ)言的很多吸引人的特性,同 時(shí)保留了讓Java和JVM晉級(jí)***開(kāi)發(fā)環(huán)境的先賢的努力成果。憑借大約9百萬(wàn)Java攻城獅的基層群體,Java仍然是世界上***的編程語(yǔ)言。我們 不能僅僅因?yàn)镴ava的語(yǔ)法有一點(diǎn)點(diǎn)繁瑣,就抹殺掉它所有的歷史和開(kāi)發(fā)工作。但是流行不等同于正確。下面我們就來(lái)看看是什么讓Java如此大放異彩。

Java虛擬機(jī)(JVM)

Java虛擬機(jī)(JVM) 已經(jīng)誕生20年了。在此期間,它被部署在成千上萬(wàn)的系統(tǒng)上,歷經(jīng)了無(wú)數(shù)的漏洞修復(fù)和性能提升。JVM的優(yōu)點(diǎn)有以下幾個(gè)方面。首先,JVM***支持日志和監(jiān) 控, 這使你可以很方便地監(jiān)控小到單個(gè)線程的性能指標(biāo)。JVM有世界上***化的垃圾回收器之一,你可以根據(jù)優(yōu)化吞吐量等因素靈活選擇垃圾回收算法。***,Java承諾的“write once, run anywhere”終于得已實(shí)現(xiàn)——你可以輕松地在任何架構(gòu)上部署一個(gè)Java應(yīng)用(大家還是承認(rèn)applet從來(lái)沒(méi)有過(guò)吧)。為什么用Scala和 Clojure這樣新式語(yǔ)言的聰明人會(huì)選擇JVM作為他們的執(zhí)行環(huán)境呢?——因?yàn)镴VM為你的代碼提供了一個(gè)無(wú)出其右的分發(fā)環(huán)境。拋棄像JVM這樣堅(jiān)如磐 石的工具是非常不合理的。

庫(kù)的支持

如 果你需要做點(diǎn)什么,很可能已經(jīng)有非常好用且經(jīng)過(guò)測(cè)試的Java庫(kù)在等著你。Java庫(kù)大部分都是成熟并用于實(shí)際生產(chǎn)開(kāi)發(fā)的。Google, Amazon, LinkedIn, Twitter和很多Apache項(xiàng)目都很倚重于Java。如果你用了Java,你可以參考這些庫(kù)和公司,從而借鑒偉大的程序員先驅(qū)們的工作。

類(lèi)型安全

Java的類(lèi)型系統(tǒng),雖然有時(shí)很繁瑣,但是這使得你可以寫(xiě)出“好用”的代碼。不再有運(yùn)行調(diào)試,它使你可以依靠編譯器而不是單元測(cè)試——單元測(cè)試只在 你知道bug在哪里的時(shí)候才有用。類(lèi)型安全也使你輕松的代碼重構(gòu)。Java同時(shí)支持范型——Go語(yǔ)言的***詬病之一。再者,Guava這樣的庫(kù)I以最小的 樣板和開(kāi)銷(xiāo),標(biāo)準(zhǔn)化了創(chuàng)建類(lèi)型安全的API的方法。 Java編譯器的改進(jìn)也意味著你可以在享受類(lèi)型安全的同時(shí)最小化范型所需的樣板代碼。

并發(fā)性

下面這條tweet總結(jié)了大多數(shù)動(dòng)態(tài)語(yǔ)言的并行狀態(tài):

 

[[164275]]

Most JS/Python/Ruby apps… pic.twitter.com/hkDkjdxpFH

— Reuben Bond (@reubenbond)

Java 卻有著對(duì)多線程和并行的***支持。對(duì)于Java 1.7, 許并行的immutable數(shù)據(jù)結(jié)構(gòu)令你輕松地在線程間共享數(shù)據(jù)。Akka庫(kù)更進(jìn)一步的提供了Erlang型的Actors來(lái)寫(xiě)并發(fā)和分布式的程序。我并 不是在說(shuō)Java比Go具有更好的并行支持,但是可以管理單個(gè)線程這一特性為Java應(yīng)用提供了異步性能;而Python是做不到這點(diǎn)的。

用***的Java來(lái)編程

現(xiàn)在你的心情可能已經(jīng)從惡心變成好奇了,那么我們?cè)?015年該如何寫(xiě)Java呢?從哪兒開(kāi)始呢?首先,讓我們回顧一些在Java 7和Java 8涌現(xiàn)的核心語(yǔ)言概念。

迭代

首先我們一起來(lái)看看迭代。下面是Java 8中的 for循環(huán):

  1. List<String> names = new LinkedList<>();  // compiler determines type of LinkedList 
  2. // ... add some names to the collection 
  3. names.forEach(name -> System.out.println(name)); 

或者是被大大簡(jiǎn)化的 for關(guān)鍵詞?

  1. for (String name : names) 
  2. System.out.println(name); 

這2種循環(huán)結(jié)構(gòu)都比你平時(shí)看到的for循環(huán)簡(jiǎn)潔的多。

Lambda函數(shù)

上面提到的***個(gè)for循環(huán)引入了Lambda函數(shù)這個(gè)新概念。Lamda函數(shù),語(yǔ)法記作->, 是Java語(yǔ)言的一項(xiàng)重大改革,并從函數(shù)式編程中引入了一些概念。

下面來(lái)看幾個(gè)Java中Lambda函數(shù)的例子。

  1. // Lambda Runnable 
  2. Runnable r2 = () -> System.out.println("Hello world two!"); 
  3. // Lambda Sorting 
  4. Collections.sort(personList, (Person p1, Person p2) -> p1.getSurName().compareTo(p2.getSurName())) 
  5. // Lambda Listener 
  6. testButton.addActionListener(e -> System.out.println("Click Detected by Lambda Listener")); 

這里無(wú)法詳細(xì)展開(kāi)Lambda函數(shù)這個(gè)話題——http://www.drdobbs.com/jvm/lambda-expressions-in-java-8/240166764文章提供了一個(gè)很好的切入點(diǎn)來(lái)更多地了解Lambda函數(shù)。

Java 8引入了流(stream)的概念,這為Java提供了很多現(xiàn)代函數(shù)式語(yǔ)言的特性。流是一種對(duì)集合上的一系列轉(zhuǎn)換延遲執(zhí)行的機(jī)制。比如我們來(lái)數(shù)一下以’A’開(kāi)頭的名字。首先想到的方法肯定是像下面這樣:

  1. List<String> names = new LinkedList<>(); 
  2. // ... add some names to the collection 
  3. long count = 0
  4. for (String name : names)  { 
  5. if (name.startsWith("A")) 
  6. ++count; 

如果用流,上述就可以簡(jiǎn)化為首先將集合轉(zhuǎn)換成流,然后使用函數(shù):

  1. List<String> names = new LinkedList<>(); 
  2. // ... add some names to the collection 
  3. long count = names.stream() 
  4. .filter(name -> name.startsWith("A")) 
  5. .count(); 

Java同時(shí)支持用parallelStream()來(lái)進(jìn)行流的并行處理。并行流允許流水線業(yè)務(wù)在獨(dú)立的線程同時(shí)執(zhí)行,這不僅改進(jìn)了語(yǔ)法,同時(shí)提高了性能。在大多數(shù)情況下,你可以簡(jiǎn)單得用parallelStream()替換stream()實(shí)現(xiàn)并行。

 Try-With-Resources結(jié)構(gòu)

在Java 6之前,打開(kāi)一個(gè)文件然后讀取內(nèi)容需要通過(guò)try/finally來(lái)完成:

  1. static String readFirstLineFromFileWithFinallyBlock(String path) 
  2. throws IOException { 
  3. BufferedReader br = new BufferedReader(new FileReader(path)); 
  4. try { 
  5. return br.readLine(); 
  6. finally { 
  7. if (br != null) br.close(); 

但是readLine和close都有可能拋出異常。在這種情況下,readLine拋出的異常被忽略,我們事實(shí)上并不知道readLine執(zhí)行失敗。

Java 7引入了 Try-With-Resources結(jié)構(gòu)來(lái)克服這種缺陷:

  1. static String readFirstLineFromFile(String path) throws IOException { 
  2. try (BufferedReader br = 
  3. new BufferedReader(new FileReader(path))) { 
  4. return br.readLine(); 

上例中,無(wú)論在何種失敗情況下,BufferedReader都會(huì)自動(dòng)關(guān)閉文件流。你可以通過(guò)用逗號(hào)分隔的方式,用一個(gè)try語(yǔ)句來(lái)打開(kāi)多個(gè)資源。

多重catch

以往Java只允許一個(gè)catch代碼塊對(duì)應(yīng)一個(gè)異常,這造成如下的代碼冗余:

  1. catch (IOException ex) { 
  2. logger.log(ex); 
  3. throw ex; 
  4. catch (SQLException ex) { 
  5. logger.log(ex); 
  6. throw ex; 

從Java 7開(kāi)始,你可以在一個(gè)代碼塊內(nèi)捕捉多個(gè)異常,從而減少了代碼冗余:

  1. catch (IOException|SQLException ex) { 
  2. logger.log(ex); 
  3. throw ex; 

數(shù)值字面常量(Numeric Literals)

數(shù)值字面常量可以添加下劃線是Java語(yǔ)言的新特性。這允許你使用_作為大數(shù)字的視覺(jué)分隔符。下面的例子不言自明:

  1. int thousand = 1_000; 
  2. int million  = 1_000_000; 

使用Java

看到現(xiàn)代Java的語(yǔ)法如何簡(jiǎn)化并擴(kuò)展了老Java之后,你可能已經(jīng)摩拳擦掌躍躍欲試Java了。我整理了一下第三方的工具和庫(kù),這些可以用來(lái)幫助你們上手。

Maven

Maven是一個(gè)Java構(gòu)建系統(tǒng),相比于配置,它更重視規(guī)范。Maven定義了應(yīng)用程序的結(jié)構(gòu),并提供了許多內(nèi)置函數(shù),比如運(yùn)行測(cè)試,打包應(yīng)用, 部署你的庫(kù)。使用Maven會(huì)顯著降低管理Java項(xiàng)目的認(rèn)知開(kāi)銷(xiāo)。 Maven Central是Java世界中的PyPI,為已發(fā)布的Java庫(kù)提供一站式服務(wù)。

核心函數(shù)

谷歌的Guava library提供了谷歌Java開(kāi)發(fā)中所使用的核心函數(shù)。這包括應(yīng)用于集合,緩存,基礎(chǔ)數(shù)據(jù)類(lèi)型,并發(fā),字符串處理工作,I/O等的常見(jiàn)函數(shù)。 Guava為如何設(shè)計(jì)好的的Java API提供了***的案例分析,提供最有效的從Java中推薦的***實(shí)踐的具體例子一個(gè)很好的案例, Effective Java中推薦的***實(shí)踐大部分都在Guava中得以體現(xiàn)。Guava被用于谷歌產(chǎn)品開(kāi)發(fā),進(jìn)行了超過(guò)286,000個(gè)單元測(cè)試,可謂經(jīng)受過(guò)實(shí)戰(zhàn)測(cè)試的考 驗(yàn)。

日期/時(shí)間函數(shù)

Joda-Time 已 經(jīng)成為Java實(shí)際上的標(biāo)準(zhǔn)日期/時(shí)間函數(shù)庫(kù)。事實(shí)上,Java 8幾乎一字不差地采用了Joda-Time規(guī)范。自此,我們建議使用java.time中的日期/時(shí)間函數(shù)代替Joda-Time。但是,如果你需要使用 Java 8之前的版本,Joda-Time提供了***的API。

分布式系統(tǒng)

Akka 提供類(lèi)似Erlang型的Actor模型的抽象層來(lái)編寫(xiě)分布式系統(tǒng)。Akka可以從容應(yīng)對(duì)許多種不同的故障,為編寫(xiě)可靠的分布式系統(tǒng)提供了更高層次的抽象。

Web應(yīng)用程序

需要用Java寫(xiě)一個(gè)功能完善的Web應(yīng)用程序?莫怕,有Play Framework罩著你。Play基于Akka的非阻塞I/O,提供了編寫(xiě)Web應(yīng)用程序的可擴(kuò)展的異步框架。如果想使用不那么前沿但是被廣泛應(yīng)用于產(chǎn)品的框架,請(qǐng)嘗試Jetty。

單元測(cè)試

JUnit 仍為編寫(xiě)單元測(cè)試的標(biāo)準(zhǔn)。最近幾年,JUnit的匹配器有所擴(kuò)展,允許你對(duì)集合作assertions。例如,您可以輕松地?cái)嘌砸粋€(gè)鏈表是否包含某個(gè)特殊值。

模擬框架(Mocking Framework)

Mockito是Java的標(biāo)準(zhǔn)模擬庫(kù)。它提供了所有你能想到的且對(duì)編寫(xiě)測(cè)試非常重要的模擬庫(kù)的功能。

然而不足的是。。。

目前為止,我一直在為Java說(shuō)好話,但是有些方面它還是很爛。

它還是Java!

Java的歷史遺留不可避免,Java仍然向下兼容其最早的版本,這意味著語(yǔ)言和標(biāo)準(zhǔn)庫(kù)的最爛的部分還存在著。Guava是為了令Java語(yǔ)言更討人喜歡而產(chǎn)生這個(gè)事實(shí)就證明了,Java和API存在不一致,令人困惑的問(wèn)題,有時(shí)甚至是完全錯(cuò)誤的。

JSON

Java缺少映射到JSON的object literal syntax(如Python的字典literal syntax)。正因如此,從Java對(duì)象映射到JSON有時(shí)需要繁復(fù)的對(duì)象實(shí)例化和映射,反之亦然。目前有各種JSON庫(kù)在這個(gè)領(lǐng)域競(jìng)爭(zhēng),Jackson是當(dāng)前的***的,但是Jackson的文檔需要進(jìn)一步完善。

模擬(Mocking)

Mockito解決了測(cè)試Java代碼中的很多痛點(diǎn),但是從像Python語(yǔ)言的靈活轉(zhuǎn)換到Java語(yǔ)言的嚴(yán)格,你需要更謹(jǐn)慎地來(lái)設(shè)計(jì)你的類(lèi)用于模擬。

REPL

我之所以喜歡Python,其中一點(diǎn)就是它可以迅速地實(shí)現(xiàn)讀取﹣求值﹣輸出循環(huán)( read-eval-print loop),從而快速評(píng)估新的想法或檢驗(yàn)假設(shè)。雖然一直有聲音說(shuō)要把讀取﹣求值﹣輸出循環(huán)添加到標(biāo)準(zhǔn)Java庫(kù),這一點(diǎn)目前還是不支持的。

語(yǔ)法累贅

雖然Java編譯器的進(jìn)步意味著明確的類(lèi)型簽名不再那么需要——尤其對(duì)于泛型——但是Java仍然比Python冗余的多。啟動(dòng)和運(yùn)行一個(gè)項(xiàng)目需要更多的樣板和開(kāi)銷(xiāo)——通常這意味更多的工作。

結(jié)論

Java擁有一個(gè)漫長(zhǎng)而傳奇的歷史,其中有好有壞。如果你已經(jīng)很多年沒(méi)有使用Java工作了,也許現(xiàn)在是一個(gè)好機(jī)會(huì)再次嘗試它。只要不是像下面這樣做:

 

 

 

責(zé)任編輯:王雪燕 來(lái)源: 董老師在硅谷
相關(guān)推薦

2018-04-10 09:17:09

NAS移動(dòng)硬盤(pán)

2018-07-06 13:58:18

程序員學(xué)習(xí)互聯(lián)網(wǎng)

2009-05-26 09:00:59

ScalaJava面向?qū)ο?/a>

2024-08-30 09:51:06

JavaPython語(yǔ)言

2010-10-09 09:20:08

.NET

2011-06-20 09:43:44

程序員

2019-08-21 15:50:11

Python程序員人生第一份工作

2011-02-14 13:05:17

PythonWeb

2020-02-22 21:51:43

程序員Microsoft SServerSQL

2015-05-18 09:23:33

2020-10-05 21:13:37

程序員技能開(kāi)發(fā)者

2014-02-26 10:59:45

程序員經(jīng)理

2018-01-29 19:33:11

程序員項(xiàng)目開(kāi)發(fā)

2011-08-30 09:45:27

程序員

2013-12-24 09:59:48

程序員管理

2009-03-13 10:45:10

程序員技術(shù)人員

2013-04-15 09:44:01

程序員

2016-04-21 17:50:26

程序員優(yōu)秀程序員

2014-01-06 09:33:32

程序員管理

2021-07-01 07:43:41

項(xiàng)目程序員代碼
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)