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

小生凡一 小生凡一     2022-11-22     399

关键词:

文章目录

写在前面

深信服面试起来感觉有点偏向应用,没有涉及高并发等等内容,想想也确实,深信服更多偏向B端。业务能力扎实也是应该的。深信服挺好的,但我想找toc的,就拒掉了。。

一面

了解过切片和数组吗?有什么区别?

切片的底层其实是数组,数组是不可变长度的,而切片是可变长度的。

那这样初始化可以吗?有什么问题?

var array []int

这种其实不好,因为这样是不能赋予地址的。所以容易报错,我们要么用 make去创建,要么用语法糖 array:=[]int去创建。

用过map吧?怎么遍历map?

for k,v:=range map
	...

那遍历 map 是有序的吗?

无序的

为什么是无序的?

不是有序的,使用 range 多次遍历 map 时输出的 key 和 value 的顺序可能不同,map在遍历时,并不是从固定的0号bucket开始遍历的,每次遍历,都会从一个随机值序号的bucket,再从其中随机的 cell 开始遍历。map 遍历时,是按序遍历 bucket,同时按需遍历 bucket 和其 overflow bucket 中 的 cell。

但是 map 在扩容后,会发生 key 的搬迁,这造成原来落在一个 bucket 中的 key,搬迁后,有可能会落到其他 bucket 中了,从这个角度看,遍历 map 的结果就不可能是按照原来的顺序了。

用过chan吧?怎么声明一个chan呢?

chan是引用类型,一般我们应该用make去创建一个chan

ch:=make(chan int)

怎么发消息给chan呢?

ch <- 1

给一个关闭的chan发消息会怎么样?

会引起panic

讲讲 GMP 吧

G:表示goroutine,存储了goroutine的执行stack信息、goroutine状态以及goroutine的任务函数等;另外G对象是可以重用的。
P:表示逻辑processor,P 的数量决定了系统内最大可并行的 G 的数量(前提:系统的物理cpu核数 >= P的数量);P的最大作用还是其拥有的各种G对象队列、链表、一些cache和状态。
M:M 代表着真正的执行计算资源,物理 Processor。

G 如果想运行起来必须依赖 P,因为 P 是它的逻辑处理单元,但是 P 要想真正的运行,他也需要与 M 绑定,这样才能真正的运行起来,P 和 M 的这种关系就相当于 Linux 系统中的用户层面的线程和内核的线程是一样的

那GC有了解过吗?

Go是采用三色标记法来进行垃圾回收的,是传统 Mark-Sweep 的一个改进,它是一个并发的 GC 算法。on-the-fly

原理如下

  1. 整个进程空间里申请每个对象占据的内存可以视为一个图, 初始状态下每个内存对象都是白色标记。
  2. stop the world,将扫描任务作为多个并发的goroutine立即入队给调度器,进而被CPU处理,第一轮先扫描所有可达的内存对象,标记为灰色放入队列
  3. 第二轮可以恢复start the world,将第一步队列中的对象引用的对象置为灰色加入队列,一个对象引用的所有对象都置灰并加入队列后,这个对象才能置为黑色并从队列之中取出。循环往复,最后队列为空时,整个图剩下的白色内存空间即不可到达的对象,即没有被引用的对象;
  4. 第三轮再次stop the world,将第二轮过程中新增对象申请的内存进行标记(灰色),这里使用了writebarrier(写屏障)去记录这些内存的身份;

这个算法可以实现 on-the-fly,也就是在程序执行的同时进行收集,并不需要暂停整个程序。

mysql 有用过吧?MVCC 是怎么实现的?

MVCC 的目的就是多版本并发控制,在数据库中的实现,就是为了解决读写冲突,它的实现原理主要是依赖记录中的 3个隐式字段,undo日志 ,Read View 来实现的。所以我们先来看看这个三个 point 的概念

  1. 隐式字段

每行记录除了我们自定义的字段外,还有数据库隐式定义的 DB_TRX_ID, DB_ROLL_PTR, DB_ROW_ID 等字段

  • DB_TRX_ID:6 byte,最近修改(修改/插入)事务 ID:记录创建这条记录/最后一次修改该记录的事务 ID
  • DB_ROLL_PTR:7 byte,回滚指针,指向这条记录的上一个版本(存储于 rollback segment 里)
  • DB_ROW_ID:6 byte,隐含的自增 ID(隐藏主键),如果数据表没有主键,InnoDB 会自动以DB_ROW_ID ,产生一个聚簇索引。
  1. undo日志
  • insert undo log:代表事务在 insert 新记录时产生的 undo log,只在事务回滚时需要,并且在事务提交后可以被立即丢弃。
  • update undo log:事务在进行 update 或 delete 时产生的 undo log ,不仅在事务回滚时需要,在快照读时也需要;所以不能随便删除,只有在快速读或事务回滚不涉及该日志时,对应的日志才会被 purge线程统一清除。
  1. Read View

Read View 就是事务进行 快照读 操作的时候生产的 读视图 (Read View),在该事务执行的快照读的那一刻,会生成数据库系统当前的一个快照,记录并维护系统当前活跃事务的 ID (当每个事务开启时,都会被分配一个 ID , 这个 ID 是递增的,所以最新的事务,ID 值越大)。

mysql 的锁是怎么实现的?

当时确实没了解如何实现的,只知道如何for update这些,可以看这篇博客,很详细了。
Mysql锁机制及原理简析

用过gin是吧?gin是怎么处理请求的?

Gin其实是通过一个context来进行上下文的传递,将这个传递参数,参数返回。

如果有一个业务给你,你怎么写这个请求?

首先肯定是传统的MVC模型来进行操作。

controller层来接受请求,service层来进行请求的处理,dao层来写sql语句。

算法:将重复的元素移到最后

二面

二面基本都是跟着项目走。

如果你的系统突然多了10w的访问量,你要怎么处理?

  1. nginx来进行负载均衡。
  2. 用户验证的信息的过期时间设置长一点,以免发生缓冲雪崩的问题。
  3. 设置布尔过滤器。
  4. 检查sql语句,是否符合要求,是否是慢sql,如果是则解决。

redis用过是吧?说说你在项目里面的排行榜?你说说redis的底层是怎么处理的?

主要是用redis的zset实现的。
zset主要是跳跃表实现的。
Redis 的跳跃表由 redis.h/zskiplistNoderedis.h/zskiplist 两个结构定义,其中 zskiplistNode 结构用于表示跳跃表节点,而 zskiplist 结构则用于保存跳跃表节点的相关信息,比如节点的数量,以及指向表头节点和表尾节点的指针等等。

上图中展示了一个跳跃表示例,最左边的就是 zskiplist 结构。

  • header:指向跳跃表的表头节点。
  • tail:指向跳跃表的表尾节点。
  • level:记录目前跳跃表内,层数最大的那个节点的层数
  • 记录跳跃表的长度,也就是,跳跃表目前包含节点的数量。
  • 层(level):节点中用L1、L2、L3等字样标记节点的各个层,L1表示第一层,L2代表第二层,以此类推。每层都带有两个属性:前进指针和跨度前进指针用于方位位于表尾方向的其他节点。而跨度则记录了前进指针所指向节点和当前节点的距离。
  • 后退(backward)指针: 节点中用BW字样标记的后退指针,他指向当前节点的前一个节点。后退指针在程序从表尾向表头遍历时使用。
  • 分值(score):各个节点中的 1.0、2.0、3.0是节点所保存的分值。在跳跃表中,节点按各个所保存的分值从小到大排序。
  • 成员对象(obj):各个节点中的o1,o2 和 o3 是节点所保存的成员对象。

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开发面经奇安信(两轮技术面)

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

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有用过是吧?如... 查看详情

深信服校招go语言开发岗位面经

原创不易,未经允许,请勿转载。文章目录一面(2021.8.21)二面(2021.9.6)三面sp面(2021.10.23)HR面(2021.10.23)一面(2021.8.21)一面忘了录音记录,仅凭记忆复现自我介绍& 查看详情

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

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

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

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

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开发面经奇安信(两轮技术面)

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

深信服c++三面(技术面30minoffer)(代码片段)

深信服C++三面(技术面、30min、offer)一、面试官问你是从哪里过来的呢?你们校区是和新都校区一样统招的吗自我介绍你挑两个你觉得写的最好的项目来说一说吧讲解两个项目,balabala(10min)你刚才提到的你... 查看详情

深信服c++三面(技术面30minoffer)(代码片段)

深信服C++三面(技术面、30min、offer)一、面试官问你是从哪里过来的呢?你们校区是和新都校区一样统招的吗自我介绍你挑两个你觉得写的最好的项目来说一说吧讲解两个项目,balabala(10min)你刚才提到的你... 查看详情

深信服c++二面(技术面50minoffer)(代码片段)

深信服C++二面(50min)一、问面试官首先是自我介绍有没有做过的什么项目可以聊一聊的聊项目balabala(15min)select多路复用如果来一个请求是怎么处理的select的优点是什么呢?缺点是什么呢?有更好... 查看详情

深信服c++二面(技术面50minoffer)(代码片段)

深信服C++二面(50min)一、问面试官首先是自我介绍有没有做过的什么项目可以聊一聊的聊项目balabala(15min)select多路复用如果来一个请求是怎么处理的select的优点是什么呢?缺点是什么呢?有更好... 查看详情