前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python简单面试题

python简单面试题

作者头像
tnt阿信
发布2020-08-05 10:14:28
9390
发布2020-08-05 10:14:28
举报
文章被收录于专栏:一个安全研究员

python简单面试题

"真的猛士敢于冒着挂科的风险做自己喜欢的事"

——鲁迅

1.Python是如何进行内存管理的?

答:从三个方面来说,一对象的引用计数机制,二垃圾回收机制,三内存池机制

一、对象的引用计数机制

Python内部使用引用计数,来保持追踪内存中的对象,所有对象都有引用计数。

引用计数增加的情况:

1,一个对象分配一个新名称

2,将其放入一个容器中(如列表、元组或字典)

引用计数减少的情况:

1,使用del语句对对象别名显示的销毁

2,引用超出作用域或被重新赋值

sys.getrefcount( )函数可以获得对象的当前引用计数

多数情况下,引用计数比你猜测得要大得多。对于不可变数据(如数字和字符串),解释器会在程序的不同部分共享内存,以便节约内存。

二、垃圾回收

1,当一个对象的引用计数归零时,它将被垃圾收集机制处理掉。

2,当两个对象a和b相互引用时,del语句可以减少a和b的引用计数,并销毁用于引用底层对象的名称。然而由于每个对象都包含一个对其他对象的应用,因此引用计数不会归零,对象也不会销毁。(从而导致内存泄露)。为解决这一问题,解释器会定期执行一个循环检测器,搜索不可访问对象的循环并删除它们。

三、内存池机制

Python提供了对内存的垃圾收集机制,但是它将不用的内存放到内存池而不是返回给操作系统。

1,Pymalloc机制。为了加速Python的执行效率,Python引入了一个内存池机制,用于管理对小块内存的申请和释放。

2,Python中所有小于256个字节的对象都使用pymalloc实现的分配器,而大的对象则使用系统的malloc。

3,对于Python对象,如整数,浮点数和List,都有其独立的私有内存池,对象间不共享他们的内存池。也就是说如果你分配又释放了大量的整数,用于缓存这些整数的内存就不能再分配给浮点数。

2.什么是lambda函数?它有什么好处?

答:lambda 表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数

lambda函数:首要用途是指点短小的回调函数

代码语言:javascript
复制
lambda [arguments]:expression
>>> a=lambdax,y:x+y
>>> a(3,11)
3.Python里面如何实现tuple和list的转换?

答:直接使用tuple和list函数就行了,type()可以判断对象的类型

4.请写出一段Python代码实现删除一个list里面的重复元素

答:

1,使用set函数,set(list)

2,使用字典函数,

代码语言:javascript
复制
>>>a=[1,2,4,2,4,5,6,5,7,8,9,0]
>>> b={}
>>>b=b.fromkeys(a)
>>>c=list(b.keys())
>>> c
5.编程用sort进行排序,然后从最后一个元素开始判断
代码语言:javascript
复制
a=[1,2,4,2,4,5,7,10,5,5,7,8,9,0,3]
a.sort()
last=a[-1]
for i inrange(len(a)-2,-1,-1):
if last==a[i]:
del a[i]
else:last=a[i]
print(a)
6.Python里面如何拷贝一个对象?(赋值,浅拷贝,深拷贝的区别)

答:赋值(=),就是创建了对象的一个新的引用,修改其中任意一个变量都会影响到另一个。

浅拷贝:创建一个新的对象,但它包含的是对原始对象中包含项的引用(如果用引用的方式修改其中一个对象,另外一个也会修改改变){1,完全切片方法;2,工厂函数,如list();3,copy模块的copy()函数}

深拷贝:创建一个新的对象,并且递归的复制它所包含的对象(修改其中一个,另外一个不会改变){copy模块的deep.deepcopy()函数}

7.介绍一下except的用法和作用?

答:try…except…except…[else…][finally…]

执行try下的语句,如果引发异常,则执行过程会跳到except语句。对每个except分支顺序尝试执行,如果引发的异常与except中的异常组匹配,执行相应的语句。如果所有的except都不匹配,则异常会传递到下一个调用本代码的最高层try代码中。

try下的语句正常执行,则执行else块代码。如果发生异常,就不会执行

如果存在finally语句,最后总是会执行。

8.Python中pass语句的作用是什么?

答:pass语句不会执行任何操作,一般作为占位符或者创建占位程序,whileFalse:pass

9.介绍一下Python下range()函数的用法?

答:列出一组数据,经常用在for in range()循环中

10.如何用Python来进行查询和替换一个文本字符串?

答:可以使用re模块中的sub()函数或者subn()函数来进行查询和替换,

格式:sub(replacement, string[,count=0])(replacement是被替换成的文本,string是需要被替换的文本,count是一个可选参数,指最大被替换的数量)

代码语言:javascript
复制
>>> import re
>>>p=re.compile(‘blue|white|red’)
>>>print(p.sub(‘colour’,'blue socks and red shoes’))
colour socks and colourshoes
>>>print(p.sub(‘colour’,'blue socks and red shoes’,count=1))
colour socks and redshoes

subn()方法执行的效果跟sub()一样,不过它会返回一个二维数组,包括替换后的新的字符串和总共替换的数量

11.Python里面match()和search()的区别?

答:re模块中match(pattern,string[,flags]),检查string的开头是否与pattern匹配。

re模块中research(pattern,string[,flags]),在string搜索pattern的第一个匹配值。

代码语言:javascript
复制
>>>print(re.match(‘super’, ‘superstition’).span())
(0, 5)
>>>print(re.match(‘super’, ‘insuperable’))
None
>>>print(re.search(‘super’, ‘superstition’).span())
(0, 5)
>>>print(re.search(‘super’, ‘insuperable’).span())
(2, 7)
12.用Python匹配HTML tag的时候,<.>和<.?>有什么区别?

答:术语叫贪婪匹配( <.> )和非贪婪匹配(<.?> )

例如:

代码语言:javascript
复制
test
<.*> :
test
<.*?> :
13.Python里面如何生成随机数?

答:random模块

随机整数:random.randint(a,b):返回随机整数x,a<=x<=b

random.randrange(start,stop,[,step]):返回一个范围在(start,stop,step)之间的随机整数,不包括结束值。

随机实数:random.random( ):返回0到1之间的浮点数

random.uniform(a,b):返回指定范围内的浮点数。

14.有没有一个工具可以帮助查找python的bug和进行静态的代码分析?

答:PyChecker是一个python代码的静态分析工具,它可以帮助查找python代码的bug, 会对代码的复杂度和格式提出警告

Pylint是另外一个工具可以进行codingstandard检查

15.如何在一个function里面设置一个全局的变量?

答:解决方法是在function的开始插入一个global声明:

代码语言:javascript
复制
def f():
    global x
16.单引号,双引号,三引号的区别

答:单引号和双引号是等效的,如果要换行,需要符号(),三引号则可以直接换行,并且可以包含注释

如果要表示Let’s go 这个字符串

代码语言:javascript
复制
单引号:s4 = ‘Let\’s go’

双引号:s5 = “Let’s go”

s6 = ‘I realy like“python”!’

这就是单引号和双引号都可以表示字符串的原因了

下面的代码输出什么?
代码语言:javascript
复制
list = ['a', 'b', 'c', 'd', 'e']
print list[10:]

上面的代码输出[],并且不会导致IndexError错误

跟你想的一样,当取列表元素的时候,如果索引值超过了元素的个数(例如在上面的列表中,取list[10])将会导致IndexError错误。但是,取一个列表的切片的时候,如果起始索引超过了元素个数,将不会引起IndexError错误,仅返回一个空列表。

这一特性将会导致一些非常难于追踪的bug,因为在运行时根本没有错误产生。

下面的代码在Python2中的输出是什么?解释你的答案
代码语言:javascript
复制
def div1(x,y):
    print "%s/%s = %s" % (x, y, x/y)

def div2(x,y):
    print "%s//%s = %s" % (x, y, x//y)

div1(5,2)
div1(5.,2)
div2(5,2)
div2(5.,2.)

另外,在Python3中上面的代码的输出有何不同(假设代码中的print语句都转化成了Python3中的语法结构)?

在Python2中,代码的输出是:

代码语言:javascript
复制
5/2 = 2
5.0/2 = 2.5
5//2 = 2
5.0//2.0 = 2.0

默认情况下,如果两个操作数都是整数,Python2默认执行整数运算。所以,5/2 结果是2,而5./2结果是2.5

注意你可以通过下面的import语句来覆盖Python2中的这一行为

from future import division 还要注意“双斜杠”(//)操作符将会一直执行整除,忽略操作数的类型。这就是为什么5.0//2.0即使在Python2中结果也是2.0

但是在Python3并没有这一行为。两个操作数都是整数时,也不执行整数运算。在Python3中,输出如下:

代码语言:javascript
复制
5/2 = 2.5
5.0/2 = 2.5
5//2 = 2
5.0//2.0 = 2.0
下面代码的输出是什么?请解释你的答案
代码语言:javascript
复制
def extendList(val, list=[]):
    list.append(val)
    return list

list1 = extendList(10)
list2 = extendList(123,[])
list3 = extendList('a')

print "list1 = %s" % list1
print "list2 = %s" % list2
print "list3 = %s" % list3

如何修改函数ExtendList的定义才能产生我们希望的行为?

输出为:

代码语言:javascript
复制
list1 = [10, 'a']
list2 = [123]
list3 = [10, 'a']

很多人会错误地预计list1等于[10],list3等于['a'],认为extendList函数的list参数在每一次函数被调用时都会被设置为默认值[]

但是,真实的情况是,默认的list只在函数定义的时候被创建一次。之后不指定list参数地调用extendList函数时,使用的都是同一个list。这是因为带默认参数的表达式是在函数定义的时候被计算的,而不是在函数调用时。

所以,list1和list3都是在操作同一个默认list,而list2是在操作它自己创建的一个独立的list(将自己的空list作为参数传递过去)

extendlist的定义可以这样定义来达到我们预期的效果:

代码语言:javascript
复制
def extendList(val, list=None):
    if list is None:
        list = []
    list.append(val)
    return list

调用修改后的函数,输出是:

代码语言:javascript
复制
list1 = [10]
list2 = [123]
list3 = ['a']
下面代码的输出是什么?请解释你的答案
代码语言:javascript
复制
class Parent(object):
    x = 1

class Child1(Parent):
    pass

class Child2(Parent):
    pass

print Parent.x, Child1.x, Child2.x
Child1.x = 2
print Parent.x, Child1.x, Child2.x
Parent.x = 3
print Parent.x, Child1.x, Child2.x
输出为:

1 1 1
1 2 1
3 2 3

让很多人感到疑惑和惊讶的是,最后一行的输出竟然不是3 2 1而是3 2 3. 为什么修改了Parent.X的值会影响到Child2.x,但是同时又没有改变Child1.x的值呢?

这个问题的关键在于,在python中,类中的变量在内部被当作字典处理。如果一个变量名在当前类的字典中没有被发现,系统将会在这个类的祖先(例如,它的父类)中继续寻找,直到找到为止(如果一个变量名在这个类和这个类的祖先中都没有,那么将会引发一个AttributeError错误)

因此,在父类中将变量x赋值为1,那么x变量将可以被当前类和所有这个类的子类引用。这就是为什么第一个print语句输出为1 1 1.

接下来,如果它的子类覆盖了这个值(例如, 当我们执行Child1.x = 2),那么这个变量的值仅仅在这个子类中发生了改变。这就是为什么第二个print语句输出1 2 1

最后,如果父类改变了这个变量的值(例如,我们执行Parent.x = 3),所有没有覆盖这个参数值的子类(在这个例子中覆盖了参数的就是Child2)都会受到影响,这就是为什么第三个print语句的输出为3 2 3

下面代码的输出是什么?请解释你的答案
代码语言:javascript
复制
def multipliers():
    return [lambda x : i * x for i in range(4)]

print [m(2) for m in multipliers()]

怎么修改multipliers的定义才能达到期望的效果?

上面代码的输出是[6, 6, 6, 6](不是[0, 2, 4, 6]).

原因是Python的闭包是延迟绑定(late binding)的。这表明在闭包中使用的变量直到内层函数被调用的时候才会被查找。结果是,当调用multipliers()返回的函数时,i参数的值会在这时被在调用环境中查找。所以,无论调用返回的哪个函数,for循环此时已经结束,i等于它最终的值3。因此,所有返回的函数都要乘以传递过来的3,因为上面的代码传递了2作为参数,所以他们都返回了6(即,3 * 2)

(顺便提一句,正如在书《The Hitchhiker’s Guide to Python》中提出来的一样, 有一种广泛传播的误解认为这个问题和lambda表达式有关,事实并非如此。通过labda表达式产生的函数并没有什么特别之处,使用普通的def定义的函数的行为和lambda表达式产生的函数的行为是一样的.)

下面是一些可以绕过这个问题的方法。

方法一是像下面一样使用Python的生成器(generator)

代码语言:javascript
复制
def multipliers():
     for i in range(4): yield lambda x : i * x 

另一个方法是创造一个闭包,通过使用一个默认参数来立即绑定它的参数

代码语言:javascript
复制
def multipliers():
    return [lambda x, i=i : i * x for i in range(4)]

或者,你也可以使用functools.partial函数:

代码语言:javascript
复制
from functools import partial
from operator import mul

def multipliers():
    return [partial(mul, i) for i in range(4)]
考虑下面的代码片段:
代码语言:javascript
复制
1. list = [ [ ] ] * 5
2. list  # output?
3. list[0].append(10)
4. list  # output?
5. list[1].append(20)
6. list  # output?
7. list.append(30)
8. list  # output?

第2,4,6,8行的输出是什么?解释你的答案.

输出如下:

代码语言:javascript
复制
[[], [], [], [], []]
[[10], [10], [10], [10], [10]]
[[10, 20], [10, 20], [10, 20], [10, 20], [10, 20]]
[[10, 20], [10, 20], [10, 20], [10, 20], [10, 20], 30]

下面是解释:

第一行的输出凭直觉就能知道,很容易理解。即:list = [ [ ] ] * 5创建了一个元素是5个列表的列表。

但是,这里要理解的关键是,list = [ [ ] ] * 5并没有创建一个包含5个不同列表的列表。创建的这个列表里的5个列表,是对同一个列表的引用(a a list of 5 references to the same list)。理解了这些,你就能更好地理解余下的输出。

list[0].append(10)将数字10添加到第一个列表。但是由于5个列表是对同一个列表的引用,所以输出是[[10], [10], [10], [10], [10]]。

同样的,list[1].append(20)将20追加到第二个列表。但是同样,由于这5个列表引用同一个列表,所以输出:[[10, 20], [10, 20], [10, 20], [10, 20], [10, 20]].

相比之下, list.append(30)是将一个全新的元素追加到“外层”的列表,所以产生了这样的输出:[[10, 20], [10, 20], [10, 20], [10, 20], [10, 20], 30].

有一个拥有N个元素的列表,用一个列表解析式生成一个新的列表,元素的值同时满足以下条件:

(a) 偶数,以及 (b) 在原列表中,索引为偶数 例如,如果list[2]的值是偶数,那么这个元素应该也被包含在新列表中,因为它在原列表中的索引也是偶数(即 2). 但是, 如果list[3]是偶数,那这个值不应该被包含在新列表中,因为它在原列表中的索引是一个奇数。

一个简单的解法如下:

代码语言:javascript
复制
[x for x in list[::2] if x%2 == 0]

例如,给出下面的列表:

代码语言:javascript
复制
   0   1   2   3    4    5    6    7    8

list = [ 1 , 3 , 5 , 8 , 10 , 13 , 18 , 36 , 78 ] 列表解析式[x for x in list[::2] if x%2 == 0] 会生成:

代码语言:javascript
复制
[10, 18, 78]

这个表达式首先取列表中索引是偶数的数字,然后过滤掉所有的奇数。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-07-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 一个安全研究员 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • python简单面试题
    • 1.Python是如何进行内存管理的?
      • 2.什么是lambda函数?它有什么好处?
        • 3.Python里面如何实现tuple和list的转换?
          • 4.请写出一段Python代码实现删除一个list里面的重复元素
            • 5.编程用sort进行排序,然后从最后一个元素开始判断
              • 6.Python里面如何拷贝一个对象?(赋值,浅拷贝,深拷贝的区别)
                • 7.介绍一下except的用法和作用?
                  • 8.Python中pass语句的作用是什么?
                    • 9.介绍一下Python下range()函数的用法?
                      • 10.如何用Python来进行查询和替换一个文本字符串?
                        • 11.Python里面match()和search()的区别?
                          • 12.用Python匹配HTML tag的时候,<.>和<.?>有什么区别?
                            • 13.Python里面如何生成随机数?
                              • 14.有没有一个工具可以帮助查找python的bug和进行静态的代码分析?
                                • 15.如何在一个function里面设置一个全局的变量?
                                  • 16.单引号,双引号,三引号的区别
                                    • 下面的代码输出什么?
                                      • 下面的代码在Python2中的输出是什么?解释你的答案
                                        • 下面代码的输出是什么?请解释你的答案
                                          • 下面代码的输出是什么?请解释你的答案
                                            • 下面代码的输出是什么?请解释你的答案
                                              • 考虑下面的代码片段:
                                                • 有一个拥有N个元素的列表,用一个列表解析式生成一个新的列表,元素的值同时满足以下条件:
                                                相关产品与服务
                                                容器服务
                                                腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                                                领券
                                                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档