【Linux进程】进程状态---进程僵尸与孤儿
📙 作者简介 :RO-BERRY
📗 学习方向:致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识
📒 日后方向 : 偏向于CPP开发以及大数据方向,欢迎各位关注,谢谢各位的支持

目录
- 1.进程排队
- 2.进程状态
- 3.Linux下的进程状态
- 查看状态
- 初遇前台进程和后台进程
- 查看T状态--停止状态
- 查看Z状态--僵尸状态
- 4.查看进程状态相关的常用命令:
1.进程排队
进程 = taskk_stuct + 可执行程序
进程不是一直在运行的
进程放在cpu上也不会一直运行的
它可能在等待某个软硬件资源
例如,我们写一个scanf函数
#include<stdio.h>
int main()
{int a;scanf("%d",&a);printf("%d\n",a);return 0;
}
我们执行了文件,但是不输入a的值,那么这个进程一直都会存在,因为它在等待我们输入数据
那为什么我们在Linux系统里写死循环都不会出现程序挂掉的情况呢?
这里我们引入一个概念叫时间片
时间片(timeslice)又称为“量子(quantum)”或“处理器片(processor slice)”是分时操作系统分配给每个正在运行的进程微观上的一段CPU时间(在抢占内核中是:从进程开始运行直到被抢占的时间)。现代操作系统(如:Windows、Linux、Mac OS X等)允许同时运行多个进程 —— 例如,你可以在打开音乐播放器听音乐的同时用浏览器浏览网页并下载文件。事实上,虽然一台计算机通常可能有多个CPU,但是同一个CPU永远不可能真正地同时运行多个任务。在只考虑一个CPU的情况下,这些进程“看起来像”同时运行的,实则是轮番穿插地运行,由于时间片通常很短(在Linux上为5ms-800ms),用户不会感觉到。
时间片由操作系统内核的调度程序分配给每个进程。首先,内核会给每个进程分配相等的初始时间片,然后每个进程轮番地执行相应的时间,当所有进程都处于时间片耗尽的状态时,内核会重新为每个进程计算并分配时间片,如此往复。
所谓进程排队,就是进程在等待一个资源
进程 = task_stuct + 可执行程序
那么是task_stuct在排队
还是可执行程序在排队呢?
例如我们找工作,我们向hr投简历,hr手里有很多分简历,他会从里面挑选出比较好的分出来,进行一份一份的查看,那么还没有看到我们的简历的过程就属于我们的简历进行排队,所以是我们的简历在排队而不是我们本人在排队,引入到进程,只要是排队,一定就是task_stuct(PCB)在排队
2.进程状态
进程是一个动态的实体,所以它是有生命的,从创建到消亡,是一个进程的整个生命周期。一般有三个状态。
就绪态 :进程已经获得所需的其他资源,正在申请处理器资源,准备开始执行,这种情况下,称进程处于就绪态
阻塞态(休眠态或者等待态):进程需要等待所需资源而放弃处理器,或者是进程不拥有处理器而且其他资源也没有满足,从而即使得到处理器也不能运行的状态
执行态:进程得到了处理器,并不需要等待其他任何资源,正在执行的状态,称之为运行态,只有在运行态时,进程才可以使用所申请的资源

- 事实上所谓的状态,本质是一个整形变量,在task_struct中的一个整形变量
#define New 1 //创建状态
#define Ready 2 //就绪状态
#define running 3 //执行状态
#define block 4 //阻塞状态
task_struct中中存有一个status整形变量,当status为不同整形数值的时候,相对应的就是不同的状态
- 状态决定了什么?
状态决定了你的后续动作
例如:有人喊你出去玩,但是你感冒了,所以你状态不好,你打算在宿舍躺平休息。
运行状态
在Linux中可能会存在多个进程,都要根据其状态来执行后续动作,这个时候就会进行进程排队
一个CPU就会维护一个运行队列,大部分电脑都是单CPU,当进程放进了CPU的对应运行队列当中,那么我们称这个状态就为运行状态
阻塞状态
进程不是一直在运行的,进程放在CPU上也不会一直运行的,它可能在等待某个软硬件资源,前面讲过操作系统管理软硬件程序是先描述再组织,对进程也是一样,将进程描述成各个结构体对象使用双链表串联起来,所以当我们的进程在等待软硬件设施的时候,就会从CPU的运行队列转移到我们软硬件资源的等待队列,就形成了阻塞状态
当我们的进程在等待软硬件资源的时候,资源如果没有就绪,我们的进程task_struct只能
1.将自己设置为阻塞状态
2.将自己的PCB连入等待的资源提供的等待队列
结论:状态的变迁,引起的是PCB会被OS变迁到不同的队列中,不同的队列(cpu运行队列,磁盘资源等待队列等等)对应着队列里的进程不同的状态
挂起状态
前提:计算机资源已经比较吃紧了
挂起就是将进程的代码数据交换到外设当中,当需要的时候再换进来,也就是一个腾空间的操作,这是因为操作系统内存不够,容易发生风险,如果操作系统挂了就会崩溃
挂起状态(Suspended)是操作系统中的一种进程状态,当一个进程被挂起时,它暂时被从内存中移除。
挂起状态通常发生在系统资源有限,如内存不足的情况下。此时,操作系统会合理地安排内存中的程序,有些进程可能会被暂时调离内存。当系统资源变得充足时,之前被挂起的进程可以再次被调入内存,并恢复到等待执行的就绪状态。挂起状态通常用于以下几种情况:
- 终端用户请求。当用户发现程序运行中存在问题,希望暂停程序以便研究或修改时,可以将程序挂起。
- 父进程请求。父进程有时希望挂起某个子进程,以便对其进行修改或协调子进程间的活动。
- 负荷调节的需要。在实时系统中,当工作负荷较重,可能会影响对实时任务的控制时,系统可能会挂起一些不重要的进程,以确保系统正常运行。
- 操作系统的需要。操作系统有时会挂起某些进程,以便检查资源使用情况或进行记账。
需要注意的是,挂起状态与阻塞状态不同。挂起状态是进程主动选择的一种状态,而阻塞状态通常发生在进程等待某些事件(如IO操作)时。
3.Linux下的进程状态
linux系统中,将各种状态进行了重新组织,得到了5种状态。
- 运行态-R:正在运行的,以及拿到时间片就能运行的(RUNNING)。
正在运行或者在就绪队列中等待运行的进程,也就是上面提到的运行态和就绪态的综合,一个进程处于RUNNING并不代表他一定在被执行,由于在多任务系统中,各个就绪进程需要并发执行,所以某个特定时刻,这些处于RUNNING状态的进程中,只有一个能得到处理器,而其他进程必须有一个就绪队列中等待,即使在多处理器的系统中,linux只能同时让一个处理器执行任务
- 不可中断休眠态-D(disk IO):不可被打断的阻塞状态(UNINTERRUPTABLE)
处于这种状态的进程正在等待队列中,当资源有效时,可以由操作系统唤醒(通过wake_up()调用唤醒),否则一直处于等待状态;
- 可中断休眠态-S(shallow):可以被打断的阻塞状态(INTERRUPTABLE)
与不可中断阻塞状态一样,处于这种状态的进程在等待队列中,当资源有效时,可以由操作系统进行唤醒,与不可中断阻塞状态区别是:处于此状态中的进程也可以被其他进程所唤醒(可以被其他进程通过信号来唤醒,或者通过操作系统的wake_up()唤醒);
- 停止态-T:停止运行(STOPPED)
也就是挂起状态,进程被暂停,需要通过其它进程的信号才能被唤醒,导致这种状态的原因有两个 1.收到相关信号的反应 2.受到父进程ptrace调用的控制,而暂时将处理器交给控制进程;
- 僵尸态-Z:程序退出后的中间等待处理状态(ZOMBIE)
表示进程结束但尚未消亡的一种状态,此时进程已经结束运行并释放掉大部分资源,但尚未释放进程控制块。
僵尸状态是一个比较特殊的状态。当进程退出并且父进程(使⽤用wait()系统调⽤)没有读取到子进程退出的返回代码时就会产生僵死(尸)进程。僵死进程会以终⽌止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态。
状态在kernel源代码里定义
/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};
查看状态
写一个myprocess.c,并运行
- 情况一


可以看到进程在运行但是右边显示处于S状态,也就是休眠状态,这是为什么?
这是因为在Linux操作系统里程序执行print函数是非常快的,并且在程序里执行了printf后接上了sleep函数,printf函数运行速度是远远快于sleep的,相当于可以看成全程在进行休眠状态
- 情况二


左边程序疯狂进行输出,但是状态依然是S休眠状态,这又是为什么?
printf的本质是向显示器打印,我们在xshell上运行时在云服务器上打印运行的,但是是在我们的显示器上来打印的,这其中是需要访问外设的,外设的速度是非常慢的,所以我们的程序%95是在等待外设资源的,只有很短时间是用来运行的,也就是说依然大部分时间处于休眠状态
- 情况三


终于可以看到,进程为R状态了,因为这是个死循环
结论:
在Linux系统里,只有运行进程真正在运行队列里才会视作为运行状态,只不过大部分运行进程都会访问外设,这是需要花费很大的时间的,所以就不会一直在运行队列当中,就会显示S状态
初遇前台进程和后台进程


我们普通运行的进程就是前台进程,可以看到我们在进程运行的时候输入指令是没有用的,并且进程是可以用【Ctrl+C】结束进程的
我们在运行的可执行程序后面加上&
./myprocess &

我们可以看到进程运行过程中输入指令是会打印数据的,并且使用热键【Ctrl+C】是无法结束进程的
这就是后台进程,这里的进程状态从S+变为S
我们结束后台进程需要使用
kill -9 PID

查看T状态–停止状态
使用指令kill -19 PID—>让进程处于暂停状态

也可以使用kill -18 PID—>让进程继续运行

这个时候使用【Ctrl+C】是结束不了进程的
需要使用kill -9 PID

查看Z状态–僵尸状态
myprocess.c
1 #include<stdio.h>2 #include<unistd.h>3 int main()4 {5 pid_t id =fork();6 if(id == 0)7 {8 //child9 int cnt = 5;10 while(cnt)11 {12 printf("I am child, pid: %d,ppid: %d\n",getpid(),getppid()); 13 sleep(1);14 cnt--;15 }16 exit(0); //让子进程直接退出17 }18 //father19 while(1)20 {21 printf("I am father, pid: %d,ppid: %d\n",getpid(),getppid());22 sleep(1);23 }24 }
Makefile
myprocess:myprocess.cgcc -o $@ $^ #-std=c99
.PHONY:clean
clean:rm -f myprocess
查看进程信息代码
while :;do ps ajx | head -1 && ps ajx | grep myprocess | grep -v grep ;sleep 1; done
运行结果:

刚开始两个进程都在跑,后来子进程挂掉了,父进程一个人在运行,右边的进程状态可以看到,我们子进程进程状态为z+,子进程成为了僵尸进程
僵尸进程的危害:
- 进程的退出状态必须被维持下去,因为僵尸进程要告诉关心它的进程(父进程),你交给我的任务,我办的怎么样了。可父进程如果⼀直不读取,那子进程就⼀直处于Z状态?是的!
- 维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话说,Z状态⼀直不退出,PCB⼀直都要维护?是的!
- 那⼀个父进程创建了很多子进程,就是不回收,是不是就会造成内存资源的浪费?是的!因为数据结构对象本身就要占⽤用内存,想想C中定义⼀个结构体变量(对象),是要在内存的某个位置进行开辟空间!
- 内存泄漏?是的!
对于上面进程状态,需要说明的是:
【暂停T和睡眠S的区别:sleep做事情了,stop没有做事情,什么都没做。】
【S为浅度睡眠,可唤醒;D状态为深度睡眠状态,不可强制唤醒。S状态的进程可以被杀死,D状态不能被杀死】

既然说到了僵尸进程,就不得不提孤儿进程了。
孤儿进程:
父进程如果提前退出,那么子进程就称之为“孤儿进程”
孤儿进程会被1号init进程领养,也就是说会由1号进程进行回收。
父进程退出后为什么没有成为僵尸进程?因为父进程的父进程bash会立刻对死掉的父进程进行回收。
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{pid_t id =fork();if(id == 0){//childint cnt = 500;while(cnt){printf("I am child, pid: %d,ppid: %d\n",getpid(),getppid());sleep(1);cnt--;}exit(0); //让子进程直接退出}int cnt = 5;//fatherwhile(cnt){cnt--; //这里让父进程先行结束printf("I am father, pid: %d,ppid: %d\n",getpid(),getppid());sleep(1);}
}

父进程先退出但是父进程没有变成僵尸进程
子进程变为孤儿进程,父进程PID变为1,即被一号进程领养,并且变为后台进程,使用热键【Ctrl+C】无法退出

4.查看进程状态相关的常用命令:
ps -l列出与本次登录有关的进程信息;
ps -aux查询内存中进程信息;
ps -aux | grep查询进程的详细信息;
top查看内存中进程的动态信息;
kill -9 pid杀死进程。
PS:显示的进程状态 STAT 列表(与上面的3种状态、5种状态不一样):
R运行 Runnable (on run queue) ,正在运行或在运行队列中等待,
S睡眠 Sleeping 休眠中, 受阻, 在等待某个条件的形成或接受到信号,
I空闲 Idle
Z僵死 Zombie(a defunct process) 进程已终止, 但进程描述符存在, 直到父进程调用wait4()系统调用后释放
D不可中断 Uninterruptible sleep (ususally IO) 收到信号不唤醒和不可运行, 进程必须等待直到有中断发生
T终止 Terminate 进程收到SIGSTOP, SIGSTP, SIGTIN, SIGTOU信号后停止运行运行,
P等待交换页
W无驻留页 has no resident pages 没有足够的记忆体分页可分配
X死掉的进程
<高优先级进程 高优先序的进程
N低优先 级进程 低优先序的进程
L内存锁页 Lock 有记忆体分页分配并缩在记忆体内
s进程的领导者(在它之下有子进程)
+进程是“位于在前台进程组”,也就是进程可以使用键盘输出
l多线程,克隆线程 multi-threaded (using CLONE_THREAD, like NPTL pthreads do)
ps -aux(ps -aux | grep***, 列出***进程的详细信息)

USER:进程的所属用户
PID:进程的进程ID号,
%CPU:进程占用的 CPU资源 百分比
%MEM:进程占用的 物理内存 百分比,
VSZ:进程使用掉的虚拟内存量 (Kbytes)
RSS:进程占用的固定的内存量 (Kbytes)
TTY:与进程相关联的终端(tty),?代表无关,tty1-tty6是本机上面的登入者程序,pts/0表示为由网络连接进主机的程序
STAT:进程的状态,具体见前文列出的状态表
START:进程开始创建的时间
TIME:进程使用的总cpu时间
COMMAND: 进程对应的实际程序
相关文章:
【Linux进程】进程状态---进程僵尸与孤儿
📙 作者简介 :RO-BERRY 📗 学习方向:致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 📒 日后方向 : 偏向于CPP开发以及大数据方向,欢迎各位关注,谢谢各位的支持 目录 1.进程排队2.进程状态…...
MySQL数据库基础知识总结(适合小白入门使用)一
文章目录 一 数据库数据表的创建等基本操作二 数据类型的测试三 完整性约束条件四 数据表结构的相关操作五 对表中数据的操作六 表达式与查询七 高级的查询功能 一 数据库数据表的创建等基本操作 #注释内容(与python很像) -- 也为注释内容 -- 创建一个数…...
历史新知网:寄快递寄个电脑显示器要多少钱?
以下文字信息由(新史知识网)编辑整理发布。 让我们赶紧来看看吧! 问题1:快递寄电脑显示器要多少钱? 此物有多重? 顺丰寄就可以了,但是必须是原包装的,不然不好寄。 问题2࿱…...
在两台CentOS 7服务器上部署MinIO集群。
环境说明: 2台Centos7服务器 IP地址分别为172.16.1.9和172.16.1.10 1. 创建minio用户和目录 在两台服务器上执行以下命令: sudo useradd -m -d /app/minio minio sudo mkdir -p /app/minioData sudo mkdir -p /app/minio/logs sudo chown -R mini…...
【计算机网络】深度学习使用应用层的HTTP协议
💓 博客主页:从零开始的-CodeNinja之路 ⏩ 收录文章:【计算机网络】深度学习使用应用层的HTTP协议 🎉欢迎大家点赞👍评论📝收藏⭐文章 文章目录 一:HTTP是什么二:HTTP请求1.HTTP请求的组成2.HTTP请求的方法…...
Ubuntu18.04 系统上配置并运行SuperGluePretrainedNetwork(仅使用CPU)
SuperGlue是Magic Leap在CVPR 2020上展示的研究项目,它是一个图神经网络(Graph Neural Network)和最优匹配层(Optimal Matching layer)的结合,训练用于对两组稀疏图像特征进行匹配。这个项目提供了PyTorch代…...
协议-http协议-基础概念01-发展历程-http组成-http是什么-相关的应用-相关的协议
发展历程-http组成-http是什么-相关的应用-相关的协议 参考来源: 极客时间-透视HTTP协议(作者:罗剑锋); 01-HTTP的发展历程 1989 年,任职于欧洲核子研究中心(CERN)的蒂姆伯纳斯 - 李(Tim Ber…...
UI学习-学习内容
教程网址1:UI 新手如何从设计规范中提升自己 推荐一下高质量的设计规范 满屏干货 语雀 B站地址1:新像素 UI 新手如何从设计规范中提升自己 推荐一下高质量的设计规范 满屏干货 UI设计培训_哔哩哔哩_bilibili 教程地址2:UI 新手成长经验分享…...
Flink CDC 提取记录变更时间作为事件时间和 Hudi 表的 precombine.field 以及1970-01-01 取值问题
博主历时三年精心创作的《大数据平台架构与原型实现:数据中台建设实战》一书现已由知名IT图书品牌电子工业出版社博文视点出版发行,点击《重磅推荐:建大数据平台太难了!给我发个工程原型吧!》了解图书详情,…...
【网络安全】网络安全意识教育实用指南
随着科技的不断发展和数字世界的变革,我们不仅从中获得前所未有的力量,也同时面临着前所未有的风险挑战。多数CISO(首席信息安全官)时刻致力于协助企业抵御各种安全威胁。在“武器库”中有一件珍贵的法宝:网络安全意识…...
wordpress模板购买网站推荐
简站wordpress主题 老牌wordpress开发团队,开发过数百款wordpress主题,作品是最好的简历,靠作品说话,看作品喜欢不喜欢就可以了。 https://www.jianzhanpress.com WP模板牛 免费wordpress下载网站,上面有上百款免费…...
LeetCode 刷题 [C++] 第240题.搜索二维矩阵 II
题目描述 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性: 每行的元素从左到右升序排列。 每列的元素从上到下升序排列。 题目分析 通过分析矩阵的特点发现,其左下角和右上角可以看作一个“二叉搜索树的根节…...
HP笔记本电脑如何恢复出厂设置?这里提供几种方法
要恢复出厂设置Windows 11或10的HP笔记本电脑,你可以使用操作系统的标准方法。如果你运行的是早期版本,你可以使用HP提供的单独程序清除计算机并重新安装操作系统。 恢复出厂设置运行Windows 11的HP笔记本电脑 所有Windows 11计算机都有一个名为“重置此电脑”的功能,可…...
Elasticsearch:了解人工智能搜索算法
作者:来自 Elastic Jessica Taylor, Aditya Tripathi 人工智能工具无处不在,其原因并不神秘。 他们可以执行各种各样的任务并找到许多日常问题的解决方案。 但这些应用程序的好坏取决于它们的人工智能搜索算法。 简单来说,人工智能搜索算法是…...
(HAL)STM32F103C6T8——软件模拟I2C驱动0.96寸OLED屏幕
一、电路接法 电路接法参照江科大视频。 二、相关代码及文件 说明:代码采用hal库,通过修改江科大代码实现。仅OLED.c文件关于引脚定义作了hal库修改,并将宏定义OLED_W_SCL(x)、OLED_W_SDA(x)作了相关修改。 1、OLED.c void OLED_I2C_Init(voi…...
分享便携式血氧仪单片机方案
血氧仪主要测量指标分别为脉率、血氧饱和度、灌注指数。血氧饱和度是临床医疗上重要的基础数据之一。以家用指压式血氧仪为例,一个血氧仪一般由MCU、存储芯片、两个控制LED的数模转换器、两个发光二极管驱动等组成。 灵动微电子的MM32MCU产品已被广泛地应用在了一些…...
【Java设计模式】四、适配器模式
文章目录 1、适配器模式2、举例 1、适配器模式 适配器模式Adapter Pattern,是做为两个不兼容的接口之间的桥梁目的是将一个类的接口转换成客户希望的另外一个接口适配器模式可以使得原本由于接口不兼容而不能一起工作的那些类可以一起工作 最后,适配器…...
RV32/64 特权架构 - 特权模式与指令
RV32/64 特权架构 - 特权模式与指令 1 特权模式2 特权指令2.1 mret(从机器模式返回到先前的模式)2.2 sret(从监管模式返回到先前的模式)2.3 wfi(等待中断)2.4 sfence.vma(内存屏障) …...
多微服务合并为一个服务
公司微服务细分太多,最近跟我提说需要将几个微服务合为单体,经过几天的查阅,决定用二次打包的方式进行合并,然后部署的时候在nginx改下合并的微服务转发路劲即可,不需要前端修改路劲了。 方案 采用二次打包的方式进行…...
Springboot企业级开发--开发入门01
目录 目录 一.Spring Boot的主要特点和优势包括: 二.Spring Boot的核心功能可以归纳为以下几点: 三.Springboot是如何解决问题? Spring Boot 是一个开源的Java框架,其设计目标是为了简化新Spring应用的初始搭建以及开发过程。…...
计算机毕业设计:Python棉花种植产量与市场价格监测系统 Django框架 ARIMA算法 数据分析 可视化 爬虫 大数据 大模型(建议收藏)✅
1、项目介绍 技术栈 采用 Python 语言开发,基于 Django 框架搭建后端服务,使用 MySQL 数据库进行数据存储,通过 requests 爬虫技术从棉花产业经济信息网采集数据,运用时间序列 ARIMA 预测算法模型进行产量与价格预测,前…...
从选题到成稿:我是如何用AI搞定本科毕业论文的
又到一年毕业季,论文这座大山如期而至。作为刚刚度过这段“水深火热”时期的过来人,太理解各位学弟学妹此刻的心情了——选题方向模糊不清,文献资料查到头秃,院校要求看得云里雾里,码字速度更是感人肺腑。我当年也是这…...
BitNet b1.58-2B-4T-GGUF快速上手:WebUI界面操作+System Prompt调优指南
BitNet b1.58-2B-4T-GGUF快速上手:WebUI界面操作System Prompt调优指南 1. 项目概述 BitNet b1.58-2B-4T-GGUF是一款革命性的开源大语言模型,采用原生1.58-bit量化技术,在保持高性能的同时大幅降低资源消耗。这个模型最特别的地方在于它的权…...
从标注文件看CV任务演进:COCO的bbox、segmentation和keypoints字段都怎么用?
COCO标注文件解析:从边界框到关键点的视觉任务演进 计算机视觉领域的研究者和工程师们每天都在与各种标注数据打交道,而COCO数据集无疑是这个领域最具影响力的基准之一。不同于简单地介绍JSON文件结构,我们将从任务演进的视角,深入…...
终极指南:深入理解Swagger-Node核心组件与工作原理
终极指南:深入理解Swagger-Node核心组件与工作原理 【免费下载链接】swagger-node Swagger module for node.js 项目地址: https://gitcode.com/gh_mirrors/sw/swagger-node Swagger-Node是Node.js生态中一款强大的API开发工具,它通过直观的YAML配…...
告别花屏!用Arduino TFT_eSPI库驱动SPI LCD显示中文的保姆级避坑指南
告别花屏!用Arduino TFT_eSPI库驱动SPI LCD显示中文的保姆级避坑指南 第一次点亮SPI接口的LCD屏幕时,那种兴奋感就像打开了新世界的大门。但随之而来的花屏、乱码、内存溢出等问题,又让人瞬间跌入谷底。作为过来人,我完全理解这种…...
别再被“一键生成”忽悠了!好写作AI教你重新定义什么叫“好用的AI写作软件”
每隔一段时间,我的后台就会收到同一条私信: “老师,AI写作软件哪个好用?能不能推荐一个?” 这个问题看起来很简单,但每次我都不知道怎么回答。因为“好用”这两个字,对不同的人来说࿰…...
MIL-101(Cr)@Fe₃O₄ NPs,MIL-101(Cr)修饰四氧化三铁纳米颗粒,化学结构特点
MIL-101(Cr)Fe₃O₄ NPs,MIL-101(Cr)修饰四氧化三铁纳米颗粒,化学结构特点MIL-101(Cr)Fe₃O₄ NPs(MIL-101(Cr)修饰四氧化三铁纳米颗粒)是一类典型的磁性核–多孔框架壳层复合纳米体系,其化学结构特点主要体现在“Fe₃…...
Dify对接API、数据库、AI模型全流程详解:3小时搭建可交付智能应用(附完整YAML模板)
第一章:Dify低代码平台集成教程概览Dify 是一款开源的 LLM 应用开发平台,支持通过可视化界面快速构建 AI 原生应用(如聊天机器人、知识库问答、自动化工作流等),同时提供标准化 API 与灵活的 SDK 集成能力。本章聚焦于…...
AI Agent 开发的工业化道路:Harness 架构深度解析
1. 引言:从提示词工程到系统工程的范式转移在 AI Agent 迈向生产环境的过程中,开发者往往会陷入“提示词迷思”,试图通过无限堆砌 Prompt 来覆盖业务边界。然而,由于大模型本质上的概率性,纯粹的提示词工程在面对长链条…...
