面试复盘
今天面试问以前的游戏项目比较多 微服务 分布式这些基本上没问 问了几个golang的基础 和mysql redis 自认为答得一般 没想到还到二面了
string会不会有并发问题 一个协程修改 协程读取 会不会出现问题 频繁修改字符串会有什么问题
- 可能会出现问题 因为string类型的底层是一个结构体 包含指针和长度字段指针指向固定的字符串数组 这个字符串数组是不可修改的 但是在赋值的时候 需要赋值长度和指针两个值 这个操作显然不是并发安全的 会出现指针修改了 长度未修改的情况 或者指针未修改 长度修改了 这样得到的结果就是错误的 如果修改的len是一样的 那么不会出现问题(个人测试的结果)
- 会造成大量内存开销和回收压力 修改一个string类型变量的本质是创建一个新的字符串数组 原有字符串数组就会等待回收
map赋值为nil 或者 只定义不初始化 能读操作吗 读到的是什么
- 这个简单了 就是读到的值是默认零值
for里面修改map 增加或者删除 能看到增加的map内容吗
- golang的for实现根据类型不同
-
slice array
The loop we generate: for_temp := range len_temp := len(for_temp) for index_temp = 0; index_temp < len_temp; index_temp++ { value_temp = for_temp[index_temp] index = index_temp value = value_temp original body }循环次数已经确定 新增元素并不影响 遍历的数组也是copy出来的 所以修改并不会影响数据
-
map
// The loop we generate: // var hiter map_iteration_struct // for mapiterinit(type, range, &hiter); hiter.key != nil; mapiternext(&hiter) { // index_temp = *hiter.key // value_temp = *hiter.val // index = index_temp // value = value_temp // original body // }map底层使用hash表实现,插入数据位置是随机的,所以遍历过程中新插入的数据不能保证遍历到,新插入的数据可能刚好插入到已经遍历过的key之前 就访问不到了 删除也是同理 如果在遍历到这个元素之前删除了 那么就读不到 如果在这之后删除了 那么也是能读到的
-
channel
// The loop we generate: // for { // index_temp, ok_temp = <-range // if !ok_temp { // break // } // index = index_temp // original body // }
channel中没有元素,则会阻塞等待,如果channel已被关闭,则会解除阻塞并退出循环。
channel赋值为nil 能读到数据吗 一个已经关闭的channel 能读到数据吗 如果能读到 数据读完之后会返回什么
- channel未初始化或者为nil的时候不能读数据 会阻塞 其实这里和map类似 是能操作 但是里面没有任何数据 所以会一直阻塞
- 已经关闭的channel是可以读操作 但是不能写操作 未读完数据之前 value,success := <-ch,value是从ch取出来的值 而success是
true读完之后 value=0 success=false - 向已经关闭的channel写数据会panic 但是向nil的channel写数据则只是会阻塞
通过channel发送一个结构体 结构体本身包含了map和slice字段 在发送之后修改这些字段 在接收方可见这些修改吗
- 是可以看到这些修改的 因为发送的时候是值拷贝 结构体会被复制一份 引用类型就是复制的一份指针数据 发送方和接收方是指向的同一块数据 我的理解是这种值拷贝是拷贝的slice和map等引用类型的header信息 这个header信息本身是可以被修改的 他是原来的header的副本 但是其中指向数据内存的指针是同一个地址 所以修改都是可见的 header副本修改则是不可见的
redis的zset底层实现是什么数据结构
-
Zset 类型的底层数据结构是由压缩列表或跳表实现的:
-
如果有序集合的元素个数小于
128个,并且每个元素的值小于64字节时,Redis 会使用压缩列表作为 Zset 类型的底层数据结构; -
如果有序集合的元素不满足上面的条件,Redis 会使用跳表作为 Zset 类型的底层数据结构;
在 Redis 7.0 中,压缩列表数据结构已经废弃了,交由 listpack 数据结构来实现了
mysql如果主键是一个无序的字段 大量增加或者修改记录的这个字段 会有什么后果
- 无序的字段 如果经常修改 会导致索引重建 耗费大量的资源
很晚了 睡觉了 后面想到什么再补充吧