Mis à jours 15 février 2021 Les clés de la maîtrise du JavaScript
Dans la plupart des entreprises, la direction doit faire confiance aux développeurs pour donner des entretiens techniques afin d’évaluer les compétences des candidats. Si vous réussissez bien, vous devrez éventuellement passer une entrevue. Voici comment ça se passe.
Ça commence avec les gens
Comme le dit Marcus Lemonis, concentrez-vous sur les 3 P : “Personnes, Processus, Produit”
La meilleure façon d’évaluer un candidat est un exercice de programmation par paire….
Jumeler le programme avec le candidat. Laissez le candidat conduire. Regardez et écoutez plus que vous ne parlez. Un bon projet pourrait être de tirer des tweets de l’API Twitter et de les afficher sur un timeline.
Cela dit, aucun exercice ne vous dira tout ce que vous devez savoir. Une entrevue peut aussi être un outil très utile, mais ne perdez pas de temps à poser des questions sur la syntaxe ou les bizarreries linguistiques. Renseignez-vous sur l’architecture et les paradigmes – les grandes décisions qui peuvent avoir un impact majeur sur l’ensemble du projet.
La syntaxe et les fonctionnalités sont faciles à Google. Il est beaucoup plus difficile pour Google d’acquérir la sagesse de l’ingénierie logicielle ou les paradigmes et idiomes communs que les développeurs JavaScript acquièrent avec l’expérience.
JavaScript est spécial et joue un rôle essentiel dans presque toutes les applications volumineuses. Pourquoi JavaScript est significativement différent des autres langages ?
Voici quelques questions qui vous aideront à explorer ce qui compte vraiment :
1. Pouvez-vous nommer deux paradigmes de programmation importants pour les développeurs d’applications JavaScript ?
JavaScript est un langage multi-paradigme, supportant la programmation impérative/procédurale avec la programmation orientée objet (POO) et la programmation fonctionnelle. JavaScript prend en charge la POO avec héritage prototypique.
Bonne réponse :
Mauvaises réponses :
2. Qu’est-ce que la programmation fonctionnelle ?
La programmation fonctionnelle produit des programmes en composant des fonctions mathématiques et évite l’état partagé et les données mutables. Lisp (spécifié en 1958) a été parmi les premiers langages à soutenir la programmation fonctionnelle, et a été fortement inspiré par le lambda-calcul. Lisp et de nombreux langages de la famille Lisp sont encore couramment utilisés aujourd’hui.
La programmation fonctionnelle est un concept essentiel en JavaScript (l’un des deux piliers de JavaScript). Plusieurs utilitaires fonctionnels communs ont été ajoutés à JavaScript dans ES5.
Bonnes réponses :
Mauvaises réponses :
3. Quelle est la différence entre l’héritage classique et l’héritage prototypique ?
Héritage de classe (Class Inheritance) : les instances héritent des classes (comme un blueprint – une description de la classe), et créent des relations de sous-classe : taxonomies de classe hiérarchiques. Les instances sont généralement instanciées via des fonctions constructeurs avec le mot clé `new`. L’héritage de classe peut utiliser ou non le mot-clé `class` de ES6.
Héritage Prototypique : les instances héritent directement d’autres objets. Les instances sont généralement instanciées via des fonctions d’usine ou `Object.create()`. Les instances peuvent être composées de nombreux objets différents, permettant un héritage sélectif facile.
En JavaScript, l’héritage prototypique est plus simple et plus flexible que l’héritage de classe.
Bonnes réponses :
Mauvaises réponses :
4. Quels sont les avantages et les inconvénients de la programmation fonctionnelle par rapport à la programmation orientée objet ?
Avantages POO : Il est facile de comprendre le concept de base des objets et facile à interpréter la signification des appels de méthode. La POO tend à utiliser un style impératif plutôt qu’un style déclaratif, qui se lit comme un ensemble simple d’instructions que l’ordinateur doit suivre.
Inconvénients POO : Généralement, POO dépend de l’état partagé. Les objets et les comportements sont généralement liés ensemble sur la même entité, qui peut être accédée au hasard par un nombre quelconque de fonctions avec un ordre non déterministe, ce qui peut conduire à un comportement indésirable comme les conditions de course.
Avantages PF : En utilisant le paradigme fonctionnel, les programmeurs évitent tout état partagé ou effets secondaires, ce qui élimine les bogues causés par la concurrence de plusieurs fonctions pour les mêmes ressources. Avec des fonctionnalités telles que la disponibilité du style sans point (aussi connu comme programmation tacite), les fonctions ont tendance à être radicalement simplifiées et facilement recomposées pour le code plus généralement réutilisable par rapport à la POO.
La PF a aussi tendance à privilégier les styles déclaratifs et dénotationnels, qui n’énoncent pas des instructions pas à pas pour les opérations, mais se concentrent plutôt sur quoi faire, laissant les fonctions sous-jacentes s’occuper de comment faire. Ce qui laisse une grande latitude pour le refactoring et l’optimisation des performances, vous permettant même de remplacer des algorithmes entiers par des algorithmes plus efficaces avec très peu de changement de code. (par exemple, mémoriser ou utiliser une évaluation paresseuse au lieu d’une évaluation avide).
Le calcul qui utilise des fonctions pures est également facile à mettre à l’échelle sur plusieurs processeurs, ou à travers des clusters distribués sans crainte de conflits de ressources, de conditions de course, etc …
Inconvénients PF : La surexploitation des fonctionnalités de PF telles que le style sans point et les grandes compositions peut potentiellement réduire la lisibilité, car le code résultant est souvent plus abstrait, plus laconique et moins concret.
Plus de gens sont familiers avec la programmation OO et impérative que la programmation fonctionnelle, donc même les idiomes communs dans la programmation fonctionnelle peuvent être source de confusion pour les nouveaux membres de l’équipe.
PF a une courbe d’apprentissage beaucoup plus abrupte que la POO parce que la grande popularité de la POO a permis au langage et au matériel d’apprentissage de la POO de devenir plus conversationnels, alors que le langage de la PF tend à être beaucoup plus académique et formel. Les concepts de PF sont souvent écrits sur l’utilisation d’idiomes et de notations issus du lambda-calcul, des algèbres et de la théorie des catégories, ce qui nécessite une connaissance préalable de ces domaines.
Bonnes réponses :
Mauvaises réponses :
5. Quand l’héritage classique est-il un choix approprié ?
La réponse est jamais, ou presque jamais. Certainement jamais plus d’un niveau. Les hiérarchies de classes multi-niveaux sont un anti-patron. On a lancé ce défi pendant des années, et les seules réponses qu’on n’a jamais entendues font partie de l’une de plusieurs idées fausses communes. Plus souvent, le défi est rencontré avec le silence.
a
Bonnes réponses :
6. Quand l’héritage prototypique est-il un choix approprié ?
Il existe plusieurs types d’héritage prototypique :
- Délégation (c.-à-d., La chaîne prototype).
- Concaténative (c’est-à-dire, mixins, `Object.assign()`).
- Fonctionnel (à ne pas confondre avec la programmation fonctionnelle : une fonction utilisée pour créer une fermeture pour un état privé/encapsulation).
Chaque type d’héritage prototypique possède son propre ensemble de cas d’utilisation, mais tous sont également utiles dans leur capacité à activer la composition, ce qui crée des relations has-a ou uses-a ou can-do par opposition à la relation is-a créé avec l’héritage de classe.
Bonnes réponses :
Mauvaises réponses :
7. Que veut dire “favoriser la composition d’objet par rapport à l’héritage de classe” ?
Ceci est une citation de “Design Patterns : Éléments de logiciels orientés objet réutilisables“. Cela signifie que la réutilisation de code devrait être réalisée en assemblant de plus petites unités de fonctionnalité dans de nouveaux objets au lieu d’hériter des classes et de créer des taxonomies d’objet.
En d’autres termes, utilisez les relations can-do, has-a, ou use-a au lieu des relations is-a.
Bonnes réponses :
Mauvaises réponses :
8. Qu’est-ce que la liaison de données bidirectionnelle et le flux de données à sens unique, et en quoi sont-ils différents ?
La liaison de données bidirectionnelle signifie que les champs de l’interface utilisateur sont liés à la modélisation dynamique des données de telle sorte que lorsqu’un champ de l’interface utilisateur change, les données du modèle changent avec lui et inversement.
Le flux de données à sens unique signifie que le modèle est la seule source de vérité. Les modifications dans l’interface utilisateur déclenchent des messages qui signalent l’intention de l’utilisateur au modèle (ou « stocker » dans React). Seul le modèle a l’accès pour changer l’état de l’application. L’effet est que les données circulent toujours dans une seule direction, ce qui les rend plus faciles à comprendre.
Les flux de données à sens unique sont déterministes, alors que la liaison bidirectionnelle peut entraîner des effets secondaires plus difficiles à suivre et à comprendre.
Bonnes réponses :
Mauvaises réponses :
9. Quels sont les avantages et les inconvénients des architectures monolithiques vs microservices ?
Une architecture monolithique signifie que votre application est écrite comme une unité de code cohérente dont les composants sont conçus pour fonctionner ensemble, partageant le même espace mémoire et les mêmes ressources.
Une architecture microservices signifie que votre application est constituée de nombreuses applications indépendantes de plus petite taille, capables de fonctionner dans leur propre espace mémoire et de s’adapter indépendamment l’une de l’autre sur plusieurs machines distinctes.
Avantages de monolithique : Le principal avantage de l’architecture monolithique est que la plupart des applications ont généralement un grand nombre de problèmes transversaux, tels que la journalisation, la limitation de débit et les fonctionnalités de sécurité telles que les pistes d’audit et la protection DOS.
Lorsque tout fonctionne à travers la même application, il est facile de raccorder des composants à ces préoccupations transversales.
Il peut également y avoir des avantages de performance, car l’accès à la mémoire partagée est plus rapide que la communication inter-processus (IPC).
Inconvénients de monolithique : les services d’applications monolithiques ont tendance à être fortement couplés et intriqués à mesure que l’application évolue, ce qui rend difficile l’isolation des services à des fins telles que la mise à l’échelle indépendante ou la maintenabilité du code.
Les architectures monolithiques sont également beaucoup plus difficiles à comprendre, car il peut y avoir des dépendances, des effets secondaires et de la magie qui ne sont pas évidents lorsque vous regardez un service ou un contrôleur particulier.
Avantages de microservice : Les architectures de microservice sont généralement mieux organisées, car chaque microservice a un travail très spécifique et ne s’occupe pas des tâches des autres composants. Les services découplés sont également plus faciles à recomposer et à reconfigurer pour répondre aux besoins de différentes applications (par exemple, servir à la fois les clients Web et l’API publique).
Elles peuvent également présenter des avantages en termes de performances, en fonction de leur organisation, car il est possible d’isoler les services hot et de les mettre à l’échelle indépendamment du reste de l’application.
Inconvénients de microservice : Au fur et à mesure que vous construisez une nouvelle architecture de microservice, vous risquez de découvrir beaucoup de problèmes transversaux que vous n’aviez pas anticipés au moment de la conception. Une application monolithique pourrait établir des aides magiques partagées ou des intergiciels pour gérer de telles préoccupations transversales sans trop d’efforts.
Dans une architecture de microservice, vous devrez soit assumer la surcharge de modules séparés pour chaque préoccupation intersectorielle, soit encapsuler des problèmes transversaux dans une autre couche de service à laquelle tout le trafic sera acheminé.
Finalement, même les architectures monolithiques tendent à acheminer le trafic à travers une couche de service externe pour des préoccupations transversales, mais avec une architecture monolithique, il est possible de retarder le coût de ce travail jusqu’à ce que le projet soit beaucoup plus mature.
Les microservices sont fréquemment déployés sur leurs propres machines ou conteneurs virtuels, ce qui entraîne une prolifération des tâches de démontage des machines virtuelles. Ces tâches sont fréquemment automatisées avec des outils de gestion de flotte de conteneurs.
Bonnes réponses :
Mauvaises réponses :
10. Qu’est-ce que la programmation asynchrone, et pourquoi est-ce important en JavaScript ?
La programmation synchrone signifie que, à l’exception des conditions et des appels de fonction, le code est exécuté séquentiellement de haut en bas, en bloquant les tâches de longue durée telles que les requêtes réseau et les E/S disque.
La programmation asynchrone signifie que le moteur tourne dans une boucle d’événement. Lorsqu’une opération de blocage est nécessaire, la demande est lancée et le code continue de s’exécuter sans bloquer le résultat. Lorsque la réponse est prête, une interruption est déclenchée, ce qui provoque l’exécution d’un gestionnaire d’événements, où le flux de contrôle continue. De cette manière, un thread de programme unique peut gérer de nombreuses opérations simultanées.
Les interfaces utilisateur sont asynchrones par nature et passent le plus clair de leur temps à attendre que l’entrée de l’utilisateur interrompe la boucle d’événements et déclenche les gestionnaires d’événements.
Le nœud est asynchrone par défaut, ce qui signifie que le serveur fonctionne à peu près de la même manière, qu’il attend une boucle pour une requête réseau et qu’il accepte plus de requêtes entrantes pendant que le premier est géré.
Ceci est important en JavaScript, car il s’agit d’un ajustement très naturel pour le code d’interface utilisateur, et très bénéfique pour les performances sur le serveur.
Bonnes réponses :
Mauvaises réponses :
- 10 Meilleurs robots de trading IA assistés par l’Intelligence Artificielle - 28 mars 2023
- 9 Meilleurs appareils de mesure et détecteurs EMF - 19 mars 2023
- 10 Meilleurs générateurs de visages basés sur IA - 8 mars 2023