一起笨笨的学C——014grep特别版

           

目录

前言

正文

原文:

要求总结:

一`点一点来:

grep学习:

glob理解:

dirent 目录函数:

加载日志文件:

 strstr与strcmp:

非首次尝试:

非二次 :

老师的:

读老师的函数一点一点来的补充:

  后语

3、老师的程序读后感:

4、glob与dirent区别:


前言

嗨,项目初体验,收获满满!

认知的圆越大,感受的压力就越多!所以说要化圆为梭、为剑,方能驰骋知识的宇宙!


正文

原文:

看到一个箭头指向的按钮了吗?你也可以试一下哦,嘿嘿……只不过可能获得 满身全是浮躁的buff。尤其是当下炎炎夏日,还能增幅120%!

要求总结:

根据grep的使用及glob函数理解,把项目要求整理下

  1. logfind  pattern file  这个命令日志文件夹下到在指定文件中搜索匹配指定模式的行,并将匹配的行输出到屏幕上。例如,logfind "eJSu" file.log将搜索file.txt文件中包含"eJSu"的行。
  2. logfind pattern  到日志文件夹查找匹配指定模式的文件,并将匹配的行输出到屏幕上,如果是多个词语就是“和”的关系。
  3. loafing -o pattern 到日志文件夹查找匹配指定模式的文件,并将匹配的行输出到屏幕上,如果是多个词语就是“或”的关系

感觉原文翻译的4描述很别扭,暂且这样,最后看看与作者的代码差距在哪里吧!

一`点一点来:

grep学习:

grep是一个非常强大的命令行工具,用于在文件中搜索指定的模式。它可以使用正则表达式作为模式,并可以通过多种选项和参数来进行精确的搜索和过滤。grep的使用方法和实例如下:

  1. 基本用法: grep pattern file 这个命令将在指定文件中搜索匹配指定模式的行,并将匹配的行输出到屏幕上。例如,grep "hello" file.txt将搜索file.txt文件中包含"hello"的行。

  2. 使用正则表达式: grep支持使用正则表达式作为模式。正则表达式可以包含特殊字符和元字符,用于指定搜索模式的规则。例如,grep "^[0-9]" file.txt将搜索file.txt文件中以数字开头的行。

  3. 忽略大小写: grep -i pattern file 使用-i选项可以忽略模式的大小写,即不区分大小写地搜索匹配项。例如,grep -i "hello" file.txt将搜索file.txt文件中包含"hello"或"HELLO"等的行。

  4. 显示行号: grep -n pattern file 使用-n选项可以显示匹配行的行号。行号将显示在每行的前面。例如,grep -n "hello" file.txt将搜索file.txt文件中包含"hello"的行,并显示行号。

  5. 搜索多个文件: grep pattern file1 file2 ... 可以同时在多个文件中搜索指定模式。grep将逐个文件输出匹配的行。例如,grep "hello" file1.txt file2.txt将搜索file1.txt和file2.txt文件中包含"hello"的行。

  6. 递归搜索目录: grep -r pattern directory 使用-r选项可以递归地搜索指定目录及其子目录中的文件。例如,grep -r "hello" /path/to/directory将搜索/path/to/directory目录及其子目录中包含"hello"的行。

  7. 打印匹配行之前或之后的内容: grep -A num -B num -C num pattern file 使用-A, -B, -C选项可以打印匹配行之前(-B)、之后(-A)或之前和之后(-C)的指定行数的内容。例如,grep -A 2 "hello" file.txt将搜索file.txt文件中包含"hello"的行,并打印匹配行及其后两行的内容。

  8. 反向匹配: grep -v pattern file 使用-v选项可以反向匹配,即只输出不匹配模式的行。例如,grep -v "hello" file.txt将搜索file.txt文件中不包含"hello"的行。

  9. 统计匹配行数: grep -c pattern file 使用-c选项可以统计匹配模式的行数,并将结果输出。例如,grep -c "hello" file.txt将统计file.txt文件中包含"hello"的行数。

glob理解:

在C语言中,可以使用glob函数来实现文件名模式匹配,查找符合特定模式的文件名。

glob函数的原型如下:

#include <glob.h>

int glob(const char *pattern, int flags, int (*errfunc)(const char *epath, int errno), glob_t *pglob);

参数解释:

  • pattern:需要匹配的模式字符串
  • flags:匹配选项,可以是以下常量的按位或组合:
    • GLOB_ERR:发生错误时,停止匹配
    • GLOB_MARK:如果匹配到的是目录,则在末尾添加一个斜杠
    • GLOB_NOSORT:不对匹配到的文件名进行排序
    • GLOB_NOESCAPE:不对模式中的特殊字符进行转义
    • GLOB_ONLYDIR:只匹配目录
    • GLOB_TILDE:对~进行波浪号扩展
    • GLOB_TILDE_CHECK:只对~进行波浪号扩展,如果用户不存在,则报错
  • errfunc:错误处理函数,可以为NULL
  • pglob:用于存储匹配结果的glob结构体变量:
    • size_t gl_pathc:表示匹配到的文件名数量。
    • char **gl_pathv:表示匹配到的文件名列表,是一个指向字符数组的指针。
    • size_t gl_offs:用于控制gl_pathv数组的起始位置。

glob函数的返回值为0表示匹配成功,其他值表示错误。

下面是一个使用glob函数的示例:

#include <stdio.h>
#include <glob.h>

int main() {
    glob_t pglob;
    int i, ret;

    ret = glob("/path/to/files/*.txt", 0, NULL, &pglob);
//调用glob函数进行模式匹配。指定的模式是"/path/to/files/*.txt",
//表示匹配以.txt结尾的文件名。传入的flags参数为0,表示使用默认的匹配选项。
    if (ret != 0) {
        printf("Error in glob\n");
        return 1;
    }

    for (i = 0; i < pglob.gl_pathc; i++) {
        printf("%s\n", pglob.gl_pathv[i]);
    }

    globfree(&pglob);

    return 0;
}

在上述示例中,glob函数被用来查找目录/path/to/files/下所有以.txt结尾的文件名,并将结果存储到pglob结构体变量中。然后通过遍历pglob.gl_pathv数组来输出匹配到的文件名。最后,使用globfree函数释放pglob变量占用的内存。

dirent 目录函数:

不知道何如开始这个项目时,就随便搜索了下,发现要用到目录函数。目录函数没接触过,不熟悉,那就先熟悉dirent。



#include <stdio.h>
#include <dirent.h>
#include "dbg.h"

int main(int argc, char *argv[])
{
        DIR *dir = opendir(".");//这个点号 是表示当前文件夹
        check(dir != NULL, "Failed open the dir");
        struct dirent *ent ;
        char filepath[1024];
        int i = 0;

        while ((ent = readdir(dir)) != NULL){//此循环是经典的用法,循环一次,
                                            //读取一个文件,还能检查是否读完
        snprintf(filepath, sizeof(filepath), "%s/%s","lcthw",  ent->d_name);
        printf("i>>:%d%s",i++,  filepath);
        }

        closedir(dir);

        return 0;
error:
        return -1;
}

        由于用的是linux,对它曾经一知半解过,所以我首先迷失在了万物起源"."(点号)。原来它就是代表当前文件夹,你把程序放在哪个文件夹,它就遍历哪个文件夹。

        由于对文件函数曾经好好的较量过,发现这个目录函数使用过程与文件使用过程相似。可能是因为一个是文件流,一个目录流,都是流。嗯,一个FILE, 一个DIR。

        看看是不是?

        好的,dirent基本操作熟悉了,课文要求我们跑到指定地方搜索日志文件。

加载日志文件:

        什么是系统日志文件及存放位置呢?

        我用的是linux,系统日志文件通常被存储在/var/log目录下。各个日志文件的具体路径和后缀名如下:

  • /var/log/messages:系统和服务的一般消息日志。
  • /var/log/auth.log:包含系统授权和认证活动的日志。
  • /var/log/kern.log:内核日志,记录与内核相关的消息和错误。
  • /var/log/syslog:所有系统日志的综合文件,包括其他日志文件的内容。
  • /var/log/dmesg:内核环缓冲区的内容,用于存储系统启动时的消息。
  • /var/log/boot.log:在系统引导期间生成的启动日志。
  • /var/log/secure:记录与系统安全性相关的信息,如认证、授权和权限更改。

        此外,不同的服务和应用程序可能会有自己的日志文件,它们通常位于/var/log目录下,具有与服务或应用程序相关的名称和后缀名。

        需要注意的是,这只是一些常见的日志文件示例,具体的日志文件路径和后缀名可能因Linux发行版和配置而异。在某些情况下,我们也可以在/etc/rsyslog.conf文件中配置日志文件的位置和后缀名。

        我们就找/var/log目录下的日志文件吧,后缀名log。看看我的乌班图linux日志文件:

        健壮的代码需要深厚的内功的,显然我刚有气感。所以咱们就简单的以后缀名查找,示例如下。      

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

int main() {
    char filename[] = "example.log";
    char *extension;

    // 找到文件名中的最后一个点号
    extension = strrchr(filename, '.');

    if (extension != NULL) {
        // 比较后缀名是否为.log
        if (strcmp(extension, ".log") == 0) {
            printf("The file is a log file.\n");
        } else {
            printf("The file is not a log file.\n");
        }
    } else {
        printf("The file has no extension.\n");
    }

    return 0;
}
 
 strstr与strcmp:

在C语言中,strstrstrcmp是字符串处理函数。

strstr函数用于在一个字符串中查找指定子字符串的第一次出现,并返回子字符串的指针。其函数原型为:

char* strstr(const char* str1, const char* str2);

其中,str1是要搜索的字符串,str2是要查找的子字符串。如果找到了子字符串,则返回子字符串第一次出现的位置的指针;如果没有找到子字符串,则返回NULL

示例用法:

const char* str1 = "Hello, World!";
const char* str2 = "World";
const char* result = strstr(str1, str2);
if (result)
    printf("Found at position: %d\n", result - str1);
else
    printf("Not found.\n");

上述代码将输出 "Found at position: 7",因为子字符串 "World" 在字符串 "Hello, World!" 中的位置从索引7开始。

strcmp函数用于比较两个字符串的大小。其函数原型为:

int strcmp(const char* str1, const char* str2);

其中,str1str2都是要进行比较的字符串。函数返回值为0表示两个字符串相等,返回值小于0表示str1小于str2,返回值大于0表示str1大于str2

示例用法:

const char* str1 = "Hello";
const char* str2 = "World";
int result = strcmp(str1, str2);
if (result == 0)
    printf("The strings are equal.\n");
else if (result < 0)
    printf("The first string is smaller.\n");
else
    printf("The first string is larger.\n");

上述代码将输出 "The first string is smaller.",因为字符串 "Hello" 在字母表中比字符串 "World" 小。

非首次尝试:

#define NDEBUG

#include <stdio.h>
#include <string.h>
#include "dbg.h"
#include <stdlib.h>
#include <dirent.h>

#define N 256

void file_find(char *filename, char *searchword)
{
	char str[N];

	FILE *fp;
	fp = fopen(filename, "r");
	check(fp, "fail open");

	debug("filename:%s", filename);
	while(fgets(str, N, fp) != NULL){
		if(strstr(str,searchword) != NULL){//用于在一个字符串中查找另一个字符串第一次出现的位置。没有则返回NULL。
			printf("str:%s", str);
		}
	}

	fclose(fp);
	return;
error:
	 exit(-1);
}

int dir_find( char *searchword)
{
	DIR *dir =opendir("/var/log");
	check(dir, "fail read dir");

	struct dirent *ent ;

	char str[N];

	FILE *fp;

	while ((ent = readdir(dir)) != NULL){
		snprintf(str, sizeof(str), "%s", ent->d_name);
		debug("filename:%s", str);
		fp = fopen(str, "r");
		check(fp, "fail open the file in the dir");

		while(fgets(str, N, fp) != NULL){
			if(strstr(str,searchword) != NULL){//用于在一个字符串中查找另一个字符串第一次出现的位置。没有则返回NULL
					printf("str:%s", str);
			}
		}	

	}

	fclose(fp);
	return 0;
error:
	 exit(-1);
}

int main(int argc, char *argv[])
{
	check((argc >1), "Please input arg");
	
	if(strcmp(argv[1], "-o") == 0){//如果两个字符串一样则返回1. "-o"biaoshi huo "||".
	  debug();
		check(argc = 2,"USAGE: ./file -o patter");
			for (int i = 2; i<argc; i++){
				if(strstr(argv[2], ".log") != NULL){
					debug("argv[2]:%s, argv[i]:%s", argv[2], argv[i]);
					file_find(argv[2], argv[i++]);
				}else{
				dir_find(argv[i]);
				}
			}	
	}else{
			 int j =1;
			if(strstr(argv[1], ".") != NULL){
				while(j < (argc)){
					file_find(argv[1], argv[j++]);
				}else{
				while (dir_find(argv[j]) == 0 ){
					if (j < (argc)){
						j++;
						continue;
					}else{
						printf("find the file\n");
						}
				}
					printf("No find\n");
			
			}	
		}
		
	
	  log_info("right end");

	return 0;
error:
	return -1;
}

非二次 :

留个坑,嘿嘿……

老师的:

#define NDEBUG
#include "dbg.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glob.h>
#include <assert.h>

const size_t MAX_LINE = 1024;


int list_files(glob_t *pglob) 
{
    char *line = calloc(MAX_LINE, 1);
    FILE *file = fopen(".logfind", "r");
    int glob_flags = GLOB_TILDE;
    int i = 0;
    int rc = -1;

    check(pglob != NULL, "Invalid glob_t given.");
    check_mem(line);
    check(file, "Failed to open .logfind. Make that first.");

    while(fgets(line, MAX_LINE-1, file) != NULL) {
        size_t line_length = strnlen(line, MAX_LINE - 1);
        assert(line_length < MAX_LINE && "Got a line length too long.");

        line[line_length] = '\0'; // drop the \n ending
        debug("Globbing %s", line);

        rc = glob(line, glob_flags, NULL, pglob);
        check(rc == 0 || rc == GLOB_NOMATCH, "Failed to glob.");

        // dumb work around to a stupid design in glob
        if(glob_flags == GLOB_TILDE) glob_flags |= GLOB_APPEND;
    }

    for(i = 0; i < pglob->gl_pathc; i++) {
        debug("Matched file: %s", pglob->gl_pathv[i]);
    }

    rc = 0; // all good

error: // fallthrough
    if(line) free(line);
    return rc;
}

int found_it(int use_or, int found_count, int search_len)
{
    debug("use_or: %d, found_count: %d, search_len: %d", use_or, found_count, search_len);

    if(use_or && found_count > 0) {
        return 1;
    } else if(!use_or && found_count == search_len) {
        return 1;
    } else {
        return 0;
    }
}

int scan_file(const char *filename, int use_or, int search_len, char *search_for[])
{
    char *line = calloc(MAX_LINE, 1);
    FILE *file = fopen(filename, "r");
    int found_count = 0;
    int i = 0;

    check_mem(line);
    check(file, "Failed to open file: %s", filename);

    // read each line of the file and search that line for the contents
    while(fgets(line, MAX_LINE-1, file) != NULL)
    {
        for(i = 0; i < search_len; i++) {
            if(strcasestr(line, search_for[i]) != NULL) {
                debug("file: %s, line: %s, search: %s", filename, line, search_for[i]);
                found_count++;
            }
        }

        if(found_it(use_or, found_count, search_len)) {
            printf("%s\n", filename);
            break;
        } else {
            found_count = 0;
        }
    }


    free(line);
    fclose(file);
    return 0;

error:
    if(line) free(line);
    if(file) fclose(file);

    return -1;
}

int parse_args(int *use_or, int *argc, char **argv[]) 
{
    (*argc)--;
    (*argv)++;

    if(strcmp((*argv)[0], "-o") == 0) {
        *use_or = 1;
        (*argc)--; // skip the -o
        (*argv)++;
        check(*argc > 1, "You need words after -o.");
    } else {
        *use_or = 0;
    }

    return 0;
error:
    return -1;
}


int main(int argc, char *argv[])
{
    int i = 0;
    int use_or = 1;
    glob_t files_found;

    check(argc > 1, "USAGE: logfind [-o] words");

    check(parse_args(&use_or, &argc, &argv) == 0, "USAGE: logfind [-o] words");

    check(list_files(&files_found) == 0, "Failed to list files.");

    for(i = 0; i < files_found.gl_pathc; i++) {
        scan_file(files_found.gl_pathv[i], use_or, argc, argv);
    }

    globfree(&files_found);
    return 0;

error:
    return 1;
}
读老师的函数一点一点来的补充:

1、strnlen:

在C语言中,strnlen是一个用于求取字符串长度的函数,它的作用是返回一个字符串的长度,但不会超过指定的最大长度。

strnlen函数的函数原型如下:

size_t strnlen(const char *str, size_t maxlen);

  • str:要计算长度的字符串的指针。
  • maxlen:要计算的最大长度。

strnlen函数会从str指向的字符串开始计数,直到遇到字符串结尾的空字符\0或者达到最大长度maxlen,并返回实际的字符串长度。

strlen不同的是,strnlen函数会限制计算的长度不超过maxlen,这样可以避免访问超过字符串长度的内存,从而增加安全性。

示例用法:

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

int main() {
    char str[] = "Hello, World!";
    
    size_t len1 = strnlen(str, 5);
    size_t len2 = strnlen(str, sizeof(str));
    
    printf("len1: %zu\n", len1);
    printf("len2: %zu\n", len2);
    
    return 0;
}

运行结果:

len1: 5
len2: 13

在上述示例中,strnlen(str, 5)计算了str的长度,但限制在最大长度为5,因此返回的长度为5。而strnlen(str, sizeof(str))计算了str的长度,没有设置最大限制,所以返回的长度为整个字符串的长度。

2、assert:

在C语言中,assert是一个宏,用于在程序运行时检查一个表达式是否为真。如果表达式为假(即0),assert宏会触发一个断言失败,并通过标准错误流输出一条错误消息,并终止程序的执行。

assert的基本语法是:

#include <assert.h>

void assert(int expression);

其中,expression是需要判断的条件表达式,如果为假则断言失败,输出错误消息。如果表达式为真,则assert宏不做任何操作。

下面是一个使用assert宏的示例:

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

int divide(int x, int y){
    assert(y != 0);
    return x / y;
}

int main(){
    printf("%d\n", divide(10, 2)); // 输出 5
    printf("%d\n", divide(10, 0)); // 断言失败,程序终止
}

在上面的示例中,assert宏用于判断除数y是否为零。如果为零,则断言失败,程序终止,并输出一条错误消息。

需要注意的是,在发布版本的程序中,assert宏会被宏定义NDEBUG禁用,因此断言检查将被跳过,不会导致程序终止。只有在开发和调试阶段使用断言进行错误检查是有意义的。(老师得的dbg宏也同样如此!)


  后语

1、这个项目的构思,由于纯粹自己构思,打翻了好几次想法。就像跟客户沟通一样,呵呵。

2、本来想放弃了,但是仔细一想,这个才是比较正式的学习笔记吧,干吧!

3、老师的程序读后感:

老师的程序就像一首诗!短短几行,让bug无处可藏!看那行首的预言吧!看看那整齐的check,看看error后面的if,怎能不让人佩服!代码虽然不多,却处处透着健壮,就像经常锻炼的人身上,没有一丝赘肉!老师的程序是一首诗,那是一首“稳健”的诗!

本以为就要出师,才知道差一点要“出事”。

范文没有用到目录函数,glob有这作用,那么问题来了,glob是不是用dirent编写的呢?

4、glob与dirent区别:

glob函数并不是用dirent函数编写的。glob函数是C标准库中的一个函数,用于匹配文件路径名模式,并返回符合条件的文件名列表。

dirent函数是用于遍历目录中的文件和子目录的函数,它可以用于获取目录中的文件名,并判断文件类型。

虽然glob函数和dirent函数都可以用于处理文件和目录,但它们的功能和用法是不同的。glob函数是用于模式匹配文件名,它支持通配符,比如*?,可以根据给定的模式匹配符合条件的文件名,并将这些文件名存放在一个glob_t结构体中。

另一方面,dirent函数是用于获取目录中的文件和子目录的函数,它提供了一组函数,如opendirreaddirclosedir,用于打开和关闭目录,以及获取目录中的文件名和子目录名。

因此,虽然glob函数和dirent函数都涉及到文件和目录的处理,但它们是不同的函数,用途和实现方式也不相同。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

易兆微电子_嵌入式软件工程师笔试题

易先电子 嵌入式软件工程师笔试题(十七) 1.关键字 extern是什么含义, 请举例说明。 修饰符extern用在变量或者函数的声明前&#xff0c;用来说明 “ 此变量 / 函数是在别处定义的&#xff0c;要在此处引用 ”。 //main.c #include <stdio.h>int main() {extern int num…

英国牛津大学基因组学方向博士后职位

英国牛津大学基因组学方向博士后职位 牛津大学&#xff08;University of Oxford&#xff09;&#xff0c;简称“牛津”&#xff08;Oxford&#xff09;&#xff0c;位于英国牛津&#xff0c;是一所公立研究型大学&#xff0c;采用传统学院制。是罗素大学集团成员&#xff0c;被…

商超智能守护:AI监控技术在零售安全中的应用

结合思通数科大模型的图像处理、图像识别、目标检测和知识图谱技术&#xff0c;以下是详细的商超合规监测应用场景描述&#xff1a; 1. 员工仪容仪表监测&#xff1a; 利用图像识别技术&#xff0c;系统可以自动检测员工是否按照规范整理妆容、穿着工作服&#xff0c;以及是否…

管理咨询公司的五个招聘秘密

在管理咨询中&#xff0c;人是业务&#xff1b;客户支付数百万美元&#xff0c;要求管理顾问确认问题&#xff0c;并推荐解决方案。由于收入和合规性受到威胁&#xff0c;招聘错误的成本可能非常昂贵&#xff0c;一些公司更倾向于谨慎而不是效率。然而&#xff0c;在当今竞争激…

Nexus安卓木马分析报告

概述 2023年3月21日晚上&#xff0c;链安与中睿天下联合研发的监控系统检测到一种新型安卓木马。在经过睿士沙箱系统捕获样本之后&#xff0c;发现该安卓木马极有可能是原安卓网银盗号木马SOVA的变种。与此同时&#xff0c;意大利安全公司Cleafy发布了一篇题为《Nexus&#xf…

API接口对接的步骤流程?有哪些注意事项?

API接口对接自动化的实现方法&#xff1f;如何调试API接口发信&#xff1f; 在现代软件开发中&#xff0c;API接口对接已成为各个系统和应用之间进行通信和数据交换的关键技术。AokSend将详细介绍API接口对接的步骤流程&#xff0c;帮助开发者更好地理解和实现这一过程。 API…

VScode基本使用

VScode下载安装&#xff1a; Visual Studio Code - Code Editing. Redefined MinGW的下载安装&#xff1a; MinGW-w64 - for 32 and 64 bit Windows - Browse Files at SourceForge.net x86是64位处理器架构&#xff0c;i686是32为处理器架构。 POSIX和Win32是两种不同的操…

Spring Cloud Gateway网关下的文档聚合(knife4j)

文章目录 引言I 服务发现自动聚合(discover)1.1 配置1.2 服务发现的路由聚合策略-数据来源1.3 编写动态路由实现类II 其他2.1 网关动态加载swagger路由和配置2.2 无法处理 lb://URI,返回503错误。2.3 SpringBoot3 解决NoResourceFoundException: No static resource favicon.i…

数据结构与算法-差分数组及应用

差分数组 差分数组&#xff1a; 其实差分数组是创建一个一个辅助数组&#xff0c;用来表示给定数组的变化&#xff0c;一般用来对数组进行区间修改的操作。 频繁操作数组区间的问题 假设我们要对一个数组进行区间操作。数组为 a {10,10, 20,20,50,… 100}。数组数据比较多。 对…

羊大师:培养儿童配得感,从自我认知开始

在儿童的成长过程中&#xff0c;配得感的培养是至关重要的。配得感&#xff0c;即孩子认为自己值得拥有美好事物和得到他人关爱的一种心理状态&#xff0c;是孩子自信心和自尊心的基石。而自我认知&#xff0c;则是培养配得感的第一步。 我们要引导孩子正确地认识自己。每个孩子…

vant组件 顶部下拉刷新和页面底部下拉获取数据

1.html部分&#xff08;顶部tab切换无&#xff0c;只有主体list部分&#xff09; <div class"yd" ><!-- yd端 --><van-pull-refresh v-model"refreshing" refresh"onRefresh"><van-listv-model"ydloading":finis…

【SpringCloud】Eureka的简单使用

本文使用的是jdk17&#xff0c;mysql8。 以下用两个服务做演示&#xff1a; 订单服务&#xff1a;提供订单ID&#xff0c;获取订单详细信息。 商品服务&#xff1a;提供商品ID&#xff0c;获取商品详细信息。 对于上篇http://t.csdnimg.cn/vcWpo 订单服务调用商品服务的时候&a…

Markdown 生成 Epub (Typora + pandoc)

文章目录 一、安装 pandoc二、Typora pandoc 导出 Pandoc 文件三、看看效果 一、安装 pandoc macOS 上使用 brew 安装 brew install pandoc其他系统可见&#xff1a;https://pandoc.org/installing.html 安装成功后查看版本 pandoc --version$ pandoc --version pandoc 2.1…

PS选不了颜色和路径描边?PS不知为何才能描边任意路径,这个办法让你秒懂

在选中路径的情况下&#xff0c;按图下操作&#xff0c;即可制作路径&#xff08;不会让你选不了颜色和路径描边&#xff09;

ArcGIS查找相同图斑、删除重复图斑

​ 点击下方全系列课程学习 点击学习—>ArcGIS全系列实战视频教程——9个单一课程组合系列直播回放 点击学习——>遥感影像综合处理4大遥感软件ArcGISENVIErdaseCognition 这次是上次 今天分享一下&#xff0c;很重要却被大家忽略的两个工具 这两个工具不仅可以找出属性…

聊一聊 Monitor.Wait 和 Pluse 的底层玩法

一&#xff1a;背景 1. 讲故事 在dump分析的过程中经常会看到很多线程卡在Monitor.Wait方法上&#xff0c;曾经也有不少人问我为什么用 !syncblk 看不到 Monitor.Wait 上的锁信息&#xff0c;刚好昨天有时间我就来研究一下。 二&#xff1a;Monitor.Wait 底层怎么玩的 1. 案…

【启明智显产品分享】Model3工业级HMI芯片详解系列专题(三):安全、稳定、高防护

芯片作为电子设备的核心部件&#xff0c;&#xff0c;根据不同的应用领域被分为不同等级。工业级芯片适用于工业自动化、控制系统和仪器仪表等领域&#xff0c;对芯片的安全、稳定、防护能力等等有着较高的要求。这些芯片往往需要具备更宽的工业温度范围&#xff0c;能够在更恶…

阿里云服务器提醒漏洞要不要打补丁?

我们自己用的电脑一旦发现漏洞&#xff0c;往往是第一时间进行打补丁重启等等&#xff0c;但是作为服务器而言&#xff0c;往往没有这个习惯&#xff0c;为什么&#xff1f;因为害怕服务器打补丁以后&#xff0c;重启后出现打不开的情况&#xff0c;毕竟稳定的运行似乎在这种情…

最新版Cisco Packet Tracer思科模拟器Windows版本64位下载

Cisco Packet Tracer是思科公司推出的一款网络仿真工具&#xff0c;主要用于网络教学、培训和实验。它提供了一个真实的网络环境模拟平台&#xff0c;让用户可以设计、构建和调试网络&#xff0c;以及进行实时互动&#xff0c;从而帮助用户理解和实践网络技术。 通过 Cisco Pa…

稳定运行 极限生存│美创韧性运行安全体系正式发布

在全面数字化的今天&#xff0c;时刻运转的业务、实时流转的数据&#xff0c;已成为组织生产经营不可或缺的基石。然而&#xff0c;云化、国产化深入推进&#xff0c;数据快速增长&#xff0c;数据库、应用、中间件等信息化资产日益散杂多乱&#xff0c;给组织的运行安全带来更…