Golang(一):基础、数组、map、struct

目录

hello world

变量

常量,iota

函数

init函数和导包过程 

指针

defer

数组和动态数组

固定长度数组

遍历数组

动态数组

len 和 cap

截取

切片的追加

map

四种声明方式

遍历map

删除

查看键是否存在

结构体

声明

作为形参

方法

封装

 继承

多态

类型断言


配置:

一文轻松实现在VSCode中编写Go代码_vscode 开发go-CSDN博客

hello world

package main//导入包
import "fmt"//主函数,入口函数
func main() { //大括号必须和函数在同一行//打印输出fmt.Println("hello go")
}

导入多个包:

import "fmt"
import "time"

or

import("fmt""time"
)

变量

四种定义方式

func main() {var a intfmt.Print(a) //默认为0var b int = 3fmt.Print(b) //3var c = 10fmt.Print(c) //10fmt.Printf("c is %T", c) //c is intd := 3.45fmt.Printf("d = %f", d) //d=3.450000
}

第四种方法只能使用于局部变量,例如下面这张方法是不可以的:

a :=200
//non-declaration statement outside function body
func main() {fmt.print(a)
}

声明多个变量

func main() {var a, b = 3, "asdad"fmt.Print(a, b)var c, d int = 3, 4fmt.Print(c, d)var (e int = 4f     = "aeasd")fmt.Print(e, f)g, h := 9, falsefmt.Println(g, h)
}

数据类型转换

一、强制类型转换 

        但是只有相同底层类型的变量之间可以进行相互转换(如将 int16 和 int32 相互转换,float 类型和 int 类型相互转换),不同底层类型的变量相互转换时会引发编译错误(如 bool 类型和 int 类型,string 与 int 类型之间的转换):

  

二、 strconv包:字符串和数值类型的相互转换 

    1. Itoa():整型转字符串  integer to alphanumeric 

    2. Atoi():字符串转整型 alphanumeric to integer 

    3. Parse 系列函数(str转其他): ParseBool()、ParseInt()、ParseUint()、ParseFloat() 

    4.Format 系列函数(其他转str): FormatBool()、FormatInt()、FormatUint()、FormatFloat() 

    5.Append 系列函数(其他转str后加到切片中): AppendBool()、AppendFloat()、AppendInt()、AppendUint() 

  

 golang的数据类型

golang 的数据类型_golang数据类型-CSDN博客

常量,iota

常量不允许重复赋值

func main() {const PI float32 = 3.14fmt.Printf("PI: %v\n", PI)const a = 90fmt.Printf("a: %v\n", a)a = 99 //cannot assign to a (neither addressable nor a map index expression)
}

常量可以枚举

const (Unknown = 0Female = 1Male = 2
)

可以使用iota实现自增赋值,例如下面这种一个一个赋值很繁琐

const (CategoryBooks    = 0CategoryHealth   = 1CategoryClothing = 2
)

于是:

const (CategoryBooks = iota // 0CategoryHealth       // 1CategoryClothing     // 2
)

在每个枚举中,iota从0开始,每行递增

也可以在第一行使用公式,下面所有行都会使用同样的公式

const (CategoryBooks = 10 * iota //0CategoryHealth   //10CategoryClothing //20
)

公式在中途也可以变化,iota的值不会中断

const (CategoryBooks    = 10 * iota //0CategoryHealth               //10CategoryClothing             //20a = 100 * iota        //300b                 //400c     //500
)

注意,iota只能在const中使用

函数

// 普通函数
func foo1(x int, y int) int {return x + y
}func foo2() {fmt.Printf("\"hello\": %v\n", "hello")
}// 多返回值函数
func foo3(x, y int) (int, string) {return 9, "asdad"
}// 给返回值命名
func foo4() (r1 int, r2 string) {fmt.Printf("r1: %v\n", r1) //0fmt.Printf("r2: %v\n", r2) //""//说明已经命名的返回值就是一个局部变量,具有默认值r1 = 9r2 = "qwqw"return
}func main() {a := foo1(1, 2)fmt.Printf("a: %v\n", a)foo2()c, d := foo3(1, 2)fmt.Printf("c: %v\n", c)fmt.Printf("d: %v\n", d)e, f := foo4()fmt.Printf("e: %v\n", e)fmt.Printf("f: %v\n", f)
}

init函数和导包过程 

 lib1:

package lib1
import ("fmt""lib2"
)
func init() {fmt.Println("lib1 init")lib2.Lib2_test()
}
func Lib1_test() {fmt.Println("lib1_test")
}

lib2:

package lib2
import "fmt"
func init() {fmt.Println("lib2 init")
}
func Lib2_test() {fmt.Println("lib2_test")
}

main:

package main
import ("fmt""lib1"
)
func main() {fmt.Print("main")lib1.Lib1_test()
// 	lib2 init
// lib1 init
// lib2_test
// mainlib1_test
}

值得注意的是,包中的函数必须是大写字母开头的,这样这个函数才能在包外被调用,可以看成是java中public的一种形式

 在golang中,如果导入了包,却不调用包的方法,会报错

但是如果我只想执行包的init函数却不使用包中的方法,可以使用匿名包,这样不能调用包的方法,但是会执行init

import ("fmt"_ "lib1"
)
func main() {fmt.Print("main")
}

可以给包起别名

import ("fmt"mylib1 "lib1"
)
func main() {fmt.Print("main")mylib1.Lib1_test()}

指针

跟c语言一样  

package main//导入包
import "fmt"func changevalue(p *int) { //申明 p 为指针型变量,指向一个int型的变量,p本身存储的是这个int变量的地址*p = *p * 10  //*p 表示指向的这个变量本身
}func main() {a := 10changevalue(&a)   //&a表示a的地址fmt.Printf("a: %v\n", a) //100
}
package main//导入包
import "fmt"func changevalue(a *int, b *int) {temp := *a*a = *b*b = temp
}func main() { //大括号必须和函数在同一行a := 10b := 20changevalue(&a, &b)fmt.Printf("a: %v\n", a) //20fmt.Printf("b: %v\n", b) //10
}

二级指针,指向指针的指针

package main//导入包
import ("fmt"
)// 普通函数func main() {a := 10var p *int = &avar p1 **int = &pfmt.Println(&p) //0xc000070030fmt.Println(p1) //0xc000070030}

defer

在当前函数体的最后运行

func main() {defer fmt.Println("main end")fmt.Printf("\"alalal\": %v\n", "alalal")
// 	"alalal": alalal
//   main end
}

如果存在多个defer,则遵循 栈 的原则

func main() {defer fmt.Println("main end1")defer fmt.Println("main end2")fmt.Printf("\"alalal\": %v\n", "alalal")// "alalal": alalal// main end2// main end1
}

在函数调用中,defer在return之后,这个很好理解,因为defer应该在函数体最后执行,最先入栈,在return之后

func returnfunc() int {fmt.Println("return end")return 0
}func testfunc() int {defer fmt.Println("func end")return returnfunc()
}
func main() {testfunc()// 	return end// func end
}

数组和动态数组

固定长度数组

func main() {var myarray [10]intmyarray2 := [10]int{1, 2, 3, 4}
}

固定长度数组需要指定数组长度,且有默认值

当固定长度数组作为形参时,进行的是值传递,而不是引用传递

func change_array(myarry [4]int) {myarry[0] = 100
}
func main() {myarray2 := [4]int{1, 2, 3, 4}change_array(myarray2)//myarray2的值不改变
}

而且当函数形参是固定长度数组时,传入其他长度的数组也不可以,非常的不方便

遍历数组

func main() {var myarray [10]intmyarray2 := [10]int{1, 2, 3, 4}for i := 0; i < len(myarray); i++ {fmt.Printf("myarray[i]: %v\n", myarray[i])}for index, value := range myarray2 {fmt.Printf("index:%d,value:%d\n", index, value)}
}

 也可以只遍历下标:

	myarray2 := [10]int{1, 2, 3, 4}for index := range myarray2 {fmt.Printf("index:%d\n", index)}

动态数组

也叫  切片

func change_array(myarry []int) {myarry[0] = 100
}
func main() {myarray2 := []int{1, 2, 3, 4}fmt.Printf("%T \n", myarray2) //[]intchange_array(myarray2)for index, value := range myarray2 {fmt.Printf("index:%d,value:%d\n", index, value)} //myarray2的值改变
}

多种声明方式

func main() {slice1 := []int{}slice1 = make([]int, 3) //开辟三个空间fmt.Printf("len(slice): %d, slice1: %v\n", len(slice1), slice1)// len(slice): 3, slice1: [0 0 0]slice2 := make([]int, 4)fmt.Printf("len(slice): %d, slice2: %v\n", len(slice2), slice2)// len(slice): 4, slice2: [0 0 0 0]}

追加元素:

func main() {slice1 := []int{}fmt.Printf("len(slice): %d, cap: %d, slice1: %v\n", len(slice1), cap(slice1), slice1)// len(slice): 0, cap: 0, slice1: []slice1 = append(slice1, 2)fmt.Printf("len(slice): %d, cap: %d, slice1: %v\n", len(slice1), cap(slice1), slice1)// len(slice): 1, cap: 1, slice1: [2]
}

len 和 cap

这里需要说一下 len 和cap

func main() {slice1 := make([]int, 3)fmt.Printf("len(slice): %d, cap: %d, slice1: %v\n", len(slice1), cap(slice1), slice1)// len(slice): 3, cap: 3, slice1: [0 0 0]slice1 = append(slice1, 2)fmt.Printf("len(slice): %d, cap: %d, slice1: %v\n", len(slice1), cap(slice1), slice1)// len(slice): 4, cap: 6, slice1: [0 0 0 2]
}

当我们为其开辟是空间3时,其默认的cap也是3,cap是系统为数组一次性开辟空间的大小

当我再次加入元素时,长度变为了4,但是cap变成了6,也就是说在加入时自动增加了三个大小的空间

当然我们也可以指定cap

func main() {slice1 := make([]int, 3, 5)fmt.Printf("len(slice): %d, cap: %d, slice1: %v\n", len(slice1), cap(slice1), slice1)// len(slice): 3, cap: 3, slice1: [0 0 0]slice1 = append(slice1, 2)fmt.Printf("len(slice): %d, cap: %d, slice1: %v\n", len(slice1), cap(slice1), slice1)// len(slice): 4, cap: 6, slice1: [0 0 0 2]slice1 = append(slice1, 2)fmt.Printf("len(slice): %d, cap: %d, slice1: %v\n", len(slice1), cap(slice1), slice1)// len(slice): 5, cap: 5, slice1: [0 0 0 2 2]slice1 = append(slice1, 2)fmt.Printf("len(slice): %d, cap: %d, slice1: %v\n", len(slice1), cap(slice1), slice1)// len(slice): 5, cap: 5, slice1: [0 0 0 2 2]}

当然只有在增加元素超过了len时,才会使用cap增加空间

截取

截取方法和python一样,值得注意的是,这里的截取都是浅拷贝

func main() {s := []int{1, 2, 3}s1 := s[0:2]s1[0] = 100fmt.Printf("s1: %v\n", s1)fmt.Printf("s: %v\n", s)// 	s1: [100 2]// s: [100 2 3]}

如果想实现深拷贝:

func main() {s := []int{1, 2, 3}s1 := make([]int, 2)copy(s1, s)s1[0] = 100fmt.Printf("s1: %v\n", s1)fmt.Printf("s: %v\n", s)// s1: [100 2]// s: [1 2 3]}

切片的追加

slice := make([]int, 2, 4)
append_slice := []int{1, 2}
fmt.Printf("slice addr:%p len:%d cap:%d slice:%v\n", slice, len(slice), cap(slice), slice)slice = append(slice, append_slice...)
fmt.Printf("slice addr:%p len:%d cap:%d slice:%v\n", slice, len(slice), cap(slice), slice)slice = append(slice, 10, 20)
fmt.Printf("slice addr:%p len:%d cap:%d slice:%v\n", slice, len(slice), cap(slice), slice)slice = append(slice, 30, 40, 50)
fmt.Printf("slice addr:%p len:%d cap:%d slice:%v\n", slice, len(slice), cap(slice), slice)//output
slice addr:0xc0420540a0 len:2 cap:4 slice:[0 0]
slice addr:0xc0420540a0 len:4 cap:4 slice:[0 0 1 2]
slice addr:0xc04207a080 len:6 cap:8 slice:[0 0 1 2 10 20]
slice addr:0xc04208a000 len:9 cap:16 slice:[0 0 1 2 10 20 30 40 50]

 删除等操作可以查看:

初识go语言之 数组与切片(创建,遍历,删除,插入,复制)_golang创建数组-CSDN博客

map

四种声明方式

声明方式1:

	var mymap map[int]stringif mymap == nil {fmt.Print("mymap is empty\n")}// mymap is empty

这种情况下给map增加键值对是非法的,因为此时mymap的容量为0

但是如果是下面这种是可以的,因为默认分配了空间:

	var mymap1 = map[int]string{}mymap1[0] = "awew"

声明方式2:

可以使用make申请空间,且这个空间是动态可以扩展的

	mymap2 := make(map[int]string, 1)mymap2[1] = "aa"mymap2[2] = "aa"fmt.Printf("mymap2: %v\n", mymap2)

声明方式3:

不主动申请空间,但是其默认是有空间的

	mymap3 := make(map[int]string)mymap3[2] = "sad"fmt.Printf("mymap3: %v\n", mymap3)

声明方式4:

	mymap4 := map[int]string{1: "aa",2: "bb",3: "cc",}mymap4[4] = "ee"fmt.Printf("mymap4: %v\n", mymap4)

遍历map

	mymap4 := map[int]string{1: "aa",2: "bb",3: "cc",}mymap4[4] = "ee"for key, value := range mymap4 {fmt.Printf("key: %v\n", key)fmt.Printf("value: %v\n", value)}// 	key: 1// value: aa// key: 2// value: bb// key: 3// value: cc// key: 4// value: ee

删除

mymap4 := map[int]string{1: "aa",2: "bb",3: "cc",}mymap4[4] = "ee"fmt.Printf("mymap4: %v\n", mymap4)delete(mymap4, 4)fmt.Printf("mymap4: %v\n", mymap4)// mymap4: map[1:aa 2:bb 3:cc 4:ee]// mymap4: map[1:aa 2:bb 3:cc]

查看键是否存在

func main() {m := make(map[string]int)m["张三"] = 10m["李四"] = 20value, ok := m["张四"]if ok {fmt.Println(value)} else {fmt.Println("查无此人")}
}

当map作为形参时,也是引用传递 

golang的map-CSDN博客

Golang底层原理剖析之map_golang map底层-CSDN博客

结构体

这里的结构体可以看出是  类 

声明

type Book struct {name  stringprice int
}func main() {var mathbook Bookmathbook.name = "lalal"mathbook.price = 12fmt.Printf("mathbook: %v\n", mathbook)// mathbook: {lalal 12}}

作为形参

type Book struct {name  stringprice int
}func changebook(book Book) {book.price = 100
}func changebook2(book *Book) {book.price = 100
}func main() {var mathbook Bookmathbook.name = "lalal"mathbook.price = 12changebook(mathbook)fmt.Printf("mathbook: %v\n", mathbook)// mathbook: {lalal 12}changebook2(&mathbook)fmt.Printf("mathbook: %v\n", mathbook)// mathbook: {lalal 100}}

这说明作为形参传递是 值传递,而不是引用传递

方法

结构体方法的定义:

type Book struct {name  stringprice int
}func (this Book) show() {fmt.Printf("this.name: %v\n", this.name)fmt.Printf("this.price: %v\n", this.price)
}func (this Book) changeprice(new_price int) {this.price = new_price
}func (this *Book) changeprice1(new_price int) {this.price = new_price
}func main() {var mathbook Bookmathbook.name = "lalal"mathbook.price = 12mathbook.show()// mathbook: {lalal 12}mathbook.changeprice(112)mathbook.show()mathbook.changeprice1(112)mathbook.show()// 	this.name: lalal// this.price: 12// this.name: lalal// this.price: 12// this.name: lalal// this.price: 112}

当调用mathbook.changeprice()时相当于changeprice(mathbook),实参和行参都是类型 Book,可以接受。此时在changeprice()中的t只是参数t的值拷贝,所以method1()的修改影响不到main中的t变量。

当调用mathbook.changeprice1()=>changeprice1(mathbook),这是将 Book 类型传给了 *Book 类型,go可能会取 mathbook 的地址传进去:changeprice1(&mathbook)。所以 changeprice1() 的修改可以影响 mathbook

由于结构体作为形参是指传递,所以在改变参数时务必使用 地址传参

封装

在go中的struct中,类名、属性名、方法名大写表示对外可以访问,也就是java中的public

 继承

type Person struct {name stringsex  string
}func (this *Person) Eat() {fmt.Print("person eat")
}type Super_man struct {Person  //继承Person类level int
}func (this *Super_man) Eat() { //重写父类方法fmt.Print("super_man eat")
}func (this *Super_man) Fly() { //定义新的方法fmt.Print("super_man fly")
}func main() {
//两种声明对象的方式super_man1 := Super_man{Person{"lee", "male"}, 2}var super_man2 Super_mansuper_man2.name = "lee"super_man2.sex = "male"super_man2.level = 2super_man1.Fly()super_man2.Fly()
}

多态

type Animal interface {Sleep()GetColor() string
}type Cat struct {color string
}func (this *Cat) Sleep() {fmt.Print("CAT IS SLEEPING\n")
}
func (this *Cat) GetColor() string {return this.color
}type Dog struct {color string
}func (this *Dog) Sleep() {fmt.Print("Dog IS SLEEPING\n")
}
func (this *Dog) GetColor() string {return this.color
}func main() {var animal Animalanimal = &Cat{"blue"}fmt.Printf("animal.GetColor(): %v\n", animal.GetColor())animal.Sleep()// animal.GetColor(): blueanimal = &Dog{"black"}fmt.Printf("animal.GetColor(): %v\n", animal.GetColor())animal.Sleep()// 	animal.GetColor(): blue// CAT IS SLEEPING// animal.GetColor(): black// Dog IS SLEEPING
}

上面这部分代码定义了一个接口  Animal,其中定义了2个方法

Cat和Dog类只需要完全实现这2个方法(也可以有接口中没有定义的方法), 就可以实现和Animal接口的多态,可以用鸭子类型理解

为了更加直观的实现多态:

func animal_is_sleeping(animal Animal) {animal.Sleep()
}func main() {mycat := Cat{"blue"}animal_is_sleeping(&mycat)// CAT IS SLEEPING
}

在golang中,只能借助接口实现多态,使用父类是无法实现多态的,当然,如果B的父类是A,而A实现了接口C的方法,那么B也可以与C形成多态

interface{}

interface接口可以跟所有的类形成多态:

func myshow(arg interface{}) {fmt.Println(arg)
}func main() {myshow(12)myshow("asdas")myshow([]int{1, 2, 3})myshow(map[int]int{1: 2, 2: 3})// 	12// asdas// [1 2 3]// map[1:2 2:3]
}

类型断言

可以判断接口现在对应的类是哪个:

	var myanimal Animalmyanimal = &Cat{"blue"}value, ok := myanimal.(*Cat)fmt.Printf("ok: %v\n", ok)fmt.Printf("value: %v\n", value)value2, ok2 := myanimal.(*Dog)fmt.Printf("ok: %v\n", ok2)fmt.Printf("value: %v\n", value2)// 	ok: true// value: &{blue}// ok: false// value: <nil>

Go Struct超详细讲解 - 掘金

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

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

相关文章

[入门到放弃]设计模式-笔记

模块化设计 20240448 模块不包含数据&#xff0c;通过实例的指针&#xff0c;实现对实例的操作&#xff1b;唯一包含的数据是用于管理这些模块的侵入式链表模块只负责更具定义的数据结构&#xff0c;执行对应的逻辑&#xff0c;实现不同实例的功能&#xff1b; 参考资料 使用…

【热门话题】常见分类算法解析

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 常见分类算法解析1. 逻辑回归&#xff08;Logistic Regression&#xff09;2. 朴…

4.Godot图片素材的获取和编辑

游戏开发中经常遇到图片素材的需求 1. 图片素材的准备 术语&#xff1a;Sprite 精灵&#xff0c;游戏开发中指一张图片来源不明的图片&#xff0c;切勿在商业用途使用&#xff0c;以免引起版权风险。 1. 在学习阶段&#xff0c;可以百度或者从一些资源网站获取&#xff0c;这…

ViT-DeiT:用于乳腺癌组织病理图像分类的集成模型

两种预训练Vision Transformer模型的集成模型&#xff0c;即Vision Transformer和数据高效视觉Transformer&#xff08;Data-Efficient Image Transformer&#xff09;。此集成模型是一种软投票模型。 近年来&#xff0c;乳腺癌的分类研究主要集中在超声图像分类、活检数据分类…

QT常用控件

常用控件 控件概述QWidget 核⼼属性核⼼属性概览enabledgeometrywindowTitlewindowIconwindowOpacitycursorfonttoolTipfocusPolicystyleSheet 按钮类控件Push ButtonRadio ButtionCheck Box 显⽰类控件LabelLCD NumberProgressBarCalendar Widget 输⼊类控件Line EditText Edi…

AI领域的最新动态:大型语言模型的崛起、AI芯片竞争与创新应用

AI领域的最新动态&#xff1a;大型语言模型的崛起、AI芯片竞争与创新应 在最近的AI新闻中&#xff0c;有几个重要的发展值得关注&#xff1a; 1. **大型语言模型的发布和更新**&#xff1a; - Google在其Google Cloud Next活动上宣布&#xff0c;Gemini 1.5现已在180多个国家/…

(学习日记)2024.04.15:UCOSIII第四十三节:任务消息队列

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

# 达梦sql查询 Sql 优化

达梦sql查询 Sql 优化 文章目录 达梦sql查询 Sql 优化注意点测试数据单表查询 Sort 语句优化优化过程 多表关联SORT 优化函数索引的使用 注意点 关于优化过程中工具的选用&#xff0c;推荐使用自带的DM Manage&#xff0c;其它工具在查看执行计划等时候不明确在执行计划中命中…

MySQL 主从复制部署(8.0)

什么是主从数据库 主从数据库是一种数据库架构模式&#xff0c;通常用于提高数据库的性能、可用性和可伸缩性。 它包括两种类型的数据库服务器&#xff1a; 1&#xff09;主数据库&#xff08;Master&#xff09;&#xff1a;主数据库是读写数据的主要数据库服务器。所有写操…

前端小技巧之轮播图

文章目录 功能htmlcssjavaScript图片 设置了一点小难度&#xff0c;不理解的话&#xff0c;是不能套用的哦&#xff01;&#xff01;&#xff01; &#xff08;下方的圆圈与图片数量不统一&#xff0c;而且宽度是固定的&#xff09; 下次写一些直接套用的&#xff0c;不整这些麻…

SpringBoot配置优先级

配置优先级排序&#xff08;从高到低&#xff09; 1&#xff09;命令行参数 2&#xff09;java系统属性 3&#xff09;application.properties 4&#xff09;application.yaml 5&#xff09;application.ymlSpringBoot的系统属性配置和命令行参数配置 1、cmd端进行配置 1&am…

边缘计算网关究竟是什么呢?它又有什么作用呢?-天拓四方

在数字化时代&#xff0c;信息的传输与处理变得愈发重要&#xff0c;而其中的关键节点之一便是边缘计算网关。这一先进的网络设备&#xff0c;不仅扩展了云端功能至本地边缘设备&#xff0c;还使得边缘设备能够自主、快速地响应本地事件&#xff0c;提供了低延时、低成本、隐私…

基本的数据类型在16位、32位和64位机上所占的字节大小

1、目前常用的机器都是32位和64位的&#xff0c;但是有时候会考虑16位机。总结一下在三种位数下常用的数据类型所占的字节大小。 数据类型16位(byte)32位(byte)64位(byte)取值范围char111-128 ~ 127unsigned char1110 ~ 255short int / short222-32768~32767unsigned short222…

Go程序设计语言 学习笔记 第十一章 测试

1949年&#xff0c;EDSAC&#xff08;第一台存储程序计算机&#xff09;的开发者莫里斯威尔克斯在他的实验室楼梯上攀登时突然领悟到一件令人震惊的事情。在《一位计算机先驱的回忆录》中&#xff0c;他回忆道&#xff1a;“我突然完全意识到&#xff0c;我余生中的很大一部分时…

SpringCloudalibaba之Nacos的配置管理

Nacos的配置管理 放个妹子能增加访问量&#xff1f; 动态配置服务 动态配置服务可以让您以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置。 动态配置消除了配置变更时重新部署应用和服务的需要&#xff0c;让配置管理变得更加高效和敏捷。 配置中心化管…

计算机网络----第十二天

交换机端口安全技术和链路聚合技术 1、端口隔离技术&#xff1a; 用于在同vlan内部隔离用户&#xff1b; 同一隔离组端口不能通讯&#xff0c;不同隔离组端口可以通讯; 2、链路聚合技术&#xff1a; 含义&#xff1a;把连接到同一台交换机的多个物理端口捆绑为一个逻辑端口…

武林风云之一个shell同时维护多个设备

仅以此文纪念linux中国 小y最近真的颓废了&#xff0c;马上就三十了&#xff0c;一下班整个人跟个废物一样&#xff0c;躺在住处刷B站&#xff0c;太颓废了。哎&#xff0c;我想这今年就收手博客了&#xff0c;后续不再更新。但是人不能这样&#xff0c;人需要和懒惰做斗争&…

Python学习笔记25 - 一些案例

1. 输出金陵前五钗 2. 向文件输出信息 3. 打印彩色字 4. print函数、进制转换 5. 猜数游戏 6. 输出ASCII码对应的字符 7. 计算100~999之间的水仙花数 8. 千年虫数组的索引及其值 9. 星座zip dict 10. 12306车次信息 11. 字符串的格式化 12. 手动抛出异常 13. 计算圆的面积和周长…

杰发科技AC7840——CAN通信简介(4)_过滤器设置

0. 简介 注意&#xff1a;过滤器最高三位用不到&#xff0c;因此最高位随意设置不影响过滤器。 1. 代码分析 注意设置过滤器数量 解释的有点看不懂 详细解释...也看不大懂 Mask的第0位是0&#xff0c;其他位都是1(就是F?)&#xff0c;那就指定了接收值就是这个数&#xff0c;…

版本控制工具Git的使用

1、Git的基本概念和使用 1、Git是什么? ● Git: 是一个开源的分布式版本控制系统&#xff0c;可以有效、高速的处理从很小到非常大的项目版本管理。 ● GitHub: 全球最大的面向开源及私有软件项目的托管平台,免费注册并且可以免费托管开源代码。 ● GitLab:与GitHub类似&a…