天天看點

Python常見面試題集錦

1.一行代碼輸出九九乘法表

print ('\n'.join([' '.join(['%s*%s=%s '%(j,i,j*i) for j in range(1,i+1)]) for i in range(1,10)]))
           

分析:

利用Python中的模闆字元串,清單生成式,還有Python中的join方法(Python join() 方法用于将序列中的元素以指定的字元連接配接生成一個新的字元串。格式:“,”.join(seq))

# arr = "\n".join([",".join(['%s*%s=%s '%(j,i,j*i) for j in range(1,i+1)]) for i in range(1,10)])
obj = (i for i in range(1,10))
print ('i for i in range(1,10)輸出結果:',obj)
# 輸出:<generator object <genexpr> at 0x0157FDF0>
# i for i in range(1,10) 這個語句生成一個疊代器對象  如果想将這個對象的值列印出來  可以将其轉化為清單
list = [i for i in range(1,10)]
print('list輸出:',list)
# 輸出    list輸出: [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(['%s*%s=%s'%(j,i,j*i) for j in range(1,i+1)] for i in range(1,10))
# 輸出:<generator object <genexpr> at 0x003CFE70>
print(','.join(['%s*%s=%s'%(j,i,j*i) for j in range(1,i+1)]) for i in range(1,10))
# 輸出:<generator object <genexpr> at 0x003CFE70>
# 此時,僅僅是将列的輸出轉化為字元串形式,沒有将行的輸出轉化為字元串,是以還需要進行下一步轉換
print('\n'.join([' '.join(['%s*%s=%s'%(j,i,j*i) for j in range(1,i+1)]) for i in range(1,10)] ))
# 将\n 指派給 join的連結符 實作輸出一行時候進行換行操作

           

2.對函數流程控制的了解

def partition(L,p,r):
    x = L[r]
    i = p - 1
    for j in range(p,r):
        if L[j] <= x:
            i += 1
            L[i],L[j] = L[j],L[i]
    L[i+1],L[r] = L[r],L[i+1]
A = [3,1,7,2,6,8,4,5]
partition(A,0,len(A)-1)
print(A)

# 分析:
'''
L=[3,1,7,2,6,8,4,5]  index=7  len=8          p=0         r=len(A)-1=7
進入函數:x=L[r]=5  i=p-1=-1   
            進入循環:range(p=0,r=7) j=0-7 
                    進入判斷:L[j=0] <= x=L[r]=5
                                    i = i+1  => -1+1=0
                                    L[i=0],L[j=0] = 3,3
                                L[j=1]  <= x=L[r]=5
                                    i += 1  => i=1
                                    L[i=1],L[j=1] = 1,1
                                L[j=2]  <= x=L[r]=5
                                   pass
                                L[j=3]  <= x=L[r]=5
                                    i += 1  => i=2
                                    L[i=2],L[j=3] = 2,7       -------->L=[3,1,2,7,6,8,4,5]
                                L[j=4]=6  <= x=L[r]=5
                                    pass
                                L[j=5]=8  <= x=L[r]=5
                                    pass
                                L[j=6]=4  <= x=L[r]=5
                                    i += 1   => i=3
                                    L[i=3],L[j=6] = L[j],L[i]  ------>L=[3,1,2,4,6,8,7,5]
                               
            L[i+1],L[r] = L[r],L[i+1]   
            => L[3+1=4],L[7] = L[7],L[4]     ------->  ==> L=[3,1,2,4,5,8,7,6]  
==> L=[3,1,2,4,5,8,7,6]          
'''
           

3.類的繼承

class A(object):
    name = "A"
class B(object):
    name = "B"
class C(A,B):
    pass
print(C.name)   # =>  先繼承的A  輸出A
C.name = "C"
print(A.name)   # => A
print(B.name)   # =>B
print(C.name)   # =>C
           

4.大資料的檔案讀取

(1)讀取大幾 G 的大檔案,可以利用生成器 generator

(2)對可疊代對象 file,進行疊代周遊:for line in file,會 自動地使用緩沖 IO(buffered IO)以及記憶體管理,而不必擔心任何 大檔案的問題。

with open('filename') as file:
  for line in file:
  do_things(line)
           

5.疊代器和生成器

( 1)疊代器是一個更抽象的概念,任何類,如果它有 next 方法和 iter 方法傳回自己本身 。對于 strings、 list、 dict、 tuple 等這類容器對象,使用 for 循環周遊是很友善的。在背景 for 語句 對容器象調用 iter()函數,iter()是 python 的内置函數。iter() 會傳回一個定義 next()方法的疊代器對象,它在容器中逐個通路容 器内元素, next()也是 python 的内置函數。在沒有後續元素時, next()會 抛出一個 StopIteration 異常

(2)生成器( Generator)是建立疊代器的簡單而強大工具。 它們寫起來就像是正規的函數,隻在需要傳回據時候使用 yield 語 句。每次 next()被調用,生成器會傳回它脫離的位置,記憶語句最 後一次執行和所有資料。 差別:生成器能做到疊代的所有事 ,而且因為自動建立了 iter()和 next()方法 ,生成器顯得特别簡潔 ,而且生成器也是 高效的 ,使用生成器表 達式取代列解析可以同時節省 記憶體。除了 建立和保程式狀态的自動方法,當發生器終結時 ,還會自動抛出 StopIteration 異常

6.線程、程序、協程

程序是具有一定獨立功能的程式關于某個資料集合上的一次運 行活動,程序是系統進行資源配置設定和排程的一個獨立機關。每個程序 都有自己的獨立記憶體空間,不同程序通過程序間通信來通信。由于進 程比較重量,占據獨立的記憶體,是以上下文程序間的切換開銷(棧、 寄存器、虛拟記憶體、檔案句柄等)比較大,但相對比較穩定安全

線程是程序的一個實體,是 CPU 排程和分派的基本機關,它 是比程序更小的能獨立運作的基本機關.線程自己基本上不擁有系統 資源,隻擁有一點在運作中必不可少的資源(如程式計數器,一組寄存 器和棧),但是它可與同屬一個程序的其他的線程共享程序所擁有的 全部資源。線程間通信主要通過共享記憶體,上下文切換很快,資源開 銷較少,但相比程序不夠穩定容易丢失資料。

協程是一種使用者态的輕量級線程,協程的排程完全由使用者控制。 協程擁有自己的寄存器上下文和棧。協程排程切換時,将寄存器上下 文和棧儲存到其他地方,在切回來的時候,恢複先前儲存的寄存器上 下文和棧,直接操作棧則基本沒有核心切換的開銷,可以不加鎖的訪 問全局變量,是以上下文的切換非常快。

7.裝飾器

裝飾器是一個很著名的設計模式,經常被用于有切面需求的場景, 較為經典的有插入日志、性能測試、事務處理等。裝飾器是解決這類 問題的絕佳設計,有了裝飾器,我們就可以抽離出大量函數中與函數 功能本身無關的雷同代碼并繼續重用。概括的講,裝飾器的作用就是 為已經存在的對象添加額外的功能

裝飾器(decorator)裡引入通用功能處理:

  • 引入日志
  • 函數執行時間統計
  • 執行函數前預備處理
  • 權限校驗等場景
  • 緩存
from time import ctime, sleep
def timefun(func):
  def wrappedfunc():
      print("%s called at %s"%(func.__name__,ctime()))
      return func()
  return wrappedfunc
@timefun
def foo():
  print("I am foo")
foo()
sleep(2)
foo()
           

8.談談你對同步異步阻塞非阻塞了解

所謂同步,就是在發出一個功能調用時,在沒有得到結果之前,該 調用就不傳回。按照這個定義,其實絕大多數函數都是同步調用(例 如 sin, isdigit 等)。但是一般而言,我們在說同步、異步的時候, 特指那些需要其他部件協作或者需要一定時間完成的任務。最常見的 例子就是 SendMessage。該函數發送一個消息給某個視窗,在對方處 理完消息之前,這個函數不傳回。當對方處理完畢以後,該函數才把 消息處理函數所傳回的 LRESULT 值傳回給調用者。

異步的概念和同步相對。當一個異步過程調用發出後,調用者不能 立刻得到結果。實際處理這個調用的部件在完成後,通過狀态、通知 和回調來通知調用者。以 CAsycSocket 類為例(注意,CSocket 從 CAsyncSocket 派生,但是起功能已經由異步轉化為同步),當一個 用戶端通過調用 Connect 函數發出一個連接配接請求後,調用者線程立 刻可以朝下運作。當連接配接真正建立起來以後,socket 底層會發送一 個消息通知該對象。這裡提到執行部件和調用者通過三種途徑傳回結 果:狀态、通知和回調。可以使用哪一種依賴于執行部件的實作,除 非執行部件提供多種選擇,否則不受調用者控制。如果執行部件用狀 态來通知,那麼調用者就需要每隔一定時間檢查一次,效率就很低(有 些初學多線程程式設計的人,總喜歡用一個循環去檢查某個變量的值,這 其實是一種很嚴重的錯誤)。如果是使用通知的方式,效率則很高, 因為執行部件幾乎不需要做額外的操作。至于回調函數,其實和通知 沒太多差別。

阻塞調用是指調用結果傳回之前,目前線程會被挂起。函數隻有在 得到結果之後才會傳回。有人也許會把阻塞調用和同步調用等同起來, 實際上他是不同的。對于同步調用來說,很多時候目前線程還是激活 的,隻是從邏輯上目前函數沒有傳回而已。例如,我們在 CSocket 中 調用 Receive 函數,如果緩沖區中沒有資料,這個函數就會一直等待, 直到有資料才傳回。而此時,目前線程還會繼續處理各種各樣的消息。 如果主視窗和調用函數在同一個線程中,除非你在特殊的界面操作函 數中調用,其實主界面還是應該可以重新整理。socket 接收資料的另外 一個函數 recv 則是一個阻塞調用的例子。當 socket 工作在阻塞模式 的時候,如果沒有資料的情況下調用該函數,則目前線程就會被挂起, 直到有資料為止。

非阻塞和阻塞的概念相對應,指在不能立刻得到結果之前,該函數 不會阻塞目前線程,而會立刻傳回。

對象的阻塞模式和阻塞函數調用。對象是否處于阻塞模式和函數是 不是阻塞調用有很強的相關性,但是并不是一一對應的。阻塞對象上 可以有非阻塞的調用方式,我們可以通過一定的 API 去輪詢狀态,在 适當的時候調用阻塞函數,就可以避免阻塞。而對于非阻塞對象,調 用特殊的函數也可以進入阻塞調用。函數 select 就是這樣的一個例子。

9.GIL 對多線程的影響?

GIL 的全稱是 Global Interpreter Lock(全局解釋器鎖),來源 是 python 設計之初的考慮,為了資料安全所做的決定。每個 CPU 在 同一時間隻能執行一個線程(在單核 CPU 下的多線程其實都隻是并發, 不是并行,并發和并行從宏觀上來講都是同時處理多路請求的概念。 但并發和并行又有差別,并行是指兩個或者多個事件在同一時刻發生; 而并發是指兩個或多個事件在同一時間間隔内發生。)

可見,某個線程想要執行,必須先拿到 GIL,我們可以把 GIL 看 作是“通行證”,并且在一個 python 程序中,GIL 隻有一個。拿不 到通行證的線程,就不允許進入 CPU 執行。

在 Python2.x 裡,GIL 的釋放邏輯是目前線程遇見 IO 操作或者 ticks 計數達到 100(ticks 可以看作是 Python 自身的一個計數器, 專門做用于 GIL,每次釋放後歸零,這個計數可以通過 sys.setcheckinterval 來調整),進行釋放。而每次釋放 GIL 鎖, 線程進行鎖競争、切換線程,會消耗資源。并且由于 GIL 鎖存在, python 裡一個程序永遠隻能同時執行一個線程(拿到 GIL 的線程才能 執行)。

IO 密集型代碼(檔案處理、網絡爬蟲等),多線程能夠有效提升 效率(單線程下有 IO 操作會進行 IO 等待,造成不必要的時間浪費, 而開啟多線程能線上程 A 等待時,自動切換到線程 B,可以不浪費 CPU 的資源,進而能提升程式執行效率),是以多線程對 IO 密集型代碼比 較友好。

在 Python 多線程下,每個線程的執行方式:

  • 擷取GIL
  • 執行代碼知道sleep或者是python虛拟機講其挂起
  • 釋放GIL

10.python 中的反射?

python中反射的核心本質其實就是利用字元串的形式去對象 (模 塊)中操作(查找/擷取/删除/添加)成員,一種基于字元串的事件 驅動。

11.python2 和 python3 的差別?
  1. 性能 Py3.0 運作 pystone benchmark 的速度比 Py2.5 慢 30%。Guido 認為 Py3.0 有極大的優化 空間,在字元串和整形操作上可 以取得很好的優化結果。 Py3.1 性能比 Py2.5 慢 15%,還有很大的提升空間。
  2. 編碼 Py3.X 源碼檔案預設使用 utf-8 編碼,這就使得以下代碼是合法的: >>> 中國 = 'china' >>>print(中國) china
  3. 文法 (1)去除了<>,全部改用!=。(2)去除``,全部改用 repr()(3)關鍵詞加入 as 和 with,還有 True,False,None。(4)整型除法傳回浮點數,要得到整型結果,請使用// 。(5)加入 nonlocal 語句。使用 noclocal x 可以直接指派外圍(非全局)變量。(6)去除 print 語句,加入 print()函數實作相同的功能。同樣的還有 exec 語句, 已經改為 exec() 函數 (7)改變了順序操作符的行為,例如 x<y,當 x 和 y 類型不比對時抛出 TypeError 而不是返 回随即的 bool 值 (8)輸入函數改變了,删除了 raw_input,用 input 代替: (9)去除元組參數解包。不能 def(a, (b, c)):pass 這樣定義函數了。(10)新式的 8 進制字變量,相應地修改了 oct()函數。(11)增加了 2 進制字面量和 bin()函數 。(12)擴充的可疊代解包。在 Py3.X 裡,a,b,*rest=seq 和 *rest,a=seq 都是合法的, 隻要求兩點:rest 是 list 對象和 seq 是可疊代的。(13)新的 super(),可以不再給 super()傳參數。 (14)新的 metaclass 文法。(15)支援 class decorator。用法與函數 decorator 一樣。(16)現在字元串隻有 str 一種類型,但它跟 2.x 版本的 unicode 幾乎一樣。 (17)Py3.X 去除了 long 類型,現在隻有一種整型——int,但它的行為就像 2.X 版本的 long 。(18)新增了 bytes 類型,對應于 2.X 版本的八位串,定義一個 bytes 字面量的方法如下: str 對象和 bytes 對象可以使用.encode() (str-> bytes)or .decode()(bytes-> str)方法互相 轉化。 (19)dict 的.keys()、.items 和.values()方法傳回疊代器,而之前的 iterkeys()等函數都被 廢棄。同時去掉的還有 dict.has_key(),用 in 替代它吧 。(20)引入抽象基類(Abstraact Base Classes,ABCs)。 (21)容器類和疊代器類被 ABCs 化,是以 cellections 子產品裡的類型比 Py2.5 多了很多。 (22)疊代器的 next()方法改名為__next__(),并增加内置函數 next(),用以調用疊代器的 next()方法 (23)增加了@abstractmethod 和 @abstractproperty 兩個 decorator,編寫抽象方法(屬性) 更加友善。(24)是以異常都從 BaseException 繼承,并删除了 StardardError 。(25)去除了異常類的序列行為和.message 屬性 。(26)用 raise Exception(args)代替 raise Exception, args 文法。(27)捕獲異常的文法改變,引入了 as 關鍵字來辨別異常執行個體。(28)異常鍊,因為__context__在 3.0a1 版本中沒有實作。(29)移除了 cPickle 子產品,可以使用 pickle。 子產品代替。最終我們将會有一個透明高效的子產品。(30)移除了 imageop 子產品。 (31))移除了 audiodev, Bastion, bsddb185, exceptions, linuxaudiodev, md5, MimeWriter, mimify, popen2, rexec, sets, sha, stringold, strop, sunaudiodev, timing 和 xmllib 子產品。(32)移除了 bsddb 子產品(單獨釋出,可以從 http://www.jcea.es/programacion/pybsddb.htm 獲 取)。(33)移除了 new 子產品 (34)os.tmpnam()和 os.tmpfile()函數被移動到 tmpfile 子產品下 。(35)tokenize 子產品現在使用 bytes 工作。主要的入口點不再是 generate_tokens,而是 tokenize.tokenize()。(36)

12.什麼是線程安全

線程安全是在多線程的環境下,能夠保證多個線程同時執行時程式依舊運作正 确, 而且要保證對于共享的資料可以由多個線程存取,但是同一時刻隻能有一個線 程進行存取。多線程環境下解決資源競争問題的辦法是加鎖來保證存取操作的唯一 性。

13.十個常用的 linux 指令

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

14.find 和 grep?

grep 指令是一種強大的文本搜尋工具,grep 搜尋内容串可以是正規表達式, 允許對文本檔案進行模式查找。如果找到比對模式, grep 列印包含模式的所有行。

find 通常用來在特定的目錄下搜尋符合條件的檔案,也可以用來搜尋特定使用者 屬主的檔案。

15.什麼是面向對象程式設計

面向對象程式設計是一種解決軟體複用的設計和程式設計方法。 這種方法把軟體系統中 相近相似的操作邏輯和操作 應用資料、狀态,以類的型式描述出來,以對象執行個體的形式 在軟體系統中複用,以達到提高軟體開發效率的作用。

16.面向對象有那些技術?

類(Class): 用來描述具有相同的屬性和方法的對象的集合。它定義了該集合中每個 對象所共有的屬性和方法。對象是類的執行個體。

類變量:類變量在整個執行個體化的對象中是公用的。類變量定義在類中且在函數體 之外。類變量通常不作為執行個體變量使用。 資料成員:類變量或者執行個體變量用于處理類及其執行個體對象的相關的資料。

方法重寫:如果從父類繼承的方法不能滿足子類的需求,可以對其進行改寫,這 個過程叫方法的覆寫(override),也稱為方法的重寫。

執行個體變量:定義在方法中的變量,隻作用于目前執行個體的類。

繼承:即一個派生類(derived class)繼承基類(base class)的字段和方法。 繼承也允許把一個派生類的對象作為一個基類對象對待。例如,有這樣一個設計:一 個 Dog 類型的對象派生自 Animal 類,這是模拟"是一個(is-a)"關系(例圖,Dog 是一個 Animal)。

執行個體化:建立一個類的執行個體,類的具體對象。

方法:類中定義的函數。

對象:通過類定義的資料結構執行個體。對象包括兩個資料成員(類變量和執行個體變量) 和方法。

17.靜态方法和類方法?

靜态方法:需要通過修飾器@staticmethod 來進行修飾,靜态方法不需要多 定義參數。

類方法:類方法是類對象所擁有的方法,需要用修飾器@classmethod 來辨別 其為類方法,對于類方法,第一個參數必須是類對象,一般以 cls 作為第一個參 數(也可以用其他名稱的變量作為其第一個參數),能夠通過執行個體對象和類對象 去通路。

18.類屬性、執行個體屬性?

類屬性:定義在類裡面但在函數外面的變量,是靜态的。類對象所擁有的屬性,它被 所有類對象的執行個體對象所共有,在記憶體中隻存在一個副本。對于公有的類屬性,在類外可 以通過類對象和執行個體對象通路。

執行個體屬性:定義在__init__()方法裡的變量就是執行個體屬性,這些屬性隻有被建立時才會 被建立。

當類屬性與執行個體屬性同名時,一個執行個體通路這個屬性時執行個體屬性會覆寫類屬性

19.如果需要執行一個定時任務,你會怎麼做?

Linux 的 Crontab 執行指令:sudocrontab-e

例:0 */1 * * * /usr/local/etc/rc.d/lighttpd restart 每一小時重新開機 apache

20.線上服務可能因為種種原因導緻挂掉怎麼辦?

Linux 下的背景程序管理利器 supervisor

每次檔案修改後在linux執行:service supervisord restart

21.python 的多程序與多線程的運作機制是什麼?有什麼差別? 分别在什麼情況下用?

運作機制:程序是具有一定獨立功能的程式關于某個資料集合上的一次運作活動,程序是 系統進行資源配置設定和排程的一個獨立機關

線程是程序的一個實體,是 CPU排程和分派的基本機關,它是比程序更小的能獨立 運作的基本機關.線程自己基本上不擁有系統資源,隻擁有一點在運作中必不可少的資源 (如果制造資料的速度時快時慢,緩沖區的好處就展現出來了。當資料制造快的時候,消 費者來不及處理,未處理的資料可以暫時存在緩沖區中。

程式計數器,一組寄存器和棧),但是它可與同屬一個程序的其他的線程共享程序所擁有 的全部資源.

差別:

多程序穩定性好,一個子程序崩潰了,不會影響主程序以及其餘程序。但是缺點是創 建程序的代價非常大,因為作業系統要給每個程序配置設定固定的資源,并且,作業系統對進 程的總數會有一定的限制,若程序過多,作業系統排程都會存在問題,會造成假死狀态。 多線程效率較高一些,但是緻命的缺點是任何一個線程崩潰都可能造成整個程序的崩 潰,因為它們共享了程序的記憶體資源池。 使用情況:如果代碼是IO密集型的,多線程。

如果代碼是CPU 密集型的,多程序是更好的選擇——特别是所使用的機器是多核 或多CPU的。

22.如何提高 Python 的運作效率,請說出不少于 2 種提高運作效 率的方法。

使用生成器

關鍵代碼使用外部功能包:Cython、Pylnlne、PyPy、Pyrex

針對循環的優化——盡量避免在循環中通路變量的屬性;

23.介紹下“消費者”和“生産者”模型。

生産者-消費者模型是多線程同步的經典案例。此模型中生産者向緩沖區 push資料,消 費者從緩沖區中pull資料。

這個Demo 中緩沖區用python 實作的Queue 來做,這個子產品是線程安全的使開發者不 用再為隊列增加額外的互斥鎖.

信号處理的實作是這樣的:

1)主線程接到一個 SIGTERM 的信号後先通知Consumer停止向緩沖區 push資料并退 出

2)Produer将緩沖區中的資料消費完全後在退出

3)主線程退出

24.生産者消費者模型的優點:

1、解耦

假設生産者和消費者分别是兩個類。如果讓生産者直接調用消費者的某個方法,那麼生産 者對于消費者就會産生依賴(也就是耦合)。将來如果消費者的代碼發生變化, 可能會 影響到生産者。而如果兩者都依賴于某個緩沖區,兩者之間不直接依賴,耦合也就相應降 低了。

2、支援并發

由于生産者與消費者是兩個獨立的并發體,他們之間是用緩沖區作為橋梁連接配接,生産者隻 需要往緩沖區裡丢資料,就可以繼續生産下一個資料,而消費者隻需要從緩沖區了拿資料 即可,這樣就不會因為彼此的處理速度而發生阻塞。

3、支援忙閑不均

如果制造資料的速度時快時慢,緩沖區的好處就展現出來了。當資料制造快的時候,消費 者來不及處理,未處理的資料可以暫時存在緩沖區中。 等生産者的制造速度慢下來,消 費者再慢慢處理掉。

25.MySQL如何做分頁

mysql資料庫做分頁用limit關鍵字,它後面跟兩個參數startIndex和pageSize

26.mysql引擎有哪些,各自的特點是什麼?

innodb和myisam兩個引擎,兩者差別是

innodb支援事物,myisam不支援

innodb支援外鍵,myisam不支援

innodb不支援全文索引,myisam支援全文索引

innodb提供送出、復原、崩潰恢複能力的事物的安全能力,實作并發控制

myisam提供較高的插入和查詢記錄的效率,主要用于插入和查詢

27.資料庫怎麼建立索引
create index account_index on `table name `(`字段名`(length))
           
28.一張表多個字段,怎麼建立組合索引
create index account_index on `table name `(`字段名`,'字段名')
           
29.如何應對資料的高并發,大量的資料計算
  1. 建立索引
  2. 資料庫讀寫分離,兩個資料庫,一個作為寫,一個作為讀
  3. 外鍵去掉
  4. django中orm表性能相關的。select_related:一對多使用,查詢主動做連表。prefetch_related:多對多或者一對多的時候使用,不做連表,做多次查詢

30.資料庫内連表、左連表、右連表

内連接配接是根據某個條件連接配接兩個表共有的資料

左連接配接是根據某個條件以及左邊的表連接配接資料,右邊的表沒有資料的話則為null

右連接配接是根據某個條件以及右邊的表連接配接資料,左邊的表沒有資料的話則為null

31.視圖和表的差別

視圖是已經編譯好的sql語句,是基于sql語句的結果集的可視化的表,而表不是。

視圖是視窗,表示内容

視圖沒有實際的實體記錄,而表有。 視圖的建立和删除隻影響視圖本身,不影響對應的表。

32.關系型資料庫的特點
  • 資料集中控制
  • 資料獨立性高
  • 資料共享性好
  • 資料備援度小
  • 資料結構化
  • 統一的資料保護能力

33.MySQL資料庫都有哪些索引

普通索引:普通索引僅有一個功能:加速查找 唯一索引:唯一索引兩個功能:加速查找和唯一限制(可含null)

外鍵索引:外鍵索引兩個功能:加速查找和唯一限制(不可為null)

聯合索引:聯合索引是将n個列組合成一個索引,應用場景:同時使用n列來進行查詢

34.存儲過程

存儲過程不允許執行return語句,但是可以通過out參數傳回多個值,存儲過程一般是作為一個獨立的部分來執行,存儲過程是一個預編譯的SQL語句。

35.sql優化:
  • select句中避免使用 '*'
  • 減少通路資料庫的次數
  • 删除重複記錄
  • 用where子句替代having子句
  • 減少對表的查詢
  • explain

36.char和vachar差別:

char是固定長度,存儲需要空間12個位元組,處理速度比vachar快,費記憶體空間

vachar是不固定長度,需要存儲空間13個位元組,節約存儲空間

37.Mechached與redis

mechached:隻支援字元串,不能持久化,資料僅存在記憶體中,當機或重新開機資料将全部失效

不能進行分布式擴充,檔案無法異步法。

優點:mechached程序運作之後,會預申請一塊較大的記憶體空間,自己進行管理。

redis:支援伺服器端的資料類型,redis與memcached相比來說,擁有更多的資料結構和并發支援更豐富的資料操作,可持久化。

五大類型資料:string、hash、list、set和有序集合,redis是單程序單線程的。

缺點:資料庫的容量受到實體記憶體的限制。

38.SQL注入

sql注入是比較常見的攻擊方式之一,針對程式設計員程式設計的疏忽,通過sql語句,實作賬号無法登陸,甚至篡改資料庫

防止:凡涉及到執行sql中有變量時,切記不要用拼接字元串的方法

39.什麼是觸發器

是對查詢出來的結果集作為一個單元來有效的處理,遊标可以定在該單元中的特定行,從結果集的目前行檢索一行或多行,可以對結果集目前行做修改,一般不使用遊标,但是需要逐條處理資料的時候,遊标顯得十分重要

40.資料庫支援多有标準的SQL資料類型,重要分為三類

數值類型(tinyint,int,bigint,浮點數,bit)

字元串類型(char和vachar,enum,text,set)

日期類型(date,datetime,timestamp)

41.MySQL慢查詢

慢查詢對于跟蹤有問題的查詢很有用,可以分析出目前程式裡哪些sql語句比較耗費資源

慢查詢定義:

指mysql記錄所有執行超過long_query_time參數設定的時間值的sql語句,慢查詢日志就是記錄這些sql的日志。

mysql在windows系統中的配置檔案一般是my.ini找到mysqld

log-slow-queries = F:\MySQL\log\mysqlslowquery.log 為慢查詢日志存放的位置,一般要有可寫權限

long_query_time = 2 2表示查詢超過兩秒才記錄

42.memcached命中率

命中:可以直接通過緩存擷取到需要的資料

不命中:無法直接通過緩存擷取到想要的資料,需要再次查詢資料庫或者執行其他的操作,原因可能是由于緩存中根本不存在,或者緩存已經過期

緩存的命中率越高則表示使用緩存的收益越高,應額用的性能越好,抗病發能力越強

運作state指令可以檢視memcached服務的狀态資訊,其中cmd—get表示總的get次數,get—hits表示命中次數,命中率=get—hits / cmd—get

43.Oracle和MySQL該如何選擇,為什麼?

他們都有各自的優點和缺點。考慮到時間因素,我傾向于MySQL

選擇MySQL而不選Oracle的原因

  • MySQL開源
  • MySQL輕便快捷
  • MySQL對指令行和圖形界面的支援都很好
  • MySQL支援通過Query Browser進行管理
44.什麼情況下适合建立索引?
  1. 為經常出現在關鍵字order by、group by、distinct後面的字段,建立索引
  2. 在union等集合操作的結果集字段上,建立索引,其建立索引的目的同上
  3. 為經常用作查詢選擇的字段,建立索引
  4. 在經常用作表連接配接的屬性上,建立索引

45.資料庫底層是用什麼結構實作的,你大緻畫一下:

底層用B+數實作,結構圖參考:

http://blog.csdn.net/cjfeii/article/details/10858721

http://blog.csdn.net/tonyxf121/article/details/8393545

46.sql語句應該考慮哪些安全性?
  1. 防止sql注入,對特殊字元進行轉義,過濾或者使用預編譯的sql語句綁定變量
  2. 最小權限原則,特别是不要用root賬戶,為不同的類型的動作或者組建使用不同的賬戶
  3. 當sql運作出錯時,不要把資料庫傳回的錯誤資訊全部顯示給使用者,以防止洩漏伺服器和資料庫相關資訊

47.資料庫事物有哪幾種?

隔離性、持續性、一緻性、原子性

48.MySQ資料表在什麼情況下容易損壞?

伺服器突然斷電導緻資料檔案損壞

強制關機,沒有先關閉mysq伺服器等

49.drop,delete與truncate的差別

drop直接删除表

truncate删除表中資料,再插入時自增長id又從1開始 delete删除表中資料,可以加where子句

50.資料庫範式
  1. 第一範式:就是無重複的列
  2. 第二範式:就是非主屬性非部分依賴于主關鍵字
  3. 第三範式:就是屬性不依賴于其他非主屬性(消除備援)

51.MySQL鎖類型

根據鎖的類型分:可以分為共享鎖、排他鎖、意向共享鎖和意向排他鎖

根據鎖的粒度分:可以分為行鎖、表鎖

對于mysql而言,事務機制更多是靠底層的存儲引擎來實作的,是以,mysql層面隻有表鎖,說明:對于更新操作(讀不上鎖),隻有走索引才可能上行鎖

MVCC(多版本并發控制)并發控制機制下,任何操作都不會阻塞讀取操作,讀取操作也不會阻塞任何操作,隻因為讀不上鎖

共享鎖:由讀表操作加上的鎖,加鎖後其他使用者隻能擷取該表或行的共享鎖,不能擷取排他鎖,也就是說隻能讀不能寫 排他鎖:由寫表操作加上的鎖,加鎖後其他使用者不能擷取該表或該行的任何鎖,典型mysql事物中的更新操作

意向共享鎖(IS):事物打算給資料行加行共享鎖,事物在給一個資料行加共享鎖前必須先取得該表的IS鎖

意向排他鎖(IX):事物打算給資料行加行排他鎖,事物在給一個資料行家排他鎖前必須先取得該表的IX鎖

52.如何解決MYSQL資料庫中文亂碼問題?
  1. 在資料庫安裝的時候指定字元集
  2. 如果在按完了以後可以更改配置檔案
  3. 建立資料庫時候:指定字元集類型
  4. 建表的時候也指定字元集
53.資料庫應用系統設計
  1. 規劃
  2. 需求分析
  3. 概念模型設計
  4. 邏輯設計
  5. 實體設計
  6. 程式編制及調試
  7. 運作及維護

54.資料庫常見面試問題總結

https://yq.aliyun.com/wenji/

55.中間件

中間件一般做認證或批量請求處理,django中的中間件,其實是一個類,在請求和結束後,django會根據自己的規則在合适的時機執行中間件中相應的方法,如請求過來 執行process_request, view,process_response方法

56.Django、Tornado、Flask各自的優勢

Django:Django無socket,django的目的是簡便,快速開發,并遵循MVC設計,多個元件可以很友善的以“插件”形式服務于整個架構

django有許多功能強大的第三方插件。django具有很強的可擴充性

Tornado:它是非阻塞式伺服器,而且速度相當快,得力于其 非阻塞的方式和對epoll的運用,Future對象,缺點:沒有session,需要自定制

Flask:是一個微型的web架構,配合SQLALchemy來使用,jinja2模闆, werkzeug接口

57.django的template的注釋是什麼樣子的

單行:{#注釋#}

多行注釋:{%comment%}

58.Django怎麼弄并發的

nginx+uwsig為django提供高并發,nginx的并發能力超過,單台并發能力過完,在純靜态的web服務中更是突出其優越的地方,由于底層使用epoll異步IO模型進行處理。

59.tornodo的ioloop知道是什麼嗎?

事件循環

select_related和prefetch_related,Q和F

select_related:一對多使用,查詢主動做連表

prefetch_related:多對多或者一對多的時候使用,不做連表,做多次查詢

Q:用于構造複雜查詢條件

F:更新時用于擷取原來的值,專門取對象中某一列進行操作

60.什麼是ORM?

ORM,即Object-Relational Mapping(對象關系映射),它的作用是在關系型資料庫和業務實體對象之間做一個映射 ORM優缺點:

優點:擺脫複雜的SQL操作,适應快速開發,讓資料結果變得簡單,資料庫遷移成本更低

缺點:性能較差,不适用于大型應用,複雜的SQL操作還需要通過SQL語句實作

61.CORS跨域資源共享

首先會發送"預檢"opption",請求,如果"預檢"成功,則發送真實資料。

62.Django的Form主要具有以下功能?

生成HTMl标簽,驗證使用者資料 is_vaild,HTML Form送出保留上次送出資料,初始化頁面顯示内容

63.CBV和FBV

CBV在指定的類上面加上裝飾器或在此方法上面添加裝飾器 @method_decorator,并繼承view

64.cookie及session

cookie:是保留在用戶端上面的一組鍵值對,cookie不是很安全,别人可以分析存放在本地的cookie

session:是儲存在伺服器上面的一組鍵值對,依賴與cookie,安全指數比cookie高

65.django的請求生命周期

請求來了先到uwsgi,把請求做一部分分裝給django架構,然後經過所有的中間件,路由,視圖,視圖處理再傳回給中間件,中間件在傳回給uwsgi,在傳回給使用者。

66.uwsgi和wsgi

wsgi:是web伺服器網關接口,是pyhton應用程式或架構和web伺服器之間的一種接口,其廣泛使用的是django架構。 wsgi:是一個web伺服器,它實作了wsgi協定,Nginx中HttpUwsgiModule的作用是與Uwsgi伺服器進行交換

67.解釋下django-debug-toolbar的使用

使用django開發站點時,可以使用django-debug-toolbar來進行調試,在settings.py中添加 'debug—toolbar.midleware.Debug ToolbarMiddleware'到項目的MIDDLEWARE_CLASSES内。