【C语言】字符函数与字符串函数

简单不先于复杂,而是在复杂之后。

89efcc89ac61428db4d5b6639b2bd948.jpeg

目录

0. 前言 

1. 函数介绍 

1.1 strlen 

1.1.1 介绍

1.1.2 strlen 函数模拟实现

1.1.2.1 计数器方法 

1.1.2.2 递归方法 

1.1.2.3 指针 - 指针方法 

1.2 strcpy 

1.2.1 介绍

1.2.2 strcpy 函数模拟实现

1.3 strcat

1.3.1 介绍

1.3.2 strcat 函数模拟实现

 1.4 strcmp

1.4.1 介绍 

1.4.2 strcmp 函数模拟实现   

1.5 strncpy

 1.5.1 函数介绍

1.6 strncat 

1.6.1 函数介绍 

 1.7 strncmp

 1.7.1 函数介绍 

1.8 strstr 

1.8.1 函数介绍 

1.8.2  strstr 函数模拟实现

1.9 strtok 

1.9.1 函数介绍 

1.10  sterror

1.10.1  函数介绍

1.11  memcpy

1.11.1 函数介绍 

1.11.2 memcpy 函数模拟实现

1.12 memmove 

1.12.1 函数介绍 

 1.12.2 memmove 函数模拟实现

1.13 memcmp

1.13.1 函数介绍 

1.14 memset 

 


 

0. 前言 

C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在常量字符串中或者字符数组中。

字符串常量适用于那些对它不做修改的字符串函数。 

1. 函数介绍 

1.1 strlen 

1.1.1 介绍

 

计算字符串长度。 

  •  字符串以 '\0' 为结束标志, strlen 函数返回的是在字符串中 '\0' 前面的字符个数(不包含 \0)。
  • 参数指向的字符串必须要以 \0 结束。
  • 注意函数的返回类型是 size_t 是无符号的。
  • 学会 strlen 的模拟实现

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>int main()
{//char arr[] = "abcdef";//a b c d e f \0char arr[] = { 'w','o','w' };//[][][][][][][][][w][o][w][][][][][][][][]int len = strlen(arr);//随机值printf("%d\n", len); return 0;
}

 

 

1.1.2 strlen 函数模拟实现

1.1.2.1 计数器方法 

 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>size_t my_strlen(const char* str)
{assert(*str);size_t count = 0;while (*str != '\0'){str++;count++;}return count;
}int main()
{char arr[] = "abcdef";size_t n = my_strlen(arr);printf("%d\n", n);return 0;
}
1.1.2.2 递归方法 

 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>size_t my_strlen(const char* str)
{if (*str == '\0'){return 0;}else{return 1 + my_strlen(str + 1);}
}int main()
{char arr[] = "abcdef";size_t n = my_strlen(arr);printf("%d\n", n);return 0;
}
1.1.2.3 指针 - 指针方法 

 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>size_t my_strlen(const char* str)
{assert(*str);char* start = str;while (*str != '\0'){str++;}return str - start;
}int main()
{char arr[] = "abcdef";size_t n = my_strlen(arr);printf("%d\n", n);return 0;
}

1.2 strcpy 

1.2.1 介绍

char* strcpy(char* destination, const char* source);

字符串拷贝。 

  •  Copies the C string pointed by source into the array pointed by destination, including the terminating null character (and stopping at that point).
  • 源字符串必须以 '\0' 结束
  • 会将源字符串中的 '\0' 拷贝到目标空间
  • 目标空间必须足够大,以确保能存放源字符串
  • 目标空间必须可变
  • 学会模拟实现

 

 

以上为正确写法。

 因为目标地址指向一个常量字符串,这个区域不可修改,所以会引发异常,故要求目标空间必须可变。

1.2.2 strcpy 函数模拟实现

 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>//strcpy 返回目标空间的起始地址
char* my_strcpy(char* dest, const char *src)
{//实现字符串拷贝只有需要解引用操作才能找到字符串内容//故两个指针不可为空指针,要对其断言assert(dest);assert(src);char* ret = dest;while (*src){*dest++ = *src++;}*dest = *src;return ret;
}int main()
{char arr1[] = { "abcdef" };char arr2[20] = { 0 };my_strcpy(arr2, arr1);printf("%s\n", arr2);return 0;
}

以上代码不够简练,可以优化:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>//strcpy 返回目标空间的起始地址
char* my_strcpy(char* dest, const char* src)
{//实现字符串拷贝只有需要解引用操作才能找到字符串内容//故两个指针不可为空指针,要对其断言assert(dest && src);char* ret = dest;while (*dest++ = *src++){;}return ret;
}int main()
{char arr1[] = { "abcdef" };char arr2[20] = { 0 };my_strcpy(arr2, arr1);printf("%s\n", arr2);return 0;
}

这样的话 *dest++ = *src++ 这个语句就做到了既赋值又判断。

1.3 strcat

1.3.1 介绍

 

 字符串追加。

  • Appends a copy of the source string to the destination string. The terminating null character in destination is overwritten by the first character of source, and a null-character is included at the end of the new string formed by the concatenation of both in destination.
  • 源字符串必须以’\0‘结束。
  • 目标空间必须足够大,能容纳下源字符串的内容.
  • 目标空间必须可修改。
  • 字符串自己给自己追加,如何?

#define _CRT_SECURE_NO_WARNINGS 1
#include<string.h>
#include<stdio.h>
//字符串追加
int main()
{char arr1[20] = "hello";strcat(arr1, "world");printf("%s\n", arr1);return 0;
}

1.3.2 strcat 函数模拟实现

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>//字符串追加
char* my_strcat(char* dest, const char* src)
{ assert(dest && src);char* ret = *dest;while (*dest != '\0'){dest++;}while (*dest++ = *src++){;}return ret;
}int main()
{char arr1[20] = "hello ";my_strcat(arr1, "world");printf("%s\n", arr1);return 0;
}

如果自己给自己追加,程序会崩溃。

因为当把源字符串的字符逐个拷贝到目标字符串后面的时候,直到该拷贝‘\0’的时候,源字符串的‘\0‘被第一个拷贝过来的字符覆盖掉了,会陷入死循环。

所以我们要尽量避免字符串自己给自己追加。 

 1.4 strcmp

1.4.1 介绍 

 

  • 比较两个字符串是否相等。
  •  This function starts comparing the first character of each string. If they are equal to each other, it continues with the following pairs until the characters differ or until a terminating null-character is reached.
  • 标准规定:

                      1. 第一个字符串大于第二个字符串,则返回大于0的数字

                      2. 第一个字符串等于第二个字符串,则返回0

                      3. 第一个字符串小于第二个字符串,则返回小于0的数字

这种写法是在比较两个数组首元素的地址。 

 两个字符串比较是否相等,应该使用 strcmp

一对字符在比较的时候比较的是 ASCII 码值。

1.4.2 strcmp 函数模拟实现   

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>int my_strcmp(const char* str1,const char* str2)
{assert(str1 && str2);while (*str1 == *str2){if (*str1 == '\0')return 0;str1++;str2++;}if (*str1 > *str2)return 1;elsereturn -1;
}int main()
{char arr1[20] = "abc";char arr2[20] = "abc";//比较一下两个字符串是否相等int ret = my_strcmp(arr1, arr2);if (ret < 0)printf("<\0");else if (ret == 0)printf("==\0");elseprintf(">\0");//arr1 和 arr2 是数组名,是数组首元素的地址,必然不相等//if (arr1 == arr2)//{//	printf("==\0");//}//else//{//	printf("!=\0");//}return 0;
}

函数还可以简化:

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);
}

当目标空间不够时,会产生越界访问导致程序崩溃,但是函数仍然可以将大小超出目标空间的字符串拷贝。 

这是潜在的安全隐患。

1.5 strncpy

 1.5.1 函数介绍

 

  •  Copies the first num characters of source to destination. If the end of the source C string(which is signaled by a null-character) is found before num characters have been copied, destination is padded with zeros until a total of num characters have been written to it.
  • 拷贝num个字符从源字符串到目标空间。
  • 如果源字符串小于num,在拷贝完源字符串时,在目标后面追加0,直到num个。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>int main()
{char arr1[] = "abcdef";char arr2[] = "hello world";strncpy(arr1, arr2, 5);printf("%s\n", arr1);return 0;
}

 

因为在源字符串后面追加了0,也就是\0, 所以在源字符串小于num时,数组里存放的虽然追加两个0,后面有字符‘f’,但是打印字符串时到第一个‘\0’ 就已经终止了,只能打印源字符串的内容。

1.6 strncat 

1.6.1 函数介绍 

char * strncat ( char * destination, const char * source, size_t num );
  • Appends the first num characters of source to destination, plus a terminating null-character.
  • If the length of the C string in source is less than num, only the content up to the terminating null-character is copied.

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>int main()
{char arr1[20] = "hello\0xxxxxxxx ";char arr2[] = "world";strncat(arr1, arr2, 3);return 0;
}

如果 num 大于源字符串,也不会像 strncpy 一样多追加几个 \0 。

 1.7 strncmp

 1.7.1 函数介绍 

int strncmp ( const char * str1, const char * str2, size_t num );
  • 比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。

 

#define _CRT_SECURE_NO_WARNINGS 1
#include<string.h>
#include<stdio.h>int main()
{char arr1[] = "abcdef";char arr2[] = "abc";int ret = strncmp(arr1, arr2, 3);if (ret == 0)printf("==");else if (ret < 0)printf("<");elseprintf(">");return 0;
}

我们以后在使用字符串函数的时候尽量使用带n的版本,更严谨一些。

1.8 strstr 

1.8.1 函数介绍 

char * strstr ( const char *str1, const char * str2);
  • Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of str1.
  • 查找子串(str2 是子串)

 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>int main()
{char email[] = "lxz@code.com";char substr[] = "code";char* ret = strstr(email, substr);if (ret == NULL){printf("子串不存在");}else{printf("%s\n", ret);}return 0;
}

1.8.2  strstr 函数模拟实现

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>char* my_strstr(const char* str1, const char* str2)
{assert(str1 && str2);const char* s1 = str1;const char* s2 = str2;const char* p = str1;while (*p){s1 = p;s2 = str2;while (*s1 != '\0' && s2 != '\0' && *s1 == *s2){s1++;s2++;}if (*s2 == '\0'){return (char*)p;}p++;}return NULL;
}int main()
{char email[] = "lxz@code.com";char substr[] = "code";char* ret = my_strstr(email, substr);if (ret == NULL){printf("子串不存在");}else{printf("%s\n", ret);}return 0;
}

这样找子串是不够高效的,有一个 KMP 算法,用来实现在一个字符串中查找子字符串,效率高但是实现难度大。 

这里不做赘述。

1.9 strtok 

1.9.1 函数介绍 

char * strtok ( char * str, const char * sep );
  • 切割字符串
  • sep 参数是个字符串,定义了用作分隔符的字符集合。
  • 第一个参数指定一个字符串,它包含了 0 个或者多个由 sep 字符串中一个或多个分隔符分割的标记。
  • strtok 函数找到 str 中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok 函数会改变被操作的字符串,所以在使用 strtok 函数切分的字符串一般都是临时拷贝的内容并且可修改。)
  • strtok 函数的第一个参数不为 NULL,函数将找到 str 中第一个标记, strtok 函数将保存它在字符串中的位置。
  • strtok 函数的第一个参数为 NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
  • 如果字符串中不存在更多的标记,则返回 NULL 指针。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>int main()
{const char* sep = "@.";char email[] = "lxz@code.com";char cp[30] = { 0 };strcpy(cp, email);char* ret = strtok(cp, sep);printf("%s\n", ret);ret = strtok(NULL, sep);printf("%s\n", ret);ret = strtok(NULL, sep);printf("%s\n", ret);return 0;
}

因为我们不知道字符串中有几个字段,所以不知道应该调用几次 strtok 函数,所以换一种写法。 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>int main()
{const char* sep = "@.";char email[] = "lxz@code.com";char cp[30] = { 0 };strcpy(cp, email);char* ret = NULL;for (ret = strtok(cp, sep);ret != NULL; ret = strtok(NULL, sep)){printf("%s\n", ret);}//char* ret = strtok(cp, sep);//printf("%s\n", ret);//ret = strtok(NULL, sep);//printf("%s\n", ret);//ret = strtok(NULL, sep);//printf("%s\n", ret);return 0;
}

 这样写利用 for 循环可以适应任意数量字段的字符串。

1.10  sterror

1.10.1  函数介绍

char * strerror ( int errnum );
  •  返回错误码,所对应的错误信息

C语言的库函数,在执行失败的时候,都会设置错误码。

 

 

字符分类函数: 

函数如果他的参数符合下列条件就返回真
iscntrl任何控制字符
isspace空白字符:空格‘ ’,换页‘\f’,换行'\n',回车‘\r’,制表符'\t'或者垂直制表符'\v'
isdigit十进制数字 0~9
isxdigit十六进制数字,包括所有十进制数字,小写字母a~f,大写字母A~F
islower小写字母a~z
isupper大写字母A~Z
isalpha字母a~z或A~Z
isalnum字母或者数字,a~z,A~Z,0~9
ispunct标点符号,任何不属于数字或者字母的图形字符(可打印)
isgraph任何图形字符
isprint任何可打印字符,包括图形字符和空白字符

这些函数用法都很简单,不做赘述。 

字符转换: 

int tolower ( int c );//转小写
int toupper ( int c );//转大写

1.11  memcpy

1.11.1 函数介绍 

void * memcpy ( void * destination, const void * source, size_t num );
  • 函数 memcpy 从 source 的位置开始向后复制 num 个字节的数据到 destination 的内存位置。
  • 这个函数在遇到 ‘\0’ 的时候并不会停下来。
  • 如果 source 和 destination 有任何的重叠,复制的结果都是未定义的。

memcpy 函数可以用于复制任何类型的数据,无论是字符、整数、浮点数还是自定义数据结构。它不关心数据的具体类型,只是按照指定的字节数进行复制。

由于 memcpy 的参数是 void* 类型,可以轻松地将不同数据类型的数据复制到目标内存中,而不需要进行类型转换。这使得代码更加灵活和可维护。

1.11.2 memcpy 函数模拟实现

 C 语言中 void* 类型的指针不能直接解引用的原因是因为 void* 是一种通用的指针类型,它可以用来存储任何数据类型的地址,但它本身并不知道指向的是什么类型的数据。因此,直接解引用 void* 指针是不允许的,因为编译器无法确定要访问多少字节的内存以及如何解释这些字节。

为了解引用 void* 指针,需要将其转换为一个特定的数据类型的指针,这通常涉及到类型转换。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>void* my_memcpy(void* dest, const void* src, size_t num)
{assert(dest && src);void* ret = dest;while (num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;	}return ret;
}int main()
{int arr1[] = { 1,2,3,4,5,6,7 };int arr2[10] = { 0 };my_memcpy(arr2, arr1, 28);return 0;
}

memcpy 负责拷贝两块独立空间中的数据,对于重叠的空间,比如将自身空间中的数据拷贝到自身空间中,是不支持的。

重叠空间的拷贝,要用到 memmove 

1.12 memmove 

1.12.1 函数介绍 

 

void * memmove ( void * destination, const void * source, size_t num );
  • 和 memcpy 的差别就是 memmove 函数处理的源内存块和目标内存块是可以重叠的。
  • 如果源空间和目标空间出现重叠, 就得使用 memmove 函数处理。

   

 1.12.2 memmove 函数模拟实现

         

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>void* my_memmove(void* dest, const void* src, size_t num)
{assert(dest && src);void* ret = dest;if (dest < src){//前->后while (num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}}else{//后->前while (num--){*((char*)dest + num) = *((char*)src + num);}}return ret;
}void test()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };my_memmove(arr1 + 2, arr1, 20);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr1[i]);}
}int main()
{test();return 0;
}

1.13 memcmp

1.13.1 函数介绍 

 

int memcmp ( const void * ptr1,
const void * ptr2,
size_t num );
  • 比较从ptr1和ptr2指针开始的num个字节
  • 返回值如下:

 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>int main()
{int arr1[] = { 1,2,3,4,5 };//01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00int arr2[] = { 1,3,2 };    //01 00 00 00 03 00 00 00 02 00 00 00int ret = memcmp(arr1, arr2, 12);printf("%d\n", ret);return 0;
}

strcmp 只能比较字符串

memcmp 可以比较任意类型的数据 

1.14 memset 

 

  • 内存设置 

 

 

 

这个函数以字节为单位初始化内容,会把每个字节改变为要改的值。 

int main()
{int arr[10] = { 0 };memset(arr, 1, 40);int i = 0;for (i = 0; i < 10; i++){printf("%d\n", arr[i]);}return 0;
}

 

 

 

 

 

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

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

相关文章

RuoYi-Vue-SqlServer配置

项目链接 https://gitee.com/linkxs/RuoYi-Vue-SqlServerhttps://gitee.com/linkxs/RuoYi-Vue-SqlServer 服务端Eclipse编译 需要在 /ruoyi-common/pom.xml 中注释掉这些exclusion才能在Eclipse编译。实际maven编译&#xff0c;可以把这一块打开。 客户端ruoyi-ui编译 使用…

【Unity实战】手戳一个自定义角色换装系统——2d3d通用

文章目录 每篇一句前言素材开始切换头型添加更改颜色随机控制头型和颜色新增眼睛同样的方法配置人物的其他部位设置相同颜色部位全部部位随机绘制UI并添加点击事件通过代码控制点击事件添加颜色修改的事件其他部位效果UI切换添加随机按钮保存角色变更数据跳转场景显示角色数据 …

Python-自动化绘制股票价格通道线

常规方案 通过将高点/低点与其 2 个或 3 个相邻点进行比较来检测枢轴点,并检查它是否是其中的最高/最低点。对所有枢轴点进行线性回归以获得上方和下方趋势线。价格离开通道后建仓。通过这样做,我们得到如下所示的价格通道。我认为我们可以利用给定的数据取得更好的结果。

【算法|动态规划No30】leetcode5. 最长回文子串

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希望…

C语言之预处理

目录 前言 宏定义define的用法 文件包含include的用法 条件编译的用法 其他预处理命令 练习题 练习一 练习二 练习三 前言 预处理命令可以改变程序设计环境&#xff0c;提高编程效率&#xff0c;它们并不是C语言本身的组成部分&#xff0c;不能直接对它们进行编译&am…

redis高可用

文章目录 redis高可用概述哨兵模式原理配置流程使用缺点 cluster集群原理特征流程缺点故障转移故障检测故障转移 集群配置和管理主要命令搭建集群创建集群查看集群配置信息测试集群主从切换扩容缩容 redis高可用概述 1、高可用是分布式的概念。 Redis的高可用性是指在Redis集群…

springsecurity学习笔记-未完

目录 前言 一、概念 1.什么是springsecurity 2.对比shiro 二、开始项目 1.建立一个空项目&#xff0c;建立module&#xff0c;引入相关依赖 2.启动项目&#xff0c;访问项目 3.自定义密码 总结 前言 记录一下学习springsecurity的过程 开发环境&#xff1a;IDEA 一、概念 1.…

解决提交到App Store时的ITMS-90478和ITMS-90062错误

解决提交到App Store时的ITMS-90478和ITMS-90062错误 目录 引言 正文 1. 什么是ITMS-90478和ITMS-90062错误&#xff1f; 2. 解决方法 2.1 确定当前的版本号和构建号 2.2 递增版本号和构建号 2.3 再次尝试提交应用 总结 参考资料 错误记录 摘要&#xff1a;本文为iOS…

鼎鑫鸿鄴引入“能源互联网+”理念 打造共赢

近年来&#xff0c;随着全球能源消耗的不断增长和环境问题的日益突出&#xff0c;清洁能源转型成为全球共同关注的话题。中国作为全球最大的能源消费国&#xff0c;也在积极推动能源结构的优化和清洁能源的发展。鼎鑫鸿鄴新能源科技有限公司在推动清洁能源转型方面制定了一系列…

北太天元安装教程 及使用方法

北太天元是面向科学计算与工程计算的国产通用型科学计算软件。提供科学计算、可视化、交互式程序设计&#xff0c;具备丰富的底层数学函数库&#xff0c;支持数值计算、数据分析、数据可视化、数据优化、算法开发等工作&#xff0c;并通过SDK与API接口&#xff0c;扩展支持各类…

Vite介绍及实现原理

Vite介绍及实现原理 一、Vite简介1.1、什么是Vite1.2 、Vite的主要特性1.3、 为什么要使用Vite 二、Vite的实现原理2.1、依赖处理2.2、静态资源加载2.3、vue文件缓存2.4、 js/ts处理 三、热更新原理四、vite基本使用4.1、安装4.2、搭建项目 一、Vite简介 1.1、什么是Vite Vite…

计算机网络——理论知识总结(上)

开新番&#xff0c;因为博主备考的学校计网只考察1/6的分值&#xff0c;而且定位偏向于送分题&#xff0c;因此在备考时并没有很高强度的复习。本帖基于王道考研的教辅总结归纳&#xff0c;虽然是408的教材&#xff0c;但忽略其中有难度的部分&#xff0c;如计算题、画图题等&a…

如何通过员工工时管理降低企业成本?

作为当今快节奏商业环境的领导者或管理者&#xff0c;掌握员工的工作时间对于控制企业成本和确保每个人都各尽其责至关重要。 员工工时表软件就是这样一款工时跟踪管理解决方案&#xff1a;数字化的工时表有助于保护企业的财务不会被无节制的开支冲垮。然而&#xff0c;引入此…

Spark SQL概述与基本操作

目录 一、Spark SQL概述 &#xff08;1&#xff09;概念 &#xff08;2&#xff09;特点 &#xff08;3&#xff09;Spark SQL与Hive异同 &#xff08;4&#xff09;Spark的数据抽象 二、Spark Session对象执行环境构建 (1)Spark Session对象 &#xff08;2&#xff09;代码演…

Flink on yarn 加载失败plugins失效问题解决

Flink on yarn 加载失败plugins失效问题解决 flink版本&#xff1a;1.13.6 1. 问题 flink 任务运行在yarn集群,plugins加载失效,导致通过扩展资源获取任务参数失效 2. 问题定位 yarn容器的jar包及插件信息,jar包是正常上传 源码定位 加载plugins入口&#xff0c;TaskMana…

TCP三次握手具体过程

四次挥手 1&#xff09;客户端进程发出连接释放报文&#xff0c;并且停止发送数据。释放数据报文首部&#xff0c;FIN1&#xff0c;其序列号为sequ&#xff08;等于前已经传送过来的数据的最后一个字节的序号加1)&#xff0c;此时&#xff0c;客户端进入FIN_WAIT_1&#xff08…

AI新能量!FortiGate NGFW面向数据中心全面集成FortiGuard AI 安全服务

企业IT技术正在以惊人的速度发展&#xff0c;转型最大的领域之一是下一代防火墙&#xff08;NGFW&#xff09;市场。如今&#xff0c;混合云、多云、边缘等多种基础设施形态共存&#xff0c;已经成为大部分企业的常态&#xff0c;不断扩张的攻击面需要不同形态防火墙的安全防护…

若依ruoyi-nbcio如何做一个仿钉钉流程设计器的思考

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 看到有些流程图采用仿钉钉的流程设计&#xff0c;比如下面界面&#xff1a; 这种方式虽然简单&#xff0c…

计算机网络文章荟萃

脑残式网络编程入门(二)&#xff1a;我们在读写Socket时&#xff0c;究竟在读写什么&#xff1f;-网络编程/专项技术区 - 即时通讯开发者社区! 1.什么是 socket - 掘金2.socket 的实现原理 - 掘金本文讲述了 socket 在 linux 操作系统下的数据结构&#xff0c;以及阻塞 IO 利用…

檢測項目簡體字

某些項目可能要求代碼中不允許使用簡體字 安裝stcheck檢查 yarn add stcheck --dev在項目根目錄創建 st.config.json 文件 {"patterns": ["./**/*.(ts|js|tsx|jsx|vue|html)","!**/node_modules/**","!.git/**"],"gitignore&q…