文章目录
1.怎么看待测试和开发?
测试和开发是软件工程中两个重要且互补的环节。它们共同的目标是确保软件产品的质量和满足用户需求,但它们的工作重点和方法有所不同。
- 工作内容:
- 开发:通过不同的编程语言,最终做出软件。
- 测试:写测试用例,执行,发送测试报告,编写自动化测试用例,开发相关的测试工具。
- 技能区别:
- 测试:技能广度的掌握(测试人员要对产品进行全面的测试,外观是否好看,WEB的UI自动化测试,APP的UI自动化,后端的接口进行测试,性能,安全等)
- 开发:技能深度的掌握(开发要写出高效的代码)
- 发展前景:
- 测试:初级测试工程师 > 中级测试工程师 > 高级测试工程师 > 架构师 > 项目经理
- 开发:初级开发工程师 > 中级开发工程师 > 高级开发工程师 > 架构师 > CTO
2.如果一个应用程序内存使用量和CPU占用非常高,应该从哪几方面去排查性能问题?
应用进程还活着,但页面出不来、不响应,这种是高CPU,高内存是应用响应慢或者内存溢出、直接死掉。
应用程序高内存占用,可能因为大文件读取、频繁IO,内存消耗频繁,导致频繁GC,进一步占用内存和CPU;
应用程序高CPU占用,可能在执行大任务计算,或者死循环、卡死,或者不断超时、重试(活锁是容易占CPU的,死锁和饥饿是容易占内存的,因为资源不释放)。
3.什么是缓存穿透、缓存击穿和缓存雪崩?出现时如何解决?
缓存击穿、缓存穿透和缓存雪崩是与缓存相关的一些常见问题,具体定义如下:
- 缓存击穿:指当一个缓存键(key)对应的数据在缓存中不存在,同时又有大量并发请求访问该缓存键时,这些请求会直接绕过缓存,查询数据库或其他存储系统,导致数据库压力增大。缓存击穿通常在缓存过期后发生。
- 缓存穿透:指当一个查询请求访问一个不存在于缓存中且也不存在于数据库中的数据时,这个请求会无效地继续访问数据库,而不会被缓存。如果黑客故意发送大量非法请求,则缓存层无法起到过滤作用,可能导致数据库负载过大。
- 缓存雪崩:指当缓存集中在某个时间点失效或由于某个原因发生故障,导致大量的请求直接打到后端数据库,造成数据库瞬时压力过大,甚至引起数据库崩溃。在缓存雪崩期间,系统性能急剧下降,无法正常提供服务。
为了应对以上问题,可以采取以下措施:
- 对热点数据采用永不过期策略,避免缓存击穿。
- 在缓存层进行空值缓存,即将查询结果为空的数据也缓存一段时间,避免缓存穿透。
- 设置合理的缓存过期时间,并使用分布式缓存的多节点部署,避免缓存雪崩。
- 引入限流、熔断等机制,控制并发访问量,保护后端系统。
- 对重要数据做冷备份,确保即使缓存失效或故障,仍能从其他系统中恢复数据。
4.编写测试用例
现有一需求文档,存在以下场景:一个包含头像,用户名和密码表单,登录按钮,注册按钮,找回密码按钮的页面,请编写测试用例,这时认为测试应该基于哪几点去考虑?
功能
界面
易用
兼容
性能
安全
网络
中断
京东登录界面测试用例
5.如何理解 JVM 虚拟机
JVM内存模型主要是指Java虚拟机在运行时所使用的内存结构。它主要包括堆、栈、方法区和程序计数器等部分。
堆是JVM中最大的一块内存区域,用于存储对象实例。一般通过new关键字创建的对象都存放在堆中,堆的大小可以通过启动参数进行调整。堆被所有线程共享,但是它的访问是线程不安全的,需要通过锁机制来保证线程安全。
栈用于存储方法调用和局部变量。每个线程在运行时都会有一个独立的栈,栈中的每个方法调用都会创建一个栈帧,栈帧包含了方法的参数、局部变量和返回值等信息。栈的大小是固定的,并且栈中的数据是线程私有的,不会被其他线程访问。
方法区用于存储类的信息和静态变量。它是所有线程共享的内存区域,存储了类的结构信息、常量池、静态变量和方法字节码等。方法区的大小也可以通过启动参数进行调整。
程序计数器是每个线程私有的,用于记录当前线程执行的字节码指令的地址。每个线程都有一个独立的程序计数器,用于控制线程的执行流程。
JVM内存模型的设计可以提供内存管理和线程安全的机制,同时也保证了Java程序的跨平台性。不同的内存区域有不同的作用和访问规则,合理地管理和利用这些内存区域可以提高Java程序的性能和稳定性。
6.使用 JVM 虚拟机的内容对平常代码中的性能问题进行定位?举例说明
7.软实力
如果产品经理向你提供的需求文档未达到你的要求,令你无法输出一份相对比较完整的我测试用例,这时你应该怎么做?
- 沟通和澄清:
与产品经理进行沟通,说明你在需求文档中发现的问题和不足之处。
提出具体的问题和需要澄清的地方,比如需求的不明确性、逻辑矛盾、功能描述的缺失等。
- 请求补充资料:
请求产品经理提供更多的信息或者补充文档,以便更好地理解产品需求。 如果可能,请求参与产品讨论会议,以便直接了解产品的设计和目标。
- 制定需求清单:
根据当前的需求文档,列出所有已经明确的需求和需要进一步明确的需求。 创建一个需求跟踪表,记录需求的变更和更新。
- 建议使用用户故事或用例:
建议产品经理采用用户故事或用例的方式来描述需求,这样更有助于理解用户的业务流程和需求场景。
- 编写初步测试用例:
根据已有的信息,尝试编写初步的测试用例,标记出那些因需求不明确而无法完成的部分。 这样可以在后续的讨论中,有针对性地解决这些未完成的部分。
- 组织需求评审会议:
邀请产品经理、开发团队和其他相关利益相关者参加需求评审会议。 在会议中逐一讨论需求,确保所有人对需求有共同的理解。
- 持续跟进:
在需求澄清过程中,持续跟进需求的变更和更新。 确保测试用例能够及时反映需求的变更。
如果问题依然无法解决,可以寻求上级或者质量保证团队的帮助。
如果验收方发现有一个地方漏测了,你会怎么做?你后续如何规避这些问题?
-
立即行动:
一旦发现漏测,立即采取行动进行测试,确保该问题得到解决。 -
分析原因:
分析导致漏测的原因。可能的原因包括需求理解不透彻、测试用例设计不全面、人为疏忽、沟通不畅等。 -
记录和报告:
将漏测的问题及其原因记录下来,并在适当的报告中向管理层或项目团队报告,以便所有相关人员都了解发生的情况。 -
制定补救措施:
根据漏测的原因,制定相应的补救措施。例如,如果是因为测试用例设计不全面,那么需要完善测试用例。 -
实施补救措施:
实施制定的补救措施,确保所有功能点都得到了测试。 -
重新验证:
对之前漏测的功能点进行重新验证,确保其满足需求并且没有引入新的问题。 -
更新测试文档:
更新测试计划、测试用例和测试报告,以反映对漏测问题的处理。 -
持续改进:
根据这次的经验,改进测试流程和方法,以防止未来再次发生类似问题。 -
团队培训和意识提升:
对测试团队进行培训,提高他们对细节的关注和风险意识,以及如何更有效地设计和执行测试用例。 -
加强沟通和协作:
加强与产品经理、开发团队和其他利益相关者之间的沟通和协作,确保需求的准确理解和传递。 -
定期审查:
定期审查测试流程和测试用例,确保它们能够覆盖所有需求和潜在的风险点。
通过上述步骤,可以有效地处理漏测问题,并采取措施减少未来发生类似问题的可能性。重要的是要从错误中学习,并持续改进测试流程。
如何向代码验收方阐述你所做的测试是充分且达到使用要求的?
向代码验收方阐述你所做的测试是充分且达到使用要求,需要提供清晰、详细的测试证据和文档,以及确保测试过程的透明度。
-
准备测试报告:
提供一个全面的测试报告,包括测试的范围、方法、执行的测试用例、发现的缺陷、缺陷的解决情况以及测试结果的总结。 -
展示测试覆盖率:
使用工具来展示代码覆盖率和测试覆盖率。这可以帮助证明测试用例覆盖了所有的功能点和代码路径。 -
演示测试过程:
如果可能的话,进行一个实时的测试演示,向验收方展示测试过程是如何进行的,包括自动化测试和手动测试。 -
提供测试用例和脚本:
提供完整的测试用例和测试脚本,以便验收方可以查看测试的细节,了解测试是如何设计的,以及它们是如何覆盖需求的。 -
说明缺陷管理过程:
说明缺陷的发现、记录、跟踪和解决过程。展示缺陷的趋势图和当前状态,以证明所有已知的严重问题都得到了妥善处理。 -
强调关键功能和风险点的测试:
强调对关键功能和潜在风险点的额外关注,包括安全性、性能和稳定性等方面的测试。 -
用户场景和验收测试:
展示如何基于用户场景进行验收测试,并证明测试涵盖了实际用户的使用情况。 -
合规性和标准:
如果适用,说明测试是如何遵循行业标准和法规要求的。 -
反馈和改进:
讨论在测试过程中收集的反馈,以及如何利用这些反馈来改进产品。 -
提供维护和支持计划:
说明在产品发布后,将如何继续进行测试和维护,以确保产品的稳定性和可靠性。 -
准备好回答问题:
准备好回答验收方可能提出的问题,比如关于特定功能的测试方法、未解决的问题的处理计划等。
通过上述步骤,你可以向验收方展示你的测试工作是全面和彻底的,并且产品已经达到了预期的质量标准和使用要求。
8.出现慢查询可能是哪几个方面的原因?
-
数据库设计不合理:数据库表结构设计不合理,如过多的关联查询、冗余数据等。
-
SQL语句编写不当:SQL语句编写不规范,使用了低效的查询方式,如全表扫描、索引失效等。
-
数据库参数配置不合理:数据库参数配置不合理,如缓冲区大小、连接数等设置不合适。
-
硬件资源不足:服务器硬件资源不足,如CPU、内存、磁盘等性能较低。
-
网络延迟:网络延迟较高,导致数据传输速度较慢。
-
数据库负载过高:数据库负载过高,导致处理请求的速度变慢。
9.怎么理解 Java 的注解,举具体的例子?有写过什么注解吗?注解执行的顺序是什么?
Java注解是一种元数据机制,用于为代码提供补充信息,这些信息可以在编译、类加载和运行时被读取并处理。
注解在Java中是一种特殊的语法元素,它们允许开发者在不改变原有代码逻辑的情况下为代码添加额外的信息。这些信息可以被用来生成文档、优化代码、进行数据校验等。从JDK5版本开始引入了注解,它们是Java语言中类、方法、变量、参数和包等元素之上的标签。与Javadoc注释不同,注解可以通过反射获取其内容,并且能够嵌入到字节码中。此外,Java也支持自定义注解,使得开发者可以根据需要创建和使用特定的注解。
例如,Java中自带的@Override
注解表示一个方法覆盖了父类的方法;@Deprecated
表明某个元素不再建议使用;@Documented
表示注解信息会出现在JavaDoc中;@Inherited
则表明注解具有继承性。自定义注解的一个实例是通过创建一个字段校验的注解来理解注解的使用,这个注解可以标记在类、字段或方法上,并通过反射获取其标注信息以实现自动化的数据校验工作。
至于Java注解的执行顺序,这通常取决于具体的应用场景。
在Spring AOP(面向切面编程)中,注解的执行顺序由其优先级决定,优先级高的通知先执行,同优先级下则按照声明顺序执行。如果定义了多个自定义注解,可以为每个注解指定一个执行顺序的值,或者通过@Order
注解来指定处理器的执行顺序。在实际应用中,还需要注意不同版本的框架可能存在的差异,以及确保正确配置执行顺序以避免潜在的问题。
10.出现线上问题,该如何处理?
-
问题定位:
- 尽快确认问题的具体表现和影响范围。
- 查看日志和监控数据,确定问题发生的时间、频率和环境。
- 使用调试工具或命令进行诊断,如
top
、ps
、tail -f
等。
-
紧急响应:
- 如果问题影响到服务可用性,立即通知相关人员,可能需要临时下线服务或进行紧急维护。
- 考虑是否有快速回滚的方案,比如恢复到上一个稳定版本。
-
问题分析:
- 根据收集的信息,分析可能的原因,包括代码缺陷、配置错误、硬件故障、网络问题等。
- 如果有可疑的变更,检查最近的代码提交、系统更新、配置更改等。
-
解决方案制定:
- 一旦确定了问题原因,制定相应的解决方案。
- 如果需要修复代码,编写相应的补丁并进行测试。
- 如果是配置问题,调整配置并重启服务。
-
问题修复:
- 在测试环境中验证解决方案的有效性。
- 在确认无误后,将解决方案部署到线上环境。
- 监控部署后的系统表现,确保问题已经解决。
-
后续复盘:
- 分析问题的根本原因,总结教训,避免类似问题再次发生。
- 更新文档,包括故障处理流程和已知问题的解决策略。
- 可能需要改进监控和报警机制,以便更快地发现问题。
-
沟通协调:
- 与团队成员沟通问题处理进度和结果。
- 向用户或客户通报问题解决情况,并提供必要的补偿措施。
-
持续改进:
- 根据问题处理的经验,改进开发、测试和部署流程。
- 强化自动化测试和持续集成,减少人为错误。
- 加强性能基线和压力测试,提高系统的鲁棒性。
在整个处理过程中,记录详细的处理步骤和所采取的措施是非常重要的,这有助于未来的故障分析和团队的知识共享。