Linux系统编程 day02 vim、gcc、库的制作与使用
Linux系统编程 day02 vim、gcc、库的制作与使用
- 01. vim
- 0101. 命令模式下的操作
- 0102. 切换到文本输入模式
- 0103. 末行模式下的操作
- 0104. vim的配置文件
- 02. gcc
- 03. 库的制作与使用
- 0301. 静态库的制作与使用
- 0302. 动态库(共享库)的制作与使用
01. vim
vim是一个编辑器,需要自行安装,可以使用命令sudo apt-get install vim。安装完之后可以在shell中输入vimtutor命令查看帮助文档。
vim有三种工作模式,分别是命令模式、文本输入模式以及末行模式。三者的切换关系如下:

0101. 命令模式下的操作
用户按下ESC键,就可以使vim进入命令模式。当用户使用vim打开一个新文件的时候也是默认进入的命令模式。命令模式中的操作如下。
| 快捷键 | 操作 |
|---|---|
| ZZ | 保存退出 |
| gg=G | 格式化代码 |
| h | 光标左移 |
| j | 光标下移 |
| k | 光标上移 |
| l | 光标右移 |
| w | 光标移动一个单词 |
| gg | 光标移动到文件开头 |
| G | 光标移动到文件末尾 |
| 0 | 光标移动到行首 |
| $ | 光标移动到行尾 |
| nG | 光标移动到第n行 |
| x | 删除光标后一个字符,相当于Delete |
| X | 删除光标前一个字符,相当于Backspace |
| dw | 删除光标后一个字单词 |
| d0 | 删除光标前本行的所有内容,不包括光标所在字符 |
| d$ | 删除光标后本行的所有内容,包括光标所在字符 |
| D | 删除光标后本行的所有内容,包括光标所在字符 |
| dd | 删除光标所在行的内容,实际上是剪切 |
| ndd | 删除光标当前行向下n行的内容,包括本行一共n行,实际上是剪切 |
| v | 非列模式视图,使用hjkl进行移动选择内容,按d删除 |
| ctrl + v | 列模式视图,使用hjkl移动选择内容,按d删除 |
| u | 撤销 |
| ctrl + r | 反撤销 |
| yy | 复制当前行的内容 |
| nyy | 复制当前行向下n行,包括本行一共n行 |
| p | 在光标位置向下开辟一行并粘贴 |
| P | 在光标位置向上开辟一行并粘贴 |
| r | 替换当前字符 |
| R | 替换当前行光标后的字符 |
| / | /xxx 从光标所在位置开始搜索,按n向下搜索,按N向上搜索 |
| ? | ?xxx 从光标所在位置开始搜索,按n向上搜索,按N向下搜索 |
| # | 将光标移动到待搜索的字符串上,然后按n向上搜索,按N向下搜索 |
| shift + k | 在带搜索的字符串上按下shift + k 或者 K 可以查看相关的帮助文档 |
| ctrl + u | 向下翻半屏,光标向上移动 |
| ctrl + d | 向下翻半屏,光标向下移动 |
| ctrl + f | 向前翻一屏 |
| ctrl + b | 向后翻一屏 |
0102. 切换到文本输入模式
从命令模式切换到文本输入模式的操作如下。
| 快捷键 | 操作 |
|---|---|
| i | 在光标前插入 |
| a | 在光标后插入 |
| I | 在光标所在行的行首插入 |
| A | 在光标所在行的行尾插入 |
| o | 在光标所在行的下面开辟一行,行首插入 |
| O | 在光标所在行的上面开辟一行,行首插入 |
| s | 删除光标后的字符并在光标当前位置插入 |
| S | 删除光标所在当前行并在行首插入 |
| 列模式插入 | 按I或者shift + i 向前插入,插入字符串后按两次ESC保存。 |
0103. 末行模式下的操作
从命名模式切换到末行模式,只需要输入:即可。下面是关于末行模式的一些操作。
| 快捷键 | 操作 |
|---|---|
| q | 退出 |
| q! | 强制退出,不保存修改内容 |
| w | 保存修改内容,不退出 |
| wq | 保存并退出 |
| x | 保存并退出 |
| : s/old/new/ | 光标所在行的第一个old替换为new |
| : s/old/new/g | 光标所在行的所有old替换为new |
| :m,ns/old/new/g | 将第m行到第n行的所有old替换为new |
| :%s/old/new/g | 将当前文件的所有old替换为new |
| :1,$s/old/new/g | 将当前文件的所有old替换为new |
| :%s/old/new/gc | 将当前文件的所有old替换为new,但是每次替换需要用户确认 |
| !shell命令 | 执行shell命令,按下两次ESC可以回到命令模式 |
| sp | 当前文件水平分屏 |
| vsp | 当前文件垂直分屏 |
| sp 文件名 | 当前文件和另一个文件水平分屏 |
| vsp 文件名 | 当前文件和另一个文件垂直分屏 |
| ctrl + w + w | 多个窗口间切换光标 |
| wall | 保存所有分屏窗口 |
| wqall | 保存并退出所有分屏窗口 |
| xall | 保存并退出所有分屏窗口 |
| qall | 退出所有分屏窗口 |
| qall! | 强制退出所有分屏窗口 |
分屏模式可以在shell中使用以下命令:
# 水平分屏
vim -on 文件1 文件2 ....
vim -o 文件1 文件2 ....
# 垂直分屏
vim -On 文件1 文件2 ....
vim -O 文件1 文件2 ....
0104. vim的配置文件
vim的配置文件分别是系统级别配置文件/etc/vim/vimrc和用户级别配置文件~/.vimrc。修改系统级别的配置文件会影响到该系统下的所有用户,如果修改的是用户级别的配置文件只会影响到当前的用户而不会影响到其它用户。在配置文件中,我们可以添加以下的设置。
| 命令 | 功能 |
|---|---|
| set nu | 设置显示行号 |
| set nonu | 设置不显示行号 |
| set shiftwidth = n | 设置gg=G缩进为n个空格,默认是8个空格 |
| set autoindent | 设置自动换行,每行按与上一行同样的标准进行缩进 |
| set list | 将制表符显示为^|,用$表示行尾 |
| set showmatch | 在vim中输入相应的右括号时光标会暂时回到相匹配的左括号 |
| set tabstop = n | 设置tab缩进的字符数目为n |
| set encoding=utf-8 | 设置编码格式为utf-8 |
| set smartindent | 为C程序提供自动缩进 |
这些命令也可以在末行模式下使用。
02. gcc
gcc编译器将C语言原程序文件生成一个可执行文件一共需要经理四个步骤,分别是预处理、编译、汇编、链接。


这四个步骤的命令如下:
# 预处理
gcc -E hello.c -o hello.i
# 编译
gcc -S hello.i -o hello.s
# 汇编
gcc -c hello.s -o hello.o
# 链接
gcc hello.o -o hello
当然我们可以一步到位:
gcc hello.c -o hello
接下来我们来看一看关于gcc的一些常用参数
| 参数 | 功能作用 |
|---|---|
| -v | 查看gcc版本号 |
| –version | 查看gcc版本号 |
| -E | 预处理,生成预处理文件 |
| -S | 编译,生成汇编文件 |
| -c | 只编译,生成.o文件,通常称为目标文件 |
| -I | 指定头文件所在路径 |
| -L | 指定库文件所在路径 |
| -l | 指定库名称 |
| -o | 指定生成的目标的名字 |
| -g | 包含调试信息,使用gdb调试的时候需要添加-g参数 |
| -On n=0~3 | 编译优化,n的值越大优化得越多 |
| -Wall | 提示更多警告信息 |
| -D | 编译时定义宏 |
03. 库的制作与使用
库是二进制文件,是源代码文件的另一种表现形式,可以认为是加了密的源代码。库是一些功能相近或者相似的函数的集合体。库可以提高代码的重用性,提高程序的健壮性,同时也可以减少开发者的代码量,缩短开发周期。库可以分为静态库和动态库,动态库也被称为共享库。
0301. 静态库的制作与使用
静态库可以认为是一些目标代码的集合,是在可执行程序运行前就已经加入到执行代码中,称为可执行程序的一部分。静态库我们习惯于用.a作为后缀名,前缀为lib,库的名称是自定义的。比如有一个库的名称是test,则该静态库的库文件名就是libtest.a。
静态库的制作主要分为两步,第一步是使用gcc中的-c参数将C语言源程序文件编译成.o文件。第二步是使用打包工具ar将.o问加你打包为.a文件。
例如此处我们有add.c、sub.c、mul.c、dive.c、main.c、head.h五个文件。其中head.h中为add.c、sub.c、mul.c、dive.c的声明部分,实现在各自的.c文件中。接下来我们需要将前面四个.c文件进行打包制作静态库,库名为smath。
首先将他们编译成.o文件。
# 第一种方法是全部直接编译
gcc -c add.c sub.c mul.c dive.c
# 第二种方法是逐个编译
gcc -c add.c -o add.o
gcc -c sub.c -o sub.o
gcc -c mul.c -o mul.o
gcc -c dive.c -o dive.o
第二步使用ar打包工具进行打包为静态库文件。
# 将.o文件打包成静态库文件
ar rcs libsmath.a add.o sub.o mul.o dive.o
在打包命令中,参数r表示更新、c表示创建、s表示建立索引。
如此以来就创建好了一个静态库文件。那么怎么使用呢,我们可以通过gcc的参数去指定静态库文件以及头文件的所在路径即可。需要注意的是-l指定库名称的时候不需要写库的前缀lib以及后缀.a。如libsmath.a只需要写smath即可。另外-L、-l、-I参数后面跟的参数可以用空格隔开,也可以不隔开。如接下里我们需要编译main.c并执行。
# 生成可执行文件,指定头文件为当前路径,库文件为当前路径,库名为smath
gcc main.c -I./ -L./ -lsmath -o main
静态库文件制作好了之后,需要将.a文件和头文件一并发布给用户。静态库最终打包到应用程序中,实现函数本地化,寻址方便、速度快。程序在运行时与函数库再无任何关系,移植方便。但是静态库消耗系统资源较大,每一个进程使用静态库都需要复制一份,浪费内存。静态库会给程序的更新、部署和发布带来麻烦。如果静态库更新了,那么所有使用它的应用程序都需要重新编译、发布给用户。对于使用者来说,也就是一个很小的改动都需要重新下载整个程序。
0302. 动态库(共享库)的制作与使用
共享库的出现正好解决了上面动态库的不足。共享库在程序编译时并不会被连接到目标代码中,而是在程序运行的时候才会被载入。不同的应用程序如果调用相同的共享库,那么在内存中只需要有一份该共享库的拷贝即可,避免了内存空间浪费的问题。由于动态库是程序运行时才会被载入,也解决了静态库对程序的更新、部署和发布带来的麻烦。动态库习惯于以.so作为后缀名,前缀也需要加上lib。比如有个动态库的名字为dmath,则完成的动态库文件名为libdmath.so。
动态库的制作也有两个步骤,第一个步骤是使用gcc中的-fpic参数创建与地址无关的编译程序,生成目标文件.o。第二步是使用gcc的-shared生成动态库。
同样,我们以静态库的那个例子生成动态库,第一步生成目标文件的过程如下:
# 生成目标文件 -fpic 创建与地址无关的编译程序 -c 只编译
gcc -fpic -c add.c sub.c mul.c dive.c
第二步是生成动态库文件,这里取库名为dmath。
# 生成动态库文件 -shared 指定生成动态库
gcc -shared add.o sub.o mul.o dive.o -o libdmath.so
如此以来就生成了动态库文件libdmath.so。那么我们如何查看一个库中有哪些内容呢?我们可以使用nm命令。
# 查看dmath动态库中有哪些内容
nm libdmath.so
# 查看smath静态库中有哪些内容
nm libsmath.a
# 查看add.o中有哪些内容
nm add.o
动态库的使用和静态库的使用方法是一样的,需要指定头文件路径、库路径以及库名。如接下来编译main.c生成可执行文件如下:
gcc main.c -I./ -L./ -ldmath -o main
这样就可以生成可执行程序main。但是在执行运行main程序的时候会报错,这是为什么呢?因为系统加载可执行代码的时候,能够直到其以来的库文件名字,但是还需要知道所依赖的库的绝对路径,此时就会有系统动态载入器,也就是lld。执行ldd命令可以查看可执行文件依赖的库文件。如下面查看main所依赖的库文件。
# 查看main所依赖的库文件
ldd main
不过执行这句话的时候有时会反馈找不到。对于ELF格式的可执行程序,是由ld-linux.so*来完成的,它搜索ELF文件的DT_RPATH段,再搜索环境变量LD_LIBRARY_PATH,再搜索/etc/ld.so.cache文件列表,最后搜索/lib/、/usr/lib/目录找到库文件并将其载入内存。如果上面的都找不到就会报错。我们可以使用file命令查看文件的类型,如查看main的类型。
# 查看main的文件类型
file main
那么如何让系统找到自己的共享库呢?首先分析程序去搜索ELF文件的DT_RPATH段,这个部分是我们不能更改的,所以我们只能对剩下的三个路径进行下手。方法如下:
- 第一种方法,拷贝自己制作的动态库放在
/lib/或者/usr/lib/目录下。 - 第二种方法, 临时设置
LD_LIBRARY_PATH,在shell中执行export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:库路径。 - 第三种方法,永久设置
LD_LIBRARY_PATH,将LD_LIBRARY_PATH=$LD_LIBRARY_PATH:库路径设置到~/.bashrc中,然后再使环境变量生效,生效可以任使用以下的其中一个方法。- 执行
. ~/.bashrc使配置文件生效 - 执行
source ~/.bashrc使配置文件生效 - 退出当前终端,然后再次登录也可以使配置文件生效
- 执行
- 第四种方法,永久设置,把
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:库路径设置到/etc/profile文件中。 - 第五种方法,添加到
/etc/ld.so.cache文件中。编辑/etc/ld.so.conf文件,假如库文件所在的目录路径,再运行sudo ldconfig -v重建/etc/ld.so.cache文件。
通过上述的方法之后,再执行ldd main就可以找到对应依赖的库文件。也就是这个程序终于可以正常运行了。
动态库把对一些库函数的链接载入推迟到了程序运行的时期。动态库实现了进程之间的资源共享。动态库使程序升级变得简单。动态库使得链接载入完全由程序员在代码中控制。
最后对比以下动态库与静态库的优缺点。
| - | 优点 | 缺点 |
|---|---|---|
| 动态库 | 1. 节省内存 2. 部署升级更新方便,只需替换动态库即可,然后再重启服务 | 1. 加载速度比静态库慢 2. 移植性差,需要把所有用到的动态库都移植 |
| 静态库 | 1. 执行速度快,因为静态库已经编译到可执行文件内部 2. 移植方便,不依赖其它库文件 | 1. 耗费内存,因为每一个静态库可执行程序都会加载一次 2. 部署更新麻烦,因为静态库修改以后所有调用这个静态库的可执行文件都需要重新编译。 |
相关文章:
Linux系统编程 day02 vim、gcc、库的制作与使用
Linux系统编程 day02 vim、gcc、库的制作与使用 01. vim0101. 命令模式下的操作0102. 切换到文本输入模式0103. 末行模式下的操作0104. vim的配置文件 02. gcc03. 库的制作与使用0301. 静态库的制作与使用0302. 动态库(共享库)的制作与使用 01. vim vim是一个编辑器࿰…...
Mistral 7B 比Llama 2更好的开源大模型 (四)
Mistral 7B在平衡高性能和保持大型语言模型高效的目标方面迈出了重要的一步。通过我们的工作,我们的目标是帮助社区创建更实惠、更高效、更高性能的语言模型,这些模型可以在广泛的现实世界应用程序中使用。 Mistral 7B在实践中,对于16K和W=4096的序列长度,对FlashAttentio…...
相似基因序列问题 ——查找
【题目背景】 生物的遗传物质存在个体间或种群水平的差异,这样的差异被称为遗传变异。突变及基因重组等因素都会导致遗传变异。尽管亲代在将其遗传信息传递给子代时会发生遗传变异,但是这些遗传变异仅占遗传物质的一小部分,通常亲代和子代之…...
【汇编】“转移”综述、操作符offset、jmp指令
文章目录 前言一、转移综述1.1 :背景:1.2 转移指令1.3 转移指令的分类按转移行为根据指令对IP修改的范围不同 二、操作符offset2.1 offset操作符是干什么的?标号是什么? 2.2 nop是什么? 三、jmp指令3.1 jmp指令的功能3.2 jmp指令&…...
Java格式化类Format
文章目录 Format介绍Format方法- format(格式化)- parseObject(解析) 格式化分类日期时间格式化1. DateFormat常用方法getInstancegetDateInstancegetTimeInstancegetDateTimeInstance 方法入参styleLocale 2. SimpleDateFormat常…...
力扣每日一题-美化数组的最少删除数-2023.11.21
力扣每日一题:美化数组的最少删除数 开篇 今天的力扣每日一题居然写出来了,好开心,迫不及待地把题目分享出来,希望你也能把它狠狠拿下。 题目链接: 2216.美化数组的最少删除数 题目描述 代码思路 创建一个list集合来保存数组&a…...
【练习】检测U盘并自动复制内容到电脑的软件
软件作用: 有U盘插在电脑上后,程序会检测到U盘的路径。 自己可以提前设置一个保存复制文件的路径或者使用为默认保存的复制路径(默认为桌面,可自行修改)。 检测到U盘后程序就会把U盘的文件复制到电脑对应的…...
【计算机毕业设计】Springboot高校论文管理系统 -96280,免费送源码,【开题选题+程序定制+论文书写+答辩ppt书写-原创定制程序】
SpringBoot论文管理系统 摘 要 随着科学技术的飞速发展,社会的方方面面、各行各业都在努力与现代的先进技术接轨,通过科技手段来提高自身的优势,高校当然也不例外。论文管理系统是以实际运用为开发背景,运用软件工程原理和开发方…...
nginx 代理接口报404 问题排查
今天遇到一个nginx代理后端接口请求报404的问题,问题是这样的,后端由于服务器没有环境,但是需要和前端联调,于是采用cpolar内网穿透的方式,穿出来了。但是前端请求跨域,于是前端用nginx代理了一下后端接口&…...
JVM 调优指南
文章目录 为什么要学 JVM一、JVM 整体布局二、Class 文件规范三、类加载模块四、执行引擎五、GC 垃圾回收1 、JVM内存布局2 、 JVM 有哪些主要的垃圾回收器?3 、分代垃圾回收工作机制 六、对 JVM 进行调优的基础思路七、 GC 情况分析实例 JVM调优指南 -- 楼兰 JV…...
澳洲猫罐头如何?我亲自喂养过的优质猫罐头分享
猫罐头要符合三点:营养配方完整均衡、原料新鲜优质、生产工艺科学可靠。只有具备这些特点,才是品质上乘的猫罐头。 猫罐头的三个要素,一个都不能少。配方不均衡,营养就不足;原料不新鲜,生产出来的猫罐头就…...
CISP练习测试题
免责声明 文章仅做经验分享用途,切勿当真,未授权的攻击属于非法行为!利用本文章所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,作者不为此承担任何责任,一旦造成后果请自行承担!!! 某公司准备在业务环境中部署一种新的计算机产品,下列哪一项…...
2023下半年软件设计师考试知识点大全思维导图
软件设计师考试知识点大全思维导图 2023年下半年第一次机考 复习资料 以上是我在学习过程中根据自己的知识结构的特点及刷到的考题 做的导图,有需要的可以留言发原版的 mmap格式文件 方便自己拓展. 软考资料 这是网上找的资料 汇总免费放在这里 吧![ 链接&#x…...
[C++ 从入门到精通] 12.重载运算符、赋值运算符重载、析构函数
📢博客主页:https://loewen.blog.csdn.net📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!📢本文由 丶布布原创,首发于 CSDN,转载注明出处🙉📢现…...
Android Binder 跨进程通信的优势是什么
Android Binder 跨进程通信的优势是什么 Android Binder 是 Android 系统中用于实现跨进程通信的底层机制,具有以下优势: 高效性:Android Binder 使用共享内存技术,在进程间传递数据时不需要进行数据拷贝,从而提高了传…...
HashMap的详细解读
HashMap是Java语言中的一个重要数据结构,它实现了Map接口,允许我们存储键值对,并且可以根据键直接访问对应的值。 特性 键值对存储:HashMap存储的是键值对数据,可以方便的通过键来获取值。无序:HashMap中…...
10个好用的Mac数据恢复软件推荐—恢复率高达99%
如果您正在寻找最好的 Mac 数据恢复软件来检索意外删除或丢失的文件,那么这里就是您的最佳选择。 我们理解,当您找不到 Mac 计算机或外部驱动器上保存的一些重要文件时,会感到多么沮丧和绝望。这些文件非常珍贵,无论出于何种原因…...
EtherCAT从站EEPROM分类附加信息详解:RXPDO(输入过程数据对象)
0 工具准备 1.EtherCAT从站EEPROM数据(本文使用DE3E-556步进电机驱动器)1 分类附加信息——RXPDO(输入过程数据对象) 1.1 分类附加信息规范 在EEPROM字64开始的区域存储的是分类附加信息,这里存储了包括设备信息、SM配置、FMMU配置在内的诸多信息。每个信息在一段连续的…...
释放锁流程源码剖析
1 释放锁流程概述 ReentrantLock的unlock()方法不区分公平锁还是非公平锁。 首先调用unlock()方法。 unlock()底层使用的是Sync.release(1)方法 public void unlock() {<!-- --> sync.release(1); } release(1)方法会调用tryRelease(1)去尝试解锁。 public fin…...
ComText让机器人有了情节记忆
为了让人类与机器人更好地交流,MIT 计算机科学与人工智能实验室的研究员开发了一个名为 ComText 的程序。这款程序给机器人增加了情节记忆,让它们能够接受更加复杂的命令。目前,他们已经在机器人 Baxter 上测试了程序。 机器人没有情景化的记…...
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用
一、方案背景 在现代生产与生活场景中,如工厂高危作业区、医院手术室、公共场景等,人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式,存在效率低、覆盖面不足、判断主观性强等问题,难以满足对人员打手机行为精…...
零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程
STM32F1 本教程使用零知标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态解算,并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化,适合嵌入式及物联网开发者。在基础驱动上新增…...
