golang init 初始化执行顺序

首先main之前会执行init。如果init中又依赖其他扩展,则先执行其他扩展中的init。类似于树的叶子节点,先执行的从叶子节点开始。这是今天遇到的一个问题,还有一个就是关于windows配置环境变量。需要注意两点,首先就是环境变量设置之后,需要关闭当前命令行才能生效。另外就是环境变量分为用户变量和系统变量,如果其中设置不生效,可以选择都设置。还有就是设置环境变量以后,是以命令行形式运行的。

golang 什么时候关闭channel

通知接收方没有更多数据了 ch := make(chan int) go func() { for i := 0; i < 5; i++ { ch <- i } close(ch) // 生产者发完了,通知接收者 }() for v := range ch { fmt.Println(v) // 接收者循环读取直

golang interface 底层相关

interface 分两种空接口(eface)和非空接口(有方法定义的接口)type eface struct {_type *_type // 具体类型信息的指针 data unsafe.Pointer // 指向实际存储的数据}也就是定义了指向位置的指针和指向类型的指针。例子:var i interface{}i = 42_type 指向 int 的类型信息。data 存放

golang 组合和继承问题

今天面试的时候,面试问我golang 如何实现继承。我直接说golang中只有组合,想实现类似继承的效果的话。就是struct嵌套struct 这种比较靠谱

golang 对json中字段类型不固定的处理

用golang读取一个json,发现有一个字段的值有的是int类型,有的是string类型。解决思路就是自定义一个类型,然后解析json的时候,自定义函数进行判断。type StringOrInt stringfunc (s *StringOrInt) UnmarshalJSON(data []byte) error {// 尝试解析为字符串 var str string if err :=

golang 实现qps 滑动窗口流量统计

思想就是用循环数组来实现整个结构。其中numSlots用来表示滑动窗口的持续时间,比如30s,间隔时间是1s执行一次,这个可以用goroutine起一个定时器实现。计数就用golang atmic 实现,这个具有原子性。每一次步进就是(curIndex+1)%numSlots 下边就是相关代码。package service import ( "fmt"

10进制转化为二进制

十进制转化为二进制就是取余的值,从右向左排序除 2 取余法例子: 用 4 除 2,记录余数:4÷2=2 余 0 用 2 除 2,记录余数:2÷2=1 余 0 用 1 除 2,记录余数:1÷2=0 余 1 获得值 100 ----------- 用 5 除 2,记录余数:5÷2=2 余1 用 2 除 2,记录余数:2÷2=1 余0 用 1 除 2,记录余数:2÷2=0 余1

goim 代码中 取模和位运算的区别

在goim ring代码中,有位运算&的操作。然后这就引发了一个疑问,为什么不用取模这是因为,在cpu层面,%不是一个便宜的操作,它通常被翻译成除法运算,而除法运算相对于其他运算是比较慢的。 idx := i % num 除法操作 通常比加/位运算慢一个数量级。所以就完全可以用下边代替,这个前提条件是num是2的幂(2, 4, 8, 16 …) idx := i & (num - 1)2 的

goim 源码分析

1.首先就是初始化discovery,然后创建与其他服务通信的gprc客户端。2.然后把其作为参数传入长链接中。接下来就是初始化黑名单,这个是非核心业务,暂时忽略。然后就是创建tcp 和 websocket 服务。addrs 就是不同的地址,创建多个tcp服务。接下来就是apue 讲的怎么创建服务器。1.bind 端口2.listen 监听端口3.accept 接受连接,这里边是阻塞的,所以可以用

tcp 关于拆包分包的的问题

tcp 所谓的分包拆包问题,其实更规范的说法,tcp是流的形式,那么就存在边界问题。而解决边界问题的方案大概有两种,一种定义包头和包体。另外一种就是尾部标识符问题。下边定义下伪代码,其实parse就是用来处理tcp的边界问题。 var buffer bytes.Buffer for { // 1. 从 TCP 连接里读取数据 tmp := mak

golang 多个携程消费任务优化 (1)

现在需求是读取一批图片,然后批量上传到七牛云。现在是第一版,思路就是起5个携程,然后对图片列表进行遍历循环,如果携程数使用超过5个就阻塞代码。这里用到channel 信号量限流作用,就是往channel 写数据,如果channel 满了,就阻塞channel,直到对向从channel里边把数据读取了。 const maxGoroutines = 5 guard := make(ch