python階段題目

Uzizi發表於2018-05-15

一、簡答題

1、簡述TCP和UDP的區別以及優缺點

區別:
UDP是面向無連線的通訊協議,UDP資料包括目的埠號和源埠號資訊。
TCP是面向連線的通訊協議,通過三次握手建立連線,通訊完成時四次揮手。

TCP優缺點:
優點:在資料傳遞時,有確認、視窗、重傳、擁塞控制機制,能保證資料正確性,較為可靠。
缺點:TCP相對於UDP速度慢一點、要求系統資源較多。

UDP優缺點:
優點:UDP速度快、操作簡單、需要求系統資源較少,由於通訊不需要連線,可以實現廣播傳送
缺點:傳送資料前並不與對方建立連線,對接收到的資料也不傳送確認訊號,傳送端不知道資料是否會正確接收,也不用重發,不可靠。

2、函式裝飾器有什麼作用請列舉出至少三個並舉出一些例項

裝飾器的作用:
裝飾器本質上是一個python函式,它可以在讓其他函式在不需要做任何程式碼的變動的前提下增加額外的功能,

裝飾器的返回值也是一個函式的物件,它經常用於有切面需求的場景,

比如:插入日誌、效能測試、事務處理、快取、許可權的校檢等場景。

有了裝飾器就可以抽離出大量的與函式功能本身無關的的雷同的程式碼併發並繼續使用。

裝飾器的例項:
無引數的函式

1. from time import ctime, sleep
2. 
3. def timefun(func):
4.     def wrapped_func():
5.         print("%s called at %s" % (func.__name__, ctime()))
6.         func()
7.     return wrapped_func
8.
9. @timefun
10.def foo():
11.    print("I am foo")
12.    
13.foo()
14.sleep(2)
15.foo()

3、簡答瀏覽器通過WSGI請求動態資源的過程


1. http請求動態資源
2. 通過wsgi呼叫一個屬性
3. 通過引用呼叫web伺服器的方法,設定返回的狀態和頭資訊
4. 呼叫返回,此時web伺服器端儲存了剛剛設定的資訊
5. 查詢資料庫等,生成動態頁面的body資訊
6. 把生成的body資訊返回給web伺服器的呼叫
7. web伺服器把資料返回給瀏覽器

4、描述用瀏覽器器訪問www.baidu.com的過程

  • baidu.com ip先要解析出對應的地址

    1. 要先使用arp獲取預設閘道器的mac地址
    2. 組織資料傳送給預設閘道器(ip還是dns伺服器的ip,但是mac地址是預設閘道器的mac地址)
    3. 預設閘道器擁有轉發資料的能力,把資料轉發給路由器
    4. 路由器根據自己的路由協議,來選擇一個合適的較快的路徑轉發資料給目的閘道器
    5. 目的閘道器(dns伺服器所在的閘道器),把資料轉發給dns伺服器
    6. dns伺服器查詢解析出baidu.com對應的ip地址,並原路返回請求這個域名的
  • 得到了baidu.com對應的ip地址之後,會傳送tcp的3次握手,進行連線

    1. http使用協議傳送請求資料個web伺服器
    2. web伺服器收到資料請求之後,通過查詢自己的伺服器得到相應的結果,原路返回給瀏覽器
    3. 瀏覽器接收到資料之後通過瀏覽器自己的渲染功能來顯示這個網頁
    4. 瀏覽器關閉tcp連線,即4次揮手結束,完成整個訪問過程。

二、程式碼題

1、匹配下列文字y中的每個的郵箱

y=’123@qq.comaaa@163.combbb@126.comasdfasfs33333@adfcom’

1. import re
2.
3. match_obj = re.findall(r"[a-zA-Z0-9]+@[a-zA-Z0-9]+\.com",y)
4. for i in match_obj:
5.   print(i)

2、編寫一個TCP伺服器把客戶端傳送的資訊返回給改客戶端

1. import socket
2.
3. if __name__ == '__main__':
4.  server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
5.  server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
6.  server_socket.bind(("", 8888))
7.  server_socket.listen(128)
8.  client_socket, ip_port = server_socket.accept()
9.  recv_data = client_socket.recv(1024)
10. print("收到客戶端的資料:", recv_data.decode("gbk"))
11. send_content = recv_data.decode("gbk")
12. client_socket.send(send_content.encode("utf-8"))
13. client_socket.close()
14. server_socket.close()

3、使用裝飾器裝飾一個函式,計算這個函式從開始到結束的執行時間。

提示:可以使用time模組。

1. import time
2.
3. def timing(func):
4.   def inner(*args, **kwavgs):
5.      start = time.time()
6.       func(*args, **kwavgs)
7.       end = time.time() - start
8.      print(end)
9.   return inner
10.
11.@timing
12.def myFunc(*args, **kwargs):
13. for i in range(100000):
14.     pass
15.
16.if  __name__ == "__main__":
17.     myfunc()

4、以下程式碼為TCP 併發伺服器的部分,請在分別修改run_forever 函式 使滿足以下要求

提示:選擇性寫出其中三個即可滿分

(1) 多執行緒實現的併發伺服器

(2) 多程式實現的併發伺服器

(3) 協程實現的併發伺服器

(4) 非阻塞、單執行緒-多路複用併發伺服器

1. import socket
2. import threading
3. import multiprocessing
4. import gevent
5. from gevent import monkey
6. monkey.patch_all()
7.
8.
9. class WSGIServer(object):
10. def __init__(self, port):
11.     self.tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
12.     self.tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
13.     self.tcp_server_socket.bind(("", 9988))
14.     self.tcp_server_socket.listen(128)
15.
16. def run_forever(self):
17.     while True:
18.         client_socket, client_addr = self.tcp_server_socket.accept()
19.         print("---一個新的客戶端到來--->", client_addr)
20.         # self.server_client(client_socket)
21.         # 執行緒版本
22.         threading.Thread(target=self.service_client(), args=(client_socket)).start()
23.         # 程式版本
24.         multiprocessing.Process(target=self.service_client(),args=(client_socket)).start()
25.         # 協程版本
26.         gevent.spawn(self.service_client, client_socket)
27.
28. def service_client(self, client_socket):# 這個函式是處理資料的函式
29.     pass
30.
31.
32.def main():
33. """建立一個WSGI伺服器"""
34. wsgi_server = WSGIServer(9988)
35. wsgi_server.run_forever()
36.
37.
38.
39.if __name__ == '__main__':
40. main()

三、三次握手與四次揮手

1、三次握手

  • 第一次握手:建立連線時,客戶端傳送syn包(syn=j)到伺服器,並進入SYN_SENT狀態,等待伺服器確認;SYN:同步序列編號(Synchronize Sequence Numbers)。

  • 第二次握手:伺服器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也傳送一個SYN包(syn=k),即SYN+ACK包,此時伺服器進入SYN_RECV狀態;

  • 第三次握手:客戶端收到伺服器的SYN+ACK包,向伺服器傳送確認包ACK(ack=k+1),此包傳送完畢,客戶端和伺服器進入ESTABLISHED(TCP連線成功)狀態,完成三次握手。

2、四次揮手

  • 第一步,當主機A的應用程式通知TCP資料已經傳送完畢時,TCP向主機B傳送一個帶有FIN附加標記的報文段(FIN表示英文finish)。

  • 第二步,主機B收到這個FIN報文段之後,並不立即用FIN報文段回覆主機A,而是先向主機A傳送一個確認序號ACK,同時通知自己相應的應用程式:對方要求關閉連線(先傳送ACK的目的是為了防止在這段時間內,對方重傳FIN報文段)。

  • 第三步,主機B的應用程式告訴TCP:我要徹底的關閉連線,TCP向主機A送一個FIN報文段。

  • 第四步,主機A收到這個FIN報文段後,向主機B傳送一個ACK表示連線徹底釋放。

相關文章