golang开发面经百度(三轮技术面)(代码片段)

小生凡一 小生凡一     2022-12-04     715

关键词:

文章目录

写在前面

百度一顿面试下来感觉挺不错的,面试官水平很高,不愧是互联网的黄埔军校,技术都很硬。可能是我项目讲的不好吧,最终挂了。

笔试

一面

一直深挖项目,挖了快半小时。然后再写两道题,最后再问一些简单的问题。

算法:判断是否为镜面二叉树

算法:二叉树的俯视图

一个协程被网络io卡住了,对应的线程会不会卡住?

不会。因为都用epoll那是非阻塞调用,网络io和系统调用不一样的处理方式。网络io 是利用非阻塞,系统调用会创建新的线程来接管其他 goroutine。

go 里面 make 和 new 有什么区别?

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 中存储一个 kv 时,通过 k 的 hash 值与 buckets 长度取余,定位到 key 在哪一个bucket中,hash 值的高8位存储在 bucket 的 tophash[i] 中,用来快速判断 key是否存在。当一个 bucket 满时,通过 overflow 指针链接到下一个 bucket。

二面

又深挖项目,这次挖了快40分钟了。。

go里面 slice 和 array 有区别吗?

slice, 是切片,是引用类型,长度可变。
array,是数组,是值类型,长度不可变。

slice的底层其实是基于array 实现的。

归并排序是稳定的吗?时间复杂度是多少?

是的,归并排序中相等元素的顺序不会改变。

总时间 = 分解时间+解决问题时间+合并时间。

  1. 分解时间就是把一个待排序序列分解成两序列,时间为一常数,时间复杂度o(1)
  2. 解决问题时间是两个递归式,把一个规模为n 的问题分成两个规模分别为 n/2 的子问题,时间为2T(n/2)。
  3. 合并时间复杂度为o(n)
  4. 总时间T(n)=2T(n/2)+o(n),这个递归式可以用递归树来解,其解是o(nlogn)

所以是O(nlogn)

写一个归并排序吧

func mergeSort(arr *[]int, l int, r int) 
	if l >= r 
		//不可再分隔,只有一个元素
		return
	
	mid := (l+r)/2
	mergeSort(arr,l,mid)
	mergeSort(arr,mid+1,r)
	if (*arr)[mid] > (*arr)[mid+1] 
		merge(arr, l, mid, r)
	


//将arr[l...mid]和arr[mid+1...r]两部分进行归并
func merge(arr *[]int, l int, mid int, r int)  
	//先把arr中[l..r]区间的值copy一份到arr2
	//注意:这里可优化,copyarr 可改为长度为r-l+1的数组,下面的赋值等操作按偏移量l来修改即可,
	copyarr := make([]int, r+1)
	for index := l; index <= r; index++ 
		copyarr[index] = (*arr)[index]
	
	//定义要合并的两个子数组各自目前数组内还没被合并的首位数字下标为i,j
	//初始化i,j
	i := l
	j := mid+1
	//遍历并逐个确定数组[l,r]区间内数字的顺序
	for k := l; k <= r; k++ 
		//防止i/j"越界",应该先判断i和j的下变是否符合条件(因为两个子数组应该符合i<=mid j<=r)
		if i > mid 
			(*arr)[k] = copyarr[j]
			j++
		else if j > r 
			(*arr)[k] = copyarr[i]
			i++
		else if copyarr[i] < copyarr[j] 
			(*arr)[k] = copyarr[i]
			i++
		else
			(*arr)[k] = copyarr[j]
			j++
		
	


func TestMerge(t *testing.T) 
	arr := []int8,6,2,3,1,5,7,4
	mergeSort(&arr, 0, len(arr)-1)
	fmt.Println(arr)


空chan和关闭的chan进行读写会怎么样?

  • 空chan

    1. 读会读取到该chan类型的零值
    2. 写会直接写到chan中。
  • 关闭的chan

    1. 读已经关闭的 chan 能一直读到东西,但是读到的内容根据通道内关闭前是否有元素而不同。如果有元素,就继续读剩下的元素,如果没有就是这个chan类型的零值,比如整型是 int,字符串是""
    2. 写已经关闭的 chan 会 panic。因为源码上面就是这样写的,可以看src/runtime/chan.go

三面

感觉就走个过场。。面完简历就共享了。。

讲讲redis分布式锁的设计与实现

这篇博客很详细了,可以看这篇博客 redis分布式锁实现

讲讲redis的哨兵模式

一主两从三哨兵集群,当 master 节点宕机时,通过哨兵(sentinel)重新推选出新的master节点,保证集群的可用性。

限流算法有哪些?令牌桶算法怎么实现?

限流算法常见有计数器算法,滑动窗口,令牌桶算法。

令牌桶算法是比较常见的限流算法之一,如下:

  1. 所有的请求在处理之前都需要拿到一个可用的令牌才会被处理;
  2. 根据限流大小,设置按照一定的速率往桶里添加令牌;
  3. 桶设置最大的放置令牌限制,当桶满时、新添加的令牌就被丢弃或者拒绝;
  4. 请求达到后首先要获取令牌桶中的令牌,拿着令牌才可以进行其他的业务逻辑,处理完业务逻辑之后,将令牌直接删除
  5. 令牌桶有最低限额,当桶中的令牌达到最低限额的时候,请求处理完之后将不会删除令牌,以此保证足够的限流

算法:交换二叉树左右节点

golang开发面经滴滴(三轮技术面)(代码片段)

文章目录写在前面笔试一面进程间通信方式栈上分配内存快还是堆上,为什么?channel底层七层模型tcp、udpredis持久化的方式以及使用场景如何实现线程池?算法:二叉树俯视图二面怎么判断给定ip是否在给定ip区间内... 查看详情

golang开发面经滴滴(三轮技术面)(代码片段)

文章目录写在前面笔试一面进程间通信方式栈上分配内存快还是堆上,为什么?channel底层七层模型tcp、udpredis持久化的方式以及使用场景如何实现线程池?算法:二叉树俯视图二面怎么判断给定ip是否在给定ip区间内... 查看详情

golang开发面经字节跳动(三轮技术面)(代码片段)

文章目录写在前面笔试一面epoll、select、poll区别epoll的水平触发和边缘触发的区别TCP的流量控制为什么有了流量控制还要有拥塞控制?TCP不是可靠传输吗?为什么会丢包呢?那你介绍一下拥塞控制的算法?进程、线程的... 查看详情

golang开发面经蔚来(两轮技术面)(代码片段)

文章目录一面1.channel缓冲与非缓冲2.mysql引擎3.索引如何建立?4.linux如何看进程5.redis字符串的底层6.线程池理解7.线程池的拒绝策略8.悲观锁,乐观锁9.HTTP各个版本的区别10.HTTP2.0之前怎么实现服务器推送机制?11.websocket... 查看详情

golang开发面经b站(两轮技术面)(代码片段)

文章目录写在前面笔试一面Go的GMP模型GO的GCGo的map底层是怎么实现的?遍历map是有序的吗?为什么?map作为函数是什么传递?在函数里面修改map会影响原来的吗?那数组呢?切片呢?linux有用过是吧?如... 查看详情

golang开发面经知乎(两轮技术面)(代码片段)

文章目录写在前面笔试一面进程和线程的区别?虚拟地址是什么?内存分段分页讲讲?http1.0,1.1,2.0区别?post和get的区别TCP连接是怎么样的?为什么是三次?断开为什么是四次?三次握手四次... 查看详情

golang开发面经深信服(两轮技术面)(代码片段)

文章目录写在前面一面了解过切片和数组吗?有什么区别?那这样初始化可以吗?有什么问题?用过map吧?怎么遍历map?那遍历map是有序的吗?为什么是无序的?用过chan吧?怎么声明一个chan呢&... 查看详情

golang开发面经深信服(两轮技术面)(代码片段)

文章目录写在前面一面了解过切片和数组吗?有什么区别?那这样初始化可以吗?有什么问题?用过map吧?怎么遍历map?那遍历map是有序的吗?为什么是无序的?用过chan吧?怎么声明一个chan呢&... 查看详情

字节跳动前端日常实习三轮技术面经

一面项目:描述项目某个功能的实现react的特点为什么要使用redux+immutable,redux和全局变量的区别diff算法react-redux的工作原理和相关源码还有一些项目的细节然后是基础知识:实现一个百度搜索框,包括垂直左右居中,自适应的... 查看详情

golang开发面经360(一轮游)(代码片段)

文章目录写在前面笔试一面TCP和UDP区别UDP能可靠传输吗?MYSQL的隔离等级左连接,右连接有什么区别?JOIN的性能一定好吗?线程的通信方式?快排原理?堆排呢?算法:topk问题写在前面这个公司估... 查看详情

golang开发面经360(一轮游)(代码片段)

文章目录写在前面笔试一面TCP和UDP区别UDP能可靠传输吗?MYSQL的隔离等级左连接,右连接有什么区别?JOIN的性能一定好吗?线程的通信方式?快排原理?堆排呢?算法:topk问题写在前面这个公司估... 查看详情

golang开发面经米哈游(一轮游)(代码片段)

文章目录写在前面笔试一面线程和进程有什么区别?各自有什么优缺点?进程之间如何进行通信?什么是信号,信号量是如何实现的?讲讲Go里面的GMP模型?Go的GMP模型map用过吧?怎么对map进行排序࿱... 查看详情

golang开发面经米哈游(一轮游)(代码片段)

文章目录写在前面笔试一面线程和协程有什么区别?各自有什么优缺点?进程之间如何进行通信?什么是信号,信号量是如何实现的?讲讲Go里面的GMP模型?Go的GMP模型map用过吧?怎么对map进行排序࿱... 查看详情

golang开发面经奇安信(两轮技术面)

文章目录写在前面笔试一面说一下TCP的三次握手和四次挥手TCP和UDP的区别怎么让UDP变得可靠写一下sql的查询语句,比如说我要查询id=3的user。说一下InnoDB的特性讲讲mysql的索引如何创建索引?画过流程图吗?我们工... 查看详情

面经分享工作两年多,面试bigo(java岗)居然挂在三轮技术面...

...家叫做Bigo(YY的子公司),面试的职位是面向3-5年的Java开发,最终自己倒在了第三轮的技术面上。虽然有些遗憾和泄气,但想着还是写篇博客来记录一下自己的面试过程好了,也算是对广大程序员同 查看详情

golang开发面经得物(两轮技术面)(代码片段)

文章目录写在前面笔试一面你用过gorm?那我直接用sql不也可以吗?为什么用gorm?你用过哪些锁?那map是线程安全的吗?为什么?chan呢?对一个关闭的chan读写会怎么样?算法:一道回溯的题目&#... 查看详情

golang开发面经知乎(两轮技术面)(代码片段)

文章目录写在前面笔试一面进程和线程的区别?虚拟地址是什么?内存分段分页讲讲?http1.0,1.1,2.0区别?post和get的区别TCP连接是怎么样的?为什么是三次?断开为什么是四次?三次握手四次... 查看详情

golang开发面经b站(两轮技术面)(代码片段)

文章目录写在前面笔试一面Go的GMP模型GO的GCGo的map底层是怎么实现的?遍历map是有序的吗?为什么?map作为函数是什么传递?在函数里面修改map会影响原来的吗?那数组呢?切片呢?linux有用过是吧?如... 查看详情