go学习之接口知识

文章目录

    • 接口
      • 1.接口案例代码展示
      • 2.基本介绍
      • 3.基本语法
      • 4.应用场景介绍
      • 5.注意事项和细节
      • 6.接口编程经典案例
      • 7.接口与继承之间的比较
      • 8.面向对象编程--多态
        • 1)基本介绍
        • 2)快速入门
        • 3)接口体现多态的两种形式
      • 9.类型断言
        • 1)先看一个需求
        • 2)基本介绍
        • 3)类型断言的最佳实践1
        • 4)类型断言实践2

接口

1.接口案例代码展示

模拟通过支持usb接口的手机和相机开始工作

package main
import ("fmt"
)//声明定义一个接口
type Usb interface{Start()Stop()
}type Phone struct {}type Camera struct {}
//让phone实现usb接口的方法
func (p Phone) Start(){fmt.Println("手机开始工作。。。")
}
func (p Phone) Stop(){fmt.Println("手机停止工作。。。")
}func (c Camera) Start(){fmt.Println("相机开始工作。。。")
}
func (c Camera) Stop(){fmt.Println("相机停止工作。。。")
}
//计算机
type Computer struct{}//编写一个方法Working方法,接收一个Usb接口类型变量
//只要是实现了Usb接口(所谓实现Usb接口,就是指实现了Usb接口声明所有方法)
func (c Computer) Working (usb Usb){//通过usb接口变量来调用Start和Stop方法usb.Start()usb.Stop()
}
func main(){//测试//先创建结构体变量computer :=Computer{}phone :=Phone{}camera := Camera{}//关键点computer.Working(phone)computer.Working(camera)}

2.基本介绍

interface类型可以定义一组方法,但是这些不需要实现。并且interface不能包含任何变量,到某个自定义类型(比如结构体Phone)要使用的时候,再根据具体情况把这些方法写出来

3.基本语法

type 接口名 interface{method1(参数列表)返回值列表method2(参数列表)返回值列表
}实现接口的方法
func (t 自定义类型)method1(参数列表)返回值列表{//方法实现
}
func (t 自定义类型)method2(参数列表)返回值列表{//方法实现
}

小结说明:

1)接口里的所有方法都没有方法体,即接口的方法都是没有实现的方法。接口体现了程序设计的多态和高内聚低耦合的思想。

2)Golang中的接口,不需要显式的实现。只要一个变量,含有接口类型中的所有方法,那么这个变量就实现这个接口。因此,Golang中没有implement这样的关键字

解释:假如有一个不同名字的接口,但是方法和原接口的方法一样,那么实现的方法也是实现了这个接口,golang中接口的实现不是基于名字而是基于方法。可以同时实现两个接口。

type Usb interface{Start()Stop()
}
type Usb2 interface{Start()Stop()
}

4.应用场景介绍

对初学者讲,理解接口不算太难,难的是不知道什么时候使用接口,下面几个例子来解释

1)现在美国要制造轰炸机,武装直升机,专家只需要把飞机需要的功能/规格定下来即可,然后让别人具体实现即可

2)就是做一个项目,在接口中定义规范让其他人去实现所定的规范

5.注意事项和细节

1)接口本身不能创建实例,但是可以指向一个实现了该接口的自定义类型的变量(实例)

package main
import ("fmt"
)type AInterface interface {Say()}type Stu struct {Name string
}
func (stu Stu)Say(){fmt.Println("Stu Say()")
}
func main(){var stu Stu  //结构体变量,实现了Say() 实现了AInterface这个接口var a AInterface =stua.Say() //Stu Say()
}

2)接口中所有的方法都没有方法体,即都是没有实现的方法

3)在Golang中,一个自定义类型需要将某个接口的所有方法都实现,我们说这个自定义类型实现了该接口

4)一个自定义类型只有实现了某个接口,才能将该自定义类型的实例(变量)赋给接口类型

5)只要是自定义数据类型,就可以实现接口,不仅仅是结构体类型(面试会问)

type integer int
type AInterface interface {Say()
}func (i integer)Say() {fmt.Println("integer Say i = ",i)
}
func main(){var i integer = 10var b AInterface = ib.Say() //integer Say i =  10
}

6)一个自定义类型可以实现多个接口

package main
import ("fmt"
)type AInterface interface {Say()}type Stu struct {Name string
}
func (stu Stu)Say(){fmt.Println("Stu Say()")
}type integer intfunc (i integer)Say() {fmt.Println("integer Say i = ",i)
}
type BInterface interface{Hello()
}
type Monster struct{}
func (m Monster) Hello(){fmt.Println("Monster Hello()~~")
}
func (m Monster) Say(){fmt.Println("Monster Say()~~")
}
//此时刻Monster就实现了AInterface和BInterfacefunc main(){var stu Stu  //结构体变量,实现了Say() 实现了AInterface这个接口var a AInterface =stua.Say() //Stu Say()var i integer = 10var b AInterface = ib.Say() //integer Say i =  10
//验证monster去实现两个接口var monster Monstervar a2 AInterface = monster //Monster Say()~~var b2 BInterface = monster //Monster Hello()~~a2.Say()b2.Hello()
}

7)Golang接口中不能有任何变量

例如,以下写法就是错误的
type AInteger interface {
Name string//这是错误的,不能这样用
test()
}

8)一个接口(比如A接口)可以继承多个别的接口(比如B,C接口),这时如果要实现A接口,也必须将B,C接口的方法也全部实现

package main
import ("fmt"
)
type BInterface interface {test01()
}
type CInterface interface {test02()
}
type AInterface interface {BInterfaceCInterfacetest03()
}
//如果需要实现AIerface,就需要把BInterface和CInterface的方法都实现
type Stu struct{}
//把所要实现的接口所有的方法都实现一下
func (stu Stu) test01(){fmt.Println("这是Test01")
}
func (stu Stu) test02(){fmt.Println("这是Test02")
}
func (stu Stu) test03(){fmt.Println("这是Test03")
}func main(){//实践var stu Stuvar a AInterface = stua.test01()a.test02()a.test03()
}

9)interface类型默认是一个指针(引用类型),如果没有对interface初始化就使用,那么就会输出nil

10)空接口interface{}没有任何方法,所以所有类型都实现了空接口

type T interface {}
func main(){//实践var stu Stuvar a AInterface = stua.test01()a.test02()a.test03()var t T =stufmt.Println(t)var t2 interface{} = stuvar num1 float64 = 8.8t2 = num1fmt.Println(t2,test02)
}

查看下列代码看看是否有错

type AInterface interface{Test01()Test02()
}
type BInterface interface{Test01()Test03()
}
type CInterface interface{AInterfaceBInterface
}
func main(){}
//这里编译错误,因为CInterface有两个test01().编译器不通过

来看第二个代码

type Usb interface{Say()
}
type Stu struct {}
func (this *Stu) Say() {
fmt,Println("Say()")
}func main() {
var stu Stu = Stu{}
//var u Usb =stu //会报错,因为stu没有实现Say()方法
var u Usb = &stu //改正之后,加个地址就可以了
u.Say()
fmt.Println("here",u)
}

6.接口编程经典案例

实现对hero结构体切片的排序:sort.Sort(data Interface)

package main
import ("fmt""sort""math/rand"
)//1.声明Hero结构体
type Hero struct {Name stringAge int
}//2.声明一个Hero的切片类型
type HeroSlice []Hero //3.实现Interface 接口
func (hs HeroSlice) Len() int {return len(hs )
}
//Less方法就是决定你是用什么标准进行排序
//1.按Hero的年龄从小到大进行排序!!
func (hs HeroSlice) Less(i,j int) bool {return hs[i].Age > hs[j].Age//修改成对姓名排序// return hs[i].Name > hs[j].Name
}func (hs HeroSlice) Swap(i,j int) {// temp := hs[i]// hs[i] =hs[j]// hs[j] = temp//简洁的交换:下面一句话等价于上面三句话hs[i],hs[j] = hs[j],hs[i]
}//声明一个Student结构体
//1.声明Student结构体
type Student struct {Name stringAge intScore int
}
//然后将上面那三个方法复制到下面//将student按成绩从大到小进行排序//声明一个Stu切片类型
type StuSlice []Student
//3.实现Interface 接口
func (stu StuSlice) Len() int {return len(stu)
}
//Less方法就是决定你是用什么标准进行排序
//1.按Hero的年龄从小到大进行排序!!
func (stu StuSlice) Less(i,j int) bool {//按成绩进行排序return stu[i].Score > stu[j].Score
}func (stu StuSlice) Swap(i,j int) {stu[i],stu[j] = stu[j],stu[i]
}func main(){//先定义一个数组/切片var intSlice = []int{0,-1,10,7,90}//要求对intSlice切片进行排序//1.冒泡排序...//2.可以使用系统提供的方法sort.Ints(intSlice)fmt.Println(intSlice)//[-1 0 7 10 90]//请对结构体进行排序//1.冒泡排序//2.系统提供的方法//测试我们是否可以对结构体进行排序var heroes HeroSlicefor i :=0;i < 10; i++{hero :=Hero {Name : fmt.Sprintf("英雄~%d",rand.Intn(100)),Age : rand.Intn(100),}//将hero append到heros切片heroes = append(heroes,hero)}//看看排序前的顺序for _, v := range heroes {fmt.Println(v)}fmt.Println( )//调用sort.Sort()sort.Sort(heroes)//看看排序后的顺序for _, v := range heroes {fmt.Println(v)}//这个接口的妙处就是将这个接口的三个方法实现然后只需要将结合挂钩梯放入到//sort方法中去就可以fmt.Println()var studentsl StuSlicefor i :=0;i < 10; i++{stus :=Student {Name : fmt.Sprintf("学生~%d",rand.Intn(100)),Age : rand.Intn(100),Score : rand.Intn(100),}//将hero append到heros切片studentsl = append(studentsl,stus)}//看看排序前的顺序for _, v := range studentsl {fmt.Println(v)}fmt.Println( )//调用sort.Sort()sort.Sort(studentsl)//看看排序后的顺序for _, v := range studentsl {fmt.Println(v)}
}

7.接口与继承之间的比较

1)大家可能对实现接口和继承比较迷茫了。那么问题来了,那么他们究竟有什么区别呢?

例如有一个猴子会爬树,然而他想学鸟儿飞翔,鱼儿游泳

package main
import ("fmt"
)
//,Monkey结构体
type Monkey struct {Name string
}//声明接口
type BirdAble interface {Flying()
}//声明接口
type FishAble interface {Swimming()
}
func (this *Monkey) climbing() {fmt.Println(this.Name,"生来会爬树")
}//创建LittleMonkey结构体
type LittleMonkey struct {Monkey //继承
}//让littleMonkey实现BirdAble的Flying()方法
func (this *LittleMonkey) Flying(){fmt.Println(this.Name,"通过学习会飞翔")
}
//littleMonkey实现FishAble的Swimming()方法
func (this *LittleMonkey) Swimming(){fmt.Println(this.Name,"通过学习会游泳")
}
func main(){//创建LittleMonkey实例monkey := LittleMonkey{Monkey {Name : "悟空",},}monkey.climbing()monkey.Flying()monkey.Swimming()}

对上面代码的小结

  1. 当A结构体继承了另外B结构体,那么A结构体就自动继承了B结构体的字段和方法,并且可以直接使用
  2. 当A结构体需要扩展功能,同时不希望去破坏继承关系,则可以去实现某个接口即可,因此我们可以认为:实现接口是对继承机制的补充。

实现接口可以看作是对继承的一种补充

在这里插入图片描述

  • 接口和继承解决的问题是不同的

继承的价值主要在于:解决代码的复用性可维护性

接口的价值主要在于:设计。设计好各种规范(方法),让其他自定义类型去实现这些方法

  • 接口比继承更加灵活 Person Student BirdAble LittleMonkey

  • 接口比继承更加灵活。继承是满足 is --a的关系。则接口只需满足like --a 的关系

  • 接口在一定程度上实现代码解耦

8.面向对象编程–多态

1)基本介绍

变量(实例)具有多种形态。面向对象的第三大特征,在Go语言,多态特征是通过接口实现的。可以按照统一的接口来调用不同的实现。这时接口变量就呈现不同的形态

2)快速入门

在前面的Usb接口案例:Usb usb 既可以接收手机变量,又可以接收相机变量,就体现了Usb接口多态特性。

//编写一个方法Working方法,接收一个Usb接口类型变量
//只要是实现了Usb接口(所谓实现Usb接口,就是指实现了Usb接口声明所有方法)
func (c Computer) Working (usb Usb){//usb变量会根据传入的实参,来判断到底是Phone还是Camera//通过usb接口变量来调用Start和Stop方法usb.Start()usb.Stop()
}
func main(){//测试//先创建结构体变量computer :=Computer{}phone :=Phone{}camera := Camera{}//关键点computer.Working(phone)//传入phon就是phon执行这个方法computer.Working(camera)}
3)接口体现多态的两种形式

多态参数

在前面的Usb接口案例,Usb usb,既可以接收手机变量,又可以接收相机变量,就体现了Usb的接口多态

多态数组

演示一个案例给Usb数组,存放phone结构体和Camera结构体变量```go
package main
import ("fmt"
)//声明定义一个接口
type Usb interface{Start()Stop()
}type Phone struct {name string
}type Camera struct {name string
}
//让phone实现usb接口的方法
func (p Phone) Start(){fmt.Println("手机开始工作。。。")
}
func (p Phone) Stop(){fmt.Println("手机停止工作。。。")
}func (c Camera) Start(){fmt.Println("相机开始工作。。。")
}
func (c Camera) Stop(){fmt.Println("相机停止工作。。。")
}
//计算机
type Computer struct{}//编写一个方法Working方法,接收一个Usb接口类型变量
//只要是实现了Usb接口(所谓实现Usb接口,就是指实现了Usb接口声明所有方法)
func (c Computer) Working (usb Usb){//通过usb接口变量来调用Start和Stop方法usb.Start()usb.Stop()
}
func main(){//定义一个Usb接口数组,可以存放Phone和Camera的结构体变量//这里就体现出多态数组var usbArr  [3]UsbusbArr[0] = Phone{"iphone"}usbArr[1] = Phone{"小米"}usbArr[2] = Camera{"佳能"}fmt.Println(usbArr) //[{iphone} {小米} {佳能}]}
```

9.类型断言

1)先看一个需求

代码

type Point struct{x inty int
}
func main() {var a interface{}var point Point = Pooint{1,2}a = point //OK//如何将A赋给一个Point变量?var b Pointb = a /可以吗? ==》errofmt.Println(b)
}
//改进之后
package main
import ("fmt"
)
type Point struct{x inty int
}
func main() {var a interface{}var point Point = Point{1,2}a = point //OK//如何将A赋给一个Point变量?var b Point//b = a //可以吗? ==》errob = a.(Point) //解决办法,类型断言//b = a.(Point)就是类型断言,表示判断a是否指向Poin类型的变量,如果是就转成了Point类型并赋给b变量,否则报错fmt.Println(b) //1 2
}

有一个具体的需要,引出了类型断言

2)基本介绍

类型断,由于接口是一般类型,不知道具体类型,如果要转成具体类型,就需要使用类型断言,具体的如下

//float32可以是其他类型,比如Point
var t float32
var x interface{}
x = t //OK
y := x.(float32)//转成float32//float32可以死其他类型,比如Point
var t float32 
var x interface{}
x = t
//转成float,待检查的
y,ok :=a.(float32)
if ok == true {
fmt.Println("convert success")
}else{
fmt.Println("convert fall")
}
/类型断言的其他案例var x interface{}var b2 float32 = 1.1x = b2 //空接口可以接收任意类型//x = >float32 【使用类型断言】y := x.(float32)fmt.Printf("y的类型是%T 值是%v",y,y) //y的类型是float32 值是1.1

对上面的代码的说明

在进行类型断言时,如果类型不匹配,就会报panic,因此进行类型断言时,要确保原来的空接口指向的就是断言的类型

如何在进行断言时带上检测机制,如果成功就ok否则也不要报panic

//类型断言(带检测)
var x interface{}
var b2 float32 = 1.1
x = b2 //空接口可以接收任意类型
//x = >float32 【使用类型断言】
//y,ok := x.(float64)
//简写if  y,ok := x.(float64);ok {fmt.Println("转换成功了")fmt.Printf("y的类型是%T 值是%v",y,y) //y的类型是float32 值是1.1
}else{fmt.Println("转换失败")
}
fmt.Println("检测失败了无妨,代码不要停")}
3)类型断言的最佳实践1

在前面的Usb接口案例做改进

给Phone结构体增加一个特有的方法call(),当Usb接口接收的是Phone变量时,还需要调用call方法。

package main
import ("fmt"
)//声明定义一个接口
type Usb interface{Start()Stop()
}type Phone struct {name string
}type Camera struct {name string
}
//让phone实现usb接口的方法
func (p Phone) Start(){fmt.Println("手机开始工作。。。")
}
func (p Phone) Stop(){fmt.Println("手机停止工作。。。")
}func (p Phone) Call(){fmt.Println("手机开始打电话。。。")
}func (c Camera) Start(){fmt.Println("相机开始工作。。。")
}
func (c Camera) Stop(){fmt.Println("相机停止工作。。。")
}
//计算机
type Computer struct{}//编写一个方法Working方法,接收一个Usb接口类型变量
//只要是实现了Usb接口(所谓实现Usb接口,就是指实现了Usb接口声明所有方法)
func (c Computer) Working (usb Usb){//通过usb接口变量来调用Start和Stop方法usb.Start()//如果usb是指向Phone结构体变量,则还需要调用Call()方法//类型断言if phone, ok := usb.(Phone); ok {phone.Call()}//否则断言失败还是继续执行下列方法usb.Stop()
}func main(){//定义一个Usb接口数组,可以存放Phone和Camera的结构体变量//这里就体现出多态数组var usbArr  [3]UsbusbArr[0] = Phone{"iphone"}usbArr[1] = Phone{"小米"}usbArr[2] = Camera{"佳能"}//fmt.Println(usbArr) //[{iphone} {小米} {佳能}]//遍历var computer Computerfor _,v := range usbArr{computer.Working(v)fmt.Println()}}
执行结果如下:
手机开始工作。。。
手机开始打电话。。。
手机停止工作。。。手机开始工作。。。
手机开始打电话。。。
手机停止工作。。。相机开始工作。。。
相机停止工作。。。
4)类型断言实践2

写一个函数,循环判断传入参数的类型

package main
import ("fmt"
)
//编写一个函数,可以判断输入的参数是什么类型
func TypeJudge(items... interface{}){for index, x := range items {switch x.(type) {case bool : fmt.Printf("第%v个参数是 bool 类型,值是%v\n",index+1,x)case float32 : fmt.Printf("第%v个参数是 float32 类型,值是%v\n",index+1,x)case float64 : fmt.Printf("第%v个参数是 float64 类型,值是%v\n",index+1,x)	case int, int32, int64 : fmt.Printf("第%v个参数是 整数 类型,值是%v\n",index+1,x)		  	  case string : fmt.Printf("第%v个参数是 string 类型,值是%v\n",index+1,x)default :fmt.Printf("第%v个参数是 类型 不确定,值是%v\n",index+1,x)	}}}
func main(){var n1 float32 = 1.1var n2 float64 = 2.3var n3 int32 = 30var name = "tom"address := "北京"n4 :=300TypeJudge(n1,n2,n3,name,address,n4)}
//运行结果如下1个参数是 float32 类型,值是1.12个参数是 float64 类型,值是2.33个参数是 整数 类型,值是304个参数是 string 类型,值是tom
第5个参数是 string 类型,值是北京
第6个参数是 整数 类型,值是300

5)类型断言的最佳实践3

在前面代码的基础上,增加判断Student类型和*Student类型

package main
import ("fmt"
)//定义Student类型
type Student struct {}
//编写一个函数,可以判断输入的参数是什么类型
func TypeJudge(items... interface{}){for index, x := range items {switch x.(type) {case bool : fmt.Printf("第%v个参数是 bool 类型,值是%v\n",index+1,x)case float32 : fmt.Printf("第%v个参数是 float32 类型,值是%v\n",index+1,x)case float64 : fmt.Printf("第%v个参数是 float64 类型,值是%v\n",index+1,x)	case int, int32, int64 : fmt.Printf("第%v个参数是 整数 类型,值是%v\n",index+1,x)		  	  case Student : fmt.Printf("第%v个参数是 Student 类型,值是%v\n",index+1,x)case *Student : fmt.Printf("第%v个参数是 *Student 类型,值是%v\n",index+1,x)case string : fmt.Printf("第%v个参数是 string 类型,值是%v\n",index+1,x)default :fmt.Printf("第%v个参数是 类型 不确定,值是%v\n",index+1,x)	}}}func main(){var n1 float32 = 1.1var n2 float64 = 2.3var n3 int32 = 30var name = "tom"address := "北京"n4 :=300stu1 := Student{}stu2 := &Student{}TypeJudge(n1,n2,n3,name,address,n4,stu1,stu2)}

数是什么类型
func TypeJudge(items… interface{}){
for index, x := range items {
switch x.(type) {
case bool :
fmt.Printf(“第%v个参数是 bool 类型,值是%v\n”,index+1,x)
case float32 :
fmt.Printf(“第%v个参数是 float32 类型,值是%v\n”,index+1,x)
case float64 :
fmt.Printf(“第%v个参数是 float64 类型,值是%v\n”,index+1,x)
case int, int32, int64 :
fmt.Printf(“第%v个参数是 整数 类型,值是%v\n”,index+1,x)
case Student :
fmt.Printf(“第%v个参数是 Student 类型,值是%v\n”,index+1,x)
case *Student :
fmt.Printf(“第%v个参数是 *Student 类型,值是%v\n”,index+1,x)
case string :
fmt.Printf(“第%v个参数是 string 类型,值是%v\n”,index+1,x)

		default :fmt.Printf("第%v个参数是 类型 不确定,值是%v\n",index+1,x)	}
}

}

func main(){
var n1 float32 = 1.1
var n2 float64 = 2.3
var n3 int32 = 30
var name = “tom”
address := “北京”
n4 :=300

stu1 := Student{}
stu2 := &Student{}TypeJudge(n1,n2,n3,name,address,n4,stu1,stu2)

}


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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

单独设置echarts图例样式

参考&#xff1a;echarts-legend legend: [{data: [{name: 正常,icon: rect}],itemWidth: 16,itemHeight: 4,top: 6%,left: 35%,textStyle: {color: #626C78,fontSize: 14}},{data: [{name: 异常,icon: rect}],itemWidth: 16,itemHeight: 4,top: 6%,left: 50%,textStyle: {col…

2013年01月16日 Go生态洞察:并发不是并行

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

京东数据运营与分析:如何全面获取电商销售数据?

随着电商行业的快速发展&#xff0c;数据分析成为了电商运营中一个非常重要的环节&#xff0c;这一环往往能够帮助品牌方来提升销售业绩和管理效率。然而&#xff0c;如何获取到电商平台中详细、全面的销售数据是很多电商品牌方所关心的问题&#xff0c;事实上&#xff0c;第三…

GitHub加速配置

1. 找到要加速的域名 GitHub&#xff1a;github.com&#xff08;这只是加载主页面的&#xff09;GitHub下载&#xff1a;codeload.github.com&#xff08;不唯一&#xff0c;自己去下载链接看&#xff09; 2. 用域名到DNS解析服务器地址 ITDOG 3. 修改 Hosts 文件 依据解…

ai批量剪辑矩阵无人直播一站式托管系统源头技术开发

一、剪辑技术开发 智能剪辑&#xff1a;咱们研发公司自主研发的&#xff0c;包括算法&#xff0c;算法是阶乘算法&#xff0c;无限产出&#xff0c;六大剪辑模式已经满足当下需求了&#xff0c;当然剪辑出的视频可以一键发布&#xff0c;也可以内部批量发布&#xff0c;都可以的…

100G 最小封装光模块——SFP112光模块

10月易天团队远赴英国格拉斯哥参加展会&#xff0c;在ECOC展会上认识和学习了许多新的产品和技术&#xff0c;其中一款备受关注的是100G SFP112光模块&#xff0c;据说它是全球最小封装的模块。下面就跟着小易一起来了解一下这位新晋级的“大咖”吧&#xff01; 100G SFP112采…

基于SpringBoot的SSMP整合案例(实体类开发与数据层开发)

实体类开发 导入依赖 Lombok&#xff0c;一个Java类库&#xff0c;提供了一组注解&#xff0c;简化POJO实体类开发<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId> </dependency>lombok版本由SpringB…

k8s笔记资源限制,亲和和性 污点和容忍

镜像下载失败 当宿主机资源不足时&#xff0c;会把pod kill &#xff0c;在其他node 重建 在宿主机放可能多的资源 requests(请求) limits(限制) 超出百分比 容器 pod namespace级别 pod使用资源过多&#xff0c;导致宿主机资源不足&#xff0c;会导致重建pod cpu 内存限…

Riskified: 2023年电商政策滥用问题恶化,正严重挑战商家盈利底线

2023年11月14日&#xff0c;中国上海 —— 近日&#xff0c;由全球领先的电子商务欺诈和风险智能解决方案提供商 Riskified 发布的《政策滥用及其对商家的影响&#xff1a;2023年全球参考基准》报告显示&#xff0c;政策滥用问题正进一步恶化&#xff0c;超过九成电商商家正在承…

只有开源才能拯救AI

导语 | 随着 AI 技术的蓬勃发展&#xff0c;大模型的开源化正成为人工智能领域的新潮流&#xff0c;但同时引发的伦理和安全风险也饱受大家关注&#xff0c;如何把握平衡其中的尺度成为开源的一大难题。我们又应该如何有效进行开源治理&#xff1f;未来将走向何方&#xff1f;今…

前端工具nvm实现node自由

node的自由之路 前言 大家使用vue框架开发的朋友可能会遇到首次运行公司项目环境的时候&#xff0c;会出现使用npm install命令安装依赖包的时候出现各种各样的问题&#xff0c;其中很重要的一个错误原因就是因为你的nodejs版本和当时搭建环境的版本不一致造成的。今天就来给…

绿盟远程安全评估系统 RSAS 使用体验-难用

最近领导让我用公司采购的RSAS对产品进行漏洞扫描&#xff0c;学习并使用了这个软件&#xff0c;体验就是真的很难用。使用遇到问题时&#xff0c;咨询售后服务&#xff0c;机器人需要有公司认证&#xff0c;不能随便问问题&#xff0c;也是无语了。咨询客服&#xff0c;客服回…

猪酒店房价采集

<?php // 设置代理 $proxy_host jshk.com.cn;// 创建一个cURL资源 $ch curl_init();// 设置代理 curl_setopt($ch, CURLOPT_PROXY, $proxy_host.:.$proxy_port);// 连接URL curl_setopt($ch, CURLOPT_URL, "http://www.zujia.com/");// 发送请求并获取HTML文档…

python实现一个简单的桌面倒计时小程序

本章内容主要是利用python制作一个简单的桌面倒计时程序&#xff0c;包含开始、重置 、设置功能。 目录 一、效果演示 二、程序代码 一、效果演示 二、程序代码 #!/usr/bin/python # -*- coding: UTF-8 -*- """ author: Roc-xb """import tkin…

asp.net学院网上报销系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

一、源码特点 asp.net学院网上报销系统是一套完善的web设计管理系统&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为vs2010&#xff0c;数据库为sqlserver2008&#xff0c;使用c#语言 开发 asp.net学院网上报销系统 应用技术…

Huggingface

1 介绍 Hugging Face 是一个开源模型社区。目前已经共享 300k 模型&#xff0c;100k 应用&#xff0c;50k 数据集&#xff08;截至 231114 数据&#xff09;&#xff0c;可视为 AI 界的 github。 2 官网 https://huggingface.co/ 3 主要功能 3.1 Models 模型 大家都用过就…

Springboot+Dubbo+Nacos 集成 Sentinel(入门)

Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件&#xff0c;主要以流量为切入点&#xff0c;从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。Sentinel 官网 1.版本选择 参考 SpringClou…

【QT】飞机大战

0 项目简介 飞机大战是我们大家所熟知的一款小游戏&#xff0c;本教程就是教大家如何制作一款自己的飞机大战 首先我们看一下效果图 玩家控制一架小飞机&#xff0c;然后自动发射子弹&#xff0c;如果子弹打到了飞下来的敌机&#xff0c;则射杀敌机&#xff0c;并且有爆炸的特…

ESP32 Arduino实战基础篇-生成 PWM 信号

在本教程中,我们将向您展示如何使用 Arduino IDE 通过 ESP32 生成 PWM 信号。作为示例,我们将构建一个简单的电路,使用 ESP32 的 LED PWM 控制器对 LED 进行调光。我们还将向您展示如何同时在不同的 GPIO 上获取相同的 PWM 信号。 在继续本教程之前,您应该在 Arduino IDE 中…