当前位置: 首页 > article >正文

第24篇:Python开发进阶:掌握Python编程中的调试技巧

第24篇:调试技巧

内容简介

在软件开发过程中,调试是确保代码正确性和稳定性的关键步骤。有效的调试技巧不仅能帮助开发者快速定位和修复错误,还能提升代码的整体质量和可维护性。本篇文章将探讨如何使用Python内置的调试工具pdb进行调试,介绍常用的调试工具与集成开发环境(IDE)的调试功能,以及详细讲解日志记录与分析**的方法。通过理论与实践相结合的方式,您将全面掌握调试的核心技巧,提升开发效率和代码质量。


目录

  1. 使用pdb进行调试
    • 什么是pdb?
    • 基本用法
    • 常用命令
    • 示例演示
  2. 常用调试工具与IDE调试功能
    • 调试工具概述
    • 常用调试工具
      • ipdb
      • pudb
      • PyCharm调试器
      • Visual Studio Code调试器
    • IDE调试功能详解
  3. 日志记录与分析
    • 为什么需要日志记录?
    • 使用logging模块进行日志记录
    • 日志级别与格式
    • 日志分析工具
    • 最佳实践
  4. 调试技巧与最佳实践
    • 系统化调试方法
    • 有效的错误定位策略
    • 避免常见调试陷阱
  5. 实践项目:调试一个有错误的程序
    • 项目概述
    • 步骤一:分析错误
    • 步骤二:使用pdb进行调试
    • 步骤三:利用IDE调试功能
    • 步骤四:添加日志记录
    • 完整代码示例
  6. 常见问题及解决方法
    • 问题1:调试器无法停止在断点处?
    • 问题2:如何调试多线程程序?
    • 问题3:日志文件过大如何管理?
  7. 总结

使用pdb进行调试

什么是pdb?

pdb是Python的内置调试器,提供了一系列命令行工具,帮助开发者在程序运行时进行交互式调试。通过pdb,您可以设置断点、逐步执行代码、检查变量值等,从而有效地定位和修复代码中的问题。

基本用法

使用pdb进行调试的基本步骤如下:

  1. 导入pdb模块

    import pdb
    
  2. 设置断点
    在代码中需要调试的地方插入:

    pdb.set_trace()
    
  3. 运行程序
    当程序执行到pdb.set_trace()时,将进入调试模式,您可以输入调试命令进行调试。

常用命令

以下是pdb中常用的调试命令:

  • hhelp:显示帮助信息,列出可用命令。
  • ccontinue:继续执行程序,直到下一个断点或程序结束。
  • nnext:执行下一行代码,不进入函数内部。
  • sstep:执行下一行代码,如果有函数调用,进入函数内部。
  • llist:显示当前执行的代码片段。
  • bbreak:设置断点,可以指定行号或函数名,例如 b 25
  • pprint:打印变量的值,例如 p variable_name
  • qquit:退出调试器并终止程序。

示例演示

以下是一个使用pdb进行调试的简单示例:

# example_pdb.pyimport pdbdef divide(a, b):pdb.set_trace()  # 设置断点return a / bdef main():x = 10y = 0result = divide(x, y)print(f"Result: {result}")if __name__ == "__main__":main()

运行程序

python example_pdb.py

调试过程

程序将在divide函数的pdb.set_trace()处暂停,进入调试模式。

> /path/to/example_pdb.py(5)divide()
-> return a / b
(Pdb) p a
10
(Pdb) p b
0
(Pdb) n
ZeroDivisionError: division by zero

通过调试器,可以发现变量b的值为0,导致了ZeroDivisionError异常。


常用调试工具与IDE调试功能

调试工具概述

除了Python内置的pdb调试器,还有许多第三方调试工具和集成开发环境(IDE)提供了强大的调试功能。这些工具通常具有图形化界面,支持断点管理、变量监视、堆栈跟踪等高级功能,能够大幅提升调试效率。

常用调试工具

ipdb

ipdbpdb的一个增强版本,集成了IPython的交互功能,提供了更友好的用户体验和更多的调试命令。

安装ipdb

pip install ipdb

使用方法

import ipdbdef add(a, b):ipdb.set_trace()return a + b
pudb

pudb是一个基于终端的图形化调试器,提供了可视化的界面,便于查看代码、变量和调用堆栈。

安装pudb

pip install pudb

使用方法

import pudbdef multiply(a, b):pudb.set_trace()return a * b

运行程序后,将进入pudb的图形化调试界面。

PyCharm调试器

PyCharm是由JetBrains开发的专业Python IDE,内置了功能强大的调试器,支持断点管理、变量监视、表达式求值、条件断点等功能。

使用方法

  1. 设置断点:在代码行号旁点击,设置断点。
  2. 启动调试:点击“Debug”按钮运行程序,程序将在断点处暂停。
  3. 调试操作:使用调试面板中的按钮进行单步执行、变量查看、堆栈导航等操作。
Visual Studio Code调试器

Visual Studio Code(VS Code)是一个轻量级但功能强大的代码编辑器,配备了内置的调试器,支持Python扩展插件,提供丰富的调试功能。

使用方法

  1. 安装Python扩展:在VS Code中安装Microsoft的Python扩展插件。
  2. 设置断点:在代码行号旁点击,设置断点。
  3. 启动调试:按F5键或点击调试按钮,启动调试会话。
  4. 调试操作:使用调试工具栏中的按钮进行单步执行、变量查看、断点管理等操作。

IDE调试功能详解

以PyCharm和VS Code为例,详细介绍IDE的调试功能。

PyCharm调试器

主要功能

  • 断点管理:支持普通断点、条件断点、日志断点等。
  • 变量监视:实时查看和修改变量的值。
  • 表达式求值:在调试过程中计算表达式的值。
  • 堆栈跟踪:查看函数调用堆栈,快速定位问题。
  • 多线程调试:支持调试多线程程序,查看各线程的执行状态。
  • 调试配置:灵活配置调试选项,如环境变量、命令行参数等。

使用技巧

  • 条件断点:在断点设置中添加条件表达式,只有满足条件时才暂停程序。
  • Evaluate Expression:在调试过程中,使用“Evaluate Expression”功能动态计算和测试代码片段。
  • Watches:添加观察变量,持续监视其变化。
  • Log Messages:在断点触发时,记录日志消息而不暂停程序。
Visual Studio Code调试器

主要功能

  • 断点管理:设置普通断点、条件断点、函数断点等。
  • 变量监视:查看和编辑变量值,支持表达式和对象属性。
  • Call Stack:查看当前调用堆栈,导航不同的堆栈帧。
  • Debug Console:在调试过程中,使用控制台执行Python代码和查看输出。
  • Inline Values:在代码旁边直接显示变量的当前值。
  • 断点条件和动作:为断点添加条件和动作,实现更精细的调试控制。

使用技巧

  • 断点条件:在断点设置中添加条件,使断点在特定条件下触发。
  • Step Over/Into/Out:使用步过、步入、步出功能,精确控制代码执行流程。
  • Debug Console:利用调试控制台,执行实时代码,测试变量状态。
  • Launch Configurations:配置不同的调试环境,支持多种运行参数和调试选项。

日志记录与分析

为什么需要日志记录?

日志记录是软件开发中的重要环节,通过记录程序的运行状态、错误信息和关键事件,帮助开发者了解程序的行为和性能,及时发现并解决问题。良好的日志记录机制不仅有助于调试,还能在生产环境中提供宝贵的数据支持,进行性能分析和安全审计。

主要原因

  • 错误追踪:记录程序错误和异常,帮助快速定位问题。
  • 性能监控:监测程序的运行性能,识别性能瓶颈。
  • 用户行为分析:了解用户在应用中的操作,优化用户体验。
  • 安全审计:记录关键操作和访问日志,提升系统安全性。
  • 系统监控:实时监控系统状态,预防潜在问题。

使用logging模块进行日志记录

Python提供了内置的logging模块,用于灵活地记录日志信息。logging模块支持多种日志级别、日志格式和日志处理器,满足不同的日志记录需求。

基本用法

import logging# 配置日志
logging.basicConfig(level=logging.DEBUG,format='%(asctime)s - %(levelname)s - %(message)s',filename='app.log',filemode='w')# 记录日志
logging.debug('这是调试信息')
logging.info('这是普通信息')
logging.warning('这是警告信息')
logging.error('这是错误信息')
logging.critical('这是严重错误信息')

说明

  • basicConfig:配置日志记录的基本设置,包括日志级别、格式、输出文件和文件模式。
  • 日志级别从低到高依次为DEBUGINFOWARNINGERRORCRITICAL
  • filename参数指定日志输出文件,filemode='w'表示覆盖写入,'a'表示追加写入。

日志级别与格式

日志级别

  • DEBUG:详细的信息,通常只在诊断问题时使用。
  • INFO:确认程序按预期运行的常规信息。
  • WARNING:表明发生了意外情况,但程序仍在继续运行。
  • ERROR:由于更严重的问题,程序无法执行某些功能。
  • CRITICAL:严重的错误,表明程序可能无法继续运行。

日志格式

日志格式可以自定义,以包含时间戳、日志级别、消息内容等信息。常用的格式化字段包括:

  • %(asctime)s:日志事件的时间。
  • %(levelname)s:日志级别名称。
  • %(message)s:日志消息。
  • %(filename)s:调用日志记录函数的文件名。
  • %(lineno)d:调用日志记录函数的行号。

示例格式

logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s',filename='app.log',filemode='a')

输出示例

2025-01-14 10:30:25,123 - INFO - example.py:15 - 程序启动
2025-01-14 10:30:26,456 - ERROR - example.py:20 - 发生错误:除以零

日志分析工具

记录大量日志后,如何高效地分析和利用这些日志信息成为一个重要问题。以下是一些常用的日志分析工具:

  • ELK Stack(Elasticsearch, Logstash, Kibana)

    • Elasticsearch:分布式搜索和分析引擎,用于存储和搜索日志数据。
    • Logstash:数据处理管道,负责从不同来源收集、转换和转发日志数据。
    • Kibana:数据可视化工具,提供强大的仪表板和图表功能,便于分析和展示日志数据。
  • Graylog

    • 集中式日志管理平台,支持实时日志收集、搜索和分析。
    • 提供强大的报警和通知功能,帮助及时响应系统异常。
  • Splunk

    • 企业级数据分析平台,支持大规模日志数据的收集、索引和分析。
    • 提供丰富的可视化和报告功能,适用于复杂的日志分析需求。
  • Loggly

    • 基于云的日志管理服务,支持实时日志收集和搜索。
    • 提供多种集成方式,便于与现有系统对接。
  • Papertrail

    • 简单易用的日志管理服务,支持实时日志流和搜索。
    • 提供方便的仪表板和报警功能,适合中小型项目使用。

选择建议

  • 项目规模:根据项目的规模和日志量选择合适的日志分析工具。
  • 功能需求:评估工具的搜索、可视化、报警等功能,选择满足需求的工具。
  • 部署方式:选择基于云还是自部署的日志分析解决方案,考虑维护和成本因素。
  • 集成性:确保日志分析工具能与现有的开发和运维工具无缝集成。

最佳实践

为了充分利用日志记录与分析,以下是一些最佳实践建议:

  1. 合理设置日志级别

    • 在开发和测试环境中使用较低的日志级别(如DEBUG),记录详细信息。
    • 在生产环境中适当提高日志级别(如WARNING),避免过多无关日志。
  2. 统一日志格式

    • 采用统一的日志格式,确保日志的一致性和可读性。
    • 包含关键信息,如时间戳、日志级别、文件名、行号和消息内容。
  3. 避免敏感信息泄露

    • 在日志中避免记录敏感数据,如密码、密钥和个人隐私信息。
    • 对必要的敏感信息进行脱敏处理。
  4. 日志轮转与归档

    • 设置日志轮转策略,防止日志文件过大影响系统性能。
    • 定期归档和备份日志,确保日志数据的安全性和可追溯性。
  5. 实时监控与报警

    • 配置实时日志监控,及时发现和响应系统异常。
    • 设置报警规则,确保关键错误能及时通知相关人员。
  6. 定期分析与优化

    • 定期分析日志数据,识别系统瓶颈和潜在问题。
    • 根据日志分析结果,优化系统性能和稳定性。

调试技巧与最佳实践

系统化调试方法

调试不仅仅是发现和修复错误,更是一种系统化的问题解决过程。以下是一个有效的调试流程:

  1. 重现问题

    • 确保能够稳定地重现问题,理解问题发生的前提条件和具体场景。
  2. 分析错误信息

    • 仔细阅读错误日志和堆栈跟踪信息,初步定位问题所在。
  3. 设置断点

    • 在关键代码处设置断点,逐步执行程序,观察变量状态和程序流程。
  4. 检查变量值

    • 通过调试器查看和修改变量值,验证程序逻辑是否正确。
  5. 简化问题

    • 尝试简化代码,隔离问题模块,缩小问题范围。
  6. 查阅文档与资源

    • 参考官方文档、社区资源和相关资料,获取更多信息和解决方案。
  7. 验证修复

    • 修复问题后,重新运行测试用例,确保问题已解决且未引入新错误。

有效的错误定位策略

错误定位是调试过程中的核心步骤,以下是几种有效的错误定位策略:

  1. 二分法

    • 将代码分成两部分,逐步缩小出错的范围,快速定位问题所在。
  2. 日志分析

    • 通过日志记录,追踪程序的执行路径和关键事件,发现异常行为。
  3. 代码审查

    • 仔细检查代码逻辑,寻找潜在的错误和漏洞。
  4. 单元测试

    • 编写单元测试,验证各个功能模块的正确性,帮助定位问题。
  5. 对比分析

    • 对比正常运行和出错时的程序状态,找出差异和异常。

避免常见调试陷阱

在调试过程中,开发者可能会遇到一些常见的陷阱,以下是避免这些陷阱的建议:

  1. 过度依赖调试器

    • 虽然调试器功能强大,但过度依赖可能导致对代码理解不足。结合调试器和代码审查,全面分析问题。
  2. 忽视日志记录

    • 忽视日志记录会增加调试难度。合理使用日志,记录关键事件和错误信息,提升调试效率。
  3. 不重现问题

    • 无法重现的问题难以调试。确保在稳定的环境中重现问题,理解问题发生的具体条件。
  4. 缺乏系统化方法

    • 随意调试可能导致效率低下。采用系统化的调试流程,逐步定位和解决问题。
  5. 不及时更新测试用例

    • 修改代码后未更新相应的测试用例,导致测试与实际代码不符。保持测试用例与代码同步,确保测试的有效性。

实践项目:调试一个有错误的程序

项目概述

本项目将通过一个存在错误的Python程序,演示如何应用pdb调试器、常用调试工具与IDE调试功能,以及日志记录与分析,系统地发现并修复代码中的问题。

步骤一:分析错误

假设有以下Python程序,旨在计算两个数的商,但存在逻辑错误:

# faulty_calculator.pydef divide(a, b):return a * b  # 错误:应为 a / bdef main():x = 10y = 0result = divide(x, y)print(f"Result: {result}")if __name__ == "__main__":main()

运行程序

python faulty_calculator.py

输出结果

Traceback (most recent call last):File "faulty_calculator.py", line 10, in <module>main()File "faulty_calculator.py", line 7, in mainresult = divide(x, y)File "faulty_calculator.py", line 4, in dividereturn a * b
ZeroDivisionError: division by zero

从错误信息中可以看出,程序在执行divide函数时,尝试用a * b进行除法运算,导致ZeroDivisionError异常。

步骤二:使用pdb进行调试

修改程序,添加pdb断点

# faulty_calculator.pyimport pdbdef divide(a, b):pdb.set_trace()  # 设置断点return a * b  # 错误:应为 a / bdef main():x = 10y = 0result = divide(x, y)print(f"Result: {result}")if __name__ == "__main__":main()

运行程序

python faulty_calculator.py

调试过程

程序将在divide函数的pdb.set_trace()处暂停,进入调试模式。

> /path/to/faulty_calculator.py(5)divide()
-> return a * b
(Pdb) p a
10
(Pdb) p b
0
(Pdb) n
ZeroDivisionError: division by zero

通过调试器,可以发现变量a10b0,并且返回值为a * b,这明显是错误的。

步骤三:利用IDE调试功能

以PyCharm为例,演示如何使用IDE的调试功能。

  1. 打开PyCharm,加载faulty_calculator.py项目。

  2. 设置断点:在divide函数的return a * b行点击行号,设置断点。

  3. 启动调试:点击“Debug”按钮运行程序,程序将在断点处暂停。

  4. 检查变量

    • 查看变量ab的值,确认b0
    • 发现返回值使用了错误的运算符*,应改为/
  5. 修改代码

def divide(a, b):pdb.set_trace()  # 可选,调试后可移除return a / b  # 修正运算符
  1. 重新运行程序,确保问题已修复。

修正后的输出

Traceback (most recent call last):File "faulty_calculator.py", line 10, in <module>main()File "faulty_calculator.py", line 7, in mainresult = divide(x, y)File "faulty_calculator.py", line 5, in dividereturn a / b
ZeroDivisionError: division by zero

发现程序仍然抛出ZeroDivisionError,因为y0。接下来,继续调试以处理除以零的情况。

步骤四:添加日志记录

为了更好地追踪程序运行状态,添加日志记录。

修改代码,添加日志

# faulty_calculator.pyimport pdb
import logging# 配置日志
logging.basicConfig(level=logging.DEBUG,format='%(asctime)s - %(levelname)s - %(message)s',filename='calculator.log',filemode='a')def divide(a, b):logging.debug(f"Called divide with a={a}, b={b}")if b == 0:logging.error("Attempted to divide by zero")raise ValueError("Cannot divide by zero!")return a / bdef main():x = 10y = 0try:result = divide(x, y)print(f"Result: {result}")except ValueError as e:logging.exception("An error occurred during division")print(e)if __name__ == "__main__":main()

运行程序

python faulty_calculator.py

输出结果

Cannot divide by zero!

查看日志文件(calculator.log)

2025-01-14 10:45:30,123 - DEBUG - Called divide with a=10, b=0
2025-01-14 10:45:30,124 - ERROR - Attempted to divide by zero
2025-01-14 10:45:30,124 - ERROR - An error occurred during division
Traceback (most recent call last):File "faulty_calculator.py", line 15, in mainresult = divide(x, y)File "faulty_calculator.py", line 9, in divideraise ValueError("Cannot divide by zero!")
ValueError: Cannot divide by zero!

说明

  • 通过日志记录,可以清晰地看到函数调用和错误信息,便于后续分析和调试。

完整代码示例

faulty_calculator.py

import pdb
import logging# 配置日志
logging.basicConfig(level=logging.DEBUG,format='%(asctime)s - %(levelname)s - %(message)s',filename='calculator.log',filemode='a')def divide(a, b):logging.debug(f"Called divide with a={a}, b={b}")if b == 0:logging.error("Attempted to divide by zero")raise ValueError("Cannot divide by zero!")return a / bdef main():x = 10y = 0try:result = divide(x, y)print(f"Result: {result}")except ValueError as e:logging.exception("An error occurred during division")print(e)if __name__ == "__main__":main()

运行程序

python faulty_calculator.py

输出结果

Cannot divide by zero!

日志文件(calculator.log)

2025-01-14 10:45:30,123 - DEBUG - Called divide with a=10, b=0
2025-01-14 10:45:30,124 - ERROR - Attempted to divide by zero
2025-01-14 10:45:30,124 - ERROR - An error occurred during division
Traceback (most recent call last):File "faulty_calculator.py", line 15, in mainresult = divide(x, y)File "faulty_calculator.py", line 9, in divideraise ValueError("Cannot divide by zero!")
ValueError: Cannot divide by zero!

常见问题及解决方法

问题1:调试器无法停止在断点处?

原因

  • 代码未正确运行到断点位置。
  • 断点设置有误,或调试器未正确配置。
  • 优化编译导致断点位置被跳过。

解决方法

  1. 确认断点位置

    • 确保断点设置在实际执行到的代码行。
    • 检查是否有条件断点导致断点未触发。
  2. 检查调试配置

    • 确保以调试模式运行程序,而非普通运行模式。
    • 检查调试器是否正确附加到运行的进程。
  3. 简化代码

    • 移除不必要的代码,确保断点位置确实会被执行。
    • 添加打印语句,确认程序是否执行到断点位置。
  4. 重启调试会话

    • 有时调试器可能出现异常,重启调试会话可能解决问题。
  5. 更新调试工具

    • 确保使用的调试工具或IDE为最新版本,避免已知的bug影响调试功能。

问题2:如何调试多线程程序?

原因

  • 多线程程序涉及多个执行流,调试过程中需要同时管理和监控多个线程。
  • 线程之间的竞争条件和同步问题增加了调试的复杂性。

解决方法

  1. 使用支持多线程调试的调试器

    • 选择支持多线程调试的工具,如PyCharm、Visual Studio Code等。
  2. 设置线程断点

    • 在关键线程操作处设置断点,观察线程之间的交互和状态。
  3. 监视线程状态

    • 使用调试器提供的线程监视功能,查看各线程的执行状态和堆栈信息。
  4. 避免死锁

    • 在调试过程中,注意线程间的锁定和资源争用,避免死锁情况。
  5. 使用日志记录

    • 结合日志记录,跟踪各线程的操作和状态,辅助定位问题。
  6. 简化测试场景

    • 尽量简化多线程程序的测试场景,减少线程数量和复杂度,便于调试。

问题3:日志文件过大如何管理?

原因

  • 长时间运行的应用程序可能生成大量日志,导致日志文件迅速增大,影响磁盘空间和性能。
  • 过大的日志文件难以查找和分析,降低日志的实用性。

解决方法

  1. 日志轮转

    • 使用logging.handlers.RotatingFileHandlerTimedRotatingFileHandler实现日志轮转,根据文件大小或时间定期创建新的日志文件。

    示例代码

    import logging
    from logging.handlers import RotatingFileHandler# 配置轮转日志处理器
    handler = RotatingFileHandler('app.log', maxBytes=5*1024*1024, backupCount=5)
    handler.setLevel(logging.DEBUG)
    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
    handler.setFormatter(formatter)logger = logging.getLogger()
    logger.setLevel(logging.DEBUG)
    logger.addHandler(handler)# 记录日志
    logger.debug('这是调试信息')
    logger.info('这是普通信息')
    logger.warning('这是警告信息')
    logger.error('这是错误信息')
    logger.critical('这是严重错误信息')
    

    说明

    • maxBytes:单个日志文件的最大字节数,超过后进行轮转。
    • backupCount:保留的旧日志文件数量,超过后自动删除最旧的日志文件。
  2. 压缩旧日志

    • 使用RotatingFileHandler结合压缩工具(如gzip)压缩旧日志,节省磁盘空间。
  3. 分级日志存储

    • 根据日志级别,将不同级别的日志存储到不同的文件中,便于管理和查找。

    示例代码

    import logging# 创建不同级别的日志处理器
    info_handler = logging.FileHandler('info.log')
    info_handler.setLevel(logging.INFO)error_handler = logging.FileHandler('error.log')
    error_handler.setLevel(logging.ERROR)# 设置日志格式
    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
    info_handler.setFormatter(formatter)
    error_handler.setFormatter(formatter)# 配置日志记录器
    logger = logging.getLogger()
    logger.setLevel(logging.DEBUG)
    logger.addHandler(info_handler)
    logger.addHandler(error_handler)# 记录日志
    logger.debug('这是调试信息')  # 不会记录到任何文件
    logger.info('这是普通信息')   # 记录到info.log
    logger.error('这是错误信息')   # 记录到error.log
    
  4. 定期清理日志

    • 编写脚本或使用工具,定期清理或归档过期的日志文件,保持日志目录整洁。
  5. 优化日志内容

    • 避免记录过多无关信息,精简日志内容,确保日志的高效性和实用性。

总结

在本篇文章中,我们深入探讨了调试技巧,介绍了如何使用Python内置的pdb调试器,详细讲解了常用的调试工具与集成开发环境(IDE)的调试功能,以及如何进行日志记录与分析。通过实践项目的演示,您不仅掌握了调试的基本方法,还了解了如何应对多线程调试、管理大型日志文件等实际问题。

学习建议

  1. 深入学习调试工具

    • 探索更多调试工具和插件,提升调试效率和能力。
    • 学习高级调试功能,如条件断点、表达式求值和多线程调试。
  2. 实践日志记录

    • 在实际项目中应用日志记录与分析,积累经验。
    • 探索不同的日志格式和处理器,优化日志管理策略。
  3. 结合调试与测试

    • 在编写单元测试和集成测试时,结合调试技巧,提高测试的有效性。
    • 使用调试器和日志记录,深入分析测试失败的原因。
  4. 参与开源项目

    • 通过参与开源项目,学习业界最佳调试实践,提升调试能力。
    • 贡献代码和调试经验,与社区共享知识。
  5. 持续优化调试流程

    • 定期评估和优化调试流程,提升问题解决的效率和效果。
    • 采用自动化工具,简化调试步骤,减少手动操作。

如果您有任何问题或需要进一步的帮助,请随时在评论区留言或联系相关技术社区。

相关文章:

第24篇:Python开发进阶:掌握Python编程中的调试技巧

第24篇&#xff1a;调试技巧 内容简介 在软件开发过程中&#xff0c;调试是确保代码正确性和稳定性的关键步骤。有效的调试技巧不仅能帮助开发者快速定位和修复错误&#xff0c;还能提升代码的整体质量和可维护性。本篇文章将探讨如何使用Python内置的调试工具pdb进行调试&am…...

Midscene.js:重新定义UI自动化的新时代工具

前言 Midscene.js 是一个创新的、面向开发者的 UI 自动化解决方案&#xff0c;并通过人工智能技术简化自动化脚本的编写与维护。 它提供了三种核心方法——交互&#xff08;.ai, .aiAction&#xff09;、提取&#xff08;.aiQuery&#xff09;和断言&#xff08;.aiAssert&am…...

go单元测试和基准测试

1、单元测试和基准测试 单元测试和基准测试代码开发中的重要环节&#xff0c;良好的单元测试和基准测试&#xff0c;能提升开发质量&#xff0c;对整体开发有非常重要的重要&#xff0c;下面介绍单元测试和基准测试的写法。 2、单元测试和基准测试写法 以排序基本排序算法&a…...

Nuxt:利用public-ip这个npm包来获取公网IP

目录 一、安装public-ip包1.在Vue组件中使用2.在Nuxt.js插件中使用public-ip 一、安装public-ip包 npm install public-ip1.在Vue组件中使用 你可以在Nuxt.js的任意组件或者插件中使用public-ip来获取公网IP。下面是在一个Vue组件中如何使用它的例子&#xff1a; <template…...

day7手机拍照装备

对焦对不上&#xff1a;1、光太暗&#xff1b;2、离太近&#xff1b;3、颜色太单一没有区分点 滤镜可以后期P 渐变灰滤镜&#xff1a;均衡色彩&#xff0c;暗的地方亮一些&#xff0c;亮的地方暗一些 中灰滤镜&#xff1a;减少光差 手机支架&#xff1a;最基本70cm即可 手…...

vue3中Teleport的用法以及使用场景

1. 基本概念 Teleport 是 Vue3 提供的一个内置组件&#xff0c;它可以将组件的内容传送到 DOM 树的任何位置&#xff0c;而不受组件层级的限制。这在处理模态框、通知、弹出菜单等需要突破组件层级限制的场景中特别有用。 1.1 基本语法 <template><teleport to&quo…...

LLM - 大模型 ScallingLaws 的指导模型设计与实验环境(PLM) 教程(4)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/145323420 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 Scalin…...

【Linux网络编程】传输层协议

目录 一&#xff0c;传输层的介绍 二&#xff0c;UDP协议 2-1&#xff0c;UDP的特点 2-2&#xff0c;UDP协议端格式 三&#xff0c;TCP协议 3-1&#xff0c;TCP报文格式 3-2&#xff0c;TCP三次握手 3-3&#xff0c;TCP四次挥手 3-4&#xff0c;滑动窗口 3-5&#xf…...

salesforce 可以 outbound profile 吗

在 Salesforce 中&#xff0c;Profile&#xff08;配置文件&#xff09; 通常不能直接通过标准的Change Set&#xff08;变更集&#xff09; 或 Outbound Migration&#xff08;外部迁移工具&#xff09; 进行完整的迁移&#xff0c;但可以通过以下方法来实现部分或全部迁移&am…...

FreeRtos的使用教程

定义&#xff1a; RTOS实时操作系统, (Real Time Operating System), 指的是当外界事件发生时, 能够有够快的响应速度,调度一切可利用的资源, 控制实时任务协调一致的运行。 特点&#xff1a; 支持多任务管理&#xff0c; 处理多个事件&#xff0c; 实现更复杂的逻辑。 与计算…...

windows系统如何检查是否开启了mongodb服务

windows系统如何检查是否开启了mongodb服务&#xff01;我们有很多软件开发&#xff0c;网站开发时候需要使用到这个mongodb数据库&#xff0c;下面我们看看&#xff0c;如何在windows系统内排查&#xff0c;是否已经启动了本地服务。 在 Windows 系统上&#xff0c;您可以通过…...

windows蓝牙驱动开发-生成和发送蓝牙请求块 (BRB)

以下过程概述了配置文件驱动程序生成和发送蓝牙请求块 (BRB) 应遵循的一般流程。 BRB 是描述要执行的蓝牙操作的数据块。 生成和发送 BRB 分配 IRP。 分配BRB&#xff0c;请调用蓝牙驱动程序堆栈导出以供配置文件驱动程序使用的 BthAllocateBrb 函数。&#xff1b;初始化 BRB…...

基于Ubuntu交叉编译ZLMediaKit

一、确保基于虚拟机VMVare的Ubuntu能正常上网 1、设置WIFI硬件无线网卡上网 菜单栏的“编辑”->选择“虚拟网络编辑器”&#xff0c;在弹出的窗口中&#xff0c;点击桥接模式的VMnet0&#xff0c;然后在下方选择“桥接模式”&#xff0c;网卡下拉栏&#xff0c;选择你目前…...

【PyTorch][chapter 29][李宏毅深度学习]Fine-tuning LLM

参考&#xff1a; https://www.youtube.com/watch?veC6Hd1hFvos 目录&#xff1a; 什么是 Fine-tune 为什么需要Fine-tuning 如何进行Fine-tune Fine-tuning- Supervised Fine-tuning 流程 Fine-tuning参数训练的常用方案 LORA 简介 示例代码 一 什么是 Fine-tune …...

git回退

git回退 1、未使用 git add 缓存代码时 git checkout –- filepathname 放弃单个文件的修改 git checkout . 放弃所有的文件修改 此命令用来放弃掉所有还没有加入到缓存区&#xff08;就是 git add 命令&#xff09;的修改&#xff1a;内容修改与整个文件删除。但是此命令不…...

数字图像处理:实验七

uu们&#xff01;这是我们目前数字图像系列的最后一张&#xff0c;之后有关人工智能结合的数字图像处理咸鱼哥正在学习和创作中&#xff0c;所以还请大家给咸鱼哥点时间&#xff0c;同时也提前预祝大家2025年新春快乐&#xff01;&#xff08;咸鱼哥真诚的祝愿每一个人&#xf…...

网易前端开发面试题200道及参考答案 (下)

阐述如何实现 img 按照原比例最大化放置在 div 中? 要让 img 按照原比例最大化放置在 div 中,可通过以下几种方式实现: 使用 object - fit 属性 object - fit 是 CSS 中用于规定如何调整替换元素(如 <img>、<video>)的内容以适应其容器的属性。 object - fit…...

通义灵码插件保姆级教学-IDEA(安装及使用)

一、JetBrains IDEA 中安装指南 官方下载指南&#xff1a;通义灵码安装教程-阿里云 步骤 1&#xff1a;准备工作 操作系统&#xff1a;Windows 7 及以上、macOS、Linux&#xff1b; 下载并安装兼容的 JetBrains IDEs 2020.3 及以上版本&#xff0c;通义灵码与以下 IDE 兼容&…...

利用双指针一次遍历实现”找到“并”删除“单链表倒数第K个节点(力扣题目为例)

Problem: 19. 删除链表的倒数第 N 个结点 文章目录 题目描述思路复杂度Code 题目描述 思路 1.欲找到倒数第k个节点&#xff0c;即是找到正数的第n-k1、其中n为单链表中节点的个数个节点。 2.为实现只遍历一次单链表&#xff0c;我们先可以使一个指针p1指向链表头部再让其先走k步…...

2025美赛倒计时,数学建模五类模型40+常用算法及算法手册汇总

数学建模美赛倒计时&#xff0c;对于第一次参加竞赛且没有相关基础知识的同学来讲&#xff0c;掌握数学建模常用经典的模型算法知识&#xff0c;并熟练使用相关软件进行建模是关键。本文将介绍一些常用的模型算法&#xff0c;以及软件操作教程。 数学建模常用模型包括&#xf…...

sql中INNER JOIN、LEFT JOIN、RIGHT JOIN

INNER JOIN 的作用 INNER JOIN 只会将相关联表匹配到的数据进行展示 假设我们有两个表&#xff1a;sys_user和 sys_user_role SELECT s1.* from sys_user s1 INNER JOIN sys_user_role s2 on s1.id s2.user_id 这样只会展示s1.id s2.user_id相匹配到的数据&#xff0c;其他数…...

二十三种设计模式-享元模式

享元模式&#xff08;Flyweight Pattern&#xff09;是一种结构型设计模式&#xff0c;旨在通过共享相同对象来减少内存使用&#xff0c;尤其适合在大量重复对象的情况下。 核心概念 享元模式的核心思想是将对象的**可共享部分&#xff08;内部状态&#xff09;提取出来进行共…...

前端【10】jQuery DOM 操作

目录 jquery捕获查取 获得内容 - text()、html() 以及 val() 获取属性 - attr() ​编辑 jQuery 修改/设置内容和属性 设置内容 - text()、html() 以及 val() 设置属性 - attr() jQuery添加元素 jQuery - 删除元素 前端【9】初识jQuery&#xff1a;让JavaScript变得更简…...

Day34:字符串的替换

在 Python 中&#xff0c;字符串替换是一个非常常见的操作&#xff0c;主要用于修改字符串中的某些部分。字符串的替换操作通常不修改原始字符串&#xff0c;因为字符串在 Python 中是不可变的&#xff0c;而是返回一个新的字符串。 Python 提供了 str.replace() 方法来执行替…...

汇编的使用总结

一、汇编的组成 1、汇编指令&#xff08;指令集&#xff09; 数据处理指令: 数据搬移指令 数据移位指令 位运算指令 算术运算指令 比较指令 跳转指令 内存读写指令 状态寄存器传送指令 异常产生指令等 2、伪指令 不是汇编指令&#xff0c;但是可以起到指令的作用&#xff0c;伪…...

力扣【347. 前 K 个高频元素】Java题解(堆)

TopK问题&#xff0c;我们直接上堆。 首先遍历一次然后把各个数字的出现频率存放在哈希表中便于后面堆的操作。 因为是出现频率前 k 高&#xff0c;所以用小顶堆&#xff0c;当我们遍历的频率值大于堆顶值时就可以替换堆顶。 代码&#xff1a; class Solution {public int[] …...

【计算机网络】host文件

host文件的主要功能&#xff1a; 域名解析 本地映射&#xff1a;host文件的主要功能是将**域名映射到相应的 IP 地址**。当计算机需要访问一个网站或服务时&#xff0c;它会首先在 host文件中查找该域名对应的 IP 地址。如果在 host文件中找到了匹配的域名和 IP 地址映射&…...

git如何设置pull的时候有些文件不pull

在 Git 中&#xff0c;没有直接的方法在 git pull 时排除特定文件&#xff0c;但可以通过以下方式实现类似效果&#xff1a; 方法 1: 使用 .gitignore .gitignore 文件可以忽略未跟踪的文件&#xff0c;但对已跟踪的文件无效。如果你希望某些文件不被拉取&#xff0c;可以先将…...

第五节 MATLAB命令

本节的内容将提供常用的一些MATLAB命令。 在之前的篇章中我们已经知道了MATLAB数值计算和数据可视化是一个交互式程序&#xff0c;在它的命令窗口中您可以在MATLAB提示符“>>”下键入命令。 MATLAB管理会话的命令 MATLAB提供管理会话的各种命令。如下表所示&#xff1a;…...

性能测试丨JVM 性能数据采集

什么是JVM性能数据采集&#xff1f; JVM性能数据采集是指通过一些工具和技术采集与Java虚拟机相关的性能数据。这些数据包括但不限于内存使用、CPU使用、垃圾回收&#xff08;GC&#xff09;行为、线程活动等。合理地分析这些数据&#xff0c;可以帮助我们找出系统的瓶颈&…...