Currículo de Desenvolvedor Web: Guia Completo
Na competitiva área de desenvolvimento web, um currículo bem estruturado pode ser a diferença entre conseguir uma entrevista ou ser ignorado. Tanto no...
Leia mais →As entrevistas de engenharia de software avaliam competências amplas: da resolução de problemas de código ao design de sistemas, passando por como você colabora sob pressão. Este guia cobre as perguntas comportamentais, técnicas e situacionais mais comuns em processos seletivos de startups a grandes empresas de tecnologia no Brasil, com respostas de exemplo baseadas no método STAR.
1. Conte sobre uma vez em que você discordou de uma decisão técnica tomada pelo seu time. Como você lidou com isso?
Resposta modelo
Na empresa anterior, o time queria adotar um banco NoSQL para uma funcionalidade que na verdade tinha consultas relacionais complexas, com múltiplos joins entre pedidos, pagamentos e estoque. Eu achava que um banco relacional seria mais adequado para esse padrão de acesso. Em vez de simplesmente discordar em voz alta na reunião, preparei um documento curto comparando as duas abordagens nos nossos padrões de consulta reais, com exemplos concretos de queries que precisaríamos escrever em cada modelo. Levei isso para a próxima revisão de design e propusemos rodar um spike de uma semana testando as duas opções com dados reais de produção anonimizados. Os números do spike confirmaram minha recomendação: a versão relacional era 3 vezes mais rápida nas consultas mais frequentes. O time mudou de abordagem sem constrangimento, porque a decisão se apoiou em dados concretos apresentados de forma objetiva. O aprendizado principal foi que evidência concreta facilita que as pessoas mudem de ideia sem perder a compostura.
2. Descreva um projeto em que você precisou aprender uma tecnologia nova rapidamente, sob pressão de prazo.
Resposta modelo
Tínhamos três semanas para lançar uma funcionalidade de acompanhamento de pedidos em tempo real que exigia WebSockets, algo que eu nunca tinha usado em produção antes. Organizei minhas manhãs para estudo focado: construí um protótipo descartável primeiro, li a documentação da biblioteca que usaríamos e depois analisei como projetos open source maiores tratavam casos extremos, como reconexão e ordenação de mensagens fora de sequência. Também pareei com um colega que já tinha experiência com WebSockets para revisar meu código antes de cada merge. Entregamos no prazo e a funcionalidade não teve nenhum incidente em produção no primeiro trimestre após o lançamento. O que aprendi foi que aprender sob pressão funciona melhor quando você constrói algo pequeno e descartável antes de tentar entender a teoria completa: a prática dá contexto para a leitura.
3. Dê um exemplo de uma vez em que você melhorou significativamente a performance de um sistema.
Resposta modelo
Nossa API voltada para o cliente tinha latência de 800ms no percentil 95. Fiz o profiling dos endpoints mais lentos e encontrei três padrões de consulta N+1 na camada de ORM. Reescrevi essas consultas com joins explícitos e adicionei um cache Redis para uma consulta de permissões de usuário que era lida com muita frequência e alterada raramente. A latência caiu para 120ms no p95. Convencer o time a investir o tempo necessário foi a parte mais difícil: construí um painel simples que ligava diretamente a latência à taxa de conversão no checkout, o que tornou o argumento de negócio óbvio para todo mundo, inclusive para quem não é técnico.
4. Conte sobre um projeto em que você trabalhou que falhou. O que você fez?
Resposta modelo
Lançamos uma funcionalidade de recomendação de vagas que levou dois meses para construir e teve engajamento próximo de zero. Otimizamos para taxa de clique, mas os usuários achavam as sugestões irrelevantes para o momento de carreira deles. Conduzi um post-mortem e identificamos a causa raiz: nunca conversamos com usuários reais antes de construir. Escrevi um resumo de uma página com os aprendizados e propus adicionar uma etapa de descoberta com entrevistas de usuário ao nosso processo de desenvolvimento de funcionalidades. Essa mudança de processo durou muito mais do que a funcionalidade em si: hoje temos uma etapa consistente de entrevista com usuários antes de qualquer construção relevante, e o time trata isso como não negociável.
1. Explique como você projetaria um encurtador de URLs como o bit.ly.
Resposta modelo
No núcleo, você precisa de duas operações: escrita (dada uma URL longa, retornar um código curto) e leitura (dado um código curto, redirecionar para a URL original). Para o código curto, eu usaria codificação Base62 de um ID autoincremental, o que dá cerca de 3,5 bilhões de códigos com 6 caracteres. O caminho de escrita grava no banco de dados e armazena o mapeamento em cache. O caminho de leitura é cache-first, com fallback para o banco de dados. Em escala, leituras superam escritas em muitas ordens de grandeza, então a taxa de acerto do cache é o fator crítico de performance. Eu adicionaria limitação de taxa nas escritas para evitar abuso, e armazenaria data de criação, ID do usuário e analytics de cliques em uma tabela separada, para manter o caminho de leitura enxuto e rápido.
2. Qual é a diferença entre um processo e uma thread? Quando você usaria um em vez do outro?
Resposta modelo
Um processo é um programa independente em execução, com seu próprio espaço de memória isolado. Uma thread é uma unidade de execução mais leve dentro de um processo, compartilhando memória com outras threads do mesmo processo. Uso threads quando as tarefas precisam se comunicar com frequência e compartilhar estado: são mais baratas de criar e trocar de contexto. Uso processos quando preciso de isolamento: se um cair, os outros continuam rodando. Na prática, recorro a threads para paralelismo ligado a CPU dentro de um único serviço, e a processos quando preciso de isolamento de memória ou de rodar serviços separados. Em Python, o GIL faz com que threads não entreguem paralelismo real de CPU, então multiprocessing costuma ser a escolha certa para trabalho pesado de CPU nessa linguagem.
3. Explique o conceito de consistência eventual. Dê um exemplo de quando você aceitaria esse modelo.
Resposta modelo
Consistência eventual significa que um sistema distribuído vai retornar o mesmo valor para uma chave em todos os nós, mas não necessariamente de forma imediata. As escritas se propagam de forma assíncrona, então leituras feitas logo após uma escrita podem retornar dados desatualizados por um curto período. Eu aceitaria consistência eventual para casos como contadores de curtidas em redes sociais, sincronização de preferências do usuário entre dispositivos ou atualização de estoque em um catálogo de e-commerce, onde ficar levemente desatualizado por um ou dois segundos não causa dano real. Eu não aceitaria esse modelo para transações financeiras, tokens de autenticação ou qualquer situação em que dados desatualizados possam gerar um resultado de negócio incorreto ou um problema de segurança, como em transferências via Pix, onde o saldo precisa refletir o estado real no momento da confirmação.
4. Como funciona a coleta de lixo (garbage collection) em uma linguagem que você conhece bem? Quais são os trade-offs?
Resposta modelo
Em Java, a JVM usa um coletor de lixo geracional. O heap é dividido em gerações jovem e antiga, de acordo com o tempo de vida dos objetos. A maioria dos objetos morre jovem, então o coletor roda GCs menores e baratos com frequência na geração jovem. Objetos que sobrevivem a várias coletas são promovidos para a geração antiga, coletada com menos frequência, mas de forma mais custosa. Os coletores G1 e ZGC minimizam pausas de stop-the-world fazendo a maior parte do trabalho de forma concorrente. O trade-off é overhead de memória e latência de pausa imprevisível: a coleta de lixo essencialmente troca throughput por gerenciamento automático de memória. Em sistemas sensíveis a latência já ajustei tamanhos de heap e configurações de GC e, em casos extremos, movi alocações do caminho quente para fora do heap para evitar a pressão de coleta por completo.
1. Você está no meio de uma sprint quando descobre uma vulnerabilidade de segurança crítica em uma biblioteca da qual seu sistema depende. O que você faz?
Resposta modelo
Primeiro avalio a severidade e a exploitabilidade: essa vulnerabilidade está sendo explorada ativamente e o nosso padrão de uso da biblioteca nos expõe? Se sim, escalo imediatamente para o tech lead e o time de segurança, e tratamos isso como incidente, não como tarefa normal de sprint. Procuro primeiro uma versão corrigida da biblioteca. Se não existir, verifico se conseguimos mitigar no nosso próprio código enquanto esperamos o patch, ou se faz sentido trocar de biblioteca. Comunico o status com clareza: quem é afetado, qual é o risco, o que estamos fazendo e qual é o prazo. O escopo da sprint muda como consequência: a correção da vulnerabilidade entra primeiro, mesmo que isso signifique adiar outras entregas planejadas para a sprint seguinte.
2. Você é designado para uma base de código legada, sem testes e sem documentação. Precisa adicionar uma funcionalidade significativa. Como você aborda isso?
Resposta modelo
Não mexo em nada antes de entender o comportamento atual. No primeiro dia, mapeio os pontos de entrada do código, o fluxo de dados e as dependências principais, rodando o sistema localmente e rastreando requisições pelo código. Antes de escrever qualquer código novo, adiciono testes de caracterização nas áreas que preciso alterar: testes que capturam o comportamento atual, não o comportamento ideal. Esses testes viram minha rede de segurança. Depois faço as menores mudanças possíveis para adicionar a funcionalidade, com testes unitários adequados para o código novo. Resisto à vontade de refatorar tudo que me incomoda: isso é uma conversa separada com o time, com seu próprio prazo e avaliação de risco, e não deve ser misturada com a entrega da funcionalidade pedida.
3. Seu time está discutindo duas abordagens arquiteturais. O engenheiro sênior prefere uma abordagem que você considera excessivamente complexa. Como você lida com isso?
Resposta modelo
Primeiro garanto que entendi completamente a abordagem dele antes de contestar: às vezes a complexidade existe por boas razões que eu ainda não enxerguei. Faço perguntas para entender as restrições que ele está otimizando. Se depois disso eu ainda achar que minha abordagem é melhor, escrevo uma comparação breve: os trade-offs de cada opção, o que ganhamos e o que perdemos em cada uma, e minha recomendação com a justificativa. Apresento como 'é assim que estou vendo, estou deixando passar alguma coisa?', em vez de simplesmente afirmar que estou certo. Se, depois da discussão, o engenheiro sênior ainda preferir a abordagem dele, eu me comprometo com ela e executo bem: divergências arquiteturais merecem um bom debate, não uma discussão contínua que trava o time inteiro.
4. Pedem para você estimar quanto tempo uma funcionalidade vai levar, mas os requisitos ainda não estão claros. O que você faz?
Resposta modelo
Eu não dou um número único para um escopo pouco claro: esse número vai sair errado e depois eu vou ser cobrado por ele. Em vez disso, faço perguntas de esclarecimento para entender o requisito principal e identificar as incertezas de maior risco. Depois dou uma faixa: 'com base no que sei hoje, isso é de 3 a 5 dias, mas essas três perguntas em aberto podem levar o prazo para 2 semanas.' Deixo claro o que preciso para reduzir a estimativa: uma decisão sobre o comportamento de um caso extremo, acesso a um sistema específico ou um dia para investigar a parte que não conheço bem. Boas estimativas nascem de uma conversa, não de um prazo tirado do ar.
Pense em voz alta durante os problemas técnicos: o processo importa tanto quanto a solução final. Para perguntas comportamentais, prepare de 5 a 6 histórias fortes da sua experiência que possam se adaptar a diferentes tipos de pergunta. Se você não souber uma resposta, diga isso e mostre como chegaria a ela.
Experimente uma entrevista simulada grátis
Pratique estas perguntas com IA
Na competitiva área de desenvolvimento web, um currículo bem estruturado pode ser a diferença entre conseguir uma entrevista ou ser ignorado. Tanto no...
Leia mais →
Na competitiva área de tecnologia, um currículo bem estruturado pode ser o diferencial entre conseguir ou não a entrevista desejada. Profissionais de TI...
Leia mais →
Um currículo bem estruturado é essencial para engenheiros que desejam impressionar recrutadores e destacar-se em processos seletivos competitivos. Os...
Leia mais →Precisa de um currículo primeiro? Ver exemplo de currículo para Engenheiro de Software →