Python基础面试20题
刘东灵
最近python是真的火,加上有许多公司都在招python方面的程序员,而网上的面试题又总是千篇一律复制粘贴,在这里博主打算自己写一些python的一些面试题一些是我遇到的,觉得还不错,一些是python必须知道的一些知识点。相应的,自己也在python这条路上,努力做的更好,也希望在测试自己同时帮到更多的小白和从别的语言转过来的同行们,如果大家喜欢,我会在以后继续拓展更多的面试题的篇幅,在基础篇中,我将仅仅提到关于python的基础。在python基础中,很明显我们需要了解python的特性,像面向对象思想,字符串的操作,推导式,实例化,多线程多进程以及初始化这些都是必须了解的。
##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) if not hasattr(cls, '_instance'): 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 ''
到此这篇关于Python基础面试20题 的文章就介绍到这了,更多相关Python基础面试题 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章,希望大家以后多多支持脚本之家!