40 Perguntas de Entrevista Go (Golang) em 2026
Resposta rápida: entrevistas de Go (também chamada de Golang) giram em torno de cinco blocos: fundamentos da linguagem (slices, maps, structs, interfaces), concorrência (goroutines, channels, select, sync, context), tratamento de erros (errors.Is, errors.As, %w, errors.Join), testes (go test, table-driven tests, -race, cobertura) e produção (profiling, memória, shutdown). Abaixo estão 40 perguntas com respostas curtas o bastante para você usar na conversa.
Dividimos em níveis para facilitar seu estudo. As perguntas 21 a 40 cobram o Go moderno — generics, iteradores, slog, roteamento na stdlib — que entrevistadores passaram a cobrar em 2025 e 2026. O guia está atualizado para o Go 1.27 (versão estável atual: 1.27.1).
Por onde começar
| Seu nível | Comece pelas perguntas | Depois estude |
|---|---|---|
| Júnior | 1–8 | Go para iniciantes |
| Pleno | 9–15 e 21–30 | Concorrência em Go e Testes em Go |
| Sênior | 16–20 e 31–40 | Entrevista técnica Go |
📗 Nível Iniciante
1. O que é Go e quais são suas principais características?
Go (Golang) é uma linguagem de programação criada pelo Google em 2009. Principais características:
- Compilada e tipada estaticamente
- Sintaxe simples e limpa
- Suporte nativo a concorrência (goroutines)
- Garbage collection eficiente
- Compilação rápida
- Biblioteca padrão robusta
2. Qual a diferença entre var e :=?
// var - declaração explícita, pode usar fora de funções
var nome string = "Go"
var idade int
// := - declaração curta, só dentro de funções
linguagem := "Go" // tipo inferido
3. O que são goroutines?
Goroutines são funções que executam concorrentemente. São mais leves que threads do sistema operacional.
go minhaFuncao() // executa em uma nova goroutine
4. Como funcionam os channels em Go?
Channels são o mecanismo de comunicação entre goroutines.
ch := make(chan int) // criar channel
ch <- 42 // enviar valor
valor := <-ch // receber valor
5. Qual a diferença entre array e slice?
- Array: tamanho fixo, definido na declaração
- Slice: tamanho dinâmico, referência a um array subjacente
arr := [3]int{1, 2, 3} // array - tamanho fixo
slice := []int{1, 2, 3} // slice - tamanho dinâmico
6. O que é a função init()?
Função especial executada automaticamente antes de main(). Usada para inicialização.
func init() {
// executado antes de main()
}
7. Como Go trata erros?
Go usa retorno de erro explícito ao invés de exceções.
resultado, err := funcaoQuePodeFalhar()
if err != nil {
// tratar erro
return err
}
8. O que é defer?
defer adia a execução de uma função até o retorno da função atual.
func exemplo() {
defer fmt.Println("fim") // executado por último
fmt.Println("início")
}
// Saída: início, fim
📘 Nível Intermediário
9. Explique a diferença entre make() e new()
new(T): aloca memória zerada, retorna ponteiro*Tmake(T): usado para slices, maps e channels, retornaTinicializado
p := new(int) // *int, valor 0
s := make([]int, 5) // []int com 5 elementos
m := make(map[string]int) // map inicializado
10. Como implementar uma interface em Go?
Interfaces são implementadas implicitamente - basta ter os métodos.
type Writer interface {
Write([]byte) (int, error)
}
type MeuWriter struct{}
func (m MeuWriter) Write(data []byte) (int, error) {
// implementação
return len(data), nil
}
// MeuWriter implementa Writer automaticamente
11. O que é um mutex e quando usar?
Mutex (mutual exclusion) protege acesso concorrente a dados compartilhados.
var mu sync.Mutex
var contador int
func incrementar() {
mu.Lock()
contador++
mu.Unlock()
}
12. Explique o padrão context em Go
Context carrega deadlines, sinais de cancelamento e valores através de chamadas de API.
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
select {
case <-ctx.Done():
return ctx.Err()
case resultado := <-operacaoLonga(ctx):
return resultado
}
13. Como funciona o garbage collector do Go?
Go usa um GC concurrent, tri-color, mark-and-sweep:
- Pausas curtas (sub-milisegundo)
- Executa concorrentemente com a aplicação
- Controlável via
GOGCenvironment variable
Desde o Go 1.26, o Green Tea GC vem habilitado por padrão — tema que já aparece em perguntas de 2026. Detalhes em Go 1.26: novidades.
14. O que são struct tags?
Metadados anexados a campos de struct, usados para serialização.
type Usuario struct {
Nome string `json:"nome" validate:"required"`
Email string `json:"email,omitempty"`
}
15. Explique select em channels
select permite esperar em múltiplos channels simultaneamente.
select {
case msg := <-ch1:
fmt.Println("Recebido de ch1:", msg)
case msg := <-ch2:
fmt.Println("Recebido de ch2:", msg)
case <-time.After(time.Second):
fmt.Println("Timeout")
}
📙 Nível Avançado
16. Como evitar race conditions?
- Use mutex para proteger dados compartilhados
- Prefira channels para comunicação
- Use
-raceflag para detectar:go run -race main.go - Evite compartilhar memória; compartilhe por comunicação
17. Explique escape analysis
O compilador decide se variáveis ficam na stack ou heap:
- Stack: rápido, limpo automaticamente
- Heap: quando variável “escapa” da função
go build -gcflags="-m" main.go # ver decisões do compilador
18. Como implementar um worker pool?
func workerPool(jobs <-chan int, results chan<- int, numWorkers int) {
var wg sync.WaitGroup
for i := 0; i < numWorkers; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for job := range jobs {
results <- processarJob(job)
}
}()
}
wg.Wait()
close(results)
}
19. O que são generics em Go?
Adicionados em Go 1.18, permitem código type-safe reutilizável.
func Min[T constraints.Ordered](a, b T) T {
if a < b {
return a
}
return b
}
Desde o Go 1.27, métodos também podem declarar seus próprios parâmetros de tipo (métodos genéricos) — pergunta que já cai em entrevistas de fim de 2026. Veja Go 1.27: novidades.
20. Como otimizar performance em Go?
- Profile com
pprof - Minimize alocações (sync.Pool)
- Use buffers adequados
- Prefira value receivers para structs pequenos
- Evite conversões string/[]byte desnecessárias
🚀 Go Moderno
21. Go e Golang são a mesma linguagem?
Sim. O nome oficial é Go; Golang é o apelido herdado do antigo domínio golang.org (hoje go.dev), popular porque “go” é uma palavra genérica difícil de pesquisar. No currículo e em texto formal, prefira “Go”; em vagas e buscas, os dois termos aparecem.
22. O que mudou na variável de loop no Go 1.22?
Até o Go 1.21, a variável do for era uma só, compartilhada por todas as iterações — a origem clássica do bug de goroutines capturando o valor errado. No Go 1.22 cada iteração passou a ter sua própria variável.
for _, v := range itens {
go func() {
fmt.Println(v) // Go 1.22+: valor da iteração correta
}()
}
Em código que ainda precisa compilar com versões antigas, mantenha o v := v explícito.
23. O que são iteradores (range-over-func) em Go?
Desde o Go 1.23 é possível usar range sobre funções com as assinaturas de iter.Seq[V] e iter.Seq2[K, V], criando sequências próprias e preguiçosas.
func Pares(nums []int) iter.Seq[int] {
return func(yield func(int) bool) {
for _, n := range nums {
if n%2 == 0 && !yield(n) {
return
}
}
}
}
for n := range Pares([]int{1, 2, 3, 4}) {
fmt.Println(n) // 2, 4
}
Padrões práticos em iteradores em Go.
24. Quando generics valem a pena?
Generics (Go 1.18+) evitam duplicação em estruturas e utilitários que só mudam de tipo: coleções, Map/Filter, caches. Não use generics quando uma interface já expressa o comportamento — a regra prática em Go é escrever o código concreto primeiro e generalizar depois. Veja generics, constraints e interfaces.
25. O que faz errors.Join?
Disponível desde o Go 1.20, agrega vários erros em um só, e errors.Is/errors.As continuam funcionando sobre o conjunto.
err := errors.Join(errFecharArquivo, errEnviarMetricas)
if errors.Is(err, errEnviarMetricas) { /* ... */ }
Útil em validações e em defer com múltiplos Close(). Aprofunde em erros em Go.
26. Qual a diferença entre errors.Is e errors.As?
errors.Is(err, alvo): compara com um valor sentinela (ErrNotFound), atravessando os%w.errors.As(err, &alvo): extrai um tipo concreto de erro para ler seus campos.
var httpErr *HTTPError
if errors.As(err, &httpErr) {
log.Println(httpErr.Status)
}
27. Como fazer logging estruturado sem dependências externas?
Com log/slog, na biblioteca padrão desde o Go 1.21.
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
logger.Info("pedido criado", "pedido_id", id, "valor", total)
Compare handlers e alternativas em slog para produção.
28. O que é GOMEMLIMIT?
Um limite soft de memória para o runtime (Go 1.19+). Ele não substitui o GOGC: faz o coletor trabalhar mais à medida que o heap se aproxima do limite, o que reduz OOM kill em contêineres com memória fixa. Detalhes em GOMEMLIMIT em produção.
29. GOMAXPROCS respeita os limites do contêiner?
A partir do Go 1.25, o runtime passou a considerar o limite de CPU do cgroup no Linux ao definir GOMAXPROCS automaticamente. Antes disso, ele usava o número de CPUs da máquina — daí a prática de ajustar GOMAXPROCS manualmente em Kubernetes. Contexto em GOMAXPROCS container-aware.
30. Como o net/http roteia por método desde o Go 1.22?
O ServeMux da stdlib passou a aceitar método e curingas no padrão, o que dispensa um roteador externo em APIs simples.
mux := http.NewServeMux()
mux.HandleFunc("GET /usuarios/{id}", buscarUsuario)
func buscarUsuario(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")
// ...
}
Exemplo completo em API REST com Go.
🧠 Perguntas de Sênior
31. Por que uma interface pode ser diferente de nil mesmo com ponteiro nulo?
Porque a interface guarda tipo + valor. Se o tipo não for nulo, a interface não é nil.
func f() error {
var e *MeuErro // nil
return e // a interface retornada != nil
}
Solução: retorne nil explicitamente em vez de um ponteiro tipado nulo. É uma das pegadinhas mais cobradas em entrevistas sênior.
32. Quando usar receiver por valor e quando por ponteiro?
Use ponteiro quando o método altera o estado, quando a struct é grande ou quando ela contém um sync.Mutex (copiar um mutex é bug). Use valor em tipos pequenos e imutáveis. Regra prática: não misture os dois estilos no mesmo tipo.
33. Qual o risco de append em slices que compartilham array?
append pode reutilizar o array subjacente e sobrescrever dados vistos por outro slice.
a := []int{1, 2, 3, 4}
b := a[:2]
b = append(b, 99) // sobrescreve a[2]
Se precisar de isolamento, copie (slices.Clone) ou limite a capacidade com a[:2:2].
34. O que acontece ao escrever em um map nil ou fechar um channel duas vezes?
- Escrever em
mapnil gera panic; ler retorna o valor zero. - Fechar um channel já fechado gera panic; enviar em channel fechado também.
- Ler de channel fechado retorna imediatamente o valor zero (use
v, ok := <-ch).
Convenção: quem escreve fecha, nunca o leitor.
35. Como controlar concorrência com limite e cancelamento?
Com errgroup: ele propaga o primeiro erro, cancela o contexto e limita o paralelismo.
g, ctx := errgroup.WithContext(ctx)
g.SetLimit(8)
for _, u := range urls {
g.Go(func() error { return baixar(ctx, u) })
}
err := g.Wait()
Mais em errgroup na prática e worker pool com backpressure.
36. O que é backpressure em um worker pool?
É limitar a entrada de trabalho quando os workers não dão conta, em vez de acumular jobs em memória. Na prática: channel de jobs com buffer limitado, envio com select mais ctx.Done(), e descarte ou fila externa quando estourar. Sem backpressure, o serviço morre por falta de memória antes de degradar.
37. Como investigar consumo de CPU ou memória em produção?
Exponha net/http/pprof numa porta interna, colete o perfil e analise:
go tool pprof http://127.0.0.1:6060/debug/pprof/heap
go tool pprof "http://127.0.0.1:6060/debug/pprof/profile?seconds=30"
Nunca deixe o endpoint público. Passo a passo em pprof em produção.
38. Como fazer graceful shutdown de um servidor HTTP?
Escute o sinal, pare de aceitar conexões e espere as requisições em andamento.
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
<-ctx.Done()
shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
srv.Shutdown(shutdownCtx)
Detalhes de deploy em graceful shutdown em Go.
39. Como escrever testes que o entrevistador considera bons?
Table-driven tests com t.Run, sem mocks desnecessários, httptest para HTTP e interfaces pequenas para isolar dependências. Rode go test -race ./... e mostre que entende que cobertura mede execução, não qualidade das verificações. Veja testes em Go e mocks, fakes e httptest.
40. Como medir se uma otimização funcionou?
Com benchmark reproduzível, não com achismo:
go test -bench=. -benchmem -count=10 ./...
Compare as execuções (por exemplo com benchstat) e confirme o gargalo no pprof antes e depois. Fundamentos em benchmarks em Go.
💡 Dicas para a Entrevista
- Pratique código ao vivo — Muitas entrevistas pedem para escrever código
- Entenda concorrência — É o diferencial do Go
- Conheça a stdlib —
net/http,encoding/json,context - Saiba debuggar —
go vet,go test -race,pprof - Mostre projetos — Código no GitHub vale muito
Próximos Passos
- Veja vagas Go disponíveis — oportunidades atualizadas no Brasil
- Conheça empresas que usam Go no Brasil — pesquise o contexto técnico antes da entrevista
- Como aprender Go — Guia completo para iniciantes
- Entrevista técnica Go em 2026 — formato do processo, live coding e system design
- Currículo de desenvolvedor Go — como chegar até a entrevista
- Primeira vaga Go no Brasil — caminho para quem está começando
- Interfaces em Go e erros em Go — os dois temas que mais derrubam candidatos
Última atualização: outubro de 2026 — revisão para o Go 1.27 (métodos genéricos, encoding/json/v2, patch 1.27.1) e Go 1.26 (Green Tea GC por padrão). Revisão anterior (setembro de 2026): 20 perguntas de Go moderno (loop var do Go 1.22, iteradores, generics, errors.Join, slog, GOMEMLIMIT, GOMAXPROCS container-aware) e de nível sênior.