24道Python面试练习题

Posted 小小程序员ol

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了24道Python面试练习题相关的知识,希望对你有一定的参考价值。

1.简述函数式编程

答:在函数式编程中,函数是基本单位,变量只是一个名称,而不是一个存储单元。除了匿名函数外,Python还使用fliter(),map(),reduce(),apply()函数来支持函数式编程。

2.什么是匿名函数,匿名函数有什么局限性

答:匿名函数,也就是lambda函数,通常用在函数体比较简单的函数上。匿名函数顾名思义就是函数没有名字,因此不用担心函数名冲突。不过Python对匿名函数的支持有限,只有一些简单的情况下可以使用匿名函数。

3.如何捕获异常,常用的异常机制有哪些?

答:如果我们没有对异常进行任何预防,那么在程序执行的过程中发生异常,就会中断程序,调用python默认的异常处理器,并在终端输出异常信息。

  • try...except...finally语句:当try语句执行时发生异常,回到try语句层,寻找后面是否有except语句。找到except语句后,会调用这个自定义的异常处理器。except将异常处理完毕后,程序继续往下执行。finally语句表示,无论异常发生与否,finally中的语句都要执行。
  • assert语句:判断assert后面紧跟的语句是True还是False,如果是True则继续执行print,如果是False则中断程序,调用默认的异常处理器,同时输出assert语句逗号后面的提示信息。
  • with语句:如果with语句或语句块中发生异常,会调用默认的异常处理器处理,但文件还是会正常关闭。

4.copy()与deepcopy()的区别

答:copy是浅拷贝,只拷贝可变对象的父级元素。 deepcopy是深拷贝,递归拷贝可变对象的所有元素。

5.函数装饰器有什么作用(常考)

答:装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。有了装饰器,就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。

6.简述Python的作用域以及Python搜索变量的顺序

答:Python作用域简单说就是一个变量的命名空间。代码中变量被赋值的位置,就决定了哪些范围的对象可以访问这个变量,这个范围就是变量的作用域。在Python中,只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域。Python的变量名解析机制也称为 LEGB 法则:本地作用域(Local)→当前作用域被嵌入的本地作用域(Enclosing locals)→全局/模块作用域(Global)→内置作用域(Built-in)。

7.新式类和旧式类的区别如何确保使用的类是新式类

答:为了统一类(class)和类型(type),python在2.2版本引进来新式类。在2.1版本中,类和类型是不同的。
为了确保使用的是新式类,有以下方法:

  • 放在类模块代码的最前面 __metaclass__ = type
  • 从内建类object直接或者间接地继承
  • 在python3版本中,默认所有的类都是新式类。

8.简述__new__和__init__的区别

答:创建一个新实例时调用__new__,初始化一个实例时用__init__,这是它们最本质的区别。

  • new方法会返回所构造的对象,init则不会。
  • new函数必须以cls作为第一个参数,而init则以self作为其第一个参数。

9.Python垃圾回收机制(常考)

答:Python GC主要使用引用计数(reference counting)来跟踪和回收垃圾。在引用计数的基础上,通过“标记-清除”(mark and sweep)解决容器对象可能产生的循环引用问题,通过“分代回收”(generation collection)以空间换时间的方法提高垃圾回收效率。

①引用计数

PyObject是每个对象必有的内容,其中ob_refcnt就是做为引用计数。当一个对象有新的引用时,它的ob_refcnt就会增加,当引用它的对象被删除,它的ob_refcnt就会减少.引用计数为0时,该对象生命就结束了。

  • 优点:简单 实时性 。
  • 缺点::维护引用计数消耗资源 循环引用 。

②标记-清除机制

基本思路是先按需分配,等到没有空闲内存的时候从寄存器和程序栈上的引用出发,遍历以对象为节点、以引用为边构成的图,把所有可以访问到的对象打上标记,然后清扫一遍内存空间,把所有没标记的对象释放。

③分代技术

分代回收的整体思想是:将系统中的所有内存块根据其存活时间划分为不同的集合,每个集合就成为一个“代”,垃圾收集频率随着“代”的存活时间的增大而减小,存活时间通常利用经过几次垃圾回收来度量。
Python默认定义了三代对象集合,索引数越大,对象存活时间越长。

10.Python中的@property有什么作用?如何实现成员变量的只读属性?

答:@property装饰器就是负责把一个方法变成属性调用,通常用在属性的get方法和set方法,通过设置@property可以实现实例成员变量的直接访问,又保留了参数的检查。另外通过设置get方法而不定义set方法可以实现成员变量的只读属性。

11.*args and **kwargs

答:*args代表位置参数,它会接收任意多个参数并把这些参数作为元组传递给函数。**kwargs代表的关键字参数,允许你使用没有事先定义的参数名,另外,位置参数一定要放在关键字参数的前面。

12.有用过with statement吗?它的好处是什么?具体如何实现?

答:with语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源,比如文件使用后自动关闭、线程中锁的自动获取和释放等。

13.what will be the output of the code below? explain your answer

def extend_list(val, list=[]):
    list.append(val)
    return list
 
list1 = extend_list(10)
list2 = extend_list(123, [])
list3 = extend_list(\'a\')
 
print(list1) # list1 = [10, \'a\']
print(list2) # list2 = [123]
print(list3) # list3 = [10, \'a\']
 
#Python小白学习交流群:725638078 
# 按照我个人的理解做这道题,extend_list函数一共有两个参数,分别是变量传参和默认传参
# 如果只是传入一个参数,说明list=[]是全局变量,会将所有仅含一个参数的的结果添加在同一个列表中,所以解释了list1和list3的结果
# 如果传递了一个变量,还使用了[],说明这个列表是局部变量,解释了list2的结果
# 新增list2 = extend_list([]),则list1,list3,list4输出都为[10, \'a\', []]
class Parent(object):
    x = 1
 
class Child1(Parent):
    pass
 
class Child2(Parent):
    pass
 
print(Parent.x, Child1.x, Child2.x)  # [1,1,1]
Child1.x = 2
print(Parent.x, Child1.x, Child2.x)  # [1,2,1]
Partent.x = 3
print(Parent.x, Child1.x, Child2.x)  # [3,2,3]

因为Child1和Child2都继承了Parent类,所以也继承了x=1的类属性
没有任何赋值的情况下,第一种情况都输出为1
当Child1的x属性被赋值为2,则只有Child1.x输出2
因为Partent是基类,当Partent.x = 3,则Child2继承的x属性也输出3,而Child1的类属性已经被重写了,所以仍为2

14.在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

arr = [[1,4,7,10,15], [2,5,8,12,19], [3,6,9,16,22], [10,13,14,17,24], [18,21,23,26,30]]
 
def getNum(num, data=None):
    while data:
        if num > data[0][-1]:
        # 如果当前的num大于二维数组的第一个数组最后一个
        # 删除第一个数组
            del data[0]
            print(data)
        elif num < data[0][-1]:
        # 如果当前的num小于二维数组的第一个数组最后一个
            data = list(zip(*data))
            del data[-1]
            data = list(zip(*data))
            print(data)
            getNum(num, data=None)
        else:
            return True
            data.clear()
    return False
  
  
if __name__ == \'__main__\':
    print(getNum(18, arr))
     
# [[2, 5, 8, 12, 19], [3, 6, 9, 16, 22], [10, 13, 14, 17, 24], [18, 21, 23, 26, 30]]
# [(2, 5, 8, 12), (3, 6, 9, 16), (10, 13, 14, 17), (18, 21, 23, 26)]
# [(3, 6, 9, 16), (10, 13, 14, 17), (18, 21, 23, 26)]
# [(10, 13, 14, 17), (18, 21, 23, 26)]
# [(18, 21, 23, 26)]
# [(18, 21, 23)]
# [(18, 21)]
# [(18,)]
# True

15.获取最大公约数、最小公倍数

a = 36
b = 21
 
 
def maxCommon(a, b):
    """
    返回最大公约数
    """
    while b:
        a, b = b, a % b
        # a,b = 21,15
        # a,b = 15,6
        # a,b = 6,3
        # a,b = 3,0
    return a
 
#Python小白学习交流群:725638078 
def minCommon(a, b):
    """
    返回最小公倍数
    """
    c = a * b
    c = 756
    while b:
        a, b = b, a % b
        # a,b = 21,15
        # a,b = 15,6
        # a,b = 6,3
        # a,b = 3,0
    # //取的是结果的最小整数
    return c // a
 
 
if __name__ == \'__main__\':
    print(maxCommon(a, b))
    print(minCommon(a, b))

16.获取中位数

def medium(data):
    data.sort()
    # //取的是结果的最小整数
    half = len(data) // 2
    return (data[half] + data[~half])/2
 
l = [1,3,4,53,2,46,8,42,82]
 
if __name__ == \'__main__\':
    print(median(l))
    # 8.0

17.输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

def getOneCount(num):
    if num > 0:
        b_num = bin(num)
        print(b_num) # 0b101
        count = b_num.count(\'1\')
        return count
    elif num < 0:
        b_num = bin(~num)
        print(b_num) # 0b100
        count = 8 - b_num.count(\'1\')
        return count
    else:
        return 8
 
if __name__ == \'__main__\':
    print(getOneCount(5)) # 2
    print(getOneCount(-5)) # 7
    print(getOneCount(0))

18.列表[1,2,3,4,5],请使用map()函数输出[1,4,9,16,25],并使用列表推导式提取出大于10的数,最终输出[16,25]

map()函数第一个参数是fun,第二个参数是一般是list,第三个参数可以写list,也可以不写,根据需求。

# map(function, iterable, ...)
res = map(lambda x:x**2, [1, 2, 3, 4, 5])
res = [i for i in res if i > 10]

19.s = "ajldjlajfdljfddd",去重并从小到大排序输出"adfjl"

s = "ajldjlajfdljfddd"
s = list(set(s))
s.sort()
res = "".join(s)

20.字典如何删除键和合并两个字典

dict = "name":"jack", "age": 18
del dict["name"]
 
dict1 = "gender": "man"
dict1.update(dict)

21.数据表student有id,name,score,city字段,其中name中的名字可有重复,需要消除重复行,请写sql语句

select  distinct  name  from  student

22.用lambda函数实现两个数相乘

z = lambda x,y:x*y
print(z(1, 4))

23.list=[2,3,5,4,9,6],从小到大排序,不许用sort,输出[2,3,4,5,6,9]

利用min()方法求出最小值,原列表删除最小值,新列表加入最小值,递归调用获取最小值的函数,反复操作。

list = [2,3,5,4,9,6]
list2 = []
#Python小白学习交流群:725638078
 
def get_min(list):
    x = min(list)
    list.remove(x)
    list2.append(x)
    if len(list) > 0:
        get_min(list)
    return list2
     
list2 = get_min(list)

24.对list排序foo = [-5,8,0,4,9,-4,-20,-2,8,2,-4],使用lambda函数从小到大排序

foo = [-5,8,0,4,9,-4,-20,-2,8,2,-4]
 
a = sorted(foo, key=lambda x:x)
print(a)
 
foo.sort(reverse=False)
print(foo)

精选50道Python面试题,快来看看你已经掌握了多少道吧

感激相遇 你好 我是阿ken

💬 公号内置:「Java、Python、前端等学习路线及电子书」,另有「升本习题、教材电子书、各科学霸笔记」

🌈 领取方式:「文末点开扫码」即可「自行免费领取」

「点击下方目录可自动跳转」

Q1、什么是Python?使用Python有什么好处?

Python是一种编程语言,包含对象,模块,线程,异常和自动内存管理。Python的好处在于它简单易用,可移植,可扩展,内置数据结构,并且它是一个开源的。

Q2、什么是PEP 8?

PEP 8是一个编码约定,关于如何编写Python代码更具可读性。

Q3、什么是序列化和非序列化?

Pickle模块接受任何Python对象并将其转换为字符串表示形式,并使用dump函数将其转储到文件中,此过程称为pickling。从存储的字符串表示中检索原始Python对象的过程称为unpickling。

Q4、如何解释Python?

Python语言是一种解释语言。Python程序直接从源代码运行。它将程序员编写的源代码转换为中间语言,再次转换为必须执行的机器语言。

Q5、如何在Python中内存管理?

Python内存由Python私有堆空间管理。所有Python对象和数据结构都位于私有堆中。程序员无权访问此私有堆,解释器负责处理此私有堆。
Python对象的Python堆空间分配由Python内存管理器完成。核心API提供了一些程序员编写代码的工具。
Python还有一个内置的垃圾收集器,它可以回收所有未使用的内存并释放内存并使其可用于堆空间。

Q6、有哪些工具可以帮助查找错误或执行静态分析?

PyChecker是一个静态分析工具,可以检测Python源代码中的错误,并警告错误的风格和复杂性。Pylint是另一种验证模块是否符合编码标准的工具。

Q7、什么是Python decorators?

Python decorators是我们在Python语法中进行的一项特定更改,可以轻松地更改函数。

Q8、list和tuple有什么区别?

列表和元组之间的区别在于列表是可变的而元组不是。元组可以被散列,例如作为词典的关键。

Q9、参数如何通过值或引用传递?

Python中的所有内容都是一个对象,所有变量都包含对象的引用。参考值是根据功能; 因此,您无法更改引用的值。但是,如果对象是可变的,则可以更改它们。

Q10、Dict和List理解是什么?

它们是语法结构,可以根据现有的iterable轻松创建Dictionary或List。

Q11、python提供的内置类型是什么?

有可变和不可变类型的Pythons,内置类型为Mutable内置类型
List
Sets
Dictionaries

不可变的内置类型
Strings
Tuples
Numbers

Q12、Python中的命名空间是什么?

在Python中,引入的每个名称都有一个存在的地方,可以被连接起来。这称为命名空间。它就像一个框,其中变量名称映射到放置的对象。每当搜索到变量时,将搜索此框以获取相应的对象。

Q13、Python中的lambda是什么?

它是一个单独的表达式匿名函数,通常用作内联函数。

Q14、为什么python中的lambda表单没有语句?

python中的lambda表单没有语句,因为它用于创建新的函数对象,然后在运行时返回它们。

Q15、什么是Python pass?

pass意味着,无操作的Python语句,或者换句话说,它是复合语句中的占位符,其中应该留有空白,并且不必在那里写入任何内容。

Q16、什么是Python中的迭代器?

在Python中,迭代器用于迭代一组元素,如列表之类的容器。

Q17、什么是Python中的单元测试?

Python中的单元测试框架称为unittest。它支持共享设置,自动化测试,测试关闭代码,将测试聚合到集合等。

Q18、在Python中切片是什么?

从序列类型(如列表,元组,字符串等)中选择一系列项目的机制称为切片。

Q19、Python中的生成器是什么?

实现迭代器的方法称为生成器。这是一个正常的函数,除了它在函数中产生表达式。

Q20、Python中的docstring是什么?

Python文档字符串称为docstring,它是一种记录Python函数,模块和类的方法。

Q21、如何在Python中复制对象?

要在Python中复制对象,可以尝试copy.copy()或copy.deepcopy()来处理一般情况。您无法复制所有对象,但大多数对象都是如此。

Q22、Python中的反向索引是什么?

Python序列可以是正数和负数的索引。对于正索引,0是第一个索引,1是第二个索引,依此类推。对于负索引,( - 1)是最后一个索引,( - 2)是倒数第二个索引,依此类推。

Q23、如何将数字转换为字符串?

要将数字转换为字符串,请使用内置函数str()。如果需要八进制或十六进制表示,请使用内置函数oct()或hex()。

Q24、Xrange和range有什么区别?

Xrange返回xrange对象,而range返回列表,并使用相同的内存,无论范围大小是多少。

Q25、Python中的module和package是什么?

在Python中,模块是构造程序的方式。每个Python程序文件都是一个模块,它导入其他模块,如对象和属性。

Python程序的文件夹是一个模块包。包可以包含模块或子文件夹。

Q26、提到Python中局部变量和全局变量的规则是什么?

局部变量:如果在函数体内的任何位置为变量赋值,则假定它是本地的。

全局变量:仅在函数内引用的那些变量是隐式全局变量。

Q27、如何跨模块共享全局变量?

要在单个程序中跨模块共享全局变量,请创建一个特殊模块。在应用程序的所有模块中导入配置模块。该模块将作为跨模块的全局变量提供。

Q28、解释如何在Unix上创建Python脚本?

要在Unix上使Python脚本可执行,您需要做两件事,

脚本文件的模式必须是可执行的
第一行必须以#开头(#!/ usr / local / bin / python)

Q29、解释如何在Python中删除文件?

使用命令os.remove(filename)或os.unlink(filename)

Q30、解释如何在Python中生成随机数?

要在Python中生成随机数,您需要将命令导入为:

import random

random.random()

这将返回[0,1)范围内的随机浮点数。

Q31、解释如何从C访问用Python编写的模块?

您可以通过以下方法访问C中用Python编写的模块,

Module = = PyImport_ImportModule(“”);

Q32、提到在Python中使用//运算符?

它是一个Floor Divisionoperator,用于分割两个操作数,结果为商,只显示小数点前的数字。例如,10 // 5 = 2和10.0 // 5.0 = 2.0。

Q33、使用Python的五大好处?

Python包含一个巨大的标准库,适用于大多数Internet平台,如电子邮件,HTML等。
Python不需要显式内存管理,因为解释器本身会将内存分配给新变量并自动释放它们
由于使用方括号,因此易于阅读
初学者易于学习
拥有内置数据类型可以节省编程时间和工作量,从而声明变量

Q34、提在Python中使用split函数?

在Python中使用split函数是使用定义的分隔符将字符串分解为更短的字符串。它给出了字符串中存在的所有单词的列表。

Q35、解释什么是Flask及其好处?

Flask是基于“Werkzeug, Jinja 2 and good intentions”BSD许可的Python的Web微框架。Werkzeug和jingja是它的两个依赖。

Flask是微框架的一部分。这意味着它对外部库几乎没有依赖性。它使框架变得轻盈,同时几乎没有更新的依赖性和更少的安全性错误。

Q36、Django,Pyramid和Flask之间有什么区别?

Flask是一个“微框架”,主要用于具有更简单要求的小型应用程序。在Flask中,您必须使用外部库。

Pyramid是为更大的应用程序构建的。它提供了灵活性,并允许开发人员为他们的项目使用正确的工具。开发人员可以选择数据库,URL结构,模板样式等。Pyramid是可配置的。

像Pyramid一样,Django也可以用于更大的应用程序。它包括一个ORM。

Q37、什么是Flask-WTF以及它们的特征是什么?

Flask-WTF提供与WTForms的简单集成。功能包括Flask WTF:
Integration with wtforms
Secure form with csrf token
Global csrf protection
Internationalization integration
Recaptcha supporting
File upload that works with Flask Uploads

Q38、解释Flask脚本工作的常用方法是什么?

Flask脚本工作的常用方法是:

应用程序的导入路径
或者是Python文件的路径

Q39、解释如何在Flask中访问会话?

会话基本上允许您记住从一个请求到另一个请求的信息。在一个Flask中,它使用签名cookie,以便用户可以查看会话内容并进行修改。如果只有密钥Flask.secret_key,则用户可以修改会话。

Q40、Flask是MVC模型,如果是,举例说明你的应用程序的MVC模式?

基本上,Flask是一个简约框架,其行为与MVC框架相同。所以MVC非常适合Flask,MVC的模式我们将考虑以下示例。

Q41、什么是负指数,功能是什么?

Python中的序列是索引的,它由正数和负数组成。积极的数字使用’0’作为第一个索引,‘1’作为第二个索引,进程继续使用。负数的索引从’-1’开始,表示序列中的最后一个索引,’ - 2’作为倒数第二个索引,序列像正数一样前进。负索引用于从字符串中删除任何换行符,并允许该字符串除了作为S [: - 1]给出的最后一个字符。负索引还用于显示索引以正确的顺序表示字符串。Q42、什么是Python包?Python包是包含多个模块的命名空间。

Q43、如何在Python中删除文件?

要在Python中删除文件,您需要导入OS模块。之后,您需要使用os.remove()函数。

Q44、什么是python的内置类型?

Python中的内置类型如下:整型、浮点型、复数、字符串、布尔等。

Q45、NumPy中有哪些操作Python列表的函数?

Python的列表是高效的通用容器。它们支持(相当)有效的插入,删除,追加和连接,Python的列表推导使它们易于构造和操作。它们有一定的局限性:它们不支持像素化加法和乘法等“向量化”操作,并且它们可以包含不同类型的对象这一事实意味着Python必须存储每个元素的类型信息,并且必须执行类型调度代码在对每个元素进行操作时。NumPy不仅效率更高; 它也更方便。你可以免费获得大量的向量和矩阵运算,这有时可以避免不必要的工作。它们也得到有效实施。NumPy数组更快,你可以使用NumPy,FFT,卷积,快速搜索,基本统计,线性代数,直方图等内置。

Q46、如何将值添加到python数组?

可以使用append(),extend()和insert(i,x)函数将元素添加到数组中。

Q47、如何删除python数组的值?

可以使用pop()或remove()方法删除数组元素。这两个函数之间的区别在于前者返回已删除的值,而后者则不返回。

Q48、Python有OOps概念吗?

Python是一种面向对象的编程语言。这意味着可以通过创建对象模型在python中解决任何程序。同时Python可以被视为程序语言和结构语言。

Q49、深拷贝和浅拷贝有什么区别?

在创建新实例类型时使用浅拷贝,并保留在新实例中复制的值。浅拷贝用于复制引用指针,就像复制值一样。这些引用指向原始对象,并且在类的任何成员中所做的更改也将影响它的原始副本。浅拷贝允许更快地执行程序,它取决于所使用的数据的大小。深拷贝用于存储已复制的值。深拷贝不会将引用指针复制到对象。它引用一个对象,并存储一些其他对象指向的新对象。原始副本中所做的更改不会影响使用该对象的任何其他副本。由于为每个被调用的对象创建了某些副本,因此深拷贝会使程序的执行速度变慢。

Q50、如何在Python中实现多线程?

Python有一个多线程库,但是用多线程来加速代码的效果并不是那么的好,Python有一个名为Global Interpreter Lock(GIL)的结构。GIL确保每次只能执行一个“线程”。一个线程获取GIL执行相关操作,然后将GIL传递到下一个线程。虽然看起来程序被多线程并行执行,但它们实际上只是轮流使用相同的CPU核心。所有这些GIL传递都增加了执行的开销。这意味着多线程并不能让程序运行的更快。

有问题请随时与我交流,一个人可以走的很快,但一群人才可以走的更远!

「关注」:提高学习效率!

👍🏻:原创不易,适当鼓励!

⭐:收藏文章,温故知新!

💬:评论交流,共同进步!

期待下次相遇 我是阿ken 再见

以上是关于24道Python面试练习题的主要内容,如果未能解决你的问题,请参考以下文章

8道Python基础面试练习题

免费领取:24个Java核心常用技术栈解析,2000道常见大厂面试题合集

100道Python经典练习题.pdf(附答案)

100道Python经典练习题.pdf(附答案)

500道全网最新python面试习题(大厂面试经典,从此面试不在愁)持续更新中(附源代码)

软件测试工程师常见的17道Python面试题多测师_王sir