面试题(二)
前言
今天的面试有点猝不及防,前面经过一轮技术面,二轮HR面,本来已经到终面了,我以为不会有太多技术性的问题,结果研发老大看到我的简历,更多的是自动化的工作,而他们需要的测试开发,感觉有点不符合,后面他问了我几个问题之后,叫来一个测试开发,问了我如下的一些问题,这些问题里,有的答的比较满意,有的比较潦草。但整体是尽力了,过不过只能听天意了。现简单的将这些问题汇总下,回答是我现场回答,参考答案是我晚上整理的
面试题汇总
你使用python多长时间?
回答:两三年了
Python里的可变数据类型和不可变数据类型有哪些?
回答:
不可变数据类型:整型、字符串、元组;
可变数据类型:列表、字典
参考答案:
不可变数据类型:整型、字符串、元组、浮点型、布尔类型
可变数据类型:列表、字典、集合
Python里如果将可变数据类型作为参数,会发生什么情况?
回答:如果将空列表作为默认参数,那么函数体中向这个列表添加元素,默认参数的值也会发生变化,当你下一次不传参使用默认参数的时候,这个默认的列表已经发生了变化
参考答案:这个题我现场要是给面试官写个函数就好了,其实我想说的是这样的情况:
def f(x, l = []):
for i in range(x):
l.append(i * i)
print(l)
f(2)
f(3, [3, 2, 1])
f(3)
# 运行结果
[0, 1]
[3, 2, 1, 0, 1, 4]
[0, 1, 0, 1, 4]
Python中不可变数据类型一般用在哪些情况?
回答:一般用于数据不改变的情况下,不会新增元素或删除元素,比如元组,我在实际中使用的时候,一般会存一些连接mysql的数据,比如host、port、user、password等
迭代器有用过吗?
回答:说到迭代器,就要提一下迭代器和可迭代对象,迭代器是实现了__iter__方法和__next__方法的函数,可迭代对象是实现了__iter__方法的函数,这个__iter__方法在可迭代对象中是指返回的迭代器对象,在迭代器中是指迭代器对象本身,也就是self。python中返回迭代器的方法有map和zip。然后为了不显示我没用过迭代器的尴尬,我说项目中使用过生成器,生成迭代器,主要是UI自动化中,使用yield返回driver,然后执行测试用例,用例执行完再做一些关闭app、环境清理的工作
参考答案:这里的含义解释有点混淆,应该是__iter__方法在可迭代对象中返回的是迭代器对象,在迭代器中返回的是迭代器对象本身,也就是self
深拷贝和浅拷贝有什么区别?
回答:深拷贝、浅拷贝可以和直接赋值做一个对比,...解释了一通,找面试官要了笔,画了一个a = [1, 2, 3, [4, 5, 6]]
,然后b = a, c = a,a变化,b和c都变化,然后解释浅拷贝就是父对象独立,子对象指向原对象的引用,所以向a中的内部的列表插入一个7,向外部的列表插入一个8,那么只有父对象不变,子对象变了,深拷贝是父对象和子对象都独立,所以都应该不变
装饰器用过没?
回答:为了掩饰我的尴尬,我说装饰器很少用,就是使用allure的时候加一些注解,然后我开始解释闭包,闭包是外部函数调用完,发现内部函数还在用它的变量(我当时口误说成了属性,尴),这时候Python的垃圾回收机制不会收回这块的内存,将变量继续给内部函数使用
参考答案:https://www.zhihu.com/question/26930016
了解Python的垃圾回收机制吗?
回答:了解一点,垃圾回收就是指引用计数为0的时候,Python会回收这块的内存,当然还有一种情况,是指相互引用,这时候Python也会找到这种相互引用的情况,将它们回收掉
参考答案:https://www.jianshu.com/p/1e375fb40506
继续问:Python在什么时候触发引用计数呢?
不知道怎么答了
补充:2022-07-18
导致引用计数+1的情况
对象被创建:a = 1
对象被引用:b = a
对象被作为参数,传入到函数中:func(a)
对象作为元素,存储在容器中:list1 = (a, a)
导致引用计数-1的情况
对象的别名被显式销毁:del a
对象的别名被赋予新的对象:a = 24
一个对象离开它的作用域,例如函数执行完毕,函数中的局部变量(全局变量不会)
对象所在的容器被销毁,或从容器中删除对象
了解多态吗?
回答:多态举个例子,就是爸爸有一些属性方法,儿子继承了爸爸的属性方法,可以使用super或者Father.__init__来继承。当然儿子也可以自定义自己的属性和方法。当时还顺便撤了下__init__和__new__的区别,我说很多人都是__init__是实例化对象方法,其实不是,__new__才是,__init__只是初始化方法
解释下接口自动化用例怎么读取数据?
回答:用笔给面试官画了一下Excel中存储数据的情况,比如第一行是case_id, description, method, url, request_data, request_context, response_content, expect...,还解释了一下为什么要采用合并单元格的形式,说有的场景是多个接口关联起来的,比较复杂,如果一行使用一个接口的话,关联起来就比较复杂不直观,所以使用合并单元格的形式,多个接口合并成一个单元格作为一个用例,然后读取的时候使用merge_cells可以得到合并单元格的范围,再将merge_cells的范围和max_rows求差集,这时候使用的是set.diff的方法,然后分别将合并单元格的字典和非合并单元格的字段都装在一个列表中,但这时候顺序乱了,得用sorted的方法排序,其实那一瞬间我还记得要用key=lambda,但是现场突然紧张了一下,突然忘了,一直在那比划给all_case_data排序,然后就忘了lambda...后面又提了ddt解包,然后for循环遍历
参考答案:我想说的其实是这种,其实在塞到列表中的时候,是字典的形式的时候,就应该使用sorted排序
#获取非合并行数据
for row in max_row_range:
case_data = []
for column in range(1, max_column + 1):
value = [self.sh.cell(row, column).value]
case_data.append(value)
all_case_data.append(dict(zip(title, case_data)))
#排序:根据case_id的数字从大到小
all_case_data = sorted(all_case_data, key=lambda case_data: case_data["case_id"][0])
set.difference求差集和list求差集有什么区别?
回答:我当时一愣,说你让我求差集,我也可以用list求差集。然后面试官告诉我,list是用for循环,我突然想起来了,也不知道对不对,当时说,set内部是HashMap实现的,因此查询速度比list要快
@staticmethod和@classmethod有什么区别?
回答:我可以比较一下实例方法,类方法和静态方法,实例方法只有对象能用,类方法和静态方法类和对象都能用,静态方法和类只是一个附属关系,但一般很少用到类的属性和方法,比如我要定义一个静态方法,打印当前时间,我不需要类给我提供其他东西
参考答案:https://blog.csdn.net/handsomekang/article/details/9615239
@property用过没?
回答:没
参考答案:https://www.liaoxuefeng.com/wiki/897692888725344/923030547069856
多线程、多进程和协程都用过哪些?
回答:Python中的多线程很少用,因为由于全局解释器锁的作用,多线程并不是真正的多线程。多进程有用过,主要是在UI自动化兼容性测试中,使用multiprocess模块开启多个进程,将实例化driver需要的设备信息放在列表里,通过在conftest里定义pytest的addoption的方法,将这些命令行参数拿到传递给实例化driver的方法。还提了一下,多线程不太消耗系统资源,多进程比较消耗资源。协程只提了一句,只知道它比线程的粒度还小,但没用过
参考答案:回来的路上,想了下,其实还可以补充:线程是系统调度的最小单位,进度是系统资源的最小单位,多线程共享同一进程的资源,因此线程间通信比较方便,多进程由于是各有各的资源空间,因此相互通信得借助工具。此外,多线程是各自依赖的,一个线程挂了会影响其他线程,多进程是各自独立的,不会受影响。还可以再提下_thread模块和threading,thread模块比较麻烦,线程同步的时候要加锁,线程结束的时候要解锁,threading是_thread的高级版,线程同步一个join()方法搞定
使用过哪些测试开发的框架?
回答:Flask,除此之外,还有自动化测试的框架,selenium, appium, pytest, unittest等等
使用过docker的xx没?
回答:我当时没听清楚,但是确定我没使用过,就说docker对我来说就是拉个镜像,创建容器,启动运行容器,这些内容。面试官说,哦,那可能是运维比较常用
Flask怎么部署服务?
回答:我在本地部署的,使用的是批处理命令。其实我工作中使用Flask封装Mysql查询接口,还是前几天刚刚学到的,工作中根本没用。。
使用Flask封装MySQL查询接口的时候用的是SQLite吗?
回答:不是,因为当时我只需要读取MySQL的数据,使用的是PyMySQL的fetchone, fetchall, fetchmany等方法,不需要ORM映射