Por ser uma linguagem de pro­gra­ma­ção am­pla­mente utilizada, o Java e seus recursos ex­clu­si­vos são bem co­nhe­ci­dos pelos re­cru­ta­do­res. É por isso que as perguntas sobre vários aspectos do Java costumam ser feitas nas primeiras etapas de uma en­tre­vista. Com­pi­la­mos uma lista de dez perguntas fre­quen­tes para de­sen­vol­ve­do­res de Java e incluímos respostas para cada uma delas.

Este artigo fornece uma visão geral das possíveis perguntas que podem ser feitas sobre Java em uma en­tre­vista de emprego para de­sen­vol­ve­do­res. De­pen­dendo do nível de ex­pe­ri­ên­cia pro­fis­si­o­nal exigido para a função, algumas perguntas podem ser mais de­ta­lha­das. Às vezes, em en­tre­vis­tas para cargos sênior, são apre­sen­ta­dos cenários que contêm erros de­li­be­ra­dos ou são cla­ra­mente enganosos para testar o co­nhe­ci­mento técnico da pessoa que está sendo en­tre­vis­tada para o cargo. Por isso, é im­por­tante estar bem preparado para a en­tre­vista.

Pergunta 1: Quais são os recursos especiais do Java e que vantagens a linguagem de pro­gra­ma­ção oferece?

Java é uma linguagem poderosa e am­pla­mente utilizada, o que a tornou uma linguagem de pro­gra­ma­ção popular para aprender. Vários recursos ex­clu­si­vos fazem com que o Java se destaque, prin­ci­pal­mente na forma como é usado. Uma das prin­ci­pais vantagens do Java é que seu código pode ser executado em vários sistemas ope­ra­ci­o­nais sem nenhuma mo­di­fi­ca­ção.

Essa fle­xi­bi­li­dade é pos­si­bi­li­tada pela Máquina Virtual Java, que garante que o de­sen­vol­vi­mento e o apli­ca­tivo não fiquem restritos a uma pla­ta­forma es­pe­cí­fica, per­mi­tindo que o código seja usado em várias pla­ta­for­mas. Isso garante que os programas sejam exe­cu­ta­dos de forma flexível e eficiente em vários dis­po­si­ti­vos.

Outra vantagem do Java é o ge­ren­ci­a­mento au­to­má­tico de memória fornecido pelo Garbage Collector, que sim­pli­fica o ge­ren­ci­a­mento de recursos de memória e reduz possíveis erros. Além disso, as extensas bi­bli­o­te­cas padrão do Java com muitas funções prontas aceleram o de­sen­vol­vi­mento de apli­ca­ti­vos.

Como uma linguagem de pro­gra­ma­ção orientada a objetos, o Java, assim como outras lin­gua­gens dessa categoria, se destaca porque os com­po­nen­tes de software podem ser modelados com mais fa­ci­li­dade e o código pode ser reu­ti­li­zado re­pe­ti­da­mente.

Pergunta 2: Como o Java lida com a herança múltipla?

Em princípio, o Java não suporta herança múltipla de classes. Isso significa que as classes só podem herdar de uma única classe. A herança múltipla pode afetar ne­ga­ti­va­mente o código na pro­gra­ma­ção orientada a objetos, sendo um problema bem conhecido o problema do diamante.

Embora a herança múltipla não seja possível para classes em Java, isso pode ser resolvido com o uso de in­ter­fa­ces. Como uma classe pode im­ple­men­tar várias in­ter­fa­ces em Java, ela pode herdar fun­ci­o­na­li­da­des de di­fe­ren­tes fontes. Essa atri­bui­ção garante que as funções sejam cla­ra­mente definidas e que não ocorram problemas com herança múltipla.

Pergunta 3: Qual é a diferença entre uma classe abstrata e uma interface em Java?

Tanto as classes abstratas quanto as in­ter­fa­ces são usadas em Java para definir tipos abstratos, que podem ser im­ple­men­ta­dos por outras classes. Há di­fe­ren­ças sig­ni­fi­ca­ti­vas, prin­ci­pal­mente quando se trata de regras de herança:

  • Inhe­ri­tance: Em Java, uma classe só pode herdar de uma classe abstrata. As classes abstratas, por sua vez, não podem realizar herança múltipla, o que significa que várias in­ter­fa­ces devem ser im­ple­men­ta­das para isso.
  • Re­la­ci­o­na­mento entre classes: como uma classe só pode herdar de uma classe abstrata, o uso de classes abstratas é mais adequado para re­la­ci­o­na­men­tos do tipo “é um”, enquanto as in­ter­fa­ces são mais adequadas para re­la­ci­o­na­men­tos do tipo “pode”.
  • Con­cre­te­ness: Uma classe abstrata pode conter métodos abstratos (não im­ple­men­ta­dos) e concretos (im­ple­men­ta­dos) e também pode ter variáveis de instância. Por outro lado, as in­ter­fa­ces só podem definir métodos abstratos e cons­tan­tes. Todos os métodos em uma interface são im­pli­ci­ta­mente abstratos e públicos.
  • Func­ti­o­na­lity: As classes abstratas dependem do com­par­ti­lha­mento de uma im­ple­men­ta­ção comum (e da im­ple­men­ta­ção de várias in­ter­fa­ces). As in­ter­fa­ces, por outro lado, são pro­je­ta­das para declarar funções es­pe­cí­fi­cas, que são então im­ple­men­ta­das em di­fe­ren­tes classes.

Pergunta 4: Qual é a diferença entre variáveis de instância e variáveis locais?

A principal diferença entre as variáveis de instância e as variáveis locais está em seu escopo e tempo de vida. As variáveis de instância são prin­ci­pal­mente pro­pri­e­da­des de um objeto em uma classe. As variáveis locais re­pre­sen­tam valores criados tem­po­ra­ri­a­mente em um escopo es­pe­cí­fico.

Variáveis de instância

  • Variáveis de instância são variáveis de­cla­ra­das no nível da classe, fora dos métodos, cons­tru­to­res e blocos.
  • Cada objeto de uma classe tem sua própria cópia de uma variável de instância.
  • As variáveis de instância são acessadas por meio da instância de uma classe. Os valores podem ser di­fe­ren­tes para cada objeto da classe.

Variáveis locais

  • As variáveis locais são de­cla­ra­das dentro de um método, de um cons­tru­tor ou de um bloco. Sua validade é limitada a essa área definida.
  • Essas variáveis devem ser ex­pli­ci­ta­mente ini­ci­a­li­za­das antes do uso e existem somente durante a execução do bloco de código.
  • Eles não são visíveis fora do bloco de código em que foram de­cla­ra­dos.

Pergunta 5: O que sig­ni­fi­cam os termos JVM, JDK e JRE e como eles diferem uns dos outros?

Embora esses termos possam parecer se­me­lhan­tes quando abre­vi­a­dos, suas tarefas sub­ja­cen­tes e seu escopo no Java são fun­da­men­tal­mente di­fe­ren­tes.

Java Virtual Machine (JVM)

  • A máquina virtual Java (JVM) é uma máquina virtual que serve como interface entre o programa Java e o hardware sub­ja­cente **ou sistema ope­ra­ci­o­nal, exe­cu­tando o bytecode Java.
  • A JVM é fun­da­men­tal porque, como um ambiente de tempo de execução, pode executar o mesmo bytecode em di­fe­ren­tes sistemas ope­ra­ci­o­nais, desde que esteja dis­po­ní­vel nas res­pec­ti­vas pla­ta­for­mas. Isso contribui sig­ni­fi­ca­ti­va­mente para a por­ta­bi­li­dade do Java.
  • Essa por­ta­bi­li­dade é pos­si­bi­li­tada pelo com­pi­la­dor Java que traduz o código-fonte Java em bytecode, que a JVM in­ter­preta.

Java De­ve­lop­ment Kit (JDK)

  • O Java De­ve­lop­ment Kit (JDK) é o pacote de de­sen­vol­vi­mento completo, que reúne várias fer­ra­men­tas que auxiliam no de­sen­vol­vi­mento de apli­ca­ti­vos Java. Ele inclui fer­ra­men­tas para criação, com­pi­la­ção e depuração de apli­ca­ti­vos.
  • O JDK contém o com­pi­la­dor Java, a Java Virtual Machine (JVM), o depurador Java e o profiler Java.
  • Além dessas fer­ra­men­tas, o JDK inclui um grande número de classes e in­ter­fa­ces pre­de­fi­ni­das para funções usadas com frequên­cia que estão dis­po­ní­veis na API Java ou na bi­bli­o­teca de classes Java.

Java Runtime En­vi­ron­ment (JRE)

  • O Java Runtime En­vi­ron­ment (JRE) fornece um ambiente reduzido onde os apli­ca­ti­vos Java podem ser exe­cu­ta­dos.
  • O JRE contém a Máquina Virtual Java (JVM) e a Java API, ambas ne­ces­sá­rias para iniciar e executar apli­ca­ti­vos.
  • As fer­ra­men­tas de de­sen­vol­vi­mento, como o com­pi­la­dor Java, não estão incluídas no JRE, portanto, ele é nor­mal­mente instalado por usuários finais.

Pergunta 6: O que são classes de coleção em Java e para que elas são usadas?

Em Java, o termo classe de coleção ge­ral­mente se refere a classes que fazem parte da estrutura de coleções Java. Essa estrutura fornece uma maneira pa­dro­ni­zada de armazenar, organizar e manipular grupos de objetos. Ela consiste em várias in­ter­fa­ces e im­ple­men­ta­ções concretas de es­tru­tu­ras de dados.

As classes de coleção são usadas para várias fi­na­li­da­des:

  • Or­ga­ni­za­ção de dados: Permitem a or­ga­ni­za­ção eficiente de dados em listas, conjuntos ou mapas.
  • Ma­ni­pu­la­ção de dados: fornecem métodos para adicionar, remover e pesquisar elementos.
  • Pro­gra­ma­ção genérica: o uso de tipos genéricos em classes de coleção permite a criação de códigos reu­ti­li­zá­veis e seguros quanto ao tipo.
  • Al­go­rit­mos: a estrutura também contém al­go­rit­mos que operam em es­tru­tu­ras de dados (por exemplo, clas­si­fi­ca­ção ou pesquisa).

Pergunta 7: Qual é a diferença entre == e equals() em Java?

== e equals() são dois me­ca­nis­mos di­fe­ren­tes ou ope­ra­do­res que são usados para comparar objetos:

  • O == operador compara as re­fe­rên­cias de objetos, não seus valores de conteúdo. Quando usado com objetos, == verifica se as duas re­fe­rên­cias apontam para o mesmo objeto (, ou seja, se referem à mesma área de memória). Em contraste, com tipos de dados pri­mi­ti­vos (e.g., char, int ou byte), o operador cor­res­ponde aos valores.
  • Com equals(), você pode comparar o conteúdo de objetos para de­ter­mi­nar se os objetos são iguais, mesmo que estejam em locais de memória di­fe­ren­tes. Por padrão, equals() comporta-se como ==, herdando a lógica de com­pa­ra­ção de re­fe­rên­cia da classe Object. No entanto, ge­ral­mente é ne­ces­sá­rio substituí-la em classes definidas pelo usuário para permitir uma com­pa­ra­ção sig­ni­fi­ca­tiva de conteúdo.

Pergunta 8: Para que são usados os cons­tru­to­res?

Os cons­tru­to­res são métodos especiais em uma classe usada para ins­tan­ciar e ini­ci­a­li­zar objetos. As quatro prin­ci­pais tarefas dos cons­tru­to­res são:

  • Ini­ci­a­li­za­ção de objetos: Os cons­tru­to­res são usados prin­ci­pal­mente para colocar um objeto em um estado válido e ini­ci­a­li­zado assim que ele é criado. Os atributos são ini­ci­a­li­za­dos e os recursos ne­ces­sá­rios são alocados.
  • Parameter passing: Os cons­tru­to­res podem aceitar pa­râ­me­tros para criar di­fe­ren­tes ins­tân­cias da classe com pro­pri­e­da­des variadas, per­mi­tindo a criação de objetos com valores de atributos es­pe­cí­fi­cos.
  • Ge­ren­ci­a­mento de código: O uso de cons­tru­to­res melhora a le­gi­bi­li­dade do código, pois a ini­ci­a­li­za­ção do objeto pode ser realizada di­re­ta­mente no cons­tru­tor. Isso também sim­pli­fica a ma­nu­ten­ção do código, pois as al­te­ra­ções na lógica de ini­ci­a­li­za­ção só precisam ser feitas em um único local.
  • Inhe­ri­tance: Os cons­tru­to­res de­sem­pe­nham um papel im­por­tante na hi­e­rar­quia de herança. Uma classe derivada nor­mal­mente chama o cons­tru­tor da classe base para lidar com sua ini­ci­a­li­za­ção antes de executar suas próprias ini­ci­a­li­za­ções.
Dica

Além das perguntas sobre in­ter­fa­ces, classes e similares, há outras áreas do Java que podem surgir em uma en­tre­vista. Aqui estão outros artigos que você pode ler para se preparar:

Pergunta 9: Java usa vários tipos di­fe­ren­tes de cadeia de ca­rac­te­res. Quais são eles e como diferem uns dos outros?

Em Java, o tipo string é re­pre­sen­tado pela classe java.lang.String. Essa classe é a principal maneira de re­pre­sen­tar cadeias de ca­rac­te­res. Ela também oferece várias opções para ma­ni­pu­la­ção e pro­ces­sa­mento de strings:

  • String­Buil­der: essa classe é usada para criar efi­ci­en­te­mente cadeias de ca­rac­te­res mo­di­fi­cá­veis em Java. Ao contrário da classe String imutável, ela permite al­te­ra­ções sem gerar uma nova instância.
  • String literal: refere-se a cadeias de ca­rac­te­res que são escritas entre aspas duplas, por exemplo "Nice to see you!". Literais de cadeia de ca­rac­te­res idênticos com­par­ti­lham uma instância no pool de cadeias de ca­rac­te­res para otimizar o uso da memória.
  • Objetos de cadeia de ca­rac­te­res: podem ser criados como uma nova instância usando a new palavra-chave, por exemplo, as new string ("Nice to see you!"). A instância é criada in­de­pen­den­te­mente do conteúdo.
  • String­Buf­fer: Como o String­Buil­der, essa classe cria cadeias de ca­rac­te­res mo­di­fi­cá­veis. A principal diferença é que String­Buf­fer é thread-safe, enquanto String­Buil­der não é.

Pergunta 10: O que distingue throw de throws?

Em Java, as palavras-chave throw e throws são ambas usadas para tratar exceções. Apesar dessa se­me­lhança, elas têm fi­na­li­da­des di­fe­ren­tes e são aplicadas em contextos di­fe­ren­tes:

  • throw é usado para lançar uma exceção ma­nu­al­mente. Os de­sen­vol­ve­do­res podem usar isso para gerar uma exceção e passá-la para o programa de chamada.
  • Em con­tra­par­tida, throws indica que um método é capaz de lançar uma exceção es­pe­cí­fica. Ele é usado na de­cla­ra­ção do método para es­pe­ci­fi­car quais exceções não podem ser tratadas pelo método, mas sim re­pas­sa­das ao chamador para tra­ta­mento, per­mi­tindo que o código reaja de acordo.
Ir para o menu principal