一、簡述可迭代對象、迭代器、生成器的關係. 注意列表生成式
可做用於for循環的對象都是可迭代對象。可做用於next()函數並不斷返回下一個值的對象稱迭代器,表示惰性計算序列。
能夠在循環過程當中不斷推算後續元素,這種一邊循環一邊計算的機制,稱爲生成器。(yeild)
生成器是迭代器的一種,可迭代對象不必定是迭代器。
list/dic/str可使用iter()函數變爲迭代器。
二、閉包的概念和做用
閉包:內部函數包含對外部做用域而非全局做用域的引用.
返回的函數對象,不只僅是一個函數對象,在該函數外還包裹了一層做用域,這使得該函數
不管在何處調用,優先使用本身外層包裹的做用域。裝飾器就是閉包的應用
裝飾器的概念和做用
裝飾器(Decorator):在代碼運行期間動態增長功能的方式,稱之爲裝飾器。對修改封閉,對擴展開放
三、Python中兩種序列化json和pickle區別
序列化是把內存的數據類型轉變爲字符串(bytes類型)。
json:用於字符串和Python數據類型之間進行轉換
pickle:用於Python特有類型(僅Python認識)和Python數據類型間進行轉換。
shelve:將內存數據經過文件持久化,支持任何pickle支持的數據格式。
四、簡述什麼是類和對象
對象是特徵與技能的結合體,類則是一系列對象類似的特徵與技能的結合體
五、簡述面向對象的三大特性
繼承:一種建立類的方式,解決代碼重用問題。
多態:一類事物有多種形態,多態性是指在不考慮實例類型的狀況下使用實例
封裝:明確區份內外,控制外部對隱藏屬性的操做行爲,隔離複雜度
組合指的是,在一個類中以另一個類的對象做爲數據屬性,稱爲類的組合
六、簡述什麼是綁定方法和非綁定方法
(1)綁定到對象的方法:在類中定義沒有加裝飾器修飾的方法。
對象.bound_method() 自動將對象當作第一個參數傳入
(2)綁定到類的方法:在類中定義的裝飾器@classmethod修飾的方法。
類.bound_method() 自動將類當第一個參數傳入
(3)非綁定方法:在類中用@staticmethod裝飾器裝飾的方法。
沒有自動傳值,不綁定類和對象,類和對象都可調用。
七、簡述什麼是反射以及實現反射的方法
反射指的是程序能夠訪問、檢測和修改它自己狀態或行爲的一種能力,也叫作自省。
hasattr(obj, name): 判斷obj對象是否有叫name字符串對應的方法或屬性。
getattr(obj, name): 獲取對象中name字符串對應的方法或屬性。
setattr(x,'y',v):給對象賦值x.y=v; delattr(x,'y'):刪除對象屬性del x.y
7.1 什麼事領域模型?
領域模型是對領域內的概念或現實世界中對象的可視化表示,發掘重要的業務領域概念,
創建業務領域概念之間的關係。
八、簡述TCP/IP各層功能
應用層:規定應用程序的數據格式。
傳輸層:創建端口到端口的通訊。
網絡層:引入一套新的地址用來區分不一樣的廣播域/子網,這套地址即網絡地址
數據鏈路層:定義了電信號的分組方式,分組方式後來造成了統一的標準,即以太網協議ethernet
物理層:主要是基於電器特性發送高低電壓(電信號),高電壓對應數字1,低電壓對應數字0
九、簡述什麼是Socket
Socket是應用層與傳輸層TCP/IP協議族通訊的中間軟件抽象層,它是一組接口。把TCP/IP協議藏在接口內,直接去調用socket,即能符合協議要求。
在設計模式中,Socket其實就是一個門面模式,它把複雜的TCP/IP協議族隱藏在Socket接口後面,對用戶來講,一組簡單的接口就是所有,讓Socket去組織數據,以符合指定的協議。
十、編寫一個學生類, 要求有一個計數器的屬性, 統計總共實例化了多少個學生。
class Student:
__count = 0
def __init__(self, name, age):
self.name = name
self.age = age
Student.__count += 1
@staticmethod
def get_count():
print("總共實例化 %s 人" % Student.__count)
stu1 = Student('hqs', 20)
stu2 = Student('egon', 19)
stu1.get_count()
Student.get_count()
十、基於socket和subprocess模塊模擬實現循環執行命令。
########################server####################
import socket, subprocess, struct
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("127.0.0.1", 9001)) # bind()內爲元組,0-65535:0-1024供操做系統使用
server.listen(5)
print('starting...')
while True:
conn, client_addr = server.accept()
print(client_addr)
while True: # 通信循環
try:
"""一、收到客戶端的命令"""
cmd = conn.recv(8096)
if not cmd:break
"""二、執行命令,拿到結果"""
obj = subprocess.Popen(cmd.decode('utf-8'), shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout = obj.stdout.read()
stderr = obj.stderr.read()
"""三、命令結果返回客戶端"""
# 第一步:製做固定長度的報頭
total_size = len(stdout) + len(stderr) # 整型
header = struct.pack('i', total_size) # 隱患:struct的i 的取值區間是-2147483648~2147483648
# 第二步:將報頭髮給客戶端
conn.send(header)
# 第三步:發送真實數據
conn.send(stdout)
conn.send(stderr)
except ConnectionResetError:
break
conn.close()
server.close()
#############################client#####################
import time, socket, struct
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(("127.0.0.1", 9001))
while True:
"""一、發命令"""
cmd = input('>>: ').strip()
if not cmd:continue
client.send(cmd.encode('utf-8'))
"""二、拿結果"""
# 第一步:拿到數據的長度——>即先收報頭
header = client.recv(4)
# 第二步:從報頭中解析出對真實數據的描述信息(數據長度)
total_size = struct.unpack('i', header)[0] # 解包以後爲元組,取第一項即打包的內容
# 第三步:接收真實的數據
recv_size = 0
recv_data = b''
while recv_size < total_size:
res = client.recv(1024) # 最大不能超過操做系統緩存大小,一次收不完,屢次收
recv_data += res
recv_size += len(res) # 最後一次收的時候將不是1024,將來若是要查看進度的時候有問題
print(recv_data.decode('utf-8'))
client.close()shell