跨平台C++单元测试框架——GTest

2023-05-16

1、简介

       GTest是google公司发布的一个跨平台的(Liunx、Mac OS X、Windows、Cygwin、Windows CE and Symbian)C++单元测试框架。它提供了丰富的断言、致命和非致命判断、参数化、死亡测试等等。

       使用gtest时,就是编写断言(assertions),断言语句会检测条件是否为真。一个断言可存在三种结果:success(成功),nonfatal failure(非致命失败),或 fatal failure(致命失败)。当出现致命失败时,终止当前函数;否则程序继续执行。

 

2、基本概念

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

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

 

3、下载与安装

下载源码:

https://github.com/google/googletest

解压:

unzip googletest-release-1.10.0.zip

编译:

cmake CMakeLists.txt

生成静态库:

make

拷贝到系统目录(不同版本位置略有不同):

sudo cp libgtest*.a  /usr/lib
sudo cp –a include/gtest /usr/include

验证:

例:gtest.cpp

#include<gtest/gtest.h>

using namespace std;

int add(int a,int b){
        return a+b;
}

TEST(testCase,test0){
        EXPECT_EQ(add(2,3),5);
}

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

        return 0;
}

编译:

g++ gtest.cpp -lgtest -lpthread

运行:./a.out,结果如下:

 

4、GTest的断言

       gtest 使用一系列断言的宏来检查值是否符合预期,主要分为两类:ASSERT 和 EXPECT。EXPECT_*和ASSERT_*的区别:EXPECT_*失败时,案例继续往下执行;ASSERT_*失败时,直接在当前函数中返回,当前函数中ASSERT_*后面的语句将不会执行,退出当前函数,并非退出当前案例。

(1)布尔值检查

Fatal assertion

Nonfatal assertion

Verifies

ASSERT_TRUE(condition);

EXPECT_TRUE(condition);

期待结果是true

ASSERT_FALSE(condition);

EXPECT_FALSE(condition);

期待结果是false

 (2)数值型数据检查

Fatal assertion

Nonfatal assertion

Verifies

ASSERT_EQ(expectedactual);

EXPECT_EQ(expectedactual);

expected == actual

ASSERT_NE(val1val2);

EXPECT_NE(val1val2);

val1 != val2

ASSERT_LT(val1val2);

EXPECT_LT(val1val2);

val1 < val2

ASSERT_LE(val1val2);

EXPECT_LE(val1val2);

val1 <= val2

ASSERT_GT(val1val2);

EXPECT_GT(val1val2);

val1 > val2

ASSERT_GE(val1val2);

EXPECT_GE(val1val2);

val1 >= val2

 (3)字符串比较

Fatal assertion

Nonfatal assertion

Verifies

ASSERT_STREQ(expected_stractual_str);

EXPECT_STREQ(expected_stractual_str);

两个C字符串有相同的内容

ASSERT_STRNE(str1str2);

EXPECT_STRNE(str1str2);

两个C字符串有不同的内容

ASSERT_STRCASEEQ(expected_stractual_str);

EXPECT_STRCASEEQ(expected_stractual_str);

两个C字符串有相同的内容,忽略大小写

ASSERT_STRCASENE(str1str2);

EXPECT_STRCASENE(str1str2);

两个C字符串有不同的内容,忽略大小写

 (4)异常检查

Fatal assertion

Nonfatal assertion

Verifies

ASSERT_THROW(statementexception_type);

EXPECT_THROW(statementexception_type);

statement throws an exception of the given type

ASSERT_ANY_THROW(statement);

EXPECT_ANY_THROW(statement);

statement throws an exception of any type

ASSERT_NO_THROW(statement);

EXPECT_NO_THROW(statement);

statement doesn't throw any exception

 

(5)浮点型检查

Fatal assertion

Nonfatal assertion

Verifies

ASSERT_FLOAT_EQ(expected, actual);

EXPECT_FLOAT_EQ(expected, actual);

the two float values are almost equal

ASSERT_DOUBLE_EQ(expected, actual);

EXPECT_DOUBLE_EQ(expected, actual);

the two double values are almost equal

 对相近的两个数比较:

Fatal assertion

Nonfatal assertion

Verifies

ASSERT_NEAR(val1, val2, abs_error);

EXPECT_NEAR(val1, val2, abs_error);

the difference between val1 and val2 doesn't exceed the given absolute error

 

(6)此外还有类型检查、谓词检查等

5、事件机制

(1)全局事件

       要实现全局事件,必须写一个类,继承testing::Environment类,实现里面的SetUp()TearDown()方法。

  • SetUp()方法在所有案例执行前执行
  • TearDown()方法在所有案例执行后执行

       还需要告诉gtest添加这个全局事件,我们需要在main函数中通过testing::AddGlobalTestEnvironment方法将事件挂进来,也就是说,我们可以写很多个这样的类,然后将他们的事件都挂上去。

(2)TestSuite事件

       我们需要写一个类,继承testing::Test,然后实现两个静态方法

  • SetUpTestCase() 方法在第一个TestCase之前执行
  • TearDownTestCase() 方法在最后一个TestCase之后执行

       在编写测试案例时,我们需要使用TEST_F这个宏,第一个参数必须是我们上面类的名字,代表一个TestSuite。

(3)TestCase事件

       TestCase事件是挂在每个案例执行前后的,实现方式和上面的几乎一样,不过需要实现的是SetUp方法和TearDown方法:

  • SetUp()方法在每个TestCase之前执行
  • TearDown()方法在每个TestCase之后执行

例:

#include <gtest/gtest.h>
#include <map>
#include <iostream>

using namespace std;

class Student{
public:
    Student(){
        age=0;
    }

    Student(int a){
        age=a;
    }

    void print(){
        cout<<"*********** "<<age<<" **********"<<endl;;
    }

private:
    int age;
};

class FooEnvironment : public testing::Environment{
public:
    virtual void SetUp() {
        cout << "Foo FooEnvironment SetUP" << std::endl;
    }

    virtual void TearDown() {
        cout << "Foo FooEnvironment TearDown" << std::endl;
    }
};

static Student *s;

class TestMap : public testing::Test
{
public:
    static void SetUpTestCase() {
        cout<<"SetUpTestCase()"<<endl;
        s=new Student(23);
}

static void TearDownTestCase(){
        delete s;
        cout<<"TearDownTestCase()"<<endl;
    }

    void SetUp() {
        cout<<"SetUp() is running"<<endl;
    }

    void TearDown() {
        cout<<"TearDown()"<<endl;
    }
};

TEST_F(TestMap, Test1)
{
    s->print();
}

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

编译:

g++ testSuit.cpp -lgtest -lpthread -o testSuit

运行:

./a.out

 

6、参数化

       当考虑多次要为被测函数传入不同的值的情况时,可以按下面的方式去测试。必须添加一个类,继承testing::TestWithParam<T>。其中T就是你需要参数化的参数类型,如下面的案例是int型参数。(官方文档上的案例)

例:

#include<gtest/gtest.h>

// Returns true iff n is a prime number.
bool IsPrime(int n)
{
    // Trivial case 1: small numbers
    if (n <= 1) return false;
    // Trivial case 2: even numbers
    if (n % 2 == 0) return n == 2;
    // Now, we have that n is odd and n >= 3.
    // Try to divide n by every odd number i, starting from 3
    for (int i = 3; ; i += 2) {
        // We only have to try i up to the squre root of n
        if (i > n/i) break;
        // Now, we have i <= n/i < n.
        // If n is divisible by i, n is not prime.
        if (n % i == 0) return false;
    }
    // n has no integer factor in the range (1, n), and thus is prime.
    return true;
}

class IsPrimeParamTest : public::testing::TestWithParam<int>
{

};

TEST_P(IsPrimeParamTest, HandleTrueReturn)
{
    int n =  GetParam();
    EXPECT_TRUE(IsPrime(n));
}

//被测函数须传入多个相关的值
INSTANTIATE_TEST_CASE_P(TrueReturn, IsPrimeParamTest, testing::Values(3, 5, 11, 23, 17));

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

 

7、命令行参数

       testing::InitGoogleTest(&argc,argv):gtest的测试案例允许接收一系列的命令行参数,将命令行参数传递给gtest,进行一些初始化操作。gtest的命令行参数非常丰富。

对于运行参数,gtest提供了三种设置的途径:

  • 系统环境变量;
  • 命令行参数;
  • 代码中指定FLAG。

命令行参数:

  • (1)--gtest_list_tests:使用这个参数时,将不会执行里面的测试案例,而是输出一个案例的列表;
  • (2)--gtest_filter:对执行的测试案例进行过滤,支持通配符;
  • (3)--gtest_also_run_disabled_tests:执行案例时,同时也执行被置为无效的测试案例;
  • (4)--gtest_repeat=[COUNT]:设置案例重复运行次数;
  • (5)--gtest_color=(yes|no|auto):输出命令行时是否使用一些五颜六色的颜色,默认是auto;
  • (6)--gtest_print_time:输出命令时是否打印每个测试案例的执行时间,默认是不打印的;
  • (7)--gtest_output=xml[:DIRECTORY_PATH\|:FILE_PATH:将测试结果输出到一个xml中,如—gtest_output=xml:d:\foo.xml  指定输出到d:\foo.xml ,如果不是指定了特定的文件路径,gtest每次输出的报告不会覆盖,而会以数字后缀的方式创建;
  • (8)--gtest_break_on_failure:调试模式下,当案例失败时停止,方便调试;
  • (9)--gtest_throw_on_failure:当案例失败时以C++异常的方式抛出;
  • (10)--gtest_catch_exceptions:是否捕捉异常,gtest默认是不捕捉异常的,这个参数只在Windows下有效。

 

8、死亡测试

       这里的”死亡”指的是程序的奔溃。通常在测试的过程中,我们需要考虑各种各样的输入,有的输入可能直接导致程序奔溃,这个时候我们就要检查程序是否按照预期的方式挂掉,这也就是所谓的”死亡测试”。

编写死亡测试案例时,TEST的第一个参数,即test_case_name,请使用DeathTest后缀,原因是gtest会优先运行死亡测试案例,应该是为线程安全考虑。

死亡测试所用到的宏:

  • (1)ASSERT_DEATH(参数1,参数2),程序挂了并且错误信息和参数2匹配,此时认为测试通过。如果参数2为空字符串,则只需要看程序挂没挂即可。
  • (2)ASSERT_EXIT(参数1,参数2,参数3),语句停止并且错误信息和被提前给的信息匹配。

例:

#include <gtest/gtest.h>

using namespace std;

int func()
{
        int *ptr = NULL;
        *ptr = 100;
        return 0;
}

TEST(FunDeathTest, Nullptr)
{
        ASSERT_DEATH(func(), "");
}

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

输出:

另:失败的案例

将上例中的func()换成如下:

int func()
{
        int *ptr = new int(99);
        return 0;
}

测试结果如下:

 

9、另外

(1)TEST(test_case_name, test_name)

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

多个测试场景需要相同数据配置的情况,用TEST_F。

(2)RUN_ALL_TESTS():运行所有测试案例。

(3)可以通过操作符"<<"将一些自定义的信息输出,如在EXPECT_EQ(v1, v2)<< "thisis a error! "

(4)testing::AddGlobalTestEnvironment(newFooEnvironment):在main函数中创建和注册全局环境对象。

 

10、实例

#include<iostream>
using namespace std;
#include<gtest/gtest.h>

struct LinkNode
{
    int _data;
    LinkNode *_next;
    LinkNode(const int& data)
        :_data(data)
        ,_next(NULL)
    {}
};

class Link
{
public:
    Link()
        :pHead(new LinkNode(0))
    {}
    void PushBack(const int& data)
    {
        if(pHead == NULL)
            return ;
        LinkNode *newNode=new LinkNode(data);
        if(pHead->_next == NULL){  //第一次插入结点
            pHead->_next=newNode;
        }
        else{  //找到最后一个结点直接尾插
            LinkNode *cur=pHead->_next;
            while(cur->_next){
                cur=cur->_next;
            }
            cur->_next=newNode;
        }
    }

    void PopBack()
    {
        if(pHead == NULL)
            return ;
        LinkNode *cur=pHead;
        LinkNode *prev=NULL;
        while(cur->_next)
        {
            prev=cur;
            cur=cur->_next;
        }
        prev->_next=NULL;
        delete cur;
    }

    LinkNode *FindNode(const int& data)
    {
        if(pHead == NULL)
            return NULL;
        LinkNode *cur=pHead->_next;
        while(cur)
        {
            if(cur->_data == data)
                return cur;
            cur=cur->_next;
        }
        return NULL;
    }

    bool Delete(int data)
    {
        LinkNode *pos=FindNode(data);
        if(pos == NULL)
            return false;
        LinkNode *cur=pHead->_next;
        while(cur->_next != pos)
        {
            cur=cur->_next;
        }
        cur->_next=pos->_next;
        delete pos;
        return true;
    }

    void Destroy()
    {
        if(pHead == NULL)
            return;
        LinkNode *cur=pHead->_next;
        while(cur)
        {
            LinkNode *del=cur;
            cur=cur->_next;
            delete del;
            del=NULL;
        }
        delete pHead;  //删除头结点
    }
    LinkNode *pHead;
};

class TestLink:public testing::Test
{
public:
    virtual void SetUp()
    {
        cout<<"SetUp"<<endl;
        for(int i=1;i<=5;i++){
            link.PushBack(i);
        }
    }
    virtual void TearDown()
    {
        cout<<"TearDown"<<endl;
        link.Destroy();
    }
    Link link;
};

TEST_F(TestLink,PushBack)
{
    ASSERT_FALSE(link.pHead == NULL);
    link.PushBack(9);
    LinkNode *res=link.FindNode(9);
    ASSERT_FALSE(res == NULL);
}

TEST_F(TestLink,PopBack)
{
    for(int i=1;i<=5;i++){
        link.PopBack();
    }
}

TEST_F(TestLink,FindNode)
{
    ASSERT_TRUE(link.FindNode(3));
    ASSERT_TRUE(link.FindNode(2));
    ASSERT_TRUE(link.FindNode(4));
    ASSERT_TRUE(link.FindNode(5));
    ASSERT_TRUE(link.FindNode(1));
    ASSERT_FALSE(link.FindNode(7));
}

TEST_F(TestLink,Delete)
{
    ASSERT_FALSE(link.pHead == NULL);
    ASSERT_TRUE(link.Delete(3) == true);
    ASSERT_TRUE(link.Delete(9) == false);
}

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

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

跨平台C++单元测试框架——GTest 的相关文章

  • 什么是大端序和小端序,为什么要有字节序

    什么是字节序 字节序 xff0c 又称端序或尾序 xff08 英语中用单词 xff1a Endianness 表示 xff09 xff0c 在计算机领域中 xff0c 指电脑内存中或在数字通信链路中 xff0c 占用多个字节的数据的字节排列
  • opencv4.3.0+Visual Studio 2019环境配置

    1 1 解压opencv并添加环境变量 下载opencv4 3 0 xff0c 进行安装 其实是解压 xff0c 之后配置环境变量 xff0c 我的电脑 gt 属性 gt 高级系统设置 gt 环境变量 xff0c 找到Path变量 xff0
  • 动画图解:十大经典排序算法动画与解析,看我就够了!(配代码完全版)

    排序算法是 数据结构与算法 中最基本的算法之一 排序算法可以分为内部排序和外部排序 内部排序是数据记录在内存中进行排序 而外部排序是因排序的数据很大 xff0c 一次不能容纳全部的排序记录 xff0c 在排序过程中需要访问外存 常见的内部排
  • 什么是 P = NP 问题?

    点击关注上方 五分钟学算法 xff0c 设为 置顶或星标 xff0c 第一时间送达干货 转自后端技术指南针 1 前言 今天和大家一起了解个高能知识点 xff1a P 61 NP问题 看到这里我们可能是一头雾水 xff0c 不由得发问 xff
  • 问题集合 ---- linux 静态库和动态库

    本文转自多网址 xff0c 对作者表示感谢 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
  • 图解:什么是二叉排序树?

    点击关注上方 五分钟学算法 xff0c 设为 置顶或星标 xff0c 第一时间送达干货 转自景禹 景禹的写作风格还是一如既往的细腻 xff1a xff09 xff0c 欢迎关注他 以下为原文 今天我们谈一谈 二叉排序树 xff0c 一种你会
  • B 站疯传,堪称最强,10 大免费的白嫖网站

    点击上方 五分钟学算法 xff0c 选择 星标 公众号 重磅干货 xff0c 第一时间送达 来源 xff1a Python知识圈 如果你喜欢在 B 站学习的话 xff0c 可以经常看到一些介绍网站类的视频 xff0c 这些视频有不俗的播放量
  • 还敢搞黄色?4 个色情网站被一锅端,9 名福利姬被刑拘!

    点击上方 五分钟学算法 xff0c 选择 星标 公众号 重磅干货 xff0c 第一时间送达 来源 xff1a 扩展迷EXTFANS 9月4日 xff0c 据 64 江苏网警 通报 xff1a 今年3月份以来 xff0c 浙江丽水莲都警方根据
  • 为什么有人劝别选计算机专业?

    大家好 xff0c 我是程序员吴师兄 xff0c 一个坚持在 CSDN 日更原创的程序员 今天想和大家聊一聊为什么有人劝别选计算机专业 和大家说一句掏心窝的话 xff1a 直到 2021 年 xff0c 计算机专业依旧是寒门改变命运的一个最
  • 看完谷歌大佬的 LeetCode 刷题笔记,我马上去字节跳动面试!

    如果你刷 LeetCode 觉得吃力 那么一定需要这份谷歌大佬的 LeetCode 刷题笔记 微信搜索 五分钟学算法 xff0c 公众号回复 04 即可获取对应的下载链接 xff0c 以下是详细介绍 在这里推荐一个谷歌大佬的刷题笔记 每一道
  • 剑指 Offer 09. 用两个栈实现队列(视频讲解)

    一 题目描述 用两个栈实现一个队列 队列的声明如下 xff0c 请实现它的两个函数 appendTail 和 deleteHead xff0c 分别完成在队列尾部插入整数和在队列头部删除整数的功能 若队列中没有元素 xff0c delete
  • 刷到 LeetCode 这个评论,被笑到了

    大家好 xff0c 我是吴师兄 今天早上我在 LeetCode 第 141 号问题 环形链表 的评论区中发现了一个称得上是天秀的解法 xff0c 简直太骚气了 xff0c 忍不住分享给大家 首先给没有见过这道题目的小伙伴补充一下前置知识 x
  • Android JNI基础篇(一)

    Android JNI 基础篇 前言 JNI学习其实并不难 xff0c 在这里 xff0c 我将引导大家学习JNI的基础知识 xff0c 认真学完本教程 xff0c 你将更加坚信我说的话 来吧 xff0c 我们一起学习 xff01 JNI
  • ROS学习(三):消息通信过程

    主节点管理节点信息 xff0c 每个节点根据需要与其他节点进行连接和消息通信 在这里 xff0c 我们来看看最重要的主节点 节点 话题 服务和动作信息的过程 一 运行主节点 节点之间的消息通信当中 xff0c 管理连接信息的主节点是为使用R
  • HTTP Digest authentication(摘要认证)和HTTP basic Authorization(普通认证)用户登出注销的方法

    最近项目中需要对普通认证HTTP basic Authorization和摘要认证HTTP Digest authenticatio登录进行注销 搜索到有几篇文章号称ie xff0c Firefox chrome都可以可以注销 xff0c
  • POCO C++库学习和分析 -- 序

    POCO C 43 43 库学习和分析 序 1 POCO库概述 xff1a POCO是一个C 43 43 的开源库集 同一般的C 43 43 库相比 xff0c POCO的特点是提供了整一个应用框架 如果要做C 43 43 程序应用框架的快
  • 【ubuntu18+QT12+OpenCV4环境配置】

    ubuntu18 43 QT12 43 OpenCV4环境配置 前些天编译了最新版本opencv4 xff0c 但是电脑内还有个opencv3 2 xff0c 有时候二者共享链接库文件即libopencv so XX xff0c 之类的路径
  • Ubuntu无法使用浏览器上网

    1 可以更新一下浏览器 xff0c 打开终端 xff0c 输入 xff1a sudo apt get install firefox 如果你用的是其他浏览器可以吧后面的 firefox 改为其他浏览器 xff0c 如谷歌浏览器 xff1a
  • 浅析C++中struct和class的区别

    文章目录 C和C 43 43 中struct的区别C 43 43 中struct和class的区别 C和C 43 43 中struct的区别 struct最早是在C语言中出现的 xff0c 但在C语言中struct只是一种 用户自定义数据类
  • C语言头文件.h互相包含所引发的一系列错误C2143之类的解决方法

    本文可解决的问题 在一个头文件 h中定义一个结构体 在另一个 h文件中使用这个结构体引发错误C2143 语法错误 缺少 在 的前面 编译源文件 等莫名的报错头文件的交叉包含 即头文件a包含了头文件b 头文件b又包含了头文件a多个不同的头文件

随机推荐

  • 使用python进行http请求自动登录处理302跳转的问题

    一 问题背景 最近在做一个自动化业务处理的程序时 xff0c 需要完成对系统的自动登录 经过抓包测试只需要使用简单的post请求后收到的回包中包含cookie信息 xff0c 因此可以据此完成登录 程序设计思路为发送求到登录验证页面 xff
  • C# TCP/UDP网络通讯调试助手(含源码)

    C TCP UDP网络通讯调试助手 1 客户端界面 1 客户端界面 源码下载地址 xff1a https download csdn net download kingleitao 11927885
  • socketcan

    参考 lt lt Linux Can编程详解 gt gt CAN原理介绍 https www cnblogs com spoorer p 6649303 html 一 初始化工作 SocketCAN 中大部分的数据结构和函数在头文件 lin
  • vscode+cmake 实现C++项目的完整编译

    1 项目目录 span class token builtin class name span bin build CMakeLists txt include array 2d h common h swap h lib src arra
  • 航模常用硅胶线、热缩管规格

    一般穿越机中信号线等用26或28awg xff0c 外径1 3 1 5mm xff0c 配套热缩管选用2mm的比较合适 供电电源线一般用10awg或12awg xff0c 外径4 5 5 4mm xff0c 配套热缩管为7mm比较合适 14
  • POCO C++库学习和分析 -- 线程 (一)

    POCO C 43 43 库学习和分析 线程 xff08 一 xff09 线程是程序设计中用的非常多的技术 xff0c 在UI设计 xff0c 网络通讯设计中广泛使用 在POCO库中 xff0c 线程模块可以分成6个部分去理解 锁 xff0
  • 100条经典C语言笔试题目

    100 条经典C语言笔试题目 题目来源 xff1a 1 中兴 华为 慧通 英华达 微软亚洲技术中心等中 外企业面试题目 xff1b 2 C 语言面试宝典 林锐 高质量编程第三版 说明 xff1a 1 部分C 语言面试题中可能会参杂部分和C
  • hadoop2.7完全分布式集群搭建以及任务测试

    要想深入的学习hadoop数据分析技术 xff0c 首要的任务是必须要将hadoop集群环境搭建起来 xff0c 本文主要讲述如何搭建一套hadoop完全分布式集群环境 环境配置 xff1a 2台64位的redhat6 5 43 1台64位
  • /etc/passwd, /etc/shadow

    使用者帐号 xff1a etc passwd etc shadow 由上面的说明您大概已经知道 xff0c 嘿嘿 xff01 帐号管理最重要的两个档案就是 etc passwd 与 etc shadow 了 xff01 这两个档案可以说是
  • 密集负载下的网卡中断负载均衡smp affinity及单队列RPS

    简单的说就是 xff0c 每个硬件设备 xff08 如 xff1a 硬盘 网卡等 xff09 都需要和 CPU 有某种形式的通信以便 CPU 及时知道发生了什么事情 xff0c 这样 CPU 可能就会放下手中的事情去处理应急事件 xff0c
  • 基于stm32f103zet6之最小系统的制作

    因为嵌入式老师一直鼓励我们去学习stm32 xff0c 他说这是一款很不错的片子 xff0c 所以就萌生了学习stm32的念头 xff0c 之前一直在学习基于arm11的OK6410 xff0c 裸机跑到触摸屏就没有再继续了 xff0c 感
  • 基于stm32f103zet6的DS1302学习

    由于硬件出了问题 xff0c 也就是外部低速晶振没用 xff0c 震不起来 xff0c 然后查看了网上的帖子 xff0c STM32的RTC果然口碑不怎么样 xff0c 所以果断换DS1302 xff0c 在移植的过程中还算顺利 xff0c
  • 基于stm32f103zet6之使用FSMC驱动TFT的学习

    在完成IO驱动彩屏的试验后 xff0c 就准备着手使用FSMC来驱动彩屏 xff0c 先了解一下预备知识 一 所谓的FSMC机制 简单介绍FSMC在这篇博文里面很清楚 xff0c 推荐一下 http blog csdn net king b
  • (转)ds18b20时序说明

    ds18b20时序说明 新手在DS18B20读写过程中要犯很多错误 老衲普度众生 xff0c 简要说明它怎么用 1 过程1 2是初始化过程 xff0c 每次读取都要初始化 xff0c 否则18b20处于待机状态 xff0c 无法成功读取 过
  • H桥驱动芯片IR2110功能简介

    1 1 驱动芯片IR2110功能简介 在功率变换装置中 xff0c 根据主电路的结构 xff0c 起功率开关器件一般采用直接驱动和隔离驱动两种方式 美国IR公司生产的IR2110驱动器 xff0c 兼有光耦隔离和电磁隔离的优点 xff0c
  • 关于示波器是否必须要接地线的疑问

    这是一个非常隐蔽的问题 xff0c 稍不注意 xff0c 在接入示波器时 xff0c 就会导致线路板上的某些芯片突然爆炸 xff0c 不仅会对项目产生非常大的影响 xff0c 也足以让我们着实郁闷上几天 所以 xff0c 应该足够引起电路设
  • POCO C++库学习和分析 -- 进程

    POCO C 43 43 库学习和分析 进程 Poco Foundation库中涉及进程的内容主要包括了4个主题 xff0c 分别是进程 Process 进程间同步 xff08 inter process synchronization x
  • Mysql安装后在服务里找不到和服务启动不起来的解决方法

    一 安装完MySQL后找不到服务 在那完MySQL数据库后 xff0c 在计算机管理 61 61 服务和应用程序 61 61 服务中找不到MySQL的服务 解决方法 xff1a 1 以管理员的身份运行cmd或者Windows powersh
  • C++中虚继承

    一 虚继承和虚基类 1 多继承产生的冲突 在C 43 43 中多继承时很容易产生命名冲突 xff0c 即使我们很小心地将所有类中的成员变量和成员函数都命名为不同的名字 xff0c 命名冲突依然有可能发生 xff0c 比如典型的是菱形继承 x
  • 跨平台C++单元测试框架——GTest

    1 简介 GTest是google公司发布的一个跨平台的 Liunx Mac OS X Windows Cygwin Windows CE and Symbian C 43 43 单元测试框架 它提供了丰富的断言 致命和非致命判断 参数化