Obsah
1. Java oslavuje 30 let od svého vzniku
3. Vstup do reálného IT světa: JIT překladač
4. Jakým tempem se má programovací jazyk vyvíjet?
5. Java neznamená pouze programovací jazyk, ale celý ekosystém
6. Programovací jazyky pro virtuální stroj Javy aneb zdaleka nejde jen o Javu
7. Stručný přehled jazyků pro JVM
8. Popularita programovacího jazyka Java
9. Třicet let v IT: uvedení do kontextu
15. Příloha: porovnání rychlosti JVM v režimu interpretru a JITu
17. Příloha: výsledek překladu metody calcIter C1 a C2 překladačem
1. Java oslavuje 30 let od svého vzniku
Na stránkách Roota jsme si připomněli (a taktéž trošku oslavili) hned několik kulatých výročí různých programovacích jazyků. Po dvojici článků o třicátých narozeninách Turbo Pascalu 5.5 a šedesátém výročí vzniku programovacího jazyka COBOL jsme si připomněli i sedmdesát let, které uběhly od vzniku nástroje, který dnes nazýváme assembler (i když se původně tento název nepoužíval).

Obrázek 1: Uživatelské rozhraní Turbo Pascalu 5.5.
Nezapomněli jsme ovšem ani na programovací jazyk ALGOL, jehož nejznámější varianta, která se jmenuje ALGOL-60, vznikla skutečně již v roce 1960 a jehož historii jsme si připomněli v tomto článku. Z dalších známých programovacích jazyků jsme oslavili dvacet let Pythonu 2 (článek je to starší, Python 2 již dnes má 25 let a stále na něj kupodivu čas od času narazím, i když méně často, než před pěti lety) a naopak z těch méně známých a populárních jazyků jsme si připomněli 55 let od vzniku jazyka APL.

Obrázek 2: Jedna z populárních dobových učebnic ALGOLU 68 (jeho výročí neslavíme, jak číslovka naznačuje).
Dnes si připomeneme kulaté výročí skutečně těžké váhy v oblasti programovacích jazyků. Třicet let od svého představení totiž slaví Java, tj. jazyk, který byl již relativně krátce po svém vzniku nejpopulárnějším programovacím jazykem vůbec a i dnes se stále (a to s velkým přehledem) drží v první desítce nejpoužívanějších a nejpopulárnějších (což nemusí být ani zdaleka totéž) programovacích jazyků. Java má za sebou poměrně zajímavou historii.
Dokázala totiž nejenom přežít jak zánik původních platforem, pro které původně vznikla, ale přežila i svou „rodnou“ firmu (Sun Microsystems). Co je ale důležitější – Java nezůstala jazykem určeným pro jedinou izolovanou niku, ale adaptovala se v nových oblastech. Tak se stalo, že z programovacího jazyka, který byl původně prezentován jako jazyk určený pro programování mikrovlnných trub a výtahů, se stal jazyk využívaný pro vývoj rozsáhlých systémů běžících na různých platformách (od mobilních telefonů přes desktopová PC až po servery a dokonce i mainframy).

Obrázek 3: Původní logo programovacího jazyka Java. Toto logo bylo používáno v letech 1996 až 2003. Autorkou tohoto loga je Susan Kare.
2. Vznik platformy Javy
Programovací jazyk Java byl navržen Jamesem Goslingem ze společnosti Sun Microsystems. Mělo se jednat o jazyk umožňující (relativně) snadnou tvorbu aplikací, navíc bez nutnosti řešení správy paměti (ta byla automatická). Z pohledu syntaxe byla Java navržena takovým způsobem, aby se do značné míry podobala jazykům C a C++, což umožnilo snadný přechod programátorů z těchto mainstreamových jazyků (ostatně podobně se postupovalo i u JavaScriptu).
Ovšem z pohledu sémantiky jde o odlišný jazyk, který podporuje objektově orientovaný návrh založený nikoli pouze na hierarchii tříd, ale i na rozhraních (interface). Navíc je to jazyk více dynamický, protože například podporuje reflexi apod. Některé nízkoúrovňové koncepty zůstaly zachovány a zajímavé je, že právě tyto koncepty jsou z dlouhodobého hlediska nejvíce problematické. Jedná se o odlišnou práci s primitivními datovými typy a taktéž o existenci nulové reference (null) – zopakovala se zde tedy (ne)slavná chyba za miliardu dolarů.
Jedním z mot nového programovacího jazyka bylo write once, run anywhere neboli WORA. Nicméně se nejedná o přenositelnost na úrovni zdrojových kódů, ale o přenositelnost již přeloženého kódu. Pokud by se programy napsané v Javě překládaly přímo do strojového kódu dané platformy, pochopitelně by to znamenalo, že přenositelnost nebude zaručena a navíc by jednou přeložené programy nemohly využívat například nová rozšíření instrukčních sad, nové registry atd. (musel by se provést nový překlad). Tento problém byl v případě Javy řešen technologií, která již byla předtím použita u jiných jazyků, například u Pascalu. Namísto překladu programů do strojového kódu se prováděl (a stále provádí) překlad do takzvaného bajtkódu, který je posléze nějakým způsobem spouštěn virtuálním strojem Javy. Bajtkód se buď interpretuje, nebo se překládá JIT (Just in Time) překladačem popř. AOT (Ahead of Time) překladačem.

Obrázek 4: Novější logo programovacího jazyka Java, které se začalo používat po roce 2003.
3. Vstup do reálného IT světa: JIT překladač
Původní virtuální stroj Javy (JVM) byl interně relativně jednoduchý. Jednalo se totiž o interpret bajtkódu. Zdrojové kódy napsané v Javě byly nejdříve standardním překladačem Javy (javac, ostatně ten je po úpravách používán dodnes) přeloženy do bajtkódu (soubory .class, taktéž používané dodnes, ovšem s vylepšeními). A tento bajtkód byl po spuštění aplikace interpretován, což je sice z implementačního hlediska jednoduché, na druhou stranu však tímto způsobem spouštěné aplikace v žádném případě neoplývaly rychlostí a nemohly v tomto ohledu konkurovat aplikacím přeloženým do nativního kódu. Velkého pokroku bylo dosaženo přidáním Just In Time (JIT) překladače, který se stal nedílnou součástí virtuálního stroje Javy a neustále se vyvíjí.

Obrázek 5: Nejnovější barvová variace loga jazyka Java.
Dnes je JIT nedílnou součástí platformy Javy. Virtuální stroj Javy se tedy vlastně skládá ze tří hlavních subsystémů. Jedná se o zmíněný JIT překladač, dále o správce paměti a taktéž o běhové prostředí (runtime – interpret, standardní class loader, synchronizační mechanismy, správce vláken). Na rychlost (výkon) aplikací má největší vliv právě JIT. V současnosti se můžeme setkat s několika typy JIT překladačů. Z historických důvodů se dělí na client a server, které se v novějších JVM kombinují do takzvaného vícevrstvého překladače tiered compiler.
Právě existence JIT umožnila, aby se v Javě začaly vytvářet i rozsáhlé a sofistikované programy, které navíc měly srovnatelný výpočetní výkon, jako programy napsané v běžných překládaných programovacích jazycích (C, C++, později například Rust). Jednalo se tedy o pomyslnou vstupenku do světa enterprise systémů – Java se začala používat pro messaging, tvorbu aplikačních serverů, ale dokonce i databází atd.
4. Jakým tempem se má programovací jazyk vyvíjet?
Původní verze programovacího jazyka Java byla z dnešního pohledu v několika ohledech omezená, protože v ní chyběly některé důležité programové konstrukce, specifikátory datových typů atd. Tvůrci Javy stáli před rozhodnutím, jakým tempem se má vlastně tento programovací jazyk vyvíjet a jak rychle do sebe má „absorbovat“ nové vlastnosti. V této oblasti (pokud se zaměříme na populární a používané programovací jazyky) můžeme vidět dva extrémy. Na jedné straně jazyk C, jehož vývoj je velmi pomalý a jeho nové verze si velmi přísně hlídají zpětnou kompatibilitu a novinky jsou poměrně malé. A na straně druhé jazyk C++, který za dobu své existence (40 let) prošel několika vlnami velkých změn, z nichž některé jsou dnes považovány za překonané, ale stále se musí z důvodu zpětné kompatibility udržovat. V tomto případě se došlo do situace, kdy se říká, že specifikace jazyka C++ má své vlastní gravitační pole.
Programovací jazyk Java je v tomto ohledu spíše konzervativní, ovšem vývoj jazyka byl a je nutný, protože se vyvíjí i způsoby tvorby aplikací. Některé změny a vylepšení Javy byly spíše kosmetické, jiné naopak jazyk posunuty na jinou úroveň. Ostatně si to můžeme ilustrovat na dvou příkladech.
První změnou v Javě bylo přidání klíčového slova strictfp v Javě 1.2. Toto klíčové slovo se používá jako modifikátor u deklarace proměnných, návratových typů metod, u tříd atd. a ovlivňuje způsob výpočtů s hodnotami s plovoucí řádovou čárkou: toto slovo vynucuje výpočty a zaokrouhlení přesně odpovídající normě IEEE 754. Jedná se tedy o malou změnu, která ale není zpětně kompatibilní, protože zavedení nového klíčového slova může znamenat, že některé zdrojové kódy nebudou přeložitelné.
Druhým příkladem je zavedení podpory pro generické datové typy. Jedná se o zcela novou sémantiku, která je kompatibilní – původní zdrojové kódy bude možné stále bez problémů přeložit. Současně se jedná o posunutí možností jazyka na novou úroveň, protože je možné pracovat s „typově bezpečnými“ kontejnery atd. Na druhou stranu se tato změna dotýká spíše samotného programovacího jazyka a nikoli jeho bajtkódu. Generické datové typy nejsou plnohodnotnými typy a informace o nich se (velmi zjednodušeně řečeno) nepropisuje do bajtkódu, takže je lze obcházet.
Na těchto příkladech je patrné, že zavádění novinek do programovacích jazyků je sice většinou nutné, ale obecně se nejedná o jednoduchou problematiku.
5. Java neznamená pouze programovací jazyk, ale celý ekosystém
V mnoha případech se termínem „Java“ nemyslí pouze samotný programovací jazyk Java, ale i celý ekosystém, který byl okolo tohoto jazyka postupně vytvořen. V první řadě se pochopitelně jedná o samotný virtuální stroj Javy (Java Virtual Machine neboli JVM), ovšem taktéž nesmíme zapomenout na celé běhové prostředí Javy (Java Runtime Environment neboli JRE), které kromě virtuálního stroje obsahuje i základní knihovnu Javy (a to je pěkný otesánek, resp. býval před podporou modularizace) a další pomocné nástroje (práce s databází certifikátů atd.). Do tohoto ekosystému patří i externí nástroje, například (dříve) Ant, dnes Maven, Gradle apod.

Obrázek 6: Důležitou součástí ekosystému Javy jsou pochopitelně i integrovaná vývojová prostředí. I ta se postupně vyvíjela a po dlouhou dobu se pravděpodobně nejvíce rozšířeným vývojovým prostředím stala platforma Eclipse, která je taktéž naprogramována v Javě.
Okolo JVM resp. JRE postupem času vznikly i mnohé další nástroje – monitorovací aplikace, nástroje, které se k JVM připojují přes JVM TI (Java Virtual Machine Tools Interface), JDI (Java Debugger Interface) či JDWP (Java Debug Wire Protocol), ale i ucelená integrovaná vývojová prostředí (IDE). Různé monitorovací nástroje využívaly další užitečné rozhraní virtuálního stroje Javy – Java Management Extensions neboli JMX.

Obrázek 7: Další ukázka dobového integrovaného vývojového prostředí pro Javu založeného na platformě Eclipse.

Obrázek 8: Eclipse je skutečně platformou, nad níž lze vytvářet další více či méně sofistikované nástroje. Příkladem je integrované vývojové prostředí pro jazyk COBOL. Tak trochu se zde připomíná tvrzení „Java je COBOLem 21.století“.
6. Programovací jazyky pro virtuální stroj Javy aneb zdaleka nejde jen o Javu
Virtuální stroj Javy (JVM), specifikace JVM a dokonce ani jeho instrukční soubor vlastně nikde striktně nepředpokládají, že JVM bude spouštět pouze bajtkód získaný překladem zdrojových kódů naprogramovaných přímo v Javě. Ve specifikaci JVM je dokonce na několika místech explicitně zmíněn předpoklad, že nad virtuálním strojem Javy budou provozovány i další programovací jazyky umožňující přímý či nepřímý překlad do bajtkódu. Kromě toho je samozřejmě možné přímo v Javě vytvořit interpret prakticky libovolného (interpretovaného) programovacího jazyka, takže vlastně nebude velkým překvapením, když zjistíme, že dnes těchto „JVM jazyků“ již existuje relativně velké množství (minimálně několik desítek) a některé z nich jsou dosti populární. V následující tabulce jsou vypsány ty nejznámější a pravděpodobně nejpoužívanější jazyky pro JVM, a to pro úplnost včetně samotné Javy:
https://www.gnu.org/software/kawa/# | Jazyk pro JVM | Stručný popis | Odkaz |
---|---|---|---|
1 | Java | primární jazyk pro JVM, bajtkód do značné míry odpovídá právě Javě | https://www.oracle.com/java/index.html |
2 | Clojure | moderní dialekt programovacího jazyka Lisp s přidanými funkcionálními prvky | https://clojure.org/ |
3 | Groovy | dynamicky typovaný jazyk pro JVM | http://groovy-lang.org/ |
4 | Rhino | jedna z implementací JavaScriptu (dnes již pravděpodobně mrtvý projekt) | https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Rhino |
5 | Nashorn | alternativní implementace JavaScriptu (tento projekt je stále živý) | https://github.com/openjdk/nashorn |
6 | JRuby | portace jazyka Ruby na JVM | http://jruby.org/ |
7 | Jython | portace jazyka Python na JVM | http://www.jython.org/ |
8 | Kotlin | moderní staticky typovaný jazyk | http://kotlinlang.org/ |
9 | Scala | další moderní jazyk pro JVM | https://www.scala-lang.org/ |
10 | Kawa | implementace jazyka Scheme s mnoha rozšířeními |

Obrázek 9: Logo programovacího jazyka Jython.
7. Stručný přehled jazyků pro JVM
Pro úplnost se ve stručnosti zmiňme o nejznámějších jazycích určených pro běh ve virtuálním stroji Javy.
Kotlin
Prvním programovacím jazykem určeným pro běh nad virtuálním strojem Javy, o němž se dnes alespoň ve stručnosti zmíníme, je jazyk pojmenovaný Kotlin. Jedná se o moderní staticky typovaný programovací jazyk vyvinutý ve společnosti JetBrains a jeho cíl je vlastně velmi podobný cíli, který si dal dále zmíněný a poněkud starší jazyk Scala – efektivní a rychlá tvorba typově bezpečných aplikací určených pro běh nad JVM. Typovost jde ještě o krok dále, než je tomu v Javě, protože například rozlišuje mezi nulovatelnými a nenulovatelnými datovými typy. Na rozdíl od Scaly je však rychlost překladu zdrojových kódů naprogramovaných v Kotlinu rychlejší a blíží se rychlosti překladu kódů napsaných v samotné Javě. Kotlin podporuje různá paradigmata: objektově orientované, procedurální i funkcionální.

Obrázek 10: Logo programovacího jazyka Kotlin.
Scala
Pravděpodobně druhým nejznámějším příkladem programovacího jazyka provozovaného nad JVM je Scala, která nabízí prakticky bezproblémovou spolupráci mezi částmi kódu psanými ve Scale a zbytkem aplikace psaným v Javě (popř. jsou některé projekty psané pouze ve Scale, ovšem provozovány jsou například na ryze javovských serverech – Tomcat, Jetty atd.). Díky tomu, že zdrojové kódy psané ve Scale jsou přímo překládány do bajtkódu, získali tvůrci tohoto programovacího jazyka prakticky zadarmo veškeré vymoženosti, které virtuální stroj Javy (či přesněji řečeno celé JRE) poskytuje – od poměrně pečlivé kontroly bajtkódu při jeho načítání do virtuálního stroje přes použití správců paměti a JIT překladačů (Just in Time Compiler) až po možnost využití rozsáhlých standardních knihoven J2SE a samozřejmě taktéž mnoha dalších knihoven a frameworků, které jsou pro JVM dostupné. Ovšem Scala samozřejmě není jediným programovacím jazykem, který díky překladu do bajtkódu umožňuje využít prakticky veškerého potenciálu JVM/JRE.

Obrázek 11: Logo programovacího jazyka Scala.
Clojure
Z dalších překladačů programovacích jazyků, které pro virtuální stroj Javy vznikly, je podle mého názoru nejzajímavějším jazykem a současně i jazykem s poměrně velkým potenciálem pro budoucnost programovací jazyk s názvem Clojure, jehož autorem a dodnes nejaktivnějším vývojářem a propagátorem je Rich Hickey. Samotný název tohoto jazyka vznikl vložením písmene „j“ (Java/JVM) do slova closure (toto slovo se používá ve smyslu „lexikální uzávěr“ – důležitá abstrakce používaná nejenom ve funkcionálních programovacích jazycích). Velká část předností a pro mnohé vývojáře taktéž záporů programovacího jazyka Clojure vychází z toho, že se jedná o programovací jazyk, jehož syntaxe a sémantika do značné míry vychází z LISPu a Scheme, tedy jazyků známých především tím, že se v programech v nich psaných používá nadměrné množství kulatých závorek. Podrobnější informace o Clojure byly uvedeny v samostatném seriálu, který již vyšel na serveru www.root.cz.

Obrázek 12: Logo programovacího jazyka Clojure.
Groovy
Dalším programovacím jazykem, a nutno říci že jazykem poměrně populárním, je Groovy. Jedná se o jazyk inspirovaný některými dalšími (většinou dynamicky typovanými) programovacími jazyky, jako je Python, Ruby, ale například i Perl. Groovy podporuje objektově orientované programování a oproti Javě umožňuje psát kratší kód, z něhož jsou odstraněny méně podstatné části, které Java jakožto silně staticky typovaný jazyk vyžaduje. Z tohoto důvodu se Groovy velmi často používá všude tam, kde je vyžadovaný skriptovací jazyk běžící nad JVM. Dobrým příkladem je například konzole Jenkinsu, která ve výchozím nastavení používá právě Groovy. Podpora pro tento jazyk je součástí mnoha populárních integrovaných vývojových prostředí, a to včetně IntelliJ IDEA, Netbeans i Eclipse (přes pluginy – doplňkové moduly).

Obrázek 13: Logo programovacího jazyka Groovy.
JRuby, Jython, Rhino a Nashhorn
Zatímco Scala, Clojure i Groovy jsou novými jazyky, které původně vznikly přímo a pouze pro potřeby programátorů používajících virtuální stroj Javy (JVM), zmíníme se v této podkapitole alespoň ve stručnosti o jazycích „klasických“, které byly na JVM pouze naportovány. V první řadě se jedná o projekty pojmenované JRuby a Jython, což jsou varianty jazyků Ruby a Python. Původní interpretry Ruby a Pythonu jsou naprogramovány v jazyku C (proto se ostatně tato varianta Pythonu nazývá CPython), JRuby a Jython jsou reimplementace pro JVM (navíc byl Python portován i na platformu .NET ve formě projektu IronPython a existuje i varianta Pythonu nazvaná PyPy naprogramovaná v samotném Pythonu, resp. přesněji řečeno v jeho zjednodušené variantě RPython). Na platformu JVM byl portován i programovací jazyk JavaScript, a to dokonce několikrát. Implementaci JavaScriptu zajišťují projekty Rhino a Nashhorn.

Obrázek 14: Logo programovacího jazyka JRuby.
Kawa
V případě projektu Kawa se jedná o implementaci jazyka Scheme naprogramovanou v Javě a běžící nad virtuálním strojem Javy (JVM). Ovšem současně se v žádném případě nejedná o pouhý primitivní interpret, ale o plnohodnotný překladač jazyka Scheme do bajtkódu JVM. Z benchmarků je patrné, že výsledný kód vůbec není pomalý ale naopak dokáže více než zdárně konkurovat dalším programovacím jazykům, které v současnosti nad JVM existují. Jenže to není vše, protože Kawa dokáže velmi dobře kooperovat i se samotným ekosystémem Javy – lze v ní vytvářet instance Javovských tříd, volat jejich metody, přistupovat k atributům atd. atd. Díky tomu může být Kawa použitelná i v rozsáhlých systémech naprogramovaných v Javě (ostatně LISPovské jazyky již dlouho slouží i ve funkci „lepidel“ mezi jednotlivými částmi aplikace).

Obrázek 15: Logo programovacího jazyka Kawa.
Další programovací jazyky portované na JVM
Na virtuální stroj Javy bylo portováno i mnoho dalších programovacích jazyků, ať již se jednalo o překladače či o interpretry. V následující tabulce jsou některé z těchto jazyků vypsány. V prvním sloupci je zobrazen název původního jazyka popř. rodiny jazyků, ve sloupci druhém pak jméno jeho konkrétní implementace pro JVM. Povšimněte si, že některé jazyky byly portovány několikrát (to se ostatně týkalo již výše zmíněného JavaScriptu):
Jazyk | Implementace pro JVM |
---|---|
Ada | JGNAT |
Arden Syntax | Arden2ByteCode |
COBOL | Micro Focus Visual COBOL |
ColdFusion Markup Language (CFML) | Adobe ColdFusion |
ColdFusion Markup Language (CFML) | Railo |
ColdFusion Markup Language (CFML) | Lucee |
ColdFusion Markup Language (CFML) | Open BlueDragon |
Common Lisp | Armed Bear Common Lisp |
Cypher | Neo4j |
Mercury | Mercury (Java grade) |
Pascal | MIDletPascal |
Pascal | Oxygene |
Perl 6 | Rakudo Perl 6 |
PHP | Quercus |
Prolog | JIProlog |
Prolog | TuProlog |
R | Renjin |
Rexx | NetRexx |
Ruby | JRuby |
Ruby | Mirah |
Scheme | Bigloo |
Scheme | Kawa |
Scheme | SISC |
Scheme | JScheme |
Tcl | Jacl |
Visual Basic | Jabaco |
8. Popularita programovacího jazyka Java
Programovací jazyk Java se přibližně po dvě desetiletí (a to je v oboru informatiky velmi dlouhá doba) pohyboval na samotné špičce popularity programovacích jazyků. Netýkalo se to „pouze“ IT profesionálů, protože se Java na některých univerzitách stala primárním programovacím jazykem, který se používal pro jak v kurzech pro výuku programování, tak i například návrhu architektury distribuovaných systémů (messaging) atd. V současnosti sice popularita Javy relativně klesá v porovnání s přímou i nepřímou konkurencí, nicméně se stále jedná o jeden z nejpopulárnějších jazyků současnosti. Z relativně velkého množství různých statistik se podívejme na známý Tiobe index, v němž se Java tento měsíc umístila na velmi dobré čtvrté příčce (dokonce před svým nejbližším konkurentem – jazykem C#):
# | |
---|---|
1 | Python |
2 | C++ |
3 | C |
4 | Java |
5 | C# |
6 | JavaScript |
7 | Go |
8 | Visual Basic |
9 | Delphi |
11 | Fortran |
Dlouhodobější trend vývoje popularity Java je zobrazen na tomto grafu.
Ovšem nemůžeme věřit pouze jedné statistice, u které navíc nejsou zcela zřejmé použité metriky. Podívejme se na známý žebříček PYPL PopularitY of Programming Language, ve kterém se Java dokonce umístila na druhém místě, ihned za Python:
1 | Python | 30.41 % | +1.3 % |
2 | Java | 15.12 % | –0.5 % |
3 | JavaScript | 7.93 % | –0.6 % |
4 | C/C++ | 6.98 % | +0.6 % |
5 | C# | 6.09 % | –0.7 % |
6 | R | 4.59 % | –0.1 % |
7 | PHP | 3.71 % | –0.8 % |
8 | Rust | 3.09 % | +0.5 % |
9 | TypeScript | 2.80 % | –0.1 % |
10 | Objective-C | 2.76 % | +0.3 % |
Na grafu získaném z této stránky je opět patrný relativní pokles popularity Javy, i když pouze pozvolný:

Obrázek 16: Popularita Javy měřená podle PYPL.
9. Třicet let v IT: uvedení do kontextu
Připomínáme si třicet let existence programovacího jazyka Java, takže je dobré uvést tento věk do kontextu. V další tabulce je vypsáno deset nejpopulárnějších programovacích jazyků podle Tiobe (vyměnil jsem jen SQL za Fortran z jedenácté pozice). Nyní nás však bude zajímat doba existence těchto jazyků. Jejich věk je uveden v posledním sloupci:
# | Jazyk | Vznik | Věk |
---|---|---|---|
1 | Python | 1991 | 34 |
2 | C++ | 1985 | 40 |
3 | C | 1972 | 53 |
4 | Java | 1995 | 30 |
5 | C# | 2000 | 25 |
6 | JavaScript | 1995 | 30 |
7 | Go | 2009 | 16 |
8 | Visual Basic (Classic) | 1991 | 24 |
9 | Delphi | 1995 | 30 |
11 | Fortran | 1957 | 68 |
Povšimněte si, že většina nejpopulárnějších jazyků je starších než 20 let. Jedinou výjimkou je Go, což ovšem na druhé straně vyvažuje Fortran (resp. původně FORTRAN). Tento údaj je zajímavý při porovnání s dalším statistikou, a to konkrétně věkem profesionálních vývojářů:
Věková skupina | Zastoupení |
---|---|
méně než 18 | 5% |
18–24 | 20% |
25–34 | 37% |
35–44 | 23% |
45–54 | 9% |
55–64 | 4% |
65-.. | 1% |
Co to znamená? 85% profesionálních vývojářů je mladších než 45 let a pokud začali svoji kariéru řekněme ve věku dvaceti let, znamená to, ze s velmi vysokou pravděpodobností pracují s programovacími jazyky, které byly používány ještě před jejich příchodem do praxe. Oblast programovacích jazyků je tedy v oblasti IT kupodivu velmi stabilní, i když to tak nemusí na první pohled vypadat díky velkému množství článků a zmínek o nových a stále rostoucích jazycích (typu Rust, Zig, před několika lety Clojure atd.).
10. Nové výzvy pro Javu
Jak jsme si již řekli v úvodní části dnešního článku, byla Java původně určena pro programování mikrovlnných trub a výtahů (alespoň tak vypadaly první prezentace). Nutno říci, že v této oblasti (mikrořadiče) se vlastně nikdy neujala, mj. i kvůli velkým paměťovým požadavkům virtuálního stroje (naopak se zde drží C popř. typicky „C s třídami“, tj. očesané C++). Ovšem právě v době vydání Javy došlo k velkému rozmachu Internetu, což již byla oblast, ve které se mohly projevit dobré vlastnosti tohoto jazyka i celé platformy – bezpečnější a přenositelnější aplikace, později relativně dobrá podpora pro paralelní běh či alespoň souběh většího množství vláken, automatický správce paměti atd.
11. Java: jazyk pro Internet
Java se začala používat pro tzv. middleware (aplikační servery a aplikace pro ně určené), vzniklo několik technologií pro dynamické generování HTML stránek (JSP, RichFaces apod.), v Javě byly vytvořeny message brokery a streaming platformy (ActiveMQ resp. Artemis a vlastně částečně i Apache Kafka) apod. Jedná se o technologie určené pro back end, nikoli pro front end.
Zapomenout nesmíme ani na Java applety, které umožňovaly běh i relativně složitých aplikací v rámci okna (plochy) webového prohlížeče. Názory na vhodnost či nevhodnost appletů se liší, ovšem díky sandboxingu (izolaci appletů) od celého desktopu se nejednalo o špatnou technologii – její plnohodnotná náhrada vlastně dodnes neexistuje, protože WebAssembly se stále vyvíjí a postrádá vlastnosti JVM (JIT a správce paměti).
12. Java na desktopu
Naproti tomu, i přes snahu některých společností, se Java příliš neprosadila na desktopu (a to existovaly snahy o vytvoření operačního systému založeného přímo na JVM). Do určité míry za to mohla problematická instalace takových aplikací (i když existovala technologie Java Web Start, dnes již nepodporovaná), ale i odlišný vzhled a chování Javovských aplikací a v neposlední řadě taktéž relativně pomalé reakce grafického uživatelského rozhraní. Systém událostí a handlerů pro každou akci generoval nové a nové objekty, o které se musel starat správce paměti.
13. Java a hry
Tradovalo se, že se programovací jazyk s automatickou správou paměti příliš nehodí pro tvorbu her; ostatně v této oblasti se stále na prvním místě používá jazyk C++. Java sice do určité míry podporovala tvorbu her, například bylo možné využít třídu VolatileImage pro kreslení v režimu celé obrazovky popř. použít BufferedImage s podporou operací typu BLT (bit block transfer). Existovaly i rozhraní pro OpenGL a Direct3D, ovšem Java se stále považovala v této oblasti za spíše druhořadý jazyk. Jenže pak přišel Minecraft, který byl (podle různých statistik) druhou nejhranější hrou roku 2024 (140 milionů hráčů, první je Roblox s 380 miliony). Minecraft ukázal, že optimalizovaný kód psaný v Javě a vhodná GUI knihovna mohou být využity pro tvorbu velmi úspěšné a graficky náročné hry.
14. Závěr
S trochou nadsázky se tvrdí, že Java je COBOLem 21.století. V oblasti enterprise systémů a middleware není toto tvrzení daleko od pravdy – a to v dobrém smyslu. Java je totiž velmi stabilní platformou, která však neustrnula ve vývoji a neustále se vylepšuje (modularita, streaming, vylepšené režimy JIT a AOT překladu atd.), takže se stále používá a pravděpodobně i bude používat. Pokud nedojde v oblasti IT k zásadní revoluci, lze předpokládat, že i za dalších třicet let se ještě s aplikacemi vytvořenými v Javě setkáme, i když nelze odhadnout, do jaké míry bude Java populární mezi mainstreamovými programátory.
15. Příloha: porovnání rychlosti JVM v režimu interpretru a JITu
Ve třetí kapitole jsme se zmínili o Just in Time překladači Javy (JIT) i o rozdílech oproti pouhé interpretaci Javovského bajtkódu. Rozdíl mezi interpretrem a JIT překladačem si ukážeme na výpočtu, který na stránkách Roota používám poměrně často (a to v různých programovacích jazycích). Jedná se o výpočet a vykreslení (rendering) Mandelbrotovy množiny s uložením výsledku do rastrového obrázku:

Obrázek 17: Výsledek běhu benchmarku by měl vypadat takto.
Úplný zdrojový kód jednoduchého benchmarku, který vykreslí Mandelbrotovu množinu, vypadá následovně:
import java.awt.Color; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; public class DrawMandelbrot { private static final int MAXITER = 1200; private static final int WIDTH = 1024; private static final int HEIGHT = 1024; public void drawMandelbrot() { BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); calcMandelbrot(image); writeImage(image); } private void writeImage(BufferedImage image) { try { ImageIO.write(image, "png", new File("mandel.png")); } catch (IOException e) { e.printStackTrace(); } } private void calcMandelbrot(BufferedImage image) { double cy = -1.5; for (int y = 0; y < HEIGHT; y++) { double cx = -2.0; for (int x = 0; x < WIDTH; x++) { double zx = 0.0, zy = 0.0; int iter = calcIter(cy, cx, zx, zy); int rgb = calcRGBColor(iter); image.setRGB(x, y, rgb); cx += 3.0/WIDTH; } cy += 3.0/HEIGHT; } } private int calcRGBColor(int iter) { Color color = Color.BLACK; if (iter < MAXITER) { color = new Color(iter&0xff, (iter*256/16)&0xff, (iter*256/32)&0xff); } int rgb = color.getRGB(); return rgb; } private int calcIter(double cy, double cx, double zx, double zy) { double zzx = zx; double zzy = zy; int iter = 0; while (iter < MAXITER) { double zx2 = zzx * zzx; double zy2 = zzy * zzy; if (zx2 + zy2 > 4.0) { break; } zzy = 2.0 * zzx * zzy + cy; zzx = zx2 - zy2 + cx; iter ++; } return iter; } public static void main(String[] args) { new DrawMandelbrot().drawMandelbrot(); } }
16. Výsledky benchmarků
Rozdíl mezi rychlostí (resp. pomalostí) interpretru oproti JIT překladačům můžeme zjišťovat jak různými sofistikovanými metodami, tak i triviálním porovnáním celkové doby běhu výše ukázaného benchmarku pro výpočet Mandelbrotovy množiny. Nejdříve je vypsán čas při použití C2 a C1 překladače a posléze i čas při přepnutí do režimu interpretace. Z výsledků je patrné, že interpretace je přibližně třikrát pomalejší (mnohdy ale bývá rozdíl i větší, například při manipulacích s poli atd.):
$ time java -server -XX:CompileThreshold=1000 DrawMandelbrot.java real 0m1.973s user 0m4.074s sys 0m0.225s $ time java -client -XX:CompileThreshold=1000 DrawMandelbrot.java real 0m1.988s user 0m3.968s sys 0m0.237s $ time java -Xint DrawMandelbrot.java real 0m13.920s user 0m13.849s sys 0m0.065s
17. Příloha: výsledek překladu metody calcIter C1 a C2 překladačem
Pro zajímavost se podívejme, jak vypadá výsledek just in time překladu metody calcIter použité v benchmarku. První varianta byla přeložena C1 překladačem (ten je rychlejší, ale neprovádí všechny optimalizace). Povšimněte si, že se jedná o 64bitový kód využívající i moderní rozšíření instrukční sady (vektorové instrukce). Navíc se parametry předávají přes registry a nikoli přes zásobník – Java zde nemusí dodržovat standardní ABI:
[Entry Point] # {method} {0x00007f93cfa888d8} 'calcIter' '(DDDD)I' in 'DrawMandelbrot' # this: rsi:rsi = 'DrawMandelbrot' # parm0: xmm0:xmm0 = double # parm1: xmm1:xmm1 = double # parm2: xmm2:xmm2 = double # parm3: xmm3:xmm3 = double # [sp+0x40] (sp of caller) 0x00007f943b9716e0: mov 0x8(%rsi),%r10d ; {no_reloc} 0x00007f943b9716e4: movabs $0x7f93d3000000,%r11 0x00007f943b9716ee: add %r11,%r10 0x00007f943b9716f1: cmp %rax,%r10 0x00007f943b9716f4: jne 0x00007f9442cad080 ; {runtime_call ic_miss_stub} 0x00007f943b9716fa: nopw 0x0(%rax,%rax,1) [Verified Entry Point] 0x00007f943b971700: mov %eax,-0x14000(%rsp) 0x00007f943b971707: push %rbp 0x00007f943b971708: sub $0x30,%rsp 0x00007f943b97170c: cmpl $0x1,0x20(%r15) 0x00007f943b971714: je 0x00007f943b97171b 0x00007f943b971716: call Stub::nmethod_entry_barrier ; {runtime_call StubRoutines (final stubs)} 0x00007f943b97171b: movabs $0x7f93cfa88d00,%rax 0x00007f943b971725: mov 0x8(%rax),%edi 0x00007f943b971728: add $0x2,%edi 0x00007f943b97172b: mov %edi,0x8(%rax) 0x00007f943b97172e: and $0xffe,%edi 0x00007f943b971734: test %edi,%edi 0x00007f943b971736: je 0x00007f943b9717fe ;*dload {reexecute=0 rethrow=0 return_oop=0} ; - DrawMandelbrot::calcIter@0 (line 63) 0x00007f943b97173c: mov $0x0,%eax 0x00007f943b971741: jmp 0x00007f943b9717e0 ;*iload {reexecute=0 rethrow=0 return_oop=0} ; - DrawMandelbrot::calcIter@11 (line 66) 0x00007f943b971746: xchg %ax,%ax 0x00007f943b971748: vmovapd %xmm2,%xmm4 0x00007f943b97174c: vmulsd %xmm2,%xmm4,%xmm4 0x00007f943b971750: vmovapd %xmm3,%xmm5 0x00007f943b971754: vmulsd %xmm3,%xmm5,%xmm5 0x00007f943b971758: vmovapd %xmm4,%xmm6 0x00007f943b97175c: vaddsd %xmm5,%xmm6,%xmm6 0x00007f943b971760: vmovsd -0xa8(%rip),%xmm7 # 0x00007f943b9716c0 ; {section_word} 0x00007f943b971768: vucomisd %xmm7,%xmm6 0x00007f943b97176c: mov $0xffffffff,%esi 0x00007f943b971771: jp 0x00007f943b97178b 0x00007f943b971777: jb 0x00007f943b97178b 0x00007f943b97177d: mov $0x0,%esi 0x00007f943b971782: je 0x00007f943b97178b 0x00007f943b971788: inc %rsi ;*dcmpl {reexecute=0 rethrow=0 return_oop=0} ; - DrawMandelbrot::calcIter@41 (line 70) 0x00007f943b97178b: test %esi,%esi 0x00007f943b97178d: jg 0x00007f943b9717eb ;*ifle {reexecute=0 rethrow=0 return_oop=0} ; - DrawMandelbrot::calcIter@42 (line 70) 0x00007f943b971793: vmulsd -0xd3(%rip),%xmm2,%xmm2 # 0x00007f943b9716c8 ; {section_word} 0x00007f943b97179b: vmulsd %xmm3,%xmm2,%xmm2 0x00007f943b97179f: vaddsd %xmm0,%xmm2,%xmm2 0x00007f943b9717a3: vsubsd %xmm5,%xmm4,%xmm4 0x00007f943b9717a7: vaddsd %xmm1,%xmm4,%xmm4 0x00007f943b9717ab: inc %eax 0x00007f943b9717ad: movabs $0x7f93cfa88d00,%rsi 0x00007f943b9717b7: mov 0xc(%rsi),%edi 0x00007f943b9717ba: add $0x2,%edi 0x00007f943b9717bd: mov %edi,0xc(%rsi) 0x00007f943b9717c0: and $0x7ffe,%edi 0x00007f943b9717c6: test %edi,%edi 0x00007f943b9717c8: je 0x00007f943b97181f ;*goto {reexecute=0 rethrow=0 return_oop=0} ; - DrawMandelbrot::calcIter@73 (line 77) 0x00007f943b9717ce: mov 0x450(%r15),%r10 ; ImmutableOopMap {} ;*goto {reexecute=1 rethrow=0 return_oop=0} ; - (reexecute) DrawMandelbrot::calcIter@73 (line 77) 0x00007f943b9717d5: test %eax,(%r10) ; {poll} 0x00007f943b9717d8: vmovapd %xmm2,%xmm3 0x00007f943b9717dc: vmovapd %xmm4,%xmm2 ;*goto {reexecute=0 rethrow=0 return_oop=0} ; - DrawMandelbrot::calcIter@73 (line 77) 0x00007f943b9717e0: cmp $0x4b0,%eax 0x00007f943b9717e5: jl 0x00007f943b971748 ;*if_icmpge {reexecute=0 rethrow=0 return_oop=0} ; - DrawMandelbrot::calcIter@16 (line 66) 0x00007f943b9717eb: add $0x30,%rsp 0x00007f943b9717ef: pop %rbp 0x00007f943b9717f0: cmp 0x448(%r15),%rsp ; {poll_return} 0x00007f943b9717f7: ja 0x00007f943b97183d 0x00007f943b9717fd: ret 0x00007f943b9717fe: movabs $0x7f93cfa888d8,%r10 ; {metadata({method} {0x00007f93cfa888d8} 'calcIter' '(DDDD)I' in 'DrawMandelbrot')} 0x00007f943b971808: mov %r10,0x8(%rsp) 0x00007f943b97180d: movq $0xffffffffffffffff,(%rsp) 0x00007f943b971815: call 0x00007f9442d74c00 ; ImmutableOopMap {rsi=Oop } ;*synchronization entry ; - DrawMandelbrot::calcIter@-1 (line 63) ; {runtime_call counter_overflow Runtime1 stub} 0x00007f943b97181a: jmp 0x00007f943b97173c 0x00007f943b97181f: movabs $0x7f93cfa888d8,%r10 ; {metadata({method} {0x00007f93cfa888d8} 'calcIter' '(DDDD)I' in 'DrawMandelbrot')} 0x00007f943b971829: mov %r10,0x8(%rsp) 0x00007f943b97182e: movq $0x49,(%rsp) 0x00007f943b971836: call 0x00007f9442d74c00 ; ImmutableOopMap {} ;*goto {reexecute=1 rethrow=0 return_oop=0} ; - (reexecute) DrawMandelbrot::calcIter@73 (line 77) ; {runtime_call counter_overflow Runtime1 stub} 0x00007f943b97183b: jmp 0x00007f943b9717ce 0x00007f943b97183d: movabs $0x7f943b9717f0,%r10 ; {internal_word} 0x00007f943b971847: mov %r10,0x460(%r15) 0x00007f943b97184e: jmp 0x00007f9442cb4000 ; {runtime_call SafepointBlob} 0x00007f943b971853: mov 0x4f8(%r15),%rax 0x00007f943b97185a: movq $0x0,0x4f8(%r15) 0x00007f943b971865: movq $0x0,0x500(%r15) 0x00007f943b971870: add $0x30,%rsp 0x00007f943b971874: pop %rbp 0x00007f943b971875: jmp 0x00007f9442d6db00 ; {runtime_call unwind_exception Runtime1 stub} 0x00007f943b97187a: hlt 0x00007f943b97187b: hlt 0x00007f943b97187c: hlt 0x00007f943b97187d: hlt 0x00007f943b97187e: hlt 0x00007f943b97187f: hlt [Exception Handler] 0x00007f943b971880: call 0x00007f9442d71100 ; {no_reloc} 0x00007f943b971885: movabs $0x7f945972c169,%rdi ; {external_word} 0x00007f943b97188f: and $0xfffffffffffffff0,%rsp 0x00007f943b971893: call 0x00007f94591cbbf0 ; {runtime_call MacroAssembler::debug64(char*, long, long*)} 0x00007f943b971898: hlt [Deopt Handler Code] 0x00007f943b971899: movabs $0x7f943b971899,%r10 ; {section_word} 0x00007f943b9718a3: push %r10 0x00007f943b9718a5: jmp 0x00007f9442cb32a0 ; {runtime_call DeoptimizationBlob} 0x00007f943b9718aa: hlt 0x00007f943b9718ab: hlt 0x00007f943b9718ac: hlt 0x00007f943b9718ad: hlt 0x00007f943b9718ae: hlt 0x00007f943b9718af: hlt -------------------------------------------------------------------------------- [/Disassembly]
Naproti tomu C2 překladač vyprodukoval poněkud odlišný strojový kód, který je navíc kratší:
[Entry Point] # {method} {0x00007feabfa888d8} 'calcIter' '(DDDD)I' in 'DrawMandelbrot' # this: rsi:rsi = 'DrawMandelbrot' # parm0: xmm0:xmm0 = double # parm1: xmm1:xmm1 = double # parm2: xmm2:xmm2 = double # parm3: xmm3:xmm3 = double # [sp+0x30] (sp of caller) 0x00007feb2fe2acc0: mov 0x8(%rsi),%r10d ; {no_reloc} 0x00007feb2fe2acc4: movabs $0x7feac3000000,%r11 0x00007feb2fe2acce: add %r11,%r10 0x00007feb2fe2acd1: cmp %r10,%rax 0x00007feb2fe2acd4: jne 0x00007feb2f6ad080 ; {runtime_call ic_miss_stub} 0x00007feb2fe2acda: xchg %ax,%ax 0x00007feb2fe2acdc: nopl 0x0(%rax) [Verified Entry Point] 0x00007feb2fe2ace0: mov %eax,-0x14000(%rsp) 0x00007feb2fe2ace7: push %rbp 0x00007feb2fe2ace8: sub $0x20,%rsp 0x00007feb2fe2acec: cmpl $0x1,0x20(%r15) 0x00007feb2fe2acf4: jne 0x00007feb2fe2adaa ;*synchronization entry ; - DrawMandelbrot::calcIter@-1 (line 63) 0x00007feb2fe2acfa: xor %eax,%eax 0x00007feb2fe2acfc: mov $0x3e8,%r11d 0x00007feb2fe2ad02: mov $0x4b0,%r10d 0x00007feb2fe2ad08: sub %eax,%r10d 0x00007feb2fe2ad0b: cmp $0x3e8,%r10d 0x00007feb2fe2ad12: cmova %r11d,%r10d 0x00007feb2fe2ad16: add %eax,%r10d 0x00007feb2fe2ad19: jmp 0x00007feb2fe2ad24 0x00007feb2fe2ad1b: nopl 0x0(%rax,%rax,1) 0x00007feb2fe2ad20: vmovapd %xmm4,%xmm2 ;*dload {reexecute=0 rethrow=0 return_oop=0} ; - DrawMandelbrot::calcIter@19 (line 68) 0x00007feb2fe2ad24: vmulsd %xmm3,%xmm3,%xmm4 ;*dmul {reexecute=0 rethrow=0 return_oop=0} ; - DrawMandelbrot::calcIter@30 (line 69) 0x00007feb2fe2ad28: vmulsd %xmm2,%xmm2,%xmm5 ;*dmul {reexecute=0 rethrow=0 return_oop=0} ; - DrawMandelbrot::calcIter@23 (line 68) 0x00007feb2fe2ad2c: vaddsd %xmm4,%xmm5,%xmm6 0x00007feb2fe2ad30: vucomisd -0x98(%rip),%xmm6 # 0x00007feb2fe2aca0 ; {section_word} 0x00007feb2fe2ad38: jbe 0x00007feb2fe2ad4d ;*ifle {reexecute=0 rethrow=0 return_oop=0} ; - DrawMandelbrot::calcIter@42 (line 70) 0x00007feb2fe2ad3a: add $0x20,%rsp 0x00007feb2fe2ad3e: pop %rbp 0x00007feb2fe2ad3f: cmp 0x448(%r15),%rsp ; {poll_return} 0x00007feb2fe2ad46: ja 0x00007feb2fe2ad94 0x00007feb2fe2ad4c: ret 0x00007feb2fe2ad4d: vsubsd %xmm4,%xmm5,%xmm4 0x00007feb2fe2ad51: vaddsd %xmm1,%xmm4,%xmm4 ;*dadd {reexecute=0 rethrow=0 return_oop=0} ; - DrawMandelbrot::calcIter@67 (line 75) 0x00007feb2fe2ad55: vaddsd %xmm2,%xmm2,%xmm2 0x00007feb2fe2ad59: vmulsd %xmm3,%xmm2,%xmm2 0x00007feb2fe2ad5d: vaddsd %xmm0,%xmm2,%xmm3 ;*dadd {reexecute=0 rethrow=0 return_oop=0} ; - DrawMandelbrot::calcIter@58 (line 74) 0x00007feb2fe2ad61: inc %eax ;*iinc {reexecute=0 rethrow=0 return_oop=0} ; - DrawMandelbrot::calcIter@70 (line 76) 0x00007feb2fe2ad63: cmp %r10d,%eax 0x00007feb2fe2ad66: jl 0x00007feb2fe2ad20 ;*goto {reexecute=0 rethrow=0 return_oop=0} ; - DrawMandelbrot::calcIter@73 (line 77) 0x00007feb2fe2ad68: mov 0x450(%r15),%r10 ; ImmutableOopMap {} ;*goto {reexecute=1 rethrow=0 return_oop=0} ; - (reexecute) DrawMandelbrot::calcIter@73 (line 77) 0x00007feb2fe2ad6f: test %eax,(%r10) ;*goto {reexecute=0 rethrow=0 return_oop=0} ; - DrawMandelbrot::calcIter@73 (line 77) ; {poll} 0x00007feb2fe2ad72: cmp $0x4b0,%eax 0x00007feb2fe2ad77: jge 0x00007feb2fe2ad7f 0x00007feb2fe2ad79: vmovapd %xmm4,%xmm2 0x00007feb2fe2ad7d: jmp 0x00007feb2fe2ad02 0x00007feb2fe2ad7f: mov $0xffffff45,%esi 0x00007feb2fe2ad84: mov %eax,(%rsp) 0x00007feb2fe2ad87: call 0x00007feb2f6b2f00 ; ImmutableOopMap {} ;*if_icmpge {reexecute=1 rethrow=0 return_oop=0} ; - (reexecute) DrawMandelbrot::calcIter@16 (line 66) ; {runtime_call UncommonTrapBlob} 0x00007feb2fe2ad8c: nopl 0x100027c(%rax,%rax,1) ;*if_icmpge {reexecute=0 rethrow=0 return_oop=0} ; - DrawMandelbrot::calcIter@16 (line 66) ; {other} 0x00007feb2fe2ad94: movabs $0x7feb2fe2ad3f,%r10 ; {internal_word} 0x00007feb2fe2ad9e: mov %r10,0x460(%r15) 0x00007feb2fe2ada5: jmp 0x00007feb2f6b4000 ; {runtime_call SafepointBlob} 0x00007feb2fe2adaa: call Stub::nmethod_entry_barrier ; {runtime_call StubRoutines (final stubs)} 0x00007feb2fe2adaf: jmp 0x00007feb2fe2acfa 0x00007feb2fe2adb4: hlt 0x00007feb2fe2adb5: hlt 0x00007feb2fe2adb6: hlt 0x00007feb2fe2adb7: hlt [Exception Handler] 0x00007feb2fe2adb8: jmp 0x00007feb2f777500 ; {no_reloc} [Deopt Handler Code] 0x00007feb2fe2adbd: call 0x00007feb2fe2adc2 0x00007feb2fe2adc2: subq $0x5,(%rsp) 0x00007feb2fe2adc7: jmp 0x00007feb2f6b32a0 ; {runtime_call DeoptimizationBlob} 0x00007feb2fe2adcc: hlt 0x00007feb2fe2adcd: hlt 0x00007feb2fe2adce: hlt 0x00007feb2fe2adcf: hlt -------------------------------------------------------------------------------- [/Disassembly]
18. Odkazy na Internetu
- Tiobe index
https://www.tiobe.com/tiobe-index/ - PYPL PopularitY of Programming Language
https://pypl.github.io/PYPL.html - StackOverflow developer survery 2024: technology
https://survey.stackoverflow.co/2024/technology - Java version history
https://en.wikipedia.org/wiki/Java_version_history - Java history
https://en.wikipedia.org/wiki/Java_(software_platform)#History - Is Java the NEW COBOL in 2024?
https://blog.stackademic.com/is-java-the-new-cobol-in-2024–4b82de559f54 - Future of Java: The Top 7 Java Trends (2025)
https://www.finoit.com/articles/future-of-java/ - The Future of a Java Developer in 2025: Navigating the Evolution
https://medium.com/@internshipgate/the-future-of-a-java-developer-in-2025-navigating-the-evolution-3c8531102c38 - Top 10 Programming Languages For 2025
https://www.geeksforgeeks.org/top-programming-languages-of-the-future-2025/ - Software Developers Are Aging Out. Here Are The Facts.
https://medium.com/@tsecretdeveloper/software-developers-are-aging-out-here-are-the-facts-9ac112640d14 - Age Demographics Among Professional Developers: Trends and Transformations in the IT Industry
https://itstarter.net/en/age-demographics-among-professional-developers/ - Java's 20 Years Of Innovation
https://www.forbes.com/sites/oracle/2015/05/20/javas-20-years-of-innovation/ - The Java Story: History and Background
https://cs.smu.ca/~porter/csc/465/notes/java_story_history.html - May 23, 1995: Sun Released Java Programming, MySQL Released RDBMS
https://dayintechhistory.com/dith/23–1995-sun-released-java-programming-mysql-released-rdbms/ - Java Logo
https://examples.javacodegeeks.com/java-logo/ - Kawa scheme language
https://www.gnu.org/software/kawa/ - Třicet let od vydání revolučního Turbo Pascalu 5.5
https://www.root.cz/clanky/tricet-let-od-vydani-revolucniho-turbo-pascalu-5–5/ - The future's bright… the future's Cobol
https://www.root.cz/clanky/the-future-s-bright-the-future-s-cobol/ - Sedmdesátiny assemblerů: lidsky čitelný strojový kód
https://www.root.cz/clanky/sedmdesatiny-assembleru-lidsky-citelny-strojovy-kod/ - Šedesátiny převratného programovacího jazyka ALGOL-60
https://www.root.cz/clanky/sedesatiny-prevratneho-programovaciho-jazyka-algol-60/ - Další kulaté výročí v IT: dvacet let existence Pythonu 2
https://www.root.cz/clanky/dalsi-kulate-vyroci-v-it-dvacet-let-existence-pythonu-2/ - Oslava 55 let od vzniku první implementace jazyka APL
https://www.root.cz/clanky/oslava-55-let-od-vzniku-prvni-implementace-programovaciho-jazyka-apl/ - Clojure
https://clojure.org/ - Groovy
http://groovy-lang.org/ - Nashorn
https://github.com/openjdk/nashorn - JRuby
http://jruby.org/ - Jython
http://www.jython.org/ - Kotlin
http://kotlinlang.org/ - Scala
https://www.scala-lang.org/ - Kawa
https://www.gnu.org/software/kawa/ - Most used programming languages among developers worldwide 2024
https://www.statista.com/statistics/793628/worldwide-developer-survey-most-used-languages/ - Susan Kare
https://en.wikipedia.org/wiki/Susan_Kare - Java Debug Wire Protocol
https://en.wikipedia.org/wiki/Java_Debug_Wire_Protocol - Java Virtual Machine Tools Interface
https://en.wikipedia.org/wiki/Java_Virtual_Machine_Tools_Interface - Java Management Extensions
https://en.wikipedia.org/wiki/Java_Management_Extensions - Seriál Programovaci jazyk Java a JVM
https://www.root.cz/serialy/programovaci-jazyk-java-a-jvm/ - NULL: The Billion Dollar Mistake
https://hackernoon.com/null-the-billion-dollar-mistake-8t5z32d6