Skip to content
Portrait de Tarik Hireche

Dernière année en informatique à l'Université de Montréal, diplomation en décembre 2026.

Tarik Hireche

Je travaille près de la machine, sur les processus, les signaux et les conteneurs, et ce qui m'intéresse c'est de savoir si la chose redémarre vraiment.

Diplôme
B.Sc. Informatique · Université de Montréal (DIRO)
Domaine
Systèmes, conteneurs, CI
Diplôme
B.Sc. Informatique, UdeM
Disponible
Décembre 2026
Point fort
Linux · Docker · Prometheus · C++
Basé à
Montréal, QC
Langues
Anglais · Français · Arabe

Expérience

  1. Mars 2026 à aujourd'hui

    Administrateur de plateforme

    Mars 2026 à aujourd'hui

    Sur appel · Télétravail

    Je suis la seule personne technique de l'entreprise. Je m'occupe de l'hébergement, du DNS, des certificats, des déploiements et des mises en ligne. Six mois plus tard, rien n'est tombé de façon imprévue. Personne n'avait jamais écrit les étapes de déploiement, alors j'ai rédigé le manuel dont le client se sert maintenant. J'ai aussi automatisé l'infolettre en Python et en JavaScript pour trois langues. Ça prenait une à trois heures. Ça prend maintenant une trentaine de minutes, sur plus de dix campagnes.

    Développeur full stack

    Mars 2026 à juillet 2026

    Contrat · Hybride

    J'ai sorti le site du client de WordPress et je lui ai écrit une plateforme de contenu en PHP pour la remplacer. Elle gère les téléversements de façon sécurisée. Un journal d'activité en ajout seul et un historique par document rendent la trace reconstituable après coup. La compression sans perte côté serveur a réduit le poids des pages de 45 %. Le propriétaire n'est pas technique et gère le tout seul. L'automatisation de l'infolettre est née de ce travail et a prolongé le contrat.

  2. Janv. 2024 à juillet 2026

    Cap Campus, Université de Montréal

    Montréal, QC

    Ambassadeur

    Sur appel · Sur place

    Je présente l'informatique à des élèves du secondaire. La plupart n'ont jamais vu de code. C'est un bon entraînement.

  3. Mai 2024 à févr. 2026

    Math Plus

    Montréal, QC

    Tuteur en mathématiques

    Contrat · Hybride

    J'ai donné du tutorat en mathématiques à mon compte, du primaire jusqu'au niveau universitaire.

  4. Janv. 2024 à mai 2024

    Université de Montréal (DIRO)

    Montréal, QC

    Auxiliaire d'enseignement, IFT1015 Programmation 1

    J'ai animé le laboratoire hebdomadaire de 120 étudiants de première année. Le travail consistait à lire du code que je n'avais jamais vu et à le déboguer en direct, devant une salle qui attend.

  5. Mai 2022 à févr. 2024

    Gatestone

    Montréal, QC

    Agent de soutien technique

    Permanent · Temps plein

    Je diagnostiquais des problèmes de connectivité et de compte pour des clients d'entreprise, sous pression de temps. Chaque appel commençait par la vérification d'identité avant que je puisse toucher à des données sensibles.

Projets choisis

5 projets

Le plus solide est en premier. L'un d'eux tourne en direct dans cette page.

containersentinelPID 1 · subreaper./appown process groupfork · execorphanadoptedreapeddocker stopSIGTERMkill(-pgid)still alive after 5s, then SIGKILLexit status: the child's own, or 128 + N
Process supervision inside a container: sentinel runs as PID 1, forks and execs the application into its own process group, forwards an incoming SIGTERM to that whole group and escalates to SIGKILL after five seconds, adopts and reaps orphaned descendants, and exits with the child's own status.

Conteneurs et Linux

2026

sentinel

Votre programme tourne en PID 1 dans un conteneur. Le noyau jette tout signal pour lequel PID 1 n'a pas de gestionnaire, donc docker stop ne fait rien et le conteneur finit tué par SIGKILL.

  • Un conteneur sous sentinel sort environ 3 ms après le SIGTERM. Le même programme seul en PID 1 ignore le signal et se fait tuer par SIGKILL au bout des dix secondes.
  • Il redémarre un enfant mort avec un délai de 1, 2, 4, 8 puis 16 secondes, et sert les compteurs de redémarrages, de plantages et d'échecs à Prometheus.
  • 13 cas de test ctest et 5 jobs de CI. La CI monte toute la pile Compose et échoue si Prometheus ne scrute pas ou si Grafana n'a pas le tableau de bord.
  • C++17
  • Linux
  • Signaux POSIX
  • Docker Compose
  • Prometheus
  • Grafana
  • GitHub Actions
Ce que PID 1 vous coûte
Arrêt après SIGTERM
2,5 à 3,1 ms

Sept exécutions, le worker supervisé par sentinel en PID 1 d'un espace de noms de processus, chronométré par wait() pour éviter toute erreur de sondage. Le même worker seul était encore vivant à l'échéance de dix secondes et a fallu le tuer par SIGKILL.

Enfant qui ignore SIGTERM
5,003 s

Même montage, worker en mode têtu, trois exécutions à moins d'une milliseconde l'une de l'autre. C'est l'escalade vers SIGKILL qui part à l'heure.

Délai entre redémarrages
1, 2, 4, 8, 16 s

Chronométré depuis le journal du superviseur avec un enfant qui meurt aussitôt. Cinq redémarrages en quarante secondes, et le délai plafonne à seize.

Suite de tests
13 sur 13

ctest sur une compilation Release, 33 s. La CI lance build, test, shellcheck, docker et compose comme jobs distincts.

Empreinte du superviseur
3,9 Mo RSS

Lu dans /proc pendant la supervision, sur deux fils. Le binaire fait 36 Ko, ou 31 Ko une fois dépouillé.

Le noyau ne délivre un signal à PID 1 que si PID 1 a installé un gestionnaire pour ce signal. Le conteneur reste donc bloqué tout le délai de grâce avant de mourir par SIGKILL. sentinel prend la place de PID 1 et laisse votre programme tourner comme un enfant ordinaire. Il sort avec le code de l'enfant, ou avec 128 plus le numéro du signal si l'enfant a été tué. Un conteneur qui sort en 137, c'est 128 plus 9. C'est l'OOM killer.

Les gestionnaires sont installés sans SA_RESTART. Ça compte : avec le drapeau, le noyau relance waitpid après un signal et la boucle de récupération n'a jamais la main. Sans lui, waitpid renvoie EINTR et la boucle garde le contrôle. Le gestionnaire appelle kill() et rien d'autre. Très peu de fonctions sont sûres en contexte de signal. L'escalade vit sous la même contrainte. Le gestionnaire de SIGTERM arme alarm(5), et un gestionnaire de SIGALRM se charge de tuer.

Il y avait une fenêtre entre le fork et la ligne qui installait les gestionnaires. Un SIGTERM qui arrivait dedans tuait sentinel et laissait l'enfant tourner en orphelin. C'est exactement la panne que sentinel existe pour empêcher. Je l'ai notée comme TODO et j'ai vécu avec un moment. La correction, c'est sigprocmask autour du fork. Il bloque SIGINT et SIGTERM avant, et les débloque une fois les gestionnaires en place. L'enfant restaure le masque d'origine avant l'exec. Sinon tout ce que sentinel lance démarre sourd à ces signaux.

Le serveur de métriques a besoin de son propre fil, parce que le fil principal reste bloqué dans waitpid et ne peut pas attendre aussi dans accept. Ce fil bloque tous les signaux pour lui-même. SIGTERM doit continuer d'arriver sur le fil principal, là où vit le gestionnaire, sinon waitpid n'obtient jamais son EINTR. Les compteurs sont atomiques puisque les deux fils y touchent.

Une seule commande compose monte sentinel, un Prometheus qui le scrute toutes les 5 s, et un Grafana avec le tableau de bord déjà provisionné. La pile fait tourner un enfant qui plante exprès, pour que les courbes montrent quelque chose de réel. Deux règles d'alerte l'accompagnent, une pour la boucle de plantage et une pour un enfant absent depuis deux minutes. La CI monte le tout à chaque poussée et échoue si Prometheus ne voit pas la cible, si le compteur de redémarrages n'a pas bougé, si les deux règles ne sont pas chargées ou si Grafana ne sert pas le tableau de bord.

pushbuildPIT runscorevs baselinedroppedexit 1, build failsheldmerge allowed
CI quality gate: every push runs PIT mutation testing, compares the score against a committed baseline, and fails the build if it dropped.

Tests et CI

2025

Tests de mutation en CI pour GraphHopper

Le pipeline de GraphHopper exécutait la suite de tests à chaque poussée. Il ne demandait jamais si ces tests étaient bons.

  • Un job de mutation PIT fait maintenant échouer la compilation quand le score passe sous une valeur de référence versionnée dans le dépôt.
  • Le pipeline est scindé en deux. Les compilations ordinaires restent rapides, et la mutation ne tourne que sur le module core.
  • J'ai cassé un test exprès, regardé le score tomber à 91 %, et regardé la compilation virer au rouge.
  • Java
  • PIT
  • Mockito
  • GitHub Actions
  • Maven
Comment je sais que la barrière échoue

Je n'avais jamais vu la barrière échouer, donc je ne savais pas si elle marchait. J'ai cassé un test pour faire passer le score de 92 % à 91 %. Le job a viré au rouge. Le signal de baisse a atteint l'étape suivante et déclenché une action maison qui Rickroll le responsable. Ce chemin tourne maintenant de bout en bout.

La suite avait besoin de tests qui tournent sans charger un vrai graphe routier. J'en ai écrit trois avec Mockito, dans leur propre paquet. Ils simulent PointList, DistanceCalcEarth et EdgeIteratorState. Un test peut alors fixer des coordonnées et des attributs d'arête exacts et vérifier le code qui les consomme.

docker composenginxfrontend · :3000Spring BootREST · JPA · :8080PostgreSQLhopital · :5432
Three-tier architecture: an Nginx frontend calls a Spring Boot REST API, which persists to PostgreSQL. All three run as Docker Compose services.

Backend et déploiement

2026

Répertoire hospitalier et plateforme d'inscription

Un répertoire du personnel et un système d'inscription des patients qui devaient démarrer sur n'importe quelle machine, y compris une qui ne les avait jamais vus.

  • Une seule commande docker compose démarre trois services. Nginx se place devant une API Spring Boot, qui tourne sur PostgreSQL.
  • L'API REST repose sur des dépôts Spring Data JPA, donc la persistance reste derrière une interface.
  • J'ai enregistré une vidéo qui va du code source à l'application qui tourne.
  • Java
  • Spring Boot
  • PostgreSQL
  • Docker Compose
  • Nginx
Ce qu'une seule commande doit garantir

Le projet est parti d'un travail de cours en trois tiers. Je l'ai construit en trois services, chacun dans son conteneur. En entrevue, j'aimerais qu'on m'interroge sur le déploiement. Il n'y a pas de README d'étapes manuelles et pas d'ordre de démarrage à retenir. N'importe qui ayant Docker obtient la même pile, dans le même état, avec une seule commande.

heapusedusedusedfree listalloc = pop head · O(1), no GC
Heap layout: a free list threads through the released blocks, so allocation pops the head of that list in constant time.

Systèmes

2025

Trois allocateurs en Zig

Un cours demandait un allocateur de tas. J'en ai écrit trois. Chacun m'a montré la limite du précédent.

  • Les trois sont un allocateur incrémental, un allocateur étiqueté avec un en-tête par bloc, et un troisième qui réutilise les blocs libérés au premier trouvé.
  • J'ai géré l'alignement et l'arithmétique de pointeurs à la main, et il n'y a aucun ramasse-miettes là-dedans.
  • Un plantage est apparu sur ARM après que tous les tests soient passés sur x86-64. Je l'ai traqué.
  • Zig
  • GDB
Le bogue apparu quand j'ai changé de machine

J'ai trouvé celui-là parce que j'ai changé de machine. Une version de l'allocateur étiqueté calculait l'alignement à partir de self.next, un décalage dans le tampon. L'adresse réelle du tampon en mémoire n'entrait jamais dans le calcul. Ça passait tous les tests sur x86-64 Linux. Sur macOS et ARM, ça tombait sur panic: incorrect alignment. Un [N]u8 alloué sur la pile ne commence pas forcément sur une frontière de 8 octets. Aligner un décalage ne vous aligne que par rapport au début du tampon, donc une adresse de base impaire décale toutes celles qui en découlent. Aligner l'adresse absolue a réglé le problème.

Les trois se construisent l'un sur l'autre. Le premier est un tampon d'octets et un index qui avance. Il n'a aucune libération par bloc, parce qu'un allocateur à pile relâche tout ou rien. Le deuxième place un en-tête devant chaque bloc, ce qui rend free() possible comme comptabilité. Un bloc libéré est marqué, puis il reste là. Le troisième parcourt ces en-têtes pour trouver un bloc assez grand avant d'allouer à la fin. Il prend le premier bloc qui convient. Ça coûte O(blocs) et gaspille la fin d'un bloc trop grand. Ça ne demande ni liste libre ni passe de fusion.

Inférence en direct

55 050 paramètres · 88,97 % sur 10k images de test

Chargement du modèle…

Apprentissage automatique

2026

Réseau de neurones et étude d'hyperparamètres

Je voulais savoir quels choix d'entraînement changent le résultat. Alors j'ai construit le réseau à partir de zéro, une pièce à la fois.

  • Les neurones, les couches, quatre fonctions d'activation et quatre fonctions de perte sont tous de moi, écrits en NumPy.
  • J'ai mené neuf expériences contrôlées, une variable à la fois. Le résultat le plus net portait sur la fonction de perte.
  • Le réseau entraîné tourne dans le panneau de gauche, dans votre navigateur. Quantifié en int8, il se télécharge en 55 Ko.
  • Python
  • NumPy
  • PyTorch
Pourquoi la MSE apprend le plus lentement là où elle se trompe le plus

Quand le modèle rate largement un exemple, le gradient de la MSE est multiplié par la dérivée de la sortie. Cette dérivée est proche de zéro précisément quand l'erreur est la plus grande. Le réseau apprend donc le plus lentement sur les exemples dont il aurait le plus à apprendre. L'entropie croisée annule ce terme. C'est pour ça qu'elle est le choix par défaut en classification.

Compétences

Fiabilité et exploitation
  • Responsabilité de la production
  • Arrêt gracieux
  • Politique de redémarrage
  • Manuels d'exploitation
  • Journalisation d'audit
  • DNS et TLS
  • Débogage d'incidents

Utilisé dans: Six mois comme seule personne technique chez Crono Design

CI/CD et déploiement
  • GitHub Actions
  • Pipelines multi-jobs
  • Barrières de fusion
  • Docker
  • Constructions multi-étages
  • Docker Compose
  • Nginx

Utilisé dans: sentinel · Tests de mutation en CI · Répertoire hospitalier

Observabilité
  • Métriques Prometheus
  • Format d'exposition texte
  • Compteurs et jauges
  • Règles d'alerte
  • Tableaux de bord Grafana

Utilisé dans: sentinel, dont la CI échoue si la pile ne scrute pas vraiment

Linux et systèmes
  • Processus et signaux
  • fork / exec / wait
  • Supervision de processus
  • Concurrence
  • Gestion manuelle de la mémoire

Utilisé dans: sentinel · Trois allocateurs en Zig · Fedora au quotidien

Langages
  • C++
  • C
  • Python
  • Bash
  • Java
  • Zig
  • SQL
  • PHP

Utilisé dans: Tous les projets présentés ici, et le travail chez Crono Design

Backend et données
  • Spring Boot
  • Spring Data JPA
  • API REST
  • Conception de schémas PostgreSQL

Utilisé dans: Répertoire hospitalier et plateforme d'inscription

Outils
  • Git
  • GDB
  • strace
  • CMake
  • ctest
  • Make

Utilisé dans: Le bogue d'alignement en Zig · la compilation de sentinel

Distinctions

Bourse d'excellence du DIRO2024
Le département d'informatique de l'Université de Montréal l'a décernée pour le dossier académique.
Top 30 au CTF NorthSec2025
Mon équipe s'est classée dans les 30 premières sur environ 93 à la plus grande compétition de sécurité appliquée d'Amérique du Nord.

À propos

Montréal, QC

Depuis six mois, je suis la seule personne technique sur la présence web d'un client. Je gère l'hébergement, le DNS, les certificats et les déploiements. J'ai rédigé le manuel d'exploitation pour qu'il arrête de m'appeler pour les changements de routine. C'est du travail ingrat. J'ai appris sur la fiabilité plus qu'avec n'importe quel travail scolaire.

La couche en dessous me ramène toujours à elle. De quoi PID 1 est-il responsable dans un conteneur ? Pourquoi une suite de tests peut-elle être verte et rater des bogues ? Je cherche un premier poste où le point difficile est le système, pas le cadriciel.

Prochaine étape

sentinel fait ce que je voulais construire. Il reste Terraform, pour monter la pile sur une machine infonuagique derrière du TLS.

Contact

Ce sur quoi je veux travailler

Des systèmes qui doivent rester debout : cycle de vie des processus, conteneurs, déploiement, pipelines qui attrapent de vraies régressions, et le backend derrière tout ça. Stage ou premier poste. Disponible dès maintenant pour un stage, à temps plein à partir de décembre 2026.

tarik.hireche@umontreal.ca
CV
PDF