2024-08-23

在Go语言中,并发编程主要通过goroutine和channel来实现。

  1. goroutine

    goroutine 是 Go 语言中并发的核心。它是一种轻量级的线程,




package main
 
import (
    "fmt"
    "time"
)
 
func hello() {
    fmt.Println("Hello world goroutine")
}
 
func main() {
    go hello() // 启动一个goroutine
 
    fmt.Println("main function done")
    time.Sleep(1 * time.Second) // 等待goroutine执行完成
}
  1. channel

    channel 是 goroutine 之间通信的一种方式。




package main
 
import (
    "fmt"
    "time"
)
 
func sum(a []int, c chan int) {
    total := 0
    for _, v := range a {
        total += v
    }
    c <- total // 把sum结果发送到channel c
}
 
func main() {
    a := []int{7, 2, 8, -9, 4, 0}
 
    c := make(chan int) // 创建一个channel
    go sum(a[:len(a)/2], c) // 计算a的前半部分的和
    go sum(a[len(a)/2:], c) // 计算a的后半部分的和
 
    x, y := <-c, <-c // 从channel接收计算结果
 
    fmt.Println(x, y, x + y)
    time.Sleep(1 * time.Second)
}
  1. select

    select 语句用于处理多个通道的发送和接收操作。




package main
 
import (
    "fmt"
    "time"
)
 
func fibonacci(c, quit chan int) {
    x, y := 0, 1
    for {
        select {
        case c <- x:
            x, y = y, x+y
        case <-quit:
            fmt.Println("quit")
            return
        }
    }
}
 
func main() {
    c := make(chan int)
    quit := make(chan int)
 
    go func() {
        time.Sleep(1 * time.Second)
        quit <- 0
    }()
 
    fibonacci(c, quit)
}
  1. 并发和并行

    并发 (concurrency) 是指同时处理多个任务,但在任意时刻只有一个任务在执行。

    并行 (parallelism) 是指同时处理多个任务,且多个任务在同时执行。




package main
 
import (
    "fmt"
    "runtime"
    "sync"
    "time"
)
 
var wg sync.WaitGroup
 
func worker(id int, wg *sync.WaitGroup) {
    defer wg.Done() // 在函数退出时执行,相当于计数器减一
    fmt.Printf("Worker %d starting\n", id)
    time.Sleep(2 * time.Second)
    fmt.Printf("Worker %d done\n", id)
}
 
func main() {
    runtime.GOMAXPROCS(1) // 设置为1核心,模拟并发
 
    for i := 1; i <= 3; i++ {
        wg.Add(1) // 将等待组计数器加一
        go worker(i, &wg) // 创建新的goroutine执行worker函数
    }
 
    wg.Wait() // 等待所有goroutine完成
}

以上代码展示了如何使用Go语言的并发特性来实现并发操作。通过创建goroutine,我们可以同时处理多个任务,而不需要额外的线

2024-08-23



package main
 
import (
    "golang.org/x/crypto/ssh"
    "golang.org/x/crypto/ssh/terminal"
    "io/ioutil"
    "log"
    "os"
)
 
func main() {
    // 读取私钥文件
    privateKey, err := ioutil.ReadFile("path/to/private/key")
    if err != nil {
        log.Fatalf("unable to read private key: %v", err)
    }
 
    // 创建SSH签名签名
    signer, err := ssh.ParsePrivateKey(privateKey)
    if err != nil {
        log.Fatalf("unable to parse private key: %v", err)
    }
 
    // 创建SSH客户端配置
    config := &ssh.ClientConfig{
        User: "username",
        Auth: []ssh.AuthMethod{
            ssh.PublicKeys(signer),
        },
        HostKeyCallback: ssh.InsecureIgnoreHostKey(), // 用于学习目的,不推荐在生产环境中使用
    }
 
    // 连接SSH服务器
    client, err := ssh.Dial("tcp", "server.com:22", config)
    if err != nil {
        log.Fatalf("unable to connect: %v", err)
    }
    defer client.Close()
 
    // 建立会话
    session, err := client.NewSession()
    if err != nil {
        log.Fatalf("unable to create session: %v", err)
    }
    defer session.Close()
 
    // 设置会话的标准输入、输出和错误输出
    session.Stdin = os.Stdin
    session.Stdout = os.Stdout
    session.Stderr = os.Stderr
    session.Run("/bin/date") // 执行远程命令
}

这段代码展示了如何使用Go语言通过SSH协议连接到一个远程服务器,并执行一个简单的命令。它使用了golang.org/x/crypto/ssh包来处理SSH密钥交换和加密算法。代码中包含了错误处理,并且为了简洁起见,忽略了主机密钥的检查,通常在生产环境中不推荐这么做。

2024-08-23



# 安装 Golang
 
# 下载最新版本的 Golang 二进制包
wget https://dl.google.com/go/go1.15.6.linux-amd64.tar.gz
 
# 解压到 /usr/local 目录
sudo tar -C /usr/local -xzf go1.15.6.linux-amd64.tar.gz
 
# 将 Golang bin 目录添加到 PATH 环境变量中
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bash_profile
 
# 刷新当前 shell 的环境变量
source ~/.bash_profile
 
# 验证安装
go version
 
 
# 卸载 Golang
 
# 删除 /usr/local/go 目录
sudo rm -rf /usr/local/go
 
# 从 ~/.bash_profile 中移除 PATH 设置
sed -i 's/:\/usr\/local\/go\/bin//' ~/.bash_profile
 
# 刷新当前 shell 的环境变量
source ~/.bash_profile
 
 
# 升级 Golang 运行环境
 
# 下载新版本的 Golang 二进制包,替换旧版本
# 下载地址从 Golang 官网获取
# 解压到 /usr/local/go,替换旧目录
# 刷新当前 shell 的环境变量
# 验证新版本

上述代码提供了在 CentOS 系统中安装、卸载和升级 Golang 的简要步骤。需要注意的是,每个版本的 Golang 可能有不同的下载地址,请从官方网站获取最新的下载链接。此外,环境变量的修改可能需要根据实际情况进行适当调整。

2024-08-23



package main
 
import (
    "fmt"
    "github.com/spf13/viper"
)
 
// 定义响应结构体
type Response struct {
    Code    int         `json:"code"`
    Message string      `json:"message"`
    Data    interface{} `json:"data"`
}
 
// 标准化返回格式
func StandardizeResponse(code int, message string, data interface{}) Response {
    return Response{
        Code:    code,
        Message: message,
        Data:    data,
    }
}
 
func main() {
    // 使用viper读取配置文件
    viper.SetConfigName("config") // 配置文件名称(不包含扩展名)
    viper.SetConfigType("json")   // 配置文件扩展名
    viper.AddConfigPath(".")      // 配置文件所在路径
    err := viper.ReadInConfig()   // 读取配置文件
    if err != nil {
        fmt.Printf("Error reading config file, %s", err)
        return
    }
 
    // 获取配置项
    port := viper.GetInt("server.port")
    fmt.Printf("服务器将在端口 %d 运行\n", port)
}

这段代码展示了如何定义一个标准化的响应结构体,并使用viper库来读取配置文件中的内容。代码简洁,注重实用性,可以作为Go语言初学者学习的样本。

2024-08-23

在Go中,测量代码测试覆盖率通常使用go test命令结合一个额外的工具,如go-cover。以下是如何使用go-cover来查看测试覆盖率的步骤:

  1. 安装go-cover工具:



go get -u github.com/matm/go-cover
  1. 运行测试并生成覆盖率文件:



go test -coverprofile=cover.out
  1. 使用go-cover工具查看覆盖率:



$GOPATH/bin/go-cover -html=cover.out

这将在默认的网页浏览器中打开一个HTML文件,显示测试覆盖率的详细信息。

注意:go-cover工具可能不是最新的,可以直接使用go tool命令查看覆盖率:




go tool cover -html=cover.out

这个命令会直接在命令行终端打开一个本地的Web服务器,显示覆盖率报告的网页。

2024-08-23



package main
 
import (
    "bytes"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
)
 
func main() {
    // 创建HTTP请求体
    postBody, _ := json.Marshal(map[string]string{
        "name": "John Doe",
        "age":  "30",
    })
 
    // 将请求体转换为字节序列
    requestBody := bytes.NewBuffer(postBody)
 
    // 发送HTTP POST请求
    resp, err := http.Post("http://example.com/post", "application/json", requestBody)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()
 
    // 读取响应体
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }
 
    // 打印响应内容
    fmt.Println(string(body))
}

这段代码演示了如何在Go中创建一个HTTP POST请求,并发送JSON格式的数据。首先,它创建了一个包含JSON数据的请求体。然后,它使用http.Post函数发送请求,并设置了正确的Content-Type头部。最后,它读取并打印了响应体。

2024-08-23

以下是一个简单的Golang程序示例,使用webview库来创建一个显示特定URL的跨平台桌面应用。

首先,确保你已经安装了webview库。如果没有安装,可以使用以下命令安装:




go get github.com/webview/webview

然后,你可以创建一个简单的Golang程序,如下所示:




package main
 
import "github.com/webview/webview"
 
func main() {
    // 初始化一个webview窗口,并设置窗口大小和标题
    w := webview.New(webview.NewWindow("Hello WebView", width, height, true))
    defer w.Destroy()
 
    // 在webview中加载一个网页
    w.Navigate("https://example.com")
    w.Run()
}
 
const (
    width  = 800
    height = 600
)

这个程序会创建一个窗口,窗口的标题是"Hello WebView",大小是800x600,并且在这个窗口中加载了"https://example.com"这个网页。

请注意,你需要根据实际需求替换widthheight的值,以及将w.Navigate("https://example.com")中的URL替换为你想要显示的网址。

2024-08-23

在Go语言中,如果你想发起一个HTTPS请求并忽略SSL证书验证,你可以使用http.Transport结合http.Client。设置TLSClientConfigInsecureSkipVerify字段为true可以实现这个目的。

以下是一个示例代码:




package main
 
import (
    "crypto/tls"
    "net/http"
    "log"
    "io/ioutil"
)
 
func main() {
    // 创建一个tls配置,忽略服务器的SSL证书验证
    tlsConfig := &tls.Config{
        InsecureSkipVerify: true,
    }
 
    // 创建一个使用自定义tls配置的transport
    transport := &http.Transport{
        TLSClientConfig: tlsConfig,
    }
 
    // 创建一个使用自定义transport的client
    client := &http.Client{
        Transport: transport,
    }
 
    // 发起一个https请求
    resp, err := client.Get("https://example.com")
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()
 
    // 读取响应内容
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatal(err)
    }
 
    log.Println(string(body))
}

在这个例子中,我们创建了一个http.Transport实例,设置了TLSClientConfig来忽略SSL证书验证。然后我们使用这个http.Transport创建了一个http.Client实例,并用它来发起一个HTTPS请求。请注意,在实际环境中忽略SSL证书验证可能会带来安全风险,所以请谨慎使用。

2024-08-23



package main
 
import (
    "encoding/json"
    "fmt"
)
 
// 假设我们有一个包含不同类型字段的JSON结构
// 这些字段的具体类型在解析之前是未知的
type DynamicField struct {
    Type  string
    Value interface{}
}
 
func main() {
    // 示例JSON数据,包含不同类型的字段
    jsonData := []byte(`{"Type":"string","Value":"Hello, World!"}`)
    jsonDataInt := []byte(`{"Type":"int","Value":42}`)
    jsonDataBool := []byte(`{"Type":"bool","Value":true}`)
 
    var field DynamicField
 
    // 反序列化字符串字段
    if err := json.Unmarshal(jsonData, &field); err != nil {
        panic(err)
    }
    fmt.Printf("String field: %v\n", field.Value)
 
    // 反序列化整数字段
    if err := json.Unmarshal(jsonDataInt, &field); err != nil {
        panic(err)
    }
    fmt.Printf("Int field: %v\n", field.Value)
 
    // 反序列化布尔字段
    if err := json.Unmarshal(jsonDataBool, &field); err != nil {
        panic(err)
    }
    fmt.Printf("Bool field: %v\n", field.Value)
}

这段代码演示了如何处理JSON中类型不定的字段。我们定义了一个结构体DynamicField,其中的Value字段是空接口类型,可以存储任何类型的值。通过反序列化,我们可以根据Type字段将JSON数据中的值映射到适当的Go类型上。这种方法可以用于处理不规则或者动态类型的数据。

2024-08-23



# 下载并安装Go语言
wget https://dl.google.com/go/go1.14.4.linux-amd64.tar.gz
sudo tar -xvf go1.14.4.linux-amd64.tar.gz -C /usr/local
 
# 设置环境变量
echo "export PATH=$PATH:/usr/local/go/bin" >> ~/.bashrc
source ~/.bashrc
 
# 验证安装
go version
 
# 下载并解压GoLand
wget https://download.jetbrains.com/goland/goland-2019.3.tar.gz
tar -xvf goland-2019.3.tar.gz
 
# 移动GoLand到opt目录下
sudo mv goland-2019.3/ /opt/goland
 
# 进入安装目录并运行安装脚本
cd /opt/goland/bin
./goland.sh
 
# 注册并激活GoLand,按照提示操作

以上脚本提供了在Linux环境下配置Go语言开发环境以及安装GoLand的步骤。注意,具体的Go版本和GoLand版本可能会更新,请根据实际情况下载最新版本。同时,安装过程中可能需要输入注册信息以及安装许可协议。