持续更新ing 软件测试面试常见问题总结( 三 )


作用:当出现一个完整任务里因意外状况只执行了一半的情况时,会回滚到事务未执行前
(2)一致性:一致性是指在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏 。这是说数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性 。
作用:比如从同一个银行一个账户向另一个账户转账的事务,要保证银行中的总金额保持不变的约束条件
(3)持久性:持久性即当一个事务提交后,对数据库的改变是永久性的,不会被回滚 。
实际实现事务对数据库的改变时,会首先写入事务日志 。如果数据库发生意外,重启服务后会首先检查日志,将应做却没做的改变持久化到数据库 。
(4)隔离性:事务隔离性是指多个事务并发执行时,相互之间无影响 。
数据库通过分事务隔离级别来避免事务之间的影响(脏读、不可重复读、幻读、丢失更新)
隔离级别(由低到高):未提交读、已提交读、可重复读、可串行读
具体实现而言,数据库通过锁来实现隔离级别 。
参考:数据库事务1
【持续更新ing软件测试面试常见问题总结】数据库事务2
3.数据库语句
详见Mysql数据库的使用

持续更新ing  软件测试面试常见问题总结

文章插图
五、数据结构类 1.队列和栈的区别,如何用栈实现队列?
队列:先入先出,从一端进,从另一端出 。list.()在列表尾部添加新值,list.pop(0)从列表开头弹出旧值 。这样的形式就是队列的结构 。中也有专门的队列格式,即deque 。
栈:后入先出,只能从一端进出 。在中的列表的默认结构就是类似栈的结构,list.()在列表尾部添加新值,list.pop()从列表末尾弹出旧值 。
栈实现队列:利用双重栈思想 。以列表模拟栈,添加新值到列表A中,再将A的值pop出作为列表B的新值,如此一来,B pop弹出的值的顺序就和添加新值到A的顺序一致了 。
2.链表 六、编程类 1.判断一个数组是不是另一个数组的全排列且不相同,是则返回True,不是则返回False 。
def judge(A:list,B:list):if A ==B:return Falseelse:A.sort()B.sort()if A ==B:return Trueelse:return Falseif __name__ =='__main__':A =['a','b','b','c']B =['a','b','c']print(judge(A,B))
这里有一个很容易出错的问题,我面试的时候就是这个地方出问题却没发现:
列表的排序有两种方法,其中[xxx].sort()改变的列表本身,而不会返回一个新的值,所以用new ==[xxx].sort()得到的结果其实是None 。
另外一种是([xxx]),这种方法会产生一个新的值,需要赋值使用 。
2.跳台阶问题
一只青蛙一次可以跳上1级台阶,也可以跳上2级 。求该青蛙跳上一个 n 级的台阶总共有多少种跳法(先后次序不同算不同的结果) 。
class Solution:def jumpFloor(self, number):if number<= 2:return numberfOne =1fTwo =2for i in range(number-2):fNew =fOne+fTwofOne =fTwofTwo =fNewreturn fNew
思路:n阶台阶,因为只有两种跳法,所以总次数f(n) =f(n-1)+f(n-2) 。
实际到代码层面,因为f(n) =f(n-1)+f(n-2),f(n-1) =f(n-2)+f(n-3)…直到最后f(3) =f(2)+f(1),此为最小单位 。于是我们从最小单位开始算,fOne和fTwo的初始值1,2为最小单位,两者之和作为新的fTwo,原本fTwo的值作为新的fOne的值,这样就是f(4) =f(3)+f(2)…如此类推 。循环n-2次后就得到了总次数 。
注意:这个问题其实也可以用递归来写,思路会简单很多,但是递归会消耗大量资源,时间复杂度太高,在有要求的笔试中是不会通过的 。