Go en entretien : 9 pièges et comment les éviter

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Introduction : Pourquoi Go et pourquoi est-ce si difficile ?

\n\n

Go (ou Golang) est un langage adoré pour sa simplicité et détesté pour la même simplicité. Lors des entretiens Go, on demande rarement « écris un tri à bulles » (bien que cela arrive). Le plus souvent, vous serez confronté à des tâches sur la concurrence, la compréhension de la gestion de la mémoire et la capacité à écrire un code propre et idiomatique. Si vous êtes habitué à Python ou Java, Go peut sembler trop strict. Mais c'est précisément cette rigueur qui en fait le langage idéal pour les systèmes de production.

\n\n

Dans cet article, nous allons analyser les sujets clés qui obligatoirement surgiront lors de l'entretien. Vous n'aurez pas seulement de la théorie, mais des exemples de code concrets et une explication « sous le capot ». C'est parti !

\n\n

1. Goroutines et canaux : les bases à connaître par cœur

\n\n

Les goroutines ne sont pas des threads

\n

La question la plus fréquente : « Quelle est la différence entre une goroutine et un thread OS ? ». Réponse : une goroutine est légère (pile à partir de 2 Ko), gérée par le planificateur de Go, et non par le noyau. Un million de goroutines est normal. Un million de threads tuerait le système.

\n\n
// Exemple : lancement de 10 goroutines\nfor i := 0; i < 10; i++ {\n    go func(id int) {\n        fmt.Printf("Goroutine %d en cours d'exécution\\n", id)\n    }(i)\n}\n// On attend (mauvaise méthode, uniquement pour l'exemple)\ntime.Sleep(time.Second)\n
\n\n

Canaux : synchronisation sans douleur

\n

Les canaux en Go sont des « tuyaux » typés pour transmettre des données entre goroutines. Retenez trois règles :

\n
    \n
  • Écrire dans un canal fermé provoque une panique.
  • \n
  • Lire depuis un canal fermé retourne la valeur zéro.
  • \n
  • Un canal non bufferisé bloque la goroutine jusqu'à l'arrivée d'un récepteur.
  • \n
\n\n
// Travail correct avec un canal\nch := make(chan int, 2) // bufferisé\n\nch <- 1\nch <- 2\nclose(ch)\n\nfor val := range ch {\n    fmt.Println(val) // 1, 2\n}\n
\n\n

Conseil pour l'entretien : si on vous interroge sur « select », montrez un exemple avec un timeout :

\n\n
select {\ncase msg := <-ch:\n    fmt.Println(msg)\ncase <-time.After(1 * time.Second):\n    fmt.Println("Timeout !")\n}\n
\n\n

2. Interfaces : pas seulement des méthodes, mais des contrats

\n\n

En Go, les interfaces sont implémentées implicitement. Cela signifie qu'une structure satisfait automatiquement une interface si elle possède toutes les méthodes nécessaires. On demande souvent : « Quelle est la différence entre interface{} et any ? » — réponse : aucune, ce sont des synonymes (depuis Go 1.18).

\n\n

Tâche typique d'entretien

\n

Écrivez une fonction qui prend un io.Writer et y écrit une chaîne. Cela teste la compréhension des interfaces de la bibliothèque standard.

\n\n
func WriteHello(w io.Writer) {\n    _, err := w.Write([]byte("Bonjour, Go !"))\n    if err != nil {\n        log.Fatal(err)\n    }\n}\n\n// Utilisation :\nvar buf bytes.Buffer\nWriteHello(&buf)\nfmt.Println(buf.String()) // Bonjour, Go !\n
\n\n

Piège : toutes les interfaces en Go sont deux pointeurs (type + valeur). Une interface vide (interface{}) n'est pas égale à nil si elle contient (*int)(nil). Souvenez-vous-en pour ne pas échouer à la question sur nil != nil.

\n\n

3. Génériques : nouveau, mais déjà obligatoire

\n\n

Depuis Go 1.18, les génériques font partie du langage. Lors d'un entretien, on peut vous demander d'écrire une fonction générique. Par exemple, une fonction qui prend une tranche de n'importe quel type et retourne sa longueur (trivial) ou trouve le maximum.

\n\n
// Fonction générique pour trouver le maximum\nfunc Max[T constraints.Ordered](a, b T) T {\n    if a > b {\n        return a\n    }\n    return b\n}\n\n// Utilisation :\nfmt.Println(Max(10, 20))     // 20\nfmt.Println(Max(3.14, 2.71)) // 3.14\n
\n\n

Notez le package constraints — il est souvent utilisé dans les questions. Mais rappelez-vous : depuis Go 1.21, il a été remplacé par le cmp.Ordered intégré.

\n\n

4. Gestion des erreurs : ne les ignorez pas

\n\n

En Go, il n'y a pas de try-catch. Les erreurs sont des valeurs.

Blogs

Book Recommendations