Como passar em uma entrevista de Go: principais perguntas de nível avançado

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Entrevista avançada de Go: de goroutines a genéricos

\n\n

A entrevista para uma posição de desenvolvedor Go de nível médio ou sênior não é apenas uma verificação de sintaxe. Os empregadores esperam um profundo entendimento do modelo de concorrência, funcionamento do runtime, gerenciamento de memória e particularidades da tipagem. Neste artigo, analisaremos as principais perguntas avançadas sobre Golang que ajudarão você a passar com confiança em uma entrevista técnica. Não vamos nos ater a conceitos básicos como "o que é uma slice" — vamos direto para tópicos complexos com exemplos de código.

\n\n

1. Goroutines, canais e padrões de sincronização

\n\n

Perguntas sobre goroutines e canais são clássicas em qualquer entrevista. No entanto, em nível avançado, perguntarão não apenas "o que é uma goroutine", mas também sobre os detalhes do funcionamento do escalonador (modelo GMP) e o uso correto de primitivas de sincronização.

\n\n

Pergunta: Como funciona o escalonador de goroutines em Go? O que são G, M, P?

\n

O escalonador Go usa o modelo GMP: G (goroutine) — thread leve, M (machine) — thread do SO, P (processor) — contexto de execução. P está vinculado a um processador lógico e gerencia a fila de goroutines. Quando uma goroutine é bloqueada (por exemplo, em uma chamada de sistema), P pode alternar M para outra goroutine, garantindo multitarefa eficiente sem criar milhares de threads do SO.

\n\n

Pergunta: Qual é a diferença entre um canal bufferizado e não bufferizado? Dê um exemplo de deadlock.

\n\n
// Canal não bufferizado — bloqueia o remetente até o recebimento\nch := make(chan int)\ngo func() {\n    ch <- 42 // bloqueia até main ler\n}()\nfmt.Println(<-ch) // 42\n\n// Canal bufferizado — não bloqueia enquanto o buffer não estiver cheio\nchBuf := make(chan int, 2)\nchBuf <- 1\nchBuf <- 2 // ok, buffer não está cheio\n// chBuf <- 3 // deadlock, se não houver leitor\n\n// Deadlock típico: leitura de um canal não bufferizado vazio\nchDead := make(chan int)\n// <-chDead // fatal error: all goroutines are asleep — deadlock!\n
\n\n

Pergunta: Como fechar um canal com segurança? O que é "range over channel"?

\n

Apenas o remetente deve fechar o canal. O receptor pode usar o segundo parâmetro (v, ok := <-ch) para verificar. A iteração for v := range ch termina quando o canal é fechado. Tentar escrever em um canal fechado causa pânico.

\n\n
ch := make(chan int)\ngo func() {\n    for i := 0; i < 3; i++ {\n        ch <- i\n    }\n    close(ch) // obrigatório fechar\n}()\nfor v := range ch {\n    fmt.Println(v) // 0, 1, 2\n}\n
\n\n

2. Interfaces, interface vazia e type assertions

\n\n

Interfaces em Go são contratos. Na entrevista, é importante entender como elas são estruturadas internamente (estrutura iface e eface) e a diferença entre tipagem estática e dinâmica.

\n\n

Pergunta: O que é uma interface vazia (interface{}) e quando usá-la?

\n

A interface vazia não contém métodos, portanto qualquer tipo a implementa. É usada para trabalhar com dados de tipo desconhecido (por exemplo, json.Unmarshal). No entanto, o uso excessivo da interface vazia viola a tipagem forte do Go e pode levar a erros em tempo de execução.

\n\n

Pergunta: Como funciona o type assertion? Qual a diferença do type switch?

\n\n
var val interface{} = "hello"\n\n// type assertion\nstr, ok := val.(string)\nif ok {\n    fmt.Println("É uma string:", str)\n}\n\n// type switch\nswitch v := val.(type) {\ncase string:\n    fmt.Println("String:", v)\ncase int:\n    fmt.Println("Número:", v)\ndefault:\n    fmt.Println("Tipo desconhecido")\n}\n
\n\n

Pergunta: Como as interfaces são armazenadas na memória?

\n

Cada interface é composta por dois ponteiros: um para o tipo (itable) e outro para o valor (data). Para a interface vazia (interface{}), c

Blogs

Book Recommendations