游戏引擎学习第22天
移除 DllMain() 并成功重新编译
以下是对内容的详细复述与总结:
-
问题和解决方案:
- 在编译过程中遇到了一些问题,特别是如何告知编译器不要退出程序,而是继续处理。问题的根源在于编译过程中传递给链接器的参数设置不正确。
- 原本尝试将一个“斜杠”后跟“l”的参数传递给链接器,但实际上这是一个编译器的选项,而不是链接器的。因此,正确的做法是将该选项作为编译器的开关传递,而不是链接器。
- 经过这个调整,问题得以解决。
-
不再需要的操作:
- 在编译和链接过程中,某些操作被发现是多余的。例如,在
game.cpp
文件的底部,曾插入了一个DllMain
函数。这通常是 Windows 系统加载程序时会调用的函数,用来检查程序是否正常启动。 - 经过检查,发现该
DLLMain
函数不再需要,因此决定删除它。
- 在编译和链接过程中,某些操作被发现是多余的。例如,在
-
构建目录的整理:
- 在完成以上调整后,构建目录得到了整理。对于可能是指构建或处理某些文件这一部分,开发者指出它仍然需要存在,但某些不必要的部分已经被清除。
- 例如,某些与可能是指某个不必要的工具或文件相关的东西不再需要,因此被移除。
-
后续步骤:
- 在进行这些调整后,接下来的目标是进一步优化和清理当前的构建设置,确保没有多余的内容或文件存在,所有操作都与当前的需求保持一致。
总结来说,调整主要集中在编译过程的参数设置以及不再需要的代码删除上,目标是优化构建流程,并清理不必要的部分,使得整个开发环境更加简洁和高效。
演示热重载,并决定减少更新延迟并启用调试
以下是对内容的详细复述和总结:
-
当前进展:
- 昨天的工作使得项目达到了一个相当不错的位置,开发者能够在游戏运行时直接修改游戏行为。例如,可以在游戏中实时改变颜色并看到效果。每次修改后,只需要保存,游戏就会定期重新加载更新内容,尽管存在一定的延迟。
-
存在的问题:
- 游戏的更新和重载有延迟,这是因为游戏仅每隔约两秒钟检查一次是否需要重新加载内容。开发者计划优化这个过程,减少延迟,提高游戏反应速度。
- 另一个问题是,如果在调试模式下运行游戏,尝试编译时会遇到困难。具体问题在于,当游戏正在运行并处于调试状态时,Visual Studio 会锁定调试信息文件,这导致无法编译更新的内容。编译器无法输出新的调试文件,因为它试图覆盖已经被锁定的文件。
-
解决方案的探索:
- 为了解决这个问题,开发者希望找到一种方法,在使用调试器时能够顺利进行编译和运行,而不需要停止调试。目的是能够在不停止调试的情况下继续工作,甚至进行实时代码修改(Live coding)。
-
总结:
- 当前的目标是优化游戏的实时更新机制,减少延迟,并解决在调试模式下无法编译的问题。开发者希望找到一种方法,使得调试和编译可以在不中断运行的情况下顺利进行,从而提升开发效率。
这些问题和解决方案反映了在游戏开发和调试过程中常见的挑战,尤其是在实时修改和调试时需要注意的文件锁定和更新问题。
# CMake 项目的基础配置
# 创建静态库或者共享库,可以选择 comment 出静态库行来生成不同的库类型。
# 如果你想要创建静态库,请取消下面一行的注释:
# add_library(game STATIC "game.cpp") # 生成 game.lib# 创建共享库(DLL)
add_library(game SHARED "game.cpp") # 生成 game.dll# 设置目标属性,手动添加 EXPORT 标志
set_target_properties(game PROPERTIESLINK_FLAGS "/EXPORT:GameUpdateAndRender /EXPORT:GameGetSoundSamples" # 设置导出函数的符号
)# 创建 win32_game 可执行文件,指定源文件
add_executable(win32_game WIN32 "win32_game.cpp")# 为编译器添加定义的全局宏
add_compile_definitions(GAME_SLOW=1 GAME_INTERNAL=1)# 获取当前时间,格式化为 年月日_时分秒
string(TIMESTAMP CURRENT_DATE "%Y%m%d_%H%M%S")
message("Current date and time: ${CURRENT_DATE}")# 为 game 目标设置 PDB 文件路径,包含当前时间戳
# 这会生成动态链接库的 PDB 文件,文件名包括编译时的时间戳
if(MSVC) # 如果使用 Microsoft Visual C++ 编译器target_link_options(game PRIVATE "/PDB:${CMAKE_BINARY_DIR}/game/game_${CURRENT_DATE}.pdb")
endif()# 使用 file(GLOB ...) 查找所有 .pdb 文件,并逐个删除
file(GLOB PDB_FILES "${CMAKE_BINARY_DIR}/game/game_*.pdb")# 创建清理所有 .pdb 文件的自定义目标 clean-all
add_custom_target(clean-allCOMMAND ${CMAKE_COMMAND} -E echo "Cleaning up game.pdb files"
)# 遍历所有 .pdb 文件,并为每个文件添加删除命令
foreach(PDB_FILE ${PDB_FILES})add_custom_command(TARGET clean-allPOST_BUILD # 在构建之后执行COMMAND ${CMAKE_COMMAND} -E remove ${PDB_FILE} # 删除每个 .pdb 文件COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_SOURCE_DIR}/CMakeLists.txtCOMMENT "removing ${PDB_FILE}" # 注释,说明正在删除的文件COMMENT "Updating CMakeLists.txt timestamp" # 跟新CMakeLists.txt时间戳)
endforeach()# 确保在构建 'game' 之前先执行 clean-all 清理操作
add_dependencies(game clean-all)# 链接 Win32 库到 win32_game
# 这里链接了三个 Windows 库:User32.lib、Gdi32.lib 和 Winmm.lib
target_link_libraries(win32_game PRIVATE User32.lib Gdi32.lib Winmm.lib)# 如果使用 MSVC 编译器,添加编译选项
if(MSVC) # 如果编译器是 MSVC(Microsoft Visual C++)# 设置 C++ 编译选项:# /WX : 将所有警告视为错误(会让编译因警告失败)# /W4 : 设置警告级别为 4,显示大多数警告# /wd4819 : 屏蔽警告 C4819,避免文件编码问题导致的警告# /wd4201 : 屏蔽警告 C4201,避免由于结构体定义引起的警告# /wd4505 : 屏蔽警告 C4505,避免由于不使用的函数引起的警告# /Zi : 生成调试信息# /FC : 显示完整的文件名和行号set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /WX /W4 /wd4819 /wd4201 /wd4505 /Zi /FC")# 设置目标属性,手动关闭增量链接功能(incremental linking),以确保导出函数的符号set_target_properties(win32_game PROPERTIESLINK_FLAGS "-incremental:no" # 禁用增量链接)
endif()# 确保使用 C++20 标准(仅在 CMake 版本大于 3.12 时才有效)
if(CMAKE_VERSION VERSION_GREATER 3.12)set_property(TARGET win32_game PROPERTY CXX_STANDARD 20)set_property(TARGET game PROPERTY CXX_STANDARD 20)
endif()
现在就可以在调试模式下面跟新人更新dll
管道输出 stdout 和 stderr
命令 del *.pdb > NUL 2> NUL
在 Windows 命令行中执行时,具有以下含义:
1. del *.pdb
这是删除当前目录下所有 .pdb
文件的命令。
del
是删除命令。*.pdb
表示当前目录下所有以.pdb
结尾的文件(即所有的 PDB 文件)。
2. > NUL
这是将标准输出(stdout)重定向到 NUL
设备。
>
是重定向操作符,表示将命令的输出写入到指定的位置。NUL
是 Windows 中的特殊设备,类似于 Unix/Linux 系统中的/dev/null
,它表示“丢弃输出”。- 这意味着执行
del *.pdb
时,标准输出(通常是删除的文件名)将被丢弃,而不会显示在命令行窗口中。
- 这意味着执行
3. 2> NUL
这是将标准错误输出(stderr)重定向到 NUL
设备。
2>
是重定向标准错误输出(stderr)的操作符。2
指的是标准错误输出流(stderr)的文件描述符(0 是标准输入,1 是标准输出,2 是标准错误输出)。NUL
再次表示丢弃错误输出。也就是说,如果删除命令遇到错误(比如没有找到任何.pdb
文件),错误信息将不会显示在命令行窗口中。
综合起来:
del *.pdb > NUL 2> NUL
的意思是:
- 删除当前目录下的所有
.pdb
文件。 - 如果删除成功,删除的文件名不会显示在命令行中(因为标准输出被重定向到
NUL
)。 - 如果发生错误(例如没有
.pdb
文件),错误信息也不会显示在命令行中(因为标准错误输出被重定向到NUL
)。
这样使用通常是为了避免在命令执行时看到不必要的输出和错误信息,确保输出干净。
发现热重载仍然存在延迟
这段代码描述了一种通过检查文件的日期戳来减少延迟的优化方法,重点在于通过检查文件的修改时间来确定是否需要重新加载某个文件。这种方法相对简单且高效,可以在每一帧中检查文件的修改日期,从而避免延迟。
主要思路:
-
减少延迟:通过定期检查文件的日期戳来减少性能损失。这种方法通过周期性地检查文件的最后修改时间来确定是否需要重新加载文件,而不需要每次都加载文件,从而减少延迟。
-
文件日期戳:文件系统中每个文件都有一个日期戳,表示文件最后一次被访问、修改或创建的时间。通过获取这些信息,可以判断文件是否发生变化。检查文件的日期戳比打开文件进行读取要更高效,避免了额外的性能消耗。
-
优化实现:
- 文件句柄与日期戳:为了避免打开文件,可以使用文件句柄获取文件的时间信息,如创建时间、最后访问时间和最后修改时间。
- 文件检查函数:使用
FindFirstFile
等API函数可以获取文件的创建、访问和修改时间,通过这些数据判断文件是否需要重新加载。 - 缓存和临时处理:为了避免不必要的重复计算和性能开销,使用缓存技术将文件的日期戳保存并在需要时进行比较,避免每次都重复操作。
-
错误处理与容错:
- 如果文件不存在,程序应该返回一个无效的句柄并进行适当的错误处理,避免程序崩溃。
- 在日期戳检查过程中,如果文件不存在或无法访问,程序会根据需要返回默认值(如0),确保系统继续运行而不被中断。
-
调试与监控:
- 在开发和调试阶段,可能会使用一些调试信息来监控文件的最后修改时间等,帮助开发者识别潜在的问题。
- 这种优化方法并不依赖于非常精确的数据,因此即使日期戳并非完全精确,它仍然能有效减少延迟。
总结:
通过这种方法,开发者能够高效地判断文件是否需要重新加载,减少不必要的计算,并通过检查文件的日期戳来优化性能。这种方法简洁且高效,适用于那些需要频繁加载文件但又不能接受高延迟的系统。
FindFirstFileA
是一个 Windows API 函数,用于查找匹配指定文件名的第一个文件。它返回一个句柄,供后续调用其他函数(如 FindNextFileA
)继续查找。
函数原型:
HANDLE WINAPI FindFirstFileA(_In_ LPCSTR lpFileName,_Out_ LPWIN32_FIND_DATAA lpFindFileData
);
参数说明:
-
lpFileName
(LPCSTR
):- 这是一个指向以 null 终止的字符串的指针,表示要搜索的文件路径。该路径可以包含通配符字符(如
*
或?
)用于匹配多个文件。例如:"C:\\path\\to\\files\\*.txt"
用于查找该路径下的所有.txt
文件。"C:\\path\\to\\files\\*"
用于查找所有文件。
- 这是一个指向以 null 终止的字符串的指针,表示要搜索的文件路径。该路径可以包含通配符字符(如
-
lpFindFileData
(LPWIN32_FIND_DATAA
):- 这是一个指向
WIN32_FIND_DATAA
结构体的指针,FindFirstFileA
函数将文件信息存储到该结构体中。这个结构体包含了文件的各种属性,如文件名、文件类型、大小、最后修改时间等。
WIN32_FIND_DATAA
结构体定义如下:typedef struct _WIN32_FIND_DATAA {DWORD dwFileAttributes; // 文件的属性,如普通文件、目录、只读等FILETIME ftCreationTime; // 文件创建时间FILETIME ftLastAccessTime; // 文件最后访问时间FILETIME ftLastWriteTime; // 文件最后写入时间DWORD nFileSizeHigh; // 文件大小(高位)DWORD nFileSizeLow; // 文件大小(低位)DWORD dwReserved0; // 保留字段DWORD dwReserved1; // 保留字段CHAR cFileName[MAX_PATH]; // 文件名CHAR cAlternateFileName[14]; // 文件的备用名称 } WIN32_FIND_DATAA;
- 这是一个指向
返回值:
- 如果成功,
FindFirstFileA
返回一个有效的搜索句柄(HANDLE
)。该句柄用于后续的查找操作,如FindNextFileA
和FindClose
。 - 如果失败,返回
INVALID_HANDLE_VALUE
。你可以通过调用GetLastError()
来获取更多的错误信息。
常见用法:
FindFirstFileA
通常与 FindNextFileA
配合使用,以便遍历所有匹配的文件。完成搜索后,必须调用 FindClose
来关闭搜索句柄。
示例代码:
#include <windows.h>
#include <iostream>int main() {WIN32_FIND_DATAA findFileData;HANDLE hFind = FindFirstFileA("C:\\path\\to\\files\\*.txt", &findFileData);if (hFind == INVALID_HANDLE_VALUE) {std::cerr << "FindFirstFileA failed!" << std::endl;return 1;}do {// 输出匹配文件的文件名std::cout << "Found file: " << findFileData.cFileName << std::endl;} while (FindNextFileA(hFind, &findFileData) != 0); // 查找下一个文件FindClose(hFind); // 关闭搜索句柄return 0;
}
函数的工作流程:
- 调用
FindFirstFileA
时,它会查找第一个匹配的文件,并将文件的相关信息存储在lpFindFileData
中。 - 如果找到文件,则
FindFirstFileA
返回一个有效的句柄,你可以使用FindNextFileA
来查找后续文件。 - 使用
FindNextFileA
可以继续查找下一个文件,直到没有更多匹配的文件为止。 - 使用
FindClose
关闭句柄,释放资源。
常见错误:
INVALID_HANDLE_VALUE
:如果调用失败,返回这个值。你可以使用GetLastError
获取详细的错误信息。- 路径格式问题:确保传递给
FindFirstFileA
的路径格式正确,并且如果需要,使用双反斜杠(\\
)来表示文件路径。
总结:
FindFirstFileA
是一个非常有用的函数,尤其是用于列出文件或目录内容,支持通配符,并能够返回文件的详细信息。它通常与 FindNextFileA
和 FindClose
结合使用,用于实现文件查找操作。
尝试将工作目录设置为数据目录,发现 Win32GetLastWriteTime() 无法找到我们的 .dll 文件
目前面临的问题是,如何确保程序能够正确加载DLL文件,特别是在特定的构建目录和数据目录之间的路径管理上。之前的做法是在构建目录中加载这些文件,而目标是将它们放回数据目录中。这样做的原因是,所有艺术资产和其他必要的文件都应位于数据目录中。
在程序加载时,Windows系统会自动通过搜索路径来查找执行文件所在目录下的DLL文件,因此当执行文件和DLL文件位于相同目录时,加载库(load library)会成功。这表明文件能在该路径下找到并被正确加载。
然而,问题出现在程序的文件日期检查上。当文件已找到时,日期检查未能通过,可能是由于系统默认只在当前目录下查找文件,而没有扩展到其他目录。这个问题可以通过修改路径设置来解决,让程序能够在任何指定的目录中找到需要的DLL文件,而不仅仅是在执行文件的目录中。
解决方案是,调整文件路径,使得无论实际的路径设置如何,DLL文件都可以在与可执行文件相同的目录下被正确找到。这涉及到创建一个搜索路径,确保DLL文件始终能够被加载,哪怕路径发生了变化。
启用 WinMain() 使用 GetModuleFilenameA() 来定位我们的 .exe 文件
在当前的开发任务中,目标是通过Windows操作系统的函数来查找和确认当前可执行文件的路径。为此,提到了使用Windows API中的 GetModuleFileName
函数,该函数可以帮助我们获取模块(即可执行文件)的路径。
首先,提到的问题是如何准确地找到可执行文件所在的路径。这是关键,因为所有相关的文件(如DLL文件)都需要根据正确的路径来定位。最简单的方法是使用 GetModuleFileName
函数,并且通过传递一个值为零的参数,可以自动获取当前可执行文件的路径,而不需要显式传递模块句柄。这样,可以确认当前执行文件所在的目录,从而在该路径下寻找相关文件。
然而,GetModuleFileName
函数有一些潜在的问题。例如,如果传递的缓冲区大小不足以容纳路径字符串,它可能会截断路径。这意味着,如果缓冲区过小,返回的路径可能会丢失部分信息,导致后续操作失败。因此,最好的做法是确保缓冲区的大小足够大,以容纳完整的路径。
另外,也提到 MAX_PATH
常量,这个常量在Windows中定义了路径的最大字符数,通常为260个字符。但这一限制现在已经不再适用,因为Windows支持更长的路径。因此,使用 MAX_PATH
时应谨慎,避免可能带来的路径截断问题。
综上所述,开发者在处理文件路径时,应该避免使用过时的 MAX_PATH
常量,并确保缓冲区大小足够,避免路径截断带来的潜在问题。同时,使用 GetModuleFileName
是获取可执行文件路径的一种有效方式,但要注意对缓冲区大小的管理。
GetModuleHandle
是一个 Windows API 函数,用于获取一个已经加载的模块(如动态链接库 DLL 或可执行文件)在内存中的句柄。这个句柄可以用来引用该模块,在之后的操作中(如获取模块路径、获取导出的函数等)使用。
发现我们得到了完整路径
相关文章:

游戏引擎学习第22天
移除 DllMain() 并成功重新编译 以下是对内容的详细复述与总结: 问题和解决方案: 在编译过程中遇到了一些问题,特别是如何告知编译器不要退出程序,而是继续处理。问题的根源在于编译过程中传递给链接器的参数设置不正确。原本尝试…...
洛谷 B2038:奇偶 ASCII 值判断
【题目来源】https://www.luogu.com.cn/problem/B2038http://shnoip.openjudge.cn/level1/39/【题目描述】 任意输入一个字符,判断其 ASCII 是否是奇数,若是,输出 YES,否则,输出 NO。 例如,字符 A 的 ASCII…...
APIRouter
当然可以!理解 FastAPI 中直接在 FastAPI 实例上定义路由与使用 APIRouter 作为路由器的区别,对于编写结构良好、可维护性高的应用程序至关重要。下面,我将详细解释这两种方法的区别、各自的优缺点以及何时使用它们。 1. 直接在 FastAPI 实例…...
算法模板2:位运算+离散化+区间合并
文章目录 1.6 位运算**位运算的常见应用**1.7 离散化**经典离散化题目例子****1. 区间合并和覆盖长度问题****2. 区间查询与修改****3. 动态求第 K 小值****4. 区间最大重叠次数****5. 动态逆序对计数****6. 二维区间问题****7. 模拟车流/时间段事件****8. 区间众数统计** **具…...

钉钉授权登录
一.找开钉钉开发平台【钉钉开放平台 (dingtalk.com)】 二。点击菜单【应用开发】->左边【钉钉应用】->【创建应用】 三。创建应用-》保存成功后,点击自己【新建的应用】,进入详细页面 四。进入应用详细页面。左边【分享设置】 注意:进…...
【视频】二维码识别:libzbar-dev、zbar-tools(zbarimg )
1、简介 ZBar可以使用多个方式识别各种条形码和二维码。 支持的格式有:EAN-13/UPC-A、UPC-E、EAN-8、Code 128、Code 93、Code 39、Codabar、Interleaved 2 of 5、QR Code和SQ Code 支持的来源有:视频流、图像文件等 libzbar-dev:二维码识别开发库 zbar-tools(zbarimg …...
C语言中的结构体,指针,联合体的使用
目录 1. 概述2. 定义和初始化3. 成员的使用4. 结构体数组5. 结构体套结构体6. 结构体赋值7. 结构体和指针8. 结构体作为函数参数9. 共用体(联合体)10. typedef就是取别名总结 1. 概述 数组:连续的相同数据类型的集合 结构体:不同…...

基于卡尔曼滤波器的 PID 控制
基于卡尔曼滤波器的PID控制算法结合了经典控制理论和现代信号处理技术。卡尔曼滤波器(Kalman Filter, KF)可以对噪声数据进行平滑处理,从而改善PID控制器的性能,特别是在处理具有噪声和不确定性的系统时。以下是详细的设计过程&am…...

CVE-2022-26201
打开是这么个页面 左上角找到Admin访问 里面有个Add Users,访问一下,能创建用户,有个能上传图片的地方 普通的一句话木马无法访问flag,需要创建一个权限马 <?php system($_GET[1]);phpinfo();?> 因为只能上传jpg形式的文…...
海信Java后端开发面试题及参考答案
TCP 的优点是什么? TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,它具有众多优点。 首先,TCP 提供可靠的传输服务。它通过序列号、确认应答、重传机制等确保数据的准确无误传输。例如,在发送数据时,发送方会…...

传智杯 3-初赛:终端
题目描述: 有一天您厌烦了电脑上又丑又没用的终端,打算自己实现一个 Terminal。具体来说,它需要支持如下命令: 1. touch filename:如果名为 filename 的文件不存在,就创建一个这样的文件,如果已经存在同名…...

大数据新视界 -- Hive 数据分区:精细化管理的艺术与实践(上)(7/ 30)
💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...
【中间件】Redis
一、什么是Redis Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理。它支持字符串、哈希表、列表、集合、有序集合,位图,hyperloglogs等数据类型。内置…...

RTSP播放器EasyPlayer.js播放器分辨率高的视频在设置container的宽高较小时,会出现锯齿状的画面效果
流媒体播放器的核心技术及发展趋势展现了其在未来数字生活中的无限潜力。随着技术的不断进步和市场的持续发展,流媒体播放器将在内容创新、用户体验优化以及跨平台互通等方面取得新的突破。对于从业者而言,把握这些趋势并积极应对挑战将是实现成功的关键…...

Java爬虫:获取商品详情的实践之旅
在当今这个信息爆炸的时代,数据的价值日益凸显。对于电商行业来说,商品详情的获取尤为重要,它不仅关系到产品的销售,还直接影响到用户体验。传统的人工获取方式耗时耗力,而自动化的爬虫技术则提供了一种高效解决方案。…...

行业分析---2024年小鹏汽车AI Day及三季度财报
1 背景 在之前的博客中,笔者撰写了多篇行业类分析的文章(科技新能源): 《行业分析---我眼中的Apple Inc.》 《行业分析---马斯克的Tesla》 《行业分析---造车新势力之蔚来汽车》 《行业分析---造车新势力之小鹏汽车》 《行业分析-…...
写时复制,读时加载
实现写时复制,读时加载,原理为,申请内存时,只给一段线性地址空间,并不分配物理内存,当cpu读、写该内存时,发生缺页中,或者写错误,中断处理程序根据前面设置的内容&#x…...
Python和R基因组及蛋白质组学和代谢组学
🌵Python片段 1. 数据处理与清理 基因组病理学的数据通常非常庞大,且可能包括 DNA 或 RNA 测序结果、基因表达数据等。Python 提供了高效的数据处理工具。 工具和库 Pandas: 用于加载、清理和操作数据。Numpy: 用于高效的数值计算。Dask: 用于大规模数…...
selenium环境搭建详细过程
一、准备工作 在开始搭建 Selenium 环境之前,确保具备以下条件: 1.稳定的网络连接: 以便能够下载所需的软件和驱动程序。 2.操作系统基础: 对您的操作系统(如 Windows、Mac 或 Linux)有基本的了解和操…...

Linux知识 - VIM
VI于VIM linux系统里边内置了一个编辑器就叫做vi(visual editor),但vi的功能非常有限,所以一般Linux的使用人员会选择一个比vi更强大的编辑器vim Vim的三种工作模式 输入模式 在正常模式中按下别字母键,会进入插入模式…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...

通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
BLEU评分:机器翻译质量评估的黄金标准
BLEU评分:机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域,衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标,自2002年由IBM的Kishore Papineni等人提出以来,…...
Oracle11g安装包
Oracle 11g安装包 适用于windows系统,64位 下载路径 oracle 11g 安装包...

从物理机到云原生:全面解析计算虚拟化技术的演进与应用
前言:我的虚拟化技术探索之旅 我最早接触"虚拟机"的概念是从Java开始的——JVM(Java Virtual Machine)让"一次编写,到处运行"成为可能。这个软件层面的虚拟化让我着迷,但直到后来接触VMware和Doc…...
TJCTF 2025
还以为是天津的。这个比较容易,虽然绕了点弯,可还是把CP AK了,不过我会的别人也会,还是没啥名次。记录一下吧。 Crypto bacon-bits with open(flag.txt) as f: flag f.read().strip() with open(text.txt) as t: text t.read…...