# 超詳細的Django面試題
1、說一下Django,MIDDLEWARES中間件的作用和應用場景?
中間件是介于request與response處理之間的一道處理過程,用于在全局范圍內改變Django的輸入和輸出。
簡單的來說中間件是幫助我們在視圖函數執行之前和執行之后都可以做一些額外的操作
例如:
(1.Django項目中默認啟用了csrf保護,每次請求時通過CSRF中間件檢查請求中是否有正確#token值
(2.當用戶在頁面上發送請求時,通過自定義的認證中間件,判斷用戶是否已經登陸或者處于禁用狀態,未登陸就去登陸。
(3.當有用戶請求過來時,判斷用戶是否在白名單或者在黑名單里
2、列舉django的內置組件?
(1)Admin是對model中對應的數據表進行增刪改查提供的組件
(2)model組件:負責操作數據庫
(3)form組件:1.生成HTML代碼2.數據有效性校驗3校驗信息返回并展示
(4)ModelForm組件即用于數據庫操作,也可用于用戶請求的驗證
3、django路由系統中name的作用?
答:用于反向解析路由,相當于給url取個別名,只要這個名字不變,即使對應的url改變,在html模板中通過該name名字也能找到該條url,不用修改HTML文件顯得很方便。
4、如何使用django orm批量創建數據?
objs\_list = \[\]
for i in range(100):
obj = People('name%s'%i,18) #models里面的People表
objs\_list.append(obj) #添加對象到列表
People.objects.bulk\_create(objs\_list,100) #更新操作
參考文檔:[python django面試題(第八章)](https://link.zhihu.com/?target=https%3A//blog.csdn.net/weixin_39726347/article/details/88567149%3Futm_medium%3Ddistribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param%26depth_1-utm_source%3Ddistribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param)
5、django中 values和 values\_list的區別?
答:values 字典列表,ValuesQuerySet查詢集
values\_list 返回元祖列表,字段值
6、DRF視圖類有幾種寫法?
答: 類名
APIView
1)繼承自View,封裝了Django 本身的HttpRequest對象為Request對象。
2)認證&權限&限流。
GenericAPIView
1)繼承自APIView,提供了操作序列化器和數據庫數據的方法,通常和Mixin擴展類配合使用。
2)過濾&排序&分頁
擴展類
類名
ListModelMixin —— 提供了一個list方法,封裝了返回模型數據列表信息的通用流程。
CreateModelMixin —— 提供了一個create方法,封裝了創建一條模型對象數據信息的通用流程。
RetrieveModelMixin ——提供了一個retrieve方法,封裝了獲取一條模型對象數據信息的通用流程。
UpdateModelMixin —— 提供了一個update方法,封裝了更新一條模型對象數據信息的通用流程。
DestroyModelMixin —— 提供了一個destroy方法,封裝了刪除一條模型對象數據信息的通用流程。
子類視圖類
類名
ListAPIView
1)繼承自ListModelMixin和GenericAPIView。
2)如果想定義一個視圖只提供`列出模型所有`信息的接口,繼承此視圖類是最快的方式。
CreateAPIView
1)繼承自CreateModelMixin和GenericAPIView。
2)如果想定義一個視圖只提供`創建一個模型信息`的接口,繼承此視圖類是最快的方式。
RetrieveAPIView
1)繼承自RetrieveModelMixin和GenericAPIView。
2)如果想定義一個視圖只提供`獲取一個模型信息`的接口,繼承此視圖類是最快的方式。
UpdateAPIView
1)繼承自UpdateModelMixin和GenericAPIView。
2)如果只想定義一個視圖只提供`更新一個模型信息`的接口,繼承此視圖類是最快的方式。
DestroyAPIView
1)繼承自DestroyModelMixin和GenericAPIView。
2)如果只想定義一個視圖只提供`刪除一個模型信息`的接口,繼承此視圖類是最快的方式。
ListCreateAPIView
1)繼承自ListModelMixin,CreateModelMixin和GenericAPIView。
2)如果只想定義一個視圖提供`列出模型所有`和`創建一個模型信息`的接口,繼承此視圖類是最快的方式。
RetrieveUpdateAPIView
1)繼承自RetrieveModelMixin,UpdateModelMixin和GenericAPIView。
2)如果只想定義一個視圖提供`獲取一個模型信息`和`更新一個模型信息`的接口,繼承此視圖類是最快的方式
RetrieveUpdateDestoryAPIView
1)繼承自RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin和GenericAPIView。
2)如果只想定義一個視圖提供`獲取一個模型信息`和`更新一個模型信息`和`刪除一個模型信息`的接口,繼承此視圖類是最快的方式。
視圖集類
類名
ViewSet
1)繼承自ViewSetMixin和APIView。
2)如果使用視圖集時不涉及數據庫的操作,可以直接繼承此類。
GenericViewSet
1)繼承自ViewSetMixin和GenericAPIView。
2)如果使用視圖集涉及數據的操作,可以直接繼承此類。
ModelViewSet
1)繼承自5個Mixin擴展和GenericViewSet。
2)如果使用視圖集想一次提供通用的5種操作,繼承這個類是最快的。
ReadOnlyModelViewSet
1)繼承自ListModelMixin,RetrieveModelMixin和GenericViewSet。
2)如果使用視圖集想一次提供list操作和retrieve操作,繼承這個類是最快的。
注: 除了常見的5種基本操作之外,如果想給一個視圖集中添加其他處理方法,直接在視圖集中定義即可。
參考文檔:[DRF框架總結\_慢行的蝸牛-CSDN博客\_drf框架](https://link.zhihu.com/?target=https%3A//blog.csdn.net/qq_42780731/article/details/81182532%3Futm_medium%3Ddistribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param%26depth_1-utm_source%3Ddistribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param)
7、list和tuple的底層數據結構是什么,dict呢?
答:python的list和tuple,均采用了順序表的結構。Tuple不支持改變內部狀態的操作。dict采用的是哈希散列表。
(1)順序表:將表元素直接順序的放在一塊劃分的連續存儲區內,所以元素的順序關系由存儲順序自然表示。鏈接表:將表元素放在通過鏈接構造起來的系列存儲塊里。兩種模型各有長短。插入和刪除的時間復雜度為O(n),增加的時間復雜度為O(1)
(2)在存儲dict的時候,首先會根據dict的key進行hash映射到對應的表元,然后再對應的表元中開辟內存,存入數據,當如果存在不同的兩個key的hash結果相同的時候,就會使用散列值的另一部分來定位散列表中的另一行。
在查找指定key時,會先計算key的散列值,然后使用散列值的一部分來定位表元,如果沒有找到相應的表元,則說明dict中不存在對應的key跑出KeyError異常。如果找到表元之后,會判斷表元中的key是否和要查找的key相等,相等就返回對應值,如果不相等則使用其對應的散列值的其他部分來定位散列表中的其他行。
參考文檔:[Python數據結構底層實現分析\_Hanhahahahah的博客-CSDN博客](https://link.zhihu.com/?target=https%3A//blog.csdn.net/Hanhahahahah/article/details/108861537)
8、Python的設計模式,你了解哪些?
答:單例模式、工廠模式、適配器模式、鴨子類型、生成器模式、visitor拜訪者模式
工廠模式,可以達到可擴展,可維護的代碼。當增加一個新的類型,不在需要修改已存在的類,只增加能夠產生新類型的子類。比如水果是一個抽象的父類,蘋果和梨子可以作為它的子類,繼承它的屬性。如果要增加一個香蕉類,只需要增加,不需要修改。定義了一個創建對象的接口(可以理解為函數),但由子類決定要實例化的類是哪一個,
class Person:
def \_\_init\_\_(self):
[self.name](https://link.zhihu.com/?target=http%3A//self.name)\= None
self.gender = None
def getName(self):
return[self.name](https://link.zhihu.com/?target=http%3A//self.name)
def getGender(self):
return self.gender
class Male(Person):
def \_\_init\_\_(self, name):
print "Hello Mr." + name
class Female(Person):
def \_\_init\_\_(self, name):
print "Hello Miss." + name
class Factory:
def getPerson(self, name, gender):
if gender == ‘M':
return Male(name)
if gender == 'F':
return Female(name)
if \_\_name\_\_ == '\_\_main\_\_':
factory = Factory() ## 工廠類
person = factory.getPerson("Chetan", "M")
所謂”工廠模式“就是專門提供一個”工廠類“去創建對象,我只需要告訴這個工廠我需要什么,它就會返回給我一個相對應的對象。
使用場景:您需要一輛汽車,可以直接從工廠里面提貨,而不用去管這輛汽車是怎么做出來的,以及這個汽車里面的具體實現。用來處理復雜的多個類。
我們只需要告訴工廠,你給我創建一個什么類即可,除了這點信息以外,不需要知道任何的額外信息,這就是所謂的“隱藏創建類的代碼邏輯” 。
復雜工廠方法模式是遵循了開放封閉原則的,用子工廠類來繼承父工廠類,這樣子增加一個香蕉類就不用修改原來的類。
class IFactory: #模擬接口
def create\_shape(self): #定義接口的方法,只提供方法的聲明,不提供方法的具體實現
pass
class CircleFactory(IFactory): #模擬類型實現某一個接口,實際上是類的繼承
def create\_shape(self, name): #重寫接口中的方法
if name =='Circle':
return Circle()
參考文檔:[一文詳解“工廠模式”以及python語言的實現\_MIss-Y的博客-CSDN博客](https://link.zhihu.com/?target=https%3A//blog.csdn.net/qq_27825451/article/details/84235974)
9、set的底層數據結構是什么?set和dict的區別
答:(1)dict是用來存儲鍵值對結構的數據的,set其實也是存儲的鍵值對,只是默認鍵和值是相同的。Python中的dict和set都是通過散列表來實現的。下面來看與dict相關的幾個比較重要的問題:
(2)dict中的數據是無序存放的
操作的時間復雜度,插入、查找和刪除都可以在O(1)的時間復雜度
鍵的限制,只有可哈希的對象才能作為字典的鍵和set的值。可hash的對象即python中的不可變對象和自定義的對象。可變對象(列表、字典、集合)是不能作為字典的鍵和set的值的。
與list相比:list的查找和刪除的時間復雜度是O(n),添加的時間復雜度是O(1)。但是dict使用hashtable內存的開銷更大。為了保證較少的沖突,hashtable的裝載因子,一般要小于0.75,在python中當裝載因子達到2/3的時候就會自動進行擴容。
參考文檔:[Python dict和set的底層原理](https://link.zhihu.com/?target=https%3A//lavi-liu.blog.csdn.net/article/details/98943272%3Futm_medium%3Ddistribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param%26depth_1-utm_source%3Ddistribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param)
10、python的鴨子類型?
答:不同的類,有相同的方法名稱,實現一個函數接口,當不同類實例化的時候,調用該接口函數,那么對應調用的是對應類的方法。和工廠模式類似
class Duck:
def fly(self):
print("Duck flying")
class Airplane:
def fly(self):
print("Airplane flying")
def lift\_off(entity):
[entity.fly](https://link.zhihu.com/?target=http%3A//entity.fly)()
duck = Duck()
plane = Airplane()
lift\_off(duck)
lift\_off(plane)
(2)再舉例,如果一個對象實現了\_\_getitem\_\_方法,那python的解釋器就會把它當做一個collection,就可以在這個對象上使用切片,獲取子項等方法;如果一個對象實現了\_\_iter\_\_和next方法,python就會認為它是一個iterator,就可以在這個對象上通過循環來獲取各個子項。
在鴨子類型中,關注的不是對象的類型本身,而是它是如何使用的
參考文檔:[python與鴨子類型 - Guo磊 - 博客園](https://link.zhihu.com/?target=https%3A//www.cnblogs.com/guolei2570/p/8830934.html)
11、你如何去實現一個迭代器的功能?
答:實現一個迭代器,只需要實現\_next\_\_方法就行了。如果實現一個可迭代對象,實現\_\_iter\_\_方法就可以了。
class TreeNode:
def \_\_init\_\_(self, data):
[self.data](https://link.zhihu.com/?target=http%3A//self.data)\= data
self.left = None
self.right = None
def \_\_iter\_\_(self):
return self.\_\_generator()
def \_\_generator(self):
if self.left is not None:
yield from iter(self.left)
yield from[self.data](https://link.zhihu.com/?target=http%3A//self.data)
if self.right is not None:
yield from iter(self.right)
root = TreeNode('1')
root.left = TreeNode('2')
root.right = TreeNode('3')
for ele in root:
print(ele)
\[root@localhost learn\_project\]# python3[2.py](https://link.zhihu.com/?target=http%3A//2.py)
2
1
3
(2)isinstance方法判斷某個對象是什么類型,返回True或者False的
from collections import Iterable
from collections import Iterator
class b(str):
pass
class a(b):
pass
class MyIterator(a):
def \_\_iter\_\_(self):
pass
def \_\_next\_\_(self):
pass
print(isinstance(MyIterator(), Iterable))
print(isinstance(MyIterator(), Iterator))
print(isinstance(MyIterator(), str))
\[root@localhost learn\_project\]# python3[3.py](https://link.zhihu.com/?target=http%3A//3.py)
True
True
True
參考文檔:[為什么Python不用設計模式?\_勇往直前的專欄-CSDN博客\_python 設計模式](https://link.zhihu.com/?target=https%3A//blog.csdn.net/zl1zl2zl3/article/details/88414182)
12、協程的特點。
答:協程是在單線程里實現任務的切換的
利用同步的方式去實現異步
不再需要鎖,提高了并發性能
13、yield和yield from有何區別?
答:yield是直接返回值,yield from調用子生成器進行迭代那個可迭代對象。比如yield一個列表,那么next(g)就是整個列表,而如果yield from 列表,next(g)得到的就是一個子元素
\------------------------------
\# yield接收值, 協程
def gen():
while True:
x = yield
print("x = %s"% x)
g = gen()
next(g) # 執行到yield, 激活協程 send(None) ”預激(prime)“協程,相當于g.send(None)。協程相當于兩個任務,一個是返回值,一個是發送值
g.send(10)
g.send(20)
g.send(30)
g.close()
"""
x = 10
x = 20
x = 30
"""
\---------------------
def gen( ):
yield from \["x", "y", "z"\]
\>>> g = gen()
\>>> g
\>>> next(g)
'x'
\>>> next(g)
'y'
\>>> next(g)
'z'
\>>> next(g)
Traceback (most recent call last):
File "", line 1, in
StopIteration
\----------------------------
\>>> def gen():
... yield \["x", "y", "z"\]
...
\>>> g = gen()
\>>> next(g)
\['x', 'y', 'z'\]
\>>> next(g)
Traceback (most recent call last):
File "", line 1, in
StopIteration
參考文檔:[Python并發編程之深入理解yield from語法(八)](https://link.zhihu.com/?target=https%3A//www.cnblogs.com/wongbingming/p/9085268.html)
14、多線程和多進程如何實現同步?
答:多進程用管道或信號量同步,多線程用鎖或者隊列同步,或者flag標記位,全局變量
15、DRF的序列化和反序列化是什么意思?
答:序列化:Model類對象轉換為字符串用于傳輸
反序列化:字符串轉換為Model類對象用于使用
16、深拷貝用在什么場景?
答:在修改時不想修改原對象,那么可以用深拷貝弄一個新的內存對象
17、python多繼承的順序?
答:自下而上,自左而右。
\[root@yhc-centos7 test\]# cat[a.py](https://link.zhihu.com/?target=http%3A//a.py)
class A(object):
def \_\_init\_\_(self):
print "init A Class"
class B(A):
def \_\_init\_\_(self):
print"init B class"
super(B, self).\_\_init\_\_()
class C(A):
def \_\_init\_\_(self):
print"init C class"
super(C, self).\_\_init\_\_()
class D(B,C):
def \_\_init\_\_(self):
print "init D class"
super(D, self).\_\_init\_\_()
class E(A):
def \_\_init\_\_(self):
print "init E class"
super(E, self).\_\_init\_\_()
class F(D,E):
def \_\_init\_\_(self):
print "init F class"
super(F, self).\_\_init\_\_()
F = F()
\[root@yhc-centos7 test\]# python2[a.py](https://link.zhihu.com/?target=http%3A//a.py)
init F class
init D class
init B class
init C class
init E class
init A Class
\[root@yhc-centos7 test\]#
參考文檔:[python中多重繼承與super函數用法 - Shaw\_LAU - 博客園](https://link.zhihu.com/?target=https%3A//www.cnblogs.com/FMS-Shaw/p/8531220.html)
18、super使用方法和用途?
答:super(子類名,self).\_\_init\_\_( ),調用父類的構造方法。super方法用來解決多重繼承的時候,只初始化父類的構造方法一次。不只是\_\_init\_\_方法,父類的其他方法也可以。
class C(P):
def \_\_init\_\_(self):
super(C,self).\_\_init\_\_()
print 'calling Cs construtor'
c=C()
19、如何訪問類的屬性?
答:(1)定義@classmethod方法,傳參cls,訪問屬性。類不需要實例化,就可以調用該裝飾器裝飾的方法
(2)直接類名.屬性操作即可。
(3)當然類方法,實例也可以調用,但是并沒有什么用,違反了初衷:類方法就是專門供類使用
(4)@classmethod只能訪問類屬性,不能訪問實例屬性。
\[root@yhc-centos7 test\]# cat[c.py](https://link.zhihu.com/?target=http%3A//c.py)
class cal:
cal\_name = '計算器'
def \_\_init\_\_(self,x,y):
self.x = x
self.y = y
@property #在cal\_add函數前加上@property,使得該函數可直接調用,封裝起來
def cal\_add(self):
return self.x + self.y
@classmethod #在cal\_info函數前加上@classmethond,則該函數變為類方法,該函數只能訪問到類的數據屬性,不能獲取實例的數據屬性
def cal\_info(cls): #python自動傳入位置參數cls就是類本身
print('這是一個%s'%cls.cal\_name) #cls.cal\_name調用類自己的數據屬性
cal.cal\_info() #>>> '這是一個計算器'
a = cal(1,2)
c = a.cal\_add
print (c)
\[root@yhc-centos7 test\]# python3[c.py](https://link.zhihu.com/?target=http%3A//c.py)
這是一個計算器
3
\[root@yhc-centos7 test\]#
參考文檔:[Python中@staticmethod和@classmethod的作用和區別 - 愛學習的小象 - 博客園](https://link.zhihu.com/?target=https%3A//www.cnblogs.com/ltb6w/p/11875480.html)
20、說下Python自省?
答:Python 是一門動態語言,有了自省,就能讓程序在運行時能夠獲知對象的類型以及該對象下有哪些方法等。
dir方法、type()、id方法
hasattr():但是,有時我們只想測試一個或多個屬性是否存在。如果對象具有我們正在考慮的屬性,那么通常希望只檢索該屬性。這個任務可以由 hasattr() 來完成.>>> import json >>> hasattr(json, "dumps")
getattr():使用 hasattr 獲知了對象擁有某個屬性后,可以搭配 getattr() 函數來獲取其屬性值。
\>>> dumps = getattr(json, "dumps")
\>>> dumps({"name": "MING"})
'{"name": "MING"}'
\>>>
- 常見面試題
- 一.Java常見面試題
- 1.Java基礎
- 3.面向對象概念
- 10.Java面試題
- Java基礎知識面試題(總結最全面的面試題)
- 設計模式面試題(總結最全面的面試題)
- Java集合面試題(總結最全面的面試題)
- JavaIO、BIO、NIO、AIO、Netty面試題(總結最全面的面試題)
- Java并發編程面試題(總結最全面的面試題)
- Java異常面試題(總結最全面的面試題)
- Java虛擬機(JVM)面試題(總結最全面的面試題)
- Spring面試題(總結最全面的面試題)
- Spring MVC面試題(總結最全面的面試題)
- Spring Boot面試題(總結最全面的面試題)
- Spring Cloud面試題(總結最全面的面試題)
- Redis面試題(總結最全面的面試題)
- MyBatis面試題(總結最全面的面試題)
- TCP、UDP、Socket、HTTP面試題(總結最全面的面試題)
- 二、MySQL面試題
- 1.基礎部分
- MySQL面試題(總結最全面的面試題)
- HBase相關面試題整理
- Nginx面試題(總結最全面的面試題)
- RabbitMQ面試題(總結最全面的面試題)
- Dubbo面試題(總結最全面的面試題)
- ZooKeeper面試題(總結最全面的面試題)
- Tomcat面試題(總結最全面的面試題)
- Linux面試題(總結最全面的面試題)
- 超詳細的Django面試題
- SSM面試題
- 15個高頻微信小程序面試題
- VUE面試題
- Python面試題
- 二、常見問題解答列表
- 1.查看端口及殺死進程
- 三、學習電子書