Comment réussir un entretien Go : les meilleures questions de A à Z
\n\nL'entretien pour un poste de développeur Go ne se résume pas à une simple vérification de la syntaxe. Les employeurs recherchent des candidats qui comprennent la philosophie du langage : simplicité, concurrence et gestion efficace de la mémoire. Dans cet article, nous analyserons les questions clés qui vous seront posées — des bases aux sujets avancés avec des exemples de code. Préparez-vous avec notre checklist et vous vous sentirez en confiance.
\n\n1. Bases de Go : types de données, structures et gestion de la mémoire
\n\nCommençons par les bases. Sans elles, rien ne va. Les recruteurs aiment poser des questions sur les types et leur comportement.
\n\nQuels sont les types de données intégrés en Go ?
\n- \n
- Basiques :
int,float64,string,bool. \n - Agrégés :
array,struct. \n - De référence :
slice,map,channel,pointer,function. \n
Quelle est la différence entre un tableau et une slice ?
\nUn tableau a une longueur fixe, définie à la compilation. Une slice est une structure dynamique qui fait référence à un tableau sous-jacent.
\n// Tableau\nvar arr [3]int = [3]int{1, 2, 3}\narr[0] = 10 // OK\n\n// Slice\nslc := []int{1, 2, 3}\nslc = append(slc, 4) // La longueur peut augmenter\n\nQuestion piège : Que se passe-t-il avec la mémoire lors d'un append si la capacité de la slice est dépassée ? (Réponse : Go alloue un nouveau tableau 2 fois plus grand et copie les données).
Comment fonctionne une map en Go ?
\nUne map est une table de hachage. L'ordre de parcours n'est pas garanti. Lors de la lecture d'une clé inexistante, la valeur zéro est retournée (par exemple, 0 pour int).
m := make(map[string]int)\nm["key"] = 42\nvalue, ok := m["key"] // ok == true si la clé existe\n\n\n2. Concurrence : goroutines, canaux et mutex
\nC'est le sujet le plus important pour Go. Sans lui, impossible de réussir l'entretien.
\n\nQu'est-ce qu'une goroutine et en quoi diffère-t-elle d'un thread OS ?
\nUne goroutine est un thread léger géré par le runtime Go. La pile d'une goroutine commence à 2-4 Ko (contre 1 Mo pour un thread OS). Des milliers de goroutines fonctionnent sur plusieurs threads OS (modèle M:N).
\n\nComment fonctionnent les canaux ? Donnez un exemple du pattern worker pool.
\nfunc worker(id int, jobs <-chan int, results chan<- int) {\n for j := range jobs {\n results <- j * 2\n }\n}\n\nfunc main() {\n jobs := make(chan int, 100)\n results := make(chan int, 100)\n\n // Lancement de 3 workers\n for w := 1; w <= 3; w++ {\n go worker(w, jobs, results)\n }\n\n // Envoi des tâches\n for j := 1; j <= 5; j++ {\n jobs <- j\n }\n close(jobs)\n\n // Collecte des résultats\n for r := 1; r <= 5; r++ {\n <-results\n }\n}\n\n\nQuelle est la différence entre un canal bufferisé et non bufferisé ?
\n- \n
- Non bufferisé : l'expéditeur est bloqué jusqu'à ce que le destinataire reçoive le message. Communication synchrone. \n
- Bufferisé : l'expéditeur est bloqué uniquement lorsque le tampon est plein. Communication asynchrone. \n
Comment éviter un deadlock ?
\nUtilisez select avec un timeout ou default :
select {\ncase msg := <-ch:\n fmt.Println(msg)\ncase <-time.After(1 * time.Second):\n fmt.Println("timeout")\n}\n\n\n3. Interfaces, génériques et gestion des erreurs
\nGo n'est pas un langage purement orienté objet, mais les interfaces y jouent un rôle clé.
\n\nComment fonctionne le duck typing en Go ?
\nUn type implémente une interface implicitement s'il possède toutes les méthodes nécessaires. Cela permet d'écrire du code flexible.
\ntype Stringer interface {\n String() string\n}\n\ntype User struct {\n Name string\n}\n\nfunc (u User) Str