J’ai été passionné par la technologie toute ma vie. J’ai commencé avec Turbo Pascal quand j’étais enfant et, depuis, j’ai travaillé sur des systèmes embarqués, le développement front-end/back-end et des projets de machine learning.
iOS/macOS est entré dans ma vie lors d’un court cursus universitaire. En un mois, j’avais appris un nouveau langage et décroché un stage chez Readdle. Cinq ans plus tard, je suis devenu Principal Engineer. Je continue néanmoins à encadrer de nouveaux coéquipiers, à participer aux entretiens et à développer mes compétences en leadership pour continuer à progresser.
Mon parcours, d’une absence totale d’expérience avec les plateformes Apple jusqu’à mon poste actuel, m’a poussé à réfléchir à ma manière d’apprendre et à dégager les grandes orientations qui m’ont aidé à progresser. Je pense que mon expérience peut être utile à d’autres ingénieurs qui se sentent bloqués ou ne savent pas quelle direction prendre ensuite.
Voici les principales approches et ressources qui m’ont aidé et qui pourraient aussi vous aider.
Comment les projets parallèles ont accéléré ma progression
Après avoir atteint le niveau intermédiaire, je suis arrivé à un plateau professionnel. J’avais l’impression d’accomplir les tâches rapidement et efficacement, de corriger les bugs sans difficulté et de bien comprendre comment concevoir l’architecture de nouvelles fonctionnalités. Mais je n’arrivais pas vraiment à comprendre ce qui me séparait du statut de véritable Senior Engineer.
Le changement s’est produit progressivement. Avec le recul, j’ai réalisé que ce qui a fait la différence, ce n’était ni un gros projet au travail ni une promotion. C’était tout le temps que j’avais passé à coder en dehors du travail.
Le soir et le week-end, je réalisais de petits projets, parfois juste pour le plaisir, parfois pour tester une idée. Ces projets parallèles m’ont exposé à des problèmes concrets en dehors de mon périmètre habituel. Cette expérience pratique s’est directement répercutée sur mon travail et m’a donné un avantage lorsque je devais faire face à des problèmes inhabituels.
La plus grande leçon a été que la plupart des compétences en développement logiciel ne sont pas liées à un seul langage ou à une seule plateforme. Quelques exemples :
- Même si vous lisez sur l’architecture d’applications iOS/macOS, vous reconnaîtrez probablement des schémas similaires dans le développement web ou les systèmes embarqués.
- La connaissance de Python dans le contexte du machine learning peut vous aider à écrire rapidement le script nécessaire pour automatiser les processus CI dans un domaine complètement différent.
- Les bases des systèmes d’exploitation vous aideront à comprendre des catégories entières de problèmes, quel que soit le langage de programmation. Après tout, tout programme, quel que soit le langage, interagit au final de manière similaire avec le système d’exploitation.
- L’un des premiers livres que j’ai lus était Effective Java, un langage que je n’ai pas utilisé depuis des années. Mais ce livre m’a appris des principes orientés objet qui s’appliquent partout. C’est le genre de connaissances qui restent.
- Si vous aimez programmer, ces projets parallèles ne vous donneront pas l’impression de travailler. D’après mon expérience, les meilleurs ingénieurs sont ceux qui codent parce qu’ils aiment construire et apprendre.
Façons d’apprendre n’importe quoi
Certaines personnes semblent apprendre plus vite que d’autres. Cela peut être un nouveau langage de programmation, un pattern, une architecture ou même quelque chose de totalement sans rapport avec le développement, comme apprendre à jouer aux échecs. Je pense que c’est parce qu’apprendre est en soi une compétence, une méta-compétence que l’on peut pratiquer.
En réfléchissant à mon propre parcours d’apprentissage, j’ai remarqué des schémas récurrents dans ma manière d’aborder de nouveaux sujets. Je pense que cela vient de mes années d’école et d’université, où le fait de jongler avec plusieurs disciplines a poussé mon cerveau à optimiser des schémas similaires. Cela m’a permis d’apprendre plus vite.
Aujourd’hui, j’ai un processus précis pour apprendre quelque chose de nouveau. Je ne pense pas que ce processus soit révolutionnaire, mais il m’a permis de rester concentré et intentionnel à la fois dans l’apprentissage et dans mon développement personnel. Dans cette section, je vais vous présenter les trois étapes de mon approche d’apprentissage : Screening, Structuring et Practice.
Sélection
Une bonne source d’information est une première étape essentielle lorsqu’on apprend une nouvelle compétence. Voici quelques recommandations basées sur mon expérience :
- La plupart des informations sur n’importe quel sujet sont disponibles gratuitement. Il est rarement nécessaire de payer pour des cours ou des conférences, sauf si vous êtes absolument sûr que le contenu est unique. Mais si vous débutez, vous n’aurez pas encore l’expertise nécessaire pour faire la différence entre de véritables idées utiles et du contenu de faible qualité.
- Les ressources textuelles sont généralement plus concises et plus faciles à assimiler que les vidéos, surtout si vous lisez vite. Avec le temps, j’ai appris à parcourir rapidement et à filtrer les informations non pertinentes, ce qui est plus difficile avec le contenu vidéo.
- Avec le temps, j’ai développé la capacité de parcourir rapidement et de filtrer les informations non pertinentes, ce qui n’est pas possible avec les contenus vidéo, parce qu’ils sont linéaires et chronophages. Il est aussi plus facile d’ajouter un signet ou de copier un extrait dans un texte que de chercher le bon moment dans une vidéo.
- Les ressources en anglais sont bien plus faciles à trouver que les ressources dans d’autres langues, surtout quand il s’agit de programmation et de technologie. Par conséquent, savoir lire et comprendre rapidement l’anglais est indispensable !
- Ne passez pas à côté des classiques. Les livres recommandés à maintes reprises (comme Clean Code ou Design Patterns) restent souvent les meilleurs supports disponibles.
- Je recommande également de constituer votre propre bibliothèque personnelle de livres sur différents sujets. Ainsi, vous aurez toujours à portée de main du contenu fiable. Personnellement, je garde un simple dossier sur mon ordinateur.
Structuration
Une fois que j’ai rassemblé quelques sources solides, je structure les informations. Ce processus comprend :
- Traiter les sources. Lorsque je lis un livre ou un article, je mets en évidence les points clés avec des signets ou je les copie dans mes notes pour m’y référer plus tard.
- Recouper les informations. Surtout lorsque le sujet est subjectif, il est très important de comparer plusieurs solutions et points de vue. Les informations qui coïncident dans plusieurs sources différentes ont de fortes chances d’être vraies. Lorsque les sources se contredisent, je reporte généralement ma décision jusqu’à avoir acquis davantage d’expérience personnelle sur le sujet. Plus tard, avec une compréhension plus approfondie, je peux choisir la meilleure approche.
- Centraliser les connaissances. Pour analyser toutes les informations reçues et trouvées, elles doivent être stockées en un seul endroit. J’utilise Obsidian pour centraliser mes connaissances. C’est gratuit, et je trouve le format markdown très pratique.
- Stocker. J’enregistre généralement les articles et les liens utiles dans de simples listes markdown. Cela m’aide à retrouver rapidement une ressource précise sans fouiller dans l’historique du navigateur. En plus, si je reviens sur le sujet plus tard, j’ai déjà une bonne base enregistrée.
Pratique
Lire ne suffit pas. On n’apprend vraiment que lorsqu’on construit quelque chose. J’essaie de consolider chaque sujet que j’étudie en créant de petits projets. Quand il s’agit de programmation, cela signifie généralement créer une application simple qui démontre ma capacité à appliquer les compétences nécessaires. Une pratique rapide révèle aussi immédiatement les lacunes de compréhension. Il m’est souvent arrivé de penser que je comprenais tout ce dont j’avais besoin, pour me heurter à des problèmes inattendus seulement 10 minutes après le début de l’implémentation.
Un exemple qui m’a particulièrement marqué est l’apprentissage des architectures UI. Quand j’ai étudié MVVM pour la première fois dans le contexte du développement iOS, je pensais que cette architecture était simple et évidente. Mais quand j’ai essayé de créer une application de liste de tâches basique, je me suis immédiatement heurté à une lacune dans mes connaissances. Les ressources expliquaient comment la View communique avec la ViewModel, et comment la ViewModel interagit avec le Model, mais aucune ne disait qui devait créer quoi, ni comment !
Mon application comportait un tableau affichant les tâches actuelles de la liste. Devais-je créer une ViewModel distincte pour chaque tâche ? Ou un seul ViewModel pour toute la table ? Et si j’avais besoin des deux ViewModels ? Qui crée laquelle ? Ces questions m’ont ouvert la voie vers la compréhension de la manière de coordonner les composants dans des architectures similaires.
Plus tard, alors que je travaillais sur PDF Expert, notre équipe a décidé d’essayer d’implémenter MVVM. J’ai pu construire l’architecture et aider à guider l’équipe dans le développement de cette fonctionnalité. C’est le genre d’expérience que je n’aurais pas acquise si je n’avais pas d’abord construit seul cette petite application de liste de tâches un peu bricolée.
Mes recommandations pour les projets parallèles
- Trouvez de l’inspiration et une idée. L’idée vient généralement en premier, puis je la rattache à un objectif d’apprentissage précis. L’idée n’a pas besoin d’être unique ni même particulièrement utile, car le but principal est d’acquérir de l’expérience. Par exemple, je peux décider de créer une application de suivi d’habitudes. À partir de là, je peux choisir de me concentrer sur l’architecture ou d’utiliser cette idée pour concevoir une UI impressionnante avec des animations. Ou peut-être ai-je besoin de créer un serveur pour cette application ? Ce pourrait être une excellente occasion d’essayer de nouvelles technologies backend.
- Définissez ce que signifie “terminé”. Si vous essayez d’amener chaque projet jusqu’à la production, vous devrez y consacrer beaucoup de temps. Je pense donc qu’il faut définir les jalons que vous voulez atteindre avec chaque projet.
- Le mieux est l’ennemi du bien. Si vous vous perdez trop dans la recherche de la solution “parfaite”, vous risquez de perdre complètement votre motivation.
- Réduisez les tâches inutiles au minimum. La palette de couleurs exacte a-t-elle vraiment de l’importance dans une application censée vous apprendre l’architecture ? Ou le système de logs ? Les projets les plus précieux étaient ceux qui étaient centrés sur un seul objectif d’apprentissage. Moins je passe de temps sur des détails peu prioritaires, plus je peux investir dans ce qui compte vraiment.
10 sujets qui ont changé ma façon de créer des logiciels
Voici 10 domaines que j’ai explorés par moi-même et qui ont eu un impact sur ma carrière.

Architectures d’applications UI
Tout ingénieur ayant travaillé sur des projets basés sur une UI connaît les schémas classiques d’organisation du code. Qui n’a jamais entendu parler de MVC, MVP, MVVM ? D’après mon expérience, de simples connaissances théoriques peuvent vous donner la confiance nécessaire pour démarrer un nouveau projet, mais sans expérience pratique, elles s’effondrent souvent au premier signe de complexité.
J’ai un jour pensé que je comprenais parfaitement le fonctionnement de MVVM, mais je n’avais pas l’expérience nécessaire pour l’essayer. Je m’en suis rendu compte quand j’ai essayé de développer une petite application MVVM. Il est devenu clair que j’avais besoin de coordinateurs et de routeurs pour naviguer et assembler ce mélange disparate de classes en une structure cohérente. Cette expérience m’a appris une leçon essentielle : il n’existe pas d’architecture universelle. Une architecture qui fonctionne bien dans un projet (ou même sur un seul écran) peut être mal adaptée ailleurs.
Patrons de conception
Toute personne ayant passé des entretiens de développeur a probablement déjà rencontré des questions sur les patrons de conception. Beaucoup d’ingénieurs semblent reconnaître certains patrons en théorie, mais ont du mal à les appliquer dans la pratique. La façon la plus simple de combler cet écart est de créer un petit projet centré sur l’implémentation d’un patron spécifique.
Le livre original utilise souvent un éditeur de texte comme exemple. D’après mon expérience, les éditeurs de différents types de documents nécessitent l’utilisation de nombreux patrons de conception. Il peut s’agir d’un éditeur de texte, d’un éditeur d’images ou même d’un programme de création de diagrammes.
Tests
Les tests de code sont une pierre angulaire des bases de code stables. Et bien que l’idée semble simple – “écrivez simplement des tests !” – écrire des tests utiles est souvent loin d’être trivial.
Le principal défi est que la maintenance des tests consomme des ressources d’équipe. Si vous devez réécrire les tests après chaque refactorisation du code, la valeur globale de ces tests devient discutable. Ce concept est connu sous le nom de Test Fragility et, d’après mon expérience, il n’est pas aussi connu qu’il devrait l’être. Vous pouvez apprendre la théorie des tests, par exemple, dans ce livre.
Un fort accent mis sur les tests a aussi un impact sur la qualité du code. En général, le code écrit en pensant aux tests sera plus modulaire et exposera une API plus propre et plus simple. Il est facile d’essayer les tests en pratique – il suffit d’intégrer des tests dans un projet existant ou de commencer un nouveau projet en mettant l’accent sur l’écriture de tests.
Algorithmes et structures de données
Connaître les algorithmes n’est pas une exigence stricte dans le développement logiciel moderne. De nombreuses entreprises incluent encore des exercices algorithmiques dans leurs entretiens, même si ces compétences ne sont pas forcément nécessaires au quotidien. Malgré tout, je pense que cela vaut la peine d’investir du temps dans l’apprentissage des algorithmes parce que c’est amusant et intéressant. En plus, aujourd’hui, vous pouvez explorer ces sujets de manière interactive via des plateformes comme LeetCode.
Si vous avez un jour l’occasion de participer à des concours de programmation algorithmique comme l’ACM ICPC, je vous recommande vivement de tenter l’expérience. Même si ces connaissances ne semblent pas directement utiles au départ, les techniques d’optimisation du code peuvent s’appliquer à n’importe quel projet, et participer à une compétition en équipe est une expérience dont vous vous souviendrez probablement avec plaisir.
Multithreading
Le multithreading est un sujet fascinant. Vous pouvez passer des années à écrire du code sans même comprendre les concepts de base. Tous les développeurs savent que bloquer le thread principal figera l’application. Mais si quelque chose tourne mal, seuls les développeurs qui comprennent vraiment le code multithreadé et peuvent visualiser toute la chronologie des événements sont capables de diagnostiquer ces bugs insaisissables, presque fantômes.
À mon avis, comprendre les primitives de synchronisation, les threads et les conséquences de la négligence de ces concepts est l’un des facteurs clés qui distinguent un développeur intermédiaire d’un Senior. Pour comprendre les concepts de base, je recommande le livre gratuit The Little Book of Semaphores.
Pour acquérir une expérience pratique, vous pouvez essayer d’écrire un programme qui effectue un traitement lourd en arrière-plan et synchronise les résultats avec l’UI, surtout si le travail en arrière-plan implique lui-même plusieurs threads. La simulation de processus physiques peut être un excellent point de départ pour ce type de projet.
Programmation graphique
Les processeurs graphiques sont l’une des rares parties d’un ordinateur avec lesquelles la plupart des développeurs ont rarement besoin d’interagir directement. Pour la majorité des applications, le rendu de l’UI se fait soit sur le CPU, soit est abstrait du périphérique GPU réel, si bien que vous n’avez même pas besoin d’y penser. Mais dès que le nombre d’éléments à l’écran devient suffisamment important et que les abstractions de haut niveau ne peuvent plus suivre les fréquences d’images requises, il faut creuser davantage. Comprendre les problèmes que les GPU sont conçus pour résoudre, ainsi que la capacité à leur “expliquer” ce qui doit être rendu, peut vous aider à identifier rapidement des solutions dans des situations similaires.
Un projet classique pour apprendre la programmation graphique consiste à créer un moteur de jeu. Si, comme moi, vous aimez les jeux vidéo, vous vous êtes probablement déjà demandé comment ils sont programmés. Il existe une multitude de ressources en ligne pour apprendre Metal, DirectX, OpenGL ou Vulkan. N’attendez simplement pas de votre projet qu’il devienne le prochain Unreal Engine. Mais si vous parvenez au stade où vous avez créé un petit jeu fonctionnant sur votre propre moteur, je vous garantis que vous rencontrerez des défis fascinants et acquerrez des connaissances précieuses.
Programmation embarquée
Quand j’ai appris pour la première fois que même les plus petits appareils électroniques autour de nous exécutent leurs propres programmes et processeurs, j’ai été immédiatement fasciné et j’ai voulu essayer de construire quelque chose de similaire. Cependant, le développement pour microprocesseurs s’accompagne de nombreuses limitations. Ces systèmes disposent généralement de moins de 128 kilo-octets de mémoire, et l’allocation dynamique de mémoire est généralement exclue.
Écrire et déboguer du code embarqué présente de nombreux défis. Mais, en contrepartie, vous pouvez voir votre code prendre vie dans le monde réel. Même faire clignoter une simple LED m’a donné l’impression d’une percée. Comprendre le fonctionnement des microcontrôleurs est une première étape importante vers la compréhension des CPU modernes et des systèmes d’exploitation. Lorsque vous travaillez avec des appareils embarqués, vous pouvez même devoir vous plonger dans un langage assembleur spécifique à la plateforme (généralement ARM).
Aujourd’hui, il est plus facile que jamais de se lancer dans le développement embarqué. Les microcontrôleurs abordables comme la gamme STM32 sont un excellent point de départ, et de nombreuses cartes prêtes à l’emploi sont livrées avec des programmateurs intégrés qui se connectent via USB. Les possibilités sont infinies, de l’éclairage dynamique d’une pièce à la création de votre propre hub IoT de maison intelligente.
Désassembleur
Parfois, pouvoir regarder un niveau plus bas dans votre code peut être inestimable. Par exemple, dans le développement pour les plateformes Apple, nous travaillons souvent avec des bibliothèques Apple majoritairement closed source. Lorsqu’un comportement ne correspond pas à ce qui est attendu, il faut généralement ouvrir un ticket via Feedback Assistant et attendre (parfois des années !) une réponse. Mais avec l’aide d’un désassembleur, vous pouvez souvent regarder sous le capot et comprendre comment le code closed source fonctionne réellement.
Comprendre le code assembleur de votre propre programme peut aussi être utile, notamment dans le contexte de l’optimisation. Ce n’est qu’en inspectant le code compilé que vous pouvez vraiment savoir ce que fait votre code. Personnellement, j’utilise Hopper Disassembler sur macOS à cette fin.
Compilateurs
Le monde de la programmation a ses propres “clubs secrets”. Si l’on pense aux personnes dont les produits ont le plus d’impact sur les ingénieurs, on en vient inévitablement à celles qui construisent les compilateurs derrière nos langages de programmation préférés. Jusqu’à ce que je passe du temps à étudier moi-même les compilateurs, ces programmes me semblaient relever de la pure magie. Mais même en apprenant les bases, le brouillard de cette magie ne permet toujours pas de saisir pleinement le génie de ceux qui ont créé des langages de programmation entiers.
La bonne nouvelle, c’est qu’il existe de nombreuses ressources et de nombreux livres sur le sujet. Deux de mes favoris sont Engineering a Compiler et, bien sûr, le classique Dragon Book. Vous pouvez vous plonger dans le développement de votre propre langage de programmation en commençant par le tutoriel Kaleidoscope de LLVM. Dans le développement logiciel du “monde réel”, à moins d’être ingénieur compilateur, ces connaissances peuvent vous donner une compréhension bien plus profonde du comportement des langages et des erreurs obscures. En plus, la plupart des compilateurs sont open source, ce qui vous permet de contribuer à des projets massifs à fort impact. Par exemple, contribuer au dépôt Swift enrichit considérablement le portfolio de n’importe quel développeur.
Fondamentaux des systèmes d’exploitation
S’il existe des projets encore plus complexes que les compilateurs, les systèmes d’exploitation viennent immédiatement à l’esprit. En tant que développeurs qui passons la plupart de notre temps à travailler sur des ordinateurs, il est étonnamment facile d’oublier qu’un système d’exploitation n’est qu’un autre programme, comme ceux que nous écrivons nous-mêmes. Une énorme couche d’abstractions au-dessus du matériel crée l’illusion que chaque programme en espace utilisateur s’exécute sur son propre processeur avec sa propre mémoire. Ces abstractions sont si précises que le code écrit et compilé une seule fois peut s’exécuter de manière fiable sur une immense variété de configurations matérielles.
Le livre Operating Systems: Three Easy Pieces est un excellent point de départ pour comprendre le fonctionnement des systèmes d’exploitation. Et si vous vous intéressez plus particulièrement aux rouages internes d’iOS ou de macOS, je recommande la ressource gratuite MacOS X and iOS Internals. Mieux comprendre le fonctionnement d’un OS comble le dernier fossé entre le matériel et le code que nous écrivons. Pour un développeur, cela signifie un contrôle et une compréhension presque complets de ce qui se passe lorsque votre programme s’exécute.
Pour conclure
Avec le recul, je n’ai pas suivi de plan strict. J’ai simplement continué à apprendre, à construire et à poursuivre ce qui m’intéressait. Cette curiosité s’est transformée en carrière.
Si vous êtes à l’aise mais vous demandez ce qui vient ensuite, essayez d’élargir vos horizons. Explorez quelque chose de nouveau. Le temps que vous investissez dans les projets parallèles et dans l’apprentissage portera ses fruits de manière cumulative, et les écarts entre les niveaux—Junior, Middle, Senior et Principal—commenceront à se réduire plus vite que vous ne le pensez.
Il y a toujours encore quelque chose à apprendre. Mais avec chaque projet, chaque erreur et chaque nouveau concept, vous avancez. Continuez à construire.
— Andrii Zinoviev, Principal Product Engineer
Vous voulez rejoindre notre équipe Engineering et avoir un impact sur des millions de personnes ? Découvrez nos offres d’emploi !
The Readdle Team