1. 程式人生 > >python 闖關之路四(上)(並發編程與數據庫理論)

python 闖關之路四(上)(並發編程與數據庫理論)

nsa 更新數據 主線程 數值類型 基礎設施 環境 文件路徑 他還 組合

並發編程重點:

並發編程:線程、進程、隊列、IO多路模型

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

生產者消息者模型、異步模型、IO多路復用模型、select\poll\epoll 高性
能IO模型源碼實例解析、高並發FTP server開發

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

    中斷是指在計算機執行期間,系統內發生任何非尋常的或非預期的急需處理事件,
使得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: 調用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的實現會負責把數據從內核拷貝到用戶空間。

21,什麽是管道,如果兩個進程嘗試從管道的同一端讀寫數據,會出現什麽情況?

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

22,為什麽要使用線程池/進程池?

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

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

這個由操作系統的調度決定。

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

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

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

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

10001001 = 1*10^7 + 1*10^3 + 1* 10^0 = 10001001 

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是堆表  (堆表的數據是隨機插入的,索引組織表的數據是有序的)

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高效獲取數據的數據結構。因此,索引的本質是一種數據結構。
在數據之外,數據庫系統還可以維護滿足特定查找算法的數據結構,這些數據結構
以某種方式指向真實數據,這樣就可以在這些數據結構上實現高級查找算法,這種
數據結構就是索引。

優點:
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樹索引的變體,本質上也是多路平衡查找樹

  

python 闖關之路四(上)(並發編程與數據庫理論)