Guide recrutement data
Test technique Spark : ce qu'on évalue vraiment en entretien
Spark reste la référence du traitement distribué. Mais entre lancer un groupBy et diagnostiquer un skew qui fait exploser un job, l'écart de niveau est considérable. Voici ce qu'on évalue.
Data Builder·Juillet 2025·11 min de lecture·Data Engineer
Spark récompense ceux qui comprennent ce qui se passe sous l'API : lazy evaluation, shuffle, partitionnement. Un profil solide raisonne en coût de calcul distribué, pas en lignes de code. Cinq dimensions.
1Modèle d'exécution
Question discriminante
Différence entre une transformation et une action — et pourquoi ça change tout ?
- Lazy evaluation : les transformations construisent un plan, rien ne s'exécute avant une action.
- Le DAG est découpé en jobs → stages → tasks.
- Les stages sont séparés par les shuffles.
- Comprendre ça, c'est pouvoir lire le Spark UI et anticiper les coûts.
2Shuffle et partitionnement
Question discriminante
Qu'est-ce qu'un shuffle, et pourquoi c'est le nerf de la performance Spark ?
- Transformations narrow (map, filter) vs wide (groupBy, join) qui déclenchent un shuffle.
repartition (shuffle, augmente) vs coalesce (sans shuffle, réduit).- Le skew : une clé sur-représentée qui sature une tâche.
- Choisir le nombre de partitions selon le volume et les cœurs disponibles.
Signal d'alerte : un candidat qui ne sait pas ce qu'est un shuffle ne pourra jamais optimiser un job Spark — éliminatoire sur un poste d'ingénierie.
3Jointures et optimisation
Question discriminante
Comment joindre efficacement une grosse table de faits avec une petite table de référence ?
from pyspark.sql import functions as F
big.join(F.broadcast(small), 'key') # évite le shuffle de la grosse table
- Broadcast join : diffuser la petite table pour éviter un shuffle coûteux.
- Sort-merge join par défaut sur deux grosses tables.
- Gérer le skew de jointure (salting, ou skew join d'AQE).
- AQE (Adaptive Query Execution) ajuste le plan à l'exécution.
4Fonctions fenêtre et agrégations
Question discriminante
Comment obtenez-vous le top-N par catégorie en PySpark ?
from pyspark.sql import Window, functions as F
w = Window.partitionBy('categorie').orderBy(F.desc('ventes'))
df.withColumn('r', F.row_number().over(w)).filter('r <= 3')
Window.partitionBy(...).orderBy(...) pour classements et cumuls.groupBy().agg() pour les agrégats distribués.- Préférer les fonctions natives aux UDF Python (coûteuses, hors optimiseur).
- Pandas UDF (vectorisées) quand une UDF est inévitable.
5Performance et production
Question discriminante
Un job Spark est lent ou tombe en OOM. Par quoi commencez-vous ?
- Lire le Spark UI : stages longs, skew, spill disque.
cache/persist à bon escient (réutilisation, pas systématique).- Formats colonnes (Parquet) + partition pruning pour lire moins.
- Dimensionner exécuteurs et mémoire ; éviter la collecte massive au driver.
6Grille par niveau
| Niveau | Maîtrise attendue | Signal GO | NO-GO |
|---|
| Junior | DataFrame API, transformations de base | Écrit un groupBy/join correct, distingue transfo/action | Collecte tout au driver (collect) |
| Confirmé | Shuffle, partitionnement, broadcast join, fenêtres | Explique un shuffle, utilise un broadcast join | Ne sait pas ce qu'est un shuffle |
| Senior | Skew, AQE, tuning mémoire, Spark UI | Diagnostique un skew et un spill dans le Spark UI | Abuse des UDF Python sans mesurer le coût |
| Lead | Architecture distribuée, coûts cluster, standards | Optimise le coût/perf global, fixe les bonnes pratiques | Ne peut pas expliquer le découpage jobs/stages/tasks |
Data hiring guide
Spark technical interview: what we really assess
Spark is still the reference for distributed processing. But between running a groupBy and diagnosing a skew that blows up a job, the gap in level is considerable. Here's what we assess.
Data Builder·July 2025·11 min read·Data Engineer
Spark rewards those who understand what happens under the API: lazy evaluation, shuffle, partitioning. A strong profile reasons in distributed compute cost, not lines of code. Five dimensions.
1Execution model
Key question
Difference between a transformation and an action — and why it changes everything?
- Lazy evaluation: transformations build a plan, nothing runs until an action.
- The DAG is split into jobs → stages → tasks.
- Stages are separated by shuffles.
- Understanding this means being able to read the Spark UI and anticipate costs.
2Shuffle and partitioning
Key question
What is a shuffle, and why is it the crux of Spark performance?
- Narrow transformations (map, filter) vs wide (groupBy, join) that trigger a shuffle.
repartition (shuffle, increases) vs coalesce (no shuffle, reduces).- Skew: an over-represented key that saturates one task.
- Choosing the number of partitions by volume and available cores.
Warning signal : a candidate who doesn't know what a shuffle is will never optimize a Spark job — disqualifying for an engineering role.
3Joins and optimization
Key question
How do you efficiently join a large fact table with a small reference table?
from pyspark.sql import functions as F
big.join(F.broadcast(small), 'key') # évite le shuffle de la grosse table
- Broadcast join: broadcast the small table to avoid a costly shuffle.
- Sort-merge join by default on two large tables.
- Handle join skew (salting, or AQE's skew join).
- AQE (Adaptive Query Execution) adjusts the plan at runtime.
4Window functions and aggregations
Key question
How do you get the top-N per category in PySpark?
from pyspark.sql import Window, functions as F
w = Window.partitionBy('categorie').orderBy(F.desc('ventes'))
df.withColumn('r', F.row_number().over(w)).filter('r <= 3')
Window.partitionBy(...).orderBy(...) for rankings and running totals.groupBy().agg() for distributed aggregates.- Prefer native functions to Python UDFs (costly, outside the optimizer).
- Pandas UDFs (vectorized) when a UDF is unavoidable.
5Performance and production
Key question
A Spark job is slow or hits OOM. Where do you start?
- Read the Spark UI: long stages, skew, disk spill.
cache/persist wisely (reuse, not by default).- Columnar formats (Parquet) + partition pruning to read less.
- Size executors and memory; avoid massive collects to the driver.
6Level grid
| Level | Expected proficiency | Signal GO | NO-GO |
|---|
| Junior | DataFrame API, basic transformations | Writes a correct groupBy/join, tells transform from action | Collects everything to the driver (collect) |
| Mid-level | Shuffle, partitioning, broadcast join, windows | Explains a shuffle, uses a broadcast join | Doesn't know what a shuffle is |
| Senior | Skew, AQE, memory tuning, Spark UI | Diagnoses skew and spill in the Spark UI | Overuses Python UDFs without measuring cost |
| Lead | Distributed architecture, cluster cost, standards | Optimizes overall cost/perf, sets best practices | Can't explain the jobs/stages/tasks breakdown |