如何面试软件测试工程师

一、开场白

1. 自我介绍

2. 项目经历

注意使用STAR法则表述进行表述:背景、过程、方式(你担任的角色)、成果

二、软件测试基础

工作内容

结合项目细聊工作内容

测试方法

  • 怎么测试一个接口
  • 软件测试方法?
  • 黑盒测试和白盒测试
  • 1990.01到2020.12等价类划分怎么设计测试用例
  • 正则表达式的匹配
    匹配一行空格?匹配数字、字母,出现的次数随机?
  • 异常 常见的异常?
  • 目前主要的防御方式,注入型的漏洞具体怎么解决
  • SQL注入
  • 接口自动化分层设计浅谈

测试文档

自动化测试

测试工具

  • 用过哪些测试工具
    postman、jmeter、fiddler、java+testNG框架

性能测试

梳理明确压测的目的和步骤:

  • 首先我们得知道一个实例在当前线上的硬件条件下的性能表现的极限是多少,即满足99线以及SLA的条件下,能到达的峰值TPS
  • 我们的目标值是多少,即在99线为多少的时候,SLA应该在1.0附近,TPS是多少(每秒处理的请求数)(一个实例)

如何定位问题以及优化

游戏测试

三、软件测试实战

排查问题的思路

  • 缓存击穿的原因
  • 访问一个页面响应慢,是什么原因?
  • 怎么判断前端还是后端问题
    前端bug:界面显示、字段校验、兼容性【浏览器的解析不一致】
    前端bug分为3类:HTML、CSS、Javascript
    区别方法:
样式问题 CSS
文本问题 HTML
交互类问题 Javascript

前端bug定位:F12在console中查看报错信息,对于出错的js可以在Sources下查看对应报错的资源文件

后台bug:逻辑【数据相关、排序错误】、性能和安全性有关
页面功能实现-谷歌浏览器F12开发者工具Network一栏

  1. 请求URL是否正确,错误-前端bug
  2. 请求参数是否正确,错误-前端bug
  3. 接口URL和参数都正确,响应内容错误,后台bug
  • 一个button, 点击后两种情况 1.没反应 2.跳转报错, 怎么查找是前端还是后端的错误
  • 在项目中,A依赖B的模块,但是中间出现问题,你怎么解决?

实战案例

功能/安全/兼容/性能/易用/外观

  • 一个产品在1.0版本的基础上进行了一次迭代,现在将它交给你进行测试,如何入手
  • a/b
  • 加入购物车-购物车-结算
  • 支付功能
  • 余额宝
  • 微信视频
  • 电梯
  • 饮料售卖机
  • 水杯
  • app中分享抢红包
  • 移动单车扫码
  • 有一个带logo的纸杯,怎么对它进行测试。(给提示,比如说杯子的材料,耐热耐冷,杯子的气味,材料;极限的测试,最高最低多少度,装入的液体是否会与纸杯发生化学反应)
  • 圆形下水井盖相对于方形的优势是?
    在同等用材的情况下他的面积最大
    如果是方的、长方的或椭圆的,那无聊之徒拎起来它就可以直接扔进地下道啦!但圆形的盖子嘛,就可以避免这种情况了

四、语言基础

Java

  • ArrayList 和 LinkedList 的区别
    1、数据结构不同
    ArrayList是Array(动态数组)的数据结构,LinkedList是Link(链表)的数据结构。
    2、效率不同
    当随机访问List(get和set操作)时,ArrayList比LinkedList的效率更高,因为LinkedList是线性的数据存储方式,所以需要移动指针从前往后依次查找。
    当对数据进行增加和删除的操作(add和remove操作)时,LinkedList比ArrayList的效率更高,因为ArrayList是数组,所以在其中进行增删操作时,会对操作点之后所有数据的下标索引造成影响,需要进行数据的移动。
    3、自由性不同
    ArrayList自由性较低,因为它需要手动的设置固定大小的容量,但是它的使用比较方便,只需要创建,然后添加数据,通过调用下标进行使用;而LinkedList自由性较高,能够动态的随数据量的变化而变化,但是它不便于使用。
    4、主要控件开销不同
    ArrayList主要控件开销在于需要在lList列表预留一定空间;而LinkList主要控件开销在于需要存储结点信息以及结点指针信息。
  • List、Set、Map的区别
  • 封装 继承 多态 面向对象三要素的理解
  • map 与 hashmap 的区别
  • hashmap底层
  • Jenkins会用吗 容器
  • JVM运行时区域
  • HashCode怎么计算(考虑哪些东西)
  • HashCode的作用(映射)
  • 内存泄漏
  • 描述一下JAVA的反射机制 为什么JAVA能实现反射C++不能
  • 描述一下生产者和消费者的模式 多线程和单线程在代码上的主要的区别
  • java八大基础类型
    byte short int long floate double char boolean
  • Java内存分为哪些部分
  • static关键字的作用
  • final关键字的作用
  • 反射的定义
  • gc机制 会马上执行嘛?可以手动?
  • 垃圾回收机制
  • ==和equals的区别

Python

  • is和==的区别
is 比较的是两个对象的id值是否相等,也就是比较俩对象是否为同一个实例对象,是否指向同一个内存地址
== 比较的是两个对象的内容是否相等,默认会调用对象的__eq__()方法
  • python中的面向对象的特性(封装继承多态)
    封装
    封装有两个方面的含义:把该隐藏的隐藏起来,把该暴露的暴露出来
    只要将 Python 类的成员命名为以双下画线开头的,Python 就会把它们隐藏起来
    继承
    class 类名(父类1, 父类2, …):按照顺序优先级,同名函数,顺序优先
    多态
    当同一个变量在调用同一个方法时,完全可能呈现出多种行为(具体呈现出哪种行为由该变量所引用的对象来决定)

  • python中的列表常用方法

  1. list.append(obj) 在列表末尾添加新的对象。一次性只能添加一个元素
 >>> name = list("scott")
 >>> name
 ['s', 'c', 'o', 't', 't']
 >>> name.append(list(" tiger"))
 >>> name
 ['s', 'c', 'o', 't', 't', [' ', 't', 'i', 'g', 'e', 'r']]
  1. list.count(obj) 统计某个元素在列表中出现的次数
>>> name = list("scott")
>>> name
['s', 'c', 'o', 't', 't']
>>> name.count('s')
1
>>> name.count("t")
2
>>> name.count("A")
0
>>> name.append(list("Python"))
>>> name
['s', 'c', 'o', 't', 't', ['P', 'y', 't', 'h', 'o', 'n']]
>>> name.count(['P', 'y', 't', 'h', 'o', 'n'])
1
  1. list.extend(seq) 在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
 >>> name = list("scott")
 >>> name
 ['s', 'c', 'o', 't', 't']
 >>> name.extend(list(" tiger"))
 >>> name
 ['s', 'c', 'o', 't', 't', ' ', 't', 'i', 'g', 'e', 'r']
  1. list.index(obj) 从列表中找出某个值第一个匹配项的索引位置
>>> name = list("scott")
>>> name
['s', 'c', 'o', 't', 't']
>>> name.index('t')    ##第一个字母t的索引位置是3
3   
>>> name.index('a')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: list.index(x): x not in list
>>> 'a' in name
False
>>> 'a' not in name
True
  1. list.insert(index, obj) 将对象插入列表,俩参数,第一个是索引位置,第二个插入的元素对象
 >>> name = list("scott")
 >>> name
 ['s', 'c', 'o', 't', 't']
 >>> name.insert(2,'tiger')     ##在索引为2的地方插入字符串tiger  
 >>> name
 ['s', 'c', 'tiger', 'o', 't', 't']
  1. list.pop([index=-1]) 移除列表的一个元素(默认最后一个),并返回元素值
>>> name = list("scott")
>>> name
['s', 'c', 'o', 't', 't']
>>> name.pop()
't'
>>> name
['s', 'c', 'o', 't']
>>> name.append("t")
>>> name
['s', 'c', 'o', 't', 't']
  1. list.remove(obj) 移除列表某个值的一个匹配项。如果有俩个相等的元素,就只是移除匹配的一个元素,如果某元素不存在某列表中,便会报错,而且一次性只能移除一个元素
>>> name = list("scott")
>>> name
['s', 'c', 'o', 't', 't']
>>> name.remove("t")    #去掉第一个t
>>> name
['s', 'c', 'o', 't']
>>> name.remove("A")    #不存在会报错
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: list.remove(x): x not in list
>>> "A" not in name
True
>>> name.remove("s","c")  #一次只能移除一个元素
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: remove() takes exactly one argument (2 given)
  1. list.reverse() 反向列表中元素
 >>> name = list("scott")
 >>> name
 ['s', 'c', 'o', 't', 't']
 >>> name.reverse()
 >>> name
 ['t', 't', 'o', 'c', 's']
  1. list.sort( key=None, reverse=False) 对列表进行排序,修改原列表,不会返回一个已排序的列表副本
 >>> result = [8,5,5,3,9]
 >>> result.sort()
 >>> result
 [3, 5, 5, 8, 9]

如果我们想要返回一个已排序的列表副本,而不影响原来的列表呢,一种方法,我们可以先复制原来列表(可以用分片赋值复制),然后在复制的列表上做sort操作,另一种方法,就是使用sorted函数,它会返回已排序的列表副本:

 >>> result = [8,5,5,3,9]
 >>> result2 = sorted(result)
 >>> result
 [8, 5, 5, 3, 9]
 >>> result2
 [3, 5, 5, 8, 9]
  1. list.clear() 清空列表
  2. list.copy() 复制列表
  • python中深拷贝浅拷贝的区别
    首先深拷贝和浅拷贝都是对象的拷贝,都会生成一个看起来相同的对象,他们本质的区别是拷贝出来的对象的地址是否和原对象一样,也就是地址的复制还是值的复制的区别
    深拷贝就是完全跟以前就没有任何关系了,原来的对象怎么改都不会影响当前对象

浅拷贝,原对象的list元素改变的话会改变当前对象,如果当前对象中list元素改变了,也同样会影响原对象。
python中的深拷贝和浅拷贝
Python 直接赋值、浅拷贝和深度拷贝解析

  • 重载
<
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值