Cobra眼睛蛇-强大的Golang CLI框架,快速上手的脚手架搭建项目工具,详细安装和使用

news2024/11/24 13:10:06

Cobra眼睛蛇-强大的Golang CLI框架,快速上手的脚手架搭建项目工具,详细安装和使用。

阅读过k8s源码的同学,应该都知道k8s Scheduler、kubeadm、kubelet等核心组件的命令行交互全都是通过spf13写的Cobra库来实现。本文就来介绍下Cobra的相关概念及具体用法。

在这里插入图片描述

关于
Cobra是一个用于Go的CLI框架。它包含一个用于创建CLI应用程序的库和一个快速生成Cobra程序和命令文件的工具。

它是由Go团队成员spf13为hugo创建的,已经被最流行的Go项目所采用。

Tips:知名Golang配置库viper也是该作者开发的。

Cobra提供:

简单的基于子命令的cli:如 app server, app fetch等等。
完全符合posix的flags(包括short版本和long版本)
嵌套的子命令
全局、本地和级联flags
使用cobra init appname和cobra add cmdname轻松生成应用程序和命令
智能建议(假如你将app server写成了错误的app srver)
自动生成命令和flags的帮助
自动识别help flag-h, --help等。
为您的应用程序自动生成bash自动完成
自动为应用程序生成man手册
命令别名,这样您就可以在不破坏它们的情况下更改内容
可以灵活的定义自己的帮助、用法等。
可选的紧密集成 viper,12-factor


安装
使用Cobra很简单。首先,使用go get安装最新版本的库。这个命令将安装cobra生成器可执行文件以及库及其依赖项:

go get -u github.com/spf13/cobra/cobra

接下来,在你的应用中加入Cobra:

import "github.com/spf13/cobra"

概念
Cobra是建立在commands、arguments和flags的结构上的。

Commands代表行为,Args是commands的参数,Flags 是这些行为的修饰符。

最好的应用程序在使用时读起来像一个通顺的句子。用户将知道如何使用该应用程序,因为他们会自然地理解如何使用它。

要遵循的模式是 APPNAME VERB NOUN --ADJECTIVE. 或 APPNAME COMMAND ARG --FLAG

一些真实世界的例子可以更好地说明这一点。

在下面的例子中,’ server ‘是命令,’ port '是flag:

hugo server --port=1313

在这个命令中,我们告诉Git clone bare url。

git clone URL --bare

Commands
命令是应用程序的中心点。应用程序支持的每个交互都将包含在命令中。一个命令可以有子命令并且可以选择运行一个动作。

在上面的示例中,“服务器”是命令。

Flags
flag是一种修改命令行为的方法。Cobra支持完全posix兼容的flag以及Go的flag包。Cobra命令可以定义持续到子命令的flag,以及仅对该命令可用的flag。

在上面的例子中,’ port '是flag。

flag功能由pflag库提供,它是flag标准库的一个分支,它在添加 POSIX 合规性的同时保持相同的接口。


入门

虽然欢迎您提供自己的项目组织,但通常基于 Cobra 的应用程序将遵循以下项目结构:

  ▾ appName/
    ▾ cmd/
        add.go
        your.go
        commands.go
        here.go
      main.go

在 Cobra 应用程序中,通常 main.go 文件非常简单。它有一个目的:初始化 Cobra。

package main

import (
  "{pathToYourApp}/cmd"
)

func main() {
  cmd.Execute()
}

使用 Cobra 生成器
Cobra 提供了自己的程序,可以创建您的应用程序并添加您想要的任何命令。这是将 Cobra 合并到您的应用程序中的最简单方法。

在这里 https://github.com/spf13/cobra/blob/master/cobra/README.md 您可以找到有关它的更多信息。

使用 Cobra 库
要手动使用 Cobra,您需要创建一个干净的 main.go 文件和一个 rootCmd 文件。您可以选择提供您认为合适的其他命令。

创建 rootCmd
Cobra 不需要任何特殊的构造函数。只需创建您的命令。

理想情况下,您将它放在 app/cmd/root.go 中:

var rootCmd = &cobra.Command{
  Use:   "hugo",
  Short: "Hugo is a very fast static site generator",
  Long: `A Fast and Flexible Static Site Generator built with
                love by spf13 and friends in Go.
                Complete documentation is available at http://hugo.spf13.com`,
  Run: func(cmd *cobra.Command, args []string) {
    // Do Stuff Here
  },
}

func Execute() {
  if err := rootCmd.Execute(); err != nil {
    fmt.Println(err)
    os.Exit(1)
  }
}

您还将在 init() 函数中定义flags和handle配置。

例如cmd/root.go:

import (
  "fmt"
  "os"

  homedir "github.com/mitchellh/go-homedir"
  "github.com/spf13/cobra"
  "github.com/spf13/viper"
)

func init() {
  cobra.OnInitialize(initConfig)
  rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)")
  rootCmd.PersistentFlags().StringVarP(&projectBase, "projectbase", "b", "", "base project directory eg. github.com/spf13/")
  rootCmd.PersistentFlags().StringP("author", "a", "YOUR NAME", "Author name for copyright attribution")
  rootCmd.PersistentFlags().StringVarP(&userLicense, "license", "l", "", "Name of license for the project (can provide `licensetext` in config)")
  rootCmd.PersistentFlags().Bool("viper", true, "Use Viper for configuration")
  viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
  viper.BindPFlag("projectbase", rootCmd.PersistentFlags().Lookup("projectbase"))
  viper.BindPFlag("useViper", rootCmd.PersistentFlags().Lookup("viper"))
  viper.SetDefault("author", "NAME HERE <EMAIL ADDRESS>")
  viper.SetDefault("license", "apache")
}

func initConfig() {
  // Don't forget to read config either from cfgFile or from home directory!
  if cfgFile != "" {
    // Use config file from the flag.
    viper.SetConfigFile(cfgFile)
  } else {
    // Find home directory.
    home, err := homedir.Dir()
    if err != nil {
      fmt.Println(err)
      os.Exit(1)
    }

    // Search config in home directory with name ".cobra" (without extension).
    viper.AddConfigPath(home)
    viper.SetConfigName(".cobra")
  }

  if err := viper.ReadInConfig(); err != nil {
    fmt.Println("Can't read config:", err)
    os.Exit(1)
  }
}

创建你的 main.go
使用 root 命令,您需要让主函数执行它。为清楚起见,应在根目录上运行 Execute,尽管它可以在任何命令上调用。

在 Cobra 应用程序中,通常 main.go 文件非常简单。它的一个目的是初始化 Cobra。

package main

import (
  "{pathToYourApp}/cmd"
)

func main() {
  cmd.Execute()
}

创建附加命令
可以定义其他命令,通常每个命令在 cmd/ 目录中都有自己的文件。

如果你想创建一个版本命令,你可以创建 cmd/version.go 并用以下内容填充它:

package cmd

import (
  "fmt"

  "github.com/spf13/cobra"
)

func init() {
  rootCmd.AddCommand(versionCmd)
}

var versionCmd = &cobra.Command{
  Use:   "version",
  Short: "Print the version number of Hugo",
  Long:  `All software has versions. This is Hugo's`,
  Run: func(cmd *cobra.Command, args []string) {
    fmt.Println("Hugo Static Site Generator v0.9 -- HEAD")
  },
}

使用Flags
Flags提供修饰符来控制操作命令的操作方式。

为命令分配Flags
由于Flags是在不同的位置定义和使用的,因此我们需要在外部定义一个具有正确范围的变量来分配要使用的Flags。

var Verbose bool
var Source string

有两种不同的方法来分配标志。

持久flag
flag可以是“持久的”,这意味着该flag将可用于分配给它的命令以及该命令下的每个命令。对于全局flag,将flag分配为根上的持久flag。

rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output")

本地flag
也可以在本地分配一个flag,它只适用于该特定命令。

rootCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")

父命令的本地flag
默认情况下,Cobra 仅解析目标命令上的本地flag,忽略父命令上的任何本地flag。通过启用Command.TraverseChildrenCobra 将在执行目标命令之前解析每个命令的本地flag。

command := cobra.Command{
  Use: "print [OPTIONS] [COMMANDS]",
  TraverseChildren: true,
}

使用配置绑定标志
你也可以用viper https://github.com/spf13/viper 绑定你的标志:

var author string

func init() {
  rootCmd.PersistentFlags().StringVar(&author, "author", "YOUR NAME", "Author name for copyright attribution")
  viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
}

在此示例中,持久flag author与 绑定viper。请注意,当用户未提供标志时,变量author将不会设置为配置中的值。–author

在本例中,持久标志author与viper绑定。注意,当user没有提供–author flag时,变量author不会被设置为config中的值。

更多信息请参见viper 文档。

必需的flag
默认情况下,flag是可选的。相反,如果您希望您的命令在未设置flag时报告错误,请将其标记为必需:

rootCmd.Flags().StringVarP(&Region, "region", "r", "", "AWS region (required)")
rootCmd.MarkFlagRequired("region")

位置和自定义参数
位置参数的验证可以使用Command的Args字段指定。

内置了以下验证器:

NoArgs - 如果有任何位置参数,该命令将报告错误。
ArbitraryArgs - 该命令将接受任何参数。
OnlyValidArgs - 如果有任何位置参数不在 的ValidArgs字段中,该命令将报告错误Command。
MinimumNArgs(int) - 如果没有至少 N 个位置参数,该命令将报告错误。
MaximumNArgs(int) - 如果有超过 N 个位置参数,该命令将报告错误。
ExactArgs(int) - 如果不完全有 N 个位置参数,该命令将报告错误。
ExactValidArgs(int) = 如果不完全有 N 个位置参数,或者如果有任何位置参数ValidArgs不在Command
RangeArgs(min, max) - 如果 args 的数量不在预期 args 的最小和最大数量之间,该命令将报告错误。

设置自定义验证器的示例:

var cmd = &cobra.Command{
  Short: "hello",
  Args: func(cmd *cobra.Command, args []string) error {
    if len(args) < 1 {
      return errors.New("requires at least one arg")
    }
    if myapp.IsValidColor(args[0]) {
      return nil
    }
    return fmt.Errorf("invalid color specified: %s", args[0])
  },
  Run: func(cmd *cobra.Command, args []string) {
    fmt.Println("Hello, World!")
  },
}

例子
在下面的示例中,我们定义了三个命令。两个在顶层,一个 (cmdTimes) 是顶级命令之一的子级。在这种情况下,root 是不可执行的,这意味着需要一个子命令。这是通过不为“rootCmd”提供“运行”来实现的。

我们只为单个命令定义了一个flag。

有关flag的更多文档,请访问https://github.com/spf13/pflag

package main

import (
  "fmt"
  "strings"

  "github.com/spf13/cobra"
)

func main() {
  var echoTimes int

  var cmdPrint = &cobra.Command{
    Use:   "print [string to print]",
    Short: "Print anything to the screen",
    Long: `print is for printing anything back to the screen.
For many years people have printed back to the screen.`,
    Args: cobra.MinimumNArgs(1),
    Run: func(cmd *cobra.Command, args []string) {
      fmt.Println("Print: " + strings.Join(args, " "))
    },
  }

  var cmdEcho = &cobra.Command{
    Use:   "echo [string to echo]",
    Short: "Echo anything to the screen",
    Long: `echo is for echoing anything back.
Echo works a lot like print, except it has a child command.`,
    Args: cobra.MinimumNArgs(1),
    Run: func(cmd *cobra.Command, args []string) {
      fmt.Println("Print: " + strings.Join(args, " "))
    },
  }

  var cmdTimes = &cobra.Command{
    Use:   "times [# times] [string to echo]",
    Short: "Echo anything to the screen more times",
    Long: `echo things multiple times back to the user by providing
a count and a string.`,
    Args: cobra.MinimumNArgs(1),
    Run: func(cmd *cobra.Command, args []string) {
      for i := 0; i < echoTimes; i++ {
        fmt.Println("Echo: " + strings.Join(args, " "))
      }
    },
  }

  cmdTimes.Flags().IntVarP(&echoTimes, "times", "t", 1, "times to echo the input")

  var rootCmd = &cobra.Command{Use: "app"}
  rootCmd.AddCommand(cmdPrint, cmdEcho)
  cmdEcho.AddCommand(cmdTimes)
  rootCmd.Execute()
}

更加完整示例,请查看Hugo。

帮助命令
当您有子命令时,Cobra 会自动向您的应用程序添加帮助命令。这将在用户运行“应用程序帮助”时调用。此外,帮助还将支持所有其他命令作为输入。比如说,你有一个名为“create”的命令,没有任何额外的配置;Cobra 将在调用“app help create”时工作。每个命令都会自动添加“–help”标志。

例子
以下输出由 Cobra 自动生成。除了命令和标志定义之外,什么都不需要。

$ cobra help

Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.

Usage:
  cobra [command]

Available Commands:
  add         Add a command to a Cobra Application
  help        Help about any command
  init        Initialize a Cobra Application

Flags:
  -a, --author string    author name for copyright attribution (default "YOUR NAME")
      --config string    config file (default is $HOME/.cobra.yaml)
  -h, --help             help for cobra
  -l, --license string   name of license for the project
      --viper            use Viper for configuration (default true)

Use "cobra [command] --help" for more information about a command.

帮助就像任何其他命令一样只是一个命令。它没有特殊的逻辑或行为。事实上,如果需要,您可以提供自己的。

定义你自己的help
您可以为默认命令提供自己的帮助命令或您自己的模板,以与以下功能一起使用:

cmd.SetHelpCommand(cmd *Command)
cmd.SetHelpFunc(f func(*Command, []string))
cmd.SetHelpTemplate(s string)

后两者也适用于任何子命令。

用法信息
当用户提供无效标志或无效命令时,Cobra 通过向用户显示“usage”来响应。

Example

您可能会从上面的帮助中认识到这一点。这是因为默认帮助将用法作为其输出的一部分嵌入。

$ cobra --invalid
Error: unknown flag: --invalid
Usage:
  cobra [command]

Available Commands:
  add         Add a command to a Cobra Application
  help        Help about any command
  init        Initialize a Cobra Application

Flags:
  -a, --author string    author name for copyright attribution (default "YOUR NAME")
      --config string    config file (default is $HOME/.cobra.yaml)
  -h, --help             help for cobra
  -l, --license string   name of license for the project
      --viper            use Viper for configuration (default true)

Use "cobra [command] --help" for more information about a command.

定义自己的 usage
您可以提供自己的使用函数或模板供 Cobra 使用。像帮助一样,函数和模板可以通过公共方法覆盖:

cmd.SetUsageFunc(f func(*Command) error)
cmd.SetUsageTemplate(s string)

Version Flag
如果在根命令上设置了 Version 字段,Cobra 会添加一个顶级“–version”标志。使用“–version”标志运行应用程序将使用版本模板将版本打印到标准输出。可以使用cmd.SetVersionTemplate(s string)函数自定义模板。

PreRun 和 PostRun 钩子

可以在命令的main Run函数之前或之后运行函数。PersistentPreRun和PreRun函数将在Run之前执行。PersistentPostRun和PostRun将在Run之后执行。如果Persistent*Run函数没有声明自己的,则将由子函数继承。这些函数的运行顺序如下:

PersistentPreRun
PreRun
Run
PostRun
PersistentPostRun

下面是使用所有这些特性的两个命令的示例。当子命令被执行时,它将运行根命令的PersistentPreRun,而不是根命令的PersistentPostRun:

package main

import (
  "fmt"

  "github.com/spf13/cobra"
)

func main() {

  var rootCmd = &cobra.Command{
    Use:   "root [sub]",
    Short: "My root command",
    PersistentPreRun: func(cmd *cobra.Command, args []string) {
      fmt.Printf("Inside rootCmd PersistentPreRun with args: %v\n", args)
    },
    PreRun: func(cmd *cobra.Command, args []string) {
      fmt.Printf("Inside rootCmd PreRun with args: %v\n", args)
    },
    Run: func(cmd *cobra.Command, args []string) {
      fmt.Printf("Inside rootCmd Run with args: %v\n", args)
    },
    PostRun: func(cmd *cobra.Command, args []string) {
      fmt.Printf("Inside rootCmd PostRun with args: %v\n", args)
    },
    PersistentPostRun: func(cmd *cobra.Command, args []string) {
      fmt.Printf("Inside rootCmd PersistentPostRun with args: %v\n", args)
    },
  }

  var subCmd = &cobra.Command{
    Use:   "sub [no options!]",
    Short: "My subcommand",
    PreRun: func(cmd *cobra.Command, args []string) {
      fmt.Printf("Inside subCmd PreRun with args: %v\n", args)
    },
    Run: func(cmd *cobra.Command, args []string) {
      fmt.Printf("Inside subCmd Run with args: %v\n", args)
    },
    PostRun: func(cmd *cobra.Command, args []string) {
      fmt.Printf("Inside subCmd PostRun with args: %v\n", args)
    },
    PersistentPostRun: func(cmd *cobra.Command, args []string) {
      fmt.Printf("Inside subCmd PersistentPostRun with args: %v\n", args)
    },
  }

  rootCmd.AddCommand(subCmd)

  rootCmd.SetArgs([]string{""})
  rootCmd.Execute()
  fmt.Println()
  rootCmd.SetArgs([]string{"sub", "arg1", "arg2"})
  rootCmd.Execute()
}

输出

Inside rootCmd PersistentPreRun with args: []
Inside rootCmd PreRun with args: []
Inside rootCmd Run with args: []
Inside rootCmd PostRun with args: []
Inside rootCmd PersistentPostRun with args: []

Inside rootCmd PersistentPreRun with args: [arg1 arg2]
Inside subCmd PreRun with args: [arg1 arg2]
Inside subCmd Run with args: [arg1 arg2]
Inside subCmd PostRun with args: [arg1 arg2]
Inside subCmd PersistentPostRun with args: [arg1 arg2]

发生“unknown command”时的建议

当“unknown command”错误发生时,Cobra将自动打印建议。这使得Cobra在发生错字时的行为与git命令类似。例如:

$ hugo srever
Error: unknown command "srever" for "hugo"

Did you mean this?
        server

Run 'hugo --help' for usage.

建议基于注册的每个子命令,并使用Levenshtein distance的实现。每个匹配最小距离为2(忽略大小写)的已注册命令都将显示为建议。

如果你需要禁用建议或调整命令中的字符串距离,请使用:

command.DisableSuggestions = true

command.SuggestionsMinimumDistance = 1

您还可以使用SuggestFor属性显式地设置指定命令的建议名称。这允许对字符串距离不近,但在您的命令集中有意义的字符串以及一些您不需要别名的字符串提供建议。

例子:

$ kubectl remove
Error: unknown command "remove" for "kubectl"

Did you mean this?
        delete

Run 'kubectl help' for usage.

为您的命令生成文档
Cobra 可以基于以下格式的子命令、标志等生成文档:

Markdown
ReStructured Text
Man Page

生成bash补全
Cobra可以生成一个bash完成文件。如果在命令中添加更多信息,这些补全功能就会非常强大和灵活。你可以在Bash补全中信息。

官网链接:https://cobra.dev/

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

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

相关文章

成都爱尔李晓峰医生解析“秋季干眼症”!该如何远离

秋高气爽?相较于夏天不然湿热难忍&#xff0c;气候逐渐干燥似乎“好过”了些。但干燥不见得都是好事&#xff0c;环境空气的干同时让人体呈现“燥”&#xff0c;如皮肤干燥、喉痒、口干、干咳、便秘等不适&#xff0c;就连眼睛也不能幸免。 由于眼部水分较其他季节蒸发快&…

时序预测 | MATLAB实现NGO-GRU北方苍鹰算法优化门控循环单元时间序列预测

时序预测 | MATLAB实现NGO-GRU北方苍鹰算法优化门控循环单元时间序列预测 目录 时序预测 | MATLAB实现NGO-GRU北方苍鹰算法优化门控循环单元时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 MATLAB实现NGO-GRU北方苍鹰算法优化门控循环单元时间序列预测&#…

STM32F407 串口使用DMA方式通信

DMA的原理&#xff0c;就是利用寄存器方式进行读写&#xff0c;这样的好处就是相对于中断触发&#xff08;往往一个字节字节的就中断一次&#xff09;&#xff0c;CPU中断次数大大降少&#xff0c;提高了效率&#xff0c;但也影响了实时性。总体来说&#xff0c;对于一般的应用…

系统安装(一)CentOS 7 本地安装

CentOS与Ubuntu并称为Linux最著名的两个发行版&#xff0c;但由于笔者主要从事深度学习图像算法工作&#xff0c;Ubuntu作为谷歌和多数依赖库的亲儿子占据着最高生态位。但最近接手的一个项目里&#xff0c;甲方指定需要在CentOS7上运行项目代码&#xff0c;笔者被迫小小cos了一…

VS Code时间轴插件:MarkWhen

文章目录 简介时间格式事件格式 简介 MarkWhen是一款文本转时间轴的工具&#xff0c;非常好用&#xff0c;也十分炫酷。可在VS Code中搜索插件MarkWhen&#xff0c;点击安装&#xff0c;然后新建一个.mw后缀的文件&#xff0c;就可以使用了&#xff0c;下面举一个简单的例子 …

嵌入式笔试面试刷题(day15)

文章目录 前言一、Linux中的主设备号和次设备号1.查看方法2.主设备号和次设备号的作用 二、软件IIC和硬件IIC的区别三、变量的声明和定义区别四、static在C和C中的区别五、串口总线空闲时候的电平状态总结 前言 本篇文章继续讲解嵌入式笔试面试刷题&#xff0c;希望大家坚持跟…

PyTorch深度学习实战(17)——多任务学习

PyTorch深度学习实战&#xff08;17&#xff09;——多任务学习 0. 前言1. 多任务学习1.1 多任务学习基本概念1.2 多任务学习优势 2. 模型与数据集分析2.1 模型分析2.2 数据集介绍 3. 实现年龄估计和性别分类小结系列链接 0. 前言 多任务学习( Multi-Task Learning, MTL )是一…

SpringCloud Alibaba 整合Sentinel的基本使用

文章目录 一、什么是Sentinel二、Sentinel 的主要特性1. 流量控制&#xff1a;2. 熔断降级&#xff1a;3. 实时监控&#xff1a;4. 规则配置&#xff1a;5. 集成方便&#xff1a; 三、Sentinel 分为哪几部分:1. 核心库&#xff08;Java 客户端&#xff09;2. 控制台&#xff08…

Matlab图像处理-区域描述

一旦一幅图像的目标区域被确定&#xff0c;我们往往用一套描述子来表示其特性。选择区域描述子的动机不单纯为了减少在区域中原始数据的数量&#xff0c;而且也应有利于区别带有不同特性的区域。因此&#xff0c;当目标区域有大小、旋转、平移等方面的变化时&#xff0c;针对这…

ThreeJS-3D教学一基础场景创建

Three.js 是一个开源的 JS 3D 图形库&#xff0c;用于创建和展示高性能、交互式的 3D 图形场景。它建立在 WebGL 技术之上&#xff0c;并提供了丰富的功能和工具&#xff0c;使开发者可以轻松地构建令人惊叹的 3D 可视化效果。 Three.js 提供了一套完整的工具和 API&#xff0…

【深度学习】实验13 使用Dropout抑制过拟合

文章目录 使用Dropout抑制过拟合1. 环境准备2. 导入数据集3. 对所有数据的预测3.1 数据集3.2 构建神经网络 3.3 训练模型3.4 分析模型 4. 对未见过数据的预测4.1 划分数据集4.2 构建神经网络4.3 训练模型4.4 分析模型 5. 使用Dropout抑制过拟合5.1 构建神经网络5.2 训练模型5.3…

基于Qt4的拉格朗日插值实现及使用

目录 1 拉格朗日插值算法 2 实现思路 3 子程序编写 1 框架搭建 2 加载节点值 3 加载插值点 4 位置查找 5 二点线性插值 3 子程序使用 1 拉格朗日插值算法 拉格朗日插值是一种常用的散点插值算法,是是以法国十八世纪数学家约瑟夫拉格朗日命名的一种多项式插值方法。是…

python爬虫——爬取豆瓣top250电影数据(适合初学者)

前言&#xff1a; 爬取豆瓣top250其实是初学者用于练习和熟悉爬虫技能知识的简单实战项目&#xff0c;通过这个项目&#xff0c;可以让小白对爬虫有一个初步认识&#xff0c;因此&#xff0c;如果你已经接触过爬虫有些时间了&#xff0c;可以跳过该项目&#xff0c;选择更有挑…

Linux Shell 实现一键部署podman

podman 介绍 使用 Podman 管理容器、Pod 和映像。从本地环境中无缝使用容器和 Kubernetes&#xff0c;Podman 提供与 Docker 非常相似的功能&#xff0c;它不需要在你的系统上运行任何守护进程&#xff0c;并且它也可以在没有 root 权限的情况下运行。 Podman 可以管理和运行…

JavaWeb后端开发登录操作 登录功能 通用模板/SpringBoot整合

登录功能的思路 前端会传入两个参数:用户名和密码 在用户表中查询用户名,并校对相应的密码(涉及查询操作) SQL语句 select * from emp where username jingyong and password 123456; 如果有则成功,没有则登录失败.不可能为多个,因为添加了unique唯一约束,最终只会有一条 …

如何将转换器应用于时序模型

一、说明 在机器学习的广阔环境中&#xff0c;变压器作为建筑奇迹屹立不倒&#xff0c;以其复杂的设计和捕获复杂关系的能力重塑了我们处理和理解大量数据的方式。 自 2017 年创建第一台变压器以来&#xff0c;变压器类型呈爆炸式增长&#xff0c;包括强大的生成 AI 模型&#…

Kubernetes部署dolphindcheduler-3.1.8问题记录

温故知新 ⁉️问题记录❓问题一&#xff1a;Unschedulable 0/3 nodes are available: pod has unbound immediate PersistentVolumeClaims. preemption: 0/3 nodes are available: 3 No preemption victims found for incoming pod..❗解决方式&#xff1a;创建PV供应&#x1f…

ARM Soc内部总线

由于soc架构&#xff0c;把常用外设&#xff08;控制器&#xff09;集成到芯片内部&#xff0c;所以需要一种总线协调ARMcore与这些内部外设的通信&#xff0c;于是有了APB and AHB以及AXi这种片上总线。 同时要注意与常说的PC时代总线区分开&#xff1a; CPU总线&#xff08;…

刷题笔记24——完全二叉树的节点个数

有些事情是不能告诉别人的,有些事情是不必告诉别人的,有些事情是根本没有办法告诉别人的,而且有些事情是,即使告诉了别人,你也会马上后悔的。——罗曼罗兰 222. 完全二叉树的节点个数 java的幂运算要 (int) Math.pow(2,l1)-1计算满二叉树的节点数量公式&#xff1a;2 ^ height…

【面试题】—— Java多线程篇(17题)

文章目录 1.什么是多线程&#xff1f;2.线程和进程的区别&#xff1f;3.我们为什么要使用线程&#xff1f;线程的优缺点&#xff1f;4.创建线程的方法有哪些&#xff1f;5.线程的状态有哪些&#xff1f;6.线程的优先级&#xff1f;7.线程常用的方法以及其作用&#xff1f;8.使用…