【C语言】字符串函数「超详细」_c语言字符串函数,31道Golang面试题

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Golang全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注go)
img

正文

请输入第二个字符串:abc
返回的值:1**

🎄第三次的运行结果🎄

请输入第一个字符串:abc
请输入第二个字符串:abcd
返回的值:-1

🎄创建自定义函数实现strcmp()🎄

思路很简单其实 👇

相等为0、大于返回1、小于返回-1,重要的点注释其实都是写了的。

示例代码如下:👇

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
int my_strcmp(const char *str1, const char *str2)
{
assert(str1 && str2 != NULL);
while (*str1 == str2)
{
//判断相等情况,有一个相等就代表
str2也是一样的
if (*str1 == ‘\0’)
{
return 0;
}
*str1++;
*str2++;//自增比较
}
if (*str1 > *str2)
return 1;//大于
else
return -1;//小于
//其实还有一种更简单的方法,大于小于。
//return *str1 - *str2;
//这个是指针减指针的概念,前面介绍有说过!
}
int main()
{
char str1[20] = { 0 };
char str2[20] = { 0 };
puts(“请输入第一个字符串:”);
scanf(“%s”, &str1);
puts(“请输入第二个字符串:”);
scanf(“%s”, &str2);
int ret = my_strcmp(str1, str2);
printf(“返回的值:%d\n”,ret);
return 0;
}

🎄第一次的运行结果🎄

请输入第一个字符串:abc
请输入第二个字符串:abc
返回的值:0

🎄第二次的运行结果🎄

请输入第一个字符串:abcd
请输入第二个字符串:abc
返回的值:1

🎄第三次的运行结果🎄

请输入第一个字符串:abc
请输入第二个字符串:abcd
返回的值:-1

以上四个字符串函数是我们学C语言必须要掌握的,包括模拟字符串函数的实现也是有必要去实现的,这样的好处可以锻炼我们对函数库的了解,增强自己写代码的能力,建议反复观看,牢记掌握这四个字符串函数~


🔧 限制 🔧

上述 strcpy、strcat、strcmp、长度是不受限制的字符串函数

而下面所说的是长度受限制的字符串函数了>>>

起始记住下面这个只需要在上面的基础上加上个str后面+n即可(^∀^●)ノシ

下面所介绍的3种函数相对比上的使用要更加安全,但并不是绝对安全。


🎋strncpy() - 复制字符串(受长度限制)🎋

这个函数实际上和**strcpy()的功能是一模一样的,唯一不同的是在于strncpy()**多了一个参数,那个参数就是受长度所限制的。

strncpy()函数的声明方式如下****👇

char *strncpy(char *dest, const char *src, size_t n)

把 src 所指向的字符串复制到 dest,最多复制 n 个字符。

当 src 的长度小于 n 时,dest 的剩余部分将用空字节填充。

dest → 指向用于存储复制内容的目标数组。

src → 要复制的字符串。

n → 要从源中复制的字符数。

Size_t→是一个无符号整型类型。

该函数最终返回所复制的字符串。

🎋strncpy()函数代码示例🎋

使用**strncpy()**函数代码示例如下 👇

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main(void)
{
char str1[20] = “helloC”;
char str2[] = “HELLO”;
printf(“字节=%d\n”, sizeof(str2));
printf(“str = %s\n”,strncpy(str1, str2, sizeof(str2)));
return 0;
}

运行结果如下 👇

字节 = 6

str = HELLO

sizeof(str2) 相当于为 6个字节,因为 char 为一个字节 里面元素有6个包括’\0’

✅来一起看看调试结果说不定会更好点✅

我们再来看下一个例子👇

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main(void)
{
char str1[20] = “helloC”;
char str2[] = “HELLO”;
printf(“字节=%d\n”, sizeof(char));
printf(“str = %s\n”, strncpy(str1, str2, sizeof(char)));
return 0;
}

运行结果如下 👇

字节 = 1

str = HELLO

sizeof(char) 结果为一个字节,因为 char 类型大小为一个字节!

✅来一起看看调试结果说不定会更好点✅

🎋strncpy()源程序实现🎋

示例代码如下:👇

char * __cdecl strncpy (
char * dest,
const char * source,
size_t count
)
{
char *start = dest;

while (count && (*dest++ = source++)) / copy string */
count–;

if (count) /* pad out with zeroes */
while (–count)
*dest++ = ‘\0’;

return(start);
}


🎋strncat() - 连接字符串(受长度限制)🎋

strncat()函数的声明方式如下****👇

char *strncat(char *dest, const char *src, size_t n)

把 src 所指向的字符串追加到 dest 所指向的字符串的结尾,直到 n 的长度为止。

dest→指向目标数组,该数组包含了一个 C语言 字符串,且足够容纳追加后的字符串,包括额外的空字符。

src→要追加的字符串。

n→追加的最大字符串。

Size_t→是一个无符号(unisgned int)整型类型。

该函数返回一个指向最终的目标字符串 dest 的指针。

注意:这里的返回值的指针类型可以是void也可以是char *🧨

🎋strncat()函数代码示例🎋

使用**strncpy()**函数代码示例如下 👇

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main(void)
{
char str1[20];
char str2[20];
strcpy(str1, “Cyuyan”);
strcpy(str2, “yyds”);
printf(strncat(str1, str2, 5));//追加字符串!
return 0;
}

运行结果如下 👇

Cyuyanyyds

✅来一起看看调试结果说不定会更好点✅

我们把 Size_t 参数改为④来看看

printf(strncat(str1, str2, 4));

运行结果依旧和上述结果是一样的。

🎋strncat()源程序实现🎋

示例代码如下:👇

char * __cdecl strncat (
char * front,
const char * back,
size_t count
)
{
char *start = front;

while (*front++)
;
front–;

while (count–)
if (!(*front++ = *back++))
return(start);

*front = ‘\0’;
return(start);
}

🎋strncmp() - 比较字符串(受长度限制)🎋

strncmp()函数的声明方式如下****👇

int strncmp(const char *str1, const char *str2, size_t n)

str1 → 要进行比较的第一个字符串。

str2 → 要进行比较的第二个字符串。

n → 要比较的最大字符数。

这个函数开始比较每个字符串的第一个字符。如果它们相等,则继续执行下面的对,直到字符不同,直到达到一个结束的空字符,或直到两个字符串中的num字符匹配,以先发生的为准。

如果返回值 < 0,则表示 str1 小于 str2。

如果返回值 > 0,则表示 str2 小于 str1。

如果返回值 = 0,则表示 str1 等于 str2。

🎋strncmp()函数代码示例🎋

使用**strncpy()**函数代码示例如下 👇

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main(void)
{
char str1[20];
char str2[20];
strcpy(str1, “Cyuyan”);
strcpy(str2, “Cyuyanyyds”);
printf(“%d”, strncmp(str1, str2, 6));

return 0;
}

运行结果如下 👇

0 → 代表****str1 等于 str2

如果这里没有追加字符串的话结果就会是-1,因为str1<str2。正因为我们追加了字符为6,它才可以是str1 = str2。

🎋strncmp()源程序实现🎋

示例代码如下:👇

int __cdecl strncmp
(
const char *first,
const char *last,
size_t count
)
{
size_t x = 0;

if (!count)
{
return 0;
}

/*

  • This explicit guard needed to deal correctly with boundary
  • cases: strings shorter than 4 bytes and strings longer than
  • UINT_MAX-4 bytes .
    /
    if( count >= 4 )
    {
    /
    unroll by four */
    for (; x < count-4; x+=4)
    {
    first+=4;
    last +=4;

if (*(first-4) == 0 || *(first-4) != (last-4))
{
return(
(unsigned char *)(first-4) - *(unsigned char *)(last-4));
}

if (*(first-3) == 0 || *(first-3) != (last-3))
{
return(
(unsigned char *)(first-3) - *(unsigned char *)(last-3));
}

if (*(first-2) == 0 || *(first-2) != (last-2))
{
return(
(unsigned char *)(first-2) - *(unsigned char *)(last-2));
}

if (*(first-1) == 0 || *(first-1) != (last-1))
{
return(
(unsigned char *)(first-1) - *(unsigned char *)(last-1));
}
}
}

/* residual loop */
for (; x < count; x++)
{
if (*first == 0 || *first != last)
{
return(
(unsigned char *)first - *(unsigned char *)last);
}
first+=1;
last+=1;
}

return 0;
}


🎍strstr() - 在一个字符串中查找另外一个字符串🎍

strstr()函数的声明方式如下****👇

char *strstr(const char *haystack, const char *needle)

在字符串 haystack 中查找第一次出现字符串 needle 的位置,不包含终止符 ‘\0’。

haystack→ 要被检索的 C 字符串。

needle→ 在 haystack 字符串内要搜索的小字符串。

该函数返回在 haystack 中第一次出现 needle 字符串的位置,如果未找到则返回 null。

注意:这里的返回值的指针类型可以是void也可以是char *🧨

🎍strstr()函数代码示例🎍

题目:在arr1中查找是否包含arr2中的数组。要求使用 strstr() 库函数。

使用**strncpy()**函数代码示例如下 👇

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main(void)
{
char arr1[20] = “abcdef”;
char arr2[20] = “bcd”;
char ret = strstr(arr1, arr2);
if (ret == NULL)
{
printf(“没找到!\n”);
}
else
{
printf(“找到了→%s\n”, ret);
}
return 0;
}

运行结果如下 👇

找到了→bcdef

那没找到的情况下,我们把 arr2 数组修改下。其它值不变🎉

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>
int main(void)
{
char arr1[20] = “abcdef”;
char arr2[20] = “bf”;
char *ret = strstr(arr1, arr2);
if (ret == NULL)
{
printf(“没找到%s!\n”,ret);
}
else
{
printf(“找到了→%s\n”, ret);
}
return 0;
}

运行结果如下 👇

找不到(null)!

对比之下,你发现了区别了没👀

🎍创建自定义函数实现strstr()🎍

分析思路🧐

其实很容易,我们只需要拿首字符地址进行比较相等的话返回,不相等的时候进行自增++(注意:这里自增++只需要str1进行++而str2依旧拿首元素地址跟它进行比较),再进行比较直到’\0’,没有就返回空指针NULL。如果str1有元素和str2首元素地址匹配上了的话那么就继续往后走~但是,这个仅仅是假设 abcd 和 bcd 所适用的场景。如果是 bbbc 和 bbc,这种怎么办?是不是发现用这种思路不行,下面就用代码来讲解下怎么实现。

示例代码如下:👇

#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 != NULL);
const char
s1 = NULL;
const char
s2 = NULL;//在不知道赋值什么的情况下直接赋值空指针。
if (str2 == ‘\0’)
return (char
)str1;//假设str2首元素地址为空字符串直接返回str1
while (*str1)
{
s1 = str1;
s2 = str2;
while (*s1 && *s2 != ‘\0’ && (*s1 == *s2))
{
s1++;
s2++;
}
if (s2 == ‘\0’)
{
return (char
)str1;//注意返回类型强制转换!
}
str1++;
}
return NULL;
}
int main(void)
{
char arr1[20] = “abbcdef”;
char arr2[20] = “bc”;
char *ret = my_strstr(arr1, arr2);
if (ret == NULL)
{
printf(“没找到%s!\n”,ret);
}
else
{
printf(“找到了→%s\n”, ret);
}
return 0;
}

运行结果如下 👇

bcdef

这个代码的实现相对来说比上面的代码都要比较复杂,希望各位理解了可以自己上手做下,因为自有当你把代码打出来了,那么才是你学到的知识。


🎍strtok() - 切割字符串🎍

这个函数比较难懂,比较奇观,使用场景也不多见。

strtok()函数的声明方式如下****👇

char * strtok ( char * str, const char * delimiters );

对该函数的调用序列将str分割成标记,标记是由连续字符组成的序列,由分隔符的任何字符分隔。

在第一次调用时,函数期望一个C的字符串作为str的参数,它的第一个字符被用作扫描标记的起始位置。在随后的调用中,该函数期望得到一个空指针,并使用最后一个标记结束后的位置作为新的扫描起始位置。

要确定标记的开始和结束,函数首先从开始位置扫描分隔符中不包含的第一个字符(它成为标记的开始)。然后从标记的这个开头开始扫描分隔符中包含的第一个字符,这个字符成为标记的结尾。如果找到终止的空字符,扫描也会停止。

这个标记的末尾会被一个空字符自动替换,而该标记的开头则由函数返回。

一旦在strtok调用中找到str的终止空字符,所有后续对该函数的调用(以空指针作为第一个参数)都返回一个空指针。

找到最后一个令牌的位置由函数保存在内部,以便下次调用时使用(为了避免数据竞争,不需要特定的库实现)。

str→要截断的C字符串。注意,这个字符串被分解成更小的字符串(令牌)。
或者,可以指定一个空指针,在这种情况下,函数继续扫描之前对该函数的成功调用结束的地方。

delimiters→包含分隔符字符的C字符串。这些在不同的调用之间可能是不同的。

返回值:如果找到令牌,则指向令牌开头的指针。否则,为空指针。当被扫描的字符串到达字符串的末尾(即一个空字符)时,总是返回一个空指针。

🎍strtok()函数代码示例🎍

题目:把字符串"Hello.Cyuyan.yyds",.之前语句进行分割最后进行打印。用strtok字符串函数实现。

使用**strtok()**函数代码示例如下 👇

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

int main(void)
{
char str[] = “Hello.Cyuyan.yyds”;
printf(“yiduanhua|%s|dezifu\n”, str);
char * pch=strtok(str, “.”);
while (pch != NULL)
{
printf(“%s\n”, pch);
pch = strtok(NULL, “.”);
}
return 0;
}

运行结果如下 👇

Hello.Cyuyan.yyds

Hello

Cyuyan

yyds

不知道你是否明白了( ゚д゚)つ

在这里思考下,那么它使用什么进行保存的呢?就是这个函数它能够记住地址,其实这个只需要用到一个关键字 static 静态局部变量就可以完美实现这种类似于记忆功能,把生命周期延长,出了函数的范围内不会销毁保留原来的值。


🎍strtok()源程序实现🎍

示例代码如下:👇

/***
*strtok.c - tokenize a string with given delimiters
*

  •   Copyright (c) Microsoft Corporation. All rights reserved.
    

*Purpose:

  •   defines strtok() - breaks string into series of token
    
  •   via repeated calls.
    

*******************************************************************************/

#include <cruntime.h>
#include <string.h>
#ifdef _SECURE_VERSION
#include <internal.h>
#else /* _SECURE_VERSION /
#include <mtdll.h>
#endif /
_SECURE_VERSION */

/***
*char *strtok(string, control) - tokenize string with delimiter in control
*
*Purpose:

  •   strtok considers the string to consist of a sequence of zero or more
    
  •   text tokens separated by spans of one or more control chars. the first
    
  •   call, with string specified, returns a pointer to the first char of the
    
  •   first token, and will write a null char into string immediately
    
  •   following the returned token. subsequent calls with zero for the first
    
  •   argument (string) will work thru the string until no tokens remain. the
    
  •   control string may be different from call to call. when no tokens remain
    
  •   in string a NULL pointer is returned. remember the control chars with a
    
  •   bit map, one bit per ascii char. the null char is always a control char.
    

*Entry:

  •   char *string - string to tokenize, or NULL to get next token
    
  •   char *control - string of characters to use as delimiters
    

*Exit:

  •   returns pointer to first token in string, or if string
    
  •   was NULL, to next token
    
  •   returns NULL when no more tokens remain.
    

*Uses:
*
*Exceptions:
*
*******************************************************************************/

#ifdef _SECURE_VERSION
#define _TOKEN context
#else /
_SECURE_VERSION /
#define _TOKEN ptd->_token
#endif /
_SECURE_VERSION */

#ifdef _SECURE_VERSION
char * __cdecl strtok_s (
char * string,
const char * control,
char ** context
)
#else /* _SECURE_VERSION /
char * __cdecl strtok (
char * string,
const char * control
)
#endif /
_SECURE_VERSION */
{
unsigned char *str;
const unsigned char *ctrl = control;

unsigned char map[32];
int count;

#ifdef _SECURE_VERSION

/* validation section */
_VALIDATE_RETURN(context != NULL, EINVAL, NULL);
_VALIDATE_RETURN(string != NULL || *context != NULL, EINVAL, NULL);
_VALIDATE_RETURN(control != NULL, EINVAL, NULL);

/* no static storage is needed for the secure version */

#else /* _SECURE_VERSION */

_ptiddata ptd = _getptd();

#endif /* _SECURE_VERSION */

/* Clear control map */
for (count = 0; count < 32; count++)
map[count] = 0;

/* Set bits in delimiter table */
do {
map[*ctrl >> 3] |= (1 << (*ctrl & 7));
} while (*ctrl++);

/* Initialize str */

/* If string is NULL, set str to the saved

  • pointer (i.e., continue breaking tokens out of the string
  • from the last strtok call) */
    if (string)
    str = string;
    else
    str = _TOKEN;

/* Find beginning of token (skip over leading delimiters). Note that

  • there is no token iff this loop sets str to point to the terminal
  • null (*str == ‘\0’) */
    while ( (map[*str >> 3] & (1 << (*str & 7))) && *str )
    str++;

string = str;

/* Find the end of the token. If it is not the end of the string,

  • put a null there. */
    for ( ; *str ; str++ )
    if ( map[*str >> 3] & (1 << (*str & 7)) ) {
    *str++ = ‘\0’;
    break;
    }

/* Update nextoken (or the corresponding field in the per-thread data

  • structure */
    _TOKEN = str;

/* Determine if a token has been found. */
if ( string == str )
return NULL;
else
return string;
}


🎍strerror() - 返回错误码🎍

该函数的功能是:返回错误码,所对应的错误信息。

strerror() 函数的声明方式如下****👇

char * strerror ( int errnum );

获取指向错误消息字符串的指针。

errnum的值,生成一个字符串,该字符串带有一条描述错误条件的消息,就像库的函数设置为errno一样。头文件是:#include <errno.h>

返回的指针指向一个静态分配的字符串,该字符串不能被程序修改。对该函数的进一步调用可能会覆盖其内容(为了避免数据竞争,不需要特定的库实现)。

strerror产生的错误字符串可能特定于每个系统和库实现。

返回值:该函数返回一个指向错误字符串的指针,该错误字符串描述了错误 errnum。

🎍strerror()函数代码示例🎍

打开文件函数是:fopen()

#include <stdio.h>
#include <string.h>
#include <errno.h>
int main(void)
{
FILE* Pf = fopen(“test.txt”, “r”);//打开文件如果以读的形式存在那么这个文件就会打开失败!
//一旦打开失败那个得到的就是NULL
if (Pf == NULL)
{
printf(“%s\n”, strerror(errno));
return 1;//返回main函数结束
}
fclose(Pf);
Pf = NULL;
return 0;
}

运行结果如下 👇

Error: No such file or directory

当然如果你在安装路径新建上一个test.txt文件就不会显示如上问题。

🎍strerror()源程序实现🎍

示例代码如下:👇

#include <cruntime.h>
#include <errmsg.h>
#include <stdlib.h>
#include <syserr.h>
#include <string.h>
#include <mtdll.h>
#include <tchar.h>
#include <malloc.h>
#include <stddef.h>
#include <dbgint.h>
#include <internal.h>

/* [NOTE: The error message buffer is shared by both strerror
and _strerror so must be the max length of both. /
/
Max length of message = user_string(94)+system_string+2 */
#define ERRMSGLEN (94+_SYS_MSGMAX+2)

#ifdef _UNICODE
#define _terrmsg _werrmsg
#else /* _UNICODE /
#define _terrmsg _errmsg
#endif /
_UNICODE */

/***
*char *strerror(errnum) - Map error number to error message string.
*
*Purpose:

  •   The strerror runtime takes an error number for input and
    
  •   returns the corresponding error message string.  This routine
    
  •   conforms to the ANSI standard interface.
    

*Entry:

  •   int errnum - Integer error number (corresponding to an errno value).
    

*Exit:

  •   char * - Strerror returns a pointer to the error message string.
    
  •   This string is internal to the strerror routine (i.e., not supplied
    
  •   by the user).
    

*Exceptions:

  •   None.
    

*******************************************************************************/

#ifdef _UNICODE
wchar_t * cdecl _wcserror(
#else /* _UNICODE /
char * __cdecl strerror (
#endif /
_UNICODE */
int errnum
)
{
_TCHAR *errmsg;
_ptiddata ptd = _getptd_noexit();
if (!ptd)
return _T(“Visual C++ CRT: Not enough memory to complete call to strerror.”);

if ( (ptd->_terrmsg == NULL) && ((ptd->_terrmsg =
_calloc_crt(ERRMSGLEN, sizeof(_TCHAR)))
== NULL) )
return _T(“Visual C++ CRT: Not enough memory to complete call to strerror.”);
else
errmsg = ptd->_terrmsg;

#ifdef _UNICODE
_ERRCHECK(mbstowcs_s(NULL, errmsg, ERRMSGLEN, _get_sys_err_msg(errnum), ERRMSGLEN - 1));
#else /* _UNICODE /
_ERRCHECK(strcpy_s(errmsg, ERRMSGLEN, _get_sys_err_msg(errnum)));
#endif /
_UNICODE */

return(errmsg);
}

/***
*errno_t strerror_s(buffer, sizeInTChars, errnum) - Map error number to error message string.
*
*Purpose:

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Go)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
This string is internal to the strerror routine (i.e., not supplied

  •   by the user).
    

*Exceptions:

  •   None.
    

*******************************************************************************/

#ifdef _UNICODE
wchar_t * cdecl _wcserror(
#else /* _UNICODE /
char * __cdecl strerror (
#endif /
_UNICODE */
int errnum
)
{
_TCHAR *errmsg;
_ptiddata ptd = _getptd_noexit();
if (!ptd)
return _T(“Visual C++ CRT: Not enough memory to complete call to strerror.”);

if ( (ptd->_terrmsg == NULL) && ((ptd->_terrmsg =
_calloc_crt(ERRMSGLEN, sizeof(_TCHAR)))
== NULL) )
return _T(“Visual C++ CRT: Not enough memory to complete call to strerror.”);
else
errmsg = ptd->_terrmsg;

#ifdef _UNICODE
_ERRCHECK(mbstowcs_s(NULL, errmsg, ERRMSGLEN, _get_sys_err_msg(errnum), ERRMSGLEN - 1));
#else /* _UNICODE /
_ERRCHECK(strcpy_s(errmsg, ERRMSGLEN, _get_sys_err_msg(errnum)));
#endif /
_UNICODE */

return(errmsg);
}

/***
*errno_t strerror_s(buffer, sizeInTChars, errnum) - Map error number to error message string.
*
*Purpose:

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Go)
[外链图片转存中…(img-buVVzjkf-1713174517830)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 13
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值