面试准备
算法题目
1、两个链表,求公共最长子串和长度(测开面经)
2、链表中和最大的子串(测开面经三面)
3、反转链表,递归非递归(后端面经)
4、任务依赖关系,排序并判断有环。拓扑排序,凭印象写了dfs的方法不过当时没想到怎么判断有环,后来面试官让用队列的方式,
5、二叉树深度(剑指Offer55)
6、两个链表的第一个公共结点(剑指Offer52)
7、和为N的连续正数序列
8、判断是否为镜面二叉树
9、二叉树的俯视图
go框架
微服务框架
go-zero
go-micro
go micro了解多少?broker
服务框架
gin
gin路由,画图模拟
算法
归并排序是稳定的吗?时间复杂度是多少?
是的,归并排序中相等元素的顺序不会改变。
总时间 = 分解时间+解决问题时间+合并时间。
-
分解时间就是把一个待排序序列分解成两序列,时间为一常数,时间复杂度
o(1)。 -
解决问题时间是两个递归式,把一个规模为n 的问题分成两个规模分别为
n/2的子问题,时间为2T(n/2)。 -
合并时间复杂度为
o(n)。 -
总时间
T(n)=2T(n/2)+o(n),这个递归式可以用递归树来解,其解是o(nlogn)。所以是O(nlogn)
mysql
MySQL高并发解决方案?MVCC 索引实现方式有哪些?B树、B+树、哈希 索引失效的情况? 索引的分类? 主从复制?读写分离可能出现什么问题?
redis
Redis数据类型?应用场景?
redis分布式锁的设计与实现
kafka
网络协议
TCP/IP协议的层次结构,以及每一层中重要协议 TCP和UDP区别?
Session和Cookie区别?集群怎么存SessionId?没答上来,又问禁用Cookie怎么存?URL
操作系统
进程和线程区别? 并发和并行区别?goroutine是哪种? 多线程可能会出现哪些问题?
一个协程被网络io卡住了,对应的线程会不会卡住?
不会。因为都用epoll那是非阻塞调用,网络io和系统调用不一样的处理方式。网络io 是利用非阻塞,系统调用会创建新的线程来接管其他 goroutine。
go 框架
go语言特性
goroutine的理解
GMP模型
channel 原理
channel的实现原理,为什么不用加锁
空chan和关闭的chan进行读写会怎么样?
- 空chan
-
-
- 读会读取到该chan类型的
零值。
- 读会读取到该chan类型的
-
- 写会直接写到chan中。
-
- 关闭的chan
-
-
- 读已经关闭的 chan 能一直读到东西,但是读到的内容根据通道内关闭前是否有元素而不同。
如果有元素,就继续读剩下的元素,如果没有就是这个chan类型的零值,比如整型是 int,字符串是""。
- 读已经关闭的 chan 能一直读到东西,但是读到的内容根据通道内关闭前是否有元素而不同。
-
- 写已经关闭的 chan 会 panic。因为源码上面就是这样写的,可以看
src/runtime/chan.go
- 写已经关闭的 chan 会 panic。因为源码上面就是这样写的,可以看
-
slice
silce遇到过哪些坑,原理?append可能导致底层数组改变 slice作为函数参数怎么解决上面的问题?答return返回,面试官说可以传slice指针
slice 和array的区别 slice, 是切片,是引用类型,长度可变。
array,是数组,是值类型,长度不可变。
slice的底层其实是基于array 实现的
new 和make的区别
make 一般用来创建引用类型 slice、map 以及 channel 等等,并且是非零值的。而new 用于类型的内存分配,并且内存置为零。make 返回的是引用类型本身;而 new 返回的是指向类型的指针。
map 是怎么实现的?
map 的底层是一个结构体
// Go map 的底层结构体表示
type hmap struct {
count int // map中键值对的个数,使用len()可以获取
flags uint8
B uint8 // 哈希桶的数量的log2,比如有8个桶,那么B=3
noverflow uint16 // 溢出桶的数量
hash0 uint32 // 哈希种子
buckets unsafe.Pointer // 指向哈希桶数组的指针,数量为 2^B
oldbuckets unsafe.Pointer // 扩容时指向旧桶的指针,当扩容时不为nil
nevacuate uintptr
extra *mapextra // 可选字段
}
const (
bucketCntBits = 3
bucketCnt = 1 << bucketCntBits // 桶数量 1 << 3 = 8
)
// Go map 的一个哈希桶,一个桶最多存放8个键值对
type bmap struct {
// tophash存放了哈希值的最高字节
tophash [bucketCnt]uint8
// 在这里有几个其它的字段没有显示出来,因为k-v的数量类型是不确定的,编译的时候才会确定
// keys: 是一个数组,大小为bucketCnt=8,存放Key
// elems: 是一个数组,大小为bucketCnt=8,存放Value
// 你可能会想到为什么不用空接口,空接口可以保存任意类型。但是空接口底层也是个结构体,中间隔了一层。因此在这里没有使用空接口。
// 注意:之所以将所有key存放在一个数组,将value存放在一个数组,而不是键值对的形式,是为了消除例如map[int64]所需的填充整数8(内存对齐)
// overflow: 是一个指针,指向溢出桶,当该桶不够用时,就会使用溢出桶
}
map底层
当向 map 中存储一个 kv 时,通过 k 的 hash 值与 buckets 长度取余,定位到 key 在哪一个bucket中,hash 值的高8位存储在 bucket 的 tophash[i] 中,用来快速判断 key是否存在。当一个 bucket 满时,通过 overflow 指针链接到下一个 bucket。
shell脚本
时间、ip、访问信息三列,shell统计访问次数最多的10个ip?
参考来源(整理自用 无意抄袭,侵删): 大厂面试分享(三面美团,四面百度)--测开面经百度 一面--------一个小时左右 1.自我介绍 2.开始讲项目,画项 - 掘金 【Golang开发面经】百度(三轮技术面) - 知乎 百度golang后端日常实习面经三轮技术面10.任务依赖关系,排序并判断有环。拓扑排序,凭印象写了dfs的方法不过当时没 - 掘金 半个月6次面试,终于进百度HR面了 - Go语言学习专栏 - SegmentFault 思否