【面试题分享】重现 string.h 库常用的函数
文章目录
- 【面试题分享】重现 string.h 库常用的函数
- 一、字符串复制
- 1. strcpy(复制字符串直到遇到 null 终止符)
- 2. strncpy(复制固定长度的字符串)
- 二、字符串连接
- 1. strcat(将一个字符串连接到另一个字符串的末尾)
- 2. strncat(将指定长度的字符串连接到另一个字符串的末尾)
- 三、字符串比较
- 1. strcmp(比较两个字符串的内容)
- 2. strncmp(比较指定长度的两个字符串的内容)
- 四、字符串搜索
- 1. strchr(在字符串中查找第一个出现的字符)
- 2. strrchr(在字符串中查找最后一个出现的字符)
- 3. strstr(在字符串中查找子字符串)
- 五、字符串长度计算
- 1. strlen(计算字符串的长度)
- 2. strnlen(在指定数量范围内计算字符串的最大长度)
- 六、内存操作
- 1. memcpy(复制内存块的内容)
- 2. memset(用指定字符填充内存块)
- 附录
- 1. 英文惯用缩写
- 2. size_t
- 3. 很多字符串函数明明不需要返回值,但为什么还是有返回值?
【面试题分享】重现 string.h 库常用的函数
在嵌入式软件开发的面试中,编程题往往是考察候选人基本功和实际动手能力的重要环节。而在众多面试题目中,重现标准库中的常用函数,如 string.h 库中的那些函数,既能展示候选人的编程技巧,也能反映其对基础概念的掌握程度。程序实现字符串操作相关的常见函数,是面试中比较常见的笔试题。本文也将重点介绍如何实现 string.h 库中的常用函数,主要包括字符串复制、连接、比较、搜索、长度计算和内存操作。通过这些实例,不仅帮助读者更好地备战面试,也能加深对标准库函数内部实现的理解。
[!CAUTION]
本文并不解释
string.h里所有的函数,只介绍一些较为常见或面试常考的函数
一、字符串复制
1. strcpy(复制字符串直到遇到 null 终止符)
strcpy,即 string copy(字符串复制)的缩写,是把从 src 地址开始且含有 NULL 结束符的字符串复制到以 dest 开始的地址空间,函数原型声明如下:
char *strcpy(char *dest, const char *src);
如果要自己实现一个与之功能相同的函数,可以如下编码:
char *myStrcpy(char *dest, const char *src)
{if (NULL == dest || NULL == src)return dest;char *temp = dest;do {*temp = *src;temp++;} while (*src++);return dest;
}
上述代码中,首先要判断 src 和 dest 是不是空指针;其次用临时指针 temp 代替 dest 指针做边遍历,这样返回值时可以直接用 dest 指针。
[!NOTE]
为什么要用
do......while,而不是while呢?根据
strcpy函数的功能,当复制完所有字符串后,还会再复制一个'\0'(空字符)。如果使用while循环,一旦判断到src指针已经指到空字符,就会立刻结束遍历,并不会把空字符复制到目标地址。所以使用do......while可以先复制再判断,确保空字符被复制。
面试中能现场写出上述的代码就算完成了,当然也可以使用下面的简化版本:
char *myStrcpy(char *dest, const char *src)
{if (NULL == dest || NULL == src)return dest;char *temp = dest;while (*temp++ = *src++);return dest;
}
while (*temp++ = *src++); 这一句,使用了指针操作来遍历和复制字符。其中,*dest++ = *src++ 语句做了以下操作:
*src获取源字符串当前字符。*dest存储该字符到目标字符串当前字符位置。- 然后两个指针分别自增,指向下一个字符位置。
[!NOTE]
为什么这里又用了
while了呢?因为当
src指向空字符时,会先复制给dest,然后while再判断*dest的值是否为空字符。
2. strncpy(复制固定长度的字符串)
strncpy 函数(string copy with n)也是复制字符串的函数,只是多了一个指定长度,把 src 所指向的字符串中以 src 地址开始的前 n 个字节复制到 dest 所指的数组中,并返回被复制后的 dest。函数原型声明如下:
char *strncpy(char *dest, const char *src, size_t n)
实现一个与之功能相同的函数,可以如下编码:
char *myStrncpy(char *dest, const char *src, size_t n)
{if (NULL == dest || NULL == src || 0 == n)return dest;char *temp = dest;while (n && (*temp++ = *src++))n--;while (n--)*temp++ = '\0';return dest;
}
代码前半部分与 strcpy 相同,后半部分的第一个 while 循环,判断 *src 是否为空字符、以及拷贝的字符数量是否指定的字符数之内。第二个 while 循环执行的前提是第一个 while 循环提前结束(即 src 中的字符数小于 n),第二个 while 循环用于填充目标字符串的剩余部分为空字符。
[!NOTE]*为什么第一个 `while` 不写成 `while (n-- && (*temp++ = *src++))`,这样不是更简洁吗?*有一种情况我们要考虑到,那就是当 `src` 指向的字符串数量大于 n 时,如果使用 `while (n-- && (*temp++ = *src++))` 这种写法,假设 n 此时为 1,`while` 先判断 n 的值,发现不为零,于是继续执行 `(*temp = *src)`,然后再执行 `n--`、`temp++`、`src++`,之后 n 的值就已经为 0 了。这时循环开始下一轮,又判断了一次 n 的值,发现为零,结束 `while` 循环,再执行 `n--`。这时就会出现,n 的值变成了 -1,第二个 `while` 循环判断的是 n 的值不为零,就会进入循环,并执行 `n--`,n 再减一就会变成 -2,如此减下去,n 只会变成更小的负数,最后导致 `temp` 越界,造成内存踩踏。
二、字符串连接
1. strcat(将一个字符串连接到另一个字符串的末尾)
strcat 是 string concatenation 的缩写。这个函数用于将一个字符串连接到另一个字符串的末尾。具体来说,strcat 函数将源字符串的内容复制到目标字符串的末尾,并自动添加一个 null 终止符来结束新的组合字符串。函数原型声明如下:
char *strcat(char *dest, const char *src);
实现一个与之功能相同的函数,可以如下编码:
char *myStrcat(char *dest, const char *src)
{if (NULL == dest || NULL == src)return dest;char *temp = dest;while (*temp)temp++;while (*temp++ = *src++);return dest;
}
第一个 while 循环的作用是为了将 temp 指针移动到目标字符串的末尾(即空字符的位置),之后就是将源字符串的内容逐字符复制到目标字符串的末尾。由于大部分代码的功能与字符串复制的一样,这里就不过多赘述。
2. strncat(将指定长度的字符串连接到另一个字符串的末尾)
strncat 是 “string concatenate with n” 的缩写,全称是 “string concatenate with length limit”。这个函数用于将源字符串的指定长度的字符追加到目标字符串的末尾,并自动添加一个 null 终止符来结束新的组合字符串。函数原型声明如下:
char *strncat(char *dest, const char *src, size_t n);
实现一个与之功能相同的函数,可以如下编码:
char *myStrncat(char *dest, const char *src, size_t n)
{if (NULL == dest || NULL == src || 0 == n)return dest;char *temp = dest;while (*temp)temp++;while (n && (*temp++ = *src++))n--;while (n--)*temp++ = '\0';return dest;
}
代码具体描述与前面的 myStrncpy 和 myStrcat 相同,这里不展开说明。
三、字符串比较
1. strcmp(比较两个字符串的内容)
strcmp 是 “string compare” 的缩写。 这个函数用于比较两个字符串的字典顺序。它根据两个字符串的字符逐一比较,直到找到不同的字符或遇到终止的 null 字符。函数原型声明如下:
int strcmp(const char *str1, const char *str2);
strcmp 的返回值是整数类型,有三种情况,分别是 -1、0 和 1,以上三种情况均是在比较到不同字符时,将两个字符直接做差得到的结果,具体情况如下:
- 如果
str1在str2之前,则返回值为 -1。 - 如果
str1等于str2,则返回值为 0。 - 如果
str1在str2之后,则返回值为 1。
实现一个与之功能相同的函数,可以如下编码:
int myStrcmp(const char *str1, const char *str2)
{if (str1 == str2)return 0;while (*str1 && (*str1 == *str2)) {str1++;str2++;}return ((*str1 - *str2) ? ((*str1 - *str2) > 0 ? 1 : -1) : 0);
}
上述代码中,先判断两个地址是否相同,如果是一样,那字符串也是一样的,直接返回 0 即可。while 循环中,除了判断 str1 当前所指的字符是否为空字符之外,还要判断 str1 和 str2 各自所指的字符是否相同,同时满足两个条件,两个指针各自递增偏移。
最后返回时,用三目运算符内嵌另一个三目运算符做一个差值判断,先判断是否为 0,如果是则返回 0,否则再判断是正数还是负数,正数返回 1,负数返回 -1。
[!NOTE]
如果两个参数中有一个传参传入了
NULL,会导致段错误,为什么这个代码没有体现出解决方法?
strcmp也是如此,只要参数中有且只有一个参数是NULL,就会出现段错误。传入两个NULL则返回 0,因此,我只是保留了原本strcmp该有功能写了这个myStrcmp。
2. strncmp(比较指定长度的两个字符串的内容)
strncmp 在 strcmp 基础上,加上了需要比较的长度,该函数用于比较两个字符串的前 n 个字符的字典顺序。它根据两个字符串的字符逐一比较,直到找到不同的字符、比较了指定的 n 个字符或遇到空字符。函数原型声明如下:
int strncmp(const char *str1, const char *str2, size_t n);
实现一个与之功能相同的函数,可以如下编码:
int myStrncmp(const char *str1, const char *str2, size_t n)
{if (str1 == str2)return 0;while (n && (*str1 && (*str1 == *str2))) {str1++;str2++;n--;}return ((*str1 - *str2) ? ((*str1 - *str2) > 0 ? 1 : -1) : 0);
}
四、字符串搜索
1. strchr(在字符串中查找第一个出现的字符)
strchr 是 “string character” 的缩写,全称是 “string character search”。这个函数用于在字符串中查找第一个出现的指定字符,并返回一个指向该字符的指针。函数原型声明如下:
char *strchr(const char *str, int c);
在被搜索的字符串 str 中,查找 c 指定的字符,虽传入的类型为 int ,但实际比较时会被转换为 char。如果在字符串 str 中找到 c ,则返回一个指向字符串中第一个出现的字符 c 的指针;如果没有没有找到,则返回 NULL。
实现一个与之功能相同的函数,可以如下编码:
char *myStrchr(const char *str, int c)
{while (*str && (*str != (char)c))str++;if (*str == (char)c)return (char *)str;return NULL;
}
上述代码中,while 循环除了判断 *str,同时还判断 *str 是否与 (char)c 是否匹配,所以退出循环就存在两个情况:一是 str 已经遍历结束,如果 c 是空字符(c 有可能是 '\0'),则返回 str 当前所指的地址,否则返回 NULL;二是在 str 遍历结束之前,找到了与 c 匹配的字符,返回 str 当前所指的地址。
[!NOTE]
为什么返回
str要强转类型为char *,直接返回不行吗?函数的返回类型是
char *,而str是const char *类型,直接返回并没有什么问题,只是在编译时会警告类型不匹配,所以这里强转只是为了消除警告。
2. strrchr(在字符串中查找最后一个出现的字符)
strrchr 是 “string reverse character” 的缩写,全称是 “string reverse character search”。该函数用于在字符串中查找最后一次出现的指定字符,并返回一个指向该字符的指针。函数原型声明如下:
char *strrchr(const char *str, int c);
与 strchr 函数类似,如果在字符串 str 中找到 c ,则返回一个指向字符串中最后一个出现的字符 c 的指针;如果没有没有找到,则返回 NULL。
实现一个与之功能相同的函数,可以如下编码:
char *myStrrchr(const char *str, int c)
{const char *last = NULL;while (*str) {if (*str == (char)c) {last = str;}str++;}if (*str == (char)c)return (char *)str;return (char *)last;
}
上述代码依然使用了 while 循环遍历的方法,在遍历的过程中查找相匹配的字符,找到字符后保存最新的地址到 last 指针并继续查找,一旦再次找到指定字符立刻更新 last 指针,直到字符串全部遍历结束。
3. strstr(在字符串中查找子字符串)
strstr 是 “string substring” 的缩写,全称是 “string substring search”。这个函数用于在字符串中查找第一次出现的子字符串,并返回一个指向该子字符串起始位置的指针。函数原型声明如下:
char *strstr(const char *haystack, const char *needle);
其中,haystack 是要搜索的主字符串,needle 是要查找的子字符串。如果 needle 是 haystack 的子字符串,则返回一个指向主字符串中第一次出现的子字符串的指针,否则返回 NULL。
char *myStrstr(const char *haystack, const char *needle)
{if (!*needle)return (char *)haystack;while (*haystack) {if (*haystack == *needle) {char *h = (char *)haystack;char *n = (char *)needle;while (*h && *n && (*h == *n)) {h++;n++;}if (!*n)return (char *)haystack;haystack++;} else {haystack++;}}return NULL;
}
可以看出,strstr 函数的代码要远比前面提到的所有函数都要复杂,所以以下是代码的剖析:
- 空字符串检查:首先检查
needle是否为空字符串(原strstr函数也是如此),如果是,直接返回haystack的指针。 - 逐字符比较:
- 外层
while (*haystack)循环遍历haystack字符串。 - 当出现第一个匹配的字符后,进入内层
while (*h && *n && *h == *n)循环逐字符比较haystack和needle,直到字符不匹配或到达needle末尾。
- 外层
- 匹配检查:如果
needle的所有字符都匹配,即!*n,返回haystack当前的位置。 - 继续搜索:如果当前字符不匹配,
haystack移动到下一个字符继续搜索。 - 未找到返回
NULL:如果遍历完haystack仍未找到needle,返回NULL。
五、字符串长度计算
1. strlen(计算字符串的长度)
strlen 是 “string length” 的缩写,该函数用于计算字符串的长度,即字符串中字符的数量(不包括终止空字符)。函数原型声明如下:
size_t strlen(const char *str);
实现一个与之功能相同的函数,可以如下编码:
size_t myStrlen(const char *str)
{const char *temp = str;while (*temp)temp++;return temp - str;
}
代码非常简短,这里就不过多讲解了。
2. strnlen(在指定数量范围内计算字符串的最大长度)
strnlen 是 “string length with n” 的缩写,全称是 “string length with length limit”。该函数用于计算字符串的长度,但最多检查指定的最大字符数。函数原型声明如下:
size_t strnlen(const char *str, size_t maxlen);
实现一个与之功能相同的函数,可以如下编码:
size_t myStrnlen(const char *str, size_t maxlen)
{const char *temp = str;size_t num = 0;while (num < maxlen && *temp) {temp++;num++;}return num;
}
六、内存操作
1. memcpy(复制内存块的内容)
memcpy 是 “memory copy” 的缩写,该函数用于从源地址复制指定数量的字节到目标地址。函数原型声明如下:
void *memcpy(void *dest, const void *src, size_t n);
dest 是指向目标内存块的指针,src 是指向源内存块的指针,n 是要复制的字节数。最后是返回目标内存块 dest 的指针。
实现一个与之功能相同的函数,可以如下编码:
void *myMemcpy(void *dest, const void *src, size_t n)
{unsigned char *d = (unsigned char *)dest;const unsigned char *s = (const unsigned char *)src;while (n--)*d++ = *s++;return dest;
}
这里要注意的就是类型问题,由于是内存复制,因此要强转为 unsigned char 类型。
2. memset(用指定字符填充内存块)
memset 是 “memory set” 的缩写,该函数用于将指定值填充到内存块中,通常用于初始化或重置内存。通常也管这个函数叫 “填充” 函数,函数原型声明如下:
void *memset(void *str, int c, size_t n);
str 是指向要填充的内存块的指针。c 是要设置的值,传递为 int 类型,填充的时候会转换为 unsigned char 类型。n 是要填充的字节数。最后是返回指向内存块 str 的指针。
实现一个与之功能相同的函数,可以如下编码:
void *myMemset(void *str, int c, size_t n){unsigned char *s = (unsigned char *)str;while (n--)*s++ = (unsigned char)c;return str;}
附录
1. 英文惯用缩写
在函数的参数列表中有两个高频出现的参数——src 和 dest,其中 src 指源操作数,是 source 的缩写,dest 指目标操作数,是 destination 的缩写。
2. size_t
size_t 是一种用于表示对象大小或数组索引的无符号整数类型。在 C 和 C++ 标准库中,对于 size_t 的定义有所不同。在不同的编译器和平台上,size_t 可能通过一些中间文件间接定义,但主要头文件通常是 stddef.h(C)和 cstddef(C++)。
在 C 语言中,stddef.h 可能包含以下内容:
#ifndef _STDDEF_H
#define _STDDEF_Htypedef unsigned long size_t;#endif // _STDDEF_H
在 C++ 中,cstddef 可能包含以下内容:
#ifndef _CSTDDEF_
#define _CSTDDEF_#include <stddef.h>namespace std {using ::size_t;
}#endif // _CSTDDEF_
3. 很多字符串函数明明不需要返回值,但为什么还是有返回值?
字符串函数返回值的设计有以下几个实用的理由,返回值的设计提供了一些附加的好处,使函数的使用更加灵活和方便。以下以 strcpy 函数为例进行说明。
-
链式调用:
strcpy返回目标字符串的指针,这使得链式调用成为可能。链式调用允许多个字符串操作函数连续使用,从而简化代码。char dest[100]; strcpy(dest, "Hello, "); strcat(dest, "world!");// 使用链式调用 strcat(strcpy(dest, "Hello, "), "world!"); -
更好的函数组合:返回目标字符串的指针使得
strcpy可以与其他需要字符串指针作为输入的函数更好地组合在一起。例如,许多字符串处理函数(如strlen)需要一个字符串指针作为参数。char dest[100]; size_t len = strlen(strcpy(dest, "Hello, world!")); -
代码一致性和便利性:在 C 标准库中,许多字符串操作函数都返回与输入相关的指针。例如,
strcat和strtok都返回指向结果字符串的指针。strcpy也遵循这个设计模式,使得整个库的设计更一致和直观。 -
调试和错误处理:尽管
strcpy本身没有提供错误处理机制,但在某些情况下,返回值可以在调试时提供便利。例如,在检查链式调用的中间结果时,可以打印返回值来验证复制操作是否成功。char dest[100]; printf("Copied string: %s\n", strcpy(dest, "Hello, world!")); -
兼容历史习惯:许多早期的 C 函数,包括
strcpy,都是遵循 UNIX 函数设计习惯的。这种习惯通常会返回一个指向结果的指针。遵循这种习惯,使得库函数更容易被广泛接受和使用。
相关文章:
【面试题分享】重现 string.h 库常用的函数
文章目录 【面试题分享】重现 string.h 库常用的函数一、字符串复制1. strcpy(复制字符串直到遇到 null 终止符)2. strncpy(复制固定长度的字符串) 二、字符串连接1. strcat(将一个字符串连接到另一个字符串的末尾&…...
6.21 移动语义与智能指针
//先构造,再拷贝构造//利用"hello"这个字符串创建了一个临时对象//并复制给了s3//这一步实际上new了两次String s3 "hello"; 背景需求: 这个隐式创建的字符串出了该行就直接销毁掉,效率比较低 可以让_pstr指向这个空间…...
Kimi还能对学术论文进行润色?我来教你!
学境思源,一键生成论文初稿: AcademicIdeas - 学境思源AI论文写作 一、引言 在学术界,论文的质量往往决定了研究的可信度和影响力。Kimi作为一款人工智能助手,可以为学术论文的润色提供有效的帮助。本文将详细介绍如何利用Kimi进…...
智汇云舟成为中煤集团中煤智能创新联盟成员单位
6月21日,第八届世界智能产业博览会平行会议暨中煤智能创新联盟交流会在天津水游城丽筠酒店顺利举行。智汇云舟受邀参与,并由中国中煤能源集团授予荣誉证书,正式成为中煤智能创新联盟成员单位。会议上,清华大学、中国矿业大学&…...
【文心智能体大赛】迎接属于你的休闲娱乐导师!
迎接属于你的休闲娱乐导师! 前言创建智能体发布智能体最后结语 前言 文心智能体平台AgentBuilder 是百度推出的基于文心大模型的智能体(Agent)平台,支持广大开发者根据自身行业领域、应用场景,选取不同类型的开发方式&…...
AI:音乐创作的未来还是毁灭的序曲?
AI:音乐创作的未来还是毁灭的序曲? 随着人工智能(AI)技术的飞速发展,它已经渗透到了我们生活的方方面面,包括音乐领域。然而,AI在音乐创作中的角色引发了广泛的讨论和争议。一些人认为AI为音乐…...
如何通过AI进行智能日志异常检测
智能日志异常检测是一种利用人工智能(AI)技术来自动识别日志数据中异常模式或行为的方法。传统日志监控依赖于预定义规则,而智能日志异常检测可以适应不同的日志模式和异常类型,提高检测准确性和效率。下面是一个完整的步骤指南&a…...
C++ GPU编程(英伟达CUDA)
安装编译环境 https://developer.download.nvidia.com/compute/cuda/12.5.0/local_installers/cuda_12.5.0_555.85_windows.exe CMakeLists.txt cmake_minimum_required(VERSION 3.10)set(CMAKE_CXX_STANDARD 17) set(CMAKE_BUILD_TYPE Release) #set(CMAKE_CUDA_ARCHITECTUR…...
肾虚学习实验第T1周:实现mnist手写数字识别
>- **🍨 本文为[🔗365天深度学习训练营](https://mp.weixin.qq.com/s/0dvHCaOoFnW8SCp3JpzKxg) 中的学习记录博客** >- **🍖 原作者:[K同学啊](https://mtyjkh.blog.csdn.net/)** 目录 一、前言 作为一名研究牲࿰…...
Python | Leetcode Python题解之第162题寻找峰值
题目: 题解: class Solution:def findPeakElement(self, nums: List[int]) -> int:n len(nums)# 辅助函数,输入下标 i,返回 nums[i] 的值# 方便处理 nums[-1] 以及 nums[n] 的边界情况def get(i: int) -> int:if i -1 or…...
定个小目标之刷LeetCode热题(26)
这道题属于一道简单题,可以使用辅助栈法,代码如下所示 class Solution {public boolean isValid(String s) {if (s.isEmpty())return false;// 创建字符栈Stack<Character> stack new Stack<Character>();// 遍历字符串数组for (char c : …...
网络爬虫设置代理服务器
目录 1.获取代理 IP 2.设置代理 IP 3. 检测代理 IP 的有效性 4. 处理异常 如果希望在网络爬虫程序中使用代理服务器,就需要为网络爬虫程序设置代理服务器。 设置代理服务器一般分为获取代理 IP 、设置代理 IP 两步。接下来,分…...
3、matlab单目相机标定原理、流程及实验
1、单目相机标定流程及步骤 单目相机标定是通过确定相机的内部和外部参数,以便准确地在图像空间和物体空间之间建立映射关系。下面是单目相机标定的流程及步骤: 搜集标定图像:使用不同角度、距离和姿态拍摄一组标定图像,并确保标…...
【gdb 如何生成并查看core dump】
生成core dump 使用ulimit命令来设置core dump文件的大小。 ulimit -c unlimitedcore dump位置 如果程序崩溃,系统会生成一个名为core的文件。可以通过以下命令查看core文件位置, cat /proc/sys/kernel/core_pattern查看core dump gdb /path/to/you…...
极简短视频查看、删除应用
本地短视频服务器 背景:我的NAS中存放了很多短视频,多到很多没看过,于是写了这个程序来随机查看并删除短视频 运行: 安装依赖后运行main.py 直接使用docker: docker pull realwang/short_video docker run -d -p 3000:…...
【秋招刷题打卡】Day01-自定义排序
Day01-自定排序 前言 给大家推荐一下咱们的 陪伴打卡小屋 知识星球啦,详细介绍 >笔试刷题陪伴小屋-打卡赢价值丰厚奖励 < ⏰小屋将在每日上午发放打卡题目,包括: 一道该算法的模版题 (主要以力扣,牛客,acwin…...
API低代码平台介绍6-数据库记录删除功能
数据库记录删除功能 在前续文章中我们介绍了如何插入和修改数据库记录,本篇文章会沿用之前的测试数据,介绍如何使用ADI平台定义一个删除目标数据库记录的接口,包括 单主键单表删除、复合主键单表删除、多表删除(整合前两者&#x…...
计算机基础之:硬件系统的性能评估标准
服务器时钟的性能通常涉及多个方面,主要包括准确性、稳定性、以及对系统性能的影响。以下是一些关键指标和衡量方法: 准确性: 时间偏移:测量服务器时钟与一个可靠时间源(如GPS时间、原子钟或NTP服务器)之间…...
高互动UI设计揭秘:动画效果如何提升用户体验
动画,由于其酷的视觉冲击,往往会产生极好的用户体验。UI设计中的动态效果可以使用户界面看起来更酷,特别是界面的功能动画,是UX设计的重要组成部分,不容忽视。为什么UI设计的动态效果如此重要?接下来&#…...
探索Java异常处理的奥秘:源码解析与高级实践
1. 引言 在Java编程的广阔天地中,异常处理是确保程序健壮性、稳定性和可维护性的重要基石。对于Java工程师而言,深入理解Java异常处理的机制,并能够在实践中灵活运用,是迈向卓越的重要一步。 2. 基本概念 在Java中,异常(Exception)是程序执行期间出现的不正常或错误情况…...
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
uniapp 小程序 学习(一)
利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 :开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置,将微信开发者工具放入到Hbuilder中, 打开后出现 如下 bug 解…...
