diff --git a/Pasted image 20231225085517.png b/Pasted image 20231225085517.png new file mode 100644 index 0000000..0a1ac29 Binary files /dev/null and b/Pasted image 20231225085517.png differ diff --git a/Pasted image 20231225090019.png b/Pasted image 20231225090019.png new file mode 100644 index 0000000..0a1ac29 Binary files /dev/null and b/Pasted image 20231225090019.png differ diff --git a/Pasted image 20231225170420.png b/Pasted image 20231225170420.png new file mode 100644 index 0000000..53eb8c9 Binary files /dev/null and b/Pasted image 20231225170420.png differ diff --git a/工作日志/2023-12-25.md b/工作日志/2023-12-25.md new file mode 100644 index 0000000..3743a06 --- /dev/null +++ b/工作日志/2023-12-25.md @@ -0,0 +1,2 @@ +1. 小组周会 +2. 学习 \ No newline at end of file diff --git a/日常学习/golang/命名规范.md b/日常学习/golang/命名规范.md new file mode 100644 index 0000000..66b37f4 --- /dev/null +++ b/日常学习/golang/命名规范.md @@ -0,0 +1,81 @@ +### 一、包名 +**使用小写字母:** 包名应该使用小写字母,不要使用下划线或混合大小写。 +```text +// 不推荐 +package my_package +// 推荐 +package mypackage +``` +**避免泛化的名称:** 包名应该具有明确的含义,避免使用过于泛化的名称。 +```text +// 不推荐 +package util +// 推荐 +package fileutil +``` +### 二、变量及常量 +**使用驼峰命名法:** 变量和函数名使用驼峰命名法,即首个单词小写,后续单词首字母大写。 +```text +// 不推荐 +var my_variable int +// 推荐 +var myVariable int +``` +**短小而具有描述性:** 变量名应该既简短又具有描述性,避免使用单字母名称,除非是循环变量。 +```text +// 不推荐 +var n int +// 推荐 +var itemCount int +``` +**常量全大写:** 常量名应该全大写,用下划线分隔单词。 +```text +// 不推荐 +const Pi = 3.14 +// 推荐 +const PI = 3.14 +``` +### 三、函数及方法 +**使用驼峰命名法:** 函数和方法名同样使用驼峰命名法。 +```text +// 不推荐 +func calculate_sum() int +// 推荐 +func calculateSum() int +``` +**使用动词:** 函数名应该使用动词,明确描述函数的操作。 +```text +// 不推荐 +func data() +// 推荐 +func fetchData() +``` +### 四、结构体及接口 +**使用驼峰命名法:** 结构体和接口名同样应该使用驼峰命名法。 +```text +// 不推荐 +type employee_data struct {} +// 推荐 +type EmployeeData struct {} +``` +**避免缩写:** 尽量避免使用缩写,除非是广泛接受的行业标准。 +```text +// 不推荐 +type HTMLParser interface {} +// 推荐 +type HTMLParserInterface interface {} +``` +### 五、测试文件 +**以 `_test.go` 结尾:** 测试文件应该以 **`_test.go`** 结尾,使其与普通源代码文件区分开。 +```text +// 测试文件名 +mypackage_test.go +``` + +**测试函数使用 `Test` 前缀:** 测试函数的命名应以 **`Test`** 为前缀,后面跟被测试的函数名。 +```text +// 不推荐 +func checkData() {} +// 推荐 +func TestCheckData() {} +``` \ No newline at end of file diff --git a/日常学习/golang/容器.md b/日常学习/golang/容器.md new file mode 100644 index 0000000..dc3826e --- /dev/null +++ b/日常学习/golang/容器.md @@ -0,0 +1,204 @@ +golang 在container包下提供了list(双链表)、heap(堆)、ring(环)等容器结构 +![[Pasted image 20231225085517.png]] +# 一、list +golang 中实现的list为双向链表。双向链表一般用于经常堆头部和尾部进行增删的场景,同时它不需要在一开始初始化它的容量,它的容量随着使用动态变化(扩大or缩小)。 +核心数据结构(Element、List): +```golang +// 链表的一个元素 +type Element struct { + next, prev *Element // 前后指针 + list *List // 所属链表 + Value any // 值 +} +``` + +```golang +// 链表 +type List struct { + root Element // 哨兵元素 + len int // 链表元素个数 +} +``` +![[Pasted image 20231225170420.png]] + +## 1.初始化 +```golang +package main + +import ( + "container/list" + "fmt" +) +func main() + // 使用list.New()直接初始化 + l1 := list.New() + l1.PushFront(1) + fmt.Println(l1.Front().Value) // 1 + + // 使用list.List{}延迟初始化 + l2 := list.List{} + l2.PushFront(2) + fmt.Println(l2.Front().Value) // 2 +} +``` + +## 2.常用API ++ PushFront 链表头部添加元素 ++ PushBack 尾部添加元素 ++ PushFrontList 链表头部插入链表 ++ PushBackList 尾部插入链表 ++ Front 获取头部元素 ++ Back 获取尾元素 ++ Len 获取长度 ++ InsertBefore 某个元素前插入 ++ InsertAfter 某个元素后插入 ++ MoveBefore 移动元素到某个元素前面 ++ MoveAfter 移动元素到某个元素后面 ++ MoveToFront 移动元素到头部 ++ MoveToBack 移动元素到尾部 + +# 二、heap +堆是一颗完全二叉树,按照比较规则不同,分为最大堆和最小堆。以最小堆为例,父节点总是比子节点小。 +堆的下标公式: +parent(i)=floor((i-1)/2) 向下取整 +left(i)=2i+1 +right(i)=2i+2 + +golang 提供了最小堆算法,其中包含5个接口需要开发者自行实现(**作为官方包,Golang 希望提供给大家一种简单的接入方式,官方提供好算法的内核,大家接入就 ok。采用的是定义一个接口,开发者来实现的方式**) +```golang +type Interface interface { + sort.Interface + Push(x any) // 入堆 + Pop() any // 出堆 +} + +type Interface interface { + Len() int //堆大小 + Less(i, j int) bool //比较 + Swap(i, j int) //交换 +} +``` +## 例一:最小堆 +```golang +package mycontainer + +type IntHeap []int + +// Push IntHeap全局共享切只有一个,所以需要对类型本身进行操作,所以使用指针 +func (h *IntHeap) Push(x any) { + //append需要传入切片,切片是引用传递所以需要*h, + *h = append(*h, x.(int)) +} + +// Pop +// +// @Description: 从数组移除一个元素 +// @receiver h +// @return any +func (h *IntHeap) Pop() any { + old := *h + n := len(old) + x := old[n-1] + *h = old[0 : n-1] + return x +} + +// Len +// +// @Description: 计算元素大小 +// @receiver h +// @return int +func (h IntHeap) Len() int { + return len(h) +} + +// Less +// +// @Description: 比较大小 +// @receiver h +// @param i +// @param j +// @return bool +func (h IntHeap) Less(i, j int) bool { + return h[i] < h[j] +} + +// Swap +// +// @Description: 交换i,j下标元素 +// @receiver h +// @param i +// @param j +func (h IntHeap) Swap(i, j int) { + h[i], h[j] = h[j], h[i] +} + + +// TestIntHeap +// +// @Description: 测试自定义堆 +// @param t +func TestIntHeap(t *testing.T) { + //因为pop和push方法需要传入指针 + h := &myc.IntHeap{7, 9, 10} + print(h) + //堆初始化,用于构建二叉树 + heap.Init(h) + //添加元素 + heap.Push(h, 3) + fmt.Printf("minimum: %d\n", (*h)[0]) + for h.Len() > 0 { + fmt.Printf("%d ", heap.Pop(h)) + } +} +``` + +## 例二:优先队列 +```golang +type Item struct { + value string + priority int + index int +} + +type PriorityQueue []*Item + +func (p *PriorityQueue) Push(x any) { + n := len(*p) + item := x.(*Item) + item.index = n + *p = append(*p, item) +} + +func (p *PriorityQueue) Pop() any { + old := *p + n := len(old) + item := old[n-1] + item.index = -1 + *p = old[0 : n-1] + return item +} + +func (p PriorityQueue) Len() int { + return len(p) +} + +func (p PriorityQueue) Less(i, j int) bool { + return p[i].priority > p[j].priority +} + +func (p PriorityQueue) Swap(i, j int) { + p[i], p[j] = p[j], p[i] + p[i].index = i + p[j].index = j +} + +// 更新元素优先级 +func (p *PriorityQueue) update(item *Item, value string, priority int) { + item.value = value + item.priority = priority + //二叉堆重排序 + heap.Fix(p, item.index) +} +``` +# 三、ring \ No newline at end of file diff --git a/日常学习/golang/引用(指针)传递和值传递.md b/日常学习/golang/引用(指针)传递和值传递.md new file mode 100644 index 0000000..92144cb --- /dev/null +++ b/日常学习/golang/引用(指针)传递和值传递.md @@ -0,0 +1,76 @@ +golang 中默认是值传递,和java有所区别,需要注意。 +在 C 语言中,数组变量是指向第一个元素的指针,但是 Go 语言中并不是。Go 语言中,数组变量属于值类型(value type),因此当一个数组变量被赋值或者传递时,实际上会复制整个数组。 +为了避免复制数组,一般会传递指向数组的指针。例如: +```golang +func square(arr *[3]int) { + for i, num := range *arr { + (*arr)[i] = num * num + } +} + +func TestArrayPointer(t *testing.T) { + a := [...]int{1, 2, 3} + square(&a) + fmt.Println(a) // [1 4 9] + if a[1] != 4 && a[2] != 9 { + t.Fatal("failed") + } +} +``` + +## 值接收者与指针接收者 +某个类型定义的方法,其接收者既有值类型,又有指针类型。例如自定义heap实现: +```golang +type IntHeap []int + +// Push IntHeap全局共享切只有一个,所以需要对类型本身进行操作,所以使用指针 +func (h *IntHeap) Push(x any) { + //append需要传入切片,切片是引用传递所以需要*h, + *h = append(*h, x.(int)) +} + +// Pop +// +// @Description: 从数组移除一个元素 +// @receiver h +// @return any +func (h *IntHeap) Pop() any { + old := *h + n := len(old) + x := old[n-1] + *h = old[0 : n-1] + return x +} + +// Len +// +// @Description: 计算元素大小 +// @receiver h +// @return int +func (h IntHeap) Len() int { + return len(h) +} + +// Less +// +// @Description: 比较大小 +// @receiver h +// @param i +// @param j +// @return bool +func (h IntHeap) Less(i, j int) bool { + return h[i] < h[j] +} + +// Swap +// +// @Description: 交换i,j下标元素 +// @receiver h +// @param i +// @param j +func (h IntHeap) Swap(i, j int) { + h[i], h[j] = h[j], h[i] +} +``` + +其中Push和Pop方法是指针接收,其他方法是值接收。其中Push和Pop方法需要设置对象本身(例如代码中的数组)因此必须使用指针,避免复制。Swap方法较为特殊,golang默认会交换指针。 \ No newline at end of file