【Golang笔记02】函数、方法、泛型、接口学习笔记
Golang笔记02:函数、方法、泛型、接口学习笔记
一、进阶学习
1.1、函数
go
中的函数使用func
关键字进行定义,go
程序的入口函数叫做:main
,并且必须是属于main包
里面。
1.1.1、定义函数
(1)普通函数
go
中定义函数,需要使用func
关键字,同时要指定函数名称,函数参数,函数返回值,函数体,这就是函数的五要素。语法格式:
func 函数名称(参数1,参数2,...)(返回值类型1,返回值类型2,...) {// 函数体
}// 当只有一个返回值类型的时候,可以省略括号(),直接写类型即可
go
语言中,函数允许返回多个返回值
,这个语法和其他的一些编程语言是有些区别的,比如:Java
语言中,只允许一个函数返回一个返回值。go
语言中,函数的特点:
- 允许返回多个返回值。
- 不允许函数重载。
// Method01 定义函数
func Method01() int {return 1 + 2
}// Method02 定义函数
func Method02(a int, b int) (int,int) {return a + b, a - b;
}
另外,如果函数参数的类型都是一致的,那么可以简写成下面这种方式:
// Method02 定义函数,参数类型相同,则可以简写
func Method02(a, b int) (int,int) {return a + b, a - b;
}
(2)函数字面量
函数字面量,是指将函数作为一个变量先定义出来,接着在需要使用的时候,通过func
重新定义一个函数,然后函数字面量指向func
函数。如下所示:
package mainimport "fmt"// 先定义一个函数字面量,函数体不定义
var method func(int, int) (int, int)// Method02 定义函数
func Method02(a int, b int) (int, int) {return a + b, a - b
}func main() {// 这里给函数字面量,指向具体的函数实现method := func(a int, b int) (int, int) {return a + b, a - b}// 调用函数add, sub := method(1, 2)fmt.Println(add, sub)
}
1.1.2、函数参数和返回值
(1)函数参数
go
语言中的函数参数,如果是相同数据类型的,则可以统一定义类型,不需要每个参数都写出类型名称。格式:
func 函数名称(参数1,参数2,参数3 数据类型)(返回值1,返回值2...) {// 函数体
}
另外,go
中函数参数的传递是值传递
,也就是说,函数参数传递的时候,会拷贝实参的值。在函数体内修改函数参数的值,不会影响实参的值。
如果要定义可变参数,那么可以使用【...
】符号,并且可变参数只能够在最后一个参数位置出现。
// 可变参数
func Method03(args ...int) {}
(2)函数返回值
go
语言中,函数的返回值允许定义多个,当只有一个返回值,则可以不写括号,超过一个返回值的时候,则必须使用括号将所有返回值包裹起来。
// 只有一个返回值,可以省略返回值的括号
func demo() int {}
// 多返回值
func demo() (int,string){}
另外,go
中函数返回值也可以定义名称,定义返回值名称之后,那么这个参数就可以在函数体中直接使用,并且通过return
返回结果。
// Method02 定义函数
func Method02(a, b int) (add int,sub int) {// 可以使用函数返回值名称add = a + bsub = a - b// 定义了返回值名称,则return的时候,可以不写// 等价于 return add, subreturn//return add, sub
}
1.1.3、匿名函数
匿名函数,顾名思义,就是没有函数名称的函数。匿名函数一般在函数内部使用,语法格式:
package mainimport "fmt"func main() {// 定义匿名函数,并且调用函数ans := func(a, b int) int {ans := a + breturn ans}(1, 2)fmt.Println(ans)
}
匿名函数也可以作为一个函数的参数,例如:
package mainimport "fmt"// 定义函数,并且函数接受一个函数作为参数
func demo(a, b int, call func(int, int) int) int {return call(a, b)
}func main() {// 调用函数ans := demo(1, 2, func(a, b int) int {return a * b})fmt.Println(ans)// 调用函数ans2 := demo(1, 2, func(a, b int) int {return a + b})fmt.Println(ans2)
}
1.1.4、闭包
go
语言中,函数有一个闭包的概念,闭包在一些编程语言中,又叫做:Lamda
表达式。闭包,可以在内部函数中访问到外部函数的变量,即使外部函数已经执行完毕,内部函数仍然可以访问到外部的变量,这个过程就叫做:闭包。
- 【
闭包=匿名函数+外部环境变量引用
】
下面给一个闭包的案例:
package mainimport "fmt"func main() {// 创建一个匿名函数,并且返回值是一个函数类型sum := func() func() int {a, b := 1, 1// 返回一个匿名函数,相当于回调函数,并且还修改外部函数 a、b 两个变量的值return func() int {// 引用外部函数的变量a, b = b, a+breturn a}}// 调用函数,并且返回值是个回调函数getSum := sum()for i := 0; i < 10; i++ {// 调用回调函数,由于闭包的特性,回调函数中仍然可以使用 sum() 函数中的变量 a、bfmt.Println(getSum())}
}
闭包结构中,外部函数执行结束之后,内部函数就相当于一个回调函数一样,仍然可以被继续调用,并且还可以使用外部函数中的变量。另外,多次调用外部函数获取到的回调函数,是互不影响的。
package mainimport "fmt"func demo() func() int {count := 0return func() int {count++return count}
}func main() {// 第一次调用外部函数f1 := demo()fmt.Println("调用f1()函数")fmt.Println(f1())fmt.Println(f1())fmt.Println(f1())// 第二次调用外部函数f2 := demo()fmt.Println("调用f2()函数")fmt.Println(f2())fmt.Println(f2())fmt.Println(f2())fmt.Println("再次调用 f1() 函数")// 再次调用 f1() 函数fmt.Println(f1())
}
上面案例中,就是演示的多次调用外部函数,获取到的回调函数之间是互不影响的。运行结果如下所示:
调用f1()函数
1
2
3
调用f2()函数
1
2
3
再次调用 f1() 函数
4
从上面的执行结果可以看到,f1()
和f2()
之间的闭包结构是互不影响的。
1.1.5、延迟调用
go
语言中,提供了一个defer
关键字,可以用于声明函数的延迟调用功能。defer
声明的延迟函数,会在外部函数执行完成之前,调用延迟函数,一般用于释放文件资源,关闭连接等操作。
注意:当一个函数中,存在多个
defer
定义的延迟函数,那么go
会根据后进先出的规则,依次调用延迟函数。
怎么理解执行完成之前,才会调用defer
延迟函数呢???
- 当声明了
defer
函数的代码块内,执行到最后一行代码语句,后面已经没有可执行的语句的时候,但是函数还没有结束执行,只有遇到函数的最后一个右花括号【}】,才算执行结束。 - 那么
defer
函数,就是在遇到右花括号【}】之前,会被调用的。
package mainimport "fmt"func deferDemo() {fmt.Println("3、执行延迟函数...")
}func main() {fmt.Println("1、执行main函数代码...")// 采用延迟函数的方式,调用方法,将在 main 函数执行完成之前,调用 deferDemo() 函数defer deferDemo()fmt.Println("2、执行main函数最后一句代码...")
}// 控制台输入结果
1、执行main函数代码...
2、执行main函数最后一句代码...
3、执行延迟函数...
从上面案例代码中,可以看到,虽然defer
函数声明在中间位置,但是从控制台输出的结果来看,defer
函数的内容确是最后打印出来的,这也就说明defer
函数是最后执行的。
注意了,当存在多个defer延迟函数的时候,Go语言会按照后进先出的顺序,依次执行defer延迟函数。案例代码:
package mainimport "fmt"func demo01() {fmt.Println("调用demo01()函数...")
}
func demo02() {fmt.Println("调用demo02()函数...")
}
func demo03() {fmt.Println("调用demo03()函数...")
}func main() {fmt.Println("开始执行main函数...")// 定义延迟函数defer demo02()defer demo01()defer demo03()fmt.Println("main函数执行完成...")
}// 执行结果
开始执行main函数...
main函数执行完成...
调用demo03()函数...
调用demo01()函数...
调用demo02()函数...
1.2、方法
go语言中,既有函数,又有方法,在其他的语言中,一般情况下,函数和方法都是同一个概念,但是在go语言里面,两者是有点不同的。
go中的函数和方法,在定义形式上大体相同,只不过方法的定义,需要显示的声明方法的接收者,只有接收者才可以调用方法。方法定义格式:
// 自定义方法接收者的类型
type 接收者类型名称 接收者实际数据类型func (方法接收者名称 接收者类型名称) 方法名称(方法参数) 返回值类 {// 方法体
}
什么是方法接收者呢???要如何理解方法接收者这个概念???
- 方法的接收者,可以理解成是方法的调用者,它是规定哪一种数据类型的对象,可以调用这个方法。
go
语言中的方法接收者,就类似于java
语言中的this
关键字,例如:this.demo()
,这个this
就是方法的接收者,也可以理解成调用者。
方法的调用一般需要和自定义类型结合使用。
调用方法的语法格式:
变量名称 := 值
变量名称.方法名称()
方法的调用和函数的调用有点区别,函数是直接在代码中调用即可,不需要指定是由谁触发的调用。而方法,则需要指定具体的调用对象,是由哪个变量对象触发的方法调用。
package mainimport "fmt"// MyInt 先自定义一个类型
type MyInt intfunc (myInt MyInt) setValue(value int) {// 修改参数值myInt = MyInt(value)fmt.Println("方法中,修改的值=", myInt)
}func main() {var myInt MyInt = 1fmt.Println("修改之前的值=", myInt)// 调用方法myInt.setValue(2)fmt.Println("调用方法,修改之后的值=", myInt)
}// 执行结果
修改之前的值= 1
方法中,修改的值= 2
调用方法,修改之后的值= 1
从上面案例代码中,可以看到,我们虽然调用了setValue()
方法去修改myInt
的变量,但是方法执行完成之后,myInt
的值仍然没有变化,这是为什么呢???
这就涉及到一个知识点了,方法的接收者分为两种情况:值接收者
和指针接收者
。
1.2.1、值接收者
go
中方法的值接收者,是指方法接收者是通过值传递到方法里面的,传递的是形参,修改形参是不会影响到实际参数的。这和Java
中的值传递的概念相同。
要想在方法里面,修改接收者的数据,那就需要通过指针接收者来实现。
1.2.2、指针接收者
方法指针接收者,这和Java
中的引用传递的概念相同,在一个方法中,对引用传递
的参数进行修改,实际上是对这个引用地址指向的数据进行了修改,会影响实际的参数。
go
中的指针接收者作用就和Java
引用传递作用相同,通过指针接收者修改数据,会将实际参数的值也一起更新了。
package mainimport "fmt"// MyInt 先自定义一个类型
type MyInt int// 方法接收者采用指针类型
func (myInt *MyInt) setValue(value int) {// 修改参数值*myInt = MyInt(value)fmt.Println("方法中,修改的值=", *myInt)
}func main() {var myInt MyInt = 1fmt.Println("修改之前的值=", myInt)// 调用方法,虽然 myInt 这里是值类型,但是 Go 会将其编译之后,就相当于是 (&myInt).setValue(2)myInt.setValue(2)fmt.Println("调用方法,修改之后的值=", myInt)
}// 执行结果
修改之前的值= 1
方法中,修改的值= 2
调用方法,修改之后的值= 2
1.3、接口介绍
Go
中的接口分为两大类:基本接口
和通用接口
。
- 基本接口:接口内部是一组方法的集合。
- 通用接口:接口内部是一组类型的集合。
接口,是一组规范的集合,也就是说,接口只会规定实现功能的规范,但是具体的功能逻辑是怎么实现的,接口不负责,具体的功能实现交给具体的实现类。
在Go
中没有类与继承的概念,而是通过结构体来实现类的功能,那么在接口实现上,也是通过结构体来实现的。你可以怎么理解,创建一个struct
结构体,就相当于是Java
中创建了一个Class
类。
1.3.1、基本接口
Go
中定义接口需要使用interface
关键字,这个关键字用于标识是接口类型。
(1)定义接口
基本接口的语法格式,如下所示:
// 基本接口的定义
type 接口名称 interface {// 定义方法方法名称(参数类型) 返回值类型方法名称(参数类型) 返回值类型方法名称(参数类型) 返回值类型
}
在定义基本接口的时候,接口内部只能够是一组方法的集合,不能存在其他的类型集合。针对接口中的方法,方法参数可以不用写参数名称,只需要指定类型即可,因为接口不具备实现逻辑,也就不会使用方法参数,所以写不写参数名称都没关系,但是类型是必须要规定的。
package mainimport "fmt"// BaseInterface 定义基本接口
type BaseInterface interface {// Say 定义两个方法Say(string) stringWalk()
}func main() {// 初始化接口var baseInterface BaseInterfacefmt.Println(baseInterface)
}
上面代码,就是定义了一个基本接口,并且在main
函数中,初始化了接口,但是这个接口还没有具体实现,只是初始化了。
(2)接口实现
接口定义好了之后,那么要如何实现这个接口中的方法呢???Go
语言中没有提供类似Java
中的implements
关键字,那么要怎么样才能实现接口呢???
在Go
语言中,接口的实现方式很简单,只需要一种类型(结构体或者自定义类型
)将接口中的所有方法都实现了,那么我们就说,这个类型实现了某某接口。
package mainimport "fmt"// BaseInterface 定义基本接口
type BaseInterface interface {// Say 定义两个方法Say(string) stringWalk()
}// CustomType 定义类型,实现接口
type CustomType struct{}// Say CustomType 实现 BaseInterface 接口的方法
func (customType CustomType) Say(s string) string {fmt.Println("CustomType实现接口:saying..." + s)return s
}// Walk CustomType 实现 BaseInterface 接口的方法
func (customType CustomType) Walk() {fmt.Println("CustomType实现接口:walking...")
}func main() {
}
上面案例代码中,自定义了CustomType
结构体类型,然后这个结构体定义了两个方法,方法和接口中定义的方法名称一致,那么这种情况下,CustomType
类型就是实现了BaseInterface
接口了。
Go
语言中接口的实现都是隐式的,不像Java
中的接口实现那样,还需要使用implements
关键字才能够实现接口。
(3)使用接口
实现接口之后,就需要在相应的地方,使用接口实现来完成业务功能啦。使用接口很简单,其实就是通过接口的实现类,调用对应的接口方法即可。
package mainimport "fmt"// BaseInterface 定义基本接口
type BaseInterface interface {// Say 定义两个方法Say(string) stringWalk()
}// CustomType 定义类型,实现接口
type CustomType struct{}// Say CustomType 实现 BaseInterface 接口的方法
func (customType CustomType) Say(s string) string {fmt.Println("CustomType实现接口:saying..." + s)return s
}// Walk CustomType 实现 BaseInterface 接口的方法
func (customType CustomType) Walk() {fmt.Println("CustomType实现接口:walking...")
}func main() {// 定义接口实现类customType := CustomType{}// 调用接口方法say := customType.Say("Hello World")fmt.Println("返回值:" + say)customType.Walk()
}
从上面案例代码中,可以发现一个问题,在使用接口的时候,我们的代码里面没有直接出现BaseInterface
这个接口,而是定义了一个CustomType
结构体的变量,然后通过结构体变量去调用了结构体实现的Say
和Walk
两个方法。
这是因为Go
语言中,某个类型(结构体或者自定义类型
)实现某个接口之后,对应的类型就已经满足接口中定义的方法规范。
(4)空接口
Go
中提供了一个空接口,空接口就是接口中没有定义任何的方法,里面是空的。空接口相当于Java
中的Object
对象,是所有类型的父类型,Go
中的空接口就是所有类型的父类型。
// 定义空接口变量
interfaceVar interface{}
空接口可以作为一个方法的参数,这个参数叫做:空接口变量
。空接口变量可以接收任意的数据类型,从而就可以实现同一个方法可以处理多种类型的参数。
package mainimport "fmt"func demo(interfaceVar interface{}) {switch v := interfaceVar.(type) {case int:fmt.Println("int 类型", v)case string:fmt.Println("string 类型", v)default:fmt.Println("都不满足的类型")}
}func main() {// 定义int类型myInt := 10demo(myInt)// 定义string类型myStr := "hello world"demo(myStr)
}
(5)类型切换和断言
Go
语言中,提供了一种特殊的语法,叫做:类型切换
和类型断言
。语法格式:
// 类型切换和类型断言
v := interfaceVar.(T)// interfaceVar 表示接口变量
// T 表示数据类型
// v 是一个变量,具体来说是一个动态类型变量,它的类型会根据 interfaceVar.(T) 检测出来的类型变化
// 当 v 的类型和 case 类型匹配时候,那么 v 变量就会被赋值对应类型的数据值
上面表达式用在switch
结构里面,能够动态的检查接口变量interfaceVar
的具体类型,并且将变量的值赋值给变量v
。
类型切换和类型断言的代码执行规则,我理解大概是这样的:
1、首先进行类型切换,通过 interfaceVar.(T),获取到具体的类型
2、将获取到具体类型赋值给 v 变量
3、v 变量的类型再和 case 中的类型进行匹配
4、如果 v 能够匹配上 case 的类型,则将对应类型的值赋值给 v 变量
案例代码:
package mainimport "fmt"func demo(interfaceVar interface{}) {switch v := interfaceVar.(type) {case int:fmt.Println("int 类型", v)case string:fmt.Println("string 类型", v)default:fmt.Println("都不满足的类型")}
}func main() {// 定义int类型myInt := 10demo(myInt)// 定义string类型myStr := "hello world"demo(myStr)// 定义 float 类型myFloat := 3.14demo(myFloat)
}
1.3.2、通用接口
go中的通用接口,需要和泛型结合使用,这样才可以定义一个通用的接口,让所有的数据类型都适用,这就是通用接口。后续介绍泛型时候,在一起介绍通用接口。
1.4、泛型
Go
语言在1.18
版本中引入泛型的概念。泛型定义的语法格式如下所示:
// 泛型定义
[泛型参数 约束类型1 | 约束类型2...]// 举个例子:
func sum[T int | float32](a,b T) T {// 方法体
}
类型约束
是指:当前泛型可以接收哪些数据类型,如果不是这里面的类型,那么就无法使用对应的方法、函数之类的。
上面就是定义泛型时候的语法格式,那要如何使用呢???
在使用泛型的时候,可以有两种方式:
- 第一种方式:使用时候指定具体的数据类型。
- 第二种方式:不指定类型,让编译期自动推断类型。
package mainimport "fmt"// 定义泛型方法
func sum[T int | float32](a, b T) T {return a + b
}func main() {// 计算 int 类型ans := sum(1, 2)fmt.Println(ans)// 主动指定类型ans2 := sum[float32](3.14, 2.86)fmt.Println(ans2)
}
泛型结构的使用注意事项:
- 泛型不能用在基本类型上。
- 泛型不能进行类型断言。
- 匿名结构中,不允许使用泛型。
- 匿名函数不支持自定义泛型。
- 方法不能使用泛型。
为什么方法上面不能使用泛型呢???
我是这么理解的,因为
Go
中不允许方法重载,所以如果方法上面使用了泛型,那不就是相当于Go
中会存在两个相同名称的方法了吗?这就和Go
中不允许方法重载的定义相违背了,所以也就不允许方法使用泛型了。
1.5、类型
Go
语言中的类型,是一种静态强类型
,什么是静态呢???
静态强类型
静态是指:Go
中的数据类型一旦定义出来之后,在编译期期间就已经确定了,后续运行程序的时候,就不能够改变类型了。
强类型是指:当我们程序员在写代码的时候,如果改变了数据类型,那么编译期就会马上提示程序员,语法错了,不能修改类型。
var a int = 1
// 编译不通过,因为前后类型不一致
a = "2"
类型后置
Go
语言中,所有的数据类型都是写在名称后面的,这是因为写在变量名称后面,能够让程序的可读性更强,类型太多的时候不至于看着混乱。
var 变量名称 数据类型
类型声明
Go
语言中,使用type
关键字声明类型,自定义类型也是使用type
关键字定义的。
// 声明类型
type 类型名称 数据类型
类型转换
Go
语言中,没有类型Java
语言中的隐式类型转换的功能,Go
语言只有显式类型转换,也就是说,必须让程序员在代码中主动的进行类型转换。
package mainimport "fmt"func main() {var f float64 = 3.14// 强制类型转换var f2 int = int(f)fmt.Println(f2)
}
以上就是Go
语言中函数、方法、泛型、接口相关的学习笔记内容。
相关文章:
【Golang笔记02】函数、方法、泛型、接口学习笔记
Golang笔记02:函数、方法、泛型、接口学习笔记 一、进阶学习 1.1、函数 go中的函数使用func关键字进行定义,go程序的入口函数叫做:main,并且必须是属于main包里面。 1.1.1、定义函数 (1)普通函数 go中…...

C#语法篇 :基类子类转换,成员变化情况
在C#中,会有从子类对象到基类对象的转换,这属于C#中的向上扩容,一般可以默认转换。 方法的转换 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace ex3._4 …...

【漫话机器学习系列】264.内距(又称四分位差)Interquartile Range
深入理解内距(Interquartile Range,IQR)——数据分析中的异常值利器 在日常的数据分析中,我们经常需要识别和处理异常值(Outliers),而内距(Interquartile Range,简称 IQR…...

海外盲盒系统开发:重构全球消费体验的科技引擎
当盲盒文化席卷全球,海外盲盒系统开发已成为重构消费体验的核心赛道。数据显示,2025年全球盲盒市场规模突破120亿,东南亚市场年增长率达4540。我们开发的海外盲盒系统,以技术创新为驱动,打造覆盖全链路的全球化解决方案…...

高噪声下扩展边缘检测算子对检测边缘的影响
目录 一、常见的边缘检测算子 二、扩展边缘检测算子对检测边缘的影响 三、结论 一、常见的边缘检测算子 Sobel 算子: Prewitt算子;...

vuejs处理后端返回数字类型精度丢失问题
标题问题描述 后端返回数据有5.00和3.30这种数据,但是前端展示的时候返回对应分别为5和3.0,小数点后0都丢失了。 接口返回数据展示network-Response: 接口返回数据展示network-Preview: 错误数据效果展示 发现问题 浏览器接口…...

mysql数据库-中间件MyCat
1. MyCat简介 在整个 IT 系统架构中,数据库是非常重要,通常又是访问压力较大的一个服务,除了在程序开发的本身做优化,如: SQL 语句优化、代码优化,数据库的处理本身优化也是非常重要的。主从、热备、分表分…...

手搓四人麻将程序
一、麻将牌的表示 在麻将游戏中,总共有一百四十四张牌,这些牌被分为多个类别,每个类别又包含了不同的牌型。具体来说,麻将牌主要包括序数牌、字牌和花牌三大类。序数牌中,包含有万子、条子和筒子,每种花色…...

PotPlayer 安装 madVR、LAV Filters 以提升解码能力和视频音频效果
PotPlayer自带的解码器并不是最好,如下两张截图都是出自 TOP GUN: Maverick 较暗、灰蒙蒙的一张,是安装插件之前明亮的一张,是安装插件之后 详细安装参考 https://www.bilibili.com/video/BV1UV5qzuE74?spm_id_from333.788.videopod.sectio…...
阿里云域名 绑定 华为云服务器ip
阿里云(万网)域名转入华为云域名图文教程 上-云社区-华为云 阿里云(万网)域名转入华为云域名图文教程-云社区-华为云 在阿里云备案了域名,解析到华为云服务器,不在同一个服务商这样可以使用么?…...
windows7安装node18
1、要安装windows系统更新 2、node下载:CNPM Binaries Mirror 3、下载zip安装包,解压后将目录添加至环境变量。 4、node -v检查是否成功安装。 5、npm install -g vite4.0.0...
Maven配置安装
(2025.1.27)最新版MAVEN的安装和配置教程(超详细)_maven安装-CSDN博客...
小刚说C语言刷题—1153 - 查找“支撑数”
1.题目描述 在已知一组整数中,有这样一种数非常怪,它们不在第一个,也不在最后一个,而且刚好都比左边和右边相邻的数大,你能找到它们吗? 输入 第一行为整数 m,表示输入的整数个数。࿰…...

Kind方式部署k8s单节点集群并创建nginx服务对外访问
资源要求 请准备好doker环境,尽量用比较新的版本。我的docker环境如下 docker 环境: Docker version 20.10.21, build 20.10.21-0ubuntu1~18.04.3 安装kind kind表现上就是一个二进制程序,下载对应版本并增加执行权限即可: cu…...

K个一组链表翻转
目录 1. 题意 2. 解题思路 3. 代码 1. 题意 给一个链表,按 k 进行翻转,也就是 k 2 ,两两进行翻转,如果不够2则不动。 2. 解题思路 首先思考怎么翻转一个链表,反转链表:https://leetcode.cn/problems…...

Python60日基础学习打卡D32
我们已经掌握了相当多的机器学习和python基础知识,现在面对一个全新的官方库,看看是否可以借助官方文档的写法了解其如何使用。 我们以pdpbox这个机器学习解释性库来介绍如何使用官方文档。 大多数 Python 库都会有官方文档,里面包含了函数…...

面向恶劣条件的道路交通目标检测----大创自用(当然你也可以在里面学到很多东西)
全部内容梳理 目标检测的两个任务: 预测标签 边界框 语义分割 实力分割 一个是类别 一个是实例级别 分类任务把每个图像当作一张图片看待 所有解决方法是先生成候选区域 再进行分类 置信度: 包括对类别和边界框预测的自信程度 输出分类和IOU分数的…...

基于Java(SSM)+MySQL实现(Web)具有智能推荐功能的图书销售系统
具有智能推荐功能的图书销售系统 1.绪论 1.1 背景、目的、意义 随着互联网的不断发展,电子商务逐渐代替传统的交易方式。各种类型的电子商务网站层出不穷,但细分之下电子商务网站主要分为 B2B,B2C,C2B,C2C 这四大类…...

浙大团队研发Earth Explorer系统,探索深时演化/地学剖面/科研场景,赋能深时地球科学研究
深时地球科学研究聚焦地球的漫长历史,探寻从数十亿年前到如今的地质演化过程,研究范畴广泛,涵盖了地球内部结构、物质组成、生命演化,以及地球与外部环境的相互作用等关键领域。近年来,地学可视化分析方法对多维时空交…...
docker 启动一个python环境的项目
安装镜像 docker pull python:3.8-slim8902端口 启动容器 tail -f /dev/null 持续监听空文件,保持容器活跃 docker run -it \-p 8902:8902 \--name api_mock2 \-v /home/py/test:/app \-w /app \python:3.8-slim \tail -f /dev/null进入容器 docker exec -it api…...

31-35【动手学深度学习】深度学习硬件
1. CPU和GPU 1.1 CPU CPU每秒钟计算的浮点运算数为0.15,GPU为12。GPU的显存很低,16GB(可能32G封顶),CPU可以一直插内存。 左边是GPU(只能做些很简单的游戏,视频处理),中…...
Linux问题排查-内存使用率高如何分析原因
以下是针对 Linux 系统内存使用率高的分步排查方法,结合用户进程占用、tmpfs 内存占用、内核内存泄漏和黑洞内存等特殊情况进行分析: 第一步:初步观察系统整体内存使用情况 1. 查看系统内存概况 命令:free -h 或 cat /proc/mem…...

SpringMVC2
一、springmvc 接收请求 类上、方法上 RequestMapping GetMapping PostMapping package com.hl.springmvc02.web; import jdk.nashorn.internal.objects.annotations.Getter; import org.springframework.web.bind.annotation.*; RestController RequestMapping(&qu…...

【每日一题丨2025年5.12~5.18】排序相关题
个人主页:Guiat 归属专栏:每日一题 文章目录 1. 【5.12】P1068 [NOIP 2009 普及组] 分数线划定2. 【5.13】P5143 攀爬者3. 【5.14】P12366 [蓝桥杯 2022 省 Python B] 数位排序4. 【5.15】P10901 [蓝桥杯 2024 省 C] 封闭图形个数5.【5.16】P12165 [蓝桥…...
ElasticSearch性能优化
ES基础概念介绍: 索引:类似于MySQL中的表,它是具有相同特征的一个数据集。文档:格式为JSON格式,类似于MySQL中的一条数据,它是数据存储的基本数据单元,每一条文档都有一个唯一的ID。查询&#x…...

Typora + PicGo + GitHub 配置图床——图片自动上传 详细教程
文章目录 一、创建 GitHub 仓库二、添加私人令牌三、下载 PicGo四、配置 PicGo五、测试 一、创建 GitHub 仓库 进入 Github 官网 注册一个属于自己的账号,点击创建仓库。 2. 创建自己的新仓库。仓库设置为公开,方便上传图片(你设置私有也可以…...

QT+Visual Studio 配置开发环境教程
一、QT架构 Qt Creator 是一个轻量级、跨平台的 IDE,专为 Qt 开发量身打造,内置对 qmake/CMake 的深度支持、Kits 配置管理、原生 QML 调试器以及较低的资源占用维基百科。 而在 Windows 环境下,Visual Studio 配合 Qt VS Tools 扩展则可将 Q…...

缺乏经验的 PCB 过孔建模方法
您是一名背板设计人员,被指派设计一种新的高速、多千兆位串行链路架构,从多个线卡到背板上的多个交换矩阵交换卡。这些链路必须在第一天以 6GB/s 的速度运行,并且为 10GB/s (IEEE 802.3KR) 做好产品演进的准备。时间表很紧,您需要提出一个背板架构,以允许程序的其余部分…...
layui 介绍
layui(谐音:类 UI) 是一套开源的 Web UI 解决方案,采用自身经典的模块化规范,并遵循原生 HTML/CSS/JS 的开发方式,极易上手,拿来即用。其风格简约轻盈,而组件优雅丰盈,从源代码到使用…...
【漫话机器学习系列】265.普拉托变换的相关问题(Issues With Platt Scaling)
Platt Scaling 的相关问题详解 | 模型校准中的隐患分析 在机器学习模型中,模型预测的“置信度”并不一定等于真实的概率。为了提高模型预测结果的可解释性和实用性,我们通常会使用一种后处理的概率校准方法——Platt Scaling(普拉托变换&…...