xv6-labs-2024 lab1
lab-1
注:实验环境在我的汇编随手记的末尾部分有搭建教程。
0.前置
第零章
xv6为我们提供了多种系统调用,其中,exec将从某个文件里读取内存镜像(这确实是一个好的说法),并且将其替换到调用它的内存空间,也就是这个打开的文件(一切皆文件)替换了当前的进程,exec仅仅是这样的功能,同时,执行完成之后,exec并不会返回当前的调用进程,而是执行我们已经加载好的指令!
如果你阅读过手写docker或者类似讲过相关概念的书,你一定会知道,我们执行命令事实上是通过创建一个子进程,再在子进程中exec我们需要的命令!
exec并不是执行程序这个操作的全部,而只是将当前进程替换为某个可执行文件的工具,它需要结合 fork 使用,才是完整的执行命令的流程。
而命令执行完成,我们的子进程就会调用exit,使得我们的父进程从wait中返回。
**文件描述符是啥?**一切皆文件,我们的文件描述符可以是管道,文件,目录,socket的抽象,但是,值得注意的是,文件描述符并不代表了这个文件,而是指向这个文件的"指针",使得我们可以对其进行访问,我们可以获取多个指向同一个文件的文件描述符,并且能够对其进行写入,读取操作。
应用比如cat指令,cat并不关心你的文件描述符指向的是什么,使得我们可以轻松的实现cat指令,所以文件描述符是一个很棒的抽象。
甚至,fork和文件描述符可以实现我们的重定向,比如当我们fork一个进程之后,关闭子进程的文件描述符0(标准输入),然后重新打开一个我们指定的文件,文件描述符0指向的是我们指定的文件,也就是说,我们的标准输入来自于文件,而不是键盘了!然后我们执行cat,就会打印出我们的文件内容,指令为:cat < test.txt
。
一般来说,通过dup和fork产生的文件描述符都将共享同一个偏移量,但是有一些特殊情况,这里不详细说了。
管道
这段代码值得分析,先创建一个管道,读端文件描述符为p[0],写端为p[1],在我们的子进程中,先将文件描述符0(标准输入)关闭,然后调用我们的dup将文件描述符p[0]复制到标准输入中,此时,我们的wc就可以从文件中读取数据了,然后,我们还需要子进程的写端,因为子进程中,写端是无用的,如果不关闭,我们在wc进程中的read将会阻塞,无法返回。
而在父进程中,指向写入,然后关闭就行了。
int p[2];
char *argv[2];
argv[0] = "wc";
argv[1] = 0;
pipe(p);
if(fork() == 0) {close(0);dup(p[0]);close(p[0]);close(p[1]);exec("/bin/wc", argv);
} else {write(p[1], "hello world\n", 12);close(p[0]);close(p[1]);
}
管道比临时文件强大得多,管道支持自动销毁,支持发送任意长度的数据,支持同步地进程间通信。
文件系统
我看这部分主要讲的是文件就是一棵树,前面没啥好说的
mknod
表示创建一个设备文件,其元信息标志他是一个设备,并且记录了主设备号和辅设备号,他们确定了唯一设备,当进程打开这个文件的时候,内核会将读写操作转发到相应的设备上,而不是文件系统。
fstat
可以通过文件描述符获取他所指向的文件的信息。
这里的一个概念也挺有意思的,就是文件名和文件有很大的区别,一个文件可以有多个文件名,一个文件名同一时刻指向一个文件(inode),比如说下面:
open("a", O_CREATE|O_WRONGLY);
link("a", "b");
这里创建了一个文件,然后通过link使得这个文件既叫a,又叫b,但是,此时我们如果执行unlink('a')
,我们的inode和磁盘空间并不会被清空,因为此时我们的文件名b还指向它,所以一个文件的的inode和磁盘空间只有link数量为0的时候才会被清除
所以
fd = open("/tmp/xyz", O_CREATE|O_RDWR);
unlink("/tmp/xyz");
是创建一个临时inode的最好方式。
1. Sleep
挺简单的,应该就是让我们提升自信心的,先fork一个子进程,在子进程中调用sleep,父进程等待。
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"int main(int argc, char *argv[]) {if (argc != 2) {fprintf(1, "Usage: sleep seconds\n");exit(1);} int pid = fork();if (pid == 0) {unsigned int seconds = atoi(argv[1]);sleep(seconds * 10);exit(0);} else {wait(0);}exit(0);
}
2. PingPong
大部分都是前置内容,也就是教材里面讲过的,需要创建两个管道,以供来相互通信,注意关闭读写端的时机:
#include "kernel/types.h"
#include "user/user.h"int main(int argc, char *argv[]) {int p1[2];int p2[2];pipe(p1);pipe(p2);int pid1 = fork();if (pid1 == 0) {close(p1[1]);close(p2[0]);char buf[1];read(p1[0], buf, 1);close(p1[0]);printf("%d: received ping\n", getpid());write(p2[1], "x", 1);close(p2[1]);exit(0);}int pid2 = fork();if (pid2 == 0) {close(p1[0]);close(p2[1]);write(p1[1], "x", 1);close(p1[1]);char buf[1];read(p2[0], buf, 1);close(p2[0]);printf("%d: received pong\n", getpid());write(p1[1], "x", 1);close(p1[1]);exit(0);}
}
3. Primes
我去,这个lab真牛逼,最核心的点就是dup去复用我们的管道,让管道可以及时地被释放,这真的很重要!否则你的程序大概率只能跑到40左右的数字(血的教训),另外就是实验要求使用埃拉托色尼筛法,这一点我最开始也搞不懂要怎么去在管道之间传递这个数字,其实就是pipe不熟悉,还是问了gpt才明白,可以一个一个传,然后一个一个读取。
然后dup的使用也是参考了别人的blog,感觉自己就是菜。
总之感觉还是挺神奇的。
#include "kernel/types.h"
#include "user/user.h"void primes(int p0[2]) __attribute__((noreturn));int main(int argc, char *argv[]) {int p[2];pipe(p);int pid = fork();if (pid == 0) {//管道的关闭逻辑在primes函数中primes(p);} else {close(p[0]);for (int i = 2; i <= 280; i++) {write(p[1], &i, sizeof(i));}close(p[1]);wait(0);}exit(0);
}void primes(int old_pipe[2]) {//及时释放管道close(0);dup(old_pipe[0]);close(old_pipe[0]);close(old_pipe[1]);int prime;if (read(0, &prime, sizeof(prime)) == 0) {close(0);exit(0);}printf("prime %d\n", prime);//新建管道,并fork子进程int new_pipe[2];pipe(new_pipe);int pid = fork();if (pid == 0) {primes(new_pipe);} else {close(new_pipe[0]);int num;while (read(0, &num, sizeof(num))) {if (num % prime != 0) {write(new_pipe[1], &num, sizeof(num));}}close(0);close(new_pipe[1]);wait(0);}exit(0);
}
4. Find
实验hint,让我们可以从ls.c中知道怎么才可以展开当前目录,这部分完全是参考了ls.c里面的方法,知道了这一点,我们就很好做判断了。
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fs.h"void find(char *path, char *filename);int main(int argc, char *argv[]) {if (argc != 3) {fprintf(2, "Usage: find filename with path\n");exit(1);}//递归搜索find(argv[1], argv[2]);exit(0);}void find(char *path, char *filename) {char buf[512], *p;int fd;struct dirent de;struct stat st;if ((fd = open(path, 0)) < 0) {fprintf(2, "find: cannot open %s\n", path);return;}if (fstat(fd, &st) < 0) {fprintf(2, "find: cannot stat %s\n", path);close(fd);return;}switch (st.type) {case T_DIR:if (strlen(path) + 1 + DIRSIZ + 1 >= sizeof(buf)) {printf("find: path too long\n");break;}strcpy(buf, path);p = buf + strlen(buf);*p++ = '/';while (read(fd, &de, sizeof(de)) == sizeof(de)) {if (de.inum == 0)continue;memmove(p, de.name, DIRSIZ);p[DIRSIZ] = 0;if (stat(buf, &st) < 0) {printf("find: cannot stat %s\n", buf);continue;}if (st.type == T_FILE && strcmp(de.name, filename) == 0) {printf("%s\n", buf);}if (st.type == T_DIR && strcmp(de.name, ".") != 0 && strcmp(de.name, "..") != 0) {find(buf, filename);}}break;default:if (strcmp(path, filename) == 0) {printf("%s\n", path);}}close(fd);
}
这里有一个很有意思很有意思的东西,我直接跳转到read的实现,实际上但是他会直接跳到qemu的文件里面,导致我以为我们的read是qemu封装好的,但是实际上并不是,read确确实实我们的xv6自己实现的!我们可以通过这样去追溯它的根源:
- 在/user/usys.S中,找到有关read的字段,可以看见,它调用了SYS_read。
- 回到/kernel/syscall.c,我们可以看见syscall_read的具体定义。
- 跳转,我们会发现,调用了fileread这个函数,继续跳转
- 在这里,会调用一个至关重要的函数,就是read()
- 跳转到这个函数里面,read就是我们读取数据的关键函数
嗯。。这个函数还是蛮复杂的,先做下一个实验吧
5. Xargs
我没用过xargs,最开始可以说是一头雾水,包括最开始做的时候,甚至还不知道可以传递多行参数,改了半天。
整体思路就是先将当前右侧的参数读取,然后循环从标准输入中读取数据,遇到换行符,则执行命令,然后重置当前的参数和缓冲区为初始状态。
#include "kernel/types.h"
#include "user/user.h"
#include "kernel/param.h"int main(int argc, char *argv[]) {if (argc < 2) {fprintf(2, "Usage: xargs command [args...]\n");exit(1);}char *cmd = argv[1];char *args[MAXARG];int i, n = 0;// 复制参数for (i = 1; i < argc && n < MAXARG - 1; i++) {args[n++] = argv[i];}int end = n;//方便重置索引char buf[512];int m = 0;while (read(0, &buf[m], 1) == 1) {if (buf[m] == '\n') {buf[m] = 0;args[n++] = &buf[0];// 参数必须以 NULL 结尾args[n] = 0;int fd = fork();if (fd == 0) {exec(cmd, args);fprintf(2, "xargs: exec failed\n");exit(1);}wait(0);// 索引重置m = 0;n = end;} else {m++;}}exit(0);
}
lab1给我感觉倒是没有太多关于os的知识,更多的是需要你去熟悉这个xv6的大体是什么样的,给他添加一些组件。
目前来看,收获更多的还得是xv6的教科书,那里面确实能够学到很多东西,给我的感觉就是比其他我看过的任何操作系统课对小白都要友好得多。
相关文章:
xv6-labs-2024 lab1
lab-1 注:实验环境在我的汇编随手记的末尾部分有搭建教程。 0.前置 第零章 xv6为我们提供了多种系统调用,其中,exec将从某个文件里读取内存镜像(这确实是一个好的说法),并且将其替换到调用它的内存空间,也就是这个…...
HTTP Form v.s. Flask-WTF Form v.s. Bootstrap Form
在Flask-WTF和Bootstrap 的Form创建中,添加了页面显示Flash Messages。 相比Flask_WTF, Bootstrap用 render_form(form)渲染样式,自动带错误提示,不需要像Flask_WTF那样手写 for error in ... 。 项目结构: register_app/ ├── HTTP_Form_App.py ├── FlaskWTF_Form…...
Linux网络编程——https的协议及其加密解密方式
目录 一、前言 https协议 常见的加密方式 1、对称加密 2、非对称加密 3、数字签名 1. 只用对称加密 2、只用单一的非对称加密 3、双方都使用非对称加密 4、非对称加密对称加密 证书 证书颁发流程 服务器与客户端的证书验证流程 5、证书非对称加密对称加密 前言 上一…...
Node.js 下载与安装(图文)
下载 官网:【直达:https://nodejs.org/en/】。 点击【Download】,选择【版本,系统】。点击【Windows Installer(.msi)】。 安装 双击【.msi文件】,选择【安装路径】,也可以一直【下一步】。 查看版本 …...
3.31-4.06 Web3 游戏周报:Pebble 玩家留存率登顶,Treasure DAO 面临重组危机
回顾上周的区块链游戏概况,查看 Footprint Analytics 与 ABGA 最新发布的数据报告。 【3.31–4.06】Web3 游戏行业动态 链游生态系统 Treasure DAO 因财务危机面临重组,将终止游戏运营和 Treasure Chain3A 链游 Shrapnel 开发商 Neon Machine 深陷财务…...
echarts生成3D立体地图react组件
地图散点图效果: react项目中安装echarts、echarts-gl依赖: npm install echarts echarts-gl 文件目录结构: 地图组件map目录下文件代码,点击散点图圆点触发事件handleCityClick: index.jsx: import { …...
Node.js 中处理 Excel 文件的最佳实践
在现代应用开发中,Excel 文件仍然是数据交换和存储的重要格式之一。在 Node.js 环境中,处理 Excel 文件的需求日益增加。本文将介绍如何在 Node.js 中高效地处理 Excel 文件,涵盖工具选择、基本操作和最佳实践。 1. 选择合适的库 在 Node.js…...
解决Ubuntu系统鼠标不流畅的问题
电脑是联想的台式组装机,安装ubuntu系统(不管是16、18、20、22)后,鼠标都不流畅。最近几天想解决这个问题,于是怀疑到了显卡驱动上。怀疑之前一直用的是集成显卡,而不是独立显卡,毕竟2060的显卡…...
【Linux】虚拟机设置静态IP
主播我今天下午学了几节微服务课,上课的时候,直接把手机拿走了去上课(电脑连的我手机的热点),虚拟机没关,晚上主播我回来继续学,电脑连上热点之后,发现虚拟机连接不上了,…...
Web API:AbortController
Web API:AbortController 主要用途基本工作原理基本用法示例高级用例1. 实现请求超时2. 取消多个请求3. 与其他异步 API 一起使用 浏览器支持总结 主要用途 AbortController 是一个 Web API,主要用于取消一个或多个 Web 请求(如 fetch 请求&…...
服务器配置虚拟IP
服务器配置虚拟IP的核心步骤取决于具体场景,主要包括本地单机多IP配置和高可用集群下的虚拟IP管理两种模式。 一、本地虚拟IP配置(单服务器多IP) 基于Linux系统: 确认网络接口:使用 ip addr 或 ifconfig 查…...
《AI大模型应知应会100篇》第5篇:大模型发展简史:从BERT到ChatGPT的演进
第5篇:大模型发展简史:从BERT到ChatGPT的演进 摘要 近年来,人工智能领域最引人注目的进步之一是大模型(Large Language Models, LLMs)的发展。这些模型不仅推动了自然语言处理(NLP)技术的飞跃&…...
小球反弹(蓝桥杯C语言)
有一长方形,长为 343720343720 单位长度,宽为 233333233333 单位长度。在其内部左上角顶点有一小球 (无视其体积),其初速度如图所示且保持运动速率不变,分解到长宽两个方向上的速率之比为 dx:dy15:17dx:dy15:17。小球碰到长方形的…...
Java面试39-Zookeeper中的Watch机制的原理
Zookeeper是一个分布式协调组件,为分布式架构下的多个应用组件提供了顺序访问控制能力。它的数据存储采用了类似于文件系统的树形结构,以节点的方式来管理存储在Zookeeper上的数据。 Zookeeper提供了一个Watch机制,可以让客户端感知到Zooke…...
3️⃣ Coze工作流基础教学(2025年全新版本)
目录 一、什么是工作流 二、为什么用工作流 三、工作流使用场景 四、怎么学习工作流 五、工作流功能概述 六、制作工作流基础流程 6.1 创建工作流 6.2 配置工作流 6.3 调试工作流 6.4 发布工作流 6.5 使用工作流 6.6 复制工作流 6.7 删除工作流 6.8 设置工作流异…...
备战蓝桥杯——走迷宫问题(BFS解决)
这是一个经典的BFS算法 1. BFS算法保证最短路径 核心机制:广度优先搜索按层遍历所有可能的路径,首次到达终点的路径长度即为最短步数。这是BFS的核心优势。队列的作用:通过队列按先进先出的顺序处理节点,确保每一步探索的都是当…...
usbip学习记录
USB/IP: USB device sharing over IP make menuconfig配置: Device Drivers -> Staging drivers -> USB/IP support Device Drivers -> Staging drivers -> USB/IP support -> Host driver 如果还有作为客户端的需要,继续做以下配置&a…...
mlir-tblgen 的应用渐进式示例
示例01 -gen-dialect-decls toy_dia.1.toy include "mlir/IR/OpBase.td" //include "mlir/IR/FunctionInterfaces.td" //include "mlir/IR/SymbolInterfaces.td" //include "mlir/Interfaces/SideEffectInterfaces.td"def Toy_Diale…...
AI大模型与未来社会结构的重构:从工具到共生体
一、引言:从蒸汽机到ChatGPT,文明的每一次跃迁都始于“工具的自我进化” 历史长河中,每一次技术革命,都伴随着人类社会组织、认知方式乃至价值体系的巨变。从18世纪的蒸汽机到20世纪的信息技术,再到21世纪的人工智能&…...
2015年-全国大学生数学建模竞赛(CUMCM)试题速浏、分类及浅析
2015年-全国大学生数学建模竞赛(CUMCM)试题速浏、分类及浅析 全国大学生数学建模竞赛(China Undergraduate Mathematical Contest in Modeling)是国家教委高教司和中国工业与应用数学学会共同主办的面向全国大学生的群众性科技活动,目的在于激励学生学习数学的积极性,提高学…...
免费Deepseek-v3接口实现Browser-Use Web UI:浏览器自动化本地模拟抓取数据实录
源码 https://github.com/browser-use/web-ui 我们按照官方教程,修订几个环节,更快地部署 步骤 1:克隆存储库 git clone https://github.com/browser-use/web-ui.git cd web-ui Step 2: Set Up Python Environment 第 2 步:设置…...
Bash判断命令是否存在
在 Bash 脚本里,你可以通过多种方法判断某个命令是否存在。下面为你详细介绍几种常见的判断方式。 1. 使用command -v command -v命令能够返回指定命令的可执行文件路径,如果该命令不存在则不会有输出。借助这一特性,我们可以结合条件判断语…...
双指针(滑动窗口)
用于在数组或字符串的进行快速排序 匹配 排序或移动操作。 双指针不是真的指针,只是用两个变量来表示下标(在后面都用指针来表示) 双指针往往和单调性 排序 联系在一起,暴力往往是O(n方)双指针利用单调性可以优化到o(n) 有对撞指针 快慢指针 美丽区间…...
在PPT中同时自动播放多个视频的方法
在PPT中同时自动播放多个视频的方法 文章目录 在PPT中同时自动播放多个视频的方法1 准备视频2 设置动画为“出现”3 设置所有视频为“自动播放”4 最终效果与其他设置 在PPT制作的过程中,我们经常遇到需要同时自动播放多个视频的情况。本文将详细介绍实现这种效果的…...
使用 Vue 快速集成 FullCalendar 日历组件教程
FullCalendar 是一款功能强大的 JavaScript 日历组件,支持 React/Vue 等主流框架,提供丰富的日历视图和交互功能。本文将手把手教你在 Vue 项目中快速集成,并演示核心功能实现。 📦 主要特性亮点 ✅ 月/周/日多视图切换 ✅…...
xv6-labs-2024 lab2
lab-2 0. 前置 课程记录 操作系统的隔离性,举例说明就是,当我们的shell,或者qq挂掉了,我们不希望因为他,去影响其他的进程,所以在不同的应用程序之间,需要有隔离性,并且࿰…...
redis导入成功,缺不显示数据
SpringBootTest class SecurityApplicationTests {AutowiredStringRedisTemplate template; //添加这句代码,自动装载,即可解决文章三处代码报错Testvoid contextLoads() {String compact Jwts.builder().signWith(Jwts.SIG.HS512.key().build()).subj…...
Flink对比Spark streaming、Storm
对比Spark streaming、Storm 产品 模型 语义 容错机制 状态管理 延时 吞吐量 Storm native at-least-once ack 无 low low Spark streaming micro-batch exactly-once RDD checkpoint 有 medium high Flink native exactly-once checkpoint 有 low …...
力扣316去除重复字母-单调栈
题目来源: 给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置)。 示例 1: 输入:s "bcabc" 输出ÿ…...
第421场周赛:数组的最大因子得分、
Q1、数组的最大因子得分 1、题目描述 给你一个整数数组 nums。 因子得分 定义为数组所有元素的最小公倍数(LCM)与最大公约数(GCD)的 乘积。 在 最多 移除一个元素的情况下,返回 nums 的 最大因子得分。 注意&…...
COMSOL 与人工智能融合的多物理场应用:28个案例的思路、方法与工具概述
应用案例概述 基于 COMSOL 与人工智能(AI)结合的应用案例涵盖了 28 个多领域场景,包括工程(如热传导优化、结构力学预测)、能源(如电池热管理、燃料电池性能)、生物医学(如药物传递…...
【算法】插入排序
算法系列五:插入排序 一、直接插入排序 1.原理 2.实现 3.性质 3.1时间复杂度 3.2空间复杂度 3.3稳定性 二、希尔排序 1.原理 1.1优化方向 1.2优化原理 2.设计 2.1比较无序时 2.2比较有序时 3.实现 4.性质 4.1时间复杂度 4.2空间复杂度 4.3稳定性…...
企业展示型网站模板HTML5网站模板下载指南
在当今数字化浪潮中,企业网站已成为企业展示形象、推广产品和服务的重要窗口。一个设计精美、功能完善的企业展示型网站,不仅能提升企业的品牌形象,还能吸引潜在客户,促进业务增长。而HTML5网站模板,凭借其跨平台兼容性…...
C盘清理——快速处理
C盘清理 | 快速处理 软件:小番茄C盘清理 https://ccleancdn.xkbrowser.com/cleanmaster/FanQieClean_13054_st.exe 前言:为什么需要专业的C盘清理工具? 作为一位长期与Windows系统打交道的技术博主,我深知C盘空间不足带来的痛苦…...
什么是模型驱动开发MDD?有哪些应用场景?
模型驱动开发(Model-Driven Development,MDD)是一种以模型为核心的软件开发方法,其核心思想是通过创建高层次的抽象模型来描述系统的结构和行为,而非直接编写代码。这些模型经过自动化工具的转换或生成,最终…...
uniapp小程序生成海报/图片并保存分享
调研结果: 方法一:canvasuni.canvasToTempFilePath耗时太长,现在卡在canvas的绘制有问题,canvas绘制的部分东西不生效但是找不到原因 方法二:使用wxml-to-canvas其实也差不多是用canvas手动绘制,可能会卡在…...
从IoT到AIoT:智能边界的拓展与AI未来趋势预测
文章目录 引言:从连接万物到感知万物1. AIoT的本质:将智能嵌入万物2. AIoT的推动力量与挑战2.1 推动力量2.2 关键挑战 3. 五大AIoT未来趋势预测趋势一:边缘智能将成为主流架构趋势二:AI模型将向自适应与多任务演进趋势三ÿ…...
2012年-全国大学生数学建模竞赛(CUMCM)试题速浏、分类及浅析
2012年-全国大学生数学建模竞赛(CUMCM)试题速浏、分类及浅析 全国大学生数学建模竞赛(China Undergraduate Mathematical Contest in Modeling)是国家教委高教司和中国工业与应用数学学会共同主办的面向全国大学生的群众性科技活动,目的在于激励学生学习数学的积极性,提高学…...
2140 星期计算
2140 星期计算 ⭐️难度:中等 🌟考点:2022、思维、省赛 📖 📚 1️⃣法一: 同余定理, import java.util.Scanner;public class Main2 {public static void main(String[] args) {Scanner sc …...
NVIDIA Jetson 环境安装指导 PyTorch | Conda | cudnn | docker
本文适用于Jetson Nano、TX1/TX2、Xavier 和 Orin系列的设备,供大家参考。 1、PyTorch不同版本安装 这里适用于Jetson Nano、TX1/TX2、Xavier 和 Orin ,需要JetPack 4.2以上。 下载地址:PyTorch for Jetson - Jetson & Embedded System…...
理解 Rust 中的 String 分配机制
在 Rust 中,哪怕是一行再普通不过的代码,也可能暗藏玄机。这次我们就来剖析这样一句看似简单的代码: let s "hello world".to_string();这行代码触发了 只读数据段(.rodata)、堆(heap࿰…...
园区网拓扑练习
1.拓扑图要求 1.按照图示的VLAN及IP地址需求,完成相关配需 2、要求SW1为VLAN 2/3的主根及主网关,SW2为vlan 20/30的主根及主网关,SW1和SW2互为备份 3.上层通过静态路由协议完成数据通信过程 4.AR1为企业出口路由器 5.要求全网可达 2.需求分…...
CentralCache
目录 一、Span和Spanlist 二、CentralCache 一、Span和Spanlist CentralCache其实也是哈希桶结构,只不过他是一个个的Span(Span是管理一定数量的页的结构),而且Span会管理一个freelist,用来挂起一个个的小内存块给Th…...
STM32 基础1
什么是GPIO的上拉和下拉电阻 下拉电阻:把一个不确定的信号通过电阳连接到地,其实就是初始化为低电平。 上拉电阻:把一个不确定的信号通过电连接到高电平,其实就是初始化为高电平。 本质:上拉地注入电流,下…...
Python爬虫第5节-urllib的异常处理、链接解析及 Robots 协议分析
目录 一、处理异常 1.1 URLError 1.2 HTTPError 二、解析链接 2.1 urlparse() 2.2 urlunparse() 2.3 urlsplit() 2.4 urlunsplit() 2.5 urljoin() 2.6 urlencode() 2.7 parse_qs() 2.8 parse_qsl() 2.9 quote() 2.10 unquote() 三、分析网站Robots协议 3.1 R…...
STM32——DAC转换
DAC简介 DAC,全称:Digital-to-Analog Converter,扑指数字/模拟转换器 ADC和DAC是模拟电路与数字电路之间的桥梁 DAC的特性参数 1.分辨率: 表示模拟电压的最小增量,常用二进制位数表示,比如:…...
因果推断【Causal Inference】(一)
文章目录 1. 什么是因果推断?2. 为什么要提出因果推断?Motivation:辛普森悖论Scenario 1Scenario 2 3. 【Note】相关性≠因果3.1 混淆(Confounding)——共同原因3.2 样本选择偏差(Selection Bias)——共同结果 4. 潜在结果(Potential Outcome…...
人工智能通识速览(Part5. 大语言模型)
五、大语言模型 1.NLP 自然语言处理(Natural Language Processing, NLP)是人工智能领域的一个重要分支,专注于研究 计算机如何理解、生成和处理人类语言。它的目标是让机器能够像人类一样“读懂”文本或语音,并执 行翻译、问答、摘…...
优化 Django 数据库查询
优化 Django 数据库查询 推荐超级课程: 本地离线DeepSeek AI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战目录 优化 Django 数据库查询**理解 N+1 查询问题****`select_related`:外键的急加载**示例何时使用 `select_re…...
MCP AI:下一代智能微服务控制平台 (.NET Core)
平台概述 MCP AI (Microservice Control Platform AI) 是基于.NET Core构建的下一代智能微服务控制平台,旨在为企业级微服务架构提供智能化、自动化的管理和控制能力。 核心特性 智能服务编排 AI驱动的动态服务路由 自适应负载均衡算法 预测性扩展与收缩 统一…...