一上来先介绍了他们的业务,是做微视带货的。
没有让我介绍,直接看简历问的。
问了一些项目问题,
有什么挑战。介绍了数据量大,接入设计,测试难点。
项目中司机数据怎么存的,有几千万,我说是分表,水平和垂直都有分,索引优化。
redis
- 问了在项目中怎么用的,用于缓存大对象,分布式锁,用zset作优先级排序。
- zset 底层是什么,空间复杂度,时间复杂度,是跳表,O(n), log(n), 又讲了几句为什么不用二叉树。
- rua 怎么实现原子操作的 ,没答上来。参考 【杂谈】如何对Redis进行原子操作 - 猫毛·波拿巴 - 博客园
算法部分
- 问我是不是在刷题,我说我经常参加比赛,为什么?兴趣,另一个学习了数据结构更好的看懂源码,可以更深入了解一些组件的底层实现。
出了2个题,leetcode上都有 - 删除链表倒数第K个元素
- 从右边看二叉树
我写了代码,还做了完整的测试。
数据库
- 索引怎么设计,讲了单个索引,联合索引,选择性。顺带讲了设计完后利用缓存大对象解决慢查询问题。
- 大数据怎么存,分表,横向,纵向分。
go
- 向nil channel里写数据怎么样,会阻塞, 还补充上 向nil channel取数据阻塞, 向close channel 写会panic, 取会返回0值。
- 出了2个 defer相关题, 问返回什么
//主函数
func main() {
fmt.Println(f1()) // 1
fmt.Println(f2()) // 5
}
func f1() (result int ){
defer func() {
result++
}()
return 0
}
func f2() (r int ){
t:=5
defer func() {
t=t+1
}()
return t
}
解释了 defer是在返回前最后的最后做的。第1 个会加1,第二个t复制了,后面加和r没关系了。
- 问以下2种定义方法有什么区别
func (a A) f1() {} // 不会改变数据,
func (a *A) f2() {} // 会改变数据
还有一个区别是
如下:当实现interface{} 方法时,指针是可以实现非指针的方法,反之不行。
package main
type A struct {
}
func (a A) f1() {}
func (a *A) f2() {}
type B interface {
f1()
f2()
}
//主函数
func main() {
var b B
b=A{}
b.f1()
b.f2()
b = &A{}
b.f1()
b.f2()
}
总体难度是中等,没有简单,也没有很难,一个系统设计也没有。基础问得深。