go调用docker远程API(二)-docker API 的容器操作

文章目录

  • 1 获取容器列表
  • 2 查看指定容器信息
  • 3. 查看容器日志
  • 4 创建容器
    • 4.1 简单使用
      • 4.1.1 语法
      • 4.1.2 完整示例
    • 4.2 端口映射
      • 4.2.1 语法
      • 4.2.2 完整示例
    • 4.3 挂载本机目录/文件
      • 4.3.1 语法
      • 4.3.2 完整代码
  • 5. 启动容器
  • 6 停止容器
  • 7 删除(已停止的)容器
  • 8 进入容器执行命令
    • 8.1 语法
    • 8.2 完整示例

1 获取容器列表

  • 语法
func (cli *Client) ContainerList(ctx context.Context, options ContainerListOptions) ([]Container, error)
  • 语法示例
containers, err := Cli.ContainerList(context.Background(), types.ContainerListOptions{All: true})
  • 完整示例
package main

import (
	"bufio"
	"context"
	"fmt"
	"github.com/docker/docker/api/types"
	"github.com/docker/docker/client"
	"io"
	"log"
	"os"
)

func main() {
	cli, err := ConnectDocker()
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("docker 链接成功")
	}
	err = GetContainers(cli)
	if err != nil {
		fmt.Println(err)
	}
}

// ConnectDocker
// 链接docker
func ConnectDocker() (cli *client.Client, err error) {
	cli, err = client.NewClientWithOpts(client.WithAPIVersionNegotiation(), client.WithHost("tcp://10.10.239.32:2375"))
	if err != nil {
		fmt.Println(err)
		return nil, err
	}

	return cli, nil
}

// GetContainers
// 获取容器列表
func GetContainers(cli *client.Client) error {
	//All-true相当于docker ps -a
	containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true})
	if err != nil {
		fmt.Println(err)
		return err
	}

	for _, container := range containers {
		fmt.Printf("%s %s\n", container.ID[:10], container.Image)
	}
	return nil
}
  • 输出
docker 链接成功
08d317f408 harbocto.boe.com.cn/public/redis:4   
c91fc7eeb1 harbocto.boe.com.cn/public/mysql:5.7 
48bcf68112 harbocto.boe.com.cn/crow/crow-qin    
381f5b2790 harbocto.boe.com.cn/magicube/ibex:0.3

2 查看指定容器信息

  • 查看方法
func (cli *Client) ContainerInspect(ctx context.Context, containerID string) (ContainerJSON, error)

语法示例

	ctx := context.Background()
	containerJson, err := cli.ContainerInspect(ctx, containerId)
  • 返回结构体types.ContainerJSON
type ContainerJSON struct {
    *ContainerJSONBase
    Mounts          []MountPoint
    Config          *Config
    NetworkSettings *NetworkSettings
}
  • *ContainerJSONBase的内容
type ContainerJSONBase struct {
    ID              string `json:"Id"`
    Created         string
    Path            string
    Args            []string
    State           *ContainerState
    Image           string
    ResolvConfPath  string
    HostnamePath    string
    HostsPath       string
    LogPath         string
    Node            *ContainerNode `json:",omitempty"`
    Name            string
    RestartCount    int
    Driver          string
    Platform        string
    MountLabel      string
    ProcessLabel    string
    AppArmorProfile string
    ExecIDs         []string
    HostConfig      *HostConfig
    GraphDriver     GraphDriverData
    SizeRw          *int64 `json:",omitempty"`
    SizeRootFs      *int64 `json:",omitempty"`
}
  • 完整示例
package main

import (
	"context"
	"fmt"
	"github.com/docker/docker/api/types"
	"github.com/docker/docker/client"
)

func main() {
	cli, err := ConnectDocker()
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("docker 链接成功")
	}

	containerId := "48bcf6811212"
	containerJson, err := GetContainer(cli, containerId)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Printf("=======容器信息======\nID:%+v\name:%+v\n", containerJson.ID[:10], containerJson.Name)
}

func GetContainer(cli *client.Client, containerId string) (containerInfo types.ContainerJSON, err error) {
	ctx := context.Background()
	containerJson, err := cli.ContainerInspect(ctx, containerId)
	if err != nil {
		fmt.Println(err)
		return containerJson, err
	}
	return containerJson, nil
}
  • 打印结果
docker 链接成功
=======容器信息======   
ID:48bcf68112
ame:/crow-qin_crow_qin_1

3. 查看容器日志

  • 语法
func (cli *Client) ContainerLogs(ctx context.Context, container string, options ContainerLogsOptions) (io.ReadCloser, error)
  • 语法示例
ctx := context.Background()
	logs, err := Cli.ContainerLogs(ctx, containerId, types.ContainerLogsOptions{ShowStdout: true, Follow: true})
  • 参数
    • ShowStdout:标准输出
    • Follow:
      • true:实时日志
      • false:当前日志
  • 完整示例
func main() {
	cli, err := ConnectDocker()
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("docker 链接成功")
	}

	err = containerLogs(cli, "48bcf68112")
	if err != nil {
		fmt.Println(err)
	}
}

// ConnectDocker
// 链接docker
func ConnectDocker() (cli *client.Client, err error) {
	cli, err = client.NewClientWithOpts(client.WithAPIVersionNegotiation(), client.WithHost("tcp://10.10.239.32:2375"))
	if err != nil {
		fmt.Println(err)
		return nil, err
	}

	return cli, nil
}

//containerLogs
//获取容器日志
func containerLogs(cli *client.Client, containerId string) error {
	ctx := context.Background()
	logs, err := cli.ContainerLogs(ctx, containerId, types.ContainerLogsOptions{ShowStdout: true, Follow: true, ShowStderr: true})
	if err != nil {
		fmt.Println(err)
		return err
	}
	_, err = io.Copy(os.Stdout, logs)
	if err != nil {
		fmt.Println(err)
		return err
	}
	return nil
}

4 创建容器

4.1 简单使用

4.1.1 语法

  • ContainerCreate() 函数
func (cli *Client) ContainerCreate(ctx context.Context, config *Config, hostConfig *HostConfig, networkingConfig *NetworkingConfig, platform *Platform, containerName string) (CreateResponse, error)
  • 结构体 *container.Config

关于container的设置在此结构体

type Config struct {
    Hostname        string
    Domainname      string
    User            string
    AttachStdin     bool
    AttachStdout    bool
    AttachStderr    bool
    ExposedPorts    PortSet `json:",omitempty"`
    Tty             bool
    OpenStdin       bool
    StdinOnce       bool
    Env             []string
    Cmd             StrSlice
    Healthcheck     *HealthConfig `json:",omitempty"`
    ArgsEscaped     bool          `json:",omitempty"`
    Image           string
    Volumes         map[string]struct{}
    WorkingDir      string
    Entrypoint      StrSlice
    NetworkDisabled bool   `json:",omitempty"`
    MacAddress      string `json:",omitempty"`
    OnBuild         []string
    Labels          map[string]string
    StopSignal      string            `json:",omitempty"`
    StopTimeout     *int              `json:",omitempty"`
    Shell           StrSlice `json:",omitempty"`
}
  • 结构体**container.HostConfig

宿主机相关配置,在这个结构体中。

type HostConfig struct {
    Binds           []string
    ContainerIDFile string
    LogConfig       LogConfig
    NetworkMode     NetworkMode
    PortBindings    PortMap
    RestartPolicy   RestartPolicy
    AutoRemove      bool
    VolumeDriver    string
    VolumesFrom     []string
    ConsoleSize     [2]uint
    CapAdd          StrSlice
    CapDrop         StrSlice
    CgroupnsMode    CgroupnsMode
    DNS             []string `json:"Dns"`
    DNSOptions      []string `json:"DnsOptions"`
    DNSSearch       []string `json:"DnsSearch"`
    ExtraHosts      []string
    GroupAdd        []string
    IpcMode         IpcMode
    Cgroup          CgroupSpec
    Links           []string
    OomScoreAdj     int
    PidMode         PidMode
    Privileged      bool
    PublishAllPorts bool
    ReadonlyRootfs  bool
    SecurityOpt     []string
    StorageOpt      map[string]string `json:",omitempty"`
    Tmpfs           map[string]string `json:",omitempty"`
    UTSMode         UTSMode
    UsernsMode      UsernsMode
    ShmSize         int64
    Sysctls         map[string]string `json:",omitempty"`
    Runtime         string            `json:",omitempty"`
    Isolation       Isolation
    Resources
    Mounts        []Mount `json:",omitempty"`
    MaskedPaths   []string
    ReadonlyPaths []string
    Init          *bool `json:",omitempty"`
}
  • *network.NetworkingConfig
type NetworkingConfig struct {
    EndpointsConfig map[string]*EndpointSettings
}

4.1.2 完整示例

package main

import (
	"context"
	"fmt"
	"github.com/docker/docker/api/types/container"
	"github.com/docker/docker/api/types/network"
	"github.com/docker/docker/client"
)

func main() {
	cli, err := ConnectDocker()
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("docker 链接成功")
	}

	config := &container.Config{
		Image: "harbocto.boe.com.cn/crow/crow-qin",
		Tty:   true,
	}

	//创建容器
	containerId, err := CreateContainer(cli, config, nil, nil, "crow-test")
	if err != nil {
		fmt.Println(err)
	}
	//验证(用前文写的查找函数验证)
	containerInfo, err := GetContainer(cli, containerId)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Printf("成功创建容器%q,状态为:%q", containerInfo.ID[:10], containerInfo.State.Status)
}

// CreateContainer
// 创建容器
func CreateContainer(cli *client.Client, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, containerName string) (containerId string, err error) {
	ctx := context.Background()

	//创建容器
	resp, err := cli.ContainerCreate(ctx, config, hostConfig, networkingConfig, nil, containerName)
	if err != nil {
		fmt.Println(err.Error())
	}
	return resp.ID, nil
}
  • 输出
docker 链接成功
成功创建容器"c13a3deefb",状态为:"created"

4.2 端口映射

4.2.1 语法

  • 容器内端口 container.Config.ExposedPorts
    • 上文已经知道 container.Config是容器的配置,它的成员 ExposedPorts即是容器内部监听的端口。
    • ExposedPorts的类型是nat.PortSet
    • nat.PortSet的类型如下
      type PortSet map[Port]struct{}
      
    • 语法示例
      config := &container.Config{
      	Image: "harbocto.boe.com.cn/crow/crow-qin",
      	Tty:   true,
      	ExposedPorts: nat.PortSet{  //这里是容器内端口设置
      		"1840": struct{}{},
      	},
      }
      
  • 绑定容器外端口 container.HostConfig.PortBindings
    • 上文已经知道 container.HostConfig是宿主机的配置
    • 它的成员 PortBindings绑定容器内外端口。
    • ExposedPorts的类型是nat.PortMap
    • nat.PortMap的类型如下
      type PortMap map[Port][]PortBinding
      
    • PortBinding的类型如下
    type PortBinding struct {
        HostIP   string `json:"HostIp"`
        HostPort string
    }
    
    • 语法示例
    	hostConfig := &container.HostConfig{
      	PortBindings: nat.PortMap{
      		"1840": []nat.PortBinding{  //容器内端口
      			{
      				HostIP:   "0.0.0.0",
      				HostPort: "1841",  //容器外端口
      			},
      		},
      	},
      }
    

4.2.2 完整示例

func main() {
	cli, err := ConnectDocker()
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("docker 链接成功")
	}

	//创建容器
	//protMap := nat.PortSet{}
	config := &container.Config{
		Image: "harbocto.boe.com.cn/crow/crow-qin",
		Tty:   true,
		ExposedPorts: nat.PortSet{
			"1840": struct{}{},
		},
	}
	hostConfig := &container.HostConfig{
		PortBindings: nat.PortMap{
			"1840": []nat.PortBinding{
				{
					HostIP:   "0.0.0.0",
					HostPort: "1841",
				},
			},
		},
	}
	containerId, err := CreateContainer(cli, config, hostConfig, nil, "crow-qin-test")

	err = StartContainer(cli, containerId)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(containerId)

}

// CreateContainer
// 创建容器
func CreateContainer(cli *client.Client, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, containerName string) (containerId string, err error) {
	ctx := context.Background()
	//创建容器
	resp, err := cli.ContainerCreate(ctx, config, hostConfig, networkingConfig, nil, containerName)
	if err != nil {
		fmt.Println(err.Error())
	}
	return resp.ID, nil

}

// StartContainer
// 启动容器
func StartContainer(cli *client.Client, containerId string) error {
	ctx := context.Background()
	err := cli.ContainerStart(ctx, containerId, types.ContainerStartOptions{})
	if err != nil {
		fmt.Println(err)
		return err
	}
	return nil
}

4.3 挂载本机目录/文件

4.3.1 语法

  • 指明容器内目录 container.Config.Volumes
    • 类型:
      Volumes         map[string]struct{}
      
    • 语法示例
      config := &container.Config{
      	Image: "harbocto.boe.com.cn/crow/crow-qin",
      	Tty:   true,
      	Volumes: map[string]struct{}{
      		"/test01": {},
      	},
      }
      
  • 容器内外路径网绑定 container.HostConfig.Binds
    • 类型:[]string
    • 语法示例
      hostConfig := &container.HostConfig{
      	Binds: []string{"/tmp/liuBei.txt:/liuBei.txt"},
      }
      
  • 注意
    • 如果只有 container.Config.ExposedPorts,容器内目录将挂载到docker的默认位置(docker目录的 /volumes下)
    • 如果写了container.HostConfig.PortBindings,则 container.Config.ExposedPorts实际可以不写

4.3.2 完整代码

func main() {
	cli, err := ConnectDocker()
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("docker 链接成功")
	}

	//创建容器
	//protMap := nat.PortSet{}

	config := &container.Config{
		Image: "harbocto.boe.com.cn/crow/crow-qin",
		Tty:   true,
		Volumes: map[string]struct{}{ //如上文,本代码这里实际可以省略
			"/test01": {},
		},
	}
	hostConfig := &container.HostConfig{
		Binds: []string{"/tmp/test01:/test01"},
	}
	containerId, err := CreateContainer(cli, config, hostConfig, nil, "crow-qin-test")

	err = StartContainer(cli, containerId)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(containerId)
}
// CreateContainer
// 创建容器
func CreateContainer(cli *client.Client, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, containerName string) (containerId string, err error) {
	ctx := context.Background()
	//创建容器
	resp, err := cli.ContainerCreate(ctx, config, hostConfig, networkingConfig, nil, containerName)
	if err != nil {
		fmt.Println(err.Error())
	}
	return resp.ID, nil

}

// StartContainer
// 启动容器
func StartContainer(cli *client.Client, containerId string) error {
	ctx := context.Background()
	err := cli.ContainerStart(ctx, containerId, types.ContainerStartOptions{})
	if err != nil {
		fmt.Println(err)
		return err
	}
	return nil
}

5. 启动容器

  • 语法
func (cli *Client) ContainerStart(ctx context.Context, containerID string, options ContainerStartOptions) error
  • 语法示例
	ctx := context.Background()
	err := cli.ContainerStart(ctx, containerId, types.ContainerStartOptions{})
  • 完整示例
package main

import (
	"context"
	"fmt"
	"github.com/docker/docker/api/types"
	"github.com/docker/docker/client"
)

func main() {
	cli, err := ConnectDocker()
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("docker 链接成功")
	}

	containerId := "c13a3deefb"
	err = StartContainer(cli, containerId)
	if err != nil {
		fmt.Println(err)
	}
	//验证(用前文写的查找函数验证)
	containerInfo, err := GetContainer(cli, containerId)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Printf("成功启动容器%q\n状态为:%q", containerInfo.ID[:10], containerInfo.State.Status)
}

//StartContainer
// 启动容器
func StartContainer(cli *client.Client, containerId string) error {
	ctx := context.Background()
	err := cli.ContainerStart(ctx, containerId, types.ContainerStartOptions{})
	if err != nil {
		fmt.Println(err)
		return err
	}
	return nil
}
  • 输出
docker 链接成功
成功启动容器"c13a3deefb"
状态为:"running"  

如上可见,我们刚才创建的容器状态从created变为running

6 停止容器

  • 语法
func (cli *Client) ContainerStart(ctx context.Context, containerID string, options ContainerStartOptions) error
  • 语法示例
ctx := context.Background()
err := cli.ContainerStart(ctx, containerId, types.ContainerStartOptions{})
  • 完整示例
package main

import (
	"context"
	"fmt"
	"github.com/docker/docker/api/types/container"
	"github.com/docker/docker/client"
)

func main() {
	cli, err := ConnectDocker()
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("docker 链接成功")
	}

	containerId := "c13a3deefba9"
	err = StopContainer(cli, containerId)
	if err != nil {
		fmt.Println(err)
	}
	//验证(用前文写的查找函数验证)
	containerInfo, err := GetContainer(cli, containerId)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Printf("成功停止容器%q\n状态为:%q", containerInfo.ID[:10], containerInfo.State.Status)
}

// StopContainer
// 停止容器
func StopContainer(cli *client.Client, containerId string) error {
	ctx := context.Background()
	err := cli.ContainerStop(ctx, containerId, container.StopOptions{})
	if err != nil {
		fmt.Println(err)
		return err
	}
	return nil
}

7 删除(已停止的)容器

  • 语法
func (cli *Client) ContainerRemove(ctx context.Context, containerID string, options ContainerRemoveOptions) error
  • 语法示例
	ctx := context.Background()
	err := cli.ContainerRemove(ctx, containerId, types.ContainerRemoveOptions{})
  • 完整示例
package main

import (
	"context"
	"fmt"
	"github.com/docker/docker/api/types"
	"github.com/docker/docker/client"
)

func main() {
	cli, err := ConnectDocker()
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("docker 链接成功")
	}

	containerId := "c13a3deefba9"
	err = DeleteContainer(cli, containerId)
	if err != nil {
		fmt.Println(err)
	}

	//验证(用前文写的查找函数验证)
	b, err := CheckContainer(cli, containerId)
	if err != nil {
		fmt.Println(err)
	}
	if b == false {
		fmt.Println("删除成功")
	} else {
		fmt.Println("删除失败")
	}
}

// DeleteContainer
// 删除已停止容器
func DeleteContainer(cli *client.Client, containerId string) error {
	ctx := context.Background()
	err := cli.ContainerRemove(ctx, containerId, types.ContainerRemoveOptions{})
	if err != nil {
		fmt.Println(err)
		return err
	}
	return nil
}
// CheckContainer
// 获取容器信息
func CheckContainer(cli *client.Client, containerId string) (result bool, err error) {
	ctx := context.Background()
	containerJson, err := cli.ContainerInspect(ctx, containerId)
	if err != nil {
		fmt.Println(err)
		return false, err
	}
	if containerJson.ContainerJSONBase == nil {
		return false,nil
	}
	fmt.Println(containerJson)
	return true, nil
}

8 进入容器执行命令

本文仅演示示例,实际应用参见本人文档《gin框架使用websocket实现进入容器内部执行命令》

8.1 语法

  • 创建配置

说明:创建一个新的exec配置来运行exec进程。

func (cli *Client) ContainerExecCreate(ctx context.Context, container string, config ExecConfig) (IDResponse, error)

语法示例

	ir, err := dockerCli.ContainerExecCreate(ctx, containerId, types.ExecConfig{
		AttachStdin:  true,
		AttachStdout: true,
		AttachStderr: true,
		Cmd:          []string{"/bin/sh"},
		Tty:          true,
	})
  • 将链接附加到exec进程

语法

func (cli *Client) ContainerExecAttach(ctx context.Context, execID string, config ExecStartCheck) (HijackedResponse, error)

语法示例

hr, err := cli.ContainerExecAttach(ctx, ir.ID, types.ExecStartCheck{Detach: false, Tty: true})
  • 命令传入
_, err = hr.Conn.Write([]byte("ls\r"))

8.2 完整示例

  • 代码
package main

import (
	"bufio"
	"context"
	"fmt"
	"github.com/docker/docker/api/types"
	"github.com/docker/docker/client"
	"io"
	"log"
	"os"
)


func main() {
	cli,err := ConnectDocker()
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("docker 链接成功")
	}
	//GetContainers()
	err = ExecContainer(cli,"48bcf68112")
	if err != nil {
		fmt.Println(err)
	}

}

// ConnectDocker
// 链接docker
func ConnectDocker() (cli *client.Client,err error)  {
	cli, err = client.NewClientWithOpts(client.WithAPIVersionNegotiation(), client.WithHost("tcp://10.10.239.32:2375"))
	if err != nil {
		fmt.Println(err)
		return nil,err
	}
	
	return cli,nil
}



func ExecContainer(cli *client.Client, containerId string) error {

	ctx := context.Background()
	//创建进程
	ir, err := cli.ContainerExecCreate(ctx, containerId, types.ExecConfig{
		AttachStdin:  true,
		AttachStdout: true,
		AttachStderr: true,
		Cmd:          []string{"/bin/sh"},
		Tty:          true,
	})
	if err != nil {
		return err
	}

	// 将链接附加到exec进程
	hr, err := cli.ContainerExecAttach(ctx, ir.ID, types.ExecStartCheck{Detach: false, Tty: true})
	if err != nil {
		return err
	}
	// 关闭链接和读取器
	defer hr.Close()

	// 输入一条命令
	_, err = hr.Conn.Write([]byte("echo liuBei > xiShu.txt\r"))
	if err != nil {
		return err
	}
	//输入第二条命令
	_, err = hr.Conn.Write([]byte("cat xiShu.txt\r"))
	if err != nil {
		return err
	}

	//输出
	scanner := bufio.NewScanner(hr.Conn)
	for scanner.Scan() {
		fmt.Println(scanner.Text())
		if err != nil {
			log.Println("写入错误", err)
			continue
		}
	}

	return nil
}

  • 结果输出
docker 链接成功
/ # echo liuBei > xiShu.txt
/ # cat xiShu.txt
liuBei

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

线程池的7种创建方式

文章目录普通方式创建线程存在的问题什么是线程池线程池的好处线程池设计思路线程池相关类的继承关系线程池的创建方式固定容量线程池——FixedThreadPool相关构造方法示例运行结果缓存线程池——CachedThreadPool相关构造方法示例运行结果单线程线程池——SingleThreadExecuto…

关于国产化系统银河麒麟(Kylin)的问题记录--持续更新

kylin 镜像 : Kylin-Server-10-SP2-x86-Release-Build09-20210524 Kylin-Server-10-SP1-Release-Build20-20210518-x86_64 1.ansible 模块无法使用yum 报错:"msg": "The Python 2 bindings for rpm are needed for this module. If you r…

Dart语言操作符?和!的用法

一.基本使用 1. ? 操作符跟在类型后面,表示当前变量可为null。 int a null; //这句代码在有空安全时,编译会提示错误如果想给一个变量赋值null要如何处理呢?只需要在类型 后面添加操作符?即可,eg: int? a null…

UWB高精度定位系统源码,工业安全定位系统源码

基于VueSpring boot前后端分离架构开发的一套UWB高精度定位系统源码。有演示。 文末获取联系 系统采用UWB高精度定位技术,可实现厘米级别定位。UWB作为一种高速率、低功耗、高容量的新兴无线局域定位技术,目前应用主要聚焦在室内外精确定位。在工业自动化…

spring boot 实现根据用户名查找用户功能

目录 1、UserEnetity类 2、UserMapper类 3、UserService类 4、UserController类 5、postman测试结果 为了实现根据用户名查询用户功能,我们需要在spring boot框架当中编写一下几个类: 1、UserEnetity类 它是根据数据库表的实体类,用于…

Downie 4 4.6.13 MAC上最好的一款视频下载工具

Downie for Mac 简介 Downie是Mac下一个简单的下载管理器,可以让您快速将不同的视频网站上的视频下载并保存到电脑磁盘里然后使用您的默认媒体播放器观看它们。 Downie 4 Downie 4 for Mac Downie 4 for Mac软件特点 支持许多站点 -当前支持1000多个不同的站点&…

蓝桥杯第19天(Python)(疯狂刷题第2天)

题型: 1.思维题/杂题:数学公式,分析题意,找规律 2.BFS/DFS:广搜(递归实现),深搜(deque实现) 3.简单数论:模,素数(只需要…

国产ARM+FPGA架构在“能源电力”中的典型应用详解

能源电力作为国民经济发展的“先导产业”和“基础行业”,面对当今复杂多变的国际形势,国内能源电力企业为追求更高的自主可控,正不断寻求各种经过行业验证的国产方案。 而单ARM架构已很难应对能源电力多通道/高速AD数据采集、处理、存储和显示的应用场景。目前,ARM + FPGA异…

Linux系统-gunzip命令简介以及常用参数

命令 – 解压提取文件内容 gzip命令 gzip命令是一种数据压缩方式,它是在Linux操作系统中常用的一种压缩工具,是GNU项目中自带的压缩程序之一。它是采用Lempel-Ziv编码(LZ77)和哈夫曼编码(Huffman Coding)进行压缩数据的,被广泛应用于软件发…

用Qt编写STM32烧录软件(ISP模式)代码

1.前言 之前写了一篇【用Qt编写STM32烧录软件(ISP模式)】,但是在文中没有具体的实现代码。 现在补上,各位有兴趣的同学可以参考以下。但是代码里面还有很多没有完善的,必定会存在一些bug,目前只是堪堪能用…

redis-数据结构、io

1.redis 数据结构 1.1 字典 kv是什么 每个键值对都会是一个dictEntry set hello word为例,因为Redis是KV键值对的数据库,每个键值对都会有一个dictEntry(源码位置:dict.h) 简单描述 加载原理 server 启动,加载redisdb进内存形…

厉害了!Facebook优惠广告让你的广告预算翻倍

如果你是一个企业主或者市场营销人员,你可能已经知道Facebook广告平台是一个强大的数字广告工具,可以帮助你推广产品和服务,并且吸引潜在客户到你的网站上。 而今天,我们将教你如何创建和投放Facebook优惠广告以及如何利用这些广…

【Redis学习】Redis事务

理论简介 是什么 可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞。 能干嘛 一个队列中,一次性、顺序性、排他性的执行一系列命令 Redis事务 V…

花3个月面过华为测开岗,拿个30K不过分吧?真不是凡尔赛。。。

背景介绍 美本计算机专业,代码能力一般,之前有过两段实习以及一个学校项目经历。第一份实习是大二暑期在深圳的一家互联网公司做前端开发,第二份实习由于大三暑假回国的时间比较短(小于两个月),于是找的实…

Apsara Clouder阿里巴巴开发规范认证

apsara n. 飞天;阿普萨拉 俗话说:“没有规矩,不成方圆。”今天我们来介绍一下,阿里巴巴对于开发规范的考试认证。 报名地址: https://edu.aliyun.com/certification/cldt04 1.证书 我们先来看一下考试通过的证书&…

vue 实现左滑图片验证

前言 众所周知,网页中滑动图片验证一直是各大网站、移动端的主流校验方式,其主要作用是为了区分人和机器以及为了防止机器人程序暴力登录或攻击从而设置的一种安全保护方式。从开发的角度来看要想实现这个功能还是需要一点时间的,但其实网上已…

C++源码剖析——forward_list

前言:之前看过侯老师的《STL源码剖析》但是那已经是多年以前的,现在工作中有时候查问题和崩溃都需要了解实际工作中使用到的STL的实现。因此计划把STL的源码再过一遍。   摘要:本文描述了llvm中libcxx的forward_list的实现。   关键字&am…

【排序算法】排序算法介绍及插入排序 ( 直接插入排序 希尔排序 )

​ ​📝个人主页:Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:数据结构 🎯长路漫漫浩浩,万事皆有期待 文章目录1.排序的概念和运用1…

关于Warning: World-writable config file ‘/etc/mysql/my.cnf‘ is ignored

不知道那个大兄弟,更改了my.cnf的权限为 0777 登陆mysqll的时候提示:Warning: World-writable config file /etc/mysql/my.cnf is ignored 里面的配置被忽略了, my.cnf不起作用 如果不是安装在docker里面的话,直接 chmod 0644 /etc/mysql/…

Java每日一练(20230405)

目录 1. 地下城游戏 🌟🌟🌟 2. 汇总区间 🌟🌟 3. 寻找旋转排序数组中的最小值 II 🌟🌟 🌟 每日一练刷题专栏 🌟 Golang每日一练 专栏 Python每日一练 专栏 C/C…