Linux上的C语言编程实践
说明:
这是个人对该在Linux平台上的C语言学习网站笨办法学C上的每一个练习章节附加题的解析和回答
ex1:
- 在你的文本编辑器中打开
ex1
文件,随机修改或删除一部分,之后运行它看看发生了什么。
vim ex1.c打开ex1.c
文件。假如我们删除return 0;
这一行代码,保存文件后,在命令行中进入该文件所在目录,然后尝试运行程序(执行./ex1
命令,前提是之前已经成功编译生成了ex1
可执行文件)。
结果:根据 C 语言程序的运行机制,main
函数如果没有显式的return
语句,在大多数实现中,函数执行结束时会隐式返回一个默认值(通常是0
,但这依赖于具体编译器实现)。而在运行时,由于程序逻辑本身没有依赖return
值去做进一步操作,所以程序可能依然能够输出Hello world.
,看起来好像正常运行了,但从代码规范性角度是存在问题的。
- 再多打印5行文本或者其它比
"Hello world."
更复杂的东西。
跳过
- 执行
man 3 puts
来阅读这个函数和其它函数的文档。
命令行中会显示puts
函数的详细文档信息,包括函数的功能描述(例如它用于向标准输出设备输出字符串,并自动在末尾添加一个换行符)、函数的原型(int puts(const char *s);
)、函数的参数说明(s
参数是要输出的字符串指针)、函数的返回值含义(成功时返回一个非负整数,出错时返回EOF
)等内容。同时,在该手册页中还会列出与之相关的其他一些函数(比如printf
、fputs
等函数)的简单介绍和参考位置
ex2:
- 创建目标
all:ex1
,可以以单个命令make
构建ex1
。
在 Makefile 里定义了 all 这个目标,并且让它依赖于 ex1,这意味着当执行 make 命令时(如果没有 指定具体目标,默认会执行 Makefile 里的第一个目标或者由 .DEFAULT_GOAL 指定的目标,这里添加 all 目标后通常就会执行它),make 会先检查 ex1 是否需要更新(例如其依赖的 ex1.c 文件是否有修改 等情况),如果需要更新就会执行 ex1 目标下定义的构建命令(即 cc $(CFLAGS) ex1.c -o ex1)来生 成 ex1 文件,这样就实现了通过单个 make 命令来构建 ex1 的功能。CFLAGS=-Wall -gall: ex1clean:rm -f ex1ex1: ex1.ccc $(CFLAGS) ex1.c -o ex1
- 阅读
man make
来了解关于如何执行它的更多信息。
跳过
- 阅读
man cc
来了解关于-Wall
和-g
行为的更多信息。
-Wall,会详细说明它启用的具体警告类别,解释不同警告所对应的代码潜在问题类型,比如变量未使用 、类型不兼容、隐式函数声明等各种情况产生的警告。而对于 -g,会讲解它如何在生成的可执行文件中 嵌入调试信息,像调试符号的存储格式、在使用调试工具(如 gdb)时如何利用这些调试信息来定位代码中的问题(例如查看变量值、跟踪函数调用流程等操作如何基于这些调试符号实现)等内容。
- 在互联网上搜索Makefile文件,看看你是否能改进你的文件。
找到文件如下:CC = gcc # 指定编译器 CFLAGS = -Wall -Wextra -g # 执行的make命令的可选选项,-Wall 表示启用所有警告,-Wextra 是额外的警告选项,会进一步给出更多类型的警告信息,-g 选项用于在生成的目标文件中添加调试信息,方便后续使用调试工具(如 gdb)来调试程序 LDFLAGS = -lm # 用于指定链接阶段的选项,-lm 表示要链接数学库(libm) SRC = $(wildcard src/*.c) # 使用 wildcard 函数来查找 src 目录下所有以 .c 为后缀的源文件 OBJ = $(SRC:.c=.o) # 变量替换,将 SRC 变量中每个文件名的后缀 .c 替换为 .o,从而得到对应的目标文件 TARGET = myprogram # 定义了最终要生成的可执行文件的名称为 myprogram.PHONY: all clean # 声明 all 和 clean 为伪目标。伪目标并不对应实际的文件,而是代表一些操作或者规则; 用伪目标可以避免与可能存在的同名文件产生冲突,保证规则正常执行all: $(TARGET) #定义了 all 这个目标依赖于 $(TARGET)$(TARGET): $(OBJ)$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) # $@代表当前规则的目标,这里为$(TRAGET);$^ 表示所有依赖,在这里就是所有的 .o 文件; -o 选项为指定生成文件名称%.o: %.c # 将所有.c 文件依赖.o 文件$(CC) $(CFLAGS) -c -o $@ $< # $< 表示第一个依赖,在这里就是对应的 .c 源文件clean:rm -f $(OBJ) $(TARGET)
- 在另一个C语言项目中找到
Makefile
文件,并且尝试理解它做了什么。
在github上找了一个开源的项目nginx/nginx: The official NGINX Open Source repository.的Makefile的,内容如下:# Compiler and linker settings CC = cc CFLAGS = -O2 -pipe -Wall # -O2 一种优化级别选项,它指示编译器对代码进行一定程度的优化,以提高生成的可执行文件的运行效率;-pipe 让编译器在编译过程中使用管道来传递中间结果,这样可以加快编译速度 LDFLAGS = # 用于指定链接阶段的选项,这里为空表示暂时没有额外添加特定的链接相关设置# Targets all: buildbuild:$(CC) $(CFLAGS) -o nginx src/*.c $(LDFLAGS) # src 目录下所有的 .c 源文件进行编译,然后通过 -o nginx 将生成的可执行文件命名为 nginxclean:rm -f nginx *.o # 强制删除名为 nginx 的可执行文件以及所有后缀为 .o 的目标文件
ex3:
- 找到尽可能多的方法使
ex3
崩溃。
改变格式化占位符与参数类型不匹配:
将 printf("I am %d years old.\n", age); 中的 %d 改为 %s,像这样 printf("I am %s years old.\n", age);,然后重新编译运行。由于 %s 期望传入的是字符串指针类型的参数,而这里传入的是 int 类型的 age,编译器会给出类型不匹配相关警告。
传入的参数个数少于格式化字符串中占位符个数:
修改 printf 语句为 printf("I am %d years %d old\n", age);,也就是在格式字符串中多写了一个 %d 占位符,但只传入了一个 age 参数。重新编译时,编译器会提示参数数量不足的警告,运行时程序输出结果会是错误的,可能会输出一些随机的数值来填充多余的占位符对应的位置,导致输出不符合预期,甚至可能因非法内存访问等原因而崩溃。
格式化字符串中使用非法的转义序列:
把 printf("I am %d years old.\n", age); 中的 \n 改为比如 \z(\z 不是合法的转义序列),变成 printf("I am %d years old.\z", age);,编译时编译器可能会给出关于非法转义序列的警告。
- 执行
man 3 printf
来阅读其它可用的'%'格式化占位符。如果你在其它语言中使用过它们,应该看着非常熟悉(它们来源于printf
)。
除了常见的 %d(用于输出十进制整数)、%s(用于输出字符串)外,还有比如:
%f:用于输出浮点数,例如 float num = 3.14; printf("The number is: %f\n", num); 可以将浮点数 num 的值以常规的小数形式输出。
%c:用于输出单个字符,像 char ch = 'A'; printf("The character is: %c\n", ch); 能输出字符 A。
%x 或 %X:分别用于以十六进制小写形式和大写形式输出整数,例如 int hex_num = 255; printf("The hex number is: %x\n", hex_num); 会输出 ff(以小写十六进制展示整数 255 的值),若使用 %X 则会输出 FF。
%o:用于以八进制形式输出整数,如 int oct_num = 10; printf("The octal number is: %o\n", oct_num); 会输出 12(八进制下 10 的表示)。
%p:用于输出指针的值(以十六进制形式展示内存地址),例如 int *ptr = # printf("The pointer address is: %p\n", ptr); 可以输出 ptr 指针所指向的内存地址(十六进制格式)。
手册页里还会介绍每个占位符对应的可选修饰符,比如设置宽度、精度、对齐方式等内容,帮助更灵活准确地进行格式化输出。
- 将
ex3
添加到你的Makefile
的all
列表中。到目前为止,可以使用make clean all
来构建你所有的练习。
添加all: ex1 ex3
- 将
ex3
添加到你的Makefile
的clean
列表中。当你需要的时候使用make clean
可以删除它。
添加:clean:rm -f ex1 ex3
ex4:
安装 Valgrind说明:
教学网站中的讲义下载Valgrind链接已经失效了,所以使用最新的版本的下载地址
curl -O https://sourceware.org/pub/valgrind/valgrind-3.24.0.tar.bz2
- 按照上面的指导,使用
Valgrind
和编译器修复这个程序。
我运行程序错误信息如下:$ valgrind ./ex4 ==19914== Memcheck, a memory error detector ==19914== Copyright (C) 2002-2024, and GNU GPL'd, by Julian Seward et al. ==19914== Using Valgrind-3.24.0 and LibVEX; rerun with -h for copyright info ==19914== Command: ./ex4 ==19914== ^[[BI am -16778024 years old. ==19914== Conditional jump or move depends on uninitialised value(s) ==19914== at 0x48D70BB: __printf_buffer (vfprintf-process-arg.c:58) ==19914== by 0x48D872A: __vfprintf_internal (vfprintf-internal.c:1544) ==19914== by 0x48CD1A2: printf (printf.c:33) ==19914== by 0x109188: main (ex4.c:9) ==19914== ==19914== Use of uninitialised value of size 8 ==19914== at 0x48CC0AB: _itoa_word (_itoa.c:183) ==19914== by 0x48D6C8B: __printf_buffer (vfprintf-process-arg.c:155) ==19914== by 0x48D872A: __vfprintf_internal (vfprintf-internal.c:1544) ==19914== by 0x48CD1A2: printf (printf.c:33) ==19914== by 0x109188: main (ex4.c:9) ==19914== ==19914== Conditional jump or move depends on uninitialised value(s) ==19914== at 0x48CC0BC: _itoa_word (_itoa.c:183) ==19914== by 0x48D6C8B: __printf_buffer (vfprintf-process-arg.c:155) ==19914== by 0x48D872A: __vfprintf_internal (vfprintf-internal.c:1544) ==19914== by 0x48CD1A2: printf (printf.c:33) ==19914== by 0x109188: main (ex4.c:9) ==19914== ==19914== Conditional jump or move depends on uninitialised value(s) ==19914== at 0x48D6D79: __printf_buffer (vfprintf-process-arg.c:186) ==19914== by 0x48D872A: __vfprintf_internal (vfprintf-internal.c:1544) ==19914== by 0x48CD1A2: printf (printf.c:33) ==19914== by 0x109188: main (ex4.c:9) ==19914== I am 31 inches tall. ==19914== ==19914== HEAP SUMMARY: ==19914== in use at exit: 0 bytes in 0 blocks ==19914== total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated ==19914== ==19914== All heap blocks were freed -- no leaks are possible ==19914== ==19914== Use --track-origins=yes to see where uninitialised values come from ==19914== For lists of detected and suppressed errors, rerun with: -s ==19914== ERROR SUMMARY: 6 errors from 4 contexts (suppressed: 0 from 0)
检测到的问题总结:
Conditional jump or move depends on uninitialised value:“条件跳转或移动操作依赖于未初始化的值”
Use of uninitialised value of size 8:“使用了大小为 8 字节的未初始化值”
这些问题表明某个变量在被正确初始化之前就被使用了,这会导致不可预测的行为
at 0x48CC0AB: _itoa_word (_itoa.c:183)
at 0x48D70BB: __printf_buffer (vfprintf-process-arg.c:58)
by 0x48D872A: __vfprintf_internal (vfprintf-internal.c:1544)
by 0x48CD1A2: printf (printf.c:33)
by 0x109188: main (ex4.c:9)
表明错误出现在程序(ex4.c)的main函数中(具体在第 9 行),特别是在printf调用期间。 栈追踪信息显示错误源于标准库中的vfprintf-process-arg.c和_itoa.c文件,这表明问题出在printf函数的格式化或参数处理方面。
使用Valgrind调试修复的这个程序:
Use --track-origins=yes to see where uninitialised values come from
这是Valgrind 给出的提示: 使用--track-origins=yes选项来确定未初始化值的确切来源。$ valgrind --track-origins=yes./ex4 valgrind: no program specified valgrind: Use --help for more information. Lin:~/ysyx/ysyx-workbench/learn_record/C_Linux/ex4$ valgrind --track-origins=yes ./ex4 ==21270== Memcheck, a memory error detector ==21270== Copyright (C) 2002-2024, and GNU GPL'd, by Julian Seward et al. ==21270== Using Valgrind-3.24.0 and LibVEX; rerun with -h for copyright info ==21270== Command: ./ex4 ==21270== I am -16778024 years old. ==21270== Conditional jump or move depends on uninitialised value(s) ==21270== at 0x48D70BB: __printf_buffer (vfprintf-process-arg.c:58) ==21270== by 0x48D872A: __vfprintf_internal (vfprintf-internal.c:1544) ==21270== by 0x48CD1A2: printf (printf.c:33) ==21270== by 0x109188: main (ex4.c:9) ==21270== Uninitialised value was created by a stack allocation ==21270== at 0x109149: main (ex4.c:4) ==21270== ==21270== Use of uninitialised value of size 8 ==21270== at 0x48CC0AB: _itoa_word (_itoa.c:183) ==21270== by 0x48D6C8B: __printf_buffer (vfprintf-process-arg.c:155) ==21270== by 0x48D872A: __vfprintf_internal (vfprintf-internal.c:1544) ==21270== by 0x48CD1A2: printf (printf.c:33) ==21270== by 0x109188: main (ex4.c:9) ==21270== Uninitialised value was created by a stack allocation ==21270== at 0x109149: main (ex4.c:4) ==21270== ==21270== Conditional jump or move depends on uninitialised value(s) ==21270== at 0x48CC0BC: _itoa_word (_itoa.c:183) ==21270== by 0x48D6C8B: __printf_buffer (vfprintf-process-arg.c:155) ==21270== by 0x48D872A: __vfprintf_internal (vfprintf-internal.c:1544) ==21270== by 0x48CD1A2: printf (printf.c:33) ==21270== by 0x109188: main (ex4.c:9) ==21270== Uninitialised value was created by a stack allocation ==21270== at 0x109149: main (ex4.c:4) ==21270== ==21270== Conditional jump or move depends on uninitialised value(s) ==21270== at 0x48D6D79: __printf_buffer (vfprintf-process-arg.c:186) ==21270== by 0x48D872A: __vfprintf_internal (vfprintf-internal.c:1544) ==21270== by 0x48CD1A2: printf (printf.c:33) ==21270== by 0x109188: main (ex4.c:9) ==21270== Uninitialised value was created by a stack allocation ==21270== at 0x109149: main (ex4.c:4) ==21270== I am 31 inches tall. ==21270== ==21270== HEAP SUMMARY: ==21270== in use at exit: 0 bytes in 0 blocks ==21270== total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated ==21270== ==21270== All heap blocks were freed -- no leaks are possible ==21270== ==21270== For lists of detected and suppressed errors, rerun with: -s ==21270== ERROR SUMMARY: 6 errors from 4 contexts (suppressed: 0 from 0)Why is the result no different from the command valgrind without --track-origins=yes
发现多了一个错误信息 Uninitialised value was created by a stack allocation
at 0x109149: main (ex4.c:4)
Valgrind 指出程序中正在使用一个未初始化的变量。在代码中的特定行(ex4.c文件里有效代码的第 4 行,并且这个错误是在main函数中出现的)包含了一个在栈上分配但在使用前未被初始化的变量。
观察代码文件ex4.c中内容
值得一提的是:在 C 语言代码中,行号计数通常是从 1 开始按顺序依次递增的,这里说的行号计数递增是是从整个源文件的角度去数的有效代码行号(空行不算),也就是包含了前面的头文件引入(#include <stdio.h>
算第 1 行)以及main
函数的定义那一行(int main()
算第 3 行)之后,int height;
所在的那一行就是第 4 行了
by 0x109188: main (ex4.c:9)
at 0x109149: main (ex4.c:4)
at部分是在追溯未初始化值的起源,也就是变量在内存中最初分配(创建)的位置。它告诉我们这个未初始化的隐患是从哪里开始的,在这个例子中就是变量height被声明的那一行。 by部分是在指出错误发生的位置,即程序在执行到哪一行代码时,因为使用了这个未初始化的值而触发了错误。这是实际产生错误行为的代码位置。
这里by使用的从代码文本编辑器显示的相对行数角度指的是printf("I am %d inches tall.\n", height);这一行,而错误的起源at使用的从整个源文件绝对行号的角度指的是int height;这一行,根据错误信息Uninitialised value was created by a stack allocation(未初始化值是通过栈分配产生的)给int height赋值从而解决改错误信息。
对于Valgrind 侧重于检测与内存访问相关的错误,例如使用未初始化的内存、无效的内存读 / 写操作或内存泄漏等情况。如果代码包含逻辑错误或与内存访问无关的问题,Valgrind 不会对其进行标记。所以对于printf("I am %d years old.\n");缺少参数的情况我们使用编译器可以轻松检查出错误问题
至此我们通过使用$ make -f ../ex2/Makefile ex4 cc -Wall -g ex4.c -o ex4 ex4.c: In function ‘main’: ex4.c:8:19: warning: format ‘%d’ expects a matching ‘int’ argument [-Wformat=]8 | printf("I am %d years old.\n");| ~^| || int ex4.c:5:9: warning: unused variable ‘age’ [-Wunused-variable]5 | int age = 10;| ^~~
Valgrind
和编译器修复了这个程序。
-
在互联网上查询
Valgrind
相关的资料。
Valgrind 官方首页:这里是获取 Valgrind 最新信息的权威来源,包含了 Valgrind 的当前版本、支持的平台、近期新闻等内容。例如,你可以了解到 2024 年 10 月 31 日发布的 Valgrind-3.24.0 版本所支持的众多操作系统和硬件架构等信息 。
Valgrind 官方文档页面:详细介绍了 Valgrind 的各种工具、使用方法、命令行选项等,是深入学习和使用 Valgrind 的必备参考。比如,关于 Memcheck 工具的详细介绍,包括它能够检测的各种内存错误类型,如使用未初始化的内存、内存泄漏等,以及相关的命令行选项如--leak-check
的具体用法等都有详细说明.
- 下载另一个程序并手动构建它。尝试一些你已经使用,但从来没有手动构建的程序。
参考如下;# 下载源码的归档文件来获得源码 # 解压归档文件,将文件提取到你的电脑上 # 运行./configure来建立构建所需的配置 # 运行make来构建源码,就像之前所做的那样 # 运行sudo make install来将它安装到你的电脑# 1) Download it (use wget if you don't have curl) curl -O http://valgrind.org/downloads/valgrind-3.6.1.tar.bz2# use md5sum to make sure it matches the one on the site md5sum valgrind-3.6.1.tar.bz2# 2) Unpack it. tar -xjvf valgrind-3.6.1.tar.bz2# cd into the newly created directory cd valgrind-3.6.1# 3) configure it ./configure# 4) make it make# 5) install it (need root) sudo make install
- 看看
Valgrind
的源码是如何在目录下组织的,并且阅读它的Makefile文件。不要担心,这对我来说没有任何意义。
Valgrind 的源码目录组织大概是这样的:有 coregrind 目录,这里面包含了它的核心功能实现代码,像内存管理以及错误检测等相关代码,是整个 Valgrind 的核心引擎所在。include 目录存放着 Valgrind 的头文件,定义了各种数据结构、函数接口这些内容,方便其他模块或者外部程序去引用。还有像 memcheck 目录,实现的是 Memcheck 工具的具体逻辑,能检测内存泄漏、越界访问等内存相关错误。cachegrind 目录包含的是 Cachegrind 工具代码,用于分析程序缓存使用情况来辅助优化性能。callgrind 目录里放着 Callgrind 工具相关代码,可分析程序调用图、函数调用关系以及收集相关性能数据。另外有 docs 目录存着文档,像用户手册、技术文档之类的,方便大家了解使用 Valgrind,tests 目录包含各种测试用例,用来测试验证 Valgrind 功能,保证其正确稳定。
Valgrind 是通过运行 “./configure” 命令,能指定像 “--prefix” 设置安装目录、“--host” 指定目标主机类型等参数。“./configure” 运行完就会生成 “Makefile” 文件,这个文件里有编译、链接等构建规则,指导 “make” 命令怎么构建 Valgrind。然后执行 “make” 命令进行编译,按规则把源文件编译成目标文件和可执行文件,最后用 “make install” 命令把编译好的文件安装到指定的安装目录下。
阅读它的 Makefile 文件的话,里面就是那些具体的编译、链接规则,还有依赖关系等内容,不同部分对应不同工具或者功能模块的构建相关设定
相关文章:
Linux上的C语言编程实践
说明: 这是个人对该在Linux平台上的C语言学习网站笨办法学C上的每一个练习章节附加题的解析和回答 ex1: 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后运行它看看发生了什么。 vim ex1.c打开 ex1.c 文件。假如我们删除 return 0…...
ubuntu中使用ffmpeg库进行api调用开发
一般情况下,熟悉了ffmpeg的命令行操作,把他当成一个工具来进行编解码啥的问题不大,不过如果要把功能集成进自己的软件中,还是要调用ffmpeg的api才行。 ffmpeg的源码和外带的模块有点太多了,直接用官网别人编译好的库就…...
基于yolov8的SAR影像目标检测系统,支持图像、视频和摄像实时检测【pytorch框架、python源码】
更多目标检测、图像分类识别、目标追踪等项目可看我主页其他文章 功能演示: 基于yolov8的SAR影像目标检测系统,支持图像、视频和摄像实时检测【pytorch框架、python源码】_哔哩哔哩_bilibili (一)简介 基于yolov8的SAR影像目标…...
【源码】Sharding-JDBC源码分析之SQL中读写分离动态策略、数据库发现规则及DatabaseDiscoverySQLRouter路由的原理
Sharding-JDBC系列 1、Sharding-JDBC分库分表的基本使用 2、Sharding-JDBC分库分表之SpringBoot分片策略 3、Sharding-JDBC分库分表之SpringBoot主从配置 4、SpringBoot集成Sharding-JDBC-5.3.0分库分表 5、SpringBoot集成Sharding-JDBC-5.3.0实现按月动态建表分表 6、【…...
服务器卸载安装的 Node.js
卸载安装的 Node.js 版本,具体步骤取决于你是通过包管理器(如 yum 或 dnf)安装的,还是通过 nvm (Node Version Manager) 安装的。以下是针对这两种情况的指南。 通过包管理器卸载 Node.js 如果你是通过 yum 或 dnf 安装的 Node.…...
一键图片提取表格导出为Excel文档工具体验
在日常工作中,我们经常会遇到需要将图片中的表格数据转换为可编辑的Excel文件的情况。这不仅能够提高工作效率,还能减少手动输入数据的错误。本文将介绍一款实用的工具,它能够帮助我们快速实现图片到Excel的转换,同时保持操作的简…...
SpringBoot异常处理
SpringBoot异常处理 一、认识异常 异常分类: Error: 代表编译和系统错误,不允许捕获Exception: 标准Java库的方法所激发的异常,包含运行异常Runtime_Exception和非运行异常 Non_RuntimeException 的子类Runtime_Exception: 运行时异常。No…...
在 OAuth 2.0 中,refreshToken(刷新令牌)存在的意义
在 OAuth 2.0 中,refreshToken(刷新令牌) 的主要目的是为了提升用户体验和安全性,同时确保访问令牌的有效性。以下是需要使用 refreshToken 的原因: 1. 访问令牌的有限生命周期 访问令牌(accessToken&…...
【Redis】壹 —— Redis 介绍
文章目录: 前言 一、认识Redis 1. Redis 用途 作为数据库 作为流引擎 二、服务端高并发分布式结构演变 1. 单机架构 2. 应用数据分离架构 3. 应用服务集群架构 4. 读写分离 / 主从分离架构 5. 冷热分离 —— 引入缓存 6. 分库分表 7. 微服务架构 8. …...
【html网页页面010】html+css制作茶品牌文创网页制作含视频元素(7页面附效果及源码)
茶主题品牌文创网页制作 🥤1、写在前面🍧2、涉及知识🌳3、网页效果完整效果(7页):代码目录结构:page1、主页page2、精品包装page3、茶园一角page4、品牌地带page5、衍生品page6、联X我们page7、视频详情页 ἰ…...
【项目实战】基于python+爬虫的电影数据分析及可视化系统
注意:该项目只展示部分功能,如需了解,文末咨询即可。 本文目录 1.开发环境2 系统设计 2.1 设计背景2.2 设计内容 3 系统页面展示 3.1 用户页面3.2 后台页面3.3 功能展示视频 4 更多推荐5 部分功能代码 5.1 爬虫代码5.2 电影信息代码 1.开发环…...
K8S命令部署后端(流水线全自动化部署)
前言 本文为链接: 云效流水线k8s半自动部署java(保姆级)的补充,本文起初的目的是为了补充完善k8s流水线的全自动化部署,但是也适用于k8s的一键重启,因为使用k8s的web页面容易出现漏点的情况,因此也可以把代码保存为shell脚本,同样可以实现一键重启。关于…...
GPS北斗卫星授时服务器功能是什么?应用是什么?
GPS北斗卫星授时服务器功能是什么?应用是什么? GPS北斗卫星授时服务器功能是什么?应用是什么? 摘 要:首先对计算机网络时间同步相关技术进行了介绍,然后阐述了时间同步技术在现代计算机网络中的应用与发展,最后指出时间同步网络…...
学习笔记064——如何手动将jar包导入到maven本地库
文章目录 1、背景:2、方法 1、背景: 有时网络慢的情况, 本地maven库需要导入外部下载的jar包。 以便于在项目的pom文件中,直接写dependency写导入依赖。 2、方法 在Windows终端中,输入: mvn install:in…...
未来趋势系列 篇二:HBM题材解析和股票梳理
文章目录 系列文章HBM题材解析环氧塑封电镀液PSPI(光敏性聚酰亚胺)前驱体封装基板其他材料TSV技术封装测试股票梳理系列文章 未来趋势系列 篇一:AI题材解析和股票梳理 HBM HBM(High Bandwidth Memory,高带宽内存)是一种专为高效能运算设计的新兴高速内存接口技术。它通…...
网卡驱动测试
以下是网卡驱动不同测试类型的具体方法和命令: 1. 功能性测试 驱动加载/卸载测试: 方法:加载/卸载网卡驱动,观察日志是否报错。命令: modprobe <driver_name> # 加载驱动 rmmod <driver_name> # 卸载驱动…...
DDR的跨4K问题
参考视频:【深入理解FPGA底层逻辑】、4k边界和outsdanding_哔哩哔哩_bilibili 1、AXI4_FULL突发写一个字节是一个地址, 2、协议规定,把AXI4从机的地址区间从0进行到了4095....每4K进行一次分配 所以突发长度的计算如下: 另外AX…...
数据结构---栈(Stack)
1. 简介 栈(Stack)是计算机科学中的一种抽象数据类型,它遵循特定的操作顺序,即后进先出(Last In First Out,LIFO)。这意味着最后添加到栈中的元素将是第一个被移除的。栈的基本操作通常包括&am…...
【JavaWeb后端学习笔记】Java上传文件到阿里云对象存储服务
阿里云对象存储 1、创建阿里云对象存储节点2、上传文件2.1 修改项目配置文件2.2 定义一个Properties类获取配置信息2.3 准备一个alioss工具类2.4 创建注册类,将AliOssUtil 注册成Bean2.5 使用AliOssUtil 工具类上传文件2.6 注意事项 使用阿里云对象存储服务分为以下…...
Unity3D RPG战斗系统详解
前言 设计一个RPG(角色扮演游戏)的战斗系统是游戏开发中的关键环节,它决定了游戏的乐趣和挑战性。在Unity3D中,可以通过多种技术和工具来实现一个功能完善的战斗系统。以下是对RPG战斗系统的技术详解以及代码实现。 对惹&#x…...
Spark架构及运行流程
Spark架构图 Driver: 解析用户的应用程序代码,转化为作业(job)。创建SparkContext上下文对象,其负责与资源管理器(ClusterManager)通信,进行资源的申请、任务的分配和监控等。跟踪Executor的执行情况。可通过UI界面查询运行情况。…...
SpringBoot3整合MyBatis
一、MyBatis整合步骤: (1).导入依赖:在Spring Boot项目的构建文件(如pom.xml)中添加MyBatis和数据库驱动的相关依赖。例如,如果使用MySQL数据库,您需要添加MyBatis和MySQL驱动的依赖。 (2).配置数据源:在application.properties或application.yml中配置…...
【计网笔记】习题
物理层 不属于物理层接口规范定义范畴的是(C) A. 接口形状 B. 引脚功能 C. 物理地址 D. 信号电平 【2023-912】光网络只能通过导向型介质传播。() 【2017-408】若信道在无噪声情况下的极限数据传输速率不小于信噪比为30dB条件下的…...
力扣56.合并区间
题目描述 题目链接56. 合并区间 以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。 示例 1: …...
【oracle】大数据删除插入
文章目录 引言本文目标 Oracle大数据插入操作插入操作的场景和需求使用并行查询进行数据插入示例代码:创建新表并插入数据解释代码中的关键点 性能优化建议 Oracle大数据删除操作删除操作的场景和需求使用游标和批量处理进行数据删除示例代码:批量删除数…...
mysql 双1设置
MySQL 的"双1"设置通常指的是两个配置参数:innodb_flush_log_at_trx_commit 和 sync_binlog。这两个参数都与 MySQL 的数据安全和性能有关。 innodb_flush_log_at_trx_commit:这个参数控制了 InnoDB 引擎中事务日志的刷新频率。它有三个可能的…...
《C++ 赋能 K-Means 聚类算法:开启智能数据分类之旅》
在当今数字化浪潮汹涌澎湃的时代,人工智能无疑是引领科技变革的核心驱动力之一。而在人工智能的广袤天地中,数据分类与聚类作为挖掘数据内在价值、揭示数据潜在规律的关键技术手段,正发挥着前所未有的重要作用。K-Means 聚类算法,…...
用Python开发一个经典贪吃蛇小游戏
Python 是开发小游戏的绝佳工具,借助第三方库,如 pygame,我们可以快速开发一个经典的贪吃蛇游戏。本篇将介绍如何用 Python 实现一个完整的贪吃蛇小游戏。 一、游戏设计 1.1 游戏规则 玩家通过方向键控制贪吃蛇移动。贪吃蛇吃到食物后会变长,同时得分增加。如果贪吃蛇撞到…...
《大宋豪侠传》客户端源码 + 服务端源码 + 工具源码 + 资源,大小16.3G
《大宋豪侠传》客户端源码 服务端源码 工具源码 资源,大小16.3G 下载地址: 通过网盘分享的文件:【源码】《大宋豪侠传》客户端源码 服务端源码 工具源码 资源,大小16.3G 链接: https://pan.baidu.com/s/1lUf84LzXKB3iM7L-1P…...
使用vue-seamless-scroll实现echarts图表大屏滚动,出现空白间隔的解决方案
一、背景介绍 最近的业务开发需求,想要实现echarts图表大屏滚动,小编首先采用vue-seamless-scroll进行实现,结果发现第二屏出现空白间隔,尝试了多种解决方案均不生效,最终选择换一个方案。 二、封装的ScrollList组件…...
zsh配置
zsh配置 https://zhuanlan.zhihu.com/p/58073103 $ cat .zshrc If you come from bash you might have to change your $PATH. export PATH H O M E / b i n : / u s r / l o c a l / b i n : HOME/bin:/usr/local/bin: HOME/bin:/usr/local/bin:PATH Path to your oh-my-zs…...
Brain.js(八):RNNTimeStep 实战教程 - 股票价格预测 - 实操需警慎
前置声明,个人浅度炒股,但计划将基金转入股市。然后 股市有风险,不是技术可以完全预测的,但是在无头绪的时候,用技术指标做个参考也不错。 本文涉及到的股票预测,只是代码简单示例,实操需警慎&a…...
Python+requests实现接口自动化测试
🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换,传…...
java------------常用API preiod duration 计算时间差
1,preiod 如果末天数比初天数小,需要进一位 package API;import java.time.LocalDate; import java.time.Period;public class preiod {public static void main(String[] args) {// 计算时间差// LocalDate获取对象其中的一个方法LocalDate d1 LocalD…...
Android水波纹效果
Android水波纹效果 需要到水波纹效果的场景还蛮少的。万一刚好你需要呢 一、思路: 自定义组件SpreadView 二、效果图: 看视频更直观点: Android轮子分享-水波纹效果 三、关键代码: public class SpreadView extends View {pr…...
yolov8 转华为昇腾om脚本
目录 yolov8 转华为昇腾 om脚本 测试ok 推理demo: yolov8 转华为昇腾 om脚本 测试ok import sys import osos.chdir(os.path.dirname(os.path.abspath(__file__)))import torchcurrent_dir = os.path.dirname(os.path.abspath(__file__))paths = [os.path.abspath(__file__)…...
【人工智能】从基础到实践:用Python和PyTorch实现深度学习图像分割模型
《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 图像分割是计算机视觉中的核心任务之一,旨在将图像划分为具有语义意义的区域,在自动驾驶、医疗影像分析等领域有广泛应用。本篇文章将从图像分割的基础知识出发,详细讲解分割任务的目标、评价指标以及常…...
AI绘画设计实战-Day2
Stable Diffusion 提示词前缀 FF,(masterpiece:1.2),best quality,highres,extremely detailed CG,perfect lighting,8k wallpaper,anime,comic,game CG, FF,(杰作:1.2),最高质量,高分辨率,极其…...
详解LeetCode地下城游戏(动态规划)——区分两种状态表示形式
地下城游戏 题目链接:174. 地下城游戏 状态表示: 按照以往题的表示,dp[i][j]表示:从起点(0,0)位置到达(i,j)位置时,所需的最小初始健康值。但是…...
CV(3)--噪声滤波和特征
前言 仅记录学习过程,有问题欢迎讨论 图像噪声(需要主动干扰的场景): 添加高斯噪声:概率密度函数服从高斯分布的一类噪声 通过设置sigma和mean生成符合高斯分布的随机数,然后计算输出像素,放缩…...
[C++]常对象、常对象成员、指向对象的常指针、指向常对象的指针变量以及对象的常引用
一、 常对象 1.定义: 一个常对象就是声明为常量的对象。我们不能改变这个对象的任何成员数据。具体来说,它是通过const关键字来声明的。 2.语法格式: const 类名 对象名;3.代码示例: class MyClass { public:int x;void setX…...
Spring Boot微服务应用实战:构建高效、可扩展的服务架构
在当今的软件开发领域,微服务架构凭借其高度的灵活性、可扩展性和可靠性,已成为众多企业的首选。而Spring Boot,作为Spring框架的一个子项目,以其简洁的API、快速的应用启动以及内嵌的Servlet容器等特点,成为了构建微服…...
如何通过 Windows 自带的启动管理功能优化电脑启动程序
在日常使用电脑的过程中,您可能注意到开机后某些程序会自动运行。这些程序被称为“自启动”或“启动项”,它们可以在系统启动时自动加载并开始运行,有时甚至在后台默默工作。虽然一些启动项可能是必要的(如杀毒软件)&a…...
力扣每日一题 - 1812. 判断国际象棋棋盘中一个格子的颜色
题目 还需要你前往力扣官网查看详细的题目要求 地址 1.给你一个坐标 coordinates ,它是一个字符串,表示国际象棋棋盘中一个格子的坐标。下图是国际象棋棋盘示意图。2.如果所给格子的颜色是白色,请你返回 true,如果是黑色ÿ…...
Python subprocess.run 使用注意事项,避免出现list index out of range
在执行iOS UI 自动化专项测试的时候,在运行第一遍的时候遇到了这样的错误: 2024-12-04 20:22:27 ERROR conftest pytest_runtest_makereport 106 Test test_open_stream.py::TestOpenStream::test_xxx_open_stream[iPhoneX-xxx-1-250] failed with err…...
UI自动化测试框架:PO模式+数据驱动
🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 1. PO 设计模式简介 什么是 PO 模式? PO(PageObject)设计模式将某个页面的所有元素对象定位和对元素对象的操作封装成一个 Pa…...
第四十六篇 Vision Transformer论文翻译
论文连接:https://arxiv.org/abs/2010.11929 GitHub:https://github.com/google-research/vision_transformer 摘要 虽然Transformer架构已成为自然语言处理任务的实际标准,但其在计算机视觉中的应用仍然有限。在计算机视觉中,注意力机制要么与卷积网络结合使用,要么在保…...
如何在Ubuntu中利用repo和git地址下载获取imx6ull的BSP
01-设置git的用户名和邮箱 git config --global user.name "suwenhao" git config --global user.email "2487872782qq.com"这里不设置的话后面在第5步的repo配置中还是会要求输入,而且以后进行相关操作都要输入,不妨现在就进行配置…...
redis数据结构和内部编码及单线程架构
博主主页: 码农派大星. 数据结构专栏:Java数据结构 数据库专栏:数据库 JavaEE专栏:JavaEE 软件测试专栏:软件测试 关注博主带你了解更多知识 1. 数据结构和内部编码 Redis会在合适的场景选择合适的内部编码 我们可以通过objectencoding命令查询内部编码 : 2. 单线程架构 …...
2412d,d的6月会议
信息:gtkD的文档位置 原文 总结 DMDARM后端 Razvan问Walter他对DMD的ARM后端的分发,并想知道他是否考虑过其他选择,如整合DMD前端与LDC后端. Walter说,人们写信告诉他,他们喜欢使用DMD,因为它体积小,速度快.多年来,就要求他实现ARM后端. 有的人想写一个,但后来因为太难或太耗…...