python部分 + 数据库 + 网络编程
生活随笔
收集整理的這篇文章主要介紹了
python部分 + 数据库 + 网络编程
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
PS:附上我的博客地址,答案中略的部分我的博客都有,直接原標題搜索即可。
https://www.cnblogs.com/Roc-Atlantis/
第一部分 Python基礎篇(80題)
為什么學習Python?
Omit
通過什么途徑學習的Python?
Omit
Python和Java、PHP、C、C#、C++等其他語言的對比?
Omit
簡述解釋型和編譯型編程語言?
編譯型語言:在運行程序之前將源代碼翻譯成目標代碼(機器語言),
運行時不需要重新翻譯,直接使用翻譯的結果,程序執行效率高,依賴編譯器運行(比如vs),
跨平臺性差。比如c,c++等。
解釋型語言:源代碼一邊翻譯成機器語言一遍執行,效率較低,
但是靈活性較高,依賴解釋器運行(比如py),修改方便,跨平臺性好。如python,java,PHP等。
Python解釋器種類以及特點?
cpython pypy jpython
位和字節的關系?
一個字節占8個bit位
b、B、KB、MB、GB 的關系?
1024關系 自行梳理
請至少列舉5個 PEP8 規范(越多越好)。
我的博客直接搜索PEP8規范
通過代碼實現如下轉換:
# 二進制轉換成十進制:v = “0b1111011”?
# int("1111011",2) # 123
# 十進制轉換成二進制:v = 18?
# print(bin(18))
# 八進制轉換成十進制:v = “011”?
# int("011",8) # 9
# 十進制轉換成八進制:v = 30?
# print(oct(30))
# 十六進制轉換成十進制:v = “0x12”?
# int("12",16) # 18
# 十進制轉換成十六進制:v = 87
# print(hex(87))
請編寫一個函數實現將IP地址轉換成一個整數。
如 10.3.9.12 轉換規則為:
10 00001010
? 3 00000011?
9 00001001
? 12 00001100?
再將以上二進制拼接起來計算十進制結果:00001010 00000011 00001001 00001100 = ?
def ip_to_int(s):
L = '0b'+''.join([bin(int(i)) for i in s.split('.')]).replace('0b','')
print(int(L,2))
if __name__ == '__main__':
s = "10.3.9.12"
ip_to_int(s)
python遞歸的最大層數?
import sys
print(sys.getrecursionlimit())
默認最大是1000層
求結果:
v1 = 1 or 3?
v2 = 1 and 3?
v3 = 0 and 2 and 1
? v4 = 0 and 2 or 1
? v5 = 0 and 2 or 1 or 4
? v6 = 0 or Flase and 1
# 1
# 3
# 0
# 1
# 1
# False
ascii、unicode、utf-8、gbk 區別?
ascii:不能表示中文,英文用一個字節表示
unicode:中文和英文都用2個字節表示
utf-8:英文用一個自己表示,中文用3個
gbk:英文用1個字節表示,中文用2個字節表示
字節碼和機器碼的區別?
機器碼是電腦CPU直接讀取運行的機器指令,運行速度最快,
但是非常晦澀難懂,也比較難編寫,一般從業人員接觸不到。
字節碼是一種中間狀態(中間碼)的二進制代碼(文件)。需要直譯器轉譯后才能成為機器碼。
三元運算規則以及應用場景?
應用場景:簡單的if else語句
a = 3 if x>10 else 12 如果if條件成立就輸出前面的結果,如果不成立就輸出后面的結果
列舉 Python2和Python3的區別?
python2默認ascii,python3默認utf-8
博客搜索python2和python3的區別
用一行代碼實現數值交換:
? a = 1
? b = 2
a = 1
b = 2
# a,b = 2,1
# print(a,b)
# c = a
# a = b
# b = c
# print(a,b)
# a,b = (2,1)
# print(a,b)
Python3和Python2中 int 和 long的區別?
python2中需要自己根據數值大小去判斷該用int還是long
python3中取消了long類型數據,會自動判斷
xrange和range的區別?
xrange(1,5)是python2里的生成器,可作為list對象得到一個列表
在python3,xrange相當于改了個名字,改成了range,也是一個生成器對象。
文件操作時:xreadlines和readlines的區別?
readlines() 讀取文件所有內容,按行為單位放到一個列表中,返回list類型。
xreadlines()官方解釋 >> Returns a generator to loop over every single line in the file
xreadlines只在python2里有
返回一個生成器,來循環操作文件的每一行。循環使用時和readlines基本一樣,但是直接打印就不同
列舉布爾值為False的常見值?
0,None,"",False
字符串、列表、元組、字典、集合每個常用的5個方法?
字符串:title(),join(),replace(),strip(),split(),eval()
元組:count(),index(),sorted(tuple)
列表:insert(),extend(),append(),pop(),remove(),sort()
字典:get(),items(),values(),keys(),clear(),copy(),pop(),setdefault()
集合:add(),deference(),discard(),remove(),pop(),symmetric_difference(),union(),intersection_update
lambda表達式格式以及應用場景?
lambda 變量名:變量表達式
通常和高階函數連用 map reduce等
pass的作用?
空函數常用
表示直接跳過繼續向下運行
*args和**kwargs作用
*args 表示接受溢出的位置參數,并以元組的形式返回給args
**kwargs 表示接受溢出的關鍵字參數,并以字典的形式返回給kwargs
is和==的區別
is判斷id是否相等
== 判斷值是否相等
為什么有時候值相同但是不同的兩個地址,is判斷卻為True?
因為python有個緩存機制,一定范圍內的整數不會獨自再分配一個內存空間,他們共享一個內存空間.
簡述Python的深淺拷貝以及應用場景?
深拷貝:拷貝后的對象的值不會再隨著被拷貝對象值的改變而改變
淺拷貝:拷貝后的對象得值會隨著被拷貝對象值的改變而改變.
淺拷貝的對象如果有多層可變類型,淺拷貝只拷貝第一層,深拷貝是遞歸拷貝,拷貝到迭代結束.
Python垃圾回收機制?
python每次定義一個變量都會帶一個引用計數,每調用一次變量值,引用計數都會加1.
每次引用被刪除,引用計數減1.當引用計數為0,變量值就會被當成垃圾回收.
Python的可變類型和不可變類型?
可變類型:列表,集合,字典
不可變類型:元組,字符串,整型
求結果:
? v = dict.fromkeys(['k1','k2'],[])? #value的內存空間是公用的,所有的鍵都指向同一個value [].
v[‘k1’].append(666)
? print(v)?
v[‘k1’] = 777
? print(v)
求結果:
{'k1': [666], 'k2': [666]}
{'k1': 777, 'k2': [666]}
列舉常見的內置函數?
map() reduce() abs() filter() len()
filter、map、reduce的作用?
filter:符合條件的元素會篩選留下來
map:作用于每一個可迭代對象的元素
reduce:python3里使用reduce需要調用functools
from functools import reduce
# res = reduce(lambda x,y: (x+y)*2, [1,2,3,4,5])
# print(res)
# ((((((1+2)*2) + 3)*2+4)*2)+5)*2 = 98
一行代碼實現9*9乘法表
"\n".join("\t".join(["%s*%s=%s" % (y, x, x*y) for y in range(1, x + 1)]) for x in range(1, 10))
如何安裝第三方模塊?以及用過哪些第三方模塊?
通常用兩種方法安裝第三方模塊:
一:直接用pip安裝
二:在第三方庫下載安裝包,在cmd命令直接安裝下載好的包
常用的第三方模塊:
requests,turtle,pymysql,gevent,mulitprocessing,threading,bs4
至少列舉8個常用模塊都有那些?
random,time,turtle,requests,math,re,os,pickle,json,logging,sys,subprocess,pymysql,hashlib
re的match和search區別?
re模塊中match(pattern,string[,flags]),檢查string的開頭是否與pattern匹配。
re模塊中research(pattern,string[,flags]),在string搜索pattern的第一個匹配值。
什么是正則的貪婪匹配?
.*從.前面的字符開始匹配,一直到*后面字符是整個字符串最后一個符合條件的才會結束。
補充下非貪婪匹配:.*? 匹配到最近的一個符合條件的字符就會停下來。
求結果:? a. [ i % 2 for i in range(10) ]? b. ( i % 2 for i in range(10) )
a [0,1,0,1,0,1,0,1,0,1]
b 生成器表達式
求結果:? a. 1 or 2? b. 1 and 2? c. 1 < (2==2)? d. 1 < 2 == 2
a 1
b 2
c False
d True
def func(a,b=[]) 這種寫法有什么坑?
會造成重復賦值,形參名不要寫成變量的形式。
如何實現 “1,2,3” 變成 [‘1’,’2’,’3’] ?
a = "1,2,3"
print(a.split(","))
如何實現[‘1’,’2’,’3’]變成[1,2,3] ?
a = ["1","2","3"]
for i in range(len(a)):
a[i] = int(a[i])
print(a)
比較: a = [1,2,3] 和 b = [(1),(2),(3) ] 以及 b = [(1,),(2,),(3,) ] 的區別?
b = [(1),(2),(3) ] 和a = [1,2,3]沒區別,最多寫的形式不一樣
b = [(1,),(2,),(3,)] 這個因為多了個小括號里的逗號,列表里相當于嵌套了元組,
打印出來結果和前面兩個是不一樣的
如何用一行代碼生成[1,4,9,16,25,36,49,64,81,100] ?
[i**2 for i in range(1,11)]
一行代碼實現刪除列表中重復的值 ?
字典key值的唯一性
print(dict.fromkeys(l).keys())
集合去重
print(set([1,2,3,4,1,2])
如何在函數中設置一個全局變量 ?
加入globals 申明下面的變量為全局變量
logging模塊的作用?以及應用場景?(待補充--通常會忘記補充)
日志模塊。
應用場景:需要生成日志在屏幕或者需要日志記錄。
請用代碼簡答實現stack 。(實現堆棧--先進先出和先進后出)
一.用到append(i)和insert(0,i) ==for循環出結果
二.線程queue中的q = queue.Queue()-先進先出和q = queue.LifoQueue() --先進后出
常用字符串格式化哪幾種?
"%s"%i
"{}-{}".format(1,2)
f"" python3新增,不太了解
簡述 生成器、迭代器、可迭代對象 以及應用場景?
可迭代對象:有__iter__方法的都是可迭代對象
迭代器:本身就是由可迭代對象經過__iter__方法轉換成迭代器對象,本身有__iter__和__next__方法。
生成器:生成器本身就是個迭代器,生成器構造有個yield函數,相當于自定義迭代器。
用Python實現一個二分查找的函數。
num = [1,3,4,5,6,8,22,33,55,778,990]
def search(search_number,num):
if len(num) == 0:return
mid = len(num) // 2
mid_nums = num[len(num)//2]
if search_number > mid_nums:
num = num[mid + 1:]
search(search_number,num)
elif search_number < mid_nums:
num = num[:mid]
search(search_number, num)
else:
print("find it")
search(363,num)
談談你對閉包的理解?
閉包就是調用函數會得到一個返回值,返回值是函數的內存地址。加括號即可調用。
閉指的是該函數是一個內部函數
包指的是該函數對外部作用域(非全局作用域)名字的引用。
os和sys模塊的作用?
os:這個模塊提供了一種方便的使用操作系統函數的方法。
sys:這個模塊可供訪問由解釋器使用或維護的變量和與解釋器進行交互的函數。
總結:os模塊負責程序與操作系統的交互,提供了訪問操作系統底層的接口;sys模塊負責程序
與python解釋器的交互,提供了一系列的函數和變量,用于操控python的運行時環境。
如何生成一個隨機數?
調用random模塊
random.randint(1,3)
random.randrange(1,3)
random.random()
如何使用python刪除一個文件?
import os
os.remove(文件路徑)
談談你對面向對象的理解?
核心是對象。對象是特征與技能的結合體,類就是一系列對象相似的特征與技能的結合體。
面向對象編程
Python面向對象中的繼承有什么特點?
繼承:子類會遺傳父類的屬性 繼承是類與類之間的關系
繼承的特點:
1、在繼承中基類的構造(__init__()方法)不會被自動調用,
它需要在其派生類的構造中親自專門調用。有別于C#
2、在調用基類的方法時,需要加上基類的類名前綴,且需要帶上self參數變量。
區別于在類中調用普通函數時并不需要帶上self參數
3、Python總是首先查找對應類型的方法,如果它不能在派生類中找到對應的方法,
它才開始到基類中逐個查找。(先在本類中查找調用的方法,找不到才去基類中找)
面向對象深度優先和廣度優先是什么?
自己理解:深度優先就是在查找方式上遍歷到最后的節點,和遞歸類似,有明確的結束條件。
廣度優先就是不優先查找最后的節點,到最后才去查找。
新式類:廣度查找優先,經典類:深度查找優先
網上:
深度優先:
將一個子節點的所有內容全部遍歷完畢之后再去遍歷其他節點實現的 (遞歸實現)
廣度優先:
廣度優先的算法的實現是通過 分層次的進行遍歷 先遍歷第一層,然后第二層,第三層 (隊列實現)
深度優先遍歷的算法是通過遞歸的方式一只只遍歷某一個節點從而進行的,
而廣度優先遍歷算法則是把上一個層次的所有節點歸入隊列全部遍歷完畢再進行下面的遍歷的
面向對象中super的作用?(具體參考博客)
要理解super的原理,就要先了解mro。mro是method resolution order的縮寫,表示了類繼承體系中的成員
解析順序。在python中,每個類都有一個mro的類方法。
可以看到mro方法返回的是一個祖先類的列表。Leaf的每個祖先都在其中出現一次,
這也是super在父類中查找成員的順序。
通過mro,python巧妙地將多繼承的圖結構,轉變為list的順序結構。super在繼承體系中向上的查找過程,
變成了在mro中向右的線性查找過程,任何類都只會被處理一次。
通過這個方法,python解決了多繼承中的2大難題:
1. 查找順序問題。從Leaf的mro順序可以看出,如果Leaf類通過super來訪問父類成員,
那么Medium1的成員會在Medium2之前被首先訪問到。
如果Medium1和Medium2都沒有找到,最后再到Base中查找。
2. 鉆石繼承的多次初始化問題。在mro的list中,Base類只出現了一次。事實上任何類都只會在mro list中
出現一次。這就確保了super向上調用的過程中,任何祖先類的方法都只會被執行一次。
是否使用過functools中的函數?其作用是什么?
搜索我博客:functools模塊中的函數
列舉面向對象中帶雙下劃線的特殊方法,如:__new__、__init__
__new__
__init__
__str__
__call__
__del__
__iter__
__next__
下面是查看對象屬性的一些方法
__name__
__main__
__doc__
__file__
__metaclass__
__dict__
如何判斷是函數還是方法?
函數:
函數是封裝了一些獨立的功能,可以直接調用,
python內置了許多函數,同時可以自建函數來使用。
方法:
方法和函數類似,同樣封裝了獨立的功能,但是方法是
需要通過對象來調用的,表示針對這個對象要做的操作,使用時采用點方法。
靜態方法和類方法區別?
靜態方法是類和對象都可以調用,調用的時候必須傳入對應的參數
類方法:類調用直接把調用的類當作參數傳入,對象調用類方法還是會自動傳入類。
列舉面向對象中的特殊成員以及應用場景
__new__
__init__
__str__
__call__
__del__
__iter__
__next__
__getitem__ 、 __setitem__ 、__delitem__ 用于索引操作,如字典。分別表示獲取、設置、刪除數據
1、2、3、4、5 能組成多少個互不相同且無重復的三位數
count = 0
for i in range(1,6):
for m in range(1,6):
for n in range(1,6):
if i != m and m != n and i!=n:
print(100*i + 10*m + n)
count+=1
print(count)
什么是反射?以及應用場景?
反射就是通過字符串來操作類和對象的屬性
hasattr(obj,attrib) 判斷對象是否存在這個屬性,存在就返回True
getattr(obj,attrib,None) 判斷屬性對象是否可以訪問,如果可以
就返回數據屬性的值或者函數屬性的內存地址。如果不能,就返會None。
setattr(obj,attrib,屬性值) 修改對象的屬性值,如果沒有該屬性則添加屬性到名稱空間
delattr(obj,attrib) 刪除對象名稱空間里的屬性值,刪除類的屬性值,數據屬性和函數屬性都可以刪除
metaclass(元類)作用?以及應用場景?
元類負責控制類的產生過程。
分為type元類創建類和自定義元類創建類。具體看我博客。
用盡量多的方法實現單例模式。
三種:一:直接在類中通過if判斷來確定__instance是否為None,如果是給他賦值,不是直接返回self.__instance
二.通過在類上加裝飾器的方法實現。裝飾器里的wrapper就是Mysql,調用wrapper相當于通過Mysql往里面傳值
,如果不傳值args和kwargs長度為0,可以以此為關鍵進行判斷。
三.自定義元類中通過傳入參數的長度來判斷是否傳參,沒傳參直接返回self.__instance,傳參則產生新對象
裝飾器的寫法以及應用場景。
單層裝飾器和多層裝飾器
為了節省代碼量,避免代碼冗余,裝飾器出現解決了這些問題。
無參裝飾器外面包著一層,有參裝飾器外面包著兩層。通常寫成語法糖的形式,放在被裝飾的對象上面。
裝飾器是為了不違背開放封閉原則的前提下,為被裝飾對象添加功能。
異常處理寫法以及如何主動拋出異常(應用場景)
異常處理:try..except..else..finally
主動拋出:raise Typeerror("拋出的異常說明")
什么是面向對象的mro
mro是子類查找父類的順序,mro列表里的類不會重復并且只會被查找一次,且按照繼承的順序來。
isinstance作用以及應用場景?
isinstance(obj,class) 判斷對象obj是不是由class生成的對象。
什么是語句,什么是表達式?
寫代碼并實現:
Given an array of integers, return indices of the two numbers such that they add up
to a specific target.You may assume that each input would
have exactly one solution, and you may not use the same element twice.
給定一個整數數組,返回兩個數字的索引,使它們相加
到一個特定的目標。你可以假設每個輸入都會只有一個解決方案,你可能不會使用相同的元素兩次。
Example:?
Given nums = [2, 7, 11, 15], target = 9,
?Because nums[0] + nums[1] = 2 + 7 = 9,?
return [0, 1]
l = [2,7,11,15]
target = 9
for i in l:
for m in l:
if i != m and i+m == target:
print(i,m)
json序列化時,可以處理的數據類型有哪些?如何定制支持datetime類型?
json不可以處理的數據類型:元組,集合,自定義類和類的對象。
datetime類型???
json序列化時,默認遇到中文會轉換成unicode,如果想要保留中文怎么辦?
Str=json.dumps(jsonData,ensure_ascii=False,indent=2)
加上ensure_ascii=False即可。 indent是用來設置排版格式。
什么是斷言?應用場景?
詳情見我博客,自己解釋不清,也不懂assert到底怎么用。
有用過with statement(with 聲明)嗎?它的好處是什么?
>>>with open('text.txt')as my_file:
...whileTrue:
...line=my_file.readline()
...if not line:
...break
...print(line)
#with語句使用所謂的上下文管理器對代碼塊進行包裝,允許上下文管理器實現一些設置和清理操作。
#例如:文件可以作為上下文管理器使用,它們可以關閉自身作為清理的一部分。
#NOTE:在PYTHON2.5中,需要使用from__future__importwith_statement進行with語句的導入
使用代碼實現查看列舉目錄下的所有文件。
import os
for file in os.listdir(r'\address'):
print(file)
簡述 yield和yield from關鍵字。
看我博客 看我博客 。
第二部分 網絡編程和并發(34題)
簡述 OSI 七層協議。
物理層:主要是基于電器特性發送高低電壓(電信號),高電壓對應數字1,低電壓對應數字0
數據鏈路層: 功能:定義了電信號分組的方式 以太網協議
網絡層:網絡層功能:引入一套新的地址用來區分不同的廣播域/子網,這套地址即網絡地址
規定網絡地址的協議叫做ip協議,它定義的地址稱為ip地址
傳輸層:傳輸層功能:建立端口到端口的通信
應用層:必須有不同協議規定電子郵件、網頁、FTP數據的格式,這些應用程序協議就構成了”應用層”。
什么是C/S和B/S架構?
客戶端與服務端通信
瀏覽器客戶端與服務端通信
先從服務器端說起。服務器端先初始化Socket,然后與端口綁定(bind),對端口進行監聽(listen),
調用accept阻塞,等待客戶端連接。在這時如果有個客戶端初始化一個Socket,然后連接服務器(connect),
如果連接成功,這時客戶端與服務器端的連接就建立了。客戶端發送數據請求,服務器
端接收請求并處理請求,然后把回應數據發送給客戶端,客戶端讀取數據,最后關閉連接,一次交互結束。
簡述 三次握手、四次揮手的流程。
第一次握手:
客戶端發送一個TCP的SYN標志位置1的包指明客戶打算連接的服務器的端口,
以及初始序號X,保存在包頭的序列號(Sequence Number)字段里。
第二次握手:
服務器發回確認包(ACK)應答。即SYN標志位和ACK標志位均為1同時,
將確認序號(Acknowledgement Number)設置為客戶的I S N加1以.即X+1。
第三次握手.
客戶端再次發送確認包(ACK) SYN標志位為0,ACK標志位為1.并且把服務器
發來ACK的序號字段+1,放在確定字段中發送給對方.并且在數據段放寫ISN的+1
連接終止協議(四次分手)
由于TCP連接是全雙工的,因此每個方向都必須單獨進行關閉。這原則是當一方完成它的數據
發送任務后就能發送一個FIN來終止這個方向的連接。收到一個 FIN只意味著這一方向上沒有數據流動,
一個TCP連接在收到一個FIN后仍能發送數據。首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉。
(1) TCP客戶端發送一個FIN,用來關閉客戶到服務器的數據傳送(報文段4)。
(2) 服務器收到這個FIN,它發回一個ACK,確認序號為收到的序號加1(報文段5)。
和SYN一樣,一個FIN將占用一個序號。
(3) 服務器關閉客戶端的連接,發送一個FIN給客戶端(報文段6)。
(4) 客戶段發回ACK報文確認,并將確認序號設置為收到序號加1(報文段7)。
什么是arp協議?
ARP協議
ARP 地址解析協議,就是 把 IP->MAC(你聽過ARP欺騙的)
arp協議由來:計算機通信基本靠吼,即廣播的方式,所有上層的包到最后都要封裝上以太網頭,
然后通過以太網協議發送,在談及以太網協議時候,我門了解到
通信是基于mac的廣播方式實現,計算機在發包時,獲取自身的mac是容易的,如何獲取目標主機的mac,
就需要通過arp協議。
一:首先通過ip地址和子網掩碼區分出自己所處的子網
二:分析172.16.10.10/24與172.16.10.11/24處于同一網絡
(如果不是同一網絡,那么下表中目標ip為172.16.10.1,通過arp獲取的是網關的mac)
三:這個包會以廣播的方式在發送端所處的自網內傳輸,所有主機接收后拆開包,
發現目標ip為自己的,就響應,返回自己的mac
最前面的”以太網標頭”,設置發出方(本機)的MAC地址和接收方(DHCP服務器)的MAC地址。
前者就是本機網卡的MAC地址,后者這時不知道,
就填入一個廣播地址:FF-FF-FF-FF-FF-FF
arp協議功能:廣播的方式發送數據包,獲取目標主機的mac地址。
TCP和UDP的區別?
TCP協議每一次傳輸都要發送請求和確認傳輸信號,安全可靠,速度較慢。
UDP協議直接傳輸,不需要經過請求,速度會很快,但容易造成數據包的丟失。
什么是局域網和廣域網?
廣域網:作用范圍大,一般可以從幾十公里至幾萬公里。
一個國家或國際間建立的網絡都是廣域網。在廣域網內,用于通信的傳輸裝置和傳輸介質可由電信部門提供。
局域網(LAN):為了完整地給出LAN的定義,必須使用兩種方式:一種是功能性定義,另一種是技術性定義。
前一種將LAN定義為一組臺式計算機和其它設備,在物理地址上彼此相隔不遠,以允許用戶相互通信
和共享諸如打印機和存儲設備之類的計算資源的方式互連在一起的系統。這種定義適用于辦公環境下
的LAN、工廠和研究機構中使用的LAN。
就LAN的技術性定義而言,它定義為由特定類型的傳輸媒體(如電纜、光纜和無線媒體)和網絡適配器
(亦稱為網卡)互連在一起的計算機,并受網絡操作系統監控的網絡系統。
為何基于tcp協議的通信比基于udp協議的通信更可靠?
tcp協議設立了接受確認和重傳機制。每一次信息傳輸都和三次握手一樣,使得每一個信息都能保證到達,很可靠。
udp是盡力傳送,沒有確認和重傳機制,udp只是將信息發送出去,對方收不收到也不進行應答
什么是socket?簡述基于tcp協議的套接字通信流程。
socket是套接字。
先從服務器端說起。服務器端先初始化Socket,然后與端口綁定(bind),對端口進行監聽(listen),
調用accept阻塞,等待客戶端連接。在這時如果有個客戶端初始化一個Socket,然后連接服務器(connect),
如果連接成功,這時客戶端與服務器端的連接就建立了。客戶端發送數據請求,服務器端接收請求并處理請求,
然后把回應數據發送給客戶端,客戶端讀取數據,最后關閉連接,一次交互結束。
什么是粘包?socket中造成粘包的原因是什么? 哪些情況會發生粘包現象?
產生粘包的原因:第一點:客戶端向服務端發起命令請求,服務端接受命令請求,并返回對應的信息,
如果信息過大,客戶端一次接受不了,那么下一次請求依然返回
上一個命令的內容,就出現了粘包的情況。
第二點:發送端需要等緩沖區滿才發送出去,造成粘包(發送數據時間間隔很短,數據了很小,
會合到一起,產生粘包)
所謂粘包問題主要還是因為接收方不知道消息之間的界限,不知道一次性提取多少字節的數據所造成的。
發送端為了將多個發往接收端的包,更有效的發到對方,使用了優化方法(Nagle算法),將多次間隔較小且數據量
小的數據,合并成一個大的數據塊,然后進行封包。這樣做,雖然節省了時間,但是發出的包卻粘在了一起,
造成粘包現象。
IO多路復用的作用?
IO復用機制可以同時監控多個描述符,當某個描述符就緒(讀或寫就緒),則立即通知相應程序進行讀或寫操作。
但select,poll,epoll本質上都是同步I/O,因為他們都需要在讀寫事件就緒后自己負責進行讀寫,也就是說
這個讀寫過程是阻塞的。
I/O多路復用的優勢并不是對于單個連接能處理的更快,而是在于可以在單個線程/進程中處理更多的連接。
與多進程和多線程技術相比,I/O多路復用技術的最大優勢是系統開銷小,系統不必創建進程/線程,
也不必維護這些進程/線程,從而大大減小了系統的開銷。
什么是防火墻以及作用?
防火墻見我博客
select、poll、epoll 模型的區別?
見我的博客
簡述 進程、線程、協程的區別 以及應用場景?
看我的博客
GIL鎖是什么鬼?
全局解釋器鎖
當程序在運行某段代碼遇到GIL鎖,此時會變成串行,需要一個線程執行完該段代碼下一個執行才可以進去。
Python中如何使用線程池和進程池?
# 進程池
from concurrent.futures import ProcessPoolExecutor
import time,os
def func1(name):
print("%s is %s"%(name,os.getpid())) # 打印了進程id
time.sleep(1)
if __name__ == "__main__":
p = ProcessPoolExecutor(4) # 指定進程池最大進程個數
for i in range(10):
obj = p.submit("omit %s"%i,i) 提交任務
# 線程池
rom concurrent.futures import ThreadPoolExecutor
import time,os,random
def func2(name):
print("%s is %s"%(name,os.getpid())) # 打印了進程id
time.sleep(random.randint(1,3))
if __name__ == "__main__":
p = ThreadPoolExecutor(4) # 指定線程池最大線程個數,不包含控制線程
for i in range(10):
obj = p.submit("omit %s"%i,i) # 提交任務
threading.local的作用?
一旦在主線程實例化了一個local,它會一直活在主線程中,并且又主線程啟動的子線程調用這個local實例時,
它的值將會保存在相應的子線程中。
1.local_data具有全局訪問權,主線程,子線程都能訪問它。
2.但是 local_data的值卻是線程隔離的,值只與各當前線程有關。
ThreadLocal 最常用的地方:
為每個線程綁定一個資源(數據庫連接,HTTP請求,用戶身份信息等),
這樣一個線程的所有調用到的處理函數都可以非常方便地訪問這些資源。
進程之間如何進行通信?
通過管道或者隊列來通信。一般用的隊列,因為隊列是管道加鎖,不用自己再加鎖。
導入multiprocessing模塊中的Queue,生成Queue對象,調用put方法把值放到隊列里,get從隊列里取值,
每取一個值也同時刪除隊列中的該值。
什么是并發和并行?
并發是偽并行,通過遇到IO切換來實現類似并行的效果。
并行多核才能實現,多個進程同時工作。
進程鎖和線程鎖的作用?
線程鎖:大家都不陌生,主要用來給方法、代碼塊加鎖。當某個方法或者代碼塊使用鎖時,那么
在同一時刻至多僅有有一個線程在執行該段代碼。當有多個線程訪問同一對象的加鎖方法/代碼塊時,
同一時間只有一個線程在執行,其余線程必須要等待當前線程執行完之后才能執行該代碼段。但是,
其余線程是可以訪問該對象中的非加鎖代碼塊的。
進程鎖:也是為了控制同一操作系統中多個進程訪問一個共享資源,只是因為程序的獨立性,
各個進程是無法控制其他進程對資源的訪問的,但是可以使用本地系統的信號量控制(操作系統基本知識)。
解釋什么是異步非阻塞?
見我博客
路由器和交換機的區別?
一、工作所在的OSI層次不一樣(根本區別,導致接下來的區別)
交換機工作在 OSI模型的數據鏈路層,所以工作原理比較簡單;
路由器工作在OSI模型的網絡層,具備更多的網絡協議信息,所以可以做出更好的數據轉發策略。
二、數據轉發所依據的對象也不一樣。
交換機工作在數據鏈路層,所以交換機轉發數據依靠的是每個物理地址(MAC地址),MAC地址一般
是設備生產商在設備出廠時固定在設備中的,不能進行更改。
路由器工作在網絡層,所以其交換數據依靠網絡地址(IP地址),而IP地址是由網絡管理員自己分配
或者系統自動獲取的。
三、是否可以分割廣播域
由交換機連接的所有端口仍然屬于同一個廣播域,所以極有可能會產生數據擁堵;
連接到路由器上的所有端口不在屬于同一個廣播域,所以不會產生類似的數據擁堵問題
什么是域名解析?
域名解析是把域名指向網站空間IP,讓人們通過注冊的域名可以方便地訪問到網站一種服務。
域名解析也叫域名指向、服務器設置、域名配置以及反向IP登記等等。說得簡單點就是將好記的域名解析成IP,
服務由DNS服務器完成,是把域名解析到一個IP地址,然后在此IP地址的主機上將一個子目錄與域名綁定。
如果是需要建站,除了注冊域名,還需要向虛擬主機提供商申請空間,如果空間是國內的還需要備份,
國外的空間則不需要。
如何修改本地hosts文件?
1.在菜單欄找到記事本
2.右鍵記事本 >>使用管理員權限打開
3.單擊文件按鈕>>下拉菜單點擊打開文件>>C:\Windows\System32\drivers\etc 這個路徑
4.如果到這步來了找不到hosts文件這是我們點擊文本文檔下拉框選擇 “所有文件”
5.輸入127.0.0.1 或你指向的IP就行了,ctrl + s 就OK
hosts記錄規則非常簡單,只需要將你的記錄以 “IP + 空格 + 域名” 的格式填寫即可。
生產者消費者模型應用場景及優勢?
生產者與消費者模式是通過一個容器來解決生產者與消費者的強耦合關系,生產者與消費者之間不直接進行通訊,
而是利用阻塞隊列來進行通訊,生產者生成數據后直接丟給阻塞隊列,消費者需要數據則從阻塞隊列獲取,實際應
用中,生產者與消費者模式則主要解決生產者與消費者生產與消費的速率不一致的問題,達到平衡生產者與消費者
的處理能力,而阻塞隊列則相當于緩沖區。
# 應用場景
由一個線程生成訂單,并將其放入隊列中.由多個線程去處理
# 優勢
平衡生產者與消費者的處理能力
簡述 gevent模塊的作用和應用場景。
Gevent 是一個第三方庫,可以輕松通過gevent實現并發同步或異步編程,在gevent中用到的主要模式是Greenlet,
它是以C擴展模塊形式接入Python的輕量級協程。 Greenlet全部運行在主程序操作系統進程的內部,但它們被
協作式地調度。
什么是cdn?
CDN的全稱是Content Delivery Network,即內容分發網絡。
其基本思路是盡可能避開互聯網上有可能影響數據傳輸速度和穩定性的瓶頸和環節,使內容傳輸的更快、更穩定。
通過在網絡各處放置節點服務器所構成的在現有的互聯網基礎之上的一層智能虛擬網絡,CDN系統能夠實時地根
據網絡流量和各節點的連接、負載狀況以及到用戶的距離和響應時間等綜合信息將用戶的請求重新導向離用戶最近
的服務節點上。
其目的是使用戶可就近取得所需內容,解決 Internet網絡擁擠的狀況,提高用戶訪問網站的響應速度。
第三部分 數據庫和緩存(46題)
列舉常見的關系型數據庫和非關系型都有那些?
關系型 : MySQL,SQL Server ,Oracle , Sybase, DB2
非關系型 : Redis, MongodDB
MySQL常見數據庫引擎及比較?
ISAM:ISAM是一個定義明確且歷經時間考驗的數據表格管理方法,它在設計之時就考慮到數據庫被查詢的次數
要遠大于更新的次數。因此,ISAM執行讀取操作的速度很快,而且不占用大量的內存和存儲資源。ISAM的兩個
主要不足之處在于,它不支持事務處理,也不能夠容錯:如果你的硬盤崩潰了,那么數據文件就無法恢復了。
如果你正在把ISAM用在關鍵任務應用程序里,那就必須經常備份你所有的實時數據,通過其復制特性,
MYSQL能夠支持這樣的備份應用程序。
MyISAM:MyISAM是MySQL的ISAM擴展格式和缺省的數據庫引擎。除了提供ISAM里所沒有的索引
和字段管理的大量功能,MyISAM還使用一種表格鎖定的機制,來優化多個并發的讀寫操作,
其代價是你需要經常運行OPTIMIZE TABLE命令,來恢復被更新機制所浪費的空間。MyISAM還有一些有用的擴展
,例如用來修復數據庫文件的MyISAMCHK工具和用來恢復浪費空間的 MyISAMPACK工具。MYISAM強調了快速讀取操作
,這可能就是為什么MySQL受到了WEB開發如此青睞的主要原因:在WEB開發中你所進行的大量數據操作都是讀取操作。所以,大多數虛擬主機提供商和INTERNET平臺提供商只允許使用MYISAM格式。MyISAM格式的一個重要缺陷就是不能在表損壞后恢復數據。
InnoDB:InnoDB數據庫引擎都是造就MySQL靈活性的技術的直接產品,這項技術就是MYSQL+API。在使用MYSQL
的時候,你所面對的每一個挑戰幾乎都源于ISAM和MyISAM數據庫引擎不支持事務處理(transaction process)
也不支持外來鍵。盡管要比ISAM和 MyISAM引擎慢很多,但是InnoDB包括了對事務處理和外來鍵的支持,這兩點
都是前兩個引擎所沒有的。如前所述,如果你的設計需要這些特性中的一者或者兩者,那你就要被迫使用后兩個
引擎中的一個了。
MEMORY: MEMORY是MySQL中一類特殊的存儲引擎。它使用存儲在內存中的內容來創建表,而且數據全部放在內存中。
這些特性與前面的兩個很不同。每個基于MEMORY存儲引擎的表實際對應一個磁盤文件。該文件的文件名與表名相同,
類型為frm類型。該文件中只存儲表的結構。而其數據文件,都是存儲在內存中,這樣有利于數據的快速處理,
提高整個表的效率。值得注意的是,服務器需要有足夠的內存來維持MEMORY存儲引擎的表的使用。如果不需要了,
可以釋放內存,甚至刪除不需要的表。MEMORY默認使用哈希索引。速度比使用B型樹索引快。當然如果你想用B型樹
索引,可以在創建索引時指定。注意,MEMORY用到的很少,因為它是把數據存到內存中,如果內存出現異常就會
影響數據。如果重啟或者關機,所有數據都會消失。因此,基于MEMORY的表的生命周期很短,一般是一次性的。
簡述數據三大范式?
1.第一范式:確保每列保持原子性
2.第二范式:確保表中的每列都和主鍵相關
3.第三范式:確保表中每一列都和主鍵列直接相關,而不是間接相關.
什么是事務?MySQL如何支持事務?
事務是邏輯上的一組操作,組成這組操作的各個單元,要不全都成功要不全都失敗,這個特性就是事務
事務可以包含一系列的sql語句,事務的執行具有原子性
1、原子性:
包含多條sql語句要么都執行成功,要么都執行不成功
2、回滾
簡述數據庫設計中一對多和多對多的應用場景?
應用場景:一對多:一個學生可以有多門課程
多對多:一個老師可以有多個學生,一個學生也可以有多個老師
如何基于數據庫實現商城商品計數器?
詳情見我博客
常見SQL(必備)
詳見武沛齊博客:https://www.cnblogs.com/wupeiqi/articles/5729934.html
簡述觸發器、函數、視圖、存儲過程?
觸發器: 在執行某種操作前后一些自定義的操作
函數: 處理參數,返回結果
視圖: 把需要的數據存放在一張臨時表中,簡化查詢
存儲過程: sql語句集,簡化了一些操作.與函數不同,他可以返回一個結果集(查詢結果)
MySQL索引種類
1. 普通索引
這是最基本的索引,它沒有任何限制,比如上文中為title字段創建的索引就是一個普通索引,
MyIASM中默認的BTREE類型的索引,也是我們大多數情況下用到的索引。
2. 唯一索引
與普通索引類似,不同的就是:索引列的值必須唯一,但允許有空值(注意和主鍵不同)。
如果是組合索引,則列值的組合必須唯一,創建方法和普通索引類似。
3. 全文索引(FULLTEXT)
MySQL從3.23.23版開始支持全文索引和全文檢索,FULLTEXT索引僅可用于 MyISAM 表;
他們可以從CHAR、VARCHAR或TEXT列中作為CREATE TABLE語句的一部分被創建,或是隨后
使用ALTER TABLE 或CREATE INDEX被添加。對于較大的數據集,將你的資料輸入一個
沒有FULLTEXT索引的表中,然后創建索引,其速度比把資料輸入現有FULLTEXT索引的速度更為快。
不過切記對于大容量的數據表,生成全文索引是一個非常消耗時間非常消耗硬盤空間的做法。
4. 單列索引、多列索引
多個單列索引與單個多列索引的查詢效果不同,因為執行查詢時,MySQL只能使用一個索引,
會從多個索引中選擇一個限制最為嚴格的索引。
5. 組合索引(最左前綴)
平時用的SQL查詢語句一般都有比較多的限制條件,所以為了進一步榨取MySQL的效率,就要考慮建立組合索引。
索引在什么情況下遵循最左前綴的規則?
聯合索引的情況下遵循最左前綴的規則。
主鍵和外鍵的區別?
主鍵 : 該表中此列唯一,非空
外鍵 : 該列中的值必須是關聯表中關聯的數據
MySQL常見的函數?
詳情見我博客
列舉 創建索引但是無法命中索引的8種情況。
1.如果條件中有or,即使其中有條件帶索引也不會使用(這也是為什么盡量少用or的原因)
注意:要想使用or,又想讓索引生效,只能將or條件中的每個列都加上索引
2.對于多列索引,不是使用的第一部分,則不會使用索引
3.like查詢是以%開頭
4.如果列類型是字符串,那一定要在條件中將數據使用引號引用起來,否則不使用索引
5.如果mysql估計使用全表掃描要比使用索引快,則不使用索引
此外,查看索引的使用情況
show status like ‘Handler_read%';
大家可以注意:
handler_read_key:這個值越高越好,越高表示使用索引查詢到的次數
handler_read_rnd_next:這個值越高,說明查詢低效
如何開啟慢日志查詢?
如何查看當前慢查詢日志的開啟情況?
在MySQL中輸入命令:
showvariables like ‘%quer%’;
主要掌握以下的幾個參數:
(1)slow_query_log的值為ON為開啟慢查詢日志,OFF則為關閉慢查詢日志。
(2)slow_query_log_file 的值是記錄的慢查詢日志到文件中(注意:默認名為主機名.log,
慢查詢日志是否寫入指定文件中,需要指定慢查詢的輸出日志格式為文件,相關命令為:
show variables like ‘%log_output%’;去查看輸出的格式)。
(3)long_query_time 指定了慢查詢的閾值,即如果執行語句的時間超過該閾值則為慢查詢語句,
默認值為10秒。
(4)log_queries_not_using_indexes 如果值設置為ON,則會記錄所有沒有利用索引的查詢(注意:如果只是將log_queries_not_using_indexes設置為ON,而將slow_query_log設置為OFF,此時該設置也不會生效,即該設置生效的前提是slow_query_log的值設置為ON),一般在性能調優的時候會暫時開啟。
數據庫導入導出命令(結構+數據)?
Mysqldump -h127.0.0.1 -P3306 -uroot -p密碼 數據庫名稱>xx.sql
數據庫優化方案?
詳情見我博客
char和varchar的區別?
#char類型:定長,簡單粗暴,浪費空間,存取速度快
#varchar類型:變長,精準,節省空間,存取速度慢
簡述MySQL的執行計劃?
詳情見博客
在對name做了唯一索引前提下,簡述以下區別:?
select * from tb where name = ‘Oldboy-Wupeiqi’ ?
select * from tb where name = ‘Oldboy-Wupeiqi’ limit 1
全局遍歷與只取一條
1000w條數據,使用limit offset 分頁時,為什么越往后翻越慢?如何解決?
越是向后,掃描的數據也就越多
解決方案:按照需求實現,可分為
限制瀏覽頁數,
存儲本頁數據兩端的主鍵,按主鍵查找后向前或向后取多少條
另外,如果數據沒有缺失的話,還可以通過頁數來計算主鍵
什么是索引合并?
使用多個主鍵進行查詢
什么是覆蓋索引?
查詢內容在主鍵中可以直接查到
簡述數據庫讀寫分離?
建立主從關系,實現高可用,并減少主服務器的壓力。
簡述數據庫分庫分表?(水平、垂直)
水平 : 數據庫字段過多
垂直 : 數據庫行數太多
https://www.cnblogs.com/Roc-Atlantis/
第一部分 Python基礎篇(80題)
為什么學習Python?
Omit
通過什么途徑學習的Python?
Omit
Python和Java、PHP、C、C#、C++等其他語言的對比?
Omit
簡述解釋型和編譯型編程語言?
編譯型語言:在運行程序之前將源代碼翻譯成目標代碼(機器語言),
運行時不需要重新翻譯,直接使用翻譯的結果,程序執行效率高,依賴編譯器運行(比如vs),
跨平臺性差。比如c,c++等。
解釋型語言:源代碼一邊翻譯成機器語言一遍執行,效率較低,
但是靈活性較高,依賴解釋器運行(比如py),修改方便,跨平臺性好。如python,java,PHP等。
Python解釋器種類以及特點?
cpython pypy jpython
位和字節的關系?
一個字節占8個bit位
b、B、KB、MB、GB 的關系?
1024關系 自行梳理
請至少列舉5個 PEP8 規范(越多越好)。
我的博客直接搜索PEP8規范
通過代碼實現如下轉換:
# 二進制轉換成十進制:v = “0b1111011”?
# int("1111011",2) # 123
# 十進制轉換成二進制:v = 18?
# print(bin(18))
# 八進制轉換成十進制:v = “011”?
# int("011",8) # 9
# 十進制轉換成八進制:v = 30?
# print(oct(30))
# 十六進制轉換成十進制:v = “0x12”?
# int("12",16) # 18
# 十進制轉換成十六進制:v = 87
# print(hex(87))
請編寫一個函數實現將IP地址轉換成一個整數。
如 10.3.9.12 轉換規則為:
10 00001010
? 3 00000011?
9 00001001
? 12 00001100?
再將以上二進制拼接起來計算十進制結果:00001010 00000011 00001001 00001100 = ?
def ip_to_int(s):
L = '0b'+''.join([bin(int(i)) for i in s.split('.')]).replace('0b','')
print(int(L,2))
if __name__ == '__main__':
s = "10.3.9.12"
ip_to_int(s)
python遞歸的最大層數?
import sys
print(sys.getrecursionlimit())
默認最大是1000層
求結果:
v1 = 1 or 3?
v2 = 1 and 3?
v3 = 0 and 2 and 1
? v4 = 0 and 2 or 1
? v5 = 0 and 2 or 1 or 4
? v6 = 0 or Flase and 1
# 1
# 3
# 0
# 1
# 1
# False
ascii、unicode、utf-8、gbk 區別?
ascii:不能表示中文,英文用一個字節表示
unicode:中文和英文都用2個字節表示
utf-8:英文用一個自己表示,中文用3個
gbk:英文用1個字節表示,中文用2個字節表示
字節碼和機器碼的區別?
機器碼是電腦CPU直接讀取運行的機器指令,運行速度最快,
但是非常晦澀難懂,也比較難編寫,一般從業人員接觸不到。
字節碼是一種中間狀態(中間碼)的二進制代碼(文件)。需要直譯器轉譯后才能成為機器碼。
三元運算規則以及應用場景?
應用場景:簡單的if else語句
a = 3 if x>10 else 12 如果if條件成立就輸出前面的結果,如果不成立就輸出后面的結果
列舉 Python2和Python3的區別?
python2默認ascii,python3默認utf-8
博客搜索python2和python3的區別
用一行代碼實現數值交換:
? a = 1
? b = 2
a = 1
b = 2
# a,b = 2,1
# print(a,b)
# c = a
# a = b
# b = c
# print(a,b)
# a,b = (2,1)
# print(a,b)
Python3和Python2中 int 和 long的區別?
python2中需要自己根據數值大小去判斷該用int還是long
python3中取消了long類型數據,會自動判斷
xrange和range的區別?
xrange(1,5)是python2里的生成器,可作為list對象得到一個列表
在python3,xrange相當于改了個名字,改成了range,也是一個生成器對象。
文件操作時:xreadlines和readlines的區別?
readlines() 讀取文件所有內容,按行為單位放到一個列表中,返回list類型。
xreadlines()官方解釋 >> Returns a generator to loop over every single line in the file
xreadlines只在python2里有
返回一個生成器,來循環操作文件的每一行。循環使用時和readlines基本一樣,但是直接打印就不同
列舉布爾值為False的常見值?
0,None,"",False
字符串、列表、元組、字典、集合每個常用的5個方法?
字符串:title(),join(),replace(),strip(),split(),eval()
元組:count(),index(),sorted(tuple)
列表:insert(),extend(),append(),pop(),remove(),sort()
字典:get(),items(),values(),keys(),clear(),copy(),pop(),setdefault()
集合:add(),deference(),discard(),remove(),pop(),symmetric_difference(),union(),intersection_update
lambda表達式格式以及應用場景?
lambda 變量名:變量表達式
通常和高階函數連用 map reduce等
pass的作用?
空函數常用
表示直接跳過繼續向下運行
*args和**kwargs作用
*args 表示接受溢出的位置參數,并以元組的形式返回給args
**kwargs 表示接受溢出的關鍵字參數,并以字典的形式返回給kwargs
is和==的區別
is判斷id是否相等
== 判斷值是否相等
為什么有時候值相同但是不同的兩個地址,is判斷卻為True?
因為python有個緩存機制,一定范圍內的整數不會獨自再分配一個內存空間,他們共享一個內存空間.
簡述Python的深淺拷貝以及應用場景?
深拷貝:拷貝后的對象的值不會再隨著被拷貝對象值的改變而改變
淺拷貝:拷貝后的對象得值會隨著被拷貝對象值的改變而改變.
淺拷貝的對象如果有多層可變類型,淺拷貝只拷貝第一層,深拷貝是遞歸拷貝,拷貝到迭代結束.
Python垃圾回收機制?
python每次定義一個變量都會帶一個引用計數,每調用一次變量值,引用計數都會加1.
每次引用被刪除,引用計數減1.當引用計數為0,變量值就會被當成垃圾回收.
Python的可變類型和不可變類型?
可變類型:列表,集合,字典
不可變類型:元組,字符串,整型
求結果:
? v = dict.fromkeys(['k1','k2'],[])? #value的內存空間是公用的,所有的鍵都指向同一個value [].
v[‘k1’].append(666)
? print(v)?
v[‘k1’] = 777
? print(v)
求結果:
{'k1': [666], 'k2': [666]}
{'k1': 777, 'k2': [666]}
列舉常見的內置函數?
map() reduce() abs() filter() len()
filter、map、reduce的作用?
filter:符合條件的元素會篩選留下來
map:作用于每一個可迭代對象的元素
reduce:python3里使用reduce需要調用functools
from functools import reduce
# res = reduce(lambda x,y: (x+y)*2, [1,2,3,4,5])
# print(res)
# ((((((1+2)*2) + 3)*2+4)*2)+5)*2 = 98
一行代碼實現9*9乘法表
"\n".join("\t".join(["%s*%s=%s" % (y, x, x*y) for y in range(1, x + 1)]) for x in range(1, 10))
如何安裝第三方模塊?以及用過哪些第三方模塊?
通常用兩種方法安裝第三方模塊:
一:直接用pip安裝
二:在第三方庫下載安裝包,在cmd命令直接安裝下載好的包
常用的第三方模塊:
requests,turtle,pymysql,gevent,mulitprocessing,threading,bs4
至少列舉8個常用模塊都有那些?
random,time,turtle,requests,math,re,os,pickle,json,logging,sys,subprocess,pymysql,hashlib
re的match和search區別?
re模塊中match(pattern,string[,flags]),檢查string的開頭是否與pattern匹配。
re模塊中research(pattern,string[,flags]),在string搜索pattern的第一個匹配值。
什么是正則的貪婪匹配?
.*從.前面的字符開始匹配,一直到*后面字符是整個字符串最后一個符合條件的才會結束。
補充下非貪婪匹配:.*? 匹配到最近的一個符合條件的字符就會停下來。
求結果:? a. [ i % 2 for i in range(10) ]? b. ( i % 2 for i in range(10) )
a [0,1,0,1,0,1,0,1,0,1]
b 生成器表達式
求結果:? a. 1 or 2? b. 1 and 2? c. 1 < (2==2)? d. 1 < 2 == 2
a 1
b 2
c False
d True
def func(a,b=[]) 這種寫法有什么坑?
會造成重復賦值,形參名不要寫成變量的形式。
如何實現 “1,2,3” 變成 [‘1’,’2’,’3’] ?
a = "1,2,3"
print(a.split(","))
如何實現[‘1’,’2’,’3’]變成[1,2,3] ?
a = ["1","2","3"]
for i in range(len(a)):
a[i] = int(a[i])
print(a)
比較: a = [1,2,3] 和 b = [(1),(2),(3) ] 以及 b = [(1,),(2,),(3,) ] 的區別?
b = [(1),(2),(3) ] 和a = [1,2,3]沒區別,最多寫的形式不一樣
b = [(1,),(2,),(3,)] 這個因為多了個小括號里的逗號,列表里相當于嵌套了元組,
打印出來結果和前面兩個是不一樣的
如何用一行代碼生成[1,4,9,16,25,36,49,64,81,100] ?
[i**2 for i in range(1,11)]
一行代碼實現刪除列表中重復的值 ?
字典key值的唯一性
print(dict.fromkeys(l).keys())
集合去重
print(set([1,2,3,4,1,2])
如何在函數中設置一個全局變量 ?
加入globals 申明下面的變量為全局變量
logging模塊的作用?以及應用場景?(待補充--通常會忘記補充)
日志模塊。
應用場景:需要生成日志在屏幕或者需要日志記錄。
請用代碼簡答實現stack 。(實現堆棧--先進先出和先進后出)
一.用到append(i)和insert(0,i) ==for循環出結果
二.線程queue中的q = queue.Queue()-先進先出和q = queue.LifoQueue() --先進后出
常用字符串格式化哪幾種?
"%s"%i
"{}-{}".format(1,2)
f"" python3新增,不太了解
簡述 生成器、迭代器、可迭代對象 以及應用場景?
可迭代對象:有__iter__方法的都是可迭代對象
迭代器:本身就是由可迭代對象經過__iter__方法轉換成迭代器對象,本身有__iter__和__next__方法。
生成器:生成器本身就是個迭代器,生成器構造有個yield函數,相當于自定義迭代器。
用Python實現一個二分查找的函數。
num = [1,3,4,5,6,8,22,33,55,778,990]
def search(search_number,num):
if len(num) == 0:return
mid = len(num) // 2
mid_nums = num[len(num)//2]
if search_number > mid_nums:
num = num[mid + 1:]
search(search_number,num)
elif search_number < mid_nums:
num = num[:mid]
search(search_number, num)
else:
print("find it")
search(363,num)
談談你對閉包的理解?
閉包就是調用函數會得到一個返回值,返回值是函數的內存地址。加括號即可調用。
閉指的是該函數是一個內部函數
包指的是該函數對外部作用域(非全局作用域)名字的引用。
os和sys模塊的作用?
os:這個模塊提供了一種方便的使用操作系統函數的方法。
sys:這個模塊可供訪問由解釋器使用或維護的變量和與解釋器進行交互的函數。
總結:os模塊負責程序與操作系統的交互,提供了訪問操作系統底層的接口;sys模塊負責程序
與python解釋器的交互,提供了一系列的函數和變量,用于操控python的運行時環境。
如何生成一個隨機數?
調用random模塊
random.randint(1,3)
random.randrange(1,3)
random.random()
如何使用python刪除一個文件?
import os
os.remove(文件路徑)
談談你對面向對象的理解?
核心是對象。對象是特征與技能的結合體,類就是一系列對象相似的特征與技能的結合體。
面向對象編程
Python面向對象中的繼承有什么特點?
繼承:子類會遺傳父類的屬性 繼承是類與類之間的關系
繼承的特點:
1、在繼承中基類的構造(__init__()方法)不會被自動調用,
它需要在其派生類的構造中親自專門調用。有別于C#
2、在調用基類的方法時,需要加上基類的類名前綴,且需要帶上self參數變量。
區別于在類中調用普通函數時并不需要帶上self參數
3、Python總是首先查找對應類型的方法,如果它不能在派生類中找到對應的方法,
它才開始到基類中逐個查找。(先在本類中查找調用的方法,找不到才去基類中找)
面向對象深度優先和廣度優先是什么?
自己理解:深度優先就是在查找方式上遍歷到最后的節點,和遞歸類似,有明確的結束條件。
廣度優先就是不優先查找最后的節點,到最后才去查找。
新式類:廣度查找優先,經典類:深度查找優先
網上:
深度優先:
將一個子節點的所有內容全部遍歷完畢之后再去遍歷其他節點實現的 (遞歸實現)
廣度優先:
廣度優先的算法的實現是通過 分層次的進行遍歷 先遍歷第一層,然后第二層,第三層 (隊列實現)
深度優先遍歷的算法是通過遞歸的方式一只只遍歷某一個節點從而進行的,
而廣度優先遍歷算法則是把上一個層次的所有節點歸入隊列全部遍歷完畢再進行下面的遍歷的
面向對象中super的作用?(具體參考博客)
要理解super的原理,就要先了解mro。mro是method resolution order的縮寫,表示了類繼承體系中的成員
解析順序。在python中,每個類都有一個mro的類方法。
可以看到mro方法返回的是一個祖先類的列表。Leaf的每個祖先都在其中出現一次,
這也是super在父類中查找成員的順序。
通過mro,python巧妙地將多繼承的圖結構,轉變為list的順序結構。super在繼承體系中向上的查找過程,
變成了在mro中向右的線性查找過程,任何類都只會被處理一次。
通過這個方法,python解決了多繼承中的2大難題:
1. 查找順序問題。從Leaf的mro順序可以看出,如果Leaf類通過super來訪問父類成員,
那么Medium1的成員會在Medium2之前被首先訪問到。
如果Medium1和Medium2都沒有找到,最后再到Base中查找。
2. 鉆石繼承的多次初始化問題。在mro的list中,Base類只出現了一次。事實上任何類都只會在mro list中
出現一次。這就確保了super向上調用的過程中,任何祖先類的方法都只會被執行一次。
是否使用過functools中的函數?其作用是什么?
搜索我博客:functools模塊中的函數
列舉面向對象中帶雙下劃線的特殊方法,如:__new__、__init__
__new__
__init__
__str__
__call__
__del__
__iter__
__next__
下面是查看對象屬性的一些方法
__name__
__main__
__doc__
__file__
__metaclass__
__dict__
如何判斷是函數還是方法?
函數:
函數是封裝了一些獨立的功能,可以直接調用,
python內置了許多函數,同時可以自建函數來使用。
方法:
方法和函數類似,同樣封裝了獨立的功能,但是方法是
需要通過對象來調用的,表示針對這個對象要做的操作,使用時采用點方法。
靜態方法和類方法區別?
靜態方法是類和對象都可以調用,調用的時候必須傳入對應的參數
類方法:類調用直接把調用的類當作參數傳入,對象調用類方法還是會自動傳入類。
列舉面向對象中的特殊成員以及應用場景
__new__
__init__
__str__
__call__
__del__
__iter__
__next__
__getitem__ 、 __setitem__ 、__delitem__ 用于索引操作,如字典。分別表示獲取、設置、刪除數據
1、2、3、4、5 能組成多少個互不相同且無重復的三位數
count = 0
for i in range(1,6):
for m in range(1,6):
for n in range(1,6):
if i != m and m != n and i!=n:
print(100*i + 10*m + n)
count+=1
print(count)
什么是反射?以及應用場景?
反射就是通過字符串來操作類和對象的屬性
hasattr(obj,attrib) 判斷對象是否存在這個屬性,存在就返回True
getattr(obj,attrib,None) 判斷屬性對象是否可以訪問,如果可以
就返回數據屬性的值或者函數屬性的內存地址。如果不能,就返會None。
setattr(obj,attrib,屬性值) 修改對象的屬性值,如果沒有該屬性則添加屬性到名稱空間
delattr(obj,attrib) 刪除對象名稱空間里的屬性值,刪除類的屬性值,數據屬性和函數屬性都可以刪除
metaclass(元類)作用?以及應用場景?
元類負責控制類的產生過程。
分為type元類創建類和自定義元類創建類。具體看我博客。
用盡量多的方法實現單例模式。
三種:一:直接在類中通過if判斷來確定__instance是否為None,如果是給他賦值,不是直接返回self.__instance
二.通過在類上加裝飾器的方法實現。裝飾器里的wrapper就是Mysql,調用wrapper相當于通過Mysql往里面傳值
,如果不傳值args和kwargs長度為0,可以以此為關鍵進行判斷。
三.自定義元類中通過傳入參數的長度來判斷是否傳參,沒傳參直接返回self.__instance,傳參則產生新對象
裝飾器的寫法以及應用場景。
單層裝飾器和多層裝飾器
為了節省代碼量,避免代碼冗余,裝飾器出現解決了這些問題。
無參裝飾器外面包著一層,有參裝飾器外面包著兩層。通常寫成語法糖的形式,放在被裝飾的對象上面。
裝飾器是為了不違背開放封閉原則的前提下,為被裝飾對象添加功能。
異常處理寫法以及如何主動拋出異常(應用場景)
異常處理:try..except..else..finally
主動拋出:raise Typeerror("拋出的異常說明")
什么是面向對象的mro
mro是子類查找父類的順序,mro列表里的類不會重復并且只會被查找一次,且按照繼承的順序來。
isinstance作用以及應用場景?
isinstance(obj,class) 判斷對象obj是不是由class生成的對象。
什么是語句,什么是表達式?
寫代碼并實現:
Given an array of integers, return indices of the two numbers such that they add up
to a specific target.You may assume that each input would
have exactly one solution, and you may not use the same element twice.
給定一個整數數組,返回兩個數字的索引,使它們相加
到一個特定的目標。你可以假設每個輸入都會只有一個解決方案,你可能不會使用相同的元素兩次。
Example:?
Given nums = [2, 7, 11, 15], target = 9,
?Because nums[0] + nums[1] = 2 + 7 = 9,?
return [0, 1]
l = [2,7,11,15]
target = 9
for i in l:
for m in l:
if i != m and i+m == target:
print(i,m)
json序列化時,可以處理的數據類型有哪些?如何定制支持datetime類型?
json不可以處理的數據類型:元組,集合,自定義類和類的對象。
datetime類型???
json序列化時,默認遇到中文會轉換成unicode,如果想要保留中文怎么辦?
Str=json.dumps(jsonData,ensure_ascii=False,indent=2)
加上ensure_ascii=False即可。 indent是用來設置排版格式。
什么是斷言?應用場景?
詳情見我博客,自己解釋不清,也不懂assert到底怎么用。
有用過with statement(with 聲明)嗎?它的好處是什么?
>>>with open('text.txt')as my_file:
...whileTrue:
...line=my_file.readline()
...if not line:
...break
...print(line)
#with語句使用所謂的上下文管理器對代碼塊進行包裝,允許上下文管理器實現一些設置和清理操作。
#例如:文件可以作為上下文管理器使用,它們可以關閉自身作為清理的一部分。
#NOTE:在PYTHON2.5中,需要使用from__future__importwith_statement進行with語句的導入
使用代碼實現查看列舉目錄下的所有文件。
import os
for file in os.listdir(r'\address'):
print(file)
簡述 yield和yield from關鍵字。
看我博客 看我博客 。
第二部分 網絡編程和并發(34題)
簡述 OSI 七層協議。
物理層:主要是基于電器特性發送高低電壓(電信號),高電壓對應數字1,低電壓對應數字0
數據鏈路層: 功能:定義了電信號分組的方式 以太網協議
網絡層:網絡層功能:引入一套新的地址用來區分不同的廣播域/子網,這套地址即網絡地址
規定網絡地址的協議叫做ip協議,它定義的地址稱為ip地址
傳輸層:傳輸層功能:建立端口到端口的通信
應用層:必須有不同協議規定電子郵件、網頁、FTP數據的格式,這些應用程序協議就構成了”應用層”。
什么是C/S和B/S架構?
客戶端與服務端通信
瀏覽器客戶端與服務端通信
先從服務器端說起。服務器端先初始化Socket,然后與端口綁定(bind),對端口進行監聽(listen),
調用accept阻塞,等待客戶端連接。在這時如果有個客戶端初始化一個Socket,然后連接服務器(connect),
如果連接成功,這時客戶端與服務器端的連接就建立了。客戶端發送數據請求,服務器
端接收請求并處理請求,然后把回應數據發送給客戶端,客戶端讀取數據,最后關閉連接,一次交互結束。
簡述 三次握手、四次揮手的流程。
第一次握手:
客戶端發送一個TCP的SYN標志位置1的包指明客戶打算連接的服務器的端口,
以及初始序號X,保存在包頭的序列號(Sequence Number)字段里。
第二次握手:
服務器發回確認包(ACK)應答。即SYN標志位和ACK標志位均為1同時,
將確認序號(Acknowledgement Number)設置為客戶的I S N加1以.即X+1。
第三次握手.
客戶端再次發送確認包(ACK) SYN標志位為0,ACK標志位為1.并且把服務器
發來ACK的序號字段+1,放在確定字段中發送給對方.并且在數據段放寫ISN的+1
連接終止協議(四次分手)
由于TCP連接是全雙工的,因此每個方向都必須單獨進行關閉。這原則是當一方完成它的數據
發送任務后就能發送一個FIN來終止這個方向的連接。收到一個 FIN只意味著這一方向上沒有數據流動,
一個TCP連接在收到一個FIN后仍能發送數據。首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉。
(1) TCP客戶端發送一個FIN,用來關閉客戶到服務器的數據傳送(報文段4)。
(2) 服務器收到這個FIN,它發回一個ACK,確認序號為收到的序號加1(報文段5)。
和SYN一樣,一個FIN將占用一個序號。
(3) 服務器關閉客戶端的連接,發送一個FIN給客戶端(報文段6)。
(4) 客戶段發回ACK報文確認,并將確認序號設置為收到序號加1(報文段7)。
什么是arp協議?
ARP協議
ARP 地址解析協議,就是 把 IP->MAC(你聽過ARP欺騙的)
arp協議由來:計算機通信基本靠吼,即廣播的方式,所有上層的包到最后都要封裝上以太網頭,
然后通過以太網協議發送,在談及以太網協議時候,我門了解到
通信是基于mac的廣播方式實現,計算機在發包時,獲取自身的mac是容易的,如何獲取目標主機的mac,
就需要通過arp協議。
一:首先通過ip地址和子網掩碼區分出自己所處的子網
二:分析172.16.10.10/24與172.16.10.11/24處于同一網絡
(如果不是同一網絡,那么下表中目標ip為172.16.10.1,通過arp獲取的是網關的mac)
三:這個包會以廣播的方式在發送端所處的自網內傳輸,所有主機接收后拆開包,
發現目標ip為自己的,就響應,返回自己的mac
最前面的”以太網標頭”,設置發出方(本機)的MAC地址和接收方(DHCP服務器)的MAC地址。
前者就是本機網卡的MAC地址,后者這時不知道,
就填入一個廣播地址:FF-FF-FF-FF-FF-FF
arp協議功能:廣播的方式發送數據包,獲取目標主機的mac地址。
TCP和UDP的區別?
TCP協議每一次傳輸都要發送請求和確認傳輸信號,安全可靠,速度較慢。
UDP協議直接傳輸,不需要經過請求,速度會很快,但容易造成數據包的丟失。
什么是局域網和廣域網?
廣域網:作用范圍大,一般可以從幾十公里至幾萬公里。
一個國家或國際間建立的網絡都是廣域網。在廣域網內,用于通信的傳輸裝置和傳輸介質可由電信部門提供。
局域網(LAN):為了完整地給出LAN的定義,必須使用兩種方式:一種是功能性定義,另一種是技術性定義。
前一種將LAN定義為一組臺式計算機和其它設備,在物理地址上彼此相隔不遠,以允許用戶相互通信
和共享諸如打印機和存儲設備之類的計算資源的方式互連在一起的系統。這種定義適用于辦公環境下
的LAN、工廠和研究機構中使用的LAN。
就LAN的技術性定義而言,它定義為由特定類型的傳輸媒體(如電纜、光纜和無線媒體)和網絡適配器
(亦稱為網卡)互連在一起的計算機,并受網絡操作系統監控的網絡系統。
為何基于tcp協議的通信比基于udp協議的通信更可靠?
tcp協議設立了接受確認和重傳機制。每一次信息傳輸都和三次握手一樣,使得每一個信息都能保證到達,很可靠。
udp是盡力傳送,沒有確認和重傳機制,udp只是將信息發送出去,對方收不收到也不進行應答
什么是socket?簡述基于tcp協議的套接字通信流程。
socket是套接字。
先從服務器端說起。服務器端先初始化Socket,然后與端口綁定(bind),對端口進行監聽(listen),
調用accept阻塞,等待客戶端連接。在這時如果有個客戶端初始化一個Socket,然后連接服務器(connect),
如果連接成功,這時客戶端與服務器端的連接就建立了。客戶端發送數據請求,服務器端接收請求并處理請求,
然后把回應數據發送給客戶端,客戶端讀取數據,最后關閉連接,一次交互結束。
什么是粘包?socket中造成粘包的原因是什么? 哪些情況會發生粘包現象?
產生粘包的原因:第一點:客戶端向服務端發起命令請求,服務端接受命令請求,并返回對應的信息,
如果信息過大,客戶端一次接受不了,那么下一次請求依然返回
上一個命令的內容,就出現了粘包的情況。
第二點:發送端需要等緩沖區滿才發送出去,造成粘包(發送數據時間間隔很短,數據了很小,
會合到一起,產生粘包)
所謂粘包問題主要還是因為接收方不知道消息之間的界限,不知道一次性提取多少字節的數據所造成的。
發送端為了將多個發往接收端的包,更有效的發到對方,使用了優化方法(Nagle算法),將多次間隔較小且數據量
小的數據,合并成一個大的數據塊,然后進行封包。這樣做,雖然節省了時間,但是發出的包卻粘在了一起,
造成粘包現象。
IO多路復用的作用?
IO復用機制可以同時監控多個描述符,當某個描述符就緒(讀或寫就緒),則立即通知相應程序進行讀或寫操作。
但select,poll,epoll本質上都是同步I/O,因為他們都需要在讀寫事件就緒后自己負責進行讀寫,也就是說
這個讀寫過程是阻塞的。
I/O多路復用的優勢并不是對于單個連接能處理的更快,而是在于可以在單個線程/進程中處理更多的連接。
與多進程和多線程技術相比,I/O多路復用技術的最大優勢是系統開銷小,系統不必創建進程/線程,
也不必維護這些進程/線程,從而大大減小了系統的開銷。
什么是防火墻以及作用?
防火墻見我博客
select、poll、epoll 模型的區別?
見我的博客
簡述 進程、線程、協程的區別 以及應用場景?
看我的博客
GIL鎖是什么鬼?
全局解釋器鎖
當程序在運行某段代碼遇到GIL鎖,此時會變成串行,需要一個線程執行完該段代碼下一個執行才可以進去。
Python中如何使用線程池和進程池?
# 進程池
from concurrent.futures import ProcessPoolExecutor
import time,os
def func1(name):
print("%s is %s"%(name,os.getpid())) # 打印了進程id
time.sleep(1)
if __name__ == "__main__":
p = ProcessPoolExecutor(4) # 指定進程池最大進程個數
for i in range(10):
obj = p.submit("omit %s"%i,i) 提交任務
# 線程池
rom concurrent.futures import ThreadPoolExecutor
import time,os,random
def func2(name):
print("%s is %s"%(name,os.getpid())) # 打印了進程id
time.sleep(random.randint(1,3))
if __name__ == "__main__":
p = ThreadPoolExecutor(4) # 指定線程池最大線程個數,不包含控制線程
for i in range(10):
obj = p.submit("omit %s"%i,i) # 提交任務
threading.local的作用?
一旦在主線程實例化了一個local,它會一直活在主線程中,并且又主線程啟動的子線程調用這個local實例時,
它的值將會保存在相應的子線程中。
1.local_data具有全局訪問權,主線程,子線程都能訪問它。
2.但是 local_data的值卻是線程隔離的,值只與各當前線程有關。
ThreadLocal 最常用的地方:
為每個線程綁定一個資源(數據庫連接,HTTP請求,用戶身份信息等),
這樣一個線程的所有調用到的處理函數都可以非常方便地訪問這些資源。
進程之間如何進行通信?
通過管道或者隊列來通信。一般用的隊列,因為隊列是管道加鎖,不用自己再加鎖。
導入multiprocessing模塊中的Queue,生成Queue對象,調用put方法把值放到隊列里,get從隊列里取值,
每取一個值也同時刪除隊列中的該值。
什么是并發和并行?
并發是偽并行,通過遇到IO切換來實現類似并行的效果。
并行多核才能實現,多個進程同時工作。
進程鎖和線程鎖的作用?
線程鎖:大家都不陌生,主要用來給方法、代碼塊加鎖。當某個方法或者代碼塊使用鎖時,那么
在同一時刻至多僅有有一個線程在執行該段代碼。當有多個線程訪問同一對象的加鎖方法/代碼塊時,
同一時間只有一個線程在執行,其余線程必須要等待當前線程執行完之后才能執行該代碼段。但是,
其余線程是可以訪問該對象中的非加鎖代碼塊的。
進程鎖:也是為了控制同一操作系統中多個進程訪問一個共享資源,只是因為程序的獨立性,
各個進程是無法控制其他進程對資源的訪問的,但是可以使用本地系統的信號量控制(操作系統基本知識)。
解釋什么是異步非阻塞?
見我博客
路由器和交換機的區別?
一、工作所在的OSI層次不一樣(根本區別,導致接下來的區別)
交換機工作在 OSI模型的數據鏈路層,所以工作原理比較簡單;
路由器工作在OSI模型的網絡層,具備更多的網絡協議信息,所以可以做出更好的數據轉發策略。
二、數據轉發所依據的對象也不一樣。
交換機工作在數據鏈路層,所以交換機轉發數據依靠的是每個物理地址(MAC地址),MAC地址一般
是設備生產商在設備出廠時固定在設備中的,不能進行更改。
路由器工作在網絡層,所以其交換數據依靠網絡地址(IP地址),而IP地址是由網絡管理員自己分配
或者系統自動獲取的。
三、是否可以分割廣播域
由交換機連接的所有端口仍然屬于同一個廣播域,所以極有可能會產生數據擁堵;
連接到路由器上的所有端口不在屬于同一個廣播域,所以不會產生類似的數據擁堵問題
什么是域名解析?
域名解析是把域名指向網站空間IP,讓人們通過注冊的域名可以方便地訪問到網站一種服務。
域名解析也叫域名指向、服務器設置、域名配置以及反向IP登記等等。說得簡單點就是將好記的域名解析成IP,
服務由DNS服務器完成,是把域名解析到一個IP地址,然后在此IP地址的主機上將一個子目錄與域名綁定。
如果是需要建站,除了注冊域名,還需要向虛擬主機提供商申請空間,如果空間是國內的還需要備份,
國外的空間則不需要。
如何修改本地hosts文件?
1.在菜單欄找到記事本
2.右鍵記事本 >>使用管理員權限打開
3.單擊文件按鈕>>下拉菜單點擊打開文件>>C:\Windows\System32\drivers\etc 這個路徑
4.如果到這步來了找不到hosts文件這是我們點擊文本文檔下拉框選擇 “所有文件”
5.輸入127.0.0.1 或你指向的IP就行了,ctrl + s 就OK
hosts記錄規則非常簡單,只需要將你的記錄以 “IP + 空格 + 域名” 的格式填寫即可。
生產者消費者模型應用場景及優勢?
生產者與消費者模式是通過一個容器來解決生產者與消費者的強耦合關系,生產者與消費者之間不直接進行通訊,
而是利用阻塞隊列來進行通訊,生產者生成數據后直接丟給阻塞隊列,消費者需要數據則從阻塞隊列獲取,實際應
用中,生產者與消費者模式則主要解決生產者與消費者生產與消費的速率不一致的問題,達到平衡生產者與消費者
的處理能力,而阻塞隊列則相當于緩沖區。
# 應用場景
由一個線程生成訂單,并將其放入隊列中.由多個線程去處理
# 優勢
平衡生產者與消費者的處理能力
簡述 gevent模塊的作用和應用場景。
Gevent 是一個第三方庫,可以輕松通過gevent實現并發同步或異步編程,在gevent中用到的主要模式是Greenlet,
它是以C擴展模塊形式接入Python的輕量級協程。 Greenlet全部運行在主程序操作系統進程的內部,但它們被
協作式地調度。
什么是cdn?
CDN的全稱是Content Delivery Network,即內容分發網絡。
其基本思路是盡可能避開互聯網上有可能影響數據傳輸速度和穩定性的瓶頸和環節,使內容傳輸的更快、更穩定。
通過在網絡各處放置節點服務器所構成的在現有的互聯網基礎之上的一層智能虛擬網絡,CDN系統能夠實時地根
據網絡流量和各節點的連接、負載狀況以及到用戶的距離和響應時間等綜合信息將用戶的請求重新導向離用戶最近
的服務節點上。
其目的是使用戶可就近取得所需內容,解決 Internet網絡擁擠的狀況,提高用戶訪問網站的響應速度。
第三部分 數據庫和緩存(46題)
列舉常見的關系型數據庫和非關系型都有那些?
關系型 : MySQL,SQL Server ,Oracle , Sybase, DB2
非關系型 : Redis, MongodDB
MySQL常見數據庫引擎及比較?
ISAM:ISAM是一個定義明確且歷經時間考驗的數據表格管理方法,它在設計之時就考慮到數據庫被查詢的次數
要遠大于更新的次數。因此,ISAM執行讀取操作的速度很快,而且不占用大量的內存和存儲資源。ISAM的兩個
主要不足之處在于,它不支持事務處理,也不能夠容錯:如果你的硬盤崩潰了,那么數據文件就無法恢復了。
如果你正在把ISAM用在關鍵任務應用程序里,那就必須經常備份你所有的實時數據,通過其復制特性,
MYSQL能夠支持這樣的備份應用程序。
MyISAM:MyISAM是MySQL的ISAM擴展格式和缺省的數據庫引擎。除了提供ISAM里所沒有的索引
和字段管理的大量功能,MyISAM還使用一種表格鎖定的機制,來優化多個并發的讀寫操作,
其代價是你需要經常運行OPTIMIZE TABLE命令,來恢復被更新機制所浪費的空間。MyISAM還有一些有用的擴展
,例如用來修復數據庫文件的MyISAMCHK工具和用來恢復浪費空間的 MyISAMPACK工具。MYISAM強調了快速讀取操作
,這可能就是為什么MySQL受到了WEB開發如此青睞的主要原因:在WEB開發中你所進行的大量數據操作都是讀取操作。所以,大多數虛擬主機提供商和INTERNET平臺提供商只允許使用MYISAM格式。MyISAM格式的一個重要缺陷就是不能在表損壞后恢復數據。
InnoDB:InnoDB數據庫引擎都是造就MySQL靈活性的技術的直接產品,這項技術就是MYSQL+API。在使用MYSQL
的時候,你所面對的每一個挑戰幾乎都源于ISAM和MyISAM數據庫引擎不支持事務處理(transaction process)
也不支持外來鍵。盡管要比ISAM和 MyISAM引擎慢很多,但是InnoDB包括了對事務處理和外來鍵的支持,這兩點
都是前兩個引擎所沒有的。如前所述,如果你的設計需要這些特性中的一者或者兩者,那你就要被迫使用后兩個
引擎中的一個了。
MEMORY: MEMORY是MySQL中一類特殊的存儲引擎。它使用存儲在內存中的內容來創建表,而且數據全部放在內存中。
這些特性與前面的兩個很不同。每個基于MEMORY存儲引擎的表實際對應一個磁盤文件。該文件的文件名與表名相同,
類型為frm類型。該文件中只存儲表的結構。而其數據文件,都是存儲在內存中,這樣有利于數據的快速處理,
提高整個表的效率。值得注意的是,服務器需要有足夠的內存來維持MEMORY存儲引擎的表的使用。如果不需要了,
可以釋放內存,甚至刪除不需要的表。MEMORY默認使用哈希索引。速度比使用B型樹索引快。當然如果你想用B型樹
索引,可以在創建索引時指定。注意,MEMORY用到的很少,因為它是把數據存到內存中,如果內存出現異常就會
影響數據。如果重啟或者關機,所有數據都會消失。因此,基于MEMORY的表的生命周期很短,一般是一次性的。
簡述數據三大范式?
1.第一范式:確保每列保持原子性
2.第二范式:確保表中的每列都和主鍵相關
3.第三范式:確保表中每一列都和主鍵列直接相關,而不是間接相關.
什么是事務?MySQL如何支持事務?
事務是邏輯上的一組操作,組成這組操作的各個單元,要不全都成功要不全都失敗,這個特性就是事務
事務可以包含一系列的sql語句,事務的執行具有原子性
1、原子性:
包含多條sql語句要么都執行成功,要么都執行不成功
2、回滾
簡述數據庫設計中一對多和多對多的應用場景?
應用場景:一對多:一個學生可以有多門課程
多對多:一個老師可以有多個學生,一個學生也可以有多個老師
如何基于數據庫實現商城商品計數器?
詳情見我博客
常見SQL(必備)
詳見武沛齊博客:https://www.cnblogs.com/wupeiqi/articles/5729934.html
簡述觸發器、函數、視圖、存儲過程?
觸發器: 在執行某種操作前后一些自定義的操作
函數: 處理參數,返回結果
視圖: 把需要的數據存放在一張臨時表中,簡化查詢
存儲過程: sql語句集,簡化了一些操作.與函數不同,他可以返回一個結果集(查詢結果)
MySQL索引種類
1. 普通索引
這是最基本的索引,它沒有任何限制,比如上文中為title字段創建的索引就是一個普通索引,
MyIASM中默認的BTREE類型的索引,也是我們大多數情況下用到的索引。
2. 唯一索引
與普通索引類似,不同的就是:索引列的值必須唯一,但允許有空值(注意和主鍵不同)。
如果是組合索引,則列值的組合必須唯一,創建方法和普通索引類似。
3. 全文索引(FULLTEXT)
MySQL從3.23.23版開始支持全文索引和全文檢索,FULLTEXT索引僅可用于 MyISAM 表;
他們可以從CHAR、VARCHAR或TEXT列中作為CREATE TABLE語句的一部分被創建,或是隨后
使用ALTER TABLE 或CREATE INDEX被添加。對于較大的數據集,將你的資料輸入一個
沒有FULLTEXT索引的表中,然后創建索引,其速度比把資料輸入現有FULLTEXT索引的速度更為快。
不過切記對于大容量的數據表,生成全文索引是一個非常消耗時間非常消耗硬盤空間的做法。
4. 單列索引、多列索引
多個單列索引與單個多列索引的查詢效果不同,因為執行查詢時,MySQL只能使用一個索引,
會從多個索引中選擇一個限制最為嚴格的索引。
5. 組合索引(最左前綴)
平時用的SQL查詢語句一般都有比較多的限制條件,所以為了進一步榨取MySQL的效率,就要考慮建立組合索引。
索引在什么情況下遵循最左前綴的規則?
聯合索引的情況下遵循最左前綴的規則。
主鍵和外鍵的區別?
主鍵 : 該表中此列唯一,非空
外鍵 : 該列中的值必須是關聯表中關聯的數據
MySQL常見的函數?
詳情見我博客
列舉 創建索引但是無法命中索引的8種情況。
1.如果條件中有or,即使其中有條件帶索引也不會使用(這也是為什么盡量少用or的原因)
注意:要想使用or,又想讓索引生效,只能將or條件中的每個列都加上索引
2.對于多列索引,不是使用的第一部分,則不會使用索引
3.like查詢是以%開頭
4.如果列類型是字符串,那一定要在條件中將數據使用引號引用起來,否則不使用索引
5.如果mysql估計使用全表掃描要比使用索引快,則不使用索引
此外,查看索引的使用情況
show status like ‘Handler_read%';
大家可以注意:
handler_read_key:這個值越高越好,越高表示使用索引查詢到的次數
handler_read_rnd_next:這個值越高,說明查詢低效
如何開啟慢日志查詢?
如何查看當前慢查詢日志的開啟情況?
在MySQL中輸入命令:
showvariables like ‘%quer%’;
主要掌握以下的幾個參數:
(1)slow_query_log的值為ON為開啟慢查詢日志,OFF則為關閉慢查詢日志。
(2)slow_query_log_file 的值是記錄的慢查詢日志到文件中(注意:默認名為主機名.log,
慢查詢日志是否寫入指定文件中,需要指定慢查詢的輸出日志格式為文件,相關命令為:
show variables like ‘%log_output%’;去查看輸出的格式)。
(3)long_query_time 指定了慢查詢的閾值,即如果執行語句的時間超過該閾值則為慢查詢語句,
默認值為10秒。
(4)log_queries_not_using_indexes 如果值設置為ON,則會記錄所有沒有利用索引的查詢(注意:如果只是將log_queries_not_using_indexes設置為ON,而將slow_query_log設置為OFF,此時該設置也不會生效,即該設置生效的前提是slow_query_log的值設置為ON),一般在性能調優的時候會暫時開啟。
數據庫導入導出命令(結構+數據)?
Mysqldump -h127.0.0.1 -P3306 -uroot -p密碼 數據庫名稱>xx.sql
數據庫優化方案?
詳情見我博客
char和varchar的區別?
#char類型:定長,簡單粗暴,浪費空間,存取速度快
#varchar類型:變長,精準,節省空間,存取速度慢
簡述MySQL的執行計劃?
詳情見博客
在對name做了唯一索引前提下,簡述以下區別:?
select * from tb where name = ‘Oldboy-Wupeiqi’ ?
select * from tb where name = ‘Oldboy-Wupeiqi’ limit 1
全局遍歷與只取一條
1000w條數據,使用limit offset 分頁時,為什么越往后翻越慢?如何解決?
越是向后,掃描的數據也就越多
解決方案:按照需求實現,可分為
限制瀏覽頁數,
存儲本頁數據兩端的主鍵,按主鍵查找后向前或向后取多少條
另外,如果數據沒有缺失的話,還可以通過頁數來計算主鍵
什么是索引合并?
使用多個主鍵進行查詢
什么是覆蓋索引?
查詢內容在主鍵中可以直接查到
簡述數據庫讀寫分離?
建立主從關系,實現高可用,并減少主服務器的壓力。
簡述數據庫分庫分表?(水平、垂直)
水平 : 數據庫字段過多
垂直 : 數據庫行數太多
轉載于:https://www.cnblogs.com/Roc-Atlantis/p/9460755.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的python部分 + 数据库 + 网络编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql服务自动关闭的解决
- 下一篇: LeetCode:225. 用队列实现栈