golang--随笔1

方法名定义:

golang定义一个方法,方法名首字母小写,代表私有的,方法名大写,代表共有的
 

获取时间:

strconv.Itoa(int(time.Now().Unix()))//获取当前时间戳 

//获取指定多久前的时间戳:
case 15://15分钟
second = 30 * 60
break
case 30://30分钟
second = 60 * 60
break
end_date := strconv.Itoa(int((time.Now().Unix() - second) * 1000))

将数组进行json加密

string,err:=json.Marshal(数组)
将json加密后的数组转化成数组类型:
myMap := make(map[string]interface{})   map[string]中string代表下标都是string型,interface代表,values值可以随机(字符/int/...)
json.Unmarshal([]byte(加密后的结果), &myMap)
 

MD5加密:

w := md5.New()   io.WriteString(w,要加密的字符)   输出加密后的值:fmt.Sprintf("%x",w.Sum(mil))
 

字符串拼接:

用+
或者:bytes.NewBufferString("")   buffer .writeString(字符)  获取拼接好的字符:buffer.String
 

查询变量数据类型

reflect.TypeOf(变量)
 

定义key=>value数组时

要先用a:=make(map['string']string)定义一个类型
然后a["a"] = "c"
 

make和new的区别:

make只用于slice/map/channel的初始化,初始化时会初始化内部结构,返回的是初始化后的类型而非指针

new用于任何类型,初始化只分配内存填0值,返回的是指向0的指针

// make 示例
s := make([]int, 3, 5)   // 返回 []int,len=3, cap=5
m := make(map[string]int) // 返回 map,可以立即使用
ch := make(chan int, 10)  // 返回 chan,缓冲区10

// new 示例
p := new(int)      // 返回 *int,指向 0
slicePtr := new([]int)  // 返回 *[]int,指向 nil slice

// 常见错误
var p *[]int = new([]int)   // 分配了 slice header,但底层数组是 nil
(*p) = append(*p, 1)        // 可以使用,但不常见

rune和byte的区别

byte是Ascll字符(1字节),rune是unicode字符(4字节)。处理中文等多字节字符时必须用rune,否则会出现乱码或长度错误

// byte = uint8,ASCII 字符
var b byte = 'A'     // 65
var b2 byte = '中'    // 错误 '中' 占 3 字节

// rune = int32,Unicode 码点
var r rune = '中'     // 20013
var r2 rune = 'A'     // 65

// 实际应用:处理中文
s := "Hello 世界"
fmt.Println(len(s))           // 12 (H e l l o 空格 世 界 = 5+1+3+3=12)
fmt.Println(utf8.RuneCountInString(s))  // 8

// 遍历字符串的正确方式
for i, ch := range s {        // range 自动按 rune 遍历
    fmt.Printf("%d: %c\n", i, ch)
}
// 输出:
// 0: H
// 1: e
// 2: l
// 3: l
// 4: o
// 5:  
// 6: 世
// 9: 界

 

panic和recover的机制:

panic是程序遇到无法处理的错误时主动崩溃的,recover只能在defer函数中捕获panic,用于防止程序完全崩溃,常用于HTTP框架中隔离单个请求panic

因:panic会沿着调用栈向上传播,直到被recover捕获或程序崩溃;recover只能在defer函数中生效

 

sync.Map与普通map+锁的区别:

sync.map通过读写分离和延迟删除来优化,适合读多写少且key集合相对稳定的场景
普通map+锁更适合频繁写操作或key变化大的场景
// 普通 map + RWMutex(适合读多写少)
type SafeMap struct {
    mu sync.RWMutex
    m  map[string]int
}

func (s *SafeMap) Get(key string) int {
    s.mu.RLock()
    defer s.mu.RUnlock()
    return s.m[key]
}

// sync.Map(适合:读多写少 + key 集合稳定)
var m sync.Map

// 写入
m.Store("key", 42)

// 读取
if val, ok := m.Load("key"); ok {
    fmt.Println(val.(int))
}

// 删除
m.Delete("key")

// 遍历
m.Range(func(key, value interface{}) bool {
    fmt.Println(key, value)
    return true  // 返回 false 停止遍历
})
 

select 机制和随机性:

select会随机选择一个可用的case执行(避免饥饿),没有可用case且没有default时会阻塞;常用于超市控制,非阻塞操作,多路复用和退出信号监听
// select 用于多路监听 channel
func selectExample() {
    ch1 := make(chan int)
    ch2 := make(chan int)
    
    go func() { ch1 <- 1 }()
    go func() { ch2 <- 2 }()
    
    select {
    case v := <-ch1:
        fmt.Println("from ch1:", v)
    case v := <-ch2:
        fmt.Println("from ch2:", v)
    default:
        fmt.Println("都没有数据")
    }
    // 输出:随机,可能是 from ch1:1 或 from ch2:2
}

// 典型用法1:超时控制
func withTimeout() {
    ch := make(chan int)
    select {
    case v := <-ch:
        fmt.Println(v)
    case <-time.After(3 * time.Second):
        fmt.Println("超时了")
    }
}

// 典型用法2:非阻塞操作
func nonBlocking(ch chan int) {
    select {
    case ch <- 42:
        fmt.Println("发送成功")
    default:
        fmt.Println("channel 满了,跳过")
    }
}

// 典型用法3:退出控制
func worker(stop <-chan struct{}) {
    for {
        select {
        case <-stop:
            fmt.Println("收到退出信号")
            return
        default:
            // 正常干活
            time.Sleep(100 * time.Millisecond)
        }
    }
}

iota是什么?有什么特性?

iota是一个常量计数器,只能在const声明中使用,会在每个const块中从0开始逐行递增。核心是为了生成枚举值或位掩码

itoa在const块中默认第一个是0,每增一行iota的值就+1,常用于定义有序常量,比如状态码。要注意的是在同一个const中即使使用_跳过某一行iota的值依然会递增。

 

go test支持的参数?性能测试如何运行?

 -v :显示详细信息输出
-run:指定要运行的测试函数正则
-count:指定运行行数
-cover:显示测试覆盖率
-bench:性能测试,后面跟一个正则表达式来匹配要运行的基准测试函数名
# 运行所有测试,显示详细输出和覆盖率
go test -v -cover ./...

# 运行基准测试,并输出内存分配统计
go test -bench=. -benchmem

# 生成CPU性能分析文件
go test -bench=. -cpuprofile=cpu.prof

  

go中如何实现单例模式:

推荐使用sync.Once来实现单例模式,sync.Once的DO能保证无论被多少个goroutine并发调用,其传入的函数都只会被执行一次,这是实现线程安全懒加载的最高效方式。代码示例:

type singleton struct{}

var instance *singleton
var once sync.Once

func GetInstance() *singleton {
    once.Do(func() {
        instance = &singleton{}
    })
    return instance
}

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posted @ 2020-06-01 11:41  阿陌i  阅读(192)  评论(0)    收藏  举报