python面试题1

1.在python中,如何交换两个变量的值?
这个问题,考了python特殊的语法,也就是a, b = b, a,这个表达式,也是其他语言所没有的,是只有python自带的。

2. 字符串的拼接–如何高效的拼接两个字符串?
我们都知道python中,拼接字符串可以用”+”来拼接,然而这个方法并不是高效的,因为如果需要拼接的字符串有很多(n个)的情况下,使用”+”的话,python解释器会申请n-1次内存空间,然后进行拷贝,因为字符串在python中是不可变的,所以当进行拼接的时候,会需要申请一个新的内存空间。所以,正确答案是,使用.join(list),因为它只使用了一次内存空间。

3. list = [a,a,a,1,2,3,4,5,A,B,C]提取出”12345”
这个考点考了python的解压赋值的知识点,即 a,b,c,*middle, e,f,g = list, *middle = [1,2,3,4,5]。注意,解压赋值提取出来的是列表。

4. python的面向对象?
类是对象的蓝图和模板,而对象是类的实例。类是抽象的概念,而对象是具体的东西。在面向对象编程的世界中,一切皆为对象,对象都有属性和行为,每个对象都是独一无二的,而且对象一定属于某个类(型)。当我们把一大堆拥有共同特征的对象的静态特征(属性)和动态特征(行为)都抽取出来后,就可以定义出一个叫做“类”的东西。面向对象有三大支柱:封装、继承和多态。

5. 什么是元类?
同上,我们讲到在python中皆为对象,而元类即是用来创建类的”东西”。类也是元类的实例。而在python中,它们要么是类的实例,要么是元类的实例,除了type。type实际上是它自己的元类。元类主要的用途是用来创建API,比如django的ORM。

6.python的search和match知识点?
search和match都在re模块中,match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None。search匹配整个字符串,直到找到一个匹配。

7. python中深浅拷贝的区别?
浅拷贝没有拷贝子对象,所以原对象发生改变,其子对象也发生了改变,而深拷贝拷贝了子对象,原对象发生改变,其本身也不会改变。具体的可以看我之前的博客python深浅copy一分钟掌握

8. 类的初始化:new() 和 init()?
new()方法用来实例化最终的类对象,在类创建之前被调用,它在类的主体被执行完后开始执行。
init()方法是在类被创建之后被调用,用来执行其他的一些输出化工作
当我们构造元类的时候,通常只需要定一个init()或new()方法,但不是两个都定义。但是,如果需要接受其他的关键词参数的话,这两个方法就要同时提供,并且都要提供对应的参数签名。

9.类的初始化?
B类继承A类,在B类自己的基础上可以调用A类所有方法,如果A,B同时拥有init, B会改写A中的init方法,A类的方法失效。
Super函数可以调用A类中的属性,B类中有同名属性时,覆盖A类中的同名属性。但调用函数时,总是先查找它自身的定义,如果没有定义,则顺着继承链向上插座,知道在某个父类中找到为止。
B类 init参数需大于或等于A 父类的init方法,因为super初始化了,参数量为父类参数量。

10.多线程?
多线程可以共享进程的内存空间,因此要实现多个线程之间的通信相对简单,比如设置一个全局变量,多个线程共享这个全局变量。但是当多个线程共享一个资源的时候,可能导致程序失效甚至崩溃,如果一个资源被多个线程竞争使用,那么对临界资源的访问需要加上保护,否则会处于“混乱”状态,比如银行存100块钱,最终很可能存不到一百块多个线程得到的余额状态都是0,所有操作都是在0上面加1,从而导致错误结果。这种情况下,锁就可以得到用处了。多线程并不能发挥cpu多核特性,因为python解释器有一个gil锁,任何线程执行前必须获得GIL锁,然后每执行100条字节码,解释器就会自动释放GIL锁让别的线程有机会执行。

11.python内存管理?
python内部使用引用计数,来保持追踪内存中的对象,Python内部记录了对象有多少个引用,即引用计数,当对象被创建时就创建了一个引用计数,当对象不再需要时,这个对象的引用计数为0时,它被垃圾回收。所有这些都是自动完成,不需要像C一样,人工干预,从而提高了程序员的效率和程序的健壮性。

12.python的filter方法?
filter就像map,reduce,apply,zip等都是内置函数,用C语言实现,具有速度快,功能强大等 优点。
用于过滤与函数func()不匹配的值, 类似于SQL中select value != ‘a’
相当于一个迭代器,调用一个布尔函数func来迭代seq中的每个元素,返回一个是bool_seq返 回为True的序列
第一个参数: function or None, 函数或None
第二个参数: sequence,序列

13. 字符串的查询替换?
考点:python的find和replace函数。
给定一串字符串:

string = 'life is short, I use python'
# 返回的为0或正数时,为其索引号
>>> string.find('life')
string.replace('short','long')
# replace 将short替换为long
>>> life is long, I use python

14.给定一串排好序的列表,打乱这个函数?
这个题考了python里的shuffle函数的用法。

# random模块中的shuffle(洗牌函数)
import random
list = [1, 2, 3, 4]
random.shuffle(list)
print(list)

15. 装饰器?
装饰器是一个函数,接收一个函数返回另一个函数。用法如下:

import time
from functools import wraps

def timethis(func):
'''
Decorator that reports the execution time.
'''
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(func.__name__, end-start)
return result
return wrapper
@timethis
def countdown(n):
'''
Counts down
'''
while n > 0:
n -= 1

>>> countdown(100000)
countdown 0.008917808532714844
>>> countdown(10000000)
countdown 0.87188299392912”

16.给定一串字典(或列表),找出指定的(前N个)最大值?最小值?
这道题的考点是python内的heapq模块的nlargest() 和 nsmallest(), 而不是min()和max()。这两个函数都能接收关键字参数,用于复杂的结构数据中:

portfolio = [
{'name': 'IBM', 'shares': 100, 'price': 91.1},
{'name': 'AAPL', 'shares': 50, 'price': 543.22},
{'name': 'FB', 'shares': 200, 'price': 21.09},
{'name': 'HPQ', 'shares': 35, 'price': 31.75},
{'name': 'YHOO', 'shares': 45, 'price': 16.35},
{'name': 'ACME', 'shares': 75, 'price': 115.65}
]
# 参数3为最大的3个值(最小的3个值)
cheap = heapq.nsmallest(3, portfolio, key=lambda s: s['price'])
expensive = heapq.nlargest(3, portfolio, key=lambda s: s['price'])
# 上面代码在对每个元素进行对比的时候,会以price的值进行比较。

17. python实现单例模式?
这个题考的是python中对单例模式的理解和运用,有4个方法实现单例模式:

#方法1,实现__new__方法
#并在将一个类的实例绑定到类变量_instance上,
#如果cls._instance为None说明该类还没有实例化过,实例化该类,并返回
#如果cls._instance不为None,直接返回cls._instance
class Singleton(object):
def __new__(cls, *args, **kw):
if not hasattr(cls, '_instance'):
orig = super(Singleton, cls)
cls._instance = orig.__new__(cls, *args, **kw)
return cls._instance

class MyClass(Singleton):
a = 1

one = MyClass()
two = MyClass()

two.a = 3
print(one.a)
#3
#one和two完全相同,可以用id(), ==, is检测
print(id(one))
#29097904
print(id(two))
#29097904
print(one == two)
#True
print(one is two)
#True

print('----------------------方法2--------------------------')
#方法2,共享属性;所谓单例就是所有引用(实例、对象)拥有相同的状态(属性)和行为(方法)
#同一个类的所有实例天然拥有相同的行为(方法),
#只需要保证同一个类的所有实例具有相同的状态(属性)即可
#所有实例共享属性的最简单最直接的方法就是__dict__属性指向(引用)同一个字典(dict)
#可参看:http://code.activestate.com/recipes/66531/
class Borg(object):
_state = {}
def __new__(cls, *args, **kw):
ob = super(Borg, cls).__new__(cls, *args, **kw)
ob.__dict__ = cls._state
return ob

class MyClass2(Borg):
a = 1

one = MyClass2()
two = MyClass2()

#one和two是两个不同的对象,id, ==, is对比结果可看出
two.a = 3
print(one.a)
#3
print(id(one))
#28873680
print(id(two))
#28873712
print(one == two)
#False
print(one is two)
#False
#但是one和two具有相同的(同一个__dict__属性),见:
print(id(one.__dict__))
#30104000
print(id(two.__dict__))
#30104000

print '----------------------方法3--------------------------'
#方法3:本质上是方法1的升级(或者说高级)版
#使用__metaclass__(元类)的高级python用法
class Singleton2(type):
def __init__(cls, name, bases, dict):
super(Singleton2, cls).__init__(name, bases, dict)
cls._instance = None
def __call__(cls, *args, **kw):
if cls._instance is None:
cls._instance = super(Singleton2, cls).__call__(*args, **kw)
return cls._instance

class MyClass3(object):
__metaclass__ = Singleton2

one = MyClass3()
two = MyClass3()

two.a = 3
print(one.a)
#3
print(id(one))
#31495472
print(id(two))
#31495472
print(one == two)
#True
print(one is two)
#True

print '----------------------方法4--------------------------'
#方法4:也是方法1的升级(高级)版本,
#使用装饰器(decorator),
#这是一种更pythonic,更elegant的方法,
#单例类本身根本不知道自己是单例的,因为他本身(自己的代码)并不是单例的
def singleton(cls, *args, **kw):
instances = {}
def _singleton():
if cls not in instances:
instances[cls] = cls(*args, **kw)
return instances[cls]
return _singleton

@singleton
class MyClass4(object):
a = 1
def __init__(self, x=0):
self.x = x

one = MyClass4()
two = MyClass4()

two.a = 3
print(one.a)
#3
print(id(one))
#29660784
print(id(two))
#29660784
print(one == two)
#True
print(one is two)
#True
one.x = 1
print(one.x)
#1
print(two.x)
#1

18. 实现一个斐波那契数列的生成器?
这道题的考点关键是生成器的yield关键字将一个普通函数改造成生成器函数:

def fib(n):
a, b = 0, 1
for _ in range(n):
a, b = b, a + b
yield a

def main():
for val in fib(20):
print(val)
if __name__ == '__main__':
main()

19. 使用字符串拼接达到字幕滚动效果?
import os
import time

def main():
content = '曹查理的python面试集-基础篇'
while True:
# 清理屏幕上的输出
os.system('cls') # os.system('clear')
print(content)
# 休眠200毫秒
time.sleep(0.2)
content = content[1:] + content[0]


if __name__ == '__main__':
main()

20. 设计一个函数返回给定文件名的后缀?
这道题考了正则表达式的简单知识点。代码如下:

def get_suffix(filename, has_dot=False):
"""
获取文件名的后缀名

:param filename: 文件名
:param has_dot: 返回的后缀名是否需要带点

:return: 文件的后缀名
"""
pos = filename.rfind('.')
if 0 < pos < len(filename) - 1:
index = pos if has_dot else pos + 1
return filename[index:]
else:
return ''

原文地址:https://www.cnblogs.com/xiaoxiaoxl/p/11110041.html