初、中、高级测试工程师面试题汇总(附答案)
2020-12-11 16:20 misswjr 阅读(1228) 评论(0) 编辑 收藏 举报【热身题】
1.为什么选择测试这行?
因为其具有挑战性和成就感,找一些系统隐藏的逻辑漏洞的时候,自己就非常的开心。并且测试需要细心和耐心,自己可以很快的分析bug的来源。
2.请描述下你公司的测试流程?
需求分析讨论-确定测试策略-设计测试用例-测试用例评审-beta测试-uat测试-测试报告
【基础题】
1.软件测试项目从什么时候开始为什么?
需求确认开始,因为在需求阶段,测试可以评审需求并进行静态测试,减少开发过程中的bug。
2.软件的评审一般由哪些人员参加?其目的是什么?
参加人员:需求业务人员、产品经理、项目经理、开发人员、测试人员;
目的:查看软件在未正式投入运行前是否还存在问题。对于不同软硬件平台能否正常运行,是否有与客户理解不一致的地方,同时可以对一些可以改进的地方再多加改进。
3.如何设计测试用例?什么样子的测试用例是好用例?
掌握边界值分析、等价类划分、错误推测等方法来设计测试用例。
好用例是一个完备的集合,它能够覆盖所有等价类以及各种边界值;需要从软件功能需求出发,全面地,无遗漏地识别出测试需求;最好是代码覆盖测试也全面的测试。
4.不能发现BUG的测试用例不是好的测试用例吗?
不一定,要看情况,如果测试用例质量高,没有发现bug,说明开发质量高。但一般程序都会有bug,如果没有发现BUG,就要思索测试场景是否有遗漏,需求是否理解没到位。
5.测试用例需要哪些人来评审?
产品经理,开发人员,测试人员,业务需求人员。
6.什么是bug?
没有实现需求说明书列出的功能,出现了没有需求说明书提到不该出现的事情;实现了多的功能;没有实现应该实现的逻辑。
7.简单概述缺陷报告,并说明包括哪些项?
缺陷描述,缺陷的优先级,缺陷的标题,缺陷所属版本号,缺陷所属的功能模块,操作步骤,预期效果,缺陷原因,缺陷所属的开发人员。
8.开发人员修复缺陷后,如何保证不影响其他功能?
重新执行测试用例,并且针对这个缺陷影响的相关点写新的测试用例。
9.开发人员说不是bug时,你如何应付?
首先把自己的理由,并以需求说明书为自己的站点,如果开发人员还是不认同,可以把自己的观点和理由,提交给产品经理,由其去决定是否为一个bug。
10.当测试过程发生错误时,有哪几种解决办法?
a.跳转其他的测试流程;
b.调用某个程序能绕过这个错误,继续后面的流程。
11.所有的软件缺陷都能修复吗?所有的软件缺陷都要修复吗?
能修复,但不一定所有的缺陷都要修复。
12.进行测试时产生了哪些文档或记录?
测试用例,测试报告,测试日报
14.功能测试在 beta 版本对外的上线标准是什么?
测试用例全部跑完并且bug都已经关闭,然后业务验收后可以上线。
15.开发人员老是犯一些低级错误怎么解决?
a.要求开发人员进行自测,把这些问题在开发阶段就解决好
b.通过缺陷管理系统对开发人员进行控制
16.为什么尽量不要让时间富裕的员工去做一些测试?
a.非专业测试人员,没有组织性的测试工作,没有规律和针对性,会影响到测试的质量和版本更新的速度。
b.专业测试人员(但不是这个项目的测试员)这些人员不受测试计划的时候和任务约定,测试完毕后评估测试小组的工作质量,不利于bug管理。
【进阶题】
1.什么是单元测试、功能测试、集成测试?
加分项:单元测试、功能测试、集成测试分别在web端、接口端、移动端的定义,你平时是怎么理解它们的?
单元测试:是针对程序模块来进行正确性检验的测试工作;
功能测试:在单元测试的基础上,测试某一个功能点;
集成测试:将所有模块按照设计要求组装成为子系统或系统,进行集成测试;
web端
单元测试/功能测试:页面元素是否正确显示其有效功能,如提交的action是否正确,搜索点击是否执行;
集成测试:调用了后端接口的数据是否显示正常,能否满足需求;
接口端:模块/系统之前的调用,接口是否与设计相符,模块组合后是否满足需求;
单元测试:某个函数/方法 写的代码是否达到编写者的预期;
功能测试:为实现一个功能点,调用几个方法/函数。
2.什么是兼容性测试?
兼容性测试是检查软件在不同软件平台,硬件平台上是否可以正常运行的测试。
主要查看软件在不同操作系统、浏览器、数据库中是否运行正常.
3.白盒和黑盒的区别,你是怎么运用的?
黑盒测试:已知产品的功能设计规格,可以进行测试证明每个实现了的功能是否符合要求。利用其检查功能是否符合需求说明书,能够正常使用。
白盒测试:已知产品的内部工作过程,可以进行测试证明每种内部操作是否符合设计规格要求,所有内部成分是否经过检查。
利用其检查程序模块的内部逻辑走向,主要覆盖程序内的逻辑。
4.静态测试和动态测试有什么区别?
静态测试:不运行程序,针对PRD等检查代码,审查代码,静态结构分析,分析代码质量;
动态测试:运行程序进行黑盒测试和白盒测试。
5.您所熟悉的测试用例设计方法都有哪些?请分别以具体的例子来说明这些方法在测试用例设计工作中的应用。
黑盒:
边界值分析法:如参数的范围0-128,输入128,129,0这些值,查看是否有错误等;
错误推测法:导入功能时,表格为空表格,表格输入1行,表格输入10000行等;
因果图方法:组合参数逻辑图;
场景分析法:根据用户操作模拟用户操作。
白盒:
逻辑覆盖法,基本路径测试。
6.您在以往的测试工作中都曾经具体从事过哪些工作?其中最擅长哪部分工作?
做过web测试,小程序测试,H5页面测试,后台测试,接口测试。最擅长接口测试,自己给公司的业务流程写过一套自动化框架,用于回归业务流程。
7.在您以往的工作中,一条软件缺陷(或者叫Bug)记录都包含了哪些内容?如何提交高质量的软件缺陷(Bug)记录?
前提条件、测试环境、操作步骤、预期结果、实际结果、严重等级、版本信息,出现概率;
问题描述和操作步骤要尽可能描述详细,可以初步分析bug是客户端的问题还是服务端的问题。
8.什么是内存泄漏、Http错误率、吞吐率。响应时间分别在web端和移动端是多少?哪些场景可以证明响应超时?
内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。
HTTP错误率(HTTP error rate) 在选定时间段内,HTTP错误数量与请求数量的比率。
吞吐率(Throughput) 是场景运行过程中服务器每秒的吞吐量。其度量单位是字节,表示每个请求连接在任何给定的每一秒从服务器获得的数据量。
web端
当用户在2秒以内得到响应时,会感觉系统的响应很快;
当用户在2-5秒之间得到响应时,会感觉系统的响应速度还可以;
而当用户在超过8秒后仍然无法得到响应时,会感觉系统糟透了,或者认为系统已经失去响应。
场景:请求超时、页面加载失败
【高级题】
1.什么是面向对象编程?
面向对象编程就是把具有共性的事务抽象成属性和方法来进行编程。
2.Thread 类中的start() 和 run() 方法有什么区别?
start()方法可以用来启动线程,调用该方法,会创建一个新的线程,然后内部执行run()方法;不能多次调用,否则会抛异常;
直接调用run()方法,不会创建新的线程;可以进行多次调用。
3.说下左连接和右连接
比如有两张表 A,B。左连接是把符合条件的所有A表的内容列出来,B表如果没有内容匹配用NULL代替。
右连接是符合条件的所有B表的内容列出来,A表如果没有内容匹配用NULL代替。
4.介绍下什么是索引
索引是由表或者视图中的一列或多列生成的键,可以加快在表或者视图中检索行的速度
【接口测试相关】
1.什么是接口测试?
接口测试是测试系统组件间接口的一种测试。接口测试就是测试不同系统或模块之间资源交互是否正确。
2.为什么要做接口测试?
因为在大部分系统和产品中,资源数据都是核心,所以接口是需要要测试的,并且接口中大部分内容都是数据,通过数据的对比可以推测系统和产品的逻辑,测试接口就是测试逻辑。所以很必要做接口测试。
3.什么时候做接口测试?
a.出现bug,通过接口测试,清晰找到bug的源头,是前端还是后端的bug;
b.回归测试,利用接口测试原有的接口是否正常,保证之前的业务流程没有受影响;
c.接口开发完成后,可以做接口测试。
4.接口测试的工具有哪些
soapUI、postman、jemeter、insomnia、paw。
5.接口测试的流程是什么?
a.接口的通过性验证:数据正确输入,是否正确返回结果。测试接口的正常场景和异常场景;
b.边界测试:不按照你接口文档上的要求输入参数,测试其边界情况。比如说必填的参数不填,输入整数类型的正常,超过参数取值范围等;
c.参数组合:如果接口中有参数需要组合用的,两个参数是组合使用,测试其各种情况;
d.异常验证:测试幂等情况,并发情况,事务测试等异常情况;
e.接口安全:绕过验证,敏感信息加密等情况;
f.性能测试:响应时间、并发数、吞吐量、服务器资源利用率。
6.请问你们公司是如何做接口测试的?
swagger 、 接口自动化脚本。
7.接口测试质量评估标准是什么?
接口表现与接口文档的一致性;
请求参数:必选和非必选、长度、字符类型、为空、缺失、组合、重复;
返回数据:正常和异常。
【自动化测试相关】
1.如何看待自动化和手动测试?怎样的一个比例才是健康的?
自动化适合做为回归测试的主要方式,新上线的功能一般都是用手动测试方式,一些极端和用户习惯操作还是手动测试比较方便。尽可能线上稳定的功能模块都做成自动化,提供效率。
2.你们公司的自动化投入产出比怎样?效益怎样?
自动化主要作为回归测试,减少测试时间。UI自动化没有弄,基本找不到bug 。
3.完整运行一次自动化用例需要多久时间?
主要跑的是业务流,所以跑一次需要半个小时左右。
4.什么是分层自动化?
金字塔结构, 最底层UnitTest,往上接口API/集成起来的service, 最上面UI自动化。
5.你的测试数据是怎么准备的?
提前准备好,在代码里的yaml文件。
6.测试脚本的维护成本是怎么样的?
业务不变的情况下,一般脚本都是不坏不动的。
【性能测试相关】
1.请问你们公司是如何做性能测试的?请讲诉性能测试的相关指标?
a.做性能需求分析,挑选了用户使用最频繁的功能来做性能测试,比如:登陆,搜索,提交订单,确定性能指标,比如:事务通过率为100%,90%的事务响应时间不超过5秒,并发用户为1000人,CPU和内存的使用率为70%以下;
b.性能测试计划,明确测试时间(通常在功能稳定后,如第一轮测试后进行)和测试环境和测试工具的选择;
c.编写性能测试用例;
d.搭建性能测试环境,准备好性能测试数据;
e.通过性能测试用例,编写性能测试脚本;
f.性能测试脚本进行调优,设置检查点、参数化、关联、集合点、事务,调整思考时间,删除冗余的脚本等;
g.设计性能测试场景,使用nmon工具监控服务器,运行测试场景;
h.分析性能测试结果,如果有问题(性能瓶颈),收集相关的日志提单给开发修改;
i.开发修改好后,回归性能测试;
j.编写性能测试报告;
相关指标:响应时间、并发数、吞吐率、资源利用率、TPS。
2.压力测试和负载测试的区别
负载测试是模拟实际软件系统所承受的负载条件的系统负荷,通过不断加载(如逐渐增加模拟用户的数量)或其它加载方式来观察不同负载下系统的响应时间和数据吞吐量、系统占用的资源(如CPU、内存)等,以检验系统的行为和特性,以发现系统可能存在的性能瓶颈、内存泄漏、不能实时同步等问题。
压力测试是在高负载情况下对系统的稳定性进行测试。是在高负载(大数据量、大量并发用户等)下的测试,观察系统在峰值使用情况下的表现,从而发现系统的功能隐患。
负载测试:多用户,用户数渐增,持续同时发同一业务请求,产出最大TPS;
压力测试:多用户,资源使用饱和,持续同时发同一业务请求,产出系统瓶颈或使用极限。
3.服务器中一般要监控哪些数据,如何监控的,怎么从监控数据中发现问题?
基础监控和应用监控。
基础监控包括机器是否死机,cpu,内存,磁盘使用率等;应用监控包括日志监控、端口监控、进程数监控等。
4.假设系统A调用系统B,我把B的接口都mock了,进行性能测试,这样有什么好处和坏处?
好处:防止系统B出错引起测试错误;不会因系统B的开发进度影响测试;mock后可以快速返回结果,提高测试效率。
坏处:很多情况下无法完全模拟出服务器的所有可能的返回情况,另外,mock掉了关联方之后,整个环境的连通性可能测试的不到位。
5.有一天早上打车高峰,滴滴服务端挂了大概30分钟,工程师抢修之后,马上上线,之后又挂了,请问有哪些原因会造成这个情况?
服务器内存不够、服务器超出负载、并发量太大、遇到恶意攻击。
【编程相关】
1.请写出冒泡排序。
#冒泡排序:n*n def bubbleSort(array): maxindex = len(array)-1 maxValue = array[maxindex] k=0 while maxindex: for i in range(1,maxindex): if array[i-1]>array[i]: temp = array[i] array[i] = array[i-1] array[i-1] = temp k+=1 maxindex -=1 print(k) return array
2.1~9999数列中数字3出现的次数。用递推方法解出。
def count_digit(number): return len(str(number)) def countThree(digit): if not isinstance(digit,int): raise TypeError('number is not int') # digit = len(str(number)) if(digit <=0): return 0 if(digit ==1): return 1 return 10*countThree(digit-1) + 10 **(digit-1) print(countThree(count_digit(9999)))
3.从一个数组中找出前4个最大的数,用最优解。
#快速排序:最快的n*logN def qiuckSort(list): if len(list)<2: return list mid = list[0] left = [i for i in list[1:] if i <= mid] right = [i for i in list[1:] if i > mid] finallyList = qiuckSort(left)+[mid] + qiuckSort(right) return finallyList array = [3, 0, 1, 832,23,45, 5, 5, 6,46, 9, 56, 897] print(qiuckSort(array)[-4:])
4.写一段程序,删除字符串a中包含的字符串b,举例 输入a = "asdw",b = "sd" 返回 字符串 “aw”,并且测试这个程序。
def delBString(a,b): if not isinstance(a,str): raise TypeError("a is not str") if not isinstance(b,str): raise TypeError("b is not str") if len(a) < len(b): raise Exception('a length must large to b length') result = [] flag = False i=0 la = len(a) lb = len(b) while i <la: j = 0 while j < lb: if i+j < la and a[i+j] == b[j]: j += 1 else : j += 1 flag = False break flag = True if flag: i += lb else: result.append(a[i]) i += 1 return "".join(result)
测试用例: class TestdelInnerStringFunctions(): def setUp(self): pass def tearDown(self): pass def test_nomorl1(self): assert delBString('asdqwe','we') == 'asdq' def test_nomorl2(self): assert delBString('asdqwe','0') == 'asdqwe' def test_nomorl3(self): assert delBString('测试asdqwe','we') == '测试asdq' def test_nomorl4(self): assert delBString('测试asdqwe','测试') == 'asdqwe' def test_nomorl5(self): assert delBString('asdqwe','') == 'asdqwe' def test_nomorl6(self): with pytest.raises(TypeError): delBString('', 0) def test_nomorl7(self): with pytest.raises(TypeError): delBString(0, 'as') def test_nomorl8(self): with pytest.raises(TypeError): delBString(True) def test_nomorl9(self): with pytest.raises(Exception) as excinfo: delBString('acd','acde') assert "a length must large to b length" in str(excinfo.value) assert excinfo.type == Exception
5.写一个方法,把字符串转为数字,比如 str="1234",变成 int 1234。并且测试这个程序。
def StrToInt(a): res ,mult,flag = 0,1,1 if not isinstance(a,str): raise TypeError("a is not str") if a[0] =='-' or a[0] == '+': if a[0] == '-': flag = -1 a = a[1:] for i in range(len(a)-1,-1,-1): if '9' >=a[i] >= '0': res +=(ord(a[i]) -48) * mult mult = mult *10 else : return 0 return res * flag def test_strToInt2(self): with pytest.raises(TypeError): StrToInt(34)
测试用例: def test_strToInt3(self): assert StrToInt('测试赛') == 0 def test_strToInt4(self): assert StrToInt('+2147689') == 2147689 def test_strToInt5(self): assert StrToInt('45') == 45 def test_strToInt6(self): assert StrToInt('1a33') == 0 def test_strToInt7(self): assert StrToInt('-5') == -5
6.给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
# Python def TargetSum(nums,target): if len(nums) < 2: return 0 for i in range(0,len(nums)-1): for j in range (i+1,len(nums)): if nums[i] + nums[j] == target: return [i,j]
# 测试用例 def test_TargetSum1(self): assert TargetSum([1,1,3,6,0,2],2) == [0,1] def test_TargetSum2(self): assert TargetSum([1],1) == 0 def test_TargetSum3(self): assert TargetSum([6,2,4,3,1,2],4) == [1,5] def test_TargetSum4(self): assert TargetSum([2, 7, 11, 15],9) == [0,1]
// Java public int[] TargetSum(int nums[],int target){ Map<Integer, Integer> map = new HashMap<>(); for(int i=0;i<nums.length;i++){ int temp = target - nums[i]; if(map.containsKey(temp)){ return new int[] { map.get(temp), i }; } map.put(nums[i],i); } return null; }
7.给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。
''' 说明: 返回的下标值(index1 和 index2)不是从零开始的。 你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。 示例: 输入: numbers = [2, 7, 11, 15], target = 9 输出: [1,2] 解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。 ''' ## python class Solution(object): def twoSum(self, numbers, target): l=0 r=len(numbers)-1 while(l<r): if(numbers[l]+numbers[r]== target): return [l+1,r+1] if(numbers[l]+numbers[r] <target): l += 1 else: r -= 1 ## 测试用例: def test_towSum1(self): assert towSum([0,1, 1, 2, 3, 6,8], 2) == [1, 4] def test_towSum2(self): assert towSum([1,2,5,6,12], 13) == [1, 5] def test_towSum3(self): assert towSum([2, 7, 11, 15], 9) == [1, 2]
## Java public int[] twoSum(int[] numbers, int target) { int left = 0; int right = numbers.length - 1; while (left < right) { if (numbers[left] + numbers[right] == target) { return new int[]{left + 1, right + 1}; } if (numbers[left] + numbers[right] < target) { left += 1; } else { right -= 1; } } return null; }
8.假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?注意:给定 n 是一个正整数。
''' 示例 1: 输入: 2 输出: 2 解释: 有两种方法可以爬到楼顶。 1. 1 阶 + 1 阶 2. 2 阶 示例 2: 输入: 3 输出: 3 解释: 有三种方法可以爬到楼顶。 1. 1 阶 + 1 阶 + 1 阶 2. 1 阶 + 2 阶 3. 2 阶 + 1 阶 ''' Python ## 不推荐 效率极低 ## def setpMethod(num): if(n == 1 or n == 2): return n else: return self.setpMethod(num-1)+self.setpMethod(num-2) ## 推荐写法 ## def climbStairs(self, n): if(n == 1 or n == 2): return n num1=1 num2=2 while(n >= 3): result = num1 + num2 num1 = num2 num2 = result n -=1 return result ## Java ## public int setpMethod(int n){ if(n ==1 || n ==2){ return n; } int result = 0,n1 = 1,n2 = 2; while (n>=3){ result = n1 + n2; n1 = n2; n2 = result; n--; } return result; }
9.给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个位置。
''' 示例 1: 输入: [2,3,1,1,4] 输出: true 解释: 从位置 0 到 1 跳 1 步, 然后跳 3 步到达最后一个位置。 示例 2: 输入: [3,2,1,0,4] 输出: false 解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。 ''' ## python ## class Solution(object): def canJump(self, nums): need = 1 if(len(nums) ==1): return True if(nums[0] == 0): return False for i in range(len(nums)-2,-1,-1): if(nums[i] == 0 or nums[i] < need): need += 1 else: need = 1 if(need == 1) : return True else: return False ## java ## public boolean canJump(int[] nums) { int n = 1; if(nums.length ==1){ return true; } if(nums[0] == 0){ return false; } for(int i=nums.length-2; i>=0; i--){ if(nums[i] >= n){ n=1; }else{ n++; } } if(n == 1){ return true; }else{ return false; } }
10.以 Unix 风格给出一个文件的绝对路径,你需要简化它。或者换句话说,将其转换为规范路径。
在 Unix 风格的文件系统中,一个点(.)表示当前目录本身;此外,两个点 (..) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。
更多信息请参阅:Linux / Unix中的绝对路径 vs 相对路径.
请注意,返回的规范路径必须始终以斜杠 / 开头,并且两个目录名之间必须只有一个斜杠 /。最后一个目录名(如果存在)不能以 / 结尾。此外,规范路径必须是表示绝对路径的最短字符串。
示例 1: 输入:"/home/" 输出:"/home" 解释:注意,最后一个目录名后面没有斜杠。 示例 2: 输入:"/../" 输出:"/" 解释:从根目录向上一级是不可行的,因为根是你可以到达的最高级。 示例 3: 输入:"/home//foo/" 输出:"/home/foo" 解释:在规范路径中,多个连续斜杠需要用一个斜杠替换。 示例 4: 输入:"/a/./b/../../c/" 输出:"/c" 示例 5: 输入:"/a/../../b/../c//.//" 输出:"/c" 示例 6: 输入:"/a//b////c/d//././/.." 输出:"/a/b/c"
##python## def simplifyPath(self, path): """ :type path: str :rtype: str """ paths = path.split('/') str = '' pathlist = [i for i in paths if I] result = [] for j in range(len(pathlist)): print(j) if(pathlist[j] == ".."): if(result): result.pop() elif(pathlist[j] == "."): continue else : result.append(pathlist[j]) if not result: return '/' for k in range(len(result)): str = str + '/' + result[k] return str
11.给定一个字符串 (s) 和一个字符模式 (p) ,实现一个支持 '?' 和 '' 的通配符匹配。'?' 可以匹配任何单个字符。'' 可以匹配任意字符串(包括空字符串)。两个字符串完全匹配才算匹配成功。
说明: s 可能为空,且只包含从 a-z 的小写字母。 p 可能为空,且只包含从 a-z 的小写字母,以及字符 ? 和 *。 示例 1: 输入: s = "aa" p = "a" 输出: false 解释: "a" 无法匹配 "aa" 整个字符串。 示例 2: 输入: s = "aa" p = "*" 输出: true 解释: '*' 可以匹配任意字符串。 示例 3: 输入: s = "cb" p = "?a" 输出: false 解释: '?' 可以匹配 'c', 但第二个 'a' 无法匹配 'b'。 示例 4: 输入: s = "adceb" p = "*a*b" 输出: true 解释: 第一个 '*' 可以匹配空字符串, 第二个 '*' 可以匹配字符串 "dce". 示例 5: 输入: s = "acdcb" p = "a*c?b" 输入: false
##python## def isMatch(self, s, p): si, pi, pj, sj = 0, 0, -1, -1 while si < len(s): if pi < len(p) and p[pi] == '*': pi += 1 pj = pi sj = si elif pi < len(p) and (p[pi] == '?' or p[pi] == s[si]): pi += 1 si += 1 elif pj != -1: pi = pj sj += 1 si = sj else: return False while (pi < len(p) and p[pi] == '*'): pi += 1 return pi == len(p)
12.给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例: 输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8 原因:342 + 465 = 807
## python ## class Solution(object): def addTwoNumbers(self, l1, l2): n =l1.val + l2.val l3 = ListNode(n%10) l3.next = ListNode(n//10) p1 = l1.next p2 = l2.next p3 = l3 while True: if p1 and p2: sum = p1.val+ p2.val + p3.next.val p3.next.val = sum % 10 p3.next.next = ListNode(sum//10) p1 = p1.next p2 = p2.next p3 = p3.next elif p1 and not p2: sum = p1.val + p3.next.val p3.next.val = sum %10 p3.next.next = ListNode(sum // 10) p1 = p1.next p3 = p3.next elif not p1 and p2: sum = p2.val +p3.next.val p3.next.val = sum % 10 p3.next.next = ListNode(sum // 10) p2 = p2.next p3 = p3.next else : if p3.next.val == 0: p3.next = None break return l3