天天看點

python 闖關之路四(上)(并發程式設計與資料庫理論)

并發程式設計重點:

并發程式設計:線程、程序、隊列、IO多路模型

作業系統工作原理介紹、線程、程序演化史、特點、差別、互斥鎖、信号、
事件、join、GIL、程序間通信、管道、隊列。

生産者消息者模型、異步模型、IO多路複用模型、select\poll\epoll 高性
能IO模型源碼執行個體解析、高并發FTP server開發
      

1,簡述計算機作業系統的中斷的作用

中斷裝置由一些特定的寄存器和控制線路組成,中央處理器和外圍裝置等識别到的
事件儲存在特定的寄存器中。
    中央處理器每執行完一條指令,均由中斷裝置判别是否有事件發生。
    若無事件發生,CPU繼續執行;
    若有事件發生,則中斷裝置中斷原占有CPU的程式的執行,讓作業系統的處理事件
服務程式占用CPU,對出現的事件進行處理,事件處理完後,再讓原來的程式繼續占用CPU執行
      

  

中斷是指在計算機執行期間,系統内發生任何非尋常的或非預期的急需處理事件,
使得cpu暫時中斷目前正在執行的程式,轉去執行相應的事件處理程式。待處理完畢
後又傳回原來被中斷處繼續執行或排程新的程序執行的過程。它使計算機可以更好更
快利用有限的系統資源解決系統響應速度和運作效率的一種控制技術。實時響應,系統排程。
      

2,簡述計算機記憶體的“核心态”和“使用者态”

核心态:cpu可以通路記憶體的所有資料,包括外圍裝置,
例如硬碟,網卡,cpu也可以将自己從一個程式切換到另一個程式。

    使用者态:隻能受限的通路記憶體,且不允許通路外圍裝置,占用cpu的能力被剝奪,
cpu資源可以被其他程式擷取
      

3,為什麼要有核心态和使用者态?

由于需要限制不同的程式之間的通路能力,防止他們擷取别的程式的記憶體資料,
或者擷取外圍裝置的資料,并發送到網絡

    cpu劃分出兩個權限等級:使用者态和核心态。
      

4,什麼是程序?

正在執行的一個程式或者說一個任務,負責執行任務的是cpu。
程序是用來把資源集中到一起的,程序是資源機關,或者說資源集合。
      

5,什麼是線程?

線程是cpu上的執行機關。同一個程序内的多個線程共享該程序内的位址資源。
    建立線程的開銷要遠小于建立程序的開銷。
    線程是作業系統能夠進行運算排程的最小機關。
    它被包含在程序之中,是程序中的實際運作機關。
    一條線程指的是程序中一個單一順序的控制流,一個程序中可以并發多個線程,
每條線程并行執行不同的任務
      

6,什麼是系統調用?

所有使用者程式都是運作在使用者态的,但是有時候程式确實需要做一些核心态的事情,
例如從硬碟讀取資料,或者從鍵盤擷取輸入等,
    而唯一能做這些事情的就是作業系統,是以此時程式就需要向作業系統請求以程式
的名義來執行這些操作。這時,就需要一個機制:使用者态程式切換到核心态,但是不能
控制在核心态中執行的指令。這種機制就叫系統調用。
      

7,threading子產品event和condition的差別;

condition: 某些事件觸發或達到特定的條件後才處理資料,預設建立了一個lock對象。
    con = threading.Condition()
    con.acquire()
    con.notify()
    con.wait()
    con.release()

event:其他線程需要通過判斷某個線程的狀态來确定自己的下一步操作,就可以用event。
    from threading import Event
    event = Event()
    event.set(): 設定event的狀态值為True,所有阻塞池的線程激活進入就緒狀态, 等待作業系統排程;
    event.is_set():傳回event的狀态值;
    event.wait():如果 event.is_set()==False将阻塞線程;
    event.clear():恢複event的狀态值為False。
      

8,程序間通信方式有哪些?

消息隊列 管道 信号量 信号 共享記憶體 套接字
      

9,簡述對管道,隊列的了解

隊列 = 管道 + 鎖
from multiprocessing import Queue,Process
    queue = Queue()
    queue.put(url)
    url = queue.get()
from multiprocessing import Pipe,Process
    pipe = Pipe()
    pipe.send(url)
    pipe.recv() 
      

10,請簡述你對join、daemon方法的了解,舉出它們在生産環境中的使用場景;

join: 等待一個任務執行完畢;可以将并發變成串行。

daemon: 
    守護程序(守護線程)會等待主程序(主線程)運作完畢後被銷毀。
    運作完畢:
        1.對主程序來說,運作完畢指的是主程序代碼運作完畢。
        2.對主線程來說,運作完畢指的是主線程所在的程序内所有非守
護線程統統運作完畢,主線程才算運作完畢。
  
      

 11,簡述IO多路複用模型的工作原理

IO多路複用實際上就是用select,poll,epoll監聽多個io對象,當io對象有
變化(有資料)的時候就通知使用者程序。好處就是單個程序可以處理多個socket。

1.當使用者程序調用了select,那麼整個程序會被block;

2.而同時,kernel會“監視”所有select負責的socket;

3.當任何一個socket中的資料準備好了,select就會傳回;

4.這個時候使用者程序再調用read操作,将資料從kernel拷貝到使用者程序。

總結:
    1.I/O 多路複用的特點是通過一種機制一個程序能同時等待多個檔案描述符,
而這些檔案描述符(套接字描述符)其中的任意一個進入讀就緒狀态,
select()函數就可以傳回。

    2.IO多路複用:需要兩個系統調用,system call (select 和 recvfrom),
而blocking IO隻調用了一個system call (recvfrom)。但是,用select的優勢
在于它可以同時處理多個connection。

    3.如果處理的連接配接數不是很高的話,使用select/epoll的web server不一定
比使用多線程 + 阻塞 IO的web server性能更好,可能延遲還更大。

    4.select/epoll的優勢并不是對于單個連接配接能處理得更快,而是在于能處理更多的連接配接。
      

12,threading中Lock和RLock的相同點和不同點

Lock():互斥鎖,隻能被acquire一次,可能會發生死鎖情況。 

RLock():遞歸鎖,可以連續acquire多次。

RLock = Lock + counter
    counter:記錄了acquire的次數,直到一個線程所有的acquire都被release,其他線程才能獲得資源。
      

13、什麼是select,請簡述它的工作原理,簡述它的優缺點;

python中的select子產品專注于I/O多路複用,提供了select poll epoll三個方法;後兩個在linux中可用,

windows僅支援select。
    fd:檔案描述符
    fd_r_list,fd_w_list,fd_e_list = select.select(rlist,wlist,xlist,[timeout])
    參數:可接受四個參數(前三個必須)
    rlist:等到準備好閱讀
    wlist:等到準備寫作
    xlist:等待“異常情況”
    逾時:逾時時間
    傳回值:三個清單

select監聽fd變化的過程分析:
    使用者程序建立socket對象,拷貝監聽的fd到核心空間,每一個fd會對應一張系統檔案表,
核心空間的fd響應到資料後,
    就會發送信号給使用者程序資料已到;
    使用者程序再發送系統調用,比如(accept)将核心空間的資料copy到使用者空間,同時作
為接受資料端核心空間的資料清除,
    這樣重新監聽時fd再有新的資料又可以響應到了(發送端因為基于TCP協定是以需要收到
應答後才會清除)。

該模型的優點:
    相比其他模型,使用select() 的事件驅動模型隻用單線程(程序)執行,占用資源少,
不消耗太多 CPU,同時能夠為多用戶端提供服務。
    如果試圖建立一個簡單的事件驅動的伺服器程式,這個模型有一定的參考價值。

該模型的缺點:
    首先select()接口并不是實作“事件驅動”的最好選擇。因為當需要探測的句柄值較大時,
select()接口本身需要消耗大量時間去輪詢各個句柄。
    很多作業系統提供了更為高效的接口,如linux提供了epoll,BSD提供了kqueue,
Solaris提供了/dev/poll,…。
    如果需要實作更高效的伺服器程式,類似epoll這樣的接口更被推薦。遺憾的是不同
的作業系統特供的epoll接口有很大差異,
    是以使用類似于epoll的接口實作具有較好跨平台能力的伺服器會比較困難。
    其次,該模型将事件探測和事件響應夾雜在一起,一旦事件響應的執行體龐大,則
對整個模型是災難性的。
      

14、什麼是epoll,請簡述它的工作原理,簡述它的優缺點;

epoll: 性能最好的多路複用I/O就緒通知方法。相比于select,epoll最大的
好處在于它不會随着監聽fd數目的增長而降低效率。

       因為在核心中的select實作中,它是采用輪詢來處理的,輪詢的fd數目越多,自然耗時越多。

epoll:同樣隻告知那些就緒的檔案描述符,而且當我們調用epoll_wait()獲得就緒檔案描述符時,
傳回的不是實際的描述符,而是一個代表就緒描述符數量的值,

       你隻需要去epoll指定的一個數組中依次取得相應數量的檔案描述符即可,這裡也使用了記憶體映射(mmap)技術,這樣便徹底省掉了這些檔案描述符在系統調用時複制的開銷。

       另一個本質的改進在于epoll采用基于事件的就緒通知方式。在select/poll中,程序隻有在調用
一定的方法後,核心才對所有監視的檔案描述符進行掃描,
       而epoll事先通過epoll_ctl()來注冊一個檔案描述符,一旦基于某個檔案描述符就緒時,核心會
采用類似callback的回調機制,迅速激活這個檔案描述符,
       當程序調用epoll_wait()時便得到通知。從以上可知,epoll是對select、poll模型的改進,
提高了網絡程式設計的性能,廣泛應用于大規模并發請求的C/S架構中。
python中的epoll: 
    隻适用于unix/linux作業系統
      

15、簡述select和epoll的差別;

select 是不斷輪詢去監聽的socket,socket個數有限制,一般為1024個;
poll還是采用輪詢方式去監聽,隻不過沒有個數限制。
epoll并不用采用輪詢方式去監聽,而是當socket有變化時通過回調方式主動告知使用者程序。
select支援多平台,epoll隻支援linux平台。
      
select: 調用select()時
  1、上下文切換轉換為核心态
  2、将fd從使用者空間複制到核心空間
  3、核心周遊所有fd,檢視其對應事件是否發生
  4、如果沒發生,将程序阻塞,當裝置驅動産生中斷或者timeout時間後,将程序喚醒,再次進行周遊
  5、傳回周遊後的fd
  6、将fd從核心空間複制到使用者空間

select: 缺點
      1、當檔案描述符過多時,檔案描述符在使用者空間與核心空間進行copy會很費時

  2、當檔案描述符過多時,核心對檔案描述符的周遊也很浪費時間

  3、select最大僅僅支援1024個檔案描述符

epoll很好的改進了select:
  1、epoll的解決方案在epoll_ctl函數中。每次注冊新的事件到epoll句柄中時,
會把所有的fd拷貝進核心,而不是在epoll_wait的時候重複拷貝。epoll保證了每
個fd在整個過程中隻會拷貝一次。

  2、epoll會在epoll_ctl時把指定的fd周遊一遍(這一遍必不可少)并為每個fd
指定一個回調函數,當裝置就緒,喚醒等待隊列上的等待者時,就會調用這個回調
函數,而這個回調函數會把就緒的fd加入一個就緒連結清單。
       epoll_wait的工作實際上就是在這個就緒連結清單中檢視有沒有就緒的fd。

  3、epoll對檔案描述符沒有額外限制。
      

16、簡述多線程和多程序的使用場景;

多程序用于計算密集型,如金融分析;利用多核實作并發。

多線程用于IO密集型,如socket,爬蟲,web。
      

17,請分别簡述threading.Condition、threading.event、threading.semaphore的使用場景;

condition: 某些事件觸發或達到特定的條件後才處理資料。

event: 用來通知線程有一些事情已發生,進而啟動後繼任務的開始。

semaphore: 為控制一個具有有限數量使用者資源而設計。
      

18、假設有一個名為threading_test.py的程式裡有一個li = [1, 2, 3, 4]的清單,另有a,b兩個函數分别往該清單中增加元素,a函數需要修改li之前需要獲得threading.Lock對象,b函數不需要,請問當線程t1執行a函數擷取到Lock對象之後并沒有release該對象的情況下,線程t2執行b函是否可以修改li,為什麼?

可以,線程的資料是共享的,a 函數雖然上了鎖,沒有釋放。由于b 函數不需要上鎖,就可以通路資源。
      

19、簡述你對Python GIL的了解;

GIL(global interpreter lock)全局解釋器鎖

    GIL是CPython的一個概念,本質是一把互斥鎖,将并發運作變成串行。
解釋器的代碼是所有線程共享的,是以垃圾回收線程也有可能通路到解釋器的代碼去執行。
是以需要有GIL鎖,保證python解釋器同一時間隻能執行一個任務的代碼。

GIL:解釋器級别的鎖(保護的是解釋器級别的資料,比如垃圾回收的資料)
Lock:應用程式的鎖(保護使用者自己開發的應用程式的資料)
      

20、什麼是同步I/O,什麼是異步I/O?

synchronous io: 做”IO operation”的時候會将process阻塞;”IO operation”是指真實的IO操作
                blocking IO,non-blocking IO,IO multiplexing都屬于synchronous IO這一類.

asynchronous io: 當程序發起IO 操作之後,就直接傳回再也不理睬了,直到kernel發送一個信号,
                 告訴程序說IO完成。在這整個過程中,程序完全沒有被block。
異步io的實作會負責把資料從核心拷貝到使用者空間。
      
各種I/O模型比較
    有沒有辦法能讓我們在I/O時,不讓我們的應用程式阻塞;從上邊的分析我們知道
向核心發起一個I/O操作,要經過等待fd就緒+核心資料到使用者資料區複制,完成一次I/O;
    Linux POSIX是這樣定義同步I/O 和 異步I/O的:
   同步I/O操作(synchronous I/O operation):導緻請求程序阻塞,直到I/O操作完成。
   異步I/O操作(asynchronous I/O operation): 不導緻請求程序阻塞。
     根據上述定義,我們的前四種模型------阻塞式I/O模型,非阻塞式I/O模型、I/O多路
複用模型和信号驅動式I/O模型,因為其中真正的I/O操作将阻塞程序。隻有異步I/O模型
與POSIX定義的異步I/O相比對;
      

21,什麼是管道,如果兩個程序嘗試從管道的同一端讀寫資料,會出現什麼情況?

管道:是兩個程序間進行單向通信的機制。由于管道傳遞資料的單向性。
管道又稱為半雙工管道。
      管道傳遞資料是單向性的,讀資料時,寫入管道應關閉。寫資料時,讀取管道應關閉。
      

22,為什麼要使用線程池/程序池?

對服務端開啟的程序數或線程數加以控制,讓機器在一個自己可以承受的
範圍内運作,這就是程序池或線程池的用途.
      

23,如果多個線程都在等待同一個鎖被釋放,請問當該鎖對象被釋放的時候,哪一個線程将會獲得該鎖對象?

這個由作業系統的排程決定。
      

24,import threading;s = threading.Semaphore(value=-1)會出現什麼情況?

當threading.Semaphore(1) 為1時,表示隻有一個線程能夠拿到許可,
其他線程都處于阻塞狀态,直到該線程釋放為止。

當然信号量不可能永久的阻塞在那裡。信号量也提供了逾時處理機制。
如果傳入了 -1,則表示無限期的等待。
      

25,請将二進制數10001001轉化為十進制;

請将二進制數10001001轉化為十進制;   
    
    經分析,二進制10001001轉化為:1*2^7 + 1*2^3 + 1*2^0 = 137        

      

26,某程序在運作過程中需要等待從磁盤上讀入資料,此時該程序的狀态将發生什麼變化?

一個程式有三種狀态:運作态,阻塞态,就緒态;

遇到IO阻塞,程序從運作态轉到阻塞态,cpu切走,儲存目前狀态;
      

27,請問selectors子產品中DefaultSelector類的作用是什麼;

IO多路複用:select poll epoll
    select: 清單循環,效率低。windows 支援。
    poll: 可接收的清單資料多,效率也不高。linux 支援。
    epoll: 效率最高 異步操作 + 回調函數。linux 支援。

selectors 子產品:
    sel=selectors.DefaultSelector()
    自動根據作業系統選擇select/poll/epoll
      

28,簡述異步I/O的原理;

使用者程序發起read操作之後,立刻就可以開始去做其它的事。
而另一方面,從kernel的角度,當它受到一個asynchronous read之後,
    首先它會立刻傳回,是以不會對使用者程序産生任何block。
    然後,kernel會等待資料準備完成,然後将資料拷貝到使用者記憶體,
當這一切都完成之後,kernel會給使用者程序發送一個signal,告訴它read操作完成了。 
      

29,請問multiprocessing子產品中的Value、Array類的作用是什麼?舉例說明它們的使用場景

python 多程序通信Queue Pipe Value Array
queue和pipe用來在程序間傳遞消息;
Value + Array 是python中共享記憶體映射檔案的方法;速度比較快.
      

30,請問multiprocessing子產品中的Manager類的作用是什麼?與Value和Array類相比,Manager的優缺點是什麼

Python multiprocessing.Manager(程序間共享資料)

Python中程序間共享資料,除了基本的queue,pipe和value+array外,
還提供了更高層次的封裝。使用multiprocessing.Manager可以簡單地使用這些進階接口。

Manager支援的類型有list,dict,Namespace,Lock,RLock,Semaphore,BoundedSemaphore,Condition,
Event,Queue,Value和Array。
      

31,請說說你對multiprocessing子產品中的Queue().put(), Queue().put_nowait(), Queue().get(), Queue().get_nowait()的了解;

q = Queue(3) 隊列 先進先出  程序間通信; 隊列 = 管道 + 鎖
q.put() 
q.put_nowait()  # 無阻塞,當隊列滿時,直接抛出異常queue.Full
q.get() 
q.get_nowait()  # 無阻塞,當隊列為空時,直接抛出異常queue.Empty 
      

32,什麼是協程?使用協程與使用線程的差別是什麼?

協程:單線程下的并發。協程是一種使用者态的輕量級線程,即協程是由使用者程式自己控制排程的。

    1.python的線程是屬于核心級别的,即由作業系統控制排程(如單線程
遇到io或執行時間過長就會被迫交出cpu執行權限,切換其他的線程運作)

    2.單線程内開啟協程,一旦遇到io,就會從應用程式級别(而非作業系統)
控制切換,以此來提升效率(!!非io操作的切換與效率無關)
      

33,asyncio的實作原理是什麼?

https://www.cnblogs.com/earendil/p/7411115.html 

Python異步程式設計:asyncio庫和async/await文法

asyncio是Python 3.4 試驗性引入的異步I/O架構,提供了基于協程做異
步I/O編寫單線程并發代碼的基礎設施。
其核心元件有事件循環(Event Loop)、協程(Coroutine)、任務(Task)、
未來對象(Future)以及其他一些擴充和輔助性質的子產品。

synchronous io: 做”IO operation”的時候會将process阻塞;”IO operation”是指真實的IO操作
                blocking IO,non-blocking IO,IO multiplexing都屬于synchronous IO這一類.
asynchronous io: 當程序發起IO 操作之後,就直接傳回再也不理睬了,直到kernel發送一個信号,
                 告訴程序說IO完成。在這整個過程中,程序完全沒有被block。異步io的實作會負責把
資料從核心拷貝到使用者空間
      

資料庫重點:

1、資料庫介紹、類型、特性
2、MySQL資料庫安裝、連接配接、啟動、停止
3、表字段類型介紹、主鍵限制、表建立語句
4、常用增删改查語句、分組、聚合
5、外鍵管理、unique字段、表結構修改文法
6、跨表查詢,inner join、left join、right join、full join文法
7、複雜SQL語句如group by、子查詢、函數的使用
8、索引原理及作用、普通索引、多列索引、唯一索引、全文索引等
9、基于hash&b+樹索引的實作原理,索引的優缺點剖析
10、事務原理,ACID特性,應用場景講解
11、事務復原
12、觸發器的特性,應用場景
13、觸發器的增删改查方法
14、存儲過程的作用及應用場景
15、建立存儲過程,參數傳遞,流程控制語句if\while\repeat\loop等,動态SQL的建立
16、視圖的作用及使用場景,視圖的增删改查
17、資料庫權限管理,使用者管理
18、資料庫備份指令及工具講解
19、基于不同業務的資料庫表結構設計、性能優化案例
20、pymysql子產品介紹和使用
      

1,說說你所知道的MySQL資料庫存儲引擎,InnoDB存儲引擎和MyISM存儲引擎的差別?

主要有
MyISM:MyISAM存儲引擎:不支援事務、也不支援外鍵,
優勢是通路速度快,對事務完整性沒有 要求或者以select,insert為主的
應用基本上可以用這個引擎來建立表

InnoDB:支援事務

Memory:Memory存儲引擎使用存在于記憶體中的内容來建立表。每個memory表
隻實際對應一個磁盤檔案,格式是.frm。memory類型的表通路非常的快,因為它
的資料是放在記憶體中的,并且預設使用HASH索引,但是一旦服務關閉,表中的數
據就會丢失掉。

Merge:Merge存儲引擎是一組MyISAM表的組合,這些MyISAM表必須結構完全
相同,merge表本身并沒有資料,對merge類型的表可以進行查詢,更新,删除操作,
這些操作實際上是對内部的MyISAM表進行的。

BLACKHOLE:黑洞存儲引擎,可以應用于主備複制中的分發主庫。

MyISM和InnoDB的差別
InnoDB支援事務,而MyISM不支援事務
InnoDB支援行級鎖,而MyISM支援表級鎖
InnoDB支援外鍵,而MyISM不支援
InnoDB支援全文索引,而MyISM不支援
InnoDB是索引組織表,MyISM是堆表  (堆表的資料是随機插入的,索引組織表的資料是有序的)
      
MyISAM:讀事務要求不高,以查詢和插入為主,可以使用這個引擎來建立表,
例如各種統計表。
 
  InnoDB:對事務要求高,儲存的是重要的資料
例如交易資料,支付資料等,對使用者重要的資料,建議使用InnoDB。
      

2、MySQL中char和varchar的差別,varchar(50)和char(50)分别代表什麼意思?

char(50): 定長,字元的長度為50,浪費空間,存取速度快,資料不足時,
會往右填充空格來滿足長度。

    varchar(50): 變長,字元的長度為50,節省空間,存取速度慢,存儲資料
的真實内容,不會填充空格,且會在真實資料前加1-2bytes,表示真實資料的bytes位元組數。
      

3、MySQL中int類型存儲多少個位元組?

int存儲4位元組  有符号:(-2147483648,2147483647)

              無符号:(0,4294967295)
      

4,主鍵具有什麼特征?

不為空且唯一
      

5、簡述你對inner join、left join、right join、full join的了解;

多表連接配接查詢:
inner join: 内連接配接,隻連接配接比對的行,找兩張表共有的部分;

left join:   外連接配接之左連接配接,優先顯示左表全部記錄,在内連接配接的基礎上增加左表有右表沒有的結果;

right join:  外連接配接之右連接配接,優先顯示右表全部記錄,在内連接配接的基礎上增加右表有左表沒有的結果;

full join:   = left join on union right join on ...  mysql 不支援full join 但是可以用 union ...
全外連接配接,顯示左右兩個表全部記錄,在内連接配接的基礎上增加左表有右表沒有和右表有左表沒有的結果;
      

6、concat, group_concat函數的作用是什麼?

定義顯示格式:
    concat() 用于連接配接字元串 
        eg: select concat('姓名:',name,'年薪:',salasy*12) as annual_salary from employee;

    concat_ws() 第一個參數為分隔符
        eg: select concat_ws(':',name,salary*12) as annual_salary from employee;

group by 與 group_concat() 函數一起使用
    select post,group_concat(name) as emp_members from employee group by post;     
      

7、請介紹事務的實作原理;

事務:用于将某些操作的多個sql作為原子性操作,一旦有某一個出現錯誤,
即可復原到原來的狀态,進而保證資料庫資料的完整性。

      原子性:一堆sql語句,要麼同時執行成功,要麼同時失敗!
      

8、索引的本質是什麼?索引有什麼優點,缺點是什麼?

索引在mysql中也稱為鍵,本質是都是通過不斷縮小想要擷取的資料範圍
來篩選最終想要的結果,同時把随機的事件變成有序的事件,也就是說,
有了索引機制,我們可以總是用同一種查找方式來鎖定資料
      
索引是幫助MySQL高效擷取資料的資料結構。是以,索引的本質是一種資料結構。
在資料之外,資料庫系統還可以維護滿足特定查找算法的資料結構,這些資料結構
以某種方式指向真實資料,這樣就可以在這些資料結構上實作進階查找算法,這種
資料結構就是索引。

優點:
1、提高資料檢索效率,降低資料庫的IO成本;

2、通過索引對資料進行排序,降低了資料排序的成本,降低了CPU的使用率;

缺點:
1、索引實際上也是一張表,索引會占用一定的存儲空間;

2、更新資料表的資料時,需要同時維護索引表,是以,會降低insert、update、delete的速度;
      

9、哪些情況下需要建立索引,哪些情況下不需要建立索引?

1、主鍵自動建立唯一非空索引;
2、頻繁作為查詢條件的字段應該建立索引;
3、頻繁更新的字段不适合履歷索引,因為每次更新不僅僅更新資料表同時還會更新索引表;
4、查詢中經常排序的字段,可以考慮建立索引;
5、如果某個字段的重複資料較多,不适合建立普通索引;
      

10、請分别介紹ACID代表的意思,什麼業務場景需要支援事務,什麼業務場景不需要支援事務?

ACID,指資料庫事務正确執行的四個基本要素的縮寫。

包含:原子性(Atomicity)、一緻性(Consistency)、隔離性(Isolation)、持久性(Durability)。
一個支援事務(Transaction)的資料庫,必須要具有這四種特性,否則在事務過程(Transaction processing)當中無法保證資料的正确性。

使用場景:
    銀行的交易系統
eg:
    start transaction; 
    update user set balance = 900 where name = 'wsb';   #買支付100元
    update user set balance = 1010 where name = 'egon'; #中介拿走10元
    uppdate user set balance = 1090 where name = 'ysb'; #賣家拿到90元,出現異常沒有拿到
    rollback;
    commit;
      

11、什麼是觸發器,請簡述觸發器的使用場景?

使用觸發器可以定制使用者對表進行【增、删、改】操作時前後的行為,注意:沒有查詢。
    觸發器無法由使用者直接調用,而知由于對表的【增/删/改】操作被動引發的。

eg: 
    create trigger tri_before_insert_tb1 before insert on tb1 for each row
    begin 
        ...      
    end  
      

12、什麼是存儲過程,存儲過程的作用是什麼?

存儲過程包含了一系列可執行的sql語句,存儲過程存放于MySQL中,
通過調用它的名字可以執行其内部的一堆sql。

優點:
    1. 用于替代程式寫的SQL語句,實作程式與sql解耦
    2. 基于網絡傳輸,傳别名的資料量小,而直接傳sql資料量大

缺點:
    1. 程式員擴充功能不友善

eg:
     delimiter //
        create procedure p1()
        begin
            select * from blog;
            insert into blog(name,sub_time) values('xxx',now());
        end //
     delimiter ;
      

13、什麼是視圖,簡單介紹視圖的作用和使用場景?

視圖是一個虛拟表(非真實存在),其本質是【根據SQL語句擷取動态的資料集,并為其命名】,
使用者使用時隻需使用【名稱】即可擷取結果集,可以将該結果集當做表來使用。
視圖取代複雜的sql語句,友善用來查詢。

eg: 
    create view teacher_view as select tid from teacher where tname='李平老師';
      

14、如何檢視SQL語句的執行計劃?

http://blog.itpub.net/12679300/viewspace-1394985/
執行計劃的檢視是進行資料庫的sql語句調優時依據的一個重要依據.
eg:
    explain select * from class;
    +----+-------------+-------+------+---------------+------+---------+------+------+-------+
    | id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra |
    +----+-------------+-------+------+---------------+------+---------+------+------+-------+
    |  1 | SIMPLE      | class | ALL  | NULL          | NULL | NULL    | NULL |   12 | NULL  |
    +----+-------------+-------+------+---------------+------+---------+------+------+-------+
Id:包含一組數字,表示查詢中執行select子句或操作表的順序;
    執行順序從大到小執行;
    當id值一樣的時候,執行順序由上往下;
Select_type:表示查詢中每個select子句的類型(簡單OR複雜),有以下幾種:
    SIMPLE:查詢中不包含子查詢或者UNION
    PRIMARY:查詢中若包含任何複雜的子部分,最外層查詢則被标記為PRIMARY
    SUBQUERY:在SELECT或WHERE清單中包含了子查詢,該子查詢被标記為SUBQUERY
    DERIVED:在FROM清單中包含的子查詢被标記為DERIVED(衍生)
    若第二個SELECT出現在UNION之後,則被标記為UNION;
    若UNION包含在FROM子句的子查詢中,外層SELECT将被标記為:DERIVED
    從UNION表擷取結果的SELECT被标記為:UNION RESULT
Type:表示MySQL在表中找到所需行的方式,又稱“通路類型”,常見有以下幾種:
    ALL:Full Table Scan, MySQL将進行全表掃描;
    index:Full Index Scan,index與ALL差別為index類型隻周遊索引樹;
    range:range Index Scan,對索引的掃描開始于某一點,傳回比對值域的行,常見于between、<、>等的查詢;
    ref:非唯一性索引掃描,傳回比對摸個單獨值的所有行。常見于使用非唯一索引或唯一索引的非唯一字首進行的查找;
    eq_ref:唯一性索引掃描,對于每個索引鍵,表中隻有一條記錄與之比對。常見于主鍵或唯一索引掃描
    const、system:當MySQL對查詢某部分進行優化,并轉換為一個常量時,使用這些類型通路。如将主鍵置于where清單中,MySQL就能将該查詢轉換為一個常量
    NULL:MySQL在優化過程中分解語句,執行時甚至不用通路表或索引
possible_keys:指出MySQL能使用哪個索引在表中找到行,查詢涉及到的字段上若存在索引,則該索引将被列出,但不一定被查詢使用;    
key:顯示MySQL在查詢中實際使用的索引,若沒有使用索引,顯示為NULL。當查詢中若使用了覆寫索引,則該索引僅出現在key清單中
key_len:表示索引中使用的位元組數,可通過該列計算查詢中使用的索引的長度
ref:表示上述表的連接配接比對條件,即那些列或常量被用于查找索引列上的值;
rows:表示MySQL根據表統計資訊及索引選用情況,估算的找到所需的記錄所需要讀取的行數;
Extra:包含不适合在其他列中顯示但十分重要的額外資訊;
    Using where:表示MySQL伺服器在存儲引擎受到記錄後進行“後過濾”(Post-filter),如果查詢未能使用索引,Using where的作用隻是提醒我們MySQL将用where子句來過濾結果集
    Using temporary:表示MySQL需要使用臨時表來存儲結果集,常見于排序和分組查詢;
    Using filesort:MySQL中無法利用索引完成的排序操作稱為“檔案排序”;
      

15、在你本地資料庫中檢視select from student*的執行計劃,并解釋每個字段分别代表什麼意思?

mysql> explain select * from student;
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows | Extra |
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
|  1 | SIMPLE      | student | ALL  | NULL          | NULL | NULL    | NULL |   16 | NULL  |
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
id: 表示查詢中執行select子句或操作表的順序。
select_type: simple 表示查詢中不包含子查詢或者union
table: student
type: all 表示mysql将進行全表掃描
possible_keys: 指出MySQL能使用哪個索引在表中找到行,查詢涉及到的字段上若存在索引,則該索引将被列出,但不一定被查詢使用;
key: 顯示MySQL在查詢中實際使用的索引,若沒有使用索引,顯示為NULL。當查詢中若使用了覆寫索引,則該索引僅出現在key清單中;
ey_len:表示索引中使用的位元組數,可通過該列計算查詢中使用的索引的長度;
ref:表示上述表的連接配接比對條件,即那些列或常量被用于查找索引列上的值;
rows:表示MySQL根據表統計資訊及索引選用情況,估算的找到所需的記錄所需要讀取的行數;
Extra:包含不适合在其他列中顯示但十分重要的額外資訊;
      

16、資料備份分為哪幾種類型?增量備份和差異備份的差別是什麼?

完整備份:備份系統中的所有資料。特點:占用空間大,備份速度慢,但恢複時一次恢複到位,恢複速度快。

增量備份:隻備份上次備份以後有變化的資料。
         特點:因每次僅備份自上一次備份(注意是上一次,不是第一次)以來有變化的檔案,
            是以備份體積小,備份速度快,但是恢複的時候,需要按備份時間順序,
逐個備份版本進行恢複,恢複時間長。

差異備份:隻備份上次完全備份以後有變化的資料。
         特點:占用空間比增量備份大,比完整備份小,恢複時僅需要恢複第一個完
整版本和最後一次的差異版本,恢複速度介于完整備份和增量備份之間。

簡單的講,完整備份就是不管三七二十一,每次都把指定的備份目錄完整的複制一遍,
不管目錄下的檔案有沒有變化;

增量備份就是每次将之前(第一次、第二次、直到前一次)做過備份之後有變化的檔案進行備份;

差異備份就是每次都将第一次完整備份以來有變化的檔案進行備份。
      

17、請介紹select語句的執行順序;

from
where
group by
having
select
distinct
order by
limit
說明:
    1.找到表:from
    2.拿着where指定的限制條件,去檔案/表中取出一條條記錄
    3.将取出的一條條記錄進行分組group by,如果沒有group by,則整體作為一組
    4.将分組的結果進行having過濾
    5.執行select
    6.去重
    7.将結果按條件排序:order by
    8.限制結果的顯示條數
      

18、請問存儲引擎MyISM和InnoDB的适合什麼樣的使用場景?

Innodb與Myisam引擎的差別與應用場景:
1. 差別:
(1)事務處理:
    MyISAM是非事務安全型的,而InnoDB是事務安全型的(支援事務處理等進階處理);
(2)鎖機制不同:
    MyISAM是表級鎖,而InnoDB是行級鎖;
(3)select ,update ,insert ,delete 操作:
    MyISAM:如果執行大量的SELECT,MyISAM是更好的選擇
    InnoDB:如果你的資料執行大量的INSERT或UPDATE,出于性能方面的考慮,應該使用InnoDB表
(4)查詢表的行數不同:
    MyISAM:select count(*) from table,MyISAM隻要簡單的讀出儲存好的行數,注意的是,當count(*)語句包含   where條件時,兩種表的操作是一樣的
    InnoDB : InnoDB 中不儲存表的具體行數,也就是說,執行select count(*) from table時,InnoDB要掃描一遍整個表來計算有多少行
(5)外鍵支援:
    mysiam表不支援外鍵,而InnoDB支援
    
2. 為什麼MyISAM會比Innodb 的查詢速度快。
    INNODB在做SELECT的時候,要維護的東西比MYISAM引擎多很多;
        1)資料塊,INNODB要緩存,MYISAM隻緩存索引塊,  這中間還有換進換出的減少; 
        2)innodb尋址要映射到塊,再到行,MYISAM 記錄的直接是檔案的OFFSET,定位比INNODB要快
        3)INNODB還需要維護MVCC一緻;雖然你的場景沒有,但他還是需要去檢查和維護
        MVCC ( Multi-Version Concurrency Control )多版本并發控制 

3. 應用場景
    MyISAM适合:(1)做很多count 的計算;(2)插入不頻繁,查詢非常頻繁;(3)沒有事務。
    InnoDB适合:(1)可靠性要求比較高,或者要求事務;(2)表更新和查詢都相當的頻繁,并且行鎖定的機會比較大的情況。
      

19、請舉出MySQL中常用的幾種資料類型;

mysql常用資料類型:
    1.數值類型:
        整數類型:tinyint smallint int bigint
        浮點型:float double decimal
            float :在位數比較短的情況下不精準(一般float得精确度也夠用了)
            double :在位數比較長的情況下不精準
                0.000001230123123123
                存成:0.000001230000
            decimal:(如果用小數,則推薦使用decimal)
                精準 内部原理是以字元串形式去存
    2.日期類型:
        最常用:datetime  year date time datetime timestamp
    3.字元串類型:
        char(6) varchar(6)
        char(10):簡單粗暴,浪費空間,存取速度快,定長;
            root存成root000000
        varchar:精準,節省空間,存取速度慢,變長;
        
        sql優化:建立表時,定長的類型往前放,變長的往後放
                        比如性别           比如位址或描述資訊
        
        >255個字元,超了就把檔案路徑存放到資料庫中。
                比如圖檔,視訊等找一個檔案伺服器,資料庫中隻存路徑或url。
    4.枚舉類型與集合類型:
        enum('male','female')
        set('play','music','read','study')
      

20、什麼情況下會産生笛卡爾乘積,如何避免?

交叉連接配接:不适用任何比對條件。生成笛卡爾積;
    select * from employee,department;
避免:    
    select 
        employee.id,employee.name,employee.age,employee.sex,department.name 
    from 
        employee,department 
    where 
        employee.dep_id=department.id; 
      

21、請列舉MySQL中常用的函數;

聚合函數:
    聚合函數聚合的是組的内容,若是沒有分組,則預設一組
    count()
    max()
    min()
    avg()
    sum()
      

22、請說明group by的使用場景;

什麼是分組,為什麼要分組?
    1、首先明确一點:分組發生在where之後,即分組是基于where之後得到的記錄而進行的
    2、分組指的是:将所有記錄按照某個相同字段進行歸類,比如針對員工資訊表的職位分組,
或者按照性别進行分組等
    3、為何要分組呢?
        取每個部門的最高工資
        取每個部門的員工數
        取男人數和女人數

    小竅門:‘每’這個字後面的字段,就是我們分組的依據
    4、大前提:
        可以按照任意字段分組,但是分組完畢後,比如group by post,隻能檢視post字段,
如果想檢視組内資訊,需要借助于聚合函數
      

23、請介紹hash索引和B+樹索引的實作原理;

哈希索引基于哈希表實作,隻有精确比對索引的所有列的查詢才有效。
對于每一行資料,存儲引擎都會對所有的索引列計算一個哈希碼,哈希碼
是一個較小的值,并且不同鍵值的行計算出來的哈希碼也不一樣。哈希索
引将所有的哈希碼存儲在索引中,同時在哈希表中儲存指向每個資料行的
指針。也就是說,由于哈希查找比起B-Tree索引,其本身對于單行查詢的
時間複雜度更低,有了哈希索引後明顯可加快單行查詢速度。

但是哈希索引也有它自己的限制:
哈希索引隻包含哈希值和行指針,而不存儲字段值,是以不能使用索引中
的值來避免讀取行。不過,通路記憶體中的行的速度很快,是以大部分情況下
這一點對性能的影響并不明顯。

哈希索引資料并不是按照索引值順序存儲的,是以也就無法用于排序。

哈希索引也不支援部分索引列比對查找,因為哈希索引始終是使用索引列的
全部内容來計算哈希值的。例如,在資料列(A, B)上建立哈希索引,如果查
詢隻有資料列A,則無法使用該索引。

哈希索引隻支援等值比較查詢,包括=、in()、<=>。不支援任何範圍查詢,
例如where price > 100。

通路哈希索引的資料非常快,除非有很多哈希沖突。如果哈希沖突很多的話,
一些索引維護操作的代價也很高。

B+樹索引是B樹索引的變體,本質上也是多路平衡查找樹
      

不經一番徹骨寒 怎得梅花撲鼻香

繼續閱讀