作者:阿秀
校招八股文学习网站:https://interviewguide.cn
这是阿秀的第「290」篇原创
小伙伴们大家好,我是阿秀。
前几天师弟上岸滴滴后给我分享了他的面经:5个面试机会,5家全部OC!最后还是选了滴滴!,他就5个面试机会,然后全都抓住了,都通过了。
今天分享一下他的滴滴面经,问的内容很细,其中有些问题也很经典,面试中主要考察的有Go、计算机网络、Linux以及算法等科目。
Golang
1、什么时候开始接触go的?
答:balabalaba
2、go接口用过吗,有什么特性,应用场景是怎样的?
答:用过,接口是一种类型,它是由一组方法签名组成的抽象集合。接口定义了对象应该具有的行为,而不关心对象的具体实现。
阿秀补充
特性:实现接口需要提供一组方法签名,这些方法签名必须与接口中定义的方法签名完全相同。如果一个对象实现了某个接口,那么这个对象就必须提供该接口中所有方法的实现 。
场景:它被广泛应用于各种领域,比如网络编程、并发编程、测试等。比如:
网络编程中,接口可以用于定义各种网络协议的通信方式。
并发编程中,接口可以用于定义各种并发模式的接口。
测试中,接口可以用于定义各种测试框架的接口。
3、go defer用过吗,有什么特性,应用场景是怎样的?
答:defer是Go语言中的一个关键字,它用于注册延迟调用。这些调用直到return前才被执行。
因此,可以用来做资源清理。如果多个defer语句,按先进后出的方式执行。
阿秀补充
defer有以下特性:
延迟调用:defer可以注册延迟调用,这些调用直到return前才被执行。
资源清理:defer可以用来释放资源,比如关闭文件、解锁等。
可以多次使用:defer可以多次使用,每次注册的延迟调用都会按照注册的顺序依次执行。
可以与goroutine一起使用:defer也可以与goroutine一起使用,当defer注册在一个goroutine中时,它会在goroutine退出时执行 。
应用场景
并发同步控制:在并发编程中,可以使用defer来确保某个函数在所有子协程都退出后再执行。
锁场景:在锁场景下,可以使用defer来确保锁释放,防止死锁等问题。
4、go切片和数组的区别
答:在Go语言中,数组和切片都是用来存储一组相同类型的数据的。
区别它们的区别主要有两点:
数组的长度是固定的,而切片的长度是可变的。
数组是值类型,而切片是引用类型。
具体来说,数组中的每个元素都有一个固定的内存地址,而切片则是由数组实现的,它只是对原始数组进行了封装。
因此,当使用切片时,我们可以通过修改切片来改变原始数组的内容。
阿秀补充
由于切片是引用类型,所以在函数调用时传递切片会创建一个新的切片副本,而传递数组则会传递指针或引用。
5、切片的扩容机制
答提供了一个 slice 这样子的结构,底层维护了一个指向数组的指针,然后还维护了一个数组的长度和一个它的空间预存的一个 CAP 的容量值。
如果将这个当前的数组 space 的大小它是小于 1024 的话,那基本上都是 2 倍的扩容,然后如果超过 1. 2 次的大小的话,基本上是 1. 25 倍的扩容。
网友补充
如果go 1.18+,原来的slice 容量oldcap小于256的时候,新 slice 的容量newcap是oldcap 的2倍;
当oldcap容量大于等于 256 的时候,newcap会有个计算公式:newcap += (newcap + 3*threshold) / 4 再对 newcap 作了一个内存对齐,这个和内存分配策略相关。
进行内存对齐之后,新 slice 的容量是要大于等于按照前半部分生成的newcap。
6、go 怎么管理内存的
答:Golang的内存管理基于tcmalloc,可以说起点挺高的。
Go语言的内存分配器的核心设计思想是:多级内存分配模块,减少内存分配时锁的使用与系统调用;多尺度内存单元,减少内存分配产生碎片。
阿秀补充
Golang在实现的时候还做了很多优化,感兴趣的还通过源码来看一下Golang的内存管理实现。
Golang的内存管理实现主要涉及以下几个方面:
内存分配器(malloc)和释放器(free):Golang使用tcmalloc作为其默认的内存分配器,它是一个高效的内存分配器,可以减少内存碎片。在Go语言中,可以使用内置函数malloc和free来分配和释放内存。
垃圾回收机制:Golang使用并发标记清除算法(Concurrent Mark Sweep,CMS)作为其默认的垃圾回收机制。CMS是一种高效的垃圾回收算法,可以在不阻塞用户线程的情况下进行垃圾回收。
内存池技术:Golang使用内存池技术来提高内存分配和释放的效率。内存池是一种预先分配一定数量内存的技术,可以避免频繁地调用系统函数分配和释放内存,从而提高程序的性能。
大对象支持:Golang支持大对象,即超过1MB的对象。为了支持大对象,Golang使用了一种称为“可变大小数组”的数据结构,它可以在运行时动态调整数组的大小。
Golang的内存管理实现非常高效和灵活,可以满足各种不同场景下的需求。
7、怎么知道变量在堆区还是栈区
答:在Golang中,变量的分配方式取决于变量的作用域。
如果变量是在函数内部定义的,那么它会被分配到栈上;如果变量是在函数外部定义的,那么它会被分配到堆上。
如果可能,Golang编译器会将函数的局部变量分配到函数栈帧(stack frame)上。
然而,如果编译器不能确保变量在函数 return 之后不再被引用,编译器就会将变量分配到堆上。
而且,如果一个局部变量非常大,那么它也应该被分配到堆上而不是栈上。
8、go中线程和协程的区别
答:在 Go 中,线程和协程都是并发执行的方式。
线程是操作系统分配的资源,而协程是由程序员手动创建的。线程之间共享进程的内存空间,而协程之间则共享栈空间。
线程之间的切换比协程之间的切换更快,因为它们需要进行更多的上下文切换。但是,由于线程之间共享进程的内存空间,因此可能会发生数据竞争和死锁等问题。
相比之下,协程之间的切换更快,因为它们共享自己的栈空间。这使得协程更容易管理,也可以避免一些并发问题。
9、go协程用过吗,应用场景是怎样的
答:协程是 Go 语言中的并发执行方式,它是由程序员手动创建的。协程之间共享自己的栈空间,因此可以避免一些常见的并发问题,例如死锁和数据竞争。
阿秀补充
Go 协程的应用场景包括但不限于:
异步 I/O 操作
网络编程
后台任务处理
并发爬虫
10、你经常怎么用协程,写一下代码
计算机网络
1、路由器和交换机的区别
答:没答好,随便说了一点。
阿秀补充
从功能上来说:
路由器和交换机都是计算机网络中的设备,但是它们的功能不同。
路由器是连接因特网中各局域网和广域网的设备,用来做网间连接,也就是用来连接不同网络的。
而交换机是一个扩大网络的器材,能为子网络中提供更多的连接端口,以便连接更多的计算机。
从层级上来说:
普通的交换机一般工作在OSI七层模型的第二层·数据链路层,而路由器则工作在第三层·网络层。
2、浏览器输入一个url,具体会发生什么,其中用到了哪些协议,这些协议分别在哪一层
答:经典问题,省略。
阿秀补充
1、首先查浏览器缓存,看看有没有已经缓存好的,如果没有
2 、检查本机host文件,
3、调用API,Linux下Socket函数 gethostbyname
4、向DNS服务器发送DNS请求,查询本地DNS服务器,这其中用的是UDP的协议
5、如果在一个子网内采用ARP地址解析协议进行ARP查询如果不在一个子网那就需要对默认网关进行DNS查询,如果还找不到会一直向上找根DNS服务器,直到最终拿到IP地址(全球400多个根DNS服务器,由13个不同的组织管理)
6、这个时候我们就有了服务器的IP地址 以及默认的端口号了,http默认是80 https是 443 端口号,会,首先尝试http然后调用Socket建立TCP连接,
7、经过三次握手成功建立连接后,开始传送数据,如果正是http协议的话,就返回就完事了,
8、如果不是http协议,服务器会返回一个5开头的的重定向消息,告诉我们用的是https,那就是说IP没变,但是端口号从80变成443了,好了,再四次挥手,完事,
9、再来一遍,这次除了上述的端口号从80变成443之外,还会采用SSL的加密技术来保证传输数据的安全性,保证数据传输过程中不被修改或者替换之类的,
10、这次依然是三次握手,沟通好双方使用的认证算法,加密和检验算法,在此过程中也会检验对方的CA安全证书。
11、确认无误后,开始通信,然后服务器就会返回你所要访问的网址的一些数据,在此过程中会将界面进行渲染,牵涉到ajax技术之类的,直到最后我们看到色彩斑斓的网页
3、https和http的区别
答:HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全, HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全。
阿秀补充
1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
2、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
Linux
1、Linux用过吗,常用哪些操作?
答:chmod chown useradd groupadd netstat等等
阿秀补充
文件相关(mv mkdir cd ls)
docker相关(docker container ls docker ps -a )
测试相关(测试连通性:ping 测试端口连通性:telnet)
2、如何查看进程用到的端口?
答:netstat
阿秀补充
可以使用以下命令查看进程使用的端口:
netstat -tunlp | grep <进程ID>
其中,-t
表示 TCP 连接,-u
表示 UDP 连接,-n
表示不进行 DNS 解析,-l
表示只显示监听状态的端口,-p
表示显示进程 ID 和名称。
3、如何查看当前cpu状态 ?
答:top命令
算法&其余
1、算法:找到两个链表的相交结点
2、算法:给一个嵌套的Json字符串作为输入,将其转换为线性的结构体数组
3、项目拷打和论文的介绍
4、Kafka有用过吗,怎么用的,kafka消费组有什么特性?
阿秀一直在做的一件事
这里也给自己的知识星球,也就是学习圈打个广告,目前星球已经满2600人了,再过一段时间会迎来一波大的涨价。
前年和去年分享的很多校招上岸经验也都是出自阿秀的学习圈中的往届上岸人,阿秀的学习圈中置顶帖的「知识图谱」和「精华区」(如下图)中有很多计算机大学本科&研究生学习以及校招的内容和问题,多看看这些能够帮你走的更稳、更顺、更平坦。
后续也会在自己组建的阿秀的学习圈中分享一些社招跳槽找工作的经验,都是自己一路走过来的经验。
星球里的精华区、知识图谱以及资源沉淀
一个人踽踽独行不如结伴而行,以后会继续在星球笔耕不辍,输出一些有价值的内容。
欢迎点击左下角阅读原文详细了解,这可能是你求职路上性价比最高的一次点击!
这段时间自己独立开发的网站就是优先给星球用户使用的,网站功能其实很简单,就是根据局部性原理开发的,关注我的大多都是计算机相关的从业者或者在校生,局部性原理应该都知道是什么意思,它本来是指CPU访问存储器时,无论是存取指令还是存取数据,所访问的存储单元都趋于聚集在一个较小的连续区域中。
其实生活中也有很多类似局部性原理的场景,比如前段时间考察某人的面试问题很有可能会在接下来的面试中再被拿去考察其余的面试者,但在三月份换工作的时候,我本来想找一个类似的网站复习面试,但并没有找到类似的网站,所以自己想自己开发一个好了。
比如我想查一下行业为互联网,公司为字节跳动,考察岗位为后端,考察时间为最近一年之类的面试题有哪些?
已经有不少小伙伴遇到原题了,具体可以看下链接:
后面还会继续开发其余星球用户专属功能,比如模拟面试以及题目收藏、甚至是真题下载打印功能等。