O princípio de trabalho do Hashmap é uma pergunta comum em entrevista em Java nos últimos anos. Quase todo programador Java conhece o Hashmap, sabe onde usar o Hashmap e sabe a diferença entre hashtable e hashmap. Então, por que essa pergunta de entrevista é tão especial? Isso ocorre porque essa pergunta é muito profunda. Essa pergunta geralmente aparece em entrevistas avançadas ou de nível intermediário. Os bancos de investimento preferem fazer essa pergunta e podem até solicitar que você implemente o HashMap para examinar suas habilidades de programação. A introdução do concorrente e outros conjuntos síncronos torna esse problema mais complicado. Vamos começar a jornada da exploração!
Vamos fazer algumas perguntas simples primeiro
"Você já usou o hashmap?" "O que é Hashmap? Por que você o usou?"
Quase todo mundo responderá "sim" e, em seguida, responderá a alguns recursos do hashmap, como o hashmap pode aceitar valores e valores de chave nulos, enquanto a hashtable não pode; Hashmap não é sincronizado; Hashmap é rápido; e Hashmap armazena pares de valor-chave, etc. Isso mostra que você usou hashmap e está familiarizado com ele. Mas o entrevistador deu uma guinada rápida e começou a fazer algumas perguntas complicadas a partir de agora, sobre detalhes mais básicos do Hashmap. O entrevistador pode fazer as seguintes perguntas:
"Você sabe como funciona o hashmap?" "Você sabe como o método get () hashmap funciona?"
Você pode responder: "Eu não procurei a API Java padrão em detalhes, você pode olhar para o código -fonte Java ou abrir JDK". "Eu posso encontrar a resposta com o Google."
Mas alguns entrevistadores podem dar a resposta: "O hashmap é baseado no princípio do hash. Usamos put (chave, valor) para armazenar objetos no hashmap e usar get (chave) para obter objetos do hashmap. Quando passamos as teclas e os valores do método Put (), primeiro chamamos o método Hashcode () na tecla e o retorno e o retorno. O ponto principal aqui é ressaltar que o Hashmap armazena objetos e objetos de valor no balde como mapa.entry. Isso ajuda a entender a lógica de obter objetos. Se você não perceber isso, ou pensa erroneamente que apenas armazena valores em baldes, não responderá à lógica de como obter objetos do Hashmap. Essa resposta é bastante correta e também mostra que o entrevistador conhece o hash e como funciona o hashmap. Mas este é apenas o começo da história. Quando o entrevistador se junta a algumas cenas reais que os programadores Java precisam encontrar todos os dias, as respostas erradas aparecem com frequência. A próxima pergunta pode ser sobre detecção de colisão no Hashmap e a solução para colisão:
"O que acontece quando o código de hash de dois objetos é o mesmo?" A partir daqui, começa a verdadeira confusão, e alguns entrevistadores responderão que, como o código de hash é o mesmo, os dois objetos são iguais e o hashmap lançará exceções ou não serão armazenados. Em seguida, o entrevistador pode lembrá -los de que existem dois métodos: Equals () e HashCode () e diga a eles que, mesmo que o HashCode seja o mesmo, eles podem não ser iguais. Alguns entrevistadores podem desistir, enquanto outros podem continuar avançando. Eles responderam: "Como o código de hash é o mesmo, a posição do balde é a mesma e a 'colisão' acontecerá. Como o Hashmap usa uma lista vinculada para armazenar objetos, esta entrada (o objeto Map.entry contendo pares de valor-chave) será armazenado na lista vinculada". Esta resposta é muito razoável. Embora existam muitas maneiras de lidar com colisões, esse método é o mais fácil e é o método de processamento de hashmap. Mas a história ainda não terminou, e o entrevistador continuará perguntando:
"Se o código de hash das duas teclas é o mesmo, como você obtém o objeto Value?" O entrevistador responderá: Quando chamarmos o método get (), o hashmap usará o código de hash do objeto principal para encontrar o local do balde e, em seguida, obter o objeto Value. O entrevistador lembra que, se dois objetos de valor forem armazenados no mesmo balde, ele dá a resposta: a lista vinculada será percorrida até que o objeto Value seja encontrado. O entrevistador perguntará, porque você não possui um objeto de valor para comparar, como você determinou se encontrar o objeto Value? A menos que o entrevistador armazena pares de valores-chave na lista vinculada até que o Hashmap os armazene na lista vinculada, eles não poderão responder a essa pergunta.
Alguns dos entrevistadores que se lembram desse importante ponto de conhecimento dirão que, depois de encontrar a localização do balde, eles chamarão o método Keys.Equals () para encontrar o nó correto na lista vinculada e, finalmente, encontrar o objeto Value. A resposta perfeita!
Em muitos casos, os entrevistadores cometerão erros neste link porque confundem os métodos hashCode () e Equals (). Porque antes que este hashcode () apareça repetidamente, e o método iguals () aparece apenas ao obter o objeto Value. Alguns desenvolvedores excelentes ressaltarão que o uso de objetos imutáveis e declarados como final e o uso dos métodos Equals () e HashCode () apropriados reduzirão a ocorrência de colisões e melhorarão a eficiência. A imutabilidade permite que o código de hash de teclas diferentes seja armazenado em cache, o que aumentará a velocidade de obter todo o objeto. Usar classes de wrapper como String e Interger como Keys é uma escolha muito boa.
Se você acha que está aqui, ficará surpreso ao ouvir a seguinte pergunta. "E se o tamanho do hashmap exceder a capacidade definida pelo fator de carga?" A menos que você realmente saiba como o Hashmap funciona, você não responderá a esta pergunta. O tamanho padrão do fator de carga é 0,75. Ou seja, quando um mapa enche 75% de baldes, como outras aulas de coleção (como a Arraylist etc.), uma matriz de balde que é o dobro do tamanho do hashmap original será criada para redimensionar o mapa e colocar o objeto original na nova matriz de balde. Esse processo é chamado de reformulação porque chama o método hash para encontrar o novo local do balde.
Se você pode responder a essa pergunta, vem a seguinte pergunta: "Você entende que problemas existem em redimensionar o hashmap?" Você pode não ser capaz de responder. Neste momento, o entrevistador lembrará que, ao multi-threading, pode haver uma condição de corrida.
Ao redimensionar o hashmap, há de fato uma concorrência condicional, porque se os dois threads descobrirem que o hashmap precisará ser redimensionado, eles tentarão redimensionar ao mesmo tempo. Durante o processo de redimensionamento, a ordem dos elementos armazenados na lista vinculada será revertida, porque, ao se mudar para a nova posição do balde, o hashmap não coloca os elementos no final da lista vinculada, mas na cabeça, que é evitar percorrer a cauda. Se ocorrer uma competição condicional, há um ciclo vicioso. Neste momento, você pode perguntar ao entrevistador por que é tão estranho que você precisa usar o hashmap em um ambiente multithread? :)
Leitores entusiasmados contribuem com mais perguntas sobre o Hashmap:
1. Por que as classes de invólucro são como string e interger adequadas como chaves? A classe Wrapper como String e Interger é a mais adequada como uma chave de hashmap, e a string é a mais usada. Porque a string é imutável e final, e os métodos iguais () e hashcode () foram reescritos. Outras classes de wrapper também têm esse recurso. A imutabilidade é necessária porque, para calcular o hashcode (), você deve impedir que o valor da chave mude. Se o valor -chave retornar um código de hash diferente ao colocar e obter, você não poderá encontrar o objeto que deseja do hashmap. A imutabilidade tem outras vantagens, como a segurança dos threads. Se você pode garantir que o HashCode permaneça inalterado apenas declarando um campo como final, faça -o. Como os métodos iguais () e hashcode () são usados ao obter objetos, é muito importante reescrever esses dois métodos corretamente. Se dois objetos desiguais retornarem diferentes códigos de hash, a chance de colisão será menor, o que pode melhorar o desempenho do hashmap.
2. Podemos usar objetos personalizados como chaves? Esta é uma extensão da pergunta anterior. Obviamente, você pode usar qualquer objeto como teclas, desde que ele siga as regras de definição dos métodos iguais () e hashcode () e não mudará novamente depois que o objeto for inserido no mapa. Se esse objeto personalizado for imutável, ele já satisfaz a condição como uma chave, pois não pode ser alterada após ser criada.
3. Podemos usar o CocurrentHashmap para substituir a hashtable? Essa é outra pergunta de entrevista muito popular, porque mais e mais pessoas usam o simplário simultâneo. Sabemos que a hashtable é sincronizada, mas a sincronização simultânea de mapa é melhor porque trava uma parte do mapa com base no nível de sincronização. O ConcorrentehashMap certamente pode substituir a hashtable, mas a hashtable fornece segurança mais forte. Confira este blog para ver a diferença entre hashtable e concorrente.
Pessoalmente, gosto muito dessa pergunta, porque a profundidade e a amplitude dessa pergunta não envolvem diretamente conceitos diferentes. Vamos dar uma olhada em quais pontos de conhecimento são sobre o design dessas perguntas:
Resumir
Como funciona o hashmap
O hashmap é baseado no princípio do hash, e armazenamos e obtemos objetos através dos métodos put () e get (). Quando passamos o par de valores-chave para o método put (), ele chama o método hashcode () do objeto chave para calcular o código de hash e, em seguida, encontra a posição do bucket para armazenar o objeto Valor. Ao obter o objeto, o par de valores de chave correto é encontrado através do método iguals () do objeto chave e, em seguida, o objeto Value é retornado. O HashMap usa listas vinculadas para resolver o problema de colisão. Quando ocorre uma colisão, o objeto será armazenado no próximo nó da lista vinculada. O hashmap armazena objetos de pares de valor-chave em cada nó da lista vinculada.
O que acontece quando o código de hash de dois objetos importantes diferentes é o mesmo? Eles serão armazenados na lista vinculada no mesmo local do balde. O método iguals () do objeto chave é usado para encontrar pares de valor-chave.
Como o Hashmap tem muitos benefícios, usei o Hashmap como cache em aplicativos de comércio eletrônico. Como o Java é muito usado no campo financeiro e, para considerações de desempenho, geralmente usamos hashmap e concorrente. Você pode ver mais artigos sobre hashmap:
A diferença entre hashmap e hashtable
A diferença entre hashmap e hashset
Link original: Javarevisited Tradução: Importnew.com - Tang Xiaojuan Link de tradução: http://www.importnew.com/7099.html