Des projets que tout programmeur devrait essayer (2019)
(austinhenley.com)- Si vous avez du mal à choisir un projet personnel, des projets comme un éditeur de texte, un jeu 2D, un compilateur ou un mini-système d’exploitation sont un bon point de départ, car plus on les refait, plus le champ d’apprentissage s’élargit
- Un éditeur de texte vous fait apprendre les structures de données et l’abstraction en implémentant vous-même la structure de stockage des documents, le comportement du curseur, l’annulation/rétablissement et les retours à la ligne
- Même un jeu 2D simple comme Space Invaders révèle la structure de base de la programmation de jeux : rendu à l’écran, gestion des entrées, boucle de jeu, gestion de l’état des objets, IA des ennemis, son, shaders et réseau
- Un compilateur Tiny BASIC et un mini-système d’exploitation vous font manipuler directement des concepts bas niveau comme le lexing, le parsing, l’analyse sémantique, la génération de code, la compilation croisée, le bootloading, la gestion mémoire et l’ordonnancement
- Un tableur et un émulateur de console combinent la difficulté des projets précédents et s’étendent jusqu’à la création d’une machine virtuelle qui imite un fonctionnement réel
Des projets à refaire plusieurs fois
- Quand vous avez besoin d’un projet personnel ou que vous voulez apprendre un nouveau langage de programmation ou framework, créer plusieurs fois le même projet permet d’apprendre quelque chose de différent à chaque itération
- Les projets recommandés varient par leur difficulté et les domaines d’apprentissage qu’ils couvrent
- Éditeur de texte : structures de données, comportement du curseur, annulation/rétablissement, représentation à l’écran
- Jeu 2D : rendu à l’écran, gestion des entrées, boucle de jeu, gestion des objets et des états
- Compilateur : lexing, parsing, analyse sémantique, génération de code
- Mini-système d’exploitation : démarrage, gestion mémoire, ordonnancement, système de fichiers
- Tableur et émulateur de console : combinaison des concepts des projets précédents dans une structure plus vaste
Éditeur de texte
- Un éditeur de texte est un outil que l’on utilise tous les jours, mais si vous l’implémentez vous-même sans composant de zone de texte de base, vous devrez gérer en détail le déplacement du curseur, la sélection, l’insertion et la suppression
- Le plus grand défi est la manière de stocker un document texte en mémoire
- Un simple tableau offre de mauvaises performances quand on insère du texte ailleurs qu’à la fin du document
- Les structures à comparer incluent les tableaux, les rope, les gap buffer et les piece table
- Le curseur ne se déplace pas simplement vers le haut et vers le bas
- Quand il passe à une ligne courte, il se place à la position possible, puis si une ligne assez longue apparaît ensuite, il tente de revenir à sa colonne d’origine : c’est un comportement de mémoire de colonne
- Après un éditeur de base, vous pouvez ajouter l’annulation/rétablissement et le retour à la ligne automatique
- Ressources
Jeu 2D - Space Invaders
- Même un jeu simple exige ses propres structures de données et design patterns
- En utilisant une bibliothèque graphique 2D de base comme SDL, SFML ou PyGame plutôt qu’un gros moteur de jeu, les parties intéressantes ne sont pas masquées
- Un jeu crée l’effet de mouvement des objets en effaçant l’écran puis en redessinant rapidement chaque élément
- Le flux réel consiste à répéter, dans une boucle de jeu, le rendu, la récupération des entrées utilisateur et le traitement de la logique du jeu
- La gestion des entrées doit tenir compte des détails comme le premier appui sur une touche ou un bouton de souris, le maintien, le relâchement et le double-clic
- Si l’on ne fait que vérifier les entrées en continu, le reste du jeu reste bloqué
- Il faut aussi gérer directement les objets du jeu et leur état
- Le factory pattern aide à créer des ennemis dont le nombre augmente dynamiquement
- Une machine à états peut être appliquée à l’IA des ennemis
- Après le jeu de base, vous pouvez ajouter un menu titre, un écran de game over, un traitement permettant d’obtenir la même vitesse d’exécution sur des ordinateurs différents, et une IA d’ennemis plus intéressante
- En allant plus loin, vous pouvez implémenter des effets de shaders, du son et même du multijoueur en ligne
- Ressources
Compilateur - Tiny BASIC
- Un compilateur est un projet qui consiste à créer un outil permettant à d’autres personnes de construire davantage de choses
- En ciblant Tiny BASIC, un petit langage de la famille BASIC, vous pouvez écrire de zéro un compilateur qui produit du code dans un autre langage que vous connaissez bien
- Par exemple, vous pouvez créer un compilateur Tiny BASIC en Python qui génère du code C#
- Si vous ne générez pas d’assembleur ou de C, vous pouvez vous concentrer davantage sur le compilateur lui-même
- Le flux d’implémentation suit étape par étape le processus de traitement d’un langage
- L’analyse lexicale, qui découpe le code d’entrée en tokens
- L’analyse syntaxique, qui vérifie la structure de l’entrée et crée une représentation arborescente
- Le recursive descent parsing
- L’abstract syntax tree
- L’analyse sémantique, qui vérifie que le code est correct sur le plan du sens et respecte les règles de typage
- Les passes d’optimisation
- La génération de code
- Un compilateur simple peut être terminé en quelques jours ; vous pouvez ensuite ajouter une bibliothèque standard, des passes d’optimisation et de meilleurs messages d’erreur
- PeayBASIC ajoute de simples fonctionnalités graphiques 2D dans sa bibliothèque standard
- Ressources
Mini-système d’exploitation
- Les algorithmes et structures de données des systèmes d’exploitation peuvent sembler abstraits ou inutiles en cours, mais ils peuvent aussi s’appliquer à de nombreux domaines, comme les jeux ou les modèles de prédiction du comportement humain
- Les implémenter vous-même permet de mieux comprendre ce qui se passe à l’intérieur d’un système d’exploitation
- À cause des dépendances matérielles, la barrière à l’entrée et la courbe d’apprentissage existent, mais en suivant des livres ou des tutoriels, vous pouvez créer un OS bootable capable d’exécuter vos propres programmes
- Les sujets à apprendre sont les suivants
- Compilation croisée
- Bootloading
- Interruptions BIOS
- modes x86
- gestion mémoire et pagination
- Ordonnancement : par exemple round robin
- Systèmes de fichiers : par exemple FAT
- Ressources
Projets plus difficiles : tableur et émulateur de console
- Une application de tableur comme Excel combine les défis de l’éditeur de texte et ceux du compilateur
- Il faut représenter le contenu des cellules en mémoire
- Il faut implémenter un interpréteur pour le langage de programmation utilisé dans les formules
- Ressources sur les tableurs
- Un émulateur de console de jeux vidéo est un projet qui rassemble en un seul les difficultés de l’implémentation d’un compilateur, d’un système d’exploitation et d’un moteur de jeu
- Pour émuler une vraie console, il faut écrire une machine virtuelle qui se comporte comme son CPU et ses autres composants matériels
- Cette machine virtuelle peut exécuter les jeux de la console concernée
- Comme point de départ, il est recommandé d’émuler CHIP-8, une console virtuelle plus simple qu’une vraie console
- La NES, la SNES, la Gameboy et la Gameboy Advance peuvent aussi être émulées, et il existe pas mal de documentation et d’émulateurs open source, mais chaque console présente des particularités intéressantes
- Certains jeux peuvent dépendre de bugs ou de fonctionnalités non documentés d’un matériel précis
- PICO-8 est devenue une console « fantasy » rentable
- Ressources sur les émulateurs
Projets suggérés en plus
- D’autres idées de projets ont été recueillies sur Hacker News, Reddit, Twitter et par e-mail
- Une base de données créée de zéro
- Un ray tracer
- Un clone de MS Paint
- Un éditeur de graphiques vectoriels
- Un décodeur d’images
- Une appli web de salon de discussion
- Un calculateur de décimales de pi
- Un utilitaire de terminal généraliste comme grep
- Un client et un serveur FTP
1 commentaires
Avis de Hacker News
Créer un éditeur de texte, un compilateur, un système d’exploitation ou un ray tracer peut faire de vous un meilleur programmeur, mais pas forcément un meilleur ingénieur logiciel.
Au contraire, cela peut vous faire intérioriser le dogme catastrophique du « Not Invented Here » et vous rendre pire en ingénierie logicielle.
Les hackers sont obsédés par la notation Big O, les structures de données et les théories très abstraites comme la HoTT, mais on discute et on pratique très peu des compétences essentielles à l’ingénierie réelle : « décider ce qu’il faut construire soi-même et ce pour quoi il faut utiliser une bibliothèque », « identifier les bonnes bibliothèques et frameworks », « déterminer ce qui vaut la peine d’être optimisé », « écrire du code qui restera lisible dans plusieurs années », « voir un projet comme un grand système complexe incluant des dépendances logicielles et non logicielles ».
Je propose donc comme exercice alternatif un moteur de recherche web. Les algorithmes de correspondance de chaînes, par exemple, ont déjà été faits par d’autres, donc ne vous en préoccupez pas ; au début, contentez-vous de « juste » construire un moteur de recherche et un crawler qui fonctionnent réellement, même s’ils ne prennent en charge qu’une partie du web et un seul utilisateur simultané.
Un éditeur de texte, un compilateur, un système d’exploitation ou un ray tracer peuvent entraîner exactement les mêmes activités.
Pour avoir travaillé sur un ray tracer utilisé dans plusieurs longs métrages, tous les points cités ci-dessus s’appliquaient aussi à ce projet.
Au final, c’est plutôt la différence entre faire quelque chose de petit et amusant, ou appliquer telles quelles les contraintes usantes de l’âme qu’on subit en entreprise contre rémunération, et supprimer tout plaisir.
Premièrement, les briques prêtes à l’emploi sont le plus souvent très médiocres, et le logiciel qui en résulte reflète cette médiocrité ; la vie ne consiste alors plus à utiliser le logiciel, mais à maintenir et amadouer ces éléments médiocres.
Deuxièmement, même si les briques sont de bonne qualité, elles limitent les types de logiciels que l’on peut créer. Idéalement, il faudrait imaginer le comportement voulu, écrire le logiciel pour le produire, et créer les briques au passage.
Si l’on n’utilise que des briques toutes faites, une grande partie des excellents logiciels ne peut tout simplement pas être construite ; c’est d’ailleurs, selon moi, l’une des raisons pour lesquelles il y a si peu d’excellents logiciels autour de nous.
Si l’on fabrique « un logiciel presque identique à ce qu’on voit toujours », le deuxième problème s’applique moins, et le premier peut rester gérable puisqu’on utilise surtout le happy path. Mais ce genre de logiciel sera bientôt utilisé par une IA, pas par des humains.
Ces compétences sont importantes elles aussi, mais à un moment donné il faut développer les bases, et devenir un meilleur programmeur aide clairement l’ensemble des compétences énumérées plus haut.
Personnellement, l’ingénierie logicielle est ce que je fais pour payer les factures ; la programmation est ce que j’ai commencé à faire parce que c’était amusant.
Les projets de cet article sont le genre de choses que j’aimerais faire pour le plaisir si j’avais le temps.
Du point de vue UI/Web, en plus d’un tableur, très utile pour comprendre les systèmes de flux de données, je recommanderais aussi ceci :
créer un jeu vidéo simple avec Unity ou Unreal permet de comprendre les contraintes de performance dans les jeux où les 30 à 60 fps sont importantes, et aide aussi à créer des interfaces rapides ailleurs, y compris sur le web.
Créer un framework JavaScript simple, similaire à React, aide à comprendre les flux de données et la gestion des événements.
Écrire soi-même une bibliothèque HTTP qui encapsule XMLHTTPRequest permet, même si fetch existe aujourd’hui, de comprendre depuis le début comment envoyer et lire des requêtes HTTP, ce qui aide plus tard à déboguer des problèmes de CORS ou des requêtes OPTIONS.
Cela avait déjà été discuté à l’époque.
Challenging projects every programmer should try - https://news.ycombinator.com/item?id=21790779 - Dec 2019 (297 comments)
Il existe aussi un article lié.
More challenging projects every programmer should try - https://news.ycombinator.com/item?id=25489879 - Dec 2020 (223 comments)
+1 pour le mini système d’exploitation.
Les développeurs d’applications dépendent de nombreuses fonctionnalités du système d’exploitation, comme la gestion de la mémoire ou le système de fichiers, et finissent par se demander : « comment tout cela fonctionne-t-il en coulisses ? »
J’ai donc bidouillé xv6(https://github.com/mit-pdos/xv6-public) pendant mon temps libre.
Apprendre dans un manuel différents algorithmes d’ordonnancement de processus et les implémenter soi-même, ce n’est pas du tout la même chose, et j’ai beaucoup appris.
En tant que développeur d’apps mobiles, il y a presque 0 chance que ces connaissances soient liées à mon travail, mais c’est clairement amusant.
Avoir essayé de développer un jeu 2D sans moteur a été l’expérience la plus humiliante qui m’ait fait comprendre à quel point les ordinateurs sont devenus absurdement rapides
Même quand on fait quelque chose dont on est persuadé que ce sera beaucoup trop lent, une Game Boy effectue déjà un million d’opérations par seconde, donc ça tourne tout simplement. Un million, c’était plus grand que ce que je pensais
On se dit : « Attends, tu cherches et dessines tous les sprites à chaque fois ? Pas de calcul différentiel malin pour ne connaître que ce qui a changé, pas de second buffer qui référence la frame précédente pour réduire le travail ? », puis on est encore plus surpris quand on voit des jeux bien plus complexes commencer réellement à utiliser ces techniques
Par exemple, un atlas de sprites est une façon typique d’utiliser ce genre de structure de données. Inutile de téléverser à chaque fois plusieurs sprites qui seront généralement rendus de manière prévisible : on envoie une grande image, puis on en échantillonne une partie
Selon les critères d’aujourd’hui, c’est vrai. Sur du matériel grand public d’entrée de gamme, même sans PC gaming, presque tout ce qui date d’il y a une quinzaine d’années peut gérer un rendu « bête et méchant » consistant à dessiner puis redessiner la scène
Comme il n’y avait que le matériel brut et l’assembleur, il fallait tout gérer à la main : graphismes, son, entrées, gestion de la mémoire, etc.
Un environnement simplifié qui permettrait à un programmeur débutant de toucher à tout cela pour créer un jeu 2D, tout en retirant une partie du fardeau excessif nécessaire pour le faire fonctionner, serait à mon avis une initiation idéale
Si vous pensez avoir besoin du patron de fabrique pour créer Space Invaders, c’est qu’il y a quelque chose qui cloche
Je doute très fortement que le jeu original ait intégré ce genre de concept de conception
Une fois que le cerveau en est infecté, il commence à chercher comment propager l’infection
Avons-nous lu deux articles différents ?
J’aimerais essayer quelque chose de beaucoup plus physique, comme une simulation précise de dynamique de vol pour des robots, des drones à pilotage automatique ou des engins spatiaux avec paramètres GNC programmables
J’ai « Fundamentals of Astrodynamics » de Bate, Mueller et autres, et j’aimerais tenter quelque chose pendant les fêtes
Je parle de simulation parce que le reste risque de coûter cher. L’aspect GNC des robots m’intéresse vraiment, et je serais preneur de bonnes recommandations de ressources
Je parle de quelque chose comme un Segway capable de rester au même endroit sans tomber ni filer hors de la table
Il faudrait probablement un microcontrôleur, une IMU, un contrôleur de moteur pas à pas, des moteurs, des roues LEGO, et peut-être un bloc de bois
Je ne l’ai pas fait moi-même, donc mes suppositions peuvent être largement à côté de la plaque
J’aimerais en savoir plus sur le contenu du livre et sur les projets qu’on peut tenter avec
Après avoir passé la journée à manipuler du logiciel, travailler vers un objet physique fait vraiment du bien
Un petit ray tracer jouet me semble aussi être un excellent défi à essayer
Il suffit de gérer des sphères, quelques sources de lumière, la réflexion diffuse et spéculaire, puis de sortir une image bitmap
Tant qu’on ne laisse pas le projet prendre trop d’ampleur, son périmètre peut rester relativement bien limité
Quand on essaie de rendre des graphismes, on apprend vraiment jusqu’où on peut pousser la géométrie et les structures de données
https://austinhenley.com/blog/morechallengingprojects.html
https://raytracing.github.io/
https://raytracing-iow.shuttleapp.rs
C’est une liste intéressante et, même si cela dépendra des inclinations et de la situation de chacun, c’est un bon point de départ si l’on cherche des idées
Je n’irais pas jusqu’à dire ce que tout programmeur devrait essayer, je vais seulement noter ce que j’ai personnellement choisi
Sur Sinclair ZX Spectrum, j’avais fait un éditeur de portées musicales et un tracker très rudimentaires, ainsi qu’un jeu 2D façon Space Invaders avec un seul envahisseur
Et cet ordinateur ne m’appartenait même pas. Sur mon premier ordinateur, un 386, j’ai créé un compresseur Huffman, un index B-Tree plus rapide que DBase/Clipper, un générateur de formulaires orienté objet, et plusieurs programmes DOS en arrière-plan, dont l’un a ensuite servi dans le processus d’installation d’une grande entreprise
Quelques années plus tard, j’ai aussi fait un vérificateur d’e-mails pour connexion dial-up, un parseur manuel pour la coloration syntaxique, quelque chose qui ressemblait à un tableur, et je continue encore aujourd’hui. J’en oublie sûrement.
Bonne liste. Ce serait bien de la maintenir comme une liste vivante, afin qu’elle puisse évoluer avec le temps
J’aimerais ajouter deux choses
Créer un memcached léger exige un mélange d’algorithmes de base et de bonnes pratiques de conception système. C’est un problème « simple », mais il faut le considérer sous plusieurs angles : invalidation, concurrence, gestion de la mémoire, etc.
Créer son propre Docker est aussi une bonne idée. Ce n’est pas aussi complexe qu’il n’y paraît, et cela donne l’occasion de comprendre les bases de la programmation système d’exploitation, que les ingénieurs utilisent moins souvent dans leur travail quotidien aujourd’hui