xxHash - 编译, 库用法

news2024/11/26 17:32:54

文章目录

    • xxHash - 编译, 库用法
    • 概述
    • 笔记
    • xxHash的代码库地址
    • 编译
    • xxHash的用法
    • 自己搭建一个测试工程
    • 测试工程文件目录
    • 程序参数怎么给?
    • -H3
    • -H3 --binary
    • 自己写一个命令行工程, 对一个buffer来做hash
    • 测试工程(vs2019 vc++ console)
    • END

xxHash - 编译, 库用法

概述

给AES设置 key, iv时, 如果长度不够, 需要填充.
刚开始实现填充时, 用的固定内容, 感觉不太好.
看到github上有个xxHash工程, 很多星, 准备用这个工程来生成固定长度的hash来填充key, iv. 这样填充内容的随机性和确定性就好很多.
不管原始key, iv的长度多少, 都先用xxHash处理成符合AES要求的key, iv长度的buf, 再调用AES加解密函数, 这样就不用考虑key, iv的填充问题了.

笔记

xxHash的代码库地址

https://github.com/Cyan4973/xxHash.git

编译

迁出到本地
打开普通的cmd命令行

cd /d D:\3rd_prj\crypt\xxHash\cmake_unofficial
mkdir .\build
cd .\build
cmake -G "Visual Studio 16 2019" -A x64 ..
cmake --build .
cmake --build . --target install

库安装后的路径为 C:\Program Files\xxHash
目录内容如下:

C:\Program Files\xxHash>tree /F
文件夹 PATH 列表
卷序列号为 BA70-59B2
C:.
├─bin
│      xxhash.dll
│      xxhsum.exe
│
├─include
│      xxh3.h
│      xxhash.h
│
├─lib
│  │  xxhash.lib
│  │
│  ├─cmake
│  │  └─xxHash
│  │          xxHashConfig.cmake
│  │          xxHashConfigVersion.cmake
│  │          xxHashTargets-debug.cmake
│  │          xxHashTargets.cmake
│  │
│  └─pkgconfig
│          libxxhash.pc
│
└─share
    └─man
        └─man1
                xxhsum.1

现在就可以拿 /lib/xxhash.lib, /include/*.h, /bin/xxhash.dll包含到自己工程干活了.

xxHash的用法

看 xxhsum.exe的实现.
在编译目录中, 有xxhsum的VS工程实现.
在这里插入图片描述
打开 xxHash.sln
在这里插入图片描述
将xxhsum设置活动工程.
找到程序入口

/*
 * The preferred method of obtaining the real UTF-16 arguments. Always works
 * on MSVC, sometimes works on MinGW-w64 depending on the compiler flags.
 */
#ifdef __cplusplus
extern "C"
#endif
int __cdecl wmain(int argc, wchar_t* utf16_argv[])
{
    return XSUM_wmain(argc, utf16_argv);
}
#else /* !XSUM_WIN32_USE_WMAIN */

下断点, 单步单步xxhsum的实现, 大致看一下.

自己搭建一个测试工程

用安装后的xxHash库和xxhsum工程实现, 自己搭建一个独立测试工程.
整了一个命令行工程(cosole x64 debug), 将库拷贝到自己工程, 设置头文件包含路径和库路径
先加入xxhsum.c, 尝试编译, 确啥补啥.
官方cli工程里面包含xxhash.h时, 都是用…/xxhash.h, 改为xxhash.h
编译通过, 功能正常.

测试工程文件目录

D:\my_dev\my_local_git_prj\study\xxHash\my_xxhsum>tree /F
文件夹 PATH 列表
卷序列号为 36AD-51CE
D:.
│  my_xxhsum.sln
│  my_xxhsum.vcxproj
│  my_xxhsum.vcxproj.filters
│  my_xxhsum.vcxproj.user
│  xsum_arch.h
│  xsum_bench.c
│  xsum_bench.h
│  xsum_config.h
│  xsum_os_specific.c
│  xsum_os_specific.h
│  xsum_output.c
│  xsum_output.h
│  xsum_sanity_check.c
│  xsum_sanity_check.h
│  xxhsum.c
│
└─xxHash_lib
    ├─bin
    │      xxhash.dll
    │      xxhsum.exe
    │
    ├─include
    │      xxh3.h
    │      xxhash.h
    │
    ├─lib
    │  │  xxhash.lib
    │  │
    │  ├─cmake
    │  │  └─xxHash
    │  │          xxHashConfig.cmake
    │  │          xxHashConfigVersion.cmake
    │  │          xxHashTargets-debug.cmake
    │  │          xxHashTargets.cmake
    │  │
    │  └─pkgconfig
    │          libxxhash.pc
    │
    └─share
        └─man
            └─man1
                    xxhsum.1

程序参数怎么给?

static int XSUM_usage(const char* exename)
{
    XSUM_log( WELCOME_MESSAGE(exename) );
    XSUM_log( "Print or verify checksums using fast non-cryptographic algorithm xxHash \n\n" );
    XSUM_log( "Usage: %s [options] [files] \n\n", exename);
    XSUM_log( "When no filename provided or when '-' is provided, uses stdin as input. \n");
    XSUM_log( "\nOptions: \n");
    XSUM_log( "  -H#          select an xxhash algorithm (default: %i) \n", (int)g_defaultAlgo);
    XSUM_log( "               0: XXH32 \n");
    XSUM_log( "               1: XXH64 \n");
    XSUM_log( "               2: XXH128 (also called XXH3_128bits) \n");
    XSUM_log( "               3: XXH3 (also called XXH3_64bits) \n");
    XSUM_log( "  -c, --check  read xxHash checksum from [files] and check them \n");
    XSUM_log( "  -h, --help   display a long help page about advanced options \n");
    return 0;
}


static int XSUM_usage_advanced(const char* exename)
{
    XSUM_usage(exename);
    XSUM_log( "\nAdvanced :\n");
    XSUM_log( "  -V, --version        Display version information \n");
    XSUM_log( "      --tag            Produce BSD-style checksum lines \n");
    XSUM_log( "      --little-endian  Checksum values use little endian convention (default: big endian) \n");
    XSUM_log( "      --binary         Read in binary mode \n");
    XSUM_log( "  -b                   Run benchmark \n");
    XSUM_log( "  -b#                  Bench only algorithm variant # \n");
    XSUM_log( "  -i#                  Number of times to run the benchmark (default: %i) \n", NBLOOPS_DEFAULT);
    XSUM_log( "  -q, --quiet          Don't display version header in benchmark mode \n");
    XSUM_log( "\n");
    XSUM_log( "The following five options are useful only when verifying checksums (-c): \n");
    XSUM_log( "  -q, --quiet          Don't print OK for each successfully verified file \n");
    XSUM_log( "      --status         Don't output anything, status code shows success \n");
    XSUM_log( "      --strict         Exit non-zero for improperly formatted checksum lines \n");
    XSUM_log( "      --warn           Warn about improperly formatted checksum lines \n");
    XSUM_log( "      --ignore-missing Don't fail or report status for missing files \n");
    return 0;
}

给出不同命令行参数, 试试效果.

-H3

-H3 D:\my_tmp\my_xxhsum.pdb
结果如下:
\XXH3_82fc89454f8a2238  D:\\my_tmp\\my_xxhsum.pdb

-H3 --binary

-H3 --binary D:\my_tmp\my_xxhsum.pdb
结果如下:
\XXH3_82fc89454f8a2238  D:\\my_tmp\\my_xxhsum.pdb

看来都是2进制读取文件内容并计算hash.
单步时, 发现 --binary 是无效的, 被忽略掉了

 if (!strcmp(argument, "--binary")) { continue; } /* Just ignore it. See https://github.com/Cyan4973/xxHash/issues/812 */

算hash的cli函数

return XSUM_hashFiles(argv+filenamesStart, argc-filenamesStart, algo, displayEndianess, convention);

看到使用xxHash库的最终用法了

/*
 * XSUM_hashStream:
 * Reads data from `inFile`, generating an incremental hash of type hashType,
 * using `buffer` of size `blockSize` for temporary storage.
 */
static Multihash
XSUM_hashStream(FILE* inFile,
                AlgoSelected hashType,
                void* buffer, size_t blockSize)
{
    XXH32_state_t state32;
    XXH64_state_t state64;
    XXH3_state_t  state3;

    /* Init */
    (void)XXH32_reset(&state32, XXHSUM32_DEFAULT_SEED);
    (void)XXH64_reset(&state64, XXHSUM64_DEFAULT_SEED);
    (void)XXH3_128bits_reset(&state3);

    /* Load file & update hash */
    {   size_t readSize;
        while ((readSize = fread(buffer, 1, blockSize, inFile)) > 0) {
            switch(hashType)
            {
            case algo_xxh32:
                (void)XXH32_update(&state32, buffer, readSize);
                break;
            case algo_xxh64:
                (void)XXH64_update(&state64, buffer, readSize);
                break;
            case algo_xxh128:
                (void)XXH3_128bits_update(&state3, buffer, readSize);
                break;
            case algo_xxh3:
                (void)XXH3_64bits_update(&state3, buffer, readSize);
                break;
            default:
                assert(0);
            }
        }
        if (ferror(inFile)) {
            XSUM_log("Error: a failure occurred reading the input file.\n");
            exit(1);
    }   }

    {   Multihash finalHash = {0};
        switch(hashType)
        {
        case algo_xxh32:
            finalHash.hash32 = XXH32_digest(&state32);
            break;
        case algo_xxh64:
            finalHash.hash64 = XXH64_digest(&state64);
            break;
        case algo_xxh128:
            finalHash.hash128 = XXH3_128bits_digest(&state3);
            break;
        case algo_xxh3:
            finalHash.hash64 = XXH3_64bits_digest(&state3);
            break;
        default:
            assert(0);
        }
        return finalHash;
    }
}

保存Hash值

    /* display Hash value in selected format */
    switch(hashType)
    {
    case algo_xxh32:
        {   XXH32_canonical_t hcbe32;
            (void)XXH32_canonicalFromHash(&hcbe32, hashValue.hash32);
            f_displayLine(fileName, &hcbe32, hashType);
            break;
        }
    case algo_xxh64:
        {   XXH64_canonical_t hcbe64;
            (void)XXH64_canonicalFromHash(&hcbe64, hashValue.hash64);
            f_displayLine(fileName, &hcbe64, hashType);
            break;
        }
    case algo_xxh128:
        {   XXH128_canonical_t hcbe128;
            (void)XXH128_canonicalFromHash(&hcbe128, hashValue.hash128);
            f_displayLine(fileName, &hcbe128, hashType);
            break;
        }
    case algo_xxh3:
        {   XXH64_canonical_t hcbe64;
            (void)XXH64_canonicalFromHash(&hcbe64, hashValue.hash64);
            f_displayLine(fileName, &hcbe64, hashType);
            break;
        }
    default:
        assert(0);  /* not possible */
    }

显示hash值

static void XSUM_printLine_GNU(const char* filename,
                               const void* canonicalHash, const AlgoSelected hashType)
{
    XSUM_printLine_GNU_internal(filename, canonicalHash, hashType, XSUM_display_BigEndian);
}
static void XSUM_printLine_GNU_internal(const char* filename,
                               const void* canonicalHash, const AlgoSelected hashType,
                               XSUM_displayHash_f f_displayHash)
{
    assert(0 <= hashType && (size_t)hashType <= XSUM_TABLE_ELT_SIZE(XSUM_algoName));
    {   const size_t hashLength = XSUM_algoLength[hashType];
        const int needsEscape = XSUM_filenameNeedsEscape(filename);
        if (needsEscape) {
            XSUM_output("%c", '\\');
        }
        XSUM_displayPrefix(hashType);
        f_displayHash(canonicalHash, hashLength);
        XSUM_output("  ");
        XSUM_printFilename(filename, needsEscape);
        XSUM_output("\n");
}   }
static void XSUM_display_BigEndian(const void* ptr, size_t length)
{
    const XSUM_U8* const p = (const XSUM_U8*)ptr;
    size_t idx;
    for (idx=0; idx<length; idx++)
        XSUM_output("%02x", p[idx]);
}

懂了

自己写一个命令行工程, 对一个buffer来做hash

官方工程是针对文件做hash, 我要的是对buffer做hash.
通过单步, 这个库的用法已经清楚了. 自己来整一遍, 只不过, 我要的是对buffer做hash.
整完了, 好使
在这里插入图片描述
在xxHash基础上, 封装了3个应用接口:

bool buffer_hash_XXH3_32bits(uint8_t* pBuf, size_t nLenBuf, uint32_t& hash_4Byte);
bool buffer_hash_XXH3_64bits(uint8_t* pBuf, size_t nLenBuf, uint64_t& hash_8Byte);
bool buffer_hash_XXH3_128bits(uint8_t* pBuf, size_t nLenBuf, uint64_t& hash_H8Byte, uint64_t& hash_K8Byte);

用这3个应用接口来做流的hash, 就方便多了.

测试工程(vs2019 vc++ console)

// @file test_xxHash_form_buffer.cpp

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#define XXH_STATIC_LINKING_ONLY   // 在包含xxhash.h之前, 必须定义这个宏
#include "xxhash.h"

#pragma comment(lib, "xxhash.lib")

bool buffer_hash_XXH3_32bits(uint8_t* pBuf, size_t nLenBuf, uint32_t& hash_4Byte);
bool buffer_hash_XXH3_64bits(uint8_t* pBuf, size_t nLenBuf, uint64_t& hash_8Byte);
bool buffer_hash_XXH3_128bits(uint8_t* pBuf, size_t nLenBuf, uint64_t& hash_H8Byte, uint64_t& hash_K8Byte);

void test_hash_128();
void test_hash_64();
void test_hash_32();

int main()
{
	printf("test xxHash from buffer\n");

	test_hash_128();
	test_hash_64();
	test_hash_32();

	return 0;
}

void test_hash_128()
{
	uint64_t hash_H8Byte = 0;
	uint64_t hash_L8Byte = 0;

	char szBuf[0x100];
	memset(szBuf, 0, sizeof(szBuf));
	strcpy(szBuf, "hello xxHash 128"); // add vs option _CRT_SECURE_NO_WARNINGS
	size_t nLenBuf = strlen(szBuf);

	if (buffer_hash_XXH3_128bits((uint8_t*)szBuf, nLenBuf, hash_H8Byte, hash_L8Byte))
	{
		printf("hash value =  %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X",
			(uint8_t)(((hash_H8Byte >> (8 * 7)) & 0xff)),
			(uint8_t)(((hash_H8Byte >> (8 * 6)) & 0xff)),
			(uint8_t)(((hash_H8Byte >> (8 * 5)) & 0xff)),
			(uint8_t)(((hash_H8Byte >> (8 * 4)) & 0xff)),
			(uint8_t)(((hash_H8Byte >> (8 * 3)) & 0xff)),
			(uint8_t)(((hash_H8Byte >> (8 * 2)) & 0xff)),
			(uint8_t)(((hash_H8Byte >> (8 * 1)) & 0xff)),
			(uint8_t)(((hash_H8Byte >> (8 * 0)) & 0xff)),

			(uint8_t)(((hash_L8Byte >> (8 * 7)) & 0xff)),
			(uint8_t)(((hash_L8Byte >> (8 * 6)) & 0xff)),
			(uint8_t)(((hash_L8Byte >> (8 * 5)) & 0xff)),
			(uint8_t)(((hash_L8Byte >> (8 * 4)) & 0xff)),
			(uint8_t)(((hash_L8Byte >> (8 * 3)) & 0xff)),
			(uint8_t)(((hash_L8Byte >> (8 * 2)) & 0xff)),
			(uint8_t)(((hash_L8Byte >> (8 * 1)) & 0xff)),
			(uint8_t)(((hash_L8Byte >> (8 * 0)) & 0xff))
		);

		printf("\n");
	}
	else {
		printf("error\n");
	}
}

void test_hash_64()
{
	uint64_t hash_8Byte = 0;

	char szBuf[0x100];
	memset(szBuf, 0, sizeof(szBuf));
	strcpy(szBuf, "hello xxHash 64"); // add vs option _CRT_SECURE_NO_WARNINGS
	size_t nLenBuf = strlen(szBuf);

	if (buffer_hash_XXH3_64bits((uint8_t*)szBuf, nLenBuf, hash_8Byte))
	{
		printf("hash value =  %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X",
			(uint8_t)(((hash_8Byte >> (8 * 7)) & 0xff)),
			(uint8_t)(((hash_8Byte >> (8 * 6)) & 0xff)),
			(uint8_t)(((hash_8Byte >> (8 * 5)) & 0xff)),
			(uint8_t)(((hash_8Byte >> (8 * 4)) & 0xff)),
			(uint8_t)(((hash_8Byte >> (8 * 3)) & 0xff)),
			(uint8_t)(((hash_8Byte >> (8 * 2)) & 0xff)),
			(uint8_t)(((hash_8Byte >> (8 * 1)) & 0xff)),
			(uint8_t)(((hash_8Byte >> (8 * 0)) & 0xff))
		);

		printf("\n");
	}
	else {
		printf("error\n");
	}
}

void test_hash_32()
{
	uint32_t hash_4Byte = 0;

	char szBuf[0x100];
	memset(szBuf, 0, sizeof(szBuf));
	strcpy(szBuf, "hello xxHash 32"); // add vs option _CRT_SECURE_NO_WARNINGS
	size_t nLenBuf = strlen(szBuf);

	if (buffer_hash_XXH3_32bits((uint8_t*)szBuf, nLenBuf, hash_4Byte))
	{
		printf("hash value =  %2.2X %2.2X %2.2X %2.2X",
			(uint8_t)(((hash_4Byte >> (8 * 3)) & 0xff)),
			(uint8_t)(((hash_4Byte >> (8 * 2)) & 0xff)),
			(uint8_t)(((hash_4Byte >> (8 * 1)) & 0xff)),
			(uint8_t)(((hash_4Byte >> (8 * 0)) & 0xff))
		);

		printf("\n");
	}
	else {
		printf("error\n");
	}
}

bool buffer_hash_XXH3_128bits(uint8_t* pBuf, size_t nLenBuf, uint64_t& hash_H8Byte, uint64_t& hash_K8Byte)
{
	bool b_rc = false;
	XXH3_state_t  state3;
	XXH128_hash_t finalHash;

	do {
		// size_t 没有负数
		if ((NULL == pBuf) || (nLenBuf <= 0))
		{
			break;
		}

		(void)XXH3_128bits_reset(&state3);
		(void)XXH3_128bits_update(&state3, pBuf, nLenBuf);
		finalHash = XXH3_128bits_digest(&state3);
		
		hash_H8Byte = finalHash.high64;
		hash_K8Byte = finalHash.low64;

		b_rc = true;
	} while (false);

	return b_rc;
}

bool buffer_hash_XXH3_64bits(uint8_t* pBuf, size_t nLenBuf, uint64_t& hash_8Byte)
{
	bool b_rc = false;
	XXH3_state_t  state3;
	XXH64_hash_t finalHash;

	do {
		// size_t 没有负数
		if ((NULL == pBuf) || (nLenBuf <= 0))
		{
			break;
		}

		(void)XXH3_128bits_reset(&state3);
		(void)XXH3_64bits_update(&state3, pBuf, nLenBuf);
		finalHash = XXH3_64bits_digest(&state3);

		hash_8Byte = finalHash;

		b_rc = true;
	} while (false);

	return b_rc;
}

bool buffer_hash_XXH3_32bits(uint8_t* pBuf, size_t nLenBuf, uint32_t& hash_4Byte)
{
	bool b_rc = false;
	XXH32_state_t state32;
	XXH32_hash_t finalHash;

	do {
		// size_t 没有负数
		if ((NULL == pBuf) || (nLenBuf <= 0))
		{
			break;
		}

		// #define XXHSUM32_DEFAULT_SEED 0                   /* Default seed for algo_xxh32 */
		(void)XXH32_reset(&state32, 0 /*XXHSUM32_DEFAULT_SEED*/);
		(void)XXH32_update(&state32, pBuf, nLenBuf);
		finalHash = XXH32_digest(&state32);

		hash_4Byte = finalHash;

		b_rc = true;
	} while (false);

	return b_rc;
}

END

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

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

相关文章

IDC发布23Q3中国存储市场报告:浪潮信息逆势增长位居前二!

近日&#xff0c;权威调研机构IDC公布《中国企业级外部存储市场跟踪报告&#xff0c;2023Q3》。报告显示&#xff0c;2023年第三季度&#xff0c;中国企业级存储(ESS)市场规模达17.1亿美元&#xff0c;同比下降2.8%。其中&#xff0c;浪潮信息存销售额同比增长10.9%&#xff0c…

WPF+Halcon 培训项目实战 完结(13):HS 鼠标绘制图形

文章目录 前言相关链接项目专栏运行环境匹配图片矩形鼠标绘制Halcon添加右键事件Task封装运行结果个人引用问题原因推测 圆形鼠标绘制代码运行结果 课程完结&#xff1a; 前言 为了更好地去学习WPFHalcon&#xff0c;我决定去报个班学一下。原因无非是想换个工作。相关的教学视…

2023全新返佣商城分销商城理财商城系统源码 全开源PHP+VUE源码

2023全新返佣商城分销商城理财商城系统源码 全开源PHPVUE源码 源码下载&#xff1a;https://download.csdn.net/download/m0_66047725/88657863

【C语言】Windows上用GTK写GUI程序

要使用GTK开发一个Windows图形用户界面程序&#xff0c;需要首先设置GTK开发环境。这通常包括安装GTK库和它的依赖&#xff0c;以及配置编译器和工具链。可以选择使用纯C语言和GTK库或者使用支持GTK绑定的其他语言&#xff0c;如Python、C或Rust。 1. 安装GTK开发库 在Window…

Access数据库C#读写验证

1、数据库简介 Access数据库是一个相当古老的文件型数据库&#xff0c;主打一个简单方便&#xff0c;没有复杂的安装过程&#xff0c;没有庞大的后端管理&#xff0c;整个数据库就是一个文件。可以像普通文件一样复制和修改&#xff0c;可以同时读写。 在小型系统中&#xff0c…

Rasa初始化聊天机器人的配置

本文详细介绍了使用 rasa init 初始化聊天机器人项目的配置&#xff0c;包括 nlu.yml、rules.yml、stories.yml、test_stories.yml、config.yml、credentials.yml、domain.yml、endpoints.yml 等文件。如下所示&#xff1a; │ config.yml │ credentials.yml │ domain.ym…

simulink代码生成(六)——多级中断的配置

假如系统中存在多个中断&#xff0c;需要合理的配置中断的优先级与中断向量表&#xff1b;在代码生成中&#xff0c;要与中断向量表对应&#xff1b;中断相关的知识参照博客&#xff1a; DSP28335学习——中断向量表的初始化_中断向量表什么时候初始化-CSDN博客 F28335中断系…

算法——字符串

这里结合的是之前一些算法&#xff0c;比如模拟、KMP等&#xff0c;题型比较丰富 最长公共前缀 最长公共前缀 题目解析 查找字符串数组中的最长公共前缀。如果不存在公共前缀&#xff0c;返回空字符串 “” 算法原理 解法一&#xff1a;两两比较&#xff1a;定义一个指…

基于图论的图像分割 python + PyQt5

数据结构大作业&#xff0c;基于图论中的最小生成树的图像分割。一个很古老的算法&#xff0c;精度远远不如深度学习算法&#xff0c;但是对于代码能力是一个很好的锻炼。 课设要求&#xff1a; &#xff08; 1 &#xff09;输入&#xff1a;图像&#xff08;例如教室场景图&a…

poi操作Excel给列设置下拉菜单(数据验证)

效果图&#xff1a; pom.xml文件增加依赖&#xff1a; <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.0.1</version></dependency> 12345Workbook实现类有三个&#xff1a;HSSFWork…

Python算法例33 删除数字

1. 问题描述 给出一个字符串A&#xff0c;表示一个n位的正整数&#xff0c;删除其中k位数字&#xff0c;使得剩余的数字仍然按照原来的顺序排列产生一个新的正整数&#xff0c;本例将找到删除k个数字之后的最小正整数&#xff0c;其中n≤240&#xff0c;k≤n。 2. 问题示例 …

计算机专业个人简历范文(8篇)

HR浏览一份简历也就25秒左右&#xff0c;如果你连「好简历」都没有&#xff0c;怎么能找到好工作呢&#xff1f; 如果你不懂得如何在简历上展示自己&#xff0c;或者觉得怎么改简历都不出彩&#xff0c;那请你一定仔细读完。 互联网运营个人简历范文> 男 22 本科 AI简历…

测试开发工具推荐(含自动化、性能、稳定性、抓包)

今天将给大家推荐14款日常工作中经常用到的测试开发工具神器&#xff0c;涵盖了自动化测试、APP性能测试、稳定性测试、抓包工具等。 一、UI自动化测试工具 1. uiautomator2 Github地址 https://github.com/openatx/uiautomator2 介绍&#xff1a; openatx开源的ui自动化…

k8s陈述式资源管理(命令行)

1、资源管理 &#xff08;1&#xff09;陈述式资源管理&#xff08;常用——查、增&#xff09; 使用kubectl工具进行命令行管理 ①特点&#xff1a;对资源的增删查比较方便&#xff0c;对改不友好 ②优点&#xff1a;90%以上的场景都可以满足 ③缺点&#xff1a;命令冗长…

小白入门java基础-注解

一&#xff1a;介绍 Java 是由 Sun Microsystems 公司于 1995 年 5 月推出的高级程序设计语言。 Java 可运行于多个平台&#xff0c;如 Windows, Mac OS 及其他多种 UNIX 版本的系统。Java语言编写的程序&#xff0c;在一次编译后&#xff0c;可以在多个系统平台上运行。 主…

Vue 插槽:让你的组件更具扩展性(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

听GPT 讲Rust源代码--library/proc_macro

File: rust/library/proc_macro/src/bridge/rpc.rs 在Rust源代码中&#xff0c;rust/library/proc_macro/src/bridge/rpc.rs文件的作用是实现了Rust编程语言的编译过程中的远程过程调用&#xff08;RPC&#xff09;机制。 这个文件定义了与编译器的交互过程中使用的各种数据结构…

CGAL的空间排序

1、介绍 许多在CGAL中实现的几何算法都是增量的&#xff0c;因此它们的速度取决于插入顺序。此软件包提供了排序算法&#xff0c;可以大大提高此类算法的运行时间。 其基本原理是沿着空间填充曲线对对象进行排序&#xff0c;这样在插入顺序上&#xff0c;几何上接近的两个对象将…

Seata服务搭建与模式实现

日升时奋斗&#xff0c;日落时自省 目录 1、简述 2、Seata优越性 3、Seata组成 4、Seata模式 4.1、XA 模式 4.2、AT 模式(默认模式) 4.3、TCC 模式 4.4、SAGA 模式 4.5、XA协议 5、Seata服务部署 5.1、文件数据源部署 5.1.1、下载并安装Seata 5.1.2、启动Seata服…

oracle 9i10g编程艺术-读书笔记2

配置Statspack 安装Statspack需要用internal身份登陆&#xff0c;或者拥有SYSDBA(connect / as sysdba)权限的用户登陆。需要在本地安装或者通过telnet登陆到服务器。 select instance_name,host_name,version,startup_time from v$instance;检查数据文件路径及磁盘空间&…