职业经验 面试总结

guolong123 · 2021年04月28日 · 最后由 guolong123 回复于 2021年05月06日 · 4576 次阅读

最近在面试,两天时间面试了 5 家,其中 4 家线下面试,一家视频面试。有三个面试有复试机会。记录下面试过程中问到的一些问题,促进自己进步。


1 ping++

ping++ 是一家做聚合支付的供应商,去面试自动化测试岗位,去先做题,题目比较简单,python 的一些基础,sql 语句,还有给了一个接口的描述信息,包括接口地址,请求参数等信息,让你设计测试用例。我主要从接口字段的约束和接口权限控制两方面来回答的,主要是测试每个字段的约束,比如长度,空,唯一,类型等,再就是权限控制,测试每种身份登录后对接口功能权限的控制,以及数据权限的测试。不知道还有没有别的测试点?

后面面试官问到了一些比较基础的 python 相关知识都没答上来,还是比较可惜,一个是深拷贝和浅拷贝的区别,再就是问了一个接口字段唯一性怎么测试,我说调用两次插入接口,正常来讲第二次是无法成功的。他说到了一个幂等,我没理解~~。聊了有 1 个小时,最后应该是挂了。

上海瑞界

这家面试过程还算顺利,他们希望我能负责公司的持续集成以及自动化测试方向;没有具体问技术细节,问到的还是比较务实。个人感觉说得还可以,后面也约了 2 面。2 面的时候是一个市场部的人来面试,全程基本在拉家常,过程中我反应了一些当前公司的问题,可能让人觉得不靠谱吧。


伯镭科技

刚开始是电话谈了下,后面见面谈,直接在电脑上操作,修改 nginx 配置文件做一个反向代理;手写一个 sql 语句等,还是比较简单的。后面再有一个电话面试,聊了些需求实现上的内容,基本没涉及到细节。在后面 hr 来沟通薪资,比我预期的薪资还是低一些,我说过几天等答复。

领视科技

面试官提了一个问题,说有老师学生 app,最近老师经常反应 app 使用卡顿,请求超时情况,你如何去定位这个缺陷?

我这边从服务器硬件性能,软件性能,服务端网络,客户端网络来分别举例测试,主要是性能测试,从负载和压力测试来得出服务器性能情况;不知道答得怎么样,但从后面她的反馈来看是不如她意的。

七牛云

七牛云找我要简历的时候我是不怎么抱希望的,觉得我的工作经历和能力以及学历应该是够不上的,但后面居然给了我一个视频面试的机会,还是感觉到非常意外的。

视频面试前半小时我就在腾讯会议等着了,然后面试官非常准时的上线,上线后不像一般的面试让我做个自我介绍,而是直接说让介绍下自己觉得最擅长的内容,然后我把我写的开源库着重的说了下。然后面试官问的问题每个说实话不难,但是比较偏和细。比如问 “你能自己实现列表的功能吗?”,这一问就比较懵逼,以前从没考虑过这个,然后他及时说没关系,我们下一个,感觉还是挺轻松,让我没有因为答不上来而紧张。后面让我实现一个方法,方法接收一个符合 Linux 规则的路径,输出一个绝对路径;写的时候思路还是有点乱,最后没能写出来,实际上后面再想想还是很简单的,思路大概就是先得知传参的路径是否以/开头,否则是相对路径。然后用/分割,循环所有分割字符,遇到..就将路径使用 rsplite 切割,保留前段,遇到.不处理,遇到其它字符直接使用/拼接。

# 事后写的

import os


def path_(path):
    paths = path.split('/')
    root = paths[0]
    if root != '/' and root != '':
        current_dir = os.path.abspath('.')
    else:
        current_dir = '/'
    for p in paths:
        if not p:
            continue
        if p == '..':
            current_dir = current_dir.rsplit('/', 1)[0]
        elif p == '.':
            pass
        else:
            current_dir = current_dir + '/' + p
    print(current_dir.replace('//', '/'))
    current_dir = current_dir.replace('//', '/')
    return current_dir

而我在面试的时候直接说分割后用 chdir 方法一个个进去,然后最终用 current_dir 方法输出绝对路径...,然后还问了些细节,问到 docker 镜像如何减少其存储空间占用,我这边从基础镜像的选择,多命令合并减少层数,删除构建缓存这三个方面回答了问题,应该还有其他的。又问 nginx,我说比较熟悉,然后他问 nginx 的高并发调优怎么做...又问懵了,我说基本上只配个反向代理啥的...,有点打脸。还有关于数据结构的、设计模式的问题都答得不好。后面一小时的时候结束了面试,意想不到的是没过多久居然收到了二面的机会,真的是非常意外。


上面说的问题在面试完了之后都去查了,还是比较简单的。知其然,知其所以然还是有必要的。


4 月 30 日更新

昨天去了七牛云线下面试,总共面了三轮。包括前面视频面算 4 轮。下面总结下面试官问的问题:

  • Python 有了 gil 为何还要线程锁?

这个问题面试官首先是问是否了解 python 的全局锁,我说了 pythonGIL 锁是为了保证 python 程序运行时同一个单位时间内只能有一个线程运行。然后他问了为什么,没答上来,后面又问到多线程时,问为何需要用多线程加锁机制,我说是因为多线程同时操作一个对象时可能会得到意外的结果,举例说明了下:A 线程和 B 线程同时操作 a+=1 的语句时我们要的结果应该是 3,但实际上可能是 2,然后面试官说既然有了 python 全局锁,为何还要在线程上加锁呢?既然同一个时间只能有一个线程执行不应该没有刚刚你说的那个问题吗?我又懵了。结束后搜索后得知,在 python 以及 c 语言中,a+=1 这种语句看起来是只有一行,但实际线程执行时是分两步来操作的,即:

tmp=a+1
a=tmp

所以,让 A 线程执行时执行到 tmp=a+1 后,线程切换到 B 的 tmp=a+1,然后再执行 a=tmp,此时 a=2,切换到 B 线程执行 a=tmp,因为此时 tmp 还是 1,所以结果还是 2。所以我们需要加锁来处理这种情况,实际上可以理解为 python 的 GIL 锁是线程锁,保证同时只能有一个线程执行,而我们自己写的锁是数据锁,只有拿到锁的线程才能去操作数据。

  • Python 不可变类型有哪些

这个问题是比较基础的,但在正常写代码过程中可能不会太在意变量是否可变,所以这个问题我比较含糊,只答出来元组是不可变的。但实际上 int,str,元组都是不可变的,列表,字典和集合是可变的。字典的 key 只能用不可变类型,元组除外。

  • 元祖中的 list 是不是可变的

这个问题我的回答是肯定的,因为在浅拷贝时元组中的 list 也是可以被引用的。面试官说的确是可变的,但操作的时候会报错。我刚刚试了没有报错,是可以 append 的:

l = ([1,2,3], 4)
l[0].append(4)
print(l)
>>> ([1,2,3,4], 4)
  • 两数之和不用双层循环求解,双层循环的时间复杂度

力扣第一题,我说能想到的就是两层循环,两数之和对比,与结果一致则返回。第二层循环时从第二个开始...

def add(l: list, sum_num: int):
    n = 0
    while n < len(l):
        m = n + 1
        while m < len(l):
            print("{}+{}={}".format(l[n], l[m], l[n] + l[m]))
            if l[n] + l[m] == sum_num:
                return l.index(l[n]), l.index(l[m])
            m += 1
        n += 1


能想到的就是这个方法,但面试官说太复杂了,问我时间复杂度多少,我没有这个概念。

  • 链表的插入,写代码实现

没答上来

  • Dbfaker 分库分表时是否能支持?

自己写的 dbfaker 库,面试官一眼就能看出不能直接支持分库分表。

  • 股票的买卖,已知一支股票连续 N 天的价格,可买卖一次求最大收益组合。
  • 元祖,列表以及字典分别使用了什么数据结构?

只知道元组和列表是用的列表数据结构,字典是映射

  • 使用 map 和 lamba 实现功能,将列表中的奇数乘 2 python map(lamba x: x*2 if % 2 == 1 else x, l)

然后问这个 map 返回是个什么类型,我回答的 list,面试官纠正说是一个迭代器,然后问,如何将这个迭代器转换为 list,我说直接套 list 方法,然后他问,是否可以多次使用 list 来对迭代器操作,回答不能,因为迭代器执行完后,会抛异常。

  • Orm 框架,在 Django 等框架中只需要创建类即可被转换为 ddl 语句,它是怎么实现的?是否了解 Python 的元类?
  • Python 的垃圾回收机制?为何需要分代回收?引用计数为 0 的时候不就可以回收了吗,为何还需要分代?

我回答了引用计数和分代回收,说明了引用计数的原理,但说不出为何需要分代回收;后面看了文档,发现分代回收是为了解决性能上的问题,如果每次都去处理所有对象是否需要回收,就会要处理所有对象,分代后,每次优先去处理新生代的对象,中年代和老年代的回收频次会降低。以达到节省性能的目的。

  • 代码实现字符串转 int

这个题目本身面试官是让我自己写一个转换方法,我理解成转换任意字符串成为 int,然后想着这个只能通过编码来转换了。后面才知道面试官说的是把"123"这种字符串转为 123,我说在 python 中直接用 int 就好了。然后他说写一些测试用例,我写的:

int('1')
int('0')
int('-1')
int('-0')
int('123')
int('2147483647')  # python中的int最大值
int('-2147483647')  # python中的int最小值
int('a123')
int('0x01')
int('\x01')

后记

记得七牛云面试二面最后的时候面试官问我,你觉得你今天答得怎么样,我说答得不怎么好,问题问的比较偏,很细节,很多问题没答上来或没完全答上来;然后面试官说了一句很印象深刻的话:面试过程就是要问到你答不上来为止,才能知道你的水平究竟在何处。

共收到 11 条回复 时间 点赞

楼主几年啊。。期望薪水多少呀

djc-Sherlock 回复

6 年了,期望 20+ 吧。

guolong123 回复

上海

高端的题目

想了半天还是不知道测接口字段唯一性跟幂等有啥关系,字段限制唯一了不就不幂等了么,求后来的解惑

app 卡顿那个是答偏了,用户抱怨说明问题可重现,不需要借助测试手段,问题定位无非是抓包以及看日志,腾讯的 perfdog 可以了解一下。

MarvinWu 回复

我想他想表达的是插入两次返回结果一致的情况下,我说的测试方法就不可行了。问这个情况下应该怎么测试。

guolong123 回复

可能理解错了,面试官想得到的答案是提交重复字段的接口应该得到与上次请求一致的响应,而不是回答的重复插入不了。正好这个帖子被顶了起来https://testerhome.com/articles/29399,对接口的幂等做了一些描述。

MarvinWu 回复

所以当返回一致的情况下,我能想到的只有去数据库中验证了

  1. 对于幂等性,我个人人认为面试官是在说你的这个测试脚本不符合幂等性。你的用例每次运行的结果就应该是一样的,多次运行结果都是一样。而你说的测试方法是运行两次,而结果却不一样,这个是不符合幂等的。
  2. 结合说的幂等性,我觉得用例应该考虑到自己准备测试数据,运行测试,进行验证,然后进行数据清理,这样就能做到幂等性。
  3. 回到说的这个唯一字段的测试,那么结合 2 中说到的这种方法,那么就应该是先自己造一个数据(模拟系统中已有这个数据),那么再次使用接口发送同样的数据,这个时候接口应该返回数据重复的提示,包含一些错误码等等,用例进行验证,最后再清除掉先前造的数据。 以上这个用例就符合幂等性,无论运行多少次,结果都是一样的。

个人意见,仅供参考!

2021/5/6 后记

今天七牛云 HR 跟我电话了,商定了后续入职手续的事情。感觉很意外,也意料之中。面试了 5 家公司最期待的公司面上了还是非常高兴的。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册