IMDS Interview Prep
IMDS Prep
★ IMDS Software — Entrevue Programmeur-Analyste

4 jours pour défendre une entrevue full-stack R&D

Programme intensif, honnête et critique, calibré pour le poste d'Analyste-Programmeur chez IMDS Software Inc. (Montréal). Objectif : combler les angles morts (Java/Spring, SQL entreprise, multithreading) tout en capitalisant sur tes forces (ML, traitement d'image, Python). Pas de promesse d'expertise : l'objectif est de tenir une conversation technique crédible et de démontrer ton potentiel R&D.

Entreprise
IMDS Software Inc.
Poste
Analyste-Programmeur full-stack
Lieu
Montréal (présentiel)
Domaine
OCR / ICR / IWR, ML documentaire
Durée de prep
4 jours (Ven → Lun)
Salaire plancher
70 000 $ CAD / an

🎯 Analyse critique : où tu joues, où tu bluffes

Lis ça en premier. Sans ça, la prep n'a pas de direction.

✔ Terrain fort — capitalise dessus :
  • Machine Learning / CV : thèse en imagerie 3D, réseaux convolutifs. IMDS fait du document ML — tu parles la langue.
  • Python + React : explicitement dans le JD, tu l'as en prod (SaaS freelance).
  • Capacité d'analyse, autonomie, R&D : profil doctoral → c'est exactement ce qu'ils cherchent dans le pitch du poste.
  • Français + Anglais : bilinguisme requis, tu l'as.
✘ Gaps réels — ne les cache pas, encadre-les :
  • Java / Spring : c'est le plus gros gap. IMDS a probablement du Java massif côté backend OCR. 4 jours ne font pas un développeur Java ; ils font un développeur qui peut lire du Java et apprendre vite.
  • C++ : utilisé pour la perf en OCR/traitement image. Si tu n'en as jamais fait sérieusement, dis-le. Mais sache expliquer RAII, pointeurs, références, templates basiques.
  • C# : atout pour Visual Studio / écosystème Microsoft. Survol suffit.
  • MSSQL / Oracle en entreprise : si ton expérience DB se limite à PostgreSQL/SQLite, il te manque la culture "procédures stockées, index en prod, transactions longues". Rattrapable en 1 jour pour tenir une conversation.
  • QA / tests automatisés : c'est "un atout". Tu as monté une formation QA (tu peux la citer). Mets-la en avant.
  • Multithreading système : Python GIL tu connais, mais Java threading / mutex / locks en environnement enterprise, il faut réviser.
⚠ Pièges à éviter :
  • Ne pas prétendre connaître ce que tu ne connais pas. Les devs seniors détectent ça en 30 secondes et c'est éliminatoire.
  • Ne pas minimiser ton doctorat. Ils recrutent en R&D, ta rigueur scientifique est un actif — mais ils voudront voir que tu sais aussi livrer du code en prod, pas juste prototyper.
  • Ne pas arriver sans question. "Aucune question" = désintérêt perçu.
  • Présentiel Montréal : si tu es en France actuellement, clarifie ta disponibilité géographique dès le début de l'entrevue.
  • "À partir de 70 k$" = ancre basse. Si on te pose la question salariale, donne une fourchette ou renvoie au dialogue, n'accepte pas le plancher d'office.
Stratégie 4 jours en une phrase : Jour 1 = bases Java/Spring (le gap principal). Jour 2 = SQL entreprise + multithreading + survol C++/C#. Jour 3 = OCR/ML documentaire (ton terrain, tu polis le pitch). Jour 4 = soft skills, questions, pitch, logistique, repos.
Progression globale — 0 / 0 items cochés 0 %

📅 Planning 4 jours — checklists actionables

Coche au fur et à mesure. Les items sont persistés dans ton navigateur (localStorage).

Jour 1 — Vendredi : combler le gap Java / Spring

Objectif : pouvoir lire du Java, discuter de Spring Boot comme d'un outil que tu comprends, et expliquer la philosophie (IoC, DI, REST).

🌅 Matin — Java fondamentaux (3h)
9h00 – 12h00
But : savoir lire un fichier Java moyen et reconnaître les idiomes.
☀ Après-midi — Spring & Spring Boot (3h)
14h00 – 17h00
But : expliquer ce que fait Spring, pourquoi Spring Boot existe, écrire un mini-REST.
🌙 Soir — Consolidation (1h30)
20h00 – 21h30

Jour 2 — Samedi : DB, threads, C++/C#

Objectif : rendre crédibles tes réponses sur SQL entreprise, multithreading, et survoler les langages secondaires.

🌅 Matin — SQL & bases de données (3h)
9h00 – 12h00
But : écrire des requêtes non-triviales et discuter performance/index.
☀ Après-midi — Multithreading (2h30)
14h00 – 16h30
But : expliquer les races, deadlocks, et citer un vrai outil dans chaque langage.
🌆 Fin d'aprem — Survol C++ & C# (1h30)
17h00 – 18h30
But : pouvoir dire "je sais lire, j'apprends vite" sans bluffer.
🌙 Soir — Flashcards (1h)
20h30 – 21h30

Jour 3 — Dimanche : OCR / ML / Computer Vision (ton terrain)

Objectif : parler pipeline de reconnaissance documentaire comme un expert — parce que tu as le background ML et CV.

🌅 Matin — Pipeline OCR classique + moderne (3h)
9h00 – 12h00
But : dessiner un pipeline complet sur tableau blanc.
☀ Après-midi — Classification, face recog, pont avec ta thèse (3h)
14h00 – 17h00
But : expliquer pourquoi ta recherche 3D médicale s'applique au document 2D.
🌙 Soir — Préparation pitch technique (1h30)
20h00 – 21h30

Jour 4 — Lundi : pitch, questions, logistique

Objectif : ne PAS apprendre de nouveau contenu technique. Polir, répéter, dormir.

🌅 Matin — Simulation à voix haute (2h)
9h00 – 11h00
But : ne pas bredouiller le jour J.
☀ Midi — Questions à poser (1h)
11h00 – 12h00
🌆 Après-midi — Logistique + repos (flex)
14h00 – 18h00
🌙 Soir — Détente (impératif)
20h00+

📚 Fiches techniques — résumés critiques

Clique sur une fiche pour la déplier. Tag rouge = critique (gap), orange = important, bleu = utile, vert = déjà maîtrisé.

Critique☕ Java — fondamentaux pour entrevue

Le strict minimum vital

Java est un langage à typage statique, orienté objet, qui tourne sur la JVM. Tout est classe (sauf primitives : int, long, double, boolean, etc.). Les classes compilent en bytecode (.class) exécuté par la JVM.

Concepts à maîtriser en 1 ligne chacun

  • Classe vs interface : une interface décrit un contrat (méthodes abstraites + defaults depuis Java 8), une classe l'implémente.
  • Abstract class : peut avoir état et méthodes concrètes, héritage simple uniquement.
  • Final : sur variable = constante ; sur méthode = non redéfinissable ; sur classe = non héritable.
  • Static : appartient à la classe, pas à l'instance.
  • Equals vs == : == compare les références, .equals() compare les valeurs (si bien redéfini).
  • hashCode + equals : contrat : si a.equals(b) alors a.hashCode() == b.hashCode(). Obligatoire pour HashMap/HashSet.
  • Exceptions checked vs unchecked : checked (ex: IOException) → le compilateur force le try/catch ou throws. unchecked (RuntimeException) → non forcées.

Collections — tableau décisionnel

BesoinChoixPourquoi
Liste indexée, peu d'insertionsArrayListAccès O(1), append amorti O(1)
Beaucoup d'insertions au milieuLinkedListInsert O(1) si position connue
Clés → valeurs, ordre non importantHashMapO(1) moyen
Clés triéesTreeMapO(log n), ordonné
Unicité sans ordreHashSetO(1)
File d'attente prioritairePriorityQueueHeap binaire

Streams (Java 8+) — exemple

List<String> names = people.stream()
    .filter(p -> p.age() > 18)
    .map(Person::name)
    .sorted()
    .collect(Collectors.toList());

Pièges que les interviewers adorent

  • String immutable : s + "x" dans une boucle = O(n²). Utiliser StringBuilder.
  • Autoboxing : Integer vs int, == sur Integer peut surprendre (cache [-128, 127]).
  • ConcurrentModificationException : modifier une collection pendant un for-each.
  • Null + Optional : Optional est là pour dire "peut être absent". Ne jamais retourner null quand Optional est approprié.
Critique🍃 Spring & Spring Boot

Le pitch en 3 phrases

Spring est un framework Java dont le cœur est l'IoC (Inversion of Control) : au lieu que ton code instancie ses dépendances, c'est le container Spring qui le fait pour toi (Dependency Injection).

Spring Boot ajoute une couche de convention over configuration : starters Maven/Gradle, auto-configuration, serveur Tomcat embarqué → un jar exécutable en 30 secondes.

Stéréotypes Spring

  • @Component — générique (bean détecté par classpath scanning).
  • @Service — couche logique métier.
  • @Repository — couche accès données (+ traduction d'exceptions DB).
  • @Controller — MVC web (retourne une vue).
  • @RestController — REST JSON (= @Controller + @ResponseBody).

Injection de dépendances — 3 styles

// ✓ Recommandé : par constructeur (immutable, testable)
@Service
public class DocumentService {
    private final OcrEngine engine;
    public DocumentService(OcrEngine engine) {
        this.engine = engine;
    }
}

// Moins recommandé : par field
@Service
public class DocumentService {
    @Autowired private OcrEngine engine;
}

Mini-REST Spring Boot (à pouvoir débiter)

@RestController
@RequestMapping("/api/documents")
public class DocumentController {

    private final DocumentService service;

    public DocumentController(DocumentService service) {
        this.service = service;
    }

    @GetMapping("/{id}")
    public ResponseEntity<Document> get(@PathVariable Long id) {
        return service.findById(id)
            .map(ResponseEntity::ok)
            .orElse(ResponseEntity.notFound().build());
    }

    @PostMapping
    public ResponseEntity<Document> create(@RequestBody @Valid DocumentDto dto) {
        Document saved = service.create(dto);
        return ResponseEntity.status(HttpStatus.CREATED).body(saved);
    }
}

Spring Data JPA — accès DB

@Entity
public class Document {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String title;
    // getters/setters
}

public interface DocumentRepository extends JpaRepository<Document, Long> {
    List<Document> findByTitleContainingIgnoreCase(String q);
}

Questions susceptibles en entrevue

  • "Quelle est la différence entre Spring et Spring Boot ?" → Spring = framework IoC/DI, Spring Boot = Spring + convention + auto-config + serveur embarqué.
  • "Pourquoi injection par constructeur ?" → immutabilité (final), testabilité (pas besoin de container pour les tests unitaires), détection précoce des dépendances circulaires.
  • "Qu'est-ce que @Transactional ?" → ouvre/commit/rollback une transaction autour d'une méthode. Fonctionne par proxy AOP — attention aux appels internes (this.method() ne déclenche pas le proxy).
Important🗄️ SQL — MSSQL & Oracle

ACID en une phrase chacun

  • Atomicité : une transaction est tout-ou-rien.
  • Cohérence : une transaction passe d'un état valide à un autre (contraintes respectées).
  • Isolation : les transactions concurrentes ne se voient pas (selon niveau).
  • Durabilité : une fois commit, les données résistent au crash.

Niveaux d'isolation (du plus faible au plus strict)

NiveauDirty readNon-repeatablePhantom
READ UNCOMMITTED
READ COMMITTED
REPEATABLE READ
SERIALIZABLE

Index — quand et pourquoi

  • Accélère SELECT/JOIN/WHERE sur la colonne indexée.
  • Ralentit INSERT/UPDATE/DELETE (index à maintenir).
  • Clustered (MSSQL) : les données elles-mêmes sont triées selon la clé (1 seul par table).
  • Non-clustered : index séparé pointant vers les lignes.
  • Index couvrant : contient toutes les colonnes du SELECT → pas besoin d'aller chercher la ligne.

MSSQL vs Oracle — différences mémorables

ConceptMSSQLOracle
Limiter résultatsSELECT TOP 10 * FROM tSELECT * FROM t WHERE ROWNUM <= 10 ou FETCH FIRST 10 ROWS
Auto-incrementIDENTITY(1,1)Séquence + trigger ou GENERATED AS IDENTITY (12c+)
Long texteVARCHAR(MAX), NVARCHAR(MAX)CLOB, NCLOB
Date couranteGETDATE()SYSDATE, CURRENT_TIMESTAMP
Concat+ ou CONCAT()|| ou CONCAT()
Pas de ligneNULL résultat SELECTIdem + exception NO_DATA_FOUND dans PL/SQL

Fonctions fenêtre (modernes, souvent demandées)

SELECT
    order_id,
    customer_id,
    total,
    ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY total DESC) AS rn
FROM orders;
-- rn = 1 pour l'ordre le plus gros de chaque client

Procédure stockée — concept IMDS-pertinent

Dans un produit OCR en prod, tu peux avoir besoin d'un batch : "traite tous les docs reçus aujourd'hui". Une procédure stockée encapsule cette logique côté DB → moins de round-trips réseau, logique réutilisable, granularité de droits.

-- MSSQL
CREATE PROCEDURE dbo.process_pending_docs
AS
BEGIN
    UPDATE documents SET status = 'processing'
    WHERE status = 'pending';
    -- ...
END;
Important🧵 Multithreading — pièges & patterns

Vocabulaire à maîtriser

  • Race condition : deux threads accèdent à une ressource partagée, résultat dépend de l'ordre.
  • Deadlock : A attend B, B attend A → plus rien ne bouge. Exemple classique : chacun locke une ressource différente dans l'ordre inverse.
  • Livelock : les threads réagissent mais n'avancent pas (comme deux personnes dans un couloir qui se décalent au même moment).
  • Starvation : un thread n'obtient jamais la ressource.
  • CPU-bound : limité par le calcul. Parallélise sur N cœurs.
  • I/O-bound : limité par les attentes (disque, réseau). Async/coroutines / thread pool.

Java — ExecutorService

ExecutorService pool = Executors.newFixedThreadPool(8);
List<Future<OcrResult>> futures = pages.stream()
    .map(p -> pool.submit(() -> ocrEngine.process(p)))
    .collect(Collectors.toList());

for (Future<OcrResult> f : futures) {
    results.add(f.get()); // bloque jusqu'à fin
}
pool.shutdown();

Java — synchronized / volatile / AtomicInteger

// synchronized : verrou sur un objet
public synchronized void increment() { counter++; }

// volatile : garantit visibilité entre threads (pas atomicité)
private volatile boolean running = true;

// Atomic : opérations atomiques sans lock explicite
AtomicInteger counter = new AtomicInteger(0);
counter.incrementAndGet();

Python — le GIL expliqué simplement

Le Global Interpreter Lock empêche 2 threads Python d'exécuter du bytecode en même temps dans le même process. Conséquence :

  • CPU-bound + threading = pas d'accélération. Utiliser multiprocessing.
  • I/O-bound + threading = ça accélère (GIL relâché pendant I/O).
  • asyncio : mono-thread coopératif, idéal pour I/O-bound massif.
from concurrent.futures import ProcessPoolExecutor
with ProcessPoolExecutor(max_workers=8) as ex:
    results = list(ex.map(ocr_process, pages))

C++ — std::thread basique

#include <thread>
#include <mutex>

std::mutex m;
int counter = 0;

void worker() {
    std::lock_guard<std::mutex> lock(m);
    counter++;
}

int main() {
    std::thread t1(worker), t2(worker);
    t1.join(); t2.join();
}

Pattern OCR parallèle (pertinent pour IMDS)

Un document de 100 pages = 100 tâches indépendantes. Le bon pattern : une queue de pages, un pool de workers, collecte ordonnée des résultats. Embarrassingly parallel → speedup quasi-linéaire jusqu'à saturation I/O disque ou mémoire GPU.

Important📄 OCR / ICR / IWR — pipeline classique

Nuances des trois termes (tu vas être testé là-dessus)

  • OCR (Optical Character Recognition) : texte imprimé, machine-lisible.
  • ICR (Intelligent Character Recognition) : caractères manuscrits, lettre par lettre (formulaires à remplir case par case).
  • IWR (Intelligent Word Recognition) : mots manuscrits entiers, cursif — niveau supérieur car il faut aussi segmenter.

Pipeline classique

  1. Acquisition : scanner, photo, PDF. Résolution conseillée : 300 DPI pour texte imprimé.
  2. Prétraitement :
    • Conversion niveaux de gris.
    • Binarisation (seuillage Otsu, adaptatif Sauvola).
    • Debruitage (médian, bilatéral).
    • Correction de perspective (Hough lines → homographie).
    • Deskew (rotation pour redresser).
  3. Segmentation/layout analysis :
    • Détection de zones (texte vs image vs tableau).
    • Segmentation en lignes, mots, caractères (classique) ou bounding boxes (deep).
    • Méthodes : connected components, XY-cut, MSER, CTPN, EAST, DBNet.
  4. Reconnaissance :
    • Classique : features + SVM / kNN (obsolète).
    • Moderne : CNN par caractère, CRNN (CNN + BiLSTM + CTC) par ligne.
    • Engine phare open source : Tesseract 4/5 (LSTM).
  5. Post-traitement :
    • Correction via dictionnaire, n-grams de langue.
    • Extraction d'entités (dates, montants, numéros) : regex ou NER.
    • Validation métier (somme d'un total, checksum IBAN…).

CTC loss — le truc à savoir expliquer

Connectionist Temporal Classification permet d'entraîner un modèle séquence-à-séquence sans alignement manuel caractère-par-caractère. Le modèle peut prédire un "blank" token et des répétitions, la CTC marginalise sur tous les alignements possibles. Indispensable pour OCR texte manuscrit où on ne sait pas où chaque caractère commence.

Métriques OCR

  • CER (Character Error Rate) = Levenshtein(pred, gt) / len(gt). Ex : 2 % signifie 2 erreurs par 100 caractères.
  • WER (Word Error Rate) : idem au niveau mot.
  • F1 sur entités extraites (dates, montants) — métrique métier.
Important🤖 OCR moderne — Transformers documentaires

Évolution rapide du domaine (2019-2025)

Depuis 2020, le paradigme bouge du pipeline modulaire (detect + recognize + layout) vers des modèles end-to-end multi-modaux qui traitent image + texte + layout simultanément.

Modèles à citer pour montrer ta veille

ModèleAnnéeConcept clé
LayoutLM / LayoutLMv3 (Microsoft)2019/2022BERT enrichi avec embeddings de position 2D (bbox) et image.
TrOCR (Microsoft)2021Vision Transformer encoder + RoBERTa decoder pour texte.
Donut (NAVER)2022OCR-free : image → JSON directement, pas de moteur OCR séparé.
Pix2Struct (Google)2022Image → séquence HTML/structure.
Nougat (Meta)2023Papers scientifiques → Markdown + maths LaTeX.
Multimodal LLMs (GPT-4V, Claude Vision)2023+Compréhension documentaire zero-shot, très forts sur docs structurés.

Tradeoffs OCR classique vs end-to-end

CritèrePipeline modulaireEnd-to-end (Donut, LayoutLM)
ExplicabilitéHaute (chaque étape inspectable)Basse (boîte noire)
LatenceMoyenneHaute (GPU requis)
Précision sur formulaires structurésMoyenneSouvent supérieure
Coût entraînementPar composantTrès lourd, besoin de données annotées spécifiques
Déploiement edgeFaisableDifficile (gros modèles)

Ce que tu peux dire en entrevue (phrase modèle)

"Le domaine a basculé de pipelines modulaires Tesseract + post-traitement vers des approches end-to-end type LayoutLM ou Donut, où le modèle ingère image + tokens + positions. Mais en production bancaire/assurance, on reste souvent sur des architectures hybrides : OCR classique pour la robustesse et l'explicabilité, modèles Transformer pour l'extraction d'entités sur formulaires complexes. Le bon choix dépend du volume de données annotées et des contraintes de latence."

Maîtrisé🖼️ Traitement d'image & CV — rappels

Ton terrain — à réutiliser dans le pitch

  • Convolutions, pooling, architectures (ResNet, U-Net, EfficientNet).
  • Data augmentation : rotation, flip, crop, color jitter, mixup, cutout.
  • Transfer learning : fine-tune un backbone pré-entraîné sur ImageNet, coût réduit.
  • Segmentation vs détection vs classification : bien distinguer les 3.
  • Pour ton doc IMDS : segmentation de zones de document → U-Net ou Mask R-CNN pertinents.

Pont thèse médicale → OCR documentaire

Les deux sont des problèmes de compréhension spatiale d'images structurées. Un CT-scan 3D a un voxel comme un scan 2D a un pixel. Les CNN/U-Net que tu as utilisés pour segmenter des organes sont les mêmes familles que ceux utilisés pour segmenter des zones de document. Le vocabulaire change, pas la machinerie.

Reconnaissance faciale — survol

  • MTCNN : Multi-Task CNN pour détecter visages + landmarks (yeux, nez, bouche).
  • FaceNet : triplet loss, embeddings 128-d, similarité cosinus.
  • ArcFace : additive angular margin loss → embeddings plus discriminants.
  • Pipeline : détection → alignement (affine sur landmarks) → embedding → matching dans DB (FAISS pour 1:N rapide).
  • Éthique à mentionner : biais démographiques documentés (NIST FRVT), consentement, RGPD.
Important⚙️ C++ — survol pour ne pas être largué

À savoir en 10 points

  1. Pointeurs vs références : un pointeur peut être nullptr et réaffecté, une référence jamais.
  2. new / delete : allocation dynamique manuelle. À éviter en moderne, préférer RAII.
  3. RAII (Resource Acquisition Is Initialization) : les ressources sont libérées dans le destructeur → pas de fuites.
  4. Smart pointers : std::unique_ptr (propriété unique), std::shared_ptr (comptage de références), std::weak_ptr (casse les cycles).
  5. Const correctness : const sur un paramètre, un return type, une méthode membre.
  6. Rule of 3/5/0 : si tu définis un destructeur, tu dois probablement définir copy constructor et copy assignment. Règle de 5 ajoute move.
  7. Move semantics (C++11) : std::move transfère la propriété sans copie. Grosse perf pour vecteurs, strings.
  8. Templates : génériques compilés, équivalent de Java generics mais plus puissants.
  9. STL : std::vector, std::map, std::unordered_map, std::string, algorithms std::sort, std::find.
  10. Versions : C++11 (move, auto, lambda), C++14, C++17 (std::optional), C++20 (concepts, ranges).

Exemple propre C++ moderne

#include <memory>
#include <vector>
#include <string>

class OcrEngine {
public:
    OcrEngine(std::string model_path) : model_path_(std::move(model_path)) {}
    std::string recognize(const std::vector<uint8_t>& image_bytes) const;
private:
    std::string model_path_;
};

auto engine = std::make_unique<OcrEngine>("model.bin");
auto text = engine->recognize(bytes);

Position honnête en entrevue

"Je lis du C++ moderne sans souci, j'ai fait de la perf numérique pendant ma thèse. Je n'ai pas mis en prod de gros projet C++, donc sur les détails ABI/build systems type CMake, je serais en apprentissage. Mais la sémantique du langage (RAII, move, templates) m'est familière."

Utile🎯 C# / .NET — survol

C# pour un dev Java

Si tu connais Java, C# est à 80 % familier. Différences notables :

  • Propriétés : public string Name { get; set; } — plus de getters/setters manuels.
  • LINQ : list.Where(x => x.Age > 18).Select(x => x.Name).ToList() — équivalent streams Java mais en méthodes extension.
  • async/await : natif, Task<T> comme CompletableFuture<T>.
  • var : inférence de type locale.
  • Délégués & événements : pointeurs de fonction typés + pattern pub/sub intégré.
  • record (C# 9+) : classes immuables en 1 ligne, comme Java 14+.
  • using : équivalent try-with-resources Java.

Écosystème

  • .NET (successeur de .NET Core) : cross-platform, open source. .NET Framework : legacy Windows-only.
  • Visual Studio : IDE historique Microsoft, très utilisé en C#/C++.
  • NuGet : équivalent Maven/npm.
  • ASP.NET Core : équivalent Spring Boot pour web.
  • Entity Framework Core : ORM équivalent JPA/Hibernate.
Maîtrisé⚛️ React — rappels rapides

Si ils posent une question, voici les points à cocher

  • JSX : sucre syntaxique pour React.createElement.
  • Hooks : useState, useEffect, useMemo, useCallback, useContext, useRef.
  • Règles des hooks : toujours au top niveau, jamais conditionnellement.
  • Reconciliation et Virtual DOM : pourquoi React est rapide.
  • Keys dans les listes : stabilité du rendu.
  • State management : Context, Redux, Zustand, Jotai — savoir quand quoi.
  • Server Components (Next.js 13+) : rendu côté serveur, pas d'hydratation.

Piège classique : useEffect et dépendances

// ✗ Bug : infinite loop
useEffect(() => {
    setUser({ ...user, name: 'New' });
}, [user]);

// ✓ Bon : pas de dépendance, effet monté une fois
useEffect(() => {
    fetchUser().then(setUser);
}, []);

JSF (mentionné dans le JD)

JavaServer Faces, framework web Java ancienne génération (composants côté serveur). Très différent de React. Si ils te demandent, dis honnêtement "je ne connais pas, mais j'ai compris que c'est un framework Java de composants UI côté serveur, avec un cycle de rendu similaire dans l'esprit à React/Angular mais exécuté sur JVM".

Utile🧪 Tests & QA — atout à valoriser

Ton levier

Tu as une formation QA publique sur ton site (/qa-formation). Cite-la. C'est un différenciateur.

Pyramide des tests

  • Unitaires (beaucoup, rapides) : une fonction isolée. JUnit + Mockito (Java), pytest (Python), xUnit/NUnit (C#).
  • Intégration (moyen) : plusieurs composants + DB réelle ou testcontainers.
  • End-to-end (peu, lents) : Selenium, Playwright, Cypress.

Patterns à connaître

  • AAA : Arrange / Act / Assert.
  • Mocks vs stubs vs fakes : mock vérifie les interactions, stub retourne une valeur pré-programmée, fake est une vraie implémentation simplifiée.
  • TDD : Red → Green → Refactor.
  • BDD : Given/When/Then (Cucumber, Gherkin).
  • Code coverage ≠ qualité. 80 % de couverture peut rater des bugs. Mutation testing (PIT) plus révélateur.

Exemple JUnit + Mockito

@ExtendWith(MockitoExtension.class)
class DocumentServiceTest {
    @Mock OcrEngine engine;
    @InjectMocks DocumentService service;

    @Test
    void shouldReturnRecognizedText() {
        when(engine.process(any())).thenReturn("hello");
        String result = service.ocr(new byte[]{1,2,3});
        assertEquals("hello", result);
        verify(engine, times(1)).process(any());
    }
}

Tests en contexte OCR

Défi spécifique : comment teste-t-on un modèle ML non-déterministe ? Réponses à avoir :

  • Tests de régression sur un dataset de validation figé avec seuil de CER acceptable.
  • Tests unitaires sur le pré/post-processing (déterministes).
  • Tests de charge (perf, mémoire).
  • Tests d'intégration sur docs "réels" du client.
  • Monitoring en prod (distribution des scores de confiance, drift de données).
Utile🏗️ Architecture logicielle — vocabulaire

Concepts à citer si la conversation dérive

  • SOLID : Single resp., Open/closed, Liskov, Interface segregation, Dependency inversion.
  • Clean Architecture / Hexagonal : domaine au centre, adapters à l'extérieur.
  • Monolithe vs microservices : IMDS est probablement sur un monolithe modulaire — ça reste légitime.
  • REST vs GraphQL vs gRPC : trade-offs (simplicité, flexibilité, perf).
  • Webservices SOAP (dans le JD !) : XML, WSDL, encore très présent dans bancaire/assurance. Survol suffit.
  • Message queues : RabbitMQ, Kafka, ActiveMQ — utile pour batch OCR asynchrone.
  • Patterns : Repository, Service Layer, Factory, Strategy, Observer, Circuit Breaker.

Architecture probable d'IMDS (spéculation raisonnée)

  • Backend Java/Spring (+ legacy C++ pour le cœur OCR performant).
  • Frontend React moderne + legacy JSF pour l'admin.
  • DB MSSQL ou Oracle (clients bancaires = Oracle souvent).
  • Intégration SOAP pour clients corporate.
  • Batch + streaming pour gros volumes de docs.

Tu peux arriver en disant "je suppose que votre archi ressemble à X, dites-moi si je me trompe" — ça montre que tu as réfléchi.

Utile🔧 Outils & écosystème

IDE

  • IntelliJ IDEA : référence Java/Kotlin. Raccourcis : Ctrl+N (classe), Ctrl+Shift+N (fichier), Shift+Shift (tout), Ctrl+Alt+L (format), F6 (move).
  • Visual Studio : C#/C++. F5 (run debug), F10/F11 (step over/into).
  • VS Code : léger, multi-langage.

Build tools

  • Java : Maven (XML, déclaratif) et Gradle (Groovy/Kotlin DSL).
  • C++ : CMake (quasi standard), Ninja, Make.
  • .NET : MSBuild, dotnet build.
  • Python : pip, poetry, uv, pyproject.toml.
  • JS : npm/pnpm/yarn, bundlers Webpack/Vite/esbuild.

CI/CD

  • Jenkins, GitLab CI, GitHub Actions, Azure DevOps, TeamCity.
  • Étapes typiques : checkout → build → test unit → test integ → scan sécurité → package → deploy staging.

Git — les trucs à savoir

  • Rebase vs merge (préférences d'équipe).
  • Stash, cherry-pick, reflog (récupérer un commit perdu).
  • Git flow vs GitHub flow vs trunk-based.
  • Hooks pre-commit (format, lint) — lien avec ta formation QA.
Maîtrisé🧠 ML basics — rappels au cas où

Vocabulaire incontournable

  • Train / val / test : ne jamais toucher le test avant la fin.
  • Overfitting : modèle qui mémorise le train, échoue en val. Régularisation, dropout, early stopping, plus de data.
  • Bias-variance tradeoff : underfit (haut biais) vs overfit (haute variance).
  • Métriques classification : accuracy, precision, recall, F1, AUC-ROC. Matrice de confusion.
  • Précision vs rappel : en OCR, si tu préfères rater un caractère que d'en inventer, tu optimises la précision.
  • Loss functions : cross-entropy, MSE, L1, Dice (segmentation), triplet (embeddings), CTC (séquences).
  • Optimizers : SGD, Adam, AdamW. Learning rate schedule (cosine, warmup).
  • Batch norm / Layer norm / Dropout : régularisation.

Transformers en 2 minutes

  • Attention = softmax(QK^T / √d) V.
  • Self-attention : Q, K, V viennent de la même séquence.
  • Multi-head : plusieurs attentions parallèles capturant différents aspects.
  • Position encoding : ajoute l'info d'ordre (sinusoïdal ou appris).
  • Encoder-only (BERT), decoder-only (GPT), encoder-decoder (T5, TrOCR).

LLMs en production (si ça dérive)

  • RAG : retrieval-augmented generation, alternative au fine-tune.
  • Vector DB : Pinecone, Weaviate, Qdrant, pgvector.
  • Chunking, embeddings, re-ranking.
  • Prompt engineering : few-shot, chain-of-thought, structured output (JSON mode).
  • Limites : hallucinations, coût, latence, privacy.
Important💬 Soft skills & communication

Framework STAR pour les anecdotes

  • Situation : contexte, en 2 phrases.
  • Task : ce qu'il fallait faire.
  • Action : ce que toi tu as fait (pas "l'équipe").
  • Result : résultat chiffré si possible.

Gérer l'inconnu

  • Ne pas bluffer. Dire "je ne connais pas X, mais voici comment je l'aborderais" vaut mieux qu'une réponse fausse.
  • Pensée à voix haute : les interviewers aiment voir ton raisonnement.
  • Poser des questions de clarification avant de répondre à un exercice technique.

Présentiel — signaux non-verbaux

  • Contact visuel, sourire pas forcé, poignée de main ferme (sans écraser).
  • Pas de téléphone sur la table.
  • Prendre des notes sur le carnet = engagement perçu.
  • "Je ne sais pas" dit calmement > 5 min d'invention.

Ton profil doctoral — à encadrer

Risque perçu : "doctorant = chercheur déconnecté du terrain". À contrer explicitement :

  • Mentionner tes SaaS freelance (tu as livré des produits en prod).
  • Parler deadlines, utilisateurs, contraintes.
  • Si tu as un GitHub actif, le mentionner.
  • Dire "j'aime autant la rigueur scientifique que l'itération rapide produit".

🎤 Questions comportementales — flashcards FR/EN

Les classiques. Clique sur une question pour révéler la réponse modèle. Entraîne-toi d'abord à répondre à voix haute, ensuite seulement révèle.

Parlez-moi de vous en 2 minutes. / Tell me about yourself.
Squelette : parcours académique (doctorat, domaine ML/imagerie) → expérience pratique (SaaS freelance, React/Python) → pourquoi IMDS (pont naturel entre ta recherche CV et leur produit OCR). Commence par un hook personnel, termine par une phrase qui invite à la question suivante. EN: Start with academic background (PhD in ML/imaging) → hands-on product work (freelance SaaS, React/Python) → why IMDS (natural bridge between your CV research and their OCR product).
Pourquoi IMDS ? / Why IMDS?
3 angles : produit (OCR/ICR au croisement de ton domaine), taille (R&D avec impact visible, pas noyé dans une boîte de 10k), secteur (bancaire/assurance/gouv = problèmes techniques riches). Éviter "parce que vous embauchez". Spécifier un élément du JD ("le pilotage matériel de numérisation m'intrigue parce que…"). EN: Three angles — product fit (OCR/ICR sits at the intersection of your PhD work), company size (R&D with visible impact), industry (banking/insurance/gov means rich technical challenges).
Votre plus grand défi technique ? / Biggest technical challenge?
Format STAR. Choisis un défi de thèse ou freelance où il y avait un enjeu réel et où tu peux chiffrer. Ex : "Mon pipeline de segmentation 3D tournait en 4h par volume, j'ai refactoré en patch-based inference parallèle GPU, ramené à 15 min, déployé en clinique". EN: Use STAR. Pick a challenge with real stakes and measurable outcome. Frame it around reducing latency, improving accuracy, or unblocking a team.
Une situation de travail en équipe ? / Team collaboration experience?
Attention, ta zone fragile (profil solo doctoral). Valorise : co-écriture d'articles, encadrement de stagiaires, collaboration avec cliniciens (si c'est ton cas), freelance avec clients. Insiste sur la communication non-technique (traduire du jargon ML à un médecin / un client). EN: Highlight paper co-authoring, intern supervision, clinician collaboration, client work. Emphasize translating technical concepts to non-technical stakeholders.
Votre plus gros échec ? / Tell me about a failure.
Règles : vrai échec (pas "je suis trop perfectionniste"), responsabilité assumée, leçon apprise et appliquée ensuite. Ex : un projet où tu as sur-ingéniéré une solution, ou raté une deadline parce que tu as mal estimé. Finis par ce que tu fais différemment maintenant. EN: Must be a real failure, with owned responsibility, and a concrete lesson applied afterwards. Don't use the "I'm a perfectionist" cliché.
Votre point faible ? / What's your weakness?
Version honnête pour ce poste : "Je viens d'un background Python/ML plus que Java enterprise. J'ai passé les 4 derniers jours à rafraîchir Spring et SQL entreprise pour arriver outillé. Je sais que je serai en courbe d'apprentissage sur votre stack legacy, mais mon rythme d'apprentissage est un atout prouvé — mon doctorat en témoigne." EN: "My background leans more toward Python/ML than enterprise Java. I've spent the last 4 days refreshing Spring and enterprise SQL. I know there'll be a learning curve on your legacy stack, but fast learning is a proven strength — my PhD is evidence."
Prétentions salariales ? / Salary expectations?
Ne jamais donner un chiffre unique. Le JD dit "à partir de 70k". Donne une fourchette qui monte : "Je regarde la fourchette 75-95k selon le package complet, mais je suis flexible en fonction de la nature du poste, des perspectives et des avantages." Renvoie le sujet à une discussion ultérieure si c'est un premier entretien. EN: Never give a single number. Give a range (75-95k CAD) and frame it as total package dependent. Defer to later rounds if this is a first interview.
Où vous voyez-vous dans 5 ans ? / Where in 5 years?
Éviter "à votre place" (cringe) et "je ne sais pas" (flou). Formule : contribuer techniquement de plus en plus (tech lead ou principal eng), rester proche de la R&D appliquée, développer un domaine d'expertise spécifique (ML documentaire). Si tu veux management, dis-le, mais c'est souvent mieux reçu d'affirmer un parcours IC. EN: Focus on technical depth (tech lead / principal engineer), staying close to applied R&D, developing expertise in document ML. Avoid clichés.
Pourquoi quitter votre poste actuel ? / Why leave current position?
Si tu es freelance/doctorant : "Je cherche à rejoindre une équipe pour contribuer sur un produit avec des utilisateurs réels sur la durée, là où le freelance m'a donné des rotations courtes et le doctorat m'a donné de la profondeur technique." Ne jamais critiquer l'ex-employeur. EN: Frame it as wanting to join a team, contribute to a product with real users, build long-term impact. Never badmouth a previous employer.
Vos attentes managériales ? / Expectations from a manager?
Autonomie technique + feedback régulier + objectifs clairs + soutien quand tu bloques. "J'ai besoin qu'on me donne un cap et qu'on me laisse choisir la route, tout en étant disponible pour les points de validation." EN: Technical autonomy + regular feedback + clear goals + support when stuck. "Tell me the destination, let me choose the route, be available for checkpoints."

🛠️ Questions techniques probables — flashcards

Révise en répondant à voix haute. Cache la réponse, reformule-la, compare. C'est le mode le plus efficace en mémorisation active.

Quelle est la différence entre une interface et une classe abstraite en Java ?
Une interface décrit un contrat (méthodes, defaults depuis Java 8), on peut en implémenter plusieurs. Une classe abstraite peut avoir un état et des méthodes concrètes, héritage simple uniquement. Je choisis interface pour décrire une capacité, classe abstraite quand il y a du code commun à partager.
Qu'est-ce que l'inversion de contrôle ?
Le framework (ex: Spring) instancie les objets et injecte les dépendances à ta place. Ton code déclare ce dont il a besoin (@Autowired, constructor injection) et le container s'occupe du câblage. Avantage : testabilité, découplage, configuration centralisée.
Différence entre @Controller et @RestController ?
@RestController = @Controller + @ResponseBody. Le premier sert à faire du MVC classique (retour de vue), le second retourne directement le corps de réponse (JSON ou autre) sérialisé par Jackson.
Qu'est-ce qu'une race condition, comment l'éviter ?
Deux threads accèdent à une ressource partagée sans synchronisation, le résultat dépend de l'ordre d'exécution. On l'évite avec des verrous (synchronized, mutex), des structures atomic (AtomicInteger), des collections concurrent (ConcurrentHashMap), ou en éliminant l'état partagé (immutabilité).
Qu'est-ce qu'un deadlock, comment le prévenir ?
Deux threads se bloquent mutuellement parce qu'ils attendent chacun une ressource détenue par l'autre. Prévention : toujours acquérir les locks dans le même ordre, utiliser des timeouts, préférer tryLock, limiter le nombre de locks, utiliser des primitives haut niveau (ExecutorService).
ACID — expliquez chaque lettre.
Atomicité : tout ou rien. Cohérence : contraintes respectées avant et après. Isolation : transactions concurrentes ne se parasitent pas. Durabilité : une fois commit, c'est persisté au crash près.
Quand utiliser un INNER JOIN vs un LEFT JOIN ?
INNER : je veux seulement les lignes qui matchent des deux côtés. LEFT : je veux toutes les lignes de gauche, même si aucune correspondance à droite (les colonnes droite seront NULL). Utile pour "tous les clients même ceux sans commande".
Pourquoi ajouter un index ?
Accélérer les SELECT filtrés ou joints sur la colonne. Coût : ralentit INSERT/UPDATE/DELETE (index à maintenir) et prend du disque. Je n'indexe pas aveuglément, je regarde le plan d'exécution (EXPLAIN) et je cible les requêtes lentes récurrentes.
Comment fonctionne le GIL en Python ?
Un verrou global qui empêche deux threads Python d'exécuter du bytecode simultanément dans le même process. Résultat : threading n'accélère pas le CPU-bound, mais marche pour I/O-bound. Pour vrai parallélisme CPU, j'utilise multiprocessing ou C extensions qui relâchent le GIL.
RAII en C++ ?
Resource Acquisition Is Initialization. Une ressource (mémoire, fichier, verrou) est encapsulée dans un objet dont le destructeur libère automatiquement la ressource quand il sort du scope. Plus besoin de libérer manuellement → pas de fuites même avec exceptions. Les smart pointers en sont l'application canonique.
Expliquez le pipeline OCR.
Acquisition → prétraitement (binarisation, deskew, denoise) → détection de zones/lignes (MSER, EAST, DBNet) → reconnaissance caractères (CRNN + CTC, ou Tesseract LSTM) → post-traitement (dictionnaire, regex pour entités). En moderne on consolide tout ça avec des end-to-end type LayoutLM ou Donut.
Qu'est-ce que CTC loss ?
Connectionist Temporal Classification. Permet d'entraîner un modèle séquence-à-séquence sans alignement explicite entre l'entrée (pixels/features) et la sortie (caractères). Le modèle peut prédire un blank token et des répétitions, CTC marginalise sur tous les alignements possibles. Indispensable en OCR manuscrit où on n'a pas d'alignement par caractère.
CER vs WER ?
CER = Character Error Rate, distance de Levenshtein normalisée au niveau caractère. WER pareil mais au niveau mot. CER plus granulaire mais moins aligné sur la perception utilisateur. Pour un client final, WER ou une métrique business (F1 sur entités extraites) est souvent plus pertinente.
Différence entre classification et détection ?
Classification : image → 1 label (chat/chien). Détection : image → liste de bounding boxes + labels. Segmentation : image → masque pixel-à-pixel. En doc : layout analysis = détection, catégorisation de document = classification, extraction de zone de signature = segmentation.
Comment testeriez-vous un modèle OCR en production ?
Plusieurs couches : (1) tests unitaires sur pré/post-processing déterministe, (2) tests de régression sur dataset figé avec seuil de CER, (3) monitoring en prod sur la distribution des scores de confiance et détection de drift de données, (4) A/B tests si comparaison de deux modèles, (5) feedback utilisateur labellisé réinjecté pour re-training.
Qu'est-ce que le transfer learning ?
Utiliser les poids d'un modèle pré-entraîné sur une grosse tâche (ex: ImageNet) comme point de départ pour une tâche cible plus petite. On freeze les premières couches (features bas-niveau génériques) et on fine-tune les dernières. Gain énorme en temps de training et en data requise.
Comment structureriez-vous un service Java Spring Boot pour traiter 1M de documents par jour ?
Ingestion via queue (Kafka/RabbitMQ), workers stateless horizontalement scalables (Spring Boot + ExecutorService ou @Async), stockage blob (S3/Azure Blob) pour les images, DB relationnelle pour le metadata/status, idempotence via ID unique, retry avec backoff exponentiel, dead-letter queue pour les docs qui échouent, monitoring Prometheus + Grafana, CI/CD avec tests d'intégration sur dataset représentatif.
Vous devez débugger un service en prod qui timeout. Par où commencez-vous ?
1) Logs récents — erreurs, exceptions. 2) Métriques — CPU, mémoire, threads, temps de réponse par endpoint. 3) DB — requêtes lentes, locks, connexions saturées. 4) Dépendances externes — call downstream qui traîne ? 5) Déploiement récent ? Rollback si fenêtre courte. 6) Reproduire en staging. Approche systémique, pas de "c'est sûrement X".

12 questions à poser à IMDS

Choisis 3-4 en fonction du déroulé de l'entrevue. Montre que tu as réfléchi au-delà de la fiche de poste.

Sur le poste

  • Quelle est la répartition typique d'une semaine entre maintenance de code legacy, développement de nouvelles features, et R&D exploratoire ?
  • Quel serait mon premier ticket ou projet dans les 3 premiers mois ?
  • À quoi ressemble une revue de code chez IMDS ? Synchrone, async, outils ?
  • Y a-t-il un mentor ou un binôme pour l'onboarding ?

Sur l'équipe

  • Quelle est la taille et la composition de l'équipe R&D ? Ratio devs / chercheurs / QA ?
  • Quelle méthodologie de développement utilisez-vous (Scrum, Kanban, autre) ?
  • Comment l'équipe décide-t-elle d'adopter une nouvelle technologie ? Y a-t-il un processus formel ?

Sur la technique

  • Où êtes-vous sur la transition OCR classique vers des architectures Transformer type LayoutLM ou Donut ? Hybride, pur legacy, migration en cours ?
  • Le traitement d'image critique est-il en C++ ou en Java ? Quelle part en Python pour le prototypage ML ?
  • Quelle couverture de tests automatisés avez-vous aujourd'hui ? Quels sont vos principaux défis QA ?

Sur l'avenir

  • Quels sont les prochains gros défis techniques pour IMDS ? Scale, nouveaux secteurs, nouveaux types de documents ?
  • Comment vous positionnez-vous face à l'émergence des LLMs multimodaux (GPT-4V, Claude Vision) sur des tâches de compréhension documentaire ?

🎯 Pitch "Parlez-moi de vous" — 2 minutes

Trame. Adapte les chiffres et les noms à ton parcours. Chronomètre-toi à voix haute.

Hook (15 s)
"Bonjour, je suis Nicolas Loiseau, docteur en [domaine exact], avec un parcours qui combine recherche en vision par ordinateur et développement produit en freelance. Ce qui m'intéresse chez IMDS, c'est précisément ce pont — prendre de la recherche solide en ML documentaire et la déployer dans des produits utilisés par des clients réels."
Parcours académique (30 s)
"Ma thèse portait sur [sujet], plus précisément [1 phrase concrète + impact]. J'y ai développé des pipelines complets : prétraitement d'images, modèles de deep learning (CNN, U-Net, Transformers), évaluation rigoureuse avec des métriques cliniques/métier. C'est exactement la même machinerie que celle utilisée en OCR et classification documentaire — le vocabulaire change, pas la démarche."
Côté produit / freelance (30 s)
"En parallèle de la thèse, j'ai construit plusieurs SaaS freelance en Python backend + React frontend. Ça m'a forcé à livrer du code en production, gérer des utilisateurs, des bugs en prod, des priorités contradictoires. Mon portfolio est visible sur loiseaunicolas.fr. C'est ce qui me distingue d'un profil purement académique."
Pourquoi IMDS (30 s)
"Quand je lis votre fiche de poste, je vois deux choses qui collent : d'abord, le cœur métier — OCR, ICR, classification documentaire, reconnaissance faciale — c'est une application directe de ce que j'ai fait en imagerie 3D. Ensuite, la diversité technique — Java, C++, Python, React — me convient : j'aime les environnements où on touche à plusieurs stacks plutôt qu'être enfermé dans une techno."
Honnêteté calibrée (15 s)
"Je suis transparent : je n'ai pas d'expérience enterprise Java/Spring profonde. J'ai passé les derniers jours à la rafraîchir pour arriver outillé. Ma force, ce n'est pas d'avoir toute la stack maîtrisée jour 1, c'est ma capacité à monter en compétence rapidement — mon doctorat en est la meilleure preuve."
Fermeture (10 s)
"Voilà pour le tour d'horizon. Je suis curieux d'en apprendre plus sur votre architecture produit et sur ce que serait concrètement mon rôle les premiers mois."
Tip critique : le pitch sert à donner des "poignées" à l'interviewer. Chaque section plante un drapeau qu'il pourra creuser. Ne dis pas tout — laisse des accroches ("plusieurs SaaS freelance", "modèles de deep learning") pour inviter aux questions.

🚀 Logistique jour J — checklist

Les détails qui font la différence.

📦 À apporter
🗓️ La veille
⏰ Le matin
🎯 Pendant
📬 Après

📋 Missions du poste — comment tu dois te positionner

Les tâches listées dans le JD. Pour chacune, ce qui est attendu, comment en parler, et les ressources pour te rafraîchir.

Important📝 Analyse & rédaction de spécifications

Ce qu'on te demandera de produire

  • Spécifications fonctionnelles : ce que le logiciel doit faire, côté métier. Public : PO, clients, QA.
  • Spécifications techniques : comment le faire — architecture, contrats d'API, schémas DB, algos. Public : devs.
  • User stories : "En tant que [rôle], je veux [action] afin de [bénéfice]." + critères d'acceptation.
  • Diagrammes UML : classe, séquence, cas d'usage, états. Ils ne demandent pas de les faire parfaits, mais de comprendre.

Structure type d'une spec technique

  1. Contexte : problème, qui est impacté, lien avec les specs fonctionnelles.
  2. Exigences : fonctionnelles (ce que ça fait) + non-fonctionnelles (perf, sécurité, scalabilité, accessibilité).
  3. Architecture : diagramme composants, flux de données.
  4. Contrats : APIs (REST endpoints, payloads), schémas DB, messages (queues).
  5. Algorithmes : pseudocode ou diagramme si complexe.
  6. Plan de test : cas nominaux, limites, erreurs.
  7. Risques & trade-offs : ce qu'on choisit, ce qu'on abandonne, pourquoi.
  8. Plan de livraison : étapes, dépendances, estimations.

Exigences non-fonctionnelles à ne pas oublier

  • Performance : latence p50/p95/p99, throughput, consommation mémoire.
  • Scalabilité : horizontale (+ machines) vs verticale (+ puissance).
  • Disponibilité : SLA, tolérance aux pannes.
  • Sécurité : authentification, autorisation, audit log, chiffrement au repos et en transit.
  • Conformité : RGPD, Loi 25 (Québec), rétention de données.
  • Accessibilité : WCAG pour le front.
  • Observabilité : logs, métriques, traces.

Pièges à éviter dans une spec

  • Décrire le "comment" avant d'avoir figé le "quoi".
  • Oublier les cas d'erreur (40 % des bugs en prod viennent de là).
  • Specs trop longues : personne ne les lit. 5-10 pages max pour une feature moyenne.
  • Pas de critères d'acceptation mesurables ("rapide" ≠ "< 200 ms p95").
  • Absence de section "ce qu'on ne fera pas" — évite le scope creep.

Ressources pour se former

  • Livre : "Software Requirements" de Karl Wiegers — la référence.
  • Livre : "Writing Effective Use Cases" d'Alistair Cockburn.
  • Format design doc : chercher "Google Design Doc Template" ou "RFC Rust" — inspirants.
  • UML : plantuml.com et mermaid.js pour diagrammes en texte versionnables.
Important🔍 Revue de code — checklist pro

Ce qu'un bon reviewer regarde, dans l'ordre

  1. Correctness : est-ce que le code fait ce qu'il prétend faire ? Y a-t-il des cas limites non couverts ?
  2. Tests : couverture suffisante ? tests déterministes ? noms explicites ?
  3. Sécurité : injection SQL, XSS, auth, secrets hardcodés, input sanitization.
  4. Performance : boucle O(n²) cachée, requêtes N+1, absence d'index, mémoire.
  5. Lisibilité : naming, complexité cognitive, commentaires utiles (pas "augmente i de 1").
  6. Architecture : respect des couches, couplage, cohésion, SOLID.
  7. Convention : style, formatting, imports — idéalement automatique (linter).
  8. Doc : Javadoc/docstrings sur API publique, README à jour ?

Ton au moment de commenter

  • "nit:" pour un détail mineur (le reviewer OK si ignoré).
  • "suggestion:" pour une amélioration non bloquante.
  • "blocker:" ou sans préfixe pour un problème qui doit être réglé avant merge.
  • Questions > ordres : "Pourquoi avoir choisi X plutôt que Y ici ?" > "Fais Y".
  • Complimenter ce qui est bien fait (pas juste les critiques).

Côté auteur de PR

  • PR petite : idéalement < 400 lignes modifiées. Au-delà, la qualité de review chute.
  • Description claire : contexte, screenshots si UI, lien vers le ticket.
  • Répondre à chaque commentaire : accepté + commit, ou argumenté en retour.
  • Tests qui passent avant de demander la review.

Ressources

  • Google Engineering Practices — Code Review (guide officiel gratuit).
  • Livre : "The Art of Readable Code" de Boswell & Foucher — concis et efficace.
Utile🧪 Procédures de tests — méthodologie

Pyramide et stratégie

Voir la fiche "Tests & QA" plus haut pour les bases. Ici, ce qu'on attend d'un analyste-programmeur : rédiger des plans de test et des cas de test, pas juste écrire des tests unitaires.

Plan de test (doc)

  • Scope : ce qui est testé / ce qui ne l'est pas.
  • Environnements : dev, staging, prod-like.
  • Données de test : jeux de données, génération, anonymisation.
  • Types de tests : unit, intégration, end-to-end, performance, sécurité, régression.
  • Critères de sortie : % de couverture, zéro bug bloquant, perf p95 < X ms.

Cas de test unitaire (template)

  1. Identifiant (ex: TC-001).
  2. Prérequis / données en entrée.
  3. Étapes.
  4. Résultat attendu.
  5. Priorité (P1/P2/P3).

Spécifique OCR

Tester un modèle non-déterministe : jeu de validation figé, seuil d'acceptation (ex: CER < 2% sur dataset X). Automatiser via un job CI qui relance à chaque changement de modèle.

Utile📚 Rédaction de documentation

Types de documentation

TypePublicOutil
README projetNouveaux arrivantsMarkdown dans le repo
Documentation APIConsommateursOpenAPI / Swagger
Javadoc / docstringsDevs internesGénéré depuis le code
Architecture (ADR)Équipe tech, futurs devsArchitecture Decision Records
Runbook / opsSRE / oncallConfluence, Notion
Guide utilisateurClients finauxHTML, PDF, help center

Framework Diátaxis (à citer, très pro)

4 quadrants selon que le lecteur cherche à apprendre ou à accomplir, et selon que le document est pratique ou théorique :

  • Tutorials — apprendre par la pratique (lesson).
  • How-to guides — résoudre une tâche précise.
  • Reference — consulter un fait.
  • Explanation — comprendre un concept.

Confondre ces modes = doc illisible (ex: un tutoriel qui bascule en explication théorique au milieu).

Javadoc / docstring — minimum viable

/**
 * Recognize text in an image using the configured OCR engine.
 *
 * @param image raw bytes of the document page (PNG or JPEG)
 * @param lang ISO 639-2 language code (e.g. "fra", "eng")
 * @return extracted text, never null, empty string if nothing recognized
 * @throws OcrException if the engine fails or the input is invalid
 */
public String recognize(byte[] image, String lang) throws OcrException { ... }
Utile🗣️ Participation aux réunions

Formats de réunion probables chez IMDS

  • Stand-up quotidien (10-15 min) : hier, aujourd'hui, blockers.
  • Sprint planning : sélection des tickets pour le sprint.
  • Sprint review / démo : montrer ce qui a été livré.
  • Rétrospective : ce qui a marché, ce qui n'a pas, ce qu'on change.
  • Design review : discussion technique d'une spec avant implémentation.
  • Réunion R&D / chercheurs : discuter papiers, explorer pistes ML.

Posture recommandée

  • Arriver avec les éléments demandés (démo prête, chiffres, liens).
  • Prendre des notes — même symboliquement, ça montre l'engagement.
  • Poser des questions intelligentes — éviter "je n'ai pas compris", préférer "peux-tu préciser X par rapport à Y ?".
  • Ne pas monopoliser la parole, mais intervenir au moins une fois par réunion.
  • Résumer les décisions par écrit à la fin (bénéfique pour tout le monde + te positionne comme rigoureux).

Réunion R&D : ton terrain

C'est là que ton profil doctoral peut briller. Être capable de :

  • Lire un paper et le résumer en 5 minutes pour l'équipe.
  • Évaluer si une approche est applicable au produit (faisabilité, coût, perf).
  • Proposer des métriques d'évaluation.
  • Identifier les limites méthodologiques d'un benchmark.

📖 Ressources de révision — que lire, que regarder

Ciblé pour 4 jours. Priorité aux ressources courtes et à haute densité. Livres = référence, tutos = rapide, docs officielles = source de vérité.

Critique☕ Java / Spring Boot

Tutos courts (1-2 h chacun)

  • Spring official guides : "Building a RESTful Web Service" — le tuto canonique sur spring.io/guides. 30 min.
  • Baeldung : référence en articles courts. Chercher "Spring Boot tutorial", "Spring annotations", "JPA tutorial".
  • Fireship — Spring in 100 seconds (YouTube) : démarrage instantané.
  • Amigoscode (YouTube) : série Spring Boot full-stack claire.

Lecture approfondie (si temps)

  • "Effective Java" de Joshua Bloch — 3e édition. La bible. Item par item.
  • "Spring in Action" de Craig Walls — 6e édition. Pragmatique.
  • "Java Concurrency in Practice" de Brian Goetz — pour le multithreading.

Docs officielles (bookmark pour référence)

  • docs.spring.io — doc officielle Spring.
  • docs.oracle.com/javase — Javadoc standard.

Exercice pratique (obligatoire)

Crée un projet Spring Boot via start.spring.io avec dependencies : Web, JPA, H2. Écris en 2 h un CRUD d'entités. Tu auras touché contrôleurs, services, repositories, entités, config — l'essentiel.

Important🗄️ SQL & bases de données

Tutos

  • SQLBolt (sqlbolt.com) : interactif, 20 leçons, fait en 2-3 h.
  • Mode Analytics SQL Tutorial : progressif jusqu'aux window functions.
  • Use The Index, Luke (use-the-index-luke.com) : le meilleur texte sur les index, gratuit.

Docs vendeurs

  • docs.microsoft.com/sql — MSSQL / T-SQL.
  • docs.oracle.com/database — Oracle / PL/SQL.

Livres

  • "SQL Performance Explained" de Markus Winand — 180 pages, absolument essentiel sur la perf.
  • "Designing Data-Intensive Applications" de Martin Kleppmann — au-delà de SQL, la référence des systèmes de données modernes.

Exercice

Sur un schéma avec 3 tables (users, orders, products), rédige sans regarder : (1) top 10 users par somme des commandes, (2) users sans commande, (3) produit le plus vendu par mois. Si tu bloques, tu sais où tu dois réviser.

Important⚙️ C++ & C#

C++ — survol rapide

  • cppreference.com — référence canonique, précise (plus que cplusplus.com).
  • "A Tour of C++" de Bjarne Stroustrup — 240 pages, écrit par le créateur du langage, survol moderne.
  • "Effective Modern C++" de Scott Meyers — pour C++11/14, excellent si temps.
  • Les Core Guidelines (isocpp.org/guidelines) — les bonnes pratiques officielles.

C# — survol

  • Microsoft Learn — C# guided tour — officiel, gratuit, compact.
  • "C# in Depth" de Jon Skeet — pour comprendre les subtilités, mais volumineux.

Objectif 4 jours

Ne cherche pas à maîtriser. Cherche à lire sans être perdu et à avoir 3-4 concepts à citer (RAII, smart pointers, move semantics en C++ ; LINQ, async/await, propriétés en C#).

Important📄 OCR & document understanding

Papers fondateurs à survoler (abstracts + figures)

  • CRNN (Shi et al., 2015) — "An End-to-End Trainable Neural Network for Image-based Sequence Recognition".
  • CTC loss (Graves et al., 2006) — le papier original, dense mais clé.
  • EAST (Zhou et al., 2017) — détection de zones de texte rapide.
  • LayoutLM / LayoutLMv3 (Microsoft, 2019/2022) — multimodal texte + layout + image.
  • Donut (Kim et al., 2022) — OCR-free document understanding.
  • TrOCR (Li et al., 2021) — Transformer-based OCR.

Outils open source

  • Tesseract — OCR historique, LSTM depuis v4. github.com/tesseract-ocr/tesseract.
  • PaddleOCR (Baidu) — alternative moderne et puissante, multi-langue.
  • EasyOCR — simple à déployer, 80+ langues.
  • docTR (Mindee) — open source end-to-end en PyTorch/TF.
  • Hugging Face Transformers — pour LayoutLM, TrOCR, Donut, Nougat.

Blogs et tutos

  • Towards Data Science — nombreux articles comparatifs OCR (qualité variable, mais bons starter).
  • Papers with Code (paperswithcode.com) — filtre "Scene Text Recognition", "Document Understanding".
Maîtrisé🧠 Machine Learning & Deep Learning

Rafraîchissement ciblé

  • "Dive into Deep Learning" (d2l.ai) — livre interactif gratuit, avec PyTorch/MXNet/TF, théorie + code.
  • "The Little Book of Deep Learning" de François Fleuret — concis (200 pages), téléchargeable.
  • "Deep Learning" de Goodfellow, Bengio, Courville — la bible (mais long).

Cours

  • CS231n (Stanford, Karpathy) — Convnets pour la vision, tous les cours en ligne.
  • Fast.ai — "Practical Deep Learning for Coders", approche top-down.
  • DeepLearning.AI (Andrew Ng, Coursera) — série historique mais toujours solide.

Chaînes YouTube

  • 3Blue1Brown — "Neural networks" série. Intuition mathématique incomparable.
  • Andrej Karpathy — "Neural Networks: Zero to Hero" — de backprop from scratch jusqu'à GPT.
  • Yannic Kilcher — analyses de papers récents.

Papers à connaître

  • AlexNet (2012), VGG (2014), ResNet (2015), Attention is All You Need (Transformer, 2017), BERT (2018), GPT series, CLIP (2021), ViT (2020).
Utile🎯 Ingénierie logicielle & entreprise

Livres structurants

  • "Clean Code" de Robert C. Martin — nommage, fonctions, objets. Classique.
  • "The Pragmatic Programmer" de Hunt & Thomas — principes agnostiques.
  • "Designing Data-Intensive Applications" de Kleppmann — pour la partie systèmes.
  • "Refactoring" de Martin Fowler — catalogue de refactos.
  • "Domain-Driven Design Distilled" de Vaughn Vernon — version courte (150 p) de DDD.

Articles

  • Google Engineering Practices (google.github.io/eng-practices) — code review, change management.
  • Martin Fowler blog (martinfowler.com) — microservices, architecture, refactoring.
Utile🗣️ Entrevue technique — préparation

Livres

  • "Cracking the Coding Interview" de Gayle McDowell — algo/ds interview classiques.
  • "System Design Interview" de Alex Xu (Vol 1 & 2) — questions de design.

Plateformes

  • LeetCode — problèmes codés. Faire 2-3 easy sur arrays/hashmap pour l'aisance.
  • HackerRank — similaire, interviews simulées.

Soft side

  • "Staff Engineer" de Will Larson — si tu vises un rôle senior à terme.
  • Recherche "STAR method interview" — framework universel pour répondre aux questions comportementales.

🧠 IA de A à Z — remémoration complète et critique

Tout ce qu'un profil ML doit avoir en tête pour une entrevue R&D chez IMDS. Du neurone à la backprop, du CNN au Transformer, de PyTorch à l'OCR. Approche critique : pas de magie, pas de buzzword, que des mécanismes.

Comment lire cette section : chaque accordéon est une "micro-leçon". Ordre conseillé pour révision : 1-maths → 2-ML vs DL → 3-neurone → 4-forward → 5-loss → 6-backprop → 7-optim → 8-reg → 9-archis → 10-PyTorch → 11-domaines → 12-métriques → 13-pièges. Si tu maîtrises, saute à la section domaines.
Base① Mathématiques essentielles

Algèbre linéaire (omniprésente)

  • Vecteur : x ∈ ℝⁿ — liste de n nombres. Une image 224×224×3 aplatie est un vecteur de dimension 150528.
  • Matrice : W ∈ ℝ^(m×n).
  • Produit matriciel : y = W x, dimensions (m×n)·(n×1) = (m×1). C'est la brique d'une couche dense.
  • Produit scalaire : a · b = Σ aᵢbᵢ. Mesure la similarité entre deux vecteurs (si normalisés = cosinus).
  • Norme : L2 = racine de la somme des carrés. Utilisée pour régulariser, mesurer la taille d'un gradient.
  • Transposition, inverse, déterminant : à connaître conceptuellement.

Calcul différentiel (cœur de l'apprentissage)

  • Dérivée : f'(x) = lim_{h→0} (f(x+h) - f(x)) / h. Pente de la tangente.
  • Gradient : généralisation multi-variée. ∇f(x) = (∂f/∂x₁, ..., ∂f/∂xₙ). Pointe dans la direction de plus forte montée.
  • Règle de la chaîne (clé de la backpropagation) : si z = f(g(x)), alors dz/dx = dz/dg · dg/dx. C'est la mécanique qui propage les gradients à travers les couches.
  • Jacobienne / Hessienne : matrices de dérivées. Rarement utilisées directement en DL (trop chères), mais fondement théorique des optimiseurs d'ordre 2.

Probabilités & statistiques

  • Distribution : p(x) donne la probabilité (ou densité) de chaque valeur.
  • Gaussienne : N(μ, σ²). Utilisée pour initialiser les poids, modéliser du bruit.
  • Maximum de vraisemblance : choisir les paramètres qui maximisent P(données | paramètres). La cross-entropy sort de là.
  • Bayes : P(A|B) = P(B|A)·P(A) / P(B). Base des méthodes bayésiennes, du naive Bayes.
  • Espérance, variance, covariance : statistique descriptive de base.

Le minimum à pouvoir expliquer en entrevue

"Un réseau de neurones est une fonction paramétrée f(x; θ). On la rend différentiable, on définit une loss L, et on met à jour θ par descente de gradient : θ ← θ - η ∇L. Tout le reste est de l'ingénierie autour de ce principe."

Base② Machine Learning vs Deep Learning — la différence honnête

Machine Learning — définition

Toute méthode où un modèle apprend des paramètres à partir de données, plutôt qu'être codé en règles manuelles. Le Deep Learning en est un sous-ensemble.

Taxonomie

  • Supervisé : on a (x, y), on apprend f(x) ≈ y. Classification, régression.
  • Non supervisé : on n'a que x, on cherche une structure. Clustering (k-means), réduction de dim (PCA, t-SNE, UMAP), génération (VAE, GAN).
  • Auto-supervisé : on fabrique les labels depuis les données elles-mêmes. BERT masque des mots et prédit, CLIP aligne image/texte. Base des LLMs modernes.
  • Renforcement : agent + environnement + récompense. AlphaGo, robotique, jeux. Moins courant en produit SaaS.

ML classique (avant 2012)

MéthodePour quoiAvantage
Régression linéaire / logistiqueBaseline quasi universelleRapide, interprétable
Arbres / Random ForestDonnées tabulairesRobuste, pas besoin de normaliser
XGBoost / LightGBM / CatBoostTabulaire (toujours compétitif en 2025)State-of-the-art sur tabulaire
SVMClassification dans des espaces bien séparésMarges maximales
kNNBaseline, recommandationsAucun entraînement
Naive BayesClassification de texte simpleTrès rapide
k-means, DBSCANClusteringSimple à expliquer
PCA, t-SNE, UMAPVisualisation, compressionDécouverte de structure

Deep Learning — ce qui change

  • Feature learning : fin du feature engineering manuel. Le réseau apprend ses propres représentations.
  • Scale : ça marche mieux avec beaucoup de données et de calcul — inverse du ML classique où le plafond arrive vite.
  • Universalité : une seule famille d'outils (réseaux + SGD) pour image, texte, audio, tabulaire, séquences.
  • Coût : besoin de GPU/TPU, datasets massifs, expertise pour que ça converge.

Quand choisir quoi — règle pragmatique

  • Données tabulaires < 100 k lignes → XGBoost / LightGBM. Souvent bat DL et reste interprétable.
  • Image, texte, audio, séquence, ou beaucoup de données → DL.
  • Besoin fort d'interprétabilité (santé, finance régulée) → régression logistique + SHAP, ou modèles hybrides.
  • Peu de labels → auto-supervisé / transfer learning à partir d'un modèle pré-entraîné.

Critique honnête

"Le DL n'est pas magique. Sur des données tabulaires en entreprise, XGBoost le bat régulièrement. Le DL gagne quand la structure des données est spatiale ou séquentielle et que le volume permet d'exploiter la capacité du modèle. Chez IMDS, sur de l'OCR, le DL est incontournable. Sur du scoring de risque sur les métadonnées de docs, XGBoost serait probablement suffisant et plus explicable."

Base③ Anatomie : neurone, couche, non-linéarité

Le neurone artificiel

Formule la plus simple :

z = w₁x₁ + w₂x₂ + ... + wₙxₙ + b   (combinaison linéaire)
a = σ(z)                            (non-linéarité)
  • w : poids appris.
  • b : biais.
  • σ : fonction d'activation (non-linéaire).

Sans la non-linéarité σ, empiler des couches reste linéaire (inutile). C'est la non-linéarité qui donne au réseau sa capacité d'approximation universelle.

Couche dense (fully connected)

z = W x + b       # W: matrice (out, in), x: vecteur (in), b: (out)
a = σ(z)          # activation

Fonctions d'activation — tableau comparatif

FonctionFormuleQuand l'utiliser
Sigmoid1/(1+e^-z) → (0, 1)Sortie binaire. Pas en couches cachées (vanishing gradient).
Tanh(-1, 1)Historique, meilleure que sigmoid mais toujours saturée.
ReLUmax(0, z)Par défaut. Simple, efficace, évite le vanishing.
Leaky ReLUmax(αz, z), α=0.01Évite les "dead neurons".
GELUVariante lisse de ReLUStandard dans les Transformers (BERT, GPT).
Softmaxe^zᵢ / Σ e^zⱼSortie multi-classe : probabilités qui somment à 1.

Piège fondamental

Un réseau sans non-linéarité = régression linéaire (même si 100 couches). Le nombre de couches ne compense jamais l'absence de non-linéarité.

Base④ Forward pass — propagation avant

Définition

Calcul de la sortie du réseau à partir de l'entrée, couche par couche, de l'input vers le output.

Réseau à 2 couches (exemple minimal)

# Input: x ∈ ℝ^n
# Hidden: h = σ(W₁ x + b₁)
# Output: ŷ = W₂ h + b₂ (régression)
# Output: ŷ = softmax(W₂ h + b₂) (classification)

Côté PyTorch

import torch
import torch.nn as nn

class MLP(nn.Module):
    def __init__(self, in_dim, hidden_dim, out_dim):
        super().__init__()
        self.fc1 = nn.Linear(in_dim, hidden_dim)
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(hidden_dim, out_dim)

    def forward(self, x):
        h = self.relu(self.fc1(x))
        return self.fc2(h)

model = MLP(784, 256, 10)
x = torch.randn(32, 784)       # batch de 32 images flatten
logits = model(x)              # shape (32, 10)

Ce qui se passe en mémoire

  • PyTorch construit un graphe de calcul dynamique à chaque forward.
  • Chaque opération (linéaire, ReLU, etc.) enregistre ses inputs pour pouvoir calculer les gradients au backward.
  • Ce graphe est stocké dans tensor.grad_fn.

Batch, vectorisation, performance

  • On traite un batch de N échantillons à la fois, pas 1 par 1 (GPU en raffole).
  • Typique : batch size 32, 64, 128, 256, 512 selon la mémoire GPU.
  • Batch size élevé = gradient plus stable mais convergence parfois pire (moins de bruit stochastique).
Base⑤ Fonctions de perte (loss) — choix par tâche

Définition

Une loss est une fonction L(ŷ, y) qui quantifie l'erreur entre la prédiction et la vérité. C'est ce qu'on minimise. Le choix de la loss dépend totalement de la tâche.

Régression (sortie = nombre réel)

  • MSE (Mean Squared Error) : 1/N Σ (ŷᵢ - yᵢ)². Sensible aux outliers.
  • MAE (Mean Absolute Error) : 1/N Σ |ŷᵢ - yᵢ|. Plus robuste aux outliers.
  • Huber loss : MSE si erreur petite, MAE si grande. Compromis.

Classification binaire

  • BCE (Binary Cross-Entropy) : -[y log(p) + (1-y) log(1-p)]. Avec sigmoid en sortie.
  • BCEWithLogitsLoss en PyTorch : combine sigmoid + BCE pour la stabilité numérique.

Classification multi-classe

  • Cross-Entropy : -Σ yᵢ log(pᵢ). Combine softmax + log + négatif.
  • Label smoothing : au lieu de 0 ou 1, utiliser 0.1 ou 0.9. Améliore la généralisation.
  • Focal loss : pondère les exemples difficiles. Utilisée en détection d'objets (classes déséquilibrées).

Segmentation

  • Dice loss : 1 - 2|A∩B| / (|A| + |B|). Bonne pour objets petits/déséquilibrés.
  • IoU / Jaccard loss : similaire à Dice, autre formulation.
  • Combo : CE + Dice. Pratique courante.

Embeddings / retrieval

  • Triplet loss : ancre, positif, négatif. Pousse positif près, négatif loin.
  • Contrastive loss : paires (similaire, dissimilaire).
  • InfoNCE : contrastive moderne, utilisée par CLIP, SimCLR.
  • ArcFace : marge angulaire pour reconnaissance faciale.

Séquences

  • CTC loss : alignement-libre, pour OCR, reconnaissance vocale.
  • Cross-Entropy par token : génération de texte, traduction.
  • Seq2Seq attention : avec teacher forcing.

Détection d'objets

  • Multi-tâche : classification + régression de bbox. Loss combinée.
  • Smooth L1 / IoU / GIoU / DIoU pour la partie bbox.

Code PyTorch

import torch.nn.functional as F

# Régression
loss = F.mse_loss(pred, target)

# Classification multi-classe (avec logits en entrée)
loss = F.cross_entropy(logits, labels)

# Classification binaire
loss = F.binary_cross_entropy_with_logits(logits, targets)

# CTC
loss = F.ctc_loss(log_probs, targets, input_lengths, target_lengths)
Critique⑥ Backpropagation — propagation arrière des gradients

L'idée en une phrase

La backpropagation n'est rien d'autre que la règle de la chaîne du calcul différentiel, appliquée systématiquement au graphe du réseau, pour calculer le gradient de la loss par rapport à chaque paramètre.

Pourquoi c'est nécessaire

Pour mettre à jour un poids w, on a besoin de ∂L/∂w. Mais L dépend de w indirectement, à travers plusieurs couches. La backprop décompose ce calcul.

Illustration à 2 couches

# Forward
z1 = W1 x + b1
a1 = σ(z1)
z2 = W2 a1 + b2
L  = loss(z2, y)

# Backward (règle de la chaîne)
dL/dz2 = dL/dz2                       # dépend de la loss
dL/dW2 = dL/dz2 · a1ᵀ                 # pour mettre à jour W2
dL/db2 = dL/dz2
dL/da1 = W2ᵀ · dL/dz2                 # propager vers la couche précédente
dL/dz1 = dL/da1 * σ'(z1)              # dérivée de l'activation
dL/dW1 = dL/dz1 · xᵀ
dL/db1 = dL/dz1

Chaque couche a deux responsabilités :

  1. Calculer dL/d(paramètres) pour se mettre à jour.
  2. Calculer dL/d(entrée) à transmettre à la couche précédente.

Autograd en PyTorch

x = torch.randn(10, requires_grad=True)
y = x.sum()
y.backward()          # calcule tous les gradients automatiquement
print(x.grad)         # gradient accumulé dans .grad

Pourquoi "accumulé" et pas "remplacé"

PyTorch accumule par défaut (utile pour gradient accumulation sur plusieurs petits batches). D'où l'appel à optimizer.zero_grad() avant chaque .backward().

Vanishing / exploding gradients

  • Vanishing : avec sigmoid/tanh en couches profondes, les gradients deviennent ~0 → les premières couches n'apprennent pas. Fix : ReLU, batch norm, skip connections (ResNet).
  • Exploding : gradients qui divergent. Fix : gradient clipping (torch.nn.utils.clip_grad_norm_).

Truc de pro : gradient checking

Pour vérifier une implémentation manuelle de backprop : comparer le gradient calculé à une dérivée numérique (f(x+ε) - f(x-ε)) / 2ε. Coûteux mais imparable.

Base⑦ Gradient descent & optimizers

SGD (Stochastic Gradient Descent)

θ ← θ - η · ∇L(θ)

# η : learning rate
# ∇L : gradient calculé sur un minibatch

Variantes majeures

OptimizerIdée cléQuand l'utiliser
SGD + momentumAjoute une "inertie" au gradientTrès utilisé en CV, souvent meilleur en fin
NesterovMomentum "regarde devant"Variante de SGD
RMSpropLearning rate adaptatif par paramètreSéquences, RNN
AdamMomentum + RMSprop combinésPar défaut dans la plupart des projets
AdamWAdam + weight decay correctement implémentéStandard pour Transformers
LionDécouvert par recherche automatique (Google 2023)Emerging alternative à AdamW

Learning rate — LE hyperparamètre

  • Trop grand → divergence, loss qui explose.
  • Trop petit → convergence lente, possible local minimum.
  • LR scheduling : diminuer progressivement. Cosine decay, step decay, reduce on plateau.
  • Warmup : augmenter progressivement au début — critique pour les Transformers.
  • LR finder (Fast.ai) : technique pour trouver un bon LR empiriquement.

Code PyTorch

optimizer = torch.optim.AdamW(model.parameters(), lr=1e-4, weight_decay=0.01)
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=100)

# Boucle d'entraînement
for epoch in range(100):
    for x, y in dataloader:
        optimizer.zero_grad()
        loss = criterion(model(x), y)
        loss.backward()
        optimizer.step()
    scheduler.step()

Batch size, epoch, iteration — vocabulaire

  • Iteration : 1 forward + 1 backward + 1 update sur 1 batch.
  • Epoch : 1 passage complet sur le dataset.
  • Dataset 10 000, batch 100 → 100 iterations par epoch.
Base⑧ Régularisation — contre l'overfitting

Diagnostiquer l'overfitting

Train loss diminue, val loss stagne ou remonte. Courbes qui divergent = overfitting.

Techniques

  • Plus de données (toujours la meilleure).
  • Data augmentation : rotation, flip, crop, color jitter, mixup, cutout, cutmix, RandAugment.
  • Dropout : désactive aléatoirement p% des neurones pendant le training. p=0.5 dans les papers originaux, 0.1-0.2 pour Transformers modernes.
  • Weight decay (L2) : pénalise la somme des carrés des poids dans la loss. Pousse vers poids petits.
  • L1 : somme des valeurs absolues, tend à rendre des poids exactement nuls (sparsité).
  • Early stopping : arrêter dès que la val loss remonte.
  • Label smoothing : évite que le modèle soit trop confiant.
  • Model ensembling : moyenner plusieurs modèles.

Normalisation — stabilise l'entraînement

  • Batch Normalization : normalise par batch. Populaire en CNN. Problèmes avec petits batches ou RNN.
  • Layer Normalization : normalise par sample. Standard en Transformers.
  • Group Norm, Instance Norm : variantes pour cas spécifiques (vision, style transfer).

Code PyTorch — dropout & L2

class Model(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(784, 256)
        self.dropout = nn.Dropout(0.3)
        self.fc2 = nn.Linear(256, 10)

    def forward(self, x):
        x = F.relu(self.fc1(x))
        x = self.dropout(x)
        return self.fc2(x)

# L2 via weight_decay dans l'optimizer
optimizer = torch.optim.AdamW(model.parameters(), lr=1e-3, weight_decay=1e-4)
Base⑨ Architectures — CNN, RNN, Transformers

CNN — Convolutional Neural Networks (vision)

  • Convolution : filtre (kernel) glissant sur l'image, produit scalaire local. Partage de poids → invariance par translation.
  • Pooling : max ou average sur une région. Réduit la dimension spatiale.
  • Receptive field : zone de l'image qui influence un neurone donné. Grandit avec la profondeur.
  • Feature map : sortie d'une couche conv (C canaux × H × W).
Architectures historiques à citer
ArchiAnnéeContribution
LeNet-51998Pionnier, sur MNIST
AlexNet2012ImageNet win, début du DL moderne
VGG2014Empilement de 3×3 convs
Inception / GoogLeNet2014Modules multi-échelle
ResNet2015Skip connections (résout vanishing) — clé
DenseNet2016Connexions denses
EfficientNet2019Scaling compound (profondeur/largeur/résolution)
ConvNeXt2022CNN modernisé pour concurrencer ViT

Architectures pour segmentation / détection

  • U-Net : encoder + decoder + skip connections. Standard pour segmentation médicale, mais aussi doc.
  • Mask R-CNN : détection + segmentation instance.
  • YOLO (v1 à v12) : détection d'objets rapide, one-stage.
  • DETR (2020) : détection via Transformer, end-to-end sans NMS.

RNN, LSTM, GRU (séquences)

Idée : état caché h_t qui intègre le passé. h_t = f(x_t, h_{t-1}).

  • Vanilla RNN : théoriquement puissant, pratiquement instable (vanishing).
  • LSTM (1997) : ajoute cell state + gates (forget, input, output). Gère mieux long terme.
  • GRU (2014) : simplifié, 2 gates. Moins de paramètres.
  • BiLSTM : deux LSTM, un dans chaque sens. Utilisé dans CRNN pour OCR.

Transformers (2017 — le tournant)

Remplace la récurrence par l'attention. Permet parallélisation massive et capture des dépendances à très long terme.

Self-attention en 3 lignes
Q = X W_Q   # queries
K = X W_K   # keys
V = X W_V   # values
Attention(Q,K,V) = softmax(QKᵀ / √d) V
  • Multi-head attention : plusieurs attentions en parallèle, concaténées.
  • Position encoding : ajoute l'info d'ordre (sinusoïdal ou appris).
  • FFN : après attention, un MLP par position.
  • LayerNorm + résiduelle : autour de chaque sous-couche.
Variantes
TypeExempleUsage
Encoder-onlyBERT, RoBERTaCompréhension (classification, NER)
Decoder-onlyGPT, LlamaGénération
Encoder-decoderT5, BART, TrOCRTraduction, seq2seq
Vision TransformerViT, SwinImages découpées en patchs
MultimodalCLIP, LayoutLM, DonutImage + texte

Pourquoi Transformers dominent depuis 2020

  • Parallélisme total (contrairement aux RNN).
  • Capacité à scaler (plus de data + plus de params = mieux).
  • Même architecture, tous domaines (texte, image, audio, vidéo).
  • Transfer learning massif via pré-entraînement auto-supervisé.
Code⑩ PyTorch — training loop complète

Les 5 briques

  1. Dataset : accès aux données.
  2. DataLoader : batch, shuffle, multi-worker.
  3. Model (nn.Module).
  4. Loss.
  5. Optimizer.

Dataset + DataLoader

from torch.utils.data import Dataset, DataLoader
from torchvision import transforms
from PIL import Image

class DocumentDataset(Dataset):
    def __init__(self, paths, labels, transform=None):
        self.paths = paths
        self.labels = labels
        self.transform = transform

    def __len__(self):
        return len(self.paths)

    def __getitem__(self, idx):
        img = Image.open(self.paths[idx]).convert("L")  # grayscale
        if self.transform:
            img = self.transform(img)
        return img, self.labels[idx]

tf = transforms.Compose([
    transforms.Resize((128, 128)),
    transforms.RandomRotation(5),
    transforms.ToTensor(),
    transforms.Normalize([0.5], [0.5]),
])

train_ds = DocumentDataset(train_paths, train_labels, transform=tf)
train_dl = DataLoader(train_ds, batch_size=64, shuffle=True, num_workers=4)

Modèle CNN simple

class DocClassifier(nn.Module):
    def __init__(self, num_classes):
        super().__init__()
        self.features = nn.Sequential(
            nn.Conv2d(1, 32, 3, padding=1), nn.ReLU(), nn.MaxPool2d(2),
            nn.Conv2d(32, 64, 3, padding=1), nn.ReLU(), nn.MaxPool2d(2),
            nn.Conv2d(64, 128, 3, padding=1), nn.ReLU(), nn.AdaptiveAvgPool2d(1),
        )
        self.fc = nn.Linear(128, num_classes)

    def forward(self, x):
        x = self.features(x)
        x = x.flatten(1)
        return self.fc(x)

Training loop pro

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = DocClassifier(num_classes=10).to(device)
optimizer = torch.optim.AdamW(model.parameters(), lr=1e-3, weight_decay=1e-4)
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=20)
criterion = nn.CrossEntropyLoss()

best_val = float('inf')
for epoch in range(20):
    model.train()
    for x, y in train_dl:
        x, y = x.to(device), y.to(device)
        optimizer.zero_grad()
        logits = model(x)
        loss = criterion(logits, y)
        loss.backward()
        torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0)
        optimizer.step()

    model.eval()
    val_loss, correct, total = 0, 0, 0
    with torch.no_grad():
        for x, y in val_dl:
            x, y = x.to(device), y.to(device)
            logits = model(x)
            val_loss += criterion(logits, y).item() * x.size(0)
            correct += (logits.argmax(1) == y).sum().item()
            total += x.size(0)
    val_loss /= total
    acc = correct / total
    print(f"Epoch {epoch}: val_loss={val_loss:.4f} acc={acc:.4f}")

    if val_loss < best_val:
        best_val = val_loss
        torch.save(model.state_dict(), "best.pt")

    scheduler.step()

Pièges fréquents

  • Oublier model.train() / model.eval() — dropout et batchnorm se comportent différemment.
  • Oublier optimizer.zero_grad() — gradients accumulés à l'infini.
  • Oublier with torch.no_grad(): en validation — RAM qui explose.
  • Oublier .to(device) — batch sur CPU, modèle sur GPU → crash.
  • Normaliser les données en train et pas en val/test.
  • Utiliser le test set pour tuning — data leakage.

Outils modernes à connaître

  • PyTorch Lightning : encapsule la training loop, gère GPU/multi-GPU/TPU.
  • Hugging Face Transformers + Accelerate : standard pour NLP/multimodal.
  • Weights & Biases, MLflow, TensorBoard : tracking des expériences.
  • Hydra / OmegaConf : gestion de config.
  • Optuna : recherche d'hyperparamètres.
IMDS⑪ Domaines d'application — tout ce que fait IMDS

Traitement d'image — prétraitement qu'on applique presque toujours

  • Conversion niveaux de gris : 0.299 R + 0.587 G + 0.114 B (luminance ITU-R BT.601).
  • Binarisation : seuillage global (Otsu maximise la variance inter-classe), ou adaptatif (Sauvola, Niblack) par fenêtre — indispensable sur scans inégalement éclairés.
  • Filtrage : gaussien (flou doux), médian (sel et poivre), bilatéral (préserve les bords), morphologique (érosion/dilation/ouverture/fermeture).
  • Détection de contours : Sobel (gradient horizontal/vertical), Canny (bords fins).
  • Transformations géométriques : rotation, perspective (homographie via OpenCV cv2.warpPerspective).
  • Hough transform : détecter lignes, cercles — utile pour deskew et détection de cadres de formulaires.
  • Connected components : identifier des régions connectées — utile pour layout analysis.
  • OpenCV est la Swiss army knife de tout ça. PIL/Pillow en alternatif pur Python.

OCR (Optical Character Recognition) — texte imprimé

Pipeline classique :

  1. Prétraitement (binarisation, deskew, denoising).
  2. Détection de zones de texte (MSER, CTPN, EAST, DBNet).
  3. Segmentation en lignes (profils horizontaux de pixels).
  4. Reconnaissance ligne par ligne : CRNN (CNN features + BiLSTM + CTC) ou Tesseract (LSTM depuis v4).
  5. Post-traitement : dictionnaire, n-grams, correction orthographique.

Moderne : bout-en-bout via Transformers (TrOCR, Donut, Pix2Struct). Pour IMDS bancaire/assurance, hybride reste pertinent : déterminisme + explicabilité.

ICR (Intelligent Character Recognition) — manuscrit case par case

  • Typiquement : formulaires où chaque lettre va dans sa propre case.
  • Segmentation triviale (boîtes imprimées).
  • Reconnaissance caractère par caractère par CNN.
  • Datasets classiques : EMNIST, NIST SD19.
  • Défi : variabilité des styles d'écriture.

IWR (Intelligent Word Recognition) — manuscrit cursif mot par mot

  • Plus dur : pas de séparateurs explicites, lettres liées.
  • Modèles : CRNN + CTC (apprend la segmentation implicitement), ou modèles sequence-to-sequence avec attention.
  • Lexique contraint améliore beaucoup (nom propre, ville, libellé attendu).
  • Datasets : IAM Handwriting Database, RIMES (français).

Reconnaissance de formes — "shape recognition"

  • Classique : moments de Hu, descripteurs de forme (Fourier descriptors), contours.
  • Moderne : CNN directement.
  • Usage IMDS typique : détecter cases à cocher, signatures, logos sur documents.

Reconnaissance faciale

  1. Détection : MTCNN, RetinaFace — bounding box + 5 landmarks.
  2. Alignement : warp affine sur les landmarks — visage centré, orienté.
  3. Embedding : réseau (FaceNet, ArcFace) produit un vecteur de 128 à 512 dim.
  4. Matching :
    • 1:1 vérification → distance cosinus + seuil.
    • 1:N identification → recherche approximate nearest neighbor (FAISS, HNSW).

Losses caractéristiques :

  • Triplet : pousser ancre-positif proche, ancre-négatif loin.
  • ArcFace : marge angulaire dans l'espace des embeddings, SOTA en 2018-2020.

Biais éthiques documentés (NIST FRVT) : accuracy qui varie selon ethnie/genre. À mentionner pour montrer maturité.

Classification de documents

  • Par image seule : CNN (ResNet, EfficientNet) sur la mise en page visuelle → marche bien quand les types ont des apparences distinctes (facture vs contrat).
  • Par texte OCR : après OCR, classification texte via TF-IDF + SVM (baseline) ou BERT-like (moderne).
  • Multimodal : LayoutLM, LayoutLMv3, Donut — image + texte + positions 2D. SOTA depuis 2020.
  • Datasets : RVL-CDIP (400k docs, 16 classes), IIT-CDIP.

Extraction d'information sur documents (KIE — Key Information Extraction)

  • Au-delà de classifier : extraire des champs structurés (date, montant, numéro).
  • Approche texte : NER (Named Entity Recognition) sur le texte OCR. spaCy, BERT NER.
  • Approche multimodale : LayoutLM fine-tuné pour token classification avec positions.
  • OCR-free : Donut génère directement le JSON structuré.
  • Datasets : FUNSD, SROIE (tickets de caisse), CORD, DocVQA.
Base⑫ Métriques — évaluer honnêtement

Classification

MétriqueFormuleQuand
Accuracy(TP+TN) / totalClasses équilibrées
PrecisionTP / (TP+FP)Coût des faux positifs élevé
RecallTP / (TP+FN)Coût des faux négatifs élevé
F12·P·R / (P+R)Compromis P/R
AUC-ROCAire sous la courbe ROCClassifieur probabiliste
AUC-PRAire sous Precision-RecallClasses déséquilibrées

OCR & reconnaissance de texte

  • CER (Character Error Rate) = Levenshtein(pred, gt) / len(gt). 2% = 2 erreurs / 100 caractères.
  • WER (Word Error Rate) : idem au niveau mot.
  • BLEU : usuel en traduction, parfois en OCR.

Détection d'objets

  • IoU (Intersection over Union) : |A∩B| / |A∪B|. Seuil typique 0.5.
  • mAP (mean Average Precision) : moyenne AP sur les classes à divers seuils d'IoU.

Segmentation

  • IoU par classe, mIoU.
  • Dice : 2|A∩B| / (|A|+|B|).
  • Pixel accuracy : trompeuse si classes déséquilibrées.

Régression

  • MSE, MAE, RMSE, MAPE, R².

Embeddings / retrieval

  • Recall@K, MRR (Mean Reciprocal Rank), NDCG.

Règle d'or : métrique ≠ objectif business

Une accuracy de 95% sur un classifieur médical qui rate les vrais positifs (cancer) est inacceptable. Toujours valider avec le stakeholder métier ce qui compte vraiment. En OCR pour IMDS, rater une date sur un formulaire peut être bien pire qu'une lettre dans le nom du client.

Lucidité⑬ Pièges & éthique — ce qui sépare un junior d'un senior

Pièges méthodologiques

  • Data leakage : info du test fuit vers le train. Normalisation calculée sur tout le dataset, split par date mal fait, features dérivées du label…
  • Split naïf : shuffle aléatoire alors que les données sont temporelles ou groupées (plusieurs échantillons d'un même patient). Toujours splitter au bon niveau.
  • Overfit sur le val set : à force de tuner sur val, on finit par overfitter val. Garder un test set vraiment intouché.
  • Metric hacking : choisir la métrique qui flatte le modèle plutôt que celle qui compte métier.
  • Sélection de seed : tester plusieurs seeds et ne reporter que le meilleur — frauduleux.
  • Survivorship bias dans les données : on n'entraîne que sur les cas qui ont été labellisés, qui sont souvent les cas "faciles".

Pièges ingénierie

  • Drift de données en prod : la distribution d'entrée change, le modèle se dégrade silencieusement. Monitoring indispensable.
  • Reproductibilité : seeds, versions de libs, déterminisme GPU (parfois impossible). Enregistrer tout (code, hash dataset, hyperparams).
  • Compute gaspillé : 10 expériences à 100k$ l'une sans hypothèse claire. Définir avant ce qu'on cherche à prouver.
  • Deployment drift : prétraitement différent entre training et inference. Tout écrire en pipeline réutilisable.

Biais dans les données

  • Reconnaissance faciale : NIST FRVT a mesuré des accuracy très différentes selon ethnie, genre, âge. Conséquence : un système "performant" en moyenne peut échouer systématiquement sur un sous-groupe.
  • OCR : datasets publics biaisés vers langues latines, police imprimée propre. Cursif arabe ou texte historique tamoul → performances catastrophiques si pas spécifiquement entraîné.
  • Toujours auditer la performance par sous-groupe, pas juste en global.

Interprétabilité

  • SHAP, LIME : expliquent des prédictions individuelles.
  • Grad-CAM, attention maps : visualiser les zones d'une image qui ont compté.
  • Contexte bancaire/assurance (clients IMDS) : le RGPD/Loi 25 Québec peut exiger une "logique du traitement" explicable.

Conformité & privacy

  • Documents = données personnelles souvent sensibles. Minimisation, pseudonymisation, chiffrement.
  • Droit à l'effacement : si un client demande, il faut pouvoir effacer ses données — y compris des embeddings en cache.
  • Entraînement sur données clients : vérifier base légale. Consentement ? Intérêt légitime ? Anonymisation robuste ?

Attitude à tenir en entrevue

Montrer ces préoccupations te distingue d'un candidat "je fit un modèle, regardez l'accuracy". Les équipes R&D matures cherchent des gens qui anticipent les problèmes de prod et d'éthique, pas juste qui codent des notebooks.

Tu es équipé si tu peux :
  • Écrire au tableau la formule z = Wx + b ; a = σ(z) et expliquer pourquoi la non-linéarité est indispensable.
  • Expliquer backprop = règle de la chaîne appliquée au graphe de calcul.
  • Coder un training loop PyTorch de mémoire (Dataset → DataLoader → model → loss → optim → boucle).
  • Distinguer CNN / RNN / Transformer en une phrase chacun.
  • Nommer 3 losses par type de tâche (régression, classif, séquence, embeddings).
  • Dessiner un pipeline OCR complet (détection → reconnaissance → post-traitement).
  • Citer un modèle moderne dans chaque famille (ResNet, BERT, ViT, LayoutLM, Donut).
  • Lister 3 pièges méthodologiques (data leakage, drift, metric hacking).

🧭 Dernière prise de hauteur

Vérité critique : 4 jours ne transforment pas un profil ML en développeur Java enterprise. Ton plan ne vise pas ça — il vise à rendre la conversation crédible et à démontrer le potentiel. Si IMDS te prend, c'est parce qu'ils croient à ta capacité d'apprentissage + à ton fit R&D, pas parce que tu auras tromp-é sur tes compétences Java. Sois honnête, tu gagneras du respect.
Ce qui doit être vrai à la fin du jour 4 :
  • Je peux lire du Java moyen et expliquer Spring Boot en 3 phrases.
  • Je peux écrire une requête SQL avec jointure + agrégation + fonction fenêtre.
  • Je peux dessiner un pipeline OCR complet au tableau blanc.
  • Je connais les 3 gros modèles doc récents (LayoutLM, Donut, TrOCR).
  • J'ai un pitch 2 min rodé, en FR et EN.
  • J'ai 4 questions précises à poser à IMDS.
  • Je dors bien la nuit précédente.
Si ça ne marche pas : ce sera probablement pour un gap Java/Spring trop profond pour le rôle. Ce n'est pas un échec personnel, c'est un signal qu'un poste plus R&D ML pur ou un poste Python-first te conviendrait mieux. L'entrevue est aussi pour toi d'évaluer eux. Pose les questions qui te permettent de décider, pas juste de plaire.