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

小生凡一 小生凡一     2022-12-13     772

关键词:

文章目录

写在前面

滴滴面试感觉还行吧,挺注重基础的,很多时间都花在了挖项目上面,所以大家一定要很熟悉自己的项目!面试官水平也很高。不过也感叹这个曾经的大厂现在变成这个样子,唉。。

笔试

一面

进程间通信方式

管道、消息队列、信号量、共享内存

栈上分配内存快还是堆上,为什么?

显然从栈上分配内存更快,因为从栈上分配内存仅仅就是栈指针的移动而已

  1. 操作系统会在底层对栈提供支持,会分配专门的寄存器存放栈的地址
  2. 栈的入栈出栈操作也十分简单,并且有专门的指令执行,所以栈的效率比较高也比较快。
  3. 堆的生长空间向上,地址越来越大,栈的生长空间向下,地址越来越小。

channel 底层

type hchan struct 
 qcount   uint   
 // channel 里的元素计数
 dataqsiz uint   
 // 可以缓冲的数量,如 ch := make(chan int, 10)。 此处的 10 即 dataqsiz
 elemsize uint16 
 // 要发送或接收的数据类型大小
 buf      unsafe.Pointer 
 // 当 channel 设置了缓冲数量时,该 buf 指向一个存储缓冲数据的区域,该区域是一个循环队列的数据结构
 closed   uint32 
 // 关闭状态
 sendx    uint  
 // 当 channel 设置了缓冲数量时,数据区域即循环队列此时已发送数据的索引位置
 recvx    uint  
 // 当 channel 设置了缓冲数量时,数据区域即循环队列此时已接收数据的索引位置
 recvq    waitq 
 // 想读取数据但又被阻塞住的 goroutine 队列
 sendq    waitq 
 // 想发送数据但又被阻塞住的 goroutine 队列
 
 lock mutex
 ...

七层模型

从上而下分别是 应用层,表示层,会话层,传输层,网络层,数据链路层,物理层等等…

tcp、udp

TCP 是可靠传输,面向连接,基于流,占用资源多,效率低。

UDP是尽最大努力交付,基于无连接,基于报文,UDP 占用系统资源较少,效率高。

redis持久化的方式以及使用场景

Redis提供 RDB 和 AOF 两种持久化机制 , 有了持久化机制我们基本上就可以避免进程异常退出时所造成的数据丢失的问题了,Redis能在下一次重启的时候利用之间产生的持久化文件实现数据恢复

  • RDB持久化就是指的讲当前进程的数据生成快照存入到磁盘中,触发RDB机制又分为手动触发与自动触发

  • AOF 持久化是以独立的日志记录每次写命令,重启 Redis 的时候再重新执行AOF文件中命令以达到恢复数据,所以AOF主要就是解决持久化的实时性

如何实现线程池?

线程池有两部分组成:同步队列和线程池。

  • 同步队列:以链表的形式创建一个同步队列,同步队列的主要工作就是通过Put()函数向队列里面添加事务,通过Get()函数从队列里面取出事务。
  • 线程池:主要由线程组(注:线程组里面存放的时 thread 类型 的共享只能指针,指向工作的线程)构成,通过Start()函数向线程组中添加numThreads个线程,并使得每一个线程调用RunThread()函数来获取同步队列的事务并执行事务;通过Stop() 函数停止线程池的工作。

算法:二叉树俯视图

二面

怎么判断给定ip是否在给定ip区间内?

IP地址可以转换成整数,可以将IP返回化整为整数范围进行排查。

package main

import (
    "fmt"
    "strconv"
    "strings"
)

func main() 
    ipVerifyList := "192.168.1.0-192.172.3.255"
    ip := "192.170.223.1"
    ipSlice := strings.Split(ipVerifyList, `-`)
    if len(ipSlice) < 0 
        return
    
    if ip2Int(ip) >= ip2Int(ipSlice[0]) && ip2Int(ip) <= ip2Int(ipSlice[1]) 
        fmt.Println("ip in iplist")
        return
    
    fmt.Println("ip not in iplist")


func ip2Int(ip string) int64 
    if len(ip) == 0 
        return 0
    
    bits := strings.Split(ip, ".")
    if len(bits) < 4 
        return 0
    
    b0 := string2Int(bits[0])
    b1 := string2Int(bits[1])
    b2 := string2Int(bits[2])
    b3 := string2Int(bits[3])

    var sum int64
    sum += int64(b0) << 24
    sum += int64(b1) << 16
    sum += int64(b2) << 8
    sum += int64(b3)

    return sum


func string2Int(in string) (out int) 
    out, _ = strconv.Atoi(in)
    return

如何优化慢SQL?

  1. 查看是否使用到了索引。
  2. 查看 SQL语句 是否符合最左匹配原则。
  3. 对查询进行优化,尽可能避免全表扫描
  4. 字段冗余,减少跨库查询或多表连接操作
  5. 将一些常用的数据结构放在缓冲中(部门名字,组织架构之类的),就不需要查数据库了。

什么情况不建议使用索引

  1. 在where条件中(包括group by以及order by)里用不到的字段不需要创建索引,索引的价值是快速定位,如果起不到定位的字段通常是不需要创建索引的。
  2. 数据量小的表最好不要使用索引,少于1000个
  3. 字段中如果有大量重复数据(性别),也不用创建索引
  4. 避免对经常更新的表创建过多的索引。
  5. 不建议使用无序的值作为索引。

线程池的几种拒绝策略及其应用场景

当时都不知道这是个啥…
具体看这篇博客吧 线程池拒绝策略应用场景

http与tcp区别

http 就是基于传输层的 tcp 实现的一个应用层协议。

长连接与短连接

长连接意味着进行一次数据传输后,不关闭连接,长期保持连通状态。

短连接意味着每一次的数据传输都需要建立一个新的连接,用完再马上关闭它。下次再用的时候重新建立一个新的连接,如此反复。

讲讲tcp的挥手?

数据传输完毕之后,通信的双方都可释放连接。现在A和B都处于ESTABLISHED状态。

  1. A的应用进程先向TCP发出连接释放报文段,并停止再发送数据,主动关闭TCP连接。A把链接释放报文段首部的终止控制位FIN置为1,其序号为seq=u,它等于前面以传送过的数据的最后一个字节的序号加1.这时候A进入了FIN-WAIT-1(终止等待1)状态,等待B的确认。

注意:TCP规定,FIN报文段即使不携带数据,他也消耗掉一个序号!!

  1. B 收到链接释放报文段后即发出确认,确认号是ack = u + 1,而这个报文段自己的序号是v,等于B前面已传送过的数据的最后一个字节的序号加1.然后B就进入CLOSE-WAIT(关闭等待)状态。TCP服务器进程这时应通知高层应用进程,因而从A到B这个方向的链接就释放了,这时的TCP链接处于半关闭状态,即A已经没有数据要发送了,但B若发送数据,A仍要接收,也就是说,从B到A这个方向的连接并未关闭。这个状态可能要维持一段时间。
  2. A收到来自B的确认后,就进入了FIN-WAIT-2(终止等待2)状态满等待B发出的连接释放报文段。若B已经没有要向A发送的数据,其应用进程就通知TCP释放连接,这时B发出的连接释放报文段必须使FIN = 1,现假定B的序号为w(在半关闭状态B可能又发送了一些数据)。B还必须重复上次已发送过的确认号ack = u + 1.这时B就进入LAST-ACK(最后确认)状态,等待A的确认。
  3. A在收到了B的链接释放报文段后,必须对此发出确认。在确认报文段中把ACK置1,确认号ack=w+1,而自己的序号是seq=u+1(根据TCP标准,前面发送过的FIN报文段要消耗一个序号)。然后进入到TIME-WAIT(时间等待)状态。注意: 现在TCP连接还没有还没有释放掉。必须经过时间等待计时器设置的时间2MSL后,A才能进入CLOSED状态。

时间MSL叫做最长报文段寿命,RFC793建议设在两分钟。但是在现在工程来看两分钟太长了,所以TCP允许不同的实现可以根据具体情况使用更小的MSL值。

time wait,过多怎么办

  1. 修改TIME_WAIT连接状态的上限值
  2. 启动快速回收机制
  3. 开启复用机制
  4. 修改短连接为长连接方式
  5. 由客户端来主动断开连接

算法:忘了…

三面

聊人生…

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

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

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

文章目录写在前面笔试一面算法:判断是否为镜面二叉树算法:二叉树的俯视图一个协程被网络io卡住了,对应的线程会不会卡住?go里面make和new有什么区别?map是怎么实现的?二面go里面slice和array有区别... 查看详情

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

文章目录写在前面笔试一面算法:判断是否为镜面二叉树算法:二叉树的俯视图一个协程被网络io卡住了,对应的线程会不会卡住?go里面make和new有什么区别?map是怎么实现的?二面go里面slice和array有区别... 查看详情

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问题写在前面这个公司估... 查看详情

滴滴java实习面经(代码片段)

滴滴Java实习1.滴滴Java一面2.滴滴Java二面1.滴滴Java一面1.自我介绍?2.Java的基本数据类型和类有什么区别呢?3.Integer.valueOf()有了解吗?传入一个1和传入一个200有什么区别吗?答:Integer.valueOf()作用:将基本... 查看详情

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连接是怎么样的?为什么是三次?断开为什么是四次?三次握手四次... 查看详情