【hello, world】计算机系统漫游

news2024/11/18 14:51:30

文章目录

  • hello程序
  • 信息就是位 + 上下文
  • 程序被其他程序翻译成不同的格式
    • 预处理阶段
    • 编译阶段
    • 汇编阶段
    • 链接阶段
  • 了解编译系统如何工作是大有益处的
    • 优化程序性能
    • 理解链接时出现的错误
    • 避免安全漏洞
  • 处理器读并解释储存在内存中的指令
    • 系统的硬件组成
      • 总线
      • I/O设备
      • 主存
      • 处理器
    • 运行hello程序
  • 高速缓存至关重要
  • 存储设备形成层次结构
  • 操作系统管理硬件
    • 进程
    • 线程
    • 虚拟内存
    • 文件
  • 系统之间利用网络通信
  • 重要主题
    • Amdahl定律
    • 并发和并行
      • 线程级并发
      • 指令级并行
      • 单指令、多数据并行
    • 计算机系统中抽象的重要性

计算机系统是硬件和系统软件互相交织的集合体

hello程序

hello.c

#include <stdio.h>

int main()
{
	printf("hello, world\n");
	return 0;
}

我们通过跟踪hello程序的生命周期来开始对系统的学习:从它被程序员创建开始,到在系统上运行,输出简单的消息,然后终止。

信息就是位 + 上下文

hello程序的生命周期是从源程序源文件)开始的,即程序员通过编辑器创建并保存的文本文件hello.c。源程序实际上就是一个由01组成的比特bit)序列。8个位被组织成一组,称为字节byte)。

ASCII标准用一个唯一单字节大小的整数值表示一个字符,如字符#对应的数值是35,字符i对应的数值是105hello.cASCII文本表示如下图所示:
在这里插入图片描述
hello.c这样可以通过标准字符集(如ASCII)解析的文件称为文本文件,所有其他文件都称为二进制文件

系统中的所有信息——包括磁盘文件、内存中的程序、内存中存放的用户数据以及网络上传送的数据,都是由一串比特表示的。区分不同数据对象的唯一方法是我们读到这些数据对象时的上下文。比如在不同的上下文中,一串相同的字节序列可能表示一个整数、浮点数、字符串或机器指令。

通常情况下,机器表示的数值是实际数值的有限近似值

程序被其他程序翻译成不同的格式

hello.c是能够被人读懂的文本文件,但为了在系统上运行它,每条C语句都必须被其他程序转化为一系列的低级机器语言指令(能被机器读懂)。然后这些指令按照一种称为可执行目标程序的格式打好包,并以二进制文件可执行目标文件)的形式存放在磁盘。

Unix系统上,从源文件目标文件的转化是由编译器驱动程序(简称编译器)完成的:
在这里插入图片描述
在这里,gcc编译器读取hello.c并生成hello的过程可分为四个阶段:预处理编译汇编链接。与此相关的预处理器编译器汇编器链接器一起构成了编译系统
在这里插入图片描述

预处理阶段

预处理器(cpp)根据以字符#开头的命令,修改原始的C程序。比如#include <stdio.h>命令告诉cpp读取系统头文件stdio.h里的内容,并把它插入程序文本中相应的位置。结果就得到了另一个以.i作为文件扩展名的C程序。

编译阶段

编译器(ccl)将文本文件hello.i翻译成文本文件hello.s,它包含一个汇编语言程序。该程序包含函数main的定义:

main:
.LFB0:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	movl	$.LC0, %edi
	call	puts
	movl	$0, %eax
	popq	%rbp
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc

上述每条汇编语句都文本的形式描述了一条低级机器语言指令。不同高级语言不同编译器针对某个确定的CPU架构输出统一的汇编语言。

汇编阶段

汇编器(as)将hello.s翻译成机器语言指令,把这些指令打包成一种叫做可重定位目标程序的格式,并将结果保存在目标文件hello.o中。hello.o中包含的是函数main的指令编码,如果在文本编辑器中打开该二进制文件,会看到一堆乱码。

链接阶段

hello程序调用了printf函数,它是每个C编译器都提供的标准C库中的一个函数。printf函数存在于一个名为printf.o的单独的预编译好了的目标文件中,这个文件必须以某种方式合并hello.o中,否则main函数将无法调用printf函数。

链接器(ld)就负责处理这种合并,结果就得到hello文件,它是一个可执行目标文件(简称可执行文件),平时存储在磁盘上,运行时被加载到内存,由系统执行。

了解编译系统如何工作是大有益处的

优化程序性能

了解编译器将不同的C语句转化为机器代码的方式,有助于我们写出更高效的代码。如:

  1. 一个switch语句是否总比一系列的if-else高效?
  2. 一个函数调用的开销有多大?
  3. while循环比for循环更有效吗?
  4. 指针引用比数组索引更有效吗?
  5. 为什么将循环求和的结果放到一个本地变量中,会比将其放到一个通过引用传递过来的参数中,运行起来快很多呢?
  6. 为什么我们只是简单地重新排列一下算术表达式中的括号就能让函数运行得更快?

理解链接时出现的错误

一些最令人困扰的程序错误都和链接有关,尤其是构建大型软件系统的时候。如:

  1. 链接器报告说它无法解析一个引用,这是什么意思?
  2. 静态变量和全局变量的区别是什么?
  3. 在不同的C文件中定义了名字相同的两个全局变量会发生什么?
  4. 静态库和动态库的区别是什么?
  5. 命令行上排列库的顺序有什么影响?
  6. 为什么有些链接错误直到运行时才会出现?

避免安全漏洞

缓冲区溢出是造成软件安全漏洞的主要原因,学习安全编程的第一步就是理解数据控制信息存储在程序栈上的方式(这种方式由编译器决定)及其会引起的后果。

处理器读并解释储存在内存中的指令

现在,hello.c源程序已经被编译系统翻译成了可执行目标文件hello,并被存放在磁盘上。要想在Unix系统上运行该可执行文件,我们将它的文件名输入到称为shell的应用程序中。
在这里插入图片描述
shell是一个命令行解释器,它输出一个提示符,等待输入一个命令行,然后执行这个命令。
在此例中,shell加载并运行hello程序,然后等待程序终止,随后再输出一个提示符,等待输入下一个命令行。

系统的硬件组成

要理解hello程序运行时发生了什么,我们需要了解一下典型系统的硬件组织。
在这里插入图片描述

总线

贯穿整个系统的是一组电子管道,称作总线bus),它携带信息字节并负责在各个部件间传递。通常总线被设计成传送定长的字节块,也就是word)。字的字节数(即字长)是一个基本的系统参数,各系统不尽相同,如32位系统的字长是4字节,64位系统的字长是8字节。

I/O设备

I/O输入/输出)设备是系统与外部世界的联系通道。图中包括4I/O设备:作为输入设备的鼠标键盘,作为输出设备的显示器,即能输入又能输出、长期存储数据和程序的磁盘驱动器(简称磁盘)。hello程序就存放在磁盘上。

每个I/O设备都通过一个控制器适配器I/O总线相连。控制器是I/O设备本身或者系统的主印制电路板(即主板)上的芯片组,适配器则是一块插在主板插槽上的卡(可插拔),它们的功能都是在I/O总线和I/O设备之间传递信息。

主存

主存(即内存)是一个临时存储设备,在处理器执行程序时,用来存放程序程序处理的数据。每条程序指令所占用的字节数不尽相同,每个数据变量所占用的字节数也不尽相同。

物理上来说,主存是由一组动态随机访问存储器DRAM)芯片组成的。逻辑上来说,主存是一个线性的字节数组,每个字节都有其唯一的地址(数组索引),地址从0开始。

处理器

中央处理单元CPU),简称处理器,是执行存储在主存中指令的引擎。处理器的核心是一个大小为一个字的存储设备(寄存器),称为程序计数器PC),PC始终指向CPU执行的当前指令或下一条指令。从系统通电开始,直到系统断电,处理器一直在不断地执行PC指向的指令,再更新PC,执行下一条指令。

处理器是按照一个简单的指令执行模型工作的,这个模型由其指令集架构(如x86_64armv8)决定。
执行指令时,处理器从PC指向的内存处读取指令解释指令中的位执行该指令指示的简单操作,然后更新PC

这样的简单操作围绕着主存寄存器文件算术逻辑单元ALU)进行。寄存器文件是一个小的存储设备,由一些单字长的寄存器组成,每个寄存器都有唯一的名字。ALU计算新的数据和地址。CPU在执行一条指令时,可能会做这些简单操作:

  1. 加载:从主存复制一个字节或一个字到寄存器,覆盖该寄存器原来的内容。
  2. 存储:从寄存器复制一个字节或一个字到主存中的某个位置,覆盖主存上该位置原来的内容。
  3. 操作:把两个寄存器的内容复制到ALU做算术运算,将结果保存到一个寄存器中。
  4. 跳转:从指令本身中抽取一个字,复制到PC上。

处理器看上去是它的指令集架构的简单实现,但是实际上现代处理器使用了非常复杂的机制来加速程序的执行。因此,我们将处理器的指令集架构和处理器的微体系结构区分开来:

  1. 指令集架构描述的是每条机器代码指令在做什么。
  2. 微体系结构描述的是处理器实际上是如何实现的。

指令集架构是对处理器的抽象表示,微体系结构是处理器的具体实现方式。

运行hello程序

当我们在shell上输入字符串./hello后,shell程序将字符逐一读入寄存器,再把它放到内存中。
在这里插入图片描述
当我们在键盘上敲回车键时,shell程序就知道我们已经结束了输入命令,于是shell便开始加载可执行文件hello,将hello目标文件中的代码数据磁盘复制到主存

利用直接存储器存取DMA)技术,字节信息可以不通过处理器而直接从磁盘达到主存。
在这里插入图片描述
一旦目标文件hello中的代码和数据被加载到主存,处理器就开始执行hello程序的main函数中的机器语言指令。这些指令将"hello, world\n"字符串中的字节从主存复制到寄存器文件,再从寄存器文件复制到显示设备,最终显示在显示器上。
在这里插入图片描述

高速缓存至关重要

可以看到程序执行时,信息在外部设备、磁盘、主存、寄存器文件之间来回传输,系统花费了大量的时间把信息(数据和指令)从一个地方复制到另一个地方。这些复制就是开销,因此提升程序性能的一个重要手段就是减少信息的复制

处理器从寄存器文件中读数据比从主存中读数据要快很多(如100倍),针对这个问题,系统设计者采用了高速缓存存储器(简称高速缓存cache),作为主存信息暂时的集结区域,存放处理器近期可能会需要的信息。cache使用一种叫做静态随机访问存储器SRAM)的硬件技术实现。

位于处理器芯片上的L1 cache,处理器访问它的速度几乎和寄存器文件一样快。容量更大、访问速度稍慢的L2 cacheL3 cache通过一条特殊的总线连接到处理器。
在这里插入图片描述

上图仅供参考,L2 cacheL3 cache也有别的实现方式,比如都集成到CPU

利用高速缓存的局部性原理(程序具有访问局部区域里的数据和代码的趋势),缓存命中率的情况下,大部分的内存操作都能在快速的高速缓存中完成,程序的性能会因此提高一个数量级

存储设备形成层次结构

每个计算机系统中的存储设备都被组织成了一个存储器层次结构。在这个层次结构中,从上至下,设备的访问速度越来越慢容量越来越大每字节的造价越来越便宜。寄存器文件处于最顶层(L0),高速缓存占用L1L2L3,主存在第四层(L4),以此类推。
在这里插入图片描述
存储器层次结构的主要思想是:上一层存储器作为下一层存储器的高速缓存

操作系统管理硬件

shell加载和运行hello程序时,它们并没有直接访问键盘、主存、磁盘和显示器。所有应用程序对硬件的操作尝试都必须通过操作系统
在这里插入图片描述
操作系统有两个基本功能:

  1. 防止硬件被失控的应用程序滥用(保护系统)。
  2. 向应用程序提供简单一致的机制来控制复杂而又通常大不相同的低级硬件设备(提供抽象)。

系统认为应用程序指令是存在安全隐患的,而操作系统指令是一定安全的。

操作系统通过几个基本的抽象(进程虚拟内存文件)来实现这两个功能。
在这里插入图片描述

文件是对I/O设备的抽象表示
虚拟内存是对主存和I/O设备的抽象表示
进程是对处理器、主存和I/O设备的抽象表示

进程

进程是操作系统对一个正在运行的程序的抽象。在一个系统上可以同时运行多个进程,而在每个进程看来,它都在独占处理器、主存和I/O设备。并发运行是说一个进程的指令和另一个进程的指令是交错执行的,这是通过处理器在进程间切换上下文切换)来实现的。

操作系统保持跟踪进程运行所需的所有状态信息,这种状态就是进程上下文,包括PC和寄存器文件的当前值、主存的内容。在任何一个时刻,单处理器系统都只能执行一个进程的代码。当操作系统要把控制权转移给其它进程时,就会进行上下文切换。即保存当前进程的上下文,恢复新进程的上下文,转移控制权给新进程,新进程就会从它上次停止的地方开始执行。

进程有两种运行状态:用户态内核态。单个进程执行过程中,也会涉及到内核态和用户态之间的切换。但这种切换相比于进程间的上下文切换,开销要小。

从一个进程到另一个进程的转换是由操作系统内核管理的,内核是操作系统代码常驻主存的部分。
内核不是一个独立的进程,它是系统管理全部进程所用代码和数据结构的集合。所以内核态和用户态之间的切换不是进程间上下文切换。
系统中可以有很多进程,但通常只有一个内核

上述通过shell进程加载和执行hello程序的场景,其简易执行流程如下:
在这里插入图片描述
更完整的流程描述:
在这里插入图片描述

readexecwrite这些函数属于系统调用,执行系统调用时,进程会切换到内核态。

  1. shell进程调用read从命令行读到字符串"./hello"
  2. shell进程创建子进程,并加载hello目标文件到该子进程。操作系统把控制权交给子进程(hello进程)。
  3. hello进程正常执行。调用write"hello, world\n"写到显示器上。
  4. hello进程终止,shell进程获得操作系统控制权。

线程

一个进程可以由多个称为线程的执行单元组成,每个线程都运行在进程的上下文中,共享同样的代码全局数据,每个线程也会有自己的资源。操作系统在同一进程的多线程之间切换开销较小。

虚拟内存

操作系统为每个进程提供了一个假象,即每个进程都在独占地使用一块超大的虚拟内存,且每个进程的虚拟内存地址空间结构是一样的。

Linux虚拟地址空间中,地址空间最上面的区域是留给内核的,底部区域存放用户进程定义的代码和数据。
在这里插入图片描述
虚拟地址空间的每个区都有各自的功能:

  1. 程序代码和数据。对所有的进程来说,代码是从同一固定地址开始的。代码和数据区是直接按照可执行目标文件的内容初始化的。它们在进程开始运行时就被指定了大小。
  2. 运行时堆。当调用mallocfree这样的C标准库函数时,堆区动态地扩展和收缩。
  3. 共享库。存放C标准库、数学库等共享库的代码和数据。
  4. 运行时栈。位于用户虚拟地址空间顶部,用于函数的调用和返回、局部变量的申请和释放等,也可以在运行时动态地扩展和收缩。
  5. 内核区。位于虚拟地址空间顶部。里面的内容对所有进程来说都是一样的。但不允许应用程序读写或者直接调用这个区域的内容。

用户进程要访问内核区的话,需要产生中断、切换到内核态,再访问内核区的代码和数据,最后切换回用户态,把结果返回给用户进程。

文件

文件就是字节序列。每个I/O设备,包括磁盘、键盘、显示器,甚至网络,都可以看成是文件。对所有的设备读写都可以通过文件读写(如UnixI/O系统函数)来实现。

系统之间利用网络通信

可以把网络看作一个I/O设备。
当系统从主存复制一串字节到网络适配器时,数据流经过网络到达另一台机器。
在这里插入图片描述
系统也可以从网络适配器上读取字节流,复制到自己的主存。
在这里插入图片描述

重要主题

Amdahl定律

阿姆达尔定律:当我们对系统的某个部分加速时,其对系统整体性能的影响取决于该部分的重要性和加速程度。若系统执行某应用程序需要时间为 T o l d T_{old} Told,假设系统某部分所需执行时间与该时间比例为 α \alpha α,而该部分性能提升比例为 k k k,即该部分初始所需时间为 α ∗ T o l d \alpha*T_{old} αTold,现在所需时间为 α ∗ T o l d / k \alpha*T_{old} / k αTold/k,总的执行时间为:
T n e w = ( 1 − α ) ∗ T o l d + α ∗ T o l d / k = T o l d ∗ [ ( 1 − α ) + α / k ] \begin{align} T_{new} = (1 - \alpha) * T_{old} + \alpha*T_{old} / k = T_{old} * [(1 - \alpha) + \alpha / k] \end{align} Tnew=(1α)Told+αTold/k=Told[(1α)+α/k]
老新时间比为:
S = T o l d T n e w = 1 ( 1 − α ) + α / k \begin{align} S = \frac{T_{old}}{T_{new}} = \frac{1}{(1 - \alpha) + \alpha / k} \end{align} S=TnewTold=(1α)+α/k1
要想显著加速整个系统,必须提升全系统中相当大部分的速度,尤其是最耗时的部分。

性能提升最好的表示方式为 T o l d T n e w \frac{T_{old}}{T_{new}} TnewTold,如果性能提升为原来的2.2倍,记作2.2X

当系统部分性能提升比例 k k k趋近于 ∞ \infty 时, S S S的值为:
S = 1 1 − α \begin{align} S = \frac{1}{1 - \alpha} \end{align} S=1α1
如果系统的某部分占整体性能的60%,那么即便对该部分做了极致的优化,使其消耗的时间可以忽略不计,那么系统整体的性能提升只有2.5X

并发和并行

并发:宏观上,系统能同时处理多个任务就叫并发。如同一时间段内,单处理器系统快速轮询处理多个任务。
并行:微观上,任意时刻,多个处理器同时处理多个任务,这些任务都不会出现被闲置的时刻。

并行并发的一种场景。

我们按照系统层次结构中由高到低(抽象到具体)的顺序讨论一下并发。

线程级并发

线程是CPU调度的基本单位。线程级并发是指程序控制流的并发。

当构建一个由操作系统内核控制的单处理器系统时,我们就得到一个单处理器系统
当构建一个由操作系统内核控制的多处理器系统时,我们就得到一个多处理器系统

多处理器又分为多核处理器超线程处理器
有些功能强大的处理器既是多核的,又是超线程的。

多核处理器是将多个CPU(称)集成到一个芯片上。每个CPU有自己的PC、寄存器文件、计算单元、高速缓存等,多核处理器可以同时维护多个控制流。如Intel i5-7200U4核处理器。

超线程,有时称同时多线程,是一项允许一个CPU执行多个控制流的技术。比如单个CPU有多份PC、寄存器文件等,也可以同时维护多个控制流。如Intel i7可以让每个核执行2个线程,做成48线程处理器。

指令级并行

现代处理器可以同时执行多条指令的属性称为指令级并行(无线程级并发的情况下)。
处理器通过流水线等技术,可以做到单个时钟周期内执行一条甚至多条机器指令,超过一条机器指令的,就称之为超标量处理器

单指令、多数据并行

许多现代处理器有特殊的硬件,允许一条指令产生多个可以并行执行的操作,即单指令、多数据(SIMD)。如图形处理器(GPU)。

计算机系统中抽象的重要性

抽象的使用是计算机科学中最为重要的概念之一。抽象带来了极大的方便,如程序员将某需求抽象为一组应用编程接口API),且为这些API在不同场景下提供了不同的实现。而调用方在不同的场景下,可以使用同一调用接口。

指令集架构提供了对实际处理器硬件的抽象。有了这个抽象,机器代码程序表现得就好像运行在一个串行执行指令的处理器上。其实处理器底层硬件要比抽象描述复杂精细得多,它并行地执行多条指令,但整体效果跟抽象模型保持一致。只要模型一样,在不同的处理器上执行时,就会产生一样的结果,但会体现出不同的开销和性能。

文件是对I/O设备的抽象。
虚拟内存是对系统存储器的抽象。
进程是对一个正在运行的程序的抽象。
虚拟机是对整个计算机系统的抽象。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/338557.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

web3:区块链共识机制系列-POS(Proof of Stake)股权证明算法

web3相关学习一并收录至该博客&#xff1a;web3学习博客目录大全 前情衔接&#xff1a;web3:区块链常见的几大共识机制及优缺点 目录前言算法公式与原理算法公式运作原理以Peer Coin为例缺陷优点缺点特点分类发展历程casper协议1.什么是无成本利益关系问题2.引入casper协议解决…

力扣33.搜索旋转排序数组

文章目录力扣33.搜索旋转排序数组题目描述方法1&#xff1a;二分查找力扣33.搜索旋转排序数组 题目描述 整数数组 nums 按升序排列&#xff0c;数组中的值 互不相同 。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&…

Android框架WiFi架构

同学,别退出呀,我可是全网最牛逼的 WIFI/BT/GPS/NFC分析博主,我写了上百篇文章,请点击下面了解本专栏,进入本博主主页看看再走呗,一定不会让你后悔的,记得一定要去看主页置顶文章哦。 一、wpa_supplicant:wpa_supplicant本身开源项目源码,被谷歌收购之后加入Android移…

Python中的类和对象(4)

1. 构造函数 &#xff08;_ init _(self[,……])&#xff09; 在类中定义 _init _() 方法&#xff0c;可以实现在实例化对象的时候进行个性化定制&#xff1a; >>> class C: ... def __init__(self, x, y): ... self.x x ... self.y y ... …

离散数学 课时二 命题逻辑等值演算

等值式(等值联结词) 1、设A、B是两个命题公式,若A、B构成的等价式 A等价于B 为重言式,那么称A与B是等值的 2、常用等值式&#xff1a; 注意&#xff1a; 1 双否定律 2 幂等律 3 交换律 4 结合律 5 吸收律 6 德摩根律 7 同一律 8 零律 9 矛盾律 10 排中律 11 蕴含表达式 12 …

十分钟带你体验一下什么是分布式事务

我们经常在网上看到很多人发关于分布式事务的理论&#xff0c;但是讲实战的却非常少&#xff0c;所以我今天想通过一个案例&#xff0c;来让小伙伴们都感受一下什么是分布式事务&#xff0c;这篇文章理论偏少&#xff0c;请文明观看。咱们今天的主角是 Seata&#xff01; 分布…

Django项目开发

一.认识NoSQL 1.SQL 关系型数据库 结构化: 定义主键&#xff0c;无符号型数据等关联的&#xff1a;结构化表和表之间的关系通过外键进行关联&#xff0c;节省存储空间SQL查询&#xff1a;语法固定 SELECT id,name,age FROM tb_user WHERE id1 ACID 2.NoSQL 非关系型数据库 Re…

通过实例告诉你lua中ipairs到底是怎么遍历的!

这个的文章挺多的&#xff0c;但是有好几种说法并且不全。有人说是忽略手动设定值&#xff0c;有人说是从1开始数&#xff0c;直到序号断开&#xff0c;还有人给出结果&#xff0c;但是和我实机测试的效果不一样&#xff0c; 所以我自己总结一篇。经过我的测试和总结得到以下结…

【2023】Prometheus-Alertmanager高可用集群

本次实验准备了三个节点&#xff0c;分别为laert-01~03 目录1.安装Alertmanager2.配置启动文件3.验证集群4.关于集群的配置项1.安装Alertmanager 这部分内容在三个节点上都要执行 下载安装包&#xff0c;将安装包解压至/data目录下 wget https://github.com/prometheus/aler…

javassm高校学生评教系统的设计与实现idea msyql

伴随着社会以及科学技术的发展&#xff0c;互联网已经渗透在人们的身边&#xff0c;网络慢慢的变成了人们的生活必不可少的一部分&#xff0c;紧接着网络飞速的发展&#xff0c;管理系统这一名词已不陌生&#xff0c;越来越多的学校、公司等机构都会定制一款属于自己个性化的管…

Scout:一款功能强大的轻量级URL模糊测试与爬取工具

关于Scout Scout是一款功能强大的轻量级URL模糊测试与爬取工具&#xff0c;可以帮助广大研究人员进行URL模糊测试&#xff0c;并爬取目标Web服务器中难以扫描发现的VHSOT、文件和目录等资源。 项目中包含了一个完整的字典文件&#xff0c;并尽可能地提供了更多的便携性&#…

【寻人启事】达坦科技持续招人ing

​​​​​​​ ❤️一起来探索前沿科技&#xff0c;做有意思的事情~ 我们是谁 达坦科技&#xff08;DatenLord&#xff09;专注于打造新一代开源跨云存储平台。通过软硬件深度融合的方式打通云云壁垒&#xff0c;实现无限制跨云存储、跨云联通&#xff0c;建立海量异地、异构…

活动星投票在时间的河流上造园分组怎么设置如何进行分组报名

“在时间的河流上造园”网络评选投票_免费小程序运行系统_企业有关的投票_微信投票的应用小程序投票活动如何做&#xff1f;很多企业在运营当中&#xff0c;都会通过投票活动来进行推广&#xff0c;从而达到吸粉、增加用户粘度等效果。而此类投票活动&#xff0c;通过小程序就可…

雅思经验(十一)

写作&#xff1a;WRITINGTASK 2Governments should spend money on railways rather than roads.To what extent do you agree or disagree with this statement?Give reasons for your answer and include any relevant examples from your own knowledge or experience.思路…

【性能优化】MySql查询性能优化必知必会

文章目录分析查询SQL查询优化器查询优化器的两种优化方式数据库存储结构数据库中的存储结构是怎样的数据页内的结构是怎样的索引索引是什么索引好坏的评价标准索引的数据结构B树B树B树是如何进行记录检索的&#xff1f;索引维护索引组织表二级索引索引设计覆盖索引函数索引前缀…

服务器如何下载百度网盘文件?Linux服务器如何在百度网盘中连接、上传下载;在Linux服务器上下载百度云盘中的资料

前言 百度云提供Python包bypy进行远程服务器的对接然后下载&#xff1a; https://github.com/houtianze/bypy 可以通过pip直接下载&#xff0c;授权本人的百度云账号后&#xff0c;就可以直接使Linux电脑本地文件与百度网盘的apps&#xff08;我的应用数据&#xff09;/bypy目…

【c语言】二叉树

主页&#xff1a;114514的代码大冒险 qq:2188956112&#xff08;欢迎小伙伴呀hi✿(。◕ᴗ◕。)✿ &#xff09; Gitee&#xff1a;庄嘉豪 (zhuang-jiahaoxxx) - Gitee.com 引入 我们之前已经学过线性数据结构&#xff0c;今天我们将介绍非线性数据结构----树 树是一种非线性的…

Element UI框架学习篇(五)

Element UI框架学习篇(五) 1 准备工作 1.1 在zlz包下创建数据传输对象类EmpDTO package com.zlz.dto;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;//根据前台来的 Data public class EmpDTO {private String name;private Stri…

SpringBoot的配置与使用

SpringBoot简介 我们的Spring是包含了众多工具的IoC容器&#xff0c;而SpringBoot则是Spring的加强版&#xff0c;可以更加方便快捷的使用 如果Spring是手动挡的车&#xff0c;那么SpringBoot就是自动挡的车&#xff0c;让我们的驾驶体验变得更好 SpringBoot具有一下几种特征…

NSSCTF Round#8 Basic

from:http://v2ish1yan.top MyDoor 使用php伪协议读取index.php的代码 php://filter/readconvert.base64-encode/resourceindex.php<?php error_reporting(0);if (isset($_GET[N_S.S])) {eval($_GET[N_S.S]); }if(!isset($_GET[file])) {header(Location:/index.php?fi…