ARTS 第12周

ARTS 第12周分享

[TOC]

Algorithm

单向链表的实现
[参考代码]

type HeroNode struct {
    No       int
    Name     string
    NickName string
    next     *HeroNode
}

type HeroList struct {
    head *HeroNode
}

//新建节点
func NewHeroNode(no int, name, nickName string) *HeroNode {
    return &HeroNode{No: no, Name: name, NickName: nickName}
}

// 新建链表
func NewHeroList() HeroList {
    return HeroList{NewHeroNode(0, "", "")}
}

// 添加
func (h *HeroList) add(heroNode *HeroNode) {
    tmp := h.head
    for {
        if (*tmp).next == nil {
            break
        }
        tmp = tmp.next
    }
    tmp.next = heroNode
}

// 遍历
func (h *HeroList) list() {
    if h.head.next == nil {
        fmt.Println("empty list")
        return
    }
    tmp := h.head.next
    for tmp != nil {
        fmt.Printf("number:%d,\tname: %s,\tnickName:%s\n", tmp.No, tmp.Name, tmp.NickName)
        tmp = tmp.next
    }
    fmt.Println("list finished...")
}

// 删除
func (h *HeroList) del(no int) {
    if h.head.next == nil {
        fmt.Println("empty list")
        return
    }

    tmp := h.head
    flag := false
    for tmp.next != nil {
        if tmp.next.No == no {
            flag = true
            break
        }
        tmp = tmp.next
    }
    if flag {
        tmp.next = tmp.next.next
    } else {
        fmt.Println("doesn't have this heroNode")
    }
}

// 有序添加
func (h *HeroList) orderAdd(newNode *HeroNode) {
    tmp := h.head
    for tmp.next != nil {
        if tmp.next.No > newNode.No {
            break
        } else if tmp.next.No == newNode.No {
            fmt.Println("have the same node")
            return
        }
        tmp = tmp.next
    }
    newNode.next = tmp.next
    tmp.next = newNode
}

// 更新
func (h *HeroList) update(node *HeroNode) {

    if h.head.next == nil {
        fmt.Println("empty link list")
        return
    }

    tmp := h.head.next
    flag := false
    for tmp != nil {
        if tmp.No == node.No {
            flag = true
            break
        }
        tmp = tmp.next
    }

    if flag {
        tmp.NickName = node.NickName
        tmp.Name = node.Name
    } else {
        fmt.Println("doesn't have this node")
    }
}

// 计算长度
func (h *HeroList) count() int {
    count := 0
    tmp := h.head
    for tmp.next != nil {
        count++
        tmp = tmp.next
    }
    return count
}

// 查找倒数第n个节点
func (h *HeroList) reIndex(no int) *HeroNode {
    if h.head.next == nil {
        fmt.Println("empty list")
        return NewHeroNode(0, "", "")
    }
    if no > h.count() || no <= 0 {
        fmt.Println("invalid index!")
        return NewHeroNode(0, "", "")
    }
    tmp := h.head.next
    // 倒数第x个节点等于: 正数:len(list) - x
    for i := 0; i < h.count()-no; i++ {
        tmp = tmp.next
    }
    return tmp
}

// 逆序
func (h *HeroList) reverse() {
    // 直接将相邻的元素的指向调转
    if h.head.next == nil || h.head.next.next == nil {
        return
    }
    pPre := h.head.next
    pCur := pPre.next
    tmp := pCur
    for pCur != nil {
        tmp = pCur.next
        pCur.next = pPre
        pPre = pCur
        pCur = tmp
    }
    h.head.next.next = nil
    h.head.next = pPre
}

// 逆序
func (h *HeroList) reverse2() {
    // 通过新建一个list
    // 然后遍历这个old list,将每一元素插入到新list的头节点后面
    if h.head.next == nil || h.head.next.next == nil {
        return
    }
    newList := NewHeroList()
    tmp := h.head.next
    tmpNext := tmp.next
    for tmp != nil {
        tmpNext = tmp.next
        tmp.next = newList.head.next
        newList.head.next = tmp
        tmp = tmpNext
    }
    h.head = newList.head
}

// 逆序遍历
func (h *HeroList) reList() {
    h.reverse()
    h.list()
    h.reverse()
}

// 逆序遍历
func (h *HeroList) reList2() {
    // 正序遍历,将每一个结果压入栈中
    // 然后将栈的结果输出
    if h.head.next == nil {
        fmt.Println("empty list")
        return
    }

    tmp := h.head.next
    hStack := NewHeroStack()
    count := 0
    for tmp != nil {
        hStack.Push(tmp)
        count++
        tmp = tmp.next
    }
    for i := 0; i < count; i++ {
        tmp = hStack.Pop()
        fmt.Printf("number:%d,\tname:%s,\tnickName:%s\n", tmp.No, tmp.Name, tmp.NickName)
    }
}

// 栈实现
type HeroStack struct {
    heroSlice []*HeroNode
    lock      sync.RWMutex
}

// 栈构造方法
func NewHeroStack() HeroStack {
    return HeroStack{heroSlice: []*HeroNode{}}
}

// 压入栈
func (h *HeroStack) Push(hero *HeroNode) {
    h.lock.Lock()
    h.heroSlice = append(h.heroSlice, hero)
    h.lock.Unlock()
}

// 从栈中提取元素
func (h *HeroStack) Pop() *HeroNode {
    h.lock.Lock()
    hero := h.heroSlice[len(h.heroSlice)-1]
    h.heroSlice = h.heroSlice[:len(h.heroSlice)-1]
    h.lock.Unlock()
    return hero
}

// 合并两个有序单项链表
func mergeOrderList(list1, list2 *HeroList) HeroList {
    // 遍历两个列表
    // 比较遍历到的单前元素的大小,依次加入一个新的列表
    tmp1 := list1.head.next
    tmp2 := list2.head.next
    lens := list1.count() + list2.count()
    newList := NewHeroList()
    for i := 0; i < lens; i++ {
        if tmp1 == nil {
            tmpNext := tmp2.next
            newList.orderAdd(tmp2)
            tmp2 = tmpNext
            continue
        }
        if tmp2 == nil {
            tmpNext := tmp1.next
            newList.orderAdd(tmp1)
            tmp1 = tmpNext
            continue
        }
        if tmp1.No < tmp2.No {
            tmpNext := tmp1.next
            newList.orderAdd(tmp1)
            tmp1 = tmpNext
        } else if tmp1.No == tmp2.No {
            tmpNext := tmp1.next
            newList.orderAdd(tmp1)
            tmp1 = tmpNext
        } else {
            tmpNext := tmp2.next
            newList.orderAdd(tmp2)
            tmp2 = tmpNext
        }
    }
    return newList
}

Review

  • Grab a Slice on the Go: https://blog.gojekengineering.com/grab-a-slice-on-the-go-c606344186c1

    • 数组在Go中是一个值类型,所以当你将一个数组拷贝给一个新的变量时一定是深拷贝
    • 不同长度的数组是不同的数据类型,因为长度是数组类型的一部分
    • 切片是数组的一种包装形式
    • 切片不存储任何数据,它只是底层数组的一个引用
    • 创建一个切片的实际过程是:先创建一个数组,然后返回的这个数组的引用
    • 切片的长度:当前切片拥有的元素个数
    • 切片的容量:当前切片底层数组拥有元素的个数

Tips

最近因为自己git仓库出上传了一些不必要的东西,需要在远端清理,所以仔细了解了一下对于远端的操作

  • 删除远程分支:git push origin –delete
  • 删除远程tag:git push origin –delete tag
  • 与远程仓库绑定:git remote add origin
  • 重命名远程分支:就是先删除远程分支,再重命名本地分支,再推送到远端

    • 删除远程:同上
    • 重命名本地分支:git branch origin -m
    • 推送分支到远端:git push origin
  • 本地tag推送到远程:git push –tags
  • 获取远程指定tag:git fetch origin tag

share

golang 中的内嵌(embeded) https://studygolang.com/articles/6934

  • 外部类型只包含了内部类型的类型名, 而没有field 名, 则是内嵌。

    • 内嵌的方式: 主要是通过结构体和接口的组合
  • 部类型包含了内部类型的类型名,还有filed名,则是聚合。

    • (总结:内嵌就是内部类型没有名字,聚合就是内部类型有名字)
  • Interface 不能嵌入非interface的类型。

    • 结构体(struct)中内嵌 结构体(struct)
    • 在结构体(struct)中内嵌 接口(interface)

      • 嵌入interface可以使得一个struct具有内嵌interface的接口,而不需要实现interface中的有声明的函数。
      • 只能调用已经实现的函数。
      • 声明只要实现了该interface的变量都可以赋值给该interface,从而内嵌与外层结构体,注意:必须是该变量的指针,因为interface是指针类型的变量。
第三周:1, 2, 3, 4, 6, 7
每个职场人,都该知道关于工作的这9个误解:  https://mp.weixin.qq.com/s/0D8CMw2PiWRRjdMsetJQhw
golang 中的内嵌 (embeded) : https://studygolang.com/articles/6934

空调 能效常识: https://mp.weixin.qq.com/s/T49Qb36y0NRWZAk1F8Yw4w
能效比越大,节省的电能就越多
空调能效比分为:制冷能效比和制热能效比
请停止学习框架: https://mp.weixin.qq.com/s/gQI7cO_vlAEwE3S4P39FeA
理解 struct 内嵌 inteface: https://blog.csdn.net/uudou/article/details/52556840
用故事来给你讲负载均衡的原理: https://mp.weixin.qq.com/s/icEZZw9cp3rrNfxxi9RgRQ

怎样做到不衰老?https://mp.weixin.qq.com/s/NyyTgqjZR-mdDy3-rOJPcg
 人生最辉煌的时刻一过,就开始衰老
防止衰老的最好方式就是,让自己一直处于上升期
做一件巨大的工程,要用一辈子去做的工程,人生的辉煌时刻就可以在最后
做价值持续积累的事,比如做一个操作系统,越完善,使用的人就越多,你的影响力就越多

怎么样的go程序设计风格好-owlcache分析有感: https://mp.weixin.qq.com/s/ynDTMF2QXcZGYVvwjZrWLQ

数据结构与算法——单链表: https://mp.weixin.qq.com/s/3oy5fIFciDYnM7RlLLrAMw
Golang 在 Mac、Linux、Windows 下如何交叉编译: https://blog.csdn.net/panshiqu/article/details/53788067
什么是交叉编译:一个在某个系统平台下可以产生另一个系统平台的可执行文件

详解git fetch与git pull的区别: https://blog.csdn.net/riddle1981/article/details/74938111
git pull 和 git fetch的区别?https://www.zhihu.com/question/38305012

Git查看、删除、重命名远程分支和tag:https://blog.zengrong.net/post/1746.html

Grab a Slice on the Go: https://blog.gojekengineering.com/grab-a-slice-on-the-go-c606344186c1
Golang 数据结构:栈与队列: https://wuyin.io/2018/01/30/golang-data-structure-stack-queue/