ELF文件结构
ELF文件结构
前文结尾说到编译器编译源代码后生成的文件叫做目标文件,而目标文件经过编译器链接之后得到的就是可执行文件。那么目标文件到底是什么?它和可执行文件又有什么区别?链接到底又做了什么呢?接下来,我们将探索一下目标文件的本质。
目标文件的格式
目前,PC平台流行的 可执行文件格式(Executable) 主要包含如下两种,它们都是 COFF(Common File Format) 格式的变种。
- Windows下的 PE(Portable Executable)
- Linux下的 ELF(Executable Linkable Format)
目标文件就是源代码经过编译后但未进行链接的那些中间文件(Windows的.obj
和Linux的.o
),它与可执行文件的格式非常相似,所以一般跟可执行文件格式一起采用同一种格式存储。在Windows下采用PE-COFF文件格式;Linux下采用ELF文件格式。
事实上,除了可执行文件外,动态链接库(DDL,Dynamic Linking Library)、静态链接库(Static Linking Library) 均采用可执行文件格式存储。它们在Window下均按照PE-COFF格式存储;Linux下均按照ELF格式存储。只是文件名后缀不同而已。
- 动态链接库:Windows的
.dll
、Linux的.so
- 静态链接库:Windows的
.lib
、Linux的.a
下面,我们将以ELF文件为例进行介绍。
ELF文件结构
注意:段(Segment
)与节(Section
)的区别。很多地方对两者有所混淆。段是程序执行的必要组成,当多个目标文件链接成一个可执行文件时,会将相同权限的节合并到一个段中。相比而言,节的粒度更小。
如图所示,为ELF文件的基本结构,其主要由四部分组成:
- ELF Header
- ELF Program Header Table (或称Program Headers、程序头)
- ELF Section Header Table (或称Section Headers、节头表)
- ELF Sections
从图中,我们就能看出它们各自的数据结构以及相互之间的索引关系。下面我们依次进行介绍。
ELF Header
我们可以使用readelf工具来查看ELF Header。
$ readelf -h hello.oELF Header:Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00Class: ELF64Data: 2's complement, little endianVersion: 1 (current)OS/ABI: UNIX - System VABI Version: 0Type: REL (Relocatable file)Machine: Advanced Micro Devices X86-64Version: 0x1Entry point address: 0x0Start of program headers: 0 (bytes into file)Start of section headers: 672 (bytes into file)Flags: 0x0Size of this header: 64 (bytes)Size of program headers: 0 (bytes)Number of program headers: 0Size of section headers: 64 (bytes)Number of section headers: 13Section header string table index: 10
ELF文件结构示意图中定义的Elf_Ehdr
的各个成员的含义与readelf具有对应关系。如下表所示:
成员 | 含义 |
---|---|
e_ident | Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |
Class: ELF32 | |
Data: 2’s complement, little end | |
Version: 1(current) | |
OS/ABI: UNIX - System V | |
ABI Version: 0 | |
e_type | Type: REL (Relocatable file) |
ELF文件类型 | |
e_machine | Machine: Advanced Micro Devices X86-64 |
ELF文件的CPI平台属性 | |
e_version | Version: 0x1 |
ELF版本号。一般为常数1 | |
e_entry | Entry point address: 0x0 |
入口地址,规定ELF程序的入口虚拟地址,操作系统在加载完该程序后从这个地址开始执行进程的指令。可重定位指令一般没有入口地址,则该值为0 | |
e_phoff | Start of program headers: 0(bytes into file) |
e_shoff | Start of section headers: 672 (bytes into file) |
Section Header Table 在文件中的偏移 | |
e_word | Flags: 0x0 |
ELF标志位,用来标识一些ELF文件平台相关的属性。 | |
e_ehsize | Size of this header: 64 (bytes) |
ELF Header本身的大小 | |
e_phentsize | Size of program headers: 0 (bytes) |
e_phnum | Number of program headers: 0 |
e_shentsize | Size of section headers: 64 (bytes) |
单个Section Header大小 | |
e_shnum | Number of section headers: 13 |
Section Header的数量 | |
e_shstrndx | Section header string table index: 10 |
Section Header字符串表在Section Header Table中的索引 |
ELF魔数
每种可执行文件的格式的开头几个字节都是很特殊的,特别是开头4个字节,通常被称为魔数(Magic Number)。通过对魔数的判断可以确定文件的格式和类型。如:ELF的可执行文件格式的头4个字节为0x7F
、e
、l
、f
;Java的可执行文件格式的头4个字节为c
、a
、f
、e
;如果被执行的是Shell脚本或perl、python等解释型语言的脚本,那么它的第一行往往是#!/bin/sh
或#!/usr/bin/perl
或#!/usr/bin/python
,此时前两个字节#
和!
就构成了魔数,系统一旦判断到这两个字节,就对后面的字符串进行解析,以确定具体的解释程序路径。
ELF文件类型
ELF文件主要有三种类型,可以通过ELF Header中的e_type
成员进行区分。
-
可重定位文件(Relocatable File):
ETL_REL
。一般为.o
文件。可以被链接成可执行文件或共享目标文件。静态链接库属于可重定位文件。 -
可执行文件(Executable File):
ET_EXEC
。可以直接执行的程序。 -
共享目标文件(Shared Object File)
:
ET_DYN
。一般为
.so
文件。有两种情况可以使用。
- 链接器将其与其他可重定位文件、共享目标文件链接成新的目标文件;
- 动态链接器将其与其他共享目标文件、结合一个可执行文件,创建进程映像。
ELF Section Header Table
ELF 节头表是一个节头数组。每一个节头都描述了其所对应的节的信息,如节名、节大小、在文件中的偏移、读写权限等。编译器、链接器、装载器都是通过节头表来定位和访问各个节的属性的。
我们可以使用readelf工具来查看节头表。
$ readelf -S hello.oThere are 13 section headers, starting at offset 0x2a0:Section Headers:[Nr] Name Type Address OffsetSize EntSize Flags Link Info Align[ 0] NULL 0000000000000000 000000000000000000000000 0000000000000000 0 0 0[ 1] .text PROGBITS 0000000000000000 000000400000000000000015 0000000000000000 AX 0 0 1[ 2] .rela.text RELA 0000000000000000 000001f00000000000000030 0000000000000018 I 11 1 8[ 3] .data PROGBITS 0000000000000000 000000550000000000000000 0000000000000000 WA 0 0 1[ 4] .bss NOBITS 0000000000000000 000000550000000000000000 0000000000000000 WA 0 0 1[ 5] .rodata PROGBITS 0000000000000000 00000055000000000000000d 0000000000000000 A 0 0 1[ 6] .comment PROGBITS 0000000000000000 000000620000000000000035 0000000000000001 MS 0 0 1[ 7] .note.GNU-stack PROGBITS 0000000000000000 000000970000000000000000 0000000000000000 0 0 1[ 8] .eh_frame PROGBITS 0000000000000000 000000980000000000000038 0000000000000000 A 0 0 8[ 9] .rela.eh_frame RELA 0000000000000000 000002200000000000000018 0000000000000018 I 11 8 8[10] .shstrtab STRTAB 0000000000000000 000002380000000000000061 0000000000000000 0 0 1[11] .symtab SYMTAB 0000000000000000 000000d00000000000000108 0000000000000018 12 9 8[12] .strtab STRTAB 0000000000000000 000001d80000000000000013 0000000000000000 0 0 1
Key to Flags:W (write), A (alloc), X (execute), M (merge), S (strings), l (large)I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)O (extra OS processing required) o (OS specific), p (processor specific)
ELF文件结构示意图中定义的Elf_Shdr
的各个成员的含义与readelf具有对应关系。如下表所示:
成员 | 含义 |
---|---|
sh_name | 节名 |
节名是一个字符串,保存在一个名为.shstrtab 的字符串表(可通过Section Header索引到)。sh_name的值实际上是其节名字符串在.shstrtab 中的偏移值 | |
sh_type | 节类型 |
sh_flags | 节标志位 |
sh_addr | 节地址:节的虚拟地址 |
如果该节可以被加载,则sh_addr为该节被加载后在进程地址空间中的虚拟地址;否则sh_addr为0 | |
sh_offset | 节偏移 |
如果该节存在于文件中,则表示该节在文件中的偏移;否则无意义,如sh_offset对于BSS 节来说是没有意义的 | |
sh_size | 节大小 |
sh_link、sh_info | 节链接信息 |
sh_addralign | 节地址对齐方式 |
sh_entsize | 节项大小 |
有些节包含了一些固定大小的项,如符号表,其包含的每个符号所在的大小都一样的,对于这种节,sh_entsize表示每个项的大小。如果为0,则表示该节不包含固定大小的项。 |
节类型(sh_type)
节名是一个字符串,只是在链接和编译过程中有意义,但它并不能真正地表示节的类型。对于编译器和链接器来说,主要决定节的属性是节的类型(sh_type
)和节的标志位(sh_flags
)。
节的类型相关常量以SHT_
开头,上述readelf -S
命令执行的结果省略了该前缀。常见的节类型如下表所示:
常量 | 值 | 含义 |
---|---|---|
SHT_NULL | 0 | 无效节 |
SHT_PROGBITS | 1 | 程序节。代码节、数据节都是这种类型。 |
SHT_SYMTAB | 2 | 符号表 |
SHT_STRTAB | 3 | 字符串表 |
SHT_RELA | 4 | 重定位表。该节包含了重定位信息。 |
SHT_HASH | 5 | 符号表的哈希表 |
SHT_DYNAMIC | 6 | 动态链接信息 |
SHT_NOTE | 7 | 提示性信息 |
SHT_NOBITS | 8 | 表示该节在文件中没有内容。如.bss 节 |
SHT_REL | 9 | 该节包含了重定位信息 |
SHT_SHLIB | 10 | 保留 |
SHT_DNYSYM | 11 | 动态链接的符号表 |
节标志位(sh_flag)
节标志位表示该节在进程虚拟地址空间中的属性。如是否可写、是否可执行等。相关常量以SHF_
开头。常见的节标志位如下表所示:
常量 | 值 | 含义 |
---|---|---|
SHF_WRITE | 1 | 表示该节在进程空间中可写 |
SHF_ALLOC | 2 | 表示该节在进程空间中需要分配空间。有些包含指示或控制信息的节不需要在进程空间中分配空间,就不会有这个标志。 |
SHF_EXECINSTR | 4 | 表示该节在进程空间中可以被执行 |
节链接信息(sh_link、sh_info)
如果节的类型是与链接相关的(无论是动态链接还是静态链接),如**重定位表、符号表、**等,则sh_link
、sh_info
两个成员所包含的意义如下所示。其他类型的节,这两个成员没有意义。
sh_type | sh_link | sh_info |
---|---|---|
SHT_DYNAMIC | 该节所使用的字符串表在节头表中的下标 | 0 |
SHT_HASH | 该节所使用的符号表在节头表中的下标 | 0 |
SHT_REL | 该节所使用的相应符号表在节头表中的下标 | 该重定位表所作用的节在节头表中的下标 |
SHT_RELA | 该节所使用的相应符号表在节头表中的下标 | 该重定位表所作用的节在节头表中的下标 |
SHT_SYMTAB | 操作系统相关 | 操作系统相关 |
SHT_DYNSYM | 操作系统相关 | 操作系统相关 |
other | SHN_UNDEF | 0 |
ELF Sections
节的分类
上述ELF Section Header Table部分已经简单介绍了节类型。接下来我们来介绍详细一些比较重要的节。
.text节
.text
节是保存了程序代码指令的代码节。一段可执行程序,如果存在Phdr,则.text
节就会存在于text
段中。由于.text
节保存了程序代码,所以节类型为SHT_PROGBITS
。
.rodata节
rodata
节保存了只读的数据,如一行C语言代码中的字符串。由于.rodata
节是只读的,所以只能存在于一个可执行文件的只读段中。因此,只能在text
段(不是data
段)中找到.rodata
节。由于.rodata
节是只读的,所以节类型为SHT_PROGBITS
。
.plt节(过程链接表)
.plt
节也称为过程链接表(Procedure Linkage Table),其包含了动态链接器调用从共享库导入的函数所必需的相关代码。由于.plt
节保存了代码,所以节类型为SHT_PROGBITS
。
.data节
.data
节存在于data
段中,其保存了初始化的全局变量等数据。由于.data
节保存了程序的变量数据,所以节类型为SHT_PROGBITS
。
.bss节
.bss
节存在于data
段中,占用空间不超过4字节,仅表示这个节本省的空间。.bss
节保存了未进行初始化的全局数据。程序加载时数据被初始化为0,在程序执行期间可以进行赋值。由于.bss
节未保存实际的数据,所以节类型为SHT_NOBITS
。
.got.plt节(全局偏移表-过程链接表)
.got
节保存了全局偏移表。.got
节和.plt
节一起提供了对导入的共享库函数的访问入口,由动态链接器在运行时进行修改。由于.got.plt
节与程序执行有关,所以节类型为SHT_PROGBITS
。
.dynsym节(动态链接符号表)
.dynsym
节保存在text
段中。其保存了从共享库导入的动态符号表。节类型为SHT_DYNSYM
。
.dynstr节(动态链接字符串表)
.dynstr
保存了动态链接字符串表,表中存放了一系列字符串,这些字符串代表了符号名称,以空字符作为终止符。
.rel.*节(重定位表)
重定位表保存了重定位相关的信息,这些信息描述了如何在链接或运行时,对ELF目标文件的某部分或者进程镜像进行补充或修改。由于重定位表保存了重定位相关的数据,所以节类型为SHT_REL
。
.hash节
.hash
节也称为.gnu.hash
,其保存了一个用于查找符号的散列表。
.symtab节(符号表)
.symtab
节是一个ElfN_Sym
的数组,保存了符号信息。节类型为SHT_SYMTAB
。
.strtab节(字符串表)
.strtab
节保存的是符号字符串表,表中的内容会被.symtab
的ElfN_Sym
结构中的st_name
引用。节类型为SHT_STRTAB
。
.ctors节和.dtors节
.ctors
(构造器)节和.dtors
(析构器)节分别保存了指向构造函数和析构函数的函数指针,构造函数是在main函数执行之前需要执行的代码;析构函数是在main函数之后需要执行的代码。
符号表
节的分类中我们介绍了.dynsym
节和.symtab
节,两者都是符号表。那么它们到底有什么区别呢?存在什么关系呢?
符号是对某些类型的数据或代码(如全局变量或函数)的符号引用,函数名或变量名就是符号名。例如,printf()
函数会在动态链接符号表.dynsym
中存有一个指向该函数的符号项(以Elf_Sym
数据结构表示)。在大多数共享库和动态链接可执行文件中,存在两个符号表。即.dynsym
和.symtab
。
.dynsym
保存了引用来自外部文件符号的全局符号。如printf
库函数。.dynsym
保存的符号是.symtab
所保存符合的子集,.symtab
中还保存了可执行文件的本地符号。如全局变量,代码中定义的本地函数等。
既然.dynsym
是.symtab
的子集,那为何要同时存在两个符号表呢?
通过readelf -S
命令可以查看可执行文件的输出,一部分节标志位(sh_flags
)被标记为了A(ALLOC)、WA(WRITE/ALLOC)、AX(ALLOC/EXEC)。其中,.dynsym
被标记为ALLOC,而.symtab
则没有标记。
ALLOC表示有该标记的节会在运行时分配并装载进入内存,而.symtab
不是在运行时必需的,因此不会被装载到内存中。.dynsym
保存的符号只能在运行时被解析,因此是运行时动态链接器所需的唯一符号。.dynsym
对于动态链接可执行文件的执行是必需的,而.symtab
只是用来进行调试和链接的。
上图所示为通过符号表索引字符串表的示意图。符号表中的每一项都是一个Elf_Sym
结构,对应可以在字符串表中索引得到一个字符串。该数据结构中成员的含义如下表所示:
成员 | 含义 |
---|---|
st_name | 符号名。该值为该符号名在字符串表中的偏移地址。 |
st_value | 符号对应的值。存放符号的值(可能是地址或位置偏移量)。 |
st_size | 符号的大小。 |
st_other | 0 |
st_shndx | 符号所在的节 |
st_info | 符号类型及绑定属性 |
使用readelf工具我们也能够看到符号表的相关信息。
$ readelf -s hello.oSymbol table '.symtab' contains 11 entries:Num: Value Size Type Bind Vis Ndx Name0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND1: 0000000000000000 0 FILE LOCAL DEFAULT ABS hello.c2: 0000000000000000 0 SECTION LOCAL DEFAULT 13: 0000000000000000 0 SECTION LOCAL DEFAULT 34: 0000000000000000 0 SECTION LOCAL DEFAULT 45: 0000000000000000 0 SECTION LOCAL DEFAULT 56: 0000000000000000 0 SECTION LOCAL DEFAULT 77: 0000000000000000 0 SECTION LOCAL DEFAULT 88: 0000000000000000 0 SECTION LOCAL DEFAULT 69: 0000000000000000 21 FUNC GLOBAL DEFAULT 1 main10: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND puts
字符串表
类似于符号表,在大多数共享库和动态链接可执行文件中,也存在两个字符串表。即.dynstr
和.strtab
,分别对应于.dynsym
和symtab
。此外,还有一个.shstrtab
的节头字符串表,用于保存节头表中用到的字符串,可通过sh_name
进行索引。
ELF文件中所有字符表的结构基本一致,如上图所示。
重定位表
重定位就是将符号定义和符号引用进行连接的过程。可重定位文件需要包含描述如何修改节内容的相关信息,从而使可执行文件和共享目标文件能够保存进程的程序镜像所需要的正确信息。
重定位表是进行重定位的重要依据。我们可以使用objdump工具查看目标文件的重定位表:
$ objdump -r hello.ohello.o: file format elf64-x86-64RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
0000000000000005 R_X86_64_32 .rodata
000000000000000a R_X86_64_PC32 puts-0x0000000000000004RELOCATION RECORDS FOR [.eh_frame]:
OFFSET TYPE VALUE
0000000000000020 R_X86_64_PC32 .text
重定位表是一个Elf_Rel
类型的数组结构,每一项对应一个需要进行重定位的项。 其成员含义如下表所示:
成员 | 含义 |
---|---|
r_offset | 重定位入口的偏移。 |
对于可重定位文件来说,这个值是该重定位入口所要修正的位置的第一个字节相对于节起始的偏移 | |
对于可执行文件或共享对象文件来说,这个值是该重定位入口所要修正的位置的第一个字节的虚拟地址 | |
r_info | 重定位入口的类型和符号 |
因为不同处理器的指令系统不一样,所以重定位所要修正的指令地址格式也不一样。每种处理器都有自己的一套重定位入口的类型。 | |
对于可执行文件和共享目标文件来说,它们的重定位入口是动态链接类型的。 |
重定位是目标文件链接成为可执行文件的关键。我们将在后面的进行介绍。
参考
- Executable and Linkable Format (ELF)
- 《Linux 二进制分析》
- 《深入理解计算机系统》
- 《程序员的自我修养——链接、装载与库》
| | 对于可执行文件或共享对象文件来说,这个值是该重定位入口所要修正的位置的第一个字节的虚拟地址 |
| r_info | 重定位入口的类型和符号 |
| | 因为不同处理器的指令系统不一样,所以重定位所要修正的指令地址格式也不一样。每种处理器都有自己的一套重定位入口的类型。 |
| | 对于可执行文件和共享目标文件来说,它们的重定位入口是动态链接类型的。 |
重定位是目标文件链接成为可执行文件的关键。我们将在后面的进行介绍。
参考
- Executable and Linkable Format (ELF)
- 《Linux 二进制分析》
- 《深入理解计算机系统》
- 《程序员的自我修养——链接、装载与库》
- Executable and Linkable Format
相关文章:
ELF文件结构
ELF文件结构 前文结尾说到编译器编译源代码后生成的文件叫做目标文件,而目标文件经过编译器链接之后得到的就是可执行文件。那么目标文件到底是什么?它和可执行文件又有什么区别?链接到底又做了什么呢?接下来,我们将探…...
【C++】有关string迭代器的几道OJ题详解
目录 一、字符串最后一个单词的长度 题目描述 完整代码 二、验证回文串 题目描述 完整代码 三、反转字符串 题目描述 完整代码 四、反转字符串中的单词 题目描述 完整代码 一、字符串最后一个单词的长度 原题链接 题目描述 计算字符串最后一个单词的长度ÿ…...
谷歌宣布向云计算客户开放 Gemini Pro,开发者可用其构建应用
12 月 14 日消息,美国时间周三,谷歌宣布了一系列升级的人工智能(AI)功能,旨在为其云计算客户提供更好的服务。这家科技巨头正试图赶上竞争对手,比如微软和 OpenAI,它们都在积极利用人工智能的热…...
软件测试用例经典方法 | 单元测试法案例
单元测试又称模块测试,是对软件设计的最小单元的功能、性能、接口和设计约束等的正确性进行检验,检查程序在语法、格式和逻辑上的错误,并验证程序是否符合规范,以发现单元内部可能存在的各种缺陷。 单元测试的对象是软件设计的最…...
Leetcode 2967. Minimum Cost to Make Array Equalindromic
Leetcode 2967. Minimum Cost to Make Array Equalindromic 1. 解题思路2. 代码实现 题目链接:2967. Minimum Cost to Make Array Equalindromic 1. 解题思路 这一题其实我的思路有点笨,多少有点暴力求解的意思。 显然,如果我们给出全部的…...
【数据结构】什么是堆?
🦄个人主页:修修修也 🎏所属专栏:数据结构 ⚙️操作环境:Visual Studio 2022 堆的概念及结构 堆的定义如下: n个元素的序列{k1,k2,...,kn}当且仅当满足以下关系时,称之为堆. 或 把这个序列对应的一维数组(即以一维数组作此序列的存储结构)看成是一个…...
生产环境_Spark处理轨迹中跨越本初子午线的经度列
使用spark处理数据集,解决gis轨迹点在地图上跨本初子午线的问题,这个问题很复杂,先补充一版我写的 import org.apache.spark.{SparkConf, SparkContext} import org.apache.spark.sql.{Row, SparkSession} import org.apache.spark.sql.func…...
Vue前端与后端放在一起的搭建方式
1.首先把后端项目搭建好 去到项目的存放位置 2.然后cmd黑窗口输入命令创建vue项目 3.创建成功后回到后端项目进行合并 3.1在File处选择Project Structure 3.2选择模块 3.3找到自己的vue项目 3.4疯狂next最后create 3.5选择Apply并确定OK,恭喜您创建成功了 二、启动…...
SI24R03国产自主可控RISC-V架构MCU低功耗2.4GHz收发芯片SoC
目录 RISC-V架构的优势SI24R03/04特性射频收发器模块特征MCU 模块特征 其他特征 RISC-V架构的优势 相对于目前主流的英特尔X86架构及ARM等架构来说,RISC-V架构具有指令精简、模块化、可扩展、开源、免费等优点。RISC-V的基础指令集只有40多条,加上其他基…...
基于FPGA的温度控制系统设计(论文+源码)
1.系统设计 本次基于FPGA的智能温度控制系统,以FPGA为控制核心,采用自顶向下的设计方法,按照模块化设计的思路分别实现各个模块,再加以整合实现整个系统,从而达到了温度控制的目的。系统以水箱为被控对象,…...
C语言训练:三个字符串比较大小,实现两个整数数的交换统计二进制中1的个数
目录 一、编写程序,输入三个字符串,比较它们的大小,并将它们按由小到大的顺序输出。要求用函数、指针实现。要求:要采用函数调用,并用指向函数的指针作为函数的参数。 1.不使用函数指针作为参数,并自己模拟strcmp。 …...
module ‘tensorflow‘ has no attribute XXX 报错解决
问题描述: 粘了别人的tensorflow项目,运行总是报错module ‘tensorflow’ has no attribute什么什么 问题解决: 导入tensorflow的代码如下 import tensorflow as tf此时,某个某块报错,比如下面这个 那么就直接把tf.…...
MySQL数据库 DDL
目录 一、DDL 二、操作数据库 三、操作表 四、数据类型 五、表操作案例 六、修改表 七、删除表 一、DDL Data Definition Language,数据定义语言,用来定义数据库对象(数据库,表,字段) 。 二、操作数据库 (1&am…...
力扣二叉树--总结篇(2)
前言 总体回顾:11.18-12.14,中间有一个星期左右因为考试没有写题。37道题。 内容 这是第二阶段刷的题 从路径到构造二叉树,合并二叉树,再到二叉搜索树,公共祖先问题 看到二叉树,看到递归 都会想&#…...
小米移动端页面练习---重点:导航栏点击下箭头内容的切换以及样式,高亮显示的实现
效果图 1.html <div><header><div class"header-ad"><img src"./images/ad.png" alt"" srcset""></div><div class"header-two-section"><div class"logo"><div c…...
从零开始创建一个项目,springBoot+mybatisPlus+mysql+swagger+maven
一,前提 从零开始创建一个项目,绑定了数据库 用到的技术栈:springBootmybatisPlusmysqlswaggermaven 二,创建项目步骤 1,创建项目 创建出来的项目结构如图所示 2,修改配置文件 因为我比较习惯yml语言&…...
【视点合成】代码解读:生成demo视频
变换工具 def render_3dphoto(src_imgs, # 输入的源图像,维度为 [batch_size, 3, height, width]mpi_all_src, # 输入的所有源图像的MPI,维度为 [batch_size, num_planes, 4, height, width]disparity_all_src, # 所有源图像的视差信息&…...
Process On在线绘制流程图
目录 一.ProcessOn 1.1.介绍 1.2.直接网上使用 二.绘制门诊流程图 三.绘制住院流程图 四.绘制药库采购入库流程图 五.绘制OA会议流程图 今天就到这里了哦!!!希望能帮到你哦!!! 一.ProcessOn 1.1.介绍 ProcessOn(流程&#…...
【Hadoop-OBS-Hive】利用华为云存储对象 OBS 作为两个集群的中间栈 load 文件到 Hive
【Hadoop-OBS-Hive】利用华为云存储对象 OBS 作为两个集群的中间栈 load 文件到 Hive 1)压缩文件2)上传文件到 OBS 存储对象3)crontab 定时压缩上传4)从 obs 上拉取下来文件后解压缩5)判断对应文件是否存在6࿰…...
直线检测算子
hough_lines_dir 接口 hough_lines_dir(ImageDir : HoughImage, Lines : DirectionUncertainty, AngleResolution, Smoothing, FilterSize, Threshold, AngleGap, DistGap, GenLines : Angle, Dist) 参数 in: ImageDir :由边缘检测算子sobel_dir、edge_image获取的…...
如何在本地Docker中部署MinIO服务并实现远程访问管理界面
文章目录 前言1. Docker 部署MinIO2. 本地访问MinIO3. Linux安装Cpolar4. 配置MinIO公网地址5. 远程访问MinIO管理界面6. 固定MinIO公网地址 前言 MinIO是一个开源的对象存储服务器,可以在各种环境中运行,例如本地、Docker容器、Kubernetes集群等。它兼…...
逛商场。。。
题目名字 逛商场 题意 见到想买的物品,只要能买得起,就一定会买下来之后才会继续往前走;如果买不起就直接跳过 思路 接着,它读取数组 aa 的值,并存储在数组中。然后,程序读取一个整数 m。初始化计数器 cn…...
RTrPPG
研究背景 心率 (HR) 和脉搏率变异性 (PRV) 是允许分析心脏行为的两个生理参数。心率监测可以通过接触式和非接触式的两种方法进行。通常用于测量 HR 和 PRV 的两种接触式技术是心电图 (ECG) 和光电容积脉搏波 (PPG)。 ECG 测量由心脏活动引起的电场。另一方面,PPG …...
web应用开发技术的一些概念
一、Servlet 1.Servlet的工作过程: Servelt的工作流程示意图 (1)客户端发起一个Http请求到服务器,请求特定的资源或者是要执行特定的操作 (2)服务器在接收到请求后,根据请求相应的URL将请求分发…...
智能优化算法应用:基于乌燕鸥算法3D无线传感器网络(WSN)覆盖优化 - 附代码
智能优化算法应用:基于乌燕鸥算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于乌燕鸥算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.乌燕鸥算法4.实验参数设定5.算法结果6.参考文…...
超聚变服务器(原华为服务器)网站模拟器
一、超聚变服务器(原华为服务器)网站模拟器: 原来了解服务器可以从他的网站上进行了解,模拟器做的很好了。 https://support.xfusion.com/server-simulators/ 有很多的模拟器,今天主要看下BMC的设置 有很多的在线工具…...
Linux常见压缩指令小结
为什么需要压缩技术 我们都知道文件是以byte作为单位的,如果我们的文件仅仅在低位占一个1 0000 0001这种情况我们完全可以压缩一下,将高位的0全部抹掉即可。 如上所说是一种压缩技术,还有一种就是将1111(此处省略96个)一共100个1࿰…...
OpenSSL的源码在哪里下载?
官方网站去下载,网址: https://www.openssl.org/source/ 比较老的版本的下载页面地址: https://www.openssl.org/source/old/ 由于某面板的OpenSSL模块的安装配置语句如下: --with-openssl/root/rpmbuild/BUILD/openssl-1.0.2u所…...
使用create-react-app脚手架创建react项目
文章目录 1、安装create-react-app脚手架2、创建 React 项目,项目名为 react-demo3、项目创建成功4、使用vscode打开项目并运行5、项目运行成功node_modules:存放项目所依赖的一些第三方包文件public:静态资源文件夹src:源码文件夹其它文件 1…...
【网络安全】网络防护之旅 - 点燃网络安全战场的数字签名烟火
🌈个人主页:Sarapines Programmer🔥 系列专栏:《网络安全之道 | 数字征程》⏰墨香寄清辞:千里传信如电光,密码奥妙似仙方。 挑战黑暗剑拔弩张,网络战场誓守长。 目录 😈1. 初识…...
注册公司多少钱起步/seo分析报告怎么写
在用php7进行开发的时候,遇到了:Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; index has a deprecated constructor这个提示本来很正常,看起来也很容易理解,而且…...
网站建设比较好的/千锋教育培训机构学费
flowplayer我试图找到一种方法来恢复在flowplayer中已暂停的实时流 。 我想知道为什么暂停后似乎无法恢复我的视频流。 暂停流的标准代码: $f(fms1).pause() 恢复流的标准代码: $f(fms1).resume(); 我也尝试了以下无济于事: $f(fms1).get…...
佛山网站页面优化/今日国际军事新闻头条
转:http://www.imdsx.cn/index.php/2017/11/22/click/ 最近有很多同学私聊问我,在通过Selenium做UI自动化的时候,明明能够在DOM树内看到这个元素,但是我在通过driver click、sendkey的时候,就是点击不到或无法输入字符…...
个人网站做接口可以么/网站建设公司地址在哪
【题目链接】:http://codeforces.com/contest/509/problem/E 【题意】 让你计算一个字符串的所有子串里面元音字母出现的频率的和; 【题解】 先处理出前缀和->pre[i]->前i个字母里面元音字母的个数; 设ans[i] 表示长度为i的子串出现的元音字母的个数(重复的也要算…...
个人网站建设 免费/长沙优化官网服务
看到版上有大牛们讨论过,想具体深入的了解下,请指点迷津:数字接收机中,信号在空口相互叠加后才进入接收机变频采样,频偏时偏用什么算法纠正?顺求详细的仿真或实验参考资料,链接,搜索…...
做seo营销网站/潍坊网站建设
linux下内存泄露检测工具Valgrind介绍 目前在linux开发一个分析实时路况的应用程序,在联合测试中发现程序存在内存泄露的情况。 这下着急了,马上就要上线了,还好发现了一款Valgrind工具,完美的解决了内存泄露的问题。 推荐大家可以…...