模板语言-Handlebars

news2025/1/12 19:07:48

Handlebars 是什么

Handlebars 是一种简单的模板语言。

它使用模板与传入的对象来生成HTML 或者其他文本格式。

Handlebars 模板看起来像是嵌入了handlebars 表达式的普通文本。

<p> {{firstname}} {{lastname}}</p>
一个handlebars表达式是使用两对尖括号包裹一些内容:{{some contet}}。当模板被执行时,表达式中的内容将被来自输入的对象中的值所替换。

引入

要使用Handlebars,首先download handlebars.js,然后再页面引入

<script src="script/lib/jquery.js"></script>
<script src="script/lib/handlebars.js"></script>

有时,输入对象包含其他对象或数组。例如:

在这种情况下,你可以使用点符号来访问嵌套属性:

template

{{person.firstname}} {{person.lastname}}

一些内置的助手代码允许你将当前上下文更改为嵌套对象。然后,你就可以像访问根对象一样访问该对象了。

#计算上下文

内置的块助手代码 eachwith 允许你更改当前代码块的值。

with 助手代码注入到对象的属性中,使你可以访问其属性。

template

{{#with person}}
{{firstname}} {{lastname}}
{{/with}}

input

​
{
  person: {
    firstname: "Yehuda",
    lastname: "Katz",
  },
}

​

each 助手代码会迭代一个数组,使你可以通过 Handlebars 简单访问每个对象的属性表达式。

template

<ul class="people_list">
  {{#each people}}
    <li>{{this}}</li>
  {{/each}}
</ul>
input
 {  people: [   
 "Yehuda Katz",  
  "Alan Johnson",  
  "Charles Jolley", 
 ],}

#模板注释

你可以像在其他语言的代码中一样在 Handlebars 代码中使用注释。由于 Handlebars 代码中通常存在一定程度的逻辑,因此这是一个好 习惯。

注释将不会出现在结果输出中。如果你想显示注释。只需使用 html 注释。它们将被输出。

任何包含 }} 或其他 Handlebars 标记的注释都应该使用 {{!--}} 语法。

template

{{! This comment will not show up in the output}}
<!-- This comment will show up as HTML-comment -->
{{!-- This comment may contain mustaches like }} --}}

#自定义助手

通过调用 Handlebars.registerHelper 方法,你可以从模板中的任何上下文中访问 Handlebars 助手代码。

template

{{firstname}} {{loud lastname}}

preparationScript

Handlebars.registerHelper('loud', function (aString) {
    return aString.toUpperCase()
})

助手代码将当前上下文作为函数的 this 指针接收。

template

{{#each people}}
   {{print_person}}
{{/each}}

preparationScript

Handlebars.registerHelper('print_person', function () {
    return this.firstname + ' ' + this.lastname
})

块助手代码

代码块表达式使你可以自定义这样的助手代码:这个助手代码可以使用与当前上下文不同的上下文来调用模板。这些块助手代码在名称前 以 # 号标识,并且需要一个名称相同的结束模板 /。让我们考虑一个生成 HTML 列表的助手代码:

preparationScript

Handlebars.registerHelper("list", function(items, options) {
  const itemsAsHtml = items.map(item => "<li>" + options.fn(item) + "</li>");
  return "<ul>\n" + itemsAsHtml.join("\n") + "\n</ul>";
});

这个示例创建了一个名为 list 的助手代码来生成我们的 HTML 列表。助手代码接收一个 people 参数和一个 options 参数 。options 包含一个名为 fn 的属性,这个属性使你能够像调用普通的 Handlebars 模板一样调用代码块的上下文。

执行后,模板将渲染:

output

<ul>
<li>Yehuda Katz</li>
<li>Carl Lerche</li>
<li>Alan Johnson</li>
</ul>

块助手代码具有其他功能,例如能够创建 else (例如,由内置的 if 函数使用)

因为调用 options.fn(context) 时 Handlebars 会转义块助手代码的内容,因此 Handlebars 不会转义块助手代码的返回结果。如果 这样做,代码块内部的内容将被两次转义。

表达式

Handlebars 表达式是 Handlebars 模板的基本单位。 您可以在 {{mustache}} 中单独使用它们或将它们用作 Handlebars 助手代码, 或将其用作 Hash 参数中的值。

#基本用法

Handlebars 表达式是一些以双花括号 {{}} 括起来的内容。在以下的模版中,firstname 是一个被声明为表达式的变量,且被双花 括号括起来。

template

<p>{{firstname}} {{lastname}}</p>

如果将以下对象输入模板:

input

{
  firstname: "Yehuda",
  lastname: "Katz",
}

表达式会编译为如下输出:

output

<p>Yehuda Katz</p>

#路径表达式

Handlebars 表达式亦可为以句点分隔的路径。

template

{{person.firstname}} {{person.lastname}}

这个表达式将会在输入对象中查找 person 属性,然后查找 person 对象中的 firstnamelastname属性。 person 对象内的 属性。

将如下输入传入模版:

input

{
  person: {
    firstname: "Yehuda",
    lastname: "Katz",
  },
}

会获得如下输出:

output

Yehuda Katz

Handlebars 同时支持一个已弃用的 / 语法,因此你可以将上面的例子这样写:

template

{{person/firstname}} {{person/lastname}}

#更改上下文

一些诸如 #with and #each 的助手代码使你能够操作嵌套的对象。当你在路径中包含 ../ 时,Handlebars 将转回父级上下文。

template

{{#each people}}
    {{../prefix}} {{firstname}} 
{{/each}}

即使在注释的上下文中输出了名称,它仍然可以返回到主上下文(根对象)以检索前缀。

注意

../ 解析的确切值根据调用该代码块的助手代码不同而有所不同。仅在上下文更改必要时使用 ../。诸如 {{#each}} 之类的子助 手代码将需要使用 ../ ,而诸如 {{#if}} 之类的助手代码则不需要。

{{permalink}}
{{#each comments}}
  {{../permalink}}
​
  {{#if title}}
    {{../permalink}}
  {{/if}}
{{/each}}

在此示例中,以上所有引用相同的前缀值,即使它们位于不同的块中也是如此。这样的行为是从 Handlebars 4 开始的, 发行说明 也讨论了先前的行为作为迁移计划。 Handlebars 还允许通过 this 来解决助手和数据字段之间的名称冲突。参考:

#文字

除了以下字符,标识符可以是任何 Unicode 文本:

Whitespace ! " # % & ' ( ) * + , . / ; < = > @ [ \ ] ^ ``{|}~`

除此之外,true, false, nullundefined 只允许在路径表达式的开头出现。

若想引用一个并非合法的标识符,你可以使用 [。在路径表达式中你不必使用 ] 来关闭它,但其他表达式中是需要的。

JavaScript 样式的字符串如 "' 也可用于替代 [

template

{{!-- wrong: {{array.0.item}} --}}
correct: array.[0].item: {{array.[0].item}}
​
{{!-- wrong: {{array.[0].item-class}} --}}
correct: array.[0].[item-class]: {{array.[0].[item-class]}}
​
{{!-- wrong: {{./true}}--}}
correct: ./[true]: {{./[true]}}

#HTML 转义

在 Handlebars 中,由 {{expression}} 返回的值是 HTML 转义的。也就是说,如果一个表达式包含 &,那么返回的 HTML 转义的内 容将会包含 &。如果你不希望 Handlebars 转义字符的话,请使用 {{{

在以下模板中,你将了解如何生成 HTML 转义的和原始的输出。

template

raw: {{{specialChars}}}
html-escaped: {{specialChars}}

将如下特殊的输入传入模版:

input

{ specialChars: "& < > \" ' ` =" }

使用 {{{ 会输出原始结果。否则将会输出 HTML 转义之后的结果,如下面的例子所示。

output

raw: & < > " ' ` =
html-escaped: &amp; &lt; &gt; &quot; &#x27; &#x60; &#x3D;

#助手代码

助手代码可以实现一些并非 Handlesbars 语言本身的功能。

在运行时可以用 HandleBars.registerHelper 可以注册助手代码。例如为了将字符串中的所有字符转换为大写。

preparationScript

Handlebars.registerHelper('loud', function (aString) {
    return aString.toUpperCase()
})

Handlebars 助手代码的调用需要一个简单标识符,且可紧接一个或多个参数(以空格分割)。每一参数为一个 Handlebars 表达式,且 将会用于上方“基本用法”中相同的方法来计算。

template

{{firstname}} {{loud lastname}}

此例子中,load 是助手代码的名称,而 lastname 为传递给助手代码的参数。此模板,将会将输入的 uppercase 属性正确地转换 为大写:

input

{
  firstname: "Yehuda",
  lastname: "Katz",
}

output

Yehuda KATZ

#避免助手代码的返回值被 HTML 转义

即使当使用 {{ 而非 {{{ 来调用助手代码时,当你的助手代码返回一个 Handlebars.Safestring 的实例,返回值也并不会被转义 。你需要留心将所有参数正确地使用 Handlebars.escapeExpression 来转义。

preparationScript

Handlebars.registerHelper("bold", function(text) {
  var result = "<b>" + Handlebars.escapeExpression(text) + "</b>";
  return new Handlebars.SafeString(result);
});

这里的单引号被转义

#具有多个参数的助手代码

我们观察一下另一个具有两个参数的助手代码:

template

{{link "See Website" url}}

此例子中,Handlebars 将把两个参数传递给 link 助手代码:字符串 See Website 与从下面提供的 people 输入对象中的 people.value

input

{ url: "https://yehudakatz.com/" }

如同代码中所述,此助手代码 link 用于生成一个超链接。

preparationScript

Handlebars.registerHelper("link", function(text, url) {
      var url = Handlebars.escapeExpression(url),
          text = Handlebars.escapeExpression(text)
          
     return new Handlebars.SafeString("<a href='" + url + "'>" + text +"</a>");
});

我们会从上面的输入获得如下输出:

output

<a href='https://yehudakatz.com/'>See Website</a>

在此例中,你可以使用同一助手代码,但使用基于 people.text 的值的动态文本:

template

{{link people.text people.url}}

input

{
  people: {
    firstname: "Yehuda",
    lastname: "Katz",
    url: "https://yehudakatz.com/",
    text: "See Website",
  },
}

#字面量参数

帮助代码调用亦可含字面量,作为参数抑或是 Hash 参数。支持的字面量有数字、字符串、true, false, nullundefined

template

{{progress "Search" 10 false}}
{{progress "Upload" 90 true}}
{{progress "Finish" 100 false}}

#含有 Hash 参数的助手代码

Handlebars 提供了额外的元数据,例如 Hash 参数来作为助手代码的最后一个参数。

template

{{link "See Website" href=person.url class="person"}}

在此模版中,最后一个参数 href=people.url class="people" 为传送至助手代码的 Hash 参数。

Hash 参数中的键必须为简单标识符,且值为 Handlebars 表达式。这意味着值可以为简单标识符,路径或字符串。

若将如下输入传入模版,其中 person.url 的值可以从 person 中获取。

input

{
  person: {
    firstname: "Yehuda",
    lastname: "Katz",
    url: "https://yehudakatz.com/",
  },
}

正如以下助手代码中的描述,Hash 参数可以从最后一个参数 options 获取,以用于助手代码内部的进一步处理。

preparationScript

Handlebars.registerHelper("link", function(text, options) {
    var attributes = [];
​
    Object.keys(options.hash).forEach(key => {
        var escapedKey = Handlebars.escapeExpression(key);
        var escapedValue = Handlebars.escapeExpression(options.hash[key]);
        attributes.push(escapedKey + '="' + escapedValue + '"');
    })
    var escapedText = Handlebars.escapeExpression(text);
    
    var escapedOutput ="<a " + attributes.join(" ") + ">" + escapedText + "</a>";
    return new Handlebars.SafeString(escapedOutput);
});

上述助手代码产生的输出如下:

output

Handlebars 亦提供了使用一个模版块来调用助手代码的机制。块助手代码可用于执行任意次数(包括零次)的代码块并且使用它所选择 的任意上下文。

了解更多:块助手代码

#助手代码和属性查找时的消歧义

如果助手代码注册时的名称和一个输入的属性名重复,则助手代码的优先级更高。如果你想使用输入的属性,请在其名称前加 ./this.。(或是已弃用的 this/。)

template

helper: {{name}}
data: {{./name}} or {{this/name}} or {{this.name}}

input

{ name: "Yehuda" }

preparationScript

Handlebars.registerHelper('name', function () {
    return "Nils"
})

#子级表达式

Handlebars 对子级表达式提供了支持,这使你可以在单个 Mustache 模板中调用多个助手代码,并且将内部助手代码调用的返回值作为 外部助手代码的参数传递。子级表达式使用括号定界。

{{outer-helper (inner-helper 'abc') 'def'}}

上例中,inner-helper 会被调用并带有字符串参数 'abc',同时不论 inner-helper 返回了什么,返回值都将被作为第一个参数 传递给 outer-helper(同时 'def' 会作为第二个参数传递)。

#空格控制

通过在括号中添加一个 ~ 字符,你可以从任何 Mustache 模板代码块的任何一侧省略模板中的空格。应用之后,该侧的所有空格将被 删除,直到第一个位于同一侧的 Handlebars 表达式或非空格字符出现。

{{#each nav ~}}
  <a href="{{url}}">
    {{~#if test}}
      {{~title}}
    {{~^~}}
      Empty
    {{~/if~}}
  </a>
{{~/each}}

以及如下内容:

{
  nav: [{ url: "foo", test: true, title: "bar" }, { url: "bar" }];
}

输出没有换行符并格式化了空格的结果:

<a href="foo">bar</a><a href="bar">Empty</a>

这扩展了「独立」助手代码(块助手代码、注释、代码片段或是空白符)在换行符时的默认行为。

{{#each nav}}
  <a href="{{url}}">
    {{#if test}}
      {{title}}
    {{^}}
      Empty
    {{/if}}
  </a>
{{~/each}}

将会渲染

<a href="foo">
  bar
</a>
<a href="bar">
  Empty
</a>

#转义 Handlebars 表达式

Handlebars 可以从这两种方式中的任何一种转义:「内联转义」或「RAW 块助手代码」。内联转义通过 Mustache 代码块前置 \ 实现 ,而 RAW 代码块通过使用 {{{{ 实现。

\{{escaped}}
{{{{raw}}}}
  {{escaped}}
{{{{/raw}}}}

RAW 代码块的操作方式与其他 块助手代码 均相同,但区别在于它的子内容被 Handlebars 视为一段字符串。

#代码片段

Handlebars 允许代码片段的复用。代码片段是一段普通的 Handlebars 模板,但它们可以直接由其他模板调用。

#基本代码片段

一个代码片段必须通过 Handlebars.registerPartial 注册。

preparationScript

Handlebars.registerPartial('myPartial', '{{prefix}}');

这个方法将注册代码片段 myPartial。可以对代码片段进行预编译,并将预编译的模板传到第二个参数。

调用代码片段是通过「代码片段调用语法」完成的:

template

{{> myPartial }}

将渲染名为 myPartial 的代码片段。当代码片段执行时,它会在当前的代码块的上下文中运行。

#动态代码片段

使用子表达式语法可以动态选择要执行的部分。

template

这将计算 whichPartial,然后渲染以函数的返回值作为名称的代码片段。

子表达式不会解析变量,因此 whichPartial 必须是一个函数。如果代码片段的名称是储存在一个变量里面的,则可以通过 lookup 助手代码来解决它。

template

{{> (lookup . 'myVariable') }}

#代码片段上下文

通过将上下文传递给代码片段,你可以在自定义上下文中执行代码片段。

template

{{> myPartial myOtherContext }}

#代码片段参数

可以通过 Hash 参数将自定义数据传递到代码片段。

template

{{> myPartial parameter=favoriteNumber }}

代码片段运行时会将参数设置为 value

这对于把数据从父级传递到代码片段的上下文中的时候特别有用:

template

#代码片段代码块

一般来讲,尝试渲染一个未注册的代码片段会抛出错误。如果需要阻止错误抛出,可以在代码块中嵌套代码片段。

template

{{#> myPartial }}
  Failover content
{{/myPartial}}

如果代码片段 myPartial 尚未注册,则 Failover content 将被渲染。

这种代码块的语法也可以用于将模板传递到代码片段中。有专门的代码片段执行此操作:@partial-block。考虑如下模板:

template

{{#> layout }}
My Content
{{/layout}}

layout 代码片段包含

partial: layout

Site Content {{> @partial-block }}

这将渲染:

output

Site Content My Content

当以这种方式调用时,代码块将在 调用时代码片段中的上下文 中执行。此时深度路径查询和代码块参数是相对于代码片段的,而非 代码片段的模板。

template

这将渲染模板中的 person.firstname 而非代码片段。

#内联代码片段

模板可以通过 inline 修饰符定义代码块范围之内的代码片段。

template

这将为每个 child 渲染 myPartial

每个内联代码片段均可用于当前代码块和所有子代码块(包括代码片段)。这使得「布局模板」和其他类似的功能成为可能:

template

{{#> layout}}
  {{#*inline "nav"}}
    My Nav
  {{/inline}}
  {{#*inline "content"}}
    My Content
  {{/inline}}
{{/layout}}

其中 layout 可能是:

partial: layout

<div class="nav">
  {{> nav}}
</div>
<div class="content">
  {{> content}}
</div>

实例展示:

代码:

<!DOCTYPE html>
<html lang="en">

<head>

  <script src="./static/js/jquery-3.6.0.min.js"></script>
  <script src="https://cdn.bootcdn.net/ajax/libs/handlebars.js/4.7.7/handlebars.js"></script>
</head>

<body>
  <main class="parent">
    <script id="epidemic_template" type="text/x-handlebars-template">
        <h2>最简单表达式 </h2>
        <div>
          <p>{{firstname}} {{loud lastname}}</p>
        </div>
        <!-- 列表 -->
        <h2>列表</h2>
        <ul class="people_list">
          {{#each people}}
            <li>{{this}}</li>
          {{/each}}
        </ul>
        <!-- 列表写法2 搭配助手  #助手名 开始  /助手名 结束-->
        <h2>列表写法2</h2>
        {{#list people2}}
        {{firstname2}} {{lastname2}}
        {{/list}}
        <!-- 嵌套助手-->
        <h2>嵌套助手</h2>
        {{outer-helper (inner-helper "abc") "def"}}
        <!-- whith 助手-->
        <!-- 。如果你不希望 Handlebars 转义字符的话,请使用 \{{{。 -->
        <h2>whith助手</h2>
        <div class="entry">
          <h3>{{title}}</h3>
          {{#with story}}
            <div class="intro">{{{intro}}}</div>
            <div class="body">{{{body}}}</div>
          {{/with}}
        </div>
        <!-- 具多个参数的助手 -->
        <h2>具多个参数的助手</h2>
        {{link "See Website" url}}
        <!-- 写法2 -->
        {{link people3.text people3.url}}

        <!-- 省略空格 ~ -->
        <div>
          {{#each nav~}}
            <a href="{{url}}">
              {{~#if test}}
                {{~title}}
              {{~else~}}
                Empty
              {{~/if~}}
            </a>
          {{~/each}}
        </div>
        <!-- html 特殊字符转义 -->
        <div>
          <div>
            raw:
            {{{specialChars}}}
          </div>
          <div>
            html-escaped:
            {{specialChars}}
          </div>
        </div>
        <!-- 转义 -->
        <h1>转义\{{}}表达式的两种方式 raw 可以用代码助手
          区别是返回的永远是一串字符春</h1>
        <div>
          \{{escaped}}
        {{{{raw}}}}
            {{escaped}}
      {{{{/raw}}}}
            {{{{raw}}}}
            {{这个会被转义 不会当作是表达式 会被当成正常的字符串 hallo world}}
    {{{{/raw}}}}
        </div>
      </script>
    <script>
      // { {<!-- 行块 转义 两种方式 一种\ 反斜杠转义  第二种 {{{{row}}}} 四个花括号转义  -- > }}
      // compile the template
      var epidemicTemplate = Handlebars.compile(
        $("#epidemic_template").html()
      );
      // execute the compiled template and print the output to the console
      var values = {
        firstname: "张",
        lastname: "3333",
        people: ["Yehuda Katz", "Alan Johnson", "Charles Jolley"],
        nav: [{ url: "foo", test: true, title: "bar" }, { url: "bar" }],
        raw: "行",
        escaped: "逃跑",
        title: "First Post",
        story: {
          intro: "Before the jump",
          body: "After the jump",
          body: "After the jump2",
        },
        people2: [
          {
            firstname2: "wang",
            lastname2: "wuwuwu",
          },
          {
            firstname2: "wang2",
            lastname2: "wuwuwu",
          },
        ],
        url: "https://yehudakatz.com/",
        people3: {
          firstname: "Yehuda",
          lastname: "Katz",
          url: "https://yehudakatz.com/",
          text: "See Website",
        },
        specialChars: "&<>\"'=",
      };

      //助手代码 单独
      Handlebars.registerHelper("loud", function (aString) {
        console.log(aString, "lastname");
        return aString.toUpperCase();
      });
      //块助手代码 {{  #助手名-list 属性名}} <li>{{this}}</li> {{ 属性名 /助手名-list}}
      Handlebars.registerHelper("list", function (items, options) {
        console.log("list", items);
        const itemsAsHtml = items.map(
          (item) => "<li>" + options.fn(item) + "</li>"
        );
        console.log(itemsAsHtml);
        return "<ul>\n" + itemsAsHtml.join("\n") + "\n</ul>";
      });
      //with 助手代码
      Handlebars.registerHelper("with", function (context, options) {
        console.log(context, options, "with助手代码");
        return options.fn(context);
      });
      //具有多个参数的助手
      Handlebars.registerHelper("link", function (text, url) {
        var url = Handlebars.escapeExpression(url), //逃逸后 不会被html化
          text = Handlebars.escapeExpression(text);

        return new Handlebars.SafeString(
          "<a href='" + url + "'>" + text + "</a>"
        );
      });

      // Handlebars.registerHelper("row", function (items, options) {
      //   console.log("row", items), "---------------------------";

      //   return items;
      // });
      Handlebars.registerHelper(
        "outer-helper",
        function (params_abc, params_def) {
          console.log("最终结果", params_abc, params_def);
          return "最终结果" + params_abc + params_def;
        }
      );
      Handlebars.registerHelper("inner-helper", function (params1) {
        console.log("wai", params1, "-----");
        return params1 + 1;
      });

      // Handlebars.registerHelper("row", function (params, options) {
      //   var text = "sdf";
      //   console.log("raw", params.options);
      //   return text + params;
      // });
      console.log(epidemicTemplate(values));

      $(".parent").append(epidemicTemplate(values));
    </script>
  </main>
</body>

</html>

结果:

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

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

相关文章

飞猪店铺小管家软件需求分析说明书

飞猪店铺小管家软件 项目背景&#xff1a; 在飞猪店铺运营过程中&#xff0c;客服人数不足导致客服团队忙不过来&#xff0c;容易出现订票信息错误&#xff0c;进而客户无法顺利参观景点&#xff0c;频繁投诉。这种情况不仅影响客户体验&#xff0c;还可能导致商家因赔付而承受…

玖章算术叶正盛:为什么 PostgreSQL 不如 MySQL 流行?|3306π活动预告

议题大纲 PostgreSQL 是业界功能最强大的开源数据库&#xff0c;为什么在全球流行度没有 MySQL 高&#xff0c;本次分享主题计划从产品、技术、商业等方面综合分析两个数据库的竞争。 议题方向&#xff1a; PostgreSQL 与 MySQL 数据库简介 市场分析 产品定位 技术优劣势 …

TensorFlow与pytorch特定版本虚拟环境的安装

TensorFlow与Python的版本对应&#xff0c;注意&#xff0c;一定要选择对应的版本&#xff0c;否则会让你非常痛苦&#xff0c;折腾很久搞不清楚原因。 建议使用国内镜像源安装 没有GPU后缀的就表示是CPU版本的&#xff0c;不加版本就是最新 pip install tensorflow -i https:…

如何创建集成 LSP 支持多语言的 Web 代码编辑器

对于一个云开发平台来说&#xff0c;一个好的 Web IDE 能很大程度地提高用户的编码体验&#xff0c;而一个 Web IDE 的一个重要组成部分就是代码编辑器。 目前有着多款 web 上的代码编辑器可供选择&#xff0c;比如 Ace、CodeMirror、Monaco&#xff0c;这三款编辑器的比较在这…

[ 云计算 华为云 ] 解决办法:如何更换华为云云耀云服务器L实例的镜像 | 文末送书

文章目录 问题描述分析原因解决办法文末送书《ANSYS Workbench项目分析与案例实操详解》博主推荐理由本书内容简介本书作者简介 废话在前&#xff08;直接看解决办法的这段可以过&#xff09;&#xff1a;讲道理&#xff0c;一般情况下云服务器&#xff0c;镜像是随便更换的&am…

13-JVM调优实战-3

上一篇&#xff1a;12-JVM调优实战-2 今天来介绍一款阿里巴巴的调优工具。 Arthas详解 Arthas 是 Alibaba 在 2018 年 9 月开源的 Java 诊断工具。支持 JDK6&#xff0c; 采用命令行交互模式&#xff0c;可以方便的定位和诊断线上程序运行问题。Arthas 官方文档十分详细&am…

【驱动开发】实现三盏灯的控制,编写应用程序测试

head.h #ifndef __HEAD_H__ #define __HEAD_H__//LED1:PE10 //LED2:PF10 //LED3:PE8#define LED_RCC 0X50000A28 //使能GPIO#define LED_MODER 0X50006000 //设置输出模式 #define LED_ODR 0X50006014 //设置输出高低电平#define LED2_MODER 0X50007000 …

一款 IDEA 插件帮你优雅转化 DTO、VO、BO、PO、DO

转自&#xff1a;码猿技术专栏 POJO 的定义是无规则简单的对象&#xff0c;在日常的代码分层中 pojo 会被分为VO、BO、 PO、 DTO VO &#xff08;view object/value object&#xff09;表示层对象 1、前端展示的数据&#xff0c;在接口数据返回给前端的时候需要转成VO 2、个…

火山引擎DataLeap的数据血缘用例与设计概述

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 数据血缘描述了数据的来源和去向&#xff0c;以及数据在多个处理过程中的转换。数据血缘是组织内使数据发挥价值的重要基础能力。本文从字节的数据链路概况开始&…

开学季,长沙又一次戳中年轻人:人才巴士,欢迎“星”同学

初秋临近&#xff0c;又是一年开学季。与往年不一样的是&#xff0c;当数以万计的学子从全国各地来到长沙&#xff0c;这座年轻人友好的城市也用独特的方式表达着对新生的欢迎与诚意&#xff1a;24辆人才巴士“穿上”欢迎词&#xff1b;60个公交站台向新生“表白”&#xff1b;…

linux一些常用的下载工具-aria2

从断点续传开始 故事的过程是这样的&#xff0c;朋友是搞科研的&#xff0c;需要在一个国外的学术网站下载一个药物的模型压缩包&#xff0c;大概有23g。关键他也不会用别的就wget下载…恩中间还断了…问我有什么方法没有断点续传&#xff0c;而是能不能更快速的下载&#xff…

实用工具JRebel XRebel【2023】配置和使用的详解

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于JRebel & XRebel的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.JRebel 的简介 二.插件的…

03深度学习-目标检测-深度学习方法与传统算法对比

一、目标学习的检测方法变迁及对比 “目标检测“是当前计算机视觉和机器学习领域的研究热点。从Viola-Jones Detector、DPM等冷兵器时代的智慧到当今RCNN、YOLO等深度学习土壤孕育下的GPU暴力美学&#xff0c;整个目标检测的发展可谓是计算机视觉领域的一部浓缩史。整个目标…

【算法与数据结构】236、LeetCode二叉树的最近公共祖先

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a; 根据定义&#xff0c;最近祖先节点需要遍历节点的左右子树&#xff0c;然后才能知道是否为最近祖先节…

【ccf-csp题解】第0次csp认证-第四题-有趣的数-组合数学

题目描述 思路说明 本题涉及组合数学的知识 目的是在n个空位上放置0、1、2、3&#xff0c;问符合题意的放法有多少种 首先注意到一个重要的事实&#xff1a; 只要0和1的位置已经确定&#xff0c;那么2和3的摆放就十分容易了 那么把所有情况分为n-2种&#xff1a; 第一种…

IntelliJ IDEA 配合 Maven 的一些技巧(prifiles)

环境 IntelliJ IDEA 2017.1 Maven 3.3.9 Nexus 3.2.1 学习前提 了解 Maven 配置的基本用法 了解私有仓库&#xff0c;比如 nexus 的一些概念 强烈建议把 Maven 的 settings.xml 文件同时放在&#xff1a;%USER_HOME%/.m2/settings.xml 和 ${maven.home}/conf/settings.xm…

给 Ubuntu 操作系统配置静态 IP

针对 Ubuntu 22.04.3 操作系统的静态 IP 配置 一、查看初始的网络信息 查看网卡名称 ifconfig查看网关信息 route -n二、编辑网络配置文件 编辑文件&#xff0c;配置文件的名称可能不一样&#xff0c;自己去 /etc/netplan/ 目录查看 sudo vim /etc/netplan/01-network-manager-…

51单片机的智能台灯控制系统仿真( proteus仿真+程序+原理图+报告+讲解视频)

51单片机的红外光敏检测智能台灯控制系统仿真 1.主要功能&#xff1a;2.仿真3. 程序代码4. 原理图5. 设计报告6. 设计资料内容清单&&下载链接 51单片机的红外光敏检测智能台灯控制系统仿真( proteus仿真程序原理图报告讲解视频&#xff09; 仿真图proteus7.8及以上 程…

服务器时间正确,Java程序时区不对问题解决

服务器执行date命令显示时间正确 执行timedatectl status命令结果如下&#xff1a; 看起来是Time zone没有设置好&#xff0c;但是登录另外一台正常的服务器&#xff0c;执行timedatectl status也是一样的 直接写一个简单的Java程序TestTimeZone.java&#xff1a; import ja…

consul 键值对操作命令

1. 创建或更新—>put [rootlocalhost ~]# consul kv put redis/config/connection 5 Success! Data written to: redis/config/connection[rootlocalhost ~]# consul kv put aaaaaaaaaaaa 5 Success! Data written to: aaaaaaaaaaaa /redis/config会生成两个目录&#xff…