David Harron, l'auteur du matériel que nous publions aujourd'hui, a posé la question suivante: «Une personne qui a travaillé pendant plus de 10 ans chez Sun Microsystems dans l'équipe Java SE, jusqu'au dernier souffle, ne devrait-elle penser qu'au bytecode Java et créer des instances d'interfaces abstraites? ". Il a posé cette question par rapport à lui-même, et pour lui la plateforme Node.js, après Java, s'est avérée être comme une bouffée d'air frais. David dit que lorsqu'il a été licencié de Sun en janvier 2009 (juste avant le rachat de cette société Oracle), il a découvert Node.js. Cette technologie l'a accroché. Qu'est-ce que cela signifie «accroché»? Depuis 2010, il a beaucoup écrit sur la programmation de Node.js. À savoir, il a écrit plusieurs livres, dont Node.js Web Development, dont la quatrième édition est sortie cette année. Il a préparé de nombreux petits documents sur Node.js publiés sur Internet. En fait, il a passé beaucoup de temps et d'efforts à parler de la plate-forme Node.js et des fonctionnalités JavaScript. Pourquoi est-ce que ceux qui travaillaient auparavant exclusivement en Java étaient si attirés par Node.js et JavaScript?

À propos du monde Java
En travaillant chez Sun, je croyais à la technologie Java. J'ai fait des présentations dans JavaONE, participé au développement de la classe java.awt.Robot, organisé l'événement Mustang Regressions Contest (c'était un concours visant à trouver des bogues en Java 1.6), aidé au lancement du projet de licence de distribution pour Java, qui a servi de réponse à la question sur les distributions JDK Linux avant l'avènement d'OpenJDK. Plus tard, j'ai joué un rôle dans le lancement du projet OpenJDK. En cours de route, pendant environ 6 ans, j'ai publié des articles de blog sur java.net (maintenant ce site est fermé). Il s'agissait de 1 à 2 articles par semaine consacrés aux événements importants de l'écosystème Java. Un rôle important dans mon travail a été joué en protégeant Java de ceux qui prédisaient un avenir sombre pour cette technologie.
Ce prix, le Duke Award, a été décerné aux employés les plus distingués de Sun. Je l'ai eu après avoir organisé le concours de régression MustangQu'est-il arrivé à la personne qui a tant fait avec tout ce qui touche à Java? En fait, ici, je veux parler de la façon dont je suis passé d'un passionné de Java à un ardent défenseur de Node.js et de JavaScript.
Je dois dire que ce qui m'est arrivé ne peut pas être qualifié d'abandon complet de Java. Au cours des 3 dernières années, j'ai écrit pas mal de code Java, utilisé Spring et Hibernate. Bien que ce que je fais maintenant dans ce domaine me plaît vraiment (je travaille dans l'industrie de l'énergie solaire, fais ce que j'aime faire, par exemple - j'écris des demandes pour travailler avec des données du secteur de l'énergie), la programmation Java dans mes yeux maintenant a perdu son ancienne splendeur.
Deux années de développement avec Spring m'ont permis de clarifier clairement une chose importante: une tentative de cacher des mécanismes complexes ne mène pas à la simplicité, elle ne fait que conduire à l'apparition de structures encore plus complexes.
Voici, en bref, les principales idées que je vais aborder dans ce document:
- Les programmes Java sont pleins de code passe-partout qui cache les intentions du programmeur.
- Travailler avec Spring et Spring Boot m'a donné une bonne leçon, à savoir qu'essayer de cacher des mécanismes complexes conduit à des constructions encore plus complexes.
- La plate-forme Java EE est un projet créé, pour ainsi dire, par des «efforts communs», qui couvre absolument tous les besoins de développement d'applications d'entreprise. En conséquence, la plate-forme Java EE s'est révélée prohibitive.
- Développer avec Spring est, jusqu'à un certain point, une expérience agréable. Cette illusion disparaît le jour où une exception qui est complètement impossible à comprendre vient des profondeurs d'un sous-système dont vous n'avez jamais entendu parler, et il faut au moins trois jours pour découvrir quel est le problème.
- De quels mécanismes auxiliaires qui créent une charge excessive sur le système avez-vous besoin d'un framework qui puisse "écrire" du code pour les programmeurs?
- Bien que les IDE comme Eclipse soient des applications puissantes, ils sont un indicateur de la complexité de l'écosystème Java.
- La plate-forme Node.js est née des efforts d'une personne pour améliorer sa vision d'une architecture événementielle légère.
- La communauté JavaScript semble être enthousiaste à l'idée de se débarrasser du code passe-partout, qui permet aux programmeurs d'exprimer leurs intentions aussi clairement que possible.
- Async / Wait est une solution au problème d'enfer de rappel JS, qui est un exemple de rejet du code de modèle et contribue à la clarté de l'expression des intentions des programmeurs.
- La programmation de Node.js est un vrai plaisir.
- Il n'y a pas de typage fort spécifique à Java en JavaScript. C'est la bénédiction et la malédiction de la langue. Cela facilite l'écriture du code, mais pour vérifier son exactitude, vous devez consacrer plus de temps aux tests.
- Le système de gestion des paquets introduit par npm / yarn est facile et amusant à utiliser. Elle ne peut pas être comparée à Maven.
- Java et Node.js offrent d'excellentes performances. Cela va à l'encontre du mythe selon lequel JavaScript est un langage lent, dont l'utilisation conduit à de mauvaises performances de la plate-forme Node.js.
- Performance Node.js s'appuie sur les efforts de Google pour améliorer la V8, le moteur qui affecte la vitesse du navigateur Chrome.
- La concurrence féroce entre les fabricants de moteurs JS basés sur navigateur contribue au développement de JavaScript, ce qui est très bénéfique pour Node.js.
À propos des problèmes de développement Java
Certains outils ou objets sont le résultat de nombreuses années d'efforts d'ingénieurs pour les améliorer. Les programmeurs essaient différentes idées, suppriment les attributs inutiles et obtiennent par conséquent des entités dans lesquelles il y a exclusivement ce qui est nécessaire pour résoudre un certain problème. Souvent, ces technologies ont une sorte de simplicité très attrayante qui cache de puissantes capacités. Cela ne s'applique pas à Java.
Spring est un framework populaire pour développer des applications Web basées sur Java.
L'objectif principal de Spring, et en particulier de Spring Boot, est de fournir la possibilité d'utiliser la pile Java EE préconfigurée. Le programmeur qui utilise Spring ne doit pas, pour créer un système prêt à l'emploi, prendre soin des servlets, des systèmes de stockage persistants, des serveurs d'applications et de ce qui est encore inconnu. Toutes ces préoccupations sont transmises à Spring, et le programmeur écrit du code qui implémente la logique de l'application. Par exemple, les mécanismes JPARepository sont responsables de la génération de requêtes de base de données pour les méthodes dont les noms ressemblent à
findUserByFirstName
. Le programmeur n'a pas à écrire le code de ces méthodes. Il suffit de transmettre la description de la méthode au système, et Spring fera le reste.
Tout cela semble très bien, c'est agréable de travailler dans ce style, mais - jusqu'à ce que quelque chose d'inattendu se produise.
Je veux dire une situation où, par exemple, une Hibernate
PersistentObjectException
est levée avec l'
detached entity passed to persist
message
detached entity passed to persist
. Qu'est-ce que cela pourrait signifier? Il a fallu plusieurs jours pour le découvrir. Il s'est avéré que si vous décrivez tout de manière très simplifiée, cela signifie que les données JSON reçues au point de terminaison REST ont des champs ID avec certaines valeurs. Hibernate, encore une fois, s'il n'entre pas dans les détails, cherche à contrôler les valeurs d'ID et, par conséquent, lève l'exception obscure ci-dessus. Il existe des milliers de ces messages d'erreur qui prêtent à confusion et sont difficiles à lire. Étant donné qu'il existe des cascades entières de sous-systèmes basés les uns sur les autres au printemps, la pile de printemps ressemble à un ennemi juré d'un programmeur qui le regarde et attend que le programmeur fasse la moindre erreur, et lorsque cela se produit, lève des exceptions qui ne sont pas compatibles avec lui fonctionnement normal de l'application.
De plus, vous pouvez ici rappeler les traces de pile les plus longues. Ils représentent plusieurs écrans remplis de toutes sortes de méthodes abstraites. Spring crée évidemment la configuration nécessaire pour implémenter ce qui est exprimé dans le code. Un tel niveau d'abstraction, sans aucun doute, nécessite une quantité considérable de logique auxiliaire, qui vise à découvrir tout ce qui est nécessaire au fonctionnement du code, par exemple, pour répondre aux demandes. Et les longues traces de pile ne sont pas nécessairement mauvaises. De telles choses sont plus probablement un symptôme, conduisant à la question de savoir quel type de charge sur le système est créé par des mécanismes auxiliaires.
Comment la méthode
findUserByFirstName
est-
findUserByFirstName
, étant donné que le programmeur n'a pas écrit le code d'une telle méthode? Le framework doit analyser le nom de la méthode, comprendre l'intention du programmeur, créer quelque chose comme une arborescence de syntaxe abstraite, générer une sorte de code SQL, etc. Comment tout cela charge-t-il le système? Et tout cela n'existe que pour que le programmeur n'ait pas besoin d'écrire du code?
Après avoir traversé quelques dizaines de fois quelque chose comme rechercher le sens de l'erreur ci-dessus, passer des semaines à essayer de percer des secrets que vous ne devriez pas, dans l'ensemble, découvrir, vous pouvez arriver à la même conclusion que je suis arrivé à . Son sens est qu'une tentative de cacher des mécanismes complexes ne conduit pas à la simplicité, elle ne fait que conduire à l'apparition de structures encore plus complexes. La plateforme Node.js est beaucoup plus simple.
Le slogan «Compatibility Matters» a caché une merveilleuse idée, selon laquelle la compatibilité descendante était la caractéristique la plus importante de la plate-forme Java. Nous avons pris cela au sérieux, en mettant des images sur des t-shirts comme celui que vous pouvez voir ci-dessous.
La rétrocompatibilité est très importante.Bien sûr, ce niveau d'attention à la compatibilité descendante peut être une source d'anxiété constante, et de temps en temps, il est utile de s'éloigner des anciens mécanismes qui ne bénéficient plus.
Java et Node.js
Spring et Java EE sont trop compliqués. La plateforme Node.js dans leur contexte est perçue comme une bouffée d'air frais. La première chose que vous remarquez lorsque vous vous familiarisez avec Node.js est l'approche de Ryan Dahl pour le développement du noyau de la plate-forme. Son expérience lui a montré que des plates-formes qui utilisent des flux sont nécessaires pour créer des systèmes complexes et lourds. Il cherchait autre chose et a passé quelques années à améliorer l'ensemble des mécanismes de base incorporés dans Node.js. En conséquence, il a obtenu un système léger qui se caractérise par un seul thread d'exécution, une utilisation inventive des fonctions JavaScript anonymes comme rappels asynchrones et une bibliothèque d'exécution qui implémente à l'origine des mécanismes asynchrones. Le message initial lors de la création d'un tel système était de fournir un traitement d'événements hautes performances avec la livraison de ces événements dans une fonction de rappel.
Ensuite, une caractéristique importante de Node.js est l'utilisation de JavaScript. On a le sentiment que ceux qui écrivent en JS ont tendance à se débarrasser du code du modèle, ce qui leur permet de décrire clairement les intentions du programmeur.
Comme exemple de la différence entre Java et JavaScript, considérons l'implémentation des fonctions d'écoute (observateurs). En Java, pour travailler avec des écouteurs, vous devez créer une instance spécifique de l'interface abstraite. Cela implique l'utilisation de constructions de langage volumineuses qui cachent l'essence de ce qui se passe. Comment discerner l'intention d'un programmeur caché sous les couvertures du code passe-partout?
JavaScript utilise à la place de simples fonctions anonymes. Lors de la mise en œuvre d'un écouteur, vous n'avez pas besoin de rechercher une interface abstraite appropriée. Il suffit, sans avoir besoin d'utiliser une variété de textes auxiliaires, d'écrire le code nécessaire.
Donc, voici une idée importante qui peut être tirée de l'analyse des mécanismes ci-dessus: la plupart des langages de programmation cachent les intentions du programmeur, ce qui conduit au fait que le code est difficile à comprendre.
La décision concernant l'utilisation des fonctions de rappel qu'offre Node.js semble très attrayante. Mais ce n'est pas sans problèmes.
Résolution de problèmes et résolution de problèmes
En JavaScript, il y a depuis longtemps deux problèmes associés à la programmation asynchrone. Le premier est ce que Node.js appelle l'enfer de rappel. Ce problème réside dans le fait que, pendant le développement, il est facile de tomber dans un piège construit à partir de fonctions de rappel profondément imbriquées, où chaque niveau d'imbrication complique le programme, ainsi que le traitement des résultats du code et des erreurs. Il y avait un autre problème lié à cela, dont l'essence était que les mécanismes du langage JavaScript n'ont pas aidé le programmeur à exprimer correctement les idées d'exécution de code asynchrone.
Plusieurs bibliothèques ont vu le jour pour simplifier le développement asynchrone sur JS. Mais ceci est un autre exemple d'une tentative de cacher des mécanismes complexes qui ne fait qu'apparaître des structures encore plus complexes.
Prenons un exemple:
const async = require('async'); const fs = require('fs'); const cat = function(filez, fini) { async.eachSeries(filez, function(filenm, next) { fs.readFile(filenm, 'utf8', function(err, data) { if (err) return next(err); process.stdout.write(data, 'utf8', function(err) { if (err) next(err); else next(); }); }); }, function(err) { if (err) fini(err); else fini(); }); }; cat(process.argv.slice(2), function(err) { if (err) console.error(err.stack); });
Il s'agit d'une imitation non descriptive de la
cat
Unix. La bibliothèque
async
dans la simplification des séquences d'appels asynchrones. Cependant, son utilisation nécessite une grande quantité de code passe-partout qui cache l'intention du programmeur.
En substance, ce code contient une boucle. Il n'est pas écrit comme un cycle régulier, il n'utilise pas de constructions naturelles de la description des cycles. De plus, les résultats de l'exécution du code et les erreurs générées par ceux-ci ne parviennent pas à l'endroit où ils auraient été exacts. Ils sont bloqués dans les rappels, ce qui n'est pas pratique. Mais, avant la mise en œuvre des normes ES2015 / 2016 dans Node.js, rien de mieux ne pouvait être fait.
Si nous réécrivons ce code en tenant compte des nouvelles fonctionnalités, qui sont notamment disponibles dans Node.js 10.x, nous obtenons ce qui suit:
const fs = require('fs').promises; async function cat(filenmz) { for (var filenm of filenmz) { let data = await fs.readFile(filenm, 'utf8'); await new Promise((resolve, reject) => { process.stdout.write(data, 'utf8', (err) => { if (err) reject(err); else resolve(); }); }); } } cat(process.argv.slice(2)).catch(err => { console.error(err.stack); });
Dans cet exemple, nous avons utilisé la construction
async/await
. Les mêmes mécanismes asynchrones sont présentés ici comme dans l'exemple précédent, mais les structures habituelles utilisées dans l'organisation des boucles sont utilisées ici. Travailler avec les résultats et les erreurs semble tout à fait normal. Un tel code est plus facile à lire et à écrire. Cette approche permet de comprendre facilement l'intention du programmeur.
Le seul inconvénient est que
process.stdout.write
n'a pas d'interface Promise, par conséquent, ce mécanisme ne peut pas être utilisé dans les fonctions asynchrones sans l'envelopper dans une promesse.
Nous pouvons maintenant conclure que le problème de l'enfer de rappel en JavaScript a été résolu d'une manière différente de celle d'essayer de cacher des mécanismes complexes. Au lieu de cela, des modifications ont été apportées à la langue, ce qui a résolu le problème lui-même et nous a évités les inconvénients causés par la nécessité d'utiliser de grandes quantités de code de modèle dans une solution temporaire. De plus, avec l'utilisation du mécanisme async / wait, le code est simplement devenu plus beau.
Nous avons commencé cette section par une discussion sur la faille de Node.js, mais une excellente solution à l'enfer d'un rappel a provoqué la discussion des failles en une discussion sur les points forts de Node.js et JavaScript.
Forte typage, interfaces et clarté de code imaginaire
À l'époque où je protégeais Java de toutes sortes d'attaques, je soulignais que le typage strict vous permet d'écrire d'énormes applications. A cette époque, le développement de systèmes monolithiques était utilisé (il n'y avait pas de microservices, il n'y avait pas de Docker et similaires). Comme Java est un langage fortement typé, le compilateur Java aide le programmeur à éviter de nombreux problèmes en l'empêchant de compiler le mauvais code.
JavaScript, contrairement à Java, n'est pas fortement typé. De cela, nous pouvons tirer la conclusion évidente que le programmeur ne sait pas exactement avec quels objets il doit travailler. Comment un programmeur peut-il savoir quoi faire, par exemple, avec un certain objet reçu de quelque part?
Le revers d'un typage Java fort est que vous devez constamment effectuer des actions passe-partout. Le programmeur jette ou vérifie constamment que tout est exactement comme prévu. Le développeur passe du temps à écrire du code, le fait avec une précision exceptionnelle, utilise des volumes considérables de modèles de modèles et espère que tout cela lui permettra de gagner du temps en détectant et en corrigeant rapidement les erreurs.
Le problème de la programmation dans un langage fortement typé est si grand qu'un programmeur, avec presque aucune option, doit utiliser un IDE grand et complexe. Un simple éditeur de code ne suffit pas ici. La seule façon de maintenir le programmeur Java dans un état adéquat (à l'exception de pizza) est de lui montrer en permanence des listes déroulantes contenant les champs d'objet disponibles ou des descriptions des paramètres de méthode. Ceci et d'autres mécanismes de prise en charge des IDE tels que Eclipse, NetBeans ou IntelliJ aident à la création de classes, facilitent le refactoring et d'autres tâches.
Et ... je ne parlerai pas de Maven. Ce n'est qu'un outil de cauchemar.
En JavaScript, les types de variables ne sont pas spécifiés lorsqu'ils sont déclarés, la conversion de type n'est généralement pas utilisée, etc. En conséquence, le code est plus facile à lire, mais cet état de choses signifie également le risque d'erreurs de programmation difficiles à détecter.
Que ce qui précède se rapporte aux avantages de Java ou aux inconvénients dépend du point de vue.
Il y a dix ans, je croyais que toutes ces difficultés se justifiaient en donnant au programmeur une plus grande confiance dans le code qu'il écrit. Aujourd'hui, je crois que le typage fort augmente la charge de travail du programmeur et il est beaucoup plus facile de développer des projets comme ils le font en JavaScript.
Combattez les erreurs avec de petits modules faciles à tester
Node.js pousse le programmeur à diviser ses projets en petits fragments, en modules dits. Vous pouvez trouver ce fait insignifiant, mais cela résout partiellement le problème que nous venons de mentionner.
Voici les principales caractéristiques du module:
- L'indépendance Le module combine le code interconnecté en une seule entité.
- Des limites claires. Le code à l'intérieur du module est protégé contre les interférences par tout mécanisme externe.
- Exportation explicite. Par défaut, les données de code et de module ne sont pas exportées. Le développeur décide indépendamment des fonctions et des données qui doivent être rendues publiques.
- Importation explicite. Lors du développement d'un module, le programmeur décide lui-même des modules dont il dépendra.
- Indépendance potentielle. Les modules peuvent être rendus publics, au sens très large du terme, en les publiant dans npm, ou, s'ils sont destinés aux besoins internes de l'entreprise, en les publiant dans des référentiels fermés. Cela facilite l'utilisation des mêmes modules dans différentes applications.
- Code facile à comprendre. Le fait que les modules soient petits, simplifie la lecture et la compréhension de leur code, ouvre la possibilité d'une discussion libre à leur sujet.
- Facilitez les tests. Un petit module, s'il est correctement implémenté, peut facilement être testé à l'unité.
Tout cela fait des modules Node.js des entités aux limites clairement définies, dont le code est facile à écrire, à lire et à tester.
Cependant, s'inquiéter de travailler avec JavaScript est le fait que le manque de frappe forte peut facilement conduire le code à faire quelque chose de mal. Dans un petit module visant à résoudre un problème étroit avec des limites claires, «quelque chose ne va pas» ne peut affecter que le code du module lui-même. Cela conduit au fait que les problèmes pouvant entraîner le manque de typage strict, sont bloqués dans le module.
Une autre solution au problème de frappe dynamique en JavaScript consiste à tester soigneusement le code.
Le développeur doit prendre les tests au sérieux, ce qui enlève une partie des avantages qui découlent de la simplicité du processus de développement JS. Les systèmes de test créés par un programmeur JS devraient trouver les erreurs que, s'il était développé par lui dans quelque chose comme Java, le compilateur pourrait trouver automatiquement. Ecrivez-vous des tests pour vos applications JS?
Pour ceux qui ont besoin d'un système de frappe statique en JavaScript, il peut être utile de jeter un œil à TypeScript. Je n'utilise pas cette langue, mais j'en ai entendu beaucoup de bonnes choses. Il est compatible avec JavaScript et étend le langage avec un système de contrôle de type et d'autres fonctionnalités utiles.
En fin de compte, nous pouvons dire que l'utilisation d'une approche modulaire du développement est la force de Node.js et de JavaScript.
Gestion des packages
Je me sens mal à la simple pensée de Maven, donc je ne peux même pas écrire normalement à ce sujet. Et, si je comprends bien, Maven, sans compromis, est soit aimé, soit détesté.
Le problème ici est que dans l'environnement Java, il n'y a pas de système holistique pour gérer les packages. Les packages Maven existent, vous pouvez les utiliser normalement, ils sont pris en charge par Gradle. Mais la façon dont le travail avec eux est organisé ne ressemble pas beaucoup aux avantages que le système de gestion de packages pour Node.js offre au développeur.
Dans le monde de Node.js, il existe deux excellents gestionnaires de packages qui travaillent en étroite collaboration. Au début, le seul outil de ce type était le référentiel npm et l'outil de ligne de commande du même nom.
Grâce à npm, nous avons un excellent schéma pour décrire les dépendances des packages. Les dépendances peuvent être strictes (disons, il est indiqué que seule la version 1.2.3 d'un certain paquet est nécessaire), ou données avec plusieurs degrés de liberté - jusqu'à
*
, ce qui signifie utiliser la dernière version d'un certain paquet.
La communauté Node.js a publié des centaines de milliers de packages dans le référentiel npm. En même temps, utiliser des packages qui ne sont pas dans npm est aussi simple que d'utiliser des packages de npm.
Le système npm s'est avéré un tel succès que non seulement les développeurs de produits serveurs sur Node.js l'utilisent, mais aussi les programmeurs frontaux. Auparavant, des outils comme Bower étaient utilisés pour gérer les packages. Bower était obsolète, et vous pouvez maintenant constater que toutes les bibliothèques JS pour le développement frontal existent en tant que packages npm. De nombreux outils de support pour le développement client, tels que la CLI Vue.js et Webpack, sont écrits en tant qu'applications Node.js.
Un autre système de gestion des packages pour Node.js, yarn, télécharge les packages à partir du référentiel npm et utilise les mêmes fichiers de configuration. Le principal avantage du fil par rapport au gestionnaire de paquets npm est sa vitesse plus élevée.
Le référentiel npm, qu'il utilise le gestionnaire de packages npm ou le gestionnaire de packages yarn, est une base puissante pour ce qui rend le développement de Node.js si facile et agréable.
Une fois, après avoir aidé à développer java.awt.Robot, j'ai été inspiré pour créer cette chose. Alors que l'image officielle de Duke est constituée de courbes, RoboDuke est construit à partir de lignes droites. Seules les articulations du coude de ce robot sont rondesPerformances
Java, JavaScript . -, , . , , - .
Java, JavaScript . Java Node.js, . JavaScript . -.
JDK Sun/Oracle HotSpot — , -. , , , , , . HotSpot — , .
JavaScript, , JS-, , , - . , JavaScript . , , . , , Google Docs, . JS .
Node.js , V8 Google Chrome.
, Google, V8, . , V8 Crankshaft Turbofan.
— , , R Python. , , . JavaScript, , ,
JavaScript.
JavaScript , TensorFlow.js. API API TensorFlow Python, . , , , .
IBM, Node.js, , , Docker/Kubernetes. , Node.js Spring Boot. -, . , Node.js , , , V8.
, Node.js . . - , Node.js , . , «Node.js Web Development», , :
JavaScript , Node.js. — Node.js-. Node.js-
node-gyp
, .
, Rust- Node.js.
WebAssembly , , JavaScript, . WebAssembly , JavaScript-.
WebAssembly Node.js.
-
- (Rich Internet Applications, RIA) . , , ( ) JS-, .
, 20 . Sun Netscape Java- Netscape Navigator. JavaScript , , Java-. , Java-, — Java-. , . .
JavaScript , . RIA, , - Java -.
, RIA . Node.js , , , . JavaScript.
Voici quelques exemples:
- Google Docs ( ), , .
- , React, Angular Vue.js, , HTML, CSS JavaScript.
- Electron — Node.js Chromium. - . , Visual Studio Code, Atom, GitKraken, Postman.
- Electron/NW.js , -, , React, Angular, Vue, .
Java, , - -, JavaScript. , , - Sun Microsystems. Sun , . . Java- , Java Java Web Start. Java- Webstart-.
Java, , , IDE NetBeans Eclipse . Java , , Java.
JavaFX.
JavaFX, 10 , Sun iPhone. , Java, , , . Flash iOS. . JavaFX , , . - React, Vue.js .
JavaScript Node Java.
Java, - JavaONE. Java . , , , .
Java
Résumé
. «P-» (Perl, PHP, Python) Java, Node.js, Ruby, Haskell, Go, Rust, . .
, , , Java, Node.js, , , Node.js-. Java , Node.js . , , , Java, .
. , , Node.js - , - . . , XBRL-. XBRL Python, , , Python. , , , .
Chers lecteurs! , , JavaScript - , - Node.js, .
