python面试相关

1、谈下python的GIL
并行:多个CPU同时执行多个任务,就好像有两个程序,这两个程序是真的在两个不同的CPU内同时被执行。
并发:CPU交替处理多个任务,还是有两个程序,但是只有一个CPU,会交替处理这两个程序
进程和线程之间的区别:
两个多线程同时执行死循环,查看单个CPU的使用率:100%
两个多线程同时执行死循环,查看两个CPU的使用率:加起来100%
两个多进程同时执行死循环,查看两个CPU使用率:每个cpu都是100%

多线程并不会充分调用两个CPU,而是会像在一个CPU上充分运转,而多进程则是会完全调用两个CPU,同时执行;

GIL全局解释器锁(global interpreter lock),每个线程在执行时候都需要先获取GIL,保证同一时刻只有一个线程可以执行代码,
即同一时刻只有一个线程使用CPU,也就是说多线程并不是真正意义上的同时执行。
GIL 是python的全局解释器锁,同一进程中假如有多个线程运行,一个线程在运行python程序的时候会霸占python解释器(加了一把锁即GIL),
使该进程内的其他线程无法运行,等该线程运行完后其他线程才能运行。
如果线程运行过程中遇到耗时操作,则解释器锁解开,使其他线程运行。所以在多线程中,线程的运行仍是有先后顺序的,并不是同时进行。
多进程中因为每个进程都能被系统分配资源,相当于每个进程有了一个python解释器,所以多进程可以实现多个进程的同时运行,缺点是进程系统资源开销大
2、fun(args,**kwargs)中的args,**kwargs什么意思?
*args:可变参数:传入个数0~∞,自动组装为一个tuple
**kwargs:关键字参数:0个或任意个含参数名的参数,在函数内部自动组装为一个dict

args与**kwargs主要用于函数定义,当不定数量的参数传递给一个函数时可以使用args与**kwargs
*args是用来发送一个键值对可变数量的参数列表给一个函数,意思就是没有key值。
**kwargs将不定长度的键值对,作为参数传递给一个函数。意思就是有key值

#example:
def a(b,*args,**kw):
    print(b,'\n')
    for x in args:
        print(x)
    for k,v in kw.items():
        print(k,':',v)
a('s','d','f','g',name='1',age='3')
#输出
s

d
f
g
name : 1
age : 3

3、python2和python3的range(100)的区别

# python2中的range返回的是一个列表
# python3中的range返回的是一个迭代值
print(range(5))#输出range(0, 5)
print(list(range(5)))#输出[0, 1, 2, 3, 4]

4、一句话解释什么样的语言能够用装饰器?
在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)
函数可以作为参数传递的语言,可以使用装饰器
5、python内建数据类型有哪些
int,bool,str,list,tuple,dict
6、列出几种魔法方法并简要介绍用途
init:对象初始化方法
new:创建对象时候执行的方法,单列模式会用到
str:当使用print输出对象的时候,只要自己定义了__str__(self)方法,那么就会打印从在这个方法中return的数据
del:删除对象执行的方法

6、简述面向对象中__new__和__init__区别
__init__是当实例对象创建完成后被调用的,然后设置对象属性的一些初始值。
__new__是在实例创建之前被调用的,因为它的任务就是创建实例然后返回该实例,是个静态方法。
__new__的返回值(实例)将传递给__init__方法的第一个参数,然后__init__给这个实例设置一些参数。
__new__至少要有一个参数cls,代表当前类,此参数在实例化时由Python解释器自动识别
__new__必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,可以return父类(通过super(当前类名, cls))__new__出来的实例,或者直接是object的__new__出来的实例
__init__有一个参数self,就是这个__new__返回的实例,__init__在__new__的基础上可以完成一些其它初始化的动作,__init__不需要返回值
7、简述with方法打开处理文件帮我我们做了什么?

#原来:
try:
    f = open('D:/codecodecode/exercise/test.txt', 'r')
    print(f.read())
finally:
    if f:
        f.close()
#用with
with open('D:/codecodecode/exercise/test.txt', 'r') as f:
    print(f.read())

打开文件在进行读写的时候可能会出现一些异常状况,如果按照常规的f.open写法,我们需要try,except,finally,做异常判断,并且文件最终不管遇到什么情况,都要执行finally f.close()关闭文件,with方法帮我们实现了finally中f.close
8、避免转义给字符串加哪个字母表示原始字符串?
r’’
9、python2和python3区别?列举5个
1、Python3 使用 print 必须要以小括号包裹打印内容,比如 print(‘hi’)
Python2 既可以使用带小括号的方式,也可以使用一个空格来分隔打印内容,比 如 print ‘hi’
2、python2 range(1,10)返回列表,python3中返回迭代器,节约内存
3、python2中使用ascii编码,python中使用utf-8编码
4、python2中unicode表示字符串序列,str表示字节序列
python3中str表示字符串序列,byte表示字节序列
5、python2中为正常显示中文,引入coding声明,python3中不需要
6、python2中是raw_input()函数,python3中是input()函数
10、列出python中可变数据类型和不可变数据类型,并简述原理
list可变dict可变
增删改查只是改变了变量的值,而不会新建一个对象,变量引用的对象的地址也不会变化,
不过对于相同的值的不同对象,在内存中则会存在不同的对象,即每个对象都有自己的地址
数值型,字符串型,tuple不可变
如果改变了变量的值,相当于是新建了一个对象,而对于相同的值的对象,在内存中则只有一个对象(一个地址),如下图用id()方法可以打印对象的id

a=1
b=1
print(id(a))
print(id(b))
#id相同

11、python中交换两个数值

a,b=2,3
print(a,b)
a,b=b,a
print(a,b)

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

list=[2,3,5,4,9,6]
for i in range(len(list)-1):
    if list[i]>list[i+1]:
       list[i],list[i+1]=list[i+1],list[i]
print(list)

#法二
#min()取最小值,从原列表remove,加入新列表

13、写一个单列模式
单例模式(Singleton Pattern)是一种常用的软件设计模式,
该模式的主要目的是确保某一个类只有一个实例存在。
法一,用模块
只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了

mysingleton.py
class Singleton(object):
    def foo(self):
        pass
singleton = Singleton()

使用时,直接在其他文件中导入此文件中的对象,这个对象即是单例模式的对象

from a import singleton

法二,new
因为创建对象时__new__方法执行,并且必须return 返回实例化出来的对象所cls.__instance是否存在,
不存在的话就创建对象,存在的话就返回该对象,来保证只有一个实例对象存在(单列),

class Singleton(object):
    __instance=None
    def __new__(cls,age,name):
        #如果类属性__instance为None,就创建一个对象,并赋值为这个对象的引用
        #下次调用这个方法时能够知道之前已经创建过对象了
        if not cls.__instance:
            cls.__instance=object.__new__(cls)
        return cls.__instance
a=Singleton(18,'dog')
b=Singleton(8,"cat")
print(id(a))
print(id(b))
a.age=19
print(b.age)
b.name='666'
print(b.name)

14、计算代码运行结果,zip函数历史文章已经说了,得出[(“a”,1),(“b”,2),(“c”,3),(“d”,4),(“e”,5)]

A=zip(("a","b","c","d","e"),(1,2,3,4,5))
A0=dict(A)
A1=range(10)
A2=[i for i in A1 if i in A0]#i in A0是abcde,是key
A3=[A0[s] for s in A0]#12345
print("A0",A0) #1:"a"..
print(list(zip(("a","b","c","d","e"),(1,2,3,4,5))))#[(:)]
print(A2)
print(A3)

输出:

A0 {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
[('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
[]
[1, 2, 3, 4, 5]

15、简述any()和all()方法
any():只要迭代器中有一个元素为真就为真
all():迭代器中所有的判断项返回都是真,结果才为真
python中什么元素为假?
答案:(0,空字符串,空列表、空字典、空元组、None, False)

a=[True,False]
print(any(a),all(a))

16、python中copy和deepcopy区别
1、复制不可变数据类型,不管copy还是deepcopy,都是同一个地址
当浅复制的值是不可变对象(数值,字符串,元组)时和=“赋值”的情况一样,
对象的id值与浅复制原来的值相同。

import copy
a="好"
b=copy.copy(a)
c=copy.deepcopy(a)
print(a,id(a))
print(b,id(b))
print(c,id(c))

输出:

284139650369628413965036962841396503696

2、复制的值是可变对象(列表和字典)
浅拷贝copy有两种情况:
第一种情况:复制的 对象中无 复杂 子对象,原来值的改变并不会影响浅复制的值,同时浅复制的值改变也并不会影响原来的值。原来值的id值与浅复制原来的值不同。
第二种情况:复制的对象中有 复杂 子对象 (例如列表中的一个子元素是一个列表), 改变原来的值 中的复杂子对象的值 ,会影响浅复制的值。
深拷贝deepcopy:完全复制独立,包括内层列表和字典

import copy
a=[1,2,[3,4]]
b=copy.copy(a)
c=copy.deepcopy(a)
print("原始数据")
print(a,id(a))
print(b,id(b))
print(c,id(c))#三个id都不同
a[0]=5
print("改简单子对象")
print(a,id(a))
print(b,id(b))
print(c,id(c))
a[2][0]=6
print("改复杂子对象")
print(a,id(a))
print(b,id(b))
print(c,id(c))

输出:

原始数据
[1, 2, [3, 4]] 2770553566976
[1, 2, [3, 4]] 2770553748800
[1, 2, [3, 4]] 2770553748160
改简单子对象
[5, 2, [3, 4]] 2770553566976
[1, 2, [3, 4]] 2770553748800
[1, 2, [3, 4]] 2770553748160
改复杂子对象
[5, 2, [6, 4]] 2770553566976
[1, 2, [6, 4]] 2770553748800
[1, 2, [3, 4]] 2770553748160

17、递归求和1+2+3+4+。。。10

sum=0
for i in range(1,11):
    sum=sum+i
print(sum)

18、用两种方法去空格

str="hello world ha ha ha"
print(str.replace(" ",""))
s=str.split(" ")
print(s)
print("".join(s))

19、int(“1.4”),int(1.4)输出结果?

print(int("1.4"))#报错
print(int(1.4))#1

20、68、C:\Users\ry-wu.junya\Desktop>python 1.py 22 33命令行启动程序并传参,print(sys.argv)会输出什么数据?

文件名和参数构成的列表
在这里插入图片描述
Sys.argv[ ]其实就是一个列表,里边的项为用户输入的参数
21、IOError、AttributeError、ImportError、IndentationError、IndexError、KeyError、SyntaxError、NameError分别代表什么异常
IOError:输入输出异常
AttributeError:试图访问一个对象没有的属性
ImportError:无法引入模块或包,基本是路径问题
IndentationError:语法错误,代码没有正确的对齐
IndexError:下标索引超出序列边界
KeyError:试图访问你字典里不存在的键
SyntaxError:Python代码逻辑语法出错,不能执行
NameError:使用一个还未赋予对象的变量
22、lambda匿名函数好处
精简代码,lambda省去了定义函数,map省去了写for循环过程
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值