得物golang一面

发布于:2025-04-20 ⋅ 阅读:(21) ⋅ 点赞:(0)

在这里插入图片描述

select * from tableA where a=1;a有索引但是走了全表扫描为什么,什么情况下会发生?

(b,a)联合索引,不满足最左匹配原则
在这里插入图片描述
在这里插入图片描述

defer panic recover

在这里插入图片描述

package main

import (
    "fmt"
)

func main() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recovered from panic:", r)
        }
    }()

    fmt.Println("Before panic")
    panic("Something went wrong!") // 触发 panic
    fmt.Println("This line will not be executed") // 不会执行
}

在这里插入图片描述

map,range两次为什么会不同,怎么实现并发安全

map 的特性:
无序:Go 的 map 是无序的,使用 range 遍历 map 时,每次遍历的顺序可能不同。
不安全:在多个 goroutine 同时读写同一个 map 时,会引发竞态条件,导致程序崩溃或返回不一致的结果。

package main

import (
    "fmt"
)

func main() {
	book := map[int]string{}
	book[1] = "why"
	book[2] = "yyy"
	book[3] = "xza"
	for i,v := range book{
		fmt.Println(i,v)
	}
	for i,v := range book{
		fmt.Println(i,v)
	}
}
输出:
3 xza
1 why
2 yyy
1 why
2 yyy
3 xza

当你两次使用 range 遍历同一个 map 时,可能会得到不同的结果。这是因为:

map 的顺序在每次迭代时都是随机的。
如果在遍历过程中对 map 进行了修改(如增加或删除元素),这会导致遍历过程中的行为未定义。

package main

import (
    "fmt"
    "sync"
)

func main() {
    // 创建一个非线程安全的 map
    data := make(map[string]int)

    // 使用 WaitGroup 来等待所有 goroutine 完成
    var wg sync.WaitGroup

    // 启动多个写入 goroutine
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func(i int) {
            defer wg.Done()
            data[fmt.Sprintf("key%d", i)] = i
        }(i)
    }

    // 启动多个读取 goroutine
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func(i int) {
            defer wg.Done()
            fmt.Println(data[fmt.Sprintf("key%d", i)])
        }(i)
    }

    // 等待所有 goroutine 完成
    wg.Wait()
}

在这里插入图片描述

go run -race main.go
0
==================
WARNING: DATA RACE
Read at 0x00c00008c150 by goroutine 12:
  runtime.mapaccess1_faststr()
      D:/Golang/src/runtime/map_faststr.go:13 +0x0
  main.main.func2()
      D:/VsCode/MycCodeGo/code/main.go:29 +0x114
  main.main.gowrap2()
      D:/VsCode/MycCodeGo/code/main.go:30 +0x41

Previous write at 0x00c00008c150 by goroutine 8:
  runtime.mapassign_faststr()
      D:/Golang/src/runtime/map_faststr.go:223 +0x0
  main.main.func1()
      D:/VsCode/MycCodeGo/code/main.go:20 +0x109
  main.main.gowrap1()
      D:/VsCode/MycCodeGo/code/main.go:21 +0x41

Goroutine 12 (running) created at:
  main.main()
      D:/VsCode/MycCodeGo/code/main.go:27 +0x1d7

Goroutine 8 (finished) created at:
  main.main()
      D:/VsCode/MycCodeGo/code/main.go:18 +0x7e
==================
==================
WARNING: DATA RACE
Read at 0x00c000024228 by goroutine 13:
  main.main.func2()
      D:/VsCode/MycCodeGo/code/main.go:29 +0x11e
  main.main.gowrap2()
      D:/VsCode/MycCodeGo/code/main.go:30 +0x41
0

Previous write at 0x00c000024228 by goroutine 8:
  main.main.func1()
      D:/VsCode/MycCodeGo/code/main.go:20 +0x115
  main.main.gowrap1()
      D:/VsCode/MycCodeGo/code/main.go:21 +0x41
0

Goroutine 13 (running) created at:
  main.main()
      D:/VsCode/MycCodeGo/code/main.go:27 +0x1d7

Goroutine 8 (finished) created at:
  main.main()
      D:/VsCode/MycCodeGo/code/main.go:18 +0x7e
==================
1
==================
WARNING: DATA RACE
Write at 0x00c00008c150 by goroutine 10:
  runtime.mapassign_faststr()
      D:/Golang/src/runtime/map_faststr.go:223 +0x0
0
  main.main.func1()
      D:/VsCode/MycCodeGo/code/main.go:20 +0x109
  main.main.gowrap1()
      D:/VsCode/MycCodeGo/code/main.go:21 +0x41

Previous write at 0x00c00008c150 by goroutine 11:
  runtime.mapassign_faststr()
      D:/Golang/src/runtime/map_faststr.go:223 +0x0
  main.main.func1()
      D:/VsCode/MycCodeGo/code/main.go:20 +0x109
  main.main.gowrap1()
      D:/VsCode/MycCodeGo/code/main.go:21 +0x41

Goroutine 10 (running) created at:
  main.main()
      D:/VsCode/MycCodeGo/code/main.go:18 +0x7e

Goroutine 11 (finished) created at:
  main.main()
      D:/VsCode/MycCodeGo/code/main.go:18 +0x7e
==================
Found 3 data race(s)
exit status 66

实现并发安全

package main

import (
    "fmt"
    "sync"
)

type SafeMap struct {
    mu   sync.Mutex
    data map[string]int
}

func NewSafeMap() *SafeMap {
    return &SafeMap{data: make(map[string]int)}
}

func (sm *SafeMap) Set(key string, value int) {
    sm.mu.Lock()
    defer sm.mu.Unlock()
    sm.data[key] = value
}

func (sm *SafeMap) Get(key string) int {
    sm.mu.Lock()
    defer sm.mu.Unlock()
    return sm.data[key]
}

func main() {
    safeMap := NewSafeMap()
    var wg sync.WaitGroup

    // 启动多个写入 goroutine
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func(i int) {
            defer wg.Done()
            safeMap.Set(fmt.Sprintf("key%d", i), i)
        }(i)
    }

    // 启动多个读取 goroutine
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func(i int) {
            defer wg.Done()
            value := safeMap.Get(fmt.Sprintf("key%d", i))
            fmt.Println(value)
        }(i)
    }

    // 等待所有 goroutine 完成
    wg.Wait()
}

git 如何进行版本管理

参考:https://blog.csdn.net/sereasuesue/article/details/117080435
git init
git clone

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

http2特性

参考:https://xiaolincoding.com/network/2_http/http2.html#http-1-1-%E5%8D%8F%E8%AE%AE%E7%9A%84%E6%80%A7%E8%83%BD%E9%97%AE%E9%A2%98
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

IO多路复用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

鉴权除了session还有哪些?

参考:https://developer.aliyun.com/article/1358589
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
使用短期的 access token 和 refresh token 的组合有几个重要的安全和设计考虑:

降低风险:如果 access token 被泄露,攻击者可以在其有效期内访问受保护的资源。短期有效的 access token 限制了潜在的损害。
过期机制:短期 token 会定期到期,限制了攻击者能够利用被盗 token 的时间窗口。
refresh token 通常在后台使用,允许用户在不干扰其体验的情况下获取新的 access token,从而避免频繁的登录。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

你了解哪些限流算法?

参考:https://zhuanlan.zhihu.com/p/376564740
简单翻译一下:在计算机网络中,限流就是控制网络接口发送或接收请求的速率,它可防止DoS攻击和限制Web爬虫。

限流,也称流量控制。是指系统在面临高并发,或者大流量请求的情况下,限制新的请求对系统的访问,从而保证系统的稳定性。限流会导致部分用户请求处理不及时或者被拒,这就影响了用户体验。所以一般需要在系统稳定和用户体验之间平衡一下。

固定窗口限流法

在这里插入图片描述
但是,这种算法有一个很明显的临界问题:假设限流阀值为5个请求,单位时间窗口是1s,如果我们在单位时间内的前0.8-1s和1-1.2s,分别并发5个请求。虽然都没有超过阀值,但是如果算0.8-1.2s,则并发数高达10,已经超过单位时间1s不超过5阀值的定义啦。

滑动窗口限流法

在这里插入图片描述
在这里插入图片描述

漏桶算法

在这里插入图片描述

令牌桶算法

在这里插入图片描述

zset常用命令

  1. 添加元素
    ZADD key score member
    向有序集合添加一个元素。如果元素已经存在,则更新其分数。
    ZADD myzset 1 “one”

  2. 获取元素
    ZRANGE key start stop [WITHSCORES]
    返回指定范围内的元素,按分数升序排列。
    ZRANGE myzset 0 -1 WITHSCORES # 获取所有元素及其分数
    ZRANK key member
    获取指定元素的索引(排名),按分数升序排列。
    ZRANK myzset “one”

  3. 删除元素
    ZREM key member [member …]
    从有序集合中删除一个或多个元素。
    ZREM myzset “one”

  4. 获取集合的大小
    ZCARD key
    返回有序集合中元素的数量。
    ZCARD myzset

  5. 获取分数
    ZSCORE key member
    返回指定元素的分数。
    ZSCORE myzset “one”

  6. 范围查询
    ZREVRANGE key start stop [WITHSCORES]
    返回指定范围内的元素,按分数降序排列。
    ZREVRANGE myzset 0 -1 WITHSCORES # 获取所有元素按分数降序

  7. 按分数范围获取元素
    ZRANGEBYSCORE key min max [WITHSCORES]
    返回在指定分数范围内的元素。
    ZRANGEBYSCORE myzset 0 5 WITHSCORES

  8. 按排名范围获取元素
    ZREVRANGEBYLEX key min max [LIMIT offset count]
    返回按字典序排序的元素,支持范围查询。
    ZREVRANGEBYLEX myzset “[a” “[z” # 获取字典序在 a 到 z 之间的元素

  9. 获取排名范围内的元素数量
    ZCOUNT key min max
    返回在指定分数范围内的元素数量。
    ZCOUNT myzset 0 5

  10. 合并两个有序集合
    ZUNIONSTORE destination numkeys key1 [key2 …]
    计算给定的一个或多个有序集合的并集,并将结果存储在目标集合中。
    ZUNIONSTORE myzset2 2 myzset1 myzset3

redis两种持久化方式

AOF日志

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

RDB快照

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到