游戏引擎学习第五天

这节貌似没讲什么
视频参考:https://www.bilibili.com/video/BV1Gmm2Y5EwE/

uint8 *A = somewhere in memory;
uint8 *B = somewhere in memory;//BEFORE WE GOT TO HERE
int Y = *B; // == whatever was actually there before the 5
*A = 5;
int X = *B; // == 5
//Obviously! Y and X 
//DUH? The compiler should just load it once

在你的代码示例中:

以下是对每部分的解释:

  • uint8 *Auint8 *B:这两个是指向内存位置的指针,指向某个内存区域。具体的内存地址在代码中没有明确给出,因此我们不清楚它们指向的具体内存。

  • int Y = *B;:这行代码将指针 B 指向的内存位置的值解引用(即读取 *B)并将其赋值给 Y

  • *A = 5;:这行代码将指针 A 指向的内存位置的值设置为 5

  • int X = *B;:最后,代码再次解引用指针 B,将其值赋给 X

问题:为什么编译器不应该重新加载 *B,而是直接使用 Y 的值?

  • “编译器应该只加载一次”: 这段注释表示,从理论上讲,一旦 *B 的值被加载到 Y 中,之后不应该再次加载,因为在代码中并没有直接修改 B 指向的内存。因此,编译器本可以通过将 *B 的值存储到临时变量中,从而避免在 X 的赋值中再次解引用 B

为什么这种优化可能没有发生?

  1. 内存访问优化: 编译器在优化内存访问时,通常假设内存可能被程序的其他部分修改,尤其是如果这些内存可能是共享的。比如,AB 如果指向同一内存区域,或者内存的值可能被其他线程或硬件修改,编译器就不能假设 *B 在两次访问之间没有发生变化。

  2. 指针别名(Pointer Aliasing): 如果 AB 是指向同一块内存区域的指针,编译器不能假设 *B 的值在两次解引用之间不变,因为对 *A 的赋值可能会影响到 *B(例如,AB 指向同一内存)。因此,编译器不能简单地优化掉第二次对 *B 的解引用。

  3. 优化标志: 现代编译器有不同的优化等级,某些优化(如这类优化)只有在设置了较高的优化标志时才会执行(例如,GCC 中的 -O2-O3)。如果没有进行优化,或者优化级别较低(如 -O0),编译器可能不会执行这种优化。

  4. 内存的易变性(Volatility): 如果 AB 指向的内存被标记为 volatile,编译器就会强制每次都解引用它们,而不进行任何假设或优化。volatile 常用于与内存映射的 I/O、硬件寄存器或并发环境中的共享内存交互。

总结

简单来说,编译器 可以 通过将 *B 的值存储到一个临时变量中,避免第二次解引用 *B(即优化掉这次内存加载),前提是 编译器能够保证 *B 的值在两次解引用之间没有改变。然而,由于指针别名、并发操作或其他潜在的副作用,编译器可能不能进行这种优化。编译器是否进行优化取决于它对内存模型的理解以及它是否能保证两次解引用之间 *B 的值不变。

在这段代码中,MSG Message; 的声明位置取决于你对 MSG 变量的作用范围的需求。一般来说,建议将其声明放在 while 循环内部,而不是外部,原因如下:

  1. 局部性和性能:
    如果将 MSG 声明放在循环外部,MSG 变量将在每次循环时保持其值,可能导致不必要的残留数据。如果将其放在循环内部,每次循环都会创建一个新的 MSG 变量,避免了不必要的状态残留。

  2. 清晰的作用范围:
    MSG Message; 放在循环内部可以限制其作用范围,使得它只在当前的循环中有效。这使得代码更加清晰,并且减少了作用域问题。例如,如果你在多个地方使用 Message,会更容易理解它的生命周期和作用域。

  3. 避免潜在的逻辑错误:
    如果 MSG Message; 放在循环外部,它可能会在消息队列没有更新时继续保留上一个循环的消息,这可能会导致错误的行为。将其放在内部能确保每次迭代都能正确接收和处理新的消息。

因此,将 MSG Message; 放在 while 循环内部是更好的选择。你的代码可以这样优化:

if (Window) { // 检查窗口句柄是否有效,若有效则进入消息循环int xOffset = 0;int yOffset = 0;Running = true;while (Running) { // 启动一个无限循环,等待和处理消息MSG Message;    // 将 MSG 声明移至 while 循环内部while (PeekMessage(&Message,0, // hWnd 为 NULL,则检查当前线程中所有窗口的消息0, 0, // 用于设定消息类型的范围PM_REMOVE // 将消息从消息队列中移除,类似于 GetMessage 的行为)) {if (Message.message == WM_QUIT) {Running = false;}TranslateMessage(&Message); // 翻译消息,如果是键盘消息需要翻译DispatchMessage(&Message); // 分派消息,调用窗口过程处理消息}RenderWeirdGradient(xOffset, yOffset); // 渲染{HDC DeviceContext = GetDC(Window);RECT WindowRect;GetClientRect(Window, &WindowRect);int WindowWidth = WindowRect.right - WindowRect.left;int WindowHeight = WindowRect.bottom - WindowRect.top;Win32UpdateWindow(DeviceContext, &WindowRect, 0, 0, WindowWidth, WindowHeight);ReleaseDC(Window, DeviceContext);}++xOffset;}
}

这样可以确保每次循环都从消息队列中正确获取新的消息,并且 MSG 变量的作用范围是局部的。

根据您提供的栈中变量地址和内容,可以绘制出堆栈结构图,展示各个局部变量如何在栈帧中存储。以下是一个简化的堆栈结构图:

栈结构图

+----------------------------------------------------+  <- 栈顶
|                    返回地址                        |  
+----------------------------------------------------+  
|                参数 cmdshow (int *)                |  <- 参数 cmdshow 存储在此,指向栈上的一个 int 值
|                0x000000721a8ffbc8                   |  
+----------------------------------------------------+  
|                参数 cmdline (char **)              |  <- 参数 cmdline 存储在此,指向栈上的一个字符串
|                0x000000721a8ffbc0                   |  
+----------------------------------------------------+  
|           参数 hInstPrev (HINSTANCE__ **)          |  <- 参数 hInstPrev 存储在此,指向一个空指针
|                0x000000721a8ffbb8                   |  
+----------------------------------------------------+  
|           参数 hInst (HINSTANCE__ **)               |  <- 参数 hInst 存储在此,指向一个有效的 HINSTANCE
|                0x000000721a8ffbb0                   |  
+----------------------------------------------------+  
|              WindowClass (WNDCLASS)                |  <- WindowClass 存储在此
|                0x000000721a8ff2f0                   |  
|                style = 0                           |  
|                lpfnWndProc = 0x0000000000000000     |  
|                cbClsExtra = 0                      |  
|                ...                                 |  
+----------------------------------------------------+  
|           BigOldBlockOfMemory (1024KB)             |  <- 大的内存块,占用 1024KB
|                0x000000721a8042d0                   |  
|                [1024KB 内存空间]                   |  <- 1MB 数据
+----------------------------------------------------+  <- 栈底

在这里插入图片描述

解释:

  1. 栈顶(返回地址):函数 WinMain 返回时,程序会跳到此地址。
  2. 参数 cmdshow, cmdline, hInstPrev, hInst:这些参数的值存储在栈帧中,按顺序排列:
    • cmdshow 存储了一个 int * 类型的地址,指向栈上的值 10
    • cmdline 存储了一个 char ** 类型的地址,指向栈上的字符串(为空字符串)。
    • hInstPrev 存储了一个 HINSTANCE__ ** 类型的地址,指向 NULL
    • hInst 存储了一个 HINSTANCE__ ** 类型的地址,指向有效的程序映像基址 game.exe
  3. WindowClass:是一个 WNDCLASS 结构体,包含多种成员(如 style, lpfnWndProc 等)。每个成员被初始化为零或 nullptr
  4. BigOldBlockOfMemory:这是一个 1MB 大小的 uint8 数组,栈上分配。它存储在 BigOldBlockOfMemory 地址处,内部包含 1024KB 的数据。

注意:

  • 栈分配顺序:栈的分配是从高地址向低地址方向进行的,所以栈顶的变量(返回地址)先存储,然后是函数参数,最后是局部变量(如 WindowClassBigOldBlockOfMemory)。
  • 指针的存储:对于指针类型的变量(如 cmdshow, cmdline, hInstPrev, hInst),它们存储的是指向实际数据的地址。这些数据的内容在栈帧中的其他位置。
// game.cpp : Defines the entry point for the application.
//#include <cstdint>
#include <stdint.h>
#include <windows.h>#define internal static        // 用于定义内翻译单元内部函数
#define local_persist static   // 局部静态变量
#define global_variable static // 全局变量typedef uint8_t uint8;
typedef uint16_t uint16;
typedef uint32_t uint32;
typedef uint64_t uint64;typedef int8_t int8;
typedef int16_t int16;
typedef int32_t int32;
typedef int64_t int64;struct win32_offscreen_buffer {BITMAPINFO Info;void *Memory;// 后备缓冲区的宽度和高度int Width;int Height;int Pitch;int BytesPerPixel;
};// TODO: 全局变量
global_variable bool Running;
global_variable win32_offscreen_buffer GlobalBackbuffer;// 添加这个去掉重复的冗余代码
struct win32_window_dimension {int Width;int Height;
};win32_window_dimension Win32GetWindowDimension(HWND Window) {win32_window_dimension Result;RECT ClientRect;GetClientRect(Window, &ClientRect);// 计算绘制区域的宽度和高度Result.Height = ClientRect.bottom - ClientRect.top;Result.Width = ClientRect.right - ClientRect.left;return Result;
}// 渲染一个奇异的渐变图案
internal void RenderWeirdGradient(win32_offscreen_buffer Buffer, int BlueOffset,int GreenOffset) {// TODO:让我们看看优化器是怎么做的uint8 *Row = (uint8 *)Buffer.Memory;      // 指向位图数据的起始位置for (int Y = 0; Y < Buffer.Height; ++Y) { // 遍历每一行uint32 *Pixel = (uint32 *)Row;          // 指向每一行的起始像素for (int X = 0; X < Buffer.Width; ++X) { // 遍历每一列uint8 Blue = (X + BlueOffset);         // 计算蓝色分量uint8 Green = (Y + GreenOffset);       // 计算绿色分量*Pixel++ = ((Green << 8) | Blue);      // 设置当前像素的颜色}Row += Buffer.Pitch; // 移动到下一行}
}// 这个函数用于重新调整 DIB(设备独立位图)大小
internal void Win32ResizeDIBSection(win32_offscreen_buffer *Buffer, int width,int height) {// device independent bitmap(设备独立位图)// TODO: 进一步优化代码的健壮性// 可能的改进:先不释放,先尝试其他方法,再如果失败再释放。if (Buffer->Memory) {VirtualFree(Buffer->Memory, // 指定要释放的内存块起始地址0, // 要释放的大小(字节),对部分释放有效,整体释放则设为 0MEM_RELEASE); // MEM_RELEASE:释放整个内存块,将内存和地址空间都归还给操作系统}// 赋值后备缓冲的宽度和高度Buffer->Width = width;Buffer->Height = height;Buffer->BytesPerPixel = 4;// 设置位图信息头(BITMAPINFOHEADER)Buffer->Info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); // 位图头大小Buffer->Info.bmiHeader.biWidth = Buffer->Width; // 设置位图的宽度Buffer->Info.bmiHeader.biHeight =-Buffer->Height; // 设置位图的高度(负号表示自上而下的方向)Buffer->Info.bmiHeader.biPlanes = 1; // 设置颜色平面数,通常为 1Buffer->Info.bmiHeader.biBitCount =32; // 每像素的位数,这里为 32 位(即 RGBA)Buffer->Info.bmiHeader.biCompression =BI_RGB; // 无压缩,直接使用 RGB 颜色模式// 创建 DIBSection(设备独立位图)并返回句柄// TODO:我们可以自己分配?int BitmapMemorySize =(Buffer->Width * Buffer->Height) * Buffer->BytesPerPixel;Buffer->Memory = VirtualAlloc(0, // lpAddress:指定内存块的起始地址。// 通常设为 NULL,由系统自动选择一个合适的地址。BitmapMemorySize, // 要分配的内存大小,单位是字节。MEM_COMMIT, // 分配物理内存并映射到虚拟地址。已提交的内存可以被进程实际访问和操作。PAGE_READWRITE // 内存可读写);Buffer->Pitch = width * Buffer->BytesPerPixel; // 每一行的字节数// TODO:可能会把它清除成黑色
}// 这个函数用于将 DIBSection 绘制到窗口设备上下文
internal void Win32DisplayBufferInWindow(HDC DeviceContext, int WindowWidth,int WindowHeight,win32_offscreen_buffer Buffer, int X,int Y, int Width, int Height) {// 使用 StretchDIBits 将 DIBSection 绘制到设备上下文中StretchDIBits(DeviceContext, // 目标设备上下文(窗口或屏幕的设备上下文)/*X, Y, Width, Height, // 目标区域的 x, y 坐标及宽高X, Y, Width, Height,*/0, 0, WindowWidth, WindowHeight,   //0, 0, Buffer.Width, Buffer.Height, //// 源区域的 x, y 坐标及宽高(此处源区域与目标区域相同)Buffer.Memory,  // 位图内存指针,指向 DIBSection 数据&Buffer.Info,   // 位图信息,包含位图的大小、颜色等信息DIB_RGB_COLORS, // 颜色类型,使用 RGB 颜色SRCCOPY); // 使用 SRCCOPY 操作符进行拷贝(即源图像直接拷贝到目标区域)
}LRESULT CALLBACK
Win32MainWindowCallback(HWND hwnd, // 窗口句柄,表示消息来源的窗口UINT Message, // 消息标识符,表示当前接收到的消息类型WPARAM wParam, // 与消息相关的附加信息,取决于消息类型LPARAM LParam) { // 与消息相关的附加信息,取决于消息类型LRESULT Result = 0; // 定义一个变量来存储消息处理的结果switch (Message) { // 根据消息类型进行不同的处理case WM_CREATE: {OutputDebugStringA("WM_CREATE\n");};case WM_SIZE: { // 窗口大小发生变化时的消息} break;case WM_DESTROY: { // 窗口销毁时的消息// TODO: 处理错误,用重建窗口Running = false;} break;case WM_CLOSE: { // 窗口关闭时的消息// TODO: 像用户发送消息进行处理Running = false;} break;case WM_ACTIVATEAPP: { // 应用程序激活或失去焦点时的消息OutputDebugStringA("WM_ACTIVATEAPP\n"); // 输出调试信息,表示应用程序激活或失去焦点} break;case WM_PAINT: { // 处理 WM_PAINT 消息,通常在窗口需要重新绘制时触发PAINTSTRUCT Paint; // 定义一个 PAINTSTRUCT 结构体,保存绘制的信息// 调用 BeginPaint 开始绘制,并获取设备上下文 (HDC),同时填充 Paint 结构体HDC DeviceContext = BeginPaint(hwnd, &Paint);// 获取当前绘制区域的左上角坐标int X = Paint.rcPaint.left;int Y = Paint.rcPaint.top;// 计算绘制区域的宽度和高度int Height = Paint.rcPaint.bottom - Paint.rcPaint.top;int Width = Paint.rcPaint.right - Paint.rcPaint.left;win32_window_dimension Dimension = Win32GetWindowDimension(hwnd);Win32DisplayBufferInWindow(DeviceContext, Dimension.Width, Dimension.Height,GlobalBackbuffer, X, Y, Width, Height);#if 0local_persist DWORD Operation = WHITENESS;// 使用 WHITENESS 操作符填充矩形区域为白色PatBlt(DeviceContext, X, Y, Width, Height, Operation);// 设置窗体的颜色在刷新时白色和黑色之间来回变换if (Operation == WHITENESS) {Operation = BLACKNESS;} else {Operation = WHITENESS;}
#endif// 调用 EndPaint 结束绘制,并释放设备上下文EndPaint(hwnd, &Paint);} break;default: { // 对于不处理的消息,调用默认的窗口过程Result = DefWindowProc(hwnd, Message, wParam,LParam); // 调用默认窗口过程处理消息} break;}return Result; // 返回处理结果
}int CALLBACK WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, //PSTR cmdline, int cmdshow) {uint8 BigOldBlockOfMemory[1004 * 1024];WNDCLASS WindowClass = {};// 使用大括号初始化,所有成员都被初始化为零(0)或 nullptrWin32ResizeDIBSection(&GlobalBackbuffer, 1280, 720);// WindowClass.style:表示窗口类的样式。通常设置为一些 Windows// 窗口样式标志(例如 CS_HREDRAW, CS_VREDRAW)。WindowClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;// CS_HREDRAW 当窗口的宽度发生变化时,窗口会被重绘。// CS_VREDRAW 当窗口的高度发生变化时,窗口会被重绘//  WindowClass.lpfnWndProc:指向窗口过程函数的指针,窗口过程用于处理与窗口相关的消息。WindowClass.lpfnWndProc = Win32MainWindowCallback;// WindowClass.hInstance:指定当前应用程序的实例句柄,Windows// 应用程序必须有一个实例句柄。WindowClass.hInstance = hInst;// WindowClass.lpszClassName:指定窗口类的名称,通常用于创建窗口时注册该类。WindowClass.lpszClassName = "gameWindowClass"; // 类名if (RegisterClass(&WindowClass)) {             // 如果窗口类注册成功HWND Window = CreateWindowEx(0,                         // 创建窗口,使用扩展窗口风格WindowClass.lpszClassName, // 窗口类的名称,指向已注册的窗口类"game",                    // 窗口标题(窗口的名称)WS_OVERLAPPEDWINDOW |WS_VISIBLE, // 窗口样式:重叠窗口(带有菜单、边框等)并且可见CW_USEDEFAULT, // 窗口的初始位置:使用默认位置(X坐标)CW_USEDEFAULT, // 窗口的初始位置:使用默认位置(Y坐标)CW_USEDEFAULT, // 窗口的初始宽度:使用默认宽度CW_USEDEFAULT, // 窗口的初始高度:使用默认高度0,             // 父窗口句柄(此处无父窗口,传0)0,             // 菜单句柄(此处没有菜单,传0)hInst,         // 当前应用程序的实例句柄0 // 额外的创建参数(此处没有传递额外参数));// 如果窗口创建成功,Window 将保存窗口的句柄if (Window) { // 检查窗口句柄是否有效,若有效则进入消息循环int xOffset = 0;int yOffset = 0;Running = true;while (Running) { // 启动一个无限循环,等待和处理消息MSG Message;    // 声明一个 MSG 结构体,用于接收消息while (PeekMessage(&Message,// 指向一个 `MSG` 结构的指针。`PeekMessage`// 将在 `lpMsg` 中填入符合条件的消息内容。0,// `hWnd` 为`NULL`,则检查当前线程中所有窗口的消息;// 如果设置为特定的窗口句柄,则只检查该窗口的消息。0, //0, // 用于设定消息类型的范围PM_REMOVE // 将消息从消息队列中移除,类似于 `GetMessage` 的行为。)) {if (Message.message == WM_QUIT) {Running = false;}TranslateMessage(&Message); // 翻译消息,如果是键盘消息需要翻译DispatchMessage(&Message); // 分派消息,调用窗口过程处理消息}RenderWeirdGradient(GlobalBackbuffer, xOffset, yOffset);// 这个地方需要渲染一下不然是黑屏{HDC DeviceContext = GetDC(Window);win32_window_dimension Dimension = Win32GetWindowDimension(Window);RECT WindowRect;GetClientRect(Window, &WindowRect);int WindowWidth = WindowRect.right - WindowRect.left;int WindowHeigh = WindowRect.bottom - WindowRect.top;Win32DisplayBufferInWindow(DeviceContext, Dimension.Width,Dimension.Height, GlobalBackbuffer, 0, 0,WindowWidth, WindowHeigh);ReleaseDC(Window, DeviceContext);}++xOffset;}} else { // 如果窗口创建失败// 这里可以处理窗口创建失败的逻辑// 比如输出错误信息,或退出程序等// TODO:}} else { // 如果窗口类注册失败// 这里可以处理注册失败的逻辑// 比如输出错误信息,或退出程序等// TODO:}return 0;
}

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

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

相关文章

<项目代码>YOLOv7 草莓叶片病害识别<目标检测>

YOLOv7是一种单阶段&#xff08;one-stage&#xff09;检测算法&#xff0c;它将目标检测问题转化为一个回归问题&#xff0c;能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法&#xff08;如Faster R-CNN&#xff09;&#xff0c;YOLOv7具有更高的…

stm32 ADC实例解析(3)-多通道采集互相干扰的问题

文章目录 一、问题现象&#xff1a;二、原因分析&#xff1a;1、测量值不准问题分析&#xff1a;2、采样干扰问题分析 三、解决办法&#xff1a;1、硬件&#xff1a;&#xff08;1&#xff09;、电源供电&#xff08;2&#xff09;、引脚电容&#xff08;3&#xff09;、减少采…

[SaaS] 数禾科技 AIGC生成营销素材

https://zhuanlan.zhihu.com/p/923637935https://zhuanlan.zhihu.com/p/923637935

android studio 轮询修改对象属性(修改多个textview的text)

android studio版本&#xff1a;23.3.1 例程名称&#xff1a;loopsettextviewtext 这几天在帮一个朋友做个数独小游戏&#xff0c;如下图&#xff1a; 要可以玩自定义游戏&#xff0c;点击清空后&#xff0c;所以数字要清除。 要把所有的内容清空&#xff0c;一共有81个text…

Linux(CentOS)项目总结(前后端分离)

项目情况&#xff1a; 前端开发&#xff1a;vue3 vite ts VSCode后端开发&#xff1a;JDK17 Spring Boot 3 Mybatis Maven IDEA数据库&#xff1a;MySQL8.4.3 SQLyog代码管理&#xff1a;Git虚拟环境&#xff1a;VMware远程登录&#xff1a;FinalShell服务器操作系统&…

C# 选择文件夹路径

通过C#代码&#xff0c;调出windows风格的文件夹选择框。提供界面来选择指定文件夹&#xff0c;并将文件夹完整路径以字符串形式返回。 示例&#xff1a; 代码&#xff1a; #region 选择指定文件夹 string folderPath ""; FolderBrowserDialog folderBrowserDialo…

unity3d————协程原理讲解

1.协程的本质 协程可以分成两部分1.协程函数本体 2.协程调度器 协程本体就是一个能够中间暂停返回的函数 协程调度器是Unity内部实现的&#xff0c;会在对应的时机帮助我们继续执行协程函数 Unity只实现了协程调度部分协程的本体本质上就是一个 C#的迭代器方法 2.协程本体是…

丹摩征文活动|CogVideoX-2b:从0到1,轻松完成安装与部署!

丹摩征文活动 | CogVideoX-2b&#xff1a;从0到1&#xff0c;轻松完成安装与部署&#xff01; CogVideoX 介绍 CogVideoX的问世&#xff0c;标志着视频制作技术迈入了一个全新的时代。它不仅打破了传统视频制作在效率与质量之间的平衡难题&#xff0c;还通过其先进的3D变分自…

知识库搭建|员工培训的效率利器

在企业的快速发展过程中&#xff0c;知识库的搭建成为了提升员工培训效率的关键一环。一个高效的知识库不仅能够为员工提供便捷的学习资源&#xff0c;还能促进知识的持续积累和传承。本文将探讨如何借助知识库工具&#xff0c;来提升员工培训的效率。 一、知识库在员工培训中…

OneRestore: A Universal Restoration Framework for Composite Degradation 论文阅读笔记

这是武汉大学一作单位的一篇发表在ECCV2024上的论文&#xff0c;文章代码开源&#xff0c;文章首页图如下所示&#xff0c;做混合图像干扰去除&#xff0c;还能分别去除&#xff0c;看起来很牛逼。文章是少见的做混合图像干扰去除的&#xff0c;不过可惜只包含了3种degradation…

2024最新版JavaScript逆向爬虫教程-------基础篇之Proxy与Reflect详解

目录 一、监听对象的操作二、Proxy基本使用2.1 创建空代理2.2 定义捕获器2.2.1 Proxy的set和get捕获器2.2.2 Proxy(handler)的13个捕获器 三、Reflect的作用3.1 Reflect的使用3.2 Reflect其余方法(9个)3.3 Proxy与Reflect中的receiver参数3.4 Reflect中的construct方法 ECMAScr…

文献解读-DNAscope: High accuracy small variant calling using machine learning

关键词&#xff1a;基准与方法研究&#xff1b;基因测序&#xff1b;变异检测&#xff1b; 文献简介 标题&#xff08;英文&#xff09;&#xff1a;DNAscope: High accuracy small variant calling using machine learning标题&#xff08;中文&#xff09;&#xff1a;DNAsc…

自动驾驶3D目标检测综述(一)

文章地址&#xff1a;[2206.09474] 3D Object Detection for Autonomous Driving: A Comprehensive Survey (arxiv.org) 这篇综述简单易懂&#xff0c;非常合适对自动驾驶和3D目标检测感兴趣的小白阅读&#xff0c;对相关算法进行初步理解。 目录 一、摘要 &#xff08;一&a…

微软域名邮箱:如何设置管理烽火域名邮箱?

微软域名邮箱的设置技巧&#xff1f;免费域名邮箱注册设置教程&#xff1f; 微软域名邮箱为企业提供了一个强大且灵活的解决方案&#xff0c;帮助企业轻松管理其域名邮箱。烽火将详细介绍如何设置和管理微软域名邮箱&#xff0c;确保您的团队能够高效地使用这一工具。 微软域…

DirectShow过滤器开发-写AVI视频文件过滤器

下载本过滤器DLL 本过滤器将视频流和音频流写入AVI视频文件。 过滤器信息 过滤器名称&#xff1a;写AVI 过滤器GUID&#xff1a;{2EF49957-37DF-4356-A2A0-ECBC52D1984B} DLL注册函数名&#xff1a;DllRegisterServer 删除注册函数名&#xff1a;DllUnregisterServer 过滤器有…

新版 idea 编写 idea 插件时,启动出现 ClassNotFound

IntelliJ IDEA 2024.1.6 (Ultimate Edition) Build #IU-241.19072.14, built on August 8, 2024 Licensed to Sophia Tout Subscription is active until June 29, 2025. For educational use only. Runtime version: 17.0.111-b1207.30 amd64 Kotlin: 241.19072.14-IJ 新版本…

vue2.x elementui 固定顶部、左侧菜单与面包屑,自适应 iframe 页面布局

vue elementui 固定顶部、左侧菜单与面包屑&#xff0c;自适应 iframe 页面布局 疑问点&#xff1a;iframe无法高度100%&#xff0c;如果写了100%就会有滚动条&#xff0c;所以只写了99.5% 【效果图】 路由示例 const routes [{title: Index,path: /,name: "Index"…

godot——主题、Theme、StyleBox

我刚开始被这些术语吓到了&#xff0c;一直不敢去接触它们&#xff0c;都用的默认样式。现在好不容易有点思路了&#xff0c;记录下来。 下面看看怎么自定义样式。 1.先新建一个Theme 2.再次点击创建好的Theme 得到 图1 这样一个面板。&#xff08;看不懂没事&#xff0c;继…

web——sqliabs靶场——第二关

今天来搞第二关&#xff0c;来看看是什么咸蛋 1.判断是否存在sql注入漏洞 输入1 存在sql注入&#xff0c;报错语句为 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near LIMIT 0,1 …

基于Matlab 火焰识别技术

课题介绍 森林承担着为人类提供氧气以及回收二氧化碳等废弃气体的作用&#xff0c;森林保护显得尤其重要。但是每年由于火灾引起的事故不计其数&#xff0c;造成重大的损失。如果有一款监测软件&#xff0c;从硬件处获得的图像中监测是否有火焰&#xff0c;从而报警&#xff0…