2019-11-04

面試

Django REST framework 框架是一個用于構建Web API 的強大而又靈活的工具。

通常簡稱為DRF框架 或 REST framework。

特點:

提供了定義序列化器Serializer的方法,可以快速根據(jù) Django ORM 或者其它庫自動序列化/反序列化;

提供了豐富的類視圖、Mixin擴展類,簡化視圖的編寫;

豐富的定制層級:函數(shù)視圖、類視圖、視圖集合到自動生成 API,滿足各種需要;

多種身份認證和權限認證方式的支持;

內置了限流系統(tǒng);

直觀的 API web 界面;

可擴展性,插件豐富

Django的中間件

Django的中間件就是一個類,分別是process_request,process_respone,process_view,process_exception,process_render_template。

中間件的應用場景

做ip限制

放在中間件類的列表中華,阻止了某些ip的訪問

2,URL訪問過濾

如果用戶訪問的是login視圖

如果訪問其他視圖(需要檢測是不是有session已經(jīng)有了放行,沒有返回login),這樣就省在多個視圖函數(shù)上寫裝飾器

3、緩存

客戶端請求來了,中間件去緩存看看有沒有數(shù)據(jù),有直接返回給用戶,沒有再去邏輯層執(zhí)行視圖函數(shù)

數(shù)據(jù)庫的結構設計,和優(yōu)化?

第一范式:保證列的原子性,保證列不可在分

第二范式:唯一性;一個表只能說明一個事物,有主鍵且非主鍵依賴主鍵

第三范式:每列都與主鍵有直接關系,不存在傳遞依賴

Ps:第二范式要遵循第一范式,第三范式要遵循第二范式

數(shù)據(jù)庫結構優(yōu)化的目的有哪些?

l? 減少數(shù)據(jù)冗余

l? 盡量避免數(shù)據(jù)維護中出現(xiàn)更新,插入,刪除異常。

l? 節(jié)約數(shù)據(jù)查詢空間

優(yōu)化mysql數(shù)據(jù)庫的8個方法

l? 選取最合適的字段j

l? 使用join來代替子查詢

l? 使用聯(lián)合來代替手動創(chuàng)建的臨時表

l? 事務? (1.維護數(shù)據(jù)庫的完整性。2.當多個用戶同時使用相同的數(shù)據(jù)源時,它可以利用鎖定數(shù)據(jù)庫的方法來為用戶提供一種安全的訪問方式,這樣可以保證用戶的操作不被其他用戶干擾)

事務的缺點:因為事務的獨占性,有時候會影響數(shù)據(jù)庫的性能,在事務執(zhí)行過程中,數(shù)據(jù)庫被鎖定,其他用戶請求只能等待該事務結束,當訪問量大時,就會產(chǎn)生較嚴重的響應延遲

l? 鎖定表 (可以維護數(shù)據(jù)的完整性,但是不能保證數(shù)據(jù)的關聯(lián)性)

l? 使用外鍵

l? 使用索引? (索引應該建立在join,where,判斷和orderby排序字段上。盡量不要對數(shù)據(jù)庫中某個含有大量重復的值的字段建立索引。)

l? 優(yōu)化查詢語句 (查詢的時候盡量不要select * ,盡量使用索引字段查詢)

多線程,多進程,celery分布式任務,定時任務和異步任務

l? 線程:一個運行的程序就是一個進程

l? 進程:調度執(zhí)行的最小單位,也叫執(zhí)行路徑,不能獨立存在,依賴進程存在一個進程至少有一個線程,叫主線程,

進程間內存是否是存是共享,如何實現(xiàn)通訊?

進程間內存不共享

1.? ? ? 可以通過Manage模塊加鎖

2.? ? ? 通過隊列或通過管道加鎖

3.? ? ? Socket實現(xiàn)通訊

l? 協(xié)程:是一種用戶態(tài)的輕? ? ? 量級線程,協(xié)程的調度完全由用戶控制

Celery是分布式異步消息任務隊列。

優(yōu)點:

l? 簡單

l? 高可用:當任務執(zhí)行失敗或執(zhí)行過程中發(fā)生連接中斷,celery會自動嘗試重新執(zhí)行任務

l? 快速:一個單進程的celery每分鐘可以處理上百萬個任務

l? 靈活:幾乎celery的各個組件都可以被擴展及定制

Celery支持定時任務,celery啟動任務有兩種方式:1.在程序中指定2.在配置文件中指定

Celery異步任務,一些耗時較長的操作,比如i/o操作,可以交給celery去異步執(zhí)行,用戶提交后可以做其他事情,讓任務完成后將結果返回用戶,可以提高用戶體驗。

互聯(lián)網(wǎng)通信協(xié)議http協(xié)議,是一個無狀態(tài)協(xié)議。

客戶端用到的手段,只能是http協(xié)議,四個表示操作方式的動詞:get,post,put,delete。它們分別對應四種操作:get用來獲取資源,post用來新建資源(也可以用于更新資源),put用來更新資源,delete用來刪除資源

計算機網(wǎng)絡傳輸協(xié)議分層

1.osi七層模型

從上到下:應用層 (應用程序的通信服務)

? 表示層 (定義數(shù)據(jù)格式及加密)

? 會話層? ()

? 傳輸層? ()

? 網(wǎng)絡層 ()

? 數(shù)據(jù)鏈路層 ()

? ? 物理層? ()

2.五層模型

從上到下:

應用層 (應用程序的通信服務)

表示層 (定義數(shù)據(jù)格式及加密)

網(wǎng)絡層 (定義包傳輸,定義節(jié)點的邏輯地址,定義路由實現(xiàn)和學習的方式,定義包的分段方法)

數(shù)據(jù)鏈路層(定義單個鏈路如何傳輸數(shù)據(jù))

物理層(傳輸介質的標準定制)

http是超文本傳輸協(xié)議,是客戶端瀏覽器或其他程序與web服務器之間的應用層通信協(xié)議。

tcp(面向連接)通過序列化應答和必要時重發(fā)數(shù)據(jù)包,tcp為應用程序提供了可靠的傳輸流和虛擬連接服務。

udp(用戶數(shù)據(jù)報協(xié)議)是與tcp相對應的協(xié)議,它是面向非連接的協(xié)議,它不與對方建立連接,而是直接把數(shù)據(jù)包發(fā)送過去

tcp/udp區(qū)別:1、tcp面向連接,udp是無連接,發(fā)送數(shù)據(jù)之前不需要連接

? 2、安全方面:tcp提供可靠服務,通過tcp連接傳送數(shù)據(jù),無差錯,不丟失,不重復,且按序到達

udp盡最大努力交付,即不保證可靠交付

3、傳輸效率的區(qū)別

TCP傳輸效率相對較低

udp傳輸效率高,適用對高傳輸和實時性有較高的通信或廣播

4、連接對象數(shù)量的區(qū)別

tcp連接只能是點到點,一對一的。

udp支持一對一,一對多,和多對一和多對多的交互通信

Http是應用層協(xié)議,tcp是傳輸層協(xié)議!

數(shù)據(jù)包在網(wǎng)絡傳輸過程中,http被封裝在tcp包內

什么是nginx?

nginx 是一個高性能http和反向代理服務器,也是一個(IMAP/POP3)代理服務器? 目前使用的最多的web服務器或者是代理服務器。

為什么要用nginx?

優(yōu)點:1.跨平臺,配置簡單 2、非阻塞。高并發(fā)連接;處理2-3w并發(fā)連接數(shù) 3、內存消耗小 4、內置的健康檢查功能:如果有一個服務器宕機,會做一個健康檢查,在發(fā)送的請求就不會發(fā)送到宕機服務器,重新將請求提交到其他節(jié)點上 5、節(jié)省寬帶 6、穩(wěn)定性高:宕機的概率非常小? 7、master/worker結構:一個master進程,生成一個或者多個worker進程 8、接受用戶請求的是異步,瀏覽器將請求發(fā)送到nginx服務器,它先將用戶請求全部接收下來,在一次性發(fā)送給后端web服務器,極大減輕了web服務器的壓力 9、一邊接收web服務器的返回數(shù)據(jù),一邊發(fā)送給瀏覽器客戶端 10、網(wǎng)絡依賴性比較低,只要ping通就可以負載均衡? 11、可以有多臺nginx服務器? 12、事件驅動:通信機制采用epoll模型

為什么nginx性能那么高?

因為他的處理機制:異步非阻塞事件處理機制:運用了epoll模型。提供了一個隊列,排隊解決

為什么不使用多線程?

因為線程創(chuàng)建上下文的切換非常消耗資源,線程占用內存大,上下文切換占用cpu也很高,采用epoll模型避免了和這個缺點

uwsgi是一個web 服務器,他實現(xiàn)了wsgi協(xié)議,uwsgi、http等協(xié)議。

wsgi是一種通信協(xié)議。 uwsgi是一種線路協(xié)議而不是通信協(xié)議,在此常用在uwsgi服務器與其他網(wǎng)絡服務器的數(shù)據(jù)通信

uwsgi是實現(xiàn)了uwsgi和wsgi兩種協(xié)議的web服務器

websocket特點:1.建立在tcp協(xié)議之上,服務器端的實現(xiàn)比較容易? 2、與http協(xié)議有良好的兼容性,默認端口是80和443,通信握手階段采用了http協(xié)議,能通過各種http代理服務器 3、數(shù)據(jù)格式比較輕量,性能開銷小,通信高效? 4.可以發(fā)送文本,也可以發(fā)送二進制數(shù)據(jù)? 5.沒有同源策略的限制,客戶端(瀏覽器)可以任意與服務器通信

同步和異步關注的是消息通信機制

同步就是在發(fā)出一個調用之后,在沒有得到結果之前,該調用就不返回,但是一旦調用返回,就得到了返回值(就是調用者主動等待這個調用結果)

異步剛好相反,調用在發(fā)出去之后,這個調用就可以直接返回,所以沒有返回結果,當一個異步調用過程調用發(fā)出去后,調用者不會立刻得到結果,而是在調用發(fā)出去后,被調用著通過狀態(tài)、通知來通知調用者,或通過回調函數(shù)處理這個調用。

Mysql的復制原理及負載均衡

Mysql主從復制工作原理

1.? 在主庫上把數(shù)據(jù)更高紀錄到二進制日志

2.? 從庫將主庫的日志復制到自己的中繼日志

3.? 從庫讀取中繼日志的事件,將其重放到從庫數(shù)據(jù)中

Mysql主從復制解決的問題

數(shù)據(jù)分布:隨意開始或停止復制,并在不同地理位置分布數(shù)據(jù)備份

負載均衡:降低單個服務器的壓力

高可用和故障切換:幫助應用程序避免單點失敗

升級測試:可以用更高版本的mysql作為從庫

設定網(wǎng)站用戶數(shù)量在千萬級,但是活躍用戶的數(shù)量只有1%,如何通過優(yōu)化數(shù)據(jù)庫提高活躍用戶訪問速度?

1.? 可以使用Mysql的分區(qū),把活躍用戶分在一個區(qū),不活躍用戶分在一個區(qū),本身活躍用戶區(qū)數(shù)據(jù)量比較少,因此可以提高活躍用戶的訪問速度

還可以水平分表,把活躍用戶分在一張表,不活躍用戶分在一張表,可以提高活躍用戶訪問速度

阻塞/非阻塞和同步異步

阻塞:在進行socket通信中,一個線程發(fā)起請求,如果當前請求沒有返回結果,則進入sleep狀態(tài),期間線程掛起不能做其他操作,直到有返回結果,或者超時(如果設置超時的話)

非阻塞:與阻塞相似,只不過在等待請求結果時,線程并不掛起而是進行其他操作,既在不能立刻得到結果之前,該函數(shù)不會阻掛起當前線程,而是會立刻返回。

進程問題

進程間內存是否是共享?如何實現(xiàn)通訊?

進程間內存不共享

1.可以通過Manage模塊加鎖

2.通過隊列或通過管道加鎖

3.Socket實現(xiàn)通訊

請聊聊進程隊列的特點和實現(xiàn)原理?

1.? 先進先出

2.? 后進先出

3.? 優(yōu)先級隊列

線程本身帶鎖通過put()和get()數(shù)據(jù),同一時間只有一個線程運行修改任務實現(xiàn)數(shù)據(jù)安全

請畫出進程的三狀態(tài)轉換圖

就緒====運行

? ? \阻塞/

談談python的裝飾器,迭代器,yield

裝飾器:裝飾器的本質是一個閉包函數(shù),他的作用就是讓其他函數(shù)在不需要任何代碼修改的前提下增加額外功能,裝飾器的返回值也是一個函數(shù)對象,我們通常在一些有切面需求的場景,比如:插入日志,性能測試,事物處理,緩存,權限校驗等場景,有了裝飾器就可以少寫很多重復代碼,提高效率

迭代器:迭代器是一種訪問可迭代對象的方式,通常從第一個元素開始訪問,知道所有的元素都被訪問完才結束,迭代器只能前進不能后退,使用迭代器可以不用事先準備好迭代過程中的所有元素,僅僅是在迭代到該元素的時候才能計算該元素,而在這之前的元素則是被銷毀,因此迭代器適合遍歷一些數(shù)據(jù)量巨大的無限的序列。

迭代器的本質就是調用iter方法,每次調用的時候返回一個元素,當沒有下一個元素的時候回排除StopIteration異常

如何解決線程安全?

線程安全是在多線程的環(huán)境下,能夠保證多個線程同時執(zhí)行時程序依舊運行正確,而且要保證對于共享的數(shù)據(jù)可以由多個線程存取,但是同一時刻只能有一個線程進行存取。多線程環(huán)境下解決資源競爭問題的辦法是加鎖來保證存取操作的唯一性。如何加鎖?分布式 負載均衡

常用linux命令?

Ls ,cd,more,clear,mkdir,pwd,rm,grep,find,mv,su,date等等

什么是面向對象編程?

回答:面向對象編程是一種軟件復用的設計和編程方法。這種方法把軟件系統(tǒng)中相近似的操作邏輯和操作應用數(shù)據(jù)、狀態(tài),以類的形式述出來,以對象實例的形式在軟件系統(tǒng)中復用,以達到高軟件開發(fā)效率的作用。封裝,繼承多態(tài)

如何提高python的運行效率,請說出不少于2種提高運行效率的方法?

1.? 使用生成器

2.? 關鍵代碼使用外部功能包:Cython,Pylnlne、pypy、pyrex

3.? 針對循環(huán)的優(yōu)化—盡量避免在循環(huán)中訪問變量的屬性;

說說mysql數(shù)據(jù)庫存儲的原理?

存儲過程是一個可編程的函數(shù),它在數(shù)據(jù)庫中創(chuàng)建并保存,它可以有sql語句和一些特殊的控制結構組成。當希望在不同的應用程序或平臺上執(zhí)行相同的函數(shù),或者是封裝特定功能時,存儲過程是非常有用的,數(shù)據(jù)庫中額度存儲過程客戶看做是對編程中面向對象方法的模擬,他允許控制數(shù)據(jù)的訪問方式。

說一下事物的特效?

1.? 原子性:事物中的全部操作在數(shù)據(jù)庫中是不可分割的,要么全部完成,要么俊不執(zhí)行

2.? 一致性:幾個并行執(zhí)行的事務,其執(zhí)行結果必須與按某一順序串行執(zhí)行的結果相一致。

3.? 隔離性:事物的執(zhí)行不受其他事務的干擾,事務執(zhí)行的中間結果對其他事務必須是透明的。

持久性:對于任意已交事務,系統(tǒng)必須保證該事務對數(shù)據(jù)庫的改變不被丟失,即使數(shù)據(jù)庫

MyISAM不支持事務,InnoDB支持事務。表鎖雖然開銷小,鎖表快,但高并發(fā)下性能低。行鎖雖然開銷大,鎖表慢,但高并發(fā)下相比之下性能更高。事務和行鎖都是在確保數(shù)據(jù)準確的基礎上提高并發(fā)的處理能力。

MySQL常用的存儲引擎是InnoDB,相對于MyISAM而言。InnoDB更適合高并發(fā)場景,同時也支持事務處理。

行鎖的劣勢:開銷大;加鎖慢;會出現(xiàn)死鎖

行鎖的優(yōu)勢:鎖的粒度小,發(fā)生鎖沖突的概率低;處理并發(fā)的能力強

加鎖的方式:自動加鎖。對于UPDATE、DELETE和INSERT語句,InnoDB會自動給涉及數(shù)據(jù)集加排他鎖;對于普通SELECT語句,InnoDB不會加任何鎖;

表鎖:開銷小,加鎖快;不會出現(xiàn)死鎖;鎖定力度大,發(fā)生鎖沖突概率高,并發(fā)度最低

行鎖:開銷大,加鎖慢;會出現(xiàn)死鎖;鎖定粒度小,發(fā)生鎖沖突的概率低,并發(fā)度高

頁鎖:開銷和加鎖速度介于表鎖和行鎖之間;會出現(xiàn)死鎖;鎖定粒度介于表鎖和行鎖之間,并發(fā)度一般

什么時候使用表鎖

對于InnoDB表,在絕大部分情況下都應該使用行級鎖,因為事務和行鎖往往是我們之所以選擇InnoDB表的理由。但在個別特殊事務中,也可以考慮使用表級鎖。

第一種情況是:事務需要更新大部分或全部數(shù)據(jù),表又比較大,如果使用默認的行鎖,不僅這個事務執(zhí)行效率低,而且可能造成其他事務長時間鎖等待和鎖沖突,這種情況下可以考慮使用表鎖來提高該事務的執(zhí)行速度。

第二種情況是:事務涉及多個表,比較復雜,很可能引起死鎖,造成大量事務回滾。這種情況也可以考慮一次性鎖定事務涉及的表,從而避免死鎖、減少數(shù)據(jù)庫因事務回滾帶來的開銷。

悲觀鎖(Pessimistic Lock), 顧名思義,就是很悲觀,每次去拿數(shù)據(jù)的時候都認為別人會修改,所以每次在拿數(shù)據(jù)的時候都會上鎖,這樣別人想拿這個數(shù)據(jù)就會block直到它拿到鎖。傳統(tǒng)的關系型數(shù)據(jù)庫里邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。

樂觀鎖(Optimistic Lock), 顧名思義,就是很樂觀,每次去拿數(shù)據(jù)的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個數(shù)據(jù),可以使用版本號等機制。樂觀鎖適用于多讀的應用類型,這樣可以提高吞吐量,像數(shù)據(jù)庫如果提供類似于write_condition機制的其實都是提供的樂觀鎖。

問題一:已登錄用戶的購物車放在哪里?未登錄用戶的購物車放在哪里?

已登錄用戶的購物車可以放在數(shù)據(jù)庫中(可以先在Redis中緩存);未登錄用戶的購物車可以保存在Cookie、localStorage或sessionStorage中(減少服務器端內存開銷)

登錄后購物車合并

當跳到購物車頁面,查詢購物車列表前,需要判斷用戶登錄狀態(tài),如果登錄:

首先檢查用戶的localStorage中是否有購物車信息

如果有,則提交后臺保存

清空Localstorage

如果未登錄,直接查詢就好

調用支付寶第三方API接口

創(chuàng)建調用支付寶的對象

在線創(chuàng)建應用時分配的ID

自己應用的私鑰

支付寶的公鑰

調用獲取支付頁面操作

生成完整的支付頁面URL

通過上面返回的鏈接可以進入支付頁面,支付完成后會自動跳轉回上面代碼中設定好的項目頁面,在該頁面中可以獲得訂單號(out_trade_no)、支付流水號(trade_no)、交易金額(total_amount)和對應的簽名(sign)并請求后端驗證和保存交易結果,代碼如下所示:

創(chuàng)建調用支付寶的對象

創(chuàng)建調用支付寶的對象

自己應用的私鑰

支付寶的公鑰

請求參數(shù)(假設是POST請求)中包括訂單號、支付流水號、交易金額和簽名

調用驗證操作

超賣現(xiàn)象:比如某商品的庫存為1,此時用戶1和用戶2并發(fā)購買該商品,用戶1提交訂單后該商品的庫存被修改為0,而此時用戶2并不知道的情況下提交訂單,該商品的庫存再次被修改為-1這就是超賣現(xiàn)象。解決超賣現(xiàn)象有三種常見的思路:

悲觀鎖控制:查詢商品數(shù)量的時候就用select ... for update對數(shù)據(jù)加鎖,這樣的話用戶1查詢庫存時,用戶2因無法讀取庫存數(shù)量被阻塞,直到用戶1提交或者回滾了更新庫存的操作后才能繼續(xù),從而解決了超賣問題。但是這種做法對并發(fā)訪問量很高的商品來說性能太過糟糕,實際開發(fā)中可以在庫存小于某個值時才考慮加鎖,但是總的來說這種做法不太可取。

樂觀鎖控制:查詢商品數(shù)量不用加鎖,更新庫存的時候設定商品數(shù)量必須與之前查詢數(shù)量相同才能更新,否則說明其他事務已經(jīng)更新了庫存,必須重新發(fā)出請求。這種做法要求事務隔離級別為可重復讀,否則仍然會產(chǎn)生問題。

嘗試減庫存:將上面的查詢(select)和更新(update)操作合并為一條SQL操作,更新庫存的時候,在where篩選條件中加上庫存>=購買數(shù)量或庫存-購買數(shù)量>=0的條件。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • --- layout: post title: "如果有人問你關系型數(shù)據(jù)庫的原理,叫他看這篇文章(轉)" date...
    藍墜星閱讀 919評論 0 3
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,656評論 1 32
  • ORA-00001: 違反唯一約束條件 (.) 錯誤說明:當在唯一索引所對應的列上鍵入重復值時,會觸發(fā)此異常。 O...
    我想起個好名字閱讀 5,970評論 0 9
  • 昨天公司組織全員開展團隊拓展活動,活動中有一項游戲為“漢諾塔”,我們分成兩個隊進行pk,率先完成任務的隊獲勝。 教...
    雲(yún)空葉閱讀 1,112評論 0 0
  • 灰蒙蒙的深圳 對不起,我沒空情緒不良,我忙著學習呢。 聽完Grace大大的課,對自己的不良情緒進行了梳理。共鳴點主...
    愛學習的萌妹閱讀 161評論 1 0

友情鏈接更多精彩內容