
本文共 13094 字,大约阅读时间需要 43 分钟。
并发编程重点:
并发编程:线程、进程、队列、IO多路模型操作系统工作原理介绍、线程、进程演化史、特点、区别、互斥锁、信号、事件、join、GIL、进程间通信、管道、队列。生产者消息者模型、异步模型、IO多路复用模型、select\poll\epoll 高性能IO模型源码实例解析、高并发FTP server开发
1、请写一个包含10个线程的程序,主线程必须等待每一个子线程执行完成之后才结束执行,每一个子线程执行的时候都需要打印当前线程名、当前活跃线程数量;
from threading import Thread,currentThread,activeCountimport timedef task(n): print('线程名:%s----%s'%(currentThread().name,n)) time.sleep(1) print('数量:%s'%activeCount()) if __name__ == "__main__": t_li = [] for i in range(10): t = Thread(target=task,args=(i,)) t.start() t_li.append(t) for t in t_li: t.join() print('主,end----')
2、请写一个包含10个线程的程序,并给每一个子线程都创建名为"name"的线程私有变量,变量值为“james”;
from threading import Threaddef task(name): print('%s is running'%name) print('end ---') if __name__ == "__main__": for i in range(10): t = Thread(target=task,args=('james_%s'%i,)) t.start() print('主 end ---')
3、请使用协程写一个消费者生产者模型;
协程知识点:
协程:单线程下,无法利用多核,可以是一个程序开多个进程,每个进程开启多个线程,每隔线程开启协程;
协程指的是单个线程,因而一旦协程出现阻塞,将会阻塞整个线程。
def consumer(): while True: x = yield print('消费:', x) def producter(): c = consumer() next(c) for i in range(10): print('生产:', i) c.send(i) producter()
4、写一个程序,包含十个线程,子线程必须等待主线程sleep 10秒钟之后才执行,并打印当前时间;
from threading import Thread,Eventimport timeimport datetimedef task(): # while not event.is_set(): # print('...') print('...') event.wait(10) print('time:',datetime.datetime.now()) if __name__ == '__main__': event = Event() for i in range(10): t = Thread(target=task) t.start() time.sleep(10) event.set()
5、写一个程序,包含十个线程,同时只能有五个子线程并行执行;
from threading import Thread,Semaphore,currentThreadimport timedef task(n): sm.acquire() print('%s---'%n,currentThread().name) time.sleep(1) print('end----') sm.release() if __name__ == '__main__': sm = Semaphore(5) for i in range(10): t = Thread(target=task,args=(i,)) t.start()
6、写一个程序 ,包含一个名为hello的函数,函数的功能是打印字符串“Hello, World!”,该函数必须在程序执行30秒之后才开始执行(不能使用time.sleep());
from threading import Timerdef hello(name): print('%s say '%name,'Hello World!') if __name__ == "__main__": t = Timer(5,hello,args=('james',)) t.start()
7、写一个程序,利用queue实现进程间通信;
from multiprocessing import Process,Queue,current_processimport timedef consumer(q): while True: res = q.get() if not res:break print('消费了:',res,'--',current_process().name) def producter(q): for i in range(5): print('生产:',i) time.sleep(1) q.put(i) if __name__ == "__main__": q = 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('主') # JoinableQueuefrom multiprocessing import Process,JoinableQueue,current_processimport timedef consumer(q): while True: res = q.get() print('消费了:',res,'--',current_process().name) q.task_done() def producter(q): for i in range(5): print('生产:',i,'--',current_process().name) time.sleep(1) q.put(i) q.join() if __name__ == "__main__": q = 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实现进程间通信;
from multiprocessing import Process,Pipedef task(conn): conn.send('hello world') conn.close() if __name__ == "__main__": parent_conn,child_conn = Pipe() p = Process(target=task,args=(child_conn,)) p.start() p.join() print(parent_conn.recv())
9、使用selectors模块创建一个处理客户端消息的服务器程序;
# server blocking IO import socketserver = 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 socketimport selectorssel = 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 socketclient = 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或者线程服务器,一个潜在的问题是,恶意的程序可能会发送大量的请求导致服务器崩溃,请写一个程序,避免此类问题;
# server socketserver 模块内部使用IO多路复用 和多进程/多线程import socketserverclass 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模块,实现一个支持同时处理多个客户端请求的服务器,要求每次启动一个新线程处理客户端请求;
socketserver模块类介绍 SocketServer内部使用 IO多路复用 以及 “多线程” 和 “多进程” ,从而实现并发处理多个客户端请求的Socket服务端。即:每个客户端请求连接到服务器时,Socket服务端都会在服务器是创建一个“线程”或者“进 程” 专门负责处理当前客户端的所有请求。 socketserver模块可以简化网络服务器的编写,python把网络服务抽象成两个主要的类,一个是server类,用于处理连接相关的网络操作,另一个是RequestHandler类,用于处理数据相关的操作。并且提供两个Mixln类,用于扩展server,实现多进程或者多线程。
import socketserverimport threadingclass 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) t = threading.Thread(target=server.serve_forever) t.start()
数据库重点:
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. 修改表名 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是可变长字符类型;
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字段;
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,删除该数据;
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表中,每个班级的学生数;
insert into student(sname,class_id) values('james',1),('durant',2),('curry',3); select count(ID) from student;
5、修改credit字段为unique属性;
alter table student modify credit varchar(32) not null unique;
6、请使用命令在你本地数据库中增加一个用户,并给该用户授予创建表的权限;
grant create on *.* to 'james'@'localhost' identified by '123';
7、请使用pymsql模块连接你本地数据库,并向student表中插入一条数据;
# _*_ coding: utf-8 _*_ # 7、请使用pymsql模块连接你本地数据库,并向student表中插入一条数据;import pymysqlconn = 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表;
mysqldump -uroot -p123 db_bj student > /home/bj/桌面/myfile/student.sql
9、创建一张名为student_insert_log的表,要求每次插入一条新数据到student表时,都向student_insert_log表中插入一条记录,记录student_id, insert_time;
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 rowbegin 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 rowbegin 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 |+------------+---------------------+
发表评论
最新留言
关于作者
