![](https://img-blog.csdnimg.cn/20201014180756926.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
go
白速龙王的回眸
一命二运三风水
四积功德五读书
六名七相八敬神
九交贵人十养生
展开
-
【Go入门】Socks5代理服务器实现 & 翻译api调用 | 青训营笔记
这是我参与「第三届青训营 -后端场」笔记创作活动的的第一篇笔记。【课程一】Go基础主要内容第一节课主要介绍了go的语法基础,包括变量、循环分支、数组切片、函数方法、错误处理、字符串、格式化处理、json模块、time模块、strconv类型转换和env环境变量等知识点项目一:猜谜游戏package mainimport ( "bufio" "fmt" "math/rand" "os" "strconv" "strings" "time")fun原创 2022-05-10 18:07:58 · 976 阅读 · 0 评论 -
FingerPrint:go转java源码解析
需求:对数据库做一个哈希压缩吧,用数字指纹看看go源码:package mainimport ( "fmt")type Label struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` Value string `protobuf:"bytes,2,opt,name=value,proto3" json原创 2022-01-25 11:20:17 · 1436 阅读 · 0 评论 -
go:mutex 和 cond
需求:mit 6.824 p17并行计算投票10个投票者,当超过五票就赢了cond 和 mutes绑定每次状态更新后都cond.broadcast一下这样主线程就可以进入cond.wait()中对应的锁中判断一下是否达到了对应的条件,如果是的话就输出代码:package mainimport ( "math/rand" "sync" "time")func main() { rand.Seed(time.Now().UnixNano()) count := 0 fin原创 2021-12-12 16:35:39 · 275 阅读 · 0 评论 -
leetcode:检测大写字母
思路:简单模拟代码:func detectCapitalUse(word string) bool { countLower := 0 countUpper := 0 for _, c := range word { if islower(c) { countLower++ } else if isupper(c) { countUpper++ } } if le.原创 2021-11-13 11:37:01 · 1984 阅读 · 0 评论 -
Go:panic + defer(recover)
通过往panic所在函数的defer中采取recover可以防止panic向上层传输package mainimport ( "fmt")func recoverName() { if r := recover(); r != nil { fmt.Println("recovered from fullName", r) }}func recoverMain() { if r := recover(); r != nil { fmt.Println("recovered f原创 2021-11-02 22:13:59 · 147 阅读 · 0 评论 -
Go:panic + defer
代码:package mainimport ( "fmt")func fullName(firstName *string, lastName *string) { defer fmt.Println("deferred call in fullName") if firstName == nil { panic("runtime error: first name cannot be nil") } if lastName == nil { panic("runtime e.原创 2021-11-02 22:01:46 · 132 阅读 · 0 评论 -
Go:通过error结构体和实现error()接口以及方法扩展,完善错误报告
先上代码:package mainimport "fmt"//这是一个特有的areaError结构体,它只需要实现Error()接口即可//里面包含err信息//实际上可以认为areaError继承了errortype areaError struct { err string //error description length float64 //length which caused the error width float64 //width which cause原创 2021-11-02 20:29:15 · 515 阅读 · 0 评论 -
Go:自定义错误两种方法
errors.New()用的是textfmt.Errorf()用的是formatpackage mainimport ( "errors" "fmt" "math")func circleArea1(radius float64) (float64, error) { if radius < 0 { return 0, errors.New("Area calculation failed, radius is less than zero") } return ma原创 2021-11-02 20:11:38 · 214 阅读 · 0 评论 -
Go:cond变量(内置mutex锁)管理通知多个协程
测试代码:package mainimport ( "fmt" "sync" "time")var locker = new(sync.Mutex)var cond = sync.NewCond(locker)func main() { for i := 0; i < 5; i++ { go func(x int) { cond.L.Lock() // wait 前,必须要先加锁 fmt.Println("I am", x, "I pass the lock.原创 2021-11-02 19:29:03 · 175 阅读 · 0 评论 -
Go:RWmutex读写一体锁
package mainimport ( "fmt" "sync" "time")var j = 0var k = 0func main() { var wg sync.WaitGroup var rm sync.RWMutex wg.Add(2) go func() { time.Sleep(20 * time.Millisecond) for i := 0; i < 1000; i++ { //写锁 rm.Lock() j++ fm.原创 2021-11-02 17:55:22 · 89 阅读 · 0 评论 -
Go:利用缓冲区大小为1的chan实现互斥(一般用于涉及线程交互的)
缓冲区为1正确的代码:package mainimport ( "fmt" "sync")var x = 0 //全局变量func increment(wg *sync.WaitGroup, ch chan bool) { ch <- true x = x + 1 //访问全局变量 <-ch wg.Done()}func main() { var w sync.WaitGroup //必须带大小为1的缓冲区(一个时间只有一个人),因为所有的协程都是以写入开始.原创 2021-11-02 17:38:42 · 209 阅读 · 0 评论 -
Go:多个协程访问同一个全局变量(利用mutex锁)
利用mutex锁,我们可以保证每个瞬间只有一个协程在访问xpackage mainimport ( "fmt" "sync")var x = 0 //全局变量func increment(wg *sync.WaitGroup, m *sync.Mutex) { m.Lock() x = x + 1 //锁定后访问全局变量 m.Unlock() wg.Done()}func main() { var w sync.WaitGroup var m sync.Mutex //声原创 2021-11-02 17:30:19 · 1674 阅读 · 0 评论 -
Go:多个协程同时修改同一全局变量(不带互斥锁)
由于同时用go拉起多个协程,可能会导致两个协程同时执行而丢失某些更新package mainimport ( "fmt" "sync")var x = 0 //全局变量func increment(wg *sync.WaitGroup) { x = x + 1 //访问全局变量 wg.Done() fmt.Println(x)}func main() { var w sync.WaitGroup for i := 0; i < 10000; i++ { w.Add原创 2021-11-02 17:26:03 · 2424 阅读 · 0 评论 -
Go:context用withValue从父节点往子节点传参
通过withValue可以将父节点的信息传递给子节点(context)package mainimport ( "context" "fmt" "time")func HandelRequest(ctx context.Context) { for { select { case <-ctx.Done(): fmt.Println("请求处理完毕") return default: fmt.Println("请求处理中……, parameter: ",原创 2021-11-02 17:19:37 · 1045 阅读 · 0 评论 -
Go:Context控制子协程之手动cancel和自动timeout
context一般来说,goroutine是平级关系,但是通过引进context可以让其有逻辑上的父子关系也就是,父要子停,子不得不停的意思揣摩一下哈手动cancelpackage mainimport ( "context" "fmt" "time")func HandelRequest(ctx context.Context) { go WriteLog(ctx) go WriteDB(ctx) for { select { case <-ctx.Done(原创 2021-11-02 17:12:07 · 1013 阅读 · 0 评论 -
Go:select多路复用选择通道机制
package mainimport ( "fmt" "time")func server1(ch chan string) { time.Sleep(1 * time.Second) //可取消 ch <- "from server1"}func server2(ch chan string) { time.Sleep(1 * time.Second) //可取消 ch <- "from server2"}func main() { output1 := m.原创 2021-11-02 16:54:05 · 191 阅读 · 0 评论 -
Go: WaitGroup多协程同步机制
package mainimport ( "fmt" "sync" "time")func process(i int, wg *sync.WaitGroup) { fmt.Println("started Goroutine ", i) time.Sleep(time.Duration(i) * time.Second) fmt.Printf("Goroutine %d ended\n", i) wg.Done() //goroutine执行结束后将信号量减1}func ma原创 2021-11-02 16:45:20 · 253 阅读 · 0 评论 -
go:一个好玩的例子,协程之间互相通信(通过chan)
在以上的例子上,我们采用二分和加一减一两种算法来区分协程的聪明程度,并计算它们找到数的时间:代码:package mainimport ( "fmt" "math/rand" "time")func main() { //建立消息通道 ch1 := make(chan int) ch2 := make(chan int) //拉起随机数协程 go generate(ch1, ch2) //拉起聪明的寻找数协程 go smart(ch1) //拉起愚蠢的寻找数协程 go.原创 2021-11-01 22:42:08 · 273 阅读 · 0 评论 -
Go: Ticker定期计时器
package mainimport ( "fmt" "time")//ticker是一个定时触发的计时器,//它会以一个间隔往channel发送信号,//而channel的接收者可以以固定的时间间隔从channel中读取信号func main() { ticker := time.NewTicker(500 * time.Millisecond) i := 0 for { //<-ticker.C fmt.Println("ticker time:", <原创 2021-11-01 21:38:35 · 229 阅读 · 0 评论 -
go:timer中的channel
先上测试代码:package mainimport ( "fmt" "time")func main() { timer1 := time.NewTimer(2 * time.Second) fmt.Println("Timer 1 begin ", time.Now()) //等待计时结束信号,信号就是当前时间戳 //<-timer1.C一直阻塞直到结束返回值 fmt.Println("<timer1.C is", <-timer1.C) fmt.Prin原创 2021-11-01 18:01:30 · 221 阅读 · 0 评论 -
go:并发例子
package mainimport ( "fmt" "time")func numbers() { for i := 1; i <= 5; i++ { time.Sleep(250 * time.Millisecond) fmt.Printf("%d ", i) }}func alphabets() { for i := 'a'; i <= 'e'; i++ { time.Sleep(400 * time.Millisecond) fmt.Printf.原创 2021-11-01 17:15:25 · 145 阅读 · 0 评论 -
go:并发编程关键字go和chan,避免死锁
先上测试代码:package mainimport ( "fmt" "time")func slowFunc(c chan bool) { fmt.Println("slowFunc began") time.Sleep(time.Second * 2) c <- true fmt.Println("sleeper() finished")}func main() { fmt.Println("main began") c := make(chan bool) //原创 2021-11-01 17:10:40 · 324 阅读 · 0 评论 -
go:sort相关
package mainimport ( "sort" "fmt")func main(){ // 1.对整形数组排序 s1 := [...]int{1,3,43,3,5,6,32,56,7,8,53,} sort.Ints(s1[:]) //切片本质上是对底层数组的一个view,不能直接修改view,通过视图来修改 fmt.Println(s1) //[1 3 3 5 6 7 8 32 43 53 56] // 2.对字符串类型数组进行排序 s2:=[...]string{"转载 2021-10-31 21:14:52 · 61 阅读 · 0 评论 -
Go:多核并行(并发)时间比较
场景模拟:在1000000个1-100的数中,插入一个101,分两种搜索:1.单核搜索,记录时间2.多核搜索,记录时间代码:package mainimport ( "fmt" "math/rand" "runtime" "time")var a []intvar b []intfunc main(){ rand.Seed(time.Now().UnixNano()) a = make([]int, 10000000) for i := 0; i < 99原创 2021-10-19 20:00:48 · 367 阅读 · 0 评论 -
Go:构建并调用自定义的接口包
构建自定义mysort包(使用bubblesort)package mySorttype Interface interface { // Len is the number of elements in the collection. Len() int // Less reports whether the element with index i // must sort before the element with index j. // // If both Less(i,原创 2021-10-19 17:21:18 · 223 阅读 · 0 评论 -
leetcode:有效的数独
思路:1.最简单的思路就是每行、每列、每块判断一次,这样要三次方复杂度2.其实我们可以给每行、每列、每块一个buffer,记录其中出现过的num的次数3.遍历81个位置,首先它得是个数字hhh,然后判断这个数字所在的行、列、块是否已经有这个数字了,有就凉凉,没有就将buffer设置为true4.如果遍历完之后还灭有异常,就是正确的代码:func isValidSudoku(board [][]byte) bool { //设置buffer,时间复杂度将为平方 rowbuffer.原创 2021-10-17 23:26:34 · 135 阅读 · 0 评论 -
leetcode:移除元素
分析:其实也无需移除,只用把不为val的放到前面即可1.特殊情况为02.用j记录放的位置3.用i遍历nums,若nums[i]为val则判断i和j若不等则交换,同时j++若相等则直接j++4.最后返回j,以及前j个元素src:func removeElement(nums []int, val int) int { if len(nums) == 0 { return 0 } //利用j将值不为val的放到前面 j := 0 for .原创 2021-10-13 22:03:04 · 58 阅读 · 0 评论 -
leetcode:K 个一组翻转链表(没弄懂)
思路:1.递归,每次处理k个,不足k个不处理2.对k个的处理用reverse进行3.reverse实际上由k+1个,通过prev,first和temp来逐次挪动src/** * Definition for singly-linked list. * type ListNode struct { * Val int * Next *ListNode * } */func reverseKGroup(head *ListNode, k int) *ListNode {.原创 2021-10-12 22:56:52 · 54 阅读 · 0 评论 -
GO:方法的对象和类型调用
举一个栗子:package mainimport ( "fmt")type Employee struct { name string age int}//方法接收者是值func (e Employee) changeName(newName string) { e.name = newName fmt.Printf("\nEmployee name in func is: %s", e.name)}//方法接收者是指针func (e *Employee) chang原创 2021-10-12 12:06:21 · 282 阅读 · 0 评论 -
Go:匿名结构体使得子类方法提升
举一个栗子:package mainimport ( "fmt")type address struct { city string state string}type person struct { firstName string lastName string address}func (a *address) fullAddress() { //接收者是子结构指针 fmt.Printf("Full address: %s, %s\n", a.city, a.原创 2021-10-12 11:11:06 · 60 阅读 · 0 评论 -
go语言结构体对应的方法——接受方为值传递和引用传递
举一个栗子package mainimport ( "fmt")type Alien struct { color string sex string}//方法接受者是valuefunc (a Alien) changeColor(newColor string) { a.color = newColor}//方法接受者是addressfunc (a *Alien) changeSex(newSex string) { a.sex = newSex}func ma原创 2021-10-11 23:28:28 · 411 阅读 · 2 评论 -
go:自定义类型+绑定方法+双金字塔打印测试
源代码:package mainimport "fmt"type Mychar runefunc (c Mychar) display(){ for i := 0; i < 10; i++ { for j := 0; j < i; j++ { fmt.Printf(" ") } for j := 0; j < 2 * (10 - i) - 1; j++ { fmt.Printf("%c", c) } for j := 0; j < i;原创 2021-10-11 12:18:41 · 98 阅读 · 0 评论 -
go语言:从指定txt读入文件,并返回频数最高的20个词
流程分析:读入txt-》去除分隔符-》计入map-》计入struct[] 并完成sort接口-》进行sort-》输出结果完整代码:package mainimport ( "fmt" "io/ioutil" "log" "sort" "strings")//define a structtype node struct { word string count int}//make some structs into a listtype nodelist []node原创 2021-09-27 16:30:26 · 124 阅读 · 0 评论 -
go:进入某个url的json接口查看一下内容
package mainimport ( "fmt" "net/http" "net/url" "strings")const IssuesURL = "https://api.github.com/search/issues"func main(){ terms := []string{"repo:golang/go","is:open", "json", "decoder"} var q string = url.QueryEscape(strings.Join(term原创 2021-09-25 22:56:41 · 203 阅读 · 0 评论 -
go语言:数组、slice、输入处理、reverse
func main() { //!+array a := [...]int{0, 1, 2, 3, 4, 5} reverse(a[:]) fmt.Println(a) // "[5 4 3 2 1 0]" //!-array //!+slice s := []int{0, 1, 2, 3, 4, 5} // Rotate s left by two positions. reverse(s[:2]) reverse(s[2:]) reverse(s) fmt.Println(..原创 2021-09-24 11:57:18 · 748 阅读 · 0 评论 -
go源码中诡异的if
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.// License: https://creativecommons.org/licenses/by-nc-sa/4.0/// See page 72.// Basename2 reads file names from stdin and prints the base name of each one.package mainimport ( "bufio"原创 2021-09-21 12:42:31 · 117 阅读 · 0 评论 -
go语言:对于多重逻辑使用位运算
背景:/* a去,b也去d,e中必有人去b,c中必有人去,但只可去1人c,d要么都去,要么都不去e去,a也去*/求解所有可能性所有可能就是32种,用5位标识,1标识去,0标识不去源码:package mainimport "fmt"/* a去,b也去 d,e中必有人去 b,c中必有人去,但只可去1人 c,d要么都去,要么都不去 e去,a也去*///多种复杂的逻辑组合//使用位运算 2^5 = 32func main(){ for i := 0; i <原创 2021-09-18 13:20:38 · 112 阅读 · 0 评论 -
Go源码分析popcount
背景统计一个64位2进制数的1bit的总数思路:分成8个8位组,每个组通过查pc表快速得出1bit数,再加起来pc表的initpackage popcount// pc[i] is the population count of i.var pc [256]bytefunc init() { for i := range pc { pc[i] = pc[i/2] + byte(i&1) }}注意!!!这里的[256]byte 是表示从0-255(十进制)而不是0到原创 2021-09-17 22:23:18 · 233 阅读 · 1 评论 -
Go源码分析FtoC
// Cf converts its numeric argument to Celsius and Fahrenheit.package mainimport ( "fmt" "os" "strconv" "gopl.io/ch2/tempconv")func main() { //_记录的是index忽略,arg记录的是参数,第0个是文件所在地址,因此从第一个开始 for _, arg := range os.Args[1:] { //strconv.Parse原创 2021-09-17 19:03:25 · 137 阅读 · 0 评论 -
Win10下go如何调用自建包(实测可用)
作为go菜鸟,最近在学习go语言,学到建立自建包并调用时,真的有暴捶电脑的感觉step 1:需要在goroot/src下加入自建包(goroot就是go就是go语言环境下文件夹的路径)如上图,这里放的是go提供的包,其中gopl.io就是我的自建包,结构如下:conv.gopackage tempconv// CToF converts a Celsius temperature to Fahrenheit.func CToF(c Celsius) Fahrenheit { retur原创 2021-09-16 13:59:04 · 350 阅读 · 0 评论