[OS_7] 访问操作系统对象 | offset | FHS | Handle
实验代码可以看去年暑假的这篇文章:【Linux】进程间通信:详解 VSCode使用 | 匿名管道
我们已经知道,进程从 execve 后的初始状态开始,可以通过 mmap 改变自己的地址空间,通过 fork 创建新的进程,再通过 execve 执行新的程序——我们慢慢已经开始理解 “操作系统上的应用生态“ 并没有魔法了。
本讲内容:操作系统还必须给应用程序提供访问操作系统对象的机制。当然,我们可以直接以 API 的形式提供,例如 Win32 API 包含 “RegOpenKeyEx” 访问注册表。这节课我们学习 UNIX 的 “Everything is a file” 带来的方便 (和不便)。
上一篇文章当中我们讲到过,边写代码边测试非常的重要,那么我们该如何实现测试呢
明确需求
- 我们需要一个状态 (Everything is a state machine)
-
- tests 里有全部测试用例且程序还没结束
- 需要遵守 libc 的约定
-
- tk_add_test 和 tk_register_hook 执行顺序不确定
- System test 里还可能调用 atexit()
解决问题
- tk_register_hook 时立即创建一个进程
-
- 等程序 atexit() 的时候把 tests 送过来
- 程序之间交换数据:“serialization”(序列化)
Prompt: 有哪些对象 serialization 的通用机制?
常见的对象序列化机制包括:
- Java 序列化:使用
Serializable
接口。 - JSON:轻量级数据交换格式,广泛用于 Web 开发。
- XML:可扩展标记语言,适用于复杂数据结构。
- Protocol Buffers:Google 的高效二进制序列化格式。
- Avro:Apache 的数据序列化系统,支持动态模式。
- MessagePack:二进制 JSON 格式,更高效。
- Thrift:Facebook 开发的跨语言序列化框架。
根据需求选择合适的机制。
在这个例子里,因为是完全相同的进程地址空间
- 我们直接做了一个 “内存复制”,保留了 argv 中指向只读数据的指针。
- 对于跨应用的对象序列化,则需要做字符串的 deep copy。
我们的做法:利用编程语言机制 hack
- 并不是好的 practice (但有时候需要)
方法一:请开发者主动调用 API
- 在 main 里 run_all_tests()
- 之前学习机 gtest 的时候用的就是这种方法
方法二:提供一个特别的编译器
- JavaScript: 这个我懂
方法三:更好的编程语言
- JVMTI: Tool Interface
testkit: Writing test cases fearlessly! 这是用于实验的第一个测试框架:支持单元测试和系统测试,自动注册测试用例并在程序退出后运行。
最重要的特点是它使用简单:只需要包含 testkit.h,并且链接 testkit.c 即可。
没有测试过的代码,都是有可能存在问题的!
操作系统中的对象
进程
- 进程 = 状态机
- 进程管理 API: fork, execve, exit
连续的内存段
- 我们可以把 “连续的内存段” 看作一个对象
-
- 可以在进程间共享
- 也可以映射文件
- 内存管理 API: mmap, munmap, mprotect, msync
操作系统肯定还有其他对象的!
是如何访问操作系统对象的呢,那通过文件来访问操作系统的对象
- 文件像键盘显示器也都可以理解为文件,哦我好像知道了
- 相当于是平时写的代码生成了程序和进程,跑在操作系统这个环境上
- 然后通过文件来访问这些东西,读取到的结果就是,例如是以我们显示器也是一个文件,来显示出来
7.1 文件描述符
文件和设备
文件:有 “名字” 的数据对象
- 字节流 (终端,random)
- 字节序列 (普通文件)
文件描述符
- 指向操作系统对象的 “指针”
-
- Everything is a file
- 通过指针可以访问 “一切”
- 对象的访问都需要指针
-
- open, close, read/write (解引用), lseek (指针内赋值/运算), dup (指针间赋值)
文件描述符:访问文件的 “指针”
- open
-
- p = malloc(sizeof(FileDescriptor));
- close
-
- delete(p);
- read/write
-
- *(p.data++);
- lseek
-
- p.data += offset;
- dup
-
- q = p;
在去年暑假,我们手写 shell 的时候,有详细写过这部分的代码,感兴趣的可以去看一下
访问操作系统中的对象--文件描述符
- 总是分配最小的未使用描述符
- 0, 1, 2 是标准输入、输出和错误
- 新打开的文件从 3 开始分配
-
- 文件描述符是进程文件描述符表的索引
- 关闭文件后,该描述符号可以被重新分配
- Linux 下一切皆文件
进程能打开多少文件?
- ulimit -n (进程限制)
- sysctl fs.file-max (系统限制)
文件描述符中的 offset
文件描述符是 “进程状态的” 的一部分
- 保存在操作系统中;程序只能通过整数编号访问
- 文件描述符自带一个 offset
Quiz: fork() 和 dup()(共享) 之后,文件描述符共享 offset 吗?
- 这就是 fork() 看似优雅,实际复杂的地方
场景 | 是否共享 offset | 原因 |
独立打开同一文件 | ❌ 不共享 | 每个 生成独立文件表项 |
| ✅ 共享(继承描述符) | 子进程复制父进程文件表项,所以他们打开同一文件的话,不会实现覆盖,顶多出现交叉写入 |
| ✅ 共享 | 描述符指向同一文件表项 |
文件描述符:文件描述符是指向操作系统对象的 “指针”——系统调用通过这个指针 (fd) 确定进程希望访问操作系统中的哪个对象。我们有 open, close, read/write, lseek, dup 管理文件描述符。
Windows 中的文件描述符
Handle (把手;握把;把柄)
- 比 file descriptor 更像 “指针”
- 你有一个 “handle” 在我手上,我就可以更好地控制你
Windows 的进程创建
面向工程的设计
- 默认 handle 是不继承的 (和 UNIX 默认继承相反)
-
- 可以在创建时设置 bInheritHandles,或者运行时修改
- “最小权限原则”
- lpStartupInfo 用于配置 stdin, stdout, stderr
(参考) Windows进程创建的工程化设计核心要点
1. 默认不继承句柄
- 安全设计:新进程默认不继承父进程的资源访问权限(句柄),防止意外泄露。
- 按需授权:通过参数
bInheritHandles
或运行时调整,显式指定需共享的资源。2. 集中式配置入口
- 统一管理:
STARTUPINFO
结构体统一配置子进程的标准输入/输出/错误流,避免参数分散。- 模块化扩展:通过结构化字段支持未来功能扩展,降低接口变动风险。
3. 安全与功能的工程权衡
- 安全优先:相比UNIX默认继承的便利性,Windows更强调最小权限原则(仅开放必要权限)。
- 灵活控制:开发者可精准指定共享资源,平衡功能需求与安全风险。
Linux 引入了 O_CLOEXEC
- fcntl(fd, F_SETFD, FD_CLOEXEC)
//对fd进行各种操作,成功返回0,失败返回-1设errno
#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, ... ); //...表示可变长参数
/*cmd:
Adversory record locking:
F_SETLK(struct flock*) //设建议锁
F_SETLKW(struct flock*) //设建议锁,如果文件上有冲突的锁,且在等待的时候捕获了一个信号,则调用被打断并在信号捕获之后立即返回一个错误,如果等待期间没有信号,则一直等待
F_GETLK(struct flock*) //尝试放锁,如果能放锁,则不会放锁,而是返回一个含有F_UNLCK而其他不变的l_type类型,如果不能放锁,那么fcntl()会将新类型的锁加在文件上,并把当前PID留在锁上
Duplicating a file descriptor:
F_DUPFD (int) //找到>=arg的最小的可以使用的文件描述符,并把这个文件描述符用作fd的一个副本
F_DUPFD_CLOEXEC(int)//和F_DUPFD一样,除了会在新的文件描述符上设置close-on-exec
F_GETFD (void) //读取fd的flag,忽略arg的值
F_SETFD (int) //将fd的flags设置成arg的值.
F_GETFL (void) //读取fd的Access Mode和其他的file status flags; 忽略arg
F_SETFL (long) //设置file status flags为arg
F_GETOWN(void) //返回fd上接受SIGIO和SIGURG的PID或进程组ID
F_SETOWN(int) //设置fd上接受SIGIO和SIGURG的PID或进程组ID为arg
F_GETOWN_EX(struct f_owner_ex*) //返回当前文件被之前的F_SETOWN_EX操作定义的文件描述符R
F_SETOWN_EX(struct f_owner_ex*) //和F_SETOWN类似,允许调用程序将fd的I/O信号处理权限直接交给一个线程,进程或进程组
F_GETSIG(void) //当文件的输入输出可用时返回一个信号
F_SETSIG(int) //当文件的输入输出可用时发送arg指定的信号
*//*…:
可选参素,是否需要得看cmd,如果是加锁,这里应是struct flock*
struct flock {short l_type; //%d Type of lock: F_RDLCK(读锁), F_WRLCK(写锁), F_UNLCK(解锁)short l_whence; //%d How to interpret l_start, 加锁的位置参考标准:SEEK_SET, SEEK_CUR, SEEK_ENDoff_t l_start; //%ld Starting offset for lock, 加锁的起始位置off_t l_len; //%ld Number of bytes to lock , 锁定的字节数pid_t l_pid; // PID of process blocking our lock, (F_GETLK only)加锁的进程号,,默认给-1
};
*/
- 文件描述符:文件描述符是指向操作系统对象的 “指针”——系统调用通过这个指针 (fd) 确定进程希望访问操作系统中的哪个对象。
Filesystem Hierarchy Standard --FHS
- enables software and user to predict the location of installed files and directories: 例如 macOS 就不遵循 FHS
只要拷对了文件,操作系统就能正常执行啦!
- 创建 UEFI 分区,并复制正确的 Loader
- 创建文件系统
-
- mkfs (格式化)
- cp -ar 把文件正确复制 (保留权限)
-
- 注意 fstab 里的 UUID
- 就得到了一个可以正常启动的系统盘!
- 运行时挂载必要的其他文件系统
-
- 磁盘上的 /dev, /proc, ... 都是空的
- mount -t proc proc /mount/point 可以 “创建” procfs
对于Linux制作系统盘的实验前文有写过,感兴趣的可以找着看一下Linux 系统盘制作 | 引导加载器(GRUB 为例)| mount
操作系统给了我们很多API,可以创建各种各样的对象
任何 “可读写” 的东西都可以是文件
真实的设备
- /dev/sda
- /dev/tty
虚拟的设备 (文件)
- /dev/urandom (随机数), /dev/null (黑洞), ...
-
- 它们并没有实际的 “文件”
- 操作系统为虚拟的设备 (文件)实现了特别的 read 和 write 操作
-
-
- /drivers/char/mem.c
- 发现的一些有意思的事情:甚至可以通过 /sys/class/backlight 控制屏幕亮度
-
- procfs 也是用类似的方式实现的
管道:一个特殊的 “文件” (流)
- 由读者/写者共享
-
- 读口:支持 read
- 写口:支持 write
匿名管道
(Unix得图灵奖的一个重要原因🙂
- 返回两个文件描述符
- 进程同时拥有读口和写口
-
- 看起来没用?不,fork 一下就有用了 (testkit)
- 然后甚至还可以再结合dup,来实现对 0 1 2 指向替代也可以
- ls | wc -l (这就是一个管道的应用)
⭕理解管道的意义:
- UNIX 管道:UNIX 管道 (pipe) 是一种典型的进程间通信机制,允许数据在不同的进程之间单向流动。
- 管道可以被视为一种特殊的文件,其中一个进程将数据写入管道的一端,而另一个进程从另一端读取数据。
- 管道实现了父子进程当中,先后的同步。
⭕sum
进程管理
- fork, execve, waitpid, exit
内存管理
- mmap, munmap, mprotect, msync
文件管理
- open, close, read, write, lseek, dup
- mkfifo 命名管道,可以属于某一个文件
- pipe 匿名管道。
- proc
- sys
- Everything is a File ...
例如来和 ag 结合,cat readme.md | ag 就可以问AI 啦
一切皆文件的好处
一套 API 访问所有对象
- 一切都可以 | grep
-
- Introducing
ag -g
- Introducing
同时,UNIX Shell 的语法广受诟病
- 稍大一些的项目就应该用更好的语言 (Python, Rust!)
- 但是:We all love quick & dirty!
ls -l /proc/*/fd/* 2>/dev/null | awk '{print $(NF-2), $(NF-1), $NF}'
grep -s VmRSS /proc/*[0-9]/status | awk '{sum += $2} END {print sum " kB"}'
Prompt: 什么是 glob patterns? 有什么实际中常用的扩展?
Glob patterns 是一种用于匹配文件路径名的模式,常用于文件搜索和操作。常见的通配符包括:
*
:匹配任意数量的字符(包括零个)?
:匹配单个字符[]
:匹配指定范围内的字符
实际中常用的扩展包括:
**
:递归匹配任意层级的子目录{}
:匹配多个模式,如{a,b,c}
匹配a
、b
或c
!(pattern)
:排除指定模式
这些扩展增强了 glob patterns 的灵活性和功能性。
字节流
- 顺序读/顺序写
-
- 没有数据时等待
- 典型代表:管道
- 但是会存在操作系统对offset默默地移动...
字节序列
- 其实就有一点点不方便了
-
- 需要到处 lseek 再 read/write
-
-
- mmap 不香吗?指针指哪打哪
- madvise, msync 提供了更精细的控制
-
lseek
用于重新定位文件偏移量(文件指针位置),支持三种定位模式:
SEEK_SET
:绝对定位(从文件头开始偏移)SEEK_CUR
:相对定位(从当前位置偏移)SEEK_END
:从文件末尾偏移补充说明:该函数不会触发任何物理 I/O 操作,仅修改内核中的文件偏移量记录。
优点
- 优雅,文本接口,就是好用
缺点
- 和各种 API 紧密耦合
-
- A fork() in the road
- im ple men ta tion 实现
- al ter na tives 替代方案
- con flates 合并
如果我fork出的父子进程,同时写Hello和world,它会是覆盖呢还是实现延续呢?
- 进程独立性
fork()
会创建子进程,父子进程的内存空间是独立的,但文件描述符(如标准输出)是共享的。因此,两者的输出会混合到同一个目标中,但不会直接覆盖(每个write
操作是原子的) - 输出顺序不确定
父子进程的执行顺序由操作系统调度决定。可能的结果包括:
-
- 父进程先输出“Hello”,子进程后输出“World” →
HelloWorld
- 子进程先输出“World”,父进程后输出“Hello” →
WorldHello
- 两者交替执行,导致字符交错(如
HWeolrllod
)
- 父进程先输出“Hello”,子进程后输出“World” →
- 对高速设备不够友好(why)
-
- 额外的延迟和内存拷贝
- 单线程 I/O
Any problem in computer science can be solved with another level of indirection. (Butler Lampson)
- Windows NT: Win32 API → POSIX 子系统
-
- Windows Subsystem for Linux (WSL)
- macOS: Cocoa API → BSD 子系统
- Fuchsia: Zircon 微内核 → POSIX 兼容层
兼容当然没法做到 100%
- sysfs, procfs 就是没法兼容
- 优雅的 WSL1 已经暴毙
-
- “Windows Subsystem for Linux”
- “Linux Subsystem for Windows” (wine)
- 对硬件做抽象,给应用程序提供服务
拓展: OpenHarmony
对于 硬件和软件
- “初学FPGA,突然顿悟何为“硬件的并行化思维”的美妙,那一瞬之后,就像打通了任督二脉,之后不管是看代码还是写代码都变得十分顺畅。更关键的是我的认知也得到了提升:那是我第一次认知到不同思维模式会对coding产生如此之大的区别。
- 其实反过来各种语言也在(强迫)塑造人的思维模式,比如cuda之类的并行编程要求程序员转换思维模式。HDL也一样。人发明工具,然后被工具改变。
- 以除法为例,软件工程师代码的除法: int val=3300/256 ; 硬件工程师:int val = 3300》8;“
相关文章:
[OS_7] 访问操作系统对象 | offset | FHS | Handle
实验代码可以看去年暑假的这篇文章:【Linux】进程间通信:详解 VSCode使用 | 匿名管道 我们已经知道,进程从 execve 后的初始状态开始,可以通过 mmap 改变自己的地址空间,通过 fork 创建新的进程,再通过 exe…...
【Vulkan 入门系列】创建帧缓冲、命令池、命令缓存,和获取图片(六)
这一节主要介绍创建帧缓冲(Framebuffer),创建命令池,创建命令缓存,和从文件加载 PNG 图像数据,解码为 RGBA 格式,并将像素数据暂存到 Vulkan 的 暂存缓冲区中。 一、创建帧缓冲 createFramebu…...
Linux 进程控制(自用)
非阻塞调用waitpid 这样父进程就不会阻塞,此时循环使用我们可以让父进程执行其他任务而不是阻塞等待 进程程序替换 进程PCB加载到内存中的代码和数据 替换就是完全替换当前进程的代码段、数据段、堆和栈,保存当前的PCB 代码指的是二进制代码不是源码&a…...
FreeSWITCH 简单图形化界面41 - 批量SIP视频呼叫测试
FreeSWITCH 简单图形化界面41 - 批量视频测试 0、界面预览00、安装测试工具1、注册分机2、设置接听选项2.1 上传媒体文件2.2 设置接听设置 3、呼叫测试 0、界面预览 http://myfs.f3322.net:8020/ 用户名:admin,密码:admin FreeSWITCH界面安…...
通过爬虫方式实现头条号发布视频(2025年4月)
1、将真实的cookie贴到代码目录中toutiaohao_cookie.txt文件里,修改python代码里的user_agent和video_path, cover_path等变量的值,最后运行python脚本即可; 2、运行之前根据import提示安装一些常见依赖,比如requests等; 3、2025年4月份最新版; 代码如下: import js…...
《AI大模型应知应会100篇》第28篇:大模型在文本创作中的应用技巧
第28篇:大模型在文本创作中的应用技巧 🧠 摘要 在内容为王的时代,AI大模型正在重塑文本创作的每一个环节。从创意构思到风格润色,从论文报告到小说脚本,AI不仅是创作者的助手,更是灵感的激发器。本文将带你…...
字节跳动发布UI-TARS-1.5,入门AI就来近屿智能
近日,字节跳动在 Hugging Face 平台正式开源了其最新多模态代理模型——UI-TARS-1.5。作为 UI-TARS 系列的革新之作,该模型以视觉语言模型为基础,突破性实现跨平台 GUI 自动化交互,为自动化与智能交互领域注入了强劲动能。无论是开…...
大数据学习栈记——MapReduce技术
本文介绍hadoop中的MapReduce技术的应用,使用java API。操作系统:Ubuntu24.04。 MapReduce概述 MapReduce概念 MapReduce是一个分布式运算程序的编程框架,核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序…...
GO语言入门:常用数学函数2
14.6 大型数值 math/big 包中公开了一些实用 API,用于表示大型整数值和浮点数值。当基础类型无法容纳要使用的数值时,应改用 big 包中提供的新类型。例如 Int、Float 等。 14.6.1 大型整数值之间的运算 若希望让下面两个整数值完成加、减法运算&#…...
Django 使用教程
Django 使用教程 Django 是一个高级的 Python Web 框架,采用了 MTV(Model-Template-View)设计模式,旨在帮助开发者快速构建高效、可维护的 Web 应用。它有着非常丰富的功能,包括 ORM、用户认证、表单处理、管理后台等…...
deepseek + kimi制作PPT
目录 一、kimi简介二、deepseek生成内容三、生成PPT四、编辑PPT 一、kimi简介 kimi是一款只能ppt生成器,擅长将文本内容生成PPT。 在这里,DeepSeek 负责内容生成与逻辑梳理,Kimi 优化表达与提供设计建议。 二、deepseek生…...
C++学习:六个月从基础到就业——内存管理:RAII原则
C学习:六个月从基础到就业——内存管理:RAII原则 本文是我C学习之旅系列的第十九篇技术文章,也是第二阶段"C进阶特性"的第四篇,主要介绍C中的RAII原则及其在资源管理中的应用。查看完整系列目录了解更多内容。 引言 在…...
量子计算与经典计算融合:开启计算新时代
一、引言 随着科技的飞速发展,计算技术正迎来一场前所未有的变革。量子计算作为前沿技术,以其强大的并行计算能力和对复杂问题的高效处理能力,吸引了全球科技界的关注。然而,量子计算并非要完全取代经典计算,而是与经典…...
RV1126网络环境TFTPNFS搭建(二)
二、RV1126 开发板TFTP环境搭建 2.1、Ubuntu下安装和配置 xinetd 执行以下指令,安装 xinetd sudo apt-get install xinetd 执行以下指令创建一个 xinetd.conf 文件 sudo vi /etc/xinetd.conf 修改 xinetd.conf 文件内容如下: # Simple configurat…...
计算机视觉7——齐次坐标与相机内外参
一、透视投影 透视投影(Perspective Projection)是计算机视觉和图形学中描述三维物体在二维平面成像的基础模型,其核心思想是模拟人类视觉系统的成像原理——中心投影。具体而言,三维空间中的点通过一个固定的投影中心࿰…...
学习笔记—C++—string(一)
目录 string 为什么学习string的类 string类的常用接口 string类对象的常见构造 string类对象的访问及遍历操作 operator[] 迭代器 范围for auto 迭代器(二) string类对象的容量操作 size,length,max_size,capacity,clear基本用法 reserve 提…...
Linux命令-Shell编程
Shell是一个命令行解释器,它接收应用程序/用户命令,然后调用操作系统内核。 写一个hello.sh脚本: 1.mkdir scripts 2.cd scripts 3.touch hello.sh 4.vim hello.sh #!/bin/bash echo "hello,world" 5.bash hello.sh(…...
基于Django的AI客服租车分析系统
基于Django的AI客服租车分析系统 【包含内容】 【一】项目提供完整源代码及详细注释 【二】系统设计思路与实现说明 【三】AI智能客服与用户交互指导手册 【技术栈】 ①:系统环境:Python 3.8,Django 4.2框架 ②:开发环境&a…...
计算机组成与体系结构:计算机结构的分类(classifications of computer architecture)
目录 Von Neumann Architecture(冯诺依曼结构) Harvard Architecture(哈佛结构) Modified Harvard Architecture(改进哈佛结构) 三种结构对比总结表 💡 从“内存访问结构”角度分类&#x…...
在阿里云和树莓派上编写一个守护进程程序
目录 一、阿里云邮件守护进程 1. 安装必要库 2. 创建邮件发送脚本 mail_daemon.py 3. 设置后台运行 二、树莓派串口守护进程 1. 启用树莓派串口 2. 安装依赖库 3. 创建串口输出脚本 serial_daemon.py 4. 设置开机自启 5. 使用串口助手接收 一、阿里云邮件守护进程 1.…...
Redis 的几种数据类型
Redis 提供了多种数据类型,以支持不同的应用场景。每种数据类型都有其特定的操作方式,并且在内部实现上也有所优化,能够满足不同的业务需求。以下是 Redis 支持的几种常见数据类型: 1. 字符串(String) 描…...
Spring之我见 - Spring Boot Starter 自动装配原理
欢迎光临小站:致橡树 Spring Boot Starter 的核心设计理念是 约定优于配置,其核心实现基于 自动配置(Auto-Configuration) 和 条件化注册(Conditional Registration)。以下是其生效原理: 约定…...
LeRobot 项目部署运行逻辑(二)—— Mobile Aloha 真机部署
LeRobot 在开源项目中详细说明了部署流程,所以首先看一下开源的内容,然后再逐步拆解 首先,LeRobot 开源的硬件是配全部在 examples 文件夹中 包括了 Stretch 3、Aloha and Aloha 2 stationary、SO-100、LeKiwi、Moss v1 等机器人 恰好实验…...
大模型面经 | 介绍一下CLIP和BLIP
大家好,我是皮先生!! 今天给大家分享一些关于大模型面试常见的面试题,希望对大家的面试有所帮助。 往期回顾: 大模型面经 | 春招、秋招算法面试常考八股文附答案(RAG专题一) 大模型面经 | 春招、秋招算法面试常考八股文附答案(RAG专题二) 大模型面经 | 春招、秋招算法…...
Java发生OOM是否必然导致JVM退出
Java发生OOM是否必然导致JVM退出? 核心结论 不一定。OOM是否导致JVM退出取决于以下因素: OOM发生的区域JVM启动参数配置是否捕获了OOM异常 详细分析 1. 不同内存区域的OOM影响 内存区域错误类型默认是否导致JVM退出可恢复性Java堆OutOfMemoryError…...
Docker Compose 外部网络(`external: true`)与内部网络的区别
Docker Compose 外部网络(external: true)与内部网络的区别 在 Docker Compose 中,external: true 声明的外部网络与普通(内部)网络有重要区别,以下是它们的详细对比: 1. 定义与创建方式 特性外部网络 (external: true)内部网络 (默认)创建…...
【Android】Wallpaper学习
从wallpaper的设置来了解相关内容: 一,静态壁纸 静态壁纸设置的原理是在WallpaperManagerService里监听/data/system/users/0/wallpaper_orig相关文件的变化来触发设置,通过相应的组件程序去进行绘制, 相应的组件如:…...
Java基础-第一章、基本数据类型
运算符: 1.算术运算符:加减乘除%等 2.逻辑运算符:与或非等 3.关系运算符:大于、小于... 4.赋值运算符: 这里牵扯运算符的运算先后顺序了。 赋值运算的返回值:就是赋值的变量本身...
《Operating System Concepts》阅读笔记:p748-p748
《Operating System Concepts》学习第 64 天,p748-p748 总结,总计 1 页。 一、技术总结 1.Transmission Control Protocol(TCP) 重点是要自己能画出其过程,这里就不赘述了。 二、英语总结(生词:3) transfer, transport, tran…...
Arduino示例代码讲解:Project 08 - Digital Hourglass 数字沙漏
Arduino示例代码讲解:Project 08 - Digital Hourglass 数字沙漏 Project 08 - Digital Hourglass 数字沙漏程序功能概述功能:硬件要求:输出:代码结构全局变量`setup()` 函数`loop()` 函数计时和点亮LED:读取倾斜开关状态:重置LED和计时器:运行过程注意事项Project 08 - …...
报告总结笔记 | Jeff Dean ETH AI趋势 笔记:AI 的重要趋势:我们是如何走到今天的,我们现在能做什么,以及我们如何塑造 AI 的未来?
报告总结笔记 | Jeff Dean ETH AI趋势 笔记:AI 的重要趋势:我们是如何走到今天的,我们现在能做什么,以及我们如何塑造 AI 的未来? 2025年 4 月 14 日,Google Research 及 Google DeepMind 的首席科学家、A…...
RocketMQ实现基于可靠消息的最终一致性
RocketMQ实现基于可靠消息的最终一致性 文章目录 RocketMQ实现基于可靠消息的最终一致性一、RocketMQ应用场景**应用解耦****流量削峰****数据分发** 二、RocketMQ 基础概念1. 核心组件2. 消费模式3. 消息可靠性 三、消息类型按发送方式分同步发送异步发送单向发送 按使用功能特…...
【题解-Acwing】790. 数的三次方根
题目:790. 数的三次方根 题目描述 给定一个浮点数 n,求它的三次方根。 输入 共一行,包含一个浮点数 n 。 输出 共一行,包含一个浮点数,表示问题的解。 注意,结果保留 6 位小数。 数据范围 −10000 ≤ n ≤ 10000 时空限制 1s / 64MB 输入样例 1000.00输出样…...
一键升级OpenSSH/OpenSSL修复安全漏洞
在服务器安全运维过程中,我们经常面临这样的问题:收到高危漏洞通报(如最近的OpenSSH多个CVE漏洞),但Ubuntu系统无法通过apt直接升级到修复版本。这种情况下,传统方法需要手动编译源码,处理依赖关…...
Pycharm 如何删除某个 Python Interpreter
在PyCharm中,点击右下角的“Interpreter Settings”按钮,或者通过菜单栏选择“File” > “Settings”(macOS用户选择“PyCharm” > “Preferences”)。在设置窗口中,导航到“Project: [Your Project Name]” >…...
【C++】深入浅出之多态
目录 多态的概念多态的定义和实现多态的构造条件虚函数虚函数的重写虚函数重写的两个例外协变析构函数作为虚函数重写 C11的override和final重载、重写(覆盖)、隐藏(重定义)的对比相关面试题⭐ 抽象类概念接口继承和实现继承 多态的原理虚函数表多态的原理动态绑定和静态绑定 e…...
精益数据分析(9/126):如何筛选创业路上的关键数据指标
精益数据分析(9/126):如何筛选创业路上的关键数据指标 大家好!在创业的漫漫长路中,数据就像一盏明灯,指引着我们前行的方向。但要让这盏灯发挥作用,关键在于找到那些真正有价值的数据指标。今天…...
【Python爬虫详解】第二篇:HTML结构的基本分析
在上一篇文章中,我们介绍了网络爬虫的基本概念、发展历程和工作原理。要进行有效的网页内容爬取,首先需要理解我们要爬取的对象 —— 网页的基本结构和语法。网页本质上是由HTML代码构成的,爬虫程序需要从HTML中提取我们需要的信息。因此&…...
【C++】 —— 笔试刷题day_21
一、爱丽丝的人偶 题目解析 现在存在n个玩偶,每个玩偶的身高是1、2、3......n; 现在我们要对这些玩偶进行排序(如果x人偶,它左右两边的玩偶一个比x高、一个比x矮,那这个玩偶就会爆炸)。 我们不想要任何一个…...
云点数据读写
一、常见点云数据格式 LAS/LAZ格式 LAS是点云数据的行业标准格式 LAZ是LAS的压缩版本 支持地理参考信息、颜色、强度等属性 PCD格式(Point Cloud Data) PCL(Point Cloud Library)开发的格式 支持ASCII和二进制存储 包含头部信息和数据部分 PLY格式(Polygon File Format…...
Matlab 汽车行驶速度PID控制系统仿真
1、内容简介 Matlab 213-汽车行驶速度PID控制系统仿真 可以交流、咨询、答疑 2、内容说明 略 3、仿真分析 略 4、参考论文 略...
STM32嵌入式
一、创建工程项目 1、进入软件首页 2、新建项目,【file】->【new project】 3、选择需要的芯片 4、系统内核部分设置 ① 选择晶振(使用外部的高速晶振) ② 选择debug形式(SW类型) 5、时钟设置 6、选择自己需要的引脚设置&a…...
机器学习(神经网络基础篇)——个人理解篇6(概念+代码)
1 在声明一个类中,构建一个属于类的函数,前面为什要加上“self”? 就像下面这一串代码: class TwoLayerNet:def __init__(self, input_size, hidden_size, output_size,weight_init_std0.01):# 初始化权重self.params {}self.p…...
Java学习手册:Filter 和 Listener
在 JavaWeb 开发中,Filter(过滤器)和 Listener(监听器)是两个重要的技术组件,它们在处理客户端请求、管理应用状态和资源以及实现全局逻辑控制等方面发挥着关键作用。 一、Filter(过滤器&#…...
深度学习总结(25)
抽样偏倚问题 非代表性数据有一个特别隐蔽又特别常见的例子,那就是抽样偏倚(sampling bias)。如果你的数据收集过程与你尝试预测的目标之间存在相互影响,就会出现抽样偏倚,从而导致有偏差的结果。 理解数据 将数据…...
探索 Model Context Protocol (MCP):它如何影响 AI 的表现?
Anthropic 公司 Anthropic 是一家技术实力雄厚的公司,也是大模型领域的重要参与者之一。其开发的 **Claude 模型** 是全球首个以编程能力见长并广受欢迎的大语言模型。这款模型凭借卓越的代码生成和理解能力,迅速成为许多开发者工具的核心组件。例如&am…...
Three.js + React 实战系列-3D 个人主页 :完成 Navbar 导航栏组件
在上一节中,我们搭建了项目的基础结构,搭建好了项目框架。 本节我们将继续完善页面结构,完成第一个视觉组件 —— Navbar 导航栏 ✅ 前置准备: ✅下载静态资源在根目录下 (src 同级)谷歌云盘地址 🎥 02 完成 Navba…...
游戏引擎学习第238天:让 OpenGL 使用我们的屏幕坐标
回顾并为今天的内容做准备 我们已经完成了硬件显示的实现,现在通过GPU来显示游戏。原本以为这会花费很长时间,但结果实际所需的时间并不多。因此,我们现在有了进展,但接下来应该做什么还不确定。虽然有很多事情可以做,…...
go+mysql+cocos实现游戏搭建
盲目的学了一段时间了,刚开始从Box2d开始学习,明白了很多,Box2d是物理模型的基础,是我们在游戏中模拟现实的很重要的一个开源工具。后来在朋友的建议下学习了cocos,也是小程序开发的利器,而golang是一款高效…...
Linux 网络基础(二) (传输协议层:UDP、TCP)
目录 一、传输层的意义 二、端口号 1、五元组标识一个通信 2、端口号范围划分 3、知名端口号(Well-Know Port Number) (1)查看端口号 4、绑定端口号数目问题 5、pidof & netstat 命令 (1)ne…...