当前位置: 首页 > news >正文

GNU链接器简介

GNU链接器简介

  • 1 使用简单程序简介链接脚本
    • 1.1 测试程序
    • 1.2 编译测试程序
      • 1.2.1 不使用链接器编译
        • 1.2.1.1 不使用链接器编译
        • 1.2.1.2 读取objdump_test 的结构
      • 1.2.2 使用链接器去链接
        • 1.2.2.1 链接脚本
        • 1.2.2.2 使用链接脚本编译
        • 1.2.2.3 读取objdump 的结构
  • 2 链接脚本
    • 2.1 基本连接器脚本概念
    • 2.2 连接器脚本格式
    • 2.3 简单链接器脚本示例

该篇文章是基于对 The GNU linker的翻译,并添加了部分自己的理解。

链接器(Linker)是编译系统中的一个重要组件,它负责将一个或多个目标文件(object files)以及库文件(library files)组合成一个可执行文件或者库。在C/C++等编程语言中,当源代码被编译时,编译器会为每个源文件生成一个对应的目标文件。这些目标文件包含了机器代码和符号表信息,其中符号表包括了函数名、变量名及其地址等。

1 使用简单程序简介链接脚本

为了介绍链接器,首先使用一个最简单的测试程序去介绍链接器的功能,主要是简要介绍链接器对于可行性程序或库的入口地址的影响。

1.1 测试程序

rlk@rlk:test$ cat objdump_test.c
#include <stdio.h>void greet() {printf("Hello, World!\n");
}int main() {greet();return 0;
}
rlk@rlk:test$

1.2 编译测试程序

1.2.1 不使用链接器编译

1.2.1.1 不使用链接器编译
gcc -o objdump_test objdump_test.c
1.2.1.2 读取objdump_test 的结构
  • Entry point address: 0x1050 可执行程序objdump_test的可执行程序的入口为0x1050
  • Number of program headers: 11 表示可执行程序有11个program section
  • Number of section headers: 29 表示可执行程序有29个section
rlk@rlk:test$ readelf -hW objdump_test
ELF 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:                              DYN (Shared object file)Machine:                           Advanced Micro Devices X86-64Version:                           0x1Entry point address:               0x1050Start of program headers:          64 (bytes into file)Start of section headers:          14664 (bytes into file)Flags:                             0x0Size of this header:               64 (bytes)Size of program headers:           56 (bytes)Number of program headers:         11Size of section headers:           64 (bytes)Number of section headers:         29Section header string table index: 28
rlk@rlk:test$ 

1.2.2 使用链接器去链接

1.2.2.1 链接脚本
rlk@rlk:test$ cat link.ld
/* linker_script.ld *//* ENTRY(_start) */ /* 指定入口点 */SECTIONS
{. = 0x10000000; /* 设置起始地址 */.init_array :{__init_array_start = .;KEEP(*(SORT(.init_array.*)))KEEP(*(.init_array))__init_array_end = .;}.text : { *(.text) } /* 定义.text段的位置 */.rodata : { *(.rodata) } /* 只读数据段 */.data : { *(.data) } /* 初始化的数据段 */.bss : { *(.bss) } /* 未初始化或清零的数据段 */
}
rlk@rlk:test$
1.2.2.2 使用链接脚本编译
gcc -o objdump objdump_test.c -T link.ld
1.2.2.3 读取objdump 的结构
  • Entry point address: 0x10000010 可执行程序的入口地址为 0x10000010,改地址也和链接脚本指定的入口地址一致。
rlk@rlk:test$ readelf -hW objdump
ELF 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:                              EXEC (Executable file)Machine:                           Advanced Micro Devices X86-64Version:                           0x1Entry point address:               0x10000010Start of program headers:          64 (bytes into file)Start of section headers:          8704 (bytes into file)Flags:                             0x0Size of this header:               64 (bytes)Size of program headers:           56 (bytes)Number of program headers:         7Size of section headers:           64 (bytes)Number of section headers:         32Section header string table index: 31
rlk@rlk:test$

2 链接脚本

Every link is controlled by a linker script. This script is written in the linker command language.
每个链接都是由链接器脚本控制的。这个脚本是用链接器命令语言编写的。
The main purpose of the linker script is to describe how the sections in the input files should be mapped into the output file, and to control the memory layout of the output file. Most linker scripts do nothing more than this. However, when necessary, the linker script can also
direct the linker to perform many other operations, using the commands described below.
链接器脚本的主要目的是描述输入文件中的各个部分应如何映射到输出文件中,并控制输出文件的内存布局。大多数链接器脚本的作用仅限于此。然而,当需要时,链接器脚本还可以使用下面描述的命令指导链接器执行许多其他操作。
The linker always uses a linker script. If you do not supply one yourself, the linker will use a default script that is compiled into the linker executable. You can use the ‘–verbose’ command-line option to display the default linker script. Certain command-line options, such as ‘-r’ or ‘-N’, will affect the default linker script.
链接器总是使用链接脚本。如果你没有提供自己的脚本,链接器将使用编译进链接器可执行文件中的默认脚本。你可以使用‘–verbose’命令行选项来显示默认的链接脚本。某些命令行选项,如‘-r’或‘-N’,将会影响默认的链接脚本。
You may supply your own linker script by using the ‘-T’ command line option. When you do this, your linker script will replace the default linker script.
您可以使用‘-T’命令行选项来提供自己的链接器脚本。当您这样做时,您的链接器脚本将替换默认的链接器脚本。
You may also use linker scripts implicitly by naming them as input files to the linker, as though they were files to be linked.
您也可以通过将链接器脚本命名为链接器的输入文件来隐式使用它们,就好像它们是要被链接的文件一样。

2.1 基本连接器脚本概念

We need to define some basic concepts and vocabulary in order to describe the linker script language.
我们需要定义一些基本概念和词汇,以便描述链接器脚本语言。
The linker combines input files into a single output file. The output file and each input file are in a special data format known as an object file format. Each file is called an object file. The output file is often called an executable, but for our purposes we will also call it an object file. Each object file has, among other things, a list of sections. We sometimes refer to a section in an input file as an input section; similarly, a section in the output file is an output section.
链接器将输入文件合并成一个单独的输出文件。输出文件和每个输入文件都是以一种特殊的称为对象文件格式的数据格式存在。每个文件被称为对象文件。输出文件通常被称为可执行文件,但为了我们的目的,我们也将其称为对象文件。每个对象文件都有一个包含许多部分的列表。我们有时将输入文件中的一个部分称为输入部分;类似地,输出文件中的一个部分是输出部分。
Each section in an object file has a name and a size. Most sections also have an associated block of data, known as the section contents. A section may be marked as loadable, which means that the contents should be loaded into memory when the output file is run. A section with no contents may be allocatable, which means that an area in memory should be set aside, but nothing in particular should be loaded there (in some cases this memory must be zeroed out). A section which is neither loadable nor allocatable typically contains some sort of debugging information.
对象文件中的每个部分都有一个名称和一个大小。大多数部分还有一个相关的数据块,称为部分内容。一个部分可以被标记为可加载的,这意味着当输出文件运行时,内容应该被加载到内存中。一个没有内容的部分可能是可分配的,这意味着应该在内存中预留一个区域,但特定的东西不应该被加载在那里(在某些情况下,这块内存必须被清零)。既不可加载也不可分配的部分通常包含某种调试信息。
Every loadable or allocatable output section has two addresses. The first is the VMA, or virtual memory address. This is the address the section will have when the output file is run. The second is the LMA, or load memory address. This is the address at which the section will be loaded. In most cases the two addresses will be the same. An example of when they might be different is when a data section is loaded into ROM, and then copied into RAM when the program starts up (this technique is often used to initialize global variables in a ROM based system). In this case the ROM address would be the LMA, and the RAM address would be the VMA.
每个可加载或可分配的输出段都有两个地址。第一个是VMA,即虚拟内存地址。这是输出文件运行时该段将拥有的地址。第二个是LMA,即加载内存地址。这是该段将被加载的地址。在大多数情况下,这两个地址是相同的。当它们可能不同时的一个例子是,当一个数据段被加载到ROM中,然后在程序启动时复制到RAM中(这种技术通常用于初始化基于ROM系统的全局变量)。在这种情况下,ROM地址将是LMA,而RAM地址将是VMA。
You can see the sections in an object file by using the objdump program with the ‘-h’ option. Every object file also has a list of symbols, known as the symbol table. A symbol may be defined or undefined. Each symbol has a name, and each defined symbol has an address, among other information. If you compile a C or C++ program into an object file, you will get a defined symbol for every defined function and global or static variable. Every undefined function or global variable which is referenced in the input file will become an undefined symbol.
你可以使用带有‘-h’选项的objdump程序查看对象文件中的各个部分。每个对象文件还有一个符号列表,称为符号表。符号可能是已定义的或未定义的。每个符号都有一个名称,每个已定义的符号都有一个地址。在其他信息中,如果你将一个C或C++程序编译成一个对象文件,你将会得到每个已定义函数和全局或静态变量的定义符号。每一个在输入文件中被引用但未定义的函数或全局变量将会变成一个未定义的符号。
You can see the symbols in an object file by using the nm program, or by using the objdump program with the ‘-t’ option.
你可以使用 nm 程序查看对象文件中的符号,或者使用带有‘-t’选项的objdump程序来查看。

2.2 连接器脚本格式

Linker scripts are text files.
链接器脚本是文本文件。
You write a linker script as a series of commands. Each command is either a keyword, possibly followed by arguments, or an assignment to a symbol. You may separate commands using semicolons. Whitespace is generally ignored.
你编写链接器脚本是一系列命令的组合。每个命令要么是一个关键字,可能后面跟着参数,要么是对一个符号的赋值。你可以使用分号来分隔命令。空白字符通常会被忽略。
Strings such as file or format names can normally be entered directly. If the file name contains a character such as a comma which would otherwise serve to separate file names, you may put the file name in double quotes. There is no way to use a double quote character in a file name.
像文件名或格式名这样的字符串通常可以直接输入。如果文件名包含逗号等字符,这些字符通常用于分隔文件名,你可以将文件名放在双引号中。文件名中无法使用双引号字符。
You may include comments in linker scripts just as in C, delimited by ‘/’ and ‘/’. As in C, comments are syntactically equivalent to whitespace.
你可以在链接器脚本中像在C语言中一样包含注释,由‘/*’‘*/’界定。就像在C语言中,注释在语法上等同于空白字符。

2.3 简单链接器脚本示例

Many linker scripts are fairly simple.
许多链接器脚本相当简单。
The simplest possible linker script has just one command: ‘SECTIONS’. You use the ‘SECTIONS’ command to describe the memory layout of the output file.
最简单的链接脚本只有一个命令:“SECTIONS”。您使用“SECTIONS”命令来描述输出文件的内存布局。
The ‘SECTIONS’ command is a powerful command. Here we will describe a simple use of it. Let’s assume your program consists only of code, initialized data, and uninitialized data. These will be in the ‘.text’, ‘.data’, and ‘.bss’ sections, respectively. Let’s assume further
that these are the only sections which appear in your input files.
“SECTIONS”命令是一个强大的命令。在这里,我们将描述它的一个简单用法。假设你的程序只包含代码、初始化数据和未初始化数据。
这些将分别位于“.text”、“.data”和“.bss”段中。进一步假设这些是你输入文件中出现的唯一段。
For this example, let’s say that the code should be loaded at address 0x10000, and that the data should start at address 0x8000000. Here is a linker script which will do that:
以这个例子来说,假设代码应该加载在0x10000地址,数据应该从0x8000000地址开始。下面是一个将实现这一点的链接器脚本:

SECTIONS
{. = 0x10000;.text : { *(.text) }. = 0x8000000;.data : { *(.data) }.bss : { *(.bss) }
}

You write the ‘SECTIONS’ command as the keyword ‘SECTIONS’, followed by a series of symbol assignments and output section descriptions enclosed in curly braces.
您将‘SECTIONS’命令写为关键字‘SECTIONS’,后面跟着一系列符号赋值和输出段描述,这些都被包含在大括号中。
The first line inside the ‘SECTIONS’ command of the above example sets the value of the special symbol ‘.’, which is the location counter. If you do not specify the address of an output section in some other way (other ways are described later), the address is set from the current value of the location counter. The location counter is then incremented by the size of the output section. At the start of the ‘SECTIONS’ command, the location counter has the value ‘0’.
上述示例中‘SECTIONS’命令的第一行设置了特殊符号‘.’的值,即位置计数器。如果你没有以其他方式指定输出段的地址(稍后将描述其他方式),地址将从位置计数器的当前值设置。然后,位置计数器会根据输出段的大小进行增加。在‘SECTIONS’命令的开始时,位置计数器的值为‘0’。
The second line defines an output section, ‘.text’. The colon is required syntax which may be ignored for now. Within the curly braces after the output section name, you list the names of the input sections which should be placed into this output section. The ‘’ is a wildcard which matches any file name. The expression ‘(.text)’ means all ‘.text’ input sections in all input files.
第二行定义了一个输出部分,名为“.text”。冒号是必需的语法,目前可以忽略。在输出部分名称后面的花括号中,你列出了应该放入这个输出部分的输入部分的名称。‘’是一个通配符,可以匹配任何文件名。表达式‘(.text)’意味着所有输入文件中的所有“.text”输入部分。
Since the location counter is ‘0x10000’ when the output section ‘.text’ is defined, the linker will set the address of the ‘.text’ section in the output file to be ‘0x10000’.
由于在定义输出段“.text”时位置计数器是‘0x10000’,链接器将会在输出文件中将“.text”段的地址设置为‘0x10000’。
The remaining lines define the ‘.data’ and ‘.bss’ sections in the output file. The linker will place the ‘.data’ output section at address ‘0x8000000’. After the linker places the ‘.data’ output section, the value of the location counter will be ‘0x8000000’ plus the size of the ‘.data’ output section. The effect is that the linker will place the ‘.bss’ output section immediately after the ‘.data’ output section in memory.
剩余的行定义了输出文件中的’.data’和’.bss’部分。链接器将会把’.data’输出部分放置在地址’0x8000000’。在链接器放置了’.data’输出部分之后,位置计数器的值将会是’0x8000000’加上’.data’输出部分的大小。结果是链接器将会把’.bss’输出部分紧接在’.data’输出部分之后放置在内存中。
The linker will ensure that each output section has the required alignment, by increasing the location counter if necessary. In this example, the specified addresses for the ‘.text’ and ‘.data’ sections will probably satisfy any alignment constraints, but the linker may have to create a small gap between the ‘.data’ and ‘.bss’ sections.
链接器将确保每个输出段都满足所需的对齐要求,如有必要,通过增加位置计数器来实现。在这个例子中,指定的‘.text’和‘.data’段的地址可能已经满足了任何对齐约束,但链接器可能需要在‘.data’和‘.bss’段之间创建一个小间隙。
That’s it! That’s a simple and complete linker script.
就这样!这是一个简单且完整的链接器脚本。

相关文章:

GNU链接器简介

GNU链接器简介 1 使用简单程序简介链接脚本1.1 测试程序1.2 编译测试程序1.2.1 不使用链接器编译1.2.1.1 不使用链接器编译1.2.1.2 读取objdump_test 的结构 1.2.2 使用链接器去链接1.2.2.1 链接脚本1.2.2.2 使用链接脚本编译1.2.2.3 读取objdump 的结构 2 链接脚本2.1 基本连接…...

欧几里得算法(简单理解版,非严格证明)

欧几里得算法用于求解两个整数的最大公约数&#xff0c;又称为辗转相除 依据的基本定理&#xff1a; GCD(a,b)GCD(a%b,b) 证明&#xff1a; 对于搞理论的人可能需要会严格证明&#xff0c;但是对于我们一般人而言&#xff0c;只要能理解其原理并记住即可&#xff0c;后者实际上…...

Mac软件介绍之录屏软件Filmage Screen

软件介绍 Filmage Screen 是一款专业的视频录制和编辑软件&#xff0c;适用于 Mac 系统 可以选择4k 60fps&#xff0c;可以选择录制电脑屏幕&#xff0c;摄像头录制&#xff0c;可以选择区域录制。同时也支持&#xff0c;简单的视频剪辑。 可以同时录制电脑麦克风声音 标准…...

Ubuntu cuda-cudnn中断安装如何卸载

文章目录 问题描述解决方法使用强制移除 问题描述 Ubuntu22.04系统&#xff0c;在终端中执行apt insatll安装或dpkg .deb安装时如果强制关闭终端会导致安装失败&#xff08;安装包会变成iu状态或ru状态&#xff0c;安装成功的应该是ii状态&#xff09; 此时&#xff0c;无论是…...

CSS——7.CSS注释

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>css注释</title><link rel"stylesheet" type"text/css" href"a.css"/></head><body><!--头部开始&#xff08;h…...

鸿蒙APP之从开发到发布的一点心得

引言&#xff1a; 做鸿蒙开发大概有1年左右时间了&#xff0c;从最开始的看官方文档、看B站视频&#xff0c;到后来成功发布两款个人APP&#xff08;房贷计算极简版、时简时钟 轻喷&#xff0c;谢谢&#xff09;。简单描述一下里边遇到的坑以及一些经历吧。 学习鸿蒙开发 个…...

某小程序sign签名参数逆向分析

文章目录 1. 写在前面2. 接口分析3. 分析还原 【&#x1f3e0;作者主页】&#xff1a;吴秋霖 【&#x1f4bc;作者介绍】&#xff1a;擅长爬虫与JS加密逆向分析&#xff01;Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Python…...

智能风控/数据分析 聚合 分组 连接

data。head&#xff08;&#xff09;查看前几行 data.head() 是一个在Python的Pandas库中常用的方法&#xff0c;用于查看DataFrame对象的前几行数据。默认情况下&#xff0c;head() 方法会返回DataFrame的前5行数据&#xff0c;但是你也可以通过传递一个整数参数来指定返回的…...

Unity3D PBR光照计算公式推导详解

前言 在Unity3D中&#xff0c;PBR&#xff08;Physically Based Rendering&#xff0c;基于物理的渲染&#xff09;光照模型是一种高级光照模型&#xff0c;它模拟了真实世界中光的传播和反射过程&#xff0c;从而提供了更加逼真的渲染效果。PBR光照模型的计算公式涉及多个物理…...

行为树详解(6)——黑板模式

【动作节点数据共享】 行为树中需要的参数可以来自游戏中的各个模块&#xff0c;如果仅需从多个模块获取少量参数&#xff0c;那么可以直接在代码中调用其他模块的单例继而层层调用获取数据。 如果获取的参数量很大&#xff0c;从架构上看&#xff0c;我们需要通过加一个中间…...

Vue.js与其他框架有哪些兼容性?

Vue.js的兼容性主要体现在几个方面&#xff0c;包括浏览器支持、运行环境适应性、与其他库和框架的集成能力等。以下是更详细的解释&#xff1a; 浏览器兼容性 现代浏览器&#xff1a;Vue.js广泛支持所有主流的现代浏览器&#xff0c;如Google Chrome, Firefox, Safari, Edge…...

Java 8 Stream 介绍

Java 8 Stream 介绍 1. 什么是Stream&#xff1f; Stream&#xff08;流&#xff09;是Java 8引入的全新概念&#xff0c;它是一个支持串行和并行聚合操作的元素序列。Stream API提供了一种声明式的方式来处理数据集合&#xff0c;可以让我们以一种类似SQL查询的方式处理数据…...

Java NIO、AIO分析

好的&#xff0c;下面将对Java中的**NIO&#xff08;Non-blocking IO&#xff09;和AIO&#xff08;Asynchronous IO&#xff09;**进行更深入的分析&#xff0c;重点探讨它们的特点和具体的应用场景。 一、Java NIO&#xff08;Non-blocking IO&#xff09;深入分析 1. 主要…...

pip下载包出现SSLError

报错&#xff1a; ERROR: Could not install packages due to an OSError: HTTPSConnectionPool(host‘files.pythonhosted.org’, port443): Max retries exceeded with url: /packages/8a/c2/ae7227e4b089c6a8210920db9d5ac59186b0a84eb1e6d96b9218916cdaf1/taming_transform…...

零成本的互联网创业创意有哪些?

在互联网时代&#xff0c;创业的门槛大大降低&#xff0c;即使没有大量的资金投入&#xff0c;也有许多机会可以实现创业梦想。以下将为您介绍一些零成本的互联网创业创意&#xff0c;帮助您在互联网的海洋中找到属于自己的宝藏。 一、内容创作与自媒体 &#xff08;一&#…...

linux ubantu重启桌面

在 Ubuntu 系统中&#xff0c;重启桌面环境通常有几种方法&#xff0c;具体取决于你所使用的桌面环境&#xff08;如 GNOME、KDE 等&#xff09;。下面是几种常用的重启桌面的方法&#xff1a; 重启 GNOME 桌面环境 如果你使用的是 GNOME 桌面环境&#xff08;Ubuntu 默认桌面…...

DeepSeek重新定义“Open“AI

“面对颠覆性技术&#xff0c;闭源所创造的护城河是暂时的。即使是OpenAI的闭源方法也无法阻止他人赶超。” ——梁文锋&#xff0c;DeepSeek CEO DeepSeek V3 是一个拥有6710亿参数的开源AI模型&#xff0c;正在提升AI效率的新标准。它在相对有限的预算下进行训练&#xff0c…...

iOS - 自旋锁

在 Objective-C 运行时中大量使用自旋锁&#xff0c;主要有以下几个原因&#xff1a; 1. 性能考虑 上下文切换成本 // 自旋锁实现 static ALWAYS_INLINE void OSSpinLockLock(volatile OSSpinLock *lock) {do {while (lock->value ! 0) {__asm__ volatile ("pause&q…...

web应用网站如何启用http2请求

要启用 HTTP/2 协议&#xff0c;您需要确保您的 Web 服务器软件支持 HTTP/2&#xff0c;并进行相应的配置。以下是一些常见的 Web 服务器软件及其启用 HTTP/2 的方法&#xff1a; 1. Nginx 对于 Nginx&#xff0c;您需要确保使用的是 1.9.5 或更高版本&#xff0c;因为这些版本…...

python进阶06:MySQL

课后大总结 Day1 一、数据库命令总结 1.连接数据库 连接数据库进入mysql安装目录打开bin文件夹&#xff0c;输入cmd(此命令后无分号)mysql.exe -u root -ppassword命令后输入密码:root 设置密码set passwordpassword("root123"); 查看所有数据库show databases; …...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...