澳门新萄京导师煞费苦心帮作者收拾出最全Pyth
分类:www.澳门新萄京赌场

 

python的函数参数字传送递

看七个例证:

a = 1
def fun(a):
    a = 2
fun(a)
print a  # 1

a = []
def fun(a):
    a.append(1)
fun(a)
print a  # [1]

抱有变量都足以领略为内部存款和储蓄器中二个对象的“援用”,大概,能够看做C中的viod*的感觉

此间记住的是项目是归属对象的,并不是变量。而指标有二种,“可改进”(mutable)与“不可更换”(immutable)对象。在python中,strings, tuples, 和numbers是不可退换的指标,而list,dict等则是足以修正的靶子。(那就是那么些主题素材的要紧卡塔尔国

当三个援用传递给函数的时候,函数自动复制生机勃勃份引用,这几个函数里的援用和外市的援引没有半毛关系了.所以第一个例子里函数把引用指向了二个不可变对象,当函数重回的时候,外面包车型地铁引用没半毛认为.而第贰个例子就差别样了,函数内的引用指向的是可变对象,对它的操作就和一贯了指针地址相似,在内部存储器里进行更正.

只要还不驾驭的话,这里有更加好的解释: http://stackoverflow.com/questions/986006/how-do-i-pass-a-variable-by-reference

几日前入眼介绍的是本人个人采摘的python面试的有个别大规模的须求和应调整的学识,上面只是内部某个,更加多的请看大家

1 台阶问题/斐波纳挈

五头青蛙三遍能够跳上1级台阶,也足以跳上2级。求该引体向上上八个n级的阶梯总共有多少种跳法。

Python

fib = lambda n: n if n <= 2 else fib(n - 1) fib(n - 2)

1
fib = lambda n: n if n <= 2 else fib(n - 1) fib(n - 2)

第三种回想方法

Python

def memo(func): cache = {} def wrap(*args): if args not in cache: cache[args] = func(*args) return cache[args] return wrap @ memo def fib(i): if i < 2: return 1 return fib(i-1) fib(i-2)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def memo(func):
    cache = {}
    def wrap(*args):
        if args not in cache:
            cache[args] = func(*args)
        return cache[args]
    return wrap
 
 
@ memo
def fib(i):
    if i < 2:
        return 1
    return fib(i-1) fib(i-2)

其两种方法

Python

def fib(n): a, b = 0, 1 for _ in xrange(n): a, b = b, a b return b

1
2
3
4
5
def fib(n):
    a, b = 0, 1
    for _ in xrange(n):
        a, b = b, a b
    return b

澳门新萄京 1

python中的元类(metaclass卡塔尔

这一个可怜的有的时候用,然则像ORM这种复杂的布局依然会供给的,实际情况请看:《深远通晓Python中的元类(metaclass卡塔尔国》

[PSC开源组GitHub]() 地址 ,里面有详尽的python面试应精晓的兼具地点的知识(最终是python后台和python服务器相关的)以至个体书籍推荐,能够留邮箱发送

Python语言特色

1 Python的函数参数字传送递

2 Python中的元类(metaclass卡塔尔国

3 @staticmethod和@classmethod

4 类变量和实例变量

5 Python自省

6 字典推导式

7 Python中单下划线和双下划线

8 字符串格式化:%和.format

9 迭代器和生成器

10*argsand**kwargs

11 面向切面编制程序AOP和装饰器

12 硬尾鸭类型

13 Python中重载

14 新式类和旧式类

15__new__和__init__的区别

16 单例方式

1 使用__new__方法

2 分享属性

3 装饰器版本

4 import方法

17 Python中的作用域

18 GIL线程全局锁

19 协程

20 闭包

21 lambda函数

22 Python函数式编制程序

23 Python里的正片

24 Python垃圾回笼机制

1 援引计数

2 标志-消释机制

3 分代技巧

25 Python的List

26 Python的is

27 read,readline和readlines

28 Python2和3的区别

29 super.init()

30 range-and-xrange

操作系统

1 select,poll和epoll

2 调治算法

3 死锁

4 程序编写翻译与链接

1 预处理

2 编译

3 汇编

4 链接

5 静态链接和动态链接

6 设想内部存款和储蓄器能力

7 分页和分层

分页与分支的基本点分化

8 页面置换算法

9 旁边触发和品位触发

数据库

1 事务

2 数据库索引

3 Redis原理

4 乐观锁和悲观锁

5 MVCC

6 MyISAM和InnoDB

网络

1 一次握手

2 六遍挥手

3 ARP协议

4 urllib和urllib2的区别

5 Post和Get

6 Cookie和Session

7 apache和nginx的区别

8 网址客商密码保存

9 HTTP和HTTPS

10 XSRF和XSS

11 幂等 Idempotence

12 RESTful架构(SOAP,RPC)

13 SOAP

14 RPC

15 CGI和WSGI

16 中间人攻击

17 c10k问题

18 socket

19 浏览器缓存

20 HTTP1.0和HTTP1.1

21 Ajax

*NIX

unix进程间通讯方式(IPC卡塔尔(قطر‎

数据布局

1 红黑树

编程题

1 台阶问题/斐波纳挈

2 相当台阶难题

3 矩形覆盖

4 杨氏矩阵查找

5 去除列表中的重复元素

6 链表成对调换

7 创造字典的措施

1 间接开立

2 工厂方法

3 fromkeys()方法

8 归拢四个不改变列表

9 交叉链表求交点

10 二分查找

11 快排

12 找零难点

13 广度遍历和纵深遍历二叉树

14 二叉树节点

15 档期的顺序遍历

16 深度遍历

17 前中后序遍历

18 求最大树深

19 求两棵树是还是不是同样

20 前序中序求后序

21 单链表逆置

Python语言特征

1 Python的函数参数字传送递

看七个例证:

a=1deffun(a):    a=2fun(a)printa#1

a=[]deffun(a):    a.append(1)fun(a)printa#[1]

不无的变量都足以驾驭是内存中三个目的的“援引”,恐怕,也得以看似c中void*的感觉。

通过id来看引用a的内部存款和储蓄器地址可以比较理解:

a=1deffun(a):print"func_in",id(a)#func_in 41322472a=2print"re-point",id(a),id(2)#re-point 41322448 41322448print"func_out",id(a),id(1)#func_out 41322472 41322472fun(a)printa#1

注:具体的值在不相同Computer上运营时可能不一致。

可以见见,在施行完a = 2之后,a援引中保留的值,即内部存款和储蓄器地址发生变化,由原本1目的的处处的地址变成了2那几个实体对象的内部存款和储蓄器地址。

而首个例子a引用保存的内存值就不会爆发变化:

a=[]deffun(a):print"func_in",id(a)#func_in 53629256a.append(1)print"func_out",id(a)#func_out 53629256fun(a)printa#[1]

此处记住的是种类是归于对象的,并不是变量。而指标有二种,“可改善”(mutable)与“不可改造”(immutable)对象。在python中,strings, tuples, 和numbers是不足修正的对象,而list,dict等则是足以修正的目的。(那便是以此难点的主要卡塔尔(قطر‎

当二个援用传递给函数的时候,函数自动复制生龙活虎份引用,这些函数里的援用和异域的引用未有半毛关系了.所以第三个例子里函数把引用指向了八个不可变对象,当函数再次来到的时候,外面包车型大巴援用没半毛认为.而第一个例子就不平等了,函数内的引用指向的是可变对象,对它的操作就和固定了指针地址同样,在内部存款和储蓄器里张开改过.

生龙活虎经还不知道的话,这里有更加好的演说:http://stackoverflow.com/questions/986006/how-do-i-pass-a-variable-by-reference

2 Python中的元类(metaclass卡塔尔(قطر‎

其黄金时代特别的一时用,可是像ORM这种复杂的布局依然会需求的,实际情况请看:http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python

3 @staticmethod和@classmethod

Python其实有3个办法,即静态方法(staticmethod卡塔尔国,类措施(classmethod卡塔尔(قطر‎和实例方法,如下:

deffoo(x):print"executing foo(%s)"%(x)classA(object):deffoo(self,x):print"executing foo(%s,%s)"%(self,x)@classmethoddefclass_foo(cls,x):print"executing class_foo(%s,%s)"%(cls,x)@staticmethoddefstatic_foo(x):print"executing static_foo(%s)"%xa=A()

那边先清楚下函数参数里面包车型地铁self和cls.这么些self和cls是对类大概实例的绑定,对于平时的函数来讲我们能够这么调用foo(x卡塔尔国,这一个函数便是最常用的,它的职业跟别的东西(类,实例卡塔尔毫无干系.对于实例方法,大家领略在类里每一次定义方法的时候都亟待绑定那一个实例,正是foo(self, x卡塔尔(英语:State of Qatar),为何要如此做吧?因为实例方法的调用离不开实例,我们供给把实例自身传给函数,调用的时候是这么的a.foo(x卡塔尔(其实是foo(a,

x卡塔尔(قطر‎卡塔尔国.类方法豆蔻梢头致,只不过它传递的是类并非实例,A.class_foo(x卡塔尔.注意这里的self和cls能够替换别的参数,可是python的预约是那俩,照旧不要改的好.

对此静态方法其实和平时的法门相像,没有需求对何人举行绑定,唯意气风发的分别是调用的时候必要运用a.static_foo(x)或者A.static_foo(x)来调用.

实例方法类措施静态方法

a = A()a.foo(x)a.class_foo(x)a.static_foo(x)

A不可用A.class_foo(x)A.static_foo(x)

越来越多关于那个主题素材:http://stackoverflow.com/questions/136097/what-is-the-difference-between-staticmethod-and-classmethod-in-python

4 类变量和实例变量

classPerson:    name="aaa"p1=Person()p2=Person()p1.name="bbb"printp1.name#bbbprintp2.name#aaaprintPerson.name#aaa

类变量便是供类使用的变量,实例变量就是供实例使用的.

此地p1.name="bbb"是实例调用了类变量,那实际和上边第一个难题同样,正是函数字传送参的主题素材,p1.name一上马是指向的类变量name="aaa",然则在实例的效劳域里把类变量的援用退换了,就产生了二个实例变量,self.name不再援引Person的类变量name了.

能够看看下面包车型大巴例子:

classPerson:    name=[]p1=Person()p2=Person()p1.name.append(1)printp1.name#[1]printp2.name#[1]printPerson.name#[1]

参考:http://stackoverflow.com/questions/6470428/catch-multiple-exceptions-in-one-line-except-block

5 Python自省

以此也是python彪悍的性子.

反躬自省正是面向对象的言语所写的顺序在运转时,所能知道对象的类型.轻松一句就是运营时可以获取对象的类型.举个例子type(卡塔尔国,dir(卡塔尔国,getattr(卡塔尔国,hasattr(卡塔尔(قطر‎,isinstance(卡塔尔.

6 字典推导式

可能你见过列表推导时,却未曾见过字典推导式,在2.7中才投入的:

d={key: valuefor(key, value)initerable}

7 Python中单下划线和双下划线

>>>classMyClass():...def__init__(self):...self.__superprivate="Hello"...self._semiprivate=", world!"...>>>mc=MyClass()>>>printmc.__superprivateTraceback (most recent call last):  File"", line1,inAttributeError: myClass instance has no attribute'__superprivate'>>>printmc._semiprivate, world!>>>printmc.__dict__{'_MyClass__superprivate':'Hello','_semiprivate':', world!'}

__foo__:意气风发种约定,Python内部的名字,用来分别别的客商自定义的命名,以免冲突.

_foo:风流倜傥种约定,用来钦命变量私有.技师用来钦点个人变量的朝气蓬勃种格局.

__foo:那几个有确实的意思:深入分析器用_classname__foo来替代那些名字,以界别和任何类相仿的命名.

详情见:http://stackoverflow.com/questions/1301346/the-meaning-of-a-single-and-a-double-underscore-before-an-object-name-in-python

或者:http://www.zhihu.com/question/19754941

8 字符串格式化:%和.format

.format在无数地点看起来更便利.对于%最烦人的是它不可能同有时候传递叁个变量和元组.你大概会想下边的代码不会有哪些难题:

"hi there %s" % name

只是,如若name恰巧是(1,2,3卡塔尔,它将会抛出叁个TypeError非凡.为了保障它连接不错的,你必须要这么做:

"hi there %s" % (name,)  # 提供多个单成分的数组并非二个参数

只是有个别丑..format就从未有过那个难题.你给的第二个难点也是那样,.format美观多了.

你干吗不要它?

不明了它(在读那一个前边卡塔尔(قطر‎

为了和Python2.5合营(譬喻logging库建议使用%(issue #4))

http://stackoverflow.com/questions/5082452/python-string-formatting-vs-format

9 迭代器和生成器

其一是stackoverflow里python排行第意气风发的标题,值得生龙活虎看:http://stackoverflow.com/questions/231767/what-does-the-yield-keyword-do-in-python

那是闽南语版:http://taizilongxu.gitbooks.io/stackoverflow-about-python/content/1/README.html

10*argsand**kwargs

用*args和**kwargs只是为着便于并未压迫行使它们.

当您不明确你的函数里将要传递多少参数时您能够用*args.比如,它能够传递任意数量的参数:

>>>defprint_everything(*args):forcount, thinginenumerate(args):...print'{0}.{1}'.format(count, thing)...>>>print_everything('apple','banana','cabbage')0. apple1. banana2. cabbage

相似的,**kwargs允许你接受未有优先定义的参数名:

>>>deftable_things(**kwargs):...forname, valueinkwargs.items():...print'{0}={1}'.format(name, value)...>>>table_things(apple='fruit',cabbage='vegetable')cabbage=vegetableapple=fruit

你也足以混着用.命名参数首先得到参数值然后具备的此外参数都传送给*args和**kwargs.命名参数在列表的最前端.举例:

def table_things(titlestring, **kwargs)

*args和**kwargs能够并且在函数的定义中,不过*args必须在**kwargs前面.

当调用函数时你也可以用*和**语法.例如:

>>>defprint_three_things(a,b,c):...print'a ={0}, b ={1}, c ={2}'.format(a,b,c)...>>>mylist=['aardvark','baboon','cat']>>>print_three_things(*mylist)a=aardvark, b=baboon, c=cat

就好像您看看的同样,它能够传递列表(可能元组卡塔尔国的每朝气蓬勃项并把它们解包.注意必得与它们在函数里的参数相契合.当然,你也得以在函数定义或然函数调用时用*.

http://stackoverflow.com/questions/3394835/args-and-kwargs

11 面向切面编制程序AOP和装饰器

以此AOP蓬蓬勃勃听上去某个懵,同学面阿里的时候就被问懵了...

装饰器是叁个很有名的设计情势,平时被用来有切面需要的光景,较为特出的有插入日志、品质测量试验、事务管理等。装饰器是化解那类难题的绝佳设计,有了装饰器,大家就足以分离出大方函数中与函数功能自身毫无干系的均等代码并继续起用。归纳的讲,装饰器的效劳就是为早就存在的对象加多额外的效果。

其豆蔻梢头标题十分大,推荐:http://stackoverflow.com/questions/739654/how-can-i-make-a-chain-of-function-decorators-in-python

中文:http://taizilongxu.gitbooks.io/stackoverflow-about-python/content/3/README.html

12 绿头鸭类型

“当看见贰头鸟走起来像红鸭、游泳起来像钻水鸭、叫起来也像红鸭,那么这只鸟就足以被称作海番鸭。”

大家并不关切对象是怎么样项目,到底是否绒鸭,只关心行为。

举个例子说在python中,有不胜枚举file-like的事物,比方StringIO,GzipFile,socket。它们有非常多平等的主意,大家把它们作为文件使用。

又比方list.extend(卡塔尔(قطر‎方法中,大家并不保养它的参数是或不是list,只要它是可迭代的,所以它的参数能够是list/tuple/dict/字符串/生成器等.

海番鸭类型在动态语言中有的时候使用,极其灵活,使得python不想java那样特地去弄一大堆的设计方式。

13 Python中重载

引自和讯:http://www.zhihu.com/question/20053359

函数重载重若是为着化解五个难点。

可变参数类型。

可变参数个数。

其余,二个宗旨的安顿性基准是,仅仅当多个函数除了参数类型和参数个数分裂以外,其据守是完全雷同的,那个时候才使用函数重载,要是八个函数的功能实在不如,那么不该利用重载,而相应接纳多个名字分歧的函数。

好吧,那么对于情形 1 ,函数效用相像,可是参数类型分化,python 如何地理?答案是根本没有必要管理,因为 python 可以接收别的类型的参数,假如函数的功用近似,那么分裂的参数类型在 python 中很只怕是均等的代码,未有供给做成多少个不等函数。

那就是说对于景况 2 ,函数功用周围,但参数个数差别,python 如哪儿理?大家掌握,答案就是缺省参数。对那一个缺乏的参数设定为缺省参数就能够缓和难点。因为您要是函数功用相似,那么这几个非常不够的参数终究是需求用的。

好了,鉴于情状 1 跟 情况 2 都有了消除方案,python 自然就不要求函数重载了。

14 新式类和旧式类

本条面试官问了,作者说了老半天,不明了他问的真的意图是什么.

stackoverflow

那篇小说很好的介绍了新式类的性状:http://www.cnblogs.com/btchenguang/archive/2012/09/17/2689146.html

风行类很早在2.2就现身了,所以旧式类完全都以协作的难题,Python3里的类全部是新式类.这里有贰个MRO难题得以领会下(新式类是广度优先,旧式类是深浅优先卡塔尔,里讲的也比超多.

15__new__和__init__的区别

这个__new__当真比超级少见到,先做询问吧.

__new__是贰个静态方法,而__init__是贰个实例方法.

__new__方法会重临五个创立的实例,而__init__什么样都不再次来到.

只有在__new__回去七个cls的实例时前面包车型客车__init__工夫被调用.

当创造三个新实例时调用__new__,开端化二个实例时用__init__.

stackoverflow

ps:__metaclass__是创设类时起作用.所以大家可以分级使用__metaclass__,__new__和__init__来分别在类成立,实例制造和实例开端化的时候做一些小手脚.

16 单例方式

本条相对常考啊.一定要牢牢记住1~2个议程,那时面试官是让手写的.

1 使用__new__方法

classSingleton(object):def__new__(cls,*args,**kw):ifnothasattr(cls,'_instance'):            orig=super(Singleton,cls)cls._instance=orig.__new__(cls,*args,**kw)returncls._instanceclassMyClass(Singleton):    a=1

2 分享属性

创制实例时把持有实例的__dict__本着同叁个字典,那样它们具备同等的质量和方法.

classBorg(object):    _state={}def__new__(cls,*args,**kw):        ob=super(Borg,cls).__new__(cls,*args,**kw)        ob.__dict__=cls._statereturnobclassMyClass2(Borg):    a=1

3 装饰器版本

defsingleton(cls,*args,**kw):    instances={}defgetinstance():ifclsnotininstances:            instances[cls]=cls(*args,**kw)returninstances[cls]returngetinstance@singletonclassMyClass:...

4 import方法

用作python的模块是纯天然的单例方式

#mysingleton.pyclassMy_Singleton(object):deffoo(self):passmy_singleton=My_Singleton()#to usefrommysingletonimportmy_singletonmy_singleton.foo()

17 Python中的功效域

Python 中,三个变量的功效域总是由在代码中被赋值的地方所主宰的。

当 Python 遇到贰个变量的话他会遵守那样的逐个实行检索:

本土成效域(Local)→当前作用域被放到的本地成效域(Enclosing locals)→全局/模块效能域(Global)→内置功能域(Built-in)

18 GIL线程全局锁

线程全局锁(Global Interpreter Lock卡塔尔国,即Python为了保险线程安全而接受的独立线程运营的限量,说白了正是二个核只好在同时运维三个线程.

见Python 最难的难题

解决办法就是多进度和底下的协程(协程也只是单CPU,可是能减小切换代价升高品质卡塔尔.

19 协程

微博被问到了,呵呵哒,跪了

归纳点说协程是经过和线程的进步版,进度和线程都面对着内核态和客商态的切换难点而消耗不知凡几切换时间,而协程正是客户自个儿说了算切换的机遇,不再必要陷入系统的基本态.

Python里最何奇之有的yield便是协程的思量!可以查阅第多少个难题.

20 闭包

闭包(closure卡塔尔国是函数式编制程序的尤为重要的语法构造。闭包也是风度翩翩种集体代码的结构,它相像升高了代码的可重新使用性。

当叁个内嵌函数援引其表面作成效域的变量,我们就能获取多个闭包. 总括一下,创设二个闭包必需知足以下几点:

必需有叁个内嵌函数

内嵌函数必得引用外界函数中的变量

外表函数的再次回到值必需是内嵌函数

倍感闭包依旧有难度的,几句话是说不知底的,依旧印证相关资料.

至关重倘使函数运维后并不会被吊销,就如16题的instance字典肖似,当函数运维完后,instance并不被销毁,而是继续留在内部存款和储蓄器空间里.那个效果相同类里的类变量,只可是迁移到了函数上.

闭包就如个空心球同样,你知道外面和此中,但您不清楚中间是怎样样.

21 lambda函数

事实上正是叁个无名函数,为啥叫lambda?因为和前边的函数式编制程序有关.

推荐:知乎

22 Python函数式编制程序

其生龙活虎须求十二分的摸底一下吧,终究函数式编制程序在Python中也做了引用.

推荐:酷壳

python中等学园函授数式编制程序扶助:

filter 函数的职能也便是过滤器。调用二个布尔函数bool_func来迭代遍历每种seq中的成分;再次回到四个使bool_seq再次回到值为true的要素的队列。

>>>a=[1,2,3,4,5,6,7]>>>b=filter(lambdax: x>5, a)>>>printb>>>[6,7]

map函数是对叁个行列的各样项依次试行函数,下边是对叁个队列各样项都乘以2:

>>>a=map(lambdax:x*2,[1,2,3])>>>list(a)[2,4,6]

reduce函数是对一个队列的各种项迭代调用函数,上边是求3的阶乘:

>>>reduce(lambdax,y:x*y,range(1,4))6

23 Python里的正片

引用和copy(),deepcopy()的区别

importcopya=[1,2,3,4, ['a','b']]#原本对象b=a#赋值,传对象的援引c=copy.copy(a卡塔尔国#对象拷贝,浅拷贝d=copy.deepcopy(a卡塔尔(英语:State of Qatar)#对象拷贝,深拷贝a.append(5卡塔尔(قطر‎#纠正对象aa[4].append('c')#改良对象a中的['a', 'b']数组对象print'a =', aprint'b =', bprint'c =', cprint'd =', d输出结果:a=[1,2,3,4, ['a','b','c'],5]b=[1,2,3,4, ['a','b','c'],5]c=[1,2,3,4, ['a','b','c']]d=[1,2,3,4, ['a','b']]

24 Python垃圾回笼机制

Python GC首要行使援引计数(reference counting)来追踪和回收废料。在援引计数的底蕴上,通过“标志-杀绝”(mark and sweep)消除容器对象也许发生的轮回援用难点,通过“分代回笼”(generation collection)以空间换时间的方法升高垃圾回毛利率。

1 援用计数

PyObject是每一种对象必有的内容,当中ob_refcnt正是做为引用计数。当叁个对象有新的援引时,它的ob_refcnt就能扩大,当援引它的目的被去除,它的ob_refcnt就能够减弱.援用计数为0时,该目的生命就停止了。

优点:

简单

实时性

缺点:

保证引用计数消耗财富

巡回援用

2 标识-杀绝机制

基本思路是先按需分配,等到没有空余内部存款和储蓄器的时候从寄放器和程序栈上的援引出发,遍历以目的为节点、以引用为边构成的图,把具备可以访谈到的靶子打上标识,然后清扫叁次内部存款和储蓄器空间,把具备没标识的指标释放。

3 分代技能

分代回笼的欧洲经济共同体思想是:将系统中的全数内部存款和储蓄器块依照其存世时间分开为不相同的集聚,每一种集合就变成贰个“代”,垃圾收集频率随着“代”的存活时间的附加而减小,存活时间常常接收经过一回垃圾回笼来衡量。

Python默肯定义了三代对象集合,索引数越大,对象共处时间越长。

举个例子来讲:当一些内部存款和储蓄器块M经过了3次垃圾收罗的洗濯之后还存世时,我们就将内部存款和储蓄器块M划到叁个会集A中去,而新分配的内存都分开到集结B中去。当垃圾搜罗起来职业时,大好多状态都只对会集B实行垃圾回收,而对会集A实行垃圾回笼要隔十分长后生可畏段时间后才开展,那就使得垃圾搜集体制亟待管理的内部存款和储蓄器少了,成效自然就加强了。在这里个进度中,会集B中的某个内部存款和储蓄器块由于现成时间长而会被撤换来集结A中,当然,集结A中实际也存在有的垃圾,那么些杂质的回笼会因为这种分代的编写制定而被延缓。

25 Python的List

推荐:http://www.jianshu.com/p/J4U6rR

26 Python的is

is是看待地址,==是相比较值

27 read,readline和readlines

read 读取整个文件

readline 读取下后生可畏行,使用生成器方法

readlines 读取整个文件到多少个迭代器以供咱们遍历

28 Python2和3的区别

推荐:Python 2.7.x 与 Python 3.x 的要害差异

29 super init

super() lets you avoid referring to the base class explicitly, which can be nice. But the main advantage comes with multiple inheritance, where all sorts of fun stuff can happen. See the standard docs on super if you haven't already.

Note that the syntax changed in Python 3.0: you can just say super().init() instead of super(ChildB, self).init() which IMO is quite a bit nicer.

http://stackoverflow.com/questions/576169/understanding-python-super-with-init-methods

30 range and xrange

都在循环时应用,xrange内部存款和储蓄器质量越来越好。for i in range(0, 20卡塔尔(قطر‎:for i in xrange(0, 20卡塔尔:What is the difference between range and xrange functions in Python 2.X? range creates a list, so if you do range(1, 10000000卡塔尔 it creates a list in memory with 9999999 elements. xrange is a sequence object that evaluates lazily.

http://stackoverflow.com/questions/94935/what-is-the-difference-between-range-and-xrange-functions-in-python-2-x

操作系统

1 select,poll和epoll

实际上具有的I/O都是轮询的艺术,只不过达成的范围差异罢了.

那几个主题材料也有一点浓重了,但相信能回复出那么些难点是对I/O多路复用有很好的问询了.个中tornado使用的正是epoll的.

selec,poll和epoll差异总计

基本上select有3个缺点:

连接数受限

搜寻配成对进程慢

数码由基本拷贝到用户态

poll改革了第三个破绽

epoll改了多少个短处.

关于epoll的:http://www.cnblogs.com/my_life/articles/3968782.html

2 调节算法

先来先服务(FCFS, First Come First Serve卡塔尔(قطر‎

短作业优先(SJF, Shortest Job First卡塔尔(英语:State of Qatar)

高高的优先权调节(Priority Scheduling卡塔尔

时刻片轮转(途睿欧Enclave, Round 罗布in卡塔尔

数不清反馈队列调整(multilevel feedback queue scheduling卡塔尔(英语:State of Qatar)

实时调治算法:

最初停止时间优先 EDF

低于松弛度优先 LLF

3 死锁

原因:

竞争能源

程序推进各种不当

供给条件:

互斥条件

要求和保全规范

不剥夺条件

环路等待条件

处理死锁基本措施:

防守死锁(废弃除1以外的尺码卡塔尔

幸免死锁(银专家算法卡塔尔

检查评定死锁(能源分配图卡塔尔(قطر‎

清除死锁

剥夺财富

撤废进度

4 程序编译与链接

推荐:http://www.ruanyifeng.com/blog/2014/11/compiler.html

Bulid进度能够表达为4个步骤:预管理(Prepressing卡塔尔, 编写翻译(Compilation卡塔尔、汇编(Assembly卡塔尔国、链接(Linking卡塔尔(قطر‎

以c语言为例:

1 预处理

预编写翻译进程主要管理那些源文件中的以“#”起初的预编写翻译指令,首要管理准绳有:

将具备的“#define”删除,并开展所用的宏定义

管理全数条件预编写翻译指令,比方“#if”、“#ifdef”、 “#elif”、“#endif”

处理“#include”预编写翻译指令,将被含有的文件插入到该编写翻译指令之处,注:此进程是递归实行的

删去全体注释

加多行号和文书名标记,以便于编译时编写翻译器发生调节和测验用的行号消息以致用于编写翻译时产生编写翻译错误或警报时可兆示行号

封存全体的#pragma编写翻译器指令。

2 编译

编译进度就是把预管理完的文书实行风华正茂类别的词法深入分析、语法解析、语义深入分析及优化后变化对应的汇编代码文件。这么些历程是任何程序营造的主题部分。

3 汇编

汇编器是将汇编代码转化成机器能够施行的下令,每一条汇编语句大约都是一条机器指令。经过编写翻译、链接、汇编输出的文书成为目的文件(Object File卡塔尔(英语:State of Qatar)

4 链接

链接的重大内容正是把各类模块之间互相引用的片段处理好,使各种模块能够准确的拼凑。链接的重要性进度包块 地址和空间的分红(Address and Storage Allocation)、符号决议(Symbol Resolution卡塔尔(英语:State of Qatar)和重定位(Relocation卡塔尔等手续。

5 静态链接和动态链接

静态链接方法:静态链接的时候,载入代码就能够把程序会用到的动态代码或动态代码的地点明确下来静态库的链接能够利用静态链接,动态链接库也得以采取这种方法链接导入库

动态链接方法:使用这种格局的次第并不在一方始就做到动态链接,而是直到真正调用动态库代码时,载入程序才总括(被调用的那某个卡塔尔国动态代码的逻辑地址,然后等到有个别时候,程序又须要调用别的某块动态代码时,载入程序又去计算那黄金时代部分代码的逻辑地址,所以,这种形式使程序初叶化时间不够长,但运营时期的习性不如静态链接的次第

6 设想内部存款和储蓄器才能

设想存款和储蓄器是指具有央求调入功用和调换作用,能从逻辑上对内部存储器体积加以增添的风姿罗曼蒂克种存储系统.

7 分页和分支

分页: 客商程序的地址空间被分开成几何恒久大小的区域,称为“页”,相应地,内部存款和储蓄器空间分成若干个物理块,页和块的深浅相等。可将客户程序的任风流浪漫页放在内存的任一块中,完毕了离散分配。

分层: 将顾客程序地址空间分成若干个大小不等的段,每段能够定义意气风发组相对完整的逻辑消息。存款和储蓄分配时,以段为单位,段与段在内部存储器中可以不相邻接,也实现了离散分配。

分页与分支的关键分歧

页是新闻的物理单位,分页是为了兑现非一而再分配,以便化解内存碎片难点,恐怕说分页是出于系统管理的内需.段是新闻的逻辑单位,它富含黄金时代组意义相对完整的新闻,分段的指标是为了越来越好地贯彻分享,满足客商的须求.

页的高低固定,由系统分明,将逻辑地址划分为页号和页各省址是由机器硬件达成的.而段的尺寸却不定点,决意于顾客所编写的顺序,日常由编写翻译程序在对源程序进行编译时依照音讯的习性来划分.

分页的作业地址空间是风度翩翩维的.分段的地点空间是二维的.

8 页面置换算法

最棒置换算法OPT:不大概完成

先进先出FIFO

那二日最久未利用算法LRU:方今后生可畏段时间里最久未有动用过的页面予以置换.

clock算法

9 边缘触发和档期的顺序触发

边缘触发是指每当状态变化时发生二个 io 事件,条件触发是黄金时代旦满意条件就发生一个 io 事件

数据库

1 事务

数据库事务(Database Transaction卡塔尔(英语:State of Qatar),是指作为单个逻辑职业单元奉行的意气风发连串操作,要么完全地施行,要么完全地不奉行。

2 数据库索引

推荐:http://tech.meituan.com/mysql-index.html

MySQL索引背后的数据构造及算法原理

聚焦索引,非聚焦索引,B-Tree,B Tree,最左前缀原理

3 Redis原理

4 乐观锁和消极锁

悲观锁:假定会发出并发冲突,屏蔽一切大概违反数据完整性的操作

有一点都不小也许锁:尽管不会发生并发冲突,只在提交操作时检查是不是违反数据完整性。

5 MVCC

6 MyISAM和InnoDB

MyISAM 相符于部分需求多量询问的接受,但其对于有大批量写操作并非很好。以至你只是需求update多个字段,整个表都会被锁起来,而别的进度,就终于读进度都力无法及操作直到读操作完结。此外,MyISAM 对于 SELECT COUNT(*卡塔尔(قطر‎ 那类的推断是相当的慢无比的。

InnoDB 的趋向会是八个特别复杂的存款和储蓄引擎,对于一些小的使用,它会比 MyISAM 还慢。他是它补助“行锁” ,于是在写操作超多的时候,会越来越美好。况兼,他还补助越多的尖端应用,比如:事务。

网络

1 叁次握手

顾客端通过向服务器端发送三个SYN来成立一个能动展开,作为三路握手的一片段。顾客端把这段连接的序号设定为随机数 A。

劳务器端应当为叁个合法的SYN回送一个SYN/ACK。ACK 的确认码应为A 1,SYN/ACK 包自身又有二个无约束序号 B。

末段,顾客端再发送一个ACK。当服务端受到那么些ACK的时候,就水到渠成了三路握手,并跻身了连年创造状态。那时候包序号被设定为接到的确认号 A 1,而响应则为 B 1。

2 肆遍挥手

3 ARP协议

地方分析契约(Address Resolution Protocol卡塔尔(قطر‎: 依据IP地址获取物理地址的多个TCP/IP左券

4 urllib和urllib2的区别

那么些面试官确实问过,那时候答的urllib2能够Post而urllib不能.

urllib提供urlencode方法用来GET查询字符串的产生,而urllib2未有。那是怎么urllib常和urllib2一同使用的原故。

urllib2能够负责三个Request类的实例来安装UEnclaveL央求的headers,urllib仅能够负责USportageL。那意味着,你不得以伪装你的User Agent字符串等。

5 Post和Get

GET和POST有怎么着分别?及为啥网络的大好多答案都以错的乐乎回答

get:RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1post:RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1

6 Cookie和Session

CookieSession

积存地点客户端服务器端

目标追踪会话,也足以保存顾客偏爱设置只怕封存顾客名密码等追踪会话

安全性不安全无恙

session本事是要采纳到cookie的,之所以现身session能力,首尽管为了安全。

7 apache和nginx的区别

nginx 相对 apache 的优点:

轻量级,相仿起web 服务,比apache 占用更加少的内部存款和储蓄器及财富

抗并发,nginx 管理须求是异步非梗塞的,接济越来越多的面世连接,而apache 则是窒碍型的,在高并发下nginx 能保持低能源低消耗高品质

配置简洁

中度模块化的统筹,编写模块相对简便易行

社区活泼

apache 相对nginx 的优点:

rewrite ,比nginx 的rewrite 强大

模块相当多,基本想到的都足以找到

少bug ,nginx 的bug 相对非常多

超稳定

8 网站客户密码保存

当着保存

明文hash后保存,如md5

MD5 Salt方式,那几个salt能够随意

网易使用了Bcrypy(好像卡塔尔(قطر‎加密

9 HTTP和HTTPS

事态码定义

1xx 告知吸收接纳到诉求,继续进度

2xx 成功步骤成功选择,被精晓,并被选择

3xx 重定向为了成功央求,必得使用越发措施

4xx 顾客端出错央浼包含错的逐个或不可能日试万言

5xx 服务器出错服务器无法落成明显有效的央浼

403: Forbidden404: Not Found

HTTPS握手,对称加密,非对称加密,TLS/SSL,索罗德SA

10 XSRF和XSS

CSGL450F(Cross-site request forgery卡塔尔(英语:State of Qatar)跨站央求杜撰

XSS(Cross Site Scripting卡塔尔跨站脚本攻击

CSLacrosseF入眼在央浼,XSS入眼在剧本

11 幂等 Idempotence

HTTP方法的幂等性是指一回和高频乞求某叁个财富应该具备同等的副作用。(注意是副作用卡塔尔

GET

DELETE方法用于删除财富,有副功效,但它应该满意幂等性。举例:DELETE

POST所对应的UCRUISERI并不是成立的财富本人,而是能源的收信人。比如:POST

PUT所对应的U奥迪Q5I是要开创或更新的能源本身。比方:PUT

12 RESTful架构(SOAP,RPC)

推荐:http://www.ruanyifeng.com/blog/2011/09/restful.html

13 SOAP

SOAP(原为Simple Object Access Protocol的首字母缩写,即轻易对象访问左券)是换到数据的后生可畏种左券正式,使用在Computer网络Web服务(web service)中,沟通带构造音讯。SOAP为了简化网页服务器(Web Server)从XML数据库中领到数额时,节省去格式化页面时间,以致不一致应用程序之间根据HTTP通讯合同,遵循XML格式试行资料沟通,使其抽象于言语达成、平台和硬件。

14 RPC

RPC(Remote Procedure Call Protocol)——远程进度调用左券,它是风流倜傥种通过网络从远程计算机程序上呼吁服务,而无需掌握底层网络本事的情商。RPC研商即使有些传输左券的留存,如TCP或UDP,为通讯程序之间辅导消息数量。在OSI互联网通讯模型中,RPC胜过了传输层和应用层。RPC使得开荒蕴涵网络遍布式多程序在内的应用程序越发便于。

小结:服务提供的两大流派.古板意义以艺术调用为导向通称RPC。为了集团SOA,若干厂家共同推出webservice,制订了wsdl接口定义,传输soap.当互连网时期,痴肥SOA被简化为http xml/json.不过简化现身各类混乱。以财富为导向,任何操作无非是对财富的增删改查,于是统豆蔻梢头的REST现身了.

发展的相继: RPC -> SOAP -> RESTful

15 CGI和WSGI

CGI是通用网关接口,是连连web服务器和应用程序的接口,客户通过CGI来获得动态数据或文件等。CGI程序是二个独自的程序,它能够用差不离全数语言来写,包蕴perl,c,lua,python等等。

澳门新萄京,WSGI, Web Server Gateway Interface,是Python应用程序或框架和Web服务器之间的意气风发种接口,WSGI的里边二个指标便是让客商能够用统意气风发的语言(Python卡塔尔编写前后端。

法定表明:PEP-3333

16 中间人攻击

在GFW里司空眼惯的,呵呵.

中档人攻击(Man-in-the-middle attack,平时缩写为MITM)是指攻击者与报纸发表的五头分别创制独立的维系,并调换其所选取的多寡,使通信的相互感到他俩正在通过二个私密的接连与对方直接对话,但事实上整个会话都被攻击者完全调节。

17 c10k问题

所谓c10k难题,指的是服务器同不常候扶持广大个客商端的主题素材,约等于concurrent 10 000 connection(那也是c10k以此名字的源委)。推荐:http://www.kegel.com/c10k.html

18 socket

推荐:http://www.360doc.com/content/11/0609/15/5482098_122692444.shtml

Socket=Ip address TCP/UDP port

19 浏览器缓存

推荐:http://www.cnblogs.com/skynet/archive/2012/11/28/2792503.html

304 Not Modified

20 HTTP1.0和HTTP1.1

推荐:http://blog.csdn.net/elifefly/article/details/3964766

需要头Host字段,多少个服务器八个网址

长链接

文本断点续传

身价认证,状态管理,Cache缓存

21 Ajax

AJAX,Asynchronous JavaScript and XML(异步的 JavaScript 和 XML), 是与在不重复加载整个页面包车型地铁场合下,与服务器调换数据并更新部分网页的技巧。

*NIX

unix进度间通讯方式(IPC卡塔尔国

管道(Pipe):管道可用于具备赤子情关系进度间的通讯,允许一个经过和另三个与它有联手祖先的历程之间实行通讯。

命名管道(named pipe):命名管道克制了管道没盛名字的界定,由此,除具有管道所具有的机能外,它还允许无赤子情关系进度间的通讯。命名管道在文件系统中有对应的文本名。命名管道通过命令mkfifo或系统调用mkfifo来创设。

时域信号(Signal):时限信号是比较复杂的通讯情势,用于公告采纳进度有某种事件时有爆发,除了用于进度间通讯外,进度还足以发送信号给进程自己;linux除了援救Unix开始的风流洒脱段时代能量信号语义函数sigal外,还帮衬语义切合Posix.1标准的实信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可信赖实信号机制,又可以联合对外接口,用sigaction函数重新达成了signal函数)。

新闻(Message)队列:新闻队列是音信的链接表,包括Posix音讯队列system V消息队列。有丰硕权限的历程能够向队列中增多新闻,被予以读权限的进度则能够读走队列中的音讯。音讯队列克服了数字信号承载音讯量少,管道只好承载无格式字节流以致缓冲区大大小小受限等缺

分享内部存款和储蓄器:使得七个进程能够访问同一块内部存款和储蓄器空间,是最快的可用IPC情势。是对准别的通讯机制运作功效极低而设计的。往往与别的通讯机制,如信号量结合使用,来达到进程间的一块儿及互斥。

内部存款和储蓄器映射(mapped memory):内部存款和储蓄器映射允许任何多少个经过间通讯,每三个施用该机制的经过经过把叁个分享的文书映射到本人的长河地址空间来完毕它。

时域信号量(semaphore):主要作为进度间以致相近进程不一致线程之间的风姿浪漫道手腕。

套接口(Socket):更为相通的长河间通讯机制,可用以差异机器之间的进度间通讯。起先是由Unix系统的BSD分支开辟出来的,但方今相符可以移植到其余类Unix系统上:Linux和System V的变种都襄助套接字。

数据构造

1 红黑树

红黑树与AVL的可比:

AVL是严酷平衡树,由此在加多依旧去除节点的时候,依据分化意况,旋转的次数比红黑树要多;

红黑是用非严加的平衡来换取增删节点时候转动次数的猛降;

由此简单说,借使您的采纳中,搜索的次数远远超过插入和删除,那么选取AVL,借使寻找,插入删除次数大致大致,应该选用RB。

编程题

1 台阶难题/斐波纳挈

三只青蛙一回能够跳上1级台阶,也得以跳上2级。求该青蛙跳上一个n级的阶梯总共有微微种跳法。

fib=lambdan: nifn<=2elsefib(n-1) fib(n-2)

其次种纪念方法

defmemo(func):    cache={}defwrap(*args):ifargsnotincache:            cache[args]=func(*args)returncache[args]returnwrap@memodeffib(i):ifi<2:return1returnfib(i-1) fib(i-2)

其二种办法

deffib(n):    a, b=0,1for_inxrange(n):        a, b=b, a breturnb

2 分外台阶难点

一只青蛙一回能够跳上1级台阶,也足以跳上2级……它也能够跳上n级。求该掌上压上八个n级的阶梯总共有稍稍种跳法。

fib=lambdan: nifn<2else2*fib(n-1)

3 矩形覆盖

我们得以用2*1的小矩形横着或然竖着去蒙蔽更加大的矩形。请问用n个2*1的小矩形无重叠地掩瞒叁个2*n的大矩形,总共有稍许种办法?

第2*n个矩形的覆盖情势等于第2*(n-1)加上第2*(n-2)的方法。

f=lambdan:1ifn<2elsef(n-1) f(n-2)

4 杨氏矩阵查找

在三个m行n列二维数组中,每意气风发行都信守从左到右依次增加的逐个排序,每一列都服从从上到下依次增加的生龙活虎一排序。请完结一个函数,输入这样的一个二维数组和三个板寸,判定数组中是不是包罗该整数。

动用Step-wise线性搜索。

defget_value(l,r,c):returnl[r][c]deffind(l,x):    m=len(l)-1n=len(l[0])-1r=0c=nwhilec>=0andr<=m:        value=get_value(l, r, c)ifvalue==x:returnTrueelifvalue>x:            c=c-1elifvalue

5 去除列表中的重复元素

用集合

list(set(l))

用字典

l1=['b','c','d','b','c','a','a']l2={}.fromkeys(l1).keys()printl2

用字典并保险顺序

l1=['b','c','d','b','c','a','a']l2=list(set(l1))l2.sort(key=l1.index)printl2

列表推导式

l1=['b','c','d','b','c','a','a']l2=[][l2.append(i)foriinl1ifnotiinl2]

面试官提到的,先排序然后删除.

6 链表成对交流

1->2->3->4转换成2->1->4->3.

classListNode:def__init__(self,x):self.val=xself.next=NoneclassSolution:#@param a ListNode#@return a ListNodedefswapPairs(self,head):ifhead!=Noneandhead.next!=None:next=head.next            head.next=self.swapPairs(next.next)next.next=headreturnnextreturnhead

7 创立字典的法子

1 直接创设

dict={'name':'earth','port':'80'}

2 工厂方法

items=[('name','earth'),('port','80')]dict2=dict(items)dict1=dict((['name','earth'],['port','80']))

3 fromkeys()方法

dict1={}.fromkeys(('x','y'),-1)dict={'x':-1,'y':-1}dict2={}.fromkeys(('x','y'))dict2={'x':None,'y':None}

8 归总八个不改变列表

今日头条远程面试需求编制程序

尾递归

def_recursion_merge_sort2(l1,l2,tmp):iflen(l1)==0orlen(l2)==0:        tmp.extend(l1)        tmp.extend(l2)returntmpelse:ifl1[0]

循环算法

def loop_merge_sort(l1, l2):

tmp = []

while len(l1) > 0 and len(l2) > 0:

if l1[0] < l2[0]:

tmp.append(l1[0])

del l1[0]

else:

tmp.append(l2[0])

del l2[0]

tmp.extend(l1)

tmp.extend(l2)

return tmp

9 交叉链表求交点

去何地的面试,没做出来.

classListNode:def__init__(self,x):self.val=xself.next=Nonedefnode(l1,l2):    length1, lenth2=0,0#求八个链表长度whilel1.next:        l1=l1.next        length1 =1whilel2.next:        l2=l2.next        length2 =1#长的链表先走iflength1>lenth2:for_inrange(length1-length2):            l1=l1.nextelse:for_inrange(length2-length1):            l2=l2.nextwhilel1andl2:ifl1.next==l2.next:returnl1.nextelse:            l1=l1.next            l2=l2.next

10 二分查找

defbinarySearch(l,t):    low, high=0,len(l)-1whilelowt:            high=midelifl[mid]

11 快排

defqsort(seq):ifseq==[]:return[]else:        pivot=seq[0]        lesser=qsort([xforxinseq[1:]ifx=pivot])returnlesser [pivot] greaterif__name__=='__main__':    seq=[5,6,78,9,0,-1,2,3,-65,12]print(qsort(seq))

12 找零难题

defcoinChange(values,money,coinsUsed):#values    T[1:n]数组#valuesCounts  钱币对应的品种数#money  找寻来的总钱数#coinsUsed  对应于当下货币总的数量i所使用的硬币数目forcentsinrange(1, money 1卡塔尔(英语:State of Qatar):        minCoins=cents#从第二个早先到money的保有景况早先forvalueinvalues:ifvalue<=cents:                temp=coinsUsed[cents-value] 1iftemp

13 广度遍历和纵深遍历二叉树

给定多个数组,塑造二叉树,何况按档案的次序打字与印刷那些二叉树

## 14 二叉树节点classNode(object卡塔尔国:def__init__(self,data,left=None,right=None):self.data=dataself.left=leftself.right=righttree=Node(1, Node(3, Node(7, Node(0)), Node(6)), Node(2, Node(5), Node(4)))## 15 档次遍历deflookup(root卡塔尔(英语:State of Qatar):    stack=[root]whilestack:        current=stack.pop(0)printcurrent.dataifcurrent.left:            stack.append(current.left)ifcurrent.right:            stack.append(current.right)## 16 深度遍历defdeep(root卡塔尔(قطر‎:ifnotroot:returnprintroot.data    deep(root.left卡塔尔国    deep(root.right卡塔尔(قطر‎if__name__=='__main__':    lookup(tree)    deep(tree)

17 前中后序遍历

深度遍历改造各样就OK了

18 求最大树深

defmaxDepth(root):ifnotroot:return0returnmax(maxDepth(root.left), maxDepth(root.right)) 1

19 求两棵树是不是生机勃勃致

defisSameTree(p,q):ifp==Noneandq==None:returnTrueelifpandq :returnp.val==q.valandisSameTree(p.left,q.left)andisSameTree(p.right,q.right)else:returnFalse

20 前序中序求后序

推荐:http://blog.csdn.net/hinyunsin/article/details/6315502

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.data

21 单链表逆置

classNode(object):def__init__(self,data=None,next=None):self.data=dataself.next=nextlink=Node(1, Node(2, Node(3, Node(4, Node(5, Node(6, Node(7, Node(8, Node(9)))))))))defrev(link):    pre=link    cur=link.next    pre.next=Nonewhilecur:        tmp=cur.next        cur.next=pre        pre=cur        cur=tmpreturnpreroot=rev(link)whileroot:printroot.data    root=root.next

2 反常台阶难题

一头青蛙一回能够跳上1级台阶,也足以跳上2级……它也能够跳上n级。求该引体向上上七个n级的阶梯总共某个许种跳法。

Python

fib = lambda n: n if n < 2 else 2 * fib(n - 1)

1
fib = lambda n: n if n < 2 else 2 * fib(n - 1)

 

@staticmethod和@classmethod

def foo(x):
    print "executing foo(%s)"%(x)

class A(object):
    def foo(self,x):
        print "executing foo(%s,%s)"%(self,x)

    @classmethod
    def class_foo(cls,x):
        print "executing class_foo(%s,%s)"%(cls,x)

    @staticmethod
    def static_foo(x):
        print "executing static_foo(%s)"%x

a=A()

此地先理解下函数参数里面包车型客车self和cls.这么些self和cls是对类或然实例的绑定,对于日常的函数来讲我们能够如此调用foo(x卡塔尔,这一个函数正是最常用的,它的劳作跟其余交事务物(类,实例卡塔尔非亲非故.对于实例方法,大家清楚在类里每便定义方法的时候都亟需绑定那么些实例,就是foo(self, x卡塔尔国,为啥要如此做啊?因为实例方法的调用离不开实例,我们需求把实例本身传给函数,调用的时候是如此的a.foo(x卡塔尔(قطر‎(其实是foo(a, x卡塔尔国卡塔尔国.类方法大器晚成致,只可是它传递的是类并不是实例,A.class_foo(x卡塔尔.注意这里的self和cls能够交替别的参数,不过python的约定是那俩,依然不要改的好.

对于静态方法其实和平凡的章程相仿,无需对什么人进行绑定,唯豆蔻梢头的界别是调用的时候须求采纳a.static_foo(x)或者A.static_foo(x)来调用.

实例方法 类方法 静态方法
a = A() a.foo(x) A.class_foo(x) A.static_foo(x)
A 不可用 A.class_foo(x) A.static_foo(x)

更加多关于那几个难点:http://stackoverflow.com/questions/136097/what-is-the-difference-between-staticmethod-and-classmethod-in-python

3 矩形覆盖

我们得以用2*1的小矩形横着可能竖着去覆盖更加大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有稍稍种办法?

2*n个矩形的覆盖格局等于第2*(n-1)加上第2*(n-2)的方法。

Python

f = lambda n: 1 if n < 2 else f(n - 1) f(n - 2)

1
f = lambda n: 1 if n < 2 else f(n - 1) f(n - 2)

Python语言特征

生机勃勃、Python的函数参数字传送递

看四个例证:

a = 1

def fun(a):

a = 2

fun(a)

print a # 1

a = []

def fun(a):

a.append(1)

fun(a)

print a # [1]

具备的变量都得以清楚是内部存款和储蓄器中一个对象的“援引”,或许,也能够看似c中void*的感觉。

透过id来看引用a的内部存款和储蓄器地址能够相比理解:

a = 1

def fun(a):

print "func_in",id(a) # func_in 41322472

a = 2

print "re-point",id(a), id(2) # re-point 41322448 41322448

print "func_out",id(a), id(1) # func_out 41322472 41322472

fun(a)

print a # 1

注:具体的值在分歧Computer上运转时只怕两样。

能够见到,在实践完a = 2之后,a引用中保留的值,即内部存款和储蓄器地址发生变化,由原本1对象的八方的地址造成了2以此实体对象的内部存款和储蓄器地址。

而第一个例证a援引保存的内部存款和储蓄器值就不会爆发变化:

a = []

def fun(a):

print "func_in",id(a) # func_in 53629256

a.append(1)

print "func_out",id(a) # func_out 53629256

fun(a)

print a # [1]

此处记住的是项目是归属对象的,并不是变量。而指标有两种,“可修改”(mutable)与“不可改良”(immutable)对象。在python中,strings, tuples, 和numbers是不行改善的靶子,而 list, dict, set 等则是能够校正的指标。(那正是其一难题的重大卡塔尔(英语:State of Qatar)

当贰个援引传递给函数的时候,函数自动复制大器晚成份援引,这么些函数里的援引和异地的援用没有半毛关系了.所以第叁个例证里函数把引用指向了多少个不可变对象,当函数重临的时候,外面包车型客车引用没半毛认为.而第二个例子就不等同了,函数内的援用指向的是可变对象,对它的操作就和定位了指针地址同样,在内部存款和储蓄器里打开更正.

二、Python中的元类(metaclass卡塔尔

以此非常的有时用,可是像ORM这种复杂的构造依然会需求的,教程就不详细介绍了。

三、 @staticmethod和@classmethod

Python其实有3个法子,即静态方法(staticmethod卡塔尔国,类措施(classmethod卡塔尔(قطر‎和实例方法,如下:

def foo(x):

print "executing foo(%s)"%(x)

class A(object):

def foo(self,x):

print "executing foo(%s,%s)"%(self,x)

@classmethod

def class_foo(cls,x):

print "executing class_foo(%s,%s)"%(cls,x)

@staticmethod

def static_foo(x):

print "executing static_foo(%s)"%x

a=A()

此处先清楚下函数参数里面包车型大巴self和cls.那一个self和cls是对类或许实例的绑定,对于经常的函数来讲我们得以这么调用foo(x卡塔尔,那几个函数正是最常用的,它的办事跟别的事物(类,实例卡塔尔毫不相关.对于实例方法,我们领略在类里每一趟定义方法的时候都急需绑定那么些实例,正是foo(self, x卡塔尔(قطر‎,为啥要如此做吗?因为实例方法的调用离不开实例,我们要求把实例自个儿传给函数,调用的时候是那样的a.foo(x卡塔尔(قطر‎(其实是foo(a, x卡塔尔(قطر‎卡塔尔(英语:State of Qatar).类方法蓬蓬勃勃致,只不过它传递的是类并非实例,A.class_foo(x卡塔尔(قطر‎.注意这里的self和cls能够更改别的参数,不过python的约定是那俩,依然不要改的好.

对于静态方法其实和平日的章程生龙活虎致,无需对什么人进行绑定,唯意气风发的区别是调用的时候须求选取a.static_foo(x)或者A.static_foo(x)来调用.

实例方法类措施静态方法a = A(卡塔尔国a.foo(x卡塔尔(英语:State of Qatar)a.class_foo(x)a.static_foo(x)A不可用A.class_foo(x)A.static_foo(x)

四、类变量和实例变量

类变量:

​是可在类的持有实例之间分享的值(也等于说,它们不是独自分配给每一个实例的)。比方下例中,num_of_instance 即是类变量,用于追踪存在着有一点点个Test 的实例。

实例变量:

实例化之后,种种实例单独具有的变量。

class Test(object):

num_of_instance = 0

def __init__(self, name):

self.name = name

Test.num_of_instance = 1

if __name__ == '__main__':

print Test.num_of_instance # 0

t1 = Test('jack')

print Test.num_of_instance # 1

t2 = Test('lucy')

print t1.name , t1.num_of_instance # jack 2

print t2.name , t2.num_of_instance # lucy 2

补充的事例

class Person:

name="aaa"

p1=Person()

p2=Person()

p1.name="bbb"

print p1.name # bbb

print p2.name # aaa

print Person.name # aaa

此处p1.name="bbb"是实例调用了类变量,那实质上和方面第三个难点相像,正是函数字传送参的难点,p1.name风流罗曼蒂克开端是指向的类变量name="aaa",不过在实例的效力域里把类变量的引用改动了,就改成了二个实例变量,self.name不再援引Person的类变量name了.

能够看看上边包车型大巴例证:

class Person:

name=[]

p1=Person()

p2=Person()

p1.name.append(1)

print p1.name # [1]

print p2.name # [1]

print Person.name # [1]

五、Python自省

以此也是python彪悍的个性.

反省就是面向对象的言语所写的次第在运作时,所能知道对象的类型.简单一句正是运维时能够收获对象的类型.例如type(卡塔尔国,dir(卡塔尔国,getattr(卡塔尔(英语:State of Qatar),hasattr(卡塔尔,isinstance(卡塔尔.

a = [1,2,3]

b = {'a':1,'b':2,'c':3}

c = True

print type(a),type(b),type(c) # <type 'list'> <type 'dict'> <type 'bool'>

print isinstance(a,list) # True

六、字典推导式

想必你见过列表推导时,却尚无见过字典推导式,在2.7中才进入的:

d = {key: value for (key, value) in iterable}

7 Python中单下划线和双下划线

>>> class MyClass():

... def __init__(self):

... self.__superprivate = "Hello"

... self._semiprivate = ", world!"

...

>>> mc = MyClass()

>>> print mc.__superprivate

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

AttributeError: myClass instance has no attribute '__superprivate'

>>> print mc._semiprivate

, world!

>>> print mc.__dict__

{'_MyClass__superprivate': 'Hello', '_semiprivate': ', world!'}

__foo__:生龙活虎种约定,Python内部的名字,用来差别别的客商自定义的命名,防止矛盾,正是诸如__init__(),__del__(),__call__(卡塔尔(英语:State of Qatar)那么些新鲜格局

_foo:意气风发种约定,用来钦命变量私有.程序猿用来钦定个人变量的生机勃勃种形式.无法用from module import * 导入,别的地点和国有同样访谈;

__foo:这些有确实的意思:剖判器用_classname__foo来代替这一个名字,以分别和其它类相似的命名,它不能够间接像公有成员平等随意访谈,通过对象名._类名__xxx那样的办法能够访谈.

七、字符串格式化:%和.format

.format在众多上面看起来更便利.对于%最烦人的是它不能同不常候传递多少个变量和元组.你大概会想上面包车型地铁代码不会有如何难点:

"hi there %s" % name

然则,假若name恰恰是(1,2,3卡塔尔(英语:State of Qatar),它将会抛出七个TypeError极度.为了确定保证它连接不错的,你必需这么做:

"hi there %s" % (name,) # 提供二个单成分的数组并非八个参数

不过多少丑..format就未有那一个难点.你给的第一个难点也是那样,.format美观多了.

你怎么不要它?

  • 不知情它(在读那个前边卡塔尔
  • 为了和Python2.5同盟(例如logging库建议使用%(issue #4))

八、迭代器和生成器

stackoverflow里python排行第大器晚成的主题材料,能够参见一下,有马耳他语版也会有普通话版的。

此地有个有关生成器的始建难点面试官有考: 问: 将列表生成式中[]校订(卡塔尔(قطر‎之后数据构造是不是改造? 答案:是,从列表变为生成器

>>> L = [x*x for x in range(10)]

>>> L

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

>>> g = (x*x for x in range(10))

>>> g

<generator object <genexpr> at 0x0000028F8B774200>

通过列表生成式,能够一贯开立一个列表。可是,受到内部存款和储蓄器限定,列表体积肯定是少数的。何况,创立叁个蕴涵百万成分的列表,不止是侵占极大的内部存款和储蓄器空间,如:我们只供给拜谒前面的几个因素,前边抢先六分之三要素所占的空中都是荒疏的。因而,未有供给创设完整的列表(节省大量内部存储器空间)。在Python中,大家能够使用生成器:边循环,边总括的建制—>generator

九、*args and **kwargs

用*args和**kwargs只是为了有扶持并从未抑遏行使它们.

当您不明确你的函数里就要传递多少参数时您能够用*args.比方,它能够传递率性数量的参数:

>>> def print_everything(*args):

for count, thing in enumerate(args):

... print '{0}. {1}'.format(count, thing)

...

>>> print_everything('apple', 'banana', 'cabbage')

  1. apple

  2. banana

  3. cabbage

相似的,**kwargs允许你利用未有优先定义的参数名:

>>> def table_things(**kwargs):

... for name, value in kwargs.items():

... print '{0} = {1}'.format(name, value)

...

>>> table_things(apple = 'fruit', cabbage = 'vegetable')

cabbage = vegetable

apple = fruit

您也得以混着用.命名参数首先获得参数值然后具有的别样参数都传送给*args和**kwargs.命名参数在列表的最前端.比如:

def table_things(titlestring, **kwargs)

*args和**kwargs能够並且在函数的定义中,不过*args必须在**kwargs前面.

当调用函数时你也足以用*和**语法.例如:

>>> def print_three_things(a, b, c):

... print 'a = {0}, b = {1}, c = {2}'.format(a,b,c)

...

>>> mylist = ['aardvark', 'baboon', 'cat']

>>> print_three_things(*mylist)

a = aardvark, b = baboon, c = cat

犹如您看见的风姿洒脱致,它可以传递列表(也许元组卡塔尔(قطر‎的每生龙活虎项并把它们解包.注意必得与它们在函数里的参数相相符.当然,你也能够在函数定义恐怕函数调用时用*.

十、面向切面编制程序AOP和装饰器

本条AOP意气风发听上去有一些懵,同学面Ali的时候就被问懵了...

装饰器是三个很著名的设计形式,平时被用来有切面需要的光景,较为精华的有插入日志、质量测验、事务管理等。装饰器是解决那类难题的绝佳设计,有了装饰器,大家就可以分离出大批量函数中与函数作用自个儿毫不相关的同一代码并一而再起用。总结的讲,装饰器的效应正是为曾经存在的靶子增多额外的意义。

十黄金年代、潜水鸭类型

“当看见一头鸟走起来像绿头鸭、游泳起来像潜水鸭、叫起来也像硬尾鸭,那么那只鸟就足以被称作秋沙鸭。”

我们并不关注对象是怎么着类型,到底是否绒鸭,只关心行为。

比方说在python中,有好些个file-like的东西,譬如StringIO,GzipFile,socket。它们有无数相符的秘技,我们把它们当作文件使用。

又比方list.extend(卡塔尔方法中,大家并不关切它的参数是还是不是list,只要它是可迭代的,所以它的参数可以是list/tuple/dict/字符串/生成器等.

硬尾鸭类型在动态语言中时时使用,极其灵活,使得python不想java那样挑升去弄一大堆的设计形式。

十二、Python中重载

函数重载首若是为着化解多少个难题。

  1. 可变参数类型。
  2. 可变参数个数。

其余,二个基本的两全基准是,仅仅当七个函数除了参数类型和参数个数差别以外,其功用是完全相似的,这时才使用函数重载,要是五个函数的效果与利益实在比不上,那么不该利用重载,而相应选拔三个名字分裂的函数。

好呢,那么对于情况 1 ,函数功效相似,但是参数类型不一样,python 如哪处理?答案是有史以来无需管理,因为 python 能够选择其余项目标参数,假设函数的功效雷同,那么区别的参数类型在 python 中很只怕是如出黄金年代辙的代码,未有供给做成多个例外函数。

那正是说对于意况 2 ,函数功能相同,但参数个数不相同,python 如哪管理?大家理解,答案就是缺省参数。对那一个缺少的参数设定为缺省参数就可以缓和难点。因为你假若函数作用雷同,那么那一个非常不足的参数终究是须要用的。

好了,鉴于情形 1 跟 情状 2 都有了实施方案,python 自然就无需函数重载了。

十七、新式类和旧式类

其一面试官问了,小编说了老半天,不知底他问的的确意图是什么.

stackoverflow

新型类很早在2.2就现身了,所以旧式类完全都以合作的标题,Python3里的类全是新式类.这里有叁个MRO难题得以领会下(新式类是广度优先,旧式类是深浅优先卡塔尔,<Python焦点编制程序>里讲的也超级多.

三个旧式类的深度优先的例子

class A():

def foo1(self):

print "A"

class B(A):

def foo2(self):

pass

class C(A):

def foo1(self):

print "C"

class D(B, C):

pass

d = D()

d.foo1()

# A

安份守己卓越类的查找顺序从左到右深度优先的平整,在拜访d.foo1(卡塔尔国的时候,D那一个类是从没有过的..那么往上追寻,先找到B,里面未有,深度优先,访问A,找到了foo1(卡塔尔(英语:State of Qatar),所以当时调用的是A的foo1(卡塔尔国,进而变成C重写的foo1(卡塔尔(英语:State of Qatar)被绕过

十四、__new__和__init__的区别

这个__new__当真少之甚少看到,先做询问吧.

  1. __new__是八个静态方法,而__init__是三个实例方法.
  2. __new__方法会再次来到一个创制的实例,而__init__什么样都不重临.
  3. 只有在__new__回来一个cls的实例时前面包车型客车__init__技巧被调用.
  4. 当创制二个新实例时调用__new__,伊始化三个实例时用__init__.

stackoverflow

ps: __metaclass__是创立类时起效用.所以我们能够独家采取__metaclass__,__new__和__init__来分别在类创立,实例创设和实例开始化的时候做一些小手脚.

十九、单例情势

​单例方式是黄金时代种常用的软件设计方式。在它的中坚布局中只包蕴多个被称呼单例类的异样类。通过单例格局能够保证系统中二个类独有二个实例况且该实例易于外部访谈,进而利于对实例个数的支配并节约系统财富。假如期待在系统中有个别类的对象只好存在二个,单例形式是最佳的解决方案。

__new__()在__init__(卡塔尔在此之前被调用,用于转移实例对象。利用那一个措施和类的习性的风味能够实现设计形式的单例形式。单例形式是指创造唯一目的,单例格局设计的类只可以实例 这几个相对常考啊.绝对要切记1~2个法子,那时面试官是让手写的.

1 使用__new__方法

class Singleton(object):

def __new__(cls, *args, **kw):

if not hasattr(cls, '_instance'):

orig = super(Singleton, cls)

cls._instance = orig.__new__(cls, *args, **kw)

return cls._instance

class MyClass(Singleton):

a = 1

2 共享属性

开创实例时把具备实例的__dict__本着同七个字典,那样它们具有同等的性质和方法.

class Borg(object):

_state = {}

def __new__(cls, *args, **kw):

ob = super(Borg, cls).__new__(cls, *args, **kw)

ob.__dict__ = cls._state

return ob

class MyClass2(Borg):

a = 1

3 装饰器版本

def singleton(cls):

instances = {}

def getinstance(*args, **kw):

if cls not in instances:

instances[cls] = cls(*args, **kw)

return instances[cls]

return getinstance

@singleton

class MyClass:

...

4 import方法

作为python的模块是后天的单例情势

# mysingleton.py

class My_Singleton(object):

def foo(self):

pass

my_singleton = My_Singleton()

# to use

from mysingleton import my_singleton

my_singleton.foo()

十二、 Python中的功用域

Python 中,四个变量的功效域总是由在代码中被赋值的地点所主宰的。

当 Python 碰着三个变量的话他会遵照那样的逐黄金时代进行搜寻:

地面成效域(Local)→当前成效域被停放的地头成效域(Enclosing locals)→全局/模块作用域(Global)→内置功用域(Built-in)

十三、 GIL线程全局锁

线程全局锁(Global Interpreter Lock卡塔尔国,即Python为了确定保证线程安全而选用的独立线程运维的约束,说白了正是三个核只可以在同一时间运维贰个线程.对于io密集型职分,python的三三十二线程起到效能,但对此cpu密集型职分,python的八线程大约占不到其余优势,还大概有希望因为争夺财富而变慢。

见Python 最难的难题

消除办法正是多进度和底下的协程(协程也只是单CPU,可是能减小切换代价提高质量卡塔尔(英语:State of Qatar).

十八、协程

搜狐被问到了,呵呵哒,跪了

粗略点说协程是进程和线程的升级版,进度和线程都面对着内核态和客商态的切换难题而消耗不胜枚举切换时间,而协程就是客商本身调整切换的空子,不再需求陷入系统的底工态.

Python里最分布的yield就是协程的思辨!能够查阅第九个难点.

十九、闭包

闭包(closure卡塔尔(英语:State of Qatar)是函数式编程的根本的语法布局。闭包也是生机勃勃种集体代码的构造,它雷同拉长了代码的可重新使用性。

当一个内嵌函数引用其外部作功能域的变量,大家就能够获取叁个闭包. 总结一下,成立一个闭包必得满意以下几点:

  1. 总得有二个内嵌函数
  2. 内嵌函数必得引用外界函数中的变量
  3. 外部函数的再次来到值必得是内嵌函数

倍感闭包依旧有难度的,几句话是说不通晓的,依旧印证相关资料.

根本是函数运转后并不会被注销,就好像16题的instance字典相仿,当函数运维完后,instance并不被消逝,而是继续留在内部存款和储蓄器空间里.那么些效果看似类里的类变量,只可是迁移到了函数上.

闭包就如个空心球相似,你精通外面和内部,但您不通晓中间是哪些样.

二十、lambda函数

实质上正是多少个无名函数,为何叫lambda?因为和后边的函数式编程有关.

推荐: 知乎

八十生机勃勃、 Python函数式编制程序

那些必要适宜的领会一下呢,毕竟函数式编制程序在Python中也做了引用.

推荐: 酷壳

python中等高校函授数式编制程序扶植:

filter 函数的成效也正是过滤器。调用三个布尔函数bool_func来迭代遍历每一个seq中的成分;再次回到二个使bool_seq重返值为true的要素的连串。

>>>a = [1,2,3,4,5,6,7]

>>>b = filter(lambda x: x > 5, a)

>>>print b

>>>[6,7]

map函数是对贰个队列的各类项依次实行函数,上面是对一个系列各样项都乘以2:

>>> a = map(lambda x:x*2,[1,2,3])

>>> list(a)

[2, 4, 6]

reduce函数是对三个种类的每一种项迭代调用函数,上面是求3的阶乘:

>>> reduce(lambda x,y:x*y,range(1,4))

6

二十九、Python里的正片

引用和copy(),deepcopy()的区别

import copy

a = [1, 2, 3, 4, ['a', 'b']] #原来对象

b = a #赋值,传对象的引用

c = copy.copy(a) #指标拷贝,浅拷贝

d = copy.deepcopy(a) #对象拷贝,深拷贝

a.append(5) #纠正对象a

a[4].append('c') #修正对象a中的['a', 'b']数组对象

print 'a = ', a

print 'b = ', b

print 'c = ', c

print 'd = ', d

输出结果:

a = [1, 2, 3, 4, ['a', 'b', 'c'], 5]

b = [1, 2, 3, 4, ['a', 'b', 'c'], 5]

c = [1, 2, 3, 4, ['a', 'b', 'c']]

d = [1, 2, 3, 4, ['a', 'b']]

八十六、Python垃圾回笼机制

Python GC首要选择引用计数(reference counting)来跟踪和回收废。在援用计数的底子上,通过“标志-清除”(mark and sweep)消除容器对象或者发生的轮回援用难题,通过“分代回笼”(generation collection)以空间换时间的章程提升垃圾回净利率。

1 援用计数

PyObject是种种对象必有的内容,在这之中ob_refcnt便是做为引用计数。当多个对象有新的引用时,它的ob_refcnt就能够追加,当引用它的靶子被删去,它的ob_refcnt就能够裁减.引用计数为0时,该对象生命就截至了。

优点:

  1. 简单
  2. 实时性

缺点:

  1. 保险引用计数消功耗源
  2. 循环引用

2 标识-撤消机制

基本思路是先按需分配,等到未有空闲内部存款和储蓄器的时候从贮存器和次序栈上的援用出发,遍历以指标为节点、以援引为边构成的图,把具备能够访谈到的指标打上标志,然后清扫叁次内部存储器空间,把具有没标识的靶子释放。

3 分代本事

分代回笼的完全思虑是:将系统中的全部内部存款和储蓄器块依照其存世时间分开为分裂的聚众,各类集合就变成叁个“代”,垃圾搜集频率随着“代”的幸存时间的附加而减小,存活时间日常选拔经过若干回垃圾回笼来度量。

Python默断定义了三代对象集结,索引数越大,对象共处时间越长。

譬世尊讲: 当有个别内部存款和储蓄器块M经过了3次垃圾采撷的洗刷之后还存世时,大家就将内部存储器块M划到贰个集结A中去,而新分配的内存都划分到集结B中去。当废品收罗起来职业时,大多数动静都只对集结B举行垃圾回笼,而对集结A进行垃圾回笼要隔不短意气风发段时间后才举行,这就使得垃圾搜聚体制亟待管理的内部存款和储蓄器少了,成效自然就增加了。在此个进程中,集结B中的某个内部存款和储蓄器块由于现成时间长而会被调换来集合A中,当然,集结A中其实也设有有的垃圾堆,那么些废品的回笼会因为这种分代的建制而被延迟。

二十四、Python的List

详见教程互连网海人民广播广播台大的,内容有一些多,小编就不一一列出来了。

二十五、Python的is

is是比照地址,==是相比值

二十六、 read,readline和readlines

  • read 读取整个文件
  • readline 读取下后生可畏行,使用生成器方法
  • readlines 读取整个文件到多少个迭代器以供大家遍历

二十七、 Python2和3的区别

推荐:Python 2.7.x 与 Python 3.x 的主要出入

二十八、super init

super() lets you avoid referring to the base class explicitly, which can be nice. But the main advantage comes with multiple inheritance, where all sorts of fun stuff can happen. See the standard docs on super if you haven't already.

Note that the syntax changed in Python 3.0: you can just say super().__init__() instead of super(ChildB, self).__init__() which IMO is quite a bit nicer.

Python2.7中的super方法浅见

二十九、range and xrange

都在循环时使用,xrange内部存款和储蓄器品质更加好。 for i in range(0, 20卡塔尔(英语:State of Qatar): for i in xrange(0, 20卡塔尔(قطر‎: What is the difference between range and xrange functions in Python 2.X? range creates a list, so if you do range(1, 10000000卡塔尔国 it creates a list in memory with 9999999 elements. xrange is a sequence object that evaluates lazily.

类变量和实例变量

class Person:
    name="aaa"

p1=Person() #类变量
p2=Person() #类变量
p1.name="bbb" #实例变量
print p1.name  # bbb
print p2.name  # aaa
print Person.name  # aaa

类变量就是供类使用的变量,实例变量正是供实例使用的.

那边p1.name="bbb"是实例调用了类变量,那实质上和方面第一个难点相像,正是函数传参的标题,p1.name一同始是指向的类变量name="aaa",但是在实例的成效域里把类变量的援引改造了,就改为了三个实例变量,self.name不再引用Person的类变量name了.

==能够看看上面的例证: (need check卡塔尔国==
==python中list是mutable的类变量, 实例化之后也是mutable的, 所以对第三个实例的name操作, 也会唤起类变量以至其它的实例中list的改观==

==怎么样制止==

class Person:
    name=[]

p1=Person()
p2=Person()
p1.name.append(1)
print p1.name  # [1]
print p2.name  # [1]
print Person.name  # [1]

参考:http://stackoverflow.com/questions/6470428/catch-multiple-exceptions-in-one-line-except-block

4 杨氏矩阵查找

在贰个m行n列二维数组中,每生龙活虎行都据守从左到右依次增加的各样排序,每一列都固守从上到下依次增加的逐个排序。请完毕二个函数,输入那样的三个二维数组和多少个平头,决断数组中是还是不是含有该整数。

操作系统

一、select,poll和epoll

实际全体的I/O都以轮询的方法,只不过完毕的范畴分化罢了.

本条标题也有一点浓厚了,但相信能回复出那些主题材料是对I/O多路复用有很好的打听了.在那之中tornado使用的正是epoll的.

selec,poll和epoll差异总括

基本上select有3个缺点:

  1. 连接数受限
  2. 搜寻配对速度慢
  3. 数码由底工拷贝到客户态

poll改革了第叁个毛病

epoll改了七个劣势.

二、调解算法

  1. 先来先服务(FCFS, First Come First Serve卡塔尔
  2. 短作业优先(SJF, Shortest Job First卡塔尔(قطر‎
  3. 最高优先权调解(Priority Scheduling卡塔尔国
  4. 日子片轮转(ENCORE奥迪Q3, Round 罗布in卡塔尔国
  • 连串反馈队列调整(multilevel feedback queue scheduling卡塔尔国

实时调治算法:

  1. 最先停止时间先行 EDF
  2. 最低松弛度优先 LLF

三、死锁

原因:

  1. 竞争能源
  2. 前后相继推动各样不当

要求条件:

  1. 互斥条件
  2. 伸手和维持标准
  3. 不剥夺条件
  4. 环路等待条件

拍卖死锁基本办法:

  1. 幸免死锁(甩掉除1以外的尺度卡塔尔
  2. 幸免死锁(银行家算法卡塔尔(قطر‎
  3. 检验死锁(财富分配图卡塔尔(قطر‎
  4. 扼杀死锁
  5. 剥夺财富
  6. 废除进程

死锁概念处理政策详细介绍的话,能够仿照效法一下互连网的。

四、程序编写翻译与链接

Bulid进度能够解释为4个步骤:预管理(Prepressing卡塔尔(英语:State of Qatar), 编写翻译(Compilation卡塔尔(英语:State of Qatar)、汇编(Assembly卡塔尔(قطر‎、链接(Linking卡塔尔(英语:State of Qatar)

python自省

其风华正茂也是python彪悍的本性.

反思正是面向对象的语言钻探所写的主次在运作时,所能知道对象的类型.轻易一句便是启动时亦可赢得对象的类型.例如type(卡塔尔,dir(卡塔尔国,getattr(卡塔尔国,hasattr(卡塔尔(英语:State of Qatar),isinstance(卡塔尔国.

5 去除列表中的重复成分

用集合

Python

list(set(l))

1
list(set(l))

用字典

Python

l1 = ['b','c','d','b','c','a','a'] l2 = {}.fromkeys(l1).keys() print l2

1
2
3
l1 = ['b','c','d','b','c','a','a']
l2 = {}.fromkeys(l1).keys()
print l2

用字典并维持顺序

Python

l1 = ['b','c','d','b','c','a','a'] l2 = list(set(l1)) l2.sort(key=l1.index) print l2

1
2
3
4
l1 = ['b','c','d','b','c','a','a']
l2 = list(set(l1))
l2.sort(key=l1.index)
print l2

列表推导式

Python

l1 = ['b','c','d','b','c','a','a'] l2 = [] [l2.append(i) for i in l1 if not i in l2]

1
2
3
l1 = ['b','c','d','b','c','a','a']
l2 = []
[l2.append(i) for i in l1 if not i in l2]

面试官提到的,先排序然后删除.

以c语言为例:

一、预处理

预编写翻译进程首要处理那多少个源文件中的以“#”开首的预编写翻译指令,首要管理法则有:

  1. 将有着的“#define”删除,并开展所用的宏定义
  2. 拍卖全体法则预编写翻译指令,比如“#if”、“#ifdef”、 “#elif”、“#endif”
  3. 处理“#include”预编写翻译指令,将被含有的公文插入到该编写翻译指令的职位,注:此进度是递归实行的
  4. 删除全体注释
  5. 增多行号和文件名标记,以便于编写翻译时编写翻译器发生调节和测量检验用的行号新闻以致用于编译时爆发编写翻译错误或警告时可展示行号
  6. 保留全部的#pragma编写翻译器指令。

二、编译

编写翻译进度正是把预管理完的文件实行蓬蓬勃勃两种的词法剖判、语法解析、语义剖判及优化后变化对应的汇编代码文件。这些进度是全体程序创设的主导部分。

三、汇编

汇编器是将汇编代码转变成机器能够履行的指令,每一条汇编语句大致都以一条机器指令。经过编写翻译、链接、汇编输出的文件成为目的文件(Object File卡塔尔(قطر‎

四、链接

链接的重大内容就是把各类模块之间人机联作援引的生龙活虎对管理好,使各类模块能够正确的拼凑。 链接的首要性进度包块 地址和空间的分红(Address and Storage Allocation)、符号决议(Symbol Resolution卡塔尔国和重定位(Relocation卡塔尔(英语:State of Qatar)等手续。

五、静态链接和动态链接

静态链接方法:静态链接的时候,载入代码就能把程序会用到的动态代码或动态代码的地点鲜明下来 静态库的链接能够运用静态链接,动态链接库也得以行使这种方法链接导入库

动态链接方法:使用这种艺术的次序并不在一发端就完了动态链接,而是直到真正调用动态库代码时,载入程序才总括(被调用的这某个卡塔尔国动态代码的逻辑地址,然后等到有个别时候,程序又需求调用别的某块动态代码时,载入程序又去总结那有个别代码的逻辑地址,所以,这种艺术使程序开头化时间很短,但运营时期的性质不及静态链接的次第

六、设想内部存款和储蓄器手艺

设想存款和储蓄器是指具备诉求调入效率和沟通成效,能从逻辑上对内部存款和储蓄器体量加以扩展的风度翩翩种存储系统.

七、分页和分支

分页: 顾客程序的地址空间被细分成几何稳住大小的区域,称为“页”,相应地,内部存款和储蓄器空间分成若干个物理块,页和块的高低相等。可将顾客程序的任生龙活虎页放在内部存款和储蓄器的任一块中,达成了离散分配。

分段: 将客商程序地址空间分成若干个大小不等的段,每段能够定义风流浪漫组相对完整的逻辑新闻。存款和储蓄分配时,以段为单位,段与段在内部存款和储蓄器中能够不相邻接,也兑现了离散分配。

分页与分支的入眼差别

  1. 页是音信的物理单位,分页是为着完成非一连分配,以便解决内部存款和储蓄器碎片难题,也许说分页是出于系统管理的急需.段是消息的逻辑单位,它包含意气风发组意义相对完好的音讯,分段的目标是为着越来越好地促成分享,知足客商的需求.
  2. 页的大小固定,由系统分明,将逻辑地址划分为页号和页内地址是由机器硬件落成的.而段的尺寸却不稳固,决计于顾客所编纂的顺序,日常由编写翻译程序在对源程序进行编写翻译时依据音讯的性能来划分.
  3. 分页的学业地址空间是蓬蓬勃勃维的.分段的地址空间是二维的.

八、页面置换算法

  1. 最棒置换算法OPT:不容许完结
  2. 先进先出FIFO
  3. 近年最久未接收算法LRU:近来生机勃勃段时间里最久未有动用过的页面予以置换.
  4. clock算法

九、边沿触发和品位触发

边缘触发是指每当状态变化时发出多少个 io 事件,条件触发是生机勃勃旦满足条件就产生二个 io 事件

字典推导式:

d = {key: value for (key, value) in iterable}

您可以用任何方法的迭代器(元组,列表,生成器..卡塔尔,只要可迭代对象的成分中有五个值.

d = {value: foo(value) for value in sequence if bar(value)}

def key_value_gen(k):
   yield chr(k 65)
   yield chr((k 13)& 65)
d = dict(map(key_value_gen, range(26)))

6 链表成对交流

1->2->3->4转换成2->1->4->3.

Python

class ListNode: def __init__(self, x): self.val = x self.next = None class Solution: # @param a ListNode # @return a ListNode def swapPairs(self, head): if head != None and head.next != None: next = head.next head.next = self.swapPairs(next.next) next.next = head return next return head

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None
 
class Solution:
    # @param a ListNode
    # @return a ListNode
    def swapPairs(self, head):
        if head != None and head.next != None:
            next = head.next
            head.next = self.swapPairs(next.next)
            next.next = head
            return next
        return head

数据库

一、事务

数据库事务(Database Transaction卡塔尔(قطر‎,是指作为单个逻辑职业单元实施的黄金年代各种操作,要么完全地实行,要么完全地不推行。

到底了然数据库事务详细教程风姿洒脱搜一大把,能够自行检索一下。

二、数据库索引

MySQL索引背后的数据布局及算法原理

聚焦索引,非聚焦索引,B-Tree,B Tree,最左前缀原理

三、Redis原理

Redis是什么?

  1. 是二个完全开源无偿的key-value内部存储器数据库
  2. 日常被感觉是叁个数据布局服务器,主假若因为其颇有足够的数据构造strings、map、 list、sets、 sorted sets

Redis数据库

​平常局限点来讲,Redis也以音信队列的花样存在,作为内嵌的List存在,满意实时的高并发需要。在动用缓存的时候,redis比memcached具备越来越多的优势,何况协理更加多的数据类型,把redis当做一个当中存款和储蓄系统,用来拍卖高并发的数据库操作

  • 进度快:使用标准C写,全部数据都在内部存储器中成就,读写速度分别达成10万/20万
  • 持久化:对数据的更新选拔Copy-on-write本领,能够异步地保留到磁盘上,首要有二种政策,一是依照时间,更新次数的快速照相(save 300 10 )二是基于语句追加格局(Append-only file,aof卡塔尔
  • 自动操作:对两样数据类型的操作都以机动的,很安全
  • 非常的慢的主--从复制,官方提供了叁个数码,Slave在21秒即成功了对亚马逊(Amazon卡塔尔网址10G key set的复制。
  • Sharding本领: 超级轻松将数据布满到八个Redis实例中,数据库的扩大是个定位的话题,在关系型数据库中,首借使以增进硬件、以分区为第一手艺情势的纵向扩张化解了广大的采纳场景,但随着web2.0、移动网络、云计算等利用的勃兴,这种增加方式已经不太相符了,所以前段时间,像选取主从配置、数据库复制方式的,Sharding这种工夫把负载布满到八个特理节点上去的横向扩充方式用场愈来愈多。

Redis缺点

  • 是数据水库蓄水体积量受到物理内部存款和储蓄器的限定,不能够用作海量数据的高质量读写,因而Redis相符的情景主要局限在不大数据量的高质量操作和平运动算上。
  • Redis较难支撑在线扩大体积,在集群容积高达上限制时间在线扩大体量会变得很复杂。为制止那生机勃勃主题素材,运营职员在系统上线时必需保证有丰硕的长空,那对财富造成了比比较大的浪费。

四、乐观锁和悲观锁

自寻烦懑锁:假定会发生并发冲突,屏蔽一切大概违反数据完整性的操作

开展锁:假使不会生出并发冲突,只在付出操作时检查是不是违反数据完整性。

五、MVCC

​全称是Multi-Version Concurrent Control,即多版本出现调整,在MVCC合同下,各种读操作会看见二个风流倜傥致性的snapshot,何况能够兑现非窒碍的读。MVCC允许数据具备七个版本,那一个版本能够是时刻戳或然是大局依次增加的政工ID,在同八个时间点,区别的专业看见的数目是例外的。

MySQL的innodb引擎是何等达成MVCC的

innodb会为每意气风发行加多四个字段,分别表示该行成立的本子和删除的本子,填入的是事情的版本号,那一个版本号随着职业的始建不断递增。在repeated read的隔开分离等第(事务的隔绝等第请看那篇小说)下,具体各个数据库操作的落到实处:

  • select:满意以下五个原则innodb会重临该行数据:
  • 该行的创制版本号小于等于当前版本号,用于保险在select操作以前全数的操作已经试行一败涂地。
  • 该行的删减版本号大于当前版本也许为空。删除版本号大于当前版本意味着有叁个油然则惹祸务将该行删除了。
  • insert:将新插入的行的创建版本号设置为当下系统的版本号。
  • delete:将在删除的行的删除版本号设置为这段日子系统的版本号。
  • update:不施行原地update,而是转变到insert delete。将旧行的删减版本号设置为近些日子版本号,并将新行insert同期安装创立版本号为当下版本号。

中间,写操作(insert、delete和update)实施时,供给将系统版本号依次增加。

​由于旧数据并不真的的删减,所以必须对这一个数量举行清理,innodb会开启一个后台线程实施清理职业,具体的家有家规是将去除版本号小于当前系统版本的行删除,那几个历程叫做purge。

由此MVCC很好的完成了业务的隔开分离性,能够高达repeated read等第,要促成serializable还必须加锁。

参考:MVCC浅析

六、MyISAM和InnoDB

MyISAM 符合于一些内需大批量询问的使用,但其对于有大气写操作而不是很好。以致你只是索要update二个字段,整个表都会被锁起来,而其他进度,就到底读进度都无能为力操作直到读操作达成。此外,MyISAM 对于 SELECT COUNT(*卡塔尔 那类的总结是一点也一点也不慢无比的。

InnoDB 的趋势会是二个特别复杂的储存引擎,对于一些小的选拔,它会比 MyISAM 还慢。他是它辅助“行锁” ,于是在写操作相当多的时候,会越来越美好。並且,他还扶植越来越多的高端应用,比如:事务。

python中单下划线和双下划线

这篇文章钻探Python中下划线_的施用。跟Python中比非常多用法相同,下划线_的不等用法绝超越1/2(不全部都是)都是往生可畏种规矩约定。

7 创造字典的措施

网络

黄金年代、 一次握手

  1. 客商端通过向服务器端发送一个SYN来创设一个积极展开,作为贰遍握手的朝气蓬勃有的。客商端把这段连接的序号设定为随意数 A。
  2. 劳动器端应当为贰个法定的SYN回送多少个SYN/ACK。ACK 的确认码应为A 1,SYN/ACK 包本身又有一个即兴序号 B。
  3. 最后,客商端再发送一个ACK。当服务端受到那一个ACK的时候,就实现了三路握手,并跻身了连接创立状态。此时包序号被设定为接到的确认号 A 1,而响应则为 B 1。

二、八回挥手

瞩目: 中断连接端能够是客商端,也得以是服务器端. 下边仅以顾客端断开连接比如, 反之亦然.

  1. 顾客端发送二个数额分段, 个中的 FIN 标志设置为1. 顾客端步入 FIN-WAIT 状态. 该地方下客商端只选拔数据, 不再发送数据.
  2. 服务器收到到含有 FIN = 1 的数额分段, 发送带有 ACK = 1 的多余数量分段, 确认收到顾客端发来的 FIN 音讯.
  3. 服务器等到独具数据传输截止, 向顾客端发送四个暗含 FIN = 1 的数码分段, 并走入 CLOSE-WAIT 状态, 等待客商端发来含有 ACK = 1 的承认报文.
  4. 客商端收到服务器发来含有 FIN = 1 的报文, 再次来到 ACK = 1 的报文确认, 为了防止服务器端未抽出供给重发, 步入 TIME-WAIT 状态. 服务器收到到报文后关闭连接. 顾客端等待 2MSL 后未接到回复, 则以为服务器成功关闭, 客商端关闭连接.

三、ARP协议

地点剖析公约(Address Resolution Protocol卡塔尔(英语:State of Qatar),其根基用为经过指标设备的IP地址,查询指标的MAC地址,以作保通讯的顺利举行。它是IPv4网络层重中之重的争论,不过在IPv6中已不复适用,并被邻里发掘合同(NDP)所代表。

四、urllib和urllib2的区别

本条面试官确实问过,那时候答的urllib2能够Post而urllib不能够.

  1. urllib提供urlencode方法用来GET查询字符串的发生,而urllib2未有。那是为啥urllib常和urllib2一齐行使的原由。
  2. urllib2能够承当八个Request类的实例来安装U福睿斯L乞请的headers,urllib仅能够承担U途观L。那代表,你不得以假装你的User Agent字符串等。

五、Post和Get

GET和POST有如何区别?及为何网络的大多数答案都以错的 腾讯网回答

get: RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1 post: RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1

六、Cookie和Session

CookieSession积存地方顾客端服务器端指标追踪会话,也可以保存用户偏心设置恐怕封存客商名密码等追踪会话安全性不安全无恙

session技巧是要选择到cookie的,之所以现身session工夫,首即使为着安全。

七、apache和nginx的区别

nginx 相对 apache 的优点:

  • 轻量级,相同起web 服务,比apache 占用更加少的内部存款和储蓄器及财富
  • 抗并发,nginx 管理诉求是异步非窒碍的,支持更加的多的面世连接,而apache 则是窒碍型的,在高并发下nginx 能保持低财富低消耗高品质
  • 安顿简洁
  • 中度模块化的布署,编写模块相对简单
  • 社区活泼

apache 相对nginx 的优点:

  • rewrite ,比nginx 的rewrite 强大
  • 模块比较多,基本想到的都可以找到
  • 少bug ,nginx 的bug 相对超级多
  • 超稳定

八、 网址客户密码保存

  1. 当面保存
  2. 明文hash后保存,如md5
  3. MD5 Salt方式,这一个salt能够轻便
  4. 今日头条使用了Bcrypy(好像卡塔尔(قطر‎加密

九、 HTTP和HTTPS

场合码定义1xx 报告吸收接纳到诉求,继续进度2xx 得逞步骤成功接受,被驾驭,并被选取3xx 重定向为了完毕乞请,必得使用更为措施4xx 顾客端出错央浼包蕴错的相继或不可能到位5xx 服务器出错服务器不能够造成明显有效的伸手

403: Forbidden 404: Not Found

HTTPS握手,对称加密,非对称加密,TLS/SSL,LX570SA

十、 XSRF和XSS

  • CS奥迪Q7F(克罗斯-site request forgery卡塔尔国跨站央求假造
  • XSS(Cross Site Scripting卡塔尔跨站脚本攻击

CS奥迪Q5F注重在呼吁,XSS入眼在本子

十一、幂等 Idempotence

HTTP方法的幂等性是指二回和频频呼吁某叁个财富应该具有相像的副效用。(注意是副效用卡塔尔国

不会变动资源的状态,无论调用一回依旧N次都未有副成效。请小心,这里重申的是三遍和N次具备同等的副功用,并不是每趟GET的结果意气风发律。

那么些HTTP诉求恐怕会每一遍得到不一致的结果,但它自个儿并从未生出任何副功用,因此是满意幂等性的。

DELETE方法用于删除能源,有副作用,但它应当满足幂等性。

调用一遍和N次对系统发生的副功能是同生龙活虎的,即删掉id为4231的帖子;因而,调用者能够每每调用或刷新页面而不用忧虑引起错误。

POST所对应的UHavalI实际不是创设的能源自己,而是财富的选择者。

HTTP响应中应包罗帖子的创导状态以至帖子的URubiconI。三次相似的POST央浼会在服务器端成立两份能源,它们有着不一样的UEnclaveI;所以,POST方法不持有幂等性。

PUT所对应的UCR-VI是要创制或更新的能源本身。举个例子:PUT

十二、RESTful架构(SOAP,RPC)

详细教程能够在网络检索一下

十三、 SOAP

SOAP(原为Simple Object Access Protocol的首字母缩写,即轻易对象访问公约)是换来数据的生龙活虎种公约正式,使用在微型机网络Web服务(web service)中,调换带构造新闻。SOAP为了简化网页服务器(Web Server)从XML数据库中领到数据时,节省去格式化页面时间,以至分化应用程序之间遵照HTTP通讯合同,固守XML格式试行资料交换,使其抽象于言语完成、平台和硬件。

十四、RPC

RPC(Remote Procedure Call Protocol)——远程进程调用左券,它是风度翩翩种通过网络从远程Computer程序上号召服务,而不供给掌握底层网络技巧的协商。RPC共商如若某个传输合同的存在,如TCP或UDP,为通信程序之间引导消息数量。在OSI网络通讯模型中,RPC超越了传输层和应用层。RPC使得开采蕴涵网络分布式多程序在内的应用程序特别便于。

小结:服务提供的两大流派.守旧意义以艺术调用为导向通称RPC。为了集团SOA,若干厂家共同推出webservice,制订了wsdl接口定义,传输soap.当网络时期,痴肥SOA被简化为http xml/json.不过简化现身各样混乱。以能源为导向,任何操作无非是对财富的增加和删除改查,于是统少年老成的REST现身了.

升高的顺序: RPC -> SOAP -> RESTful

十五、CGI和WSGI

CGI是通用网关接口,是连接web服务器和应用程序的接口,客商通过CGI来获得动态数据或文件等。 CGI程序是一个独门的程序,它能够用大概全数语言来写,包含perl,c,lua,python等等。

WSGI, Web Server Gateway Interface,是Python应用程序或框架和Web服务器之间的风流倜傥种接口,WSGI的里边一个指标正是让顾客能够用联合的语言(Python卡塔尔(قطر‎编写前后端。

合法证实:PEP-3333

十一、中间人抨击

在GFW里袖手阅览的,呵呵.

中档人攻击(Man-in-the-middle attack,常常缩写为MITM)是指攻击者与杂志发表的三头分别创造独立的维系,并沟通其所选择的多寡,使通信的相互认为他俩正在通过一个私密的接连与对方直接对话,但事实上整个会话都被攻击者完全调节。

十七、 c10k问题

所谓c10k难题,指的是服务器同一时间扶助广大个顾客端的主题素材,约等于concurrent 10 000 connection(那也是c10k以此名字的原故)。

十八、socket

详尽教程笔者就超级小器晚成一列举了,大家能够自动物检疫索一下。

十三、浏览器缓存

详见教程作者就不后生可畏一列举了,大家能够活动物检疫索一下。

304 Not Modified

二十、 HTTP1.0和HTTP1.1

  1. 央浼头Host字段,叁个服务器多个网址
  2. 长链接
  3. 文本断点续传
  4. 地方验证,状态管理,Cache缓存

HTTP供给8种方法介绍 HTTP/1.1切磋中国共产党定义了8种HTTP诉求方法,HTTP须要方法也被称呼“央求动作”,分歧的不二等秘书诀规定了区别的操作钦命的能源情势。服务端也会基于分化的乞求方法做差异的响应。

GET

GET央浼会凸显央浼内定的能源。常常的话GET方法应该只用于数据的读取,而不应有用于会发出副效能的非幂等的操作中。

GET会办法诉求钦命的页面新闻,并再次回到响应宗旨,GET被感到是不安全的办法,因为GET方法会被网络蜘蛛等随便的访谈。

HEAD

HEAD方法与GET方法朝气蓬勃致,都以向服务器发出指定能源的央求。可是,服务器在响应HEAD央浼时不会回传能源的剧情部分,即:响应中央。那样,我们能够不传输全体内容的图景下,就足以拿走服务器的响应头消息。HEAD方法常被用来客商端查看服务器的品质。

POST

POST央浼会 向钦定财富提交数据,诉求服务器实行管理,如:表单数据交到、文件上传等,要求数据会被含有在乞求体中。POST方法是非幂等的点子,因为那个诉求大概会创立新的财富或/和改变现成财富。

PUT

PUT诉求会身向钦点能源职分上传其最新内容,PUT方法是幂等的秘技。通过该措施顾客端能够将钦定能源的摩登数据传送给服务器替代内定的财富的从头到尾的经过。

DELETE

DELETE央求用于须求服务器删除所央浼U宝马7系I(统一财富标志符,Uniform Resource Identifier)所标志的能源。DELETE诉求后钦点能源会被删去,DELETE方法也是幂等的。

CONNECT

CONNECT方法是HTTP/1.1切磋预先留下的,能够将接连改为管道情势的代理服务器。常常用于SSL加密服务器的链接与非加密的HTTP代理服务器的通讯。

OPTIONS

OPTIONS必要与HEAD形似,平日也是用以客商端查看服务器的习性。 那几个方法会诉求服务器再次来到该财富所支撑的保有HTTP须求方法,该措施会用’*’来代表财富名称,向服务器发送OPTIONS乞请,能够测量试验服务器功效是或不是寻常。JavaScript的XMLHttpRequest对象开展COEnclaveS跨域能源分享时,正是应用OPTIONS方法发送嗅探乞求,以咬定是或不是有对点名财富的拜访权限。 允许

TRACE

TRACE乞求服务器回显其吸取的央求音信,该办法重要用以HTTP央浼的测量检验或确诊。

HTTP/1.1从此增添的诀窍

在HTTP/1.1正经制订之后,又陆续扩大了一些主意。此中使用中很多的是 PATCH 方法:

PATCH

PATCH方法现身的较晚,它在2009年的GranTurismoFC 5789行业内部中被定义。PATCH央浼与PUT诉求形似,相近用于能源的立异。二者有以下两点差别:

但PATCH日常用来财富的局地更新,而PUT日常用于能源的欧洲经济共同体立异。 当能源不设有的时候,PATCH会创造二个新的财富,而PUT只会对已在能源开展翻新。

二十一、Ajax

AJAX,Asynchronous JavaScript and XML(异步的 JavaScript 和 XML), 是与在不另行加载整个页面包车型大巴景观下,与服务器调换数据并立异部分网页的本事。

单下划线(_)

关键有二种情状:

  1. 解释器中

_标识是指相互解释器中最后三遍实践语句的回来结果。这种用法最早出今后CPython解释器中,别的解释器后来也都跟进了。

>>> _
Traceback (most recent call last):
  File "", line 1, in 
NameError: name '_' is not defined
>>> 42
>>> _
42
>>> 'alright!' if _ else ':('
'alright!'
>>> _
'alright!'
  1. 作为名称使用

本条跟上面有一点点相似。_作为被放任的名号。根据惯例,那样做能够让阅读你代码的人知晓,那是个不会被采用的特定称谓。比方,你大概不在乎多少个循环计数的值:

n = 42
for _ in range(n):
    do_something()
  1. i18n

_还足以被用作函数名。这种情景,单下划线常常被看做国际化和本土壤化学字符串翻译查询的函数名。这种惯例好像源点于C语言。例如,在 Django documentation for translation 中你可能拜望到:

from django.utils.translation import ugettext as _
from django.http import HttpResponse

def my_view(request):
    output = _("Welcome to my site.")
    return HttpResponse(output)

其次种和第三种用法会引起冲突,所以在随性所欲代码块中,假诺采纳了_作i18n翻译查询函数,就活该幸免再用作被撇下的变量名。

1 直接开立

Python

dict = {'name':'earth', 'port':'80'}

1
dict = {'name':'earth', 'port':'80'}

*NIX

unix进程间通信方式(IPC卡塔尔(قطر‎

  1. 管道(Pipe):管道可用于具有赤子情关系进度间的通讯,允许二个经过和另贰个与它有一同祖先的进程之间开展通讯。
  2. 命名管道(named pipe):命名管道战胜了管道未有名字的限量,由此,除具备管道所独具的效果与利益外,它还允许无亲缘关系进程间的通讯。命名管道在文件系统中有相应的公文名。命名管道通过命令mkfifo或系统调用mkfifo来创制。
  3. 时限信号(Signal):时域信号是比较复杂的通讯格局,用于布告采用进程有某种事件发生,除了用于进度间通讯外,进度还足以发送复信号给进程本身;linux除了扶植Unix中期信号语义函数sigal外,还支持语义切合Posix.1标准的非时域信号函数sigaction(实际上,该函数是依赖BSD的,BSD为了贯彻可信复信号机制,又能够合併对外接口,用sigaction函数重新达成了signal函数)。
  4. 新闻(Message)队列:音讯队列是音信的链接表,包括Posix音信队列system V音信队列。有丰富权限的进度能够向队列中加多音讯,被予以读权限的经过则能够读走队列中的新闻。音讯队列征性格很顽强在荆棘载途或巨大压力面前不屈了随机信号承载音信量少,管道只好承载无格式字节流以致缓冲区大大小小受限等缺
  5. 分享内部存款和储蓄器:使得三个进程能够访谈同一块内部存款和储蓄器空间,是最快的可用IPC情势。是针对性任何通讯机制运作成效十分低而陈设的。往往与其余通讯机制,如能量信号量结合使用,来到达进度间的同步及互斥。
  6. 内部存款和储蓄器映射(mapped memory):内部存款和储蓄器映射允许任何多个进程间通信,每二个利用该机制的进程经过把叁个分享的文本映射到温馨的经过地址空间来得以达成它。
  7. 功率信号量(semaphore):重要用作进程间以致相似进度不一致线程之间的一路手腕。
  8. 套接口(Socket):更为相通的进度间通信机制,可用于区别机器之间的经过间通讯。起始是由Unix系统的BSD分支开拓出来的,但近期雷同能够移植到别的类Unix系统上:Linux和System V的变种都协助套接字。

单下划线前缀的名称(譬喻_shahriar)

以单下划线做前缀的名称钦点了那些名称是“私有的”。在 有个别 导入import * 的光景中,下贰个行令你代码的人(大概你作者)会知晓这些名称仅内部使用。Python documentation里面写道:

a name prefixed with an underscore (e.g. _spam) should be treated as a non-public part of the API (whether it is a function, a method or a data member). It should be considered an implementation detail and subject to change without notice.

故而说在在 有个别 import * 的气象,是因为导入时解释器确实对单下划线早先的名目做了管理。假若你如此写from <module/package> import *,任何以单下划线起始的名号都不会被导入,除非模块/包的__all__列表明显包含了这么些名称。越多相关音信见““Importing * in Python”

2 工厂方法

Python

items=[('name','earth'),('port','80')] dict2=dict(items) dict1=dict((['name','earth'],['port','80']))

1
2
3
items=[('name','earth'),('port','80')]
dict2=dict(items)
dict1=dict((['name','earth'],['port','80']))

数据布局

红黑树

红黑树与AVL的可比:

AVL是严厉平衡树,因而在大增还是去除节点的时候,根据区别意况,旋转的次数比红黑树要多;

红黑是用非严加的平衡来换取增加和删除节点时候转动次数的下挫;

故此简单说,若是你的使用中,搜索的次数远远出乎插入和删除,那么选拔AVL,假设找寻,插入删除次数大约大致,应该接受RB。

双下划线前缀的称呼(举个例子__shahriar

以双下划线做前缀的名称(极度是方式名)并非后生可畏种规矩;它对解释器有特定含义。Python会改写这几个名称,防止与子类中定义的称呼爆发冲突。Python documentation中提到,任何__spam这种情势(起码以七个下划线做起来,绝超越百分之五十都还也会有多个下划线做最终)的标记符,都会文件上被交流为_classname__spam,在那之中classname是眼前类名,并带上几个下划线做前缀。
看下边那些事例:

>>> class A(object):
...     def _internal_use(self):
...         pass
...     def __method_name(self):
...         pass
... 
>>> dir(A())
['_A__method_name', ..., '_internal_use']

正如所料,_internal_use未有成形,但__method_name被改写成了_ClassName__method_name。现在创立一个A的子类B(那可不是个好名字),就不会随随意便的覆盖掉A中的__method_name了:

>>> class B(A):
...     def __method_name(self):
...         pass
... 
>>> dir(B())
['_A__method_name', '_B__method_name', ..., '_internal_use']

这种特定的行事多数等价于Java中的final方法和C 中的符合规律方式(非虚方法)。

3 fromkeys()方法

Python

dict1={}.fromkeys(('x','y'),-1) dict={'x':-1,'y':-1} dict2={}.fromkeys(('x','y')) dict2={'x':None, 'y':None}

1
2
3
4
dict1={}.fromkeys(('x','y'),-1)
dict={'x':-1,'y':-1}
dict2={}.fromkeys(('x','y'))
dict2={'x':None, 'y':None}

编程题

生龙活虎、台阶难题/斐波那契

一头青蛙三回能够跳上1级台阶,也能够跳上2级。求该掌上压上三个n级的台阶总共有多少种跳法。

fib = lambda n: n if n <= 2 else fib(n - 1) fib(n - 2)

第三种回忆方法

def memo(func):

cache = {}

def wrap(*args):

if args not in cache:

cache[args] = func(*args)

return cache[args]

return wrap

@memo

def fib(i):

if i < 2:

return 1

return fib(i-1) fib(i-2)

其二种方法

def fib(n):

a, b = 0, 1

for _ in xrange(n):

a, b = b, a b

return b

二、失常台阶难点

一头青蛙三回能够跳上1级台阶,也足以跳上2级……它也能够跳上n级。求该掌上压上叁个n级的阶梯总共有稍许种跳法。

fib = lambda n: n if n < 2 else 2 * fib(n - 1)

三、矩形覆盖

大家得以用2*1的小矩形横着依然竖着去覆盖越来越大的矩形。请问用n个2*1的小矩形无重叠地隐讳三个2*n的大矩形,总共有多少种方法?

第2*n个矩形的隐瞒措施等于第2*(n-1)加上第2*(n-2)的方法。

f = lambda n: 1 if n < 2 else f(n - 1) f(n - 2)

四、杨氏矩阵查找

在三个m行n列二维数组中,每生龙活虎行都遵照从左到右依次增加的逐一排序,每一列都遵照从上到下依次增加的依次排序。请完毕一个函数,输入那样的二个二维数组和三个整数,判断数组中是还是不是富含该整数。

应用Step-wise线性寻找。

def get_value(l, r, c):

return l[r][c]

def find(l, x):

m = len(l) - 1

n = len(l[0]) - 1

r = 0

c = n

while c >= 0 and r <= m:

value = get_value(l, r, c)

if value == x:

return True

elif value > x:

c = c - 1

elif value < x:

r = r 1

return False

五、去除列表中的重复成分

用集合

list(set(l))

用字典

l1 = ['b','c','d','b','c','a','a']

l2 = {}.fromkeys(l1).keys()

print l2

用字典并维持顺序

l1 = ['b','c','d','b','c','a','a']

l2 = list(set(l1))

l2.sort(key=l1.index)

print l2

列表推导式

l1 = ['b','c','d','b','c','a','a']

l2 = []

[l2.append(i) for i in l1 if not i in l2]

sorted排序况且用列表推导式.

l = ['b','c','d','b','c','a','a'] [single.append(i) for i in sorted(l) if i not in single] print single

七、链表成对交流

1->2->3->4转换成2->1->4->3.

class ListNode:

def __init__(self, x):

self.val = x

self.next = None

class Solution:

# @param a ListNode

# @return a ListNode

def swapPairs(self, head):

if head != None and head.next != None:

next = head.next

head.next = self.swapPairs(next.next)

next.next = head

return next

return head

七、成立字典的法子

1 直接创建

dict = {'name':'earth', 'port':'80'}

2 工厂方法

items=[('name','earth'),('port','80')]

dict2=dict(items)

dict1=dict((['name','earth'],['port','80']))

3 fromkeys()方法

dict1={}.fromkeys(('x','y'),-1)

dict={'x':-1,'y':-1}

dict2={}.fromkeys(('x','y'))

dict2={'x':None, 'y':None}

八、合併多少个不改变列表

和讯远程面试必要编制程序

尾递归

def _recursion_merge_sort2(l1, l2, tmp):

if len(l1) == 0 or len(l2) == 0:

tmp.extend(l1)

tmp.extend(l2)

return tmp

else:

if l1[0] < l2[0]:

tmp.append(l1[0])

del l1[0]

else:

tmp.append(l2[0])

del l2[0]

return _recursion_merge_sort2(l1, l2, tmp)

def recursion_merge_sort2(l1, l2):

return _recursion_merge_sort2(l1, l2, [])

循环算法

思路:

概念一个新的空驶列车表

正如多少个列表的第多个因素

小的就插入到新列表里

把早就插入新列表的因素从旧列表删除

截止三个旧列表有一个为空

再把旧列表加到新列表前边

def loop_merge_sort(l1, l2):

tmp = []

while len(l1) > 0 and len(l2) > 0:

if l1[0] < l2[0]:

tmp.append(l1[0])

del l1[0]

else:

tmp.append(l2[0])

del l2[0]

tmp.extend(l1)

tmp.extend(l2)

return tmp

pop弹出

a = [1,2,3,7]

b = [3,4,5]

def merge_sortedlist(a,b):

c = []

while a and b:

if a[0] >= b[0]:

c.append(b.pop(0))

else:

c.append(a.pop(0))

while a:

c.append(a.pop(0))

while b:

c.append(b.pop(0))

return c

print merge_sortedlist(a,b)

九、交叉链表求交点

实际上动脑筋可以坚决守护从尾伊始相比七个链表,要是相交,则从尾开首必然风姿浪漫致,只要从尾领头相比较,直至不相像的地点即为交叉点,如图所示

澳门新萄京 2

 

# 使用a,b八个list来模拟链表,能够看看交叉点是 7这些节点

a = [1,2,3,7,9,1,5]

b = [4,5,7,9,1,5]

for i in range(1,min(len(a),len(b))):

if i==1 and (a[-1] != b[-1]):

print "No"

break

else:

if a[-i] != b[-i]:

print "交叉节点:",a[-i 1]

break

else:

pass

别的黄金时代种比较标准的点子,架构链表类

class ListNode:

def __init__(self, x):

self.val = x

self.next = None

def node(l1, l2):

length1, lenth2 = 0, 0

# 求多少个链表长度

while l1.next:

l1 = l1.next

length1 = 1

while l2.next:

l2 = l2.next

length2 = 1

# 长的链表先走

if length1 > lenth2:

for _ in range(length1 - length2):

l1 = l1.next

else:

for _ in range(length2 - length1):

l2 = l2.next

while l1 and l2:

if l1.next == l2.next:

return l1.next

else:

澳门新萄京导师煞费苦心帮作者收拾出最全Python面试题,拿着那份Python宝典去面试。l1 = l1.next

l2 = l2.next

校订了风流洒脱晃:

#coding:utf-8

class ListNode:

def __init__(self, x):

self.val = x

self.next = None

def node(l1, l2):

length1, length2 = 0, 0

# 求八个链表长度

while l1.next:

l1 = l1.next#尾节点

length1 = 1

while l2.next:

l2 = l2.next#尾节点

length2 = 1

#假使相交

if l1.next == l2.next:

# 长的链表先走

if length1 > length2:

for _ in range(length1 - length2):

l1 = l1.next

return l1#回到交点

else:

for _ in range(length2 - length1):

l2 = l2.next

return l2#回来交点

# 若是不相交

else:

return

十、二分查找

#coding:utf-8

def binary_search(list,item):

low = 0

high = len(list)-1

while low<=high:

mid = (low high)/2

guess = list[mid]

if guess>item:

high = mid-1

elif guess<item:

low = mid 1

else:

return mid

return None

mylist = [1,3,5,7,9]

print binary_search(mylist,3)

十一、快排

#coding:utf-8

def quicksort(list):

if len(list)<2:

return list

else:

midpivot = list[0]

lessbeforemidpivot = [i for i in list[1:] if i<=midpivot]

biggerafterpivot = [i for i in list[1:] if i > midpivot]

finallylist = quicksort(lessbeforemidpivot) [midpivot] quicksort(biggerafterpivot)

return finallylist

print quicksort([2,4,6,7,1,2,5])

更加多排序难题凸现:数据结构与算法-排序篇-Python描述

十四、找零难点

#coding:utf-8

#values是硬币的票面价值values = [ 25, 21, 10, 5, 1]

#valuesCounts 钱币对应的项目数

#money 搜索来的总钱数

#coinsUsed 对应于如今货币总的数量i所使用的硬币数目

def coinChange(values,valuesCounts,money,coinsUsed):

#遍历出从1到money全数的钱数大概

for cents in range(1,money 1):

minCoins = cents

#把装有的硬币面值遍历出来和钱数做比较

for kind in range(0,valuesCounts):

if (values[kind] <= cents):

temp = coinsUsed[cents - values[kind]] 1

if (temp < minCoins):

minCoins = temp

coinsUsed[cents] = minCoins

print ('面值:{0}的起码硬币使用数为:{1}'.format(cents, coinsUsed[cents]))

十四、广度遍历和深度遍历二叉树

给定一个数组,营造二叉树,并且按档案的次序打字与印刷那几个二叉树

十七、二叉树节点

class Node(object):

def __init__(self, data, left=None, right=None):

self.data = data

self.left = left

self.right = right

tree = Node(1, Node(3, Node(7, Node(0)), Node(6)), Node(2, Node(5), Node(4)))

十八、 等级次序遍历

def lookup(root):

row = [root]

while row:

print(row)

row = [kid for item in row for kid in (item.left, item.right) if kid]

十九、深度遍历

def deep(root):

if not root:

return

print root.data

deep(root.left)

deep(root.right)

if __name__ == '__main__':

lookup(tree)

deep(tree)

十六、 前中后序遍历

纵深遍历改造各个就OK了

#coding:utf-8

#二叉树的遍历

#轻巧易行的二叉树节点类

class Node(object):

def __init__(self,value,left,right):

self.value = value

self.left = left

self.right = right

#中序遍历:遍历左子树,访谈当前节点,遍历右子树

def mid_travelsal(root):

if root.left is None:

mid_travelsal(root.left)

#拜见当前节点

print(root.value)

if root.right is not None:

mid_travelsal(root.right)

#前序遍历:访问当前节点,遍历左子树,遍历右子树

def pre_travelsal(root):

print (root.value)

if root.left is not None:

pre_travelsal(root.left)

if root.right is not None:

pre_travelsal(root.right)

#后续遍历:遍历左子树,遍历右子树,访谈当前节点

def post_trvelsal(root):

if root.left is not None:

post_trvelsal(root.left)

if root.right is not None:

post_trvelsal(root.right)

print (root.value)

十六、求最大树深

def maxDepth(root):

if not root:

return 0

return max(maxDepth(root.left), maxDepth(root.right)) 1

十二、求两棵树是或不是一律

def isSameTree(p, q):

if p == None and q == None:

return True

elif p and q :

return p.val == q.val and isSameTree(p.left,q.left) and isSameTree(p.right,q.right)

else :

return False

四十、前序中序求后序

def rebuild(pre, center):

if not pre:

return

cur = 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:])

return cur

def deep(root):

if not root:

return

deep(root.left)

deep(root.right)

print root.data

三十意气风发、单链表逆置

class Node(object):

def __init__(self, data=None, next=None):

self.data = data

self.next = next

link = Node(1, Node(2, Node(3, Node(4, Node(5, Node(6, Node(7, Node(8, Node(9)))))))))

def rev(link):

pre = link

cur = link.next

pre.next = None

while cur:

tmp = cur.next

cur.next = pre

pre = cur

cur = tmp

return pre

root = rev(link)

while root:

print root.data

root = root.next

三十九、 四个字符串是不是是变位词

class Anagram:

"""

@:param s1: The first string

@:param s2: The second string

@:return true or false

"""

def Solution1(s1,s2):

alist = list(s2)

pos1 = 0

stillOK = True

while pos1 < len(s1) and stillOK:

pos2 = 0

found = False

while pos2 < len(alist) and not found:

if s1[pos1] == alist[pos2]:

found = True

else:

pos2 = pos2 1

if found:

alist[pos2] = None

else:

stillOK = False

pos1 = pos1 1

return stillOK

print(Solution1('abcd','dcba'))

def Solution2(s1,s2):

alist1 = list(s1)

alist2 = list(s2)

alist1.sort()

alist2.sort()

pos = 0

matches = True

while pos < len(s1) and matches:

if alist1[pos] == alist2[pos]:

pos = pos 1

else:

matches = False

return matches

print(Solution2('abcde','edcbg'))

def Solution3(s1,s2):

c1 = [0]*26

c2 = [0]*26

for i in range(len(s1)):

pos = ord(s1[i])-ord('a')

c1[pos] = c1[pos] 1

for i in range(len(s2)):

pos = ord(s2[i])-ord('a')

c2[pos] = c2[pos] 1

j = 0

stillOK = True

while j<26 and stillOK:

if c1[j] == c2[j]:

j = j 1

else:

stillOK = False

return stillOK

print(Solution3('apple','pleap'))

八十四、动态规划难点

可参照:动态规划(DP卡塔尔(قطر‎的股价整理-Python描述

 

上下都含有双下划线的名称(举例__init__

那些是Python的特别规措施名,那仅仅是黄金年代种规矩,意气风发种保证Python系统中的名称不会跟顾客自定义的名称发生冲突的情势。平常你可以覆写那几个办法,在Python调用它们时,爆发你想得到的表现。举个例子,当写一个类的时候日常会覆写__init__方法。
你也能够写出自个儿的“特殊措施”名(不过别那样做):

>>> class C(object):
...     def __mine__(self):
...         pass
...
>>> dir(C)
... [..., '__mine__', ...]

抑或不要那样写方法名,只让Python定义的非常情势名使用这种惯例吧。

详情见:http://stackoverflow.com/questions/1301346/the-meaning-of-a-single-and-a-double-underscore-before-an-object-name-in-python

或者: http://www.zhihu.com/question/19754941

8 合併八个不改变列表

博客园远程面试需要编制程序

尾递归

Python

def _recursion_merge_sort2(l1, l2, tmp): if len(l1) == 0 or len(l2) == 0: tmp.extend(l1) tmp.extend(l2) return tmp else: if l1[0] < l2[0]: tmp.append(l1[0]) del l1[0] else: tmp.append(l2[0]) del l2[0] return _recursion_merge_sort2(l1, l2, tmp) def recursion_merge_sort2(l1, l2): return _recursion_merge_sort2(l1, l2, [])

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def _recursion_merge_sort2(l1, l2, tmp):
    if len(l1) == 0 or len(l2) == 0:
        tmp.extend(l1)
        tmp.extend(l2)
        return tmp
    else:
        if l1[0] < l2[0]:
            tmp.append(l1[0])
            del l1[0]
        else:
            tmp.append(l2[0])
            del l2[0]
        return _recursion_merge_sort2(l1, l2, tmp)
 
def recursion_merge_sort2(l1, l2):
    return _recursion_merge_sort2(l1, l2, [])

循环算法

Python

def loop_merge_sort(l1, l2): tmp = [] while len(l1) > 0 and len(l2) > 0: if l1[0] < l2[0]: tmp.append(l1[0]) del l1[0] else: tmp.append(l2[0]) del l2[0] tmp.extend(l1) tmp.extend(l2) return tmp

1
2
3
4
5
6
7
8
9
10
11
12
def loop_merge_sort(l1, l2):
    tmp = []
    while len(l1) > 0 and len(l2) > 0:
        if l1[0] < l2[0]:
            tmp.append(l1[0])
            del l1[0]
        else:
            tmp.append(l2[0])
            del l2[0]
    tmp.extend(l1)
    tmp.extend(l2)
    return tmp

字符串格式化:%和.format

.format在超多上边看起来更便利.对于%最烦人的是它无法同期传递三个变量和元组.你可能会想上边包车型大巴代码不会有啥难题:

hi there %s" % name

不过,如若name恰恰是(1,2,3卡塔尔国,它将会抛出三个TypeError分外.为了确认保障它连接不错的,你必得这么做:

hi there %s" % (name,) # 提供一个单元素的数组而不是一个参数

可是多少丑..format就不曾这个难点.你给的第贰个问题也是这么,.format美观多了.

您干什么不用它?

不明了它(在读这一个此前卡塔尔国
为了和Python2.5十二分(比方logging库建议使用%(issue #4))

http://stackoverflow.com/questions/5082452/python-string-formatting-vs-format

9 交叉链表求交点

去何地的面试,没做出来.

Python

class ListNode: def __init__(self, x): self.val = x self.next = None def node(l1, l2): length1, lenth2 = 0, 0 # 求多少个链表长度 while l1.next: l1 = l1.next length1 = 1 while l2.next: l2 = l2.next length2 = 1 # 长的链表先走 if length1 > lenth2: for _ in range(length1 - length2): l1 = l1.next else: for _ in range(length2 - length1): l2 = l2.next while l1 and l2: if l1.next == l2.next: return l1.next else: l1 = l1.next l2 = l2.next

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None
def node(l1, l2):
    length1, lenth2 = 0, 0
    # 求两个链表长度
    while l1.next:
        l1 = l1.next
        length1 = 1
    while l2.next:
        l2 = l2.next
        length2 = 1
    # 长的链表先走
    if length1 > lenth2:
        for _ in range(length1 - length2):
            l1 = l1.next
    else:
        for _ in range(length2 - length1):
            l2 = l2.next
    while l1 and l2:
        if l1.next == l2.next:
            return l1.next
        else:
            l1 = l1.next
            l2 = l2.next

迭代器和生成器

那一个是stackoverflow里python排名第意气风发的标题,值得后生可畏看: http://stackoverflow.com/questions/231767/what-does-the-yield-keyword-do-in-python

那是普通话版: http://taizilongxu.gitbooks.io/stackoverflow-about-python/content/1/README.html

10 二分查找

Python

def binarySearch(l, t): low, high = 0, len(l) - 1 while low < high: print low, high mid = (low high) / 2 if l[mid] > t: high = mid elif l[mid] < t: low = mid 1 else: return mid return low if l[low] == t else False if __name__ == '__main__': l = [1, 4, 12, 45, 66, 99, 120, 444] print binarySearch(l, 12) print binarySearch(l, 1) print binarySearch(l, 13) print binarySearch(l, 444)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def binarySearch(l, t):
    low, high = 0, len(l) - 1
    while low < high:
        print low, high
        mid = (low high) / 2
        if l[mid] > t:
            high = mid
        elif l[mid] < t:
            low = mid 1
        else:
            return mid
    return low if l[low] == t else False
 
if __name__ == '__main__':
    l = [1, 4, 12, 45, 66, 99, 120, 444]
    print binarySearch(l, 12)
    print binarySearch(l, 1)
    print binarySearch(l, 13)
    print binarySearch(l, 444)

Iterables

当您创立了三个列表,你能够叁个八个的读取它的每一项,那名字为iteration:

>>> mylist = [1, 2, 3]
>>> for i in mylist:
...    print(i)
1
2
3

Mylist是可迭代的.当你用列表推导式的时候,你就创办了叁个列表,而这么些列表也是可迭代的:

>>> mylist = [x*x for x in range(3)]
>>> for i in mylist:
...    print(i)
0
1
4

具备你能够用在for...in...语句中的都是可迭代的:比如lists,strings,files...因为那些可迭代的靶子你能够自由的读取所以这个有利易用,不过你一定要把它们的值放到内部存款和储蓄器里,当它们有成都百货上千值时就能损耗太多的内存.

11 快排

Python

def qsort(seq): if seq==[]: return [] else: pivot=seq[0] lesser=qsort([x for x in seq[1:] if x<pivot]) greater=qsort([x for x in seq[1:] if x>=pivot]) return lesser [pivot] greater if __name__=='__main__': seq=[5,6,78,9,0,-1,2,3,-65,12] print(qsort(seq))

1
2
3
4
5
6
7
8
9
10
11
12
def qsort(seq):
    if seq==[]:
        return []
    else:
        pivot=seq[0]
        lesser=qsort([x for x in seq[1:] if x<pivot])
        greater=qsort([x for x in seq[1:] if x>=pivot])
        return lesser [pivot] greater
 
if __name__=='__main__':
    seq=[5,6,78,9,0,-1,2,3,-65,12]
    print(qsort(seq))

Generators

生成器也是迭代器的少年老成种,可是你只可以迭代它们一次.缘由超级轻松,因为它们不是100%存在内部存款和储蓄器里,它们只在要调用的时候在内部存款和储蓄器里转换:

>>> mygenerator = (x*x for x in range(3))
>>> for i in mygenerator:
...    print(i)
0
1
4

生成器和迭代器的界别正是用(卡塔尔替代[],还大概有你无法用for i in mygenerator第贰次调用生成器:首先总计0,然后会在内部存款和储蓄器里放任0去总括1,直到总计完4.

12 找零难题

Python

def coinChange(values, money, coinsUsed): #values T[1:n]数组 #valuesCounts 钱币对应的品类数 #money 搜索来的总钱数 #coinsUsed 对应于当下钱币总的数量i所使用的硬币数目 for cents in range(1, money 1卡塔尔国: minCoins = cents #从第一个开首到money的兼具景况起头 for value in values: if value <= cents: temp = coinsUsed[cents - value] 1 if temp < minCoins: minCoins = temp coinsUsed[cents] = minCoins print('面值为:{0} 的矮小硬币数目为:{1} '.format(cents, coinsUsed[cents]) ) if __name__ == '__main__': values = [ 25, 21, 10, 5, 1] money = 63 coinsUsed = {i:0 for i in range(money 1)} coinChange(values, money, coinsUsed)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def  coinChange(values, money, coinsUsed):
    #values    T[1:n]数组
    #valuesCounts   钱币对应的种类数
    #money  找出来的总钱数
    #coinsUsed   对应于目前钱币总数i所使用的硬币数目
    for cents in range(1, money 1):
        minCoins = cents     #从第一个开始到money的所有情况初始
        for value in values:
            if value <= cents:
                temp = coinsUsed[cents - value] 1
                if temp < minCoins:
                    minCoins = temp
        coinsUsed[cents] = minCoins
        print('面值为:{0} 的最小硬币数目为:{1} '.format(cents, coinsUsed[cents]) )
 
if __name__ == '__main__':
    values = [ 25, 21, 10, 5, 1]
    money = 63
    coinsUsed = {i:0 for i in range(money 1)}
    coinChange(values, money, coinsUsed)

Yield

Yield的用法和第一字return大约,下边包车型地铁函数将会重返一个生成器:

>>> def createGenerator():
...    mylist = range(3)
...    for i in mylist:
...        yield i*i
...
>>> mygenerator = createGenerator() # 创建生成器
>>> print(mygenerator) # mygenerator is an object!
<generator object createGenerator at 0xb7555c34>
>>> for i in mygenerator:
...     print(i)
0
1
4

在那地那么些事例好像没什么用,然则当您的函数要赶回叁个不行大的集纳並且你指望只读二回的话,那么它就充足的有利了.

要精通Yield你不得不先驾驭当你调用函数的时候,函数里的代码并未运转.函数仅仅重返生成器对象,那正是它最微妙的地点:-卡塔尔(قطر‎

接下来呢,每当for语句迭代生成器的时候你的代码才会运营.

前段时间,到了最难的有个别:

当for语句第三遍调用函数里再次回到的生成器对象,函数里的代码就起来运转,直到蒙受yield,然后会回到这一次巡回的第三个重临值.所以下叁遍调用也将运营三遍循环然后归来下一个值,直到未有值可以重回.

举例函数运营并未境遇yeild语句就感到生成器已经为空了.原因有不小希望是循环甘休只怕还未有满意if/else之类的.

13 广度遍历和深度遍历二叉树

给定二个数组,构建二叉树,并且按档期的顺序打字与印刷那么些二叉树

Python

## 14 二叉树节点 class Node(object卡塔尔(قطر‎: def __init__(self, data, left=None, right=None): self.data = data self.left = left self.right = right tree = Node(1, Node(3, Node(7, Node(0)), Node(6)), Node(2, Node(5), Node(4))) ## 15 档期的顺序遍历 def lookup(root卡塔尔(英语:State of Qatar): stack = [root] while stack: current = stack.pop(0) print current.data if current.left: stack.append(current.left) if current.right: stack.append(current.right) ## 16 深度遍历 def deep(root卡塔尔(قطر‎: if not root: return print root.data deep(root.left卡塔尔 deep(root.right卡塔尔 if __name__ == '__main__': lookup(tree) deep(tree)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
## 14 二叉树节点
class Node(object):
    def __init__(self, data, left=None, right=None):
        self.data = data
        self.left = left
        self.right = right
 
tree = Node(1, Node(3, Node(7, Node(0)), Node(6)), Node(2, Node(5), Node(4)))
 
## 15 层次遍历
def lookup(root):
    stack = [root]
    while stack:
        current = stack.pop(0)
        print current.data
        if current.left:
            stack.append(current.left)
        if current.right:
            stack.append(current.right)
## 16 深度遍历
def deep(root):
    if not root:
        return
    print root.data
    deep(root.left)
    deep(root.right)
 
if __name__ == '__main__':
    lookup(tree)
    deep(tree)

Itertools你的好好友

itertools模块包含了部分极度的函数能够操作可迭代对象.有未有想过复制二个生成器?链接八个生成器?把嵌套列表里的值组织成三个列表?Map/Zip还不用创制另叁个列表?

来吧import itertools

来贰个事例?让大家看看4匹马比赛有微微个排行结果:

>>> horses = [1, 2, 3, 4]
>>> races = itertools.permutations(horses)
>>> print(races)
<itertools.permutations object at 0xb754f1dc>
>>> print(list(itertools.permutations(horses)))
[(1, 2, 3, 4),
 (1, 2, 4, 3),
 (1, 3, 2, 4),
 (1, 3, 4, 2),
 (1, 4, 2, 3),
 (1, 4, 3, 2),
 (2, 1, 3, 4),
 (2, 1, 4, 3),
 (2, 3, 1, 4),
 (2, 3, 4, 1),
 (2, 4, 1, 3),
 (2, 4, 3, 1),
 (3, 1, 2, 4),
 (3, 1, 4, 2),
 (3, 2, 1, 4),
 (3, 2, 4, 1),
 (3, 4, 1, 2),
 (3, 4, 2, 1),
 (4, 1, 2, 3),
 (4, 1, 3, 2),
 (4, 2, 1, 3),
 (4, 2, 3, 1),
 (4, 3, 1, 2),
 (4, 3, 2, 1)]

知道迭代的内部机制

迭代是可迭代对象(对应iter(卡塔尔(قطر‎方法卡塔尔和迭代器(对应next(卡塔尔(英语:State of Qatar)方法卡塔尔的二个进程.可迭代对象正是任何你能够迭代的目的(废话啊卡塔尔国.迭代器便是可以让你迭代可迭代对象的对象(有一点绕口,意思正是其一意思卡塔尔(英语:State of Qatar)

17 前中后序遍历

纵深遍历退换各个就OK了

*args and **kwargs

用*args和**kwargs只是为了便利并未强逼行使它们.

当您不鲜明你的函数里将在传递多少参数时你可以用*args.例如,它可以传递狂妄数量的参数:

>>> def print_everything(*args):
        for count, thing in enumerate(args):
...         print '{0}. {1}'.format(count, thing)
...
>>> print_everything('apple', 'banana', 'cabbage')
0. apple
1. banana
2. cabbage

相似的,**kwargs允许你利用未有事情未发生前定义的参数名:

>>> def table_things(**kwargs):
...     for name, value in kwargs.items():
...         print '{0} = {1}'.format(name, value)
...
>>> table_things(apple = 'fruit', cabbage = 'vegetable')
cabbage = vegetable
apple = fruit

*args和**kwargs 必需放在参数列表的末尾。

18 求最大树深

Python

def maxDepth(root): if not root: return 0 return max(maxDepth(root.left), maxDepth(root.right)) 1

1
2
3
4
def maxDepth(root):
        if not root:
            return 0
        return max(maxDepth(root.left), maxDepth(root.right)) 1

面向切面编制程序AOP和装饰器

本条AOP生机勃勃听上去有一点懵,同学面Ali的时候就被问懵了…

  • 装饰器正是把任何函数当参数的函数。
    装饰器是一个很著名的设计形式,平时被用于有切面要求的情状,较为精髓的有插入日志、品质测验、事务管理等。装饰器是消逝那类难题的绝佳设计,有了装饰器,大家就足以分离出大批量函数中与函数功效本人毫不相关的如出朝气蓬勃辙代码并世袭起用。总结的讲,装饰器的机能正是为早就存在的对象加多额外的功能。

其一难题超级大,推荐: http://stackoverflow.com/questions/739654/how-can-i-make-a-chain-of-function-decorators-in-python

中文: http://taizilongxu.gitbooks.io/stackoverflow-about-python/content/3/README.html

  • 看二个轻巧的例证
# 字体变粗装饰器
def makebold(fn):
    # 装饰器将返回新的函数
    def wrapper():
        # 在之前或者之后插入新的代码
        return "<b>"   fn()   "</b>"
    return wrapper

# 斜体装饰器

def makeitalic(fn):
# 装饰器将赶回新的函数
def wrapper():
# 在在此之前依旧现在插入新的代码
return "<i>" fn() "</i>"
return wrapper

@makebold
@makeitalic
def say():
return "hello"

print say()

19 求两棵树是不是同样

Python

def isSameTree(p, q): if p == None and q == None: return True elif p and q : return p.val == q.val and isSameTree(p.left,q.left) and isSameTree(p.right,q.right) else : return False

1
2
3
4
5
6
7
def isSameTree(p, q):
    if p == None and q == None:
        return True
    elif p and q :
        return p.val == q.val and isSameTree(p.left,q.left) and isSameTree(p.right,q.right)
    else :
        return False

输出: <b><i>hello</i></b>

20 前序中序求后序

推荐:

Python

def rebuild(pre, center): if not pre: return cur = 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:]) return cur def deep(root): if not root: return deep(root.left) deep(root.right) print root.data

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def rebuild(pre, center):
    if not pre:
        return
    cur = 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:])
    return cur
 
def deep(root):
    if not root:
        return
    deep(root.left)
    deep(root.right)
    print root.data

这一定于

def say():
return "hello"
say = makebold(makeitalic(say))

print say()

21 单链表逆置

Python

class Node(object): def __init__(self, data=None, next=None): self.data = data self.next = next link = Node(1, Node(2, Node(3, Node(4, Node(5, Node(6, Node(7, Node(8, Node(9))))))))) def rev(link): pre = link cur = link.next pre.next = None while cur: tmp = cur.next cur.next = pre pre = cur cur = tmp return pre root = rev(link) while root: print root.data root = root.next

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Node(object):
    def __init__(self, data=None, next=None):
        self.data = data
        self.next = next
 
link = Node(1, Node(2, Node(3, Node(4, Node(5, Node(6, Node(7, Node(8, Node(9)))))))))
 
def rev(link):
    pre = link
    cur = link.next
    pre.next = None
    while cur:
        tmp = cur.next
        cur.next = pre
        pre = cur
        cur = tmp
    return pre
 
root = rev(link)
while root:
    print root.data
    root = root.next

输出: <b><i>hello</i></b>

- 用法:
    1. 传统用法是给外部的不可更改的库做扩展
    2. Django用装饰器管理缓存和试图的权限.
    3. Twisted用来修改异步函数的调用.
    4. etc.

# 鸭子类型
“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”

我们并不关心对象是什么类型,到底是不是鸭子,只关心行为。

比如在python中,有很多file-like的东西,比如StringIO,GzipFile,socket。它们有很多相同的方法,我们把它们当作文件使用。

又比如list.extend()方法中,我们并不关心它的参数是不是list,只要它是可迭代的,所以它的参数可以是list/tuple/dict/字符串/生成器等.

鸭子类型在动态语言中经常使用,非常灵活,使得python不想java那样专门去弄一大堆的设计模式。

# Python中重载
引自知乎:http://www.zhihu.com/question/20053359

函数重载主要是为了解决两个问题:

  - 可变参数类型
  - 可变参数个数

另外,一个基本的设计原则是,仅仅当两个函数除了参数类型和参数个数不同以外,其功能是完全相同的,此时才使用函数重载,如果两个函数的功能其实不同,那么不应当使用重载,而应当使用一个名字不同的函数。

好吧,那么对于情况 1 ,函数功能相同,但是参数类型不同,python 如何处理?答案是根本不需要处理,因为 python 可以接受任何类型的参数,如果函数的功能相同,那么不同的参数类型在 python 中很可能是相同的代码,没有必要做成两个不同函数。

那么对于情况 2 ,函数功能相同,但参数个数不同,python 如何处理?大家知道,答案就是缺省参数。对那些缺少的参数设定为缺省参数即可解决问题。因为你假设函数功能相同,那么那些缺少的参数终归是需要用的。

好了,鉴于情况 1 跟 情况 2 都有了解决方案,==python 自然就不需要函数重载了==

# 新式类与旧式类
这个面试官问了,我说了老半天,不知道他问的真正意图是什么.

stackoverflow(http://stackoverflow.com/questions/54867/what-is-the-difference-between-old-style-and-new-style-classes-in-python)

这篇文章很好的介绍了新式类的特性: http://www.cnblogs.com/btchenguang/archive/2012/09/17/2689146.html

简单的说,新式类是在创建的时候继承内置object对象(或者是从内置类型,如list,dict等),而经典类是直
接声明的。使用dir()方法也可以看出新式类中定义很多新的属性和方法,而经典类好像就2个:

新式类很早在2.2就出现了,所以旧式类完全是兼容的问题,Python3里的类全部都是新式类.这里有一个MRO问题可以了解下(新式类是广度优先,旧式类是深度优先),<Python核心编程>里讲的也很多.

新式类

class C(object):
pass

经典类

class B:
pass

# `__new__`和`__init__`的区别
这个`__new__`确实很少见到,先做了解吧.

`__new__`是一个静态方法,而`__init__`是一个实例方法.

`__new__`方法会返回一个创建的实例,而`__init__`什么都不返回.

只有在`__new__`返回一个cls的实例时后面的`__init__`才能被调用.

当创建一个新实例时调用`__new__`,初始化一个实例时用`__init__`.

stackoverflow(http://stackoverflow.com/questions/674304/pythons-use-of-new-and-init)

ps: `__metaclass__`是创建类时起作用.所以我们可以分别使用`__metaclass__`,`__new__`和`__init__`来分别在类创建,实例创建和实例初始化的时候做一些小手脚.

# 单例模式
==这个绝对长考, 绝对要记住1~2个方法.==

所谓单例,是指一个类的实例从始至终只能被创建一次。

## 使用`__new__`方法

class Singleton(object):
def new(cls,args,kwargs):
if not hasattr(cls,'_inst'):
cls._inst=super(Singleton,cls).new(cls,
args,**kwargs)
return cls._inst
if name=='main':
class A(Singleton):
def init(self,s):
self.s=s
a=A('apple')
b=A('banana')
print id(a),a.s
print id(b),b.s

结果:

29922256 banana
29922256 banana

通过`__new__`方法,将类的实例在创建的时候绑定到类属性`_inst`上。如果`cls._inst`为None,说明类还未实例化,实例化并将实例绑定到`cls._inst`,以后每次实例化的时候都返回第一次实例化创建的实例。注意从Singleton派生子类的时候,不要重载`__new__`。
## 共享属性
有时候我们并不关心生成的实例是否具有同一id,而只关心其状态和行为方式。我们可以允许许多个实例被创建,但所有的实例都共享状态和行为方式:

class Borg(object):
_shared_state={}
def new(cls,args,kwargs):
obj=super(Borg,cls).new(cls,
args,**kwargs)
obj.dict=cls._shared_state
return obj

将所有实例的__dict__指向同一个字典,这样实例就共享相同的方法和属性。对任何实例的名字属性的设置,无论是在__init__中修改还是直接修改,所有的实例都会受到影响。不过实例的id是不同的。要保证类实例能共享属性,但不和子类共享,注意使用cls._shared_state,而不是Borg._shared_state。

因为实例是不同的id,所以每个实例都可以做字典的key:

if name=='main':
class Example(Borg):
pass
a=Example()
b=Example()
c=Example()
adict={}
j=0
for i in a,b,c:
adict[i]=j
j =1
for i in a,b,c:
print adict[i]
结果:
0
1
2

如果这种行为不是你想要的,可以为Borg类添加__eq__和__hash__方法,使其更接近于单例模式的行为:

class Borg(object):
_shared_state={}
def new(cls,args,kwargs):
obj=super(Borg,cls).new(cls,
args,**kwargs)
obj.dict=cls._shared_state
return obj
def hash(self):
return 1
def eq(self,other):
try:
return self.dict is other.dict
except:
return False
if name=='main':
class Example(Borg):
pass
a=Example()
b=Example()
c=Example()
adict={}
j=0
for i in a,b,c:
adict[i]=j
j =1
for i in a,b,c:
print adict[i]
结果:
2
2
2

所有的实例都能当一个key使用了。
## 装饰器版本

def singleton(cls, *args, *kw):
instances = {}
def getinstance():
if cls not in instances:
instances[cls] = cls(
args, **kw)
return instances[cls]
return getinstance

@singleton
class MyClass:
...

## 基于元组
当你编写一个类的时候,某种机制会使用类名字,基类元组,类字典来创建一个类对象。新型类中这种机制默认为type,而且这种机制是可编程的,称为元类__metaclass__ 。

class Singleton(type):
def init(self,name,bases,class_dict):
super(Singleton,self).init(name,bases,class_dict)
self._instance=None
def call(self,args,kwargs):
if self._instance is None:
self._instance=super(Singleton,self).call(
args,**kwargs)
return self._instance
if name=='main':
class A(object):
metaclass=Singleton
a=A()
b=A()
print id(a),id(b)
结果:

34248016 34248016

id是相同的。

例子中我们构造了一个Singleton元类,并使用`__call__`方法使其能够模拟函数的行为。构造类A时,将其元类设为Singleton,那么创建类对象A时,行为发生如下:

`A=Singleton(name,bases,class_dict)`,A其实为Singleton类的一个实例。

创建A的实例时,`A()=Singleton(name,bases,class_dict)()=Singleton(name,bases,class_dict).__call__()`,这样就将A的所有实例都指向了A的属性`_instance`上,这种方法与方法1其实是相同的。
## import方法
作为python的模块是天然的单例模式

mysingleton.py

class My_Singleton(object):
def foo(self):
pass

my_singleton = My_Singleton()

to use

from mysingleton import my_singleton

my_singleton.foo()

## python中的作用域
Python 中,一个变量的作用域总是由在代码中被赋值的地方所决定的。

当 Python 遇到一个变量的话他会按照这样的顺序进行搜索:

本地作用域(Local)→当前作用域被嵌入的本地作用域(Enclosing locals)→全局/模块作用域(Global)→内置作用域(Built-in)
## GIL线程全局锁

线程全局锁(Global Interpreter Lock),即Python为了保证线程安全而采取的独立线程运行的限制,说白了就是一个核只能在同一时间运行一个线程.

见Python 最难的问题http://www.oschina.net/translate/pythons-hardest-problem

==解决办法就是多进程和下面的协程(协程也只是单CPU,但是能减小切换代价提升性能).==
## 协程
知乎被问到了,呵呵哒,跪了

简单点说协程是进程和线程的升级版,进程和线程都面临着内核态和用户态的切换问题而耗费许多切换时间,而协程就是用户自己控制切换的时机,不再需要陷入系统的内核态.

Python里最常见的yield就是协程的思想!可以查看第九个问题.
## 闭包
闭包(closure)是函数式编程的重要的语法结构。闭包也是一种组织代码的结构,它同样提高了代码的可重复使用性。

当一个内嵌函数引用其外部作作用域的变量,我们就会得到一个闭包. 总结一下,创建一个闭包必须满足以下几点:

必须有一个内嵌函数
内嵌函数必须引用外部函数中的变量
外部函数的返回值必须是内嵌函数

感觉闭包还是有难度的,几句话是说不明白的,还是查查相关资料.

重点是函数运行后并不会被撤销,就像16题的instance字典一样,当函数运行完后,instance并不被销毁,而是继续留在内存空间里.这个功能类似类里的类变量,只不过迁移到了函数上.

闭包就像个空心球一样,你知道外面和里面,但你不知道中间是什么样.
## lambda函数
其实就是一个匿名函数,为什么叫lambda?因为和后面的函数式编程有关.

推荐: 知乎(http://www.zhihu.com/question/20125256 )
## python函数式编程
这个需要适当的了解一下吧,毕竟函数式编程在Python中也做了引用.

推荐: 酷壳(http://coolshell.cn/articles/10822.html )

python中函数式编程支持:

filter 函数的功能相当于过滤器。调用一个布尔函数bool_func来迭代遍历每个seq中的元素;返回一个使bool_seq返回值为true的元素的序列。

a = [1,2,3,4,5,6,7]
b = filter(lambda x: x > 5, a)
print b
[6,7]

map函数是对一个序列的每个项依次执行函数,下面是对一个序列每个项都乘以2:

a = map(lambda x:x*2,[1,2,3])
list(a)
[2, 4, 6]

reduce函数是对一个序列的每个项迭代调用函数,下面是求3的阶乘:

reduce(lambda x,y:x*y,range(1,4))
6

## python里的拷贝
引用和copy(),deepcopy()的区别:
1. copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象。
2. copy.deepcopy 深拷贝 拷贝对象及其子对象
3. copy拷贝一个对象,但是对象的属性还是引用原来的,deepcopy拷贝一个对象,把对象里面的属性也做了拷贝,deepcopy之后完全是另一个对象了

import copy
a = [1, 2, 3, 4, ['a', 'b']] #原有对象

b = a #赋值,传对象的援用
c = copy.copy(a) #对象拷贝,浅拷贝,里面包车型地铁[]照旧引用原本的
d = copy.deepcopy(a) #指标拷贝,深拷贝, 全部的性质引用全部都以新的

a.append(5) #改过对象a
a[4].append('c') #改良对象a中的['a', 'b']数组对象

print 'a = ', a
print 'b = ', b
print 'c = ', c
print 'd = ', d

出口结果:
a = [1, 2, 3, 4, ['a', 'b', 'c'], 5]
b = [1, 2, 3, 4, ['a', 'b', 'c'], 5]
c = [1, 2, 3, 4, ['a', 'b', 'c']]
d = [1, 2, 3, 4, ['a', 'b']]

## python 垃圾回收机制
Python GC主要使用引用计数(reference counting)来跟踪和回收垃圾。在引用计数的基础上,通过“标记-清除”(mark and sweep)解决容器对象可能产生的循环引用问题,通过“分代回收”(generation collection)以空间换时间的方法提高垃圾回收效率。
### 引用计数
PyObject是每个对象必有的内容,其中`ob_refcnt`就是做为引用计数。当一个对象有新的引用时,它的`ob_refcnt`就会增加,当引用它的对象被删除,它的ob_refcnt就会减少.引用计数为0时,该对象生命就结束了。

- 优点:

  - 简单
  - 实时性

- 缺点:

  - 维护引用计数消耗资源
  - 循环引用

## 标记-清楚机制
基本思路是先按需分配,等到没有空闲内存的时候从寄存器和程序栈上的引用出发,遍历以对象为节点、以引用为边构成的图,把所有可以访问到的对象打上标记,然后清扫一遍内存空间,把所有没标记的对象释放。
## 分代技术
分代回收的整体思想是:将系统中的所有内存块根据其存活时间划分为不同的集合,每个集合就成为一个“代”,垃圾收集频率随着“代”的存活时间的增大而减小,存活时间通常利用经过几次垃圾回收来度量。

Python默认定义了三代对象集合,索引数越大,对象存活时间越长。

举例:
  当某些内存块M经过了3次垃圾收集的清洗之后还存活时,我们就将内存块M划到一个集合A中去,而新分配的内存都划分到集合B中去。当垃圾收集开始工作时,大多数情况都只对集合B进行垃圾回收,而对集合A进行垃圾回收要隔相当长一段时间后才进行,这就使得垃圾收集机制需要处理的内存少了,效率自然就提高了。在这个过程中,集合B中的某些内存块由于存活时间长而会被转移到集合A中,当然,集合A中实际上也存在一些垃圾,这些垃圾的回收会因为这种分代的机制而被延迟。
# python的list
推荐: http://www.jianshu.com/p/J4U6rR (c语言的实现)
- 基本列表操作:
    - 删除  
    `del list[2]`
    - 分片赋值  
    `name[2:] = list('ar')`
- append

list.append(2)

- count

x = [[1,2],1,1,[2,1,[1,2]]]
x.count([1,2])
1
x.count(1)
2

- append
用于在列表末尾追加新的对象

lst = [1,2,3,4]
lst.append[4]
lst
[1,2,3,4]

- extend
可以在列表末尾一次性追加另一个序列的多个值

a = [1,2,3]
b = [4,5,6]
a.extend(b)
a
[1,2,3,4,5,6]

看起来与`a b`操作很像, 但是extend方法修改了被扩展序列,而`a b`则是返回新的序列

a = [1,2,3]
b = [4,5,6]
a b
[1,2,3,4,5,6]
a
[1,2,3]

- index方法
查找元素在列表中的位置

L= [1,2,3,3]
[1,2,3,3]
L.index(3)
2

- insert方法

L= [1,2,3]
[1,2,3]
L.insert(0,10)
[10,1,2,3]

- pop方法

L= [1,2,3]
[1,2,3]
L.pop(0)
1
L
[2,3]

Perl的列表array里面pop只能弹出右侧的一个元素, 而这个可以弹出指定的index元素
有返回值, 返回值是弹出的元素, 并且修改了原列表
- remove方法
移除列表中某个值的第一个匹配项

L= [1,2,3,3,4]
[1,2,3,3,4]
L.remove(3)
L
[1,2,3,4]

没有返回值,原位修改
- sort方法
sort方法用于在原位置对列表进行排序。

L= [1,2,3,5,4]
L.sort()
L
[1,2,3,4,5]

- reverse方法

L= [1,2,3,3,4]
[1,2,3,3,4]
L.reverse()
L
[4,3,3,2,1]

- sort 与sorted()的关系
- 相同:
    - 都是排序
    - 都支持key, reverse参数, 其中key的话可以实现高级排序
- 不同
    -  sort只对list起作用, 而sorted是全局函数,对任何可迭代的序列均可以使用
    -  sort是原位修改,而sorted()会返回新的列表

详情请看( https://github.com/qiwsir/algorithm/blob/master/python_sort.md )

# python的is
is是对比地址,==是对比值
# read, readline和readlines
- read 读取整个文件
- readline 读取下一行,使用生成器方法
- readlines 读取整个文件到一个迭代器以供我们遍历

# python2和3的区别
推荐:《Python 2.7.x 和 3.x 版本的重要区别》http://python.jobbole.com/80006/
# 操作系统
## select,poll和epoll
其实所有的I/O都是轮询的方法,只不过实现的层面不同罢了.

这个问题可能有点深入了,但相信能回答出这个问题是对I/O多路复用有很好的了解了.其中tornado使用的就是epoll的.

selec,poll和epoll区别总结(http://www.cnblogs.com/Anker/p/3265058.html )

基本上select有3个缺点:

  - 连接数受限
  - 查找配对速度慢
  - 数据由内核拷贝到用户态

poll改善了第一个缺点

epoll改了三个缺点.

关于epoll的: http://www.cnblogs.com/my_life/articles/3968782.html
## 调度算法
1. 先来先服务(FCFS, First Come First Serve)
2. 短作业优先(SJF, Shortest Job First)
3. 最高优先权调度(Priority Scheduling)
4. 时间片轮转(RR, Round Robin)
5. 多级反馈队列调度(multilevel feedback queue
6. scheduling)

- 实时调度算法:

1. 最早截至时间优先 EDF
2. 最低松弛度优先 LLF

## 死锁
- 原因:

1. 竞争资源
2. 程序推进顺序不当

- 必要条件:

1. 互斥条件
2. 请求和保持条件
3. 不剥夺条件
4. 环路等待条件

- 处理死锁基本方法:

1. 预防死锁(摒弃除1以外的条件)
2. 避免死锁(银行家算法)
3. 检测死锁(资源分配图)
4. 解除死锁
    1. 剥夺资源
    2. 撤销进程

## 程序编译与链接
推荐: http://www.ruanyifeng.com/blog/2014/11/compiler.html

Bulid过程可以分解为4个步骤:预处理(Prepressing), 编译(Compilation)、汇编(Assembly)、链接(Linking)

以c语言为例:

- 预处理

预编译过程主要处理那些源文件中的以“#”开始的预编译指令,主要处理规则有:

将所有的“#define”删除,并展开所用的宏定义
处理所有条件预编译指令,比如“#if”、“#ifdef”、 “#elif”、“#endif”
处理“#include”预编译指令,将被包含的文件插入到该编译指令的位置,注:此过程是递归进行的
删除所有注释
添加行号和文件名标识,以便于编译时编译器产生调试用的行号信息以及用于编译时产生编译错误或警告时可显示行号
保留所有的#pragma编译器指令。

- 编译

编译过程就是把预处理完的文件进行一系列的词法分析、语法分析、语义分析及优化后生成相应的汇编代码文件。这个过程是整个程序构建的核心部分。

- 汇编

汇编器是将汇编代码转化成机器可以执行的指令,每一条汇编语句几乎都是一条机器指令。经过编译、链接、汇编输出的文件成为目标文件(Object File)

- 链接

链接的主要内容就是把各个模块之间相互引用的部分处理好,使各个模块可以正确的拼接。
链接的主要过程包块 地址和空间的分配(Address and Storage Allocation)、符号决议(Symbol Resolution)和重定位(Relocation)等步骤。

- 静态链接和动态链接

静态链接方法:静态链接的时候,载入代码就会把程序会用到的动态代码或动态代码的地址确定下来
静态库的链接可以使用静态链接,动态链接库也可以使用这种方法链接导入库

动态链接方法:使用这种方式的程序并不在一开始就完成动态链接,而是直到真正调用动态库代码时,载入程序才计算(被调用的那部分)动态代码的逻辑地址,然后等到某个时候,程序又需要调用另外某块动态代码时,载入程序又去计算这部分代码的逻辑地址,所以,这种方式使程序初始化时间较短,但运行期间的性能比不上静态链接的程序

- 虚拟内存技术

虚拟存储器是值具有请求调入功能和置换功能,能从逻辑上对内存容量加以扩充的一种存储系统.

- 分页和分段

分页: 用户程序的地址空间被划分成若干固定大小的区域,称为“页”,相应地,内存空间分成若干个物理块,页和块的大小相等。可将用户程序的任一页放在内存的任一块中,实现了离散分配。

分段: 将用户程序地址空间分成若干个大小不等的段,每段可以定义一组相对完整的逻辑信息。存储分配时,以段为单位,段与段在内存中可以不相邻接,也实现了离散分配。

分页与分段的主要区别

页是信息的物理单位,分页是为了实现非连续分配,以便解决内存碎片问题,或者说分页是由于系统管理的需要.段是信息的逻辑单位,它含有一组意义相对完整的信息,分段的目的是为了更好地实现共享,满足用户的需要.
页的大小固定,由系统确定,将逻辑地址划分为页号和页内地址是由机器硬件实现的.而段的长度却不固定,决定于用户所编写的程序,通常由编译程序在对源程序进行编译时根据信息的性质来划分.
分页的作业地址空间是一维的.分段的地址空间是二维的.

- 页面置换算法

最佳置换算法OPT:不可能实现
先进先出FIFO
最近最久未使用算法LRU:最近一段时间里最久没有使用过的页面予以置换.
clock算法

- 边沿触发和水平触发

边缘触发是指每当状态变化时发生一个 io 事件,条件触发是只要满足条件就发生一个 io 事件

# 数据库
## 事物
数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。
## 数据库索引
推荐: http://tech.meituan.com/mysql-index.html

MySQL索引背后的数据结构及算法原理(http://blog.jobbole.com/24006/)

聚集索引,非聚集索引,B-Tree,B Tree,最左前缀原理
## Redis原理
## 乐观锁和悲观锁
悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作

乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。
## MVCC
## MyISAM和InnoDB
MyISAM 适合于一些需要大量查询的应用,但其对于有大量写操作并不是很好。甚至你只是需要update一个字段,整个表都会被锁起来,而别的进程,就算是读进程都无法操作直到读操作完成。另外,MyISAM 对于 SELECT COUNT(*) 这类的计算是超快无比的。

InnoDB 的趋势会是一个非常复杂的存储引擎,对于一些小的应用,它会比 MyISAM 还慢。他是它支持“行锁” ,于是在写操作比较多的时候,会更优秀。并且,他还支持更多的高级应用,比如:事务。

本文由澳门新萄京发布于www.澳门新萄京赌场,转载请注明出处:澳门新萄京导师煞费苦心帮作者收拾出最全Pyth

上一篇:调用腾讯云API的实例 下一篇:没有了
猜你喜欢
热门排行
精彩图文