defer panic recover
json序列化
monster := Monster{"a",2,"d"}
jsonStr,err := json.Marshal(monster)
if err != nil{
fmt.Println("json ", err)
}
fmt.Println(string(jsonStr))
data,err := json.Marshal(&monster)
fmt.Println(string(data))
json反序列化
var monster Monster
err := json.Unmarshal([]byte(str),&monster)
%c = 字符 该值对应的unicode码值
%d = 整数 表示为十进制
%v = 值的默认格式表示
%f = 有小数部分但无指数部分,如123.456
%t = 单词true或false
基本数据转string
第一
fmt.Sprintf("%参数",表达式)
第二
var num3 int = 99
str = strconv.FormatInt(int64(num3),10)
fmt.Printf("str type %T str=%q\n",str,str)
var num4 float64 = 23.857
str = strconv.FormatFloat(num4,'f',10,64)
var b2 boot = true
str=strconv.FormatBool(b2)
var num5 int64 = 4567
str = strconv.Itoa(int(num5))
string转基本数据
var str string = "true"
var b bool
b,_ = strconv.ParseBool(str)
var str2 string = "1234567890"
var n1 int64
n1,_ = strconv.ParseInt(str,10,64)
fmt.Print("n1 type %T n1=%v",n1,n1)
var str3 string = "123.456"
var f1 float64
f1,_ = strconv.ParseFloat(str3,64)
时间函数
获取当前时间
now := time.Now()
fmt.Printf("now=%v now type=%T",now,now)
//2.通过now可以获取到年月日,时分秒
fmt.Printf("年=%v\n",now.Year())
fmt.Printf("月=%v\n",now.Month()) fmt.Printf("月=%v\n",int(now.Month()))
fmt.Printf("日=%v\n",now.Day())
fmt.Printf("时=%v\n",now.Hour())
fmt.Printf("分=%v\n",now.Minute())
fmt.Printf("秒=%v\n",now.Second())
格式化日期和时间
1、
fmt.Prinf("当前年月日 %d-%d-%d %d:%d:%d \n",now.Year(),now.Month(),now.Day(),now.Hour(),now.Minute(),now.Second())
dateStr := fmt.SPrintf("当前年月日 %d-%d-%d %d:%d:%d \n",now.Year(),now.Month(),now.Day(),now.Hour(),now.Minute(),now.Second())
fmt.Printf("datestr=%v",dateStr)
2、
now := time.Now()
fmt.Printf(now.Format("2006/01/02 15:04:05"))
fmt.Printf(now.Format("2006/01/02"))
fmt.Printf(now.Format("15:04:05"))
Unix和UnixNano的使用
now := time.Now()
fmt.Printf("Unix时间=%v UnixNano时间=%v \n",now.Unix(),now.UnixNano())
===================================================
===================================================
链表
//给链表插入一个结点
//编写第一种插入方法,在单链表的最后加入.[简单]
func InsertHeroNode(head *HeroNode, newHeroNode *HeroNode) {
//思路
//1. 先找到该链表的最后这个结点
//2. 创建一个辅助结点[跑龙套, 帮忙]
temp := head
for {
if temp.next == nil { //表示找到最后
break
}
temp = temp.next // 让temp不断的指向下一个结点
}
//3. 将newHeroNode加入到链表的最后
temp.next = newHeroNode
}
//给链表插入一个结点
//编写第2种插入方法,根据no 的编号从小到大插入..【实用】
func InsertHeroNode2(head *HeroNode, newHeroNode *HeroNode) {
//思路
//1. 找到适当的结点
//2. 创建一个辅助结点[跑龙套, 帮忙]
temp := head
flag := true
//让插入的结点的no,和temp的下一个结点的no比较
for {
if temp.next == nil {//说明到链表的最后
break
} else if temp.next.no >= newHeroNode.no {
//说明newHeroNode 就应该插入到temp后面
break
} else if temp.next.no == newHeroNode.no {
//说明我们额链表中已经有这个no,就不然插入.
flag = false
break
}
temp = temp.next
}
if !flag {
fmt.Println("对不起,已经存在no=", newHeroNode.no)
return
} else {
newHeroNode.next = temp.next
temp.next = newHeroNode
}
}
//删除一个结点
func DelHerNode(head *HeroNode, id int) {
temp := head
flag := false
//找到要删除结点的no,和temp的下一个结点的no比较
for {
if temp.next == nil {//说明到链表的最后
break
} else if temp.next.no == id {
//说明我们找到了.
flag = true
break
}
temp = temp.next
}
if flag {//找到, 删除
temp.next = temp.next.next
} else {
fmt.Println("sorry, 要删除的id不存在")
}
}
//显示链表的所有结点信息
func ListHeroNode(head *HeroNode) {
//1. 创建一个辅助结点[跑龙套, 帮忙]
temp := head
// 先判断该链表是不是一个空的链表
if temp.next == nil {
fmt.Println("空空如也。。。。")
return
}
//2. 遍历这个链表
for {
fmt.Printf("[%d , %s , %s]==>", temp.next.no,
temp.next.name, temp.next.nickname)
//判断是否链表后
temp = temp.next
if temp.next == nil {
break
}
}
}
func main() {
//1. 先创建一个头结点,
head := &HeroNode{}
//2. 创建一个新的HeroNode
hero1 := &HeroNode{
no : 1,
name : "宋江",
nickname : "及时雨",
}
hero2 := &HeroNode{
no : 2,
name : "卢俊义",
nickname : "玉麒麟",
}
hero3 := &HeroNode{
no : 3,
name : "林冲",
nickname : "豹子头",
}
// hero4 := &HeroNode{
// no : 3,
// name : "吴用",
// nickname : "智多星",
// }
//3. 加入
InsertHeroNode2(head, hero3)
InsertHeroNode2(head, hero1)
InsertHeroNode2(head, hero2)
// 4. 显示
ListHeroNode(head)
// 5 删除
fmt.Println()
DelHerNode(head, 1)
DelHerNode(head, 3)
ListHeroNode(head)
}
===================================================
===================================================
//对列
//使用一个结构体管理环形队列
type CircleQueue struct {
maxSize int // 4
array [5]int // 数组
head int //指向队列队首 0
tail int //指向队尾 0
}
//如队列 AddQueue(push) GetQueue(pop)
//入队列
func (this *CircleQueue) Push(val int) (err error) {
if this.IsFull() {
return errors.New("queue full")
}
//分析出this.tail 在队列尾部,但是包含最后的元素
this.array[this.tail] = val //把值给尾部
this.tail = (this.tail + 1) % this.maxSize
return
}
//出队列
func (this *CircleQueue) Pop() (val int, err error) {
if this.IsEmpty() {
return 0, errors.New("queue empty")
}
//取出,head 是指向队首,并且含队首元素
val = this.array[this.head]
this.head = (this.head + 1) % this.maxSize
return
}
//显示队列
func (this *CircleQueue) ListQueue() {
fmt.Println("环形队列情况如下:")
//取出当前队列有多少个元素
size := this.Size()
if size == 0 {
fmt.Println("队列为空")
}
//设计一个辅助的变量,指向head
tempHead := this.head
for i := 0; i < size; i++ {
fmt.Printf("arr[%d]=%d\t", tempHead, this.array[tempHead])
tempHead = (tempHead + 1) % this.maxSize
}
fmt.Println()
}
//判断环形队列为满
func (this *CircleQueue) IsFull() bool {
return (this.tail + 1) % this.maxSize == this.head
}
//判断环形队列是空
func (this *CircleQueue) IsEmpty() bool {
return this.tail == this.head
}
//取出环形队列有多少个元素
func (this *CircleQueue) Size() int {
//这是一个关键的算法.
return (this.tail + this.maxSize - this.head ) % this.maxSize
}
func main() {
//初始化一个环形队列
queue := &CircleQueue{
maxSize : 5,
head : 0,
tail : 0,
}
var key string
var val int
for {
fmt.Println("1. 输入add 表示添加数据到队列")
fmt.Println("2. 输入get 表示从队列获取数据")
fmt.Println("3. 输入show 表示显示队列")
fmt.Println("4. 输入exit 表示显示队列")
fmt.Scanln(&key)
switch key {
case "add":
fmt.Println("输入你要入队列数")
fmt.Scanln(&val)
err := queue.Push(val)
if err != nil {
fmt.Println(err.Error())
} else {
fmt.Println("加入队列ok")
}
case "get":
val, err := queue.Pop()
if err != nil {
fmt.Println(err.Error())
} else {
fmt.Println("从队列中取出了一个数=", val)
}
case "show":
queue.ListQueue()
case "exit":
os.Exit(0)
}
}
}
===================================================
===================================================
//栈
//使用数组来模拟一个栈的使用。
type Stack struct{
MaxTop int //表示我们栈最大可以存放数个数
Top int //表示栈顶,因为栈顶固定,因此我们直接使用Top
arr [5]int //数组模拟栈
}
//入栈
func (this *Stack) Push(val int) (err error){
//先判断栈是否满了
if this.Top == this.MaxTop -1 {
fmt.Println("stack full")
return errors.New("stack full")
}
this.Top++
//放入数据
this.arr[this.Top] = val
}
//出栈
func (this *Stack) Pop() (val int,err error){
//判断栈是否空
if this.Top == -1 {
fmt.Println("stack mepty!")
return 0,errors.New("stack empty")
}
//先取值,再 this.Top--
var = this.arr[this.Top]
this.Top--
return val,nil
}
//遍历栈,从栈顶开始遍历
func (this *Stack) List(){
//判断栈是否空
if this.Top == -1{
fmt.Println("stack empty")
return
}
//curTop := this.Top
for i := this.Top; i>=0; i-- {
fmt.Println("arr[%d]=%d\n",i,this.arr[i])
}
}
func main(){
stack := &Stack{
MaxTop : 5,
Top : -1,
}
//入栈
stack.Push(1)
stack.Push(2)
stack.Push(3)
stack.Push(4)
stack.Push(5)
//显示
stack.List()
val,_ := stack.Pop()
fmt.Println("出栈",val)
stack.List()
}
===================================================
===================================================
二叉树
type Hero struct{
No int
Name string
Left *Hero
Right *Hero
}
//前序
func PreOrder(node *Hero){
if node != nil {
fmt.Printf("no=%d name=%s\n",node.No,node.Name)
PreOrder(node.Left)
PreOrder(node.Right)
}
}
//中序
func InfixOrder(node *Hero){
if node != nil {
InfixOrder(node.Left)
fmt.Printf("no=%d name=%s\n",node.No,node.Name)
InfixOrder(node.Right)
}
}
//后序
func PostOrder(node *Hero){
if node != nil {
PostOrder(node.Left)
PostOrder(node.Right)
fmt.Printf("no=%d name=%s\n",node.No,node.Name)
}
}
func main(){
root := &Hero{
No : 1,
Name : "aa",
}
left1 := &Hero{
No : 2,
Name : "bb",
}
node10 := &Hero{
No : 10,
Name : "tom"
}
node12 := &Hero{
No : 12,
Name : "tomA
}
left1.Left = node10
left1.Right = node12
right1 := &hero{
No : 3,
Name : "cc",
}
root.Left = left1
root.Right = right1
right2 := &hero{
No : 4,
Name : "dd",
}
right1.Right = right2
PreOrder(root)
}
===================================================
===================================================
//闭包
func AddUpper() func(int) int {
var n int = 10
return func(x int) int {
n = n + x
return n
}
}
func main(){
f := AddUpper()
fmt.Println(f(1)) //11
fmt.Println(f(2)) //13
fmt.Println(f(3)) //16
}
===================================================
===================================================
//错误处理
func test(){
//使用defer + recover 来捕获和处理异常
defer func(){
err := recover() // recover() 捕获异常
if err != nil{
fmt.Println("err=",err)
}
}()
num1 := 10
num2 := 20
res := num1 /num2
fmt.println("res=",res)
}
func main(){
test()
for{
fmt.Println("")
time.Sleep(time.Second)
}
}
===================================================
===================================================
//斐波那契
func fbn(n int) ([]uint64){
fbnSlice := make([]uint64,n)
fbnSlice[0]=1
fbnSlice[1]=1
for i := 2; i
}
return fbnSlice
}
func main(){
fnbSlice := fbn(10)
fmt.Println("fnbSlice",fnbSlice)
}
===================================================
===================================================
//冒泡排序
func BubbleSort(arr *[5]int) {
fmt.Println("排序前arr=",(*arr))
temp := 0
for i := 0; i< len(*arr)-1; i++ {
for j :=0; j
temp = (*arr)[j]
(*arr)[j] = (*arr)[j + 1]
(*arr)[j + 1] = temp
}
}
}
fmt.Println("排序后arr=",(*arr))
}
===================================================
===================================================
//三种排序 选择排序 8万数据 用时:12秒
// 插入排序 8万数据 用时:4秒
// 快速排序 8万数据 用时:0秒
//选择排序
func selectSort(arr *[5]int){
for j:=0;j
maxIndex := j
for i :=j+1;i
max = arr[i]
maxIndex = i
}
}
//交换
if maxIndex != j{
arr[j],arr[maxIndex] = arr[maxIndex],arr[j]
}
fmt.Printf("第%d次 %v\n ",j+1,*arr)
}
}
func main(){
arr := [5]int{10,34,19,100,80}
fmt.Println(arr)
selectSort(&arr)
fmt.Println("main")
fmt.Println(arr)
}
===================================================
===================================================
//插入排序
func InsertSort(arr *[5]int){
for i := 1; i < len(arr);i++{
insertVal :=arr[i]
insertIndex := i - 1 //下标
//从大到小
for insertIndex >= 0 && arr[insertIndex] < insertVal {
arr[insertIndex + 1] = arr[insertIndex] //数据后移
insertIndex --
}
//插入
if insertIndex + 1 != i {
arr[insertIndex + 1] =insertVal
}
fmt.Println("第%d次插入后",*arr)
}
}
func main(){
arr := [5]int{23,0,12,56,34}
fmt.Println("原始数组=",arr)
InsertSort($arr)
fmt.Println("main")
fmt.Println(arr)
}
===================================================
===================================================
//快速排序
//left 表示 数组左边的下标
//right 表示 数组右边的下标
//array 表示要排序的数组
func QuickSort(left int,right int,array *[6]int){
l := left
r := right
//pivot 是中轴,支点开发左右分
pivot := array[(left + right) / 2]
temp := 0
//for 循环的目标是将比较 pivot 小的数放到了左边 比 pivot 大的放到右边
for ;l < r;{
for ; array[l] < pivot; {
l++
}
for ; array[r] < pivot; {
r--
}
if l >= r {
break
}
temp = array[l]
array[l] = array[r]
array[r] = temp
if array[l] == pivot {
r--
}
if array[r] == pivot {
l++
}
}
if l == r {
l++
r--
}
if left < r {
QuickSort(left,r,array)
}
if right > l {
QuickSort(l,right,array)
}
}
func main() {
arr := [6]int{-9,78,0,23,-576,70}
QuickSort(0,len(arr)-1,&arr)
}
===================================================
===================================================
//顺序查找
names := [4]string{"a","b","c","d","e","f"}
var heroName = ""
fmt.Scanln(&heroName)
for i := 0;i
fmt.Printf("找到",heroName,i)
break
} else if i==(len(names)-1) {
fmt.Printf("没找到",heroName)
}
}
===================================================
===================================================
//二分
func BinaryFind(arr *[6]int,leftindex int,rightIndex int, findVal int){
if leftindex > rightIndex {
fmt.Println("没找到")
return
}
middle = (leftindex + rightIndex)/2
if (*arr)[middle] > findVal {
BinaryFind(arr,leftIndex,middle -1,findVal)
}else if (*arr)[middle] < findVal {
BinaryFind(arr,middle+1,rightIndex,findVal)
}else{
fmt.Printf("找到",middle)
}
}
func main(){
arr := [6]int{1,4,6,9,5,33,22,75}
BinaryFind(&arr,0,len(arr)-1,33)
}
===================================================
===================================================
//map排序
map1 := make(map[int]int,10)
map1[10] = 100
map1[1]=13
map1[4]=56
var keys []int
for k,_:= range map1 {
keys = append(keys,k)
}
sort.Ints(keys)
for _,k := range keys {
fmt.Printf("map1[%v]=%v \n",k,map1[k])
}
===================================================
===================================================
//协程
//协程特点
1、有独产的栈空间
2、共享程序堆空间
3、调度由用户控制
4、协程是轻量级的线程
num := runtime.NumCPU() //CPU数
runtime.GOMAXPROCS(num)//num-1 cpu运行go程序
1)全局变量加锁
2)chan
//加锁
var lock sync.Mutex //加互斥锁
time.Sleep(10 * time.Second)
lock.Lock()
for k,v := range m{
fmt.Printf('%d != %v\n',k,v)
}
lock.Unlock()
===================================================
===================================================
//协程与管道
//write Data
func writeData(intChan chan int){
for i := 1;i <= 50; i++ {
//放入数据
intChan<- i
}
close(intChan)//关闭
}
//read data
func readData(intChan chan int,exitChan chan bool){
for {
v,ok := <-intChan
if !ok {
break
}
fmt.Printf("readData 读到数据=%v\n",v)
}
//readData 读取完数据后,任务完成
exitChan<- true
close(exitChan)
}
func main(){
//创那建两个管道
intChan := make(chan int,50)
exitChan := make(chan bool,1)
go writeData(intChan)
go readData(intChan,exitChan)
for {
_,ok := <-exitChan
if !ok {
break
}
}
}
===================================================
===================================================
//使用select可以解决从管道取数据的阻塞问题
func main(){
//使用select可以解决从管道取数据的阻塞问题
// 1.定义一个管道 10个数据
intChan := make(chan int,10)
for i := 0; i<10;i++ {
intChan <- i
}
// 2.定义一个管道 5个数据string
stringChan := make(chan string, 5)
for i := 0; i < 5; i++ {
stringChan <- "hello" + fmt.Sprintf("%d",i)
}
label :
for {
//注意:这里,如果intChan一直没有关闭,不会一直阻塞而deadlock
//会自动到下一个case匹配
select {
case v := <-intChan :
fmt.Printf("从intChan读取的数据%d\n",v)
case v := <-stringChan :
fmt.Printf("从stringChan读取的数据%s\n",v)
default:
fmt.Printf("都取不到了取的数据\n")
//return
break label
}
}
}
===================================================
===================================================
var intArr3 [5]int
//为了每次生成的随机数不一样,我们需要给一个seed值
rand.Seed(time.Now().UnixNano())
for i := 0; i < len(intArr3); i++ {
intArr3[i] = rand.Intn(100) //0<=n<100
}
fmt.Println("交换前=",intArr3)
//反转打印,交换的次数是 len / 2,
//倒数第一个和第一个元素交换,倒数第二个和第二个元素交换
temp := 0
for i := 0; i < len(intArr3) / 2; i++ {
temp = intArr3[len(intArr3) - 1 - i]
intArr3[len(intArr3) - 1 - i] = intArr3[i]
intArr3[i] = temp
}
fmt.Println('交换后=',intArr3)
go build gocode\ch06\fundeme01\main //会生成 main.exe
go build -o bin\my.exe gocode\ch06\fundeme01\main //会生成 my.exe
在生成的全局订单ID头部添加了分库与分表的信息,这样只根据订单ID,我们也能快速的查询到对应的订单信息。