JAR 文件规范详解

介绍

JAR文件是基于ZIP文件格式的一种文件格式,用来将许多文件整合成一个文件。一个JAR文件本质上是包含可选目录META-INF的zip文件,可以通过命令行jar工具或者在Java平台上使用java.util.jar中的API来创建。JAR文件的命名没有严格的要求,可以是特定平台上的任意合法文件名称。

在很多场景中,JAR文件不仅仅用来对java class文件和资源文件进行归档,还被用来作应用程序及其扩展的构建块。如果包含META-INF目录,则是用来存储包信息和扩展配置数据,配置数据包括安全信息,版本控制信息,扩展信息和服务信息等。

META-INF目录

在Java 2平台会识别和解释META-INF目录下面的文件和目录,以配置应用程序、扩展、类加载器和服务。

MANIFEST.MF是用来定义扩展和包相关数据的清单文件。

INDEX.LIST通过jar工具的-i选项来生成,它包含应用程序及其扩展程序中的包的位置信息,同时它是JarIndex实现的一部分,类加载器使用它来提高类的加载速度。

**x.SF **是JAR文件的签名文件,x表示基本文件名称。

**x.DSA **是于x.SF关联的签名块文件,它们有相同的基本文件名。此文件存储相应签名文件的数字签名。

services/ 该目录存储所有服务提供程序配置文件。

名称-值对和节

在我们深入每个配置文件的细节之前,需要定义一些格式约定。

在大部分场景中,包含在清单文件和签名文件中的信息表示为受RFC822标准启发的所谓的“名称:值”对。“名称:值”对也被称为头和属性。名称-值对组称为“节”,每一“节”通过空行分离。

任何形式的二进制数据都表示为base64。行的长度超过72字节的二进制数据需要延续。摘要和签名就是二进制数据的例子。

实现应该最多支持65535字节的头值。

本文档中的所有规范使用相同的语法,其中终端符号以固定宽度字体显示,非终端符号以斜体字体显示。

  1. section: *header +newline

  2. nonempty-section: +header +newline

  3. newline: CR LF | LF | CR (not followed by LF)

  4. header: name : value

  5. name: alphanum *headerchar

  6. value: SPACE *otherchar newline *continuation

  7. continuation: SPACE *otherchar newline

  8. alphanum: {A-Z} | {a-z} | {0-9}

  9. headerchar: alphanum | - | _

  10. otherchar: any UTF-8 character except NUL, CR and LF

  11. ;Also: To prevent mangling of files sent via straight e-mail, no

  12. ;header will start with the four letters "From".

JAR Manifest

01

概述

JAR文件的清单由主节和拥有多个私有JAR文件条目的单独节列表,每行通过换行符分隔。主节和单独节都遵循上面指定的节语法。它们都有自己特定的限制和规则。

主节包括包括JAR文件自身的安全和配置信息,以及此JAR文件所属应用程序及扩展。清单文件同样定义了每个单独清单条目的主属性。每节中没有属性可以使用“Name”作为名称。每一节通过空行结束。

单独节定义了JAR文件中包和文件的各种属性。不是所有在JAR文件中的文件都需要被作为条目列在清单中,但是所有被签名的文件必须被列出。清单文件自身不需要被列出。每节必须以名称“Name”的属性作为开始,并且值必须是该文件的的相对路径或者是应用存档外部数据的绝对URL。

如果相同条目有多个单独节,则这些单独节中的属性会被合并。如果不同节中的相同属性有不同的值,则识别最后一个。

不理解的属性会被忽略。这些属性可能包含应用程序使用的实现特定信息。

02

清单文件规范

  1. manifest-file: main-section newline *individual-section

  2. main-section: version-info newline *main-attribute

  3. version-info: Manifest-Version : version-number

  4. version-number : digit+{.digit+}*

  5. main-attribute: (any legitimate main attribute) newline

  6. individual-section: Name : value newline *perentry-attribute

  7. perentry-attribute: (any legitimate perentry attribute) newline

  8. newline : CR LF | LF | CR (not followed by LF)

  9. digit: {0-9}

03

主属性

主属性是清单中出现在主节中的属性。他们可以分为以下几类:

  1. Manifest-Version: 定义清单版本。如上面规范所述,值是何方的版本号

  2. Create-By: 定义生成此清单文件的java实现版本和供应商。该属性由jar工具生成。

  3. Signature-Version: 定义jar文件的签名版本。该值应该是一个有效的版本号字符串。

  4. Class-Path: 此属性的值指定此应用程序或扩展所需的扩展名或依赖库的相对url。url由一个或多个空格分隔。应用程序或扩展类加载器使用此属性的值来构造其内部搜索路径。参见Class-Path属性。

  5. Main-class:此属性的值是启动程序在启动时加载的主应用程序类的类名。该值不能将.class扩展追加到类名。

  6. Extension-List: 此属性指示applet需要的扩展。此属性中列出的每个扩展都有一组附加属性,applet使用这些属性来指定需要的扩展的版本和供应商。

  7. <extension>-Extension-Name: 此属性是扩展的唯一名称。Java插件将此属性的值与已安装扩展清单中的extension - name属性进行比较,以确定是否安装了该扩展。

  8. <extension>-Specification-Version: 该属性指定了applet所需的最小扩展规范版本。Java插件将比较此属性的值与已安装扩展的Specification-Version属性,以确定该扩展是否是最新的。

  9. <extension>-Implementation-Version: 这个属性指定了applet所需要的最小扩展实现版本号。Java插件将比较此属性的值与已安装扩展的实现版本属性,以查看是否需要下载更近期的实现。

  10. <extension>-Implementation-Vendor-Id: 如果applet需要来自特定厂商的实现,则此属性可用于标识扩展实现的厂商。Java插件将此属性的值与已安装扩展的Implementation-Vendor-Id属性进行比较。

  11. <extension>-Implementation-URL: 此属性指定一个URL,如果尚未安装所需的扩展版本,则可以使用该URL获取扩展的最新版本。

Extension-Name: 此属性指定Jar文件中包含的扩展名的名称。名称应该是唯一的标识符,如包含扩展的主包的名称。

 
  1. Implementation-Title: 值是定义扩展实现标题的字符串。

  2. Implementation-Version: 值是定义扩展实现版本的字符串。

  3. Implementation-Vendor: 值定义维护扩展实现的供应商。

  4. Implementation-Vendor-Id: 值是一个字符串id,惟一地定义了维护扩展实现的供应商。这个属性可能在将来的版本中被忽略。

  5. Implementation-URL: 此属性定义可从其中下载扩展实现的URL。这个属性可能在将来的版本中被忽略。

  6. Specification-Title: 值是定义扩展规范标题的字符串。

  7. Specification-Version: 值是定义扩展规范版本的字符串。

  8. Specification-Vendor: 值是一个字符串,它定义维护扩展规范的供应商。

  9. Sealed: 这个属性定义了这个JAR文件是否是密封的。值可以是“true”或“false”,大小写被忽略。如果它被设置为“true”,那么JAR文件中的所有包默认都是密封的,除非它们分别被定义。

04

每个条目的属性

 
  1. Manifest-Version: 1.0

  2. Created-By: 1.2 (Sun Microsystems Inc.)

  3. Sealed: true

  4. Name: foo/bar/

  5. Sealed: false

每个条目的属性分为以下几组:

① 定义文件内容的属性

Content-Type:此属性可用于指定JAR文件中特定文件条目的MIME类型和数据子类型。值应该是type/subtype形式的字符串。

例如,“image/bmp”是一个带有bmp(表示位图)子类型的图像类型。这将把文件条目指示为图像,并将数据存储为位图。RFC 1521和1522讨论并定义MIME类型。

② 定义版本和封装信息的属性

这些属性与上面定义的用于定义扩展包版本控制和封装信息的主属性相同。当作为每个条目属性使用时,这些属性将覆盖主属性,但仅应用于清单条目指定的单个文件。

③ 定义bean对象的属性

Java-Bean: 定义特定的jar文件条目是否是Java bean对象。值应该是“true”或“false”,大小写被忽略。

④ 定义签名的属性

这些属性用于签名和验证目的。更多细节在这里。

**x-Digest-y:**此属性的名称指定用于计算对应jar文件条目的摘要值的摘要算法的名称。此属性的值存储实际的摘要值。前缀'x'指定算法名称,可选后缀'y'表示应该根据哪种语言验证摘要值。

**Magic: **这是一个可选属性,应用程序可以使用它来指示verifier应该如何计算清单项中包含的摘要值。这个属性的值是一组逗号分隔的上下文特定字符串。

签名的JAR文件

01

概述

markdown

META-INF/MANIFEST.MF META-INF/*.SF META-INF/*.DSA META-INF/*.RSA META-INF/SIG-*

可以使用java.security API对JAR文件的子集进行签名。签名JAR文件与原始JAR文件完全相同,除了它的清单被更新和两个附加文件被添加到META-INF目录:一个签名文件和一个签名块文件。如果不使用jarsigner,签名程序必须同时构造签名文件和签名块文件。

对于签名JAR文件中的每个文件条目,会在清单文件中为它创建一个单独的清单条目。每个清单条目列出一个或多个摘要属性和一个可选的Magic属性。

02

签名文件

  1. x-Digest-Manifest-Main-Attributes: 其中x是java.security.MessageDigest算法的标准名称,此属性的值是清单文件的主属性的摘要值。

  2. x-Digest-Manifest : 其中x是java.security.MessageDigest算法的标准名称,此属性的值是整个清单的摘要值。

2.1

签名验证

如果签名是有效的,并且在签名生成之后,JAR文件中的任何文件都没有被更改,那么就会发生成功的JAR文件验证。JAR文件验证包括以下步骤:

① 在第一次解析清单时,验证在签名文件上的签名。为了提高效率,这种验证应该被记忆。注意,此验证仅验证签名说明本身,而不是实际的归档文件。

② 如果签名文件中存在x-Digest-Manifest属性,则根据根据整个清单计算的摘要验证该值。如果签名文件中存在多个x-Digest-Manifest属性,验证其中至少有一个与计算的摘要值匹配。

③ 如果签名文件中不存在x-Digest-Manifest属性,或者在前面的步骤中计算的摘要值都不匹配,那么将执行优化较少的验证:

Ⅰ.如果签名文件中存在x-Digest-Manifest-Main-Attributes条目,则根据根据清单文件中的主要属性计算的摘要验证该值。如果计算失败,则JAR文件验证失败。这项决定可以因其效率而被记忆。如果签名文件中不存在x-Digest-Manifest-Main-Attributes条目,那么它的不存在不会影响JAR文件验证,并且清单的主属性也不会被验证。

Ⅱ.根据根据清单文件中相应条目计算的摘要值,验证签名文件中每个源文件信息部分中的摘要值。如果任何摘要值不匹配,则JAR文件验证失败。

④ 对于清单中的每个条目,根据根据在“Name:”属性中引用的实际数据计算的摘要验证清单文件中的摘要值,该属性指定一个相对文件路径或URL。如果任何摘要值不匹配,则JAR文件验证失败。

 
  1. Manifest-Version: 1.0

  2. Created-By: 1.7.0 (Sun Microsystems Inc.)

  3. Name: common/class1.class

  4. SHA-256-Digest: (base64 representation of SHA-256 digest)

  5. Name: common/class2.class

  6. SHA1-Digest: (base64 representation of SHA1 digest)

  7. SHA-256-Digest: (base64 representation of SHA-256 digest)

  8. Signature-Version: 1.0

  9. SHA-256-Digest-Manifest: (base64 representation of SHA-256 digest)

  10. SHA-256-Digest-Manifest-Main-Attributes: (base64 representation of SHA-256 digest)

  11. Name: common/class1.class

  12. SHA-256-Digest: (base64 representation of SHA-256 digest)

  13. Name: common/class2.class

  14. SHA-256-Digest: (base64 representation of SHA-256 digest)

Magic属性

验证给定清单条目上签名的另一个要求是验证者理解该条目的清单条目中Magic键对值的值。Magic属性是可选的,但如果解析器正在验证条目的签名,则必须理解该条目的Magic key的值。

Magic属性的值是一组逗号分隔的特定于上下文的字符串。逗号之前和之后的空格将被忽略。大小写被忽略,magic属性的确切含义是依赖于具体的应用程序。这些值指示如何计算清单条目中包含的散列值,因此对于签名的正确验证至关重要。关键字可以用于动态或嵌入式内容,可以用于多语言文档的多个散列,等等。

  1. Name: http://www.example-scripts.com/index#script1

  2. SHA-256-Digest: (base64 representation of SHA-256 hash)

  3. Magic: JavaScript, Dynamic

  4. Name: http://www.example-tourist.com/guide.html

  5. SHA-256-Digest: (base64 representation of SHA-256 hash)

  6. SHA-256-Digest-French: (base64 representation of SHA-256 hash)

  7. SHA-256-Digest-German: (base64 representation of SHA-256 hash)

  8. Magic: Multilingual

在第一个示例中,这些Magic的值可能表明http查询的结果是嵌入到文档的脚本中(而不是文档本身),而且脚本是动态生成的。这两个信息说明了如何计算哈希值来比较清单的摘要值,从而比较有效签名。

03

数字签名

数字签名是. sf签名文件的已签名版本。这些是二进制文件,人类无法解释。

.RSA (PKCS7 signature, SHA-256 + RSA) .DSA (PKCS7 signature, DSA)

包括上面没有列出的签名算法的数字签名文件必须在META-INF目录和前缀“SIG-”。相应的签名文件(.sf文件)也必须具有相同的前缀。

对于那些不支持外部签名数据的格式,该文件应由. sf文件的签名副本组成。因此,有些数据可能是重复的,验证者应该比较两个文件。

支持外部数据的格式要么引用. sf文件,要么使用隐式引用对其执行计算。

每个. sf文件可以有多个数字签名,但是这些签名应该由同一法律实体生成。

文件扩展名可以是1到3个字母数字字符。未识别的扩展将被忽略。

Manifest和签名文件的说明

① 解析前:如果文件的最后一个字符是EOF字符(代码26),则EOF被视为空格。附加了两个新行(一个用于编辑器,编辑器不会在最后一行的末尾放一个新行,另一个用于语法不必对最后一个条目进行特殊处理,因为它后面可能没有空行)。

② 属性:在所有情况下,对于所有部分,不理解的属性将被忽略;属性名称不区分大小写,然而,生成清单和签名文件的程序应该使用本规范中所示的情况;属性名不能在节中重复。

③ 版本:Manifest-Version和Signature-Version必须是第一个,除此之外,主节中属性的顺序并不重要。

④ 顺序:单个清单条目的顺序不重要;单个签名条目的顺序并不重要,除非被签名的摘要按此顺序。

⑤ 行长度:以utf8编码的形式,行长度不能超过72字节(不是字符)。如果一个值使初始行比这个长,那么它应该在额外的行上继续(每个行以一个空格开始)。

⑥ 错误:如果不能根据此规范解析文件,则应该输出一个警告,并且所有签名都不可信。

⑦ 限制:因为头名称不能换行,头名称的最大长度是70字节(名称后面必须有冒号和空格);NUL、CR和LF不能嵌入header值中,NUL、CR、LF和":"不能嵌入header名称中;实现应该支持65535字节(不是字符)的头值,以及每个文件65535个头,它们可能会耗尽内存,但不应该在这些值以下硬编码限制。

⑧ 签名者:不同的实体可以使用不同的签名算法来共享单个签名文件,这在技术上是可能的。但是这违反了标准,额外的签名可能会被忽略。

⑨ 算法:本标准不强制或限制摘要或签名算法;必须支持至少一种摘要算法;如果摘要算法、签名算法或密钥大小受到jdk.jar.disabledAlgorithms安全属性的限制,JAR将被视为未签名的。注意,jdk.jar.disabledAlgorithms安全属性被JDK引用实现,它不能保证被其他实现检查和使用。

JAR索引

01

概述

从1.3开始,引入JarIndex来优化网络应用程序,特别是applet的类加载器的类搜索过程。最初,applet类加载器使用一个简单的线性搜索算法来搜索其内部搜索路径上的每个元素,内部搜索路径是由“ARCHIVE”标签或“class - path”主属性构造的。类加载器加载并在其搜索路径中打开每个元素,直到找到类或资源为止。如果类加载器试图找到一个不存在的资源,那么必须下载应用程序或applet中的所有jar文件。对于大型网络应用程序和applet,这可能导致启动缓慢、响应迟缓和浪费网络带宽。JarIndex机制收集applet中定义的所有jar文件的内容,并将信息存储在索引文件中,该索引文件位于applet类路径的第一个jar文件中。加载第一个jar文件后,applet类加载器将使用收集到的内容信息来高效地加载jar文件。

现有的jar工具被增强,使其能够检查jar文件列表并生成关于哪些类和资源驻留在哪些jar文件中的目录信息。这个目录信息存储在根jar文件的META-INF目录中的一个名为INDEX.LIST的简单文本文件中。当类加载器加载根jar文件时,它读取INDEX.LIST文件,并使用它构造哈希表,哈希表是从文件和包名称到jar文件名列表的映射。为了找到类或资源,类装入器查询散列表以查找适当的jar文件,然后在必要时加载它。

02

索引文件规范

INDEX.LIST文件包含一个或多个节,每节由一个空行分隔。每节定义一个特定jar文件的内容,头文件定义jar文件路径名,后面是一个包或文件名列表,每行一个。所有jar文件路径都相对于根jar文件的代码基。这些路径名的解析方式与当前扩展机制对绑定扩展的解析方式相同。

UTF-8编码用于支持索引文件中的文件或包名称中的非ASCII字符。

 
  1. index file : version-info blankline section*

  2. version-info : JarIndex-Version: version-number

  3. version-number : digit+{.digit+}*

  4. section : body blankline

  5. body : header name*

  6. header : char+.jar newline

  7. name : char+ newline

  8. char : any valid Unicode character except NULL, CR andLF

  9. blankline: newline newline

  10. newline : CR LF | LF | CR (not followed by LF)

  11. digit: {0-9}

03

向后兼容

新的类加载方案完全向后兼容在当前扩展机制之上开发的应用程序。当类加载器加载第一个jar文件,并在META-INF目录中找到INDEX.LIST文件,它将构造索引哈希表并为扩展使用新的加载方案,否则,类加载器将只使用原始的线性搜索算法。

服务提供者

01

概述

服务由抽象类表示。给定服务的提供程序包含一个或多个具体类,这些类使用数据和具体的代码逻辑扩展此服务类。这个provider类通常不是整个provider本身,而是一个代理,它包含足够的信息来决定provider是否能够满足特定的请求,以及可以根据需要创建实际provider的代码。提供者类的细节往往是高度订制服务的;没有一个类或接口可以统一它们,因此没有定义这样的类。这里强制执行的唯一要求是,提供程序类必须有一个零参数的构造函数,以便在查找期间可以实例化它们。

02

提供者配置文件

服务提供者通过在资源目录META-INF/services中放置一个提供者配置文件来标识自己。文件的名称应该由抽象服务类的完全限定名组成。该文件应该包含一个以换行符分隔的惟一具体提供程序类名称列表。空格和制表符以及空白行都将被忽略。注释字符是'#' (0x23);在每行中,第一个注释字符之后的所有字符都将被忽略。该文件必须用UTF-8编码。

03

例子

 
  1. public abstract CharEncoder getEncoder(String encodingName);

  2. public abstract CharDecoder getDecoder(String encodingName);

每个方法都返回一个适当的对象,如果它不能转换给定的编码,则返回null。典型的CharCodec提供程序将支持多种编码。如果sun.io.StandardCodec是CharCodec服务的提供者,那么它的jar文件将包含文件META-INF/services/java.io.spi.CharCodec。该文件将包含一行:

sun.io.StandardCodec # Standard codecs for the platform

 
  1. CharEncoder getEncoder(String encodingName) {

  2. Iterator ps = Service.providers(CharCodec.class);

  3. while (ps.hasNext()) {

  4. CharCodec cc = (CharCodec)ps.next();

  5. CharEncoder ce = cc.getEncoder(encodingName);

  6. if (ce != null)

  7. return ce;

  8. }

  9. return null;

  10. }

Class-Path属性

应用程序的清单可以指定一个或多个相对url,引用它需要的其他库的JAR文件和目录。这些相对url被当作相对于加载应用程序的代码基进行处理。

Class-Path: servlet.jar infobus.jar acme/beans.jar images/

每个相对URL都根据加载包含应用程序或库的代码库解析。如果结果URL无效或引用了无法找到的资源,则将忽略它。

生成的URL用于扩展应用程序、applet或servlet的类路径,方法是在类路径中紧跟着包含JAR文件的URL插入URL。省略任何重复的url。例如,给定以下类路径:

a.jar b.jar

假设b.jar包含以下类路径清单属性:

Class-Path: x.jar a.jar

结果是应用程序类路径如下:

a.jar b.jar x.jar

如果x.jar有自己的依赖项,那么将根据后续每个URL的相同规则添加这些依赖项。在实际的实现中,JAR文件依赖项被延迟处理,因此JAR文件直到需要时才打开。

包封装

Name: javax/servlet/internal/ Sealed: true

这指定了javax.servlet.internal包是密封的,并且包中的所有类都必须从同一个JAR文件加载。

Sealed: true

这指定此归档中的所有包都是密封的,除非为清单项中具有sealed属性的特定包显式重写。

如果缺少这个属性,为了向后兼容,假设JAR文件不是密封的。然后,系统默认检查包头的密封信息。

包密封对于安全性也很重要,因为它将对受包保护的成员的访问限制为仅对来自同一JAR文件的包中定义的类的访问。

未命名的包是不可密封的,因此要密封的类必须放在它们自己的包中。

 

总结:

感谢每一个认真阅读我文章的人!!!

作为一位过来人也是希望大家少走一些弯路,如果你不想再体验一次学习时找不到资料,没人解答问题,坚持几天便放弃的感受的话,在这里我给大家分享一些自动化测试的学习资源,希望能给你前进的路上带来帮助。

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

 

          视频文档获取方式:
这份文档和视频资料,对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!以上均可以分享,点下方小卡片即可自行领取。

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

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

相关文章

免费采集伪原创工具,采集伪原创软件

在内容创作领域,为了提高生产效率和节省时间,许多站长和网络写手会借助采集伪原创工具来生成大量文章。这些工具能够从网络上抓取内容,并通过一定的处理和修改,生成看起来与原始内容不同但意义相近的伪原创文章。以下将就采集伪原…

leetcode:392. 判断子序列

题目: class Solution { public:bool isSubsequence(string s, string t) {} }; 题解: 很巧妙的题解:循环遍历两个字符串,两个字符串都没遍完就继续遍历,字符串s先遍历完结果为true,字符串t先遍历完结果为…

Elasticsearch 向量搜索

目标记录 ["你好,我的爱人","你好,我的爱妻","你好,我的病人","世界真美丽"] 搜索词 爱人 预期返回 ["你好,我的爱人","你好,我的爱妻"] 示例代码…

故障排查指南:通过连接电脑查找iOS应用崩溃日志的有效技巧

在iOS应用开发过程中,调试日志和奔溃日志是开发者必不可少的工具。当iOS手机崩溃时,我们可以连接电脑并使用Xcode Console等工具来查看日志。然而,这种方式可能不够方便,并且处理奔溃日志也相当繁琐。克魔助手的出现为开发者带来了…

基于springboot实现图书个性化推荐系统项目【项目源码+论文说明】

基于springboot实现图书个性化推荐系统演示 摘要 本论文主要论述了如何使用JAVA语言开发一个图书个性化推荐系统,本系统将严格按照软件开发流程进行各个阶段的工作,采用B/S架构,面向对象编程思想进行项目开发。在引言中,作者将论…

Nodejs 16与 gitbook搭建属于你自己的书本网站-第一篇

最近想重新搭建一个网站来存放自己的相关知识点,并向网络公开,有个hexo博客其实也不错的,但是总感觉hexo很多花里胡哨的玩意,导致挂载的博客异常卡,这样反而不利于我自己回顾博客了,于是我就开始钻研这个鬼…

computed计算属性、watch侦听器、生命周期

计算属性 点击查看 Vue文档 基础语法 多次使用计算属性,计算属性方法也只执行一次, 调用计算属性的方法不能加() 直接修改计算数学的值 计算属性不能通过双向绑定修改(默认不能改) 想要修改计算属性,就必须使用计…

LeetCode 206.反转链表

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例 1: 输入:head [1,2,3,4,5] 输出:[5,4,3,2,1] 示例 2: 输入:head [1,2] 输出:[2,1] 示例 3: …

webpack项目打包console git分支、打包时间等信息 exec

相关链接 MDN toLocaleString child_process Node.js strftime 格式 代码 buildinfo.js const { execSync, exec } require("child_process"); // exec: 在 Windows 执行 bat 和 cmd 脚本// execSync 同步 // exec 异步// exec 使用方法 // exec(git show -s,…

SMBV100A罗德与施瓦茨SMBV100A信号源

181/2461/8938产品概述: 罗德与施瓦茨 SMBV100A 提供卓越的射频性能以及非常高的输出电平和较短的设置时间。同时,SMBV100A可配备内部基带发生器,以生成多种数字标准(例如LTE、LTE-Advanced、IEEE802.11ac、GNSS)。9 …

【C++杂货铺】内管管理

目录 🌈前言🌈 📁 C/C中内存分布 📁 new 和 delete的使用 📁 new 和 delete的优点 📁 new 和 delete的原理 📂 operator new 和 operator delete函数 📂 内置类型 &#x1f4c2…

Java中读取html文件转成String,展示在浏览器

这里写目录标题 第一章1.1&#xff09;pom中引入依赖和html文件示例1.2&#xff09;使用hutool工具包读取html文件转为string1.3&#xff09;页面显示 第一章 1.1&#xff09;pom中引入依赖和html文件示例 引入hutool工具包依赖 <dependency><groupId>cn.hutool&…

【C++程序员的自我修炼】基础语法篇(一)

心中若有桃花源 何处不是水云间 目录 命名空间 &#x1f49e;命名空间的定义 &#x1f49e; 命名空间的使用 输入输出流 缺省参数 函数的引用 引用的定义&#x1f49e; 引用的表示&#x1f49e; 引用的特性&#x1f49e; 常量引用&#x1f49e; 引用的使用场景 做参数 做返回值…

Docker进阶:Docker Swarm(集群搭建) —实现容器编排的利器

Docker进阶&#xff1a;Docker Swarm&#xff08;集群搭建&#xff09; —实现容器编排的利器 1、什么是Docker Swarm&#xff1f;2、Docker Swarm 与 Docker Compose的区别3、创建一个Swarm集群&#xff08;1-Manager&#xff0c;2-Worker&#xff09;1、资源准备2、初始化Swa…

使用Windows编辑工具直接编辑Linux上的代码

windows直接编辑Linux上代码 步骤如下&#xff1a; 1、按照samba 2、vim /etc/samba/smb.conf 3、输入以下内容 4 、重启下samba 输入以下内容 pkill smbd smbd 查看采用 ps -ef|grep smbd 给予文件权限&#xff1a; chmod 777 /code 5、winr 修改全选才能进入并且编写。…

快速上手Spring Cloud 六:容器化与微服务化

快速上手Spring Cloud 一&#xff1a;Spring Cloud 简介 快速上手Spring Cloud 二&#xff1a;核心组件解析 快速上手Spring Cloud 三&#xff1a;API网关深入探索与实战应用 快速上手Spring Cloud 四&#xff1a;微服务治理与安全 快速上手Spring Cloud 五&#xff1a;Spring …

vue3+ts白屏问题解决

文章目录 打开白屏解决方法可能出现问题使用base导致的使用baseUrl导致的 注意点vue3ts白屏问题知识分享 打开白屏 解决方法 在vue.config.js页面 添加publicPath:./, const { defineConfig } require(vue/cli-service)module.exports defineConfig({ transpileDependenci…

AcWing 4609:火柴棍数字 ← 贪心算法

【题目来源】 https://www.acwing.com/problem/content/4612/【题目描述】 给定 n 个火柴棍&#xff0c;你可以用它们摆出数字 0∼9。 摆出每个数字所需要的具体火柴棍数量如下图所示&#xff1a; 请你用这些火柴棍摆成若干个数字&#xff0c;并把这些数字排成一排组成一个整数…

Git版本管理使用手册 - 8 - 合并分支、解决冲突

合并整个开发分支 切换到本地test分支&#xff0c;选择右下角远程开发分支&#xff0c;选择Merge into Current。然后提交到远程test仓库。 合并某次提交的代码 当前工作区切换成test分支&#xff0c;选择远程仓库中的dev开发分支&#xff0c;选择需要合并的提交版本右击&a…

SQL Server 实验二:数据库视图的创建和使用

目录 第一关 相关知识 什么是表 操作数据表 创建数据表 插入数据 修改表结构 删除数据表 编程要求 第一关实验代码&#xff1a; 第二关 相关知识 视图是什么 视图的优缺点 视图的优点 视图的缺点 操作视图 创建视图 通过视图向基本表中插入数据 通过视图修改基本表的…