【进阶C语言】字符串与内存库函数认识与模拟实现

本章内容大致目录:

1.strlen函数

2.strcpy函数

3.strcmp函数

4.strcat函数

5.strstr函数

6.strtok函数

7.strerror与perror函数

8.字符操作函数

9.内存操作函数

10.总结

以上函数均属于库函数,有的函数则会介绍如何模拟实现。


一、strlen函数

前言:求字符串长度函数

1.函数原型

size_t为无符号整形,接受他的返回值的变量类型也应该为size_t

函数参数就是字符指针类型。const为了修饰*str,防止原字符串的数据被修改。

需要包含的头文件为:#include<string.h>

2.库函数举例

代码展示:

#include<stdio.h>
#include<string.h>
int main()
{char arr[] = "love you every day";size_t ret = strlen(arr);printf("%d\n",ret);
}

运行结果:

可以直接使用该函数去计算字符串的长度,该长度不包括\0。

3.模拟实现

我们也可以自己写代码来模拟该函数的功能,下面介绍三种方法。

(1)计数器

代码展示:

#include<stdio.h>
#include<string.h>
size_t my_strlen(const char* str)
{int count = 0;while (*str){count++;str++;}return count;
}
int main()
{char arr1[10] = "love you";size_t ret = my_strlen(arr1);printf("%zd\n", ret);printf("%d\n",ret);return 0;
}

运行结果:

思路:通过一个count变量,用来记录字符串的个数,遇到\0才停下。

知识点:因为ret的类型为size_t类型,所以打印该类型的格式需要用%zd。

(2)函数递归

代码:

#include<stdio.h>
#include<string.h>
int my_strlen(const char* str)
{if (*str == '\0')return 0;elsereturn 1 + my_strlen(str + 1);
}
int main()
{char arr1[10] = "love you";size_t ret = my_strlen(arr1);printf("%zd\n", ret);return 0;
}

运行结果:

该方法利用了函数递归的思想,只要没遇到\0就一直递归下去;当遇到\0后便开始回溯。

(3)指针-指针

代码:

#include<stdio.h>
#include<string.h>
int my_strlen(const char* s)
{char* p = s;while (*p != '\0'){p++;}return p - s;
}
int main()
{char arr1[10] = "love you";size_t ret = my_strlen(arr1);printf("%zd\n", ret);return 0;
}

运行结果:

通过两个指针,一个指向字符串末端,一个指向首元素,他们之差就是字符串的个数,也就是字符串的长度。

二、strcpy与strncpy函数

前言:字符串拷贝函数

1.函数原型

参数意义:把第二个参数的(所有)数据拷贝到第一个参数里面。

const依旧是保护第二个参数所指向的字符串数据不被修改。

2.库函数使用

代码:

#include<stdio.h>
#include<string.h>
int main()
{char arr1[20] = { 0 };char arr2[12] = "like apple";char* ret=strcpy(arr1,arr2);printf("%s\n",ret);printf("%s\n", arr1);
}

运行结果:

使用细节把控: 

1.目标空间(第一个参数所指向的数组)的空间要足够大,否则拷贝后容易溢出。

2.原字符串必须包含\0,用来作为字符串结束的标志。

3.若是需要用变量来接受strcpy函数的返回值,该变量的类型为字符指针类型(char*)。

其他细节:

经过这样的操作之和,arr2中的值是不会变的;但是arr1中的值变成了:like you\0##,因为中间有\0,所以打印的时候只会显示它前面的内容。

3.模拟实现

代码展示:

#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strcpy(char* dest, const char* src)//注意这里的格式
{char* ret = dest;//记录目标空间的起始地址,等下用来返回assert(dest != NULL);assert(src != NULL);//这两步断言操作,避免传入空指针while ((*dest++ = *src++))//先解引用操作再++,一个个数据拷贝{;}return ret;
}
int main()
{char arr1[20] = { 0 };char arr2[10] = "love you";my_strcpy(arr1,arr2);//正常传参printf("%s\n", arr1);return 0;
}

1.从第一个数据往后拷贝,直到遇见\0。

2.assert为断言操作,若指针为空,会直接结束程序的运行;使用时需要包含#include<assert.h>的头文件。

4.strncpy函数

(1)函数原型

1.该函数就是在strcpy函数的基础上多了一个参数。

2.多一个参数的作用是可以控制拷贝数据的个数。

 (2)使用

代码:

#include<stdio.h>
#include<string.h>
int main()
{char arr1[20] = { 0 };char arr2[10] = "love you";strncpy(arr1,arr2,4);printf("%s\n", arr1);return 0;
}

 运行结果:

1.参数num的意义是指定字符的个数。

2.该函数暂时不实现模拟。(*)

三、strcmp与strncmp函数

前言:字符串比较函数

1.函数原型

(1)返回值解析

1.返回值为整形类型。会返回>0、<0或=0的值。

2.第一个字符>第二个字符(ASLII值),则会返回>0的数字。

3.第一个字符<第二个字符,则会返回<0的数字。

4.第一个字符=第二个字符,则会返回0。

(2)如何比较

1.第一个字符串的第一个字符与第一个字符串的第二个字符比较。

2.若第一个比较不出来,则往后,直到比较完。

3.若是a与b前面的字符都相同,此时a结束了,但是b后面还有字符,则b字符串大。

2.strcmp函数使用

代码:

#include<stdio.h>
#include<string.h>
int main()
{char arr1[] = "abcdef";char arr2[] = "abcdddd";int ret = strcmp(arr1,arr2);printf("%d\n",ret);
}

运行结果:

1. 很明显,第四个字符e>d,所以第一个字符大,返回一个>0的数字。该环境为vs2022,默认返回1或-1

2.使用该库函数也需要包含#include<stdio.h>的头文件

3.strcmp模拟实现

代码:

#include<stdio.h>
#include<assert.h>
#include<string.h>
int my_strcmp(const char* str1,const char* str2)
{assert(str1&&str2);while (*str1==*str2){if (*str1 == '\0')return 0;//必须在外头++,否则无法判断长短str1++;str2++;}return *str1 - *str2;}
int main()
{char arr1[20] = "love myself";char arr2[10] = "love you";int ret = my_strcmp(arr1,arr2);if (ret > 0)printf("arr1>arr2\n");else if (ret == 0)printf("arr1==arr2\n");elseprintf("arr1<arr2\n");return 0;
}

运行结果:

因为我们的目的只是比较两个字符串,所以加const修饰,防止修改其内容。

4.strncmp函数

(1)函数原型

1.与strcmp函数相比,strncmp函数同样多了一个参数。

2.该参数的单位是字符个数,可以指定比较字符的数目。

(2)例题代码

#include<stdio.h>
#include<string.h>
int main()
{char arr1[] = "abcdefg";char arr2[] = "abcdfff";int ret = strncmp(arr1,arr2,5);int tmp = strncmp(arr2,arr1,5);printf("%d\n%d",ret,tmp);return 0;
}

运行结果:

可以指定前面的多少位字符比较

模拟实现暂时不实现(*)

四、strcat函数

前言:字符追加函数

1.函数原型

函数目的:把第二个数组(一参数)的数据加在第一个数组(二参数)的末尾,实现链接

2.strcat函数的使用

代码:

#include<stdio.h>
#include<string.h>
int main()
{char arr1[20] = "love ";char arr2[15] = "Only to you";strcat(arr1, arr2);printf("%s\n", arr1);return 0;
}

 运行结果:

1.原本arr1中的内容为love,当把arr2中的内容追加到arr1末尾后,arr1中的内容变成了love Only to you;这就是该函数的用法

2.使用同样需要包含头文件#include<stdio.h>

3.第一个数组的空间足够大,第二个数组有\0

3.strcat模拟实现

代码:

#include<stdio.h>
#include<assert.h>
char* my_strcat(char* str1,const char* str2)
{assert(str1&&str2);//1.找arr1末尾while (*str1 != '\0'){str1++;}//2.追加数据while (*str2!='\0'){//*str1的值需要修改,*str2则不需要*str1 =*str2;str1++;str2++;}return NULL;
}
int main()
{char arr1[20] = "love ";char arr2[15] = "Only to you";my_strcat(arr1, arr2);printf("%s\n",arr1);return 0;
}

1.该函数的模拟分为两步:找到第一个数组的末端和把第二个数组的内容追加在第一个数组的末端

2.要求第一个数组的空间足够大,第二个字符串要有\0

4.strncat函数

(1)函数原型

比strcat函数多了一个参数,用来指定追加的数据元素个数

(2)函数使用

代码:

#include<stdio.h>
#include<string.h>
int main()
{char arr1[20] = "abcd";printf("%s\n",arr1);char arr2[10] = "efghijk";strncat(arr1,arr2,2);printf("%s",arr1);
}

运行结果:

五、strstr函数

前言:找字符串的子集

1.函数原型

1.函数目的:在第一个字符串里面找第二个字符串,第二个字符串相当于第一个字符串的子集。

2.如果找到了,那就返回:第一个字符串里面子集的首地址

3.需要包含#include<stdio.h>文件

2.strstr函数使用

代码:

#include<stdio.h>
#include<string.h>
int main()
{char arr1[] = "abcdefgh";char arr2[] = "cde";char* ret=strstr(arr1, arr2);if (ret != NULL){printf("%s\n", ret);}elseprintf("找不到\n");
}

运行结果:

1.接收返回值后,需要判断是否为空

2.需要包含头文件#include<stdio.h>

3.模拟实现strstr

代码:

#include<stdio.h>
#include<string.h>
#include<assert.h>
const char* my_strstr(const char* str1,const char* str2)
{assert(str1&&str2);//检测指针是否为空const char* s1;//遍历str1const char* s2;//遍历str2const char* cp;//定义返回指针cp = str1;while (*cp){s1 = cp;//不相等一次,cp++s2 = str2;//只要不相等,s2从头开始while (*s1==*s2&&*s1&&*s2){s1++;s2++;}if (*s2 == '\0')return cp;cp++;}return NULL;
}
int main()
{char arr1[] = "abbbcefg";char arr2[] = "bbc";char* ret = my_strstr(arr1,arr2);if (ret == NULL)printf("找不到\n");elseprintf("%s\n",ret);return 0;
}

1.需要定义五个指针

2.两个指针分别记录两个字符串的首位置

3.第三个指针用来找到子集后,记录子集的首地址,作为返回值返回

4.第四、第五个指针用来遍历两个字符串的内容,并且比对是否相同

六、strtok函数

前言:字符串分割函数

1.函数原型

1.返回切割好的第一段字符串的首地址

2.第一个参数为要切割的对象,第二个为切割的标志(存放在字符数组中)

3.包含头文件#include<stdio.h>

4.直接使用会改变原字符串中的内容,一般拷贝一份使用

2.函数的使用

(1)使用效果展示

代码:

#include<stdio.h>
#include<string.h>
int main()
{char arr1[20] = "loveyou@qq.com";char arr2[20] = { 0 };strcpy(arr2,arr1);char* s = "@.";char* p=NULL;for (p = strtok(arr2, s); p != NULL; p = strtok(NULL, s)){printf("%s\n", p);}return 0;
}

运行结果:

为什么会分成三段打印呢?与返回的首地址有关,接下来我们了解他的返回值类型

(2)函数返回值理解

 

1. 函数的第一个参数(需要被分割的字符串)不为NULL(比如我们把loveyou@qq.com的首地址传给该函数),strtok函数将找到第一个标记,并且把它后面的记号(@)改成\0,并且会记录记号(@)后面的第一个地址(qq.com的首地址),并且返回。

2.函数的第一个参数为NIULL(我们给该函数的第一个参数传送空指针NULL),函数将在同一个字符串中被保存的位置(qq.com的首地址)开始,查找下一个标记,并把后面的记号改成\0,以此类推,直到后面不再有标记,返回空指针。

 (3)使用教程

因为调用一次,只能得到一个标记的地址,也就是只能得到一小串字符,想要完整得到原字符的所有标记,就需要用到循环

七、strerror与perror函数

前言:都为字符串报错函数

1.strerror函数原型

1.函数作用:将错误码翻译成错误信息,返回错误信息的字符串的起始地址。

2.函数的参数:错误码(如网站的404)

3.关联知识点:C语言在使用库函数时,如果发生错误,就会将错误码放在errno的变量中(errno是一个全局的变量,可以直接使用)

2.使用过程和解析

(1)第一种情况

代码:

#include<stdio.h>
#include<string.h>
int main()
{int i = 0;for (i = 0; i < 10; i++){printf("%d:%s\n",i,strerror(i));}printf("%s\n",strerror(404));return 0;
}

运行结果:

把0-9的数字作为参数传入strerror函数中,该函数就会把这些数字代表的错误类型翻译成一串串字符串,并把这些字符串的首地址返回来。

 (2)打开某文件失败的例子

代码:

#include<stdio.h>
#include<string.h>
int main()
{FILE* p = fopen("add.txt", "r");if (p == NULL){printf("打开文件失败,原因是:%s\n", strerror(errno));return 1;}elseprintf("打开文件成功\n");return 0;
}

结果:

strerror函数的作用:将错误的信息翻译成字符串的信息,返回字符串首地址

3.perror函数

(1)函数原型

(2)函数的作用

1.直接将错误码的原因打印出来。

2.strerror的作用是将“错误的原因”的首地址返回了,并没有打印。

(3)函数举例

#include<stdio.h>
#include<string.h>
int main()
{FILE* p = fopen("add.txt", "r");if (p == NULL){printf("打开文件失败,原因是:%s\n", strerror(errno));return 1;}elseprintf("打开文件成功\n");return 0;
}

结果:

1.打印规则:自定义信息:错误原因

2.相当于断言的作用,只需要把该函数放在代码中,有类似的错误就会直接打印出来。

八、字符操作函数

前言:字符操作函数就是针对单个字符的,这里我们只介绍四个比较常用的字符库函数。

1.islower函数

(1)定义

1.该函数的作用是用来判断一个字母是否为小写。

2.若该字母是小写字母,则会返回非0的数字(为真),不是小写则返回0(假)。

3.需要包含#include<stype.h>d的头文件

(2)简单用法

#include<stdio.h>
#include<ctype.h>
int main()
{int ret = islower('a');int tmp = islower('A');printf("%d\n%d",ret,tmp);return 0;
}

运行结果:

2.isupper函数

(1)定义

1.用来判断一个字母是否是大写

2.如果是大写,则返回非0的数字(真),不是大写则返回0(假)

3.使用时需要包含头文件#include<ctype.h>

(2)简单用法

#include<stdio.h>
#include<ctype.h>
int main()
{int ret = isupper('a');int tmp = isupper('A');printf("%d\n%d", ret, tmp);return 0;
}

 结果:

3.tolower

(1)定义--字符转换函数

1.把大写字母转换成小写字母,小写字母则原封不动

2.返回值一定是小写字母

3.使用时需要包含头文件#include<ctype.h>

(2)简单用法

#include<stdio.h>
#include<ctype.h>
int main()
{int ret = tolower('A');int tmp = tolower('a');printf("%c\n%c", ret, tmp);return 0;
}

 程序结果;

4.toupper

(1)定义--字符转换函数

 

1.将小写字母转换成大写字母,大写原封不动。

2.返回值一定是大写字母

3.使用时需要包含头文件#include<ctype.h>

(2)简单用法

#include<stdio.h>
#include<ctype.h>
int main()
{int ret = toupper('A');int tmp = toupper('a');printf("%c\n%c", ret, tmp);return 0;
}

 结果:

九、内存操作函数

前言:内存操作函数和字符串操作函数的行为差不多,只不过内存操作函数操作的对象是内存,范围更加广,而字符串操作只能针对字符串。下面介绍四个内存操作函数

1.memcpy函数

(1)定义--内存拷贝函数

1.该函数可以针对任意的数据类型

2.第三个参数为需要拷贝的字节个数,以字节为单位进行拷贝

3.从第二个参数拷贝到第一个参数中 

4.头文件#include<string.h>

(2)简单使用

目的:将arr2中的内容拷贝到arr1中

#include<stdio.h>
#include<string.h>
int main()
{int arr1[10] = { 0 };int arr2[] = {1,2,3,4,5};memcpy(arr1,arr2,20);int i = 0;for (i = 0; i < 5; i++){printf("%d ",arr1[i]);}return 0;
}

结果:

 

(3)memcpy函数模拟实现 

#include<stdio.h>
#include<string.h>
#include<assert.h>
void* my_memcpy(void* str1,const void* str2,size_t sz)
{assert(str1&&str2);void* dest = str1;//一个一个字节拷贝while (sz--)//后置--{*((char*)str1) = *((char*)str2);str1 = (char*)str1 + 1;str2 = (char*)str2 + 1;}return dest;
}
int main()
{int arr1[10] = {0};int arr2[] = { 5,2,0 ,1,3,1,4};my_memcpy(arr1,arr2,28);int i = 0;for (i = 0; i < 7; i++) {printf("%d ", arr1[i]);}return 0;
}

1.void*的意思是可以接收任意类型的指针,但是不能直接++或者解引用,需要先进行类型转换。

2.拷贝的是任意类型,所以拷贝的时候为一个一个字节的拷贝。

3.memcpy函数一般用来拷贝内容不重叠的数据(两个以上的对象)。

2.memmove函数

(1)定义--内存移动

1.void*表示可以接收任意的数据类型。

2.size_t num依旧是以字节为单位的数据,以字节的形式移动数据。

3.包含头文件#include<string,h>

(2)简单使用

#include<stdio.h>
#include<string.h>
int main()
{int arr[10] = {1,2,3,4,5,6,7,8,9,10};memmove(arr,arr+4,20);int i = 0;for (i=0;i<10;i++){printf("%d ",arr[i]);}return 0;
}

结果:

目的与分析:

(3)memmove模拟实现

在模拟的时候,我们需要注意第一个参数和第二个参数的位置,选择合适的移动方式:从前往后或者从后往前移动数据,以防止数据被覆盖,达不到目的。

#include<stdio.h>
#include<string.h>
#include<assert.h>
void* my_memmove(void* dest, const void* str, size_t sz)
{assert(dest&&str);void* ret = dest;//数组往后,内存越大if (dest<str)//从前往后移动{while (sz--){*((char*)dest) = *((char*)str);dest = (char*)dest + 1;str = (char*)str + 1;}}else{while (sz--){*((char*)dest + sz) = *((char*)str + sz);}}return ret;
}
int main()
{int arr1[10] = {1,2,3,4,5,6,7,8,9,10};my_memmove(arr1,arr1+2,12);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr1[i]);}return 0;
}

1.根据两个指针的前后位置选择合适的移动方式

2.从后往前移动需要根据编译器的存储方式(小端存储或者大端存储)

3.memcmp函数

(1)定义--内存比较

1.比较结果返回:第一个>第二个,返回>0的数字;第一个=第二个,返回=0的数字;第一个<第二个,返回<0的数字

2.可以比较任意类型的数据,比较的数据以字节为单位

3.头文件#include<string.h>

(2)使用方法

#include<stdio.h>
#include<string.h>
int main()
{int arr1[5] = { 1,2,3,4,5 };int arr2[5] = { 1,2,3,5 };int ret=memcmp(arr1,arr2,12);int tmp = memcmp(arr1,arr2,13);printf("%d\n%d",ret,tmp);return 0;
}

 结果:

1.当第一次比较的是12个字节(前面三个数据)的时候,他们都是一样的,所以返回0

2.第二次比较的是13个字节,因为是小端存储,所以第一个字节(第十三位字节)就是数据,4<5,所以返回-1。

4.memset函数

(1)定义--内存设置函数

1.头文件#include<string.h> 

2.第一个参数:被操作的位置;第二个参数:修改成的数据;第三个参数:需要修个多少个字节。

3(*).每一个字节都会被修改成第二个参数所指定的数据。

(2)使用方法

#include<stdio.h>
#include<string.h>
int main()
{char arr[]="##########";memset(arr + 2, 'A', 5);printf("%s",arr);return 0;
}

 从arr+2的位置开始,将后面的数据设置成’A‘,但是只修改五个字节

 如果是整形数组:

#include<stdio.h>
#include<string.h>
int main()
{int arr[10] = {1,2,3,4,5,6,7,8,9,10};memset(arr + 2, 1, 12);int i = 0;for (i=0;i<10;i++){printf("%d ",arr[i]);}return 0;
}

设置修改成1,实际却输出这么大的数据;原因是将每个字节都设置成了1

 内存布局图:

由此可见,memset函数比较射手char类型的数据

十、总结

1.字符串库函数的使用都需要包含#include<string.h>的头文件

2.字符库函数的使用需要包含#include<ctype.h>的头文件

3.内存操作函数需要包含#include<string.h>的头文件

 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯每日一题2023.9.22

4960. 子串简写 - AcWing题库 题目描述 题目分析 原本为纯暴力但是发现会超时&#xff0c;可以加入前缀和&#xff0c;从前往后先记录一下每个位置c1出现的次数 再从前往后扫一遍&#xff0c;如果遇到c2就将答案加上此位置前的所有c1的个数&#xff08;直接加上此位置的前缀…

Ubuntu22.04 vnc远程黑屏

一、原因 原因是Ubuntu22.04使用的gnome启用了Wayland。vnc、teamviewer、向日葵、todesk等均无法使用或者远程黑屏等。 简单的说vnc、teamviewer、向日葵、todesk等均基于xorg实现&#xff08;xorg太流行&#xff09;&#xff0c;并不兼容Wayland&#xff0c;所以vnc无法正常…

iOS 17 Simulator Failed with HTTP status 400:bad request

升级 xcode 15 要 ios17 的 sdk 才能运行&#xff0c;但是更新这个 sdk 400 错误了 解决方案&#xff1a; 直接去官网下载开发者后台下载dmg文件&#xff0c;使用命令行快速安装即可 https://developer.apple.com/documentation/xcode/installing-additional-simulator-runti…

医学影像信息(PACS)系统软件源码

PACS系统是PictureArchivingandCommunicationSystems的缩写&#xff0c;与临床信息系统&#xff08;ClinicalInformationSystem,CIS&#xff09;、放射学信息系统(RadiologyInformationSystem,RIS)、医院信息系统(HospitalInformationSystem,HIS)、实验室信息系统&#xff08;L…

3288S Android11 适配红外遥控功能(超详细)

目录 一、rk3288平台红外遥控介绍二、原理图分析三、配置设备树并使能红外遥控功能四、打开红外打印功能&#xff0c;查看红外遥控的用户码和键值五、将查看到的红外遥控用户码和键值添加到设备树和.kl文件六、Android红外遥控.kl文件映射知识和使用添加新的.kl文件七、补充&am…

3、ARIMA序列预测Matlab代码、可视化(可做算法对比)

1、文件包中程序均收集、整理、汇总自网络。 2、文件包完整内容&#xff1a; 1&#xff09;【ARIMA-功能函数】仅包含一个ARIMA算法函数&#xff0c;需要调用到自己的程序中使用。 函数部分代码及预览图&#xff1a; function [result] ARIMA_algorithm(data, Periodicity,…

python脚本批量创建数据

背景 批量创建测试数据&#xff0c;利用python自带的库如faker库&#xff0c;节省大量的人工。准备工作 1、安装python&#xff0c;参考地址 https://www.runoob.com/python3/python3-install.html 2、设置环境变量(不同操作系统) PATH“$PATH:/usr/local/bin/python” 3、查…

【深度学习】实验13 使用Dropout抑制过拟合

文章目录 使用Dropout抑制过拟合1. 环境准备2. 导入数据集3. 对所有数据的预测3.1 数据集3.2 构建神经网络 3.3 训练模型3.4 分析模型 4. 对未见过数据的预测4.1 划分数据集4.2 构建神经网络4.3 训练模型4.4 分析模型 5. 使用Dropout抑制过拟合5.1 构建神经网络5.2 训练模型5.3…

进入数据结构的世界

数据结构和算法的概述 一、什么是数据结构二、什么是算法三、如何去学习数据结构和算法四、算法的时间复杂度和空间复杂度4.1 算法效率4.2 大O的渐进表示法4.3 时间复杂度4.4 空间复杂度4.5 常见复杂度对比 一、什么是数据结构 数据结构是计算机存储、组织数据的方式。&#x…

基于Spring Boot的医院预约挂号系统设计与实现(源码+lw+部署文档+讲解等)

前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f447;&#x1f3fb;…

【虚拟化】虚拟机vcpu绑核物理机

文章目录 一、NUMA二、虚拟机xml配置解析 参考文章 第一篇&#xff1a;KVM虚拟化CPU技术总结 第二篇&#xff1a;虚机cpu和mem的配置&#xff08;cputune和numatune&#xff09; 第三篇&#xff1a;libvirt 中cpu, numa 的配置 第四篇&#xff1a;如何提高虚拟机性能&#xff1…

xx-job凌晨一点清除oss指定文件夹以及指定保留时间的文件

ps&#xff1a;文件下面还有文件夹&#xff0c;这代码不能完全保证是否遍历到所有该文件夹以及子文件夹的文件&#xff0c;因为不可能一点点上到服务器去数&#xff0c;只是代码上做到应该不会出现重复的文件夹以及出现死循环 public static void main(String[] args) {long st…