為什么Java仍很滋潤(rùn)的活著?
我寫這篇很長(zhǎng)的文章是對(duì)文章"為什么Java即將死去"的回應(yīng)。我對(duì)此文本的評(píng)論名列前茅,我覺得我必須做出一個(gè)完全反對(duì)的聲明,這應(yīng)該返回平衡。
對(duì)于作者的嘗試,最好的簡(jiǎn)短答案是Coder:76的答案,它獲得了數(shù)百次鼓掌:
"在過去的15年中,Java對(duì)那些希望引起關(guān)注的編程博客作者來說已經(jīng)死了。" |
很難不同意。
" Java快死了"的說法有什么問題?
"為什么Java即將死去"的文章收到了70多個(gè)評(píng)論,其中大多數(shù)是關(guān)鍵評(píng)論,每個(gè)評(píng)論都有成千上萬(wàn)的掌聲。為什么這么多人做出如此消極的反應(yīng)?原因看起來很簡(jiǎn)單:該文章以挑釁的方式撰寫,包含許多有爭(zhēng)議的陳述,對(duì)于使用Java的人來說,這些陳述遠(yuǎn)非現(xiàn)實(shí)。讓我們來看看其中的一些。
"例如,在這里,Spring可以在后臺(tái)設(shè)置自動(dòng)裝配(bean注入),這是可以理解的,但是Lombok在應(yīng)用程序上下文中的位置又是如何在兩者之間協(xié)調(diào)消息傳遞的呢?" |
對(duì)于使用上述技術(shù)的人們來說,這種說法是錯(cuò)誤的。Lombok是一個(gè)編譯時(shí)庫(kù),而Spring是一個(gè)運(yùn)行時(shí)庫(kù)。它們?cè)趹?yīng)用程序生命周期的不同時(shí)間以不同級(jí)別工作,并且不直接交互。對(duì)于作者的問題" Lombok在應(yīng)用程序上下文中住哪兒?"的正確答案。是"沒有"。
" Java的重點(diǎn)似乎仍然是愚蠢的規(guī)則,這些規(guī)則規(guī)定了應(yīng)使用的類名,應(yīng)使用的包以及變量是私有的還是受保護(hù)的。說真的,誰(shuí)在乎?" |
從事大型,長(zhǎng)期項(xiàng)目的人會(huì)照顧他們。這些規(guī)則對(duì)他們來說并不愚蠢。
"相比之下,'我們都在這里成年'實(shí)際上是Python對(duì)該語(yǔ)言中缺少訪問說明的官方回應(yīng)。" |
毫無疑問,團(tuán)隊(duì)中的某人會(huì)認(rèn)為其他人不是成年人,這是一個(gè)淺薄的主意。問題在于,由大型團(tuán)隊(duì)創(chuàng)建的,持續(xù)時(shí)間很長(zhǎng)的大型項(xiàng)目需要規(guī)則。否則,它們將失敗。大型項(xiàng)目就像一座大城市:它需要建筑基礎(chǔ),規(guī)劃,關(guān)注點(diǎn)分離,私有和公共區(qū)域。如果熟練的程序員將語(yǔ)言結(jié)構(gòu)分為公共結(jié)構(gòu)和私有結(jié)構(gòu),則他們很可能會(huì)創(chuàng)建"街道",以正確的方式領(lǐng)導(dǎo)其他人,從而節(jié)省時(shí)間,并將輔助基礎(chǔ)設(shè)施隱藏在"地下",以至于沒有人迷路。
"為什么Java即將死去"一文中還有很多爭(zhēng)議性的陳述,但是我的目的不是詳細(xì)分析。我想做的是利用這次機(jī)會(huì)來談?wù)揓ava本身的現(xiàn)代狀態(tài)。
多年來,Java是編程語(yǔ)言中的首選,同時(shí)也是批評(píng)家的首選。不是因?yàn)樗缓?,而是因?yàn)樗且患笫?,如果想看起來比?shí)際的大,必須說出反對(duì)某件大事的字眼,并祈求有人注意。從這個(gè)意義上講,Java是一個(gè)很好的目標(biāo)。但是現(xiàn)在呢?Java是否仍然是一件大事,還是像某些人所說的那樣"瀕死"?讓我們討論最重要且值得商榷的主題,以便找出答案。
語(yǔ)法
> Image by Harry Fabel from Pixabay
Java的語(yǔ)法通常被批評(píng)最多:"不夠簡(jiǎn)潔","不適合現(xiàn)代任務(wù)","太多樣板"等。對(duì)這些"參數(shù)"的唯一正確答案是顯示代碼。我將不在這里討論特殊的語(yǔ)法功能。有很多詳細(xì)的指南,涵蓋了Java語(yǔ)法的所有細(xì)微差別。相反,我僅選擇了五個(gè)代碼片段供您了解現(xiàn)代Java如何針對(duì)不同的實(shí)際任務(wù)進(jìn)行操作。
- import static spark.Spark.*;
- public class HelloWorld {
- public static void main(String[] args) {
- port(80);
- get("/hello", (request, response) -> "Hello World");
- }
- }
上述代碼使用HTTP GET方法和/ hello上下文路徑在端口80上使用Spark Java啟動(dòng)一個(gè)簡(jiǎn)單的Web服務(wù)器,當(dāng)請(qǐng)求時(shí)該上下文路徑將返回常量字符串。非常簡(jiǎn)單明了,不是嗎?
- ...
- OrderRepository orders;
- QOrder qorder = QOrder.order;
- DateTimeFormatter yyyyMMdd = DateTimeFormatter.ofPattern("yyyy-MM-dd");
- public Iterable<Order> getShopOrdersByDate(ShopId id, ZonedDateTime date){
- return orders.findAll(
- qorder.shopId.eq(id).and(qorder.date.eq(yyyyMMdd.format(date)))
- );
- }
- ...
上述代碼結(jié)合使用Querydsl和Spring Data從SQL數(shù)據(jù)庫(kù)中獲取信息。一切看起來都非常簡(jiǎn)單:方法getShopOrdersByDate返回具有特定日期和特定日期格式的特定商店的訂單。有趣的部分:這里沒有SQL,只有Java構(gòu)造,以后會(huì)在庫(kù)中將其轉(zhuǎn)換為安全的SQL。這意味著查詢本身是類型安全的,并且在編譯時(shí)(而不是在運(yùn)行時(shí)中)被可靠地檢查。而且,IDE可以像其他Java代碼一樣幫助您完成自動(dòng)補(bǔ)全,使您的生活更輕松。開箱即用地支持大量數(shù)據(jù)庫(kù),例如PostgreSQL,MySQL,Oracle甚至MongoDB。另外,如果要交換查詢代碼,則無需更改查詢代碼。
- import java.nio.file.Files;
- import java.util.stream.Stream;
- import static java.nio.file.Paths.get;
- import static java.util.stream.Collectors.*;
- public class Example {
- public static void main(String[] args) throws Exception {
- List<String> fileLines = Files.readAllLines(get("huge.txt"));
- String fileStats = fileLines.parallelStream()
- .flatMap(line -> Stream.of(line.split("\\s+")))
- .filter(word -> !"dumb".equalsIgnoreCase(word))
- .collect(groupingBy(word -> word.charAt(0), counting()))
- .entrySet().parallelStream()
- .map(letterStats -> letterStats.getKey() + ":" + letterStats.getValue())
- .collect(joining("\n"));
- System.out.println(fileStats);
- }
- }
這里沒有其他庫(kù),只有純Java。從巨大的文件中讀取所有行,將其分成單獨(dú)的單詞,過濾出啞詞以保持所有內(nèi)容的清潔,將單詞按第一個(gè)字母分組,計(jì)算每個(gè)組中的單詞數(shù),創(chuàng)建結(jié)果組的字符串表示形式并進(jìn)行計(jì)數(shù),打印結(jié)果??勺x性強(qiáng)且易于維護(hù)。當(dāng)然,所有事情都是在并行線程中完成的,以便于開箱即用地進(jìn)行適當(dāng)?shù)募铀伲员隳男?6核怪物可以證明其成本合理。在里面裝有Java 15的4核筆記本電腦上,此代碼平均需要6秒鐘才能對(duì)填充有隨機(jī)單詞的1.2 Gb文本文件執(zhí)行。對(duì)于這種文件大小和直接的未經(jīng)優(yōu)化的代碼來說還不錯(cuò)。
- ...
- public MultiLayerNetwork createModel() {
- return new MultiLayerNetwork(new NeuralNetConfiguration.Builder()
- .regularization(true).l2(0.001)
- .learningRate(0.01)
- .weightInit(WeightInit.XAVIER)
- .activation(Activation.RELU)
- .optimizationAlgo(STOCHASTIC_GRADIENT_DESCENT)
- .updater(new Nesterovs(0.9))
- .list()
- .layer(convolution(5, 25).nIn(3).build())
- .layer(maxPooling(2).build())
- .layer(convolution(3, 50).build())
- .layer(maxPooling(2).build())
- .layer(convolution(3, 100).build())
- .layer(maxPooling(2).build())
- .layer(dense(200).dropOut(0.5).build())
- .layer(dense(200).dropOut(0.5).build())
- .layer(outputClassification(10))
- .setInputType(convolutionalFlat(28, 28, 3))
- .backprop(true).pretrain(false)
- .build());
- }
- ConvolutionLayer.Builder convolution(int filterSize, int filterCount) {
- return new ConvolutionLayer.Builder(filterSize, filterSize)
- .activation(IDENTITY).nOut(filterCount);
- }
- SubsamplingLayer.Builder maxPooling(int size) {
- return new SubsamplingLayer.Builder(PoolingType.MAX)
- .kernelSize(size, size).stride(size, size);
- }
- DenseLayer.Builder dense(int size) {
- return new DenseLayer.Builder().nOut(size);
- }
- OutputLayer outputClassification(int numOfClasses) {
- return new OutputLayer.Builder(LossFunction.MCXENT)
- .nOut(numOfClasses).activation(SOFTMAX).build();
- }
- ...
這個(gè)簡(jiǎn)單的示例顯示了在學(xué)習(xí)階段之前使用Dl4j準(zhǔn)備神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)的階段。那些處于深度學(xué)習(xí)領(lǐng)域的人將輕松識(shí)別許多熟悉的單詞。沒什么特別的。是的,您通常可以使用Java進(jìn)行深度學(xué)習(xí)和機(jī)器學(xué)習(xí)。
- import lombok.AllArgsConstructor;
- import lombok.Data;
- @Data
- @AllArgsConstructor
- public class User {
- String name;
- String surName;
- List<ContactInfo> contacts;
- }
你討厭樣板嗎?然后使用lombok。此代碼片段顯示了功能齊全的數(shù)據(jù)類,其中正確完成的所有字段上均具有g(shù)etter,setter,equals,hashcode,toString,最后是AllArgsConstructor。如果愿意,您當(dāng)然可以覆蓋其中的任何一個(gè)。
來自Java生態(tài)系統(tǒng)外部的人們通常會(huì)爭(zhēng)辯說" Lombok使Java不是Java。"我不同意:Lombok是Java。它是現(xiàn)代Java生態(tài)系統(tǒng)的一部分,使用合法的Java機(jī)制來添加其功能,可以幫助您處理幾乎零缺點(diǎn)的Java代碼,并且受到許多Java開發(fā)人員的喜愛。多少?最流行的Java IDE之一將Lombok插件下載數(shù)量估計(jì)為11+百萬(wàn)。許多。這是一種使Java更好的工具,因此從實(shí)際意義上講,它是數(shù)百萬(wàn)使用Java的人的Java。不過,Java社區(qū)中有一部分人反對(duì)Lombok,他們擁有這樣做的全部權(quán)利-如果您不喜歡Lombok,則沒有人會(huì)強(qiáng)迫您這樣做。
現(xiàn)在想象一下這些示例在其他語(yǔ)言中的外觀。您可能會(huì)發(fā)現(xiàn)用于達(dá)成相同目標(biāo)的語(yǔ)言所包含的字符要少一些。但是,該代碼是否會(huì)像Java語(yǔ)言一樣可靠,可讀性,可維護(hù)性和快速性?我?guī)缀醪贿@么認(rèn)為。
與語(yǔ)法相關(guān)的另一重要事項(xiàng)是IDE支持。這不是抽象的理論問題,例如語(yǔ)言結(jié)構(gòu)的強(qiáng)大程度或開發(fā)人員必須編寫多少符號(hào)才能執(zhí)行某項(xiàng)操作。 IDE添加了一個(gè)實(shí)用層,將所有抽象問題轉(zhuǎn)換為一個(gè)問題:特定任務(wù)將花費(fèi)多少開發(fā)人員時(shí)間。將精心設(shè)計(jì)的語(yǔ)言與現(xiàn)代IDE結(jié)合使用,與使用功能更強(qiáng)大或更簡(jiǎn)潔但對(duì)IDE友好程度更低的語(yǔ)言相比,開發(fā)人員可以更快地達(dá)到目標(biāo)。 Java具有以下語(yǔ)法,這是Java最好的IDE支持之一:它不太復(fù)雜,同時(shí)也不太自由選擇,因此IDE可以了解您當(dāng)前正在使用的上下文并預(yù)測(cè)您想做什么。接下來非常精確。最后要說的是,Java的語(yǔ)法允許使用不同的編程樣式。您的代碼可以用面向?qū)ο蟮姆独帉懀渲袑?duì)象彼此交互。在程序范式中,命令式程序調(diào)用的順序改變了全局狀態(tài);或在功能范式中,您可以組合和應(yīng)用功能以實(shí)現(xiàn)目標(biāo)。有時(shí)人們會(huì)區(qū)分更多的范例-例如,Java非常適合面向方面或基于參與者的范例。 Java為您提供了極大的靈活性,使您可以思考自己的任務(wù),因此它為應(yīng)對(duì)周期性發(fā)生的編程范式時(shí)尚轉(zhuǎn)變做好了充分的準(zhǔn)備。
綜上所述,Java的語(yǔ)法沒有問題。它相對(duì)簡(jiǎn)單,靈活且富有表現(xiàn)力。此外,它還允許IDE通過多種方式有效地幫助開發(fā)人員,從而大大提高了他們的生產(chǎn)率。如果您精通Java,編寫清晰的代碼,并使用正確的工具集來完成任務(wù),那么您的程序?qū)⑹敲烙^,可維護(hù)和簡(jiǎn)潔的。不要讓人們?cè)谶@個(gè)話題上欺騙您。
保證
> Photo by Joshua Hoehne on Unsplash
與許多其他技術(shù)不同,Java作為一種語(yǔ)言和平臺(tái)為您提供了許多可以依賴的保證。
Java語(yǔ)言具有Java語(yǔ)言規(guī)范,這是對(duì)Java代碼的構(gòu)造應(yīng)該如何工作和應(yīng)該如何使用的主要判斷。它為什么如此重要?因?yàn)槟梢则?yàn)證自己的工作并以嚴(yán)格,可預(yù)測(cè)的方式解決問題或糾紛。對(duì)于沒有規(guī)范的語(yǔ)言,您不太確定會(huì)發(fā)生什么情況:您可能會(huì)在手冊(cè),博客或語(yǔ)言創(chuàng)建者的推文中找到一些信息,但是直到語(yǔ)言獲得規(guī)范,所有這些信息才具備保證一切的堅(jiān)實(shí)基礎(chǔ)。
當(dāng)然,規(guī)范可能具有不同的質(zhì)量或不同的詳細(xì)程度,因此可能會(huì)遺漏某些內(nèi)容。盡管如此,具有規(guī)范的語(yǔ)言比沒有語(yǔ)言的語(yǔ)言給您提供了更高的信心,使您確信自己在做正確的事情。Java的規(guī)范非常深入和詳細(xì),幾乎沒有歧義。
Java版本對(duì)規(guī)范和公共Java API中的內(nèi)容具有強(qiáng)烈的向后兼容性。這意味著,如果您使用使用20年前編寫的版本1.3的公共Java API的代碼,并且今天在Java 15上運(yùn)行它,它將可以正常工作。同時(shí),如果您使用私有Java API,該API由不應(yīng)由開發(fā)人員直接使用的類和方法/字段組成,則可能會(huì)遇到麻煩。我認(rèn)為這很合理:如果您使用可以保證向后兼容的產(chǎn)品,則可以依靠它,但是如果您使用了不打算使用的產(chǎn)品,請(qǐng)不要期望它們永遠(yuǎn)有效。
Java是安全可靠的-并非絕對(duì)如此;實(shí)際上。Java代碼是安全的,因?yàn)榕c許多其他語(yǔ)言相比,開發(fā)人員使用Java代碼出錯(cuò)的可能性較小。從Java代碼不能直接訪問操作系統(tǒng)或硬件的角度來看,這是安全的,因此Java運(yùn)行時(shí)可以安全地限制Java程序可以做什么和不能做什么。
Java代碼是可移植的。這意味著您可以在一個(gè)平臺(tái)上編譯Java代碼,并且可以在實(shí)現(xiàn)Java虛擬機(jī)的任何平臺(tái)上運(yùn)行它,而無需重新編譯。"編寫一次,隨處運(yùn)行" –古老的Java標(biāo)語(yǔ),直到25年后的今天仍然可行。廣泛的可移植性以及向后兼容性是保證的非常強(qiáng)的組合,這使開發(fā)人員確信他們的努力和知識(shí)不會(huì)很快過時(shí)。當(dāng)然,在某些特殊情況下,由于諸如硬件限制之類的各種原因,某些虛擬機(jī)僅允許Java語(yǔ)言規(guī)范的子集。例如,您可以在8kB RAM微控制器上運(yùn)行Java代碼,但是必須考慮一些限制。
Java代碼是可維護(hù)的。與C ++之類的語(yǔ)言相比,Java的語(yǔ)法非常簡(jiǎn)化。它缺乏C ++具有的許多功能,自定義項(xiàng)和強(qiáng)大的構(gòu)造。同時(shí),與腳本語(yǔ)言相比,Java具有許多乍一看都是多余的"儀式"。從這個(gè)意義上講,Java試圖在復(fù)雜性,功能和可讀性之間保持平衡,以最大化長(zhǎng)期代碼可維護(hù)性。什么是可維護(hù)性?我將其描述為普通技術(shù)開發(fā)人員將更改應(yīng)用于現(xiàn)有代碼庫(kù)(可能是舊代碼庫(kù))所需的時(shí)間,這可以達(dá)到開發(fā)人員的目標(biāo),并且不會(huì)破壞其他任何東西。所需時(shí)間越短,可維護(hù)性就越高。
從這個(gè)意義上講,Java是好的。一方面,它功能強(qiáng)大,足以表達(dá)開發(fā)人員所需的許多內(nèi)容,但同時(shí)又不像語(yǔ)言那樣復(fù)雜,人們可以使用極其強(qiáng)大的語(yǔ)言構(gòu)造(只能由其創(chuàng)建者理解)來創(chuàng)建精美,無法解決的迷宮。另一方面,Java要求開發(fā)人員編寫比開發(fā)人員通常用腳本語(yǔ)言編寫的更詳盡的代碼,并且編寫更明確的內(nèi)容,以提高可讀性并易于理解時(shí)間流逝后發(fā)生的事情。
Java很快。如果您嘗試研究此主題,可能會(huì)發(fā)現(xiàn)許多文章,例如" Java比X快"和" X比Java快",其中包含矛盾的陳述和結(jié)論。如果您嘗試進(jìn)行實(shí)驗(yàn),則可以輕松地構(gòu)造Java速度慢而Java快速發(fā)展的示例-順便說一句,您可以使用其他語(yǔ)言來完成相同的技巧。關(guān)于為什么過去認(rèn)為Java速度很慢有很好的評(píng)論?,F(xiàn)在有點(diǎn)過時(shí)了。例如,最新的Java運(yùn)行時(shí)中的字符串處理要比七年前好得多,而且我也不同意其他一些聲明。但是總的結(jié)論是,對(duì)于每個(gè)發(fā)行版,Java都會(huì)進(jìn)行優(yōu)化以提高其性能。還記得本文"語(yǔ)法"部分的第三個(gè)示例,其中處理了巨大的1.2 Gb文件?使用Java 8,在我的筆記本上平均要花十秒鐘,而使用Java 15,只有相同配置的六秒鐘。這是該語(yǔ)言的開發(fā)人員為我們提供的重要保證之一:Java足夠快,足以應(yīng)付當(dāng)今的許多任務(wù),并且將來會(huì)更快。
關(guān)于擔(dān)保的最后一件事要說的是:它們已經(jīng)實(shí)現(xiàn)了25年以上,并且沒有理由在未來的幾年中不會(huì)實(shí)現(xiàn)。
Java緩慢實(shí)現(xiàn)現(xiàn)代語(yǔ)言功能
> Photo by Makarios Tang on Unsplash
是。通常,慢是一件壞事嗎?不。問自己以下。如果您騎著自行車,偶爾看到前方的墻壁,您會(huì)喜歡什么:加速還是減速?我打賭你選擇和我一樣。
那么,為什么Java采用的功能比其他某些語(yǔ)言的速度慢?由于擔(dān)保,我們?cè)谏弦还?jié)中討論過。這些保證就是一堵墻,它迫使對(duì)功能進(jìn)行仔細(xì)地討論,過濾或以某種方式進(jìn)行變換,在這里,慢是比著急更好的朋友。關(guān)于如何將更改應(yīng)用于Java語(yǔ)言的正式過程稱為Java社區(qū)過程。此過程的主要目的是驗(yàn)證所提出的功能不會(huì)破壞保證。有時(shí)候,這并不是一項(xiàng)顯而易見且快速的任務(wù)。
Java語(yǔ)言的開發(fā)人員試圖在創(chuàng)新和保證之間保持平衡,這比"讓我們現(xiàn)在將這種很酷的功能添加到我們的語(yǔ)言中"要難得多。但是,從長(zhǎng)遠(yuǎn)來看,它可以帶來更多利潤(rùn),因?yàn)楸WC意味著信任,這對(duì)未來來說比有價(jià)值的功能集更有價(jià)值。Brian Goetz討論了Java的這種策略和總體哲學(xué)。請(qǐng)看一看。
另外,值得一提的是當(dāng)前的Java發(fā)布時(shí)間表。9月和3月每六個(gè)月發(fā)布一次Java的新版本,該版本完全可以使用,并在接下來的六個(gè)月中逐步更新。每三年,其中一個(gè)這樣的版本將成為長(zhǎng)期支持(LTS)版本,并在接下來的三年中逐步更新?,F(xiàn)在,Java 15是最新版本,而Java 11是當(dāng)前的LTS。LTS的下一個(gè)發(fā)行版將是Java 17,計(jì)劃于2021年9月發(fā)布。每個(gè)版本都可以包含許多"預(yù)覽功能",對(duì)于這些功能,不能保證將來的發(fā)行版具有兼容性。他們的目標(biāo)是為開發(fā)人員提供嘗試有爭(zhēng)議的創(chuàng)新并留下反饋的可能性。如果某個(gè)功能未標(biāo)記為預(yù)覽,則表示該功能已完全包含在平臺(tái)中,并將具有Java提供的所有保證。
生態(tài)系統(tǒng)
> Photo by Greg Rakozy on Unsplash
有些人狹義地理解語(yǔ)言生態(tài)系統(tǒng),僅將其概念限制為程序員可以使用的一組庫(kù)。我更傾向于將生態(tài)系統(tǒng)視為解決問題的工具。開發(fā)人員可以用該語(yǔ)言解決的問題越多,其生態(tài)系統(tǒng)就越廣泛。優(yōu)先選擇哪個(gè)含義都沒有關(guān)系:Java具有龐大的生態(tài)系統(tǒng)。
這是我之前問自己解決我遇到的問題的個(gè)人隨機(jī)問題列表:
- 我可以使用對(duì)HTML,JS和CSS零知識(shí)的純Java編寫Web應(yīng)用程序嗎?是。
- 我可以在毫秒級(jí)的世界范圍內(nèi)使用TB級(jí)的堆嗎?是的,很容易。
- 我可以用純Java處理圖像和視頻以實(shí)現(xiàn)可移植性嗎?是。
- 我可以使用Java進(jìn)行深度學(xué)習(xí)嗎?是的,請(qǐng)。
- 我可以使用Java對(duì)在黑色星期五購(gòu)買的機(jī)器人進(jìn)行編程嗎?是。
- 我可以找到有關(guān)Java的隨機(jī)愚蠢問題的答案嗎?是。
該列表絕對(duì)是個(gè)人的,但是我可以肯定,在大多數(shù)情況下,當(dāng)問題在編程環(huán)境中并且涉及Java時(shí),"是"的實(shí)例將壓倒"否"的實(shí)例。
在Java生態(tài)系統(tǒng)的幫助下,您可以解決許多領(lǐng)域中的許多問題,此外,通常您也有多種選擇方式。如果您想了解Java生態(tài)系統(tǒng)的廣闊程度,請(qǐng)查看此資源。
啟動(dòng)時(shí)間和內(nèi)存占用量
> Photo by Bill Oxford on Unsplash
Java代碼被編譯為稱為Java字節(jié)碼的中間形式,然后在稱為JVM的運(yùn)行時(shí)平臺(tái)上執(zhí)行。除了抱怨Java語(yǔ)法外,評(píng)論家通常還會(huì)抱怨JVM內(nèi)存占用量和啟動(dòng)時(shí)間。讓我們更詳細(xì)地討論。
JVM代表Java虛擬機(jī),這意味著您的應(yīng)用程序由虛擬計(jì)算機(jī)在沙箱中運(yùn)行。這種方法有很多好處。開發(fā)人員無需考慮運(yùn)行應(yīng)用程序的操作系統(tǒng)和硬件的細(xì)微差別。虛擬沙箱提供了更高的安全性,因?yàn)樗辉试S應(yīng)用直接與低級(jí)事物進(jìn)行交互。虛擬環(huán)境位于您的應(yīng)用程序外部,可以動(dòng)態(tài)優(yōu)化它,以提高在不同情況下的性能等。
缺點(diǎn)是JVM需要額外的資源(包括內(nèi)存和處理器時(shí)間)才能運(yùn)行,并且具有啟動(dòng)和預(yù)熱時(shí)間。
在通常的使用情況下,根據(jù)應(yīng)用程序的不同,標(biāo)準(zhǔn)的Oracle HotSpot JVM會(huì)引入數(shù)十或數(shù)百兆字節(jié)的額外空間,平均需要幾秒鐘的啟動(dòng)時(shí)間。(JVM本身通常在不到一秒鐘的時(shí)間內(nèi)啟動(dòng),但是其他一些庫(kù)由于其內(nèi)部例程而增加了該時(shí)間。)而且,在啟動(dòng)后的最初幾秒鐘內(nèi),JVM可以消耗比平均更多的CPU,因?yàn)樗梢宰R(shí)別并編譯"字節(jié)碼中的"熱門"部分以優(yōu)化其將來的用法。
在大多數(shù)情況下,這些缺點(diǎn)對(duì)于許多類型的應(yīng)用都是合理的。但是在某些情況下,它們并非如此,您希望以某種方式權(quán)衡利弊。那你該怎么辦?您是否應(yīng)該放棄Java而改用其他東西?通常不會(huì)-僅選擇另一個(gè)適合您特定任務(wù)的運(yùn)行時(shí)。
考慮例如微服務(wù)域?,F(xiàn)代微服務(wù)應(yīng)用程序通常需要最少的內(nèi)存占用空間和啟動(dòng)時(shí)間,以有效地填充Kubernetes等容器編排器。為了滿足這一需求,Java開發(fā)人員創(chuàng)建了GraalVM。它允許開發(fā)人員從Java代碼創(chuàng)建本機(jī)映像,這些映像將在數(shù)十毫秒的啟動(dòng)時(shí)間和僅幾兆字節(jié)的額外內(nèi)存占用下運(yùn)行。許多Java Web框架使GraalVM適應(yīng)微服務(wù)領(lǐng)域:Quarkus,Micronaut,Spring和Helidon。
交易弊端?您將失去可移植性,并且生成的映像只能在GraalVM為其編譯的平臺(tái)上運(yùn)行。但是對(duì)于微服務(wù)而言,這并不是很重要,因?yàn)槟膽?yīng)用很可能會(huì)在具有預(yù)定義環(huán)境的容器中運(yùn)行。您可能還會(huì)面臨其他一些限制。無論如何,當(dāng)您聽到Java不適合現(xiàn)代微服務(wù)需求時(shí),請(qǐng)記?。涸撽愂鍪清e(cuò)誤的。
正如許多批評(píng)家所說,Java并不意味著過度使用內(nèi)存和縮短啟動(dòng)時(shí)間。內(nèi)存使用情況和啟動(dòng)時(shí)間主要取決于最終運(yùn)行應(yīng)用程序所用的運(yùn)行時(shí)以及所使用的其他庫(kù)。從這個(gè)意義上講,Java生態(tài)系統(tǒng)根據(jù)您的需求為您提供選擇。
Java真正的目的是什么?
> Photo by Xavi Cabrera on Unsplash
Java可以用于您想像的一切:API和Web服務(wù)器,游戲和多媒體軟件,UI和Web應(yīng)用程序,IoT和機(jī)器人技術(shù),AR和VR,機(jī)器學(xué)習(xí)和數(shù)據(jù)流,數(shù)據(jù)庫(kù)和云原生微服務(wù),大型企業(yè)系統(tǒng)和小原型。有沒有排除事項(xiàng)?技術(shù)上不,實(shí)際上是。Java并不是低級(jí)系統(tǒng)語(yǔ)言,因此用Java創(chuàng)建操作系統(tǒng)或硬件驅(qū)動(dòng)程序的核心不是一個(gè)好主意。從技術(shù)上講是可能的,但是針對(duì)這些情況,有比Java更好的工具。
但是我們必須為Java付費(fèi),對(duì)吧?
> Photo by Jp Valery on Unsplash
不,如果您使用免費(fèi)的Java發(fā)行版,則不必為Java付費(fèi)。Java是開源的,因此任何人都可以構(gòu)建現(xiàn)成的Java發(fā)行版,并且有許多免費(fèi)的預(yù)構(gòu)建發(fā)行版,例如OpenJDK,AdoptOpenJDK,AWS Coretto,Azul Zulu等。這些發(fā)行版的使用是絕對(duì)免費(fèi)的,并且它們中的任何一個(gè)極有可能滿足您的要求。如果您想了解更多有關(guān)此信息,請(qǐng)參閱本文。
Java的未來
> Photo by Karsten Würth on Unsplash
總結(jié)一切:Java仍然是一個(gè)很重要的語(yǔ)言。
它的作用是成為許多領(lǐng)域的核心技術(shù),在創(chuàng)新,功能和可維護(hù)性之間取得平衡,以可持續(xù)地支持所使用的項(xiàng)目。如果您想嘗試新穎的語(yǔ)言構(gòu)想,請(qǐng)選擇另一種技術(shù)。但是,如果您看到某個(gè)特定功能最終找到了它成為Java規(guī)范的方式,則可以確定不是由于偶然的情況或很小的時(shí)尚波動(dòng)而添加了該功能,而是經(jīng)過深入研究和為達(dá)到相同水平而付出的巨大努力設(shè)計(jì)的結(jié)果保證其他Java功能具有。從這個(gè)意義上講,您可以信任Java,這與市場(chǎng)上的許多其他技術(shù)不同。
如果您在問初學(xué)或初學(xué)時(shí)應(yīng)該學(xué)習(xí)哪種計(jì)算機(jī)語(yǔ)言,只需嘗試一下Java。我敢肯定Java將在我們身邊住很長(zhǎng)時(shí)間。
我敢打賭,關(guān)于Java為什么會(huì)長(zhǎng)壽,本文還遺漏了許多其他好的論點(diǎn),歡迎您在評(píng)論中分享它們。
原文鏈接:https://medium.com/better-programming/why-java-is-perfectly-alive-e3f25a576f95
【責(zé)任編輯:趙寧寧 TEL:(010)68476606】