10 Perguntas Avançadas de Entrevista para SDET, Automação e GenAI (2026) — Com Respostas
Por Himanshu Agarwal · himanshuai.com
A barra para funções de teste sêniores em 2026 não é mais "você consegue escrever um script Selenium?" — é se você consegue raciocinar sobre concorrência, testes instáveis, segurança de API, e a nova pilha de testes de IA (LLMs, RAG, MCP) em voz alta, com trade-offs e exemplos reais.
Abaixo estão 10 perguntas reais de entrevista — abrangendo todos os 9 domínios — respondidas da maneira que um SDET Sênior ou Arquiteto de Testes responderia. Esta é uma prévia gratuita do meu guia completo de 112 páginas.
📘 Primeiro — pegue o guia completo
Este artigo é uma prévia gratuita de 10 perguntas. O ebook completo de 112 páginas contém 50 perguntas aprofundadas + 150 perguntas de acompanhamento totalmente respondidas (200 Q&A no total) sobre Java, Python, REST Assured, Teste de API, Automação, Teste de IA, LLM, RAG & MCP — cada uma com uma explicação técnica profunda, um exemplo real de empresa, erros comuns e a exata "melhor resposta" a ser dada na sala. Além de um roteiro de entrevista de 30 dias.
👉 Obtenha o guia completo no Gumroad: >>https://himanshuai.gumroad.com/l/200InterviewSDETtoAITestArchitectQnA2026<<
1. Internos do ConcurrentHashMap & Segurança de Thread
Categoria: Core Java
Dificuldade: ⭐⭐⭐⭐⭐
Categoria: Java
Experiência de Entrevista: Os entrevistadores perguntam isso para separar pessoas que usam ConcurrentHashMap de pessoas que entendem por que ele é seguro. Em um framework de teste que executa centenas de threads paralelas, um mapa compartilhado ingênuo é a fonte mais comum de falhas instáveis e não reproduzíveis. Eles querem ver se você entende a granularidade do bloqueio, a visibilidade da memória e a diferença entre "seguro para thread" e "atômico entre operações".
Pergunta
Como o ConcurrentHashMap alcança segurança de thread no Java moderno, e por que um mapa seguro para thread ainda não é suficiente para tornar map.get() seguido de map.put() correto?
Resposta
O ConcurrentHashMap fornece segurança de thread através de sincronização fina, a nível de balde, em vez de bloquear todo o mapa. Desde o Java 8, ele abandonou o antigo bloqueio baseado em segmentos e, em vez disso, sincroniza no primeiro nó de cada balde, usa CAS (compare-and-swap) para inserção em baldes vazios e trata leituras como livres de bloqueio, confiando na semântica volatile da tabela e dos nós. Ele é seguro para operações individuais, mas uma sequência verificar-então-agir como if (!map.containsKey(k)) map.put(k, v) ainda é uma condição de corrida porque outra thread pode intercalar entre as duas chamadas. Você deve usar os métodos atômicos compostos — putIfAbsent, computeIfAbsent, compute, merge — para tornar toda a operação atômica.
Explicação Técnica Profunda
-
Estrutura: um array de baldes (
Node[] table). Cada balde é vazio, uma lista encadeada ou (uma vez que excede o limite de treeify de 8 nós com tamanho da tabela ≥ 64) uma árvore rubro-negra. -
Escritas: para inserir em um balde vazio, ele usa um CAS na posição do array — nenhum bloqueio necessário. Se o balde estiver ocupado, ele
synchronized-bloqueia no nó cabeça desse balde apenas, então a contenção é limitada às chaves que hash para o mesmo balde. -
Leituras:
get()não adquire nenhum bloqueio. A correção vem de leiturasvolatileda referência da tabela e dos valores dos nós, que estabelecem as relações necessárias de acontece-antes para que um leitor veja uma gravação concluída. -
Redimensionamento: múltiplas threads podem cooperativamente ajudar a transferir baldes durante um redimensionamento usando um marcador
ForwardingNode, evitando uma rehash que para o mundo. -
Por que operações compostas importam: cada método é individualmente atômico, mas a atomicidade não se compõe.
computeIfAbsent(key, k -> expensiveInit())garante que a função de mapeamento seja executada no máximo uma vez por chave ausente sob o bloqueio do balde, que é exatamente o que você deseja para inicialização preguiçosa, uma vez apenas.
Exemplo Real de Empresa
Em um mecanismo de execução paralela estilo Selenium Grid, armazenamos em cache WebDriver fábricas indexadas por navegador+versão. O código original fazia if (!cache.containsKey(key)) cache.put(key, buildDriver()). Sob 200 threads paralelas, isso construía o mesmo driver duas vezes para a mesma chave, vazando sessões e esgotando a grade. Substituí-lo por cache.computeIfAbsent(key, k -> buildDriver()) garantiu a construção exatamente uma vez e eliminou o vazamento.
Erros Comuns
- Afirmar que
ConcurrentHashMapainda usa segmentos (removido no Java 8). - Dizer que leituras levam um bloqueio (não levam).
- Usar
containsKey+pute assumir que é seguro. - Colocar chaves ou valores
null(diferente deHashMap, ele proíbe ambos — precisamente para que um retornonulldegetseja inequívoco sob concorrência).
Melhor Resposta na Entrevista
"É seguro para thread por operação via bloqueio a nível de balde synchronized mais CAS em baldes vazios, com leituras livres de bloqueio através de semântica volatile. Mas a atomicidade não se compõe, então para verificar-então-agir eu uso computeIfAbsent ou merge em vez de containsKey + put."
Perguntas de Acompanhamento
(As respostas detalhadas a essas perguntas de acompanhamento estão no guia completo de 112 páginas.)
- Por que
computeIfAbsentalerta contra modificar o mesmo mapa dentro da função de mapeamento? - Como o limite de treeification interage com uma má distribuição de
hashCode? -
Contraste isso com
Collections.synchronizedMap— por que é pior sob contenção?Principais Conclusões
Bloqueio a nível de balde + CAS + leituras livres de bloqueio.
A atomicidade não se compõe — use os métodos atômicos compostos.
Sem chaves ou valores nulos, por design.
2. O GIL do Python & Verdadeira Concorrência
Categoria: Python
Dificuldade: ⭐⭐⭐⭐⭐
Categoria: Python
Experiência de Entrevista: O GIL é o único tópico mais mal compreendido em entrevistas de Python. Os entrevistadores perguntam isso para ver se você consegue escolher o modelo de concorrência certo para uma carga de trabalho em vez de recorrer reflexivamente a threads. Para um SDET, isso decide se a geração de dados de teste ou a simulação de carga realmente utiliza a máquina.
Pergunta
Explique o GIL e, dado uma tarefa vinculada à CPU, uma tarefa vinculada à I/O e um enorme número de chamadas HTTP concorrentes, diga-me qual modelo de concorrência você escolheria para cada um e por quê.
Resposta
O Global Interpreter Lock é um mutex no CPython que permite que apenas uma thread execute bytecode Python por vez, então as threads não podem executar código Python verdadeiramente em paralelo em múltiplos núcleos. Para trabalho vinculado à CPU, eu uso multiprocessing (ou um ProcessPoolExecutor) para contornar o GIL com interpretadores separados entre processos. Para trabalho vinculado à I/O, as threads são adequadas porque o GIL é liberado durante a I/O bloqueante, então as threads sobrepõem suas esperas. Para HTTP massivo concorrente, asyncio é o melhor — uma única thread multiplexando cooperativamente.
As empresas brasileiras precisam se adaptar às novas exigências de testes automatizados, especialmente com a integração de IA. O conhecimento sobre a pilha de testes de IA e a capacidade de raciocinar sobre concorrência são cruciais para garantir a qualidade do software. Preparar equipes para essas competências pode melhorar a eficiência e a segurança dos processos de desenvolvimento.


