Python常见的基础面试题(day01)

2019-03-11  本文已影响0人  莫辜负自己的一世韶光

一.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]))
上一篇 下一篇

猜你喜欢

热点阅读