【Go学习】-01-6-数据库泛型新特性

news2025/1/7 12:26:57

【Go学习】-01-6-数据库泛型新特性

  • 1 数据库操作
    • 1.1 操作mysql
      • 1.1.1 Insert
      • 1.1.2 Select
      • 1.1.3 Update
      • 1.1.4 Delete
      • 1.1.5 sql事务
    • 1.2 go操作Redis
  • 2 泛型
    • 2.1 非泛型函数
    • 2.2 泛型函数
    • 2.3 泛型类型
      • 2.3.1 泛型结构体
      • 2.3.2 泛型接口
    • 2.4 泛型约束
    • 2.5 泛型切片和映射
      • 2.5.1 泛型切片
      • 2.5.2 泛型映射
    • 2.6 泛型实际应用
  • 3 workspace
    • 3.1 概念
    • 3.2 workspace案例
  • 4 模糊测试
    • 4.1概念
    • 4.2 如何使用模糊测试
    • 4.3 模糊测试常见用法
    • 4.4 自定义输入生成


1 数据库操作

1.1 操作mysql

创建go_learn数据库后创建user表

CREATE TABLE `user` (
    `user_id` int(11) NOT NULL AUTO_INCREMENT,
    `username` varchar(255) DEFAULT NULL,
    `sex` varchar(255) DEFAULT NULL,
    `email` varchar(255) DEFAULT NULL,
    PRIMARY KEY (`user_id`)
  ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

mysql的前置知识,我们这里就不讲了,可自行去学习mysql教程

在这里插入图片描述

1.1.1 Insert

首先,需要引入mysql驱动

通过go get github.com/go-sql-driver/mysql@v1.6.0引入依赖

_ "github.com/go-sql-driver/mysql"

我们的数据库地址是192.168.101.68:3306

用户名:root

密码:mysql

插入一条记录:名字bblb,性别man,邮箱bblb123456789@qq.com

package main

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"log"
	"time"
)

var DB *sql.DB

func init() {
	db, err := sql.Open("mysql", "root:mysql@tcp(192.168.101.68:3306)/go_learn")
	if err != nil {
		panic(err)
	}
	//最大空闲连接数,默认不配置,是2个最大空闲连接
	db.SetMaxIdleConns(5)
	//最大连接数,默认不配置,是不限制最大连接数
	db.SetMaxOpenConns(100)
	// 连接最大存活时间
	db.SetConnMaxLifetime(time.Minute * 3)
	//空闲连接最大存活时间
	db.SetConnMaxIdleTime(time.Minute * 1)
	err = db.Ping()
	if err != nil {
		log.Println("数据库连接失败")
		db.Close()
		panic(err)
	}
	DB = db

}

func save() {
	r, err := DB.Exec("insert into user (username,sex,email) values(?,?,?)", "bblb", "man", "bblb123456789@qq.com")
	if err != nil {
		log.Println("执行sql语句出错")
		panic(err)
	}
	id, err := r.LastInsertId()
	if err != nil {
		panic(err)
	}
	fmt.Println("插入成功:", id)
}
func main() {
	defer DB.Close()
	save()
}

查看数据库

在这里插入图片描述

1.1.2 Select

type User struct {
	UserId   int    `db:"user_id"`
	Username string `db:"username"`
	Sex      string `db:"sex"`
	Email    string `db:"email"`
}

func query(id int)  (*User,error) {
	rows, err := DB.Query("select * from user where user_id=? limit 1", id)
	if err != nil{
		log.Println("查询出现错误:",err)
		return nil,errors.New(err.Error())
	}
	user := new(User)
	for rows.Next() {
		if err := rows.Scan(&user.UserId,&user.Username,&user.Sex,&user.Email); err != nil{
			log.Println("scan error:",err)
			return nil,errors.New(err.Error())
		}
	}
	return user,nil
}
func main() {
	defer DB.Close()
	//save()
	user,err := query(2)
	if err != nil{
		log.Println("查询出现错误:",err)
		return
	}
	fmt.Printf("查询成功:%+v\n",user)
}

可以看到我们刚刚插入的id是2所以查2

查询成功:&{UserId:2 Username:bblb Sex:man Email:bblb123456789@qq.com}

1.1.3 Update

func update(username string, id int)  {
	ret, err := DB.Exec("update user set username=? where user_id=?", username, id)
	if err != nil {
		log.Println("更新出现问题:",err)
		return
	}
	affected, _ := ret.RowsAffected()
	fmt.Println("更新成功的行数:",affected)
}

1.1.4 Delete

func delete(id int)  {
	ret, err := DB.Exec("delete from user where user_id=?", id)
	if err != nil {
		log.Println("删除出现问题:",err)
		return
	}
	affected, _ := ret.RowsAffected()
	fmt.Println("删除成功的行数:",affected)
}

1.1.5 sql事务

mysql事务特性:

  1. 原子性
  2. 一致性
  3. 隔离性
  4. 持久性
func insertTx(username string)  {
	tx, err := DB.Begin()
	if err != nil {
		log.Println("开启事务错误:",err)
		return
	}
	ret, err := tx.Exec("insert into user (username,sex,email) values (?,?,?)", username, "man", "test@test.com")
	if err != nil {
		log.Println("事务sql执行出错:",err)
		return
	}
	id, _ := ret.LastInsertId()
	fmt.Println("插入成功:",id)
	if username == "lisi" {
		fmt.Println("回滚...")
		_ = tx.Rollback()
	}else {
		_ = tx.Commit()
	}

}

1.2 go操作Redis

redis不另行介绍,默认会,如果不了解,先去学习redis教程

安装:go get github.com/go-redis/redis/v8

package main

import (
	"context"
	"fmt"
	"github.com/go-redis/redis/v8"
)

func main() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "192.168.101.68:6379",
		Password: "redis", // no password set
		DB:       0,       // use default DB
	})

	err := rdb.Set(ctx, "key", "value", 0).Err()
	if err != nil {
		panic(err)
	}

	val, err := rdb.Get(ctx, "key").Result()
	if err != nil {
		panic(err)
	}
	fmt.Println("key", val)

	val2, err := rdb.Get(ctx, "key2").Result()
	if err == redis.Nil {
		fmt.Println("key2 does not exist")
	} else if err != nil {
		panic(err)
	} else {
		fmt.Println("key2", val2)
	}
}

在这里插入图片描述

2 泛型

2.1 非泛型函数

两个 不同类型的映射:一种用于存储值,一种用于存储值。int64float64

package main

import "fmt"

// SumInts adds together the values of m.
func SumInts(m map[string]int64) int64 {
    var s int64
    for _, v := range m {
       s += v
    }
    return s
}

// SumFloats adds together the values of m.
func SumFloats(m map[string]float64) float64 {
    var s float64
    for _, v := range m {
       s += v
    }
    return s
}
func main() {
    // Initialize a map for the integer values
    ints := map[string]int64{
       "first":  34,
       "second": 12,
    }

    // Initialize a map for the float values
    floats := map[string]float64{
       "first":  35.98,
       "second": 26.99,
    }

    fmt.Printf("Non-Generic Sums: %v and %v\n",
       SumInts(ints),
       SumFloats(floats))
}

针对不同的类型我们都需要写对应的函数来进行求和,这是非常麻烦的

2.2 泛型函数

Go 1.18 引入了泛型(Generics),这是 Go 语言的一项重大更新。通过泛型,Go 开发者可以编写更通用、更可复用的代码,而不需要手动编写多个类型的重复代码。

为了支持这一点,将编写一个函数,在添加到其普通函数参数中。这些类型参数使 function generic,使其能够处理不同类型的参数。将使用类型参数和普通函数参数调用函数。

package main

import "fmt"

// 定义一个泛型函数,接受一个类型参数 T
func Print[T any](value T) {
    fmt.Println(value)
}

func main() {
    Print(123)    // 输出: 123
    Print("hello") // 输出: hello
}

T 是类型参数,any 是 Go 1.18 中的类型约束,表示可以是任何类型。

在函数 Print[T any](value T) 中,T 是类型参数,表示 value 参数的类型。

可以为类型参数指定约束,使其只能是某些特定的类型。例如,限制类型参数只能是整数类型:

package main

import "fmt"

// 定义一个泛型函数,限制 T 类型为整型(int, int32, int64)
func Sum[T int | int32 | int64](a, b T) T {
    return a + b
}

func main() {
    fmt.Println(Sum(1, 2))     // 输出: 3
    fmt.Println(Sum(int32(3), int32(4))) // 输出: 7
}

2.3 泛型类型

2.3.1 泛型结构体

泛型不仅可以用于函数,也可以用于结构体和接口。

package main

import "fmt"

// 定义一个泛型结构体,类型参数 T
type Pair[T any] struct {
    First  T
    Second T
}

func main() {
    // 使用泛型结构体,传入 int 类型
    pair1 := Pair[int]{First: 1, Second: 2}
    fmt.Println(pair1) // 输出: {1 2}

    // 使用泛型结构体,传入 string 类型
    pair2 := Pair[string]{First: "hello", Second: "world"}
    fmt.Println(pair2) // 输出: {hello world}
}

在这个例子中,Pair[T any] 是一个泛型结构体,T 代表结构体字段的类型。

2.3.2 泛型接口

package main

import "fmt"

// 定义一个泛型接口,支持多种数值类型(int, float64)
type Adder[T int | float64] interface {
    Add(a, b T) T
}

// 泛型类型:支持任意数值类型
type NumberAdder[T int | float64] struct{}

func (na NumberAdder[T]) Add(a, b T) T {
    return a + b
}

func main() {
    // 使用 NumberAdder 支持 int 类型
    intAdder := NumberAdder[int]{}
    fmt.Println(intAdder.Add(3, 4)) // 输出: 7

    // 使用 NumberAdder 支持 float64 类型
    floatAdder := NumberAdder[float64]{}
    fmt.Println(floatAdder.Add(3.0, 4.0)) // 输出: 7.0
}

在这里,Adder[T any] 是一个泛型接口,NumberAdder 实现了这个接口。

2.4 泛型约束

泛型支持类型约束,用于指定类型参数的合法类型范围。类型约束通过 interface{} 或更具体的接口来实现。

Go 1.18 提供了一些内置的类型约束,如 any(表示任何类型)和 comparable(表示可以进行比较的类型)。

package main

import "fmt"

// 定义一个泛型函数,约束 T 为可比较类型
func Compare[T comparable](a, b T) bool {
    return a == b
}

func main() {
    fmt.Println(Compare(1, 1))       // 输出: true
    fmt.Println(Compare("a", "b"))   // 输出: false
    // fmt.Println(Compare([]int{1}, []int{1}))  // 编译错误: slices are not comparable
}

在这个例子中,T comparable 限制了类型参数 T 必须是可以进行比较的类型。

2.5 泛型切片和映射

泛型在 Go 中也支持切片(slices)和映射(maps)等常见数据结构。

2.5.1 泛型切片

package main

import "fmt"

func PrintSlice[T any](s []T) {
    for _, v := range s {
        fmt.Println(v)
    }
}

func main() {
    PrintSlice([]int{1, 2, 3})      // 输出: 1 2 3
    PrintSlice([]string{"a", "b"})  // 输出: a b
}

2.5.2 泛型映射

package main

import "fmt"

// 泛型映射,支持任意类型作为键和值
func PrintMap[K comparable, V any](m map[K]V) {
    for k, v := range m {
        fmt.Println(k, v)
    }
}

func main() {
    m1 := map[string]int{"a": 1, "b": 2}
    PrintMap(m1) // 输出: a 1  b 2

    m2 := map[int]string{1: "one", 2: "two"}
    PrintMap(m2) // 输出: 1 one  2 two
}

2.6 泛型实际应用

Go 中可以用于实现许多常见的算法和数据结构,如链表、栈、队列等。

package main

import "fmt"

type Stack[T any] struct {
    items []T
}

func (s *Stack[T]) Push(item T) {
    s.items = append(s.items, item)
}

func (s *Stack[T]) Pop() T {
    if len(s.items) == 0 {
        panic("stack is empty")
    }
    item := s.items[len(s.items)-1]
    s.items = s.items[:len(s.items)-1]
    return item
}

func main() {
    stack := &Stack[int]{}
    stack.Push(1)
    stack.Push(2)
    fmt.Println(stack.Pop()) // 输出: 2
    fmt.Println(stack.Pop()) // 输出: 1
}

3 workspace

go 1.18 引入了 workspace 功能,旨在简化多个模块(module)的管理和开发。workspace 允许你在一个工作空间中同时管理多个 Go 模块,这对于开发大型项目或依赖多个模块时非常有用。

3.1 概念

工作空间(workspace)是 Go 1.18 引入的一个新概念,它可以包含多个 Go 模块。这样,你可以在同一个目录下处理多个模块(module),而无需通过 $GOPATH 来管理它们。

在 Go 1.18 版本中,你需要通过创建一个名为 go.work 的文件来启用工作空间。这个文件定义了工作空间内的 Go 模块及其路径。

3.2 workspace案例

工作空间文件 go.work 用来指定工作空间中包含的模块。例如,如果你有多个模块在不同的目录中,可以在 go.work 中列出它们的路径。

假设你有两个模块 moduleAmoduleB,它们位于不同的文件夹中,你可以在根目录下创建一个 go.work 文件,将这两个模块包括在内:

go 1.23

use (
    ./moduleA
    ./moduleB
)

这将指示 Go 使用 moduleAmoduleB 两个模块进行构建。

一旦设置了 go.work 文件,Go 命令会自动识别工作空间并处理模块之间的依赖关系。例如,你可以使用 go buildgo run 命令时,Go 会自动处理跨模块依赖。

例如,运行 go run . 时,Go 会处理 go.work 文件并且可以跨模块找到所需的依赖,而不需要单独执行每个模块的命令。

假设你有以下文件结构:

/workspace
    go.work
    /moduleA
        go.mod
        main.go
    /moduleB
        go.mod
        main.go

go.work 文件:

go 1.23

use (
    ./moduleA
    ./moduleB
)

moduleA/go.mod 文件:

module moduleA

go 1.23

moduleB/go.mod 文件:

module moduleB

go 1.23

moduleB/utilsB 文件:

package moduleB

import "fmt"

func HelloB() {
    fmt.Println("HelloB")
}

moduleA/main 文件:

package main

import "moduleB"

func main() {
    moduleB.HelloB()
}

在根目录 /workspace 下运行 go run 或其他 Go 命令。

Go 会处理 go.work 中列出的模块路径,并根据需求解析、构建或运行所有模块。

Go 1.18 引入的工作空间功能使得多模块管理变得更为简单,适用于大型项目或需要协调多个模块的开发场景。通过创建 go.work 文件,可以让 Go 项目更好地管理跨模块依赖,同时提高开发效率和可维护性。

4 模糊测试

Go 1.18 引入了 模糊测试(Fuzzing)功能,它是一种自动化的测试技术,用于发现程序中的潜在缺陷和安全漏洞。模糊测试通过自动生成大量的随机输入数据来测试程序的健壮性,帮助开发者发现代码中的异常行为、崩溃、内存泄漏等问题。

在 Go 1.18 中,模糊测试被集成到了标准库中,你可以直接在 Go 中进行模糊测试,而不需要额外的工具或库。

4.1概念

模糊测试是一种通过向程序输入大量随机、无意义的(或者故意设计的异常的)数据来检测程序潜在漏洞的技术。它主要用于:

  • 发现代码中的边界情况、崩溃、未处理的异常等。
  • 测试程序对异常输入的处理能力,增强程序的健壮性。
  • 通过大量随机的输入数据测试算法、输入验证、错误处理等方面。

4.2 如何使用模糊测试

Go 1.18 引入了对模糊测试的内置支持,允许通过 testing 包来编写模糊测试函数。模糊测试的函数以 Fuzz 开头,使用 testing 包中的 Fuzz 类型来定义。

基本步骤:

  1. 创建模糊测试函数:在测试代码中定义一个模糊测试函数,函数的参数是一个类型为 testing.F 的对象,代表模糊测试框架。
  2. 编写测试逻辑:在模糊测试函数内部,编写逻辑来处理模糊输入并验证输出。
  3. 运行测试:使用 go test 命令来运行模糊测试。

示例:

假设我们有一个函数 Add,它简单地将两个整数相加。

package main

import "fmt"

func Add(a, b int) int {
    return a + b
}

我们可以编写一个模糊测试函数来测试 Add 函数。

定义模糊测试函数:

package main

import (
    "testing"
)

func FuzzAdd(f *testing.F) {
    // 预设一些初始的模糊测试用例
    f.Add(1, 2)
    f.Add(3, 4)

    // 模糊测试逻辑
    f.Fuzz(func(t *testing.T, a, b int) {
        result := Add(a, b)

        // 简单验证:返回的结果是否为预期
        if result != a+b {
            t.Errorf("Add(%d, %d) = %d; want %d", a, b, result, a+b)
        }
    })
}

在这个示例中,我们使用 f.Add 来添加初始的输入值,之后通过 f.Fuzz 来生成随机的输入对,并使用 t.Errorf 来报告结果是否符合预期。

运行模糊测试:

你可以通过 go test 来运行模糊测试。

go test -fuzz=FuzzAdd

此命令会开始执行模糊测试并生成随机的测试输入来执行 Add 函数。Go 会根据生成的输入验证函数行为是否正确。

模糊测试参数

  • f.Add: 用于为模糊测试提供初始输入。这些输入会在测试过程中作为种子,基于这些种子数据,Go 会生成更多的随机数据。
  • f.Fuzz: 用于定义实际的模糊测试逻辑。这里你可以编写逻辑来处理模糊输入并进行断言。

4.3 模糊测试常见用法

模糊测试特别适用于以下几种场景:

  • 函数边界情况测试:例如,测试字符串处理函数是否能正确处理空字符串、特殊字符、非常长的字符串等。
  • 错误处理验证:验证程序在接收到不合法输入时是否会崩溃或产生错误。
  • 性能和压力测试:通过给定极限的输入来检查程序在边界条件下的表现。

4.4 自定义输入生成

Go 的模糊测试功能允许开发者对生成的输入进行更细粒度的控制。例如,你可以为模糊测试提供自定义的输入生成器,来专门生成特定类型的测试数据。

示例:自定义输入生成

func FuzzCustomInput(f *testing.F) {
    f.Add([]byte("initial input"))

    f.Fuzz(func(t *testing.T, data []byte) {
        if len(data) > 100 {
            t.Errorf("input data too long: %v", data)
        }
    })
}

运行模糊测试的其他选项

  • -fuzztime: 设置运行模糊测试的时间限制。默认情况下,模糊测试会一直运行直到手动停止,可以通过 -fuzztime 参数来控制运行时长。

    go test -fuzz=FuzzAdd -fuzztime=30s
    

    这将限制模糊测试的运行时间为 30 秒。

  • -fuzzminimize: 尝试最小化产生错误的测试用例,这样可以帮助开发者快速定位问题。

    go test -fuzz=FuzzAdd -fuzzminimize
    

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

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

相关文章

STM32-笔记20-测量按键按下时间

1、按键按下的时间-思路 我们先检测下降沿信号,检测到以后,在回调函数里切换成检测上升沿信号,当两个信号都检测到的时候,这段时间就是按键按下的时间,如图所示:>N*(ARR1)CCRx的值 N是在这段时间内&…

【数据结构-堆】力扣2530. 执行 K 次操作后的最大分数

给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。你的 起始分数 为 0 。 在一步 操作 中&#xff1a; 选出一个满足 0 < i < nums.length 的下标 i &#xff0c; 将你的 分数 增加 nums[i] &#xff0c;并且 将 nums[i] 替换为 ceil(nums[i] / 3) 。 返回在 恰好…

软件逆向之标志位

进位标志CF&#xff08;Carry Flag&#xff09; 介绍&#xff1a;如果运算结果的最高位产生了一个进位&#xff08;加法&#xff09;或借位&#xff08;减法&#xff09;&#xff0c;那么&#xff0c;其值为1&#xff0c;否则其值为0。无符号数。 示例&#xff1a; mov al&…

api接口技术开发系列如何调用电商平台的按图搜索商品API?

不同电商平台的按图搜索商品 API 调用方法大致相似&#xff0c;以下是一般的调用步骤&#xff1a; 注册与获取权限 注册账号&#xff1a;在相应的电商开放平台注册成为开发者&#xff0c;如淘宝平台、1688 平台等。创建应用&#xff1a;登录后创建应用&#xff0c;填写应用的相…

【Seed-Labs 2.0】Buffer Overflow Attack Lab (Server Version)

说在前面 实验总述 缓冲区溢出是指程序试图写入超出缓冲区边界的数据。恶意用户可利用这一漏洞改变程序的流控制&#xff0c;从而导致恶意代码的执行。本实验的目的是让学生从实践中了解这种类型的漏洞&#xff0c;并学习如何在攻击中利用这种漏洞。 在本实验中&#xff0c;…

WPS表格技巧01-项目管理中的基本功能-计划和每日记录的对应

前言&#xff1a; 在项目管理中&#xff0c;一般就是用些项目管理工具来管理这个任务和 task&#xff0c;但是就是要学这些工具很麻烦&#xff0c;比较好的方法&#xff0c;通用的方法就是用 Excel 表格去做&#xff08;这非常适合松散的团队组织&#xff09;&#xff0c;然后…

SpringBoot入门之创建一个Hello World项目

文章目录 一、使用传统的方式1、创建一个SpringBoot项目2、配置pom.xml文件3、下载Maven依赖4、创建一个Controller类&#xff1a;com.devops.controller.HelloController5、创建一个引导类&#xff1a;com.devops.HelloApplication6、启动项目8、访问80809、完整项目结构 二、…

机器学习笔记 - 单幅图像深度估计的最新技术

1、深度估计简述 单眼深度估计是一项计算机视觉任务,AI 模型从单个图像中预测场景的深度信息。模型估计场景中对象从一个照相机视点的距离。单目深度估计已广泛用于自动驾驶、机器人等领域。深度估计被认为是最困难的计算机视觉任务之一,因为它要求模型理解对象及其深度信息之…

探索AI在地质科研绘图中的应用:ChatGPT与Midjourney绘图流程与效果对比

文章目录 个人感受一、AI绘图流程1.1 Midjourney&#xff08;1&#xff09;环境配置&#xff08;2&#xff09;生成prompt&#xff08;3&#xff09;完善prompt&#xff08;4&#xff09;开始绘图&#xff08;5&#xff09;后处理 1.2 ChatGPT不合理的出图结果解决方案 二、主题…

HTML——28.音频的引入

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>音频引入</title></head><body><!--audio:在网页中引入音频当属性名和属性值一样&#xff0c;可以只写属性名src属性:指定音频文件路径&#xff0c;必…

SMTP发送邮件的过程

&#xff08;1&#xff09;SMTP客户端首先请求与服务器端的25号端口建立TCP连接(1分)。&#xff08;2&#xff09;连接建立成功后&#xff0c;客户端和服务器通过握手阶段验证双方身份(1分)。&#xff08;3&#xff09;验证成功后&#xff0c;客户端首先向服务器端通告邮件发送…

计算机毕设-基于springboot的酒店管理系统的设计与实现(附源码+lw+ppt+开题报告)

博主介绍&#xff1a;✌多个项目实战经验、多个大型网购商城开发经验、在某机构指导学员上千名、专注于本行业领域✌ 技术范围&#xff1a;Java实战项目、Python实战项目、微信小程序/安卓实战项目、爬虫大数据实战项目、Nodejs实战项目、PHP实战项目、.NET实战项目、Golang实战…

从零开始RTSP协议的实时流媒体拉流(pull)的设计与实现(一)

此文为系列文章&#xff0c;此系列主要讲解RTSP客户端的拉流及播放&#xff0c;文章持续更新&#xff0c;会从rtsp的基本协议讲起&#xff0c;如何一步步实现音视频的拉流过程&#xff0c;包括一系列涉及到的协议&#xff0c;rtsp&#xff0c;sdp&#xff0c; rtp&#xff08;本…

量子力学复习

黑体辐射 热辐射 绝对黑体&#xff1a; &#xff08;辐射能力很强&#xff0c;完全的吸收体&#xff0c;理想的发射体&#xff09; 辐射实验规律&#xff1a; 温度越高&#xff0c;能量越大&#xff0c;亮度越亮 温度越高&#xff0c;波长越短 光电效应 实验装置&#xf…

如何排查 Apache Doris 中 “Failed to commit txn“ 导入失败问题?

今天来聊聊 Doris 数据导入那些事儿。你是不是在数据导入的时候遇到各种状况&#xff0c;让人头疼不已&#xff1f;别担心&#xff0c;这篇文章给你答案&#xff01; 在 Doris 的版本里&#xff0c;< 2.0.3 的时候&#xff0c;数据迁移存在一些已知的问题&#xff0c;比如可…

基于AT89C51单片机的可暂停八路抢答器设计

点击链接获取Keil源码与Project Backups仿真图&#xff1a; https://download.csdn.net/download/qq_64505944/90196607?spm1001.2014.3001.5503 C15 部分参考设计如下&#xff1a; 摘要 随着社会进步和科技发展&#xff0c;电子设备在各类活动中的应用日益普遍&#xff0c…

OSCP - Proving Grounds - Pelican

主要知识点 当信息多的时候&#xff0c;耐心搜索Zookeeper exhibitor RCE漏洞 具体步骤 依旧执行Nmap Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-10-13 22:44 UTC Nmap scan report for 192.168.54.98 Host is up (0.00090s latency). Not shown: 65526 closed …

计算机毕业设计PyHive+Hadoop深圳共享单车预测系统 共享单车数据分析可视化大屏 共享单车爬虫 共享单车数据仓库 机器学习 深度学习

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

WebRtc01:课程导学、框架介绍

应用 难点 课程大纲 学习收获 涉及内容 概述 用途 学习收获

特殊车辆检测数据集VOC+YOLO格式2730张3类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;2730 标注数量(xml文件个数)&#xff1a;2730 标注数量(txt文件个数)&#xff1a;2730 …