国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

python常用知識點(diǎn)

2019-11-06 06:10:48
字體:
供稿:網(wǎng)友
Python語言特性

1 Python的函數(shù)參數(shù)傳遞

看兩個例子:

Python
12345a = 1def fun(a):    a = 2fun(a)PRint a  # 1

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

所有的變量都可以理解是內(nèi)存中一個對象的“引用”,或者,也可以看似c中void*的感覺。

這里記住的是類型是屬于對象的,而不是變量。而對象有兩種,“可更改”(mutable)與“不可更改”(immutable)對象。在python中,strings, tuples, 和numbers是不可更改的對象,而list,dict等則是可以修改的對象。(這就是這個問題的重點(diǎn))

當(dāng)一個引用傳遞給函數(shù)的時候,函數(shù)自動復(fù)制一份引用,這個函數(shù)里的引用和外邊的引用沒有半毛關(guān)系了.所以第一個例子里函數(shù)把引用指向了一個不可變對象,當(dāng)函數(shù)返回的時候,外面的引用沒半毛感覺.而第二個例子就不一樣了,函數(shù)內(nèi)的引用指向的是可變對象,對它的操作就和定位了指針地址一樣,在內(nèi)存里進(jìn)行修改.

如果還不明白的話,這里有更好的解釋: http://stackoverflow.com/questions/986006/how-do-i-pass-a-variable-by-reference

2 Python中的元類(metaclass)

這個非常的不常用,但是像ORM這種復(fù)雜的結(jié)構(gòu)還是會需要的,詳情請看:《深刻理解Python中的元類(metaclass)》

3 @staticmethod和@classmethod

Python其實有3個方法,即靜態(tài)方法(staticmethod),類方法(classmethod)和實例方法,如下:

Python
12345678910111213141516def 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()

這里先理解下函數(shù)參數(shù)里面的self和cls.這個self和cls是對類或者實例的綁定,對于一般的函數(shù)來說我們可以這么調(diào)用foo(x),這個函數(shù)就是最常用的,它的工作跟任何東西(類,實例)無關(guān).對于實例方法,我們知道在類里每次定義方法的時候都需要綁定這個實例,就是foo(self, x),為什么要這么做呢?因為實例方法的調(diào)用離不開實例,我們需要把實例自己傳給函數(shù),調(diào)用的時候是這樣的a.foo(x)(其實是foo(a, x)).類方法一樣,只不過它傳遞的是類而不是實例,A.class_foo(x).注意這里的self和cls可以替換別的參數(shù),但是python的約定是這倆,還是不要改的好.

對于靜態(tài)方法其實和普通的方法一樣,不需要對誰進(jìn)行綁定,唯一的區(qū)別是調(diào)用的時候需要使用a.static_foo(x)或者A.static_foo(x)來調(diào)用.

/實例方法類方法靜態(tài)方法
a = A()a.foo(x)a.class_foo(x)a.static_foo(x)
A不可用A.class_foo(x)A.static_foo(x)

更多關(guān)于這個問題:http://stackoverflow.com/questions/136097/what-is-the-difference-between-staticmethod-and-classmethod-in-python

4 類變量和實例變量

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

類變量就是供類使用的變量,實例變量就是供實例使用的.

這里p1.name="bbb"是實例調(diào)用了類變量,這其實和上面第一個問題一樣,就是函數(shù)傳參的問題,p1.name一開始是指向的類變量name="aaa",但是在實例的作用域里把類變量的引用改變了,就變成了一個實例變量,self.name不再引用Person的類變量name了.

可以看看下面的例子:

Python
123456789class 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

5 Python自省

這個也是python彪悍的特性.

自省就是面向?qū)ο蟮恼Z言所寫的程序在運(yùn)行時,所能知道對象的類型.簡單一句就是運(yùn)行時能夠獲得對象的類型.比如type(),dir(),getattr(),hasattr(),isinstance().

6 字典推導(dǎo)式

可能你見過列表推導(dǎo)時,卻沒有見過字典推導(dǎo)式,在2.7中才加入的:

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

7 Python中單下劃線和雙下劃線

Python
1234567891011121314>>> class MyClass():...     def __init__(self):...             self.__superprivate = "Hello"...             self._semiprivate = ", world!"...>>> mc = MyClass()>>> print mc.__superprivateTraceback (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內(nèi)部的名字,用來區(qū)別其他用戶自定義的命名,以防沖突.

_foo:一種約定,用來指定變量私有.程序員用來指定私有變量的一種方式.

__foo:這個有真正的意義:解析器用_classname__foo來代替這個名字,以區(qū)別和其他類相同的命名.

詳情見: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在許多方面看起來更便利.對于%最煩人的是它無法同時傳遞一個變量和元組.你可能會想下面的代碼不會有什么問題:

Python
1"hi there %s"%name

但是,如果name恰好是(1,2,3),它將會拋出一個TypeError異常.為了保證它總是正確的,你必須這樣做:

Python
1"hi there %s" % (name,)   # 提供一個單元素的數(shù)組而不是一個參數(shù)

但是有點(diǎn)丑..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 *args and **kwargs

*args**kwargs只是為了方便并沒有強(qiáng)制使用它們.

當(dāng)你不確定你的函數(shù)里將要傳遞多少參數(shù)時你可以用*args.例如,它可以傳遞任意數(shù)量的參數(shù):

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

相似的,**kwargs允許你使用沒有事先定義的參數(shù)名:

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

你也可以混著用.命名參數(shù)首先獲得參數(shù)值然后所有的其他參數(shù)都傳遞給*args**kwargs.命名參數(shù)在列表的最前端.例如:

Python
1deftable_things(titlestring,**kwargs)

*args**kwargs可以同時在函數(shù)的定義中,但是*args必須在**kwargs前面.

當(dāng)調(diào)用函數(shù)時你也可以用***語法.例如:

Python
1234567>>> 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

就像你看到的一樣,它可以傳遞列表(或者元組)的每一項并把它們解包.注意必須與它們在函數(shù)里的參數(shù)相吻合.當(dāng)然,你也可以在函數(shù)定義或者函數(shù)調(diào)用時用*.

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

11 面向切面編程AOP和裝飾器

這個AOP一聽起來有點(diǎn)懵,同學(xué)面阿里的時候就被問懵了…

裝飾器是一個很著名的設(shè)計模式,經(jīng)常被用于有切面需求的場景,較為經(jīng)典的有插入日志、性能測試、事務(wù)處理等。裝飾器是解決這類問題的絕佳設(shè)計,有了裝飾器,我們就可以抽離出大量函數(shù)中與函數(shù)功能本身無關(guān)的雷同代碼并繼續(xù)重用。概括的講,裝飾器的作用就是為已經(jīng)存在的對象添加額外的功能。

這個問題比較大,推薦: 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 鴨子類型

“當(dāng)看到一只鳥走起來像鴨子、游泳起來像鴨子、叫起來也像鴨子,那么這只鳥就可以被稱為鴨子。”

我們并不關(guān)心對象是什么類型,到底是不是鴨子,只關(guān)心行為。

比如在python中,有很多file-like的東西,比如StringIO,GzipFile,socket。它們有很多相同的方法,我們把它們當(dāng)作文件使用。

又比如list.extend()方法中,我們并不關(guān)心它的參數(shù)是不是list,只要它是可迭代的,所以它的參數(shù)可以是list/tuple/dict/字符串/生成器等.

鴨子類型在動態(tài)語言中經(jīng)常使用,非常靈活,使得python不想java那樣專門去弄一大堆的設(shè)計模式。

13 Python中重載

引自知乎:http://www.zhihu.com/question/20053359

函數(shù)重載主要是為了解決兩個問題。

可變參數(shù)類型。可變參數(shù)個數(shù)。

另外,一個基本的設(shè)計原則是,僅僅當(dāng)兩個函數(shù)除了參數(shù)類型和參數(shù)個數(shù)不同以外,其功能是完全相同的,此時才使用函數(shù)重載,如果兩個函數(shù)的功能其實不同,那么不應(yīng)當(dāng)使用重載,而應(yīng)當(dāng)使用一個名字不同的函數(shù)。

好吧,那么對于情況 1 ,函數(shù)功能相同,但是參數(shù)類型不同,python 如何處理?答案是根本不需要處理,因為 python 可以接受任何類型的參數(shù),如果函數(shù)的功能相同,那么不同的參數(shù)類型在 python 中很可能是相同的代碼,沒有必要做成兩個不同函數(shù)。

那么對于情況 2 ,函數(shù)功能相同,但參數(shù)個數(shù)不同,python 如何處理?大家知道,答案就是缺省參數(shù)。對那些缺少的參數(shù)設(shè)定為缺省參數(shù)即可解決問題。因為你假設(shè)函數(shù)功能相同,那么那些缺少的參數(shù)終歸是需要用的。

好了,鑒于情況 1 跟 情況 2 都有了解決方案,python 自然就不需要函數(shù)重載了。

14 新式類和舊式類

這個面試官問了,我說了老半天,不知道他問的真正意圖是什么.

stackoverflow

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

新式類很早在2.2就出現(xiàn)了,所以舊式類完全是兼容的問題,Python3里的類全部都是新式類.這里有一個MRO問題可以了解下(新式類是廣度優(yōu)先,舊式類是深度優(yōu)先),<Python核心編程>里講的也很多.

15 __new____init__的區(qū)別

這個__new__確實很少見到,先做了解吧.

__new__是一個靜態(tài)方法,而__init__是一個實例方法.__new__方法會返回一個創(chuàng)建的實例,而__init__什么都不返回.只有在__new__返回一個cls的實例時后面的__init__才能被調(diào)用.當(dāng)創(chuàng)建一個新實例時調(diào)用__new__,初始化一個實例時用__init__.

stackoverflow

ps: __metaclass__是創(chuàng)建類時起作用.所以我們可以分別使用__metaclass__,__new____init__來分別在類創(chuàng)建,實例創(chuàng)建和實例初始化的時候做一些小手腳.

16 單例模式

這個絕對常考啊.絕對要記住1~2個方法,當(dāng)時面試官是讓手寫的.

1 使用__new__方法

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

2 共享屬性

創(chuàng)建實例時把所有實例的__dict__指向同一個字典,這樣它們具有相同的屬性和方法.

Python
123456789class 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 裝飾器版本

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

4 import方法

作為python的模塊是天然的單例模式

Python
1234567891011# mysingleton.pyclass My_Singleton(object):    def foo(self):        pass my_singleton = My_Singleton() # to usefrom mysingleton import my_singleton my_singleton.foo()

17 Python中的作用域

Python 中,一個變量的作用域總是由在代碼中被賦值的地方所決定的。

當(dāng) Python 遇到一個變量的話他會按照這樣的順序進(jìn)行搜索:

本地作用域(Local)→當(dāng)前作用域被嵌入的本地作用域(Enclosing locals)→全局/模塊作用域(Global)→內(nèi)置作用域(Built-in)

18 GIL線程全局鎖

線程全局鎖(Global Interpreter Lock),即Python為了保證線程安全而采取的獨(dú)立線程運(yùn)行的限制,說白了就是一個核只能在同一時間運(yùn)行一個線程.

見Python 最難的問題

解決辦法就是多進(jìn)程和下面的協(xié)程(協(xié)程也只是單CPU,但是能減小切換代價提升性能).

19 協(xié)程

知乎被問到了,呵呵噠,跪了

簡單點(diǎn)說協(xié)程是進(jìn)程和線程的升級版,進(jìn)程和線程都面臨著內(nèi)核態(tài)和用戶態(tài)的切換問題而耗費(fèi)許多切換時間,而協(xié)程就是用戶自己控制切換的時機(jī),不再需要陷入系統(tǒng)的內(nèi)核態(tài).

Python里最常見的yield就是協(xié)程的思想!可以查看第九個問題.

20 閉包

閉包(closure)是函數(shù)式編程的重要的語法結(jié)構(gòu)。閉包也是一種組織代碼的結(jié)構(gòu),它同樣提高了代碼的可重復(fù)使用性。

當(dāng)一個內(nèi)嵌函數(shù)引用其外部作作用域的變量,我們就會得到一個閉包. 總結(jié)一下,創(chuàng)建一個閉包必須滿足以下幾點(diǎn):

必須有一個內(nèi)嵌函數(shù)內(nèi)嵌函數(shù)必須引用外部函數(shù)中的變量外部函數(shù)的返回值必須是內(nèi)嵌函數(shù)

感覺閉包還是有難度的,幾句話是說不明白的,還是查查相關(guān)資料.

重點(diǎn)是函數(shù)運(yùn)行后并不會被撤銷,就像16題的instance字典一樣,當(dāng)函數(shù)運(yùn)行完后,instance并不被銷毀,而是繼續(xù)留在內(nèi)存空間里.這個功能類似類里的類變量,只不過遷移到了函數(shù)上.

閉包就像個空心球一樣,你知道外面和里面,但你不知道中間是什么樣.

21 lambda函數(shù)

其實就是一個匿名函數(shù),為什么叫l(wèi)ambda?因為和后面的函數(shù)式編程有關(guān).

推薦: 知乎

22 Python函數(shù)式編程

這個需要適當(dāng)?shù)牧私庖幌掳?畢竟函數(shù)式編程在Python中也做了引用.

推薦: 酷殼

python中函數(shù)式編程支持:

filter 函數(shù)的功能相當(dāng)于過濾器。調(diào)用一個布爾函數(shù)bool_func來迭代遍歷每個seq中的元素;返回一個使bool_seq返回值為true的元素的序列。

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

map函數(shù)是對一個序列的每個項依次執(zhí)行函數(shù),下面是對一個序列每個項都乘以2:

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

reduce函數(shù)是對一個序列的每個項迭代調(diào)用函數(shù),下面是求3的階乘:

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

23 Python里的拷貝

引用和copy(),deepcopy()的區(qū)別

Python
1234567891011121314151617181920import copya = [1, 2, 3, 4, ['a', 'b']]  #原始對象 b = a  #賦值,傳對象的引用c = copy.copy(a)  #對象拷貝,淺拷貝d = copy.deepcopy(a)  #對象拷貝,深拷貝 a.append(5)  #修改對象aa[4].append('c')  #修改對象a中的['a', 'b']數(shù)組對象 print 'a = ', aprint 'b = ', bprint 'c = ', cprint 'd = ', d 輸出結(jié)果: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垃圾回收機(jī)制

Python GC主要使用引用計數(shù)(reference counting)來跟蹤和回收垃圾。在引用計數(shù)的基礎(chǔ)上,通過“標(biāo)記-清除”(mark and sweep)解決容器對象可能產(chǎn)生的循環(huán)引用問題,通過“分代回收”(generation collection)以空間換時間的方法提高垃圾回收效率。

1 引用計數(shù)

PyObject是每個對象必有的內(nèi)容,其中ob_refcnt就是做為引用計數(shù)。當(dāng)一個對象有新的引用時,它的ob_refcnt就會增加,當(dāng)引用它的對象被刪除,它的ob_refcnt就會減少.引用計數(shù)為0時,該對象生命就結(jié)束了。

優(yōu)點(diǎn):

簡單實時性

缺點(diǎn):

維護(hù)引用計數(shù)消耗資源循環(huán)引用

2 標(biāo)記-清除機(jī)制

基本思路是先按需分配,等到?jīng)]有空閑內(nèi)存的時候從寄存器和程序棧上的引用出發(fā),遍歷以對象為節(jié)點(diǎn)、以引用為邊構(gòu)成的圖,把所有可以訪問到的對象打上標(biāo)記,然后清掃一遍內(nèi)存空間,把所有沒標(biāo)記的對象釋放。

3 分代技術(shù)

分代回收的整體思想是:將系統(tǒng)中的所有內(nèi)存塊根據(jù)其存活時間劃分為不同的集合,每個集合就成為一個“代”,垃圾收集頻率隨著“代”的存活時間的增大而減小,存活時間通常利用經(jīng)過幾次垃圾回收來度量。

Python默認(rèn)定義了三代對象集合,索引數(shù)越大,對象存活時間越長。

舉例:當(dāng)某些內(nèi)存塊M經(jīng)過了3次垃圾收集的清洗之后還存活時,我們就將內(nèi)存塊M劃到一個集合A中去,而新分配的內(nèi)存都劃分到集合B中去。當(dāng)垃圾收集開始工作時,大多數(shù)情況都只對集合B進(jìn)行垃圾回收,而對集合A進(jìn)行垃圾回收要隔相當(dāng)長一段時間后才進(jìn)行,這就使得垃圾收集機(jī)制需要處理的內(nèi)存少了,效率自然就提高了。在這個過程中,集合B中的某些內(nèi)存塊由于存活時間長而會被轉(zhuǎn)移到集合A中,當(dāng)然,集合A中實際上也存在一些垃圾,這些垃圾的回收會因為這種分代的機(jī)制而被延遲。

25 Python的List

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

26 Python的is

is是對比地址,==是對比值

27 read,readline和readlines

read 讀取整個文件readline 讀取下一行,使用生成器方法readlines 讀取整個文件到一個迭代器以供我們遍歷

28 Python2和3的區(qū)別

推薦:《Python 2.7.x 和 3.x 版本的重要區(qū)別》

操作系統(tǒng)

1 select,poll和epoll

其實所有的I/O都是輪詢的方法,只不過實現(xiàn)的層面不同罷了.

這個問題可能有點(diǎn)深入了,但相信能回答出這個問題是對I/O多路復(fù)用有很好的了解了.其中tornado使用的就是epoll的.

selec,poll和epoll區(qū)別總結(jié)

基本上select有3個缺點(diǎn):

連接數(shù)受限查找配對速度慢數(shù)據(jù)由內(nèi)核拷貝到用戶態(tài)

poll改善了第一個缺點(diǎn)

epoll改了三個缺點(diǎn).

關(guān)于epoll的: http://www.cnblogs.com/my_life/articles/3968782.html

2 調(diào)度算法

先來先服務(wù)(FCFS, First Come First Serve)短作業(yè)優(yōu)先(SJF, Shortest Job First)最高優(yōu)先權(quán)調(diào)度(Priority Scheduling)時間片輪轉(zhuǎn)(RR, Round Robin)多級反饋隊列調(diào)度(multilevel feedback queue scheduling)

實時調(diào)度算法:

最早截至?xí)r間優(yōu)先 EDF最低松弛度優(yōu)先 LLF

3 死鎖

原因:

競爭資源程序推進(jìn)順序不當(dāng)

必要條件:

互斥條件請求和保持條件不剝奪條件環(huán)路等待條件

處理死鎖基本方法:

預(yù)防死鎖(摒棄除1以外的條件)避免死鎖(銀行家算法)檢測死鎖(資源分配圖)解除死鎖剝奪資源撤銷進(jìn)程

4 程序編譯與鏈接

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

Bulid過程可以分解為4個步驟:預(yù)處理(Prepressing), 編譯(Compilation)、匯編(Assembly)、鏈接(Linking)

以c語言為例:

1 預(yù)處理

預(yù)編譯過程主要處理那些源文件中的以“#”開始的預(yù)編譯指令,主要處理規(guī)則有:

將所有的“#define”刪除,并展開所用的宏定義處理所有條件預(yù)編譯指令,比如“#if”、“#ifdef”、 “#elif”、“#endif”處理“#include”預(yù)編譯指令,將被包含的文件插入到該編譯指令的位置,注:此過程是遞歸進(jìn)行的刪除所有注釋添加行號和文件名標(biāo)識,以便于編譯時編譯器產(chǎn)生調(diào)試用的行號信息以及用于編譯時產(chǎn)生編譯錯誤或警告時可顯示行號保留所有的#pragma編譯器指令。

2 編譯

編譯過程就是把預(yù)處理完的文件進(jìn)行一系列的詞法分析、語法分析、語義分析及優(yōu)化后生成相應(yīng)的匯編代碼文件。這個過程是整個程序構(gòu)建的核心部分。

3 匯編

匯編器是將匯編代碼轉(zhuǎn)化成機(jī)器可以執(zhí)行的指令,每一條匯編語句幾乎都是一條機(jī)器指令。經(jīng)過編譯、鏈接、匯編輸出的文件成為目標(biāo)文件(Object File)

4 鏈接

鏈接的主要內(nèi)容就是把各個模塊之間相互引用的部分處理好,使各個模塊可以正確的拼接。鏈接的主要過程包塊 地址和空間的分配(Address and Storage Allocation)、符號決議(Symbol Resolution)和重定位(Relocation)等步驟。

5 靜態(tài)鏈接和動態(tài)鏈接

靜態(tài)鏈接方法:靜態(tài)鏈接的時候,載入代碼就會把程序會用到的動態(tài)代碼或動態(tài)代碼的地址確定下來靜態(tài)庫的鏈接可以使用靜態(tài)鏈接,動態(tài)鏈接庫也可以使用這種方法鏈接導(dǎo)入庫

動態(tài)鏈接方法:使用這種方式的程序并不在一開始就完成動態(tài)鏈接,而是直到真正調(diào)用動態(tài)庫代碼時,載入程序才計算(被調(diào)用的那部分)動態(tài)代碼的邏輯地址,然后等到某個時候,程序又需要調(diào)用另外某塊動態(tài)代碼時,載入程序又去計算這部分代碼的邏輯地址,所以,這種方式使程序初始化時間較短,但運(yùn)行期間的性能比不上靜態(tài)鏈接的程序

6 虛擬內(nèi)存技術(shù)

虛擬存儲器是值具有請求調(diào)入功能和置換功能,能從邏輯上對內(nèi)存容量加以擴(kuò)充的一種存儲系統(tǒng).

7 分頁和分段

分頁: 用戶程序的地址空間被劃分成若干固定大小的區(qū)域,稱為“頁”,相應(yīng)地,內(nèi)存空間分成若干個物理塊,頁和塊的大小相等。可將用戶程序的任一頁放在內(nèi)存的任一塊中,實現(xiàn)了離散分配。

分段: 將用戶程序地址空間分成若干個大小不等的段,每段可以定義一組相對完整的邏輯信息。存儲分配時,以段為單位,段與段在內(nèi)存中可以不相鄰接,也實現(xiàn)了離散分配。

分頁與分段的主要區(qū)別

頁是信息的物理單位,分頁是為了實現(xiàn)非連續(xù)分配,以便解決內(nèi)存碎片問題,或者說分頁是由于系統(tǒng)管理的需要.段是信息的邏輯單位,它含有一組意義相對完整的信息,分段的目的是為了更好地實現(xiàn)共享,滿足用戶的需要.頁的大小固定,由系統(tǒng)確定,將邏輯地址劃分為頁號和頁內(nèi)地址是由機(jī)器硬件實現(xiàn)的.而段的長度卻不固定,決定于用戶所編寫的程序,通常由編譯程序在對源程序進(jìn)行編譯時根據(jù)信息的性質(zhì)來劃分.分頁的作業(yè)地址空間是一維的.分段的地址空間是二維的.

8 頁面置換算法

最佳置換算法OPT:不可能實現(xiàn)先進(jìn)先出FIFO最近最久未使用算法LRU:最近一段時間里最久沒有使用過的頁面予以置換.clock算法

9 邊沿觸發(fā)和水平觸發(fā)

邊緣觸發(fā)是指每當(dāng)狀態(tài)變化時發(fā)生一個 io 事件,條件觸發(fā)是只要滿足條件就發(fā)生一個 io 事件

數(shù)據(jù)庫

1 事務(wù)

數(shù)據(jù)庫事務(wù)(Database Transaction) ,是指作為單個邏輯工作單元執(zhí)行的一系列操作,要么完全地執(zhí)行,要么完全地不執(zhí)行。

2 數(shù)據(jù)庫索引

推薦: http://tech.meituan.com/MySQL-index.html

MySQL索引背后的數(shù)據(jù)結(jié)構(gòu)及算法原理

聚集索引,非聚集索引,B-Tree,B+Tree,最左前綴原理

3 Redis原理

4 樂觀鎖和悲觀鎖

悲觀鎖:假定會發(fā)生并發(fā)沖突,屏蔽一切可能違反數(shù)據(jù)完整性的操作

樂觀鎖:假設(shè)不會發(fā)生并發(fā)沖突,只在提交操作時檢查是否違反數(shù)據(jù)完整性。

5 MVCC

6 MyISAM和InnoDB

MyISAM 適合于一些需要大量查詢的應(yīng)用,但其對于有大量寫操作并不是很好。甚至你只是需要update一個字段,整個表都會被鎖起來,而別的進(jìn)程,就算是讀進(jìn)程都無法操作直到讀操作完成。另外,MyISAM 對于 SELECT COUNT(*) 這類的計算是超快無比的。

InnoDB 的趨勢會是一個非常復(fù)雜的存儲引擎,對于一些小的應(yīng)用,它會比 MyISAM 還慢。他是它支持“行鎖” ,于是在寫操作比較多的時候,會更優(yōu)秀。并且,他還支持更多的高級應(yīng)用,比如:事務(wù)。

網(wǎng)絡(luò)

1 三次握手

客戶端通過向服務(wù)器端發(fā)送一個SYN來創(chuàng)建一個主動打開,作為三路握手的一部分。客戶端把這段連接的序號設(shè)定為隨機(jī)數(shù) A。服務(wù)器端應(yīng)當(dāng)為一個合法的SYN回送一個SYN/ACK。ACK 的確認(rèn)碼應(yīng)為 A+1,SYN/ACK 包本身又有一個隨機(jī)序號 B。最后,客戶端再發(fā)送一個ACK。當(dāng)服務(wù)端受到這個ACK的時候,就完成了三路握手,并進(jìn)入了連接創(chuàng)建狀態(tài)。此時包序號被設(shè)定為收到的確認(rèn)號 A+1,而響應(yīng)則為 B+1。

2 四次揮手

3 ARP協(xié)議

地址解析協(xié)議(Address Resolution Protocol): 根據(jù)IP地址獲取物理地址的一個TCP/IP協(xié)議

4 urllib和urllib2的區(qū)別

這個面試官確實問過,當(dāng)時答的urllib2可以Post而urllib不可以.

urllib提供urlencode方法用來GET查詢字符串的產(chǎn)生,而urllib2沒有。這是為何urllib常和urllib2一起使用的原因。urllib2可以接受一個Request類的實例來設(shè)置URL請求的headers,urllib僅可以接受URL。這意味著,你不可以偽裝你的User Agent字符串等。

5 Post和Get

GET和POST有什么區(qū)別?及為什么網(wǎng)上的多數(shù)答案都是錯的

get: RFC 2616 – Hypertext Transfer Protocol — HTTP/1.1post: RFC 2616 – Hypertext Transfer Protocol — HTTP/1.1

6 Cookie和session

 CookieSession
儲存位置客戶端服務(wù)器端
目的跟蹤會話,也可以保存用戶偏好設(shè)置或者保存用戶名密碼等跟蹤會話
安全性不安全安全

session技術(shù)是要使用到cookie的,之所以出現(xiàn)session技術(shù),主要是為了安全。

7 apache和nginx的區(qū)別

nginx 相對 apache 的優(yōu)點(diǎn):

輕量級,同樣起web 服務(wù),比apache 占用更少的內(nèi)存及資源抗并發(fā),nginx 處理請求是異步非阻塞的,支持更多的并發(fā)連接,而apache 則是阻塞型的,在高并發(fā)下nginx 能保持低資源低消耗高性能配置簡潔高度模塊化的設(shè)計,編寫模塊相對簡單社區(qū)活躍

apache 相對nginx 的優(yōu)點(diǎn):

rewrite ,比nginx 的rewrite 強(qiáng)大模塊超多,基本想到的都可以找到少bug ,nginx 的bug 相對較多超穩(wěn)定

8 網(wǎng)站用戶密碼保存

明文保存明文hash后保存,如md5MD5+Salt方式,這個salt可以隨機(jī)知乎使用了Bcrypy(好像)加密

9 HTTP和HTTPS

狀態(tài)碼定義
1xx 報告接收到請求,繼續(xù)進(jìn)程
2xx 成功步驟成功接收,被理解,并被接受
3xx 重定向為了完成請求,必須采取進(jìn)一步措施
4xx 客戶端出錯請求包括錯的順序或不能完成
5xx 服務(wù)器出錯服務(wù)器無法完成顯然有效的請求

403: Forbidden404: Not Found

HTTPS握手,對稱加密,非對稱加密,TLS/SSL,RSA

10 XSRF和XSS

CSRF(Cross-site request forgery)跨站請求偽造XSS(Cross Site Scripting)跨站腳本攻擊

CSRF重點(diǎn)在請求,XSS重點(diǎn)在腳本

11 冪等 Idempotence

HTTP方法的冪等性是指一次和多次請求某一個資源應(yīng)該具有同樣的副作用。(注意是副作用)

GET http://www.bank.com/account/123456,不會改變資源的狀態(tài),不論調(diào)用一次還是N次都沒有副作用。請注意,這里強(qiáng)調(diào)的是一次和N次具有相同的副作用,而不是每次GET的結(jié)果相同。GET http://www.news.com/latest-news這個HTTP請求可能會每次得到不同的結(jié)果,但它本身并沒有產(chǎn)生任何副作用,因而是滿足冪等性的。

DELETE方法用于刪除資源,有副作用,但它應(yīng)該滿足冪等性。比如:DELETE http://www.forum.com/article/4231,調(diào)用一次和N次對系統(tǒng)產(chǎn)生的副作用是相同的,即刪掉id為4231的帖子;因此,調(diào)用者可以多次調(diào)用或刷新頁面而不必?fù)?dān)心引起錯誤。

POST所對應(yīng)的URI并非創(chuàng)建的資源本身,而是資源的接收者。比如:POST http://www.forum.com/articles的語義是在http://www.forum.com/articles下創(chuàng)建一篇帖子,HTTP響應(yīng)中應(yīng)包含帖子的創(chuàng)建狀態(tài)以及帖子的URI。兩次相同的POST請求會在服務(wù)器端創(chuàng)建兩份資源,它們具有不同的URI;所以,POST方法不具備冪等性。

PUT所對應(yīng)的URI是要創(chuàng)建或更新的資源本身。比如:PUT http://www.forum/articles/4231的語義是創(chuàng)建或更新ID為4231的帖子。對同一URI進(jìn)行多次PUT的副作用和一次PUT是相同的;因此,PUT方法具有冪等性。

12 RESTful架構(gòu)(SOAP,RPC)

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

13 SOAP

SOAP(原為Simple Object access Protocol的首字母縮寫,即簡單對象訪問協(xié)議)是交換數(shù)據(jù)的一種協(xié)議規(guī)范,使用在計算機(jī)網(wǎng)絡(luò)Web服務(wù)(web service)中,交換帶結(jié)構(gòu)信息。SOAP為了簡化網(wǎng)頁服務(wù)器(Web Server)從xml數(shù)據(jù)庫中提取數(shù)據(jù)時,節(jié)省去格式化頁面時間,以及不同應(yīng)用程序之間按照HTTP通信協(xié)議,遵從XML格式執(zhí)行資料互換,使其抽象于語言實現(xiàn)、平臺和硬件。

14 RPC

RPC(Remote Procedure Call Protocol)——遠(yuǎn)程過程調(diào)用協(xié)議,它是一種通過網(wǎng)絡(luò)從遠(yuǎn)程計算機(jī)程序上請求服務(wù),而不需要了解底層網(wǎng)絡(luò)技術(shù)的協(xié)議。RPC協(xié)議假定某些傳輸協(xié)議的存在,如TCP或UDP,為通信程序之間攜帶信息數(shù)據(jù)。在OSI網(wǎng)絡(luò)通信模型中,RPC跨越了傳輸層和應(yīng)用層。RPC使得開發(fā)包括網(wǎng)絡(luò)分布式多程序在內(nèi)的應(yīng)用程序更加容易。

總結(jié):服務(wù)提供的兩大流派.傳統(tǒng)意義以方法調(diào)用為導(dǎo)向通稱RPC。為了企業(yè)SOA,若干廠商聯(lián)合推出webservice,制定了wsdl接口定義,傳輸soap.當(dāng)互聯(lián)網(wǎng)時代,臃腫SOA被簡化為http+xml/json.但是簡化出現(xiàn)各種混亂。以資源為導(dǎo)向,任何操作無非是對資源的增刪改查,于是統(tǒng)一的REST出現(xiàn)了.

進(jìn)化的順序: RPC -> SOAP -> RESTful

15 CGI和WSGI

CGI是通用網(wǎng)關(guān)接口,是連接web服務(wù)器和應(yīng)用程序的接口,用戶通過CGI來獲取動態(tài)數(shù)據(jù)或文件等。CGI程序是一個獨(dú)立的程序,它可以用幾乎所有語言來寫,包括perl,c,lua,python等等。

WSGI, Web Server Gateway Interface,是Python應(yīng)用程序或框架和Web服務(wù)器之間的一種接口,WSGI的其中一個目的就是讓用戶可以用統(tǒng)一的語言(Python)編寫前后端。

官方說明:PEP-3333

16 中間人攻擊

在GFW里屢見不鮮的,呵呵.

中間人攻擊(Man-in-the-middle attack,通常縮寫為MITM)是指攻擊者與通訊的兩端分別創(chuàng)建獨(dú)立的聯(lián)系,并交換其所收到的數(shù)據(jù),使通訊的兩端認(rèn)為他們正在通過一個私密的連接與對方直接對話,但事實上整個會話都被攻擊者完全控制。

17 c10k問題

所謂c10k問題,指的是服務(wù)器同時支持成千上萬個客戶端的問題,也就是concurrent 10 000 connection(這也是c10k這個名字的由來)。推薦: http://www.kegel.com/c10k.html

18 socket

推薦: http://www.cnblogs.com/bingyun84/archive/2009/10/16/1584387.html

Socket=Ip address+ TCP/UDP + port

19 瀏覽器緩存

推薦: http://web.jobbole.com/84367/

304 Not Modified

20 HTTP1.0和HTTP1.1

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

請求頭Host字段,一個服務(wù)器多個網(wǎng)站長鏈接文件斷點(diǎn)續(xù)傳身份認(rèn)證,狀態(tài)管理,Cache緩存

21 Ajax

AJAX,Asynchronous Javascript and XML(異步的 JavaScript 和 XML), 是與在不重新加載整個頁面的情況下,與服務(wù)器交換數(shù)據(jù)并更新部分網(wǎng)頁的技術(shù)。

*NIX

unix進(jìn)程間通信方式(IPC)

管道(Pipe):管道可用于具有親緣關(guān)系進(jìn)程間的通信,允許一個進(jìn)程和另一個與它有共同祖先的進(jìn)程之間進(jìn)行通信。命名管道(named pipe):命名管道克服了管道沒有名字的限制,因此,除具有管道所具有的功能外,它還允許無親緣關(guān)系進(jìn)程間的通信。命名管道在文件系統(tǒng)中有對應(yīng)的文件名。命名管道通過命令mkfifo或系統(tǒng)調(diào)用mkfifo來創(chuàng)建。信號(Signal):信號是比較復(fù)雜的通信方式,用于通知接受進(jìn)程有某種事件發(fā)生,除了用于進(jìn)程間通信外,進(jìn)程還可以發(fā)送信號給進(jìn)程本身;linux除了支持Unix早期信號語義函數(shù)sigal外,還支持語義符合Posix.1標(biāo)準(zhǔn)的信號函數(shù)sigaction(實際上,該函數(shù)是基于BSD的,BSD為了實現(xiàn)可靠信號機(jī)制,又能夠統(tǒng)一對外接口,用sigaction函數(shù)重新實現(xiàn)了signal函數(shù))。消息(Message)隊列:消息隊列是消息的鏈接表,包括Posix消息隊列system V消息隊列。有足夠權(quán)限的進(jìn)程可以向隊列中添加消息,被賦予讀權(quán)限的進(jìn)程則可以讀走隊列中的消息。消息隊列克服了信號承載信息量少,管道只能承載無格式字節(jié)流以及緩沖區(qū)大小受限等缺共享內(nèi)存:使得多個進(jìn)程可以訪問同一塊內(nèi)存空間,是最快的可用IPC形式。是針對其他通信機(jī)制運(yùn)行效率較低而設(shè)計的。往往與其它通信機(jī)制,如信號量結(jié)合使用,來達(dá)到進(jìn)程間的同步及互斥。內(nèi)存映射(mapped memory):內(nèi)存映射允許任何多個進(jìn)程間通信,每一個使用該機(jī)制的進(jìn)程通過把一個共享的文件映射到自己的進(jìn)程地址空間來實現(xiàn)它。信號量(semaphore):主要作為進(jìn)程間以及同一進(jìn)程不同線程之間的同步手段。套接口(Socket):更為一般的進(jìn)程間通信機(jī)制,可用于不同機(jī)器之間的進(jìn)程間通信。起初是由Unix系統(tǒng)的BSD分支開發(fā)出來的,但現(xiàn)在一般可以移植到其它類Unix系統(tǒng)上:Linux和System V的變種都支持套接字。

數(shù)據(jù)結(jié)構(gòu)

1 紅黑樹

紅黑樹與AVL的比較:

AVL是嚴(yán)格平衡樹,因此在增加或者刪除節(jié)點(diǎn)的時候,根據(jù)不同情況,旋轉(zhuǎn)的次數(shù)比紅黑樹要多;

紅黑是用非嚴(yán)格的平衡來換取增刪節(jié)點(diǎn)時候旋轉(zhuǎn)次數(shù)的降低;

所以簡單說,如果你的應(yīng)用中,搜索的次數(shù)遠(yuǎn)遠(yuǎn)大于插入和刪除,那么選擇AVL,如果搜索,插入刪除次數(shù)幾乎差不多,應(yīng)該選擇RB。

編程題

1 臺階問題/斐波納挈

一只青蛙一次可以跳上1級臺階,也可以跳上2級。求該青蛙跳上一個n級的臺階總共有多少種跳法。

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

第二種記憶方法

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

第三種方法

Python
12345deffib(n):    a,b=0,1    for_inxrange(n):        a,b=b,a+b    returnb

2 變態(tài)臺階問題

一只青蛙一次可以跳上1級臺階,也可以跳上2級……它也可以跳上n級。求該青蛙跳上一個n級的臺階總共有多少種跳法。

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

3 矩形覆蓋

我們可以用2*1的小矩形橫著或者豎著去覆蓋更大的矩形。請問用n個2*1的小矩形無重疊地覆蓋一個2*n的大矩形,總共有多少種方法?

2*n個矩形的覆蓋方法等于第2*(n-1)加上第2*(n-2)的方法。

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

4 楊氏矩陣查找

在一個m行n列二維數(shù)組中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函數(shù),輸入這樣的一個二維數(shù)組和一個整數(shù),判斷數(shù)組中是否含有該整數(shù)。

5 去除列表中的重復(fù)元素

用集合

Python
1list(set(l))

用字典

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

用字典并保持順序

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

列表推導(dǎo)式

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

面試官提到的,先排序然后刪除.

6 鏈表成對調(diào)換

1->2->3->4轉(zhuǎn)換成2->1->4->3.

Python
123456789101112131415class 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

7 創(chuàng)建字典的方法

1 直接創(chuàng)建

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

2 工廠方法

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

3 fromkeys()方法

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

8 合并兩個有序列表

知乎遠(yuǎn)程面試要求編程

尾遞歸

Python
12345678910111213141516def _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, [])

循環(huán)算法

Python
123456789101112defloop_merge_sort(l1,l2):    tmp=[]    whilelen(l1)>0andlen(l2)>0:        ifl1[0]<l2[0]:            tmp.append(l1[0])            dell1[0]        else:            tmp.append(l2[0])            dell2[0]    tmp.extend(l1)    tmp.extend(l2)    returntmp

9 交叉鏈表求交點(diǎn)

去哪兒的面試,沒做出來.

Python
1234567891011121314151617181920212223242526class ListNode:    def __init__(self, x):        self.val = x        self.next = Nonedef 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

10 二分查找

Python
12345678910111213141516171819defbinarySearch(l,t):    low,high=0,len(l)-1    whilelow<high:        printlow,high        mid=(low+high)/2        ifl[mid]>t:            high=mid        elifl[mid]<t:            low=mid+1        else:            returnmid    returnlowifl[low]==telseFalse if__name__=='__main__':    l=[1,4,12,45,66,99,120,444]    printbinarySearch(l,12)    printbinarySearch(l,1)    printbinarySearch(l,13)    printbinarySearch(l,444)

11 快排

Python
123456789101112def 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))

12 找零問題

Python
1234567891011121314151617181920def  coinChange(values,money,coinsUsed):    #values    T[1:n]數(shù)組    #valuesCounts   錢幣對應(yīng)的種類數(shù)    #money  找出來的總錢數(shù)    #coinsUsed   對應(yīng)于目前錢幣總數(shù)i所使用的硬幣數(shù)目    forcentsinrange(1,money+1):        minCoins=cents    #從第一個開始到money的所有情況初始        forvalueinvalues:            ifvalue<=cents:                temp=coinsUsed[cents-value]+1                iftemp<minCoins:                    minCoins=temp        coinsUsed[cents]=minCoins        print('面值為:{0} 的最小硬幣數(shù)目為:{1} '.format(cents,coinsUsed[cents])) if__name__=='__main__':    values=[25,21,10,5,1]    money=63    coinsUsed={i:0foriinrange(money+1)}    coinChange(values,money,coinsUsed)

13 廣度遍歷和深度遍歷二叉樹

給定一個數(shù)組,構(gòu)建二叉樹,并且按層次打印這個二叉樹

Python
123456789101112131415161718192021222324252627282930## 14 二叉樹節(jié)點(diǎn)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)

17 前中后序遍歷

深度遍歷改變順序就OK了

18 求最大樹深

Python
1234defmaxDepth(root):        ifnotroot:            return0        returnmax(maxDepth(root.left),maxDepth(root.right))+1

19 求兩棵樹是否相同

Python
1234567def 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

20 前序中序求后序

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

Python
123456789101112131415defrebuild(pre,center):    ifnotpre:        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:])    returncur defdeep(root):    ifnotroot:        return    deep(root.left)    deep(root.right)    printroot.data

21 單鏈表逆置

Python
12345678910111213141516171819202122classNode(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))))))))) defrev(link):    pre=link    cur=link.next    pre.next=None    whilecur:        tmp=cur.next        cur.next=pre        pre=cur        cur=tmp    returnpre root=rev(link)whileroot:    printroot.data    root=root.next

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 温宿县| 藁城市| 黄山市| 张家川| 尖扎县| 增城市| 赣州市| 嘉定区| 元朗区| 呼玛县| 隆子县| 阜平县| 彭泽县| 湖口县| 洪泽县| 防城港市| 胶州市| 浏阳市| 洛阳市| 枣庄市| 同仁县| 鄱阳县| 顺平县| 柘荣县| 乡宁县| 华宁县| 凤城市| 祁阳县| 敦煌市| 苏尼特右旗| 汾西县| 青州市| 长宁区| 漾濞| 无极县| 黔西县| 突泉县| 什邡市| 浑源县| 蓬安县| 赤水市|