python的毕业答辩问题及答案_Python面试必须要看的15个问题

更新时间:2023-07-11 05:27:58 阅读: 评论:0

python的毕业答辩问题及答案_Python⾯试必须要看的15个问
for s in A0]
A4 = [i for i in A1 if i in A3]
A5 = {i:i*i for i in A1}
A6 = [[i,i*i] for i in A1]
答案A0 = {'a': 1, 'c': 3, 'b': 2, 'e': 5, 'd': 4}
A1 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
A2 = []
A3 = [1, 3, 2, 5, 4]
A4 = [1, 2, 3, 4, 5]
A5 = {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
A6 = [[0, 0], [1, 1], [2, 4], [3, 9], [4, 16], [5, 25], [6, 36], [7, 49], [8, 64], [9, 81]]
为什么提这个问题:
列表解析(list comprehension)⼗分节约时间,对很多⼈来说也是⼀个⼤的学习障碍。
如果你读懂了这些代码,就很可能可以写下正确地值。
其中部分代码故意写的怪怪的。因为你共事的⼈之中也会有怪⼈。问题4
Python和多线程(multi-threading)。这是个好主意码?列举⼀些让Python代码以并⾏⽅式运⾏的⽅法。
答案
Python并不⽀持真正意义上的多线程。Python中提供了多线程包,但是如果你想通过多线程提⾼代码的速度,使⽤多线程包并不是个好主意。Python中有⼀个被称为Global Interpreter Lock(GIL)的东西,它会确保任何时候你的多个线程中,只有⼀个被执⾏。线程的执⾏速度⾮常之快,会让你误以为线程是并⾏执⾏的,但是实际上都是轮流执⾏。经过GIL这⼀道关卡处理,会增加执⾏的开销。这意味着,如果你想提⾼代码的运⾏速度,使⽤threading包并不是⼀个很好的⽅法。
不过还是有很多理由促使我们使⽤threading包的。如果你想同时执⾏⼀些任务,⽽且不考虑效率问题,那么使⽤这个包是完全没问题的,⽽且也很⽅便。但是⼤部分情况下,并不是这么⼀回事,你会希望把多线程的部分外包给操作系统完成(通过开启多个进程),或者是某些调⽤你的Python代码的外部程序(例如Spark或Hadoop),⼜或者是你的Python代码调⽤的其他代码(例如,你可以在Python中调⽤C函数,⽤于处理开销较⼤的多线程⼯作)。
为什么提这个问题
因为GIL就是个混账东西(A-hole)。很多⼈花费⼤量的时间,试图寻找⾃⼰多线程代码中的瓶颈,直到他们明⽩GIL的存在。问题5
cric你如何管理不同版本的代码?
答案:
版本管理!被问到这个问题的时候,你应该要表现得很兴奋,甚⾄告诉他们你是如何使⽤Git(或是其他你最喜欢的⼯具)追踪⾃⼰和奶奶的书信往来。我偏向于使⽤Git作为版本控制系统(VCS),但还有其他的选择,⽐如subversion(SVN)。
为什么提这个问题:
因为没有版本控制的代码,就像没有杯⼦的咖啡。有时候我们需要写⼀些⼀次性的、可以随⼿扔掉的脚本,这种情况下不作版本控制没关系。但是如果你⾯对的是⼤量的代码,使⽤版本控制系统是有利的。版本控制能够帮你追踪谁对代码库做了什么操作;发现新引⼊了什么bug;管理你的软件的不同版本和发⾏版;在团队成员中分享源代码;部署及其他⾃动化处理。它能让你回滚到出现问题之前的版本,单凭这点就特别棒了。还有其他的好功能。怎么⼀个棒字了得!问题6
下⾯代码会输出什么:def f(x,l=[]):
for i in range(x):
l.append(i*i)
print l
f(2)
f(3,[3,2,1])
f(3)
答案:[0, 1]
knowledgemanagement
[3, 2, 1, 0, 1, 4]
[0, 1, 0, 1, 4]
呃?
第⼀个函数调⽤⼗分明显,for循环先后将0和1添加⾄了空列表l中。l是变量的名字,指向内存中存储的⼀个列表。第⼆个函数调⽤在⼀块新的内存中创建了新的列表。l这时指向了新⽣成的列表。之后再往新列表中添加0、1、2和4。很棒吧。第三个函数调⽤的结果就有些奇怪了。它使⽤了之前内存地址中存储的旧列表。这就是为什么它的前两个元素是0和1了。
不明⽩的话就试着运⾏下⾯的代码吧:l_mem = []
l = l_mem          # the first call
for i in range(2):
l.append(i*i)
print l            # [0, 1]
l = [3,2,1]        # the cond call
for i in range(3):
l.append(i*i)
print l            # [3, 2, 1, 0, 1, 4]
l = l_mem          # the third call
yearsold
for i in range(3):
l.append(i*i)
print l            # [0, 1, 0, 1, 4]
问题7
jealous是什么意思
“猴⼦补丁”(monkey patching)指的是什么?这种做法好吗?
答案:
“猴⼦补丁”就是指,在函数或对象已经定义之后,再去改变它们的⾏为。
举个例⼦:import datetime
w = lambda: datetime.datetime(2012, 12, 12)
⼤部分情况下,这是种很不好的做法 - 因为函数在代码库中的⾏为最好是都保持⼀致。打“猴⼦补丁”的原因可能是为了测试。mock包对实现这个⽬的很有帮助。
为什么提这个问题?
答对这个问题说明你对单元测试的⽅法有⼀定了解。你如果提到要避免“猴⼦补丁”,可以说明你不是那种喜欢花⾥胡哨代码的程序员(公司⾥就有这种⼈,跟他们共事真是糟糕透了),⽽是更注重可维护性。还记得KISS原则码?答对这个问题还说明你明⽩⼀些Python底层运作的⽅式,函数实际是如何存储、调⽤等等。
另外:如果你没读过mock模块的话,真的值得花时间读⼀读。这个模块⾮常有⽤。问题8
这两个参数是什么意思:*args,**kwargs?我们为什么要使⽤它们?
答案
如果我们不确定要往函数中传⼊多少个参数,或者我们想往函数中以列表和元组的形式传参数时,那就使要⽤*args;如果我们不知道要往函数中传⼊多少个关键词参数,或者想传⼊字典的值作为关键词参数时,那就要使⽤**kwargs。args和kwargs这两个标识符是约定俗成的⽤法,你当然还可以⽤*bob和**billy,但是这样就并不太妥。
下⾯是具体的⽰例:def f(*args,**kwargs): print args, kwargs
scratch是什么意思l = [1,2,3]
t = (4,5,6)
d = {'a':7,'b':8,'c':9}
f()
f(1,2,3)                    # (1, 2, 3) {}
f(1,2,3,"groovy")          # (1, 2, 3, 'groovy') {}
f(a=1,b=2,c=3)              # () {'a': 1, 'c': 3, 'b': 2}
f(a=1,b=2,c=3,zzz="hi")    # () {'a': 1, 'c': 3, 'b': 2, 'zzz': 'hi'}
f(1,2,3,a=1,b=2,c=3)        # (1, 2, 3) {'a': 1, 'c': 3, 'b': 2}
f(*l,**d)                  # (1, 2, 3) {'a': 7, 'c': 9, 'b': 8}
f(*t,**d)                  # (4, 5, 6) {'a': 7, 'c': 9, 'b': 8}
f(1,2,*t)                  # (1, 2, 4, 5, 6) {}
f(q="winning",**d)          # () {'a': 7, 'q': 'winning', 'c': 9, 'b': 8}
f(1,2,*t,q="winning",**d)  # (1, 2, 4, 5, 6) {'a': 7, 'q': 'winning', 'c': 9, 'b': 8}
def f2(arg1,arg2,*args,**kwargs): print arg1,arg2, args, kwargs
f2(1,2,3)                      # 1 2 (3,) {}
f2(1,2,3,"groovy")              # 1 2 (3, 'groovy') {}
f2(arg1=1,arg2=2,c=3)          # 1 2 () {'c': 3}
f2(arg1=1,arg2=2,c=3,zzz="hi")  # 1 2 () {'c': 3, 'zzz': 'hi'}
f2(1,2,3,a=1,b=2,c=3)          # 1 2 (3,) {'a': 1, 'c': 3, 'b': 2}
f2(*l,**d)                  # 1 2 (3,) {'a': 7, 'c': 9, 'b': 8}
f2(*t,**d)                  # 4 5 (6,) {'a': 7, 'c': 9, 'b': 8}
f2(1,2,*t)                  # 1 2 (4, 5, 6) {}
f2(1,1,q="winning",**d)      # 1 1 () {'a': 7, 'q': 'winning', 'c': 9, 'b': 8}
f2(1,2,*t,q="winning",**d)  # 1 2 (4, 5, 6) {'a': 7, 'q': 'winning', 'c': 9, 'b': 8}
为什么提这个问题?
有时候,我们需要往函数中传⼊未知个数的参数或关键词参数。有时候,我们也希望把参数或关键词参数储存起来,以备以后使⽤。有时候,仅仅是为了节省时间。问题9
下⾯这些是什么意思:@classmethod, @staticmethod, @property?
回答背景知识
这些都是装饰器(decorator)。装饰器是⼀种特殊的函数,要么接受函数作为输⼊参数,并返回⼀个函数,要么接受⼀个类作为输⼊参数,并返回⼀个类。@标记是语法糖(syntactic sugar),可以让你以简单易读得⽅式装饰⽬标对象。@my_decorator
def my_func(stuff):
do_things
Is equivalent to
def my_func(stuff):
do_things
my_func = my_decorator(my_func)
真正的答案
prd@classmethod, @staticmethod和@property这三个装饰器的使⽤对象是在类中定义的函数。下⾯的例⼦展⽰了它们的⽤法和⾏为:class MyClass(object):
def __init__(lf):
lf._some_property = "properties are nice"
lf._some_other_property = "VERY nice"
def normal_method(*args,**kwargs):
print "calling normal_method({0},{1})".format(args,kwargs)
@classmethod
def class_method(*args,**kwargs):
print "calling class_method({0},{1})".format(args,kwargs)
@staticmethod
removaldef static_method(*args,**kwargs):
print "calling static_method({0},{1})".format(args,kwargs)
@property
def some_property(lf,*args,**kwargs):
print "calling some_property getter({0},{1},{2})".format(lf,args,kwargs)
return lf._some_property
@
def some_property(lf,*args,**kwargs):
print "calling some_property tter({0},{1},{2})".format(lf,args,kwargs)
lf._some_property = args[0]
@property
def some_other_property(lf,*args,**kwargs):
print "calling some_other_property getter({0},{1},{2})".format(lf,args,kwargs) return lf._some_other_property
o = MyClass()
# 未装饰的⽅法还是正常的⾏为⽅式,需要当前的类实例(lf)作为第⼀个参数。
# >
# normal_method((<__main__.myclass instance at>,),{})
# normal_method((<__main__.myclass instance at>, 1, 2),{'y': 4, 'x': 3})
# 类⽅法的第⼀个参数永远是该类
o.class_method
# >
o.class_method()
# class_method((,),{})
o.class_method(1,2,x=3,y=4)
# class_method((, 1, 2),{'y': 4, 'x': 3})
# 静态⽅法(static method)中除了你调⽤时传⼊的参数以外,没有其他的参数。
o.static_method
#
o.static_method()
# static_method((),{})
o.static_method(1,2,x=3,y=4)
# static_method((1, 2),{'y': 4, 'x': 3})
发型师学习网
剩余价值的生产过程
# @property是实现getter和tter⽅法的⼀种⽅式。直接调⽤它们是错误的。
the怎么读音# “只读”属性可以通过只定义getter⽅法,不定义tter⽅法实现。
o.some_property
# 调⽤some_property的getter(<__main__.myclass instance at>,(),{})
# 'properties are nice'

本文发布于:2023-07-11 05:27:58,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/78/1090290.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:参数   函数   代码   问题   作为   版本
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图