郑大钱呀

V1

2023/03/18阅读:16主题:凝夜紫

Python 面试题,参考一下

关注我啦

关注【郑大钱呀】【~公~】【~众~】【~号~】,我们一起交流,一起学习。

问题1

问: ==和is的区别是? 答:

  1. is 用于判断两个变量引用对象是否为同一个,即判断对象的内存地址,可以通过id()函数,能够获取对象的内存地址
  2. == 用于判断引用变量的值是否相等

代码演示和讲解

a=[1,2,3]
b=a[:] 
print(a==b,a is b)
# 运行结果如下:True False

上面的a和b两个列表的内容是一样的,但是内存地址不一样,肯定有人疑问,为什么举的例子,这么特殊,像这样a=1;b=1;这样不行么?我们看一段示例代码:

a=1
b=1 
print(a==b,a is b)
# 运行结果如下:True True

通过上面的代码,发现两者的结果一致,这是因为,Python出于对性能的考虑,凡是不可变对象,在同一个代码块中的对象,只要是值相同的对象,就不会重复创建,而是直接引用已经存在的对象。类似的问题:!=和is not运算符的区别原理都是一样的

问题2

问: 什么是lambda函数? 答: Lambda函数是不带名称的单行函数,也被称为匿名函数,它直接接受参数的数量以及使用该参数执行的条件或操作,该参数以冒号分隔,并返回最终结果。lambda函数有如下特点:

  1. 没有名称
  2. Lambda函数有返回值,但是不能写return
  3. 函数只能写在一行中
  4. 不用于代码重用

Lambda函数适用于高阶函数(将一个函数的函数名作为参数传给另外一个函数,被传参的函数就称为高阶函数),举个例子,如果我们想用一个函数,实现加减两种计算,我们就可以这样来实现。

代码演示和讲解

def calc(func,a,b):
    return func(a,b)

add_func = lambda a,b: a+b
sub_func = lambda a,b: a-b
add_res=calc(add_func,1,2)
sub_res=calc(sub_func,1,2)
print(add_res,sub_res)
# 运行结果如下:3 -1

问题3

问: Python中的生成器是什么?
答: 生成器简单的说就是按照一定的规则逐个的生成数据的代码,生成器生成一个数据后,yield关键字就会把数据返回出去,并将函数处于阻塞状态,直到下一次使用next()方法将其唤醒,再输入下一个值。
生成器与普通函数的区别就是:假如我们要喝10000瓶果汁,普通函数是一次性把10000瓶果汁生产好,然后放到仓库里,你去喝,而生成器是你要喝的时候我生产一瓶给你,喝完了想再喝了,就告诉我,我在给你生产,这样的好处,不需要一个很大的仓库,这里的仓库就是我们电脑的内存。

代码演示和讲解

def generator_test():
    for i in range(0,100):
        yield i;
g = generator_test()
print(next(g),next(g),next(g),next(g))
# 运行结果 0 1 2 3

上面的代码是生成0-99 一百个数,但是由于我们这里使用了生成器,并没有一次性生成,而是当我们需要的时候,使用next()方法唤醒取出下一个数。

问题4

问: 如何使用索引来反转Python中的列表元素?
答:

a=[1,2,3,4,5]
print(a[::-1])
# 运行结果 [5, 4, 3, 2, 1]

问题5

问: 描述一下break语句的作用?
答:

  1. break语句用来终止循环语句,即循环条件没有False条件或者语句还没有执行全部,也会停止执行循环语句。
  2. break语句用在while和for循环中。如果使用嵌套循环,break语句将停止执行最深层的循环,并开始执行下一行代码,示例代码如下

代码演示和讲解

for i in range(0,100):
    for j in range(0,2):
        if i==10:
            print("break",i)
            break;
    if i%25==0:
        print(i)
        
"""
运行结果如下:
0
break 10
25
50
75
"""

问题6

问: 解释下python的GIL?
答: Python解释器的实现是有多个版本的:CPython(CPython就是用C语言实现Python解释器), Jpython等等,而python 默认的官方解释器为Python,GIL的问题实际上是存在于CPython中的。

GIL 是python的全局解释器锁,同一进程中假如有多个线程运行,线程非独立的,同一进程里的线程的数据是共享的,当各个线程访问数据资源时会出现竞争状态,造成数据混乱,这就是线程的不安全。所以引进了互斥锁,确保某段关键代码、共享数据只能由一个线程从头到尾完整地执行。保证同一时刻只有一个线程在解释器中运行呢

所以Python语言中多线程其实是假的多线程,即多个线程的代码,轮流被解释器执行,只不过切换的很频繁很快,给人一种多线程同时在执行的错觉,其实就是并发(不同的代码块交替执行),而不是并行(不同的代码块同时执行)

解决GIL问题的方法是,使用多进程,用multiprocess(多进程)替代Thread,每个进程有自己的独立的GIL,因此也不会出现进程之间的GIL争抢,但是多进程会带来更大的内存开销,也会增加程序实现时线程间数据通讯和同步的困难。

问题7

问: python实现列表去重的方法?
答:

list = [1,234,44,34,5,1,4,5,5]
print(set(list))
# 运行结果如下:{1, 34, 4, 5, 234, 44}

问题8

问: 函数中的*args,**kwargs参数什么意思?
答: *args 和**kwargs,为不定长参数,主要用于函数定义。你可以将不定数量的参数传递给一个函数。这里的不定的意思是:预先并不知道,函数使用者会传递多少个参数给你,所以在这个场景下使用这两个关键字。
代码演示和讲解

def func_test_list(*args):
    print("args",args);

def func_test_dict(**kwargs):
    print("kwargs",kwargs);

func_test_list(1,23,3,4)
func_test_dict(name="test",sex="male")

# 运行结果如下
#args (1, 23, 3, 4)
#kwargs {'name': 'test', 'sex': 'male'}

*args使用用来接受非键值对的不定长参数,而**kwargs是用来接受键值对的不定长参数。

问题9

问: 介绍一下Python中range()函数?
答: range的作用,是在指定的范围,根据步长,生成返回一个可迭代对象,并不是迭代器,也是可惰性迭代的一种,即不管range对象表示的整数序列有多长,所有range对象占用的内存空间都是相同的,因为仅仅需要储存start,stop,step,只有当用到range对象时,才会去计算序列中的相关元素,,值得注意的是:可迭代对象不支持next()方法,而迭代器本身不支持切片方法
代码演示和讲解

a = range(1,1000)
print(type(a)
# 运行结果如下
#<class 'range'>

问题10

问: 简述Python的super类
答: 首先super不是方法不是函数也不是关键字啥的,是个类,作用是调用父类的某个方法,一般多用于继承中,比如有两个类,父类A,子类B,子类继承父类,此时我们会在子类中写这一句super(B,self).__init__(),可以这样理解:super(B, self)首先找到B的父类(就是类A),然后把类B的对象self转换为类A的对象,然后“被转换”的类A对象调用自己的__init__函数。
代码演示和讲解

class A():
    def __init__(self,msg):
        print("__init__ A")
        self.msg =msg

    def say(self):
        print("say",self.msg)

class B(A):
    def __init__(self):
        print("__init__ B")


if __name__ == '__main__':
    b = B()
    b.say()

运行报错如下:

__init__ B
Traceback (most recent call last):
  File "Study.py", line 16, in <module>
    b.say()
  File "Study.py", line 7, in say
    print("say",self.msg)
AttributeError: 'B' object has no attribute 'msg'

上面B类继承了父类,但是没有调用父类的初始化方法,所以在调用父类的方法的时候就报错了,这个时候我们用super关键字,调用父类的构造方法初始化一下,代码如下:

class A():
    def __init__(self,msg):
        print("__init__ A")
        self.msg =msg

    def say(self):
        print("say",self.msg)

class B(A):
    def __init__(self,name):
        #写法一:super(当前类名,self).__init__(父类初始化需要的参数)
        # super(B,self).__init__(name)
        #写法二:super().__init__(父类初始化需要的参数)
        super().__init__(name)
        print("__init__ B")


if __name__ == '__main__':
    b = B("Mike")
    b.say()

运行结果如下:

__init__ A
__init__ B
say Mike

super(当前类名,self),第一个是type(也就是一个class),第二个是type或者ojbect,第二个参数决定了要把父类的初始化方法绑定到哪个对象身上。

问题11

问: 简述面向对象中__new__方法
答:

  1. __new__是一种负责创建类实例的静态方法,它无需使用 staticmethod 装饰器修饰,且该方法会优先 __init__() 初始化方法被调用,覆写__new__方法需要调用超类的super().new()。
  2. __new__至少要有一个参数cls,代表当前类,此参数在实例化时由Python解释器自动识别
  3. _new__必须要有返回值,返回实例化出来的实例

代码演示和讲解

class Study:
    def __new__(cls,*args,**kwargs):
        print("__new__():",cls,args,kwargs)
        instance = super().__new__(cls)
        return instance
    def __init__(self):
        print("__init__")

Study.__new__(Study,[1,2,3,4],name="test")

运行结果如下:

__new__(): <class '__main__.Study'> ([1234],) {'name': 'test'}

一般情况下,覆写 new() 的实现将会使用合适的参数调用其超类的 super().new(),并在返回之前修改实例

问题12

问: Python 实现冒泡排序
答: 菜鸟教程

冒泡排序(Bubble Sort)是一种简单直观的排序算法,它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成,这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端。

代码演示和讲解

def sortList(args):
    for i in range(len(args)-1):
        for j in range(len(args)-i-1):
            if args[j]>args[j+1]:
                # 前一个数比后一个数大,则互换位置
                args[j],args[j+1]= args[j+1],args[j]
        print("第%s轮排序完结果 %s" %((i+1),str(args)))
    return args

sortList([5,4,3,2,1])

运行结果如下:

1轮排序完结果 [43215]
2轮排序完结果 [32145]
3轮排序完结果 [21345]
4轮排序完结果 [12345]

我们以五个数,要从从小到达排序为例,五个数相邻两个数比较只需比较四次,即可找出本轮比较的最大值,经过第一轮比较已经找出最大值,所以第二轮只需要比较前四个数,在这四个数中比较,找出这个四个数中的最大值,也就是所有数中的第二大值,以此类推,五个数,只需经过4轮比较即可对列表完成全部排序

参考文档

1. 110道pythonn面试题

结尾

为了方便大家学习交流,我们建立了一个交流群,以技术(以软件测试为主)和业务(以金融业务为主)学习交流为主,如有需要加入,可以扫描文章末尾的二维码入群。

本期的内容就到这里了,如有不足之处还请大家多多指正,欢迎大家留言关注转发收藏,谢谢。

分类:

后端

标签:

Python

作者介绍

郑大钱呀
V1

微信搜索【郑大钱呀】公众号