2020年度python面试题100

2020年度python面试题100

ID:83055229

大小:185.36 KB

页数:99页

时间:2023-09-20

上传者:简单2019
2020年度python面试题100_第1页
2020年度python面试题100_第2页
2020年度python面试题100_第3页
2020年度python面试题100_第4页
2020年度python面试题100_第5页
2020年度python面试题100_第6页
2020年度python面试题100_第7页
2020年度python面试题100_第8页
2020年度python面试题100_第9页
2020年度python面试题100_第10页
资源描述:

《2020年度python面试题100》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库

2020年python面试题!00

1Python语言特性1Python的函数参数传递看两个如下例子,分析运行结果:代码ー:a=1deffun(a):a=2fun(a)print(a)#1代码二:a=[]deffun(a):(1)fun(a)

2print(a)#[1]所有的变量都可以理解是内存中一个对象的“引用”,或者,也可以看似c中void*的感觉。这里记住的是类型是属于对象的,而不是变量。而对象有两种,“可更改"(mutable)与"不可更改"(immutable)对象。在python中,strings,tuples,和numbers是不可更改的对象,而list,diet等则是可以修改的对象。(这就是这个问题的重点)当ー个引用传递给函数的时候,函数自动复制ー份引用,,当函数返回的时候,,函数内的引用指向的是可变对象,对它的操作就和定位了指针地址一样,在内存里进行修改.2Python中的元类(metadass)元类就是用来创建类的"东西”。你创建类就是为了创建类的实例对象,但是我们已经学习到了Python中的类也是对象。好吧,元类就是用来创建这些类(对象)的,元类就是类的类这个非常的不常用,详情请看:《深刻理解Python中的元类(metaclass)》3@staticmethod和@dassmethodPython其实有3个方法,即静态方法(staticmethod),类方法(classmethod)和实例方法,如下:

3classA(object):deffoo(self,x):printMexecutingfoo(%s,%s)H%(self,x)@classmethoddefclass_f(M)(cls,x):print("executingclass_foo(%s,%s)"%(cls,x))@staticmethoddefstatic_foo(x):print("executingstatic_foo(%s)"%x)a=A(),我们知道在类里每次定义方法的时候都需要绑定这个实例,就是foo(self,x),为什么要这么做呢?因为实例方法的调用离不开实例,我们需要把实例自己传给函数,(x)(其实是foo(a,x)).类方法一样,只不过它传递的是类而不是实例,(x).注意这里的self和cis可以替换别的参数,但是python的约定是这俩,还是不要改的好.对于静态方法其实和普通的方法一样,不需要对谁进行绑定,(x)(x)来调用.\实例方法类方法静态方法a=A()a.foo(x)a.class_foo(x)a.static_foo(x)

4实例方法类方法静态方法A不可用A.class_foo(x)A.static_foo(x)4类变量和实例变量classPerson:name=,,aaaupl=Person()p2=Person()pl.name=,,bbb,*print(pl.name)#bbbprint(p2.name)#aaaprint(Person.name)#aaa类变量就是供类使用的变量,实例变量就是供实例使用的.ゴbbb”是实例调用了类变量,这其实和上面第一个问题ー样,就是函数传参的问题尸"aaa”,但是在实例的作用域里把类变量的引用改变了,就变成了一个实例变量,.可以看看下面的例子:classPerson:name=[]

5pl=PersonOp2=Person()pl.name.append(l)print(pl.name)#[1]print(p2.name)#[1]print(Person.nanie)#[1]5Python自省这个也是python彪悍的特性.自省就是面向对象的语言所写的程序在运行时,(),dir(),getattr(),hasattr(),isinstance().6字典推导式可能你见过列表推导时,却没有见过字典推导式,:d={key:valuefor(key,value)initerable)7Python中单下划线和双下划线1»>classMyClassO:2...def_init_(self):3...self._superprivate="Hello”

6self._semiprivate=",world!"6»>me=MyClassO7»>print(mc._superprivate)8Traceback(mostrecentcalllast):9File"",linel,in10AttributeError:myClassinstancehasnoattribute*_superprivate,11»>print(mc._semiprivate)12,world!13»>printme._diet_14{[MyClass_superprivate':'Hello',]semiprivate':',world!'}ー种约定,Python内部的名字,用来区别其它用户自定义的命名,以防冲突._foo:ー种约定,._f。。:这个有真正的意义:解析器用/lassname_f。。来代替这个名字,以区别和其它类相同的命名.详情见:8字符串格式化:%.%:Python:

7"hithere%s"%name但是,如果name恰好是(1,2,3)“你必须这样做:"hithere%s"%(name,)#提供ー个单元素的数组而不是ー个参数9迭代器和生成器在Python中,这种ー边循环ー边计算的机制,称为生成器:generator。可以被next。函数调用并不断返回下ー个值的对象称为迭代器:Iterator。这个是stackoverflow里python排名第一的问题,值得一看:10*argsand**kwargs用・args和**kwargs只是为了方便并没有强制使用它们.当你不确定你的函数里将要传递多少参数时你可以用・,它可以传递任意数量的参数:1»>defprint_everything(*args):forcount,thinginenumerate(args):

8print'{〇}.{l}'.format(count,thing)5»>print_everything('apple*,'banana','cabbage')60.apple71.banana82.cabbage相似的,**kwargs允许你使用没有事先定义的参数名:1»>deftable_things(**kwargs):2...forname,valueinkwargs.items():3...print'{0}={l}'.format(name,value)4…5»>table_things(apple='fruit',cabbage='vegetable')6cabbage=vegetable7apple=fruit*args和**:1deftable_things(titlestring9**kwargs)*args和・*kwargs可以同时在函数的定义中,但是・args必须在**kwargs前面.当调用函数时你也可以用・和**:1»>defprint_three_things(a,b,c):

91...print*a={〇},b={1},c={2}'.format(a,b,c)23»>mylist=[*aardvark\'baboon*,'cat*]4»>print_three__things(*mylist)56a=aardvark,b=baboon,c=cat就像你看到的ー样,它可以传递列表(或者元组),你也可以在函数定义或者函数调用时用・.11面向切面编程AOP和装饰器这个AOPー听起来有点懵,同学面试的时候就被问懵了…装饰器是ー个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装饰器是解决这类问题的绝佳设计,有了装饰器.我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。这个问题比较大,推荐:中文:12鸭子类型

10“当看到ー只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”我们并不关心对象是什么类型,到底是不是鸭子,只关心行为。比如在python中,有很多file-like的东西,比如StringlO.GzipFile,socket.它们有很多相同的方法,我们把它们当作文件使用。0方法中,我们并不关心它的参数是不是list,只要它是可迭代的,所以它的参数可以是list/tuple/dict/字符串/生成器等.鸭子类型在动态语言中经常使用,非常灵活,使得python不想java那样专门去弄一大堆的设计模式。13Python中重载引自知乎:函数重载主要是为了解决两个问题。1.可变参数类型。2.可变参数个数。另外,一个基本的设计原则是,仅仅当两个函数除了参数类型和参数个数不同以外,其功能是完全相同的,此时オ使用函数重载,如果两个函数的功能其实不同,那么不应当使用重载,而应当使用一个名字不同的函数。好吧,那么对于情况1,函数功能相同,但是参数类型不同,python

11如何处理?答案是根本不需要处理,因为python可以接受任何类型的参数,如果函数的功能相同,那么不同的参数类型在python中很可能是相同的代码,没有必要做成两个不同函数。那么对于情况2,函数功能相同,但参数个数不同,python如何处理?大家知道,答案就是缺省参数。对那些缺少的参数设定为缺省参数即可解决问题。因为你假设函数功能相同,那么那些缺少的参数终归是需要用的。好了,鉴于情况1跟情况2都有了解决方案,python自然就不需要函数重载了。14新式类和旧式类这个面试官问了,我说了老半天,不知道他问的真正意图是什么.这篇文章很好的介绍了新式类的特性:,所以旧式类完全是兼容的问题,(新式类是广度优先,旧式类是深度优先),〈Python核心编程》里讲的也很多.15_new_和_init_的区别这个—new_确实很少见到,先做了解吧.1._new_是一个静态方法,而_init_是一个实例方法.2.new_方法会返回一个创建的实例,而_init_什么都不返回.

123.只有在—new_返回ー个cis的实例时后面的_init_才能被调用.4.当创建一个新实例时调用_new_,初始化ー个实例时用_init_.ps:,_new_和_init_来分别在类创建,实例创建和实例初始化的时候做ー些小手脚.16单例模式~2个方法,当时面试官是让手写的.!使用—new_方法classSingleton(object):def_new_(cis,*args,**kw):ifnothasattr(cls,*_instance*):orig=super(Singleton,cis)cls._instance=orig._new_(cis,*args,**kw)returncls._instanceclassMyClass(Singleton):a=12共享属性创建实例时把所有实例的_dict_指向同一个字典,这样它们具有相同的属性和方法.

131classBorg(object):2_state={}3def_new_(cis,*args,**kw):4ob=super(Borg,cis)._new_(cis,*args,**kw)5ob._diet_=cls._state6returnob78classMyClass2(Borg):9a=13装饰器版本defsingleton(cls,*args,**kw):2instances={}3defgetinstance():4ifcisnotininstances:5instances[cls]=cls(*args,**kw)6returninstances[clsj7returngetinstance89@singleton10classMyClass:11

144import方法作为python的模块是天然的单例模式#mysingleton.pyclassMy_Singleton(object):deffoo(self):passmy_singleton=My_Singleton()#tousefrommysingletonimportmy_singletonmy_singleton.foo()17Python中的作用域Python中,ー个变量的作用域总是由在代码中被赋值的地方所决定的。当Python遇到ー个变量的话他会按照这样的顺序进行捜索:本地作用域(Local)一目前作用域被嵌入的本地作用域(Enclosinglocals)ー全局/模块作用域(Global)ー内置作用域(Built-in)18GIL线程全局锁

15线程全局锁(GlobalInterpreterLock),即Python为了保证线程安全而采取的独立线程运行的限制,说白了就是ー个核只能在同一时间运行ー个线程.解决办法就是多进程和下面的协程(协程也只是单CPU,但是能减小切换代价提升性能).19协程简单点说协程是进程和线程的升级版,逬程和线程都面临着内核态和用户态的切换问题而耗费许多切换时间,而协程就是用户自己控制切换的时机,不再需要陷入系统的内核态«Python里最常见的yield就是协程的思想!可以查看第九个问题.20闭包闭包(closure)是函数式编程的重要的语法结构。闭包也是ー种组织代码的结构,它同样提高了代码的可重复使用性。当一个内嵌函数引用其外部作作用域的变量,我们就会得到ー个闭包.总结一下,创建一个闭包必须满足以下几点:1.必须有一个内嵌函数2.内嵌函数必须引用外部函数中的变量3.外部函数的返回值必须是内嵌函数感觉闭包还是有难度的,几句话是说不明白的,还是查查相关资料.

16重点是函数运行后并不会被撤销,就像16题的instance字典一样,当函数运行完后,instance并不被销毁“只不过迁移到了函数上.闭包就像个空心球一样,你知道外面和里面,但你不知道中间是什么样.21lambda函数其实就是ー个匿名函数,为什么叫lambda?因为和后面的函数式编程有关.22Python函数式编程这个需要适当的了解一下吧,毕竟函数式编程在Python中也做了引用.python中函数式编程支持:filter函数的功能相当于过滤器。调用一个布尔函数bool_func来迭代遍历每个seq中的元素;返回一个使bool_seq返回值为true的元素的序列。»>a=[1,2,33,5,6,7]»>b=filter(lambdax:x>5,a)»>printb>>>[6,7]map函数是对ー个序列的每个项依次执行函数,下面是对一个序列每个项都乘以2:

17»>a=map(lambdax:x*2,[l,2,3J)»>list(a)[2,4,6]reduce函数是对ー个序列的每个项迭代调用函数,下面是求3的阶乘:»>reduce(lambdax,y:x*y,range(1,4))621Python里的拷贝弓I用和copy(),deepcopy()的区别1importcopy2a=[1,2,3,4,「a「か]]#原始对象34b=a#赋值,传对象的引用5c=copy.copy(a)#对象拷贝,浅拷贝6d=copy.deepcopy(a)#对象拷贝,深拷贝78a.append(5)#修改对象a9a[4].appendCc')#修改对象a中的「a'b]数组对象1011print*a=*,a12print*b=*,b

1813print*c=*,c14print'd=\d1516输出结果:17a=[1,2,3,4,['a','b','c'],5]18b=[1,2,3,4,['a','b','c'],5]19c=[1,2,3,4,['a','b','c']]20d=[l,2,3,4,['a','b'J]24Python垃圾回收机制PythonGC主要使用引用计数(referencecounting)来跟踪和回收垃圾。在引用计数的基础上,通过“标记一清除"(markandsweep)解决容器对象可能产生的循环引用问题,通过“分代回收"(generationcollection)以空间换时间的方法提高垃圾回收效率。1引用计数PyObject是每个对象必有的内容,其中ob_refent就是做为引用计数。当ー个对象有新的引用时,它的objefent就会增加,当引用它的对象被删除,,该对象生命就结束了。优点:1.简单2.实时性缺点:

191.维护引用计数消耗资源2•循环引用2标记一清除机制基本思路是先按需分配,等到没有空闲内存的时候从寄存器和程序栈上的弓I用出发,遍历以对象为节点、以引用为边构成的图,把所有可以访问到的对象打上标记,然后清扫一遍内存空间,把所有没标记的对象释放。3分代技术分代回收的整体思想是:将系统中的所有内存块根据其存活时间划分为不同的集合,每个集合就成为ー个“代”,垃圾收集频率随着“代”的存活时间的增大而减小,存活时间通常利用经过几次垃圾回收来度量。Python默认定义了三代对象集合,索引数越大,对象存活时间越长。举例:当某些内存块M经过了3次垃圾收集的清洗之后还存活时,我们就将内存块M划到一个集合A中去,而新分配的内存都划分到集合B中去。当垃圾收集开始工作时,大多数情况都只对集合B进行垃圾回收,而对集合A进行垃圾回收要隔相当长一段时间后オ逬行,这就使得垃圾收集机制需要处理的内存少了,效率自然就提高了。在这个过程中,集合B中的某些内存块由于存活时间长而会被转移到集合A中,当然,集合A中实际上也存在ー些垃圾,这些垃圾的回收会因为这种分代的机制而被延迟。

2025Python里面如何实现tuple和list的转换?答:tup/e,可以说是不可变的他t,访问方式还是通过索引下标的方式.当你明确定义个tup/e是,如果仅有一个元素,必须带有,例如:(1,).当然,,pgthon里还増加了命名式的tup/e!至于有什么用,首先第一点,楼主玩过python都知道,pgthon的函数可以有多返回值的,而python里,多返回值,就是用tup/e来表示,这是用的最广的了,比如说,你需要定义一个常量的列表,但你又不想使用!ist,那也可以是要你管tuple,例如:ifain('A.,J,B','C,}:pass26Python的isis是对比地址尸=是对比值27readfreadline和readlines・read读取整个文件・readline读取下一行,使用生成器方法readlines读取整个文件到ー个迭代器以供我们遍历

2128Python2和3的区别大部分Python库都同时支持Python,所以不管选择哪个版本都是可以的。但为了在使用Python时避开某些版本中一些常见的陷阱,或需要移植某个Python项目使用—future_模块print函数整数除法Unicodexrange触发异常处理异常next。()方法For循环变量与全局命名空间泄漏

22比较无序类型使用input。解析输入内容返回可迭代对象,而不是列表推荐:《Python和版本的重要区别》29到底什么是Python?你可以在回答中与其它技术逬行对比答案下面是一些关键点:•Python是ー种解释型语言。这就是说,与C语言和C的衍生语言不同,Python代碣在运行之前不需要编译。其它解释型语言还包括PHP和Ruby.•Python是动态类型语言,指的是你在声明变量时,不需要说明变量的类型。你可以直接编写类似X=lll和x="I'mastring”这样的代码,程序不会报错。•Python非常适合面向对象的编程(OOP),因为它支持通过组合(composition)与继承(inheritance)的方式定义类(class).Python中没有访问说明符(accessspeCifier,类似C++中的public和private),这么设计的依据是“大家都是成年人了”.

23・在Python语言中,函数是第一类对象(first-classobjects)。这指的是它们可以被指定给变量,函数既能返回函数类型,也可以接受函数作为输入。类(class)也是第一类对象。•Python代码编写快,但是运行速度比编译语言通常要慢。好在Python允许加入基于C语言编写的扩展,因此我们可以优化代码,消除瓶颈,这点通常是可以实现的。numpy就是ー个很好地例子,它的运行速度真的非常快,因为很多算术运算其实并不是通过Python实现的。•Python用途非常广泛——网络应用,自动化,科学建模,大数据应用,等等。它也常被用作“胶水语言",帮肋其它语言和组件改善运行状况。•Python让困难的事情变得容易,因此程序员可以专注于算法和数据结构的设计,而不用处理底层的细节。为什么提这个问题:如果你应聘的是ー个Python开发歯位,你就应该知道这是门什么样的语言,以及它为什么这么酷。以及它哪里不好。30补充缺失的代码defprint_directory_contents(sPath):

24这个函数接受文件夹的名称作为输入参数,返回该文件夹中文件的路径,以及其包含文件夹中文件的路径。ItIfIf#补充代码答案defprint_directory_contents(sPath):importosforsChildin(sPath):sChildPath=(sPath,sChild)if(sChildPath):print_directory_contents(sChildPath)else:printsChildPath尤其要注意以下几点:命名规范要统ー。如果样本代码中可以看出命名规范,遵循其已有的规范。

25・递归函数需要递归并终止。确保你明白其中的原理,否则你将面临无休无止的调用栈(Callstack).«我们使用OS模块与操作系统逬行交互,同时做到交互方式是可以跨平台的。你可以把代码写成sChildPath=sPath++sChild,但是这个在Windows系统上会出错。«熟悉基础模块是非常有价值的,但是别想破脑袋都背下来,记住Google是你工作中的良师益友。•如果你不明白代码的预期功能,就大胆提问。.坚持KISS原则!保持简单,不过脑子就能懂!为什么提这个问题:・说明面试者对与操作系统交互的基础知识«递归真是太好用啦31阅读下面的代码,写出AO,A1至An的最终值。AO=dict(zip(('a',七’,'c','d','e'),(l,2,3,4,5)))Al=range(lO)A2=[iforiinAlifiinAO]A3=[AO[s]forsinAO]A4=[iforiinAlifiinA3]

26A5={i:i*iforiinAl}A6=[[i,i*i]foriinAl]答案AO={'a':1,'c':3,b':2,'e':5,'d':4}Al=[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]]为什么提这个问题:•列表解析(listcomprehension)十分节约时间,对很多人来说也是一个大的学习障碍。•如果你读懂了这些代码,就很可能可以写下正确地值。•其中部分代码故意写的怪怪的.因为你共事的人之中也会有怪人。32下面代码会输出什么:

27deff(x,l=[]):foriinrange(x):(i*i)print(l)f(2)f(3,[3,2,1])f⑶答案:01][3,2,1,0,1,4][0,1,〇,1,4]

28呃?第一个函数调用十分明显,for循环先后将〇和!添加至了空列表I中。I是变量的名字,指向内存中存储的一个列表。第二个函数调用在一块新的内存中创建了新的列表。I这时指向了新生成的列表。之后再往新列表中添加〇、!和4。很棒吧。第三个函数调用的结果就有些奇怪了。它使用了之前内存地址中存储的旧列表。这就是为什么它的前两个元素是〇和1了。33你如何管理不同版本的代码?答案:版本管理!被问到这个问题的时候,你应该要表现得很兴奋,甚至告诉他们你是如何使用Git(或是其它你最喜欢的工具)追踪自己和奶奶的书信往来。我偏向于使用Git作为版本控制系统(VCS)»但还有其它的选择,比如subversion(SVN).

29为什么提这个问题:因为没有版本控制的代码,就像没有杯子的咖啡。有时候我们需要写ー些一次性的、可以随手扔掉的脚本,这种情况下不作版本控制没关系。但是如果你面对的是大量的代码,使用版本控制系统是有利的。版本控制可以帮你追踪谁对代码库做了什么操作;发现新引入了什么bug;管理你的软件的不同版本和发行版;在团队成员中分享源代码;部署及其它自动化处理。它能让你回滚到出现问题之前的版本,单凭这点就尤其棒了。还有其它的好功能。怎么ー个棒字了得!34“猴子补丁"(monkeypatching)指的是什么?这种做法好吗?答案:“猴子补丁”就是指,在函数或对象已经定义之后,再去改变它们的行为。举个例子:importdatetime=lambda:(,12,12)大部分情况下,这是种很不好的做法一因为函数在代码库中的行为最好是都保持一致。打"猴子补丁”的原因可能是为了测试。mock包对实现这个目的很有帮助。为什么提这个问题?答对这个问题说明你对单元测试的方法有一定了解。你如果提到要避免"猴子补丁”,可以说明你不是那种喜欢花里胡哨代码的程序员(公司里就有这种人,跟他们共事真是糟糕透了),而是

30更注重可维护性。还记得KISS原则码?答对这个问题还说明你明白ー些Python底层运作的方式,函数实际是如何存储、调用等等。另外:如果你没读过mock模块的话,真的值得花时间读ー读。这个模块非常有用。35阅读下面的代码,它的输出结果是什么?classA(object):defgo(self):print"goAgo!"defstop(self):print"stopAstop!"defpause(self):raiseException("NotImplemented")classB(A):defgo(self):super(B,self).go()print"goBgo!"

31classC(A):defgo(self):super(C,self).go()print"goCgo!"defstop(self):super(C,self).stop()print"stopCstop!"classD(B,C):defgo(self):super(D,self).go()print"goDgo!"defstop(self):super(D,self).stop()print"stopDstop!"defpause(self):

32print"waitDwait!"classE(B,C):passa=A()b=B()c=C()d=D0e=EO#说明下列代码的输出结果0000

33000000000答案输出结果以注释的形式表示:0#goAgo!

34#goAgo!#goBgo!0#goAgo!#goCgo!0#goAgo!#goCgo!#goBgo!#goDgo!0#goAgo!#goCgo!

35#goBgo!0#stopAstop!0#stopAstop!0#stopAstop!#stopCstop!0#stopAstop!#stopCstop!#stopDstop!

36#stopAstop!#...Exception:NotImplemented#...Exception:NotImplemented#...Exception:NotImplemented#waitDwait!#...Exception:NotImplemented

37为什么提这介问题?因为面向对象的编程真的真的很重要.不骗你。答对这道问题说明你理解了继承和Python中super函数的用法。36阅读下面的代码,它的输出结果是什么?classNode(object):def_init_(self,sName):=[]=sNamedef_repr_(self):return"〈Node'{}'>".fonnat()defappend(self,*args,**kwargs):(*args,**kwargs)defprint_all_l(self):printselfforoChildin:

38defprint_all_2(self):defgen(o):IAII=[0,]whileIAII:oNext=(0)0yieldoNextforoNodeingen(self):printoNodeoRoot=Node("root")oChildl=Node("childl")oChild2=Node("child2")oChild3=Node("child3")oChild4=Node("child4")oChildS=Node("child5")oChild6=Node("child6")

39oChild7=Node("child7")oChild8=Node("child8")oChild9=Node("child9")oChildlO=Node("childlO")(oChildl)(oChild2)(oChild3)(oChild4)(oChild5)(oChild6)(oChild7)(oChild8)(oChild9)(oChildlO)#说明下面代码的输出结果

400答案()会打印下面的结果:>()会打印下面的结果:

41〈Node'root'〉为什么提这个问题?因为对象的精髓就在于组合(composition)与对象构造(objectconstruction)«对象需要有组合成分构成,而且得以某种方式初始化。这里也涉及到递归和生成器(generator)的使用。生成器是很棒的数据类型。你可以只通过构造ー个很长的列表,然后打印列表的内容,就可以取得与print_all_2类似的功能。生成器还有一个好处,就是不用占据很多内存。

42有一点还值得指出,就是print_all_!会以深度优先(depth-first)的方式遍历树(tree),而print.all_2则是宽度优先(width-first).有时候,ー种遍历方式比另ー种更合适。但这要看你的应用的具体情况。9^:try...except...except...[else...][finally...]执行try下的语句,如果引发异常,则执行过程会跳到except语句。对每个except分支顺序尝试执行,如果引发的异常与except中的异常组匹配,执行相应的语句。如果所有的except都不匹配,则异常会传递到下ー个调用本代码的最高层try代码中。try下的语句正常执行,则执行else块代码。如果发生异常,就不会执行如果存在finally语句,最后总是会执行。9答:pass语句不会执行任何操作,一般作为占位符或者创建占位程序,whileFalse:pass()函数的用法?答:列出ー组数据,经常用在forinrange。循环中

43答:可以使用re模块中的sub()函数或者subn()函数来进行查询和替换,格式:sub(replacement,string[,count=0])(replacement是被替换成的文本,string是需要被替换的文本,count是ー个可选参数,指最大被替换的数量)>>>importre>>>p=('blue|white|red')>>>print(('colour'/bluesocksandredshoes'))coloursocksandcolourshoes>>>print(('colour','bluesocksandredshoes',count=l))coloursocksandredshoessubn()方法执行的效果跟sub()ー样,不过它会返回一个二维数组,包括替换后的新的字符串和总共替换的数量()和search()的区别?

44答:re模块中match(pattern,string[,flags]),检查string的开头是否与pattern匹配。re模块中research(pattern,string[,flags]),在string搜索pattern的第一个匹配值。>>>print(('super','superstition').span())(0,5)>>>print(('super','insuperable'))None>>>print(('super','superstition').span())(0.5)>>>print(('super','insuperable').span())(2,7)tag的时候,<.*>和く.*?>有什么区别?答:术语叫贪婪匹配(<.*>)和非贪婪匹配(く・?〉)例如:test

45test<.*?>:9答:random模块随机整数:(a,b):返回随机整数x,a<=x<=b(start,stop,Lstep]):返回一个范围在(start,st。p,step)之间的随机整数,不包括结束值。随机实数:():返回〇到1之间的浮点数(a,b):返回指定范围内的浮点数。9答:PyChecker是一个python代码的静态分析工具,它可以帮助查找python代码的bug,会对代码的复杂度和格式提出警告Pylint是另外一个工具可以逬行codingstandard检查

46答:解决方法是在function的开始插入ー个global声明:deff()globalx,双引号,三引号的区别答:单引号和双引号是等效的,如果要换行,需要符号(ヽ),三引号则可以直接换行,并且可以包含注释如果要表示Let'sgo这个字符串单引号:s4=*LetVsgo,双引号:s5="Let'sgo”s6='Irealylike*'python"!'这就是单引号和双引号都可以表示字符串的原因了46Python和多线程(multi-threading)〇这是个好主意码?列举ー些让Python代码以并行方式运行的方法。

47Python并不支持真正意义上的多线程。Python中提供了多线程包,但是如果你想通过多线程提高代码的速度,使用多线程包并不是介好主意。Python中有一介被称为GlobalInterpreterLock(GIL)的东西,它会确保任何时候你的多个线程中,只有一个被执行。线程的执行速度非常之快,会让你误以为线程是并行执行的,但是实际上都是轮流执行。经过GIL这一道关卡处理,会增加执行的开销。这意味着,如果你想提高代码的运行速度,使用threading包并不是一介很好的方法。不过还是有很多理由促使我们使用threading包的。如果你想同时执行ー些任务,而且不考虑效率问题,那么使用这介包是完全没问题的,而且也很方便。但是大部分情况下,并不是这么一回事,你会希望把多线程的部分外包给操作系统完成(通过开启多介迸程),或者是某些调用你的Python代码的外部程序(例如Spark或Hadoop),又或者是你的Python代码调用的其它代码(例如,你可以在Python中调用C函数,用于处理开销较大的多线程工作I为什么提这个问题因为GIL就是个混账东西(A-hole!很多人花费大量的时间,试图寻找自己多线程代码中的瓶颈,直到他们明白GIL的存在。47将下面的函数按照执行效率高低排序。它们都接受由0至1之间的数字构成的列表作为输入。这介列表可以很长。ー

48个输入列表的示例如下:[()foriinrange(100000)].你如何证明自己的答案是正确的。deffl(IIn):11=sorted(IIn)12=[iforiin11ifi<]return[i*iforiin12]deff2(IIn):13=[iforiinIlnifi<]14=sorted(ll)return[i*iforiin12]deff3(IIn):15=[i*iforiinIln]16=sorted(ll)return[iforiin11ifi<(*)]

49按执行效率从高到低排列:f2、fl和f3.要证明这个答案是对的,你应该知道如何分析自己代码的性能。Python中有一个很好的程序分析包,可以满足这个需求。importcProfilelln=[()foriinrange(lOOOOO)]('fl(Hn),)Cf2(IIn),)Cf3(IIn),)为了向大家逬行完整地说明,下面我们给出上述分析代码的输出结果:>>>('fl(IIn),)4functioncallsinsecondsOrderedby:standardnamencallstottimepercallcumtimepercallfilename:lineno(function)

501:l(fl)1:l()1{method'disable'of"objects}1{sorted}>>>('f2(IIn),)4functioncallsinsecondsOrderedby:standardnamepercallncallstottimepercallcumtimefilename:lineno(function)1:l(f2)1:l()1{method'disable'of"objects}1{sorted}>>>('f3(IIn),)

514functioncallsinsecondsOrderedby:standardnamencallstottimepercallcumtimepercallfilename:lineno(function)1:l(f3)1:l()1{method'disable,of"objects}1{sorted}为什么提这个问题?定位并避免代码瓶颈是非常有价值的技能。想要编写许多高效的代码,最终都要回答常识上来——在上面的例子中,如果列表较小的话,很明显是先进行排序更快,因此如果你可以在排序前先进行筛选,那通常都是比较好的做法。其它不

52显而易见的问题仍然可以通过恰当的工具来定位。因此了解这些工具是有好处的。9可以使用sub()方法来进行査询和替换»sub方法的格式为:sub(replacement,string[,count=0])replacement是被替换成的文本string是需要被替换的文本count是一个可选参数,指最大被替换的数量()和match。的区别?match。函数只检测RE是不是在string的开始位置匹配,search。会扫描整个string查找匹配,也就是说match。只有在〇位置匹配成功的话オ有返回,如果不是开始位置匹配成功的话,match。就返回nonetag的时候,<.*>和く.*?>有什么区别?前者是贪婪匹配,会从头到尾匹配va>xyz,而后者是非贪婪匹配,只匹配到第一个>〇

53importrandom0它会返回一个随机的〇和1之间的浮点数操作系统1selectrpoll和epoll其实所有的!/O都是轮询的方法,只不过实现的层面不同罢了.这个问题可能有点深入了,但相信能回答出这个问题是对1/.基本上select有3个缺点:1.连接数受限2.查找配对速度慢3.数据由内核拷贝到用户态pol!改善了第一个缺点epoll改了三个缺点.

542调度算法1.先来先服务(FCFS,FirstComeFirstServe)2.短作业优先(SJF,ShortestJobFirst)3.最高优先权调度(PriorityScheduling)4.时间片轮转(RR,RoundRobin)5.多级反馈队列调度(multilevelfeedbackqueuescheduling)实时调度算法:1.最早截至时间优先EDF2.最低松弛度优先LLF3死锁原因:1.竞争资源2.程序推逬顺序不当必要条件:1.互斥条件2.请求和保持条件3.不剥夺条件处理死锁基本方法:

551.预防死锁(摒弃除1以外的条件)2.避免死锁(银行家算法)3.检测死锁(资源分配图)4.解除死锁1,剥夺资源2,撤销逬程4程序编译与链接Bulid过程可以分解为4个步骤:预处理(Prepressing),编译(Compilation)、汇编(Assemb卜)、链接(Linking)以c语言为例:1预处理预编译过程主要处理那些源文件中的以“犷开始的预编译指令,主要处理规则有:1.将所有的"#define”删除,并展开所用的宏定义2.处理所有条件预编译指令,比如"#if"、"#ifdef"、"#elif"、"#endif"3.处理“include”预编译指令,将被包含的文件插入到该编译指令的位置,注:此过程是递归进行的5.添加行号和文件名标识,以便于编译时编译器产生调试用的行号信息以及用于编译时产生编译错误或警告时可显示行号

565.保留所有的#pragma编译器指令。2编译编译过程就是把预处理完的文件进行一系列的词法分析、语法分析、语义分析及优化后生成相应的汇编代码文件。这个过程是整个程序构建的核心部分。3汇编汇编器是将汇编代码转化成机器可以执行的指令,每一条汇编语句几乎都是一条机器指令。经过编译、链接、汇编输出的文件成为目标文件(ObjectFile)4链接链接的主要内容就是把各个模块之间相互弓I用的部分处理好,使各个模块可以正确的拼接。链接的主要过程包块地址和空间的分配(AddressandStorageAllocation)、符号决议(SymbolResolution)和重定位(Relocation)等步骤。5静态链接和动态链接静态链接方法:静态链接的时候,载入代码就会把程序会用到的动态代码或动态代码的地址确定下来静态库的链接可以使用静态链接,动态链接库也可以使用这种方法链接导入库

57动态链接方法:使用这种方式的程序并不在一开始就完成动态链接,而是直到真正调用动态库代码时,载入程序オ计算(被调用的那部分)动态代码的逻辑地址,然后等到某个时候,程序又需要调用另外某块动态代码时,载入程序又去计算这部分代码的逻辑地址,所以,这种方式使程序初始化时间较短,但运行期间的性能比不上静态链接的程序6虚拟内存技术虚拟存储器是值具有请求调入功能和置换功能,能从逻辑上对内存容量加以扩充的一种存储系统.7分页和分段分页:用户程序的地址空间被划分成若干固定大小的区域,称为“页”,相应地,内存空间分成若干个物理块,页和块的大小相等。可将用户程序的任一页放在内存的任一块中,实现了离散分配。分段:将用户程序地址空间分成若干个大小不等的段,每段可以定义一组相对完整的逻辑信息。存储分配时,以段为单位,段与段在内存中可以不相邻接,也实现了离散分配。分页与分段的主要区别1.页是信息的物理单位,分页是为了实现非连续分配,以便解决内存碎片问题,,它含有一组意义相对完整的信息,分段的目的是为了更好地实现共享,满足用户的需要.2.页的大小固定,由系统确定,,决定于用户所编写的程序,通常由编译程序在对源程序进行编译时根据信息的性质来划分.

581..8页面置换算法1.最佳置换算法OPT:不可能实现2.先进先出FIFO3.最近最久未使用算法LRU:最近一段时间里最久没有使用过的页面予以置换.4.dock算法9边沿触发和水平触发边缘触发是指每当状态变化时发生一个io事件,条件触发是只要满足条件就发生一个!o事件数据库!事务数据库事务(DatabaseTransaction),是指作为单个逻辑工作单元执行的ー系列操作,要么完全地执行,要么完全地不执行。2数据库索引

59索引是对数据库表中一列或多列的值进行排序的ー种结构,使用索引可快速访问数据库表中的特定信息。索引分为聚簇索引和非聚簇索引两种,聚簇索引是按照数据存放的物理位置为顺序的,而非聚簇索引就不一样了;聚簇索引能提高多行检索的速度,而非聚簇索引对于单行的检索很快。推荐:3Redis原理4乐观锁和悲观锁悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作乐观锁:假设不会发生并发冲突,只在提交操作时检査是否违反数据完整性。5MVCC大多数的MySQL事务型存储引擎如InnoDB,Falcon以及PBXT都不使用一种简单的行锁机制。事实上,他们都和另外一种用来增加并发性的被称为〃多版本并发控制(MVCCr的机制

60来一起使用。MVCC不只使用在MySQL中,Oracle.PostgreSQL,以及其它ー些数据库系统也同样使用它。5MylSAM和!nnoDBMylSAM适合于ー些需要大量查询的应用,但其对于有大量写操作并不是很好。甚至你只是需要update一个字段,整个表都会被锁起来,而别的进程,就算是读进程都无法操作直到读操作完成。另外,MylSAM对于SELECTCOUNT(*)这类的计算是超快无比的。InnoDB的趋势会是ー个非常复杂的存储引擎,对于ー些小的应用,它会比MylSAM还慢。他是它支持“行锁”,于是在写操作比较多的时候,会更优秀。并且,他还支持更多的高级应用,比如:事务。网络1三次握手1.客户端通过向服务器端发送ー个SYN来创建一个主动打开,作为三路握手的一部分。客户端把这段连接的序号设定为随机数A。

611.服务器端应当为ー个合法的SYN回送ー个SYN/ACK0ACK的确认码应为A+l,SYN/ACK包本身又有一个随机序号Bo2.最后,客户端再发送ー个ACK,当服务端受到这个ACK的时候,就完成了三路握手,并逬入了连接创建状态。此时包序号被设定为收到的确认号A+1,而响应则为B+lo2四次挥手CP的连接的拆除需要发送四个包,因此称为四次挥手(four-wayhandshake)o客户端或服务器均可主动发起挥手动作,在socket编程中,任何一方执行close。操作即可产生挥手操作。(1)客户端A发送ー个FIN,用来关闭客户A到服务器B的数据传送。(2)服务器B收到这个FIN,它发回ー个ACK,确认序号为收到的序号加1〇和SYN一样,一个FIN将占用ー个序号。

62(3)服务器B关闭与客户端A的连接,发送一个FIN给客户端A。(4)客户端A发回ACK报文确认,并将确认序号设置为收到序号加1〇3ARP协议地址解析协议(AddressResolutionProtocol):根据IP地址获取物理地址的一个TCP/IP协议4urllib和urllib2的区别这个面试官确实问过,当时答的urllib2可以Post而urllib不可以.1.urllib提供urlencode方法用来GET查询字符串的产生,而urllib2没有。这是为何urllib常和urllib2ー起使用的原因。2.urllib2可以接受一个Request类的实例来设置URL请求的headers,urllib仅可以接受URL。这意味着,你不可以伪装你的UserAgent字符串等。5Post和Get区别GET后退按钮7刷新无害,POST数据会被重新提交(浏览器应该告知用户数据会

63GET书签可收藏,POST为书签不可收藏。GET能被缓存,POST不能缓存。GET编码类型application/x-www-form-url,POST编码类型encodedapplication/x-www-form-urlencoded或multipart/form-data.为二进制数据使用多重编码。GET历史参数保留在浏览器历史中。POST参数不会保存在浏览器历史中。GET对数据长度有限制,当发送数据时,GET方法向URL添加数据;URL的长度是受限制的(URL的最大长度是2048个字符)。POST无限制。GET只允许ASCI!字符。POST没有限制。也允许二进制数据。与POST相比,GET的安全性较差,因为所发送的数据是URL的一部分。在发送密码或其它敏感信息时绝不要使用GET!POST比GET更安全,因为参数不会被保存在浏览器历史或web服务器日志中。GET的数据在URL中对所有人都是可见的。POST的数据不会显示在URL中。5Cookie和SessionCookieSession

64储存客户端服务器端位置跟踪会话,也可以保存用户偏好设置或者目的跟踪会话保存用户名密码等安全不安全安全性session技术是要使用到cookie的,之所以出现session技术,主要是为了安全。5apache和nginx的区别nginx相对叩ache的优点:•轻量级,同样起web服务,比叩ache占用更少的内存及资源•抗并发,nginx处理请求是异步非阻塞的,支持更多的并发连接,而apache则是阻塞型的,在高井发下nginx能保持低资源低消耗高性能•配置简洁•高度模块化的设计,编写模块相对简单•社区活跃apache相对nginx的优点:•rewrite,比nginx的rewrite强大•模块超多,基本想到的都可以找到«少bug,nginx的bug相对较多

65•超稳定8网站用户密码保存1.明文保存2.明文hash后保存,如md53.MD5+Salt方式,这个salt可以随机4.知乎使用了Bcrypy(好像)加密9HTTP和HTTPSHTTPS(全称:HypertextTransferProtocoloverSecureSocketLayer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL»因此加密的详细内容就需要SSL,它是ー个URIscheme(抽象标识符体系),句法类同http:体系。用于安全的HTTP数据传输。https:URL表明它使用了HTTP,但HTTPS存在不同于HTTP的默认端口及ー个加密/身份验证层(在HTTP与TCP之间)•这个系统的最初研发由网景公司逬行,提供了身份验证与加密通讯方法,现在它被广泛用于万维网上安全敏感的通讯,例如交易支付方面。超文本传输协议(HTTP-Hypertexttransferprotocol)是一种详细规定了浏览器和万维网服务器之间互相通信的规则,通过因特网传送万维网文档的数据传送协议。10XSRF和XSSCSRF(Cross-siterequestforgery)跨站请求伪造•XSS(CrossSiteScripting)跨站脚本攻击CSRF重点在请求,XSS重点在脚本

6611RESTful架构(SOAP,RPC)推荐:12SOAPSOAP(原为SimpleObjectAccessProtocol的首字母缩写,即简单对象访问协议)是交换数据的一种协议规范,使用在计算机网络Web服务(webservice)中,交换带结构信息。SOAP为了简化网页服务器(WebServer)从XML数据库中提取数据时,节省去格式化页面时间,以及不同应用程序之间按照HTTP通信协议,遵从XML格式执行资料互换,使其抽象于语言实现、平台和硬件。13RPCRPC(RemoteProcedureCallProtocol)远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OS!网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。总结:。为了企业SOA,若干厂商联合推出webservice,制定了wsdl接口定义,,腺肿SOA被简化为http+xml/O以资源为导向,任何操作无^是对资源的増删改查,于是统一的REST出现了.进化的顺序:RPC->SOAP->RESTful14CG!和WSGICGI是通用网关接口,是连接web服务器和应用程序的接口,用户通过CGI来获取动态数据或文件等。CGI程序是一个独立的程序,它可以用几乎所有语言来写,包括perl,c,lua,python等等。

67WSGI,WebServerGatewayInterface,是Python应用程序或框架和Web服务器之间的ー种接口,WSGI的其中一个目的就是让用户可以用统一的语言(Python)编写前后端。16中间人攻击在GFW里屡见不鲜的,呵呵.中间人攻击(Man-in-the-middleattack,通常缩写为MITM)是指攻击者与通讯的两端分别创建独立的联系,并交换其所收到的数据,使通讯的两端认为他们正在通过一个私密的连接与对方直接对话,但事实上整个会话都被攻击者完全控制。17clOk问题

68所谓clOk问题,指的是服务器同时支持成千上万个客户端的问题,也就是concurrent10000connection(这也是clOk这个名字的由来)。18socketSocket=Ipaddress+TCP/UDP+port19浏览器缓存推荐:浏览器缓存机制其实主要就是HTTP协议定义的缓存机制(如:Expires;Cache-contro・等)Expires策略Expires是Web服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。Cache-control策略(重点关注)

69Cache-Control与Expires的作用一致,都是指明目前资源的有效期,控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据。只不过Cache-Control的选择更多,设置更细致,如果同时设置的话,其优先级高于Expires20推荐:1.请求头Host字段,ー个服务器多个网站2.长链接3.文件断点续传4.身份认证,状态管理,Cache缓存21AjaxAJAX,AsynchronousJavaScriptandXML(异步的JavaScript和XML),是与在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术。

70数据结构!红黑树红黑树与AVL的比较:AVL是严格平衡树,因此在增加或者删除节点的时候,根据不同情况,旋转的次数比红黑树要多;红黑是用非严格的平衡来换取熠删节点时候旋转次数的降低;所以简单说,如果你的应用中,搜索的次数远远大于插入和删除,那么选择AVL,如果搜索,插入删除次数几乎差不多,应该选择RB。1台阶问题/斐波纳挈ー只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。1fib=lambdan:nifn<=2elsefib(n-1)+fib(n-2)第二种记忆方法defmemo(func):cache={}defwrap(*args):ifargsnotincache:

71cache[args]=func(*args)returncache[argslreturnwrap@memodeffib(i):ifi<2:return1returnfib(i-l)+fib(i-2)第三种方法1defHb(n):2a,b=0,13for_inxrange(n):4a,b=b,a+b5returnb2变态台阶问题ー只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。fib=lambdan:nifn<2else2*fib(n-1)13矩形覆盖

72我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖ー个2*n的大矩形,总共有多少种方法?第2*n个矩形的覆盖方法等于第2*(n-l)加上第2*(n-2)的方法。f=lambdan:1ifn<2elsef(n-1)+f(n-2)4杨氏矩阵查找在一个m行n列二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。5去除列表中的重复元素用集合1list(set(l))用字典1II=212={}.fromkeys(ll).keys()3print12用字典并保持顺序

73111=[•b\,c,,,d,,,b\*c,,,a,,,a,]212=list(set(ll))312.sort(key=ll.index)4print121H=[,bVcVdVbVcVaVa,]212=[]3[12.append(i)foriin11ifnotiin12]面试官提到的,先排序然后删除.6链表成对调换1->2->3->4转换成2->1->4->3.classListNode:def_init_(self,x):self.val=xself.next=NoneclassSolution:#@paramaListNode#@returnaListNodedefswapPairs(self,head):ifhead!=Noneandhead.next!=None:

74next=head.nexthead.next=self.swapPairs(next.next)next.next=headreturnnextreturnhead7创建字典的方法1直接创建1diet={'name':'earth','port':'80'}2工厂方法1items=[('name','earth'),('port','80')]2dict2=dict(items)3dictl=dict((['name*,'earth'],['port*,'80']))3fromkeys()方法1dictl={}.fromkeys(('x','y'),-l)2dict={'x,:-l,y:-l}3dict2={}.fromkeys(('x','y'))4dict2={'x':None,'y':None)8合并两个有序列表知乎远程面试要求编程尾递归

75def_recursion_merge_sort2(ll,12,tmp):iflen(ll)==0orlen(12)==0:tmp.extend(ll)tmp.extend(12)returntmpelse:if[〇]v12[0]:tmp.append(ll[O])del11[0]else:tmp.append(12[0])delI2[O]return_recursion_merge_sort2(l1,12,tmp)defrecursion__merge_sort2(ll,12):return_recursion_merge_sort2(ll,12,[])循环算法defloop_merge_sort(ll,12):tmp=[]whilelen(ll)>0andlen(12)>0:ifll[0]<12[0]:tmp.append(ll[O])

76else:tmp.append(12[0])del12)0]tmp.extend(ll)tmp.extend(12)returntmp9交叉链表求交点去哪儿的面试,没做出来.classListNode:def—init_(self,x):self.val=xself.next=Nonedefnode(ll,12):lengthl,lenth2=0,0#求两个链表长度while11.next:11=ll.nextlength1+=1while)2.next:12=I2.nextlength2+=1#长的链表先走iflength1>Ienth2:

77for_inrange(lengthl-length!):11=11.nextelse:for_inrange(length2-lengthl):12=12.nextwhile11and12:if11.next==12.next:return11.nextelse:13=11.next14=I2.next10二分查找defbinarySearch(l,t):low,high=0,len(l)-1whilelowt:high=midelifl|mid|

78returnmidreturnlowifI[low]==telseFalseif_name_==*_main_1=[1,4,12,45,66,99,120,444]printbinarySearch(l,12)printbinarySearch(l,1)printbinarySearchd,13)printbinarySearchd,444)11快排1defqsort(seq):2ifseq==[]:3return[]4else:5pivot=seq[0]6lesser=qsort([xforxinseq[l:]ifx=pivot])8returnlesser+[pivot]+greater910if_name_==*_main_1:11seq=[5,6,78,9,0,-l,2,3,-65,12]12print(qsort(seq))12找零问题

79defcoinChange(values,money,coinsUsed):#valuesT[l:n]数组#valuesCounts钱币对应的种类数#money找出来的总钱数#coinsUsed对应于目前钱币总数i所使用的硬币数目forcentsinrange(1,money+1):minCoins=cents#从第一个开始到money的所有情况初始forvalueinvalues:ifvalue<=cents:temp=coinsUsed[cents-value]+1iftemp

80classNode(object):def_init_(self,data,left=None,right=None):self.data=dataself.left=leftself.right=righttree=Node(l,Node(3,Node(7,Node(O)),Node(6)),Node(2,Node(5),Node(4)))##15层次遍历deflookup(root):stack=[rootlwhilestack:current=stack.pop(O)printcurrent.dataifcurrent.left:stack.append(current.left)ifcurrent.right:stack.append(current.right)##16深度遍历defdeep(root):ifnotr(M)t:returnprintroot.datadeep(root.left)

81deep(root.right)if_name_=='_main—lookup(tree)deep(tree)17前中后序遍历深度遍历改变顺序就OK了18求最大树深1defmaxDepth(root):2ifnotroot:3return04returnmax(maxDepth(root.left),maxDepth(root.right))+119求两棵树是否相同1defisSameTree(p,q):2ifp==Noneandq==None:3returnTrue4elifpandq:5returnp.val==q.valandisSameTree(p.left,q.left)andisSameTree(p.right,q.right)6else:returnFalse

8220前序中序求后序defrebuild(pre,center):ifnotpre:returncur=Node(pre[0])index=center.index(pre[0])cur.left=rebuild(pre[1:index+1],center[:index])cur.right=rebuild(pre[index+1:],center)index+1:])returncurdefdeep(root):ifnotroot:returndeep(root.left)deep(root.right)printroot.data21单链表逆置classNode(object):def_init_(self,data=None,next=None):self.data=dataself.next=nextlink=Node(l,Node(2,Node(3,Node(4,Node(5,Node(6,Node(7,Node(8,Node(9)))))))))

83defrev(link):pre=linkcur=link.nextpre.next=Nonewhilecur:tmp=cur.nextcur.next=prepre=curcur=tmpreturnpreroot=rev(link)whileroot:printroot.dataroot=root.nextPythonWeb相关

84解释一下WSG!和FastCG!的关系?CGI全称是“公共网关接口”(CommonGatewaylnterface),HTTP服务器与你的或其它机器上的程序进行“交谈”的一种工具,其程序须运行在网络服务器上。CGI可以用任何ー种语言编写,只要这种语言具有标准输入、输出和环境变量。如php,perl,tcl等。FastCG!像是ー个常驻(long-live)型的CGI»它可以一直执行着,只要激活后,不会每次都要花费时间去fork一次(这是CGI最为人诟病的fork-and-execute模式)。它还支持分布式的运算,即FastCGI程序可以在网站服务器以外的主机上执行并且接受来自其它网站服务器来的请求。FastCGI是语言无关的、可伸缩架构的CG!开放扩展,其主要行为是将CGI解释器进程保持在内存中并因此获得较高的性能。众所周知,CGI解释器的反复加载是CG!性能低下的主要原因,如果CGI解释器保持在内存中并接受FastCG!进程管理器调度,则可以提供良好的性能、伸缩性、Fail-Over特性等等。WSGI的全称为:PythonWebServerGatewayInterface(PythonWeb服务器网关接口),它是Python应用程序和WEB服务器之间的ー种接口。它的作用,类似于FCGI或FASTCGI之类的协议的作用。WSGI的目标,是要建立一个简单的普遍适用的服务器与WEB框架之间的接口。

85Flup就是使用Python语言对WSGI的一种实现,是可以用于Python的应用开发中的ー种工具或者说是一种库。Spawn-fcgi是ー个小程序,这个程序的作用是管理fast-cgi进程,那么管理wsgi进程也是没有问题的,功能和php-fpm类似。故,简单地说,WSG!和FastCGI都是ー种CGI,用于连接WEB服务器与应用程序,而WSGI专指Python应用程序。而flup是WSGI的ー种实现,Spawn-fcgi是用于管理flup进程的ー个工具,可以启动多个wsgi进程,并管理它们。解释一下Django和Tornado的关系、差别Django源自ー个在线新闻Web站点,于年以开源的形式被释放出来。Django框架的核心组件有:用于创建模型的对象关系映射为最终用户设计的完美管理界面一流的URL设计设计者友好的模板语言缓存系统等等它鼓励快速开发,并遵循MVC设计。Django遵守BSD版权,最新发行版本是Djangoハ快速的开发数据库驱动的网站。它强渦代码复用,多个组件可以很方便的以“插件”形式服务于整个框架,Djang。有许多功能强大的第三方插件,你甚至可以很方便的开发出自己的工具包。这使得Djang。具有很强的可扩展性。它还强调快速开发和DRY(DoNotRepeatYourself)原则。Tornad。是FriendFeed使用的可扩展的非阻塞式web服务器及其相关工具的开源版本。这个

86Web框架看起来有些像或者Google的webapp,不过为了能有效利用非阻塞式服务器环境,这个Web框架还包含了一些相关的有用工具和优化。Tornado和现在的主流Web服务器框架(包括大多数Python的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快。得利于其非阻塞的方式和对epoll的运用,Tornado每秒可以处理数以千计的连接,这意味着对于实时Web服务来说,Tornado是ー个理想的Web框架。我们开发这个Web服务器的主要目的就是为了处理FriendFeed的实时功能在FriendFeed的应用里每ー个活动用户都会保持着ー个服务器连接。(关于如何扩容服务器,以处理数以千计的客户端的连接的问题。解释下django-debug-toolbar的使用使用django开发站点时,可以使用django-debug-toolbar来进行调试。’’到项目的MIDDLEWARE_CLASSES内。解释下Django使用redis缓存服务器为了能在Django中使用redis,还需要安装redisforDjango的插件。然后在Django的settings中配置了。现在连接和配置都已经完成了,接下来是ー个简单的例子:fromdjango.confimportsettings

87fromdjango.core.cacheimportcache#readcacheuseriddefread_from_cache(self,user_name):key='user_id_of_'+user_namevalue=cache.get(key)ifvalue==None:data=Noneelse:data=json.loads(value)returndata#writecacheuseriddefwrite_to_cache(self,user_name):key='user_id_of_'+user_namecache.set(key,json.dumps(user_name),settings.NEVER_REDIS_TIMEOUT)如何进行Django单元测试Django的单元测试使用python的unittest模块,这个模块使用基于类的方法来定义测试。fromdjango.testimportTestCasefrommyapp.modelsimportAnimalclassAnimalTestCase(TestCase):

88defsetUp(self):Animal.objects.create(name=t,li(>n",sound=,,roarH)Ammal.objects.create(name=HcatH,sound=MmeowH)deftest_animals_can_speak(self):,,M,'Animalsthatcanspeakarecorrectlyidentified,M,Hlion=Animal.objects.get(name=HlionH)cat=Animal.objects.get(name=McatM)self.assertEquaKlion.speak(),'Thelionsays"roar"')self.assertEquaKcat.speak(),'Thecatsays"meow"')执行目录下所有的测试(所有的test*.py文件):运行测试的时候,测试程序会在所有以test开头的文件中查找所有的testcases。,自动建立测试集然后运行测试。1$pythonmanage.pytest执行animals项目下tests包里的测试:$pythonmanage.pytestanimals.tests执行animals项目里的test测试:1$pythonmanage.pytestanimals

89单独执行某个testcase:1$pythonmanage.pytestanimals.tests.AnimalTestCase单独执行某个测试方法:1$pythonmanage.pytestanimals.tests.AnimalTestCase.test_animals_can_speak为测试文件提供路径:1$pythonmanage.pytestanimals/通配测试文件名:1$pythonmanage.pytest-pattern=Htests_*.pyM启用warnings提醒:1$python-Wallmanage.pytest

90解释下Http协议HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。HTTP协议的主要特点可概括如下:0:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST,每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另ー方面,在服务器不需要先前信息时它的应答就较快。解释下Http请求头和常见响应状态码Accept:指浏览器或其它客户可以接爱的MIME文件格式。可以根据它判断并返回适当的文件格式。Accept-Charset:指出浏览器可以接受的字符编码。英文浏览器的默认值是ISO-8859-1.

91Accept-Language:指出浏览器可以接受的语言种类,如en或en-us,指英语。Accept-Encoding:指出浏览器可以接受的编码方式。编码方式不同于文件格式,它是为了压缩文件并加速文件传递速度。浏览器在接收到Web响应之后先解码,然后再检查文件格式。Cache-Control:设置关于请求被代理服务器存储的相关选项。一般用不到。Connection:用来告诉服务器是否可以维持固定的HTTP连接。HTTP/,这样,当浏览器需要多个文件时(比如一个HTML文件和相关的图形文件),不需要每次都建立连接。Content-Type:用来表名request的内容类型。可以用HttpServletRequest的getContentType()方法取得。Cookie:浏览器用这个属性向服务器发送Cookie.Cookie是在浏览器中寄存的小型数据体,它可以记载和服务器相关的用户信息,也可以用来实现会话功能。状态代码有三位数字组成,第一个数字定义了响应的类别,且有五种可能取值:lxx:指示信息-表示请求已接收,继续处理2xx:成功-a示请求已被成功接收、理解、接受3xx:重定向ヨ完成请求必须进行更进一步的操作4xx:客户端错误ー请求有语法错误或请求无法实现5xx:服务器端错误一服务器未能实现合法的请求

92常见状态代码、状态描述、说明:200OK〃客户端请求成功400BadRequest〃客户端请求有语法错误,不能被服务器所理解401Unauthorized〃请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用403Forbidden〃服务器收到请求,但是拒绝提供服务404NotFound〃请求资源不存在,eg:输入了错误的URL500InternalServerError〃服务器发生不可预期的错误503ServerUnavailable〃服务器目前不能处理客户端的请求,一段时间后可能恢复正常eg:HTTP/200OK(CRLF)

93爬虫ー、试列出至少三种目前流行的大型数据库的名称:其中您最熟悉的是从年开始使用。Oracle,Mysql,SQLServerOracle根据自己情况二、有表List,并有字段A、B、C,类型都是整数。表中有如下几条记录:ABC2795643119现在对该表一次完成以下操作:查询出B和C列的值,要求按B列升序排列写出一条新的记录,值为{7,9,8}査询C列,要求消除重复的值,按降序排列写出完成完成以上操作的标

94准的SQL语句,并且写出操作3的结果。

95□createtableList(Aint,Bint,Cint)SelectB,CfromListorderbyBInsertintoListvalues(7,9,8)Selectdistinct(C)fromListorderbydesc;984三、请简要说明视图的作用日。四、列举您使用过的python网络爬虫所用到的网络数据包(最熟悉的在前):requests、urllib、urllib2%httplib2五、列举您使用过的python网络爬虫所用到的解析数据包(最熟悉的在前):

96BeautifulSoup^pyquery、Xpath、Ixml六、列举您使用过的python中的编码方式(最熟悉的在前):UTF-8,ASCIIfgbkB七、日对于ー个可迭代的(iterable)/可遍历的对象(如列表、字符串),enumerate将其组成一个索引序列,利用它可以同时获得索引和值enumerate多用于在for循环中得到计数ハ、99的八进制表示是□143九、请举出三种常用的排序算法日冒泡、选择、快速十、列出比较熟悉的爬虫框架□Scrapy十ー、用4、9、2、7四个数字,可以使用+、ー、*和/,毎个数字使

97用一次,使表达式的结果为24,表达式是□(9+7-4)*2十二、对你最有影响的或是您认为最有价值的软件方面的几本书是?十三、,查询脚本定时任务的命令是1AIX,envcrontab十四、写出在网络爬虫爬取数据的过程中,遇到的防爬虫问题的解决方案通过headers反爬虫:解决策略,伪造headers基于用户行为反爬虫:动态变化去爬取数据,模拟普通用户的行为基于动态页面的反爬虫:跟踪服务器发送的ajax请求,模拟ajax请求十五、阅读以下Python程序foriinrange(5,0,-l):print(i)请在下面写出打印结果54321十六、在某系统中一个整数占用两个八位字节,使用Python按下面的要求编写完整程序。

98接收从标准输入中依次输入的五个数字,将其组合成为ー个整数,放入全局变量n中,随后在标准输出输出这个整数。(ord(char)获取字符ASCII值的函数)人,从刚出生来到这个世界,便开始探索这个世界。累了就歇会,精神了就继续探索,直至死亡。

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。
最近更新
更多
大家都在看
近期热门
关闭