Entrevistas de Java backend cobrem a semântica central da linguagem, collections, concorrência, Spring e como você raciocina sobre a JVM. Abaixo estão as perguntas mais frequentes, cada uma com uma resposta modelo. Junior: teoria básica, definições e casos práticos simples.
1
Qual é a diferença entre == e equals() para objetos?
Resposta
== compara referências — se duas variáveis apontam para o mesmo objeto na memória. equals() compara conteúdo, se a classe o sobrescreve; o Object.equals padrão cai de volta no ==. É por isso que comparar duas Strings construídas em runtime com == retorna false enquanto equals() retorna true, e essa é a pegadinha mais comum em entrevistas de Java.
2
Qual é a diferença entre uma interface e uma classe abstrata?
Resposta
Uma classe abstrata pode ter estado e construtores e descreve o que algo é; uma classe só pode estender uma. Uma interface descreve o que algo pode fazer e uma classe pode implementar várias. Desde o Java 8 as interfaces podem ter métodos default, então a regra prática é: estado compartilhado significa classe abstrata, capacidade compartilhada significa interface.
3
O que é autoboxing e onde ele morde?
Resposta
Autoboxing é o compilador convertendo automaticamente entre primitivos e seus wrappers. Ele morde em dois lugares: comparar wrappers com == funciona por acidente para valores pequenos por causa do cache de Integer entre -128 e 127 e depois para de funcionar silenciosamente, e fazer unboxing de um Integer null lança NullPointerException numa linha que parece aritmética comum.
4
Explique final, finally e finalize.
Resposta
Apesar dos nomes parecidos, não têm relação. final torna uma variável não reatribuível, um método não sobrescrevível, ou uma classe não extensível. finally é o bloco que roda independentemente de ter sido lançada uma exceção, usado para limpeza. finalize era um método que o garbage collector podia chamar antes de recolher um objeto; era pouco confiável e está deprecated — use try-with-resources em vez disso.
5
Qual é a diferença entre ArrayList e LinkedList?
Resposta
ArrayList envolve um array redimensionável: o acesso por índice é O(1), mas inserir no meio desloca tudo que vem depois. LinkedList é uma lista duplamente encadeada: inserir num nó conhecido é O(1), mas chegar ao índice n custa n passos e cada elemento carrega overhead de ponteiro. Na prática o ArrayList vence quase sempre, porque a localidade de cache supera o big-O no hardware real.
6
O que a palavra-chave static realmente significa?
Resposta
Um membro static pertence à classe, não a uma instância, então existe uma única vez independentemente de quantos objetos você criar e pode ser usado sem um. A consequência que as pessoas esquecem é que um campo static é estado mutável compartilhado por toda a aplicação — conveniente para constantes, fonte de bugs difíceis para qualquer coisa que muda.
7
Qual é a diferença entre exceções checked e unchecked?
Resposta
Checked estendem Exception e o compilador obriga você a capturar ou declarar; descrevem condições das quais quem chama pode razoavelmente se recuperar, como um arquivo ausente. Unchecked estendem RuntimeException e sinalizam erros de programação — uma referência nula, um argumento inválido. Use unchecked para bugs, e checked com moderação, porque forçar todo chamador a tratar algo costuma gerar blocos catch vazios.
8
Qual é o contrato entre `equals()` e `hashCode()`?
Resposta
Se dois objetos são iguais, eles devem retornar o mesmo hash code; o inverso não é exigido. Quebre isso e um HashMap para de funcionar — você guarda um objeto, procura por um igual a ele e recebe null, porque a busca foi parar em outro bucket. Por isso sobrescrever um sem o outro é um bug, não uma questão de estilo.
9
Por que `String` é imutável em Java?
Resposta
Porque ela é compartilhada. Os literais vivem no string pool e uma instância pode ser referenciada de vários lugares, então uma string mutável deixaria um detentor mudar o valor de outro. A imutabilidade também torna as strings thread-safe sem sincronização, permite cachear o hash code e as mantém seguras para uso em class loading e parâmetros de conexão, onde uma mudança tardia seria uma brecha de segurança.
10
Dá para sobrescrever um método static?
Resposta
Não — você só pode escondê-lo. O overriding é resolvido em tempo de execução a partir do tipo do objeto, enquanto um método static é resolvido em tempo de compilação a partir do tipo da referência. Então uma subclasse que declara a mesma assinatura static não substitui a da classe pai; qual delas roda depende do tipo declarado, não do objeto real, e é exatamente por isso que chamar um static através de uma referência de instância é desaconselhado.