Go — Cheat Sheet

Tag: go, golang, backend, concurrency, goroutines, channels

Livello: intermedio

TL;DR: Sintesi dei concetti essenziali di Go (Golang), con focus su concorrenza, gestione della memoria, interfacce e pattern architetturali per sviluppo backend.

Concetti chiave

-

Tipizzazione statica e forte, compilazione nativa veloce in un singolo binario statico.

-

Assenza di classi ed ereditarieta': il design usa struct e composizione.

-

Interfacce implicite: un tipo implementa un'interfaccia semplicemente possedendo i suoi metodi.

-

Goroutine: thread leggeri gestiti dal runtime Go, multiplexati su thread del sistema operativo.

-

Channel: meccanismo nativo per comunicare e sincronizzare goroutine senza lock espliciti.

-

Gestione errori esplicita: gli errori sono valori restituiti dalle funzioni, nessuna eccezione.

-

Garbage collector: concorrente, non compattante, ottimizzato pesantemente per la bassa latenza.

-

Defer: posticipa l'esecuzione di una chiamata di funzione al termine della funzione corrente.

-

Context: standard per gestire timeout, scadenze e cancellazioni attraverso alberi di goroutine.

Domande tipiche e risposte pronte

-

Q: Qual e' la differenza tra concorrenza e parallelismo in Go?R: La concorrenza riguarda la gestione strutturale di piu' compiti (goroutine). Il parallelismo e' l'esecuzione simultanea fisica su piu' core.

-

Q: Come funzionano i channel bufferizzati rispetto ai non bufferizzati?R: Quelli non bufferizzati bloccano il mittente finche' il ricevente non e' pronto. I bufferizzati bloccano solo quando il buffer e' pieno.

-

Q: Quando useresti un Mutex invece di un Channel?R: Uso un Mutex per proteggere l'accesso esclusivo a uno stato condiviso semplice (es. cache in memoria), evitando l'overhead dei channel.

-

Q: Cos'e' una goroutine leak e come la previeni?R: Accade quando una goroutine resta bloccata per sempre in attesa su un channel. La prevengo usando i context per il timeout.

Insidie e errori comuni

-

Catturare la variabile del ciclo (loop variable capture) all'interno di una goroutine (risolto nativamente da Go 1.22).

-

Dimenticare di chiudere i response body delle chiamate HTTP deferendo sempre resp.Body.Close().

-

Inviare dati su un channel gia' chiuso, operazione che provoca un panic immediato del runtime.

-

Dichiarare una map senza inizializzarla con make: scrivere su una map nil causa panic.

Snippet e comandi

// Esempio di concorrenza con goroutine, channel e context
package main

import (
	"context"
	"fmt"
	"time"
)

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
	defer cancel()

	ch := make(chan int)

	go func() {
		// Simulazione di un'operazione I/O o calcolo
		time.Sleep(1 * time.Second)
		ch <- 42
	}()

	select {
	case res := <-ch:
		fmt.Println("Risultato ottenuto:", res)
	case <-ctx.Done():
		fmt.Println("Operazione interrotta:", ctx.Err())
	}
}

Da ripassare

-

[ ] Internals dello scheduler di Go (modello M:N).

-

[ ] Primitive avanzate del pacchetto sync (WaitGroup, Cond, sync.Map).

-

[ ] Profiling dell'applicazione tramite pprof.

Jarvis Interviews
Jarvis