Python常见的基础面试题(day01)
一.Python程序的执行流程
大致上就是三步:
第一步: 先去查找.pyc文件,如果这个文件的修改时间和源文件的修改时间一致.就直接运行这个文件
第二步:如果这个.pyc文件不存在,或者不是最新版本,就会编译解释源码,然后会根据解释器的设定是否存储编译结果到.pyc文件
第三步:存储编译后的结果到.pyc文件,不更新时间
二.实现异常重试装饰器,一个函数的异常重试的最高次数,并且再执行的时候可以由延时.
思路就是,写一个装饰器,当有异常的时候,根据最高次数,如果还有剩余次数,就先休眠一段时间,然后再执行原来的函数.
# encoding:utf-8
__author__ = 'Fioman'
__time__ = '2019/3/8 12:36'
from functools import wraps
import time
def retry_with_delay(retry=0,delay=0):
def wrap(f):
@wraps(f)
def inner(*args,**kwargs):
nonlocal delay,retry
try:
return f(*args,**kwargs)
except Exception as e:
if retry == 0:
return str(e)
if retry >= 1:
retry -= 1
time.sleep(delay)
return f(*args,**kwargs)
return inner
return wrap
三.给定一个已经排序好的数组,去除数组中的重复元素,只保留一个重复的元素,并且返回新数组的长度.
要求:
不能使用新的数据结构.不要给数组分配额外的空间,你必须使用常量的内存大小进行原地操作.
单层循环使用count.
# encoding:utf-8
__author__ = 'Fioman'
__time__ = '2019/3/8 15:22'
def remove_duplicates(arr):
for i in arr:
if arr.count(i) > 1:
arr.remove(i)
return len(arr)
remove_duplicates([1, 2, 3, 4, 4, 5])
例如:给出已经排序的数组A=[1,1,2],你的函数调用之后必须返回长度length=2,并且A[:2]现在变成[1,2]
使用enumerate()带下标的循环实现版本
# encoding:utf-8
__author__ = 'Fioman'
__time__ = '2019/3/8 13:00'
# 思路,外层循环遍历所有的元素
# 内层循环让这个元素跟后面的元素逐个进行,比较,如果发现相同的,就移除掉.
def remove_duplicates(arr):
for i,value in enumerate(arr):
if i == len(arr): # 如果是最后一个元素,内层循环就没有必要了
break
for j,e in enumerate(arr):
if e == value and j != i:
del arr[j]
return len(arr)
A = [1,1,2,2,3]
length = remove_duplicates(A)
print(length,A[:2])
注意,这里必须使用del arr[index]的方式实现
使用remove实现,比较麻烦,因为remove是删除第一个遇到的元素.我们使用pop来实现以下.
def remove_duplicates(arr):
for i in arr:
for j in arr:
if j == i and arr.index(i) != arr.index(j):
arr.pop(arr.index(j))
return len(arr)
A = [1,1,2,2,3]
length = remove_duplicates(A)
print(length,A[:2])
这段代码并不行,因为arr.index()是获取的这个元素第一次出现的下标,必须获取当前下标才可以.还有一种方法就是删除第一个重复的元素.
def remove_duplicates(arr):
for i in arr:
for j in range(arr.index(i) + 1,len(arr)):
if j == i:
arr.pop(arr.index(j))
return len(arr)
A = [1,1,2,2,3]
length = remove_duplicates(A)
print(length,A[:2])
这种方式也是可以的,也就是说遍历所有的它后面的元素,然后又重复的就删除重复的.当然这个版本的也可以使用 remove
def remove_duplicates(arr):
for i in arr:
for j in range(arr.index(i)+1,len(arr)):
if j == i:
arr.remove(j)
return len(arr)
A = [1,1,2,2,3]
length = remove_duplicates(A)
print(length,A[:2])
四.利用List来模拟栈的push和pop操作
# encoding:utf-8
__author__ = 'Fioman'
__time__ = '2019/3/8 13:54'
# 首先要明白什么是栈,栈是后进先出的数据结果.
# 一般栈里面有的方法是,压栈,出栈,查看栈是否是空,获取栈顶元素,查找对象所在栈的位置.
class Stack(object):
def __init__(self):
self.stack = []
# 判断栈是否是空
def empty(self):
return len(self.stack) == 0
# 获取栈顶元素
def peek(self):
return self.stack[-1] if not self.empty() else None
# 压栈
def push(self,data):
self.stack.append(data)
# 弹栈
def pop(self):
return self.stack.pop() if not self.empty() else None
# 查找对象在栈中的位置,注意这里对象一般是不重复的
def search(self,obj):
return self.stack.index(obj) if not self.empty() else None
拓展, 利用栈来模拟队列
# encoding:utf-8
__author__ = 'Fioman'
__time__ = '2019/3/8 14:17'
# 和栈类似,唯一不同的就是队列是先进先出
class Queue(object):
def __init__(self):
self.L = []
# 判断队列是否是空
def empty(self):
return len(self.L) == 0
# 获取队列的首元素
def peek(self):
return self.L[0] if not self.empty() else None
# 加入队列
def add(self,data):
self.L.append(data)
# 移除队列元素
def poll(self):
if not self.empty():
return self.L.pop(0)
return None
五.给定一个非负的整数i,求它的二进制数中的1的个数.
思路,先转换为二进制字符串格式,使用count统计1的个数
# encoding:utf-8
__author__ = 'Fioman'
__time__ = '2019/3/8 14:24'
# 例如num = 20 它的二进制格式是 21 = 16 + 4 + 1 0001 0101
def count_num(num,dup):
return bin(num).count(str(dup))
if __name__ == '__main__':
num = 21
print(count_num(num,1))
bin(num).count(str(1))
六.给出以下代码的输出结果
# encoding:utf-8
__author__ = 'Fioman'
__time__ = '2019/3/8 14:32'
a = [[0]*3 for i in range(3)] # 一个序列和数字相乘表示的是,以相同的元素扩展这个序列
b = a[:] # 切片是浅拷贝,不影响原来的序列.所以这里a 和 b不是同一个对象
a[1][2] = 666 # a里面存放的是列表的引用,当其值改变的时候,因为b也是这个列表的引用.所以也会改变
print(a) # [[0,0,0],[0,0,666],[0,0,000]]
print(b) # [[0,0,0],[0,0,666],[0,0,666]]
print(a[0] is b[0]) # 因为a[0] 和 b[0]指向的是同一对象,所以地址是相同的
print(a is b) # 因为a和b是两个不同的对象,所以a和b是不同的
七.使用元类实现单例模式
思路:1. 增加一个属性_instance
,因为每次创建对象的时候相当于是调用了元类的__call__
方法.
2: 所以我们在元类中的__call__中获取这个这个属性,如果是None,就创建一个对象,如果存在就直接使用
# encoding:utf-8
__author__ = 'Fioman'
__time__ = '2019/3/10 15:22'
from threading import RLock,Thread
mutex_lock = RLock()
class SingletonMetaClass(type):
def __init__(self,*args,**kwargs):
self._instance = None
super().__init__(*args,**kwargs)
def __call__(self, *args, **kwargs):
if self._instance is None:
with mutex_lock:
if self._instance is None:
self._instance = super().__call__(*args,**kwargs)
return self._instance
class A(metaclass=SingletonMetaClass):
pass
if __name__ == '__main__':
a = A()
print(a)
for i in range(10):
t = Thread(target=lambda:print(A()),args=() )
t.start()
八.代码实现计算1到100之间,所有奇数的和.
方法1: 使用循环
ret = 0
for i in range(1,101):
if i % 2 != 0:
ret += i
print(ret)
使用sum函数
ret = sum([i for i in range(1,101) if i % 2 != 0])
print(ret)
九.for和while中的else是什么意思,什么时候会使用到for...else和whiel...else
当for和while使用else的时候,当循环顺利执行完,不是通过break语句跳出循环的时候就会执行else.
# encoding:utf-8
__author__ = 'Fioman'
__time__ = '2019/3/10 16:35'
for i in range(10):
print(i)
if i % 2 == 0:
continue
else:
print('循环顺利遍历完毕,没有通过break跳出,这里会执行')
for i in range(10):
if i % 2 != 0:
break
else:
print('通过break退出来了,else分支不会执行')
for i in range(10):
print(i)
continue
break
else:
print("这里也会打印,break,相当于是不会执行!")
十.代码实现:统计一篇文章中,每个单词出现的个数?
通过字典加for循环的方式
# encoding:utf-8
__author__ = 'Fioman'
__time__ = '2019/3/10 16:55'
import re
def count_words(article):
# 1.先将单词分割
word_list = re.split('[ ,.?!]',article)
d = {}
for word in word_list:
if word not in d:
d[word] = 1
else:
d[word] += 1
return d
if __name__ == '__main__':
article = 'I am a student,who are you ,I am a boy just so so so,hei hei.' \
'? I just know ? shit!'
d = count_words(article)
for key ,value in d.items():
print('单词{}出现的次数是{}'.format(key,value))
先去重复,然后使用count组合成元组
def count_words2(article):
word_list = re.split('[ ,.?!]',article)
word_set = set(word_list)
ret = [(word,word_list.count(word)) for word in word_set]
return ret
if __name__ == '__main__':
article = 'I am a student,who are you ,I am a boy just so so so,hei hei.' \
'? I just know ? shit!'
l = count_words2(article)
for item in l:
print('{}出现的次数是{}'.format(item[0],item[1]))