python3 测试开发工程师面试题

一、python如何查看帮助文档

>>>dir(sys):查看sys模块的方法,只列出方法名;

>>>help("sys"):查看sys模块的详细使用;

在交互解释器下
>>> import sys
>>> sys.modules.keys()

python -m pydoc -p 4567 :表示打开pydoc模块,pydoc是查看python文档的首选工具;-p 4567表示在4567端口上启动server;
在浏览器中访问http://localhost:4567/

在命令行下运行$ pydoc modules


二、list与tuple的区别:
相同点:都可以进行的操作包括索引,切片,加,乘,检查成员,序列的长度,最大元素和最小元素;
list:
1.数据项使用方括号括起来;
2.数据项不需要有相同的类型;
3.可对列表的数据进行修改,更新,删除;

tuple:
1.元组的元素不能修改,删除;
2.元组使用小括号;
3.元组只有一个元素时,需要在元素后面添加逗号,否则括号会被当做运算符使用;

三、sys.path与os.path的区别:
1.os.path 是一个模块,用来处理目录、路径相关的模块。 主要用于对系统路径文件的操作。
2.sys.path 是一个列表,主要是对python解释器的系统环境参数的操作(动态改变python搜索路径)。返回解释器相关的目录列表、环境变量、注册表等初始化。 
信息

四、装饰器的作用和功能:
1.引入日志
2.函数执行时间统计
3.执行函数前预备处理
4.执行函数后的清理功能
5.权限校验等场景
6.缓存

def log(func):
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)
    return wrapper
@log

五、简单谈下GIL:

Global Interpreter Lock(全局解释器锁)

Python代码的执行由Python 虚拟机(也叫解释器主循环,CPython版本)来控制,Python 在设计之初就考虑到要在解释器的主循环中,同时只有一个线程在执行,即在任意时刻,只有一个线程在解释器中运行。对Python 虚拟机的访问由全局解释器锁(GIL)来控制,正是这个锁能保证同一时刻只有一个线程在运行。

六、闭包

内部函数wrap可以引用外部函数memo的参数和局部变量,当memo返回函数wrap时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)

def memo(func):
	cache = {}
	def wrap(*args):
		if args not in cache:
			cache[args] = func(*args)
		return cache[args]
	return wrap
	
@memo

def fib(n):
	if n <= 2:
		return 1
	return fib(n-1) + fib(n-2)
	
if __name__ == "__main__":
	n = int(input("请输入一个整数: "))
	print(fib(n))

七、列表推导式 

[表达式 for 变量 in 列表]    或者  [表达式 for 变量 in 列表 if 条件]

list = [1,2,3,4,5]
print([num**2 for num in list])
print([num*5 for num in list if num > 3])

八、访问限制(python私有变量)

如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问。

class Student(object):

    def __init__(self, name, score):
        self.__name = name
        self.__score = score

    def print_score(self):
        print '%s: %s' % (self.__name, self.__score)

九、Python内置的@property装饰器

    @property最大的好处就是在类中把一个方法变成属性调用,起到既能检查属性,还能用属性的方式来访问该属性的作用

class Student(object):

    @property
    def birth(self):
        return self._birth

    @birth.setter
    def birth(self, value):
        self._birth = value

    @property
    def age(self):
        return 2019 - self._birth

十、python错误处理(异常处理except) 

try:
    print 'try...'
    r = 10 / 0
    print 'result:', r
except ZeroDivisionError, e:
    print 'except:', e
finally:
    print 'finally...'
print 'END'

十一、python 中__new__ 和 __init__ 的区别

         __new__: 创建对象时调用,会返回当前对象的一个实例;

        __init__: 创建完对象后调用,对当前对象做一些实例初始化,无返回值。

class Data(object):
    def __new__(self):
        print("new")
    def __init__(self):
        print("init")

data = Data()

十二、Mysql索引优化   

  1. 全值匹配

  2. 最佳左前缀法则:指查询从索引最左前列开始并且不跳过索引中的列

  3. 不在索引列上做任何操作(计算、使用函数、(自动或手动)类型转换),会导致索引失效而转向全表扫描

  4. 存储引擎不能使用索引中范围条件右边的列

  5. 尽量使用覆盖索引(只访问索引的查询(索引列和查询列一致)),减少select *

  6. mysql在使用不等于(!= 或者<>)的时候无法使用索引导致全表扫描

  7. is null,is not null 也无法使用索引

  8. like以通配符开头('%dgd'),mysql索引失效会变成全表扫描的操作

  9. 字符串不加单引号索引失效

  10. 少用or,用它来连接时索引会失效

  11. 不要过多创建索引,除了增加额外的磁盘空间外,对于DML操作的速度影响很大,因为其每增删改一次就得从新建立索引

SELECT `sname` FROM `stu` WHERE `age`+10=30;-- 不会使用索引,因为所有索引列参与了计算 

SELECT `sname` FROM `stu` WHERE LEFT(`date`,4) <1990; -- 不会使用索引,因为使用了函数运算,原理与上面相同 

SELECT * FROM `houdunwang` WHERE `uname` LIKE'后盾%' -- 走索引 

SELECT * FROM `houdunwang` WHERE `uname` LIKE "%后盾%" -- 不走索引 

-- 正则表达式不使用索引,这应该很好理解,所以为什么在SQL中很难看到regexp关键字的原因 

-- 字符串与数字比较不使用索引; 
CREATE TABLE `a` (`a` char(10)); 
EXPLAIN SELECT * FROM `a` WHERE `a`="1" -- 走索引 
EXPLAIN SELECT * FROM `a` WHERE `a`=1 -- 不走索引 

select * from dept where dname='xxx' or loc='xx' or deptno=45 --如果条件中有or,即使其中有条件带索引也不会使用。换言之,就是要求使用的所有字段,都必须建立索引,我们建议大家尽量避免使用or 关键字 


SELECT `sname` FROM `stu` WHERE LEFT(`date`,4) <1990; — 不会使用索引,因为使用了函数运算,原理与上面相同
SELECT * FROM `houdunwang` WHERE `uname` LIKE’后盾%’ — 走索引
SELECT * FROM `houdunwang` WHERE `uname` LIKE “%后盾%” — 不走索引

-- 如果mysql估计使用全表扫描要比使用索引快,则不使用索引

十三、 python实现字符串反转的几种方法

#第一种方法:切片
s='abcdef'
result = s[::-1]
print(result)

#第二种方法:使用reverse方法
s='abcdef'
l = list(s)
l.reverse()
result = "".join(l)
print(result)


#第三种方法:出栈
>>> def popFunc(s):
...   l = list(s)
...   result = ""
...   while len(l)>0:
...     result += l.pop()
...   return result
...
>>> result = popFunc(s)
>>> print(result)
fedcba

十四、字符串去重

#!/usr/bin/python3


def singleElement(s):
	sets=set(s)    #使用set去掉重复的元素
	lists=list(sets)   #将set转换成list,使用sort方法根据原始s的下标进行排序。list可以用sort方法
	lists.sort(key=s.index)
	print("".join(lists))  #将元素无分隔符连接
	
s="abcd2132oopppdsadjg"
singleElement(s)

十五、 python实现九九乘法表

for i in range(1, 10):
    for j in range(1, i+1):
        result = i * j
        print("%d * %d = % -3d" % (j,i,result),end="\t")
    print()

十六、 python实现冒泡排序

>>> list = [1,3,65,3,7,6,5,10]
>>> for i in range(len(list)-1):
...   for j in range(len(list)-1-i):
...     if list[j] > list[j+1]:
...       list[j],list[j+1] = list[j+1],list[j]
...
>>> list
[1, 3, 3, 5, 6, 7, 10, 65]

十七、 python实现二分查找,二分查找又称折半查找

1. 优点:比较次数少,查找速度快,平均性能好;

2. 缺点:要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。

>>> def binary_search(list, left, right, num):
...   if left > right:
...     return -1
...   mid = (left+right) // 2
...   if num < list[mid]:
...     right = mid -1
...   elif num > list[mid]:
...     left = mid + 1
...   else:
...     return mid
...   return binary_search(list, left, right, num)
...
>>> list = [11,33,32,64,8,94,5,7]
>>> print(list)
[11, 33, 32, 64, 8, 94, 5, 7]
>>> list.sort()  #先对列表进行排序,后执行二分查找
>>> print(list)
[5, 7, 8, 11, 32, 33, 64, 94]
>>> while 1:
...   num = int(input("Please input an int: "))
...   result = binary_search(list,0,len(list)-1,num)
...   print(result)
...   if result == -1:
...     print("Not Found")
...   else:
...     print(result)

十八、 python 字典合并,相同key的value相加,不同可以则保留    

#!/usr/bin/python3
#方法一
x = {'a':1,'b':2,'c':3,'d':4}
y = {'b':3,'d':5,'e':7,'m':9}
from collections import Counter
dict(Counter(x)+Counter(y))
#方法二
>>> def func(dict1, dict2):
...   for i,j in dict2.items():
...     if i in dict1.keys():
...       dict1[i] += j
...     else:
...       dict1.update({f'{i}':dict2[i]})
...   return dict1

>>> x = {'a':1,'b':2,'c':3,'d':4,'dd':'dddd'}
>>> y = {'b':3,'d':5,'e':7,'m':9,'yy':'yyyy'}
>>> print(func(x,y))
{'a': 1, 'b': 5, 'c': 3, 'd': 9, 'dd': 'dddd', 'e': 7, 'm': 9, 'yy': 'yyyy'}

十九、引起系统(app)Crash的原因总结

1. 空指针
2. 野指针
3. 数组下标越界
4. 内存管理错误
5. 逻辑错误
6. 整数除零
7. 缓冲区溢出
8. 对无权限对象进行读写操作
9. 数据库磁盘IO操作异常
10. 死锁
11. 死循环


二十、python实现单例模式

#!/usr/bin/python3

def Singleton(cls):
	_instance = {}
	
	def _singleton(*args, **kwargs):
		if cls not in _instance:
			_instance[cls] = cls(*args, **kwargs)
		return _instance[cls]
	return _singleton
	
@Singleton
class A(object):
	a = 1
	def __init__(self, x=0):
		self.x = x
		
a1 = A(2)
a2 = A(3)
print(a1, a2)
#!/usr/bin/python3

import threading

class Singleton(object):
	_instance_lock = threading.Lock()
	
	def __init__(self):
		pass
		
	def __new__(cls, *args, **kwargs):
		if not hasattr(Singleton, "_instance"):
			with Singleton._instance_lock:
				Singleton._instance = object.__new__(cls)
		return Singleton._instance
		
obj1 = Singleton()
obj2 = Singleton()
print(obj1, obj2)

def task(arg):
	obj = Singleton()
	print(obj)
	
for i in range(10):
	t = threading.Thread(target=task, args=[i,])
	t.start()

二十一、对int类型1234567,进行千分位分隔,输出“1,234,567”

#!/usr/bin/python3


def splitNums(s,mark):
    slist=str(s)[::-1]
    temp=[]
    i = 0
    while i < len(slist):
      temp.append(slist[i:i+3])
      i += 3
    reverse = mark.join(temp)[::-1]
    if s < 0:
      return 'ERROR: n 小于0'
    else:
        return reverse

s=1234567
mark=','
result = splitNums(s,mark)
print(result)

二十二、python3实现多任务线程

#!/usr/bin/python3


import threading
import time

num = 0
lock = threading.Lock() # get locked

def task1(loop):
	global num
	for i in range(loop):
		lock.acquire()  # 加锁
		temp = num
		num = temp + 1
		lock.release()  #解锁
	print("task1: ",num)
	
def task2(loop):
	global num
	for i in range(loop):
		lock.acquire()
		temp = num
		num = temp + 1
		lock.release()
	print("task2: ",num)
	
if __name__ == '__main__':
	thread1 = threading.Thread(target = task1, args=(1000000,))
	thread2 = threading.Thread(target = task2, args=(1000000,))
	thread1.start()
	thread2.start()
	
#	for item in threading.enumerate():
#		print(item)
#threading.enumerate()的使用。此方法返回当前运行中的Thread对象列表
	while len(threading.enumerate()) != 1:
		time.sleep(1)
	print("main: ",num)

  • 4
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值