paint-brush
Depurando como um desenvolvedor sênior: observe e avaliepor@shai.almog
996 leituras
996 leituras

Depurando como um desenvolvedor sênior: observe e avalie

por Shai Almog6m2022/12/20
Read on Terminal Reader

Muito longo; Para ler

A área de observação do depurador é uma ferramenta poderosa, valendo duas aulas no curso. Se você não conhece a Marcação de Objetos, precisa ver isso!
featured image - Depurando como um desenvolvedor sênior: observe e avalie
Shai Almog HackerNoon profile picture

Esta foi uma semana espetacularmente intensa. O novo canal do YouTube que oferece o curso está explodindo de inscrições; está entrando na 3ª semana...


O site do curso já está no ar; você pode ver todo o curso lá, embora eu esteja adicionando vídeos o tempo todo e tenha feito aproximadamente 1/3 do trabalho.


Neste momento, tem 3 horas e 17 minutos de conteúdo. Tenho mais uma hora de conteúdo pronta para adicionar e estou trabalhando em várias outras. Tenho certeza de que o curso terá mais de 6 horas quando concluído.


Também estou trabalhando em alguns outros vídeos interessantes, como um sobre como se proteger de ataques de serialização . Vou escrever um post completo no blog cobrindo isso nas próximas semanas.


Se você tiver quaisquer perguntas, pensamentos ou ideias, eu adoraria ouvir de você. Abaixo está o vídeo desta semana e a transcrição.

Transcrição

Bem-vindo de volta à terceira parte da depuração em escala, onde aprendemos a caçar bugs como os profissionais!

Nesta seção, discutiremos expressões de observação que são a base da depuração. Isso é tão importante que revisitarei o assunto novamente mais tarde.


A área de exibição é a área na parte inferior da tela


No IntelliJ, também podemos incorporar expressões de observação ao lado do código. O relógio é um dos recursos mais importantes de um depurador. É assim que podemos ver o que está acontecendo no depurador.


Mas vou muito mais fundo do que isso. Especialmente para marcação de objetos, que é um dos recursos de depuração mais legais de todos os tempos.

Valor de retorno

Você já voltou de um método apenas para pensar: “o que esse método retornou?”


Isso é muito comum, especialmente quando o valor de retorno não é armazenado em uma variável. Felizmente, o IDE tem a opção de salvar esse valor para que possamos inspecioná-lo imediatamente!


Ao ativar esta opção, podemos ver os valores de retorno de todos os métodos futuros. Se entrarmos no método isPrime e depois sairmos, você poderá ver o valor de retorno do método aqui embaixo.

Avalie

Avaliar a expressão é um dos recursos interessantes do depurador que não usamos o suficiente.


Podemos iniciar a caixa de diálogo de expressão de avaliação no menu do botão direito e digitar qualquer expressão Java válida. Esta é uma ferramenta poderosa que pode invocar qualquer método, fazer aritmética e até mesmo alterar o valor das variáveis como resultado.


Se você precisa simular algo difícil de testar no código atual, este é o lugar onde você pode brincar com a plataforma e testar “teorias malucas”.


Isso é muito parecido com o REPL que temos nas versões mais recentes do Java, mas é melhor em muitos aspectos porque podemos executar o código no contexto do nosso aplicativo.


Se eu tiver um método que retorna o valor errado, geralmente copio a chamada em uma caixa de diálogo de avaliação e tento várias combinações da chamada para ver “o que funciona”.


Apenas tentar todas as opções sem reiniciar pode nos poupar muito tempo!


Você pode iniciar esta caixa de diálogo com a combinação de teclas Alt-F8 .

Ver

A capacidade de assistir no IntelliJ é absolutamente espetacular.


O IntelliJ nos permite incorporar o relógio diretamente no editor IDE selecionando “Adicionar relógio embutido” no menu de contexto. Esse é um recurso incrível que, até onde eu sei, é exclusivo da JetBrains.


Uma vez selecionado, o relógio aparece à direita ao lado da linha onde adicionamos o relógio inline, o que facilita a avaliação com o código. Isso é muito conveniente ao retornar à mesma linha várias vezes.


Também podemos usar o relógio padrão que adicionará elementos com as outras variáveis. Isso é útil para objetos que queremos rastrear em grandes áreas do código. Tenho muito a dizer sobre a área de observação à medida que avançamos, mas, por enquanto, vamos deixar isso em espera.

Alterar estado

O valor definido é um recurso que muitas vezes esqueço de usar durante a depuração.


Isso é uma pena porque é tão poderoso. Podemos definir o valor de qualquer campo clicando com o botão direito do mouse e selecionando definir valor.


Também podemos usar F2 para acelerar isso


Posso alterar o valor para qualquer valor arbitrário. Isso também pode se aplicar a objetos nos quais posso atribuir um valor existente ou invocar um método de criação, uma nova instrução ou qualquer expressão que desejar.


É um recurso extremamente poderoso onde podemos modificar o objeto dinamicamente para reproduzir um estado que queremos testar.


Podemos combinar esse recurso com pular para a linha que discutimos anteriormente e testar um método por meio de muitas permutações diferentes. Mesmo aqueles que podem não ser reproduzíveis normalmente. Um bom exemplo seria o código que tenho que só roda no Windows. Mas eu tenho um Mac.


Eu apenas altero o valor da variável estática que indica o sistema operacional atual e testo esse código.

Marcação de objetos

A marcação de objetos é um dos recursos mais interessantes que discutiremos neste curso e é quase desconhecido.

É um pouco sutil; primeiro, adicionaremos um watch para Thread.currentThread() que retorna a instância do objeto que representa o thread atual.


Como você pode ver, posso ver o tópico atual no relógio.


Agora, posso executar esse método várias vezes e ver o thread atual; o método é sempre executado a partir do mesmo thread?


Bem, posso ver o ID do tópico e sim. É o mesmo. Então, provavelmente é thread-safe. Mas como posso verificar isso?


Normalmente anoto o ID do objeto ou o ponteiro da variável em um pedaço de papel e verifico se é o mesmo valor. Isso é uma dor e não escala. Com que frequência posso pressionar continuar de novo e de novo?


No menu do botão direito, seleciono Marcar objeto e digito um nome arbitrário. MyThread neste caso, depois de fazer isso, posso pressionar OK


Isso substitui o valor do thread atual agora pelo novo rótulo. Portanto, podemos assumir incorretamente que este é apenas um nome para uma expressão de observação. Não é. Declaramos uma nova variável e demos a ela o nome MyThread .


Copiamos o valor atual da expressão de observação para essa variável. Agora podemos tratar essa variável como tratamos a maioria das variáveis no IDE.


Podemos avaliar o valor aqui e conseguir tudo o que quisermos. Observe o sufixo _DebugLabel adicionado pelo IntelliJ para evitar colisões de nomes, mas fora isso, podemos invocar qualquer operação neste objeto, como obter o nome ou até mesmo acessar o nome do campo privado.


Mas isso fica muito melhor…


Vamos adicionar um ponto de interrupção a este método, um ponto de interrupção completamente padrão, como fizemos antes.


Este será um ponto de interrupção condicional padrão; discutiremos isso em breve em profundidade, mas agora, tudo o que você precisa saber é que posso definir uma condição que determinará se o ponto de interrupção será interrompido ou não.


Vamos ampliar.


Vamos digitar a condição; Posso comparar MyThread com o valor atual do thread. Observe que essa condição se comportará de acordo, pois o valor de MyThread é independente da instrução watch original de Thread.currentThread() .


Portanto, se o thread atual for realmente diferente, o ponto de interrupção será interrompido neste ponto.


Isso é imensamente útil ao lidar com muitos objetos. Nesse caso, posso verificar literalmente se o método será atingido com o mesmo thread. Posso usá-lo para comparar quaisquer objetos em vez de escrever seus ponteiros em um pedaço de papel!

Sim. Eu literalmente sentava com um pedaço de papel e copiava o endereço do ponteiro para ter certeza de que estava certo se o visse novamente. Isso é melhor de muitas maneiras!


Costumo usar isso com APIs como JPA, onde às vezes podemos ter duas instâncias de objeto com a mesma identidade. Isso é realmente difícil de detectar. Basta marcar um objeto e, em seguida, você poderá ver instantaneamente que é uma instância diferente.


Como este caso é obviamente de thread único, o ponto de interrupção nunca será atingido novamente. Mas isso funciona muito bem para casos muito elaborados e é uma ferramenta extremamente útil!

Finalmente

A seguir, vamos nos aprofundar nos pontos de interrupção e nas coisas incríveis que eles podem fazer. Este é um vídeo profundo que você não pode perder.

Se você tiver alguma dúvida, use a seção de comentários. Obrigado!