go语言基本操作--四

面向对象编程

对于面向对象编程的支持go语言设计得非常简洁而优雅。因为,Go语言并没有沿袭面向对象编程中诸多概念,比如继承(不支持继承,尽管匿名字段的内存布局和行为类似继承,但它并不是继承)、虚函数、构造函数和析构函数、隐藏的this指针等.
尽管go语言中没有封装,继承,多态这些概念,但同样通过别的方式实现这些特性:
1:封装:通过方法实现
2:继承:通过匿名字段实现
3:多态:通过接口实现

匿名字段作用—继承

一般情况下,定义结构体的时候是字段名与其类型一 一对应,实际上go支持只提供类型,而不写字段名的方式,也就是匿名字段,也称为嵌入字段。
当匿名字段也是一个结构体的时候,那么这个结构体所拥有的全部字段都被隐式地引入了当前定义的这个结构体。

//定义一个结构体类型type Person struct {name string //名字sex  byte   //性别age  int    //年龄
}type Student struct {Person //只有类型 没有名字,匿名字段,继承了Person的成员id     intaddr   string
}

匿名字段初始化

package mainimport "fmt"//定义一个结构体类型type Person struct {name string //名字sex  byte   //性别age  int    //年龄
}type Student struct {Person //只有类型 没有名字,匿名字段,继承了Person的成员id     intaddr   string
}func main() {//顺序初始化var s1 Student = Student{Person{"mike", 'm', 18},1,"bj",}fmt.Println("s1 = ", s1) //s1 =  {{mike 109 18} 1 bj}//自动推导类型s2 := Student{Person{"mike", 'm', 18},1,"bj",}fmt.Println("s2 = ", s2) //s2 =  {{mike 109 18} 1 bj}//%+v 显示更详细fmt.Printf("s2 = %+v\n", s2) //s2 = {Person:{name:mike sex:109 age:18} id:1 addr:bj}//指定成员初始化,没有初始化的常用自动赋值为0s3 := Student{id: 1}fmt.Printf("s3 = %+v\n", s3) //s3 = {Person:{name: sex:0 age:0} id:1 addr:}s4 := Student{Person: Person{name: "mike"}, id: 1}fmt.Printf("s4 = %+v\n", s4) //s4 = {Person:{name:mike sex:0 age:0} id:1 addr:}
}

成员的操作

package mainimport "fmt"//定义一个结构体类型type Person struct {name string //名字sex  byte   //性别 字符类型age  int    //年龄
}type Student struct {Person //只有类型 没有名字,匿名字段,继承了Person的成员id     intaddr   string
}func main() {//自动推导类型s1 := Student{Person{"mike", 'm', 18}, 1, "bj"}fmt.Println(s1.name, s1.sex, s1.id, s1.addr, s1.age) //mike 109 1 bj 18s1.name = "yoyo"                                     //等价于s1.Person.name = "mike"s1.sex = 'f's1.age = 22s1.id = 666s1.addr = "wh"fmt.Println(s1.name, s1.sex, s1.id, s1.addr, s1.age) //yoyo 102 666 wh 22s1.Person = Person{"go", 'm', 23}fmt.Println(s1.name, s1.sex, s1.id, s1.addr, s1.age) //go 109 666 wh 23
}

同名字段

package mainimport "fmt"//定义一个结构体类型type Person struct {name string //名字sex  byte   //性别 字符类型age  int    //年龄
}type Student struct {Person //只有类型 没有名字,匿名字段,继承了Person的成员id     intaddr   stringname   string //和Person同名了
}func main() {//声明(定义一个变量)var s Student//默认规则(就近原则),如果能在本作用域找到此成员,就操作此成员//如果没有找到,找到继承的字段s.name = "mike" //操作的是Student的names.sex = 'm's.age = 18s.addr = "bj"fmt.Printf("s = %+v\n", s) //s = {Person:{name: sex:109 age:18} id:0 addr:bj name:mike}//显示调用s.Person.name = "yoyo"fmt.Printf("s = %+v\n", s) //s = {Person:{name:yoyo sex:109 age:18} id:0 addr:bj name:mike}
}

非结构体匿名字段

package mainimport "fmt"//定义一个结构体类型type mystr string //自定义类型,给一个类型改名type Person struct {name string //名字sex  byte   //性别 字符类型age  int    //年龄
}type Student struct {Person //只有类型 没有名字,匿名字段,继承了Person的成员int    //基础类型的匿名字段mystr  //基础类型的匿名字段
}func main() {s := Student{Person{"mike", 'm', 18}, 666, "hehehe"}fmt.Printf("s = %+v\n", s) //s = {Person:{name:mike sex:109 age:18} int:666 mystr:hehehe}fmt.Println(s.name, s.age, s.sex, s.int, s.mystr) //mike 18 109 666 hehehefmt.Println(s.Person, s.int, s.mystr)             //{mike 109 18} 666 hehehes.Person = Person{"go", 'm', 22}fmt.Println(s.Person, s.int, s.mystr)             //{go 109 22} 666 hehehefmt.Println(s.name, s.age, s.sex, s.int, s.mystr) //go 22 109 666 hehehe
}

结构体指针类型匿名字段

package mainimport "fmt"//定义一个结构体类型type mystr string //自定义类型,给一个类型改名type Person struct {name string //名字sex  byte   //性别 字符类型age  int    //年龄
}type Student struct {*Person //指针类型id      intaddr    string
}func main() {s1 := Student{&Person{"mike", 'm', 18}, 1, "wh"}fmt.Println("s1 = ", s1)                             //s1 =  {0xc00008e380 1 wh}fmt.Println(s1.name, s1.sex, s1.age, s1.id, s1.addr) //mike 109 18 1 wh//先定义变量var s2 Students2.Person = new(Person) //分配空间s2.name = "yoyo"s2.sex = 'm's2.age = 19s2.id = 2s2.addr = "wh"fmt.Println("s2 = ", s2)                             //s2 =  {0xc000054400 2 wh}fmt.Println(s2.name, s2.sex, s2.age, s2.id, s2.addr) //yoyo 109 19 2 wh
}

方法介绍—封装

在面向对象编程中,一个对象其实也就是一个简单的值或者一个变量,在这个对象中会包含一些函数,这种带有接收者的函数,我们称为方法。本质上,一个方法则是一个和特殊关联的函数。
一个面向对象的程序会用方法来表达其属性和对应的操作,这样使用这个对象的用户就不需要直接去操作对象,而是借助方法来做这种事情。
在Go语言中,可以任意自定义类型(包括内置类型,但不包括指针类型)添加相应的方法。
方法总是绑定对象实例,并隐式将实例作为第一实参(receiver),方法的语法如下:
func (receiver ReceiverType) funcName(parameters)(results)
1:参数receiver可任意命名.如方法中未曾使用,可以省略参数.
2: 参数receiver类型可以是T或*T。基类型T不能是接口或者指针
3:不支持重载方法,也就是说,不能定义名字相同但是不同参数的方法。

面向过程和面向对象函数区别

package mainimport "fmt"// 实现2数相加
// 面向过程
func Add01(a, b int) int {return a + b
}// 面向对象,方法:给某个类型绑定一个函数
type long int //改名// tmp叫接收者,接收者就是传递的一个参数
func (tmp long) Add02(other long) long {return tmp + other
}func main() {result := Add01(1, 1)            //普通函数调用方式fmt.Println("result = ", result) //result = 2//定义一个变量var a long = 2//调用方法格式add1 := a.Add02(3)fmt.Println("result = ", add1) //result =  5//面向对象只是换了一种表现形式
}

结构体类型添加方法

package mainimport "fmt"type Person struct {name stringsex  byteage  int
}//带有接收者的函数叫方法func (tmp Person) PrintInfo() {fmt.Println("tmp = ", tmp)
}// 通过一个函数,给成员赋值
func (p *Person) SetInfo(name string, sex byte, age int) {p.name = namep.sex = sexp.age = age
}
func main() {//定义同时初始化p := Person{"mike", 'm', 18}p.PrintInfo() //tmp =  {mike 109 18}//定义一个结构体变量var p2 Person(&p2).SetInfo("yoyo", 'm', 19)p2.PrintInfo() //tmp =  {yoyo 109 19}
}
type pointer *int
//pointer 为接收者类型,它本身不能是指针类型
func (tmp pointer) test(){} //error invalid receiver type pointer

//不支持重载,只要接收者类型不一样,这个方法就算同名,也是不同方法,不会出现重复定义函数的错误

func (tmp Person) PrintInfo() {fmt.Println("tmp = ", tmp)
}type char bytefunc (tmp char) PrintInfo() {}

值语义和引用语义

package mainimport "fmt"type Person struct {name stringsex  byteage  int
}// 接收者为普通变量,非指针,值语义,一份拷贝
func (p Person) SetInfoValue(name string, sex byte, age int) {p.name = namep.sex = sexp.age = agefmt.Println("SetInfoValue p = ", p)      //SetInfoValue p =  {mike 109 19}fmt.Printf("SetInfoValue &p = %p\n", &p) //SetInfoValue &p = 0xc00008e3c0
}// 接收者为指针变量,引用传递
func (p *Person) SetInfoPoubter(name string, sex byte, age int) {p.name = namep.sex = sexp.age = agefmt.Printf("SetInfoPoubter p = %p\n", &p) //SetInfoPoubter p = 0xc00008e380fmt.Println("SetInfoPoubter &p = ", *p)   //SetInfoPoubter &p =  {mike 109 19}
}
func main() {s1 := Person{"go", 'm', 18}fmt.Printf("&s1 = %p\n", &s1) //&s1 = 0xc00008e380//值语义s1.SetInfoValue("mike", 'm', 19)fmt.Println("s1 = ", s1) //s1 =  {go 109 18}//引用语义(&s1).SetInfoPoubter("mike", 'm', 19)fmt.Println("s1 = ", s1) //s1 =  {mike 109 19}
}

指针类型和普通类型的方法集

指针类型的方法集

package mainimport "fmt"type Person struct {name stringsex  byteage  int
}// 接收者为普通变量,非指针,值语义,一份拷贝
func (p Person) SetInfoValue() {fmt.Println("SetInfoValue")
}// 接收者为指针变量,引用传递
func (p *Person) SetInfoPoubter() {fmt.Println("SetInfoPoubter")
}
func main() {//假如,结构体是一个指针变量,它能够调用那些方法,这些方法就是一个集合,简称方法集p := &Person{"mike", 'm', 18}p.SetInfoPoubter()(*p).SetInfoPoubter() //把(*p)转换成p调用,等价于上面//内部做的转换,先把指针p,转成*p后再调用//(*p).SetInfoValue()p.SetInfoValue()
}

普通类型的方法集

package mainimport "fmt"type Person struct {name stringsex  byteage  int
}// 接收者为普通变量,非指针,值语义,一份拷贝
func (p Person) SetInfoValue() {fmt.Println("SetInfoValue")
}// 接收者为指针变量,引用传递
func (p *Person) SetInfoPoubter() {fmt.Println("SetInfoPoubter")
}
func main() {p := Person{"mike", 'm', 18}p.SetInfoPoubter() //内部会先把p转化为&p再调用(&p).SetInfoPoubter()p.SetInfoValue()
}

方法的继承

package mainimport "fmt"type Person struct {name stringsex  byteage  int
}// Person类型,实现一个方法
func (tmp *Person) PrintInfo() {//PrintInfo: name = mike,sex = m, age = 18fmt.Printf("PrintInfo: name = %s,sex = %c, age = %d\n", tmp.name, tmp.sex, tmp.age)
}// 有一个学生,继承Person字段,成员和方法都继承了
type Student struct {Person //匿名字段id     intaddr   string
}func main() {s := Student{Person{"mike", 'm', 18}, 666, "bj"}s.PrintInfo()
}

方法的重写

package mainimport "fmt"type Person struct {name stringsex  byteage  int
}// PrintInfo Person类型,实现一个方法
func (tmp *Person) PrintInfo() {//PrintInfo: name = mike,sex = m, age = 18fmt.Printf("PrintInfo: name = %s,sex = %c, age = %d\n", tmp.name, tmp.sex, tmp.age)
}// PrintInfo Student也实现了一个方法,这个方法和Person方法重名,这个方法叫重写
func (tmp *Student) PrintInfo() {//PrintInfo: name = mike,sex = m, age = 18fmt.Println("Student: tmp = ", tmp)   //Student: tmp =  &{{mike 109 18} 666 bj}fmt.Println("Student: *tmp = ", *tmp) //Student: *tmp =  {{mike 109 18} 666 bj}
}// Student 有一个学生,继承Person字段,成员和方法都继承了
type Student struct {Person //匿名字段id     intaddr   string
}func main() {s := Student{Person{"mike", 'm', 18}, 666, "bj"}//就近原则:先找本作用域的方法,找不到再用继承的方法s.PrintInfo() //这样会调用Student的//显示调用继承的方法s.Person.PrintInfo() //PrintInfo: name = mike,sex = m, age = 18
}

方法值

package mainimport "fmt"type Person struct {name stringsex  byteage  int
}func (p Person) SetInfoValue() {fmt.Printf("SetInfoValue: %p,%v\n", &p, p)
}func (p *Person) SetInfoPointer() {fmt.Printf("SetInfoPointer %p, %v\n", p, *p) //SetInfoPointer 0xc00008e380, {mike 109 18}
}func main() {p := Person{"mike", 'm', 18}fmt.Printf("main: %p,%v\n", &p, p) //main: 0xc00008e380,{mike 109 18}p.SetInfoPointer() //传统调用方式//保存方式入口地址pFunc := p.SetInfoPointer //这个就是方法值,调用函数时,无需再传递接收者,隐藏了接收者pFunc()                   //等价于p.SetInfoPointer() SetInfoPointer 0xc00008e380, {mike 109 18}vFunc := p.SetInfoValuevFunc() //等价于p.SetInfoValue() SetInfoValue: 0xc000054440,{mike 109 18} 值传递
}

方法表达式

package mainimport "fmt"type Person struct {name stringsex  byteage  int
}func (p Person) SetInfoValue() {fmt.Printf("SetInfoValue: %p,%v\n", &p, p)
}func (p *Person) SetInfoPointer() {fmt.Printf("SetInfoPointer %p, %v\n", p, *p) //SetInfoPointer 0xc00008e380, {mike 109 18}
}func main() {p := Person{"mike", 'm', 18}fmt.Printf("main: %p,%v\n", &p, p) //main: 0xc00008e380,{mike 109 18}p.SetInfoPointer() //传统调用方式//方法值,f := p.SetInfoPointer//隐藏了接收者//方法表达式f := (*Person).SetInfoPointerfmt.Println("=========")f(&p) //显示把接收者传递过去 ---->p.SetInfoPointer() SetInfoPointer 0xc0000543a0, {mike 109 18}f2 := (Person).SetInfoValuef2(p) //SetInfoValue: 0xc000054440,{mike 109 18}
}

接口类型介绍

在go语言,接口是一个自定义类型,接口类型具体描述了一系列方法的集合。
接口类型时一种抽象的类型,它不会暴露出它所代表的对象的内部值的结构和这个对象支持的基础操作的集合,它们只会展示出它们自己的方法。因此接口类型不能将其实例化。
接口定义:
1:接口命令习惯以er结尾
2:接口只有方法声明,没有实现,没有数据字段
3:接口可以匿名嵌入其他接口,或嵌入到结构中

接口的定义和实现

package mainimport "fmt"// Humaner 定义接口类型
type Humaner interface {//方法,只有声明,没有实现,由别的类型(自定义类型)实现sayhi()
}type Student struct {name stringid   int
}// Student实现了此方法
func (tmp *Student) sayhi() {fmt.Printf("Student[%s, %d] sayhi\n", tmp.name, tmp.id)}type Teacher struct {addr  stringgroup string
}// Teacher实现了此方法
func (tmp *Teacher) sayhi() {fmt.Printf("Teacher[%s, %s] sayhi\n", tmp.addr, tmp.group)}type MyStr string// MyStr实现了此方法
func (tmp *MyStr) sayhi() {fmt.Printf("MyStr[%s] sayhi\n", *tmp)
}type MyStr1 stringfunc (tmp MyStr1) sayhi() {fmt.Printf("MyStr1[%s] sayhi\n", tmp)
}func main() {//定义接口类型的变量var i Humaner//只要实现了此接口方法的类型,那么这个类型的变量(接收者类型)就可以给i赋值s := &Student{"mike", 666}i = si.sayhi() //Student[mike, 666] sayhit := &Teacher{"wh", "go"}i = ti.sayhi() //Teacher[wh, go] sayhivar str MyStr = "hello cheng"i = &stri.sayhi() //MyStr[hello cheng] sayhivar str1 MyStr1 = "hello"i = str1i.sayhi() //MyStr1[hello] sayhi
}

多态的表现

package mainimport "fmt"// Humaner 定义接口类型
type Humaner interface {//方法,只有声明,没有实现,由别的类型(自定义类型)实现sayhi()
}type Student struct {name stringid   int
}// Student实现了此方法
func (tmp *Student) sayhi() {fmt.Printf("Student[%s, %d] sayhi\n", tmp.name, tmp.id)}type Teacher struct {addr  stringgroup string
}// Teacher实现了此方法
func (tmp *Teacher) sayhi() {fmt.Printf("Teacher[%s, %s] sayhi\n", tmp.addr, tmp.group)}type MyStr string// MyStr实现了此方法
func (tmp *MyStr) sayhi() {fmt.Printf("MyStr[%s] sayhi\n", *tmp)
}type MyStr1 stringfunc (tmp MyStr1) sayhi() {fmt.Printf("MyStr1[%s] sayhi\n", tmp)
}// 定义一个普通函数,函数的参数为接口类型
// 只有一个函数,可以有不同表现,多态
func WhoSayHi(i Humaner) {i.sayhi()
}func main() {s := &Student{"mike", 666}t := &Teacher{"wh", "go"}var str MyStr = "hello cheng"var str1 MyStr1 = "hello"//调用同一函数,不同表现,多态,多种形态WhoSayHi(s)WhoSayHi(t)WhoSayHi(&str)WhoSayHi(str1)//创建一个切片x := make([]Humaner, 4)x[0] = sx[1] = tx[2] = &strx[3] = str1//第一个返回下标,第二个返回鞋标所对应的值for _, data := range x {fmt.Println("===========")WhoSayHi(data)}
}

接口继承—(接口嵌入)

如果一个interface1作为interface2的一个嵌入字段,那么interface2隐式地包含了interface1里面的方法。

package mainimport "fmt"// Humaner 定义接口类型
type Humaner interface { //子集//方法,只有声明,没有实现,由别的类型(自定义类型)实现sayhi()
}type Personer interface { //超集Humaner //匿名字段,继承了sayhi()sing(lrc string)
}type Student struct {name stringid   int
}// Student实现了此方法
func (tmp *Student) sayhi() {fmt.Printf("Student[%s, %d] sayhi\n", tmp.name, tmp.id)}func (tmp *Student) sing(lrc string) {fmt.Println("Student在唱着:", lrc)
}func main() {//定义一个接口类型的变量var i Personers := &Student{"mike", 666}i = si.sayhi()    //继承过来的方法 //Student[mike, 666] sayhii.sing("三月") //Student在唱着: 三月
}

接口转换

package mainimport "fmt"// Humaner 定义接口类型
type Humaner interface { //子集//方法,只有声明,没有实现,由别的类型(自定义类型)实现sayhi()
}type Personer interface { //超集Humaner //匿名字段,继承了sayhi()sing(lrc string)
}type Student struct {name stringid   int
}// Student实现了此方法
func (tmp *Student) sayhi() {fmt.Printf("Student[%s, %d] sayhi\n", tmp.name, tmp.id)}func (tmp *Student) sing(lrc string) {fmt.Println("Student在唱着:", lrc)
}func main() {//超集可以转换为子集,反过来不可以var iPro Personer //超集iPro = &Student{"mike", 666}var i Humaner //子集//cannot use i (variable of type Humaner) as Personer value in assignment://Humaner does not implement Personer (missing method sing)//iPro = i //errori = iPro //OK 超集可以转换为子集i.sayhi()
}

空接口

空接口不包含任何的方法,正因为如此,所有的类型都实现了空接口,因此空接口可以存储任意类型,它有点类似于C语言的void*类型。
在这里插入图片描述

package mainimport "fmt"func xxx(args ...interface{}) {}func main() {//空接口万能类型,保存任意类型的值var i interface{} = 1fmt.Println("i = ", i)i = "abc"fmt.Println("i = ", i)
}

通过if实现类型断言

在这里插入图片描述

package mainimport "fmt"type Student struct {name stringid   int
}func main() {i := make([]interface{}, 3)i[0] = 1                    //inti[1] = "hello go"           //stringi[2] = Student{"mike", 666} //Student//类型查询,类型断言//第一个返回下标,第二个返回下标对应的值,data是i[0],i[1],i[2]for index, data := range i {//第一个返回值,接口变量本身,第二个返回判断结果的真假if value, ok := data.(int); ok == true {fmt.Printf("x[%d] 类型为int,内容为%d\n", index, value) //x[0] 类型为int,内容为1fmt.Println("int data = ", data)                 //int data =  1fmt.Println("------------------")} else if value, ok := data.(string); ok == true {fmt.Printf("x[%d] 类型为string, 内容为%s\n", index, value) //x[1] 类型为string, 内容为hello gofmt.Println("string data = ", data)                  //string data =  hello gofmt.Println("------------------")} else if value, ok := data.(Student); ok == true {fmt.Printf("x[%d] 类型为Student, 内容为name = %s, id = %d\n", index, value.name, value.id) //x[2] 类型为Student, 内容为name = mike, id = 666fmt.Println("Student data = ", data)                                                 //Student data =  {mike 666}fmt.Println("------------------")}}
}

通过switch实现类型断言

package mainimport "fmt"type Student struct {name stringid   int
}func main() {i := make([]interface{}, 3)i[0] = 1                    //inti[1] = "hello go"           //stringi[2] = Student{"mike", 666} //Student//类型查询,类型断言//第一个返回下标,第二个返回下标对应的值,data是i[0],i[1],i[2]for index, data := range i {switch value := data.(type) { //type参数类型case int:fmt.Printf("x[%d] 类型为int,内容为%d\n", index, value) //x[0] 类型为int,内容为1fmt.Println("int data = ", data)                 //int data =  1fmt.Println("------------------")case string:fmt.Printf("x[%d] 类型为string, 内容为%s\n", index, value) //x[1] 类型为string, 内容为hello gofmt.Println("string data = ", data)                  //string data =  hello gofmt.Println("------------------")case Student:fmt.Printf("x[%d] 类型为Student, 内容为name = %s, id = %d\n", index, value.name, value.id) //x[2] 类型为Student, 内容为name = mike, id = 666fmt.Println("Student data = ", data)                                                 //Student data =  {mike 666}fmt.Println("------------------")}}
}

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

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

相关文章

HTTP代理如何设置

HTTP代理是一种非常重要的网络工具,它可以帮助我们在访问互联网时提高访问速度,保护用户隐私等等。在使用HTTP代理时,需要先进行设置。下面就来介绍一下HTTP代理如何设置。 一、了解HTTP代理 在开始设置HTTP代理之前,我们需要先了…

html 标签简介

概述 标签的效果不重要,重要的是标签的语义。 文本标签 文本标签用于包裹:词汇、短语等。排版标签,比如div,p,h1等。排版标签更宏观(大段的文字),文本标签更微观(词汇、短语)。文…

西门子LAD编程扫描周期带来的步序跳转问题

一、程序目的 按一下启动,程序进入第一步。延时五秒之后进入第二步进行自加1,然后回到第一步继续延时5秒循环,依次类推。 二、出现的问题 第一次程序进入第一步时,定时器正常定时,计数正常加1,但从第二轮开…

文件上传漏洞-upload靶场5-12关

文件上传漏洞-upload靶场5-12关通关笔记(windows环境漏洞) 简介 ​ 在前两篇文章中,已经说了分析上传漏的思路,在本篇文章中,将带领大家熟悉winodws系统存在的一些上传漏洞。 upload 第五关 (大小写绕过…

【DataV/echarts】vue中使用,修改地图和鼠标点击部分的背景色

引入:使用 DataV 引入地图的教程是参考别人的,主要介绍修改地图相关的样式; 引入地图 是参考别人的,这里自己再整理一遍,注意需要安装 5 版本以上的 echarts; DataV 网址:https://datav.aliyun.…

浅谈Http协议、TCP协议(转载)

TCP标志位,有6种标示:SYN(synchronous建立联机) ,ACK(acknowledgement 确认) ,PSH(push传送),FIN(finish结束) ,RST(reset重置), URG(urgent紧急) Sequence number(顺序号码) ,Acknowledge num…

《向量数据库指南》——向量数据库Milvus Cloud 2.3的可运维性:从理论到实践

一、引言 在数据科学的大家庭中,向量数据库扮演着重要角色。它们通过独特的向量运算机制,为复杂的机器学习任务提供了高效的数据处理能力。然而,如何让这些数据库在生产环境中稳定运行,成为了运维团队的重要挑战。本文将深入探讨向量数据库的可运维性,并分享一些有趣的案…

新风机未来什么样?

新风机在未来将会有许多令人期待的发展和改进,让我们一起来看一看吧!以下是新风机未来的一些可能性: 智能化和智能家居:新风机将更多地与智能家居系统整合,通过物联网和人工智能技术,实现智能控制和智能调节…

听觉刺激期间的神经血管耦合:ERPs和fNIRS血流动力学

导读 强度依赖性振幅变化(IDAP)已在事件相关电位(ERPs)中进行了广泛的研究,并与多种精神疾病相关联。本研究旨在探讨功能近红外光谱(fNIRS)在IDAP范式中的应用,该范式与ERPs相关,可以指示神经血管耦合的存在。两个实验分别有33和31名参与者。…

JS的深拷贝和浅拷贝

‍本文作者是360奇舞团开发工程师 数据类型的数据存储 在讨论深拷贝和浅拷贝之前,先来了解下Js基本数据和引用数据类型的存储问题 基本数据类型:Number String Boolean Undefined Symbol Null引用类型 :Object,function,Array等 基本数据类型…

ChatGPT:深度学习和机器学习的知识桥梁

目录 ChatGPT简介 ChatGPT的特点 ChatGPT的应用领域 ChatGPT的工作原理 与ChatGPT的交互 ChatGPT的优势 ChatGPT在机器学习中的应用 ChatGPT在深度学习中的应用 总结 近年来,随着深度学习技术的不断发展,自然语言处理技术也取得了显著的进步。其…

Bean 的生命周期总结

目录 一、Bean生命周期的五个阶段 Bean的初始化 二、PostConstruct 和 PreDestroy 各自的效果 三、 实例化和初始化的区别 四、为什么要先设置属性在进⾏初始化呢? 一、Bean生命周期的五个阶段 Java 中的公共类称之为 Bean 或 Java Bean,而 Spring 中的…

STM32F4X RNG随机数发生器

STM32F4X RNG随机数发生器 随机数的作用STM32F4X 随机数发生器RNG控制寄存器RNG状态寄存器RNG数据寄存器RNG数据步骤RNG例程 随机数的作用 随机数顾名思义就是随机产生的数字,这种数字最大的特点就是其不确定性,你不知道它下一次产生的数字是什么。随机…

计算机网络-谢希任第八版学习笔记总结

一.计算机网络概述 21世纪三个特点 数字化 信息化 智能化,其中主要是围绕智能化。 网络的常见分类: 电话网络 有线电视网络 计算机网络 互联网:Internet 由数量极大的计算机网络相连接 特点: 共享性 连通性 互联网&…

【深度学习】基于卷积神经网络的铁路信号灯识别方法

基于卷积神经网络的铁路信号灯识别方法 摘 要:1 引言2 卷积神经网络模型2.1 卷积神经网络结构2.2.1 卷积层2.2.2 池化层2.2.3 全连接层 3 卷积神经网络算法实现3.1 数据集制作3.2 卷积神经网络的训练过程3.2.1 前向传播过程 4 实验5 结语 摘 要: 目前中…

系统架构设计师(第二版)学习笔记----系统架构设计师概述

【原文链接】系统架构设计师(第二版)学习笔记----系统架构设计师概述 文章目录 一、架构设计师的定义、职责和任务1.1 架构设计师的定义1.2 架构设计师的任务 二、架构设计师应具备的专业素质2.1 架构设计师应具备的专业知识2.2 架构设计师的知识结构2.3…

网络威胁防御+资产测绘系统-Golang开发

NIPS-Plus 网络威胁防御资产测绘系统-Golang开发 项目地址:https://github.com/jumppppp/NIPS-Plus NIPS-Plus 是一款使用golang语言开发的网络威胁防御系统(内置资产测绘系统) 网络威胁流量视图网络威胁详细信息浏览列表网络威胁反制探测攻…

CRM 自动化如何改善销售和客户服务?

许多 B2B 和 B2C 公司都使用 CRM 系统来组织业务流程,使复杂的任务更容易完成。企业可以使用 CRM 自动化来自动化工作流程,让团队有更多的时间来执行高价值的任务,而不是陷于一堆琐碎事情中。 什么是CRM自动化? CRM 自动化是指 C…

VScode SSH无法免密登录

配置方法 引用高赞贴:点击 debug方法 连不上需要找到问题原因,看ssh的 log Linux服务器:2222是我们指定的端口,可以是1234等 sudo /usr/sbin/sshd -d -p 2222windows这边:端口号要一致 ssh -vvv ubuntusername192…

自然语言处理——数据清洗

一、什么是数据清洗 数据清洗是指发现并纠正数据文件中可识别的错误的最后一道程序,包括检查数据一致性,处理无效值和缺失值等。与问卷审核不同,录入后的数据清理一般是由计算机而不是人工完成。 ——百度百科 二、为什么要数据清洗 现实生…