| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 开发测试 -> 软件测试面试题 -> 正文阅读 |
|
[开发测试]软件测试面试题 |
性能测试面试题 不错的性能测试博客 https://www.cnblogs.com/zhongyehai/p/10327725.html
公司压测主要是针对公司的投保流程接口做压测,包括核心接口试算,核保,承保。 1.首先是确定压测目标,指标是TPS1200,响应时间小于1S,内存使用率小于百分之八十,cpu使用率小于百分之八十。 2.编写性能测试脚本,调试通过 3.使用命令监控操作系统服务器,数据库服务器 4.压测逐渐加压直到到瓶颈,单接口场景压测,混合场景压测,稳定性测试 5.查看监控数据,包括线程状态等,分析性能瓶颈。 6.开发调优,达到目标 7.总结本次压测过程,结果,生成性能测试报告,供领导和组内成员参考
这个原因比较多,压测整个链路上任何一个环节有瓶颈或者问题都有可能导致
Cpu过高分两种情况,一种是响应时间很短TPS很大,说明是正常现象,不需要优化,另一种是响应时间很长,TPS很低,性能不好需要优化 一般cpu过高有下面几种原因:
定位分析过程:
使用top命令进行排序查找出占用cpu最高的java进程
使用top-H –p<pid>查看线程占用情况
将线程id转换成16进制 #printf %x15664 3d30 ?? 使用jstack命令查询线程堆栈信息,定位到代码级别 ?? Jstack<pid>|grep –a 线程id??
一般响应时间过长有下面几个原因:
分析方法:使用jprofiler工具去统计每个方法耗费时间定位到代码级别
参考文章:https://www.cnblogs.com/zhongyehai/p/10322088.html 通过jvisualvm或者jstack,进行线程dump,对线程状态进行分析,获取到哪行代码导致的死锁 Jstack可以查看堆栈信息,把堆栈日志打印到log文件,去查看 现象:出现死锁,tps将为0,压测工具得不到服务器响应,服务器硬件资源空闲,通过jvisualvm,至少两个线程一直处于红色阻塞。 解锁办法:重启tomcat 解决思路:避免嵌套加锁 ????????? 减小锁粒度,锁越少越不容易发生死锁 阻塞问题一般是log4j日志打印问题可以导致,需要提升日志级别,减少不必要日志输出。换成log4j2框架 线程问题排查流程:
Prometheus+grafana可以监控数据库,redis,主要监控数据库连接数,cpu各项指标,数据库线程情况等 也可以自己连接数据库服务器去监控cpu硬件资源 首先要知道什么是慢查询,就是mysql可以配置指定一个查询时间,超过这个时间的就叫慢查询。 Mysql自带的慢查询工具mysqldumpslow可以分析慢查询日志。 主要包括 Sql出现次数 执行最长时间 累计耗费总时间 等待锁的时间 扫描总行数 一般sql或者数据库有问题都可以看到数据库占的cpu最高,从而去分析数据库方面问题主要就是sql 这条语句是显示耗费时间最长的50个sql 这个时候用explain去分析这条语句,看type类型去判断有没有加索引。 参考博客:https://www.cnblogs.com/zhongyehai/p/10328438.html
线上压测最大问题就是测试数据不能影响正常生产数据,做好数据隔离,主要包括有两种方式,一是按照一定规则和正常数据区别,比如正常账号都是纯数字的,然后你们压测就造一批有字母的。压测结束之后由dba统一清理。 第二种时在数据库中创建和生产一样的影子表,压测请求入参加标识,数据库中间件识别出来存入影子表,结束后清空影子表 为了最大程度减少对生产的影响,一般线上压测可以在晚上12点到早上6点进行。
压测过程中发现有不少线程阻塞现象,通过jvisualvm去分析dump文件,dump文件可以用命令生成,定位分析到代码级别发现是log4j打印日志导致。 优化方案:减少不必要日志输出,提升日志级别,但是这些都比较固定,不好改变,最后是更换成了跟它类似的但是性能更好的组件log4j2去解决,大大提升了性能
我们是微服务架构,每个服务都是两台服务器,4核8G(核保,承保,esg)或者8核8G(gateway,试算),生产是测试环境的4倍,所以我们测试环境一般压测目标是1200TPS,测试达到这个值的话,生产就完全没问题。
我们测试环境一般压测目标是1200TPS,测试达到这个值的话,生产就完全没问题,生产环境服务器配置数量是测试环境的4倍
Cpu:top 内存:free 磁盘:iostat 网络:netstat 同时查看四个可以用vmstat或者dstat 也可以用可视化工具nmon等
主要是单一接口测试和混合场景测试 单一接口测试就是只压测试算,和核保接口 混合场景就是整个出单投保流程 除此之外还会针对混合场景做稳定性测试,几个小时长时间进行压测
这个问题相对开放,什么都可以回答 比如回答哪些接口需要进行压测,如何确定压测目标TPS,一般是比较核心重要的接口做压力测试。 如何确定目标TPS,去测试小牛进阶公众号,写过一篇文章,详细进行了介绍。 性能测试指标如何确定都可以
TPS确定参考小牛测试进阶公众号文章 响应时间一般在几百ms级别 Cpu:小于百分之八十 内存:小于百分之八十
一般表关系复杂 优点:数据完整性比较好
表关系简单,6数量少,不适合复杂的数据结构 优点速度快 存储过程流程:
接口自动化面试题
公司主要将保险投保流程做成了自动化,核心接口是试算核保承保三个接口,可以实现不同渠道不同产品自动出单,除此之外,还将我们部门的其它接口比如签约绑卡等等做了自动化,主要用来进行回归测试。 Requests????? 发起接口请求 Unnitest框架? 主要用来管理测试用例 ddt?????????? 数据驱动 openpyxl????? 用来读取excel logging?????? 用来打印执行日志 htmltestrunner? 生成测试报告 pymysql?????? 操作数据库 除此之外,还集成了jenkins,自动定时构建,并自动发送邮件等功能。 ?? 做法是在excel中写入试算,核保,承保ini文件路径地址,也可以传核心入参,断言期望结果。然后在对应的ini文件里面写请求接口地址, ?? 请求报文,读取数据库操作,断言读取等等
因为公司业务比较复杂,每个部门情况都不太一样,所以我们公司都是每个部门各自来决定搭建维护自己的自动化框架。这样更加符合部门业务场景,使用起来更加高效。 我们部门因为有续保场景,就是用户买了保险,第二年到期后要进行续保。做的时候就需要先执行完一个测试用例,再去执行第二个,比较复杂,而不是简单单接口调用,自己定制更加灵活。
每天都会运行一次,从而监控是否有因开发代码变更或者新功能添加而导致的遗漏的bug 1.开发有时候会修改一些公共代码和底层代码,影响未评估完全,影响到一些其它接口,需要发版前全部跑一遍,之前就有一个文件上传接口,改了底层代码,没测出来,自动化测试用例执行报错,分析接口返回发现的 2.下游有时候会改动加一些接口校验之类的,但是没有通知我们,这时候跑自动化就可以及时发现,比如之前有个退保接口,下游加了证件有效期校验,导致跑不通,下游系统和接口比较多,这时候自动化可以发现问题,并及时去评估到相关影响。 做自动化之前全部回归一遍接口需要2-3人日,而且还覆盖不全都是回归核心接口核心功能,也出现过回归不到导致生产问题,自动化只需要一个小时就可以回归一遍,覆盖更全,大大提升了效率,节约了人力。
参考问题5答案,也可以从这方面去回答 其它问题都是代码层面问题比较多,比如unittest生成报告,加载测试套件用例获取不到,原因是路径传错问题等等,一般是通过百度绝大部分都能解决。
最难的难点还是测试框架执行不够稳定上面,比如某几条测试用例执行失败了,但是拿出来在本地跑发现却可以跑通,可能是环境问题或者下游在部署导致。 针对这个问题主要从两方面去解决,一个是执行时间,可以在半夜去定时执行用例,相对来说比较稳定。 第二是增加重试机制,失败的用例重试5次,看能否执行成功,排除环境干扰原因
主要是通过配置定时自动构建,跑测试用例,自动发送邮件到相关测试人员邮箱,每天晚上自动跑自动化,上线前或者重大改动也会手动构建去看执行结果。
目前四五百条测试用例,执行时间一个多小时,在可以接受范围内,之后可以尝试使用多线程去并行执行测试用例,缩短执行时间。
Testcase:unnitest,ddt,excel操作函数 Testdata:excel数据 Transaction:ini文件数据请求地址报文等等 http:接口请求 Db:数据库操作 Logging:日志处理 Output:输出报告 Common:工具类,加密方法,数据替换,接口关联处理等等 Config:环境地址,数据库连接方式密码等等
这种工具包括一些开源框架最大的缺点就是不够灵活,如果是单接口的接口自动化还好处理,但是一旦系统复杂起来,这些工具和开源的就不好用了,比如我们有续保场景,首先是建立在新保的基础上的,然后新保变成续保还需要改数据,进行大量数据库操作,包括执行存储过程,抽档一系列操作,比较复杂,其它平台就不太好用。
我主要负责数据库校验部分,excel读取数据,日志打印相关模块,除此之外还写了很多自动化测试用例,我们总共三人参与,有一个资深外加一个外包。外包负责编写用例更多,资深负责架构方面多一些。共享代码包括测试用例数据主要通过svn共享,右键team,提交即可。每次写代码之前要先update一下保证是最新代码和数据。
数据驱动主要是使用unittest结合ddt框架实现,ddt主要是减少代码重复,比如一个接口有很多测试用例,但区别是不同入参不一样,断言等都类似,比如一些必填项校验之类的,这时候可以用ddt,把数据都读取出来,传入data即可 还有数据驱动就是采用了excel读取测试用例的方式将数据和代码进行分离 做法是在excel中写入试算,核保,承保ini文件路径地址,也可以传核心入参,断言期望结果。然后在对应的ini文件里面写请求接口地址,请求报文,读取数据库操作,断言读取等等
大概覆盖了百分之六十到七十左右,这个主要使用第三方工具来进行统计的,使用jacoco+ant可以进行统计 Jacoco是一个开源的覆盖率工具,通过插桩方式来记录代码执行轨迹。 Ant是java生成工具,类似于unix中的make工具,都是用来编译生成ant运行时需要一个xml文件(构建文件) 流程:
总共500条左右测试用例,执行一次一个小时左右,总共覆盖了五十多个接口,核心出单接口十几个。
提取上一个接口的返回值,设置为全局变量,下一个接口调用这个全局变量。 提取上一个接口返回值使用的是jsonpath处理的。 全局变量的实现是:定义一个全局变量envdata,通过setattr函数将提取到的结果,动态设置为envdata的类属性。 然后读取到ini文件中的请求报文,使用正则替换请求当中特定变量名,变量名使用#变量名#表示要被替换的 Class person: ?? Envadata=12 Setattr(person,’age’,40)
我们接口自动化并没有使用到鉴权之类的,因为不需要记录用户状态,不像登陆之类的接口。 不过这个我有了解过,接口鉴权主要是cookie,sesson机制来处理的,比如登陆接口服务器会生成一个cookie,返回给客户端,客户端再次访问其它接口的时候就需要带上这个cookie才能访问成功,这个期间还会生成session,主要保存在服务端和cookie相匹配。Requests库里面有专门的session类来进行处理。 除此之外还有token,就是令牌跟cookie机制差不多,都是一个接口生成之后,下一个接口访问需要带上token
数据参数化主要是ini文件入参一些字段可以进行替换,excel中传入实际字段值被替换对象用#参数#表示,然后使用正则替换请求当中的变量名。 数据驱动主要是使用unittest结合ddt框架实现,ddt主要是减少代码重复,比如一个接口有很多测试用例,但区别是不同入参不一样,断言等都类似,比如一些必填项校验之类的,这时候可以用ddt,把数据都读取出来,传入data即可 还有数据驱动就是采用了excel读取测试用例的方式将数据和代码进行分离 做法是在excel中写入试算,核保,承保ini文件路径地址,也可以传核心入参,断言期望结果。然后在对应的ini文件里面写请求接口地址, ?? 请求报文,读取数据库操作,断言读取等等
主要是断言的时候检查用的,还有就是需要查询,修改数据
2.新保改续保单子需要改单子生效日期,进行跑job抽挡等操作,最后一步需要将一张表一个字段状态01改为06
其实就是问Get和Post区别,比较基础不再赘述。
Requests和unittest库logging库等等 # # def quickSort(lst): # if len(lst) <= 1: # return lst # # 以第一个数 # left = [l for l in lst[1:] if l<=lst[0]] # right = [r for r in lst[1:] if r>lst[0]] # return quickSort(left) + [lst[0]] + quickSort(right) # # lists = [4, 6, 9, 1, 8, 7, 2, 5, 4, 0] # print("\r\n排序前: %s\r\n" % lists) # print("排序后: %s" % quickSort(lists)) # #冒泡 # a=[2,4,1,1,1] # b=len(a) # 控制交换趟数 # for i in range(b-1): # 控制每趟交换次数 # for j in range(b-1-i): # if(a[j]>a[j+1]): # c=a[j+1] # a[j+1]=a[j] # a[j]=c # for k in a: # print(k) # # m = 11
1.退保,保单状态变更,保全系统发mq通知我们,我们表里面状态变化之后会回传渠道,会出现未回传,或者回传失败情况,去微服务查看日志,调渠道接口报空指针,调用esg异常等。 2.核保调下游接口,除了上游传过来的字段,自己系统要去apollo读取配置字段,比如通过数字区分渠道来源,或者自己包装一些字段传给下游,有时候会出现漏传这种情况,下游拿不到就报错了定,位一般是去看调下游系统报文日志。 2.用例设计
通用答案从以下方面来回答: ?? 功能测试 ?? 从使用功能上面出发 ?? Ui测试
安全测试 输入用户名或者密码或者评论内容是否以加密的形式传给服务器 是否有sql注入等情况 是否能用脚本恶意抢红包 兼容性测试 不同浏览器,不同手机机型测试是否功能正常 网络测试: 弱网,无网情况下功能怎么样,是否会有相关提示。 性能测试: 对相关接口做压力测试,关注服务器硬件资源,以及监控数据库包括中间件等等看有没有性能瓶颈 发红包,或者评论或者登陆看下需要多长时间,越短越好 大用户并发同时操作的时候功能是否还正常 ?? 接口测试: ?? 入参每一个字段校验情况,和下游系统联调,数据库落库情况,看日志等等 中间件面试题
正向代理代理的是客户端,比如我们访问谷歌访问不到,通过一个代理就可以访问到。 反向代理代理的是服务器,比如nginx这种,转发请求给到服务器
保单状态变更,比如退保,下游部门保全会给我们发mq,我们收到mq时,我们自己的表状态就会变更。报文内容就是一些保单信息包括保单状态。 电子保单下载接口,生成电子保单,下游契约也会给我们发mq。 一般比如说,我们表状态过了很久,发现没有变排查会怀疑mq的问题,这时候一般关注看对方有没有发mq,然后再看我们有没有收到,发mq是通过平台查mq,有没有收到可以看日志。
? 缺点,增加了系统复杂性,比如消息队列挂了,然后就出问题了 ??????? 比如消息队列需要考虑发送消息的可靠性以及避免消息是否重复消费,这些都是引入mq才有的问题 ?????? Rocketmq是阿里出品的,java语言,修改源码的话,可以做一些定制开发。
高并发:一旦涉及大数据量需求,比如一些商品抢购等,或者主页瞬间访问量大的时候,磁盘读写上千上万次,有性能弊端。容易造成数据库瘫痪,服务器宕机。数据库顶不住,需要缓存分担一部分压力。Redis基于内存的读写速度更快 高性能:有一个请求查询数据库600ms,但是接下来几个小时都不变了,这时候就可以放缓存数据库,可能查一下2ms。 主要用在一些复杂操作,后面不变,且有很多请求时,直接放入缓存读缓存即可 弊端容易引起雪崩,击穿,穿透等问题。 五种数据类型: 字符串,哈希,列表,集合,有序集合 不会单独对redis这个中间件测试,主要还是放到业务代码中结合业务来测试。比如我们有个银行签约场景,我们和银行签约会请求我们下游保全,保全会生成协议号,并存到我们表中。下一次再签约查询的是时候就会把协议号存入redis中,而且有时间限制,只有这个时间段内才会从缓存中取数据返回。这个是在apollo上面配置的,所以测试点就需要去redis拿key去查,看是否存储成功,改缓存数据,看是不是取的缓存,还有就是测试到一定时间,缓存数据是否消失。 1.签约查询结果存入缓存redis 2.并将商品信息写入缓存,关键字*baseIpoCommodityInfo*; 3.将赠险起赠份数信息写入缓存,关键字*stock* 4.将赠险份数信息写入缓存,关键字cmdy_stock:{activity}:{treeCode}:{field},cmdy_stock:default:AM000000085
雪崩:比如数据库和缓存一起可以抗住每秒5千请求,缓存抗4千,但是缓存发生宕机意外挂了,这时所有请求都会打在数据库上,数据库就挂了,dba重启,还会接着挂,这就是雪崩机制。 解决方案:发生之前:就设置主从加哨兵机制,不让它发生这件事,高可用。 ????????? 发生了话:要限流,重启dba时先快速加载数据从磁盘到缓存,减轻数据库压力。 缓存穿透主要是黑客恶意攻击,比如缓存idkey都是大于1的,黑客发来的请求都是负数id,直接打到数据库,可能搞挂 解决方案:缓存中查不到就设置这个key为空值unknown放到缓存中,这样相同的key来访问,就会从缓存中读取数据 击穿:某个key访问频率非常高,突然失效就会打到数据库,就击穿了缓存。 设置为一些热点数据设置为永不过期 1.查询时元祖比列表更快 创建一个元祖比列表快很多 ipython模块中有函数timeit timeit list[1,2,3]可以计算创建时间,还可以计算函数执行时间 2.列表在内存中存数据会进行扩容,存的越多分配内存越多,元组不可变的内存不能变,元祖占用内存比列表小 同时存50条数据元祖占内存少 3.元祖性能更好,能选择元祖一定要用元祖,比如不可变,只是需要查询 4.命名元祖使用namedtuple可以按照键值对可以存数据 集合是可变类型的数据集合字典是无序的 字典的底层是key放在一个列表里面,所有的值放在一个列表里面,存储是哈希散列 数据类型:数值 1 ????????? 序列:字符串,列表,元祖 ????????? 散列:字典集合,内部是无序的 可变和不可变就是可hash,不可hash 不可变才可以进行hash操作 集合只能存储不可变类型,不能放列表字典 集合用的最多的就是对列表去重 字典最耗费内存,其次是集合,其次是列表,最后是元祖 查找元素最快是集合然后是字典,然后是元祖然后是列表 集合使用不方便,知道元素才好查 二.推导是 列表退到死 字典退到死 生成器表达式 退到死可以快速帮我们创建列表和字典 比如快速生成一个列表 Urls=[i for i in range(1,100)] 字典 Urls={i:i+1 for i in range(1,100)}\ b=(i for i in range(1,100))出来结果不是元祖是生成器对象 生成器就是一个计算规则,生成器对象可以转列表 a=next(b) 打印a 为1,再next往后走,生成器都被取出来最后一个元素再去取会报错,提升性能 Yield只能用在函数里面,通过这个可以定义生成器对象 Yield 100 Yield 1001 Yield 1002 通过next往后取 迭代器比生成器范围更广,只要可以next取值的都可叫迭代器 迭代器协议 可迭代对象 列表可以for循环就是一个可迭代对象,可以for循环遍历的都是,列表不是迭代器,不能next去取值,内部只实现了iter方法 生成器是迭代器的一种??????????????????????????????????????????????????? 可以通过iter进行转换,可迭代对象变成迭代器,列表放进去就成了迭代器,可以next取值 迭代器内部实现了next和iter方法 生成器相比迭代器多了几种方法 迭代器type是列表迭代器 生成器type是生成器 生成器比迭代器多了send方法,还有close,throw方法 Send方法与生成器交互 可以理解为生成器是子类,迭代器是父类 生成器在遇到很大数据读取存储的时候,把它存到生成器存起来可以节约内存 Send方法用来与生成器进行交互,可以往生成器里面传数据 递归函数 函数自身调用自身,但是一定要加结束条件 Def Fun(): Print(“1111“) Fun() Fun() 递归能实现的循环都可以实现 纯函数返回结果,只跟传入参数有关,不能引用外部变量,受外部变量影响的都不是纯函数 内置函数中有很多类不是函数,比如str() 内置函数只跟传入参数有关,内置函数除了那些不是函数的都是纯函数,没有副作用 匿名函数适用场景:简单的函数定义(只有一个表达私) 用在filter函数 Res=Lambda a,b :a+b Print(res(11,12)) 偏函数可以用来原函数的部分参数,从而调用时更加简单 递归最大限制1000次,解释器默认的 闭包需要满足三个条件 1.函数中嵌套函数 2.外层函数返回内存嵌套函数 3.内存嵌套函数有引用外层的一个非全局变量 用途:实现数据的锁定,提高稳定性 装饰器就是闭包的一个使用 装饰器作用,在不改变原功能函数内部代码,并且不改变调用方法的情况下为原函数增加新的功能 装饰器的应用场景 登陆验证 函数运行时间统计 执行函数之前做准备工作 执行函数之后做清理工作 装饰器可以装饰类 必须写return装饰函数不一定要写 装饰器不仅用函数(闭包)实现还可以用类实现 还可以多个装饰器装饰同一个函数 一个函数被多个装饰器装饰从下往上装饰,从上往下执行 被classmethod装饰之后该方法就是一个类方法 静态方法,实例和类都可以调用 内置装饰器 Classmethod Staticmethod静态方法实例和类都可以调用 Property这个装饰器装饰完之后,该方法可像属性一样被调用 魔术方法 Python中双下划线开头,双下划线结尾的都是魔术方法,自己不要去定义 __init__初始化对象的创建对象,调用之前会调用new方法,在父类里面 单例模式不管实例对象多少次,只返回第一次创建的对象 通过类来实现装饰器本质就是通过__call__方法,可以把类当做装饰器来使用 @myclass Def fun(): ?? 16,多态 |
|
开发测试 最新文章 |
pytest系列——allure之生成测试报告(Wind |
某大厂软件测试岗一面笔试题+二面问答题面试 |
iperf 学习笔记 |
关于Python中使用selenium八大定位方法 |
【软件测试】为什么提升不了?8年测试总结再 |
软件测试复习 |
PHP笔记-Smarty模板引擎的使用 |
C++Test使用入门 |
【Java】单元测试 |
Net core 3.x 获取客户端地址 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/17 20:25:57- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |