python 闖關之路四(下)(併發編程與數據庫編程) 併發編程重點

python 闖關之路四(下)(併發編程與數據庫編程)

 

併發編程重點:

1
2
3
4
5
6
7
併發編程:線程、進程、隊列、IO多路模型
 
操做系統工做原理介紹、線程、進程演化史、特色、區別、互斥鎖、信號、
事件、join、GIL、進程間通訊、管道、隊列。
 
生產者消息者模型、異步模型、IO多路複用模型、select\poll\epoll 高性
能IO模型源碼實例解析、高併發FTP server開發

一、請寫一個包含10個線程的程序,主線程必須等待每個子線程執行完成以後才結束執行,每個子線程執行的時候都須要打印當前線程名、當前活躍線程數量;html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from  threading  import  Thread,currentThread,activeCount
import  time
def  task(n):
     print ( '線程名:%s----%s' % (currentThread().name,n))
     time.sleep( 1 )
     print ( '數量:%s' % activeCount())
     
if  __name__  = =  "__main__" :
     t_li  =  []
     for  in  range ( 10 ):
         =  Thread(target = task,args = (i,))
         t.start()
         t_li.append(t)
     for  in  t_li:
         t.join()
         
     print ( '主,end----' )

二、請寫一個包含10個線程的程序,並給每個子線程都建立名爲"name"的線程私有變量,變量值爲「james」;python

1
2
3
4
5
6
7
8
9
10
11
from  threading  import  Thread
def  task(name):
     print ( '%s is running' % name)
     print ( 'end ---' )
     
if  __name__  = =  "__main__" :
     for  in  range ( 10 ):
         =  Thread(target = task,args = ( 'james_%s' % i,))
         t.start()
         
     print ( '主 end ---' )

三、請使用協程寫一個消費者生產者模型;mysql

協程知識點:http://www.javashuo.com/article/p-adknkdvb-ct.htmlsql

協程:單線程下,沒法利用多核,能夠是一個程序開多個進程,每一個進程開啓多個線程,每隔線程開啓協程;數據庫

  協程指的是單個線程,於是一旦協程出現阻塞,將會阻塞整個線程。編程

1
2
3
4
5
6
7
8
9
10
11
12
13
def  consumer():
     while  True :
         =  yield
         print ( '消費:' , x)
         
def  producter():
     =  consumer()
     next (c)
     for  in  range ( 10 ):
         print ( '生產:' , i)
         c.send(i)
         
producter()

四、寫一個程序,包含十個線程,子線程必須等待主線程sleep 10秒鐘以後才執行,並打印當前時間性能優化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from  threading  import  Thread,Event
import  time
import  datetime
def  task():
     # while not event.is_set():
     #     print('...')
     print ( '...' )
     event.wait( 10 )
     print ( 'time:' ,datetime.datetime.now())
     
if  __name__  = =  '__main__' :
     event  =  Event()
     for  in  range ( 10 ):
         =  Thread(target = task)
         t.start()
         
     time.sleep( 10 )
     event. set ()

五、寫一個程序,包含十個線程,同時只能有五個子線程並行執行;服務器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from  threading  import  Thread,Semaphore,currentThread
import  time
def  task(n):
     sm.acquire()
     print ( '%s---' % n,currentThread().name)
     time.sleep( 1 )
     print ( 'end----' )
     sm.release()
     
if  __name__  = =  '__main__' :
     sm  =  Semaphore( 5 )
     for  in  range ( 10 ):
         =  Thread(target = task,args = (i,))
         t.start()

六、寫一個程序 ,包含一個名爲hello的函數,函數的功能是打印字符串「Hello, World!」,該函數必須在程序執行30秒以後纔開始執行(不能使用time.sleep());網絡

1
2
3
4
5
6
7
from  threading  import  Timer
def  hello(name):
     print ( '%s say ' % name, 'Hello World!' )
     
if  __name__  = =  "__main__" :
     =  Timer( 5 ,hello,args = ( 'james' ,))
     t.start()

七、寫一個程序,利用queue實現進程間通訊;多線程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
from  multiprocessing  import  Process,Queue,current_process
import  time
def  consumer(q):
     while  True :
         res  =  q.get()
         if  not  res: break
         print ( '消費了:' ,res, '--' ,current_process().name)
         
def  producter(q):
     for  in  range ( 5 ):
         print ( '生產:' ,i)
         time.sleep( 1 )
         q.put(i)
         
if  __name__  = =  "__main__" :
     =  Queue()
     p1  =  Process(target = producter,args = (q,))
     c1  =  Process(target = consumer,args = (q,))
     c2  =  Process(target = consumer,args = (q,))
     p1.start()
     c1.start()
     c2.start()
   
     p1.join()
     q.put( None )
     q.put( None )
     print ( '主' )
     
# JoinableQueue
from  multiprocessing  import  Process,JoinableQueue,current_process
import  time
def  consumer(q):
     while  True :
         res  =  q.get()
         print ( '消費了:' ,res, '--' ,current_process().name)
         q.task_done()
         
def  producter(q):
     for  in  range ( 5 ):
         print ( '生產:' ,i, '--' ,current_process().name)
         time.sleep( 1 )
         q.put(i)
     q.join()
     
if  __name__  = =  "__main__" :
     =  JoinableQueue()
     p1  =  Process(target = producter,args = (q,))
     p2  =  Process(target = producter, args = (q,))
     c1  =  Process(target = consumer,args = (q,))
     c2  =  Process(target = consumer,args = (q,))
     p1.start()
     p2.start()
     
     c1.daemon  =  True
     c2.daemon  =  True
     c1.start()
     c2.start()
     
     p1.join()
     p2.join()
     print ( '主' )

八、寫一個程序,利用pipe實現進程間通訊;

1
2
3
4
5
6
7
8
9
10
11
from  multiprocessing  import  Process,Pipe
def  task(conn):
     conn.send( 'hello world' )
     conn.close()
     
if  __name__  = =  "__main__" :
     parent_conn,child_conn  =  Pipe()
     =  Process(target = task,args = (child_conn,))
     p.start()
     p.join()
     print (parent_conn.recv())

九、使用selectors模塊建立一個處理客戶端消息的服務器程序;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# server  blocking IO 
import  socket
server  =  socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(( '127.0.0.1' , 8080 ))
server.listen( 5 )
while  True :
     conn,addr  =  server.accept()
     print (addr)
     while  True :
         try :
             data  =  conn.recv( 1024 )
             if  not  data:  break
             conn.send(data.upper())
         except  Exception as e:
             print (e)
             break
             
# server  IO多路複用 selectors 會根據操做系統選擇select poll epoll          
import  socket
import  selectors
sel  =  selectors.DefaultSelector()
def  accept(server_fileobj,mask):
     conn,addr  =  server_fileobj.accept()
     print (addr)
     sel.register(conn,selectors.EVENT_READ,read)
     
def  read(conn,mask):
     try :
         data  =  conn.recv( 1024 )
         if  not  data:
             print ( 'closing..' ,conn)
             sel.unregister(conn)
             conn.close()
             return
         conn.send(data.upper())
     except  Exception:
         print ( 'closeing...' ,conn)
         sel.unregister(conn)
         conn.close()
         
server_fileobj  =  socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server_fileobj.bind(( '127.0.0.1' , 8080 ))
server_fileobj.listen( 5 )
server_fileobj.setblocking( False )
sel.register(server_fileobj,selectors.EVENT_READ,accept)
while  True :
     events  =  sel.select()
     for  sel_obj,mask  in  events:
         callback  =  sel_obj.data
         callback(sel_obj.fileobj,mask)
         
# client
# -*- coding:utf-8 -*-
import  socket
client  =  socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(( '127.0.0.1' , 8080 ))
while  True :
     msg  =  input ( '>>>:' ).strip()
     if  not  msg: continue
     client.send(msg.encode( 'utf-8' ))
     data  =  client.recv( 1024 )
     print (data.decode( 'utf-8' ))
 

十、使用socketserver建立服務器程序時,若是使用fork或者線程服務器,一個潛在的問題是,惡意的程序可能會發送大量的請求致使服務器崩潰,請寫一個程序,避免此類問題;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# server socketserver 模塊內部使用IO多路複用 和多進程/多線程
import  socketserver
class  Handler(socketserver.BaseRequestHandler):
     def  handle( self ):
         print ( 'new connection:' , self .client_address)
         while  True :
             try :
                 data  =  self .request.recv( 1024 )
                 if  not  data: break
                 print ( 'client data:' ,data.decode())
                 self .request.send(data.upper())
             except  Exception as e:
                 print (e)
                 break
                 
if  __name__  = =  "__main__" :
     server  =  socketserver.ThreadingTCPServer(( '127.0.0.1' , 8080 ),Handler)
     server.serve_forever()

十一、請使用asyncio實現一個socket服務器端程序;

 十二、寫一個程序,使用socketserver模塊,實現一個支持同時處理多個客戶端請求的服務器,要求每次啓動一個新線程處理客戶端請求;

1
2
3
4
5
6
7
8
9
socketserver模塊類介紹
       SocketServer內部使用 IO多路複用 以及 「多線程」 和 「多進程」 ,
從而實現併發處理多個客戶端請求的Socket服務端。即:每一個客戶端請求
鏈接到服務器時,Socket服務端都會在服務器是建立一個「線程」或者「進 程」
  專門負責處理當前客戶端的全部請求。
         socketserver模塊能夠簡化網絡服務器的編寫,python把網絡服務抽
象成兩個主要的類,一個是server類,用於處理鏈接相關的網絡操做,另外一個
是RequestHandler類,用於處理數據相關的操做。而且提供兩個Mixln類,
用於擴展server,實現多進程或者多線程。

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import  socketserver
import  threading
 
 
class  MyServer(socketserver.BaseRequestHandler):
     def  handle( self ):
         while  True :
             self .data  =  self .request.recv( 1024 ).decode()
             print ( self .data)
             self .request.send( self .data.upper().encode())
         
         
if  __name__  = =  '__main__' :
     server  =  socketserver.ThreadingTCPServer(( '127.0.0.1' 9999 ), MyServer)
     =  threading.Thread(target = server.serve_forever)
     t.start()

  

數據庫重點:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
語法:
1.  修改表名
       ALTER TABLE 表名
                           RENAME 新表名;
 
2.  增長字段
       ALTER TABLE 表名
                           ADD 字段名  數據類型 [完整性約束條件…],
                           ADD 字段名  數據類型 [完整性約束條件…];
       ALTER TABLE 表名
                           ADD 字段名  數據類型 [完整性約束條件…]  FIRST;
       ALTER TABLE 表名
                           ADD 字段名  數據類型 [完整性約束條件…]  AFTER 字段名;
 
3.  刪除字段
       ALTER TABLE 表名
                           DROP 字段名;
 
4.  修改字段
       ALTER TABLE 表名
                           MODIFY  字段名 數據類型 [完整性約束條件…];
       ALTER TABLE 表名
                           CHANGE 舊字段名 新字段名 舊數據類型 [完整性約束條件…];
       ALTER TABLE 表名
                           CHANGE 舊字段名 新字段名 新數據類型 [完整性約束條件…];

  

一、建立一個表student,包含ID(學生學號),sname(學生姓名),gender(性別),credit(信用卡號),四個字段,要求:ID是主鍵,且值自動遞增,sname是可變長字符類型,gender是枚舉類型, credit是可變長字符類型;

1
2
3
4
5
6
create table student(
     ID  int  primary key auto_increment,
     sname varchar( 16 not  null,
     gender enum( 'male' , 'female' not  null default  'female' ,
     credit varchar( 32 )
);

  

二、在上面的student表中增長一個名爲class_id的外鍵,外鍵引用class表的cid字段;

1
2
3
4
5
6
7
create table  class (
     cid  int  primary key auto_increment,
     cname varchar( 16 not  null
);
   
alter table student add class_id  int  not  null;
alter table student add foreign key(class_id) references  class (cid) on delete cascade on update cascade;

 

三、向該表新增一條數據,ID爲1,學生姓名爲alex,性別女,修改ID爲1的學生姓名爲wupeiqi,刪除該數據;

1
2
3
4
5
6
insert into  class (cname) values
( '一班' ),
( '二班' );
insert into student values( 1 , 'alex' , 'female' , '12345' , 1 );
update student  set  sname  =  'wupeiqi'  where  id  =  1 ;
delete  from  student where  id  =  1 ;

  

四、查詢student表中,每一個班級的學生數;

1
2
3
4
5
insert into student(sname,class_id) values
( 'james' , 1 ),
( 'durant' , 2 ),
( 'curry' , 3 );
select count( ID from  student;

  

五、修改credit字段爲unique屬性;

1
alter table student modify credit varchar( 32 not  null unique;

  

六、請使用命令在你本地數據庫中增長一個用戶,並給該用戶授予建立表的權限;

1
grant create on  * . *  to  'james' @ 'localhost'  identified by  '123' ;      

  

七、請使用pymsql模塊鏈接你本地數據庫,並向student表中插入一條數據;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# _*_ coding: utf-8 _*_
# 七、請使用pymsql模塊鏈接你本地數據庫,並向student表中插入一條數據;
import  pymysql
conn  =  pymysql.connect(
     host  =  '127.0.0.1' ,
     port  =  3306 ,
     user  =  'root' ,
     password  =  '******' ,
     db  =  'test622' ,
     charset  =  'utf8'
)
cursor  =  conn.cursor()
sql  =  "insert into student values(13,'park','男','123456',1)"
rows  =  cursor.execute(sql)
 
conn.commit()
cursor.close()
conn.close()

  

八、請使用mysqldump命令備份student表;

1
mysqldump  - uroot  - p123 db_bj student >  / home / bj / 桌面 / myfile / student.sql

  

九、建立一張名爲student_insert_log的表,要求每次插入一條新數據到student表時,都向student_insert_log表中插入一條記錄,記錄student_idinsert_time;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
mysql> desc student;
+ - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - + - - - - - + - - - - - - - - - + - - - - - - - - - - - - - - - - +
| Field    |  Type                   | Null | Key | Default | Extra          |
+ - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - + - - - - - + - - - - - - - - - + - - - - - - - - - - - - - - - - +
ID        int ( 11 )               | NO   | PRI | NULL    | auto_increment |
| sname    | varchar( 16 )           | NO   |     | NULL    |                |
| gender   | enum( 'male' , 'female' ) | NO   |     | female  |                |
| credit   | varchar( 32 )           | NO   | UNI | NULL    |                |
| class_id |  int ( 11 )               | NO   | MUL | NULL    |                |
+ - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - + - - - - - + - - - - - - - - - + - - - - - - - - - - - - - - - - +
   
create table student_insert_log(
     student_id  int  not  null,
     insert_time datetime  not  null
);
     
建立一個觸發器:
delimiter  / /
create trigger tri_after_insert_student after insert on student  for  each row
begin
     insert into student_insert_log values(new. ID ,now());
end  / /
delimiter ;
     
insert into student(sname,credit,class_id) values ( 'alice' , '123' , 2 );
insert into student(sname,credit,class_id) values
( 'egon1' , '1234' , 1 ),
( 'egon2' , '12345' , 2 );
     
mysql> select  *  from  student;
+ - - - - + - - - - - - - + - - - - - - - - + - - - - - - - - - + - - - - - - - - - - +
ID  | sname | gender | credit  | class_id |
+ - - - - + - - - - - - - + - - - - - - - - + - - - - - - - - - + - - - - - - - - - - +
|   4  | alcie | female |  123456   |         1  |
|   7  | alcie | female |  1234567  |         1  |
|   8  | alice | female |  123      |         2  |
|   9  | egon1 | female |  1234     |         1  |
10  | egon2 | female |  12345    |         2  |
+ - - - - + - - - - - - - + - - - - - - - - + - - - - - - - - - + - - - - - - - - - - +
     
mysql> select  *  from  student_insert_log;
+ - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - +
| student_id | insert_time         |
+ - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - +
|           8  2018 - 04 - 24  21 : 29 : 46  |
|           9  2018 - 04 - 24  21 : 32 : 05  |
|          10  2018 - 04 - 24  21 : 32 : 05  |
+ - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - +
10 、建立一張名爲student_update_log的表,要求每次更新student表中的記錄時,都向student_update_log表中插入一條記錄,記錄student_id, update_time;
create table student_update_log(
     student_id  int  not  null,
     update_time datetime
); 
     
建立一個觸發器
delimiter  / /
create trigger tri_after_update_student after update on student  for  each row
begin
     insert into student_update_log values(new. ID ,now());
end  / /
delimiter ;
     
show triggers\G;
     
update student  set  sname  =  'alex'  where  ID  in  ( 9 , 10 );
mysql> select  *  from  student;
+ - - - - + - - - - - - - + - - - - - - - - + - - - - - - - - - + - - - - - - - - - - +
ID  | sname | gender | credit  | class_id |
+ - - - - + - - - - - - - + - - - - - - - - + - - - - - - - - - + - - - - - - - - - - +
|   4  | alcie | female |  123456   |         1  |
|   7  | alcie | female |  1234567  |         1  |
|   8  | alice | female |  123      |         2  |
|   9  | alex  | female |  1234     |         1  |
10  | alex  | female |  12345    |         2  |
+ - - - - + - - - - - - - + - - - - - - - - + - - - - - - - - - + - - - - - - - - - - +
5  rows  in  set  ( 0.00  sec)
     
mysql> select  *  from  student_update_log;
+ - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - +
| student_id | update_time         |
+ - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - +
|           9  2018 - 04 - 24  21 : 47 : 24  |
|          10  2018 - 04 - 24  21 : 47 : 24  |
+ - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - +
相關文章
相關標籤/搜索