併發編程:線程、進程、隊列、IO多路模型 操做系統工做原理介紹、線程、進程演化史、特色、區別、互斥鎖、信號、 事件、join、GIL、進程間通訊、管道、隊列。 生產者消息者模型、異步模型、IO多路複用模型、select\poll\epoll 高性 能IO模型源碼實例解析、高併發FTP server開發
一、請寫一個包含10個線程的程序,主線程必須等待每個子線程執行完成以後才結束執行,每個子線程執行的時候都須要打印當前線程名、當前活躍線程數量;html
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 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----')
二、請寫一個包含10個線程的程序,並給每個子線程都建立名爲"name"的線程私有變量,變量值爲「james」;python
from threading import Thread def 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 ---')
三、請使用協程寫一個消費者生產者模型;mysql
協程知識點:http://www.javashuo.com/article/p-adknkdvb-ct.htmlsql
協程:單線程下,沒法利用多核,能夠是一個程序開多個進程,每一個進程開啓多個線程,每隔線程開啓協程;數據庫
協程指的是單個線程,於是一旦協程出現阻塞,將會阻塞整個線程。編程
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()
四、寫一個程序,包含十個線程,子線程必須等待主線程sleep 10秒鐘以後才執行,並打印當前時間;性能優化
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 i in range(10): t = Thread(target=task) t.start() time.sleep(10) event.set()
五、寫一個程序,包含十個線程,同時只能有五個子線程並行執行;服務器
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 i in range(10): t = Thread(target=task,args=(i,)) t.start()
六、寫一個程序 ,包含一個名爲hello的函數,函數的功能是打印字符串「Hello, World!」,該函數必須在程序執行30秒以後纔開始執行(不能使用time.sleep());網絡
from threading import Timer def hello(name): print('%s say '%name,'Hello World!') if __name__ == "__main__": t = Timer(5,hello,args=('james',)) t.start()
七、寫一個程序,利用queue實現進程間通訊;多線程
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 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('主') # 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 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('主')
八、寫一個程序,利用pipe實現進程間通訊;
from multiprocessing import Process,Pipe def 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())
九、使用selectors模塊建立一個處理客戶端消息的服務器程序;
# 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或者線程服務器,一個潛在的問題是,惡意的程序可能會發送大量的請求致使服務器崩潰,請寫一個程序,避免此類問題;
# 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模塊,實現一個支持同時處理多個客戶端請求的服務器,要求每次啓動一個新線程處理客戶端請求;
socketserver模塊類介紹 SocketServer內部使用 IO多路複用 以及 「多線程」 和 「多進程」 , 從而實現併發處理多個客戶端請求的Socket服務端。即:每一個客戶端請求 鏈接到服務器時,Socket服務端都會在服務器是建立一個「線程」或者「進 程」 專門負責處理當前客戶端的全部請求。 socketserver模塊能夠簡化網絡服務器的編寫,python把網絡服務抽 象成兩個主要的類,一個是server類,用於處理鏈接相關的網絡操做,另外一個 是RequestHandler類,用於處理數據相關的操做。而且提供兩個Mixln類, 用於擴展server,實現多進程或者多線程。
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) t = threading.Thread(target=server.serve_forever) t.start()
一、數據庫介紹、類型、特性 二、MySQL數據庫安裝、鏈接、啓動、中止 三、表字段類型介紹、主鍵約束、表建立語句 四、經常使用增刪改查語句、分組、聚合 五、外鍵管理、unique字段、表結構修改語法 六、跨表查詢,inner join、left join、right join、full join語法 七、複雜SQL語句如group by、子查詢、函數的使用 八、索引原理及做用、普通索引、多列索引、惟一索引、全文索引等 九、基於hash&b+樹索引的實現原理,索引的優缺點剖析 十、事務原理,ACID特性,應用場景講解 十一、事務回滾 十二、觸發器的特性,應用場景 1三、觸發器的增刪改查方法 1四、存儲過程的做用及應用場景 1五、建立存儲過程,參數傳遞,流程控制語句if\while\repeat\loop等,動態SQL的建立 1六、視圖的做用及使用場景,視圖的增刪改查 1七、數據庫權限管理,用戶管理 1八、數據庫備份命令及工具講解 1九、基於不一樣業務的數據庫表結構設計、性能優化案例 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 舊字段名 新字段名 新數據類型 [完整性約束條件…];
一、建立一個表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) );
二、在上面的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;
三、向該表新增一條數據,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;
四、查詢student表中,每一個班級的學生數;
insert into student(sname,class_id) values ('james',1), ('durant',2), ('curry',3); select count(ID) from student;
五、修改credit字段爲unique屬性;
alter table student modify credit varchar(32) not null unique;
六、請使用命令在你本地數據庫中增長一個用戶,並給該用戶授予建立表的權限;
grant create on *.* to 'james'@'localhost' identified by '123';
七、請使用pymsql模塊鏈接你本地數據庫,並向student表中插入一條數據;
# _*_ 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表;
mysqldump -uroot -p123 db_bj student > /home/bj/桌面/myfile/student.sql
九、建立一張名爲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 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 | +------------+---------------------+ 十、建立一張名爲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 | +------------+---------------------+