Dans les articles précédents, nous avons parlé de ce que nos étudiants font en stage: scientifique (par exemple, dans JetBrains Research ) et industriel . Dans ce post, nous voulons partager comment nous enseignons la programmation industrielle.

En bref: dans quatre cours, un ancien élève essaie une douzaine ou deux technologies et langages, écrit et supprime constamment beaucoup de code, passe une revue de code de camarades plus expérimentés (pas toujours la première tentative), plonge dans un sujet et défend finalement un diplôme significatif. Tout cela se passe directement à l'université et donne un diplôme d'État. Et en été, vous pouvez vous détendre ou faire un stage en Russie chez JetBrains, Yandex et JetBrains Research (si vous voulez plus de science) ou aller à l'étranger (Google, Facebook et autres). Maintenant plus en détail.
À propos de moi
Je m'appelle Yegor Suvorov, j'étudie à la Higher School of Economics, internée avec Google (deux fois), Asana, GSA Capital, a participé avec succès à des programmes internationaux ( étudiants et écoles ) Olympiades. L'année dernière, j'ai obtenu mon diplôme de premier cycle de l'Université académique, j'ai donc parcouru presque tout ce qui est décrit dans le post. Je participe également au développement d'un programme de formation en génie logiciel et réalise des exercices pratiques dans plusieurs matières (Paradigmes et langages de programmation, C ++).
Composants principaux
Dans cet article, nous ne considérerons que la sous-direction «Programmation industrielle». Bien que nous ayons encore l'apprentissage automatique, les langages de programmation et quelques autres, les programmes dans les directions se chevauchent, en particulier dans les deux premiers cours.
La formation se compose de trois parties principales. Je vais d'abord donner un aperçu général, puis je parlerai plus en détail de chaque partie.
- Articles de base . Dès le premier semestre, les enfants apprennent à travailler avec leurs mains. Tous les six mois, tous les "programmeurs industriels" doivent réussir 2 à 4 sujets de base (et certains sujets sont requis pour d'autres sous-directions). Objectif: pomper un élève dans plus ou moins tous les domaines de la programmation, afin que vous puissiez parcourir les niveaux d'abstractions de haut en bas. À partir de l'écriture de votre système d'exploitation jouet avec espace utilisateur en C avec une pincée d'assembleur (pour les plus persistants) et de la ligne de commande, puis en passant par la sémantique de mouvement en C ++ et jusqu'aux transformateurs monades. Cela est nécessaire pour former les horizons et l'expérience de différentes programmations. Nous enseignons non seulement les langues: programmation parallèle, réseaux, bases de données, aussi. Et, bien sûr, peu de sujets ne concernent pas le code, mais c'est toujours la même chose dans le cas: par exemple, l'ingénierie logicielle (cours de synthèse: pourquoi avons-nous besoin d'équipes / managers / gestion de projet et des risques) et la conception d'interfaces (sinon ils penseront que «les moules sont rivés - c'est facile. ") Il y a aussi des mathématiques et des algorithmes, mais c'est un sujet pour un article séparé.
- Pratique semestrielle . Ils doivent obligatoirement être complétés, à partir du deuxième semestre. Objectif: donner à l'élève d'essayer de faire des choses différentes plus que les devoirs et de comprendre ce qui ressemble le plus. Au début du semestre, une foire aux projets a lieu où les chefs de file potentiels de la recherche discutent de ce que vous pouvez en faire. Soit dit en passant, un diplôme pour un leader est facultatif - beaucoup plus important est ce qu'une personne et une pratique spécifiques peuvent donner à l'étudiant. En un semestre, vous pouvez créer une application desktop + mobile sur Qt et comprendre comment travailler généralement sur un projet pour tout le semestre sans exigences techniques claires (avec difficulté). La prochaine chose est d'essayer Android et de se sentir comme «faire un client fiable pour le réseau social» - cela s'avère difficile, même si la fonctionnalité est sévèrement limitée. Dans un autre, essayez de créer une sorte d'outil d'apprentissage automatique en Python et réalisez que vous ne voulez pas du tout aborder ce sujet. Dans le quatrième - allez finir le compilateur Haskell, soyez horrifié et retournez au C ++ amoureux au diplôme. Ou vice versa. Cela dépend de l'élève - c'est le sens de la pratique. En conséquence, l'étudiant forme soit une direction préférée (dans laquelle vous pouvez travailler et faire un diplôme), soit une expérience dans un tas de directions différentes. Gagnant-gagnant de toute façon. Soit dit en passant, si vous n’aimez aucun des projets, vous pouvez créer le vôtre. Mais dans ce cas, vous devez d'abord intéresser un conseiller scientifique ou trouver quelqu'un de l'extérieur, puis nous convaincre que quelque chose de significatif et de protégé peut sortir du projet.
- Éléments facultatifs . Apparaît la troisième année. Raison: tout le monde ne veut pas se plonger dans le noyau Linux, tout comme tout le monde ne veut pas se plonger dans la conception des collections Scala avec des tonnes de collections implicites. Et vous pouvez donc choisir les sujets à approfondir. Par exemple, si un étudiant n'a pas aimé le nombre de façons de tirer un genou dans les avantages, il peut suivre un cours sur la virtualisation de conteneurs sous Linux, écrire en C pur et être heureux. Et vice versa: si «le volume 3 du manuel du développeur du logiciel d'architectures Intel 64 et IA-32» fait encore des cauchemars, vous pouvez entrer dans le magnifique monde de Scala avec des abstractions de licornes. Dans chaque module (un semestre), environ 4 cours sont proposés, dont deux doivent être choisis.
De plus, nous voulons que les étudiants aiment apprendre. À tout moment, vous pouvez discuter avec les responsables de programme et proposer des améliorations dans n'importe quel domaine. Nous collectons les retours quatre fois par an et - attention - en tenons compte et améliorons constamment le programme. Nous ne recrutons pas spécifiquement de nombreux étudiants afin d'avoir l'opportunité de parler personnellement avec tout le monde. Il y a 30 étudiants en deuxième et troisième années, et en quatrième année - 15.
Nous créons également ou recherchons constamment de nouveaux cours à la demande des étudiants, à la recherche de bons professeurs qui comprennent le sujet et sont capables d'enseigner. Ainsi, dans ce module, en quelques semaines seulement, un cours expérimental d'ingénierie inverse de SPbCTF est apparu avec succès dans le programme. Et si vous ne trouvez pas de cours approprié, vous pouvez, par accord, passer par quelque chose de significatif avec Computer Science Center , ShAD ou Coursera.
Articles de base
Sujets de programmation de base: C ++, systèmes de type Unix, paradigmes et langages de programmation, architecture informatique, Java, systèmes d'exploitation, programmation fonctionnelle, bases de données, conception de logiciels, génie logiciel, programmation parallèle, technologies de réseaux informatiques, conception d'interfaces, développement mobile.
Ensemble, ces sujets couvrent presque toutes les tâches qui peuvent survenir au travail. Ils protègent également contre diverses erreurs "classiques", telles que la comparaison de nombres à virgule flottante avec ==, les attentes d'adéquation d'un comportement indéfini, les conditions de concurrence et parlent de l'existence de modèles de conception et de tâches non programmables dans le développement de produits.
Bien sûr, dans le processus d'apprentissage, les élèves «mettent constamment la main sur le laboratoire et les devoirs». Prenons quelque chose de classique, par exemple, l'implémentation de l'archiveur sur l'algorithme Huffman. Faire en sorte qu'il "fonctionne d'une manière ou d'une autre" n'est pas si difficile. Mais pour faire une bonne architecture du projet (au moins pour séparer les entrées-sorties, la compression des bits et l'algorithme lui-même), utilisez correctement les capacités de C ++ (la règle de trois ou cinq selon le semestre) et concevez généralement le code de manière à ce qu'il soit agréable à lire et pas complètement gênant mettre en open-source - un art distinct que les enseignants enseignent dans un cours de C ++, communiquant constamment avec les étudiants et analysant en détail toutes les lignes de code. Sur les sujets restants est similaire. Aucun cours n'est limité aux tests théoriques. Sur tous les sujets avec écriture de code, un programmeur expérimenté révisera le code.
C ++ . La première année d'études. Commençant par C, se terminant par C ++ 14. Nous montrons RAII, Valgrind et autotests, apprenons à écrire à la fois les bibliothèques (my_vector avec une garantie d'exceptions) et les applications (le même archiveur). Pourquoi: parce que C ++ est toujours activement utilisé dans l'industrie, et qu'il résonne activement avec la programmation système (manque de collecte des ordures, vous pouvez montrer la disposition des données en mémoire ...).
Systèmes de type Unix . Premier semestre. Le cours du jeune combattant sur l'utilisation de la ligne de commande et du système de fichiers sans C:\
et D:\
. Exemple de travail de test: sur la paire, l'image d'un Ubuntu installé légèrement cassé se fait entendre, il faut la réparer. Un exemple de devoir: parcourez les fichiers d'un dossier sur Bash et appelez quelqu'un d'utile avec des expressions régulières.
Paradigmes et langages de programmation . Premier semestre. Une douzaine de sujets (au moins OOP, programmation fonctionnelle, SQL, multithreading), et chaque sujet les étudiants peuvent essayer un ou deux devoirs. Bien sûr, tout à fait superficiellement, mais cela donne toujours une compréhension de la polyvalence de la programmation et des éléments sympas qui peuvent être assemblés en utilisant différentes méthodes. OOP, FP et SQL seront ensuite décrits en détail, mais dès la première année, l'étudiant connaît leur existence et peut, par exemple, organiser des assertions dans le code ou écrire quelques tests unitaires simples s'il le souhaite.
Architecture informatique . Première année. Registres, assemblage de quelque chose de semblable à un ordinateur à partir de portes logiques, de caches, d'un pipeline de processeur, de représentation de nombres et d'autres théories. Pourquoi: regrouper des informations sur toutes sortes de choses de bas niveau en une seule image.
Java Deuxième année d'études. Il se termine par des flux et un projet de cours pour Android (par exemple, jouer à un tic-tac-toe récursif avec un bot et un mode réseau). Nous montrons Maven, IDEA, JUnit, le travail asynchrone avec le réseau. Pourquoi: il y a beaucoup de choses qui tournent sur la JVM maintenant, il y a des tonnes de bibliothèques, c'est bon à savoir.
Systèmes d'exploitation . Deuxième année. Hardcore Pas de tracas ennuyeux avec les chargeurs de démarrage - les étudiants reçoivent un démarrage multiple dans le préfabriqué, passant en mode protégé, puis vous pouvez écrire un allocateur de mémoire, des threads, des processus, un système de fichiers, un partitionnement de l'anneau de protection et même un chargement ELF en C. Peut-être pas aussi étendu que les «systèmes d'exploitation modernes» de Tannenbaum, mais vous pouvez clairement voir s'il est intéressant de s'y plonger ou de rester dans un espace utilisateur isolé. Si vous êtes intéressé, bienvenue dans un cours spécial de programmation du noyau Linux. Soit dit en passant, une version très légère est disponible sur Stepik - il n'y a pas d'écriture de système d'exploitation là-bas, mais il y a les tâches de théorie et de vérification nécessaires. Afin de ne pas voler en raison de performances médiocres, il suffit de le parcourir.
Programmation fonctionnelle . Deux cours sur le calcul lambda, puis se sont rendus à Haskell. Nous terminons avec des transformateurs de monades. Bien sûr, tout est détaillé: une monade n'est pas une boîte, mais juste une abstraction utile d'un tel modèle pour écrire du code. Les projets intermédiaires, cependant, sont plus théoriques que pratiques - écrivez l'inférence de type automatique dans le calcul lambda. Mais maintenant, la poursuite du cours est en préparation (en tant que sujet supplémentaire du programme de master), où le multithreading et un serveur Web sont prévus. Lisez également au Computer Science Center .
Bases de données Nous nous familiarisons avec les SGBD relationnels (sur l'exemple de PostgreSQL), SQL. Nous concevons une base de données pour une certaine matière, puis organisons une révision du code les uns pour les autres sur la base des conseils de l'enseignant. Ensuite, l'enseignant fait une revue de code. Concours du formulaire «rédiger une telle demande pour cette base de données». Travaux de requêtes de profilage simples (EXPLAIN). Encore une fois, fait écho au cours au Computer Science Center .
Génie logiciel . Il explique comment le travail d'un programmeur peut être organisé, ce que tout le monde fait dans l'entreprise, pourquoi les bons gestionnaires sont toujours utiles et pourquoi la gestion des projets est également difficile. Quel est l'intérêt de la planification, pourquoi cela ne fonctionne pas toujours, pourquoi tous les bugs n'ont pas besoin d'être corrigés ... Le but est d'avoir une compréhension de ce qui est nécessaire pour des projets autres que des personnes. Bien sûr, il n'est pas réaliste de tout divulguer en détail dans un semestre, mais, par exemple, il est utile de savoir qu'après le développement du projet, il n'y a toujours pas de soutien moins important.
Conception de logiciels . Toutes sortes de façons de modéliser la réalité et (diagrammes UML), méthodes de décomposition, modèles de conception. À titre d'exemples, à la fin du cours, nous comprenons GFS, BigTable, CMake ... En pratique, nous apprenons non seulement à écrire du code, mais aussi à décrire l'architecture et à appliquer des modèles là où ils sont appropriés.
Programmation simultanée Nous commençons avec de simples threads et mutex, à la fin nous analysons et écrivons des algorithmes sans verrouillage / sans attente, pénétrons MESI, étudions des technologies de plus haut niveau comme le framework de jointure en fourche, OpenMP, OpenCL, Intel TBB.
Technologie des réseaux informatiques . Conférences: un aperçu détaillé des principaux protocoles de la pile TCP / IP: messages dans ICMP, une excursion historique dans RIP, toutes sortes d'enregistrements dans DNS, comment fonctionne FTP / HTTP / SMTP / DHCP, ce qu'est le NAT, et même un peu d'IPv6. Pratiques: nous écrivons sur les avantages de notre client et serveur TCP multiplateforme, d'abord pour le messager jouet, puis le client UDP pour DNS.
Conception d'interface L'étudiant n'écrit pas une seule ligne de code, mais passe par toutes les étapes de la conception d'une bonne expérience utilisateur: il propose un projet, mène des recherches (y compris une enquête auprès de personnes réelles), développe et vérifie des scénarios d'utilisation, et à la toute fin, vous pouvez dessiner une interface dans Sketch ou Figma . Le but est de comprendre que pour un bon produit, vous avez besoin non seulement de code, mais aussi d'un tas d'autres travaux préparatoires. La révision du code n'est pas là, mais tous les artefacts intermédiaires sont activement discutés avec l'enseignant. Il me semble irréaliste de passer les devoirs à la première tentative (cependant, ce n'est pas obligatoire).
Développement mobile . Cours avancé de développement Android. Nous écrivons déjà plus sur Kotlin que sur Java, nous utilisons toutes sortes de choses spécifiques à Kotlin pour Android. Par rapport au projet Java de la deuxième année, l'application est plus compliquée ici, nous travaillons plus avec des dépendances externes et des bibliothèques, nous pensons plus à l'interface et aux utilisateurs (ici le cours a quelque chose en commun avec la conception d'interface).
Tests de logiciels . Fondamentalement, il y a beaucoup de théorie qui donne des noms à toutes les pratiques standard que les étudiants ont probablement inventées dans d'autres matières: test du flux de contrôle ou du flux de données, test par paires (test toutes paires) ... Il y a aussi un peu de pratique spécifique - pour élaborer un plan de test pour telle ou telle méthodologie, pour trouver des cas extrêmes dans telle ou telle application, et pour exécuter plusieurs scénarios dans une application web utilisant Selenium, afin qu'il ne soit pas ennuyeux de simplement composer des cas.
Génie logiciel Big Data, alias Génie logiciel Big Data. Lisez avec Computer Science Center . Nous connectons des bases de données, une programmation parallèle, des systèmes distribués et d'autres mots à la mode - ce sont dans des conférences. En pratique, l'année dernière, les étudiants ont rédigé leur annuaire téléphonique distribué à partir de zéro. Dans les prochains lancements, il semble correct de déplacer l'accent d'un niveau bas vers des outils réellement utilisés dans l'industrie comme Zookeeper, Cassandra et d'autres animaux effrayants. Jusqu'à présent, la principale difficulté est de savoir comment émuler les conditions de «big data» pour les étudiants et évaluer leurs solutions: il n'est pas nécessaire de lever Zookeeper s'il n'y a pas de démonstration claire que sans lui tout est très mauvais.
Pratique
La deuxième partie importante de la formation est la pratique. Dès la première année, l'étudiant effectue des tâches pratiquement utiles sous la direction d'un collègue expérimenté. Par exemple, une autre application pour gérer un calendrier ou des notes. Ou de nouvelles fonctionnalités dans une application existante. Ou il étudie la complexité de calculabilité d'une famille de formules s'il est amené dans la direction de l'informatique.
Dans les premiers cours, nous n'avons pas besoin de nouveauté ou de praticité (après tout, l'objectif est de donner du jeu), mais les exigences de diplôme pour la qualité des projets et la protection augmentent. Dans les derniers cours, en plus de la question «qu'est-ce qui a été fait?» il est important que les élèves expliquent pourquoi cela a été fait et pourquoi. En même temps, «je veux vraiment cette entreprise particulière, dans laquelle travaille mon directeur de recherche», n'est pas en soi la réponse. Mais «là, les disques durs meurent à chaque seconde, donc cette open-source ne fonctionne pas, cet article est purement théorique, mais Google a une solution, mais elle est fermée» - complètement. Cela ne fonctionnera pas comme un diplôme pour protéger un exercice inutile de la deuxième année - les développeurs curieux avec des ordinateurs portables et Google sont prêts à défendre (et certains prédéfenses). «Personne n'a encore fait cela» - pratiquement la chose la plus dangereuse qu'on puisse dire. Soit dit en passant, nous défendons non seulement les diplômes, mais aussi les pratiques, régulièrement dès la première année.
Voici quelques photos avec une protection typique. Photographe: Dima Drozdov.


Les pratiques vous permettent d'apprendre à travailler «sur le long terme» avec de grands projets, parfois partiellement écrits par d'autres développeurs. Il n'est pas toujours possible de deviner avec le thème du projet: par exemple, après avoir essayé un développement de bas niveau, un étudiant peut décider de s'y engager à l'avenir. C'est le sens de la pratique: comprendre ce que l'on aime et ce qui ne l'est pas, pas au travail, mais dans des conditions avec des tarifs plus bas. Bien que cette dernière pratique devrait devenir un baccalauréat substantiel. «Fondé», c'est quand, selon le diplôme, vous pouvez au moins écrire un article sur Habr et ne pas aller en négatif. Ou, si le travail est très bon, publiez dans une revue scientifique, parlez lors d'une conférence, ou au moins collectez les avantages.
Articles électifs
La troisième partie, mais également importante, concerne les éléments supplémentaires. Les thèmes sont spécifiques, probablement pas nécessaires à tout le monde, mais les étudiants intéressés peuvent les goûter. Dans les cours supérieurs, il y a la plupart de ces matières: il y a une base, il reste à élargir nos horizons dans une direction intéressante pour l'étudiant. Malheureusement, il n'y a pas assez de temps pour prendre tous les articles. Parfois, l'ensemble des cours change, voici ceux qui m'ont été proposés:
Langues alternatives pour la JVM . Un cours de deux modules: l'un parle de Kotlin, l'autre de Scala. Pour Kotlin, nous analysons à la fois Java Interop, et écrivons notre propre DSL et nos coroutines. Le dernier devoir facultatif consiste à ajouter un débogueur utilisant la corutine à l'interpréteur de langage jouet (écrit dans les devoirs précédents). Quant à Scala ... La langue est grosse, mais nous avons le temps de comprendre toutes sortes d'implicit'y :)
Programmation dans le noyau Linux . Pas à pas, un module de noyau est en cours de développement qui émule un périphérique de stockage virtuel: mmap, tampons, accès simultané, E / S non bloquantes. Sur le chemin, vous pouvez rappeler des interruptions et évincer le multitâche du cours des systèmes d'exploitation et étudier les structures internes de Linux (par exemple, la file d'attente).
Compilateurs Nous écrivons notre compilateur de micro-langage en OCaml. Une pile intermédiaire, compilation en x86 sans LLVM, intégration avec libc. Surpris d'exclamations d'étudiants "pourquoi ne tombe-t-il que sur l'expression d'une centaine?" (probablement parce que le bogue est dans l'allocation des registres). Soit dit en passant, un cours similaire est également disponible au Computer Science Center .
Infographie . Cours de relativement bas niveau: nous étudions OpenGL, écrivons nos shaders pour les ombres et le rendu différé, comparons le mélange des couleurs avec et sans correction gamma.
Construire un SGBD . Base de données de périphériques internes. Toutes sortes d'algorithmes de connexion, modèles formels, SGBD de colonnes. En pratique, vous pouvez implémenter plusieurs algorithmes de traitement bloc par bloc dans un SGBD jouet avec des avantages (par exemple, une jointure de hachage doublement pipelinée).
Virtualisation de conteneurs . Une étude détaillée des conteneurs sous Linux. Les espaces de noms et les cgroups, par exemple - et l'API, et comment cela fonctionne. Toutes sortes d'outils auxiliaires pour le réseau. Dans le processus, nous écrivons notre conteneur comme Docker, mais ce n'est pas si simple - vous devez limiter correctement un tas de tout, configurer le réseau, transmettre les fichiers nécessaires au conteneur ... Cependant, l'orchestration de haut niveau utilisant Kubernetes comme exemple est également prise en compte.
Ce que nous voulons améliorer
Nos étudiants et nous-mêmes sommes plus susceptibles d'être satisfaits du programme obtenu (à en juger par les sondages). Cependant, vous pouvez faire encore mieux, non seulement améliorer les éléments existants, mais également en ajouter de nouveaux.
Par exemple, on ne sait toujours pas comment transférer certains aspects de «l'expérience de travail» à l'université. Le même travail avec le code hérité - utile? Et puis. Il existe même des livres et des techniques spécifiques. Mais pour en faire un bon parcours, plusieurs facteurs doivent être combinés:
- Ne distrayez pas les enseignants de leur travail principal pendant longtemps, afin qu'ils aident constamment les élèves à comprendre un grand projet. Et s'il existe une bonne documentation - ce n'est plus le cas pour Legacy.
- Les étudiants devraient être intéressés. "Ajoutez mille lignes de code à un projet dont vous n'avez pas besoin" n'est pas inclus.
- Le résultat devrait être prévisible. "Il semble que ce soit une tâche insoluble, désolé, ils n'y ont pas pensé" - de mauvaises nouvelles selon les résultats de la vérification des devoirs.
Malheureusement, nous n'avons pas encore trouvé comment procéder. Le plus proche est dans le sens de l'apprentissage automatique, où des séminaires ont lieu chaque semaine au cours desquels les étudiants font des présentations sur certains des derniers articles. Peut-être cette expérience peut-elle être transférée à la programmation industrielle.
Les seuls domaines qui ne sont pas couverts actuellement sont peut-être le développement Web (y compris le front-end), les systèmes d'automatisation complexes (comme 1C ou SAP) et la sécurité informatique (un cours expérimental commencé au début de février 2019). Nous avons peut-être oublié quelque chose d'autre, ou vous savez comment vous pouvez apprendre à programmer encore mieux - nous serons heureux de discuter dans les commentaires.
Néanmoins, nous pensons que les diplômés qui sont prêts à travailler et qui, si nécessaire, doivent être spécialement formés, puis peut-être les systèmes internes de l'entreprise, quittent déjà le baccalauréat. Soit dit en passant, un sujet distinct sur lequel nous pensons et essayons maintenant de mettre en œuvre est ce que, après un ensemble si dense de cours, étudier dans une magistrature, mais c'est un sujet pour un poste séparé.