C#中的Dump:解锁程序调试新姿势

一、Dump 初印象

在 C# 的编程世界里,Dump 就像是一个神奇的 “透视镜”,它生成的 dump 文件是程序运行状态的快照,这个快照可不是普通的照片,它把程序运行时的所有关键信息,像变量值、线程状态、堆栈跟踪等都清晰地记录下来 。在实际开发中,它的作用举足轻重,尤其是当程序出现性能问题,比如运行速度越来越慢,或者突然崩溃,又或者遭遇内存泄漏,导致内存占用不断攀升等棘手情况时,dump 文件能成为我们定位和解决问题的关键线索。就好比医生给病人做全面检查,通过各种检查报告来诊断病情,dump 文件就是程序的 “检查报告”,帮助开发者深入了解程序内部的状况,从而精准地找到问题根源,进行修复。

二、生成 Dump 文件的 “十八般武艺”

(一)借助任务管理器或 Process Explorer

使用任务管理器生成 Dump 文件的操作非常简单。当程序出现问题时,我们只需按下 “Ctrl + Shift + Esc” 组合键打开任务管理器,切换到 “详细信息” 选项卡 。在进程列表中找到目标程序的进程,右键点击它,然后选择 “创建转储文件” 选项。此时,系统会自动在默认路径下生成一个 Full Dump 文件,这个默认路径通常是系统盘的 “用户 \ 当前用户名 \AppData\Local\Temp” 文件夹 。不过,在 64 位操作系统上,要注意使用 32 位任务管理器给 32 位进程生成转储文件,用 64 位任务管理器给 64 位进程生成转储文件,32 位的任务管理器位于 C:\Windows\SysWOW64\taskmgr.exe。

而 Process Explorer 是一款功能更强大的进程管理工具,它可以看作是任务管理器的增强版。我们可以从微软官方网站下载并解压后直接使用。运行 Process Explorer 后,在搜索框中输入程序名称,就能快速过滤出目标进程。右键点击该进程,选择 “Create Dump” 选项,这里提供了 “Create Mini Dump” 和 “Create Full Dump” 两个选项,我们可以根据实际需求选择生成 Mini Dump 文件还是 Full Dump 文件,并且还能自由选择生成 Dump 文件的保存路径。

(二)使用 DebugDiag 工具

DebugDiag 是一款专门用于诊断程序问题的强大工具,它能够帮助我们在程序出现崩溃、卡死、断言等情况时,生成详细的 Dump 文件,以便深入分析问题。

首先,我们需要从微软官方网站下载 DebugDiag 工具的安装包,根据系统版本选择 32 位或 64 位的安装程序进行安装 。安装完成后,在开始菜单中找到 “DebugDiag 2 Collection” 并打开它。

接下来进行规则设置。在打开的窗口中,点击 “Add Rule” 按钮,在弹出的 “Rule Wizard” 对话框中,选择 “Crash” 规则类型,表示我们要针对程序崩溃的情况生成 Dump 文件,然后点击 “Next”。在 “Process Selection” 页面,选择 “A specific process”,并在下方输入框中填写目标程序的进程名,例如 “myProgram.exe”,再点击 “Next”。在 “Advanced Options” 页面,可以根据需要勾选一些选项,比如 “Log Stack Trace”,它能记录程序崩溃时的堆栈信息,这对于定位问题非常有帮助,完成选择后继续点击 “Next”。在 “Save & Activate” 页面,给这个规则取一个名字,比如 “myProgram Crash Rule”,然后点击 “Finish” 完成规则设置并激活它。

当目标程序发生崩溃时,DebugDiag 就会按照我们设置的规则,在指定的文件夹中生成 Dump 文件,这个指定文件夹可以在规则设置的 “Advanced Options” 页面中进行配置,默认是 DebugDiag 安装目录下的 “Logs” 文件夹。

(三)利用 CLRMD 库以编程方式实现

CLRMD(Common Language Runtime Managed Debugging)库提供了一种通过编程方式生成 Dump 文件的方法,这在一些自动化测试或特定的开发场景中非常有用。

在使用 CLRMD 库之前,需要先在项目中添加对它的引用。如果是使用 NuGet 包管理器,只需在 “程序包管理器控制台” 中输入 “Install-Package Microsoft.Diagnostics.Runtime” 命令,即可安装 CLRMD 库。

下面是一个使用 CLRMD 库生成 Dump 文件的简单示例代码:

using System;
using System.Diagnostics;
using Microsoft.Diagnostics.Runtime;class Program
{static void Main(){// 获取目标进程ID,这里假设目标进程ID为1234,实际使用时需要根据实际情况获取int targetProcessId = 1234;// 打开目标进程using (DataTarget dataTarget = DataTarget.AttachToProcess(targetProcessId, 5000, AttachFlag.Passive)){// 设置Dump文件保存路径string dumpFilePath = @"C:\Dumps\myDump.dmp";// 生成Dump文件dataTarget.WriteDump(dumpFilePath, ClrDataCreateDumpFlags.WithPrivateReadWriteMemory);Console.WriteLine($"Dump文件已生成: {dumpFilePath}");}}
}

在这段代码中,首先定义了目标进程 ID,然后使用DataTarget.AttachToProcess方法尝试附加到目标进程,如果在 5000 毫秒(5 秒)内成功附加,则返回一个DataTarget对象 。接着,指定了 Dump 文件的保存路径,最后调用dataTarget.WriteDump方法生成 Dump 文件,并传入了ClrDataCreateDumpFlags.WithPrivateReadWriteMemory标志,表示在生成的 Dump 文件中包含进程的私有读写内存信息,这样生成的 Dump 文件会更全面,有助于后续的分析。运行这段代码后,就会在指定路径下生成一个 Dump 文件。

三、解读 Dump 文件的 “密码本”

(一)Visual Studio:调试的得力助手

Visual Studio 是一款功能强大的集成开发环境,对于分析 Dump 文件也提供了非常便捷且实用的功能。

当我们需要分析一个 Dump 文件时,首先在 Visual Studio 中选择 “文件” 菜单,然后点击 “打开”,再选择 “转储文件”,找到我们之前生成的 Dump 文件并打开它 。打开后,Visual Studio 会自动检测并加载相关的符号文件(PDB 文件),这些符号文件包含了程序的调试信息,如变量名、函数名、行号等,对于准确分析问题至关重要 。如果 Visual Studio 没有自动找到符号文件,我们可以通过 “调试” 菜单下的 “选项和设置”,在 “符号” 选项中手动设置符号文件的路径,确保符号文件能够正确加载。

加载完成后,Visual Studio 会自动对崩溃转储进行分析,它会在 “诊断工具” 窗口中展示详细的分析结果。在这里,我们可以看到许多关键信息,比如异常类型和异常消息,这能让我们快速了解程序崩溃的直接原因。以一个简单的除法运算程序为例,如果出现除零异常,我们就能在诊断工具窗口中看到异常类型为 “DivideByZeroException”,异常消息会提示具体在哪个方法、哪一行代码发生了除零操作 。

同时,还能查看线程信息,包括每个线程的状态(运行、等待、阻塞等)、线程的调用栈。通过线程的调用栈,我们可以清晰地看到线程在程序崩溃前执行的方法调用顺序,这对于追踪问题的根源非常有帮助。比如在一个多线程的文件处理程序中,某个线程出现问题,通过查看线程调用栈,我们可以发现它在调用文件读取方法时出现了异常,进而深入分析文件读取的参数设置、文件是否存在等问题 。

此外,Visual Studio 还会突出显示一些重要信息,如占用大量内存的对象、长时间运行的线程等,这些信息都能引导我们更快地定位到程序中的潜在问题。

(二)WinDbg:深度分析的利器

WinDbg 是微软提供的一款强大的调试工具,它在深度分析 Dump 文件方面有着独特的优势,能够帮助我们挖掘出更底层的信息。

在使用 WinDbg 之前,需要先从微软官方网站下载并安装它。安装完成后,打开 WinDbg,我们就可以开始加载 Dump 文件进行分析了。

加载 Dump 文件的操作很简单,在 WinDbg 的菜单中选择 “File” -> “Open Crash Dump”,然后选择要分析的 Dump 文件。加载成功后,我们需要加载调试扩展,其中最常用的是 SOS(Son of Strike)扩展,它专门用于调试托管代码。加载 SOS 扩展的命令是:.loadby sos clr ,这里的 “clr” 表示公共语言运行时,通过这个命令,WinDbg 会加载与当前 Dump 文件对应的 SOS 扩展,以便后续使用各种针对托管代码的调试命令 。

加载完扩展后,就可以使用一系列常用的分析命令了。例如,使用!clrstack命令可以查看当前线程的托管堆栈信息,它会列出堆栈上的所有方法调用,以及每个方法的参数和局部变量 。假设我们有一个递归调用的方法导致了栈溢出问题,通过!clrstack命令,我们可以清晰地看到递归调用的层次和每一层的方法参数,从而找到递归的起始点和可能导致栈溢出的原因 。

!threads命令用于查看所有托管线程的信息,包括线程 ID、线程状态、线程优先级等。这在分析多线程问题时非常有用,比如在一个多线程的服务器程序中,通过!threads命令可以查看是否存在线程死锁、线程长时间阻塞等问题 。

!dumpheap -stat命令用于统计托管堆上各种对象的数量和大小,这对于查找内存泄漏问题非常关键。如果我们发现某个对象类型的数量不断增加,而没有相应的减少,就可能存在内存泄漏的情况 。通过进一步分析这些对象的创建和引用关系,就有可能找到内存泄漏的根源 。

四、代码中的 Dump 魔法秀

(一).NET Framework 版本中的应用

在.NET Framework 版本中,我们可以通过调用 Windows API 函数MiniDumpWriteDump来生成 Dump 文件。不过,在使用之前,需要先定义相关的枚举和结构体,并且使用DllImport特性来导入dbghelp.dll库中的MiniDumpWriteDump函数。下面是一个完整的示例代码:

using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Diagnostics;public class Program
{// 定义Dump类型的枚举,这里只列举了部分常用的,更多详情可查看MSDN[Flags]public enum MiniDumpType : uint{MiniDumpNormal = 0x00000000,MiniDumpWithFullMemory = 0x00000002,MiniDumpWithHandleData = 0x00000004}// 定义MiniDumpExceptionInformation结构体,用于传递异常信息[StructLayout(LayoutKind.Sequential, Pack = 4)]public struct MiniDumpExceptionInformation{public uint ThreadId;public IntPtr ExceptionPointers;[MarshalAs(UnmanagedType.Bool)]public bool ClientPointers;}// 导入dbghelp.dll中的MiniDumpWriteDump函数[DllImport("dbghelp.dll", SetLastError = true)]public static extern bool MiniDumpWriteDump(IntPtr hProcess,uint processId,SafeHandle hFile,uint dumpType,ref MiniDumpExceptionInformation expParam,IntPtr userStreamParam,IntPtr callbackParam);public static void Main(){CreateDump();}public static void CreateDump(){// 获取当前正在运行的进程Process currentProcess = Process.GetCurrentProcess();// 创建一个MiniDumpExceptionInformation对象MiniDumpExceptionInformation eInfo = new MiniDumpExceptionInformation();eInfo.ThreadId = (uint)currentProcess.Threads[0].Id;eInfo.ExceptionPointers = Marshal.GetExceptionPointers();eInfo.ClientPointers = false;// 设置Dump文件的保存路径string filePath = @"C:\temp\dumpfile.dmp";// 使用FileStream创建一个文件,用于保存Dump数据using (FileStream stream = new FileStream(filePath, FileMode.Create)){// 调用MiniDumpWriteDump函数生成Dump文件bool success = MiniDumpWriteDump(currentProcess.Handle,(uint)currentProcess.Id,stream.SafeFileHandle,(uint)MiniDumpType.MiniDumpWithFullMemory,ref eInfo,IntPtr.Zero,IntPtr.Zero);// 检查生成是否成功,如果失败则抛出异常if (!success){throw new Exception("MiniDumpWriteDump failed");}}}
}

在这段代码中,首先定义了MiniDumpType枚举,它包含了不同的 Dump 类型选项,这里只展示了MiniDumpNormal(普通 Dump)、MiniDumpWithFullMemory(包含完整内存的 Dump)和MiniDumpWithHandleData(包含句柄数据的 Dump) 。然后定义了MiniDumpExceptionInformation结构体,用于存储异常相关的信息,如线程 ID、异常指针和客户端指针标志 。通过DllImport特性导入MiniDumpWriteDump函数,该函数负责将进程的状态信息写入到指定的文件中,生成 Dump 文件 。

在CreateDump方法中,获取当前进程,初始化MiniDumpExceptionInformation对象,指定 Dump 文件的保存路径,然后调用MiniDumpWriteDump函数生成 Dump 文件 。如果生成过程失败,会抛出异常提示用户。

(二).NET Core 之后版本的实现

在.NET Core 中,由于其跨平台的特性,无法直接使用MiniDumpWriteDump这个 Windows API 函数。不过,我们可以借助第三方库Microsoft.Diagnostics.NETCore.Client来实现生成 Dump 文件的功能。

首先,需要在项目中安装Microsoft.Diagnostics.NETCore.Client库。可以通过 NuGet 包管理器来安装,具体步骤如下:

  1. 打开 Visual Studio,在解决方案资源管理器中右键点击项目名称,选择 “管理 NuGet 程序包”。

  2. 在打开的 NuGet 包管理器窗口中,搜索 “Microsoft.Diagnostics.NETCore.Client”。

  3. 找到该包后,点击 “安装” 按钮,将其安装到项目中。

安装完成后,就可以使用以下代码来生成 Dump 文件:

using Microsoft.Diagnostics.NETCore.Client;
using System;namespace DumpDemo
{internal class Program{static void Main(string[] args){// 从命令行参数获取要收集Dump的进程ID和Dump文件保存路径int processId = int.Parse(args[0]); string dumpFilePath = args[1]; CreateDump(processId, dumpFilePath);}public static void CreateDump(int processId, string dumpFilePath){// 创建DiagnosticsClient对象,用于与目标进程进行交互var client = new DiagnosticsClient(processId);// 调用WriteDump方法生成Dump文件,这里使用Normal类型的Dumpclient.WriteDump(DumpType.Normal, dumpFilePath);}// 定义DumpType枚举,包含不同类型的Dumppublic enum DumpType{Normal = 1,WithHeap = 2,Triage = 3,Full = 4}}
}

在这段代码中,首先从命令行参数获取要收集 Dump 的进程 ID 和 Dump 文件的保存路径 。然后创建DiagnosticsClient对象,该对象用于与目标进程进行交互,通过它可以执行各种诊断操作,如生成 Dump 文件 。调用client.WriteDump方法生成 Dump 文件,传入DumpType.Normal表示生成普通类型的 Dump 文件,这种类型的 Dump 文件主要包含线程和某些系统信息,但不包括堆信息,文件相对较小,适用于在处理能力有限的环境中快速捕获应用程序的状态 。如果需要生成包含更多信息的 Dump 文件,如包含堆信息的WithHeap类型、用于快速诊断常见问题的Triage类型或包含进程所有内存的Full类型,可以根据实际需求修改传入的DumpType参数 。

五、Dump 使用的注意事项与技巧

(一)优化 Dump 文件大小

在实际应用中,Dump 文件可能会因为包含大量的内存信息而变得非常庞大,这不仅会占用大量的磁盘空间,还会增加传输和分析的难度。因此,优化 Dump 文件大小是一个需要重视的问题。

一种有效的方法是只保存必要的内存区域。在生成 Dump 文件时,可以根据实际需求选择只包含关键线程的信息,而不是整个进程的所有线程信息。例如,在一个多线程的服务器程序中,可能只有处理关键业务逻辑的线程出现了问题,那么我们可以只保存这些线程的相关内存区域,这样可以大大减少 Dump 文件的大小 。在使用MiniDumpWriteDump函数时,可以通过设置合适的MiniDumpType参数来实现这一目的,比如使用MiniDumpNormal类型,它只包含调用栈相关信息,相比包含全部可访问内存的MiniDumpWithFullMemory类型,生成的 Dump 文件会小很多 。

另一种常见的优化方法是对 Dump 文件进行压缩。在 C# 中,可以使用System.IO.Compression命名空间下的相关类来实现文件压缩。例如,使用ZipFile.CreateFromDirectory方法将 Dump 文件压缩成 ZIP 格式 。以下是一个简单的示例代码:

using System.IO.Compression;class Program
{static void Main(){string sourceDumpFilePath = @"C:\Dumps\myDump.dmp";string zipFilePath = @"C:\Dumps\myDump.zip";ZipFile.CreateFromDirectory(sourceDumpFilePath, zipFilePath);}
}

在这个示例中,sourceDumpFilePath是原始的 Dump 文件路径,zipFilePath是压缩后的 ZIP 文件路径。通过执行这段代码,就可以将原始的 Dump 文件压缩成一个 ZIP 文件,从而减小文件大小,方便存储和传输 。

(二)保障 Dump 文件安全

由于 Dump 文件包含了程序运行时的内存信息,其中可能包含敏感数据,如用户密码、数据库连接字符串、重要的业务数据等,因此 Dump 文件的安全性至关重要。如果这些文件被攻击者获取,他们可能会从中提取敏感信息,进而对系统造成严重的安全威胁,比如利用获取的数据库连接字符串进行非法的数据访问,或者使用用户密码进行恶意登录等 。

为了保障 Dump 文件的安全,一种常见的措施是对 Dump 文件进行加密。在 C# 中,可以使用System.Security.Cryptography命名空间下的加密算法来实现。例如,使用 AES(高级加密标准)算法对 Dump 文件进行加密。以下是一个简单的加密示例代码:

using System;
using System.IO;
using System.Security.Cryptography;class Program
{static void Main(){string sourceDumpFilePath = @"C:\Dumps\myDump.dmp";string encryptedDumpFilePath = @"C:\Dumps\myEncryptedDump.dmp";string key = "ThisIsASecretKey12345"; // 实际应用中应使用更安全的密钥管理方式using (Aes aesAlg = Aes.Create()){aesAlg.Key = System.Text.Encoding.UTF8.GetBytes(key);aesAlg.IV = new byte[16]; // 初始化向量,这里简单设置为全0,实际应用中应随机生成ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);using (FileStream sourceFileStream = new FileStream(sourceDumpFilePath, FileMode.Open, FileAccess.Read)){using (FileStream encryptedFileStream = new FileStream(encryptedDumpFilePath, FileMode.Create, FileAccess.Write)){using (CryptoStream cryptoStream = new CryptoStream(encryptedFileStream, encryptor, CryptoStreamMode.Write)){sourceFileStream.CopyTo(cryptoStream);}}}}}
}

在这段代码中,首先定义了原始 Dump 文件路径sourceDumpFilePath和加密后 Dump 文件路径encryptedDumpFilePath,以及一个加密密钥key(实际应用中应使用更安全的密钥管理方式,如密钥管理系统) 。然后使用Aes.Create()方法创建 AES 加密对象,设置密钥和初始化向量(这里简单设置为全 0,实际应用中应随机生成) 。接着创建加密器encryptor,通过CryptoStream将原始 Dump 文件的内容加密后写入到新的加密文件中 。

除了加密,还可以通过限制访问权限来保障 Dump 文件的安全。在 Windows 系统中,可以利用文件系统的访问控制列表(ACL)来设置只有特定的用户或组才能访问 Dump 文件 。例如,将 Dump 文件存储在一个特定的文件夹中,然后通过文件夹的属性设置,只赋予管理员组和开发人员组读取和写入权限,其他用户或组则没有任何访问权限,这样可以有效防止 Dump 文件被非法访问和获取 。

六、总结与展望

在 C# 的编程旅程中,Dump 无疑是一把强大的 “瑞士军刀”,它生成的 dump 文件承载着程序运行状态的关键信息,在程序出现性能瓶颈、崩溃、内存泄漏等复杂问题时,成为我们定位和解决问题的有力武器。通过任务管理器、Process Explorer、DebugDiag 工具以及 CLRMD 库等多种方式,我们能够灵活地生成不同类型的 dump 文件,满足各种场景下的调试需求 。

在分析 dump 文件时,Visual Studio 和 WinDbg 等工具为我们提供了深入探究程序内部状态的能力,从异常类型和线程信息,到托管堆栈和内存使用情况,这些工具帮助我们抽丝剥茧,找出问题的根源 。在代码实现方面,无论是在.NET Framework 版本中调用 Windows API 函数,还是在.NET Core 之后的版本中借助第三方库,我们都能根据具体的平台和项目需求,实现 dump 文件的生成 。

然而,在使用 Dump 的过程中,我们也需要关注一些重要的事项。比如,优化 dump 文件大小,避免因文件过大带来的存储和传输难题;保障 dump 文件的安全,防止敏感信息泄露,对 dump 文件进行加密和限制访问权限等措施必不可少 。

展望未来,随着 C# 语言和.NET 框架的不断发展,Dump 在程序开发和调试中的应用前景将更加广阔。在云计算和分布式系统日益普及的今天,Dump 技术有望在处理大规模、复杂的分布式应用程序的调试和性能优化方面发挥更大的作用 。例如,在微服务架构中,当多个服务之间出现通信问题或性能瓶颈时,通过在各个服务节点上生成 dump 文件,并进行统一的分析和诊断,能够快速定位问题所在,提高系统的稳定性和可靠性 。同时,随着人工智能和机器学习技术的发展,未来可能会出现更加智能的 Dump 分析工具,它们能够自动识别常见的问题模式,并提供针对性的解决方案,进一步提升开发人员的调试效率 。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/14635.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Dify Ollama本地私有化模型实践

今天给大家带来一篇deepseek本地部署,笔者最近由于研究AI大模型应用开发,笔记较少,后面将持续输出关于AI行业应用知识,请大家继续关注,话不多说,开始吧,啊哈哈。 DeepSeek 呢,最近十…

Kafka中的KRaft算法

我们之前的Kafka值依赖于Zookeeper注册中心来启动的,往里面注册我们节点信息 Kafka是什么时候不依赖Zookeeper节点了 在Kafka2.8.0开始就可以不依赖Zookeeper了 可以用KRaft模式代替Zookeeper管理Kafka集群 KRaft Controller和KRaft Leader的关系 两者关系 Lea…

GitPuk快速安装配置教程(入门级)

GitPuk是一款国产开源免费的代码管理工具,工具简洁易用,开源免费,本文将讲解如何快速安装和配置GitPuk,以快速入门上手。 1、安装 支持 Windows、Mac、Linux、docker 等操作系统。 1.1 Linux安装 以下以Centos7安装…

2025年02月08日Github流行趋势

项目名称:anything-llm 项目地址url:https://github.com/Mintplex-Labs/anything-llm项目语言:JavaScript历史star数:34323今日star数:675项目维护者:timothycarambat, shatfield4, MrSimonC, franzbischof…

【C语言标准库函数】指数与对数函数:exp(), log(), log10()

目录 一、头文件 二、函数简介 2.1. exp(double x) 2.2. log(double x) 2.3. log10(double x) 三、函数实现(概念性) 3.1. exp(double x) 的模拟实现 3.2. log(double x) 和 log10(double x) 的模拟实现 四、注意事项 4.1. exp(double x) 的注…

Linux之kernel(1)系统基础理论(1)

Linux之Kernel(1)系统基础理论(1) Author: Once Day Date: 2025年2月6日 一位热衷于Linux学习和开发的菜鸟,试图谱写一场冒险之旅,也许终点只是一场白日梦… 漫漫长路,有人对你微笑过嘛… 全系列文章可参考专栏: Linux内核知识_Once-Day的…

从 Facebook 到元宇宙:社交网络的技术进化与前景

引言 社交网络的演变不仅仅是技术进步的体现,更是人类沟通方式革命的缩影。从 Facebook 的诞生到元宇宙的兴起,我们见证了社交互动从简单的信息交换到沉浸式虚拟体验的转变。本文将探讨这一技术演进的历程,并展望社交网络在元宇宙时代的新形…

内容中台赋能人工智能技术提升业务创新能力

内容概要 在当今快速变化的市场环境中,企业需要不断寻求创新以保持竞争力。内容中台作为一种新型的内容管理架构,能够极大地提升企业在内容创建、管理和分发方面的效率。通过与人工智能技术的深度融合,企业能够将海量的数据和信息转化为有价…

qt部分核心机制

作业 1> 手动将登录项目实现,不要使用拖拽编程 并且,当点击登录按钮时,后台会判断账号和密码是否相等,如果相等给出登录成功的提示,并且关闭当前界面,发射一个跳转信号,如果登录失败&#…

深度解析全钢陶瓷防静电地板在机房装修中应用较多的原因

全钢陶瓷防静电地板之所以在机房装修中应用较多,是因为它结合了全钢结构和陶瓷面层的双重优势,能够满足高要求场景(如数据中心、实验室、医疗设施等)对防静电性能、承重能力、耐用性及环境适应性的综合需求。以下是具体原因分析&a…

数据表中的视图操作

文章目录 一、视图概述二、为什么要使用视图三、创建视图四、查看视图 一、视图概述 小学的时候,每年都会举办一次抽考活动,意思是从每一个班级里面筛选出几个优秀的同学去参加考试,这时候很多班级筛选出来的这些同学就可以临时组成一个班级…

zzcms接口index.php id参数存在SQL注入漏洞

zzcms接口index.php id参数存在SQL注入漏洞 漏洞描述 ZZCMS 2023中发现了一个严重漏洞。该漏洞影响了文件/index.php中的某些未知功能,操纵参数id会导致SQL注入,攻击可能是远程发起的,该漏洞已被公开披露并可被利用。攻击者可通过sql盲注等手段,获取数据库信息。 威胁等级:…

Mobaxterm上传下载文件

上传文件 ctrl 右击,选择send file use z-modem 弹窗选择要上传的文件即可 下载文件 输入sz xxx.log ctrl 右击,选择receive file use z-modem 弹窗选择要文件下载的路径即可

cs106x-lecture2(上)(Autumn 2017)

打卡cs106x(Autumn 2017)-lecture2 1、parameterMysteryBCA What is the output of the following code? void mystery(int& b, int c, int& a) {a;b--;c a; } ​ int main() {int a 5;int b 2;int c 8;mystery(c, a, b);cout << a << " "…

e2studio开发RA2E1(9)----定时器GPT配置输入捕获

e2studio开发RA2E1.9--定时器GPT配置输入捕获 概述视频教学样品申请硬件准备参考程序源码下载选择计时器时钟源UART配置UART属性配置设置e2studio堆栈e2studio的重定向printf设置R_SCI_UART_Open()函数原型回调函数user_uart_callback ()printf输出重定向到串口定时器输入捕获配…

JVM虚拟机以及跨平台原理

相信大家已经了解到Java具有跨平台的特性&#xff0c;即“一次编译&#xff0c;到处运行”&#xff0c;例如在Windows下编写的程序&#xff0c;无需任何修改就可以在Linux下运行&#xff0c;这是C和C很难做到的。 那么&#xff0c;跨平台是怎样实现的呢&#xff1f;这就要谈及…

激活函数篇 02 —— 双曲正切函数tanh

本篇文章收录于专栏【机器学习】 以下是激活函数系列的相关的所有内容: 一文搞懂激活函数在神经网络中的关键作用 逻辑回归&#xff1a;Sigmoid函数在分类问题中的应用 tanh ⁡ ( x ) e x − e − x e x e − x \tanh(x)\frac{e^x - e^{-x}}{e^x e^{-x}} tanh(x)exe−xex…

redis高级数据结构布隆过滤器

文章目录 背景什么是布隆过滤器Redis 中的布隆过滤器布隆过滤器使用注意事项实现原理空间占用估计 背景 我们在使用新闻客户端看新闻时&#xff0c;它会给我们不停地推荐新的内容&#xff0c;它每次推荐时要去重&#xff0c;去掉那些已经看过的内容。问题来了&#xff0c;新闻…

存储异常导致的Oracle重大生产故障

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 作者&#xff1a;IT邦德 中国DBA联盟(ACDU)成员&#xff0c;10余年DBA工作经验 Oracle、PostgreSQL ACE CSDN博客专家及B站知名UP主&#xff0c;全网粉丝10万 擅长主流Oracle、MySQL、PG、高斯…

在 Navicat 17 中扩展 PostgreSQL 数据类型 | 创建自定义域

定义域 以适当的格式存储数据可以确保数据完整性&#xff0c;防止错误&#xff0c;优化性能&#xff0c;并通过实施验证规则和支持高效数据管理来维护系统间的一致性。基于这些原因&#xff0c;顶级关系数据库&#xff08;如PostgreSQL&#xff09;提供了多种数据类型。此外&a…