程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python面試題

編輯:Python

1、 python多線程有個全局解釋器鎖(global interpreter lock),這個鎖的意思是任一時間只能有一個線程使用解釋器,跟單 cpu跑多個程序一個意思,大家都是輪著用的,這叫“並發”,不是“並行”。
多進程間共享數據,可以使用 multiprocessing.Value和multiprocessing.Array。 2、什麼是lambda函數?它有什麼好處?
2、 lambda 函數是一個可以接收任意多個參數(包括可選參數)並且返回單個表達式值的函數。lambda 函數不能包含命令,它們所包含的表達式不能超過一個。不要試圖向lambda 函數中塞入太多的東西;如果你需要更復雜的東西,應該定義一個普通函數,然後想讓它多長就多長。
3、Python是如何進行類型轉換的? ①函數描述
② int(x [,base ]) 將x轉換為一個整數 ③long(x [,base ]) 將x轉換為一個長整數 ④float(x ) 將x轉換到一個浮點數 ⑤complex(real [,imag ]) 創建一個復數 ⑥str(x ) 將對象 x 轉換為字符串 ⑦repr(x ) 將對象 x 轉換為表達式字符串
⑧eval(str ) 用來計算在字符串中的有效Python表達式,並返回一個對象 ⑨tuple(s ) 將序列 s 轉換為一個元組 ⑩list(s ) 將序列 s 轉換為一個列表 ⑪chr(x ) 將一個整數轉換為一個字符 ⑫unichr(x ) 將一個整數轉換為Unicode字符 ⑬ord(x ) 將一個字符轉換為它的整數值 ⑭hex(x ) 將一個整數轉換為一個十六進制字符串 ⑮oct(x ) 將一個整數轉換為一個八進制字符串 4、python多線程與多進程的區別

                在UNIX平台上,當某個進程終結之後,該進程需要被其父進程調用wait,否則進程成為僵屍進程(Zombie)。所以,有必要對每個Process對象調用join()方法 (實際上等同於wait)

            。對於多線程來說,由於只有一個進程,所以不存在此必要性。 
                多進程應該避免共享資源。在多線程中,我們可以比較容易地共享資源,比如使用全局變量或者傳遞參數。在多進程情況下,由於每個進程有自己獨立的內存空間,以上方法並不合適。此時我們可以通過共享內存和Manager的方法來共享資源。
            但這樣做提高了程序的復雜度,並因為同步的需要而降低了程序的效率。 5、Python
            裡面如何拷貝一個對象? 
標准庫中的copy模塊提供了兩個方法來實現拷貝。一個方法是copy,它返回和參數包含內容一樣的對象。使用deepcopy方法,對象中的屬性也被復制。            
1
2
3
4
5
6
7
6、介紹一下except的用法和作用?
Python的except用來捕獲所有異常,因為Python裡面的每次錯誤都會拋出一個異常,所以每個程序的錯誤都被當作一個運行時錯誤。
7 、Python中pass語句的作用是什麼?
pass語句什麼也不做,一般作為占位符或者創建占位程序,pass語句不會執行任何操作。
8、Python解釋器種類以及特點?
Python是一門解釋器語言,代碼想運行,必須通過解釋器執行,Python存在多種解釋器,分別基於不同語言開發,每個解釋器有不同的特點,但都能正常運行Python代碼,以下是常用的五種Python解釋器:
CPython:當從Python官方網站下載並安裝好Python2.7後,就直接獲得了一個官方版本的解釋器:Cpython,這個解釋器是用C語言開發的,所以叫CPython,在命名行下運行python,就是啟動CPython解釋器,CPython是使用最廣的Python解釋器。 IPython:IPython是基於CPython之上的一個交互式解釋器,也就是說,IPython只是在交互方式上有所增強,但是執行Python代碼的功能和CPython是完全一樣的,好比很多國產浏覽器雖然外觀不同,但內核其實是調用了IE。
PyPy:PyPy是另一個Python解釋器,它的目標是執行速度,PyPy采用JIT技術,對Python代進行動態編譯,所以可以顯著提高Python代碼的執行速度。
Jython:Jython是運行在Java平台上的Python解釋器,可以直接把Python代碼編譯成Java字節碼執行。
IronPython:IronPython和Jython類似,只不過IronPython是運行在微軟.Net平台上的Python解釋器,可以直接把Python代碼編譯成.Net的字節碼。
在Python的解釋器中,使用廣泛的是CPython,對於Python的編譯,除了可以采

            用以上解釋器進行編譯外,技術高超的開發者還可以按照自己的需求自行編寫Python解釋器來執行
      
            Python代碼,十分的方便! 9、列舉布爾值為
        False的常見值?       
             0, [] , () , {} , '' , False , None 10、字符串、列表、元組、字典每個常用的            
            5個方法?                     
            字符串:repleace,strip,split,reverse,upper,lower,join.....     
         列表:append,pop,,remove,sort,count,index.....                 
            元組:index,count,__len__(),__dir__() 
            字典:get,keys,values,pop,popitems,clear,,items..... 11、lambda表達式格式以及應用場景? 
                表達式格式:lambda後面跟一個或多個參數,緊跟一個冒號,以後是一個表達式。冒號前是參數,冒號後是返回值。例如:lambda x : 2x 

            應用場景:經
            常與一些內置函數
            相結合使用,
            比如說
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
map(),filter(),sorted(),reduce()等
12、pass的作用?
①空語句do nothing;
②保證格式完整;
③保證語義完整。 13、arg
和 *kwarg作用?
萬能參數,解決了函數參數不固定的問題
*arg:會把位置參數轉化為tuple
**kwarg:會把關鍵字參數轉化為dict

14、is和==的區別?

               is:判斷內存地址是否相等;     ==:判斷數值是否相等。 
1
15、簡述Python的深淺拷貝以及應用場景?
copy():淺copy,淺拷貝指僅僅拷貝數據集合的第一層數據 deepcopy():深copy,深拷貝指拷貝數據集合的所有層

16、Python垃圾回收機制?
python采用的是引用計數機制為主,標記-清除和分代收集(隔代回收、分代回收)兩種機制為輔的策略 計數機制:
Python的GC模塊主要運用了引用計數來跟蹤和回收垃圾。在引用計數的基礎上,還可以通過“標記-清除”
解決容器對象可能產生的循環引用的問題。通過分代回收以空間換取時間進一步提高垃圾回收的效率。 標記-清除:
標記-清除的出現打破了循環引用,也就是它只關注那些可能會產生循環引用的對象。
缺點:該機制所帶來的額外操作和需要回收的內存塊成正比。隔代回收:

原理:將系統中的所有內存塊根據其存活時間劃分為不同的集合,每一個集合就成
        
            
        
            為一個“代”, 

        
            
        
            垃圾收集的頻率隨著“代”的存活時間的增大而減小。也就是說,活得越長的對象,就越不可能是垃圾, 
就應該減少對它的垃圾收集頻率。那麼如何來衡量這個存活時間:通常是利用幾次垃圾收集動作來衡量, 
如果一個對象經過的垃圾收集次數越多,可以得出:該對象存活時間就越長。 17、python的可變類型和不可變類型? 
不可變類型(數字、字符串、元組、不可變集合); 
        
            
        
                可變類型(列表、字典、可變集合)。 
        
            
        
            18、Python裡面search()和match()的區別? 
match()函數只檢測RE是不是在string的開始位置匹配,search()會掃描整個
        
            
        
            string查找匹配, 也就是說match()
        
            
        
            只有在0位置匹配成功的話才有返回,如果不是開始位置匹配成功的話,
        
            
        
            match()就返回none 
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
31
32
33
34
19、用Python匹配HTML tag的時候,<.>和<.?>有什麼區別?
前者是貪婪匹配,會從頭到尾匹配 xyz,而後者是非貪婪匹配,只匹配到第一個 >。
20、Python裡面如何生成隨機數? import random;
random.random();

2021年最新Python面試題及答案
1、Python裡面如何拷貝一個對象?(賦值,淺拷貝,深拷貝的區別)
答:賦值(=),就是創建了對象的一個新的引用,修改其中任意一個變量都會影響到另一個。
淺拷貝:創建一個新的對象,但它包含的是對原始對象中包含項的引用(如果用引用的方式修改其中一個對象,另外一個也會修改改變){1,完全切片方法;2,工廠函數,如list();3,copy模塊的copy()函數}
深拷貝:創建一個新的對象,並且遞歸的復制它所包含的對象(修改其中一個,另外一個不會改變){copy模塊的()函數}
2、Python裡面match()和search()的區別?
答:re模塊中match(pattern,string[,flags]),檢查string的開頭是否與pattern匹配。
re模塊中research(pattern,string[,flags]),在string搜索pattern的第一個匹配值。

print(‘super’, ‘superstition’).span())
(0, 5)
print(‘super’, ‘insuperable’))
None
print(‘super’, ‘superstition’).span())
(0, 5)
print(‘super’, ‘insuperable’).span())
(2, 7)
3、有沒有一個工具可以幫助查找python的bug和進行靜態的代碼分析?
答:PyChecker是一個python代碼的靜態分析工具,它可以幫助查找python代碼的bug, 會對代碼的復雜度和格式提出警告
Pylint是另外一個工具可以進行codingstandard檢查
4、簡要描述Python的垃圾回收機制(garbage collection)。
答案
這裡能說的很多。你應該提到下面幾個主要的點:
Python在內存中存儲了每個對象的引用計數(reference count)。如果計數值變成0,那麼相應的對象就會小時,分配給該對象的內存就會釋放出來用作他用。
偶爾也會出現引用循環(reference cycle)。垃圾回收器會定時尋找這個循環,並將其回收。舉個例子,假設有兩個對象o1和o2,而且符合 == o2和 == o1這兩個條件。如果o1和o2沒有其他代碼引用,那麼它們就不應該繼續存在。但它們的引用計數都是1。
Python中使用了某些啟發式算法(heuristics)來加速垃圾回收。例如,越晚創建的對象更有可能被回收。對象被創建之後,垃圾回收器會分配它們所屬的代(generation)。每個對象都會被分配一個代,而被分配更年輕代的對象是優先被處理的。
5、什麼是lambda函數?它有什麼好處?
答:lambda 表達式,通常是在需要一個函數,但是又不想費神去命名一個函數的場合下使用,也就是指匿名函數
lambda函數:首要用途是指點短小的回調函數
lambda [arguments]:expression
a=lambdax,y:x+y
a(3,11)
6、請寫出一段Python代碼實現刪除一個list裡面的重復元素
答:
1,使用set函數,set(list)
2,使用字典函數,
a=[1,2,4,2,4,5,6,5,7,8,9,0]
b={}
b=(a)
c=list())
c
7、用Python匹配HTML tag的時候,<.>和<.?>有什麼區別?
答:術語叫貪婪匹配( <.> )和非貪婪匹配(<.?> )
例如:
test
<.> :
test
<.?> :
8、如何在一個function裡面設置一個全局的變量?
答:解決方法是在function的開始插入一個global聲明:
def f()
global x
9、編程用sort進行排序,然後從最後一個元素開始判斷
a=[1,2,4,2,4,5,7,10,5,5,7,8,9,0,3]
()
last=a[-1]
for i inrange(len(a)-2,-1,-1):
if last==a[i]:
del a[i]
else:last=a[i]
print(a)
10、下面的代碼在Python2中的輸出是什麼?解釋你的答案
def div1(x,y):
print “%s/%s = %s” % (x, y, x/y)

def div2(x,y):
print "%s2)
div2(5,2)
div2(5.,2.)
另外,在Python3中上面的代碼的輸出有何不同(假設代碼中的print語句都轉化成了Python3中的語法結構)?
在Python2中,代碼的輸出是:
5/2 = 2
2 =
52結果是
注意你可以通過下面的import語句來覆蓋Python2中的這一行為
from future import division
還要注意“雙斜槓”(//)操作符將會一直執行整除,忽略操作數的類型。這就是為什麼/即使在Python2中結果也是
但是在Python3並沒有這一行為。兩個操作數都是整數時,也不執行整數運算。在Python3中,輸出如下:
5/2 =
2 =
5//2 = 2
/ =


Python基礎知識筆試
一、單選題(2.5分*20題)

 下列哪個表達式在Python中是非法的? B
1
A. x = y = z = 1
B. x = (y = z + 1)
C. x, y = y, x
D. x += y
2. python my.py v1 v2 命令運行腳本,通過 from sys import argv如何獲得v2的參數值? C
A. argv[0]
B. argv[1]
C. argv[2]
D. argv[3]
3. 如何解釋下面的執行結果? B
print 1.2 - 1.0 == 0.2
False
A. Python的實現有錯誤
B. 浮點數無法精確表示
C. 布爾運算不能用於浮點數比較
D. Python將非0數視為False
4. 下列代碼執行結果是什麼? D
x = 1
def change(a):
x+= 1
print x
change(x)
A. 1
B. 2
C. 3
D. 報錯
5. 下列哪種類型是Python的映射類型? D
A. str
B. list
C. tuple
D. dict
6. 下述字符串格式化語法正確的是? D
A. ‘GNU’s Not %d %%’ % ‘UNIX’
B. ‘GNU’s Not %d %%’ % ‘UNIX’
C. ‘GNU’s Not %s %%’ % ‘UNIX’
D. ‘GNU’s Not %s %%’ % ‘UNIX’
7. 在Python 2.7中,下列哪種是Unicode編碼的書寫方式?C
A. a = ‘中文’
B. a = r‘中文’
C. a = u’中文’
D. a = b’中文’
8. 下列代碼的運行結果是? D
print ‘a’ < ‘b’ < ‘c’
A. a
B. b
C. c
D. True
E. False
9. 下列代碼運行結果是? C
a = ‘a’
print a > ‘b’ or ‘c’
A. a
B. b
C. c
D. True
E. False
10. 下列哪種不是Python元組的定義方式? A
A. (1)
B. (1, )
C. (1, 2)
D. (1, 2, (3, 4))
11. a與b定義如下,下列哪個是正確的? B
a = ‘123’
b = ‘123’
A. a != b
B. a is b
C. a == 123
D. a + b = 246
12. 下列對協程的理解錯誤的是? D
A. 一個線程可以運行多個協程
B. 協程的調度由所在程序自身控制
C. Linux中線程的調度由操作系統控制
D. Linux中協程的調度由操作系統控制
13. 下列哪種函式參數定義不合法? C
A. def myfunc(*args):
B. def myfunc(arg1=1):
C. def myfunc(*args, a=1):
D. def myfunc(a=1, args):
14. 下列代碼執行結果是? A
[ii for i in xrange(3)]
A. [1, 1, 4]
B. [0, 1, 4]
C. [1, 2, 3]
D. (1, 1, 4)
15. 一個段代碼定義如下,下列調用結果正確的是?A
def bar(multiple):
def foo(n):
return multiple ** n
return foo
A. bar(2)(3) == 8
B. bar(2)(3) == 6
C. bar(3)(2) == 8
D. bar(3)(2) == 6
16. 下面代碼運行結果? C
a = 1
try:
a += 1
except:
a += 1
else:
a += 1
finally:
a += 1
print a
A. 2
B. 3
C. 4
D. 5
17. 下面代碼運行後,a、b、c、d四個變量的值,描述錯誤的是? D
import copy
a = [1, 2, 3, 4, [‘a’, ‘b’]]
b = a
c = copy.copy(a)
d = copy.deepcopy(a)
a.append(5)
a[4].append(‘c’)
A. a == [1,2, 3, 4, [‘a’, ‘b’, ‘c’], 5]
B. b == [1,2, 3, 4, [‘a’, ‘b’, ‘c’], 5]
C. c == [1,2, 3, 4, [‘a’, ‘b’, ‘c’]]
D. d == [1,2, 3, 4, [‘a’, ‘b’, ‘c’]]
18. 有如下函數定義,執行結果正確的是? A
def dec(f):
n = 3
def wrapper(*args,**kw):
return f(*args,**kw) * n
return wrapper

@dec
def foo(n):
return n * 2
A. foo(2) == 12
B. foo(3) == 12
C. foo(2) == 6
D. foo(3) == 6
19. 有如下類定義,下列描述錯誤的是? D
class A(object):
pass

class B(A):
pass

b = B()
A. isinstance(b, A) == True
B. isinstance(b, object) == True
C. issubclass(B, A) == True
D. issubclass(b, B) == True
20. 下列代碼運行結果是? C
a = map(lambda x: x**3, [1, 2, 3])
list(a)
A. [1, 6, 9]
B. [1, 12, 27]
C. [1, 8, 27]
D. (1, 6, 9)
二、多選題(5分5題)
21. Python中函數是對象,描述正確的是? ABCD
A. 函數可以賦值給一個變量
B. 函數可以作為元素添加到集合對象中
C. 函數可以作為參數值傳遞給其它函數
D. 函數可以當做函數的返回值
22. 若 a = range(100),以下哪些操作是合法的? ABCD
A. a[-3]
B. a[2:13]
C. a[::3]
D. a[2-3]
23. 若 a = (1, 2, 3),下列哪些操作是合法的? ABD
A. a[1:-1]
B. a3
C. a[2] = 4
D. list(a)
24. Python中單下劃線_foo與雙下劃線__foo與__foo__的成員,下列說法正確的是?ABC
A. _foo 不能直接用於’from module import ’
B. __foo解析器用_classname__foo來代替這個名字,以區別和其他類相同的命名
C. __foo__代表python裡特殊方法專用的標識
D. __foo 可以直接用於’from module import ’
25. __new__和__init__的區別,說法正確的是? ABCD
A. new__是一個靜態方法,而__init__是一個實例方法
B. new__方法會返回一個創建的實例,而__init__什麼都不返回
C. 只有在__new__返回一個cls的實例時,後面的__init__才能被調用
D. 當創建一個新實例時調用__new,初始化一個實例時用__init
三、填空題(5分5題)
26. 在Python 2.7中,執行下列語句後,顯示結果是什麼? 答:0 0.5
from future importdivision
print 1//2, 1/2
27. 在Python 2.7中,執行下列語句後的顯示結果是什麼? 答:none 0
a = 1
b = 2 * a / 4
a = “none”
print a,b
28. 下列語句執行結果是什麼? 答:[1, 2, 3, 1, 2, 3, 1, 2, 3]
a = [1, 2, 3]
print a3
29. 下列語句的執行結果是什麼? 答:3
a = 1
for i in range(5):
if i == 2:
break
a += 1
else:
a += 1
print a
30. 下列代碼的運行結果是多少? 答:4
def bar(n):
m = n
while True:
m += 1
yield m
b = bar(3)
print b.next()

附錄:Python常見面試題精選
一、 基礎知識(7題)
題01:Python中的不可變數據類型和可變數據類型是什麼意思?
難度: *****【參考答案】
不可變數據類型是指不允許變量的值發生變化,如果改變了變量的值,相當於是新建了一個對象,而對於相同的值的對象,在內存中則只有一個對象(一個地址)。數值型、字符串string和元組tuple都屬於不可變數據類型。
可變數據類型是指允許變量的值發生變化,即如果對變量執行append、+=等操作,只會改變變量的值,而不會新建一個對象,變量引用的對象的地址也不會變化。不過對於相同的值的不同對象,在內存中會存在不同的對象,即每個對象都有自己的地址,相當於內存中對於同值的對象保存了多份,這裡不存在引用計數,是實實在在的對象。列表list和字典dict都屬於可變數據類型。
題02:請簡述Python中is和==的區別。
難度:***** 【參考答案】
Python中的對象包含三個要素:id、type和value。is比較的是兩個對象的id。==比較的是兩個對象的value。
題03:請簡述function(args, **kwargs)中的 args, kwargs分別是什麼意思?
難度:***** 【參考答案】
*args和kwargs主要用於函數定義的參數。Python語言允許將不定數量的參數傳給一個函數,其中args表示一個非鍵值對的可變參數列表,kwargs則表示不定數量的鍵值對參數列表。注意:*args和kwargs可以同時在函數的定義中,但是args必須在**kwargs前面。
題04:請簡述面向對象中__new__和__init__的區別。
難度: *****【參考答案】
(1)__new__至少要有一個參數cls,代表當前類,此參數在實例化時由Python解釋器自動識別。

            (2) __new__返回生成的實例,可以返回父類(通過super(當前類名, cls)的方式)__new__出來的實例,
1
或者直接是對象的__new__出來的實例。這在自己編程實現__new__時要特別注意。
(3) __init__有一個參數self,就是這個__new__返回的實例,__init__在__new__的基礎上可以完成一
些其它初始化的動作,init__不需要返回值。
(4) 如果__new__創建的是當前類的實例,會自動調用__init,通過返回語句裡面調用的__new__函
數的第一個參數是cls來保證是當前類實例,如果是其他類的類名,那麼實際創建並返回的就是其他類的實例,也就不會調用當前類或其他類的__init__函數。
題05:Python子類繼承自多個父類時,如多個父類有同名方法,子類將繼承自哪個方法?
難度:*****

             【參考答案】 
1
Python語言中子類繼承父類的方法是按照繼承的父類的先後順序確定的,例如,子類A繼承自父類B、C,且B、C中具有同名方法Test(),那麼A中的Test()方法實際上是繼承自B中的Test()方法。
題06:請簡述Python中如何避免死鎖?
難度:*****

             【參考答案】 
1
死鎖是指不同線程獲取了不同的鎖,但是線程間又希望獲取對方的鎖,雙方都在等待對方釋放鎖,這種相互等待資源的情況就是死鎖。Python語言可以使用threading.Condition對象,基於條件事件通知的形式去協調線程的運行,即可避免死鎖。
題07:什麼是排序算法的穩定性?常見的排序算法如冒泡排序、快速排序、歸並排序、堆排
序、Shell排序、二叉樹排序等的時間、空間復雜度和穩定性如何?
難度:*****

             【參考答案】 
1
假定在待排序的記錄序列中,存在多個具有相同的關鍵字的記錄,若經過排序,這些記錄的相對次序保持不變,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序後的序列中,r[i]仍在r[j]之前,則稱這種排序算法是穩定的;否則稱為不穩定的。
常見排序算法的時間、空間復雜度和穩定性如下表所示。


*基數排序的復雜度中,r表示關鍵字的基數,d表示長度,n表示關鍵字的個數。

二、 字符串與數字(7題)
題08:字符串內容去重並按字母順序排列。
難度:*****
令 s = “hfkfdlsahfgdiuanvzx”,試對 s 去重並按字母順序排列輸出 “adfghiklnsuvxz”。
【參考答案】

s = "hfkfdlsahfgdiuanvzx" 
s = list(set(s)) s.sort(reverse=False) print("".join(s))


1
2
3
4
題09:判斷兩個字符串是否同構。
難度:*****
字符串同構是指字符串s中的所有字符都可以替換為t中的所有字符。在保留字符順序的同時,必須用另一個字符替換所有出現的字符。不能將s中的兩個字符映射到t中同一個字符,但字符可以映射到自身。試判定給定的字符串s和t是否同構。 例如: s = “add” t = “apple” 輸出 False s = “paper” t = “title”
輸出
True 【參考答案】

print(len(set(s)) == len(set(t)) == len(set(zip(s, t))))

1
2
題10:使用Lambda表達式實現將IPv4的地址轉換為int型整數。
難度:*****
例如:ip2int(“192.168.3.5”) 輸出:
3232236293

【參考答案】


ip2int = lambda x:sum([256**j*int(i) for j,i in enumerate(x.split('.')[::-1])]) 
1
2
題11:羅馬數字使用字母表示特定的數字,試編寫函數romanToInt(),輸入羅馬數字字符
串,輸出對應的阿拉伯數字。
難度:*****

【參考答案】
羅馬數字中字母與阿拉伯數字的對應關系如下:
M:1000,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL: 40,X:10,IX:9,V:5,VI:4,I:1

   def romanToInt(s): 
    table = {'M':1000, 'CM':900, 'D':500, 'CD':400, 'C':100, 'XC':90, 'L':50, 'XL': 40, 'X':10, 'IX':9, 'V':5, 'VI':4, 'I':1}     result = 0 
    for i in range(len(s)): 
        if i > 0 and table[s[i]] > table[s[i-1]]:             result += table[s[i]]             result -= 2 * table[s[i-1]]         else: 
            result += table[s[i]]     return result 
1
2
3
4
5
題12:判斷括號是否成對。
難度:*****
給定一個只包含字符“(”“)”“{”“}”“[”和“]”的字符串,試編寫函數isParenthesesValid(),輸入該字符串,確定輸入的字符串是否有效。括號必須以正確的順序關閉,例如“()”和“()[]{}”都是有效的,但“(]”和“([]]”不是。
【參考答案】

 def isParenthesesValid(s):     pars = [None] 
    parmap = {')': '(', '}': '{', ']': '['}     for c in s: 
        if c in parmap: 
            if parmap[c] != pars.pop():                 return False         else: 
            pars.append(c)     return len(pars) == 1 
1
2
3
4
5
題13:編寫函數輸出count-and-say序列的第n項。
難度:*****
count-and-say序列是一個整數序列,其前五個元素如下: 1 11 21

            1211 111221 
1
1讀作“1”或11。11讀作“兩個1”或21。21讀作“一個2,然後一個1”或1211。即下一項是將上一項“讀出來”再寫成數字。
試編寫函數CountAndSay(n),輸出count-and-say序列的第n項。 【參考答案】


                def CountAndSay(n):     ans = "1"     n -= 1     while n > 0:         res = ""         pre = ans[0]         count = 1 
        for i in range(1, len(ans)):             if pre == ans[i]:                 count += 1             else: 
                res += str(count) + pre                 pre = ans[i]                 count = 1         res += str(count) + pre         ans = res 

         
                        n -= 1     return ans 
1
2
3
4
5
6
7
題14:不使用sqrt

            函數,試編寫squareRoot()函數,輸入一個正數,輸出它的平方根的整
1
數部分
難度:***** 【參考答案】

  def squareRoot(x):     result = 1.0 
                    while abs(result * result - x) > 0.1:         result = (result + x / result) / 2 
                    return int(result) 
1
2
3
三、 正則表達式(4題)
題15:請寫出匹配中國大陸手機號且結尾不是4和7的正則表達式。
難度:***** 【參考答案】

            import re 
1
tels = [“159********”, “14456781234”, “12345678987”, “11444777”] for tel in tels:
print(“Valid”) if (re.match(r"1\d{9}[0-3,5-6,8-9]", tel) != None) else print(“Invalid”)
題16:請寫出以下代碼的運行結果。
難度:*****

 import re 

  str = '<div class="nam">中國</div>' 
res = re.findall(r'<div class=".*">(.*?)</div>',str) print(res) 
1
2
3
4
            結果如下: 【參考答案】 
1
['中國 ']
題17:請寫出以下代碼的運行結果。
難度:*****

import re 

                match = re.compile('www\....?').match("www.baidu.com") if match: 
    print(match.group()) else:                                
                    print("NO MATCH") 
1
2
3
4
5
【參考答案】
www.bai
題18:請寫出以下代碼的運行結果。
難度:*****

 import re  
example = "<div>test1</div><div>test2</div>" Result = re.compile("<div>.*").search(example) 
      
                print("Result = %s" % Result.group()) 
1
2
3
4
【參考答案】
Result =

test1
test2
            四、 列表、字典、元組、數組、矩陣(9題) 
1
題19:使用遞推式將矩陣轉換為一維向量。
難度:***** 使用遞推式將 [[ 1, 2 ], [ 3, 4 ], [ 5, 6 ]]
轉換為

             [1, 2, 3, 4, 5, 6]。 【參考答案】 
            a = [[1, 2], [3, 4], [5, 6]] print([j for i in a for j in i]) 
1
2
題20:寫出以下代碼的運行結果。
難度:*****

def testFun():  

                    temp = [lambda x : i*x for i in range(5)]  
            
                
            
                    return temp 
for everyLambda in testFun():      print (everyLambda(3)) 
1
2
3
4
5
6
7
8
結果如下: 【參考答案】

            12 12 12 12 12 
1
題21:編寫Python程序,打印星號金字塔。
難度:*****
編寫盡量短的Python程序,實現打印星號金字塔。例如n=5時輸出以下金字塔圖形:

                 * 
        
            
        
                ***    *****   *******  ********* 
1
2
3
4
5
參考代碼如下: 【參考答案】

                n = 5 
for i in range(1,n+1): 
    print(' '*(n-(i-1))+'*'*(2*i-1)) 
1
2
3
題22:獲取數組的支配點。
難度:*****
支配數是指數組中某個元素出現的次數大於數組元素總數的一半時就成為支配數,其所在下標稱為支配點。編寫Python

            函數FindPivot(li),輸入數組,輸出其中的支配點和支配數,若數組中不存在支配數,輸出None。 
1
例如:[3,3,1,2,2,1,2,2,4,2,2,1,2,3,2,2,2,2,2,4,1,3,3]中共有23個元素,其中元素2出現了12次,其支配點和支配數組合是(18, 2)。 【參考答案】

  def FindPivot(li):     mid = len(li)/2     for l in li:         count = 0         i = 0         mark = 0         while True:             if l == li[i]:                 count += 1                 temp = i             i += 1 
            if count > mid:                 mark = temp 
                return (mark, li[mark])             if i > len(li) - 1:                 break 
1
2
3
題23:將函數按照執行效率高低排序
難度:*****
有如下三個函數,請將它們按照執行效率高低排序。

  def S1(L_in): 
    l1 = sorted(L_in) 
    l2 = [i for i in l1 if i<0.5]     return [i*i for i in l2]  

            
                
            
                def S2(L_in): 
    l1 = [i for i in L_in if i<0.5]     l2 = sorted(l1) 
    return [i*i for i in l2]  
def S3(L_in): 
    l1 = [i*i for i in L_in]     l2 = sorted(l1) 
    return [i for i in l2 if i<(0.5*0.5)] 
1
2
3
4
5
6
7
8
9
10
11
12
13
【參考答案】
使用cProfile庫即可測試三個函數的執行效率:

import random import cProfile  
L_in = [random.random() for i in range(1000000)] 
                cProfile.run('S1(L_in)') cProfile.run('S2(L_in)') cProfile.run('S3(L_in)') 
1
2
3
從結果可知,執行效率從高到低依次是S2、S1、S3。
題24:螺旋式返回矩陣的元素
難度:*****
給定m×n個元素的矩陣(m行,n列),編寫Python

            函數spiralOrder(matrix),以螺旋順序返回矩陣的所有元素。 
1
例如,給定以下矩陣: [[ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ]]
應該返回[1,2,3,6,9,8,7,4,5]
【參考答案】

   def spiralOrder(matrix): 
    if len(matrix) == 0 or len(matrix[0]) == 0:         return []     ans = [] 
    left, up, down, right = 0, 0, len(matrix) - 1, len(matrix[0]) - 1     while left <= right and up <= down:         for i in range(left, right + 1):             ans += matrix[up][i],         up += 1 
        for i in range(up, down + 1):             ans += matrix[i][right],         right -= 1 
        for i in reversed(range(left, right + 1)):             ans += matrix[down][i],         down -= 1 
        for i in reversed(range(up, down + 1)):             ans += matrix[i][left],         left += 1 
    return ans[:(len(matrix) * len(matrix[0]))] 
1
2
3
4
5
6
7
題25:矩陣重整
難度:*****

            對於一個給定的二維數組表示的矩陣,以及兩個正整數r和c,分別表示所需重新整形矩陣的行數和列數。reshape函數生成一個新的矩陣,並且將原矩陣的所有元素以與原矩陣相同的行遍歷順序填充進去,將該矩陣重新整形為一個不同大小的矩陣但保留其原始數據。對於給定矩陣和參數的reshape操作是可以完成且合法的,則輸出新的矩陣;否則,輸出原始矩陣。請使用Python語言實現reshape函數。 例如: 

        
            
        
            輸入 
1
2
3
4
5
6
r, c 輸出

說明

nums = [[1,2], [3,4]] r = 1,c =
4 [[1,2,3,4]]
行遍歷的是[1,2,3,4]。新的重新形狀矩陣是1 * 4矩陣,使用前面的列表逐行填充。
nums = [[1,2], [3,4]]
r = 2,c =
4
[[1,2], [3,4]]
無法將2 * 2矩陣重新整形為2 * 4矩陣。所以輸出原始矩陣。
注意:給定矩陣的高度和寬度在[1,100]范圍內。給定的r和c都是正數。
【參考答案】

def matrixReshape(nums, r, c):     """ 
    if r * c != len(nums) * len(nums[0]):         return nums     m = len(nums)     n = len(nums[0]) 
    ans = [[0] * c for _ in range(r)]     for i in range(r * c): 
        ans[i / c][i % c] = nums[i / n][i % n]     return ans 
1
2
3
4
題26:查找矩陣中第k個最小元素。
難度:*****
給定n×n矩陣,其中每行每列元素均按升序排列,試編寫Python函數kthSmallest(matrix, k),找到矩陣中的第k個最小元素。
注意:查找的是排序順序中的第k個最小元素,而不是第k個不同元素。 例如: 矩陣= [[1,5,9], [10,11,13], [12,13,15]] k = 8,應返回13。

            【參考答案】 
1
 import heapq  
def kthSmallest(matrix, k):     visited = {(0, 0)} 
    heap = [(matrix[0][0], (0, 0))] 
                
    while heap: 
        val, (i, j) = heapq.heappop(heap)         k -= 1         if k == 0:             return val 
                    if i + 1 < len(matrix) and (i + 1, j) not in visited: 
   
                            heapq.heappush(heap, (matrix[i + 1][j], (i + 1, j)))             visited.add((i + 1, j)) 
        if j + 1 < len(matrix) and (i, j + 1) not in visited:             heapq.heappush(heap, (matrix[i][j + 1], (i, j + 1)))             visited.add((i, j + 1)) 
1
2
3
4
5
6
7
8
9
10
題27:試編寫函數largestRectangleArea(),求一幅柱狀圖中包含的最大矩形的面積。
難度:***** 例如對於下圖:

輸入:[2,1,5,6,2,3] 輸出:10
【參考答案】

def largestRectangleArea(heights):     stack=[]     i=0     area=0 
    while i<len(heights): 

                        if stack==[] or heights[i]>heights[stack[len(stack)-1]]:  # 遞增直接入棧 
               stack.append(i)         else:  # 不遞增開始彈棧             
                            curr=stack.pop()             if stack == []:                 width = i              else: 
                width = i-stack[len(stack)-1]-1             area=max(area,width*heights[curr])             i-=1         i+=1  
   while stack != []:         curr = stack.pop()         if stack == []:             width = i          else: 
            width = len(heights)-stack[len(stack)-1]-1         area = max(area,width*heights[curr])     return area 
1
2
3
4
5
6
7
8
9
五、 設計模式(3

            題) 
1
題28:使用Python語言實現單例模式。
難度:*****

【參考答案】

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 
1
2
3
題29:使用Python語言實現工廠模式。
難度:*****
編寫適當的Python程序,完成以下功能: 1. 定義基類Person,含有獲取名字,性別的方法。 2. 定義Person類的兩個子類Male和Female,含有打招呼的方法。 3. 定義工廠類,含有getPerson方法,接受兩個輸入參數:名字和性別。 4. 用戶通過調用getPerson方法使用工廠類。
【參考答案】

class Person: 
                    def __init__(self):         self.name = None         self.gender = None  
    def getName(self):         return self.name  
    def getGender(self):         return self.gender  
class Male(Person): 
    def __init__(self, name):         print("Hello Mr." + name)  
                class Female(Person): 
    def __init__(self, name):         print("Hello Miss." + name)  
class Factory: 
    def getPerson(self, name, gender):         if(gender == 'M'):             return Male(name)         if(gender == 'F'):             return Female(name)  
if __name__ == '__main__':     factory = Factory() 
    person = factory.getPerson("Huang", "M") 
1
2
3
4
5
6
7
8
9
10
11
12
題30:使用Python語言實現觀察者模式。
難度:*****
給定一個數字,現有的默認格式化顯示程序以十進制格式顯示此數字。請編寫適當的Python程序,實現支持添加(注冊)更多的格式化程序(如添加一個十六進制格式化程序和一個二進制格式化程序)。每次數值更新時,已注冊的程序就會收到通知,並顯示更新後的值。
【參考答案】

import itertools class Publisher:     def __init__(self):         self.observers = set()  
    def add(self, observer, *observers): 
        for observer in itertools.chain((observer, ), observers):             self.observers.add(observer) 
                            observer.update(self)  
    def remove(self, observer):         try: 
            self.observers.discard(observer)         except ValueError: 
            print('移除 {} 失敗!'.format(observer))  
    def notify(self): 
        [observer.update(self) for observer in self.observers]  
class DefaultFormatter(Publisher):     def __init__(self, name):         Publisher.__init__(self)         self.name = name         self._data = 0  
    def __str__(self): 
        return "{}: '{}' 的值 = {}".format(type(self).__name__, self.name, self._data)  
    @property     def data(self):         return self._data  
    @data.setter 
    def data(self, new_value):         try: 
            self._data = int(new_value)         except ValueError as e:             print('錯誤: {}'.format(e))         else: 
            self.notify()  
class HexFormatter: 
    def update(self, publisher): 
        print("{}: '{}' 的十六進制值 = {}".format(type(self).__name__, publisher.name, hex(publisher.data)))  
class BinaryFormatter: 
    def update(self, publisher): 
        print("{}: '{}' 的二進制值 = {}".format(type(self).__name__, publisher.name, bin(publisher.data)))  
def main(): 
    df = DefaultFormatter('test1')     print(df)                            
    hf = HexFormatter()           
                    df.add(hf)     df.data = 37     print(df)               
    bf = BinaryFormatter()     df.add(bf)     df.data = 23     print(df)  
    df.remove(hf)     df.data = 56     print(df)        
                    df.remove(hf)     df.add(bf)  
    df.data = 'hello'     print(df)  
    df.data = 7.2     print(df)  
if __name__ == '__main__':     main() 
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
31
32
33
六、 樹、二叉樹、圖(5題)
題31:使用Python編寫實現二叉樹前序遍歷的函數preorder(root, res=[])。
難度:***** 【參考答案】

def preorder(root, res=[]):     if not root:         return  
    res.append(root.val)     preorder(root.left,res)     preorder(root.right,res)     return res 
1
2
題32:使用Python實現一個二分查找函數。
難度:*****

【參考答案】

def binary_search(num_list, x):     num_list = sorted(num_list)     left, right = 0, len(num_list) - 1     while left <= right: 
                        mid = (left + right) // 2         if num_list[mid] > x:             right = mid - 1         elif num_list[mid] < x:             left = mid + 1         else: 
            return '待查元素{0}在排序後列表中的下標為:  
                {1}'.format(x, mid)     return '待查找元素%s不存在指定列表中' %x 

            
1
2
3
4
5
6
            33:編寫Python函數maxDepth(),實現獲取二叉樹root最大深度。 
1
難度:***** 【參考答案】

def maxDepth(self, root):         if root == None:             return 0 
        return max(self.maxDepth(root.left),self.maxDepth(root.right))+1 
1
2
題34:輸入兩棵二叉樹Root1、Root2,判斷Root2是否Root1的子結構(子樹)。
難度:***** 【參考答案】

class TreeNode: 
    def __init__(self, x):         self.val = x         self.left = None         self.right = None  
def istree(pRoot1, pRoot2):     if not pRoot2:         return True 
    if not pRoot1 and pRoot2:         return False 
    if pRoot1.val != pRoot2.val:         return False 
    elif pRoot1.val == pRoot2.val: 
        return istree(pRoot1.left, pRoot2.left) and istree(pRoot1.right, pRoot2.right) 
                 
def HasSubtree(pRoot1, pRoot2):     if not pRoot1 or not pRoot2:         return False       
                    if pRoot1.val == pRoot2.val:         return istree(pRoot1, pRoot2)     else: 
        return HasSubtree(pRoot1.left, pRoot2) or HasSubtree(pRoot1.right, pRoot2) 
1
2
3
4
5
6
7
8
9
10
11
題35:判斷數組是否某棵二叉搜索樹後序遍歷的結果。
難度:*****
編寫函數VerifySquenceOfBST(sequence),實現以下功能:輸入一個整數數組,判斷該數組是不是某二叉搜索樹的後序遍歷的結果。如果是則輸出True,否則輸出False。假設輸入數組的任意兩個數字都互不相同。 【參考答案】

def VerifySquenceOfBST(sequence):     if not sequence: 
            
                
            
                        return False     i= 0 
    for i in range(len(sequence)-1): 
            
                
            
                        if sequence[i]>sequence[-1]:             break 
    if i < len(sequence)-2: 
        for j in range(i+1,len(sequence)-1):             if sequence[j]<sequence[-1]:                 return False     left = True     right = True     if i>0: 
        left = VerifySquenceOfBST(sequence[:i])     elif i< len(sequence)-2: 
        right = VerifySquenceOfBST(sequence[i:-1])     return left and right 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
七、 文件操作(3題)
題36:計算test.txt中的大寫字母數。
難度:***** 【參考答案】

import os os.chdir('D:\\') 
with open('test.txt') as test:     count = 0 
    for i in test.read():         if i.isupper():             count+=1 
         print(count) 
1
2
3
4
題37:補全缺失的代碼。
難度:*****
def print_directory_contents(sPath): # 補充該函數的實現代碼
print_directory_contents()函數接受文件夾路徑名稱作為輸入參數,返回其中包含的所有子文件夾和文件的完整路徑。
【參考答案】

 def print_directory_contents(sPath):     import os 
    for sChild in os.listdir(sPath):  
        sChildPath = os.path.join(sPath,sChild)         if os.path.isdir(sChildPath): 
            print_directory_contents(sChildPath)         else: 
            print(sChildPath) 
1
2
3
4
5
題38:設計內存中的文件系統。
難度:*****
使用Python語言設計內存中的文件系統,實現以下命令。
ls:給定字符串格式的路徑。如果是文件路徑,則返回僅包含此文件名稱的列表。如果是目錄路徑,則返回此目錄中的文件和目錄名稱列表。輸出結果(文件和目錄名稱)應按字典順序排列。
mkdir:如果目錄路徑不存在,則應根據路徑創建新目錄。如果路徑中的中間目錄也不存在,則也應該創建它們。此函數具有void返回類型。 注:
可以假設所有文件或目錄路徑都是以/開頭並且不以/結尾的絕對路徑,除了路徑只是“/”。 可以假設所有操作都將傳遞有效參數,用戶不會嘗試檢索文件內容或列出不存在的目錄或文件。 可以假設所有目錄名稱和文件名只包含小寫字母,並且同一目錄中不存在相同的名稱。

【參考答案】

  class FileNode(object):     def __init__(self, name):         self.isFolder = True         self.childs = {}         self.name = name         self.data = ""  
class FileSystem(object):     def __init__(self): 
        self.root = FileNode("/")  
    def ls(self, path): 
        fd = self.lookup(path, False)         if not fd:             return []         if not fd.isFolder:             return [fd.name]         files = [] 
        for file in fd.childs:             files.append(file)         files.sort()         return files  
    def lookup(self, path, isAutoCreate):         path = path.split("/")         p = self.root         for name in path:             if not name:                 continue 
            if name not in p.childs:                 if isAutoCreate: 
                    p.childs[name] = FileNode(name)                 else: 
                    return None             p = p.childs[name]         return p  
    def mkdir(self, path): 
        self.lookup(path, True)       # 測試 
obj = FileSystem() obj.mkdir("/test/path") obj.ls("/test") 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
            八、 網絡編程(4題)
1
題39:請至少說出三條TCP和UDP協議的區別。
難度:*****

【參考答案】
(1) TCP面向連接(如打電話要先撥號建立連接);UDP是無連接的,即發送數據之前不需要建立連
接。
(2) TCP提供可靠的服務。也就是說,通過TCP連接傳送的數據,無差錯,不丟失,不重復,且按序
到達;UDP盡最大努力交付,即不保證可靠交付。
(3) TCP面向字節流,實際上是TCP把數據看成一連串無結構的字節流;UDP是面向報文的,UDP沒
有擁塞控制,因此網絡出現擁塞不會使源主機的發送速率降低(對實時應用很有用,如IP電話,實時視頻會議等)。
(4) 每一條TCP連接只能是點到點的;UDP支持一對一,一對多,多對一和多對多的交互通信。 (5) TCP首部開銷20字節;UDP的首部開銷小,只有8個字節。
(6) TCP的邏輯通信信道是全雙工的可靠信道,UDP則是不可靠信道。
題40:請簡述Cookie和Session的區別。
難度:*****

【參考答案】
(1) Session在服務器端,Cookie在客戶端(浏覽器)。
(2) Session可以存放在文件、數據庫或內存中,默認以文件方式保存。 (3) Session的運行依賴Session ID,而Session ID保存在Cookie中。因此,如果浏覽器禁用了Cookie,
同時Session也會失效。
題41:請簡述向服務器端發送請求時的GET方式與POST方式的區別。
難度:*****

【參考答案】
(1) 在浏覽器回退時GET方式沒有變化,而POST會再次提交請求。 (2) GET請求會被浏覽器主動緩存,而POST不會,除非手動設置。 (3) GET請求只能進行URL編碼,而POST支持多種編碼方式。
(4) GET請求參數會被完整保留在浏覽器歷史記錄裡,而POST中的參數不會被保留。 (5) 對參數的數據類型,GET只接受ASCII字符,而POST沒有限制。
(6) GET比POST更不安全,因為參數直接暴露在URL上,所以不能用來傳遞敏感信息。
(7) GET參數通過URL傳遞且傳送的參數是有長度限制的,POST放在Request body中且長度沒有
限制。
(8) 對於GET方式的請求,浏覽器會把http header和data一並發送出去,服務器響應200(返回數
據);而對於POST,浏覽器先發送header,服務器響應100 continue,浏覽器再發送data,服務器響應200 ok(返回數據)。

題42:使用threading組件編寫支持多線程的Socket服務端。
難度:*****
使用Python語言的threading組件編寫支持多線程的Socket服務端,支持-x和-p參數,分別表示指定最大連接數和監聽端口。

【參考答案】

  import socket 
import threading,getopt,sys,string                  
opts, args = getopt.getopt(sys.argv[1:], "hp:l:",["help","port=","list="])  list=50 port=8001  
for op, value in opts: 
    if op in ("-x","--maxconn"):         list = int(value)     elif op in ("-p","--port"):         port = int(value)  
def Config(client, address):     try: 
        client.settimeout(500)         buf = client.recv(2048)         client.send(buf)     except socket.timeout:         print('time out')     client.close()  
def main(): 
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)     sock.bind(('localhost', port))     sock.listen(list)     while True: 
        client,address = sock.accept() 
        thread = threading.Thread(target=Config, args=(client, address))         thread.start()  
if __name__ == '__main__':     main() 
1
2
3
4
5
6
7
8
9
10
11
12
九、 數據庫編程(6題)
題43:簡述數據庫的第一、第二、第三范式的內容。

難度:*****

【參考答案】
范式是“符合某一種級別的關系模式的集合,表示一個關系內部各屬性之間的聯系的合理化程度”,實際上就是一張數據表的表結構所符合的某種設計標准的級別。
1NF的定義為:符合1NF的關系中的每個屬性都不可再分。1NF是所有關系型數據庫的最基本要求。 2NF在1NF的基礎之上,消除了非主屬性對於碼的部分函數依賴。判斷步驟如下。 第一步:找出數據表中所有的碼。
第二步:根據第一步所得到的碼,找出所有的主屬性。
第三步:數據表中,除去所有的主屬性,剩下的就都是非主屬性了。 第四步:查看是否存在非主屬性對碼的部分函數依賴。
3NF在2NF的基礎之上,消除了非主屬性對於碼的傳遞函數依賴。
題44:根據以下數據表結構和數據,按照要求編寫SQL語句。
難度:*****
數據庫中現有Course、Score、Student和Teacher四張數據表,其中數據分別如下所示。

試編寫SQL語句,查詢平均成績大於80的所有學生的學號、姓名和平均成績。
【參考答案(使用SQLServer)】

select a.s_id, b.s_name, avg(a.s_score) as avg_score from Score a, Student b where a.s_id=b.s_id group by a.s_id, b.s_name having avg(a.s_score)>80 
1
查詢結果如下:


題45:按照44題所給條件,編寫SQL語句查詢沒有學全所有課程的學生信息。
難度:*****
【參考答案(使用SQLServer)】

select b.s_id, b.s_name from Score a, Student b where a.s_id=b.s_id 
  group by b.s_id, b.s_name 
having count(a.c_id)<(select count(c_id) from Course) 
1
2
3
查詢結果如下:


題46:按照44題所給條件,編寫SQL語句查詢所有課程第2

            名和第3名的學生信息及該課
1
程成績。
難度:*****
【參考答案(使用SQLServer)】

  select * from ( 
select a.s_id, b.s_name, b.s_birth, b.s_sex, a.c_id, a.s_score, row_number() over (partition by a.c_id order by a.s_score desc) rno from Score a, Student b where a.s_id=b.s_id 
    ) as a where a.rno in (2, 3) order by c_id, rno 
1
2
3
查詢結果如下:


題47:按照44題所給條件,編寫SQL語句查詢所教課程有2人及以上不及格的教師、課
程、學生信息及該課程成績。
難度:*****

            【參考答案(使用SQLServer)】 
1
  select a.s_id, d.s_name, a.s_score, a.c_id, b.c_name, b.t_id, c.t_name from Score a, Course b, Teacher c, Student d 
where a.c_id=b.c_id and b.t_id=c.t_id and a.s_id=d.s_id and a.s_score<60 and c.t_id in (  SELECT c.t_id   
                 FROM Score a, Course b, Teacher c 
 where a.c_id=b.c_id and b.t_id=c.t_id and a.s_score<60  group by c.t_id  having count(1)>1 

1
2
3
4
5
查詢結果如下:


題48:按照44題所給條件,編寫SQL語句生成每門課程的一分段表(課程ID、課程名
稱、分數、該課程該分數人數、該課程累計人數)。

            難度:*****
1
【參考答案(使用SQLServer)】

select a.c_id, b.c_name, a.s_score, COUNT(1) 人數, 
(select COUNT(1) from Score c where c.c_id=a.c_id and c.s_score>=a.s_score) 累計人數 from Score a, Course b where a.c_id=b.c_id 
group by a.c_id, b.c_name, a.s_score order by a.c_id, b.c_name, a.s_score desc; 
1
2
3
查詢結果如下:


十、 圖形圖像與可視化(2題)

題49:繪制一個二次函數的圖形,並同時畫出使用梯形法求積分時的各個梯形。
難度:*****

             【參考答案】 
1
以𝑓(𝑥)=6𝑥2+7𝑥+13為例,代碼如下:

  def Quadratic_Function(x): 

                    return 6*x**2 + 7*x + 13  
import numpy as np 
import matplotlib.pyplot as plt from ipywidgets import interact  
def plot_ladder(laddernum): 
    x = np.linspace(-5, 5, num=100)     y = Quadratic_Function(x)     plt.plot(x, y)      
    a = np.linspace(-5, 5, num=laddernum)     for i in range(laddernum): 
        plt.plot([a[i], a[i]], [0, Quadratic_Function(a[i])], color="blue")  
    ladders = [] 
                    for i in range(laddernum): 
        ladders.append([a[i], Quadratic_Function(a[i])])      
    npladders = np.array(ladders) 
    plt.plot(npladders[:,0], npladders[:,1])  
interact(plot_ladder, laddernum=(1, 80, 1)) 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
運行結果如下(使用Jupyter Notebook):


題50:將給定數據可視化並給出分析結論
難度:*****
某門店部分顧客的年齡、月收入以及每月平均在本店消費情況如下表所示。


請據此使用Python語言繪制適當的圖形並分析得到結論。 【參考答案】

import matplotlib.pyplot as plt plt.figure(figsize=(10, 5)) # 年齡 
age = [34, 40, 37, 30, 44, 36, 32, 26, 32, 36] # 收入 
income = [7000, 9000, 3380, 3780, 3660, 1600, 3320, 2400, 1500, 2800] # 消費額 
expense = [1230, 1140, 1350, 1390, 1170, 1210, 1330, 1400, 1330, 1330] # 年齡,收入 散點圖 ax1 = plt.subplot(121) ax1.scatter(age, income) 
ax1.set_title('年齡,收入 散點圖', family='kaiti', size=16) # 年齡,消費額 散點圖 ax2 = plt.subplot(122) ax2.scatter(age, expense) 
ax2.set_title('年齡,消費額 散點圖', family='kaiti', size=16) plt.show() 
1
2
3
4
5
6


從圖中可以看到,顧客年齡與消費額幾近負相關,收入與消費額也幾乎負相關,而年齡與收入之間沒有特別明顯的關聯關系。

140.對Flask藍圖(Blueprint)的理解?
藍圖的定義
藍圖 /Blueprint 是Flask應用程序組件化的方法,可以在一個應用內或跨越多個項目共用藍圖。使用藍圖可以極大簡化大型應用的開發難度,也為Flask擴展提供了一種在應用中注冊服務的集中式機制。 藍圖的應用場景:
把一個應用分解為一個藍圖的集合。這對大型應用是理想的。一個項目可以實例化一個應用對象,初始化幾個擴展,並注冊一集合的藍圖。
以URL前綴和/或子域名,在應用上注冊一個藍圖。URL前綴/子域名中的參數即成為這個藍圖下的所有視圖函數的共同的視圖參數(默認情況下) 在一個應用中用不同的URL規則多次注冊一個藍圖。
通過藍圖提供模板過濾器、靜態文件、模板和其他功能。一個藍圖不一定要實現應用或視圖函數。
初始化一個Flask擴展時,在這些情況中注冊一個藍圖。 藍圖的缺點:
不能在應用創建後撤銷注冊一個藍圖而不銷毀整個應用對象。 使用藍圖的三個步驟 1.創建一個藍圖對象
blue = Blueprint(“blue”,name)
2.在這個藍圖對象上進行操作,例如注冊路由、指定靜態文件夾、注冊模板過濾器…
@blue.route(‘/’) def blue_index():
return “Welcome to my blueprint”
3.在應用對象上注冊這個藍圖對象

            app.register_blueprint(blue,url_prefix="/blue") 
1
141.Flask 和 Django 路由映射的區別?

            在django中,路由是浏覽器訪問服務器時,先訪問的項目中的url,再由項目中的url找到應用中url,這些url是放在一個列表裡,遵從從前往後匹配的規則。在flask中,路由是通過裝飾器給每個視圖函數提供的,而且根據請求方式的不同可以一個url用於不同的作用。 
1
Django
142.什麼是wsgi,uwsgi,uWSGI?
WSGI:
web服務器網關接口,是一套協議。用於接收用戶請求並將請求進行初次封裝,然後將請求交給web框架。
實現wsgi協議的模塊:wsgiref,本質上就是編寫一socket服務端,用於接收用戶請求(django)
werkzeug,本質上就是編寫一個socket服務端,用於接收用戶請求(flask) uwsgi:
與WSGI一樣是一種通信協議,它是uWSGI服務器的獨占協議,用於定義傳輸信息的類型。 uWSGI:
是一個web服務器,實現了WSGI的協議,uWSGI協議,http協議
143.Django、Flask、Tornado的對比?
1、 Django走的大而全的方向,開發效率高。它的MTV框架,自帶的
ORM,admin後台管理,自帶的sqlite數據庫和開發測試用的服務器,給開發者提高了超高的開發效率。 重量級web框架,功能齊全,提供一站式解決的思路,能讓開發者不用在選擇上花費大量時間。
自帶ORM和模板引擎,支持jinja等非官方模板引擎。
自帶ORM使Django和關系型數據庫耦合度高,如果要使用非關系型數據庫,需要使用第三方庫 自帶數據庫管理app 成熟,穩定,開發效率高,相對於Flask,Django的整體封閉性比較好,適合做企業級網站的開發。python web框架的先驅,第三方庫豐富
2、 Flask 是輕量級的框架,自由,靈活,可擴展性強,核心基於Werkzeug WSGI工具 和jinja2 模板引擎
適用於做小網站以及web服務的API,開發大型網站無壓力,但架構需要自己設計
與關系型數據庫的結合不弱於Django,而與非關系型數據庫的結合遠遠優於Django
3、 Tornado走的是少而精的方向,性能優越,它最出名的異步非阻塞的設計方式
Tornado的兩大核心模塊:
iostraem:對非阻塞的socket進行簡單的封裝 ioloop: 對I/O 多路復用的封裝,它實現一個單例
144.CORS 和 CSRF的區別?
什麼是CORS?
CORS是一個W3C標准,全稱是“跨域資源共享"(Cross-origin resoure sharing). 它允許浏覽器向跨源服務器,發出XMLHttpRequest請求,從而客服了AJAX只能同源使用的限制。 什麼是CSRF?
CSRF主流防御方式是在後端生成表單的時候生成一串隨機token,內置到表單裡成為一個字段,同時,將此串token置入session中。每次表單提交到後端時都會檢查這兩個值是否一致,以此來判斷此次表單提交是否是可信的,提交過一次之後,如果這個頁面沒有生成CSRF token,那麼token將會被清空,如果有新的需求,那麼token會被更新。 攻擊者可以偽造POST表單提交,但是他沒有後端生成的內置於表單的token,session中沒有token都無濟於事。
145.Session,Cookie,JWT的理解
為什麼要使用會話管理
眾所周知,HTTP協議是一個無狀態的協議,也就是說每個請求都是一個獨立的請求,請求與請求之間並無關系。但在實際的應用場景,這種方式並不能滿足我們的需求。舉個大家都喜歡用的例子,把商品加入購物車,單獨考慮這個請求,服務端並不知道這個商品是誰的,應該加入誰的購物車?因此這個請求的上下文環境實際上應該包含用戶的相關信息,在每次用戶發出請求時把這一 小部分額外信息,也做為請求的一部分,這樣服務端就可以根據上下文中的信息,針對具體的用戶進行操作。所以這幾種技術的出現都是對HTTP協議的一個補充,使得我們可以用HTTP協議+狀態管理構建一個的面向用戶的WEB應用。
Session 和Cookie的區別
這裡我想先談談session與cookies,因為這兩個技術是做為開發最為常見的。那麼session與cookies的區別是什麼?個人認為session與cookies最核心區別在於額外信息由誰來維護。利用cookies來實現會話管理時,用戶的相關信息或者其他我們想要保持在每個請求中的信息,都是放在cookies中,而
cookies是由客戶端來保存,每當客戶端發出新請求時,就會稍帶上cookies,服務端會根據其中的信息進行操作。 當利用session來進行會話管理時,客戶端實際上只存了一個由服務端發送的session_id,而由這個session_id,可以在服務端還原出所需要的所有狀態信息,從這裡可以看出這部分信息是由服務端來維護的。
除此以外,session與cookies都有一些自己的缺點: cookies的安全性不好,攻擊者可以通過獲取本地cookies進行欺騙或者利用cookies進行CSRF攻擊。使用cookies時,在多個域名下,會存在跨域問題。 session 在一定的時間裡,需要存放在服務端,因此當擁有大量用戶時,也會大幅度降低服務端的性能,當有多台機器時,如何共享session也會是一個問題.(redis集群)也就是說,用戶第一個訪問的時候是服務器A,而第二個請求被轉發給了服務器B,那服務器B如何得知其狀態。實際上,session與cookies是有聯系的,比如我們可以把session_id存放在cookies中的。 JWT是如何工作的
首先用戶發出登錄請求,服務端根據用戶的登錄請求進行匹配,如果匹配成功,將相關的信息放入payload中,利用算法,加上服務端的密鑰生成
token,這裡需要注意的是secret_key很重要,如果這個洩露的話,客戶端就可以隨機篡改發送的額外信息,它是信息完整性的保證。生成token後服務端將其返回給客戶端,客戶端可以在下次請求時,將token一起交給服務端,一般是說我們可以將其放在Authorization首部中,這樣也就可以避免跨域問題。
146.簡述Django請求生命周期
一般是用戶通過浏覽器向我們的服務器發起一個請求(request),這個請求會去訪問視圖函數,如果不涉及到數據調用,那麼這個時候視圖函數返回一個模板也就是一個網頁給用戶) 視圖函數調用模型毛模型去數據庫查找數據,然後逐級返回,視圖函數把返回的數據填充到模板中空格中,最後返回網頁給用戶。 1.wsgi ,請求封裝後交給web框架(Flask,Django)
2.中間件,對請求進行校驗或在請求對象中添加其他相關數據,例如:csrf,request.session
3.路由匹配 根據浏覽器發送的不同url去匹配不同的視圖函數 4.視圖函數,在視圖函數中進行業務邏輯的處理,可能涉及到:orm,templates
5.中間件,對響應的數據進行處理 6.wsgi,將響應的內容發送給浏覽器
147.用的restframework完成api發送時間時區
當前的問題是用django的rest framework模塊做一個get請求的發送時間以及時區信息的api

class getCurrenttime(APIView):    def get(self,request): 
       local_time = time.localtime() 
       time_zone =settings.TIME_ZONE 
       temp = {'localtime':local_time,'timezone':time_zone}        return Response(temp) 
1
2
3
4
148.nginx,tomcat,apach到都是什麼?
Nginx(engine x)是一個高性能的HTTP和反向代理服務器,也是 一個IMAP/POP3/SMTP服務器,工作在OSI七層,負載的實現方式:輪詢,
IP_HASH,fair,session_sticky. Apache HTTP Server是一個模塊化的服務器,源於NCSAhttpd服務器 Tomcat 服務器是一個免費的開放源代碼的Web應用服務器,屬於輕量級應用服務器,是開發和調試JSP程序的首選。
149.請給出你熟悉關系數據庫范式有哪些,有什麼作用?
在進行數據庫的設計時,所遵循的一些規范,只要按照設計規范進行設計,就能設計出沒有數據冗余和數據維護異常的數據庫結構。
數據庫的設計的規范有很多,通常來說我們在設是數據庫時只要達到其中一些規范就可以了,這些規范又稱之為數據庫的三范式,一共有三條,也存在著其他范式,我們只要做到滿足前三個范式的要求,就能設陳出符合我們的數據庫了,我們也不能全部來按照范式的要求來做,還要考慮實際的業務使用情況,所以有時候也需要做一些違反范式的要求。 1.數據庫設計的第一范式(最基本),基本上所有數據庫的范式都是符合第一范式的,符合第一范式的表具有以下幾個特點:
數據庫表中的所有字段都只具有單一屬性,單一屬性的列是由基本的數據類型(整型,浮點型,字符型等)所構成的設計出來的表都是簡單的二比表 2.數據庫設計的第二范式(是在第一范式的基礎上設計的),要求一個表中只具有一個業務主鍵,也就是說符合第二范式的表中不能存在非主鍵列對只對部分主鍵的依賴關系
3.數據庫設計的第三范式,指每一個非主屬性既不部分依賴與也不傳遞依賴於業務主鍵,也就是第二范式的基礎上消除了非主屬性對主鍵的傳遞依賴
150.簡述QQ登陸過程
qq登錄,在我們的項目中分為了三個接口,
第一個接口是請求qq服務器返回一個qq登錄的界面;
第二個接口是通過掃碼或賬號登陸進行驗證,qq服務器返回給浏覽器一個code和state,利用這個code通過本地服務器去向qq服務器獲取
access_token覆返回給本地服務器,憑借access_token再向qq服務器獲取用戶的openid(openid用戶的唯一標識)
第三個接口是判斷用戶是否是第一次qq登錄,如果不是的話直接登錄返回的jwt-token給用戶,對沒有綁定過本網站的用戶,對openid進行加密生成token進行綁定
151.post 和 get的區別?
1.GET是從服務器上獲取數據,POST是向服務器傳送數據
2.在客戶端,GET方式在通過URL提交數據,數據在URL中可以看到,POST方式,數據放置在HTML——HEADER內提交
3.對於GET方式,服務器端用Request.QueryString獲取變量的值,對於POST方式,服務器端用Request.Form獲取提交的數據
152.項目中日志的作用
一、日志相關概念
1.日志是一種可以追蹤某些軟件運行時所發生事件的方法
2.軟件開發人員可以向他們的代碼中調用日志記錄相關的方法來表明發生了某些事情
3.一個事件可以用一個包含可選變量數據的消息來描述
4.此外,事件也有重要性的概念,這個重要性也可以被成為嚴重性級別(level) 二、日志的作用
1.通過log的分析,可以方便用戶了解系統或軟件、應用的運行情況; 2.如果你的應用log足夠豐富,可以分析以往用戶的操作行為、類型喜好,地域分布或其他更多信息;
3.如果一個應用的log同時也分了多個級別,那麼可以很輕易地分析得到該應用的健康狀況,及時發現問題並快速定位、解決問題,補救損失。
4.簡單來講就是我們通過記錄和分析日志可以了解一個系統或軟件程序運行情況是否正常,也可以在應用程序出現故障時快速定位問題。不僅在開發中,在運維中日志也很重要,日志的作用也可以簡單。總結為以下幾點: 1.程序調試
2.了解軟件程序運行情況,是否正常 3,軟件程序運行故障分析與問題定位
4,如果應用的日志信息足夠詳細和豐富,還可以用來做用戶行為分析
153.django中間件的使用?
Django在中間件中預置了六個方法,這六個方法的區別在於不同的階段執行,對輸入或輸出進行干預,方法如下:
1.初始化:無需任何參數,服務器響應第一個請求的時候調用一次,用於確定是否啟用當前中間件
def init(): pass
2.處理請求前:在每個請求上調用,返回None或HttpResponse對象。
def process_request(request): pass
3.處理視圖前:在每個請求上調用,返回None或HttpResponse對象。
def process_view(request,view_func,view_args,view_kwargs): pass
4.處理模板響應前:在每個請求上調用,返回實現了render方法的響應對象。
def process_template_response(request,response): pass
5.處理響應後:所有響應返回浏覽器之前被調用,在每個請求上調用,返回HttpResponse對象。 def process_response(request,response): pass
6.異常處理:當視圖拋出異常時調用,在每個請求上調用,返回一個HttpResponse對象。
def process_exception(request,exception): pass
154.談一下你對uWSGI和nginx的理解?
1.uWSGI是一個Web服務器,它實現了WSGI協議、uwsgi、http等協議。Nginx中HttpUwsgiModule的作用是與uWSGI服務器進行交換。WSGI是一種Web服務器網關接口。它是一個Web服務器(如nginx,uWSGI等服務器)與web應用(如用Flask框架寫的程序)通信的一種規范。 要注意WSGI/uwsgi/uWSGI這三個概念的區分。 WSGI是一種通信協議。
uwsgi是一種線路協議而不是通信協議,在此常用於在uWSGI服務器與其他網絡服務器的數據通信。
uWSGI是實現了uwsgi和WSGI兩種協議的Web服務器。 nginx 是一個開源的高性能的HTTP服務器和反向代理: 1.作為web服務器,它處理靜態文件和索引文件效果非常高
2.它的設計非常注重效率,最大支持5萬個並發連接,但只占用很少的內存空間
3.穩定性高,配置簡潔。
4.強大的反向代理和負載均衡功能,平衡集群中各個服務器的負載壓力應用
155.Python中三大框架各自的應用場景?
django:主要是用來搞快速開發的,他的亮點就是快速開發,節約成本,,如果要實現高並發的話,就要對django進行二次開發,比如把整個笨重的框架給拆掉自己寫socket實現http的通信,底層用純c,c++寫提升效率,ORM框架給干掉,自己編寫封裝與數據庫交互的框架,ORM雖然面向對象來操作數據庫,但是它的效率很低,使用外鍵來聯系表與表之間的查詢; flask: 輕量級,主要是用來寫接口的一個框架,實現前後端分離,提考開發效率,Flask本身相當於一個內核,其他幾乎所有的功能都要用到擴展(郵件擴展Flask-Mail,用戶認證Flask-Login),都需要用第三方的擴展來實現。比如可以用Flask-extension加入ORM、文件上傳、身份驗證等。Flask沒有默認使用的數據庫,你可以選擇MySQL,也可以用NoSQL。
其WSGI工具箱用Werkzeug(路由模塊),模板引擎則使用Jinja2,這兩個也是Flask框架的核心。
Tornado: Tornado是一種Web服務器軟件的開源版本。Tornado和現在的主流Web服務器框架(包括大多數Python的框架)有著明顯的區別:它是非阻塞式服務器,而且速度相當快。得利於其非阻塞的方式和對epoll的運用,Tornado每秒可以處理數以千計的連接因此Tornado是實時Web服務的一個理想框架
156.Django中哪裡用到了線程?哪裡用到了協程?哪裡用到了進程?
1.Django中耗時的任務用一個進程或者線程來執行,比如發郵件,使用celery. 2.部署django項目是時候,配置文件中設置了進程和協程的相關配置。
157.有用過Django REST framework嗎?
Django REST framework是一個強大而靈活的Web API工具。使用RESTframework的理由有:
Web browsable API對開發者有極大的好處 包括OAuth1a和OAuth2的認證策略 支持ORM和非ORM數據資源的序列化
全程自定義開發–如果不想使用更加強大的功能,可僅僅使用常規的function-based views額外的文檔和強大的社區支持
158.對cookies與session的了解?他們能單獨用嗎?
Session采用的是在服務器端保持狀態的方案,而Cookie采用的是在客戶端保持狀態的方案。但是禁用Cookie就不能得到Session。因為Session是用Session ID來確定當前對話所對應的服務器Session,而Session ID是通過Cookie來傳遞的,禁用Cookie相當於SessionID,也就得不到Session。
爬蟲
159.試列出至少三種目前流行的大型數據庫 160.列舉您使用過的Python網絡爬蟲所用到的網絡數據包?
requests, urllib,urllib2, httplib2
161.爬取數據後使用哪個數據庫存儲數據的,為什麼? 162.你用過的爬蟲框架或者模塊有哪些?優缺點?
Python自帶:urllib,urllib2 第三方:requests 框架: Scrapy
urllib 和urllib2模塊都做與請求URL相關的操作,但他們提供不同的功能。 urllib2: urllib2.urlopen可以接受一個Request對象或者url,(在接受Request對象時,並以此可以來設置一個URL的headers),urllib.urlopen只接收一個url。 urllib 有urlencode,urllib2沒有,因此總是urllib, urllib2常會一起使用的原因 scrapy是封裝起來的框架,他包含了下載器,解析器,日志及異常處理,基於多線程,twisted的方式處理,對於固定單個網站的爬取開發,有優勢,但是對於多網站爬取100個網站,並發及分布式處理不夠靈活,不便調整與擴展 requests是一個HTTP庫,它只是用來請求,它是一個強大的庫,下載,解析全部自己處理,靈活性高
Scrapy優點:異步,xpath,強大的統計和log系統,支持不同url。shell方便獨立調試。寫middleware方便過濾。通過管道存入數據庫 163.寫爬蟲是用多進程好?還是多線程好? 164.常見的反爬蟲和應對方法?
165.解析網頁的解析器使用最多的是哪幾個? 166.需要登錄的網頁,如何解決同時限制ip,cookie,session 167.驗證碼的解決?
168.使用最多的數據庫,對他們的理解? 169.編寫過哪些爬蟲中間件? 170.“極驗”滑動驗證碼如何破解?
171.爬蟲多久爬一次,爬下來的數據是怎麼存儲? 172.cookie過期的處理問題?
173.動態加載又對及時性要求很高怎麼處理? 174.HTTPS有什麼優點和缺點?
175.HTTPS是如何實現安全傳輸數據的? 176.TTL,MSL,RTT各是什麼?
177.談一談你對Selenium和PhantomJS了解
178.平常怎麼使用代理的 ?
179.存放在數據庫(redis、mysql等)。 180.怎麼監控爬蟲的狀態?
181.描述下scrapy框架運行的機制? 182.談談你對Scrapy的理解?
183.怎麼樣讓 scrapy 框架發送一個 post 請求(具體寫出來)
184.怎麼監控爬蟲的狀態 ? 185.怎麼判斷網站是否更新?
186.圖片、視頻爬取怎麼繞過防盜連接
187.你爬出來的數據量大概有多大?大概多長時間爬一次?
188.用什麼數據庫存爬下來的數據?部署是你做的嗎?怎麼部署? 189.增量爬取
190.爬取下來的數據如何去重,說一下scrapy的具體的算法依據。
191.Scrapy的優缺點?
192.怎麼設置爬取深度?
193.scrapy和scrapy-redis有什麼區別?為什麼選擇redis數據庫?
194.分布式爬蟲主要解決什麼問題?
195.什麼是分布式存儲?
196.你所知道的分布式爬蟲方案有哪些?
197.scrapy-redis,有做過其他的分布式爬蟲嗎?
 


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved