go的学习笔记
中文标准库文档:https://studygolang.com/pkgdoc
第一段代码
所有代码的主文件都是main.go,下面的代码直接在项目里面创建main.go运行
package main // 声明文件所在的包,每个go文件必须有归属的包import "fmt" // 引入程序需要的包,为了使用包下的函数,比如Printlnfunc main() { // 程序的主函数,程序的运行入口fmt.Println("Hello World") // 在控制台打印输出一句话
}
如果是vscode等工具需要执行go run main.go
来运行,我这里使用的是goLand
右键直接运行了
注意事项:
- 源文件以
.go
为扩展名 - 程序的执行入口是main()函数
- 严格区分大小写
- 方法由一条条语句构成,每个语句后面不需要加分号,这也体现出go的简洁性
- Go编译器是一行行进行编译的,因此一行就写一条语句,不能把多个语句写在同一行,否则报错
- 定义的变量或者import的包如果没有使用到,代码不能编译通过
- 大括号都是成对出现的,缺一不可
变量的定义和使用
package mainimport "fmt"// 全局变量: 定义在函数外的变量
var n9 = 100
var n10 = 9.7// 一次性定义多个全局变量
var (n11 = 12n12 = "你好"
)func main() {// 定义在{}中的变量叫: 局部变量// 变量重复定义会报错var name string // 声明变量和类型name = "小明" // 赋值变量fmt.Println(name) // 打印值var age int = 18 // 声明变量和类型并赋值fmt.Println(age)var address = "北京" // 声明没指定类型时,根据后面的值的类型自动推断类型//address = 12 // 报错,因为上面类型推断为stringfmt.Println(address)stuName := "萧寂" // 声明和赋值fmt.Println("学生姓名为: ", stuName) // 打印值//count = 1 // 不能直接写等于号,除非:=或者var count = 1 必须要声明fmt.Println("--------------------------------------------")// 声明多个变量不赋值var n1, n2, n3 intfmt.Println(n1, n2, n3) // 不赋值情况下会打印每个类型的原始值// 声明多个变量并赋值var n4, n5, n6 = 14, "jack", 12.7fmt.Println(n4, n5, n6) // 声明多个变量并赋值n7, n8 := 12, "hahaha"fmt.Println(n7, n8)// 打印全局变量fmt.Println(n9, n10, n11, n12)
}
数据类型介绍
- 基本数据类型
- 数值型
- 整数类型(
int,int8,int16,int32,int64,uint,uint8,uint16,uint32,uint64,byte
) - 浮点类型(
float32,float64
)
- 整数类型(
- 字符型(
没有单独的字符型,使用byte来保存单个字母字符
) - 布尔型(
bool
) - 字符串(
string
)
- 数值型
- 派生数据类型(也是复杂数据类型)
- 指针
- 数组
- 结构体
- 管道
- 函数
- 切片
- 接口
- map
整数类型
package mainimport ("fmt""unsafe"
)func main() {// 整数类型// 定义一个整数类型//var num1 int8 = 230 // 报错(230超出int8范围)//fmt.Println(num1)// 定义整数类型var num2 = -20fmt.Println(num2)// 打印类型// 其他占位符的使用: https://www.jianshu.com/p/66aaf908045efmt.Printf("num2的类型是: %T", num2)fmt.Println() // 换行作用fmt.Println(unsafe.Sizeof(num2)) // 打印字节数// 定义byte类型var num3 byte = 20fmt.Println(num3)
}
浮点类型
package mainimport "fmt"func main() {// 定义浮点类型的数据var num1 float32 = 3.14var num2 float64 = 3.15fmt.Println(num1, num2)
}
字符类型
package mainimport "fmt"func main() {// 定义字符类型的数据var c1 byte = 'a'var c2 byte = 'b'var c3 byte = '('var c4 byte = '6'var c5 int = '中' // 底层是Unicode编码fmt.Println(c1, c2, c3, c4, c5)
}
布尔类型
package mainimport "fmt"func main() {// 测试布尔类型的数值var flag1 bool = truevar flag2 bool = falsevar flag3 = 5 < 9fmt.Println(flag1, flag2, flag3)
}
字符串类型
package mainimport "fmt"func main() {// 测试布尔类型的数值var str string = "你好"var str2 string = "世界"fmt.Println(str)fmt.Println(str+str2)
}
基本数据类型之间的转换
package main
import "fmt"
func main(){//进行类型转换:var n1 int = 100//var n2 float32 = n1 在这里自动转换不好使,比如显式转换fmt.Println(n1)//fmt.Println(n2)var n2 float32 = float32(n1)fmt.Println(n2)//注意:n1的类型其实还是int类型,只是将n1的值100转为了float32而已,n1还是int的类型fmt.Printf("%T",n1) //intfmt.Println()//将int64转为int8的时候,编译不会出错的,但是会数据的溢出var n3 int64 = 888888var n4 int8 = int8(n3)fmt.Println(n4)//56var n5 int32 = 12var n6 int64 = int64(n5) + 30 //一定要匹配=左右的数据类型fmt.Println(n5)fmt.Println(n6)var n7 int64 = 12var n8 int8 = int8(n7) + 127 //编译通过,但是结果可能会溢出//var n9 int8 = int8(n7) + 128 //编译不会通过fmt.Println(n8)//fmt.Println(n9)
}
基本数据类型转string
package main
import "fmt"
func main(){var n1 int = 19var n2 float32 = 4.78var n3 bool = falsevar n4 byte = 'a'var s1 string = fmt.Sprintf("%d",n1)fmt.Printf("s1对应的类型是:%T ,s1 = %q \n",s1, s1)var s2 string = fmt.Sprintf("%f",n2)fmt.Printf("s2对应的类型是:%T ,s2 = %q \n",s2, s2)var s3 string = fmt.Sprintf("%t",n3)fmt.Printf("s3对应的类型是:%T ,s3 = %q \n",s3, s3)var s4 string = fmt.Sprintf("%c",n4)fmt.Printf("s4对应的类型是:%T ,s4 = %q \n",s4, s4)
}
string转基本数据类型
package mainimport ("fmt""strconv"
)func main() {//string-->boolvar s1 string = "true"var b bool//ParseBool这个函数的返回值有两个:(value bool, err error)//value就是我们得到的布尔类型的数据,err出现的错误//我们只关注得到的布尔类型的数据,err可以用_直接忽略b, _ = strconv.ParseBool(s1)fmt.Printf("b的类型是:%T,b=%v \n", b, b)//string---》int64var s2 string = "19"var num1 int64num1, _ = strconv.ParseInt(s2, 10, 64)fmt.Printf("num1的类型是:%T,num1=%v \n", num1, num1)//string-->float32/float64var s3 string = "3.14"var f1 float64f1, _ = strconv.ParseFloat(s3, 64)fmt.Printf("f1的类型是:%T,f1=%v \n", f1, f1)//注意:string向基本数据类型转换的时候,一定要确保string类型能够转成有效的数据类型,否则最后得到的结果就是按照对应类型的默认值输出var s4 string = "golang"var b1 boolb1, _ = strconv.ParseBool(s4)fmt.Printf("b1的类型是:%T,b1=%v \n", b1, b1)var s5 string = "golang"var num2 int64num2, _ = strconv.ParseInt(s5, 10, 64)fmt.Printf("num2的类型是:%T,num2=%v \n", num2, num2)
}
指针
package mainimport ("fmt"
)func main() {var age int = 18//&符号+变量 就可以获取这个变量内存的地址fmt.Println(&age) //0xc0000a2058//定义一个指针变量://var代表要声明一个变量//ptr 指针变量的名字//ptr对应的类型是:*int 是一个指针类型 (可以理解为 指向int类型的指针)//&age就是一个地址,是ptr变量的具体的值var ptr *int = &agefmt.Println(ptr)fmt.Println("ptr本身这个存储空间的地址为:", &ptr)//想获取ptr这个指针或者这个地址指向的那个数据:fmt.Printf("ptr指向的数值为:%v", *ptr) //ptr指向的数值为:18
}
运算符
算术运算符
package mainimport "fmt"func main() {//+加号://1.正数 2.相加操作 3.字符串拼接var n1 int = +10fmt.Println(n1)var n2 int = 4 + 7fmt.Println(n2)var s1 string = "abc" + "def"fmt.Println(s1)// /除号:fmt.Println(10 / 3) //两个int类型数据运算,结果一定为整数类型fmt.Println(10.0 / 3) //浮点类型参与运算,结果为浮点类型// % 取模 等价公式: a%b=a-a/b*bfmt.Println(10 % 3) // 10%3= 10-10/3*3 = 1fmt.Println(-10 % 3)fmt.Println(10 % -3)fmt.Println(-10 % -3)//++自增操作:var a int = 10a++fmt.Println(a)a--fmt.Println(a)//++ 自增 加1操作,--自减,减1操作//go语言里,++,--操作非常简单,只能单独使用,不能参与到运算中去//go语言里,++,--只能在变量的后面,不能写在变量的前面 --a ++a 错误写法
}
赋值运算符
package mainimport "fmt"func main() {var num1 int = 10fmt.Println(num1)var num2 int = (10+20)%3 + 3 - 7 //=右侧的值运算清楚后,再赋值给=的左侧fmt.Println(num2)var num3 int = 10num3 += 20 //等价num3 = num3 + 20;fmt.Println(num3)//练习:交换两个数的值并输出结果:var a int = 8var b int = 4fmt.Printf("a = %v,b = %v", a, b)//交换://引入一个中间变量:var t intt = aa = bb = tfmt.Printf("a = %v,b = %v", a, b)
}
关系运算符
package mainimport "fmt"func main() {fmt.Println(5 == 9) //判断左右两侧的值是否相等,相等返回true,不相等返回的是false, ==不是=fmt.Println(5 != 9) //判断不等于fmt.Println(5 > 9)fmt.Println(5 < 9)fmt.Println(5 >= 9)fmt.Println(5 <= 9)
}
逻辑运算符
package mainimport "fmt"func main() {//与逻辑:&& :两个数值/表达式只要有一侧是false,结果一定为false//也叫短路与:只要第一个数值/表达式的结果是false,那么后面的表达式等就不用运算了,直接结果就是false -->提高运算效率fmt.Println(true && true)fmt.Println(true && false)fmt.Println(false && true)fmt.Println(false && false)//或逻辑:||:两个数值/表达式只要有一侧是true,结果一定为true//也叫短路或:只要第一个数值/表达式的结果是true,那么后面的表达式等就不用运算了,直接结果就是true -->提高运算效率fmt.Println(true || true)fmt.Println(true || false)fmt.Println(false || true)fmt.Println(false || false)//非逻辑:取相反的结果:fmt.Println(!true)fmt.Println(!false)
}
获取用户终端输入数据
package mainimport "fmt"func main() {//实现功能:键盘录入学生的年龄,姓名,成绩,是否是VIP//方式1:Scanlnvar age int// fmt.Println("请录入学生的年龄:")//传入age的地址的目的:在Scanln函数中,对地址中的值进行改变的时候,实际外面的age被影响了//fmt.Scanln(&age)//录入数据的时候,类型一定要匹配,因为底层会自动判定类型的var name string// fmt.Println("请录入学生的姓名:")// fmt.Scanln(&name)var score float32// fmt.Println("请录入学生的成绩:")// fmt.Scanln(&score)var isVIP bool// fmt.Println("请录入学生是否为VIP:")// fmt.Scanln(&isVIP)//将上述数据在控制台打印输出://fmt.Printf("学生的年龄为:%v,姓名为:%v,成绩为:%v,是否为VIP:%v",age,name,score,isVIP)//方式2:Scanffmt.Println("请录入学生的年龄,姓名,成绩,是否是VIP,使用空格进行分隔")fmt.Scanf("%d %s %f %t", &age, &name, &score, &isVIP)//将上述数据在控制台打印输出:fmt.Printf("学生的年龄为:%v,姓名为:%v,成绩为:%v,是否为VIP:%v", age, name, score, isVIP)
}
流程控制语句
if语句
单分支
package main
import "fmt"
func main(){//实现功能:如果口罩的库存小于30个,提示:库存不足://var count int = 100//单分支:// if count < 30 {// fmt.Println("对不起,口罩存量不足")// }//if后面表达式,返回结果一定是true或者false,//如果返回结果为true的话,那么{}中的代码就会执行//如果返回结果为false的话,那么{}中的代码就不会执行//if后面一定要有空格,和条件表达式分隔开来//{}一定不能省略//条件表达式左右的()是建议省略的//在golang里,if后面可以并列的加入变量的定义:if count := 20;count < 30 {fmt.Println("对不起,口罩存量不足")}
}
双分支
package mainimport "fmt"func main() {//实现功能:如果口罩的库存小于30个,提示:库存不足,否则提示:库存充足//定义口罩的数量:var count int = 70if count < 30 { //这个条件表达式返回的是true的话,后面{}执行了fmt.Println("库存不足")} else { //count >= 30fmt.Println("库存充足")}//双分支一定会二选一走其中一个分支。}
多分支
package mainimport "fmt"func main() {//实现功能:根据给出的学生分数,判断学生的等级:// >=90 -----A// >=80 -----B// >=70 -----C// >=60 -----D// <60 -----E//方式1:利用if单分支实现://定义一个学生的成绩:var score int = 18//对学生的成绩进行判定:// if score >= 90 {// fmt.Println("您的成绩为A级别")// }// if score >= 80 && score < 90 {// fmt.Println("您的成绩为B级别")// }// if score >= 70 && score < 80 {// fmt.Println("您的成绩为C级别")// }// if score >= 60 && score < 70 {// fmt.Println("您的成绩为D级别")// }// if score < 60 {// fmt.Println("您的成绩为E级别")// }//上面方式1利用多个单分支拼凑出多个选择,多个选择是并列的,依次从上而下顺序执行,即使走了第一个分支,那么其它分支也是需要判断//方式2:多分支:优点:如果已经走了一个分支了,那么下面的分支就不会再去判断执行了// if score >= 90 {// fmt.Println("您的成绩为A级别")// } else if score >= 80 {//else隐藏:score < 90// fmt.Println("您的成绩为B级别")// } else if score >= 70 {//score < 80// fmt.Println("您的成绩为C级别")// } else if score >= 60 {//score < 70// fmt.Println("您的成绩为D级别")// } else {//score < 60// fmt.Println("您的成绩为E级别")// } //建议你保证else的存在,只有有了else才会真正 起到多选一 的效果if score > 10 {fmt.Println("aaa")} else if score > 6 {fmt.Println("bbb")}
}
switch语句
package mainimport "fmt"func main() {//实现功能:根据给出的学生分数,判断学生的等级:// >=90 -----A// >=80 -----B// >=70 -----C// >=60 -----D// <60 -----E//给出一个学生分数:var score int = 187//根据分数判断等级://switch后面是一个表达式,这个表达式的结果依次跟case进行比较,满足结果的话就执行冒号后面的代码。//default是用来“兜底”的一个分支,其它case分支都不走的情况下就会走default分支//default分支可以放在任意位置上,不一定非要放在最后。switch score / 10 {case 10:fmt.Println("您的等级为A级")case 9:fmt.Println("您的等级为A级")case 8:fmt.Println("您的等级为B级")case 7:fmt.Println("您的等级为C级")case 6:fmt.Println("您的等级为D级")case 5:fmt.Println("您的等级为E级")case 4:fmt.Println("您的等级为E级")case 3:fmt.Println("您的等级为E级")case 2:fmt.Println("您的等级为E级")case 1:fmt.Println("您的等级为E级")case 0:fmt.Println("您的等级为E级")default:fmt.Println("您的成绩有误")}}
注意事项:
- switch后是一个表达式(即:常量值、变量、一个有返回值的函数等都可以)
- case后面的值如果是常量值(字面量),则要求不能重复
- case后的各个值的数据类型,必须和 switch 的表达式数据类型一致
- case后面可以带多个值,使用逗号间隔。比如 case 值1,值2…
- case后面不需要带break
- default语句不是必须的,位置也是随意的。
- switch后也可以不带表达式,当做if分支来使用
- switch后也可以直接声明/定义一个变量,分号结束,不推荐
- switch穿透,利用fallthrough关键字,如果在case语句块后增加fallthrough ,则会继续执行下一个case,也叫switch穿透。
循环
for循环
go语言只有for循环
package mainimport "fmt"func main() {//实现一个功能:求和: 1+2+3+4+5://求和://利用for循环来解决问题:var sum int = 0for i := 1; i <= 5; i++ {sum += i}//输出结果:fmt.Println(sum)// for循环的语法格式:// for 初始表达式; 布尔表达式(条件判断); 迭代因子 {// 循环体;--》反复重复执行的内容// }// 注意:for的初始表达式 不能用var定义变量的形式,要用:=// 注意:for循环实际就是让程序员写代码的效率高了,但是底层该怎么执行还是怎么执行的,底层效率没有提高,只是程序员写代码简洁了而已
}
细节1:格式灵活
package mainimport "fmt"func main() {i := 1 //变量的初始化for i <= 5 { //条件表达式。判断条件fmt.Println("你好 Golang") //循环体i++ //迭代}
}
细节2:死循环
package mainimport "fmt"func main() {//死循环:// for {// fmt.Println("你好 Golang")// }for {fmt.Println("你好 Golang")}
}
for renge键值对循环
(键值循环) for range结构是Go语言特有的一种的迭代结构,在许多情况下都非常有用,for range 可以遍历数组、切片、字符串、map 及通道,for range 语法上类似于其它语言中的 foreach 语句
package mainimport "fmt"func main() {//定义一个字符串:var str string = "hello golang你好"//方式1:普通for循环:按照字节进行遍历输出的 (暂时先不使用中文)// for i := 0;i < len(str);i++ {//i:理解为字符串的下标// fmt.Printf("%c \n",str[i])// }//方式2:for rangefor i, value := range str {fmt.Printf("索引为:%d,具体的值为:%c \n", i, value)}//对str进行遍历,遍历的每个结果的索引值被i接收,每个结果的具体数值被value接收//遍历对字符进行遍历的
}
关键字
break
- switch分支中,每个case分支后都用break结束当前分支,但是在go语言中break可以省略不写。
- break可以结束正在执行的循环
- break的作用结束离它最近的循环
package main
import "fmt"
func main(){//功能:求1-100的和,当和第一次超过300的时候,停止程序var sum int = 0for i := 1 ; i <= 100 ; i++ {sum += ifmt.Println(sum)if sum >= 300 {//停止正在执行的这个循环:break }}fmt.Println("-----ok")
}
深入理解
package main
import "fmt"
func main(){//双重循环:for i := 1; i <= 5; i++ {for j := 2; j <= 4; j++ {fmt.Printf("i: %v, j: %v \n",i,j)if i == 2 && j == 2 {break}}}
}
标签的使用展示
package mainimport "fmt"func main() {//双重循环:
label2:for i := 1; i <= 5; i++ {for j := 2; j <= 4; j++ {fmt.Printf("i: %v, j: %v \n", i, j)if i == 2 && j == 2 {break label2 //结束指定标签对应的循环}}}fmt.Println("-----ok")
}
continue
- continue的作用是结束离它近的那个循环,继续离它近的那个循环
package main
import "fmt"
func main(){//功能:输出1-100中被6整除的数://方式1:// for i := 1; i <= 100; i++ {// if i % 6 == 0 {// fmt.Println(i)// }// }//方式2:for i := 1; i <= 100; i++ {if i % 6 != 0 {continue //结束本次循环,继续下一次循环}fmt.Println(i)}
}
深入理解
package main
import "fmt"
func main(){//双重循环:for i := 1; i <= 5; i++ {for j := 2; j <= 4; j++ { if i == 2 && j == 2 {continue}fmt.Printf("i: %v, j: %v \n",i,j)}}fmt.Println("-----ok")
}
标签的使用展示
package mainimport "fmt"func main() {//双重循环:
label:for i := 1; i <= 5; i++ {for j := 2; j <= 4; j++ {if i == 2 && j == 2 {continue label}fmt.Printf("i: %v, j: %v \n", i, j)}}fmt.Println("-----ok")
}
goto
- Golang的 goto 语句可以无条件地转移到程序中指定的行。
- goto语句通常与条件语句配合使用。可用来实现条件转移.
- 在Go程序设计中一般不建议使用goto语句,以免造成程序流程的混乱。
package mainimport "fmt"func main() {fmt.Println("hello golang1")fmt.Println("hello golang2")if 1 == 1 {goto label1 //goto一般配合条件结构一起使用}fmt.Println("hello golang3")fmt.Println("hello golang4")fmt.Println("
相关文章:

go的学习笔记
中文标准库文档:https://studygolang.com/pkgdoc 第一段代码 所有代码的主文件都是main.go,下面的代码直接在项目里面创建main.go运行 package main // 声明文件所在的包,每个go文件必须有归属的包import "fmt" // 引入程序需要的包,为了使用包下的函数,比如Print…...

卷积和转置卷积的输出尺寸计算
卷积和转置卷积的输出尺寸计算 卷积 h是输出的高,h是输入的高,k_h是卷积核的高 w类似stride1 h h - k_h padding*2 1通用公式 stride1就是上面的公式 h (h - k_w 2*padding stride)//stride 一些常见的卷积 高宽不变的卷积:kernel…...

vue3+ts 使用amCharts展示地图,1.点击左侧国家,可以高亮并放大右侧地图对应的国家。 2.展示数据球。
效果图展示: 1.点击左侧国家,可以高亮并放大右侧地图对应的国家。 2.展示数据球。 下载依赖 yarn add amcharts/amcharts5其中,props.countryData的数据格式为 [{ “country”: “加拿大”, “code”: “CA”, “deviceCount”: 1 },{ “c…...

汽车无钥匙启动功能工作原理
移动管家无钥匙启动是一种科技化的汽车启动方式,它允许车主在不使用传统钥匙的情况下启动车辆。这种技术通过智能感应系统实现,车主只需携带智能钥匙,当靠近车辆时,车辆能够自动解锁并准备启动。启动车辆时,车主无…...

C++标准的一些特性记录:C++11的auto和decltype
文章目录 auto容器遍历配合lambda表达式decltype两者对引用类型的处理是相同的decltype保留const,而auto不会保留const在C++11中,引入了两个新的关键字,auto和decltype两个关键字,都是用于做类型推断。但是使用的场景有些区别。 auto 容器遍历 auto这个关键字,我个人在编…...

【Elasticsearch系列四】ELK Stack
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

【新手上路】衡石分析平台使用手册-认证方式
认证方式 用户登录衡石系统时,系统需要对输入的用户名和密码进行验证,保证系统的安全。衡石提供 CAS、SAML2、OAUTH2等多种单点登录认证方式。在 SSO 单点登录中,衡石是服务提供者 SP(Service Provider)为用户提供所…...

数字电路与逻辑设计-触发器功能测试及其应用
一、实验目的 1.验证基本RS、JK、D、T和T’触发器的逻辑功能及使用方法; 2.能进行触发器之间的相互转换; 3.学习触发器的一些应用。 二、实验原理 触发器具有两个能够自行保持的稳定状态,用以表示逻辑状…...

【网站架构部署与优化】web服务与http协议
文章目录 HTMLHTML 概述HTML 语法规则HTML 文件结构头标签中常用标签静态网页与动态网页1. 静态网页2. 动态网页3. 动态网页语言 HTTP协议概述主要的HTTP版本包括:HTTP方法GET与POST方法的比较 HTTP状态码分类及常见状态码HTTP常见状态码 HTTP 请求流程分析1. 请求报…...

【字符函数】strcpy函数(字符串复制函数)+strcat函数(字符串追加)+strcmp函数(字符串比较)【笔记】
1.复制函数--------------strcpy函数 函数使用 char*strcpy(char* destination, const char* source) strcpy函数用于拷贝字符串,即将一个字符串中的内容拷贝到另一个字符串中(会覆盖原字符串内容)。它的参数是两个指…...

codetop字符串刷题,刷穿地心!!不再畏惧!!暴打面试官!!
主要供自己回顾与复习,题源codetop标签字符串近半年,会不断更新 1.有效的括号字符串2.括号生成3.最长单词4.字符串转换整数(atoi)5.整数转罗马数字6.罗马数字转整数7.比较版本号8.最长公共前缀9.面试题17.15.最长单词10.验证IP地址11.面试题01.06.字符串…...

快速体验Linux发行版:DistroSea详解与操作指南
DistroSea 是一个功能强大的在线平台,允许用户在无需下载或安装的情况下,通过浏览器直接测试多种Linux和BSD发行版。该平台非常适合Linux爱好者、系统管理员和开发者,提供一个简便的方式来体验各种操作系统而无需影响本地设备。 为什么选择D…...

Java设计模式—面向对象设计原则(二) --------> 里氏代换原则 LSP (完整详解,附有代码+案列)
文章目录 里氏代换原则3.2.1 概述3.2.2 改进上述代码 里氏代换原则 里氏代换原则:Liskov Substitution Principle,LSP 3.2.1 概述 里氏代换原则是面向对象设计的基本原则之一。 里氏代换原则:任何基类可以出现的地方,子类一定…...

使用ShardingSphere实现MySql的分库分表
目录 一 什么是ShardingSphere分库分表 二 代码实现 1.导入相关依赖 2.配置相关参数 3.创建学生类以及mapper接口 4.实现 StandardShardingAlgorithm接口自定义分片算法 唐洋洋我知道你在看!!!嘿嘿 一 什么是ShardingSphere分库分表 我们平时在设计数据库的时候…...

为什么 Feign 要用 HTTP 而不是 RPC?
一、引言 在现代微服务架构中,服务之间的通信是至关重要的环节。Feign 是一种常用的声明式 HTTP 客户端工具,它简化了服务间的调用过程。然而,在服务通信的领域中,除了基于 HTTP 的方式,还有 RPC(Remote Pr…...

OJ在线评测系统 前端开发设计优化通用菜单组件二 调试用户自动登录
通用的菜单组件开发二 接下来要完善 权限功能 就是只有登录后才能进入题目查看界面 用户只能看到我们有权限的菜单 我们要在路由文件里面去操作 原理是控制路由设置隐藏 只要用户没有权限 就过滤掉隐藏 全局权限管理 实现想清楚有那些权限 /*** 权限定义*/ const ACCES…...

mongodb 安装教程
mongodb 安装教程: https://blog.51cto.com/u_13646338/5449015 wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-5.0.9.tgz tar -zxvf mongodb-linux-x86_64-rhel70-5.0.9.tgz -C /opt/module/ [roothadoop102 module]# mv mongodb-linux-…...

切换淘宝最新镜像源npm
要切换淘宝的npm镜像源,可以按照以下步骤进行: 1. 打开命令行工具(如Terminal、CMD等)。 2. 输入以下命令来查看当前的npm镜像源: npm config get registry 3. 如果当前的镜像源不是淘宝镜像源ÿ…...

SpringAI-基于java大模型的胡言乱语
最近看了一点相关的springAI知识,做个小总结 胡言乱语开始 1.不同的ai调用api一般单独汇总成一个依赖,比如说调用openai的api的依赖是spring-ai-openai-spring-boot-starter。 2.最常用的展示方式是流式对话,AI的数据是一个字一个字生成的…...

python提问及解析
在看答案之前,可以先试试自己做哦! 1.图书馆借书还书系统 问题描述 问题:设计一个Python程序,该程序模拟一个大型图书馆的图书管理系统。图书馆拥有成千上万的书籍,每本书都有一个唯一的ISBN号、书名、作者、出版年份…...

从Apple Intelligence到IoT Intelligence,端侧生成式AI时代加速到来
9月10日凌晨1点,苹果新品发布会如期举行,全新iPhone16系列成为苹果生态中真正意义上的第一款原生AI手机,在第二代3nm工艺A18和A18 Pro芯片的加持下,iPhone16系列能够容纳并快速运行以Apple Intelligence为中心的生成式AI功能在手机…...

智能AC管理系统HTTPD-AC 1.0服务存在未授权访问漏洞
@[toc] 智能AC管理系统HTTPD-AC 1.0服务存在未授权访问漏洞 免责声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文章作者无关。该文章仅供学习用途…...

Sidewalk介绍
目录 1 前言2 简介2.1 注意事项 3 结束语 1 前言 Sidewalk是Amazon出的一个针对IoT物联网的协议,类似于LoRaWAN协议,针对小而美的低功耗设备。Amazon Sidewalk支持低带宽和远程连接,使用BLE进行短距离通信,使用900MHz的频率的LoR…...

Java数据结构 (泛型第二节) 泛型擦除机制/泛型的限制/上界下界
书接上回:Java数据结构 (泛型第一节) 为什么要有泛型/泛型语法/泛型方法-CSDN博客 访问作者Github: https://github.com/Joeysoda/Github_java/blob/main/20240908%E6%B3%9B%E5%9E%8B/src/%E6%B3%9B%E5%9E%8B.java 目录 1. 为什么要有擦除机制? 2. 类…...

数据安全标准在非结构化数据中台的遵守
在数字化转型的浪潮中,非结构化数据中台作为企业数据管理的核心枢纽,承载着海量且多样的数据资产。这些数据不仅关乎企业的运营决策,更涉及客户隐私、商业机密等敏感信息。因此,确保非结构化数据中台遵守数据安全标准,…...

探索Go语言中的Goroutine并发机制
什么是Goroutine 在Go语言中,Goroutine 是程序中最基本的并发单位。事实上,每个Go程序都会自动创建一个goroutine,那就是主goroutine,程序启动时会立即执行。Goroutine是Go语言中处理并发问题的核心工具,因此理解它的工作原理至关重要。 简而言之,Goroutine是并发执行的…...

实现实时Web应用,使用AJAX轮询、WebSocket、还是SSE呢??
文章目录 短轮询(Short Polling)长轮询(Long Polling)Comet “服务器推” (这玩意现在用的很少了,了解一下即可)WebSocket原理:方法:事件: SSE原理事件 总结 …...

3GPP协议入门——物理层基础(一)
1. 频段/带宽 NR指定了两个频率范围,FR1:通常称Sub 6GHz,也称低频5G;FR2:通常称毫米波(Millimeter Wave),也称高频5G。 2. 子载波间隔 NR中有15kHz,30kHz,6…...

关于Java数据结构中集合的一个小知识
在我们以后刷题的过程,我们会遇到一些奇怪的集合数据类型。 如下图 这里,我们以顺序表的集合类为例,我们看到上图函数的返回值类型有点奇怪,其实并不奇怪,也就是穿过去的参数类型是一个顺序表的集合类型,也…...

leetcode41. 缺失的第一个正数,原地哈希表
leetcode41. 缺失的第一个正数 给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。 请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。 示例 1: 输入:nums [1,2,0] 输出:3 解释…...