全网最实用的ideadebug调试技巧(超详细案例)(代码片段)

程序员囧辉 程序员囧辉     2023-02-27     426

关键词:

目录

前言

正文

Debug 的常见使用场景

基础操作

行断点(Line Breakpoints)

方法断点(Method Breakpoint)

字段断点(Field Watchpoints)

异常断点(Exception Breakpoints)

主动抛异常(Throw Exception)

降帧(Drop Frame)

断点条件(Condition)

强制返回(Force Return)

Stream 调试(Trace Current Stream Chain)

执行表达式(Evaluate Expression)

远程调试(Remote JVM Debug)

远程调试使用教程

多线程调试(Suspend)

Thread模式执行

All 模式执行

Debug Advance

推荐阅读


前言

Debug 是程序员的开发神器,使用好了可以帮助我们非常高效的工作、学习、排查问题等。毫不客气的说,是决定我们进阶到更高层级的一个重要技能。

今天跟大家分享一下 IDEA 中 Debug 调试的各种奇技淫巧。

本文内容有视频版本,喜欢看视频的同学可以直接通过下面的二维码观看。如果你对文章的内容有疑惑,有可以先看视频的对应内容,视频可能讲的会更细一点。

全网最实用的 IDEA Debug 调试技巧(超详细案例)https://www.bilibili.com/video/BV1xa411Y72S?spm_id_from=333.999.0.0

正文

Debug 的常见使用场景

  • 需求代码测试:通过debug你才能知道你的代码究竟是怎么运行的,更容易发现问题

  • 问题排查:只要能进入到问题流程的debug,就没有排查不了的问题

  • 源码学习:源码通常很庞大,通过Debug 我们能更清晰的知道执行到哪个地方,执行时的各个变量数据

基础操作

Step over:程序往下执行一行

Step into:进入方法内,可以进入自定义方法或三方库方法,JDK方法无法进入 

Force step into:强制进入方法内,一般 Step into 进不去时可以使用 

Step out:退出方法,跟(force)step into 配合使用 

Resume Program:恢复运行程序,运行到下一个断点的地方

5个操作从上往下分别对应下图的1-5,这也是 Debug 最常用的几个基础操作。

行断点(Line Breakpoints)

图标:红色圆形

功能:最常用的断点,在断点所在行进行暂停。

理论上只要有行断点和上面的基本操作,就可以完成大部分的 Debug 调试了,但是很多场景下只使用这些功能,调试是很低效了,接下来我们将依次介绍各种好用的调试技巧。

方法断点(Method Breakpoint)

图标:红色菱形

功能:在方法入口(entry)和出口(exit)都会自动暂停。在方法入口暂停可以让我们从头调试整个方法,而在方法出口处暂停可以让我们看到方法执行完毕时,方法内各个变量的数据情况。

有时候我们的一个接口会存在很多实现类,我们短时间内难以分析究竟是运行到了哪个实现类中,这个时候就可以使用方法断点,我们将断点打在接口方法上,运行到该方法时,会自动跳到实际执行的实现类,无需通过上下文环境去分析是哪个实现类。

缺点:可能会大大降低debug速度

字段断点(Field Watchpoints)

图标:红色眼睛

功能:在字段发生变更(默认)或者被访问(需要额外设置)时暂停。

如果我们想知道某个属性在什么时候被修改,从入口处开始调试太麻烦,我们可以直接在字段上打上字段断点,这样字段被修改的时候就会自动暂停。

而如果我们想在字段被访问时也暂停,则可以右键字段断点,将【Field access】勾选上即可。

异常断点(Exception Breakpoints)

图标:红色闪电

功能:可以在抛出异常的地方进行暂停

异常断点是无需在具体的代码上打断点的,而是在断点详情页中直接添加,后续在执行时,如果抛出我们监听的异常,则会自动暂停在抛出异常的地方。

主动抛异常(Throw Exception)

图标:无,Frames 堆栈中右键显示

功能:主动抛出指定异常

在上面的例子中,我们通过代码构造了一个异常,但是这种方式其实是不太方便的,特别是如果我们想在远程环境抛出一个异常,需要修改代码重新部署,测试完后还要修改回来再次部署。而 Throw Exception 则可以直接抛出一个异常,避免了这些繁琐的流程。

降帧(Drop Frame)

图标:如下图

功能:当我们 Debug 从 A 方法进入 B 方法时,通过降帧(退帧)可以返回到调用 B 方法前,这样我们就可以再一次调用 B 方法。

通常用于当我们快执行完 B 方法后,发现某个重要流程被我们跳过了,想再看一下,则此时可以先回退到 A 方法,然后再次进入 B 方法。

我们知道方法的执行和结束在 JVM 中对应的是栈帧的入栈和出栈,因此栈帧描述的就是方法对应的模型,而降帧(退帧)则对应的就是回退到上一个方法。

断点条件(Condition)

图标:如下图

功能:当程序执行到断点位置时,需要 Condition 中的表达式返回 true,才会暂停,否则会直接跳过。

用于断点所在的地方执行次数过多时,避免浪费时间在不想关注的流程上。例如我们有一个 Spring bean 的初始化存在问题,我们想跳过其他 bean 的初始化流程,则可以在初始化的入口设置 beanName.equals("") 表达式,来达到只在我们关注的 bean 执行时才暂停。

强制返回(Force Return)

图标:如下图

功能:强制结束当前程序运行流程,直接返回。

当我们调试时,发现继续往下执行就要将错误的数据写入数据库时,我们可以通过 Force Return 来强行结束当前流程。

而如果我们是通过 Stop 按钮来结束,此时结束的是 Debug 流程,而程序流程还是会往下执行,从而将错误数据写入数据库。

Stream 调试(Trace Current Stream Chain

图标:如下图

功能:当我们暂停在 Stream 的处理代码行时,可以将 Stream 的整个处理流程以图形化界面的形式展示。

合理的使用 Stream 会让我们的代码更加简洁,但是现在存在大量滥用 Stream 的情况,Stream 本身就比较抽象,大量滥用会使得 Stream 的代码难以理解和调试。

当我们发现问题出在 Stream 的处理流程中时,我们可以通过该功能来看到每个步骤处理前和处理后的数据,方便我们定位排查是哪一步出了问题。

执行表达式(Evaluate Expression

图标:计算器,如下图

功能:用于执行一段我们实时写的代码,例如查看数据、修改数据。

当我们在测试时,发现某段代码逻辑很难有符合条件的数据时,可以通过该功能直接修改数据,来加快我们的测试。

该功能非常强大,我们可以在这边执行任何逻辑,举个例子:可以将数据保存到数据库、可以发送一个RPC请求等等。

远程调试(Remote JVM Debug

图标:如下图所示

功能:调试部署在远程服务器上的代码。

远程调试最常见的使用场景是排查线上问题,下面举个例子。

有一个用户(userId=8888)请求某个接口会出现异常,但是其他用户是正常的,包括我们的各种测试账号。

此时我们可以使用测试账号(userId=1222),在预发布环境向该接口发起请求,并且我们会通过远程 Debug 在接口入口处拦截住该请求,然后我们通过执行表达式功能,将userId从1222修改为8888,则接下来我们就可以模拟出现问题的用户来调试整个接口了,从而帮助我们快速定位到问题。

注意:使用远程Debug的环境必须不能对外网访问,否则可能存在安全隐患。

远程调试使用教程

不同版本的远程 Debug 所需的配置参数不同,通过Idea 可以看到不同版本对应的参数。

各个版本所需配置参数: 

// JDK1.3 or earlier
-Xnoagent -Djava.compiler=NONE -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005
// JDK1.4
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005
// JDK5-8:
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
// JDK9 or later 
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005

配置方式主要用以下两种:

1)使用启动命令 

java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar java-study-demo-0.0.1-SNAPSHOT.jar

2)在启动脚本中增加上述配置

下面在本地模拟一个流程:

1)模拟启动一个服务,使用了远程 Debug 的参数启动

2)通过浏览器发送请求,可以看到此时由于被我们 Debug 住,所以左上角会有个图标在转圈圈等待

3)可以看到请求确实被我们拦截住了,接着我们就可以像本地Debug一样来进行调试了

多线程调试(Suspend)

图标:如下图

Suspend 有两种模式:All 和 Thread。

Thread:暂停进入断点的线程,不影响其他线程执行。所有进入断电的线程依次Debug。

All:暂停全部线程。只能 Debug 第一个暂停线程。

这边两种模式的后半句如果难以理解,可以看下我视频里面的案例来帮助理解。

Thread模式执行

通过输出内容,可以看到线程1被阻塞,线程2和主线程都已经执行结束

All 模式执行

可以看到线程2和主线程没有使用断点,但是也被暂停了,因为没有输出内容。

Debug Advance

最后一个它不是一个真正的技巧,而是想跟大家分享一些经验。

有一句话叫:比你优秀的人不可怕,可怕的是比你优秀的人学习工作效率比你还高。

这样子我们其实就很难去追赶那些比我们更优秀的人。因为他们比我们厉害,然后效率还比我们还高。所以我们其实应该尽可能的去提升我们的一些学习还有工作的效率。

我今天讲的这些例子里面,我相信多多少少应该会有几个是你们没有用过的,或者说甚至没有听过的。

但是通过我之前的介绍,我们可以发现文中的每个 Debug 技巧其实在不同的场景上它都能发挥发挥一定的作用,提升我们的效率。少的话可能提升个几分钟,可能就是一次重新运行的时间,多的话可能是几小时,甚至是几天,甚至有的问题你不用这些技巧,其实你很难去排查出来。

所以掌握这些技巧其实对于 Java 开发其实还是很有必要的。所以我建议大家还是可以花点时间在这上面。因为这些技巧其实掌握起来很简单,你可能只需要看一遍或者两遍吧。然后大概你就知道了有这些东西,然后你在日后的学习工作中去把它应用一下,然后就熟能生巧,然后就变成你们的东西了后续对你们的学习,还有工作上其实都会有不小的帮助。

推荐阅读

面试官:如何进行 JVM 调优(附真实案例)

Java 基础高频面试题(2021年最新版)

Java 集合框架高频面试题(2021年最新版)

面试必问的 Spring,你懂了吗?

面试必问的 MySQL,你懂了吗?

史上最全的ideadebug调试技巧(超详细!建议收藏!)(代码片段)

来源:https://www.cnblogs.com/chiangchouDebug用来追踪代码的运行流程,通常在程序运行过程中出现异常,启用Debug模式可以分析定位异常发生的位置,以及在运行过程中参数的变化。通常我们也可以启用Debug模式来跟踪代... 查看详情

史上最全的ideadebug调试技巧(超详细!建议收藏!)(代码片段)

来源:https://www.cnblogs.com/chiangchouDebug用来追踪代码的运行流程,通常在程序运行过程中出现异常,启用Debug模式可以分析定位异常发生的位置,以及在运行过程中参数的变化。通常我们也可以启用Debug模式来跟踪代... 查看详情

你不知道的ideadebug调试小技巧

一、多线程调试断点IntellijIDEA的debug断点调试是有一个模式的选择的,就像下面这张图,平时我们都使用的是默认的ALL(在Eclipse中默认是线程模式),这种模式我们只能将一个线程断下来,但其他线程却已经执行过了;而将其改... 查看详情

ideadebug断点调试技巧

Debug用来追踪代码的运行流程,通常在程序运行过程中出现异常,启用Debug模式可以分析定位异常发生的位置,以及在运行过程中参数的变化。通常我们也可以启用Debug模式来跟踪代码的运行流程去学习三方框架的源码。一、Debug... 查看详情

idea--ideadebug断点调试技巧

  目录一、Debug开篇二、基本用法&快捷键三、变量查看四、计算表达式五、智能步入六、断点条件设置七、多线程调试八、回退断点九、中断DebugDebug用来追踪代码的运行流程,通常在程序运行过程中出现异常,启用Debu... 查看详情

intellijidea超实用使用技巧分享

https://blog.csdn.net/weixin_38405253/article/details/102583954 知识点概览:高效率配置日常使用必备快捷键(★★)查找跳转切换编码相关代码阅读相关版本管理相关编码效率相关(★★)文件代码模板实时代码模板其他代码调试源码阅... 查看详情

全网最详细的实用的搜索工具listary和everything对比的区别堪称比everything要好(图文详解)

      不多说,直接上干货! 引言  无论是工作还是科研,我们都希望工作既快又好,然而大多数时候却迷失在繁杂的重复劳动中,久久无法摆脱繁杂的事情。   你是不是曾有这样一种想法:如果我有哆... 查看详情

全网最详细的接口测试实战案例!全文57000字小白必看!(代码片段)

最近知乎给我推荐了几个问题,都还比较有代表性。作为一个初级测试,想学接口测试,但是一点头绪都没有。求教大神指点,有没有好的书或者工具推荐?-知乎如何做接口测试呢?接口测试有哪些工具-... 查看详情

如何优雅的使用ideadebug进行调试(代码片段)

如何优雅的使用IDEADebug进行调试Debug是我们在开发过程中经常会使用到的一种排查问题的手段,我们用它来定位分析异常的出现,以及程序在运行中参数的变化。IDEA本身具有很强的调试功能,掌握IDEA的一些Debug技巧&#x... 查看详情

vs编译器实用调试技巧

一、Debug和Release的区别debug通常称为调试版本,它包含调试信息,并且不做任何优化,便于程序员调试程序。release称为发布版本,他往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好使用代码... 查看详情

22个案例详解pandas数据分析/预处理时的实用技巧,超简单(代码片段)

作者|俊欣来源| 关于数据分析与可视化今天小编打算来讲一讲数据分析方面的内容,整理和总结一下Pandas在数据预处理和数据分析方面的硬核干货,我们大致会说Pandas计算交叉列表Pandas将字符串与数值转化成时间类型Pand... 查看详情

超实用技巧✨|提高写文的质量和速率必学技能:❤️typora图床配置详细说明❤️windows版(代码片段)

❤️提高写文的质量和速率必学技能:Typora图床配置【Windows版】📢前言🌲图床简介🌲Typora简介🌟方法一:PicGo-Core(commandline)+gitee仓库🏳️‍🌈1.安装Typora软件🏳️‍🌈2.在Typor 查看详情

编程技巧│超实用nginx中常见的配置合集

查看详情

全网最详细最好懂pytorchcnn案例分析识别手写数字(代码片段)

先来看一下这是什么任务。就是给你手写数组的图片,然后识别这是什么数字:dataset首先先来看PyTorch的dataset类:我已经在从零学习pytorch第2课Dataset类讲解了什么是dataset类以及他的运行原理classMNIST_data(Dataset):"""MNISTdt... 查看详情

全网最详细,fiddler抓包实战-网页浏览器https请求(超详细)

目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜&#... 查看详情

继续分享5个实用的vs调试技巧(代码片段)

继续分享5个实用的vs调试技巧原总结调试vs2019vs前言我在上一篇文章《5个非常实用的vs调试技巧》中分享了5个我认为非常值得了解的vs调试技巧,本周继续分享5个很基础但同样实用的调试技巧。1.条件断点作用简介:顾名思义,... 查看详情

超实用的jquery小技巧(代码片段)

JQuery是一个JavaScript库,她极大的简化了我们对JavaScript的编程。今天我们总结了下平常项目中用到的一些小技巧,仅供参考。1、替换元素//替换元素$(document).ready(function()$("#id").replaceWith(‘<p>Ihavebeenrepaced</p>‘));2、延时加... 查看详情

实用调试技巧(代码片段)

调试技巧调试是什么?有多重要?一、调试的基本步骤二、Debug和Release的介绍。三、学会快捷键四、调试的时候查看程序当前信息五.实例实例一实例二六.如何写出好(易于调试)的代码示范注意七.编程常见错误... 查看详情