7. 进程控制-进程替换
目录
1. 进程替换
1.1 单进程版:
1.2 进程替换的原理
1.3 多进程版-验证各种程序替换接口
2. 进程替换的各种接口
2.1 execl
2.2 execlp
2.3 execv
2.4 execvp
2.5 execle
1. 进程替换
上图为程序替换的接口,之后会详细介绍。
1.1 单进程版:
最简单的看看程序替换的效果:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int main()
{printf("before: i am a process, pid: %d, ppid: %d\n", getpid(), getppid());execl("/usr/bin/ls", "ls", "-a", "-l", NULL);printf("after: i am a process, pid: %d, ppid: %d\n", getpid(), getppid());return 0;
}
我们可以看到,before...执行了,然后执行了execl里的内容,最重要的是after...的内容没有被执行。这就叫程序替换。
1.2 进程替换的原理
让我们分析一下上面代码的执行过程,刚开始肯定执行本代码,也就是before,然后execl,关键就在于这个接口,这个接口是执行了 ls -l -a,但并不是创建新进程去执行这个指令,而是在这个进程上,直接替换代码和数据,从新程序的main处开始运行,新程序的code和data替换掉老的。
也就是说我们运行起来的 myproc 这个进程,在运行到execl时,这个进程的代码和数据被换成了 execl 中的命令内容的代码和数据。
1.3 多进程版-验证各种程序替换接口
int main()
{//多进程版的程序替换pid_t id = fork();if(id == 0){printf("before: i am a process, pid: %d, ppid: %d\n", getpid(), getppid());sleep(5);execl("/usr/bin/top", "top", NULL);printf("after: i am a process, pid: %d, ppid: %d\n", getpid(), getppid());exit(0);}//fatherpid_t ret = waitpid(id, NULL, 0);if(ret > 0)printf("wait success, father pid: %d, ret id: %d\n", getpid(), ret);sleep(5);return 0;
程序一运行起来就有两个进程,其中一个是子进程,替换后就结束了,然后父进程5秒后也退出。
有几个现象结论:
- 子进程执行程序替换,不会影响父进程父进程在等待子进程结束,没有直接top完就退出
- execl时,替换数据时发生写时拷贝,此时替换的代码也发生了写时拷贝!子进程的代码被替换,但是父进程的还在执行。
- 程序替换有无创建新进程呢?进程最多都是两个,所以没有!
程序替换成功之后,exec*之后的代码不会被执行;如果替换失败呢?才可能执行后续的代码,所以exec*系列的函数,只有失败返回值,没有成功返回值,因为成功了就替换成功了,显示被替换后的代码的结果。
我们的CPU如何知道程序的入口地址在哪?代码区这么大,程序替换后的main在哪里呢?
2. 进程替换的各种接口
通过对接口参数的学习,我们可以回答上面的问题。
文章一开头的图片就是这一系列的各种接口,有6个,但是其实有7个,剩下那个不在这个手册里。
我们这里介绍5个,剩下的就都知道怎么用了。
2.1 execl
exec是一样的,l 代指 list。
所以这一系列的函数的第一个参数:你要执行一个程序的第一件事情是什么?就是先找到这个程序!这个参数就是决定如何找到程序的,什么路径下的什么程序!
找到这个程序之后,接下来要怎么办?就是如何执行这个程序,主要就是要不要涵盖选项,涵盖哪些?所以从第二个参数开始,命令行中怎么输入,就怎么输入!只不过都要加上""
execl("usr/bin/ls", "ls", "-l", NULL);
最后的NULL是必须要加的。
2.2 execlp
我们发现它的第一个参数是file,不是path,说明第一个参数只用写明文件就行,不需要指明路径(当然指明也是可以的),它会自动去PATH环境变量中去找这个指令。
execlp("ls", "ls", "-l", NULL);
2.3 execv
这个接口的最后一个是 v,表示vector,这种不外乎是将传参的形式改变了,之前是传list,现在是传个vector。
char* const myargv[] = {"ls","-l","-a",NULL
};execv("/usr/bin/ls", myargv);
exec 会在内部把命令行参数传给ls,exec就是代码层面的加载器,把可执行程序导到内存里。
2.4 execvp
一带p就不用写path,只写file就可以。带v就是把传的参数列表换成vector
2.5 execle
这个e是我们没见过的,它的意思是环境变量,意味着我们可以自己往里传环境变量,前面的命令行参数我们知道可以在内部传给指令,那这个环境变量会传给替换后的代码吗?
在验证这个问题之前,先来讲一些前置知识:
1. 怎么用一个makefile生成两个可执行文件?
我们都知道makefile会把它碰到的第一个文件定位目标文件,那怎么能有两个目标文件呢?总得有个先后吧,所以我们可以这样处理:
.PHONY:all
all:otherExe mycommandotherExe:otherExe.cppg++ -o $@ $^ -std=c++11
mycommand:mycommand.cgcc -o $@ $^ std=c99
.PHONY:clean
clean:rm -f mycommand otherExe
接下来我们实现一下:一个可执行程序调用另一个可执行程序:
mycommand.c 中可以通过exec系列接口调用其他可执行程序,当然这个可执行程序也得是编译好的,所以需要一个makefile编译两个文件。
int main()
{pid_t id = fork();if(id == 0){printf("before: i am a process, pid: %d, ppid: %d\n", getpid(), getppid());execl("./otherExe", "otherExe", NULL);}return 0;
}
这里有一个小问题:我们在调用 otherExe时,是 ./otherExe 这样执行,为什么我们传的第二个参数是otherExe,而不是 ./otherExe 呢?
- 因为前面已经说明它在哪里了,这里就不用再写一遍了
既然我一个C程序可以调用C++程序,那能不能调用其他语言写的程序呢?
让我们来验证一下:
脚本语言(所谓的脚本语言就是bash从文件中一行一行的执行):test.sh:
#!/usr/bin/bashecho "hello 1"
echo "hello 1"
echo "hello 1"
echo "hello 1"
echo "hello 1"
echo "hello 1"
echo "hello 1"
ls -a -l
要注意直接./test.sh是不能执行的。
int main()
{pid_t id = fork();if(id == 0){printf("before: i am a process, pid: %d, ppid: %d\n", getpid(), getppid());//execl("./otherExe", "otherExe", NULL);execl("/usr/bin/bash", "bash", "test.sh", NULL);}return 0;
}
这样就可以在C程序中执行脚本代码,还可以发现其他什么 .py 这种python文件也一样可以运行。
无论是我们的可执行程序,还是脚本,为什么能跨语言调用呢???
这是因为:所有的语言写成的运行起来,本质都是进程!!!只要是进程,就能用exec系列接口调用。
回到正题:将这个的目的就是为了验证execle时,要传环境变量,因为我们自己写的程序是可以让他输出环境变量、命令行参数的,所以要用我们自己写的程序验证是否传入成功。
这时就需要观察:由一个程序形成的环境变量如何导给另一个程序(需要我们自己写程序并且一个调用另一个)
先来验证一下命令行参数:我们前面的结论说,命令行参数会在接口内部传给那个命令。
mycommand.c:
int main()
{pid_t id = fork();if(id == 0){printf("before: i am a process, pid: %d, ppid: %d\n", getpid(), getppid());char *const myargv[] = {"otherExe","-a","-b","-c",NULL};execv("./otherExe", myargv);}return 0;
}
它会把这些个命令行参数传给 otherExe,然后otherExe.cpp:
int main(int argc, char *argv[])
{cout << argv[0] << " begin running" << endl;for(int i=0; argv[i]; i++){cout << i << ":" << argv[i] << endl;}cout << argv[0] << " stop running" << endl;return 0;
}
他会接收到命令行参数,然后打印出来,事实上的效果:
可以看到命令行参数确实传递成功了。
接下来验证一下环境变量:
将otherExe修改成:
int main(int argc, char *argv[], char* env[])
{cout << argv[0] << " begin running" << endl;cout << "这是命令行参数" << endl;for(int i=0; argv[i]; i++){cout << i << ":" << argv[i] << endl;}cout << "这是环境变量" << endl;for(int i=0; env[i]; i++){cout << i << ":" << env[i] << endl;}cout << argv[0] << " stop running" << endl;return 0;
}
我们可以看到:我们调用execv,只传了命令行参数,都没传环境变量,就能打印出来。
环境变量是什么时候给进程的呢?
环境变量也是数据,在创建子进程的时候,环境变量已经被子进程继承下去了!!!
所以即便没传,也有上面继承下来的环境变量。
所以,程序替换中,环境变量信息不会被替换!会一路继承。
bash创建一个子进程,会传给它环境变量,./mycommand也会创建进程,程序替换后调用./otherExe,也会创建进程,一路继承。
如果不想让bash创建环境变量,非要在mycommand中创建环境变量也是可以的:
- putenv("PRIVATE_ENV=2025516");
-
extern char** environ; execle("./otherExe", "otherExe", "-a", "-b", NULL, environ);
这个environ就是父进程环境变量
自定义环境变量也是可以的,但是这样传过去就只有自己定义的环境变量了,其他的就看不到了。
所以我们想给子进程传递环境变量,该怎么传递??
- 新增环境变量
- 父进程地址空间中直接putenv
- bash直接添加
- 彻底替换
相关文章:
7. 进程控制-进程替换
目录 1. 进程替换 1.1 单进程版: 1.2 进程替换的原理 1.3 多进程版-验证各种程序替换接口 2. 进程替换的各种接口 2.1 execl 2.2 execlp 2.3 execv 2.4 execvp 2.5 execle 1. 进程替换 上图为程序替换的接口,之后会详细介绍。 1.1 单进程版&am…...
关于计算机系统和数据原子性的联系
目录 1、计算机架构 1.1、处理器架构 1.2、内存寻址能力 1.3、性能差异 1.4、软件兼容性 1.5、指令集 1.6、开发和维护 2.、基本数据类型 3、原子类型 3.1、基本概念 3.2、基本数据类型的原子性 3.3、原子操作的解释 3.4、不保证原子性 3.5、解决方案 4、原子性…...
Armijo rule
非精线搜索步长规则Armijo规则&Goldstein规则&Wolfe规则_armijo rule-CSDN博客 [原创]用“人话”解释不精确线搜索中的Armijo-Goldstein准则及Wolfe-Powell准则 – 编码无悔 / Intent & Focused...
从数据包到可靠性:UDP/TCP协议的工作原理分析
之前我们已经使用udp/tcp的相关接口写了一些简单的客户端与服务端代码。也了解了协议是什么,包括自定义协议和知名协议比如http/https和ssh等。现在我们再回到传输层,对udp和tcp这两传输层巨头协议做更深一步的分析。 一.UDP UDP相关内容很简单…...
Prometheus实战教程:k8s平台-Mysql监控案例
配置文件优化后的 Prometheus 自动发现 MySQL 实例的完整 YAML 文件。该配置包括: MySQL Exporter 部署:使用 ConfigMap 提供 MySQL 连接信息。Prometheus 自动发现:通过 Kubernetes 服务发现自动抓取 MySQL 实例。 1、mysql 配置文件 &…...
执行apt-get update 报错ModuleNotFoundError: No module named ‘apt_pkg‘的解决方案汇总
Ubuntu版本ubuntu18.04 报错内容: //执行apt-get upgrade报错: Traceback :File “/usr/lib/cnf-update-db”, line 8, in <module>from CommandNotFound.db.creator import DbcreatorFile “/usr/lib/python3/dist-packages/CommandNotFound/db…...
QT6 源(101)篇一:阅读与注释 QPlainTextEdit,其继承于QAbstractScrollArea,属性学习与测试
(1) (2) (3)属性学习与测试 : (4) (5) 谢谢...
Redis(2):Redis + Lua为什么可以实现原子性
Redis 作为一款高性能的键值对存储数据库,与 Lua 脚本相结合,为实现原子性操作提供了强大的解决方案,本文将深入探讨 Redis Lua 实现原子性的相关知识 原子性概念的厘清 在探讨 Redis Lua 的原子性之前,我们需要明确原子性的概念…...
ios打包ipa获取证书和打包创建经验分享
在云打包或本地打包ios应用,打包成ipa格式的app文件的过程中,私钥证书和profile文件是必须的。 其实打包的过程并不难,因为像hbuilderx这些打包工具,只要你输入的是正确的证书,打包就肯定会成功。因此,证书…...
Python生成器:高效处理大数据的秘密武器
生成器概述 生成器是 Python 中的一种特殊迭代器,通过普通函数的语法实现,但使用 yield 语句返回数据。生成器自动实现了 __iter__() 和 __next__() 方法,因此可以直接用于迭代。生成器的核心特点是延迟计算(lazy evaluation&…...
C++11(2)
文章目录 右值引用和移动语义在传参中的提效list容器push_back & insert右值版本的模拟实现类型分类 (了解即可)引用折叠万能引用 完美转发(跟引用折叠有关) 简介:这篇文章是继续介绍C11的一些新语法知识点,也是对…...
unity terrain 在生成草,树,石头等地形障碍的时候,无法触发碰撞导致人物穿过模型
1.terrain地形的草,石头之类要选择模型预制体 2.在人物身上挂碰撞器和刚体,或者单挂一个character controller组件也行 3.在预制体上挂碰撞盒就好了,挂载meshcollider会导致碰撞无效...
以项目的方式学QT开发C++(二)——超详细讲解(120000多字详细讲解,涵盖qt大量知识)逐步更新!
API 描述 函数原型 参数说明 push_back() 在 list 尾部 添加一个元素 void push_back(const T& value); value :要添 加到尾部的元 素 这个示例演示了如何创建 std::list 容器,并对其进行插入、删除和迭代操作。在实际应用中&am…...
养生:健康生活的极简攻略
在追求高效生活的当下,养生也能化繁为简。通过饮食、运动、睡眠与心态的精准调节,就能轻松为健康续航。 饮食上,遵循 “均衡、节制” 原则。早餐用一杯热豆浆搭配水煮蛋和半个苹果,唤醒肠胃活力;午餐以糙米饭为主食&am…...
C语言-8.数组
8.1数组 8.1.1初试数组 如何写一个程序计算用户输入的数字的平均数? #include<stdio.h> int main() {int digit;//输入要求平均数的数字double sum=0;//记录输入数字的和int count=0;//记录输入数字的个数printf("请输入一组数字,用来求平均数,以-1结束\n&quo…...
代码随想录算法训练营第四十一天
LeetCode题目: 739. 每日温度496. 下一个更大元素 I503. 下一个更大元素 II 其他: 今日总结 往期打卡 739. 每日温度 跳转: 739. 每日温度 学习: 代码随想录公开讲解 问题: 给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer &…...
c++,windows,多线程编程详细介绍
目录 一、C11 标准库 <thread> 实现多线程编程1. 基本线程创建2. 线程管理3. 线程传参4. 同步机制5. 异步编程 二、Windows API 实现多线程编程1. 基本线程创建2. 线程管理3. 线程传参 三、两种方法的对比 在 Windows 平台上使用 C 进行多线程编程,可以通过 C…...
Python多线程
Python多线程 作为一名Python开发者,你是否遇到过这样的场景:程序需要同时处理多个任务,但单线程执行效率太低?这时候,多线程技术就能派上用场了。本文将带你深入浅出地理解Python多线程,并通过丰富的示例…...
VisionPro斑点寻找工具Blob
斑点寻找工具Blob 斑点概述 斑点分析 探测并且分析图像中的二维形状Blob是先根据用户设定好的灰阶范围对图像进行分割,然后对目标进行查找和分析。斑点报告多种属性: 面积质心周长主轴…….. 应用场景 Blob分析非常适合以下场合的应用: 对…...
【Python】【面试凉经】Fastapi为什么Fast
核心的关键词:ASGI、原生异步、协程、uvloop、异步生态、Pydantic编译时生成校验代码、DI system预计算依赖树 interviewer 00:32:49 FastAPI 它优越于其他一些主流web框架像 django或 flask 的这个点在哪里? 我 00:33:00fastapi 就是说它的 fast 性能高…...
LocalDateTime类型的时间在前端页面不显示或者修改数据时因为LocalDateTime导致无法修改,解决方案
1.数据库中的时间数据,在控制台可以正常返回,在前端无法返回,即显示空白,如下图所示: 2.这种问题一般时由于数据库和我们实体类的名称不一致引起的,我们数据库一般采用_的方式命名,但是在Java中我们一般采用…...
【Linux】gcc从源码编译安装,修改源码,验证修改的源码
前阵子电脑使用的win10,win10过几天就让升级,烦得不行。 然后把操作系统切换到ubuntu24的样子,然后也是让升级,又烦的不行,然后切换到ubuntu server版本,感觉用起来要舒服些了,至少不会天天让升级。 回到标…...
牛客网NC22157:牛牛学数列2
牛客网NC22157:牛牛学数列2 📝 题目描述 🔍 输入输出说明 输入描述: 输入一个整数 N,范围在 0 到 1000 输出描述: 输出一个保留6位小数的浮点数 示例: 输入:2输出:1.500000 …...
智能手表集成测试报告(Integration Test Report)
📄 智能手表集成测试报告(Integration Test Report) 项目名称:Aurora Watch S1 测试阶段:系统集成测试 测试周期:2025年xx月xx日 – 2025年xx月xx日 报告编号:AW-S1-ITR-2025-001 版本…...
1C:ENTERPRISE 8.3 实用开发者指南-示例和标准技术(Session1-Session3)
1C:ENTERPRISE 8.3(1课-3课) 本博客是全网首个关于1C:Enterprice的中文指南,支持快速吸收使用 1C:Enterprise 8.3 软件开发和调整应用程序的技术 在这篇博客中我会基于实际应用示例,演示各种系统对象的结构、功能和用法。使用内…...
AgenticSeek开源的完全本地的 Manus AI。无需 API,享受一个自主代理,它可以思考、浏览 Web 和编码,只需支付电费。
一、软件介绍 文末提供程序和源码下载 AgenticSeek开源的完全本地的 Manus AI。无需 API,享受一个自主代理,它可以思考、浏览 Web 和编码,只需支付电费。这款支持语音的 AI 助手是 Manus AI 的 100% 本地替代品 ,可自主浏览网页…...
Java类一文分解:JavaBean,工具类,测试类的深度剖析
解锁Java类的神秘面纱:从JavaBean到测试类的深度剖析 前言一、JavaBean 类:数据的守护者(一)JavaBean 类是什么(二)JavaBean 类的特征(三)JavaBean 类的使用场景(四&…...
2025认证杯数学建模第二阶段C题:化工厂生产流程的预测和控制,思路+模型+代码
2025认证杯数学建模第二阶段思路模型代码,详细内容见文末名片 一、探秘化工世界:问题背景大揭秘 在 2025 年 “认证杯”数学中国数学建模网络挑战赛第二阶段 C 题中,我们一头扎进了神秘又复杂的化工厂生产流程预测与控制领域。想象一下&…...
day 17 无监督学习之聚类算法
一、聚类流程 1. 利用聚类发现数据模式 无监督算法中的聚类,目的就是将数据点划分成不同的组或 “簇”,使得同一簇内的数据点相似度较高,而不同簇的数据点相似度较低,从而发现数据中隐藏的模式。 2. 对聚类后的类别特征进行可视…...
渗透测试流程-上篇
#作者:允砸儿 #日期:乙巳青蛇年 四月十八 本期就开始进入到网安的内容了笔者会和大家一起开始实操练习。在此之前笔者的老师和我说要知己知彼,胆大心细。笔者也把他的理念传出去,网安的知识比较复杂且使用的工具很多。笔者看过…...
Ubuntu离线安装Minio
MinIO 支持在 Linux 环境下离线安装,非常适合内网或无法联网的服务器环境。下面是详细的 Linux 离线安装 MinIO 服务端 的步骤: ✅ 一、准备工作 1. 创建安装目录(可选) mkdir -p /opt/minio cd /opt/minio2. 下载 MinIO 可执行…...
2025年山东省数学建模F题思路
2025年山东省数学建模F题思路 一、问题背景 在现代金融市场中,资产价格波动呈现出非线性、高噪声、强跨市场联动性等复杂动态特征。例如,2020年新冠疫情期间,美股数次熔断事件引发全球股市剧烈震荡;而2023年美元加息周期&#x…...
C++核心编程--3 函数提高
函数的一些高级用法。 3.1 函数形参默认值 C中,函数的形参可以有默认值,调用函数时,未进行赋值的形参会使用默认值 void func(int f_var1 10, int f_var2 20); // 声明 void func(int f_var1, int f_var2) // 定义 {std::cout <&l…...
AI Agent开发第67课-彻底消除RAG知识库幻觉(1)-文档分块全技巧
开篇 在上篇《AI Agent开发第66课-彻底消除RAG知识库幻觉-带推理的RAG》放出后,网友们反响很大。有得告诉我:原来还有Rewrite这么一招?早知道这一招很多之前的一些遗留问题都能解决了。不过在上一篇结尾我已经提到了,要真正解决一个AI Agent在响应时产生的幻觉我们用提示语…...
c++多态面试题之(析构函数与虚函数)
有以下问题展开 析构函数要不要定义成虚函数?基类的析构函数要不要定义成虚函数?如果不定义会有什么问题,定义了在什么场景下起作用。 1. 基类析构函数何时必须定义为虚函数? 当且仅当通过基类指针(或引用)…...
buildroot使用外部编译链编译bluez蓝牙工具
buildroot使用外部编译链编译bluez蓝牙工具 主要参见这个csdn buildroot使用外部编译链编译bluez蓝牙工具_bluez编译-CSDN博客 设置交叉编译工具路径时,设置到bin目录之前 如果menuconfig不能改路径,就去 .config下去改 这样才能编译过...
自定义类型:结构体
1.结构体类型的声明 1.1.1结构的声明 struct tag {member-list; }variable-list; 描述一个学生:只包含了学生的名字、年龄、性别、学号 struct Stu {char name[20];//名字int age;//年龄char sex[5];//性别char id[20];//学号 }; 1.1.2 结构体变量的创建和初始…...
以项目的方式学QT开发C++(一)——超详细讲解(120000多字详细讲解,涵盖qt大量知识)逐步更新!
以项目的方式学QT开发 以项目的方式学QT开发 P1 QT介绍 1.1 QT简介 1.2 QT安装 1.2.1 Windows QT安装 1.2.2 QT Creator 使用基本介绍 P2 C基础 2.1 命名空间 2.1.1 命名空间作用 2.1.2 自定义命名空间 2.2 从C语言快速入门 2.2.1 输入输出 2.2.2 基…...
Spring框架的事务管理
引言 在企业级应用开发中,事务管理是一个至关重要的环节,它确保了数据的一致性和完整性。Spring 框架为我们提供了强大而灵活的事务管理功能,能够帮助开发者更轻松地处理复杂的事务场景。本文将深入探讨 Spring 框架的事务管理,包…...
TypeScript:类
一、基本概念 TypeScript 类是基于 ES6 类的语法扩展,增加了类型注解和访问修饰符等特性,提供了更强大的面向对象编程能力。 二、基本语法 class Person {name: string;age: number;constructor(name: string, age: number) {this.name name;this.ag…...
Python继承
在Python编程中,继承是一个让新手又爱又怕的概念。今天我们就来聊聊这个看似高深实则简单的特性,保证让你看完后能拍着胸脯说:“继承嘛,小菜一碟!” 一、什么是继承? 想象一下你正在玩一个养成游戏。你创…...
浏览器宝塔访问不了给的面板地址
注意你们的端口,服务器的端口开放了没!!!宝塔给的端口是否在范围之内!! 我的当时是1000/10000 (阿里云服务器) 但是宝塔给的是 4W多 对不上!! 更换安全组…...
强化学习入门:马尔科夫奖励过程
文章目录 前言1、组成部分2、应用例子3、马尔科夫奖励过程总结 前言 最近想开一个关于强化学习专栏,因为DeepSeek-R1很火,但本人对于LLM连门都没入。因此,只是记录一些类似的读书笔记,内容不深,大多数只是一些概念的东…...
RHCE实验:通过脚本判断用户是否存在
一、实验要求 1、 写一个脚本,使用函数完成 1 、函数能够接受一个参数,参数为用户名; 判断一个用户是否存在 如果存在, 就返回此用户的 shell 和 UID ;并返回正常状态值; 如果不存在,就说此用…...
Windows软件插件-音视频捕获
下载本插件 音视频捕获就是获取电脑外接的话筒,摄像头,或线路输入的音频和视频。 本插件捕获电脑外接的音频和视频。最多可以同时获取4个视频源和4个音频源。插件可以在win32和MFC程序中使用。 使用方法 首先,加载本“捕获”DLL,…...
每日算法 - 【Swift 算法】Two Sum 问题:从暴力解法到最优解法的演进
【Swift 算法】Two Sum 问题:从暴力解法到最优解法的演进 本文通过“Two Sum”问题,带你了解如何从最直观的暴力解法,逐步优化到高效的哈希表解法,并对两者进行对比,适合算法入门和面试准备。 💡 问题描述 …...
2025年,如何制作并部署一个完整的个人博客网站
欢迎访问我的个人博客网站:欢迎来到Turnin的个人博客 github开源地址:https://github.com/Re-restart/my_website 前言 2024年年初,从dji实习回来之后,我一直想着拓宽自己的知识边界。在那里我发现虽然大家不用java,…...
深度学习框架---TensorFlow概览
一、TensorFlow 概述 1. 发展历程 1.x 版本:基于静态图(Graph)和会话(Session),需预先定义计算图,调试较复杂。2.x 版本:默认启用动态图(Eager Execution)&…...
鸿蒙OSUniApp制作自定义的下拉菜单组件(鸿蒙系统适配版)#三方框架 #Uniapp
UniApp制作自定义的下拉菜单组件(鸿蒙系统适配版) 前言 在移动应用开发中,下拉菜单是一个常见且实用的交互组件,它能在有限的屏幕空间内展示更多的选项。虽然各种UI框架都提供了下拉菜单组件,但在一些特定场景下&…...
扣子(Coze)案例:工作流生成小红书心理学卡片
大家好!我是 Robin。专注于 AI 技术探索与实践,持续分享 Coze 智能体、Coze 模板,以及 Coze 工作流搭建案例。 工作流智能体作用: 输入需要生成小红书心理学知识卡片的数量,工作流自动批量生成图文。 首先演示一下生…...