2023最新高级测试开发面试题(答案+解析)

前言

前几天和一个测试开发小伙伴,谈人生聊理想,聊到了最近积累的测试开发面试题,打算分享出来,供大家参考。

主要面试了大疆、华润万家和微众,统招本科,毕业5年左右。

同时,我也准备了一份软件测试视频教程(含接口、自动化、性能测试等内容),需要的可以直接在下方观看,或者直接关注VX公众号:互联网杂货铺,免费领取

软件测试视频教程观看处:

【软件测试】用300道面试题帮你上岸,每天刷一遍,让你直接入职,斩获心仪offer

大疆

1、看你简历上有写测试用例管理平台,可以介绍一下吗?

答:测试平台无非就是那几个模块,接口管理、用例管理、权限管理等等,重点聊聊这个平台实现的逻辑,以及测试用例平台用到的技术框架。感兴趣的同学可以网上找一些测试平台源码研究下。

2、介绍一下接口自动化平台,定时任务是怎么实现的?

答:功能模块+实现逻辑+技术框架等等,如果小项目的自动化平台,实现定时任务的功能有很多方式,

linux :crontab

Java:SpringBoot的EnableScheduling、Java原生的Timer、ScheduledExecutorService线程池等等,如果是项目规模比较大,Java有天然的开源框架xxl-job。

python:

1、死循环 + time.sleep()

2、利用Timer对象实现定时输出

3、sched 事件调度器

4、APScheduler

3、你们做的这个平台,是谁来测试的,单元测试的时候,有没有遇到过两个模块单独跑可以通过,一起跑就不通过的场景

答:看你的测试平台规模,一般大型的测试平台,都会有专门的测试,小规模的测试平台,测试开发自测。

4、你们做的这个接口平台有没有遇到过性能问题,比如大量用例一起跑的时候,出现CPU过高,是怎么解决的,有没有做过负载均衡

答:


jps 获取Java进程的PID。
jstack pid >> java.txt 导出CPU占用高进程的线程栈。
top -H -p PID 查看对应进程的哪个线程占用CPU过高。
echo “obase=16; PID” | bc 将线程的PID转换为16进制,大写转换为小写。
在第二步导出的Java.txt中查找转换成为16进制的线程PID。找到对应的线程栈。
分析负载高的线程栈都是什么业务操作。优化程序并处理问题。

5、你们自动化是怎么通过jenkins执行的,是每个人创建一个image还是公用一个,为啥不公用一个image(我说的每个人根据自己的dockerfile创建自己的镜像)

答:一般都是使用公共的镜像,这样避免编译、制作镜像耗费时间,但是有些特殊逻辑还是要单独使用个人镜像。

6、有没有遇到过自动化时候两个人操作同一个数据,导致用例失败的场景,你们是怎么解决的?

答:可能触发数据库唯一索引,或者并发安全策略。

7、用过python没有,如何输出元组的后面四个数

答:​​​​​​​


tuple2 = (1,2,3,4,5,6)
print(tuple2[-4:])

8、python装饰器的作用是什么,对使用装饰器的函数有什么限制要求

答:python装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能,

9、你们开发的平台是自己部署的还是运维部署的,是只有你们自己测试组使用还是开发也在使用

答:看测试平台项目规模,大型自研测试平台几乎都是运维部署、开发测试都会用。

10、有没有经历过自动化跑出来的bug,提交到开发那边,开发说是你们环境的问题,你们是如何避免的

答:那必须得有,这道题其实就问你如何维护测试用例的稳定性


增加重试机制:
pytest里的出错重试机制实现,在测试框架pytest里,已经实现了有关出错重试的策略,我们首先需要安装一个此类的插件,在cmd内执行以下命令安装:
pipinstallpytest-rerunfailures
Java的testng 的IRetryAnalyzer 接口

华润万家

1、为什么选java不选python

答:Java 提供了类型保护,可以在累积的时间内解决所有可能的错误,因此,运行时潜在错误的可能性降低了,而不是 Python 在运行时捕获。最后,这突出表明,监督大型应用程序变得更加简单。尽管 Python 是一种功能强大的语言,但在运行时会出错,运行时错误比订单时间错误更难调查。

2、你的这个平台包含哪些功能

答:测试平台无非就是那几个模块,接口管理、用例管理、权限管理等

3、用例执行是怎么实现的

答:一般都是数据驱动+分层封装模式

4、测试报告是怎么实现的

答:allure 报告

5、springboot是什么,你是如何理解的

答:Spring Boot是基于Spring开发,它本身并不提供Spring框架的核心特性和扩展功能,只是用于快速、便捷地开发新一代基于Spring框架的应用程序,也就是说SpringBoot并不是用来替代Spring的解决方案,而是和Spring框架紧密结合用于提升Spring开发者体验的工具,SpringBoot以约定大于配置的核心思想,默认帮我们进行了很多设置,同时它集成了大量常用的第三方库配置,SpringBoot应用中这些第三方库几乎可以零配置的开箱即用。

6、你是怎么理解aop的

答:面向切面编程,老八股文了都,spring框架经典特性,aop 和ioc

7、aop,过滤器,拦截器的区别是什么

答:

1)区别与概念

Filter过滤器:拦截web访问url地址。

Interceptor拦截器:拦截以 .action结尾的url,拦截Action的访问。

Spring AOP拦截器:只能拦截Spring管理Bean的访问(业务层Service)

概念:

Spring AOP:

Spring AOP,是AOP的一种实现,使用的是代理模式。

Filter:

Filter(过滤器)是J2EE的规范,Servlet2.3开始引入/实现的是职责链模式。Filter可以用来设置字符集、控制权限、控制转向等等。Filter也是AOP的一种实现。

Interceptor:

Interceptor (拦截器),是Spring MVC中的概念。同样是AOP的一种实现。

2)Filter与Interceptor联系与区别

拦截器是基于java的反射机制,使用代理模式,而过滤器是基于函数回调。

拦截器不依赖servlet容器,过滤器依赖于servlet容器。

拦截器只能对action起作用,而过滤器可以对几乎所有的请求起作用(可以保护资源)。

拦截器可以访问action上下文,堆栈里面的对象,而过滤器不可以。

执行顺序:过滤前-拦截前-Action处理-拦截后-过滤后。

3)拦截器和过滤器的区别

拦截器是基于Java的反射机制,过滤器是基于java的函数回调

拦截器不依赖于servlet容器,而过滤器依赖于servlet容器

拦截器只能对action请求起作用,过滤器几乎对所有的请求起作用

拦截器可以访问action上下文,值栈里的对象,而过滤器不能访问

在action生命周期中,拦截器可以被多次调用,过滤器只能在servlet初始化是调用一次

拦截器可以获取IOC容器中的各个bean,过滤器不行,在拦截器中注入一个service可以调用逻辑业务

8、给你一个需求,如何保证测试质量

答:测试人员应该从整个测试流程来把控软件质量,在整个过程中应当与其他研发人员共同提高产品的功能。

测试流程:需求评审>测试计划>测试计划>测试方案>编写用例>执行用例>回归测试>提交缺陷报告>提交测试报告

从以下几个方面来参考:

1)需求评审阶段,要对需求有准确的定位,尽可能和开发、产品对齐需求时有大致相同的需求理解;

2)测试方案及测试用例评审,对测试用例有更高的覆盖率,全面的测试类型,和有一个明确的测试重要性等级;

3)交叉测试,进行交叉测试,提高软件的易容性,不同的人对于不同的功能有不同的看法,也可以发现不同的问题;

4)回归测试,对于回归测试不仅要回归目标bug,也要进行深度和广度的测试,防止开发在修复bug时,引出其他问题;

5)与产品对齐,在研发阶段定期与产品人员对齐,确保软件的走向及市场需求准确;

6)Beta测试,如有条件做beta测试,则进行必要的beta测试,从真实使用的场景把控软件;

7)引入自动化测试:

对于适用自动化测试的产品,可以引入自动化测试,节约投入成本,提高迭代测试效率。

9、你对这个平台未来有没有什么规划,有没有需要优化的地方

答:规划就说吹呗,提供一个思路,首先肯定完善或新增更多功能,方便用户使用,技术上,可以考虑分布式架构,其次推广给全公司或者形成商业化产品等等。

10、一个退订单的业务,你是如何测试幂等性,不用jmeter等工具等情况下,你要如何实现并发的场景

答:可以考虑代码中实现多线程请求退单接口。尽量开启多个线程同时访问接口,可以用到Java的CyclicBarrier,循环屏障。它是一个同步工具,可以实现让一组线程等待至某个状态之后再全部同步执行。在所有等待线程都被释放之后,CyclicBarrier 可以被重用。​​​​​​​

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class CountDownLatchDemo2 {
    public static void main(String[] args) throws InterruptedException {
        int N = 4;
        // 定义 CyclicBarrier
        CyclicBarrier barrier = new CyclicBarrier(N);
        for (int i = 0; i < N; i++) {
            new BusinessThread(barrier).start();
            Thread.sleep(1000);
        }
    }

    // 定义业务线程
    static class BusinessThread extends Thread {
        private CyclicBarrier cyclicBarrier;

        public BusinessThread(CyclicBarrier cyclicBarrier) {
            this.cyclicBarrier = cyclicBarrier;
        }

        @Override
        public void run() {
            try {
                // 执行业务代码
                Thread.sleep(2000);
                System.out.println(Thread.currentThread().getName() + "执行结束,等待其他线程");
                // 业务代码执行结束,等待其他线程成为 Barrier 状态
                cyclicBarrier.await();// 当进入 Barrier状态的线程达到数组的时候,就能接着向下执行
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "结束");
        }
    }

11、如何保证一个退订单的业务不会被操作两次,你是如何测试的

答:和上题一样,工具或代码都行。

12、Jenkins k8s如何实现自动打包,自动部署

答:百度吧,我也没整过,网上应该有。

13、一个登录接口,最大tps只能达到100,但是产品要求500,你能考虑到从哪些方面来提高?

答:可以理解如何提高接口或服务端的性能,包括但不限于以下几方面,不一定全说出来这些,建议说几个自己熟悉的点,譬如你对redis比较熟悉,那就说加redis缓存,熟悉索引,就说加索引等等。

面试尽量把面试官引导到自己擅长的领域。​​​​​​​

加索引
代码重构
增加缓存
引入一些中间件,比如 mq
分库分表
拆分服务
并行调用
避免大事务
锁粒度
分页处理
优化jvm配置,优化gc时间

14、如果有两个任务都会用到登录接口,两个任务同时执行,任务a登录的时候,任务b登录就失效了,那任务b就会执行失败,如何解决这样的现象

答:这种就是单点登录的功能,我这边有个思路,目前大部分项目的token或cookie都是放在redis缓存里的,我们可以直接连接测试环境的redis,每次登录前调用redis客户端,查询同一个用户的登录凭证是否存在缓存中,如果存在,获取凭证到本地,直接使用,无需登录。

微众银行

1、介绍一个你做过的一个项目,你在里面担任的什么角色,做了那些事,做出了什么贡献,取得了什么成就

答:见大疆1

2、介绍一下你们的接口自动化,实现了哪些业务,给你们带来了什么样的价值

答:首先肯定是提高了回归测试效率,减少了线上bug的产生(举个自动化发现的bug例子)

3、单接口的数据校验,有没有什么规律,比如每个每个接口参数都要做为空校验,像这种你们是如何减少代码耦合度的,有没有做过代码自动生成之类的

答:这个网上有开源的工具了。

4、持续集成理想化是没有问题的,但实际使用过程总会遇到各种问题,比如开发某个功能还没写完,你们就把执行代码拉过来,然后打包到测试环境,这种情况用例就会有大量失败,然后又花费大量的时间去定位,结果发现是环境问题,这种情况要怎么有效的去解决?

答:可以考虑设置代码门禁策略,将自动化项目集成到测试环境,每次开发提交代码,都触发一次自动化回归;其次也可以规范开发提交代码的行为。等等

5、市场上有很多开源工具基本可以实现这些,你们为什么要选择自己开发。

答:略

6、整个平台的开发过程中,你有没有遇到过什么问题,然后是怎么解决的

答:每个人遇到的困难不一样,建议提前准备一个,建议可以从幂等性保障、慢sql优化等技术细节入手。

7、redis和数据库是怎么做同步的?

答:

方案1:同步删除
顾名思义在修改数据库数据的时候,同步删除缓存

缺点:
1、不能保证每个入口都能同步删除
2、如果直接修改数据库不能同步删除
3、如果缓存删除失败,会出现脏数据

方案2: 延迟双删
删除缓存-》修改数据库-〉等待一段时间再删除一次缓存
缺点:
1、无法确定延迟时间(主从同步会出现延迟)
2、无法绝对保障数据一致

方案3: 异步监听binlog删除+重试
使用中间件监听数据库产生的binlog-》删除缓存数据(消费失败重试)

缺点:
1、相对于同步删除,脏数据窗口较大(相对来说,实际上时间是比较短的)
2、mq可能挂机(几率较小)
3、新老库迁移,可能出现数据不一致(大部分场景不会出现)

8、怎么解决redis和数据库数据不一致的问题

答:如上

9、消息队列的参数是怎么配置的

答:生产者消费者的配置参数,要看mq的类型,简单聊聊rocketmq的配置,kafka 和rabbitmq大家可以自己查寻。​​​​​​​


生产者:
rocketmq:
  producer:
    # 支持配置多个连接
    producerlist:
      - groupName: ${spring.application.name}
        # 生产者唯一标识
        producerId: chenkeTest
        # mq的nameserver地址
        namesrvAddr: 127.0.0.1:9876
        # 消息最大长度 默认 1024 * 4 (4M)
        maxMessageSize: 4096
        # 发送消息超时时间,默认 3000
        sendMsgTimeOut: 3000
        # 发送消息失败重试次数,默认2
        retryTimesWhenSendFailed: 2


消费者:
consumer:
    # 支持配置多个连接
    consumerlist:
      - groupName: mqdemo
        # mq的nameserver地址
        namesrvAddr: 127.0.0.1:9876
        # 消费者订阅的主题topic和tags,tagName=*则代表监听topic所有,tagName=tag1||tag2||tags3则代表监听部分
        # 实际业务处理类必须实现MqConsumerInterface接口
        # 每个topic对应一个处理类,根据topicName获取对应类,例如:mqConsumerHandle.ChenkeTopic,mqConsumerHandle固定值
        topics:
          - topicName: ChenkeTopic
            tagName: test
          - topicName: ChenkeTopic2
            tagName: '*'
        # 消费者线程数据量
        consumeThreadMin: 4
        consumeThreadMax: 4
        # 设置一次消费的条数,默认1
        consumeMessageBatchMaxSize: 1
        # 是否顺序消费
        orderly: false
        # 消费模式
        messageModel: CLUSTERING
      - groupName: mqdemoOrderly
        # mq的nameserver地址
        namesrvAddr: 127.0.0.1:9876
        # 消费者订阅的主题topic和tags,tagName=*则代表监听topic所有,tagName=tag1||tag2||tags3则代表监听部分
        # 实际业务处理类必须实现MqConsumerInterface接口
        # 每个topic对应一个处理类,根据topicName获取对应类,例如:mqConsumerHandle.ChenkeTopic,mqConsumerHandle固定值
        topics:
          - topicName: ChenkeTopic3
            tagName: '*'
        # 消费者线程数据量
        consumeThreadMin: 4
        consumeThreadMax: 4
        # 设置一次消费的条数,默认1
        consumeMessageBatchMaxSize: 1
        # 是否顺序消费
        orderly: true
        # 消费模式
        messageModel: CLUSTERING

10、你们性能测试是怎么做的,说一下流程,介绍一个业务,你测试过程中发现了哪些问题,开发都做了哪些优化,没有优化前是什么样子,优化后达到了什么样的效果?

答:

确定测试目的与需求——根据需求与场景,
梳理测试要点——根据测试目的,
制定测试方案——准备测试环境与数据——测试执行(脚本或工具)
——统计测试结果——分析结果——测试报告

PS:

1 .测试执行时,执行多次,取平均结果更为准确。

2. 单机并发不够时,采用多机分布式并发;

3. 测试过程,一定要尽可能模拟实际应用场景;

发现的问题,每个项目不一样,这边提供以下几个思路:

问题一:响应时间不达标

查看事务所消耗的时间主要在网络传输还是服务器,如果是网络,就结合Throughput(网络吞吐量)图,计算带宽是否存在瓶颈,如果存在瓶颈,就要考虑增加带宽,或对数据的传输进行压缩处理;如果不存在瓶颈,那么,可能是网路不稳定导致。如果主要时间是消耗在服务器上,就要分别查看web服务器和数据库服务器的CPU,内存的使用率是否过高,因为过高的CPU,内存必定会造成响应时间过长,如果是web服务器的问题,就把web服务器对应上对应的用户操作日志取下来,发给开发定位;如果是数据库的问题,就把数据库服务器对应上对应的日志取下来,发给开发定位。

问题二:服务器CPU指标异常

分析思路:就把web服务器对应上对应的用户操作日志取下来,发给开发定位。

问题三:数据库CPU指标异常

分析思路:把数据库服务器对应上对应的日志取下来,发给开发定位。

问题四:内存泄漏

分析思路:把内存的heap数据取出来,分析是哪个对象消耗内存最多,然后发给开发定位。

问题五:程序在单用户场景下运行成功,多用户运行则失败,提示连不上服务器。

原因:程序可能是单线程处理机制

写在最后

如需软件测试学习资料,可在公众号(互联网杂货铺)后台回复1,小编后面会逐步完善自己收藏的资料。

整理不易,给个关注点个赞吧,谢谢各位大佬!

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值