MIT 6.S081 2020 Lab4 traps 个人全流程
零、写在前面
做之前可以看看Chapter 4:Traps and systems calls,了解XV6 下的陷入机制
https://pdos.csail.mit.edu/6.828/2020/xv6/book-riscv-rev1.pdf
这个实验旨在探索系统调用如何实现了trap,会先做一个有关栈的练习,然后实现用户级陷入处理。
一些有关的文件:
kernel/trampoline.S
: 涉及用户态 / 内核态切换的汇编代码。kernel/trap.c
: 处理中断的所有代码。
记得切换到 traps 分支。
完整代码见:https://github.com/58164/MIT6.S081/tree/traps
一、RISC-V assembly
运行 make fs.img
来编译 user/call.c 文件,会反馈一个 call.asm 汇编文件。
// user/call.c
// headerint g(int x) {return x+3;
}int f(int x) {return g(x);
}void main(void) {printf("%d %d\n", f(8)+1, 13);exit(0);
}
然后我们需要回答以下问题:
1、哪些寄存器保存传递给函数的参数?例如,在 main()
调用 printf()
时,哪个寄存器中包含 13?
一共有 a0~a7 8个参数寄存器,RISC-V 函数传参优先使用寄存器传递,返回值可以放在 a0
和 a1
寄存器,当参数个数超过寄存器个数,额外的参数选择存放在栈上。
a0~a7 保存传递给函数的参数,13存放在 a2中:
2、main函数的汇编代码中,函数f的调用位置?函数g 的调用位置?(提示:编译器可能会内联函数)
题目1中的截图可知,编译器将函数调用内联,将结果常量优化为了12,所以是没有f和g的调用的。
3、函数 printf 的地址?
auipc
ra,0x0 - 即 将PC内存的值 + 0x0 存入 ra寄存器,然后我们又跳转到了 ra + 1536 的位置所以可以推断:printf 的地址为 0x30 + 0x600 = 0x630(1536的16进制为0x600)
4、在main函数中 jalr 到 printf后,寄存器 ra
中的值是什么?
0x38,即 调用位置的下一条指令地址
5、运行以下代码,输出是什么?(结果是小端序)如果 RISC-V 是大端序,你需要将 i
设置为什么值才能得到相同的输出? 57616 的值是否需要改变?
unsigned int i = 0x00646c72;
printf("H%x Wo%s", 57616, &i);
输出 He110 World
设置为 0x726c6400 即可,即颠倒下大小端序,57616 的值不用改,因为十六进制值是固定的。
6、下面的代码中,y= 后面会打印什么?(注意:答案不是特定值)出现这种结果的原因?
printf("x=%d y=%d", 3);
y= 后面显然是一个随机值,而 这个随机值是从寄存器 a2 中取的,所以取决于上一次a2中保存了什么值。
二、Backtrace
2.1 说明
在调试过程中,回溯信息往往非常有用。它列出了错误发生时,调用堆栈中位于当前函数之上的所有函数调用。
在 kernel/printf.c
中实现一个 backtrace()
函数。在 sys_sleep
中插入对此函式的调用,然后执行 bttest
,它会调用 sys_sleep
。你应该有如下输出:
backtrace:
0x0000000080002cda
0x0000000080002bb6
0x0000000080002898
你可以参考:
- kernel/sysproc.c:74
- kernel/syscall.c:224
- kernel/trap.c:85
编译器在每一个栈帧里面存放一个帧指针,每一个帧指针存放了调用者的位置。你的backtrace 应该利用这些帧指针来遍历栈,并打印每一个栈帧中保存的返回地址
官网的一些hint:
-
在 kernel/defs.h 中添加backtrace 的声明
-
GCC 会把当前函数的帧指针放在寄存器s0,你可以在 kernel/riscv.h中添加这个函数:
static inline uint64 r_fp() {uint64 x;asm volatile("mv %0, s0" : "=r" (x) );return x; }
然后在 backtrace 中调用,这样可以通过内联汇编来读帧指针到s0
-
XV6 内核为每一个栈帧分配了一个page,即其地址是页对齐的,你可以使用PGROUNDDOWN(fp) 和 PGROUNDUP(fp)来计算栈页面顶部和底部地址。
-
- lecture note 中指出了 返回地址 是存放在 帧指针地址 - 8 的位置的,上一个帧指针是在当前帧指针 - 16位置的
-
一旦你的backtrace 可以正常工作,那么可以在 panic.c 中调用,当内核出现panic,你可以看到内核的回溯追踪。
2.2 实现
根据提示,我们先添加这个辅助函数来获取帧指针
static inline uint64
r_fp()
{uint64 x;asm volatile("mv %0, s0" : "=r" (x) );return x;
}
然后在 kernal/defs.h 中添加函数声明
然后我们来实现一下 backtrace:
void backtrace(void) {printf("backtrace:\n");uint64 fp = r_fp();uint64 top = PGROUNDUP(fp); // stack page topuint64 bottom = PGROUNDDOWN(fp); // stack page downwhile (bottom <= fp && fp < top) {uint64 ra = *(uint64*)(fp - 8);printf("%p\n", ra);fp = *(uint64*)(fp - 16);}
}
然后在 kernel/sysproc.c 中添加调用:
我们测试一下:
非常的顺利
三、Alarm
3.1 说明
在本练习中,你将为 xv6 添加一个功能,使其能够在进程使用 CPU 时间时周期性地向其发出警报。这对于计算密集型进程(希望限制其消耗的 CPU 时间量)或那些既要进行计算又希望执行某些周期性操作的进程可能很有用。更广泛地说,你将实现一种用户级中断/故障处理程序的原始形式;例如,你可以使用类似的方法来处理应用程序中的页面错误。
你应该添加一个新的 sigalarm(interval, handler)
系统调用。如果一个应用程序调用 sigalarm(n, fn)
,那么在该程序每消耗 n
个 CPU 时间tick 后,内核应该促使应用程序函数 fn
被调用。当 fn
返回时,应用程序应该从它中断的地方继续执行。在 xv6 中,tick是一个相当任意的时间单位,由硬件计时器产生中断的频率决定。如果一个应用程序调用 sigalarm(0, 0)
,内核应该停止产生周期性的警报调用。
你会在你的 xv6 代码库中找到一个名为 user/alarmtest.c
的文件。请将其添加到 Makefile 中。在你添加 sigalarm
和 sigreturn
系统调用(见下文)之前,它将无法正确编译。
alarmtest
在 test0
中调用 sigalarm(2, periodic)
,以请求内核每隔 2 个滴答强制调用一次 periodic()
函数,然后进入一个忙等待循环。你可以在 user/alarmtest.asm
中看到 alarmtest
的汇编代码,这可能对调试有所帮助。当 alarmtest
产生如下所示的输出并且 usertests
也正确运行时,你的解决方案就是正确的:
$ alarmtest
test0 start
........alarm!
test0 passed
test1 start
...alarm!
..alarm!
...alarm!
..alarm!
...alarm!
..alarm!
...alarm!
..alarm!
...alarm!
..alarm!
test1 passed
test2 start
................alarm!
test2 passed
$ usertests
...
ALL TESTS PASSED
$
关于测试程序:
test0:调用处理程序
首先修改内核,使其跳转到用户空间的警报处理程序,这将导致 test0 打印 “alarm!”。暂时不用担心 “alarm!” 输出之后会发生什么;目前,如果你的程序在打印 “alarm!” 后崩溃是没关系的。以下是一些提示:
-
你需要修改 Makefile,使
alarmtest.c
作为 xv6 用户程序进行编译。 -
需要在 user/user.h 中放入正确的声明如下:
int sigalarm(int ticks, void (*handler)()); int sigreturn(void);
-
更新 user/usys.pl(它会生成 user/usys.S)、kernel/syscall.h 和 kernel/syscall.c,以允许
alarmtest
调用sigalarm
和sigreturn
系统调用。 -
目前,你的
sys_sigreturn
应该只返回零。 -
你的
sys_sigalarm()
应该将警报间隔和处理函数指针存储在proc
结构(位于kernel/proc.h
)的新字段中。 -
你需要跟踪自上次调用进程的警报处理程序以来已经过了多少个tick(或距离下次调用还剩多少tick);为此,你也需要在
struct proc
中添加一个新字段。你可以在proc.c
的allocproc()
中初始化proc
的字段。 -
每个tick,硬件时钟会强制产生一个中断,该中断在
kernel/trap.c
的usertrap()
中处理。 -
只有在发生定时器中断时,你才希望操作进程的警报tick;你想要的类似于
-
if(which_dev == 2) ...
-
-
仅当进程尚有待处理的警报时才调用警报函数。请注意,用户警报函数的地址可能是 0(例如,在 user/alarmtest.asm 中,
periodic
的地址是 0)。 -
你需要修改
usertrap()
,以便当进程的警报间隔到期时,用户进程执行处理函数。当 RISC-V 上的陷阱返回到用户空间时,是什么决定了用户空间代码恢复执行的指令地址? -
如果你告诉 qemu 只使用一个 CPU,那么用 gdb 查看陷阱会更容易,你可以通过运行
make CPUS=1 qemu-gdb
来实现。
如果 alarmtest
打印出 “alarm!”,你就成功了。
test1/test2():恢复被中断的代码
alarmtest
很可能在打印 “alarm!” 之后,在 test0 或 test1 中崩溃,或者 alarmtest
(最终)打印 “test1 failed”,或者 alarmtest
在没有打印 “test1 passed” 的情况下退出。要解决这个问题,你必须确保当警报处理程序完成时,控制权返回到用户程序最初被定时器中断打断的那条指令。你必须确保寄存器内容恢复到中断发生时的值,这样用户程序才能在警报后不受干扰地继续执行。最后,你应该在每次警报触发后“重新设置”(re-arm)警报计数器,以便处理程序能够周期性地被调用。
开始时,我们已经为你做出了一个设计决策:用户警报处理程序在完成时需要调用 sigreturn
系统调用。可以查看 alarmtest.c
中的 periodic
作为示例。这意味着你可以在 usertrap
和 sys_sigreturn
中添加代码,它们协同工作以使用户进程在处理完警报后能正确恢复执行。
一些提示:
- 你的解决方案将需要你保存和恢复寄存器——你需要保存和恢复哪些寄存器才能正确地恢复被中断的代码?(提示:会有很多)。
- 当定时器触发时,让
usertrap
在struct proc
中保存足够的状态,以便sigreturn
能够正确地返回到被中断的用户代码。 - 防止对处理程序的可重入调用——如果一个处理程序尚未返回,内核不应该再次调用它。
test2
会测试这一点。
一旦你通过了 test0
、test1
和 test2
,运行 usertests
以确保你没有破坏内核的其他任何部分。
具体test是如何工作的详见alarmtest.c
3.2 实现
总体还是比较简单:
- 添加新的系统调用(类似Lab2)
- 实现 用户态和内核态的相互切换
- 进程上下文的保存与恢复
- 实现时钟中断
3.2.1 系统调用的实现
先在 user.h 中添加要求实现的两个系统调用的声明:
然后我们为 proc 添加如下字段:
int alarm_interval; // alarm intervalvoid (*alarm_handler)(); // alarm handlerint ticks_cnt; // ticks have passed since last callstruct trapframe *alarm_trapframe; // proc context before interruptint alarm_on; // alarm is on?
然后在 sysproc.c 中添加 两个系统调用的定义
- 两个系统调用分别用于初始化和清空
uint64 sys_sigalarm(void) {int interval; // alarm intervaluint64 handler; // address for handler// get interval from a0if(argint(0, &interval) < 0)return -1;// get handler from a1if(argaddr(1, &handler) < 0)return -1;struct proc *p = myproc();// initializep->alarm_interval = interval;p->alarm_handler = (void(*)())handler;p->ticks_cnt = 0;p->alarm_on = 0;return 0;
}uint64 sys_sigreturn(void)
{struct proc *p = myproc();*p->trapframe = *p->alarm_trapframe; // restore the contextp->alarm_on = 0; // clearreturn 0;
}
在 user.pl 添加跳板函数:
在 syscall.h 添加系统调用号
在 syscall.c 中完善系统调用表
3.2.2 时钟中断的实现
- 根据官网的hint,which_dev = 2说明是定时器中断,我们在这里添加逻辑
- 我们tick计数+1
- 如果 达到interval,并且handler没有运行,我们更新 alarm_on = 1
- 注意如果是第一次调用,我们还需分配空间来保存上下文
- 保存完上下文后,我们直接更改pc为handler,来保证后续对于handler的调用
void
usertrap(void)
{int which_dev = 0;// ...// give up the CPU if this is a timer interrupt.if(which_dev == 2) {++ p->ticks_cnt; // ticks inc 1// reach alarm interval and alarm handler not onif (p->ticks_cnt >= p->alarm_interval && p->alarm_on == 0) {p->ticks_cnt = 0;p->alarm_on = 1;// alloc space to store context when first callif(p->alarm_trapframe == 0)p->alarm_trapframe = kalloc();// store the proc context*p->alarm_trapframe = *p->trapframe;// pc points to handlerp->trapframe->epc = (uint64)p->alarm_handler;}yield();}usertrapret();
}
在Makefile添加测试程序:
运行结果:
下班!
相关文章:
MIT 6.S081 2020 Lab4 traps 个人全流程
零、写在前面 做之前可以看看Chapter 4:Traps and systems calls,了解XV6 下的陷入机制 https://pdos.csail.mit.edu/6.828/2020/xv6/book-riscv-rev1.pdf 这个实验旨在探索系统调用如何实现了trap,会先做一个有关栈的练习,然后…...
基于YOLOv8-OBB的旋转目标检测:从数据制作到自动标注完整指南
一、引言 目标检测作为计算机视觉中的核心任务,广泛应用于安防监控、自动驾驶、工业质检等场景。传统的目标检测方法多使用水平边界框(HBB)进行目标定位。然而在一些特殊应用场景(如遥感图像、文本检测、PCB检测等)中…...
【自然语言处理与大模型】向量数据库:Chroma使用指南
Chroma是一款功能强大的开源 AI 应用数据库,专为高效数据存储与检索而设计。它不仅支持 Embedding 和 Metadata 的存储,还集成了多项核心功能,包括向量搜索、全文搜索、Document 存储、Metadata 过滤以及多模态检索。此外,Chroma …...
一文掌握工业相机选型计算
目录 一、基本概念 1.1 物方和像方 1.2 工作距离和视场 1.3 放大倍率 1.4 相机芯片尺寸 二、公式计算 三、实例应用 一、基本概念 1.1 物方和像方 在光学领域,物方(Object Space)是与像方(Image Space)相对的…...
【周输入】510周阅读推荐-3
前文 【周输入】510周阅读推荐-1-CSDN博客 【周输入】510周阅读推荐-2-CSDN博客 本次推荐 目录 前文 本次推荐 算法技术 模型产品 算法技术 vLLM和DeepSpeed部署模型的优缺点_vllm deepspeed-CSDN博客 优点缺点总结vLLM 适用于推理 优化内存管理 高效并行化 功能单…...
机器学习(11)——xgboost
文章目录 1. 算法背景和动机1.1. 提升算法(Boosting)1.2. XGBoost的改进动机2. 算法基础 3. 核心创新3.4 稀疏感知算法 4. 系统优化4.1 列块(Column Block)4.2 缓存感知访问4.3 外存计算 5. 算法细节5.1 树生长策略5.2 特征重要性评估5.3 自定义目标函数…...
大语言模型上下文长度:发展历程、局限与技术突破
1. 引言:什么是上下文长度及其重要性 上下文长度(Context Length),也称为上下文窗口(Context Window),指的是大语言模型(LLM)在处理和生成文本时能够有效记忆和利用的信…...
ControlNet简洁
ControlNet 什么是ControlNet ControlNet是一种用于控制扩散模型生成结果的网络结构。该结构可以将边缘图,结构图等信息注入扩散模型,从而能够对生成结果进行更为精细的控制。 ControlNet是怎么实现的 在模型结构方面,其大致结构如下图所…...
【C】C程序内存分配
文章目录 1. C程序内存布局 1. C程序内存布局 从低地址到高地址依次为: 代码段 存储内容:存放编译后的机器指令特点:代码段是只读的;可共享,多个进程可共享同一份代码 数据段 存储内容 已初始化的全局变量已初始化的静…...
论文学习:《引入TEC - LncMir,通过对RNA序列的深度学习来预测lncRNA - miRNA的相互作用》
长链非编码RNA ( long noncoding RNAs,lncRNAs )是一类长度通常大于200个核糖核苷酸的非编码RNA ,微小RNA ( microRNAs,miRNAs )是一类由22个核糖核苷酸组成的短链非编码RNA。近年来,越来越多的研究表明,lncRNA和miRNA…...
【每日一题丨2025年5.12~5.18】排序相关题
个人主页:Guiat 归属专栏:每日一题 文章目录 1. 【5.12】P1068 [NOIP 2009 普及组] 分数线划定2. 【5.13】P5143 攀爬者3. 【5.14】P12366 [蓝桥杯 2022 省 Python B] 数位排序4. 【5.15】P10901 [蓝桥杯 2024 省 C] 封闭图形个数5.【5.16】P12165 [蓝桥…...
AIDA64 extreme7.5 版本注册激活方法
一、AIDA 7.5 序列号 3BQN1-FUYD6-4GDT1-MDPUY-TLCT7 UVLNY-K3PDB-6IDJ6-CD8LY-NMVZM 4PIID-N3HDB-IWDJI-6DMWY-9EZVU 二、安装激活方法 激活步骤: 1、打开AIDA64软件,点击顶部菜单栏的“帮助”→“输入序列号” 2、将生成的序列号粘贴至输入框&a…...
Python 条件语句详解
条件语句是编程中用于控制程序流程的基本结构,Python 提供了几种条件语句来实现不同的逻辑判断。 1. if 语句 最基本的条件语句形式: if 条件:# 条件为真时执行的代码块示例: age 18 if age > 18:print("你已经成年了")2. …...
模型评估与调优(PyTorch)
文章目录 模型评估方法混淆矩阵混淆矩阵中的指标ROC曲线(受试者工作特征)AUCR平方残差均方误差(MSE)均方根误差(RMSE)平均绝对误差(MAE) 模型调优方法交叉验证(CV&#x…...
oppo手机安装APK失败报错:安装包异常
如果你的apk文件在oppo手机安装失败了,像这样: 先说我们当时解决方式: 如果还没上架应用市场的测试包,在上面图一中需要关闭“超级守护”,类似华为的纯净模式。如果开启了还还不行,安装页面的报错太笼统不…...
互联网大厂Java面试场景:从缓存到容器化的技术问答
场景:互联网大厂Java面试之旅 面试官:严肃的技术专家 应聘者:搞笑的水货程序员明哥 第一轮:缓存技术与数据库优化 面试官:明哥,你能谈谈Redis的常见使用场景和一些优化技巧吗? 明哥…...
【android bluetooth 协议分析 01】【HCI 层介绍 6】【WriteLeHostSupport命令介绍】
HCI 指令 HCI_Write_LE_Host_Support 是 Bluetooth Host 向 Controller 发送的一条指令,用于启用或禁用主机对 Bluetooth Low Energy(LE)的支持能力。该指令属于 HCI(Host Controller Interface)命令集合中,…...
Helm配置之为特定Deployment配置特定Docker仓库(覆盖全局配置)
文章目录 Helm配置之为特定Deployment配置特定Docker仓库(覆盖全局配置)需求方法1:使用Helm覆盖值方法2: 在Lens中临时修改Deployment配置步骤 1: 创建 Docker Registry Secret步骤 2: 在 Deployment 中引用 Secret参考资料Helm配置之为特定Deployment配置特定Docker仓库(覆…...
项目:在线音乐播放服务器——基于SSM框架和mybatis
介绍项目 项目主要是基于SSM框架和mybatis进行实现 主要的功能: 登陆界面,用户注册,音乐的播放列表,删除指定的歌曲,批量删除指定的歌曲,收藏歌曲,查询歌曲,从收藏列表中删除收藏…...
Linux配置vimplus
配置vimplus CentOS的配置方案很简单,但是Ubuntu的解决方案网上也很多但是有效的很少,尤其是22和24的解决方案,在此我整理了一下我遇到的问题解决方法 CentOS7 一键配置VimForCPP 基本上不会有什么特别难解决的报错 sudo yum install vims…...
Ubuntu22.04开机运行程序
新建启动文件 sudo vim /etc/systemd/system/trojan.service 2. 写入配置文件 [Unit] DescriptionTrojan Proxy Service Afternetwork.target[Service] Typesimple ExecStart/home/cui/Downloads/trojan/trojan -c /home/cui/Downloads/trojan/config.json Restarton-failur…...
高效查询:位图、B+树
1. 位图(BitMap)与布隆过滤器(Bloom Filter) 1.1. 问题背景与解决方案 问题背景 场景:网页爬虫判重 搜索引擎的爬虫会不断地解析网页中的链接并继续爬取。一个网页可能在多个页面中出现,容易重复爬取。…...
HashMap的扩容机制
在添加元素或初始化的时候需要调用resize方法进行扩容,第一次添加数据初始化数组长度为16,以后每次每次扩容都是达到了扩容阈值(数组长度 * 0.75) 每次扩容的时候,都是扩容之前容量的2倍; 扩容之后&#…...
从坏道扫描到错误修复:HD Tune实战指南
一、硬盘检测的必要性 随着计算机使用时间的增加,机械硬盘和固态硬盘都会出现不同程度的性能衰减。定期进行硬盘健康检查可以:及时发现潜在故障;预防数据丢失风险;掌握存储设备实际状态。 二、HD Tune功能解析 性能测试&#x…...
Leetcode 3553. Minimum Weighted Subgraph With the Required Paths II
Leetcode 3553. Minimum Weighted Subgraph With the Required Paths II 1. 解题思路2. 代码实现 题目链接:3553. Minimum Weighted Subgraph With the Required Paths II 1. 解题思路 这一题很惭愧,并没有自力搞定,是看了大佬们的解答才有…...
算法加训之最短路 上(dijkstra算法)
目录 P4779 【模板】单源最短路径(标准版)(洛谷) 思路 743. 网络延迟时间(力扣) 思路 1514.概率最大路径(力扣) 思路 1631.最小体力消耗路径 思路 1976. 到达目的地的方案数 …...
01 Nginx安装及基本配置
01 Nginx安装 # 官网:https://nginx.org/en/ # 点击下载图1 Nginx下载官网 # https://nginx.org/en/download.html # 全是各个平台的源码包图2 Nginx下载版本 # 找到最下面的stable and mainline(稳定版和主线版)图3 找到最下面的稳定版 # https://nginx.org/en/li…...
ABP vNext 多租户系统实现登录页自定义 Logo 的最佳实践
🚀 ABP vNext 多租户系统实现登录页自定义 Logo 的最佳实践 🧭 版本信息与运行环境 ABP Framework:v8.1.5.NET SDK:8.0数据库:PostgreSQL(支持 SQLServer、MySQL 等)BLOB 存储:本地…...
Docker 网络
目录 前言 1. Docker 网络模式 2. 默认 bridge 网络详解 (1)特点 (2)操作示例 3. host 网络模式 (1)特点 (2)操作示例 4. overlay…...
btc交易所关键需求区 XBIT反弹与上涨潜力分析
在加密货币市场的浪潮中,狗狗币(DOGE)近期的走势吸引了众多投资者的目光。根据XBIT分析,狗狗币刚刚踏入关键需求区,此前虽从高点大幅下跌了10%,但XBIT去中心化交易所平台分析师认为,短期内它有望…...
深度剖析:YOLOv8融入UNetv2 SDI模块的性能提升之旅
文章目录 一、引言二、SDI多层次特征融合模块概述(一)背景和动机(二)模块设计原理 三、SDI模块实现(一)关键代码结构(二)代码解析 四、将SDI模块融入YOLOv8(一࿰…...
图像定制大一统?字节提出DreamO,支持人物生成、 ID保持、虚拟试穿、风格迁移等多项任务,有效解决多泛化性冲突。
字节提出了一个统一的图像定制框架DreamO,支持人物生成、 ID保持、虚拟试穿、风格迁移等多项任务,不仅在广泛的图像定制场景中取得了高质量的结果,而且在适应多条件场景方面也表现出很强的灵活性。现在已经可以支持消费级 GPU(16G…...
spark数据处理练习题详解【下】
12. (单选题) def main(args: Array[String]): Unit { println(func1("张三",f1)) } def func1(name:String,fp:(________________)): String { fp(name) } def f1(s:String): String { "welcome "s } 选择填空() A.String>S…...
Vue基础(11)_条件渲染
原生css想让显示的元素隐藏,方式有以下几点: display: none; opacity: 0; visibility: hidden; 那么vue中是怎样实现元素显示/隐藏的呢? 条件渲染 v-show 写法:v-show"表达式" 判断:表达式转换为布尔值(tr…...
湖北理元理律师事务所:债务优化服务的四维创新实践
在债务问题普遍影响家庭经济稳定的当下,专业法律服务机构的价值不仅在于提供解决方案,更需构建可持续的服务生态。湖北理元理律师事务所通过“法律心理技术教育”四维服务体系,探索出一条兼顾债务化解与生活质量保障的创新路径。 服务模式创…...
ubuntu工控机固定设备usb串口号
ubuntu工控机固定设备usb串口号 1、多个USB设备的ID相同 ubuntu系统中的串口使用权限并没有对所有的用户进行开放,所以在使用代码对串口进行操作时,需要打开用户对串口的使用权限,否则在代码中会出现“串口无法打开的报错”,只有…...
MongoDB的安装及简单使用
MongoDB 是一个开源的文档型 NoSQL 数据库,由 MongoDB Inc. 开发,专为灵活性和可扩展性设计。 特点: 1.文档模型:数据以 BSON(二进制 JSON)格式存储,支持嵌套结构。 2.动态 S…...
卷积神经网络进阶:转置卷积与棋盘效应详解
【内容摘要】 本文深入解析卷积神经网络中的转置卷积(反卷积)技术,重点阐述标准卷积与转置卷积的计算过程、转置卷积的上采样作用,以及其常见问题——棋盘效应的产生原因与解决方法,为图像分割、超分辨率等任务提供理论…...
Linux进程信号(三)之信号产生2
文章目录 4. 由软件条件产生信号5. 硬件异常产生信号模拟一下除0错误和野指针异常除0错误野指针错误 总结思考一下 4. 由软件条件产生信号 SIGPIPE是一种由软件条件产生的信号,在“管道”中已经介绍过了。 软件条件不就绪,很明显这个软件条件没有直接报错ÿ…...
【AWS入门】Amazon SageMaker简介
【AWS入门】Amazon SageMaker简介 [AWS Essentials] Brief Introduction to Amazon SageMaker By JacksonML 机器学习(Machine Learning,简称ML) 是当代流行的计算机科学分支技术。通常,人们在本地部署搭建环境,以满足机器学习的要求。 AWS…...
MySQL--day2--基本的select语句
(以下内容全部来自上述课程) SQL概述 结构化查询语句 1. SQL分类 DDL:数据定义(definition)语言:create、drop、alter… DML:数据操作(manipulation)语言ÿ…...
程序代码篇---python获取http界面上按钮或者数据输入
文章目录 前言 前言 本文简单接受了python获取http界面上按钮或者数据输入...
网络安全利器:蜜罐技术详解
蜜罐是网络安全领域中一种主动防御和情报收集的重要工具。本文将深入探讨蜜罐技术的原理、类型、应用场景以及部署注意事项。 1. 什么是蜜罐? 蜜罐(Honeypot)是一种安全资源,其价值在于被探测、攻击或未经授权使用。简单来说,蜜罐就是一个诱饵系统,用来吸引黑客的注意力…...
回溯实战篇3
文章目录 前言排列全排列全排列II 棋盘问题N皇后解数独 其他递增子序列重新安排行程 前言 今天继续带大家进行回溯的实战篇3,去学习如何用回溯的方法去解决排列和棋盘以及其他用回溯方法解决的问题,最重要的就是学会回溯三部曲的构建,一文带…...
Spark 基础自定义分区器
(一)什么是分区 【复习提问:RDD的定义是什么?】 在 Spark 里,弹性分布式数据集(RDD)是核心的数据抽象,它是不可变的、可分区的、里面的元素并行计算的集合。 在 Spark 中…...
【提高+/省选−】洛谷P1495 —— 【模板】中国剩余定理(CRT)/ 曹冲养猪
见:P1495 【模板】中国剩余定理(CRT)/ 曹冲养猪 - 洛谷 题目描述 自从曹冲搞定了大象以后,曹操就开始捉摸让儿子干些事业,于是派他到中原养猪场养猪,可是曹冲满不高兴,于是在工作中马马虎虎&a…...
系统架构设计师考前冲刺笔记-第1章-系统工程与信息系统基础
文章目录 第1章 系统工程与信息系统基础大纲13 DSS5678 BSP910 SCM11 OLAP12 OLAP14 BRP15 集成16 企业门户19 边缘计算 第1章 系统工程与信息系统基础 大纲 1 3 DSS DSS 决策支持系统 Decision Support System 5 6 7 8 BSP 9 10 SCM 注意:生产计划 11 OLAP O…...
Vue环境下数据导出Excel的全面指南
文章目录 1. 前言2. 原生JavaScript实现方案2.1 使用Blob对象和URL.createObjectURL2.2 使用Base64编码实现 3. 常用第三方库方案3.1 使用SheetJS (xlsx)3.2 使用ExcelJS3.3 使用vue-json-excel 4. 服务器端导出方案4.1 前端请求服务器生成Excel4.2 使用Web Worker处理大数据导…...
Linux下 使用 SSH 完成 Git 绑定 GitHub
文章目录 1、检查 SSH2、生成 SSH key3、添加 SSH key4、验证绑定是否成功 1、检查 SSH Git Bash 中输入ssh命令,查看本机是否安装 SSH: 2、生成 SSH key (1)输入 ssh-keygen -t rsa 命令,表示我们指定 RSA 算法生…...
Jsoup库和Apache HttpClient库有什么区别?
Jsoup 和 Apache HttpClient 是两个功能不同的库,它们在 Java 开发中被广泛使用,但用途和功能有明显的区别: Jsoup 用途:Jsoup 是一个用于解析 HTML 文档的库。它提供了非常方便的方法来抓取和解析网页内容,提取和操作…...