python 闯关之路四(下)(并发编程与数据库编程) 并发编程重点 python 闯关之路四(下)(并发编程与数据库编程)

python 闯关之路四(下)(并发编程与数据库编程)

 

并发编程重点:

1
2
3
4
5
6
7
并发编程:线程、进程、队列、IO多路模型
 
操作系统工作原理介绍、线程、进程演化史、特点、区别、互斥锁、信号、
事件、join、GIL、进程间通信、管道、队列。
 
生产者消息者模型、异步模型、IO多路复用模型、select\poll\epoll 高性
能IO模型源码实例解析、高并发FTP server开发

1、请写一个包含10个线程的程序,主线程必须等待每一个子线程执行完成之后才结束执行,每一个子线程执行的时候都需要打印当前线程名、当前活跃线程数量;

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----' )

2、请写一个包含10个线程的程序,并给每一个子线程都创建名为"name"的线程私有变量,变量值为“james”;

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 ---' )

3、请使用协程写一个消费者生产者模型;

协程知识点:https://www.cnblogs.com/wj-1314/p/9040121.html

协程:单线程下,无法利用多核,可以是一个程序开多个进程,每个进程开启多个线程,每隔线程开启协程;

  协程指的是单个线程,因而一旦协程出现阻塞,将会阻塞整个线程。

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()

4、写一个程序,包含十个线程,子线程必须等待主线程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 ()

5、写一个程序,包含十个线程,同时只能有五个子线程并行执行;

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()

6、写一个程序 ,包含一个名为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()

7、写一个程序,利用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 ( '主' )

8、写一个程序,利用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())

9、使用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' ))
 

10、使用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()

11、请使用asyncio实现一个socket服务器端程序;

 12、写一个程序,使用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 旧字段名 新字段名 新数据类型 [完整性约束条件…];

  

1、创建一个表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 )
);

  

2、在上面的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;

 

3、向该表新增一条数据,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 ;

  

4、查询student表中,每个班级的学生数;

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

  

5、修改credit字段为unique属性;

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

  

6、请使用命令在你本地数据库中增加一个用户,并给该用户授予创建表的权限;

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

  

7、请使用pymsql模块连接你本地数据库,并向student表中插入一条数据;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# _*_ coding: utf-8 _*_
# 7、请使用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()

  

8、请使用mysqldump命令备份student表;

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

  

9、创建一张名为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  |
+ - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - +

并发编程重点:

1
2
3
4
5
6
7
并发编程:线程、进程、队列、IO多路模型
 
操作系统工作原理介绍、线程、进程演化史、特点、区别、互斥锁、信号、
事件、join、GIL、进程间通信、管道、队列。
 
生产者消息者模型、异步模型、IO多路复用模型、select\poll\epoll 高性
能IO模型源码实例解析、高并发FTP server开发

1、请写一个包含10个线程的程序,主线程必须等待每一个子线程执行完成之后才结束执行,每一个子线程执行的时候都需要打印当前线程名、当前活跃线程数量;

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----' )

2、请写一个包含10个线程的程序,并给每一个子线程都创建名为"name"的线程私有变量,变量值为“james”;

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 ---' )

3、请使用协程写一个消费者生产者模型;

协程知识点:https://www.cnblogs.com/wj-1314/p/9040121.html

协程:单线程下,无法利用多核,可以是一个程序开多个进程,每个进程开启多个线程,每隔线程开启协程;

  协程指的是单个线程,因而一旦协程出现阻塞,将会阻塞整个线程。

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()

4、写一个程序,包含十个线程,子线程必须等待主线程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 ()

5、写一个程序,包含十个线程,同时只能有五个子线程并行执行;

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()

6、写一个程序 ,包含一个名为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()

7、写一个程序,利用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 ( '主' )

8、写一个程序,利用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())

9、使用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' ))
 

10、使用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()

11、请使用asyncio实现一个socket服务器端程序;

 12、写一个程序,使用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 旧字段名 新字段名 新数据类型 [完整性约束条件…];

  

1、创建一个表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 )
);

  

2、在上面的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;

 

3、向该表新增一条数据,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 ;

  

4、查询student表中,每个班级的学生数;

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

  

5、修改credit字段为unique属性;

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

  

6、请使用命令在你本地数据库中增加一个用户,并给该用户授予创建表的权限;

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

  

7、请使用pymsql模块连接你本地数据库,并向student表中插入一条数据;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# _*_ coding: utf-8 _*_
# 7、请使用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()

  

8、请使用mysqldump命令备份student表;

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

  

9、创建一张名为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  |
+ - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - +

猜你喜欢

转载自www.cnblogs.com/anzhangjun/p/9459131.html
今日推荐