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(16not 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(16not 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(IDfrom student;

  

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

1
alter table student modify credit varchar(32not 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 |
+------------+---------------------+

python 闯关之路四(下)(并发编程与数据库编程) 并发编程重点的更多相关文章

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

    并发编程重点: 并发编程:线程.进程.队列.IO多路模型 操作系统工作原理介绍.线程.进程演化史.特点.区别.互斥锁.信号. 事件.join.GIL.进程间通信.管道.队列. 生产者消息者模型.异步模 ...

  2. python 闯关之路四(上)(并发编程与数据库理论)

    并发编程重点: 并发编程:线程.进程.队列.IO多路模型 操作系统工作原理介绍.线程.进程演化史.特点.区别.互斥锁.信号. 事件.join.GIL.进程间通信.管道.队列. 生产者消息者模型.异步模 ...

  3. python 闯关之路一(语法基础)

    1,什么是编程?为什么要编程? 答:编程是个动词,编程就等于写代码,那么写代码是为了什么呢?也就是为什么要编程呢,肯定是为了让计算机帮我们搞事情,代码就是计算机能理解的语言. 2,编程语言进化史是什么 ...

  4. python闯关之路一(语法基础)

      1,什么是编程?为什么要编程? 答:编程是个动词,编程就等于写代码,那么写代码是为了什么呢?也就是为什么要编程呢,肯定是为了让计算机帮我们搞事情,代码就是计算机能理解的语言. 2,编程语言进化史是 ...

  5. python 闯关之路三(面向对象与网络编程)

    1,简述socket 通信原理 如上图,socket通信建立在应用层与TCP/IP协议组通信(运输层)的中间软件抽象层,它是一组接口,在设计模式中,socket其实就是一个门面模式,它把复杂的TCP/ ...

  6. python 闯关之路二(模块的应用)

    1.有如下字符串:n = "路飞学城"(编程题) - 将字符串转换成utf-8的字符编码的字节,再将转换的字节重新转换为utf-8的字符编码的字符串 - 将字符串转换成gbk的字符 ...

  7. python闯关之路(五)前端开发

    一,HTML部分 1,XHTML和HTML有什么区别 HTML是一种基本的WEB网页设计语言,XHTML是一个基于XML的置标语言最主要的不同: XHTML 元素必须被正确地嵌套. XHTML 元素必 ...

  8. python闯关之路二(模块的应用)

    1.有如下字符串:n = "路飞学城"(编程题) - 将字符串转换成utf-8的字符编码的字节,再将转换的字节重新转换为utf-8的字符编码的字符串 - 将字符串转换成gbk的字符 ...

  9. C#设计模式开启闯关之路

    前言背景 这是一条望不到尽头的编程之路,自踏入编程之路开始.就面临着各式各样的挑战,而我们也需要不断的挑战自己.不断学习充实自己.打好坚实的基础.以使我们可以走的更远.刚踏入编程的时候.根据需求编程, ...

随机推荐

  1. JAVA反射练习

    JAVA反射练习 题目 实现一个方法 public static Object execute(String className, String methodName, Object args[]) ...

  2. [荐]推荐一个shell学习的网站

    最近再用shell脚本,发现一个脚本学习的网站,非常好用,特此推荐一下. shell学习网站链接:http://c.biancheng.net/cpp/shell/

  3. Linux文件的三个时间属性(Atime,Mtime,Ctime)

    Linux下,一个文件有三种时间,分别是: 访问时间:atime 修改时间:mtime 状态时间:ctime 访问时间:对文件进行一次读操作,它的访问时间就会改变.例如像:cat.more等操作,但是 ...

  4. Dll注入:注册表注入

    在系统中每一个进程加载User32.dll时,会受到DLL_PROCESS_ATTACH通知,当User32.dll对其进行处理时,会取得注册表键值HKEY_LOCAL_MACHINE\Softwar ...

  5. HDU2433 最短路 + 剪枝优化

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2433 ,最短路(SPFA或优化过的Dijstra) + 剪枝优化 这道题关键还是在几个剪枝上面,没有剪 ...

  6. cesium加载shp格式数据

    方法一: shp格式转换为GeoJson格式并加载 首先注意shp的坐标系,要转换为WGS84,使用arcgis或QGIS 工具:http://mapshaper.org/: 注意:export时,输 ...

  7. js 中//<![CDATA[ 意义

    CDATA内部所有东西都会被解析器忽略,加入文本中包含了大量< 和 $符号,就像编程中经常出现的情况一样,那么这个元素就可以被定义为一个CDATA部分 ,CDATA 区段开始于 "&l ...

  8. IOS 强指针(strong)和弱指针(weak)

    // strong 强指针        // weak 弱指针        // ARC, 只要对象没有强指针就会自动释放        // OC中默认都是强指针

  9. noip模拟赛#39

    昨晚打开的题想了一会发现都不会后决定慢慢想.然后早上开校会的时候莫名其妙的都想出来了... T1:m=100,ai=50000,i<=5.1到m的数每个数只能用一次,判断是否能够有这些数的某些数 ...

  10. PHP 的那些错误总结

    问题1: [root@web01 data]# lsof  -i :9000 [root@web01 data]# /application/php/sbin/php-fpm /application ...