Go语言之函数、方法、接口
一、函数
函数的基本语法:
func 函数名(形参列表)(返回值列表) {执行语句...return 返回值列表
}
1.形参列表:表示函数的输入
2.函数中的语句:表示为了实现某一功能的代码块
3.函数可以有返回值,也可以没有
- 函数的调用
func main() {sum = max(1, 2)fmt.Printf("最大值是:%d\n", sum)
}
//一个返回值不用加括号
func max(num1, num2 int) int {var result intif num1 > num2 {result = num1 } else {result = num2}return result
}
- 函数首字母大写,该函数可以被本文件包和其他包文件使用,类似public;首字母小写,只能被本包文件使用,其他包文件不能被使用,类似private
- Go函数不支持函数重载
func text(a int){fmt.Println(a)
}
//Go语言不支持传统的函数重载,会报函数重复定义
func **text**(a int , b int) {}
- 在Go中函数也是一种数据类型,可以赋值给一个变量,则该变量就是一个函数类型的变量了。通过该变量可以对函数调用
func getSum(n1 int, n2 int) int {return n1 + n2
}func main() {a := getSum //将函数赋值给一个变量,此时变量a是函数类型fmt.Printf("a的类型%T, getSum类型是%T\n", a, getSum)// a的类型func(int, int) int, getSum类型是func(int, int) intres := a(10, 40) // 等价 res := getSum(10, 40)fmt.Println("res=", res) //res= 50}
函数参数
传递参数:
- 基本数据类型和数组默认都是值传递的,即进行值拷贝。在函数内修改,不会影响到原来的值。
func test01(n1 int) {n1 = n1 + 10fmt.Println("test01() n1= ", n1) //test01() n1= 30
}func main() {num := 20test01(num)fmt.Println("main() num= ", num) //main() num= 20
}
- 如果希望函数内的变量能修改函数外的变量(指的是默认以值传递的方式的数据类型),可以传入变量的地址&,函数内以指针的方式操作变量。从效果上看类似引用。
// n1 就是 *int 类型
func test02(n1 *int) {fmt.Printf("n1的值=%v\n", n1) //n1的值=0xc04200e0b0*n1 = *n1 + 10fmt.Println("test02() n1= ", *n1) // test02() n1= 30
}func main() {num = 20fmt.Printf("num的地址=%v\n", &num) //num的地址=0xc04200e0b0test02(&num)fmt.Println("main() num= ", num) // main() num= 30
}
- 值类型和引用类型
值类型:基本数据类型int系列, float 系列, boo1, string 、数组和结构体struct
引用类型:指针、slice切片、map、管道chan、interface 等都是引用类型 - 不管是指针、引用类型,还是其他类型参数,都是值拷贝传递。区别只是拷贝目标对象还是拷贝指针而已。
可变参数:
//支持o到多个参数
func sum(args... int) sum int {}
//支持1到多个参数
func sum(n1 int, args... int) sum int {
}
- 可变参数本质就是一个切片,args[index]可以访间到各个值,只能接收一个到多个同类型参数,且必须放在列表尾部
func sum(n1 int, args... int) int {sum := n1 //遍历args for i := 0; i < len(args); i++ {sum += args[i] //args[0] 表示取出args切片的第一个元素值,其它依次类推}return sum
}func main() {res4 := sum(10, 90, 10,100)fmt.Println("res4=", res4) //res4= 210
}
- 将切片作为变参时,需进行展开操作,如果是数组,先将其转换为切片
func test(a ...int) {fmt.Println(a) //[10 20 30]
}func main() {a := []int{10, 20, 30} //先将数组转成slicetest(a...) //将slice展开
}
函数作为另一个函数的参数:
- 函数既然是一种数据类型,因此在Go中,函数可以作为形参,并且调用
func getSum(n1 int, n2 int) int {return n1 + n2
}//函数既然是一种数据类型,因此在Go中,函数可以作为形参,并且调用
func myFun(funvar func(int, int) int, num1 int, num2 int ) int {return funvar(num1, num2)
}func main() {//看案例res2 := myFun(getSum, 50, 60) //将getSum函数作为myFun函数的参数fmt.Println("res2=", res2)
}
返回值
- 返回值列表也可以是多个
func swap(x, y string) (string, string) {return y, x
}func main() {a, b := swap("Google", "Runoob")fmt.Println(a, b)
}
- 使用_标识符,忽略返回值
func cal(n1 int, n2 int) (int, int) {sum := n1 + n2sub := n1 - n2return sum, sub
}func main() {res1, _ := cal(10, 20) //忽略第二个返回值fmt.Printf("res1=%d\n", res1) //res1=30
}
命名返回值:支持对函数返回值命名(优缺点共存)
- 命名返回值和参数一样,可当作函数局部变量使用,最后由return隐式返回
//支持对函数返回值命名
func getSumAndSub(n1 int, n2 int) (sum int, sub int){sub = n1 - n2sum = n1 + n2return
}
func main() {a1, b1 := getSumAndSub(1, 2)fmt.Printf("a=%v b=%v\n", a1, b1) //a1=3 b1=-1
}
匿名函数
Go支持匿名函数,匿名函数就是没有名字的函数,如果我们某个函数只是希望使用一次,可以考虑使用匿名函数,匿名函数也可以实现多次调用。
- 在定义匿名函数时就直接调用,这种方式匿名函数只能调用一次。
func main() {//在定义匿名函数时就直接调用,这种方式匿名函数只能调用一次res1 := func (n1 int, n2 int) int {return n1 + n2}(10, 20)fmt.Println("res1=", res1) //res1= 30
}
- 将匿名函数赋给一个变量(函数变量),再通过该变量来调用匿名函数
func main() {//将匿名函数func (n1 int, n2 int) int赋给 a变量//则a 的数据类型就是函数类型 ,此时,我们可以通过a完成调用a := func (n1 int, n2 int) int {return n1 - n2}res2 := a(10, 30)fmt.Println("res2=", res2) //res2= -20res3 := a(90, 30)fmt.Println("res3=", res3) //res3= 60
}
闭包:
闭包就是一个函数和其他的相关的引用环境组合的一个整体(实体)
//累加器
func AddUpper() func (int) int {var n int = 10 return func (x int) int {n = n + xreturn n}
}func main() {//使用前面的代码f := AddUpper()fmt.Println(f(1))// 11 fmt.Println(f(2))// 13fmt.Println(f(3))// 16
}
- 返回的是一个匿名函数,但是这个匿名函数引用到函数外的n ,因此这个匿名函数就和n形成一个整体,构成闭包。
延迟处理defer
在函数中,程序员经常需要创建资源(比如:数据库连接、文件句柄、锁等),为了在函数执行完毕后,及时的释放资源,Go的设计者提供defer (延时机制)。
- 当go执行到一个defer时,不会立即执行defer后的语句,而是将defer后的语句压入到一个栈中,然后继续执行函数下一个语句。
- 当函数执行完毕后,在从defer栈中,依次从栈顶取出语句执行(注:遵守栈先入后出的机制)。
- 在defer将语句放入到栈时,也会将相关的值拷贝同时入栈
func sum(n1 int, n2 int) int {//当执行到defer时,暂时不执行,会将defer后面的语句压入到独立的栈(defer栈)//当函数执行完毕后,再从defer栈,按照先入后出的方式出栈,执行defer fmt.Println("ok1 n1=", n1) //defer 3. ok1 n1 = 10defer fmt.Println("ok2 n2=", n2) //defer 2. ok2 n2= 20//增加一句话n1++ // n1 = 11n2++ // n2 = 21res := n1 + n2 // res = 32fmt.Println("ok3 res=", res) // 1. ok3 res= 32return res
}func main() {res := sum(10, 20)fmt.Println("res=", res) // 4. res= 32
}
- 最佳实践:当函数执行完毕后,可以及时的释放函数创建的资源
func test() {//关闭文件资源file = openfile(文件名)defer file.close()//其他代码
}
错误处理
在Go语言中,错误被认为是一种可以预期的结果;而异常则是一种非预期的结果,发生异常可能表示程序中存在BUG或发生了其它不可控的问题。
错误:
Go语言中,错误被认为是一种可以预期的结果;而异常则是一种非预期的结果,发生异常可能表示程序中存在BUG或发生了其它不可控的问题。
Go中的错误类型:error
type error interface {Error() string
}
函数通常可在最后一个返回值中返回错误信息,自定义错误:errors.New(“错误说明”),会返回一个error类型的值,表示一个错误
func myF(f float64) (float64, error) {if f < 0 {return 0, errors.New("Not legal input ")}// 实现return 0.0, nil
}func main() {_, e := myF(-1)_, e2 := myF(2)fmt.Println(e) // Not legal inputfmt.Println(e2) // <nil>
}
异常处理:
Go语言追求简洁优雅,所以,Go语言不支持传统的 try…catch…finally 这种处理
Go中引入的处理方式为: defer, panic, recover。Go中可以抛出一个panic 的异常,然后在defer中通过recover捕获这个异常,然后正常处理
-
defer是Go提供的一种延迟执行机制,每次执行 defer,都会将对应的函数压入栈中。在函数返回或者 panic 异常结束时,Go 会依次从栈中取出延迟函数执行。
-
panic用于主动抛出程序执行的异常,会终止其后将要执行的代码,并依次逆序执行 panic 所在函数可能存在的 defer 函数列表。panic 内置函数 ,接收一个interface{}类型的值(也就是任何值了)作为参数。可以接收error类型的变量,输出错误信息,并退出程序.
-
recover 关键字主要用于捕获异常,将程序状态从严重的错误中恢复到正常状态。 必须在 defer 函数中才能生效。
defer+panic+recover的代码样例:
func my(i int) int {defer func() {if err := recover(); err != nil {fmt.Println("发生了异常", err)}}()if i != 5 {return i} else {panic("panic")}return -1
}
func main() {for i := 0; i < 10; i++ {a := my(i)fmt.Println(a)}
}
运行结果:
0
1
2
发生了异常 panic
0
4
使用defer+recover来处理错误:
func test() {//使用defer + recover 来捕获和处理异常defer func() {err := recover() // recover()内置函数,可以捕获到异常if err != nil { // 说明捕获到错误fmt.Println("err=", err)//这里就可以将错误信息发送给管理员....fmt.Println("发送邮件给admin@sohu.com~")}}()num1 := 10num2 := 0res := num1 / num2fmt.Println("res=", res)
}
func main() {test()
}

内置函数
Go 语言拥有一些不需要进行导入操作就可以使用的内置函数。它们有时可以针对不同的类型进行操作,例如:len、cap 和 append,或必须用于系统级的操作
append -- 用来追加元素到数组、slice中,返回修改后的数组、slice
close -- 主要用来关闭channel
delete -- 从map中删除key对应的value
panic -- 停止常规的goroutine (panic和recover:用来做错误处理)
recover -- 允许程序定义goroutine的panic动作
real -- 返回complex的实部 (complex、real imag:用于创建和操作复数)
imag -- 返回complex的虚部
make -- 用来分配内存,返回Type本身(只能应用于slice, map, channel)
new -- 用来分配内存,主要用来分配值类型,比如int、struct。返回指向Type的指针
cap -- capacity是容量的意思,用于返回某个类型的最大容量(只能用于切片和 map)
copy -- 用于复制和连接slice,返回复制的数目
len -- 来求长度,比如string、array、slice、map、channel ,返回长度
print、println -- 底层打印函数,在部署环境中建议使用 fmt 包
new的使用:
func main() {num1 := 100fmt.Printf("num1的类型%T , num1的值=%v , num1的地址%v\n", num1, num1, &num1)num2 := new(int) // *int//num2的类型%T => *int//num2的值 = 地址 0xc04204c098 (这个地址是系统分配)//num2的地址%v = 地址 0xc04206a020 (这个地址是系统分配)//num2指向的值 = 100*num2 = 100fmt.Printf("num2的类型%T , num2的值=%v , num2的地址%v\n num2这个指针,指向的值=%v", num2, num2, &num2, *num2)
}

二、方法
2.1 方法简介
方法是与指定的数据类型绑定的特殊函数
- go方法的声明:
func (t type) methodName (参数列表) (返回值列表){方法体return 返回值
}
// t type 表示这个方法和type这个类型进行绑定,t为type的一个实例
- func (p Person) methodName (参数列表) (返回值列表){},t表示哪个Person变量调用,这个p就是它的副本。
- 举例说明:
type Person struct {Name stringAge int Hometown string score map[string]int
}
func (p Person) test() {p.Age += 1p.score["China"] += 1 //对于引用数据类型会修改其值
}func main() {m0 := make(map[string]int)m0["China"] = 80person0 := Person{"szc", 23, "Henan Anyang", m0}person2 := new (Person)(*person2).Name = "Jason"(*person2).Age = 24m2 := make(map[string]int)m2["Math"] = 90(*person2).score = m2person0.test()fmt.Println(person0)(*person2).test()fmt.Println(*person2)
}

方法的调用和传参机制:
- 方法的调用和传参机制和函数基本一样。不一样的地方时,变量调用方法时,该变量本身也会作为一个参数传递到方法(如果变量是值类型,则进行值拷贝,如果变量是引用类型,则进行地质拷贝)
方法的注意事项:
- 如果希望修改结构体变量的值,可以通过结构体指针的方式来处理
type Circle struct {radius float64
}//为了提高效率,通常我们方法和结构体的指针类型绑定
func (c *Circle) area2() float64 {//因为 c是指针,因此我们标准的访问其字段的方式是 (*c).radius//return 3.14 * (*c).radius * (*c).radius// (*c).radius 等价 c.radius fmt.Printf("c 是 *Circle 指向的地址=%p\n", c)c.radius = 10return 3.14 * c.radius * c.radius
}func main() {//创建一个Circle 变量var c Circle fmt.Printf("main c 结构体变量地址 =%p\n", &c)c.radius = 7.0//res2 := (&c).area2()//编译器底层做了优化 (&c).area2() 等价 c.area()//因为编译器会自动的给加上 &cres2 := c.area2()fmt.Println("面积=", res2)fmt.Println("c.radius = ", c.radius) //10
}

- Golang中的方法作用在指定的数据类型上的(即:和指定的数据类型绑定),因此自定义类型,都可以有方法,而不仅仅是struct,比如int , float32等都可以有方法。
func (i integer) print() {fmt.Println("i=", i)
}
//编写一个方法,可以改变i的值
func (i *integer) change() {*i = *i + 1
}func main() {var i integer = 10i.print()i.change()fmt.Println("i=", i)
}
- 如果一个类型实现了String()这个方法,那么fint.Println默认会调用这个变量的String()进行输出
如果String()方法绑定的是结构体指针,那么输出时要传入地址,否则会按照原来的方式输出
type Student struct {Name stringAge int
}//给*Student实现方法String()
func (stu *Student) String() string {str := fmt.Sprintf("Name=[%v] Age=[%v]", stu.Name, stu.Age)return str
}func main() {//定义一个Student变量stu := Student{Name : "tom",Age : 20,}//如果你实现了 *Student 类型的 String方法,就会自动调用fmt.Println(&stu)
}
- 对于方法(如 struct的方法),接收者为值类型时,可以直接用指针类型的变量调用方法,反过来同样也可以
- 对于普通函数,接收者为值类型时,不能将指针类型的数据直接传递,反之亦然
type Person struct {Name string
} //函数
//对于普通函数,接收者为值类型时,不能将指针类型的数据直接传递,反之亦然func test01(p Person) {fmt.Println(p.Name)
}func test02(p *Person) {fmt.Println(p.Name)
}//对于方法(如struct的方法),
//接收者为值类型时,可以直接用指针类型的变量调用方法,反过来同样也可以func (p Person) test03() {p.Name = "jack"fmt.Println("test03() =", p.Name) // jack
}func (p *Person) test04() {p.Name = "mary"fmt.Println("test03() =", p.Name) // mary
}func main() {p := Person{"tom"}test01(p)test02(&p)p.test03()fmt.Println("main() p.name=", p.Name) // tom(&p).test03() // 从形式上是传入地址,但是本质仍然是值拷贝fmt.Println("main() p.name=", p.Name) // tom(&p).test04()fmt.Println("main() p.name=", p.Name) // maryp.test04() // 等价 (&p).test04 , 从形式上是传入值类型,但是本质仍然是地址拷贝}
*不管调用形式如何,真正决定是值拷贝还是地址拷贝,看这个方法是和哪个类型绑定。如果是值类型,比如(p Person),则是值拷贝,如果和指针类型,比如是( Person)则是地址拷贝。

通过方法封装
封装的实现步骤:
- 将结构体、字段的首字母小写;
- 给结构体所在的包提供一个工厂模式的函数,首字母大写,类似一个构造函数;
- 提供一个首字母大写的 Set 方法(类似其它语言的 public),用于对属性判断并赋值;
- 提供一个首字母大写的 Get 方法(类似其它语言的 public),用于获取属性的值。
type person struct {Name stringage int //其它包不能直接访问..sal float64
}//写一个工厂模式的函数,相当于构造函数
func NewPerson(name string) *person {return &person{Name : name,}
}//为了访问age 和 sal 我们编写一对SetXxx的方法和GetXxx的方法
func (p *person) SetAge(age int) {if age >0 && age <150 {p.age = age} else {fmt.Println("年龄范围不正确..")//给程序员给一个默认值}
}
func (p *person) GetAge() int {return p.age
}func (p *person) SetSal(sal float64) {if sal >= 3000 && sal <= 30000 {p.sal = sal} else {fmt.Println("薪水范围不正确..")}
}func (p *person) GetSal() float64 {return p.sal
}func main() {var p *person = NewPerson("smith")p.SetAge(18)p.SetSal(5000)fmt.Println(*p)fmt.Println(p.Name, " age =", p.GetAge(), " sal = ", p.GetSal())
}
三、接口
接口简介
interface 类型可以定义一组方法,但是这些不需要实现,并且 interface不能包含任何变量。
-
Go接口实现机制很简洁,只要目标类型方法集内包含接口声明的全部方法,就被视为实现了该接口,无须做显式声明
-
接口可以嵌入其他接口类型
-
接口只能声明方法,不能实现
-
一个自定义类型可以实现多个接口
-
接口通常以 er 作为名称后缀
-
只要是自定义数据类型,就可以实现接口,不仅仅是结构体类型。
type integer int func (i integer) Say() {fmt.Println("inter Say i =" , i )
}var i integer = 10 var b AInterface = ib.Say()// integer Say i = 10
代码示例:
//声明/定义一个接口
type Usber interface {//声明了两个没有实现的方法Start() Stop()
}type Phone struct {} //让Phone 实现 Usb接口的方法,就实现了Usb接口
func (p Phone) Start() {fmt.Println("手机开始工作。。。")
}
func (p Phone) Stop() {fmt.Println("手机停止工作。。。")
}//计算机
type Computer struct {}//编写一个方法Working 方法,接收一个Usb接口类型变量
//只要是实现了 Usb接口 (所谓实现Usb接口,就是指实现了 Usb接口声明所有方法)
func (c Computer) Working(usb Usber) {//通过usb接口变量来调用Start和Stop方法usb.Start()usb.Stop()
}func main() {//测试//先创建结构体变量computer := Computer{}phone := Phone{}//关键点computer.Working(phone)
}

类型转换
- 类型转换可将接口变量还原为原始类型,或用来判断是否实现了某个更具体的接口类型
//类型断言的其它案例
var x interface{}
var b2 float32 = 1.1
x = b2 //空接口,可以接收任意类型
// x=>float32 [使用类型断言]
y := x.(float32)
fmt.Printf("y 的类型是 %T 值是=%v", y, y) //y 的类型是 float32 值是=1.1
- 待检测机制的类型断言
type Point struct {x inty int
}func main() {var a interface{}var point Point = Point{1, 2}a = point //okvar b Point//类型断言(带检测的),如果成功返回trueb, ok := a.(Point)if ok {fmt.Println("convert success")fmt.Printf("y 的类型是 %T 值是=%v", b, b)} else {fmt.Println("convert fail")}
}相关文章:
Go语言之函数、方法、接口
一、函数 函数的基本语法: func 函数名(形参列表)(返回值列表) {执行语句...return 返回值列表 } 1.形参列表:表示函数的输入 2.函数中的语句:表示为了实现某一功能的代码块 3.函数可以有返回…...
【Week Y2】使用自己的数据集训练YOLO-v5s
Y2-使用自己的数据集训练YOLO-v5s 零、遇到的问题汇总(1)遇到git的import error(2)Error:Dataset not found(3)Error:删除中文后,训练图片路径不存在 一、.xml文件里保存…...
蓝桥杯--基础(哈夫曼)
import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Scanner;public class BASIC28 {//哈夫曼书public static void main(String[] args) {Scanner Scannernew Scanner(System.in);int nScanner.nextInt();List<Integer&…...
【Redis内存数据库】NoSQL的特点和应用场景
前言 Redis作为当今最流行的内存数据库,已经成为服务端加速的必备工具之一。 NoSQL数据库采用了非关系型的数据存储模型,能够更好地处理海量数据和高并发访问。 内存数据库具有更快的读写速度和响应时间,因为内存访问速度比磁盘访问速度快…...
JavaScript基础知识2
求数组的最大值案例 let arr[2,6,1,7,400,55,88,100]let maxarr[0]let minarr[0]for(let i1;i<arr.length;i){max<arr[i]?maxarr[i]:maxmin>arr[i]?minarr[i]:min}console.log(最大值是:${max})console.log(最小值是:${min}) 操作数组 修改…...
Linux之线程同步
目录 一、问题引入 二、实现线程同步的方案——条件变量 1、常用接口: 2、使用示例 一、问题引入 我们再次看看上次讲到的多线程抢票的代码:这次我们让一个线程抢完票之后不去做任何事。 #include <iostream> #include <unistd.h> #inc…...
03 龙芯平台openstack部署搭建-keystone部署
#!/bin/bash #创建keystone数据库并授权,可通过mysql -ukeystone -ploongson验证授权登录 mysql -uroot -e “set password for rootlocalhost password(‘loongson’);” mysql -uroot -ploongson -e ‘CREATE DATABASE keystone;’ #本地登录 mysql -uroot -ploo…...
定义了服务器的端口号和Servlet的上下文路径
server: port: 1224 servlet: context-path: /applet 这个配置定义了服务器的端口号和Servlet的上下文路径。 下面是配置的解释: server.port: 1224:这表示服务器应该监听在1224端口上。server.servlet.context-path: /applet:这表…...
AI论文速读 | UniST:提示赋能通用模型用于城市时空预测
本文是时空领域的统一模型——UniST,无独有偶,时序有个统一模型新工作——UniTS,感兴趣的读者也可以阅读今天发布的另外一条。 论文标题:UniST: A Prompt-Empowered Universal Model for Urban Spatio-Temporal Prediction 作者&…...
rabbitmq-spring-boot-start配置使用手册
rabbitmq-spring-boot-start配置使用手册 文章目录 1.yaml配置如下2.引入pom依赖如下2.1 引入项目resources下libs中的jar包依赖如下2.2引入maven私服依赖如下 3.启动类配置如下4.项目中测试发送消息如下5.项目中消费消息代码示例6.mq管理后台交换机队列创建及路由绑定关系如下…...
操作系统知识-操作系统作用+进程管理-嵌入式系统设计师备考笔记
0、前言 本专栏为个人备考软考嵌入式系统设计师的复习笔记,未经本人许可,请勿转载,如发现本笔记内容的错误还望各位不吝赐教(笔记内容可能有误怕产生错误引导)。 本章的主要内容见下图: 1、操作系统的作用…...
Go语言中的锁与管道的运用
目录 1.前言 2.锁解决方案 3.管道解决方案 4.总结 1.前言 在写H5小游戏的时候,由于需要对多个WebSocket连接进行增、删、查的管理和对已经建立连接的WebSocket通过服务端进行游戏数据交换的需求。于是定义了一个全局的map集合进行连接的管理,让所有…...
前端 - 基础 表单标签 -- 表单元素( input - type属性) 文本框和密码框
表单元素 : 在表单域中可以定义各种表单元素,这些表单元素就是允许用户在表单中输入或选择 的内容控件。 表单元素的外观也各不一样,有小圆圈,有正方形,也有方框,乱七八糟的,各种各样…...
关于MySQL模糊搜索不区分大小写
在我们日常使用ORM框架进行模糊查询时,会发现,搜索的结果是不区分关键字的英文大小写的,那这是为什么呢? 原因是MySQL的like本就不区分大小写;如果在建表的时候,没有设置好字段区分大小 //包含j和J的都会被…...
论文阅读——MoCo
Momentum Contrast for Unsupervised Visual Representation Learning 动量在数学上理解为加权移动平均: yt-1是上一时刻输出,xt是当前时刻输入,m是动量,不想让当前时刻输出只依赖于当前时刻的输入,m很大时࿰…...
ARM 寄存器学习:(一)arm多种模式下得寄存器
一.ARM7种状态以及每种状态的寄存器: ARM 处理器共有 7 种不同的处理器模式,在每一种处理器模式中可见的寄存器包括 15 个通用寄存器( R0~R14)、一个或两个(User和Sys不是异常模式,没有spsr寄存器)状态寄存器(cpsr和spsr&…...
【nfs报错】rpc mount export: RPC: Unable to receive; errno = No route to host
NFS错误 问题现象解决方法 写在前面 这两天搭建几台服务器,需要使用nfs服务,于是六台选其一做服务端,其余做客户端,搭建过程写在centos7离线搭建NFS共享文件,但是访问共享时出现报错:rpc mount export: RPC…...
备战蓝桥杯---牛客寒假训练营2VP
题挺好的,收获了许多 1.暴力枚举(许多巧妙地处理细节方法) n是1--9,于是我们可以直接暴力,对于1注意特判开头0但N!1,对于情报4,我们可以把a,b,c,d的所有取值枚举一遍,那么如何判断有…...
QCustomPlot-绘制X轴为日期的折线图
主要代码如下: void Widget::InitQLineXDateAddData() {customPlot new QCustomPlot(this);// 创建日期时间类型的刻度生成器QSharedPointer<QCPAxisTickerDateTime> dateTimeTicker(new QCPAxisTickerDateTime);dateTimeTicker->setDateTimeFormat(&quo…...
腾讯春招后端一面(算法篇)
前言: 哈喽大家好,前段时间在小红书和牛客上发了面试的经验贴,很多同学留言问算法的具体解法,今天就详细写个帖子回复大家。 因为csdn是写的比较详细,所以更新比较慢,大家见谅~~ 就题目而言,…...
eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...
JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...
