Systèmes d’exploitation et Linux
Comprendre processus, mémoire, système de fichiers, permissions et outils de ligne de commande Linux.
APPROFONDI
Objectifs d’apprentissage
- Décrire le cycle de vie d’un processus, ses états, son PID et le rôle de l’ordonnanceur.
- Expliquer la mémoire virtuelle, la traduction pages-cadres et les principaux indicateurs d’observation.
- Lire et modifier des permissions Linux en appliquant le principe du moindre privilège.
- Composer des commandes avec le shell, les flux standard, les tubes, les expansions et les codes de retour.
- Écrire, tester et documenter un script de sauvegarde robuste pour un répertoire Unix.
Prérequis utiles
- Savoir manipuler des fichiers et répertoires depuis un terminal.
- Maîtriser les variables, conditions et boucles élémentaires d’un langage de programmation.
- Connaître les bases de représentation binaire et de raisonnement algorithmique.
Processus et ordonnanceur
Définitions et idée centrale
Un processus est un programme en cours d’exécution, avec un espace mémoire, des registres, une pile et des descripteurs de fichiers. Son identifiant (PID) permet au noyau de le distinguer. Un thread partage généralement l’espace mémoire du processus qui le contient, alors que deux processus sont isolés par défaut. L’ordonnanceur choisit une tâche prête pour utiliser le processeur : la transition simplifiée est Ppret→Pelu→Pbloque.
Méthode et limites
On observe les états avec ps ou top, puis on relie parent et enfant avec pstree. Une attente d’entrée/sortie ne signifie pas que le programme est terminé. Confondre PID et code de retour est une erreur fréquente : wait récupère ce dernier, tandis que kill cible le PID.
Exemple guidé
Lancer sleep 2 &, relever son PID avec $!, puis wait $!. Le shell crée l’enfant, l’enfant dort en état bloqué, puis se termine; wait rend la main après son code de sortie.
Point de contrôle : expliquer pourquoi plusieurs processus prêts ne s’exécutent pas simultanément sur un seul cœur.
- Un processus possède un contexte et un PID.
- L’ordonnanceur alterne les tâches prêtes et les attentes d’entrée/sortie.
- PID, état et code de retour sont trois informations différentes.
Un processus est un programme en cours d’exécution, avec un espace mémoire, des registres, une pile et des descripteurs de fichiers. Son identifiant (PID) permet au noyau de le distinguer.
Dossier complet — Systèmes d’exploitation et Linux
L2 · S3 · Programmation et systèmes
Dossier pédagogique original Matrice MI. Contenu d’entraînement non officiel; il ne remplace pas le support ou la maquette d’un établissement.
Objectifs d’apprentissage
-
Décrire le cycle de vie d’un processus, ses états, son PID et le rôle de l’ordonnanceur.
-
Expliquer la mémoire virtuelle, la traduction pages-cadres et les principaux indicateurs d’observation.
-
Lire et modifier des permissions Linux en appliquant le principe du moindre privilège.
-
Composer des commandes avec le shell, les flux standard, les tubes, les expansions et les codes de retour.
-
Écrire, tester et documenter un script de sauvegarde robuste pour un répertoire Unix.
Prérequis
-
Savoir manipuler des fichiers et répertoires depuis un terminal.
-
Maîtriser les variables, conditions et boucles élémentaires d’un langage de programmation.
-
Connaître les bases de représentation binaire et de raisonnement algorithmique.
Cours
1. Processus et ordonnanceur
Définitions et idée centrale
Un processus est un programme en cours d’exécution, avec un espace mémoire, des registres, une pile et des descripteurs de fichiers. Son identifiant (PID) permet au noyau de le distinguer. Un thread partage généralement l’espace mémoire du processus qui le contient, alors que deux processus sont isolés par défaut. L’ordonnanceur choisit une tâche prête pour utiliser le processeur : la transition simplifiée est Ppret→Pelu→Pbloque.
Méthode et limites
On observe les états avec ps ou top, puis on relie parent et enfant avec pstree. Une attente d’entrée/sortie ne signifie pas que le programme est terminé. Confondre PID et code de retour est une erreur fréquente : wait récupère ce dernier, tandis que kill cible le PID.
Exemple guidé
Lancer sleep 2 &, relever son PID avec $!, puis wait $!. Le shell crée l’enfant, l’enfant dort en état bloqué, puis se termine; wait rend la main après son code de sortie.
Point de contrôle : expliquer pourquoi plusieurs processus prêts ne s’exécutent pas simultanément sur un seul cœur.
Points-clés
- Un processus possède un contexte et un PID.
- L’ordonnanceur alterne les tâches prêtes et les attentes d’entrée/sortie.
- PID, état et code de retour sont trois informations différentes.
2. Fichiers et permissions
Définitions
Linux présente les fichiers comme des objets nommés dans une arborescence; un répertoire associe des noms à des inœuds. Les droits r, w et x sont évalués séparément pour le propriétaire, le groupe et les autres. Pour un répertoire, x autorise la traversée et w permet de modifier ses entrées. Le principe du moindre privilège réduit les dommages en cas d’erreur.
Méthode et limites
ls -l, id, stat et namei -l permettent d’expliquer un refus. En octal, 640 signifie propriétaire rw-, groupe r--, autres ---; chmod 640 rapport.txt applique ce choix. Attention : le droit du fichier ne suffit pas si un répertoire parent interdit la traversée, et ACL ou umask peuvent compléter le modèle.
Exemple guidé
Pour un script privé lisible et exécutable par son propriétaire, utiliser chmod 700 sauvegarde.sh. Le propriétaire obtient 4+2+1=7, groupe et autres 0; un collègue ne peut donc ni le lire ni le lancer.
Point de contrôle : justifier pourquoi chmod 600 est adapté à une clé secrète, mais pas à un programme partagé.
Points-clés
- Les permissions s’appliquent au fichier et au chemin qui y mène.
- Les chiffres octaux codent lecture, écriture et exécution.
- Le moindre privilège et la umask limitent l’exposition.
3. Shell et redirections
Définitions
Un shell interprète une ligne, développe les variables et motifs, puis lance une commande. Le processus reçoit l’entrée standard (0), écrit sur la sortie standard (1) et la sortie d’erreur (2). Une redirection change une destination; un tube | relie la sortie d’une commande à l’entrée de la suivante. La différence entre > (écraser) et >> (ajouter) est essentielle.
Méthode
On construit un pipeline par étapes et on vérifie chaque précondition. grep -R "TODO" src/ | sort | uniq filtre, trie puis déduplique. 2> sépare les erreurs; && n’exécute la suite qu’en cas de succès, contrairement à ;. Les guillemets évitent l’expansion inattendue des espaces et caractères spéciaux.
Exemple guidé
Pour compter les fichiers C contenant main, exécuter grep -R -l 'main' --include='*.c' src/ | wc -l. grep émet un chemin par fichier, le tube transmet ces lignes et wc -l les compte. Si le répertoire manque, l’erreur reste visible sur le descripteur 2.
Point de contrôle : expliquer le comportement de cmd > sortie 2>&1 et l’ordre des redirections.
Points-clés
- Les descripteurs 0, 1 et 2 structurent les échanges.
- Un pipeline compose des filtres sans fichier intermédiaire.
- Quotage, ordre des redirections et codes de retour évitent les surprises.
4. Mémoire, adresses et isolation
Définitions
La mémoire virtuelle donne à chaque processus un espace d’adresses apparent, indépendant des adresses physiques. Le noyau traduit les pages virtuelles en cadres physiques grâce aux tables de pages; une page absente peut provoquer un défaut de page et un chargement depuis le stockage. La pile contient notamment les appels de fonctions, le tas sert aux allocations dynamiques et le segment de code contient les instructions.
Propriété et méthode
L’isolation empêche un processus de lire arbitrairement la mémoire d’un autre. free, pmap et /proc/<pid>/status aident à distinguer mémoire virtuelle réservée et mémoire résidente. La mémoire partagée est une exception explicitement configurée. Une erreur fréquente consiste à interpréter toute hausse de mémoire virtuelle comme une consommation physique.
Exemple guidé
Si une page fait 4096 octets et qu’une adresse virtuelle vaut 10000, le numéro de page est ⌊10000/4096⌋=2 et le déplacement vaut 10000−2×4096=1808. Le noyau utilise l’entrée 2 de la table puis ajoute 1808 au cadre obtenu.
Point de contrôle : distinguer défaut de page, fuite mémoire et dépassement de pile.
Points-clés
- La mémoire virtuelle sépare adresses vues et mémoire physique.
- Pages, cadres et défauts de page structurent la traduction.
- La mesure doit distinguer mémoire réservée, résidente et partagée.
5. Scripts robustes et automatisation Unix
Méthode de conception
Un script de sauvegarde fiable valide ses entrées, échoue explicitement et laisse une trace exploitable. On commence par #!/usr/bin/env bash, puis set -euo pipefail avec discernement : -e peut interrompre une commande dont l’échec était attendu. Les variables sont citées ("$source") afin de préserver les espaces; mktemp évite les noms temporaires prévisibles.
Exemple guidé complètement résolu
Pour archiver un répertoire vers un dossier de destination :
#!/usr/bin/env bash
set -euo pipefail
src=${1:?répertoire source requis}
dst=${2:?destination requise}
test -d "$src" || { printf 'Source invalide\n' >&2; exit 2; }
mkdir -p -- "$dst"
tar -czf "$dst/backup-$(date +%F).tar.gz" -C "$(dirname "$src")" "$(basename "$src")"
Le test protège tar, -- limite l’ambiguïté des noms et le code 2 signale une mauvaise utilisation.
Limites et contrôle
Une sauvegarde n’est pas validée sans restauration d’essai, somme ou journal. Tester avec un chemin contenant des espaces et un fichier illisible. Point de contrôle : proposer une stratégie contre l’écrasement d’une archive existante.
Points-clés
- Un script utile définit un contrat d’entrée et des codes d’erreur.
- Le quotage protège les chemins et les expansions du shell.
- Une sauvegarde doit être testée par restauration, pas seulement créée.
Exercices corrigés
Exercice 1 · Fondamental
Le fichier rapport.txt appartient à alice, son groupe est projet et ls -l affiche -rw-r-----. Donner les droits en octal, dire si bob (membre de projet) peut le lire, puis proposer la commande pour ajouter l’écriture au groupe sans modifier les autres droits.
Correction détaillée
- Les triplets sont
rw-(6),r--(4) et---(0) : le mode est donc640. 2. Bob est dans le groupeprojet, il peut lire le fichier mais pas l’écrire. 3. Ajouter l’écriture au groupe donne660; la commande estchmod g+w rapport.txt(ouchmod 660 rapport.txtsi l’état initial est garanti). Les droits des autres restent nuls.
Exercice 2 · Fondamental
Dans src/, compter les fichiers .c qui contiennent au moins une occurrence de malloc, en ignorant la casse, sans compter plusieurs fois un même fichier. Écrire une commande et expliquer chaque étape.
Correction détaillée
grep -R -l -i --include='*.c' 'malloc' src/renvoie un seul chemin par fichier correspondant grâce à-l, récursivement et sans tenir compte de la casse. 2.wc -lcompte ces chemins. 3. La commande complète estgrep -R -l -i --include='*.c' 'malloc' src/ | wc -l. Les erreurs éventuelles restent sur stderr; elles ne sont pas mélangées au comptage.
Exercice 3 · Intermédiaire
Un shell lance sleep 30 &, puis l’utilisateur exécute ps -o pid,ppid,stat,cmd -p $!. Décrire les informations attendues, expliquer pourquoi l’état peut contenir S, et donner une séquence propre pour terminer le processus puis récupérer son code de sortie.
Correction détaillée
pidest l’identifiant desleep,ppidcelui du shell etcmdcontientsleep 30;statcontient typiquementS, état dormant interruptible, car le processus attend l’expiration du temporisateur. 2. Envoyerkill $!demande une terminaison polie. 3.wait $!attend la fin et rend le code; après SIGTERM, le shell indique généralement un échec associé au signal. Une séquence robuste estpid=$!; kill \"$pid\"; wait \"$pid\" || rc=$?; printf 'code=%s\\n' \"${rc:-0}\".
Exercice 4 · Intermédiaire
Une machine utilise des pages de 1024 octets. Une adresse virtuelle 3587 est traduite par la table : page 0→cadre 4, page 1→cadre 7, page 2→cadre 1, page 3→cadre 6. Calculer page, déplacement et adresse physique.
Correction détaillée
- Division euclidienne : 3587=3×1024+515, donc la page virtuelle vaut 3 et le déplacement 515. 2. La table associe la page 3 au cadre 6. 3. L’adresse physique est 6×1024+515=6659. Il faut vérifier que l’entrée est présente; sinon un défaut de page aurait lieu et le calcul ne pourrait pas être conclu immédiatement.
Exercice 5 · Avancé
Concevoir un script Bash backup.sh SOURCE DEST qui refuse une source inexistante, crée DEST, produit une archive datée sans suivre les chemins absolus, écrit les erreurs sur stderr et refuse d’écraser une archive du même jour. Donner le script et justifier les choix.
Correction détaillée
#!/usr/bin/env bash
set -euo pipefail
src=${1:?SOURCE manquante}; dest=${2:?DEST manquante}
test -d -- "$src" || { printf 'source invalide\n' >&2; exit 2; }
mkdir -p -- "$dest"
name="$dest/backup-$(basename -- "$src")-$(date +%F).tar.gz"
test ! -e "$name" || { printf 'archive existante\n' >&2; exit 3; }
tar -czf "$name" -C "$(dirname -- "$src")" "$(basename -- "$src")"
``` 1. Les expansions sont citées, donc les espaces sont sûrs. 2. `-C` évite d’enregistrer un chemin absolu. 3. Le test préalable empêche l’écrasement; les codes 2 et 3 distinguent entrée invalide et conflit. Tester avec un nom contenant des espaces, une seconde exécution et une restauration avec `tar -tzf`.
## Quiz d’autoévaluation
### Question 1
Quel identifiant désigne un processus Linux en cours d’exécution ?
✓ Le PID
• Le masque umask
• Le descripteur 2
• Le numéro de page
**Explication :** Le PID (process identifier) identifie le processus; umask concerne les permissions et 2 désigne stderr.
### Question 2
Quel état décrit typiquement un processus qui attend une entrée ou une temporisation ?
• R, prêt
✓ S, dormant interruptible
• Z, zombie uniquement
• X, exécuté définitivement
**Explication :** S correspond à sleeping : le processus n’utilise pas le CPU et peut être réveillé par un événement.
### Question 3
Que signifie le mode octal 640 ?
✓ rw-r-----
• rwxr-----
• rw-r--r--
• r--------
**Explication :** 6 vaut rw-, 4 vaut r-- et 0 vaut ---, dans l’ordre propriétaire, groupe, autres.
### Question 4
Quel opérateur ajoute la sortie à la fin d’un fichier ?
• <
• |
✓ >>
• 2>
**Explication :** `>>` ouvre en ajout; `>` écrase, `<` redirige l’entrée et `2>` cible stderr.
### Question 5
Dans un pipeline, que transmet `|` ?
✓ La sortie standard vers l’entrée standard suivante
• Les permissions du fichier
• Le code source vers stderr
• La mémoire virtuelle entière
**Explication :** Le tube connecte stdout d’une commande à stdin de la suivante, permettant une composition de filtres.
### Question 6
Avec des pages de 4096 octets, quel est le déplacement de l’adresse 5000 ?
• 0
✓ 904
• 4096
• 5000
**Explication :** $5000=1\times4096+904$ : la page vaut 1 et le déplacement vaut 904.
### Question 7
Pourquoi citer `"$src"` dans un script ?
• Pour convertir en entier
✓ Pour préserver les espaces du chemin
• Pour rendre le fichier exécutable
• Pour désactiver le noyau
**Explication :** Les guillemets empêchent le découpage en plusieurs mots et limitent les expansions indésirables.
### Question 8
Quelle pratique valide réellement une sauvegarde ?
• Regarder uniquement la taille de l’archive
✓ La restaurer dans un répertoire de test
• Changer le nom du fichier
• Supprimer le répertoire source
**Explication :** Une restauration d’essai vérifie que l’archive est lisible et contient les données attendues; la taille seule ne le prouve pas.
## Glossaire
- **Processus** — Instance d’un programme en cours, dotée d’un contexte d’exécution, d’un espace d’adresses et de descripteurs.
- **PID** — Identifiant numérique attribué par le noyau à un processus pour l’observer ou lui envoyer un signal.
- **Ordonnanceur** — Composant du noyau qui choisit quelle tâche prête obtient un temps de processeur.
- **Mémoire virtuelle** — Mécanisme qui présente à chaque processus un espace d’adresses isolé et traduit vers des cadres physiques.
- **Inœud** — Structure de métadonnées Unix décrivant un fichier, ses droits, son propriétaire et ses blocs, indépendamment de son nom.
- **Permission** — Droit de lecture, écriture ou exécution évalué pour le propriétaire, le groupe ou les autres.
- **Tube** — Canal interprocessus qui relie la sortie standard d’une commande à l’entrée standard d’une autre.
- **Umask** — Masque utilisé lors de la création d’objets pour retirer des permissions par défaut.
## TP · Automatiser et vérifier une sauvegarde de répertoire
Dans un répertoire de travail fictif, une équipe veut archiver les fichiers `.c` et `.h`, produire un journal lisible et pouvoir contrôler le contenu sans modifier l’original. Le mini-cas réutilise `find`, les permissions, les redirections et un script Bash; il ne suppose aucun accès administrateur.
### Objectifs
- Analyser les droits et repérer les fichiers non lisibles par le propriétaire.
- Construire un pipeline de sélection et de comptage reproductible.
- Écrire un script cité, paramétré et muni de codes d’erreur.
- Tester une archive par inspection et restauration dans un dossier temporaire.
### Étapes
1. Créer `atelier/src` avec trois fichiers `.c`, un `.h` et un fichier texte, dont un nom contient un espace; relever `find`, `stat` et `ls -l`.
2. Écrire puis tester un pipeline qui liste les sources, trie les chemins et compte ceux qui contiennent `main`; rediriger le journal et les erreurs séparément.
3. Implémenter `backup.sh SOURCE DEST` avec validation, `set -euo pipefail`, `tar`, nom daté et refus d’écrasement.
4. Exécuter le script deux fois, avec une source invalide et avec un chemin contenant des espaces; conserver les sorties et codes.
5. Créer `restore-test`, extraire l’archive, comparer la liste attendue à la liste restaurée et documenter toute différence.
### Livrables attendus
- `backup.sh` exécutable et commenté, avec exemples d’appel.
- Un journal texte contenant commandes, sorties, codes d’erreur et permissions observées.
- Un court compte rendu de restauration avec liste attendue, résultat et limites.
### Critères d’évaluation
- Fonctionnalité : l’archive et la restauration reproduisent les fichiers attendus (40 %).
- Robustesse : entrées invalides, espaces, erreurs et écrasement sont gérés (25 %).
- Compréhension Unix : permissions, flux, tube et processus sont correctement expliqués (20 %).
- Traçabilité : commandes, unités de temps, résultats et limites sont vérifiables (15 %).
### Piste de résolution
Sélectionner les chemins avec `find` ou `grep -l` sans concaténer naïvement des noms; citer toutes les variables. Créer l’archive avec `tar -C` depuis le parent de la source et vérifier l’absence du fichier cible avant écriture. Séparer stdout et stderr, conserver le code de retour, puis utiliser `tar -tzf` et une extraction dans `restore-test`. Une solution acceptable explicite ses hypothèses et ne modifie jamais la source.
## Sujets originaux d’entraînement (non officiels)
### Sujet de préparation — systèmes d’exploitation et Linux
> Sujet original non officiel, créé pour l’entraînement; il ne s’agit jamais d’une épreuve d’une année passée ni d’un cours officiel.
#### Exercice 1
Une commande `find logs -type f -name '*.log' -print0` est suivie d’un traitement. Expliquer l’intérêt de `-print0` et proposer une consommation sûre en Bash.
**Correction :** `-print0` sépare les chemins par octet nul, donc les espaces et retours à la ligne dans les noms ne cassent pas le découpage. On peut utiliser `while IFS= read -r -d '' f; do printf '%s\n' "$f"; done < <(find logs -type f -name '*.log' -print0)`. `IFS=` et `-r` préservent le contenu; chaque chemin est ensuite cité. Une simple substitution de commande ou une boucle sur `$(find ...)` serait fragile.
#### Exercice 2
Décrire le cycle d’un processus fils créé par un shell, depuis `fork` jusqu’à `wait`, en mentionnant le cas zombie.
**Correction :** Le shell appelle `fork`, qui crée un fils avec un nouvel espace de processus; le fils peut appeler `exec` pour remplacer son image par la commande. Le parent peut continuer. À la fin, le fils devient zombie tant que son statut n’a pas été collecté. `wait` récupère ce statut et libère l’entrée du noyau. Si le parent meurt, un autre processus adopte le fils; cela ne rend pas le zombie permanent si le statut est finalement récolté.
#### Exercice 3
Un fichier secret est créé avec une umask 027 à partir d’un mode demandé 0666. Calculer le mode effectif et justifier les droits obtenus.
**Correction :** La umask retire les bits correspondants : `0666 & ~0027 = 0640`. Le propriétaire obtient `rw-`, le groupe `r--`, les autres aucun droit. La umask ne donne pas de droit supplémentaire et s’applique à la création; elle ne modifie pas rétroactivement les fichiers existants. Le résultat exact peut aussi dépendre du mode demandé par le programme, mais pour 0666 le calcul est 640.
---
### Sujet de préparation — reprise systèmes, shell et permissions
> Sujet original non officiel, conçu pour une préparation autonome; il ne s’agit jamais d’une annale, d’une épreuve d’années passées ou d’un document institutionnel.
#### Exercice 1
Un script exécute `grep -R TODO src/ >todo.txt 2>&1`. Expliquer précisément où vont stdout et stderr, puis proposer une variante séparant les deux flux.
**Correction :** La redirection `>todo.txt` affecte stdout, puis `2>&1` duplique vers stderr la destination actuelle de stdout : les deux flux vont donc dans `todo.txt`. Pour les séparer, écrire `grep -R TODO src/ >todo.txt 2>todo-errors.txt`. L’ordre compte : `2>&1 >todo.txt` enverrait stderr vers l’ancienne destination, souvent le terminal, puis stdout vers le fichier.
#### Exercice 2
Une application consomme beaucoup de mémoire puis est tuée par le noyau. Donner trois hypothèses observables et une démarche de diagnostic non intrusive.
**Correction :** Hypothèses : fuite d’allocation, croissance légitime du jeu de données, ou pression mémoire globale déclenchant l’OOM killer. Observer avec `ps -o pid,rss,vsz,stat,cmd`, `pmap -x PID`, `free` et les journaux du noyau; comparer RSS au fil du temps pendant une charge reproductible. VSZ seul ne prouve pas une consommation physique. Ne pas conclure sans distinguer mémoire partagée, résidente et réservée; limiter l’essai dans un environnement de test.
#### Exercice 3
Proposer une politique de permissions pour un répertoire `projet` partagé par le groupe dev, où les nouveaux fichiers doivent rester privés aux membres du groupe et où seul le propriétaire peut supprimer les entrées qu’il crée.
**Correction :** Créer le répertoire avec propriétaire adéquat et groupe dev, par exemple `chgrp dev projet; chmod 2770 projet` : le bit setgid conserve le groupe. Pour empêcher la suppression d’autrui, ajouter le sticky bit, par exemple `chmod 3770 projet` (setgid + sticky + 770). Les fichiers créés doivent être contrôlés par une umask de groupe, souvent 007, selon le besoin de lecture/écriture. Vérifier avec `stat`, deux comptes du groupe et des tentatives de création, lecture et suppression; le comportement dépend aussi des ACL.
## Parcours de révision sur quatre semaines
### Semaine 1 · Processus, PID, états et ordonnanceur
Dessiner les transitions prêt/élu/bloqué, exécuter `ps` et `pstree`, puis expliquer trois sorties observées. Avant de terminer, reformule les notions sans tes notes, vérifie les résultats dans le cours et note une difficulté précise à reprendre la semaine suivante.
### Semaine 2 · Mémoire virtuelle et système de fichiers
Résoudre cinq traductions page-déplacement, inspecter `/proc`, et justifier des modes `600`, `640` et `755`. Avant de terminer, reformule les notions sans tes notes, vérifie les résultats dans le cours et note une difficulté précise à reprendre la semaine suivante.
### Semaine 3 · Shell, redirections et scripts
Construire trois pipelines, séparer stdout/stderr et écrire une première version de `backup.sh` testée sur des noms avec espaces. Avant de terminer, reformule les notions sans tes notes, vérifie les résultats dans le cours et note une difficulté précise à reprendre la semaine suivante.
### Semaine 4 · Intégration et préparation
Réaliser le TP en temps limité, restaurer une archive, corriger les erreurs puis traiter un sujet de préparation sans consulter le corrigé. Avant de terminer, reformule les notions sans tes notes, vérifie les résultats dans le cours et note une difficulté précise à reprendre la semaine suivante.