游戏引擎学习第22天

news2024/11/29 8:01:50

移除 DllMain() 并成功重新编译

以下是对内容的详细复述与总结:

  1. 问题和解决方案

    • 在编译过程中遇到了一些问题,特别是如何告知编译器不要退出程序,而是继续处理。问题的根源在于编译过程中传递给链接器的参数设置不正确。
    • 原本尝试将一个“斜杠”后跟“l”的参数传递给链接器,但实际上这是一个编译器的选项,而不是链接器的。因此,正确的做法是将该选项作为编译器的开关传递,而不是链接器。
    • 经过这个调整,问题得以解决。
  2. 不再需要的操作

    • 在编译和链接过程中,某些操作被发现是多余的。例如,在 game.cpp 文件的底部,曾插入了一个 DllMain 函数。这通常是 Windows 系统加载程序时会调用的函数,用来检查程序是否正常启动。
    • 经过检查,发现该 DLLMain 函数不再需要,因此决定删除它。
  3. 构建目录的整理

    • 在完成以上调整后,构建目录得到了整理。对于可能是指构建或处理某些文件这一部分,开发者指出它仍然需要存在,但某些不必要的部分已经被清除。
    • 例如,某些与可能是指某个不必要的工具或文件相关的东西不再需要,因此被移除。
  4. 后续步骤

    • 在进行这些调整后,接下来的目标是进一步优化和清理当前的构建设置,确保没有多余的内容或文件存在,所有操作都与当前的需求保持一致。

总结来说,调整主要集中在编译过程的参数设置以及不再需要的代码删除上,目标是优化构建流程,并清理不必要的部分,使得整个开发环境更加简洁和高效。

演示热重载,并决定减少更新延迟并启用调试

以下是对内容的详细复述和总结:

  1. 当前进展

    • 昨天的工作使得项目达到了一个相当不错的位置,开发者能够在游戏运行时直接修改游戏行为。例如,可以在游戏中实时改变颜色并看到效果。每次修改后,只需要保存,游戏就会定期重新加载更新内容,尽管存在一定的延迟。
  2. 存在的问题

    • 游戏的更新和重载有延迟,这是因为游戏仅每隔约两秒钟检查一次是否需要重新加载内容。开发者计划优化这个过程,减少延迟,提高游戏反应速度。
    • 另一个问题是,如果在调试模式下运行游戏,尝试编译时会遇到困难。具体问题在于,当游戏正在运行并处于调试状态时,Visual Studio 会锁定调试信息文件,这导致无法编译更新的内容。编译器无法输出新的调试文件,因为它试图覆盖已经被锁定的文件。
  3. 解决方案的探索

    • 为了解决这个问题,开发者希望找到一种方法,在使用调试器时能够顺利进行编译和运行,而不需要停止调试。目的是能够在不停止调试的情况下继续工作,甚至进行实时代码修改(Live coding)。
  4. 总结

    • 当前的目标是优化游戏的实时更新机制,减少延迟,并解决在调试模式下无法编译的问题。开发者希望找到一种方法,使得调试和编译可以在不中断运行的情况下顺利进行,从而提升开发效率。

这些问题和解决方案反映了在游戏开发和调试过程中常见的挑战,尤其是在实时修改和调试时需要注意的文件锁定和更新问题。
在这里插入图片描述
在这里插入图片描述

# CMake 项目的基础配置
# 创建静态库或者共享库,可以选择 comment 出静态库行来生成不同的库类型。
# 如果你想要创建静态库,请取消下面一行的注释:
# add_library(game STATIC "game.cpp")  # 生成 game.lib

# 创建共享库(DLL)
add_library(game SHARED "game.cpp") # 生成 game.dll

# 设置目标属性,手动添加 EXPORT 标志
set_target_properties(game PROPERTIES
  LINK_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-all
  COMMAND ${CMAKE_COMMAND} -E echo "Cleaning up game.pdb files"
)

# 遍历所有 .pdb 文件,并为每个文件添加删除命令
foreach(PDB_FILE ${PDB_FILES})
  add_custom_command(
    TARGET clean-all
    POST_BUILD # 在构建之后执行
    COMMAND ${CMAKE_COMMAND} -E remove ${PDB_FILE} # 删除每个 .pdb 文件
    COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_SOURCE_DIR}/CMakeLists.txt
    COMMENT "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 PROPERTIES
    LINK_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)。

这样使用通常是为了避免在命令执行时看到不必要的输出和错误信息,确保输出干净。

发现热重载仍然存在延迟

这段代码描述了一种通过检查文件的日期戳来减少延迟的优化方法,重点在于通过检查文件的修改时间来确定是否需要重新加载某个文件。这种方法相对简单且高效,可以在每一帧中检查文件的修改日期,从而避免延迟。

主要思路:

  1. 减少延迟:通过定期检查文件的日期戳来减少性能损失。这种方法通过周期性地检查文件的最后修改时间来确定是否需要重新加载文件,而不需要每次都加载文件,从而减少延迟。

  2. 文件日期戳:文件系统中每个文件都有一个日期戳,表示文件最后一次被访问、修改或创建的时间。通过获取这些信息,可以判断文件是否发生变化。检查文件的日期戳比打开文件进行读取要更高效,避免了额外的性能消耗。

  3. 优化实现

    • 文件句柄与日期戳:为了避免打开文件,可以使用文件句柄获取文件的时间信息,如创建时间、最后访问时间和最后修改时间。
    • 文件检查函数:使用FindFirstFile等API函数可以获取文件的创建、访问和修改时间,通过这些数据判断文件是否需要重新加载。
    • 缓存和临时处理:为了避免不必要的重复计算和性能开销,使用缓存技术将文件的日期戳保存并在需要时进行比较,避免每次都重复操作。
  4. 错误处理与容错

    • 如果文件不存在,程序应该返回一个无效的句柄并进行适当的错误处理,避免程序崩溃。
    • 在日期戳检查过程中,如果文件不存在或无法访问,程序会根据需要返回默认值(如0),确保系统继续运行而不被中断。
  5. 调试与监控

    • 在开发和调试阶段,可能会使用一些调试信息来监控文件的最后修改时间等,帮助开发者识别潜在的问题。
    • 这种优化方法并不依赖于非常精确的数据,因此即使日期戳并非完全精确,它仍然能有效减少延迟。

总结:

通过这种方法,开发者能够高效地判断文件是否需要重新加载,减少不必要的计算,并通过检查文件的日期戳来优化性能。这种方法简洁且高效,适用于那些需要频繁加载文件但又不能接受高延迟的系统。

FindFirstFileA 是一个 Windows API 函数,用于查找匹配指定文件名的第一个文件。它返回一个句柄,供后续调用其他函数(如 FindNextFileA)继续查找。

函数原型:

HANDLE WINAPI FindFirstFileA(
    _In_ LPCSTR lpFileName,
    _Out_ LPWIN32_FIND_DATAA lpFindFileData
);

参数说明:

  1. lpFileName (LPCSTR):

    • 这是一个指向以 null 终止的字符串的指针,表示要搜索的文件路径。该路径可以包含通配符字符(如 *?)用于匹配多个文件。例如:
      • "C:\\path\\to\\files\\*.txt" 用于查找该路径下的所有 .txt 文件。
      • "C:\\path\\to\\files\\*" 用于查找所有文件。
  2. 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)。该句柄用于后续的查找操作,如 FindNextFileAFindClose
  • 如果失败,返回 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;
}

函数的工作流程:

  1. 调用 FindFirstFileA 时,它会查找第一个匹配的文件,并将文件的相关信息存储在 lpFindFileData 中。
  2. 如果找到文件,则 FindFirstFileA 返回一个有效的句柄,你可以使用 FindNextFileA 来查找后续文件。
  3. 使用 FindNextFileA 可以继续查找下一个文件,直到没有更多匹配的文件为止。
  4. 使用 FindClose 关闭句柄,释放资源。

常见错误:

  • INVALID_HANDLE_VALUE:如果调用失败,返回这个值。你可以使用 GetLastError 获取详细的错误信息。
  • 路径格式问题:确保传递给 FindFirstFileA 的路径格式正确,并且如果需要,使用双反斜杠(\\)来表示文件路径。

总结:

FindFirstFileA 是一个非常有用的函数,尤其是用于列出文件或目录内容,支持通配符,并能够返回文件的详细信息。它通常与 FindNextFileAFindClose 结合使用,用于实现文件查找操作。

在这里插入图片描述

尝试将工作目录设置为数据目录,发现 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 或可执行文件)在内存中的句柄。这个句柄可以用来引用该模块,在之后的操作中(如获取模块路径、获取导出的函数等)使用。

发现我们得到了完整路径

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

Paper -- 建筑物高度估计 -- 使用街景图像、深度学习、轮廓处理和地理空间数据的建筑高度估计

基本信息 论文题目: Building Height Estimation using Street-View Images, Deep-Learning, Contour Processing, and Geospatial Data 中文题目: 使用街景图像、深度学习、轮廓处理和地理空间数据的建筑高度估计 作者: Ala’a Al-Habashna 作者单位: 加拿大统计局特别商业项…

如何为 ext2/ext3/ext4 文件系统的 /dev/centos/root 增加 800G 空间

如何为 ext2/ext3/ext4 文件系统的 /dev/centos/root 增加 800G 空间 一、引言二、检查当前磁盘和分区状态1. 使用 `df` 命令检查磁盘使用情况2. 使用 `lsblk` 命令查看分区结构3. 使用 `fdisk` 或 `parted` 命令查看详细的分区信息三、扩展逻辑卷(如果使用 LVM)1. 检查 LVM …

命令行使用ssh隧道连接远程mysql

本地电脑A 跳板机B 主机2.2.2.2 用户名 B ssh端口号22 登录密码bbb 远程mysql C 地址 3.3.3.3 端口号3306 用户名C 密码ccc A需要通过跳板机B才能访问C; navicat中配置ssh可以实现在A电脑上访问C 如何实现本地代码中访问C呢? # 假设本地使…

Vatee万腾平台:以数字之名,筑企业未来之路

在当今这个瞬息万变的数字化时代&#xff0c;企业若想在激烈的市场竞争中脱颖而出&#xff0c;就必须紧跟时代步伐&#xff0c;实现全面数字化转型。而Vatee万腾平台&#xff0c;正是这样一款能够帮助企业迈向数字化未来的强大工具。 Vatee万腾平台&#xff0c;作为数字化转型…

深度学习——损失函数与BP算法

一、损失函数 1. 线性回归损失函数 1.1 MAE损失 MAE&#xff08;Mean Absolute Error&#xff0c;平均绝对误差&#xff09;通常也被称为 L1-Loss&#xff0c;通过对预测值和真实值之间的绝对差取平均值来衡量他们之间的差异。MAE的公式如下&#xff1a; 其中&#xff1a; 是…

机器学习-决策树(ID3算法及详细计算推导过程)

决策树是一种基于树结构进行决策的机器学习算法 &#xff0c;以下是关于它的详细介绍&#xff1a; 1.基本原理 决策树通过一系列的条件判断对样本进行分类或预测数值。它从根节点开始&#xff0c;根据不同的属性值逐步将样本划分到不同的分支&#xff0c;直到到达叶节点&…

【AI系统】LLVM 架构设计和原理

LLVM 架构设计和原理 在上一篇文章中&#xff0c;我们详细探讨了 GCC 的编译过程和原理。然而&#xff0c;由于 GCC 存在代码耦合度高、难以进行独立操作以及庞大的代码量等缺点。正是由于对这些问题的意识&#xff0c;人们开始期待新一代编译器的出现。在本节&#xff0c;我们…

浅谈网络 | 应用层之HTTPS协议

目录 对称加密非对称加密数字证书HTTPS 的工作模式重放与篡改 使用 HTTP 协议浏览新闻虽然问题不大&#xff0c;但在更敏感的场景中&#xff0c;例如支付或其他涉及隐私的数据传输&#xff0c;就会面临巨大的安全风险。如果仍然使用普通的 HTTP 协议&#xff0c;数据在网络传输…

基于 JNI + Rust 实现一种高性能 Excel 导出方案(上篇)

每个不曾起舞的日子&#xff0c;都是对生命的辜负。 ——尼采 一、背景&#xff1a;Web 导出 Excel 的场景 Web 导出 Excel 功能在数据处理、分析和共享方面提供了极大的便利&#xff0c;是许多 Web 应用程序中的重要功能。以下是一些典型的场景&#xff1a; 数据报表导出&am…

最新Linux下使用conda配置Java23或17保姆教程(附赠安装包)

随着技术的不断进步&#xff0c;越来越多的开发者开始在Linux环境下进行Java应用的开发。Java 17作为长期支持版本&#xff08;LTS&#xff09;&#xff0c;提供了许多新特性和性能改进。当然现在最新的是Java23&#xff0c;这个还作为实验版本未广泛使用。对于需要管理多个编程…

RHEL7+Oracle11.2 RAC集群-多路径(multipath+udev)安装步骤

RHEL7Oracle11.2RAC集群-多路径&#xff08;multipathudev&#xff09;安装 配置虚拟存储 使用StarWind Management Console软件&#xff0c;配置存储 dggrid1: 1g*3 Dggrid2: 1g*3 Dgsystem: 5g*1 系统表空间&#xff0c;临时表空间&#xff0c;UNDO&#xff0c;参数文件…

PyTorch 模型转换为 ONNX 格式

PyTorch 模型转换为 ONNX 格式 在深度学习领域&#xff0c;模型的可移植性和可解释性是非常重要的。本文将介绍如何使用 PyTorch 训练一个简单的卷积神经网络&#xff08;CNN&#xff09;来分类 MNIST 数据集&#xff0c;并将训练好的模型转换为 ONNX 格式。我们还将讨论 PTH …

VM Virutal Box的Ubuntu虚拟机与windows宿主机之间设置共享文件夹(自动挂载,永久有效)

本文参考如下链接 How to access a shared folder in VirtualBox? - Ask Ubuntu &#xff08;1&#xff09;安装增强功能&#xff08;Guest Additions&#xff09; 首先&#xff0c;在网上下载VBoxGuestAdditions光盘映像文件 下载地址&#xff1a;Index of http://…

CA系统(file.h---申请认证的处理)

#pragma once #ifndef FILEMANAGER_H #define FILEMANAGER_H #include <string> namespace F_ile {// 读取文件&#xff0c;返回文件内容bool readFilename(const std::string& filePath);bool readFilePubilcpath(const std::string& filePath);bool getNameFro…

【Git】Git 命令参考手册

目录 Git 命令参考手册1. 创建仓库1.1 创建一个新的本地仓库1.2 克隆一个仓库1.3 克隆仓库到指定目录 2. 提交更改2.1 显示工作目录中已修改的文件&#xff0c;准备提交2.2 将文件添加到暂存区&#xff0c;准备提交2.3 将所有已修改的文件添加到暂存区&#xff0c;准备提交2.4 …

【Linux系列】Chrony时间同步服务器搭建完整指南

1. 简介 Chrony是一个用于Linux系统的高效、精准的时间同步工具&#xff0c;通常用于替代传统的NTP&#xff08;Network Time Protocol&#xff09;服务。Chrony不仅在系统启动时提供快速的时间同步&#xff0c;还能在时钟漂移较大的情况下进行及时调整&#xff0c;因此广泛应…

数据库日志

MySQL中有哪些日志 1&#xff0c;redo log重做日志 redo log是物理机日志&#xff0c;因为它记录的是对数据页的物理修改&#xff0c;而不是SQL语句。 作用是确保事务的持久性&#xff0c;redo log日志记录事务执行后的状态&#xff0c;用来恢复未写入 data file的已提交事务…

【vue for beginner】Vue该怎么学?

&#x1f308;Don’t worry , just coding! 内耗与overthinking只会削弱你的精力&#xff0c;虚度你的光阴&#xff0c;每天迈出一小步&#xff0c;回头时发现已经走了很远。 vue2 和 vue3 Vue2现在正向vue3逐渐更新中&#xff0c;官方vue2已经不再更新。 这个历程和当时的pyt…

【Ubuntu 24.04】How to Install and Use NVM

参考 下载 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash激活 Activate NVM: Once the installation script completes, you need to either close and reopen the terminal or run the following command to use nvm immediately. exp…

SeggisV1.0 遥感影像分割软件【源代码】讲解

在此基础上进行二次开发&#xff0c;开发自己的软件&#xff0c;例如&#xff1a;【1】无人机及个人私有影像识别【2】离线使用【3】变化监测模型集成【4】个人私有分割模型集成等等&#xff0c;不管是您用来个人学习 还是公司研发需求&#xff0c;都相当合适&#xff0c;包您满…