Skip to content

测试岗面试

应用

接口测试如何定位bug

  1. 通过发送相同的请求数据来重现 Bug。如果问题随机出现,记录详细的请求和响应数据,寻找是否有特定的触发条件。

  2. 验证请求格式:确保请求的 Headers、Body、URL 参数的格式和内容符合接口要求。尤其是 JSON 格式、参数类型、长度等是否正确。

  3. 分析响应状态码:状态码比如 400(请求参数错误)、401(认证问题)、500(服务器错误)等。

  4. 检查响应数据:如果状态码为 200,但数据异常,可能是后端逻辑错误。查看响应内容和日志,确认数据是否符合预期。

  5. 查看服务器日志

浏览器开多个窗口是多线程还是多进程

现代浏览器开多个窗口通常是多进程而不是多线程的设计。主流浏览器(如 Chrome、Firefox、Edge)使用多进程架构来提高安全性和稳定性,具体的设计通常包括以下几个进程:

  1. 浏览器主进程:负责管理窗口、标签页、网络请求、用户输入等,并负责协调不同进程的通信。

  2. 渲染进程:每个标签页或窗口通常会分配一个独立的渲染进程。渲染进程负责 HTML、CSS 和 JavaScript 的解析、页面布局、绘制等工作。

  3. 插件进程:如果页面中需要使用插件(如 Flash),浏览器会为每个插件创建独立的进程。

  4. 网络进程:独立处理网络请求和数据加载,减少了资源冲突。

多进程的好处

  • 稳定性:单个窗口或标签页的崩溃不会影响整个浏览器。

  • 安全性:多进程隔离可以限制恶意代码的影响范围,降低跨站脚本攻击等风险。

  • 内存管理:独立的进程允许浏览器更好地管理和释放资源,每个标签页关闭时相应的进程也会结束,回收内存。

登录页面怎么测

  1. 功能测试
  • 正确输入:使用有效的用户名和密码,确认登录成功,并且正确跳转到登录后的页面。

  • 错误输入

    • 输入错误的用户名或密码,检查是否会提示“用户名或密码错误”。

    • 账户被锁定或禁用的情况下,验证登录是否会被拒绝,并显示相应的提示。

  • 边界测试

    • 用户名和密码的长度、特殊字符、空格等输入边界。

    • 处理空字段:不填写用户名和/或密码,查看系统响应。

  • 多次失败测试

    • 测试多次输入错误的用户名或密码后,是否有锁定账户的功能,并检查是否有合适的解锁机制。
  • 重置密码:检查是否提供“忘记密码”功能,以及是否能通过邮箱或手机正确地重置密码。

  • 记住我:测试“记住我”功能,确认再次访问时无需重新登录。

  • 安全性测试

  • SQL 注入:在用户名或密码字段输入 SQL 语句,验证是否能防止 SQL 注入攻击。

  • 跨站脚本攻击 (XSS):在输入框中输入恶意脚本,检查是否会被过滤。

  • 跨站请求伪造 (CSRF):确认是否有防止 CSRF 攻击的措施,如 CSRF token。

  • 敏感信息加密

    • 验证密码在传输过程中是否加密,比如 HTTPS 传输。

    • 检查 Cookie 和 Token 的存储是否安全,并确保不直接存储用户名和密码。

  • 多设备登录限制:测试多设备或多浏览器登录的处理方式,看是否有防止并发登录或异地登录的机制。

  • 验证码:如果启用了验证码,验证是否可以防止暴力破解攻击。

  • 性能测试
  • 响应时间:测试登录的响应速度,确保在正常负载下能快速响应。

  • 并发测试:在高并发情况下测试登录系统的稳定性和响应时间,以确保不会导致系统崩溃。

  • 压力测试:在极端负载下测试系统的承受能力,确认在超负载的情况下是否能正常拒绝请求,并返回友好的提示信息。

  • 兼容性测试
  • 浏览器兼容性:在不同浏览器(如 Chrome、Firefox、Safari、Edge 等)中测试登录功能,确保一致性。

  • 设备兼容性:在不同设备(如 PC、手机、平板)上进行测试,验证页面在小屏幕上的显示和操作是否正常。

  • 用户体验测试
  • 界面设计:检查页面布局、元素间距、按钮和提示信息的易读性和友好性。

  • 可用性测试

    • 登录按钮是否在输入完信息后自动激活。

    • 登录表单是否提供清晰的提示信息。

  • 错误信息:错误提示是否清晰友好,例如“用户名或密码错误,请重试”。

  • 自动化测试:可以通过自动化脚本模拟多种登录场景,提升测试效率和覆盖率。

  • 边缘场景测试
  • 网络不稳定:在网络不稳定或断网的情况下尝试登录,验证系统的响应及提示。

  • 多语言支持:如果页面支持多语言,测试在不同语言环境下的显示效果和功能是否正常。

  • 频繁登录退出:反复登录和退出,检查系统是否有资源泄漏或响应变慢的情况。

测试售货机的支付功能怎么设计测试用例

一、测试用例设计

1. 功能性测试

  • 用例 1:测试选择饮料并进行支付

    • 输入:选择饮料(如可乐)、输入支付金额(如 5 元)

    • 预期输出:支付成功,饮料成功出货

  • 用例 2:测试支付不足

    • 输入:选择饮料(如可乐)、输入支付金额(如 4 元)

    • 预期输出:提示支付金额不足,无法购买

  • 用例 3:测试支付成功但选择无效饮料

    • 输入:选择饮料(如饮料已售罄)、输入支付金额(如 5 元)

    • 预期输出:提示饮料售罄,退款成功

  • 用例 4:测试取消支付

    • 输入:选择饮料(如可乐)、选择取消支付

    • 预期输出:取消成功,不扣款,返回主界面

2. 性能测试

  • 用例 5:测试高并发支付

    • 输入:多个用户同时选择同一种饮料并进行支付

    • 预期输出:系统稳定响应,无崩溃,正确处理订单

3. 安全性测试

  • 用例 6:测试无效支付方式

    • 输入:选择饮料(如可乐)、输入无效的信用卡信息

    • 预期输出:提示支付失败,返回主界面

4. 兼容性测试

  • 用例 7:测试不同支付方式

    • 输入:使用不同的支付方式(如现金、信用卡、移动支付)

    • 预期输出:所有支付方式均可正常使用,且正确完成交易

二、问题排查

如果付款成功后,售货机没有饮料出来,可以按照以下步骤进行问题排查:

  1. 检查支付系统

    • 确认支付是否真正成功。查看支付系统的返回结果和日志,确认是否有交易记录。

    • 检查支付状态是否更新,确认系统是否收到支付成功的通知。

  2. 检查售货机状态

    • 查看售货机是否有足够的库存。检查售货机内的饮料存量,确认所选饮料是否确实可用。

    • 检查售货机的硬件状态(如出货口、投币口、显示屏等),确认是否有任何故障。

  3. 查看系统日志

    • 查看售货机和支付系统的日志,寻找任何异常或错误信息。

    • 检查是否有系统异常,导致支付成功但未能触发出货。

  4. 执行重现测试

    • 重现问题,选择相同的饮料进行支付,确认是否能够稳定复现此问题,以便进行进一步分析。
  5. 联系支持团队

    • 如果以上步骤无法解决问题,联系技术支持团队,提供详细信息(如支付时间、饮料种类等),请求帮助。

多线程并发爬虫时,对url做去重

1.哈希表(HashSet) + 布隆过滤器(Bloom Filter)

  • 哈希表:使用 ConcurrentHashSet 存储已经爬取的 URL。HashSet 提供常数级别的时间复杂度 O(1) 查询和插入操作,适合 URL 去重,但在大规模 URL 爬取中内存占用较高。

  • 布隆过滤器:布隆过滤器是一种基于哈希的空间效率极高的概率型数据结构,可以用于初步去重。它的特点是可以快速判断元素是否存在,查询时间复杂度接近 O(1)。布隆过滤器可以有效减少对 HashSet 的访问,降低内存消耗。

具体做法是将每个 URL 先经过布隆过滤器,如果布隆过滤器判断 URL 存在,再使用 HashSet 确认是否真的存在。

2.初始化布隆过滤器和哈希表

  • 设置布隆过滤器的大小和哈希函数的个数。布隆过滤器的容量可以根据需要爬取的 URL 总数估计,尽量保证假阳性率较低。

  • 初始化一个线程安全的 ConcurrentHashSet来保存去重后的 URL 集合。

URL 检查与去重方法

  • 方法接收每个新 URL,首先在布隆过滤器中检查,如果布隆过滤器判断该 URL 存在,则进行二次确认。

  • ConcurrentHashSet 中进一步确认,确保无误后再将新 URL 添加到 ConcurrentHashSet 和布隆过滤器中。

3. 时间复杂度

  • 布隆过滤器检查:查询复杂度接近 O(1),而且无锁,极大地提高并发效率。

  • 哈希表检查ConcurrentHashMap 查询和插入操作平均为 O(1)。整体时间复杂度近似为 O(1)。

4. 空间复杂度

  • 布隆过滤器:空间复杂度取决于布隆过滤器的位数组大小和哈希函数的数量,通常远低于直接存储所有 URL。

  • 哈希表ConcurrentHashMap 存储去重的 URL 集合,空间复杂度为 O(N),其中 N 是 URL 数量。在内存受限或并发量极高的场景,可以考虑适当清理过期的 URL。

5.实现

java
import java.util.concurrent.ConcurrentHashMap;
import java.util.BitSet;
import java.util.concurrent.locks.ReentrantLock;

public class URLDeduplicator {
    private final BitSet bloomFilter;
    private final int bloomSize;
    private final int[] hashSeeds;
    private final ConcurrentHashMap<String, Boolean> urlSet;
    private final ReentrantLock lock = new ReentrantLock();

    public URLDeduplicator(int bloomSize, int[] hashSeeds) {
        this.bloomSize = bloomSize;
        this.hashSeeds = hashSeeds;
        this.bloomFilter = new BitSet(bloomSize);
        this.urlSet = new ConcurrentHashMap<>();
    }

    // URL hash function based on seed value
    private int hash(String url, int seed) {
        int hash = 0;
        for (int i = 0; i < url.length(); i++) {
            hash = hash * seed + url.charAt(i);
        }
        return Math.abs(hash % bloomSize);
    }

    public boolean isUnique(String url) {
        // Check Bloom filter first
        for (int seed : hashSeeds) {
            if (!bloomFilter.get(hash(url, seed))) {
                return true; // Not in bloom filter, likely unique
            }
        }

        // If bloom says exists, check HashSet
        lock.lock();
        try {
            if (urlSet.containsKey(url)) {
                return false; // Confirmed duplicate
            } else {
                urlSet.put(url, true); // Add new URL
                for (int seed : hashSeeds) {
                    bloomFilter.set(hash(url, seed));
                }
                return true; // Unique URL added
            }
        } finally {
            lock.unlock();
        }
    }
}

设计个指标去评判电梯的调度机制

1. 平均等待时间

  • 定义:所有乘客在发出请求到电梯到达之间的平均等待时间。

  • 计算方式:记录每个请求的等待时间,最终对所有等待时间求平均。

  • 意义:等待时间直接影响乘客的使用体验,平均等待时间越短,说明调度机制的响应速度越快。

2. 平均乘梯时间

  • 定义:乘客从进入电梯到到达目标楼层之间的平均时间。

  • 计算方式:记录乘客从进入电梯到到达目标楼层的时间,对所有乘梯时间求平均。

  • 意义:在优化调度时,减少乘梯时间也是核心目标之一。平均乘梯时间越短,说明电梯在目标分配和运行路径上效率越高。

3. 请求响应率

  • 定义:在特定时间内所有电梯响应的请求数量占总请求数量的比例。

  • 计算方式请求响应率 = 成功响应的请求数量 / 总请求数量

  • 意义:请求响应率反映了调度机制处理乘客请求的覆盖能力,数值越接近 100%,说明调度机制响应能力越强。

4. 电梯空载率

  • 定义:电梯在运行过程中空载行驶的时间占总行驶时间的比例。

  • 计算方式:记录每部电梯空载行驶的时间,求所有空载时间占电梯总行驶时间的比例。

  • 意义:过高的空载率会增加电梯的能源消耗和资源浪费,而合理的空载率可以反映调度机制的资源分配合理性。

5. 拥挤度(负载均衡性)

  • 定义:在特定时间窗口内,电梯的乘客数量方差,或最大负载电梯与最小负载电梯的负载差。

  • 计算方式:记录每部电梯在某一时间段的平均负载人数,计算负载人数的标准差或最大最小差值。

  • 意义:负载均衡程度高的调度机制可以合理分配乘客,避免某一电梯超载而其他电梯空闲,提升整体效率和用户体验。

6. 高峰期响应效率

  • 定义:在早晚高峰期间(或指定高峰时段),调度机制的响应效果。

  • 计算方式:分早高峰和晚高峰统计平均等待时间、请求响应率等指标。

  • 意义:高峰期是电梯调度的重点难点,反映调度机制在高峰期的适应性和稳定性。

概念

测试开发本质

测试开发的本质是助力业务成功。

软件测试的意义

通过一系列测试活动,「提前」发现和定位软件产品质量的薄弱环节,并倒逼开发人员修正,从而保证交付的软件质量满足客户需求。

有研究表明,越早发现软件中存在的问题,开发费用就越低,软件质量越高,软件发布后的维护费用越低。因此,提前发现和定位问题极为重要,而在软件开发的整个历程中,越是新兴的软件开发模型,越重视「提前测试」。提前测试可以使得在需求分析时期就可发现的错误,不必等到开发完成才被发现。

测试开发流程

测试方法

  1. 冒烟测试(Smoke Testing):

冒烟测试是在软件开发的早期阶段进行的一种表面级功能验证测试。它主要用于确认软件的基本功能是否正常工作,以便在后续的测试阶段中能够进行更详细的测试。冒烟测试通常只验证最核心、最重要的功能,并不深入测试每个细节。

冒烟测试的目标是迅速检查系统是否满足最低程度的可接受性要求,例如是否能够启动、登录、基本功能是否可用。如果冒烟测试未通过,测试团队将不再投入更多时间和资源进行进一步的测试,而是返回给开发人员解决问题。

假设我们正在开发一个电商网站,核心功能包括用户注册、浏览商品、添加到购物车和下订单。在冒烟测试中,我们只需要验证这些基本功能是否正常工作。例如,我们可以进行以下验证:

用户注册:尝试注册一个新用户,并确认是否成功创建了用户账号。

商品浏览:随机选择几个商品,打开它们的详情页面,确保商品信息能够正确地显示出来。

添加到购物车:选择一个商品并将其添加到购物车,然后查看购物车页面是否正确显示所选商品。

下订单:从购物车中选择一个或多个商品进行结算,填写必要的信息并提交订单,确保订单是否成功生成。

以上场景只是最基本的冒烟测试,旨在验证系统的主要功能是否能够正常工作。如果这些基本功能都通过了测试,那么我们可以进一步进行更详细的功能和边界测试。

  • 回归测试(Regression Testing):

回归测试是在软件经过修改、修复或新功能添加后进行的一种测试。它旨在确保修改后的代码与原始代码之间没有引入新的错误,并且之前的功能仍然正常工作。回归测试是为了验证软件在进行修改后是否依然稳定和可靠。

回归测试一般包括重新执行已有的测试用例,通过比较预期结果和实际结果来确定系统是否出现了问题。它可以使用自动化测试工具来提高效率,并确保每次进行回归测试时都能够覆盖到所有关键功能和模块。

回归测试的目标是捕获并修复由于修改引入的新错误,以及确保系统的稳定性和可靠性。通过回归测试,可以防止在软件开发过程中引入新的问题,并验证之前已经修复的问题是否仍然解决了。

单元测试:通常情况下是白盒测试

最小设计单元(模块)的验证,确保模块被正确编码,对重要控制路径进行测试以发现模块内错误,通常情况下是白盒测试,对代码风格和规则、程序设计和结构、业务逻辑等进行静态测试,及早发现解决不易显现的错误。

集成测试:黑盒白盒结合

测试接口是否一致、模块间数据流控制流是否按照设计实现其功能、以及结果的正确性验证

  • 系统测试:黑盒测试

系统测试是对整个系统的测试,将硬件、软件、操作人员看作一个整体,检验它是否有不符合系统说明书的地方,主要包括功能测试、界面测试、可靠性测试、易用性测试、性能测试。 功能测试主要针对包括功能可用性、功能实现程度

  • 验收测试

也称交付测试,是针对用户需求、业务流程进行的正式的测试,以确定系统是否满足验收标准,由用户、客户或其他授权机构决定是否接受系统。

验收测试包括alpha测试和beta测试,alpha测试是由开发者进行的软件测试,beta测试是由用户在脱离开发环境下进行的软件测试。

常用的自动化测试工具

1、Selenium

WEB自动化测试

Selenium是网页应用中最流行的开源自动化测试框架。起源于2000年,10多年来不断地完善,Selenium成为许多Web自动化测试人员的选择,尤其是那些有高级编程和脚本技能的人。Selenium也成为了其他开源自动化测试工具比如Katalon Studio,Watir,Protractor和Robot Framework的核心框架。

2、Jmeter

接口测试,性能测试

Apache JMeter是一个开源的Java桌面应用程序,主要用于web应用程序的负载测试。它还支持单元测试和有限的功能测试。

它有很多好的特性,比如动态报告、可移植性、强大的测试IDE等,并且支持不同类型的应用程序、协议、shell脚本、Java对象和数据库。

3、Postman

接口测试

Postman 提供功能强大的Web API和HTTP请求的调试,它能够发送任何类型的HTTP请求 (GET, POST, PUT, DELETE…),并且能附带任何数量的参数和Headers。不仅如此,它还提供测试数据和环境配置数据的导入导出,付费的Post Cloud用户还能够创建自己的 Team Library用来团队协作式的测试,并能够将自己的测试收藏夹和用例数据分享给团队。

设计一个不错的测试案例

开放问题

1.对测试开发的理解

测试开发首先离不开测试,而软件测试是指,在规定的条件下对程序进行操作,以发现程序错误,衡量软件质量,并对其是否能满足设计要求进行评估的过程。

而且,现在不仅仅是通过手工测试来发现定位Bug,也会通过编写脚本、测试工具来完成自动化测试,因此,对于测试开发人员来说,他除了保证产品质量之外,还要编写脚本以及开发测试工具。这就是我对测试开发的一点理解。

2.为什么做测试而不是去做开发

首先,后端开发的工作侧重于编码和实现功能,而测试工作不仅能关注系统的功能实现,还能更全面地了解系统的性能、安全性、兼容性等多维度的问题。还能培养更加严谨、细致的思维方式,训练快速定位和分析问题的能力,所以我觉得做测试开发会对我的技术提升很有帮助。

其次,在近几年,国内对软件测试越来越重视,测试的前景是非常好的。

并且,测试在一个项目开发的过程中是非常重要的一环。开发人员很难在开发的时候又要全面兼顾产品的质量,测试人员就是项目内部的最后把关者,最大程度的保证项目上线不会出现问题。

责任非常大,责任越大成就感就越大。我很喜欢这样的工作。

在网上看到一句话,说:写程序的人就像在造没有护栏的桥,自己去走那肯定安全,那怕摸黑也不至于掉河里去;测试则像给桥修护栏的,让桥的普通使用者也能像开发那样来去自如。从这一点上说,可以体现出测试的重要性。

3.如何处理矛盾

我觉得做测试和程序员发生冲突是难免的,人与人之间在一起生活,难免会发生冲突。发生冲突不能用争吵解决,要坦诚相待,心平气和地与对方沟通,善于倾听对方的观点,并理解对方,然后向对方阐述自己的观点。如果还是产生差异,我会请示上级。

4.职业发展

对于这一行来说,经验越多,能力就越高。前几年先积累经验,不断地更新自己、改正自己,然后一步一步朝着高级测试开发工程师走去。

5.你认为测试人员需要具备哪些素质。(你有哪些优点围绕这些来说)

首先要有一定的沟通协调能力,因为测试人员经常会与开发人员接触处理一些问题,需要心平气和地沟通。还需要有一定的耐心,不能放过每一个错误;

要有责任感,要尽自己最大的能力,保证产品的质量。要有好奇心,保持一种怀疑的态度,测试人员的任务是找出缺陷,不是证明没有缺陷,所以需要保持怀疑。

要细心;乐观;

6.你为什么能够胜任这个岗位

虽然之前的实习是开发,接触的测试比较少,但是我的分析业务的能力得到了很大锻炼,而且在实习和做项目的过程中,我对自己的需求和自己做的系统也都进行了各种测试,我是有一定的测试经验的。我相信自己的学习能力,可以快速上手。而且我还有良好的沟通能力,很有耐心,有责任感,我觉得这在测试中也是很重要的一些素质。