从打印日志到断点调试
刚开始写Java程序那会儿,碰到问题第一反应就是加System.out.println。比如算个用户积分总和,结果不对,就在循环里打印每一步的值。这招虽然土,但在没有调试工具或者远程环境受限时还挺管用。
后来用上了IDEA或Eclipse,才发现断点调试才是效率神器。在关键代码行前点一下设置断点,运行Debug模式,程序执行到那里就会暂停。这时候能看当前所有变量的值,还能一步步往下走,想跳进某个方法就F7,想直接执行完当前行就F8。
条件断点避免无效中断
有个同事之前处理订单系统,要在十万条数据里找一个特定用户的问题记录。他一开始在循环里打了个普通断点,结果每次都要手动放行九万多次。后来改成了条件断点——只在userId等于目标值时才停下来,省了大把时间。
设置方式也很简单,在断点上右键选“Edit breakpoint”,输入条件表达式就行。比如想让i等于500的时候中断:
i == 500利用异常断点快速定位崩溃点
有时候程序跑着突然抛NullPointerException,堆栈信息可能很长,逐层排查费劲。这时候可以试试异常断点。在调试器里找到“Caught Exceptions”选项,添加NullPointerException类名,一旦出现这个异常,不管在哪一层都会立刻停下。
有次排查线上同步任务失败,就是靠这个功能直接定位到是第三方接口返回了null没做校验,省去了翻几十个方法的时间。
远程调试连接生产环境
本地好好的,一上线就出问题?这种情况适合用远程调试。启动Java应用时加上JVM参数:
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005然后在IDE里配置远程调试连接,填上服务器IP和端口。连上之后就跟本地调试一样操作。注意别在高流量时段开,会影响性能,最好先在预发环境试。
动态修改变量值辅助测试
调试过程中发现某个判断条件卡住了流程,又不想重启整个流程怎么办?可以在断点处直接修改变量值。比如看到isValid标志是false导致跳过处理,手动把它改成true,继续往下走看后续逻辑是否正常。
这个功能在模拟极端场景时特别有用,比如测试账户余额为负数时的扣款逻辑,不用真去改数据库。
善用日志框架配合调试
光靠断点不够全面,尤其是多线程或异步任务。建议搭配Slf4j这类日志框架,在关键路径输出trace信息。调试时把某类的日志级别调成DEBUG,观察执行轨迹。
比如排查消息队列消费延迟,通过日志发现某一批消息被反复重试,再结合断点确认是数据库锁超时,问题一下子就清晰了。