记一次面试经历

面试概况

  1. 岗位:golang开发
  2. 公司:*** (公司名字就匿了,避免看了题再去面试对其他小伙伴不公平)
  3. 途经:朋友内推
  4. 方向:IoT(物联网)/区块链
  5. 用时2个多小时(其中半个小时在答题)
  6. 结果::sob: :sob:
    虽然失败了但是还是有很多值得参考的地方,我还是挺看好这个公司发展的方向的,希望对想到这个(类)公司面试的小伙伴有帮助

面试题目

共10题,答题时间30min,其实这些题都很基础,答案我放题后面

不定项选择题

具体选项不完全确定是这些,但是考察的大概就这些内容

  1. 对于func add(args ...int) int {}调用方式正确的选项有()
    A. add(1, 2)
    B. add(1, 3, 7)
    C. add([]int{1, 2})
    D. add([]int{1, 3, 7}…)
  2. 变量的初始化,下面正确的使用方式是()
    A. var i int = 10
    B. var i = 10
    C. i := 10
    D. i = 10
  3. golang中的引用类型包括()
    A. string
    B. map
    C. channel
    D. interface
  4. 关于整型切片的初始化,下面正确的是()
    A. s := make([]int)
    B. s := make([]int, 0)
    C. s := make([]int, 5, 10)
    D. s := []int{1, 2, 3, 4, 5}
  5. 关于channel,下面语法正确的是()
    A. var ch chan int
    B. ch := make(chan int)
    C. <- ch
    D. ch <-
  6. 关于无缓冲和有缓冲的channel,下面说法正确的是()
    A.无缓冲的channel是默认的缓冲为1的channel
    B.无缓冲的channel和有缓冲的channel都是同步的
    C.无缓冲的channel和有缓冲的channel都是非同步的
    D.无缓冲的channel是同步的,而有缓冲的channel是非同步的

不定项选择题答案
以下答案仅供参考,主程没给我最终答案,上面部分问题是我在网上搜索golang面试题后才回想起来的
只要好好准备,这些题都简单,全是基础

  1. ABD
  2. ABC
  3. BCD
  4. BCD
  5. ABC
  6. D

解答题

不管是选择题还是解答题都做到过类似的题型,所以多刷面试题和leetcode没毛病
算法题给我出的都是leetcode里面的简单难度的,以至于我都觉得不算算法题了~
除了算法还考了点基础概念

  1. 简要描述下变量逃逸
  2. 简要描述下slice在append时发生了什么
  3. 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。leetcode链接
  4. 给定两个数组,编写一个函数来计算它们的交集、以及差集(交集简单,重点在差集上)。leetcode 上只讲了交集没讲差集
    如输入nums1 = [4,9,5], nums2 = [7,5,10,8,4]
    交集返回[4,5]
    差集返回[9],[7,10,8]

变量逃逸这题我懵了,我没看过这个的定义,所以就乱写了一堆

  1. 答:不知此题是否想考golang的垃圾回收机制,golang的垃圾回收机制使用的是三色标记法,即先标记后删除,具体逻辑可在面试时详讲(解释起来有点长太长,所以就写了的面试时在直接给面试官讲…)

但是,实际情况是这样的吗?
并不是!!!下面会有解释

  1. 答:
    先看原来的cap够不够装下需要添加进去的元素,如果够,则直接添加
    如果不够,则判断现在slice的大小,大于1024则扩容1.25倍,不够再扩1.25倍;如果小于1024,则扩容到原来的两倍,同理,不够再扩2倍

emmmm,这道题感觉回答得没啥问题,毕竟面试前恶补过
下面为官方实际扩容的规则代码

func grow(s Value, extra int) (Value, int, int) {
    i0 := s.Len()
    i1 := i0 + extra
    if i1 < i0 {
        panic("reflect.Append: slice overflow")
    }
    m := s.Cap()
    if i1 <= m {
        return s.Slice(0, i1), i0, i1
    }
    if m == 0 {
        m = extra
    } else {
        for m < i1 {
            if i0 < 1024 {
                m += m
            } else {
                m += m / 4
            }
        }
    }
    t := MakeSlice(s.Type(), i1, m)
    Copy(t, s)
    return t, i0, i1
}

后面两道题都是leetcode的题,我就不详细解释了
不过我会在下面的主程面试中讲下我是怎么做的,以及怎么‘忽悠’面试官,让他知道我能做出更好的解决方案的

做完题我感觉我有了,我在考虑要15K?16K?18K?了

主程面试

由于是内推(在此感谢@刘水水同学的推荐),直接跳过了前面的步骤,做完题面主程了(好像也没跳过啥~~,反正就是给了机会)

面试题讲解

主程先给我讲了下多选题的第三题,我选反了…给说了下引用类型的概念,我还在第三题下面备注了下
抱歉,对于引用类型的概念我不熟悉,根据题意我猜测答案要么是A要么是BCD(即反过来)
结果我还是选反了~不过面试官还是比较满意的我觉得这里也很重要,不要不会就直接放弃了,总要给出自己的结论,并且解释下为什么我这样想备注里面我没写我为什么这样猜测,不过面试是我给面试官解释了下比如chan 不能单独作为类型,只能是chan int,chan string 等map和interface同样的道理(我都想到这里了居然还能答反,我也是醉了)

简答题1. 面试官给我解释了下变量逃逸的概念:变量逃逸就是变量的作用域的改变
面试官说到这里的时候,我接过来解释到:就是变量从栈逃逸到堆上面去了吗?
得到肯定的回答后,我继续说(为了表明其实我还是理解,只是专业名词不熟悉而已,所以该接过来说的,必须主动接过来说),从栈到堆后会影响运行速度什么的~因为堆上的变量需要GC来处理(顺便就吧我上面答的三色原理提了下,表明虽然我的答案有问题,但是也不是毫无关联的~~哈哈哈,机智如我,我觉得此处很重要,即使题没答对至少要让面试官知道我是知道些东西的
Go变量逃逸分析具体可以参考这篇博文

算法题1 我用的是两次for循环遍历,在面试官评价之前我就先解释了下,一共半个小时,外加手写代码,没办法去考虑更优解,然后就讲了用map来解的更优方案(假装完美混过去)
实际上是:面试官问我,你为什么第一眼没想到用map呢?
emmmm 好的我错了(不过至少让面试官知道我知道更好的解决方案),实际上两次for的做法,在leetcode上都能得到双90的得分了~

算法题2,交集我的做法是把长slice放map里面,然后循环短的slice判定另外一个的map里面是否含有,若有,则把对应项append到结果集中(其实到这里我就反应过来上一题该用map了,但是…答题卡位置有限加上时间限制…我就放弃了修改)
差集同样的用map加上slice的循环找出结果,主程给我说,此处更好的解决方案是使用map自带的delete方法,把交集删除后,剩下的就是差集了,可以把你们的答案留在评论区。。。。
emmmm的确更好哈,可惜我没想到
ok面试题就到这里了,接下来是考了些go的基础

go基础的考核

我尽量回忆当时主程问了的问题,不确定能回忆完
后面的问答题稍微要比前面的题难一点点,不过也没啥太难的
下面只做列举,让同行知道下面试官关心哪些问题

  1. 简单谈下defer的应用场景及注意事项(关闭文件网络请求等,先进后出)
  2. 简单谈下chan的应用场景及注意事项
  3. 简述进程、线程、协程的含义及区别
  4. 往一个对象里写入10w条数据,怎样保证数据的准确性(chan、mutex之类的胡扯就对了)
  5. 闭包的注意事项(这里变量的引用是个坑)
  6. 简单介绍下interface的应用场景(我给扯出什么2.0go打算加入泛型什么的,实际上面试官想问的是接口不是interface{}这个数据类型…,等面试官给我纠正了下思路然后,我又继续讲接口相关的东西…)
    … …
    ok golang的基础考核完了,我感觉我目前问题不大基本能过面试这关了
    继续考虑我的15K?16K?18K?了~~~

和公司业务相关的技术考核

emmmm,然后我就挂在了这里了
由于他们公司是做IoT的所以偏向底层
所以就考了我一些操作系统原理的问题
作为一个非科班出生的人,我当场懵逼
我知道接下来我将面临的问题是我无法正确解答的
不过抱着试一试的心态继续淦
以下答案请勿参考,我是乱答的,你只需要看题就够了

  1. 线上cpu和内存突然飙高后应该怎么排错(debug)

    emmmm,linux应该有命令能直接查看哪个进程导致的,然后….
    好吧我不知道

  2. 哪些操作会导致内存泄漏

    有大量的io的情况(我也不知道对不对,后来去搜了下,好像是没close才会出现)

  3. 哪些操作会导致io开销大幅上升

    大量的文件读写操作会导致io开销剧增,所以可以用bufio缓冲
    还有呢?
    emmm 比如数据库的大量读写
    还有呢?
    emmm 比如缓存的读写…
    还有呢?
    (好吧我错了)不知道了
    网络请求也会造成大量的io,严格意义上来讲数据库的读写也属于网络请求中的一种
    emmmm (好的,我明白了,实际上第一次答的时候去掉’文件’这两个字就好了)

…后面还问了些比较涉及操作系统底层的东西,由于我不太能理解所以就记得不太清除了

面试官结语

面:你golang的基础不错,语言上没有什么问题,但是我们公司做的IoT方向,除了语言本身,还要懂的操作系统原理才行,比如你的算法题,你就没去考虑时间空间的问题,如果你去一个偏向业务的岗位问题不大,但是我们公司是偏向底层的,所以不太适合你
我:那贵公司是否有其他偏向业务开发的部门呢?
面:公司还有个部门是做区块链的,更偏向底层
emmmmm

面试官走了hrbp来了(其实就已经结束了)

如果我们公司有其他岗位适合你的,我们这边会通知你的
(哦,理解了,大概意思就是你现在不适合我们公司,面试结束)

个人觉得重要的中间细节

  1. 简答题最好一开始就写最好的方案
  2. 有的东西不知道没关系,但是不回答那你肯定就没戏了,胡扯也得扯,反正你跑远了,面试官会把你拉回来的(有的人觉得,懂就是懂,不懂就是不懂,不要在面试官面前胡扯,面试官都能看出来的,其实我不这样认为,胡扯即使说错了至少能让面试官看到我在其他哪个哪个方面也还是略懂的)
  3. 虽然打断面试官的话是不礼貌的,但是你应该酌情考虑在关键地方合适的‘打断’面试官的发言,然后你接上往后说,让面试官知道你是知道这个知识点的(这个地方一定要把握好度,没把握好的话,你之前回答的再好你都无了)
  4. 明确你面试的公司的‘属性’针对性的复习下(但凡我提前看过操作系统原理,我都不会挂得那么毫无悬念)
  5. 如果你有不错开源项目(或者参与的开源项目)一定要写在简历里,如果不是我简历 里面写了和开源相关的东西,我可能连面试的机会都没有,如果有合适的工作岗位,欢迎小伙伴们给推荐哦,我的简历 在github上有一份~~

讲道理
我已经很满意我面试的表现了
虽然挂了,但是我把我知道的都说出来了(当然grpc,http2那些没考)
而且通过面试官对我的评价以及答题情况让我对自己在go语言基础操作上更有自信了
然后就是,一个人、一本书、一个月还你一个奇迹(操作系统原理从入门到放弃)
一年前的我:php是世界上最好的语言:sunglasses:
现在的我:go是世界上最好的语言:rocket:

最后
祝我自己今年能成功转入go开发者的行列中

最后的最后
祝go红红火火

本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由 wangchunbo 于 3年前 加精
讨论数量: 10

简答题第三题用桶排序应该可以实现交集和差集

3年前 评论
Iwanna (楼主) 3年前
php炎黄

只能说明公司不缺人

3年前 评论
Iwanna (楼主) 3年前

大佬厉害~我是GO小白,上面问题除了选择题会几个,其他都不知道 = = ...说个我面试的奇葩经历,那时候考官问我什么,只要我不知道的,我全部回答不知道,不管他怎么追问,怎么要我想想,怎么试着带我,我全部回答不知道,凡有任何一点我一知半解我也全部回答不知道。。。哈哈哈。。。基本问十个问题,7个回答不知道。。。而且声音还很理直气壮。。。我前面几个人都比我回答的好,但不知道为啥那考官就是要我去上班。。。当然,我没去。。。而且像这样的面试不止一次,也不止一次要我去,真心不懂他们是为啥。。。

3年前 评论
Iwanna (楼主) 3年前
赌赌赌赌赌赌赌圣! (作者) 3年前

我也想试试。 :blush:

3年前 评论
Iwanna (楼主) 3年前

变量逃逸指的应该就是内存逃逸方面的内容吧

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!