由於文章過長,小編也貼心的把文章整理成了PDF文檔,想要觀看學習起來更方便的話點此下載
上篇_拿著阿裡師兄精心整理 170 道 Python 面試題,我已成功上岸【綜合篇:網絡編程】
上上篇_靠著阿裡師兄給的170 道 Python 面試題,我已成功上岸【Python基礎篇】
綜合篇:數據庫和框架
121. 列舉常見的數據庫
122. 數據庫設計三大范式
123. 什麼是數據庫事務
124. MySQL 索引種類
125. 數據庫設計中一對多和多對多的應用場景
126. 簡述觸發器、函數、視圖、存儲過程
127. 常用 SQL 語句
128. 主鍵和外鍵的區別
129. 如何開啟 MySQL 慢日志查詢
130. MySQL 數據庫備份命令
131. char 和 varchar 的區別
132. 最左前綴原則
133. 無法命中索引的情況
134. 數據庫讀寫分離
135. 數據庫分庫分表
136. redis 和 memcached 比較
137. redis中數據庫默認是多少個 db 及作用
138. redis 有哪幾種持久化策略
139. redis 支持的過期策略
140. 如何保證 redis 中的數據都是熱點數據
141. Python 操作 redis
142. 基於 redis 實現發布和訂閱
143. 如何高效的找到 redis 中的某個 KEY
144. 基於 redis 實現先進先出、後進先出及優先級隊列
145. redis 如何實現主從復制
146. 循環獲取 redis 中某個非常大的列表數據
147. redis 中的 watch 的命令的作用
148. redis 分布式鎖
149. http 協議
150. uwsgi,uWSGI 和 WSGI 的區別
151. HTTP 狀態碼
152. HTTP常見請求方式
153. 響應式布局
154. 實現一個簡單的 AJAX 請求
155. 同源策略
156. 什麼是 CORS
157. 什麼是 CSRF
158. 前端實現輪詢、長輪詢
159. 簡述 MVC 和 MTV
160. 接口的冪等性
161. Flask 框架的優勢
162. 什麼是 ORM
163. PV、UV 的含義
164. supervisor 的作用
165. 使用 ORM 和原生 SQL 的優缺點
166. 列舉一些 django 的內置組件
167. 列舉 Django 中執行原生 sql 的方法
168. cookie 和 session 的區別
169. beautifulsoup 模塊的作用
170. Selenium 模塊簡述
關系型數據庫:MySQL,Oracle,SQLServer,SQLite,DB2
非關系型數據庫:MongoDB,Redis,HBase,Neo4j
建立科學的,規范的的數據庫是需要滿足一些規范的,以此來優化數據數據存儲方式,在關系型數據庫中這些規范就可以稱為范式
第一范式:當關系模式 R 的所有屬性都不能在分解為更基本的數據單位時,稱 R 是滿足第一范式的,簡記為 1NF
關系模式R的所有屬性不能再分解
第二范式:如果關系模式 R 滿足第一范式,並且 R 的所有非主屬性都完全依賴於 R 的每一個候選關鍵屬性,稱 R 滿足第二范式,簡記為 2NF
非主屬性都要依賴於每一個關鍵屬性
三范式:設 R 是一個滿足第一范式條件的關系模式,X 是 R 的任意屬性集,如果 X 非傳遞依賴於 R 的任意一個候選關鍵字,稱 R 滿足第三范式,簡記為 3NF
數據不能存在傳遞關系,即每個屬性都跟主鍵有直接關系而不是間接關系
事務(Transaction)是並發控制的基本單位。所謂的事務,它是一個操作序列,這些操作要麼都執行,要麼都不執行,它是一個不可分割的工作單位
在關系數據庫中,一個事務可以是一條 SQL 語句、一組 SQL 語句或整個程序。四個屬性:原子性,一致性,隔離性和持久性
MySQL 目前主要有以下幾種索引類型:
普通索引
唯一索引
主鍵索引
組合索引
全文索引
一對一關系示例:一個學生對應一個學生檔案材料,或者每個人都有唯一的身份證編號
一對多關系示例:一個學生只屬於一個班,但是一個班級有多名學生
多對多關系示例:一個學生可以選擇多門課,一門課也有多名學生
觸發器:觸發器是一個特殊的存儲過程,它是數據庫在 insert、update、delete 的時候自動執行的代碼塊
函數:數據庫中提供了許多內置函數,還可以自定義函數,實現 sql 邏輯
視圖:視圖是由查詢結果形成的一張虛擬表,是表通過某種運算得到的一個投影
存儲過程:把一段代碼封裝起來,當要執行這一段代碼的時候,可以通過調用該存儲過程來實現(經過第一次編譯後再次調用不需要再次編譯,比一個個執行 sql 語句效率高)
DML(數據操作語言)
SELECT - 從數據庫表中獲取數據
UPDATE - 更新數據庫表中的數據
DELETE - 從數據庫表中刪除數據
INSERT INTO - 向數據庫表中插入數據
DDL(數據定義語言)
CREATE DATABASE - 創建新數據庫
ALTER DATABASE - 修改數據庫
CREATE TABLE - 創建新表
ALTER TABLE - 變更(改變)數據庫表
DROP TABLE - 刪除表
CREATE INDEX - 創建索引(搜索鍵)
DROP INDEX - 刪除索引
定義主鍵和外鍵主要是為了維護關系數據庫的完整性 主鍵是能確定一條記錄的唯一標識。不能重復,不允許為空
外鍵用於與另一張表關聯。是能確定另一張表記錄的字段,用於保持數據的一致性
主鍵外鍵索引定義唯一標識一條記錄,不能重復,不允許為空表的外鍵是另一表的主鍵,外鍵可以重復,可以是空值該字段沒有重復值,但可以有空值作用用來保證數據完整性用來和其他表建立聯系提高查詢排序的速度個數只能有一個可有多個可有多個
修改配置文件,然後重啟服務生效
在linux下,vim /etc/my.cnf,在[mysqld]內容項下增加:slow_query_log = ON long_query_time = 2 # 查詢超過2秒的就會記錄
命令行,但是重啟服務後會失效 SET GLOBAL slow_query_log = 'ON'; SET GLOBAL long_query_time = 2;
mysqldump -u 用戶名 -p 數據庫名 > 導出的文件名
char:存儲定長數據很方便,CHAR 字段上的索引效率級高,必須在括號裡定義長度,可以有默認值,比如定義 char(10)
varchar:存儲變長數據,但存儲效率沒有 CHAR 高,必須在括號裡定義長度,可以有默認值
mysql 建立多列索引(聯合索引)有最左前綴的原則,即最左優先,如:
如果有一個2列的索引(col1,col2),則已經對(col1)、(col1,col2)上建立了索引
如果有一個3列索引(col1,col2,col3),則已經對(col1)、(col1,col2)、(col1,col2,col3)上建立了索引
使用or關鍵字會導致無法命中索引
左前導查詢會導致無法命中索引,如 like '%a' 或者 like '%a%' 單列索引的索引列為 null 時全值匹配會使索引失效,組合索引全為 null 時索引失效
組合索引不符合左前綴原則的列無法命中索引,如我們有4個列 a、b、c、d,我們創建一個組合索引 INDEX(a,b,c,d),那麼能命中索引的查詢為 a,ab,abc,abcd,除此之外都無法命中索引
強制類型轉換會導致索引失效
負向查詢條件會導致無法使用索引,比如 NOT IN,NOT LIKE,!= 等 如果 mysql 估計使用全表掃描要比使用索引快,則不使用索引
讀寫分離,就是將數據庫分為了主從庫,一個主庫用於寫數據,多個從庫完成讀數據的操作,主從庫之間通過某種機制進行數據的同步,是一種常見的數據庫架構
數據庫水平切分,是一種常見的數據庫架構,是一種通過算法,將數據庫進行分割的架構。一個水平切分集群中的每個數據庫,通常稱為一個“分片”。每一個分片中的數據沒有重合,所有分片中的數據並集組成全部數據。
水平切分分為庫內分表和分庫分表,是根據表內數據內在的邏輯關系,將同一個表按不同的條件分散到多個數據庫或多個表中,每個表中只包含一部分數據,從而使得單個表的數據量變小,達到分布式的效果
redis 和 memcached 都是將數據存放在內存中,都是內存數據庫。不過 memcached 還可用於緩存其他東西,例如圖片、視頻等等
redis 不僅僅支持簡單的 k/v 類型的數據,同時還提供 list,set,hash 等數據結構的存儲
分布式設定, 都可以做一主多從或一主一從
存儲數據安全,memcached 掛掉後,數據完全丟失;redis 可以定期保存到磁盤(持久化)
災難恢復,memcached 掛掉後,數據不可恢復; redis 數據丟失後可以通過 aof 恢復
redis 默認有16個數據庫,每個數據庫中的數據都是隔離的,這樣,在存儲數據的時候,就可以指定把不同的數據存儲到不同的數據庫中。且只有單機才有,如果是集群就沒有數據庫的概念
RDB 持久化:是將 Reids 在內存中的數據庫記錄定時 dump 到磁盤上的持久化 AOF(append only file)持久化:將 Reids 的操作日志以追加的方式寫入文件
通用的三種過期策略
定時刪除 在設置 key 的過期時間的同時,為該 key 創建一個定時器,讓定時器在 key 的過期時間來臨時,對 key 進行刪除
惰性刪除 key 過期的時候不刪除,每次從數據庫獲取 key 的時候去檢查是否過期,若過期,則刪除,返回 null
定期刪除 每隔一段時間執行一次刪除過期 key 操作
redis 采用惰性刪除+定期刪除策略
限定 Redis 占用的內存,Redis 會根據自身數據淘汰策略,加載熱數據到內存。所以,計算一下所有熱點數據大約占用的內存,然後設置一下 Redis 內存限制即可
使用 redis 第三方庫來操作
import redis
# 創建一個 redis 連接池
def redis_conn_pool():
pool = redis.ConnectionPool(host='redis-host', port=redis-port,
decode_responses=True, password='redis-pwd')
r = redis.Redis(connection_pool=pool)
return r
訂閱者
if __name__ == "__main__":
conn = redis.Redis(host='',
port=12143, password='')
ps = conn.pubsub()
ps.subscribe('chat') # 從 chat 訂閱消息
for item in ps.listen(): # 監聽狀態:有消息發布了就拿過來
if item['type'] == 'message':
print(item)
print(item['channel'])
print(item['data'])
發布者
if __name__ == "__main__":
number_list = ['300033', '300032', '300031', '300030']
signal = ['1', '-1', '1', '-1']
pool = redis.ConnectionPool(host='redis-12143.c8.us-east-1-3.ec2.cloud.redislabs.com', port=12143,
decode_responses=True, password='pkAWNdYWfbLLfNOfxTJinm9SO16eSJFx')
r = redis.Redis(connection_pool=pool)
for i in range(len(number_list)):
value_new = str(number_list[i]) + ' ' + str(signal[i])
print(value_new)
r.publish("chat", value_new)
import redis
con = redis.Redis()
con.keys(pattern='key*') # *代表通配符
class Zhan:
def __init__(self,conn):
self.conn = conn
def push(self,val):
self.conn.rpush('aaa',val)
def pop(self):
return self.conn.rpop('aaa')
class Dui:
def __init__(self,conn):
self.conn = conn
def push(self,val):
self.conn.rpush('bbb',val)
def get(self):
return self.conn.lpop('bbb')
class Xu:
def __init__(self,conn):
self.conn = conn
def push(self,val,count):
self.conn.zadd('ccc',val,count)
def get(self):
a = self.conn.zrange('ccc', 0, 0)[0]
self.conn.zrem('ccc', a)
return a
在從服務器中配置 SLAVEOF 127.0.0.1 6380 # 主服務器 IP,端口
def list_iter(name):
"""
自定義redis列表增量迭代
:param name: redis中的name,即:迭代name對應的列表
:return: yield 返回 列表元素
"""
list_count = r.llen(name)
for index in xrange(list_count):
yield r.lindex(name, index)
watch 用於在進行事務操作的最後一步也就是在執行 exec 之前對某個 key 進行監視,如果這個被監視的 key 被改動,那麼事務就被取消,否則事務正常執行
為 redis 集群設計的鎖,防止多個任務同時修改數據庫,其本質就是為集群中的每個主機設置一個會超時的字符串,當集群中有一半多的機器設置成功後就認為加鎖成功,直至鎖過期或解鎖不會有第二個任務加鎖成功
超文本傳輸協議(HTTP,HyperText Transfer Protocol)是互聯網上應用最為廣泛的一種網絡協議。HTTP 是一個客戶端和服務器端請求和應答的標准。客戶端是終端用戶,服務器端是網站。一般由 HTTP 客戶端發起一個請求,建立一個到服務器指定端口(默認是80端口)的 TCP 連接,HTTP 服務器則在那個端口監聽客戶端發送過來的請求,並給與響應
WSGI:全稱是 Web Server Gateway Interface,是一種描述 web server 如何與 web application 通信的規范。django,flask 等都遵循該協議
uwsgi:是服務器和服務端應用程序的一種協議,規定了怎麼把請求轉發給應用程序和返回; uwsgi 是一種線路協議而不是通信協議,在此常用於在 uWSGI 服務器與其他網絡服務器的數據通信
uWSGI:是一個 Web 服務器,它實現了 WSGI 協議、uwsgi、http 等協議。Nginx 中 HttpUwsgiModule 的作用是與 uWSGI 服務器進行交換
1xx: 信息
2xx:成功
3xx:重定向
4xx:客戶端錯誤
5xx:服務器錯誤
GET,POST,PUT,DELETE,PATCH 等
響應式布局是 Ethan Marcotte 在2010年5月份提出的一個概念,簡而言之,就是一個網站能夠兼容多個終端——而不是為每個終端做一個特定的版本
AJAX 是一種在無需重新加載整個網頁的情況下,能夠更新部分網頁的技術。
AJAX = 異步 JavaScript 和 XML
$(function(){
$('#send').click(function(){
$.ajax({
type: "GET",
url: "test.json",
data: {username:$("#username").val(), content:$("#content").val()},
dataType: "json",
success: function(data){
$('#resText').empty(); //清空resText裡面的所有內容
var html = '';
$.each(data, function(commentIndex, comment){
html += '<div class="comment"><h6>' + comment['username']
+ ':</h6><p class="para"' + comment['content']
+ '</p></div>';
});
$('#resText').html(html);
}
});
});
});
同源策略限制了從同一個源加載的文檔或腳本如何與來自另一個源的資源進行交互。這是一個用於隔離潛在惡意文件的重要安全機制
如果兩個頁面的協議,端口(如果有指定)和主機都相同,則兩個頁面具有相同的源。我們也可以把它稱為“協議/主機/端口 tuple”,或簡單地叫做“tuple". ("tuple" ,“元”,是指一些事物組合在一起形成一個整體,比如(1,2)叫二元,(1,2,3)叫三元)
CORS 全稱是跨域資源共享(Cross-Origin Resource Sharing),是一種 AJAX 跨域請求資源的方式,支持現代浏覽器
CSRF(Cross-site request forgery),中文名稱:跨站請求偽造,也被稱為:one click attack/session riding,縮寫為:CSRF/XSRF
輪詢
var xhr = new XMLHttpRequest();
setInterval(function(){
xhr.open('GET','/user');
xhr.onreadystatechange = function(){
};
xhr.send();
},1000)
長輪詢
function ajax(){
var xhr = new XMLHttpRequest();
xhr.open('GET','/user');
xhr.onreadystatechange = function(){
ajax();
};
xhr.send();
}
所謂 MVC 就是把 web 應用分為模型(M),控制器(C),視圖(V)三層,他們之間以一種插件似的,松耦合的方式連接在一起。模型負責業務對象與數據庫的對象(ORM),視圖負責與用戶的交互(頁面),控制器(C)接受用戶的輸入調用模型和視圖完成用戶的請求
Django 中的 MTV 模式:
Model(模型):負責業務對象與數據庫的對象(ORM)
Template(模版):負責如何把頁面展示給用戶
View(視圖):負責業務邏輯,並在適當的時候調用 Model 和 Template,本質上與 MVC 相同
接口冪等性就是用戶對於同一操作發起的一次請求或者多次請求的結果是一致的,不會因為多次點擊而產生了副作用
簡潔,輕巧,擴展性強,自由度高
ORM 的全稱是 Object Relational Mapping,即對象關系映射。它的實現思想就是將關系數據庫中表的數據映射成為對象,以對象的形式展現,這樣開發人員就可以把對數據庫的操作轉化為對這些對象的操作
PV:是(page view)訪問量,頁面浏覽量或點擊量,衡量網站用戶訪問的網頁數量。在一定統計周期內用戶每打開或刷新一個頁面就記錄1次,多次打開或刷新同一頁面則浏覽量累計
UV:是(Unique Visitor)獨立訪客,統計一段時間內訪問某站點的用戶數(以cookie為依據)
supervisor 管理進程,是通過 fork/exec 的方式將這些被管理的進程當作 supervisor 的子進程來啟動,所以我們只需要將要管理進程的可執行文件的路徑添加到 supervisor 的配置文件中即可
優點:
方便的使用面向對象,語句清晰
有效的防止 SQL 注入
方便動態構造語句,對於不同的表的相同操作采用多態實現更優雅;
一定程度上方便重構數據層
方便設置設置鉤子函數
缺點:
不太容易處理復雜查詢語句
性能較直接用 SQL 差
Admin 組件:是對 model 中對應的數據表進行增刪改查提供的組件
model 組件:負責操作數據庫
form 組件:生成 HTML 代碼;數據有效性校驗;校驗信息返回並展示
ModelForm 組件:用於數據庫操作,也可用於用戶請求的驗證
使用 execute 執行自定義的 SQL 直接執行 SQL 語句(類似於 pymysql 的用法)
from django.db import connection
cursor = connection.cursor()
cursor.execute("SELECT DATE_FORMAT(create_time, '%Y-%m') FROM blog_article;")
ret = cursor.fetchall()
print(ret)
使用 extra 方法:queryset.extra(select={"key": "原生的SQL語句"})
使用 raw 方法
執行原始 sql 並返回模型
依賴於 model 模型,多用於查詢操作
cookie 是保存在浏覽器端的鍵值對,可以用來做用戶認證
sesseion 是將用戶的會話信息保存在服務端,key 值是隨機產生的字符串,value 值是 session 的內容,依賴於 cookie 將每個用戶的隨機字符串保存到用戶浏覽器中
BeautifulSoup 庫是解析、遍歷、維護“標簽樹”的功能庫
url = "http://www.baidu.com/"
request = requests.get(url)
html = request.content
soup = BeautifulSoup(html, "html.parser", from_encoding="utf-8")
Selenium 是模擬操作浏覽器的庫,可以根據我們的指令,讓浏覽器自動加載頁面,獲取需要的數據,甚至頁面截屏,或者判斷網站上某些動作是否發生等
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
print(browser.page_source) # browser.page_source 是獲取網頁的全部 html
browser.close()