Google Test 学习笔记(简称GTest)

news2024/11/15 21:00:26

文章目录

  • 一、介绍
    • 1.1 介绍
    • 1.2 教程
  • 二、使用
    • 2.1 基本使用
      • 2.1.1 安装GTest (下载和编译)
      • 2.1.2 编写测试
      • 2.1.3 运行测试
      • 2.1.4 高级特性
      • 2.1.5 调试和分析
    • 2.2 源码自带测试用例
    • 2.3 TEST 使用
      • 2.3.1 TestCase的介绍
      • 2.3.2 TEST宏
        • demo1
        • demo2
      • 2.3.3 TEST_F宏
      • 2.3.4 TEST 和 TEST_IF 区别
    • 2.4 EXPECT_*和ASSERT_*的宏介绍
      • 2.4.1 gtest之断言
      • 2.4.2 Boolean断言类型
      • 2.4.3 二元值断言类型
      • 2.4.4 字符串断言类型
  • 三、参考资料
  • 四、其他内容
    • 4.1 gtest 和 C++ 版本

一、介绍

1.1 介绍

Google Test(通常简称GTest)是Google开发的一个用于C++的单元测试框架,它可以帮助你轻松地编写和运行测试用例,确保代码的质量和稳定性。

  • 最大好处:实现自动化单元测试

1.2 教程

  • 官网:https://google.github.io/googletest/
  • 源码:https://github.com/google/googletest
  • 参考:gtest教程(记录小白从0学习gtest的过程)
  • GoogleTest测试框架介绍(二)
  • C++ 的测试框架之使用 gtest 编写单元测试

二、使用

  1. 编译库
  2. 编写工程代码
  3. 编写测试用例代码
  4. 工程:
    • 工程源码:库 / 程序
    • samples:示例程序,演示如何使用库的基本功能。
    • test:gtest

2.1 基本使用

2.1.1 安装GTest (下载和编译)

1.下载源码:
访问Google Test GitHub仓库,下载或克隆源码。

2.编译GTest:
GTest可以通过CMake等构建工具来构建。以CMake为例,你需要创建一个构建目录,然后运行CMake和Make工具。

mkdir build
cd build
cmake ..
make

3.安装GTest:
将GTest的库文件和头文件复制到你的项目中,或者在你的构建系统中链接GTest库。

2.1.2 编写测试

1.包含GTest头文件:
在你的测试文件中,需要包含GTest的头文件。

#include "gtest/gtest.h"

2.定义测试用例和测试函数:
测试用例(TEST_F)通常对应于一组相关的测试函数,而测试函数(TEST)则是具体执行的测试逻辑。

TEST(FactorialTest, PositiveNumbers) {  // 单独的测试函数
  EXPECT_EQ(1, Factorial(0));
  EXPECT_EQ(1, Factorial(1));
  EXPECT_EQ(2, Factorial(2));
  EXPECT_EQ(6, Factorial(3));
}

class MyMathTest : public ::testing::Test {
protected:
  void SetUp() override {
    // 初始化工作
  }
};

TEST_F(MyMathTest, TestAddition) {
  EXPECT_EQ(5, Add(2, 3));
}

3.断言:
使用GTest提供的断言来检查函数的行为是否符合预期。例如,EXPECT_EQ用于比较两个值是否相等。

4.测试驱动:
在main函数中调用::testing::InitGoogleTest和RUN_ALL_TESTS来初始化GTest并运行所有的测试。

int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

2.1.3 运行测试

1.编译测试:
使用你的构建系统(如Makefile或CMakeLists.txt)来编译你的测试代码。

2.执行测试:
运行生成的可执行文件来执行测试。GTest会输出测试的结果,包括通过、失败或跳过的测试。

2.1.4 高级特性

  • 参数化测试:使用INSTANTIATE_TEST_SUITE_P来创建一系列使用不同参数的测试用例。
  • 死亡测试:使用ASSERT_DEATH或EXPECT_DEATH来检查代码是否会在特定条件下崩溃。
  • Google Mock:GTest的一部分,用于创建和使用mock对象来进行更复杂的测试。

2.1.5 调试和分析

  • 测试过滤:在运行测试时,可以使用–gtest_filter参数来指定运行哪些测试。
  • 测试日志:使用–gtest_output=xml:test_results.xml等选项来生成测试报告。

2.2 源码自带测试用例

  • 参考:https://gitcode.csdn.net/65acab6ab8e5f01e1e451947.html

我们还没有添加我们自己的源码,和针对源码的测试用例,但是谷歌已经写好了一些例子,可以先体验下,放在如下路径:/xxx/googletest-1.15.0/googletest

测试:

  1. 修改 CMakeLists.txt

    # 这里 OFF 改成 ON
    option(gtest_build_samples "Build gtest's sample programs." OFF)
    

    相关编译内容:

    if (gtest_build_samples)
      cxx_executable(sample1_unittest samples gtest_main samples/sample1.cc)
      cxx_executable(sample2_unittest samples gtest_main samples/sample2.cc)
      cxx_executable(sample3_unittest samples gtest_main)
      cxx_executable(sample4_unittest samples gtest_main samples/sample4.cc)
      cxx_executable(sample5_unittest samples gtest_main samples/sample1.cc)
      cxx_executable(sample6_unittest samples gtest_main)
      cxx_executable(sample7_unittest samples gtest_main)
      cxx_executable(sample8_unittest samples gtest_main)
      cxx_executable(sample9_unittest samples gtest)
      cxx_executable(sample10_unittest samples gtest)
    endif()
    
  2. 编译:

    mkdir build
    cd build
    cmake -DCMAKE_INSTALL_PREFIX=pwd/result -DGOOGLETEST_VERSION=1.5.0 ..
    make -j4
    
    # 单个文件编译
    # g++ ../src/gtest_main.cc sample1.cc sample1_unittest.cc -o test -lgtest -lgmock -lpthread -std=c++11
    
  3. 运行:

    ./sample1_unittest 
    

    输出:在这里插入图片描述

  4. 理解:

    • gtest_main.cc :测试主程序入口,不是我们待测源码的主程序入口。

      情况一:整个工程有两个main函数,一个是测试的main,一个可能是待测源码的main,两个包含main的文件不能同时编译,因为一个执行程序只能有一个入口。(可以n个文件n个main函数)

      情况二:一个main函数通过宏定义区分启动

    • sample1.cc:待测源码,就是测试对象,我们就是要对个源码进行白盒测试。
    • sample1_unittest.cc:测试用例,里面就是我们针对源码写的测试用例脚本。
  5. 工程:

    • 工程源码:库 / 程序
    • samples:示例程序,演示如何使用库的基本功能。
    • test:gtest
  6. 遗留问题:编译没看懂—>再看

2.3 TEST 使用

  • 转自:Gtest入门2 Gtest之TEST宏的用法

2.3.1 TestCase的介绍

Gtest提供了若干个case方法进行测试不同的用例。主要常见的有TEST/TEST_F及TEST_P宏的使用。

在每个TestCase中可以通过断言提供的方法进行控制检查程序的预期走向是否是期望的结果,从而以此来判定程序的正确性。

在同一份TestCase中不能同时出现TEST和TEST_F两者进行混用;

其次TEST_F比TEST强的地方是会通过继承::testing::Test生成一个新类,而且这是必须的。

在新类中可以通过void SetUp();和void TearDown();进行创建和清除相关的资源数据;

2.3.2 TEST宏

TEST宏的作用是创建一个简单测试,它定义了一个测试函数,在这个函数里可以使用任何C++代码并使用提供的断言来进行检查。

TEST语法定义:
TEST(test_case_name, test_name)
  • test_case_name第一个参数是测试用例名,通常是取测试函数名或者测试类名
  • test_name 第二个参数是测试名这个随便取,但最好取有意义的名称
  • 当测试完成后显示的测试结果将以"测试用例名.测试名"的形式给出
demo1
// test.cpp
// g++ -std=c++14 ../../src/gtest_main.cc test.cpp -o test -I../../include -L ../lib -lgtest -lpthread
#include <iostream>
#include <memory>
#include <gtest/gtest.h>

using namespace std;

class Base {
public:
	Base(std::string name):m_name{name} {
		std::cout << "name: " << m_name << std::endl;
	}

	std::string getName() {
		return m_name;
	}
	~Base() {
		
		std::cout << "destory base" << std::endl;
	}
private:
	std::string m_name;
};

void getNameFunc(std::shared_ptr<Base> base) {
	std::cout << __func__ << " : usercount: " << base.use_count() << std::endl;
	std::cout << __func__ << " : name: " << base->getName() << std::endl;
	// EXPECT_EQ(2, base.use_count());
}

TEST(Base, createInstance) {
	std::unique_ptr<Base> instance = make_unique<Base>("SvenBaseUnique");
	// 测试创建的instance实例是否不为nullptr
	EXPECT_NE(instance, nullptr);
	instance.reset();
	// 测试instance实例是否为nullptr
	EXPECT_EQ(instance, nullptr);
}

TEST(Base, getName) {
	std::unique_ptr<Base> instance = make_unique<Base>("BaseUnique");
	EXPECT_NE(instance, nullptr);
	auto name = instance->getName();
	// 测试获取的name值是否和被给的值相等
	EXPECT_STREQ(name.c_str(), "BaseUnique");
	instance.reset();
	EXPECT_EQ(instance, nullptr);
}

TEST(Base, shared_ptr) {
	std::shared_ptr<Base> instance = std::make_shared<Base>("BaseShared");
	EXPECT_NE(instance, nullptr);
	std::cout << "shared_ptr.use_count: " << instance.use_count() << std::endl;
	// 测试instance引用次数是否为1
	EXPECT_EQ(1, instance.use_count());
	getNameFunc(instance);
	EXPECT_EQ(1, instance.use_count());
}

TEST(Base, unique_ptr) {
	std::unique_ptr<Base> instance = make_unique<Base>("BaseUnique");
	EXPECT_NE(instance, nullptr);
	getNameFunc(std::move(instance));
	EXPECT_EQ(instance, nullptr);
}
demo2
// test_2.cc
// g++ -std=c++14  test_2.cc -o test_2 -I../../include -L ../lib -lgtest -lpthread
#include <gtest/gtest.h>
#include <vector>
#include <string>
#include <cmath>

// 示例函数,用于测试
int Add(int a, int b) {
    return a + b;
}

std::vector<int> GetPrimesUnder100() {
    std::vector<int> primes = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97};
    return primes;
}

class StringClass {
public:
    std::string Reverse(const std::string& s) {
        return std::string(s.rbegin(), s.rend());
    }
};

// 测试类
class MyTest : public ::testing::Test {
protected:
    StringClass stringObj;
};

// 测试用例:测试 Add 函数
TEST(AdditionTest, HandlesZeroInput) {
    EXPECT_EQ(Add(0, 0), 0);
    ASSERT_EQ(Add(0, 1), 1);
    // EXPECT_EQ(Add(0, 0), 30);   // error test
    // ASSERT_EQ(Add(0, 1), 30);
    // ASSERT_EQ(Add(1, 1), 2);
}

TEST(AdditionTest, HandlesPositiveInput) {
    EXPECT_EQ(Add(2, 3), 5);
    ASSERT_EQ(Add(-1, 1), 0);
}

TEST(AdditionTest, HandlesNegativeInput) {
    EXPECT_EQ(Add(-1, -1), -2);
    ASSERT_EQ(Add(-2, 3), 1);
}

// 测试用例:测试 GetPrimesUnder100 函数
TEST(PrimeTest, ReturnsCorrectPrimes) {
    auto primes = GetPrimesUnder100();
    ASSERT_EQ(primes.size(), 25);
    EXPECT_EQ(primes[0], 2);
    EXPECT_EQ(primes[24], 97);
}

// 测试用例:测试 StringClass 的 Reverse 方法
TEST_F(MyTest, ReversesString) {
    std::string original = "hello";
    std::string reversed = stringObj.Reverse(original);
    EXPECT_EQ(reversed, "olleh");
}

TEST_F(MyTest, ReversesEmptyString) {
    std::string original = "";
    std::string reversed = stringObj.Reverse(original);
    EXPECT_EQ(reversed, "");
}

TEST_F(MyTest, ReversesSingleCharacterString) {
    std::string original = "a";
    std::string reversed = stringObj.Reverse(original);
    EXPECT_EQ(reversed, "a");
}

// 测试用例:测试浮点数比较
TEST(FloatTest, ComparesFloats) {
    float a = 1.0f + 1e-5f;
    float b = 1.0f;
    EXPECT_NEAR(a, b, 1e-4f);
}

// 测试用例:测试布尔值
TEST(BooleanTest, ChecksTrue) {
    bool condition = true;
    EXPECT_TRUE(condition);
    ASSERT_TRUE(condition);
}

TEST(BooleanTest, ChecksFalse) {
    bool condition = false;
    EXPECT_FALSE(condition);
    ASSERT_FALSE(condition);
}

// 测试用例:测试异常
TEST(ExceptionTest, ThrowsException) {
    ASSERT_THROW(throw std::runtime_error("test exception"), std::runtime_error);
}

// 测试用例:测试子测试
TEST(SubtestTest, Subtest1) {
    SUCCEED() << "This is a subtest.";
    EXPECT_EQ(1, 1);
}

TEST(SubtestTest, Subtest2) {
    SUCCEED() << "This is another subtest.";
    EXPECT_EQ(2, 2);
}

int main(int argc, char **argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

2.3.3 TEST_F宏

TEST_F主要是进行多样测试,就是多种不同情况的测试TestCase中都会使用相同一份的测试数据的时候将会才用它。
即用相同的数据测试不同的行为,如果采用TEST宏进行测试那么将会为不同的测试case创建一份数据。TEST_F宏将会共用一份避免重复拷贝共具灵活性。

语法定义为:
TEST_F(test_case_name, test_name);
  • test_case_name第一个参数是测试用例名,必须取类名。这个和TEST宏不同
  • test_name 第二个参数是测试名这个随便取,但最好取有意义的名称
  • 使用TEST_F时必须继承::testing::Test类。并且该类提供了两个接口void SetUp(); void TearDown();
    void SetUp()函数,为测试准备对象.
    void TearDown()函数 为测试后销毁对象资源
    

2.3.4 TEST 和 TEST_IF 区别

在 Google Test 中,TESTTEST_F 是用来定义测试用例的两个不同的宏。它们之间的主要区别在于是否需要测试夹具(test fixture):

  1. TEST(SuiteName, TestName)

    • TEST 宏用于定义不需要特殊初始化或清理的简单测试用例。
    • 它不接受任何参数,因此也不需要测试夹具类。
    • 测试用例函数是自动实例化的,并且每个测试用例都是独立的,不共享任何设置。
    • 适用于快速、独立的测试,不需要重复的初始化逻辑。

    示例代码:

    TEST(MultiplicationTest, HandlesZero) {
      EXPECT_EQ(0 * 5, 0);
    }
    
  2. TEST_F(TestFixture, TestName)

    • TEST_F 宏用于定义需要使用测试夹具的测试用例。
    • 测试夹具是一个从 ::testing::Test 派生的类,你可以在里面定义公共和受保护的成员,这些成员在每个测试用例中都可以访问。
    • 测试夹具类允许你在 SetUp 方法中编写初始化代码,这些代码会在每个测试用例运行之前执行,而在 TearDown 方法中编写清理代码,这些代码会在每个测试用例运行之后执行。
    • 适用于需要共享初始化逻辑和成员数据的测试用例。

    示例代码:

    class MultiplicationTest : public ::testing::Test {
    protected:
      int result;
    
      void SetUp() override {
        result = 0;
      }
    
      void TearDown() override {
        // 清理工作,如果需要的话
      }
    };
    
    TEST_F(MultiplicationTest, HandlesZero) {
      result = 0 * 5;
      EXPECT_EQ(result, 0);
    }
    

除了 TESTTEST_F,Google Test 还有一个宏 TEST_P,它用于定义参数化测试。参数化测试允许你用不同的参数多次运行同一个测试用例。

关于 TEST_IF 宏,实际上 Google Test 标准库中并没有这个宏。可能你指的是 TEST_P 或者某个特定版本的 Google Test 中的宏,或者是第三方扩展。通常情况下,TEST_P 用于参数化测试,允许你为测试用例提供参数,并且可以结合 INSTANTIATE_TEST_CASE_P 宏来实例化多个测试用例。

如果你需要更具体的信息或者有特定的使用场景,请提供更多的上下文,我可以给出更准确的答案。

2.4 EXPECT_*和ASSERT_*的宏介绍

  • 转自:Gtest入门2 Gtest之TEST宏的用法

2.4.1 gtest之断言

要测试一个类或函数,我们需要对其行为做出断言。当一个断言失败时,Google Test会在屏幕上输出该代码所在的源文件及其所在的位置行号,以及错误信息。也可以在编写断言时,提供一个自定义的错误信息,这个信息在失败时会被附加在Google Test的错误信息之后。

断言常常成对出现,它们都测试同一个类或者函数,但对当前功能有着不同的效果。

  • ASSERT_*版本的断言失败时会产生致命失败,并结束当前函数。
  • EXPECT_*版本的断言产生非致命失败,而不会中止当前函数。

通常更推荐使用EXPECT_*断言,因为它们运行一个测试中可以有不止一个的错误被报告出来。但如果在编写断言如果失败,就没有必要继续往下执行的测试时,你应该使用ASSERT_*断言。 因为失败的ASSERT_*断言会立刻从当前的函数返回,可能会跳过其后的一些的清洁代码,这样也许会导致空间泄漏。

gtest中断言的宏可以分为两类:一类是ASSERT宏,另一类就是EXPECT宏了。
1、ASSERT_*系列:如果当前点检测失败则退出当前函数
2、EXPECT_*系列:如果当前点检测失败则继续往下执行

2.4.2 Boolean断言类型

在这里插入图片描述

2.4.3 二元值断言类型

比较两个值的大小。
在这里插入图片描述

2.4.4 字符串断言类型

比较两个字符串。
在这里插入图片描述

三、参考资料

  • 玩转C++单元测试之快速上手gtest

  • Google Test(GTEST)使用入门(1)- 下载编译安装执行

四、其他内容

4.1 gtest 和 C++ 版本

Google Test(GTest)对不同版本的 C++ 标准的支持有所变化。下面是 Google Test 对 C++ 标准版本支持的大致时间线和相关信息。

Google Test 对 C++ 标准的支持

  • GTest 1.8.1(发布于 2015 年 7 月 29 日):

    • 支持 C++98、C++03、C++11、C++14。
    • 从 GTest 1.8.1 开始,GTest 支持 C++14,并且开始逐渐移除对旧版本 C++ 标准的支持。
  • GTest 1.10.0(发布于 2019 年 10 月 28 日):

    • 支持 C++11、C++14、C++17。
    • GTest 1.10.0 版本开始正式移除对 C++98 和 C++03 的支持。
  • GTest 1.11.0(发布于 2021 年 1 月 25 日):

    • 支持 C++11、C++14、C++17。
    • GTest 1.11.0 版本继续支持 C++11、C++14 和 C++17。
  • GTest 1.12.1(发布于 2022 年 8 月 17 日):

    • 支持 C++11、C++14、C++17、C++20。
    • GTest 1.12.1 版本增加了对 C++20 的支持。
  • GTest 1.13.0(发布于 2023 年 11 月 2 日):

    • 支持 C++14、C++17、C++20。
    • GTest 1.13.0 版本移除了对 C++11 的支持,现在仅支持 C++14 及以上版本。

总结

  • 最新版本(截至 2024 年 7 月 25 日):

    • GTest 1.13.0 支持 C++14、C++17 和 C++20。
  • 历史版本

    • GTest 1.12.1 支持 C++11、C++14、C++17 和 C++20。
    • GTest 1.11.0 支持 C++11、C++14 和 C++17。
    • GTest 1.10.0 支持 C++11、C++14 和 C++17。
    • GTest 1.8.1 支持 C++98、C++03、C++11 和 C++14。

建议

  • 使用最新版本

    • 如果您的项目可以使用较新的 C++ 版本,建议使用 GTest 1.13.0 或更高版本,以获得更好的特性和支持。
    • 对于 C++14 及以上版本的支持,您可以使用 GTest 1.13.0。
  • 使用较旧版本

    • 如果您的项目受限于旧版本的 C++,您可以考虑使用相应的 GTest 版本。例如,如果您的项目使用 C++11,您可以考虑使用 GTest 1.12.1 或更低版本。

示例编译命令

如果您使用的是 GTest 1.13.0 或更高版本,并且您的编译器支持 C++14 或更高版本,您可以使用以下编译命令:

g++ -std=c++14 ../../src/gtest_main.cc test.cpp -o test -I../../include -L ../lib -lgtest -lpthread

请确保您的编译器支持所需的 C++ 标准版本。如果您的编译器不支持 C++14 或更高版本,您可能需要升级编译器或考虑使用较低版本的 GTest。

如果您需要使用 C++11,您可以使用 GTest 1.12.1 或更低版本,并相应地更新编译命令中的 C++ 标准版本:

g++ -std=c++11 ../../src/gtest_main.cc test.cpp -o test -I../../include -L ../lib -lgtest -lpthread

请根据您的具体需求调整编译命令中的 C++ 标准版本。

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

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

相关文章

2-45 基于matlab的递归最小二乘法(RLS)对声音信号去噪

基于matlab的递归最小二乘法&#xff08;RLS&#xff09;对声音信号去噪,并对消噪前后的信号进行FFT分析&#xff0c;对比消噪前后的效果。可替换自己的声音信号进行分析。程序已调通&#xff0c;可直接运行。 2-45 递归最小二乘法&#xff08;RLS&#xff09; FFT分析 - 小红书…

聘请TPM管理咨询公司如何赢得员工认可?

聘请TPM管理咨询公司是一个重要的决策&#xff0c;它不仅能提升企业的运营效率和质量管理水平&#xff0c;而且需要得到员工的广泛认可才能确保改革的顺利实施。然而&#xff0c;赢得员工的认可并非易事&#xff0c;需要公司管理层和咨询公司共同努力&#xff0c;采取一系列措施…

崖山异构数据库迁移利器YMP初体验-Oracle迁移YashanDB

前言 首届YashanDB「迁移体验官」开放后&#xff0c;陆续收到「体验官」们的投稿&#xff0c;小崖在此把优秀的投稿文章分享给大家~今天分享的用户文章是《崖山异构数据库迁移利器YMP初体验-Oracle迁移YashanDB》&#xff08;作者&#xff1a;小草&#xff09;&#xff0c;满满…

C++ | Leetcode C++题解之第275题H指数II

题目&#xff1a; 题解&#xff1a; class Solution { public:int hIndex(vector<int>& citations) {int n citations.size();int left 0, right n - 1;while (left < right) {int mid left (right - left) / 2;if (citations[mid] > n - mid) {right m…

C++ primer plus 第16章string 类和标准模板库, 函数符概念

C primer plus 第16章string 类和标准模板库, 函数符概念 C primer plus 第16章string 类和标准模板库, 函数符概念 文章目录 C primer plus 第16章string 类和标准模板库, 函数符概念16.5.1 函数符概念程序清单16.15 functor.cpp 16.5.1 函数符概念 正如 STL定义了容器和迭代…

【AOP实战】掌握Spring Boot AOP:重构代码,提升效率

文章目录 Spring Boot AOP - 面向切面编程AOP到底有什么不同AOP中的编程术语和常用注解定义切面环绕通知通知方法传参总结 Spring Boot AOP - 面向切面编程 AOP&#xff0c;即面向切面编程&#xff0c;其核心思想就是把业务分为核心业务和非核心业务两大部分。例如一个论坛系统…

ESP32和mDNS学习

目录 mDNS的作用mDNS涉及到的标准文件组播地址IPv4 多播地址IPv6 多播地址预先定义好的组播地址 mDNS调试工具例程mDNS如何开发和使用注册服务查询服务 mDNS的作用 mDNS 是一种组播 UDP 服务&#xff0c;用来提供本地网络服务和主机发现。 你要和设备通信&#xff0c;需要记住…

PHP基础语法-Part1

脚本格式 PHP脚本以<?php开头&#xff0c;以?>结尾&#xff1b; PHP语句以分号结尾&#xff08;;&#xff09; PHP是解释型语言&#xff1b; 输入和输出 获取用户的输入&#xff1a; $input readline("input:"); echo $input; echo "input:";…

EEtrade:区块链是什么

区块链&#xff0c;这个近年来频繁出现在我们视野中的术语&#xff0c;已经从一个技术小众圈的词汇&#xff0c;逐渐演变为全球关注的焦点。从比特币的诞生&#xff0c;到如今在金融、供应链、物联网等领域的广泛应用&#xff0c;区块链技术正在深刻地改变着我们的生活。那么&a…

将YOLOv8模型从PyTorch的.pt格式转换为TensorRT的.engine格式

TensorRT是由NVIDIA开发的一款高级软件开发套件(SDK)&#xff0c;专为高速深度学习推理而设计。它非常适合目标检测等实时应用。该工具包可针对NVIDIA GPU优化深度学习模型&#xff0c;从而实现更快、更高效的运行。TensorRT模型经过TensorRT优化&#xff0c;包括层融合(layer …

ARCGIS PRO DSK GraphicsLayer创建文本要素

一、判断GraphicsLayer层【地块注记】是否存在&#xff0c;如果不存在则新建、如果存在则删除所有要素 Dim GraphicsLayer pmap.GetLayersAsFlattenedList().OfType(Of ArcGIS.Desktop.Mapping.GraphicsLayer).FirstOrDefault() 获取当前map对象中的GetLayer图层 Await Queue…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第五十六章 设备驱动IO控制

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

云计算安全扩展要求解读

云计算简介&#xff1a; 一种全新网络服务方式&#xff0c;将传统的以桌面为核 心的任务处理转变为以网络为核心的任务处理&#xff0c; 利用互联网实现自己想要完成的一切处理任务&#xff0c; 使网络成为传递服务、计算力和信息的综合媒 介&#xff0c;真正实现按需计算、多…

揭秘Django与Neo4j:构建智能知识图谱的终极指南

揭秘Django与Neo4j:构建智能知识图谱的终极指南 前言 图是一种用于对象之间的成对关系进行建模的数学结构。 它由两个主要元素组成:节点和关系。 节点:节点可以看作是传统数据库中的记录。每个节点代表一个对象或实体,例如一个人或一个地方。节点按标签分类,这有助于根…

自研点直播转码核心

1. 背景 视频转码是将视频文件经过解封装、解码、滤镜处理、编码、封装从而转换为另一个视频文件的过程&#xff0c;B站每天都有大量的视频原片上传后经过转码系统转换为多个不同分辨率。转换后的视频在画质接近原片的前提下会拥有更低的码率&#xff0c;因此会提高网络传输时的…

3.3-LSTM的改进

文章目录 1改进点1.1多层化1.2 dropout1.2.1具体概念1.2.2应该插入到LSTM模型的哪里 1.3权重共享 2改进之后的LSTMLM的代码实现2.1初始化2.2前向计算2.3反向传播 3相应的学习代码的实现4总结 1改进点 1.1多层化 加深神经网络的层数往往能够学习更复杂的模式&#xff1b;因此这…

定制化爬虫管理:为企业量身打造的数据抓取方案

在数据驱动的时代&#xff0c;企业如何高效、安全地获取互联网上的宝贵信息&#xff1f;定制化爬虫管理服务应运而生&#xff0c;成为解锁专属数据宝藏的金钥匙。本文将深入探讨定制化爬虫管理如何为企业量身打造数据抓取方案&#xff0c;揭秘其在海量信息中精准捕获价值数据的…

C++初阶学习——探索STL奥秘——标准库中的string类

1. 为什么学习string类&#xff1f; 在我们学习C语言的时候&#xff0c;有一个点是非常难处理的&#xff0c;那就是字符串&#xff0c;在我们对字符串访问&#xff0c;增删查改时都是非常不便的&#xff0c;所以我们封装了一个string类主要来处理字符串有关的问题 2. 标准库中…

Premiere简约手绘风格箭头标题文字动画素材MOGRT

18个简约手绘风格箭头标题文字动画 | Premiere Pro mogrt 具有可定制的颜色和可编辑的文本。包括手绘箭头和文本动画&#xff0c;非常适合在项目中添加动态指针、标记和方向指示器。非常适合信息图表、社交媒体内容、下三分之一、徽章和简约界面。 项目特点&#xff1a; 独特…

python机器学习8--网络

1.超文本传输协议HTTP GET 在实际开发应用程序时&#xff0c;一定都会利用WiFi网络进行连接&#xff0c;再通过HTTP的方式读入后台的数据&#xff0c;并下载和显示在用户的PC上。这靠的是网络服务的技术&#xff0c;也就是大家提到的Web Service。而与HTTP服务器交换数据有两种…