Visual Studio调试C/C++指南

news/2024/5/17 15:59:05

1. 前言

Visual Studio(VS)是微软开发的一款集成开发环境(IDE)软件,支持C/C++、C#、VB、Python等开发语言,开发桌面、Web等应用程序。VS功能极其强大,使用极其便利,用户数量最多,被誉为"宇宙第一IDE"。

熟悉地掌握基于VS的C/C++调试技术,可以大幅提升调试性能。随着VS版本的更新,其功能越来越强大,本文的内容是基于VS2019进行验证测试的,之前版本VS可能有少量特性不支持。

2. 基础

 

2.1. 调试

代码调试主要指使用调试工具来检查和修复代码中的错误和问题。代码调试主要有运行调试、打印调试、内存分析、静态分析、性能分析等。

2.2. 符号文件

符号文件(Symbol File)是指在编译程序时生成的包含调试信息的文件。它们通常与可执行文件或动态链接库(DLL)配对存在,用于提供程序的调试信息。VC生成的符号文件为PDB(Program Database)文件。其中存储变量名、函数名、代码行号、类型信息和栈信息等。exe/dll与pdb文件是一一对应的。每次重新编译代码,都会生成新的pdb。

2.3. 调试器

Microsoft Visual C/C++的调试器名称叫做"Visual Studio Debugger"。在调试exe时,其会读取exe文件中记录的PDB路径信息(这个路径是开发电脑编译时生成的PDB路径),如果这个PDB路径不存在,那么调试器会在exe目录去找PDB,如果依然找不到PDB,则启用无PDB调试。无PDB调试只能查看汇编信息和寄存器信息。

调试方式

3.1. 本地调试

VS工程默认即为本地调试(Local Windows Debugger)。选定启动工程,按F5或通过菜单Debug->Start Debugging。

  • 命令行参数(Command Arguments),给exe配置命令行参数。

  • 附加(Attach),默认No。Yes表示附加当前路径的进程进行调试。

3.2. 远程调试

  1. 将开发电脑上的Remote Debugger目录拷贝到生产电脑。

  1. 根据程序的类型x64/x86打开相应的目录,并打开生产电脑目录下的msvsmon.exe。

  2. 首次调用时,会弹出远程调试配置窗口,勾选所有的允许远程调试器与这些网络通信。

  3. 配置msvsmon.exe的Tools->Options。4015是默认的端口号,一般不建议修改。

  1. 获取生产电脑的IP,局域网网络通信,可以使用计算机名:端口号的方式,也可以使用IP:端口号的方法。但是在访问跨网关的局域网电脑时,计算机名可能无法解析出对应的IP地址,导致访问失败,所以更推荐IP:端口号的访问方式。

  2. 依据下图配置相关信息。

  3. 按F5启动调试,调试远程exe和调试本地exe后续操作完全一致。

3.3.  附加调试

  1. 打开exe。

  2. 从菜单启动Debug->Attach to Process,选择需要调试的进程进行附加。如果是远程进程,配置下图信息。

3.4. 外网调试

远程调试一般是针对局域网进行调试。但是有些时候,问题进程在外地,出差不方便或成本太高,非常需要一种能够穿透广域网进行调试的方法。最简单的方法是使用VPN将目标电脑远程连接到开发电脑,这样目标电脑和开发电脑就相当于处在同一个局域网,就可以使用普通的远程调试来进行外网目标电脑调试。

3.5. DLL调试

在DLL工程的属性中Debugging的Command中选择要执行的exe,然后在dll中设置相关断点。再按F5调试,即会中断在DLL工程的断点处。

4. 断点调试

int 3是x86-64架构CPU上的中断指令,用于在程序执行过程中触发软件中断。VS在给代码添加断点时,就是将指定行对应的代码修改为int 3指令,并且调试器接管代码。继续单步执行时,会还原int 3覆盖的代码。

4.1. 断点类型

4.1.1. 普通断点

在代码指定行按F9或右键菜单Breakpoint->Insert Breakpoint设置普通断点。

4.1.2. 条件断点

在断点上右键选择Conditions。

设置 i == 5, 然后点击Close。按F5执行,代码会停止在断点处,此时i==5。

指定当前断点触发指定次数时中断下来。

当前断点运行在指定线程时才中断下来。

4.1.3. 行为断点

行为断点(Actions Breakpoint),也称Tracepoint,因为断点触发时会在Output窗口打印信息。Continue Code Execution勾选表示不停止在断点处,如果选空表示停止在断点处。

Output窗口显示:The value of z is 0x0000001e. 0x2C74

$PID,是伪指令。可用的伪指令如下:

4.1.4. 数据断点

数据断点(Data Breakpoint),当然变量地址的内容发生改变时,即中断下来。如下图,Address编辑框可以直接填写变量的地址,也可以使用取地址符来获取变量的地址。数据断点只能针对有效数据设置断点,并且只能在已经开始调试之后,在Breakpoint窗口的菜单New->Data Breakpoint来设置。

4.1.5. 系统函数断点

例如想在CreateFile函数中下断点。可以使用dhb.exe在相应的

dbh.exe -s:srv*C:\Symbols*Symbol information -d C:\Windows\SysWOW64\kernel32.dll enum *CreateFile*

然后Breakpoints->New->Function Breakpoint:

运行就会断在系统API函数处,通过调用栈查找到调用的函数。

4.1.6. 软件断点

除了通过VS来添加断点外,我们也可以在代码中主动添加软件断点__debugbreak()/DebugBreak函数,或是断言ASSERT(0)。

__debugbreak()/DebugBreak是代码到此处立即中断,而断言则是根据参数逻辑值来决定是否中断。软件断点主要用来在代码潜在的异常出现时产生中断提示开发者。

4.2. 调试行为

4.2.1. 基本行为

工具栏或Debug菜单或鼠标右键都有调试行为的选项。

  1. Break All,中断当前所有正在执行的代码。当代码进入死循环时,点击Break All,代码即会中断下来,此时遍历线程查看函数调用栈,即能发现死循环代码位置。

  2. Stop Debugging,停止当前调试。

  3. Restart,重新开始调试。

  4. Show Next Statement,光标跳到下一次要执行的代码处。

  5. Step Into,快捷键F11,进入当前语句所调用的函数内部,并停在函数的第一行。如果当前行没有函数调用,则直接运行至下一行。

  6. Step Over,快捷键F10,执行当前语句,但不进入函数内部。

  7. Step Out, 快捷键Shift+F11,执行完当前函数,暂停在函数调用处。

  8. Step Backward,即退回到上一次代码暂停的位置,恢复上次调试的信息。Step Forward,前行到退回前的代码暂停的位置。这是基于栈快照进行的调试,VS会在几次中断时,保存对应栈信息,尤其是当我们想反复调试一个算法时,使用Step Backward会非常方便。

4.2.2. 高级行为

  1. Run To Cursor,运行到光标处中断,可以通过鼠标右键来执行,也可在光标处的代码行的图标上点击。

  1. Force Run To Cursor,强制运行到光标处,会跳过中间设置的断点。

  2. 自定义,鼠标放在箭头上,可以将下一个可执行代码的位置拖动到任意位置。拖动需要依赖先前的代码,否则可能产生异常。

5. 调试窗口

5.1. Output 

Output Debug窗口主要输出调试过程的信息,主要包括:

  • Exception Messages

  • Step Filtering Messages

  • Module Load Messages

  • Module Unload Messages

  • Process Exit Messages

  • Thread Exit Messages

  • Program Qutput

其中Program Output是代码运行时输出的信息,主要通过Trace函数或OutputDebugString函数来将信息输出到Output窗口。如果是非调试状态下,OutputDebugString的输出信息则需要DbgView工具来接收并显示。

5.2. Locals

Locals窗口显示调试时当前执行代码所在函数所在的栈的局部变量的值和类型。

5.3. Autos

Autos窗口显示调试时当前执行代码所在函数所在的栈的上下文栈变量值和类型。

5.4. Watch

Watch窗口总共有4个,可以在菜单Debug->Windows->Wartch中选择。Watch窗口可以显示当前栈内存的局部变量,全局变量等,支持16进制形式显示,并支持实时修改变量值。

支持简单的表达式显示,如x+y, sizeof(x)等。

支持格式化显示,如(int*)(szBuff),4将Buff转换为int*,再格式化为4个元素显示。

Watch窗口还支持显示伪变量,如:

  • $tid – 当前线程的的线程 ID

  • $pid – 进程 ID

  • $cmdline – 附加进程的命令行字符串

  • $user – 运行在程序中的账户信息

  • $registername – 显示指定寄存器的寄存器内容

  • $err – 显示最近错误的错误码

  • $err, hr – 显示最近错误的消息

5.5. Memory

Memory窗口是用来显示地址对应的内容,Memory窗口有4个从菜单Debug->Windows->Memory中选择。

Adress编辑框填写变量地址,Columns选择每行显示的内容数量。

5.6. QuickWatch

QuickWatch窗口是快捷观察、修改变量的窗口。

5.7. Disassembly

参数传递、函数返回等一些复杂的语法形式,要想理解其深层执行逻辑,就需要单步执行汇编代码来观察其隐藏逻辑细节。

5.8. Registers

寄存器窗口,显示当线程的寄存器信息。

5.9. Call Stack

函数调用栈窗口,显示当前线程的函数栈调用情况。可以通过Threads窗口选定当前线程。

5.10. Immediate Window

Debug->Windows->Immediate窗口。立即窗口主要用来查看、修改变量,执行函数,表达式等。

6. 多线程

6.1. Threads

Threads是显示当前进程的所有运行的线程信息的窗口。双击线程所在行,即将当前代码窗口、调用栈窗口等相关窗口的内容更新为选定线程。

当进程有多个工作者线程时,且只想调试其中一个线程时,可以将不关心的线程使用Freeze冰冻起来。冰冻的线程在按F5运行时,依然冰冻着不运行。使用Thaw解冻线程,线程将恢复为正常可以调试的状态。

6.2. 条件断点

在多线程中,根据线程信息来设置相应的断点来观察期望的变量信息。

6.3. Parallel Watch

Debug->Window->Parallel Watch可以显示几个线程同时调用的函数变量的情况,更方便地调试多线程。

6.4. 线程结构图

打开Debug->Windows->Parallel Stack窗口,会显示所有线程的栈,并显示当前线程栈。相比Threads窗口更直观。

7. 参数配置

7.1. 增量链接

增量链接在Debug下默认打开,在Release下默认关闭。通过Linker->General->Enable Incremental Linking来开启和关闭。增量链接还需要配置C/C++->General->Debug Information Format->Program Database for Edit And Continue (/ZI)。

增量链接的用处是在断点单步调试代码的时候,编辑代码,然后继续单步执行时,VS会自动增量链接,不用重新编译源代码,然后继续单步执行代码进行调试。

增量链接是调试时使用,增量编译则是编译时只编译修改的源文件,两者不相同。

7.2. 优化级别

Debug版本下,默认关闭代码优化,此时代码的调试信息与代码源文件是一一对应,调试更方便。Release版本下,默认使用O2优化,此时代码优化程度非常大,调试信息与代码源文件无法一一对应。如果想调试Release版本,则需要关闭优化。

7.3 宏展开

一些复杂的宏,非常难以调试。如何查看宏预处理之后展开形成的代码呢?C/C++->Preporcessor->Preprocess to a File配置默认是关闭的,打开此配置为Yes(/P)表示将生成预处理后的文件,文件与源文件同名,后缀为.i。在.i文件中可以查看所有宏展开的结果,以及其他预处理的结果。

7.4. 显示链接细节

VS 链接器默认只显示一些关键的链接信息。可以通过Linker->General->Show Progress配置Display all progress messages(/VERBOSE)来显示详细的链接信息,可以更方便地分析一些链接异常的错误。

7.5. 警告

7.5.1. 编译警告

为了提升代码的可靠性,警告也需要认真对等。

  • C/C++->All Options->Warning Level,选择合适的警告级别,初期可以选择W3级别。

  • C/C++->All Options->Treat Warning As Errors,初期可以不设置。

  • C/C++->All Options->Treat Specific Warnings As Errors,可以将一些关键警告设置为错误。

7.5.2. 链接警告

Linker->All Options->Treat Linker Warning As Errors,根据需要将警告作为错误对待。

Dump调试

8.1. 概念

Dump文件(Dump File),也叫转储文件,以.DMP为文件后缀。dump文件是进程在内存中的镜像文件,通过转换然后存储成以.DMP后缀的文件。dump文件根据存储时的选项不同,会生成不同大小的文件,其中记录信息也自然有所不同。

8.2. 转储文件生成

  1. 通过Windows进程管理器,选择指定的进程,右键生成转储文件。

  2. 通过函数MiniDumpWriteDump生成转储文件。

8.3. 调试转储文件

  • 选择与生成Dump文件相同版本的VS。

  • 启动VS并打开Dump文件。

  • 必须保证生成Dump文件的程序的PDB文件和源代码相一致。

  • VS2005打开Dump文件时,直接按F5调试,代码会停在出错的地方,通过Call Stack窗口查看。

  • VS2010打开Dump文件时,

需要通过Set symbol paths设置符号文件路径,也即PDB文件路径。然后点击Debug with Native Only,代码即会中断在出错的地方,通过Call Stack窗口查看相关信息。

变量溢出

变量内存溢出分为上溢(Overflow)和下溢(Underflow)。内存溢出导致的异常是C++代码最为难以调试的Bug之一,因为内存溢出导致的异常往往不会立即出现,而是展现在后面的函数中。因为内存溢出可能覆盖了后面的代码,导致后面的代码执行异常。

AddressSanitizer (ASan) 是一种编译器和运行时技术,它通过和编译器配合,通过插桩技术,向内存的前后添加标识,来识别运行时产生的上溢和下溢异常。其对代码执行性能影响较大,VS中默认是关闭的,需要手动打开。

ASan可以识别栈内存、堆内存、静态内存的溢出,另外也能检测重复释放,释放后使用内存。

通过C/C++->General->Enable Address Sanitizer使能,此配置与编辑并继续、增量链接和/RTC不兼容。

更多信息:AddressSanitizer | Microsoft Learn

资源泄露

电脑上的内核资源是有限的,申请使用完了,就要释放,否则资源可能不够用,导致后续申请失败而运行异常。所以资源泄露也是比较严重的问题,需要解决。

10.1. 内存泄露

在调试运行进程时,退出调试后,可能会在VS的Output窗口中显示如下信息:

这就是内存泄露的提示信息。上面的信息有时会指出内存泄露的位置,有的时候指出的位置却不准确。第三方工具 Visual Leak Detector,可以用来检测内存泄露,其主要是通过重载内存申请和释放函数,然后记录内存申请的地址和详细源文件行号,最后退出时检测所有申请的地址是否释放,如果没有释放,则打印出内存申请的信息。

Visual Leak Detector的使用非常简单,下载安装,然后在工程的启动接口文件中添加#include <vld.h>即可。

详细信息见:Home · KindDragon/vld Wiki · GitHub

10.2. 句柄泄露

除了内存泄露外,句柄也是容易泄露的资源。

  • 可以使用WinDbg的句柄快照对比功能找出未正常释放的句柄。

  • 可以使用第三方工具Deleaker,可以注册试用版本使用14天。Deleaker会检测出代码申请未释放的行号。

11. 静态调试

相比于动态调试(在代码运行时调试),静态调试是在代码编译时来调试,其效率更高。

11.1. 静态断言

静态断言static_assert是C++11中引入的新语法,可以在编译时进行一些判断,并打印相应信息。

static_assert(sizeof(int) == 4, "int must be 4 bytes"); // 检查 int 类型是否为 4 字节template <typename T>
void process(T value) {static_assert(std::is_integral<T>::value, "T must be an integral type"); // 检查模板类型是否为整数类型
}

11.2. 静态分析

VS自带的静态分析,功能非常强大,能够发现很多隐藏的问题。开启静态分析之后,会在编译期间进行静态分析代码,所以会加大编译时间。建议定期开启静态分析检查代码,并修复相关问题。

另外还可以选择相应的静态分析规则:

12. 性能调试

VS提供了性能度量工具(Performance Profiler),帮助开发者优化代码和提高应用程序性能。Profiler的主要功能是诊断内存、CPU 使用率。Debug下的性能分析,因为有很多调试及优化的影响,所以很不准确,建议是在Release版本下进行性能调试分析。

通过Debug->Performance Profiler。C/C++更多用来分析CPU和Memory。

点击Start之后,目标程序开始执行,并开始监控性能,并通过Take Snapshot给当前进程拍摄快照。

12.1. 内存分析

通过Stop Collection或等进程结束,会显示如下信息。每个快照会保存详细的进程堆栈信息。

点击上面的内存分配次数、分配次数增量等数据,可以获取详细信息:

双击相应对象分配行,可以得到详细的对象信息包括调用堆栈信息,通过调用栈可以查看相应的代码:

12.2. CPU分析

内存分类统计:

内存分线程统计:

双击函数名,可以详细函数占比分析:

12.3. 性能提示

调试器在断点或单步执行操作中停止执行时,中断与上一个断点之间经过的时间会显示为在编辑器窗口中的提示。

更多信息见:在 Visual Studio 中度量性能 - Visual Studio (Windows) | Microsoft Learn

协同调试

VS提供了多人协作进行调试的功能,使用非常简单。

  1. 登录VS帐号。

  2. 点击如下图中红圈的图标,启用协作会话。

  1. 协作会话启动完成后,会显示如下信息。默认已经将协作邀请链接进行了拷贝。如果协作方只需要查看代码,不需要调试,可以点击Make read-only。

  1. 将协作邀请链接发给协作方并打开,弹出如下窗口。

  1. 打开VS Code,主持人开始调试,协作方也可以通过VS Code查看调试信息。

  1. 通过VS的File->Join Live Share Session来加入协作调试。

  2. 还可以进行协作的管理,以及协作时聊天。

14. 调试技巧

14.1. 小技巧

  • 使用快捷键,另外还可以自定义快捷键。

  • 固定数据提示信息

  • 格式化内存

调试器也能在 Watch 窗口中显示格式化的内存值,高达 64 个字节。你能用下面的说明符在表达式(变量或内存地址)后来格式化数据。

  • mb / m - BYTE

  • mw - WORD

  • md - DWORD

  • mq – 8BYTE

  • ma – 16BYTE

14.2. 管理员权限调试

通过Linker->Manifest File->UAC Execution Level->requireAdministrator,启用管理员权限,然后启用调试,则被调试的进程也将获取管理员权限。

14.3. 生成调用栈信息

void printStackTrace() 
{HANDLE process = GetCurrentProcess();SymInitialize(process, nullptr, TRUE);void* stack[100];WORD frames = CaptureStackBackTrace(0, 100, stack, nullptr);SYMBOL_INFO* symbol = (SYMBOL_INFO*)malloc(sizeof(SYMBOL_INFO) + 256 * sizeof(char));symbol->MaxNameLen = 255;symbol->SizeOfStruct = sizeof(SYMBOL_INFO);for (WORD i = 0; i < frames; ++i) {SymFromAddr(process, (DWORD64)(stack[i]), 0, symbol);printf("[%d] %s\n", i, symbol->Name);}free(symbol);
}

14.4. 内存耗尽

Windows下的32位应用程序,只能申请2GB内存。所以在申请过的总内存过大时,可能超过2GB,导致程序异常。可以使用下面代码提示总内存过大的提示。

void NoMoreMemory()
{LPVOID lpMsgBuf;if (!FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,NULL,0x00000008, // Memory error	MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language(LPTSTR) &lpMsgBuf,0,NULL )){return;}// Display the string.MessageBox( NULL, (LPCTSTR)lpMsgBuf, _T("Error"), MB_OK | MB_ICONINFORMATION );abort();
}// Add to this function to the entry of EXE/DLL.
set_new_handler(NoMoreMemory);

14.5. 未初始化异常

14.5.1. Debug

VS在Debug下为了方便用户调试,编译器会强制将未初始化的变量强制赋值指定值做标记。

栈变量强制赋值0xCCCCCCCC,堆内存强制赋值为0xCDCDCDCD。

14.5.2. Release

在VS下,C/C++中的变量编译器不会对变量进行初始化。栈变量和堆内存都是随机的。养成变量初始化的习惯是提升代码质量的好习惯。

14.6. 调试运行时库代码

VS运行时库,有一些提供了代码,有一些没有提供。如CString的GetLength()函数。VS2012及之前的版本默认不会进入库函数,VS2015及之后版本默认在使用Step Into时会进入库函数。如果无法进入库函数,可以进入汇编调试,然后再Step Into就可以进入库函数了。

14.7. Debug和Release的差异

  1. 编译优化:

    • Debug 模式下,编译器不会进行任何优化,以便于调试和错误定位。

    • Release 模式下,编译器会进行各种优化,以提高程序的性能和执行效率。

  2. 调试信息:

    • Debug 模式下,编译器会生成完整的调试信息,包括变量名、行号等,方便进行调试。

    • Release 模式下,编译器会尽量减少调试信息的生成,以减小程序的体积。

  3. 运行时检查:

    • Debug 模式下,编译器会添加额外的运行时检查,如数组越界检查、内存泄漏检查等,以帮助发现程序中的错误。

    • Release 模式下,这些运行时检查通常会被禁用,以提高程序的执行速度。

  4. 断言和异常处理:

    • Debug 模式下,程序会更加严格地检查各种断言和异常,以帮助开发者发现问题。

    • Release 模式下,这些检查通常会被禁用或简化,以提高程序的稳定性和性能。

  5. 编译器定义宏:

    • Debug 模式下,编译器会定义 _DEBUG 宏,用于在代码中进行条件编译。

    • Release 模式下,编译器会定义 NDEBUG 宏,用于在代码中进行条件编译。

  6. 编译器优化标志:

    • Debug 模式下,编译器通常会使用 /Od 标志禁用优化。

    • Release 模式下,编译器通常会使用 /O2 标志启用最高级别的优化。

  7. 链接器优化:

    • Debug 模式下,链接器通常不会进行任何优化。

    • Release 模式下,链接器会进行各种优化,如去除未使用的函数和数据等。

  8. 运行时库:

    • Debug 模式下,程序会链接到 Debug 版本的运行时库,提供更多的错误检查和调试支持。

    • Release 模式下,程序会链接到 Release 版本的运行时库,以提高性能和减小程序体积。

14.8. 构建事件

有时需要在编译前后附加一些操作来简单调试,就可以使用编译事件配置,选择相应的构建事件然后配置命令行来执行需要附加的操作。

14.9. 日志

日志是调试工具的重要手段,除了使用Trace和OutputDebugString之外,还可以使用自定义的日志函数。

14.10. 调试窗口

VS自带的Spy++可以用来查看窗口信息,还可以用来监控窗口消息。

14.11. 查看DLL接口

dumpbin是VS自带的命令行工具,可以用来查看DLL的接口函数。通过Tools->Command Line来使用。

这是一个命令行工具,可以用于查看 DLL 文件的结构和内容。常用命令:

  • dumpbin /exports <DLL_FILE_PATH>: 查看 DLL 的导出函数

  • dumpbin /dependents <DLL_FILE_PATH>: 查看 DLL 的依赖项

  • dumpbin /headers <DLL_FILE_PATH>: 查看 DLL 的头部信息

15. 总结

调试是手段,不是目的,不能为了调试而调试。目的是更高效地开发,为此,减少问题,减少调试才是最重要的。


http://www.mrgr.cn/p/23445325

相关文章

陇剑杯 省赛 攻击者1 CTF wireshark 流量分析

陇剑杯 省赛 攻击者1 题目 链接&#xff1a;https://pan.baidu.com/s/1KSSXOVNPC5hu_Mf60uKM2A?pwdhaek 提取码&#xff1a;haek ├───LogAnalize │ ├───linux简单日志分析 │ │ linux-log_2.zip │ │ │ ├───misc日志分析 │ │ acce…

7-01. 创建主菜单 UI

创建 Menu Canvas创建 Panel添加底图添加标题、版本、按钮如果希望图片周围没有黑框,需要把图片的 Read/Write 改成透明再添加一个说明 Panel再添加一个开始 Panel创建 MenuUI将三个 Panel 拖动到 MenuUI 上 对于 Panel 里面的每个 Button,调用 SwitchPanel 解决点击按钮中间…

kafka---topic详解

一、分区与高可用 在Kafka中,事件(events 事件即消息)是以topic的形式进行组织的;同时topic是分区(partitioned)的,这意味着一个topic分布在Kafka broker上的多个“存储桶”(buckets)上。这种数据的分布式放置对于可伸缩性非常重要,因为它允许客户端应用程序同时从多个…

keycloak~jwt的rs256签名的验证方式

接口地址keycloak开放接口地址:/auth/realms/fabao/.well-known/openid-configurationrsa算法相关术语 RSA算法是一种非对称加密算法,其安全性基于大整数分解的困难性。在RSA算法中,有以下几个关键参数:n(模数):n 是一个大整数,通常为两个大素数 p 和 q 的乘积,即 n =…

机器学习(31)PINN

文章目录 摘要Abstract一、监督学习二、文献阅读1. 题目2. abstract3. 偏微分方程的数据驱动解3.1连续时间模型example(Schrodinger equation)&#xff1a; 3.2离散时间模型Example (Allen–Cahn equation)&#xff1a; 4. 文献解读4.1 Introduction4.2 创新点 三、实验内容1.实…

管道流设计模式结合业务

文章目录 流程图代码实现pomcontextEventContextBizTypeAbstractEventContext filterEventFilterAbstractEventFilterEventFilterChainFilterChainPipelineDefaultEventFilterChain selectorFilterSelectorDefaultFilterSelector 调用代码PipelineApplicationcontrollerentitys…

vue3+elementplus+axios+router的入门项目总结

一、使用vite方式创建项目:1、创建空文件夹,用vscode打开空文件夹,终端上运行如下命令$ npm init vite-app [项目名]:初始化项目 $ cd [项目名]:进入项目 $ npm install:安装项目依赖 $ npm run dev:启动项目2、启动项目后会出现访问地址: 3、进入访问地址: 二、引入…

找win电脑代理地址

1.进入控制面板2.Internet属性3.局域网设置

C语言野指针【入门详解】

目录 一、什么是野指针 二、野指针的成因 2.1 指针未初始化 2.2 指针越界访问 2.3 指针指向的空间释放 三、如何规避野指针 3.1 初始化指针 3.2 小心越界访问 3.3 当指针不用时&#xff0c;及时置为空 3.4 避免返回局部变量的地址 *结语&#xff1a; 希望这篇关于指…

RHCE2

一.配置server主机要求如下&#xff1a; 1.server主机的主机名称为 ntp_server.example.com //修改主机名 hostnamectl set-hostname ntp_server.example.comreboot 修改主机名后一定要记住重启。 2.server主机的IP为&#xff1a; 172.25.254.100 //主机ip配置 [rootntpse…

BOSHIDA DC电源模块的发展趋势和前景展望

BOSHIDA DC电源模块的发展趋势和前景展望 随着电子产品的普及和多样化,对电源模块的需求也越来越大。其中,DC电源模块作为一种重要的电源供应方式,在各个领域有着广泛的应用。在过去的几十年里,DC电源模块已经经历了多次技术革新和发展,未来的发展趋势也值得关注。本文将从…

Vue3 + vite 项目自定义一个svg-icon组件

1. 安装vite-plugin-svg-icons插件npm i vite-plugin-svg-icons -D2.vite.config.ts中配置import path from "path"; import { createSvgIconsPlugin } from "vite-plugin-svg-icons"; export default defineConfig({plugins: [......createSvgIconsPlugin…

HarmonyOS NEXT应用开发之Tab组件实现增删Tab标签

介绍 本示例介绍使用了Tab组件实现自定义增删Tab页签的功能。该场景多用于浏览器等场景。 效果图预览使用说明:点击新增按钮,新增Tab页面。 点击删除按钮,删除Tab页面。实现思路设置Tab组件的barHeight为0,隐藏组件自带的TabBar。Tabs() {... } .barHeight(0) // 隐藏tab组…

光学雨量计雨量传感器技术的优势与应用范围

光学雨量计雨量传感器技术的优势与应用范围 光学雨量计是一种利用光学原理来测量降雨量的仪器。相比于传统的雨量计,光学雨量计具有许多优势,也扩大了其应用范围。 光学雨量计的优势之一就是其高精度和高分辨率。光学雨量计可以实时记录和计算降雨量,精确到0.1毫米的分辨率…

【R语言】动画图:散点图

绘制成如下的散点图&#xff1a; 如果数据量大&#xff0c;有多个年份&#xff0c;就会生成多张图&#xff0c;例如&#xff1a; 具体代码如下&#xff1a; library(gapminder)#加载 gapminder 包&#xff0c;其中包含了从 1952 年至 2007 年各个国家的 GDP、预期寿命和人口数据…

2024-04-18 tsconfig.json 常用的配置项作用

TypeScript 编译器的配置文件,用于指定编译 TypeScript 代码时的编译选项和编译目标等信息。 通过修改该文件,可以定制 TypeScript 编译器的行为,例如指定编译目标、启用或禁用特定的语言特性、设置代码检查规则等。以下是一些常用的配置项及其作用: compilerOptions:编译…

【原创教程】EPLAN电气图纸设计规范

EPLAN电气图纸中的通用说明&#xff0c;说白了就是电气图纸的图纸概述、制图规范&#xff08;这里的规范根据每个公司及客户的要求不同进行更改&#xff09;。下面就以我们公司的规范要求&#xff0c;以实际的项目案例来对照讲述一下&#xff0c;通用说明的制作。 1.首先新建页…

实验6循环结构程序设计(for语句的应用)

实验6循环结构程序设计(for语句的应用) 一、实验目的 1.熟练掌握三种循环语句并能正确运用; 2.能够用循环实现一些常用算法,如穷举法,迭代法,递推法等; 3.进一步学习程序调试; 4.了解中国算法,百钱买百鸡。 二、实验硬、软件环境 Windows计算机、Devc6.0 三、实验内容…

Perforce (P4)版本控制使用指南

转载自:https://blog.csdn.net/zyhse/article/details/119083666以下为P4常规和一些必要操作如何达到同步?本质就是需要告诉P4你干了什么,然后P4再别人的机器上模拟你所做的操作操作的宗旨如果想让别人知道你的操作,就需要去主动通知✘31、登录账号密码相关信息会在入职手册…

模拟电路学习笔记——半导体基础知识

1.纯净的具有晶体结构的半导体称为本征半导体 2.导体导电只有一种载流子,即自由电子导电本征半导体含两种载流子:自由电子和空穴载流子:运载电荷的粒子 3.杂质半导体*本征半导体中掺入少量合适的杂质元素,便可得到杂质半导体3.1 N型半导体:纯净的硅晶体中掺入五价元素(如磷…