python网络编程

python网络编程

第一部分

1.简述OSI7层模型及其作用?

# OSI7层模型
应用层 HTTP,HTTPS,FTP
表示层
会话层
传输层 封装端口 TCP/UDP协议
网络层 封装IP,ipv4,ipv6
数据链路层   封装mac地址,通过arp协议
物理层 转换成二进制字节流,封装成数据包,加上各种请求头,通过网络进行传输数据

 

2.简述TCP三次握手、四次挥手的流程。

三次握手是TCP协议建立连接的过程
假设,客户端想要连接服务端,首先客户端发给服务端一个syn请求,意思就是我客户端想要和服务端建立连接,然后服务端发送给客户端一个ack请求,意思就是可以和你建立连接,同时也发送一个syn请求,意思就是我和你客户端建立连接,TCP的数据传输需要两端都同意建立连接,所以TCP协议很安全,客户端收到syn请求,回给服务器一个syn随机数+n,和一个ack请求,意思就是我客户端同意了

四次挥手是TCP协议断开连接的过程
FIN
ACK
FIN
ACK


SYN   请求创建连接
FIN 请求断开连接
ACK 确认响应

 

3.TCP和UDP的区别?

TCP协议 可靠、面向连接、速度慢、能传输的数据长度不限

UDP协议 即时通讯工具,不可靠 面上数据包 速度快 能传输的数据长度有限

TCP协议 面向连接,传输速度慢,数据安全,传输的数据没有限制

UDP协议 面向数据包,传输速度块,数据可能丢包,传输的数据有限制

 

4.什么是黏包?

由于TCP协议传输数据是通过数据流传输的,数据和数据之间没有边界,如果发送端处理过快,或者接收端接收数据慢,都会造成数据包的黏包

5.什么是B/S和C/S架构?

B/S浏览器对服务器架构,节省资源,不用更新,不依赖环境

C/S客户端对服务器架构,安全性高,程序庞大

6.请实现一个简单的socket编程(客户端和服务端可以进行收发信息)

# 基于TCP协议的socket
# Server
import socket

sk = socket.socket()
sk.bind(('127.0.0.1',8000))
sk.listen()

conn,addr = sk.accept()
msg = conn.recv(1024).decode('utf-8')
print(msg)

conn.close()
sk.close()

# Client
import socket
sk = socket.socket()
sk.connect(('127.0.0.1',8000))

msg = input('请输入信息:')
sk.send(msg.encode('utf-8'))
# 支持TCP的并发服务
import socketserver
class MyServer(socketserver.BaseRequestHandler):
def handle(self):
conn = self.request

if __name__ == '__main__':
server = socketserver.ThreadingTCPServer(('127.0.0.1',9005),MyServer)
server.serve_forever()
# 基于UDP协议的socket
# server
improt socket
sk = socket.socket(type=socket.SOCK_DGRAM)
sk.bind(('127.0.0.1',8000))

msg,cli_addr = sk.recvfrom(1024)
print(msg.decode('utf-8'))

# client   stuff
import socket
sk = socket.socket(type=socket.SOCK_DGRAM)
ser_addr = ('127.0.0.1',8000)
sk.sendto(b'request', ser_addr)

 

7.简述进程、线程、协程的区别?

进程是操作系统分配资源的最小单位,一个进程中可以有多个线程

线程是操作系统调度的最小单位,同一个进程中的线程共享进程中的资源,只能并发,不能并行

协程也被称为微线程,实现单线程在多任务之间的自由切换,是线程执行任务的一种方式

 

8.什么是GIL锁?

GIL锁是python解释器中特有的锁
作用是每一个进程同一时刻,只能有一个线程被调用

 

9.进程之间如何进行通信?

IPC通信
1.管道Pipe(进程和进程之间只能单向通信)
2.Queue进程和进程之间可以双向通信
3.基于文件

 

10.python如何使用线程池、进程池?

from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
p = ProcessPoolExecutor()
p = TheadPoolExecutor

res = p.submit(func,参数1,参数2)

res_new = res.result()

p.shutdown()

 

11.请通过yield关键词实现一个协程?

# 创建生成器
1.生成器表达式,(i for i in range(10))
2.生成器函数 函数中含有yield,需要初始化才能使用

def producer():
for i in range(100):
n = yield i
print('结果是%s',n)

def consumer():
g = producer()
g.send(None)


fo i in range(10):
res = g.send(i)
print(res)
customer()

 

12.什么是异步非阻塞?

同步:从上到下按照顺序依次执行
异步:不需等待异步的代码执行完毕,直接向下依次执行,自己又开启了一个线程,独自执行

异步非阻塞就是代码一旦遇到阻塞代码,就把阻塞代码异步

 

13.什么是死锁?如何避免?

互斥锁,死锁,递归锁
只上锁不解锁就是死锁
避免交叉使用锁,如果必须要使用,那就都是交叉使用的锁是同一个锁

 

14.程序从flag a执行到flag b的时间大致是多少秒?

import threading
import time
def _wait():
time.sleep(60)

# flag a
t = threading.Thread(target=_wait)
t.setDeamon(False)
t.start()
# flag b

0.0001

 

15.程序从flag a 执行到flag b的时间大致是多少秒?

improt threading
improt time
def _wait():
time.sleep(60)

# flag a
t = theading.Thread(target=_wait)
t.setDeamon(True)
t.start()
# flag b

0.01

16.程序从flag a执行到flag b的时间大致是多少秒?

import theading
import time
def _wait():
time.sleep(60)
# flag a
t = theading.Thread(target=_wait)
t.start()
t.join()
# flag b

60

17.读程序,请确认执行到最后number是否一定为0

import threaing 
loop = int(1E7)
def _add(loop:int =1):
global number
for _ in range(loop):
number += 1

def _sub(loop:int=1):
global number
for _ in range(loop):
number-=1
number = 0

ta = theading.Thread(target=_add,args=(loop,))
ts = theading.Thread(target=_sub,args=(loop,))
ta.start()
ta.join()
ts.start()
ts.join()

一定为0

18.读程序,请确认执行到最后number是否一定为0

import threaing 
loop = int(1E7)
def _add(loop:int =1):
global number
for _ in range(loop):
number += 1

def _sub(loop:int=1):
global number
for _ in range(loop):
number-=1
number = 0

ta = theading.Thread(target=_add,args=(loop,))
ts = theading.Thread(target=_sub,args=(loop,))
ta.start()
ts.start()
ta.join()
ts.join()

# 不一定为0

19.Mysql常见数据库引擎及区别?

innodb
menmory
myisam
blackhole

 

20.简述事务及其特性?

事务就是一个程序执行单元
一致性  
原子性 事务中的所有sql语句,要么一起成功,要么事务并回滚
隔离性   事务和事务之间的过程是相互隔离的,并且有锁的机制,就是说当一条数据被一个事务操作时,其他需要操作本数据的事务需要等待
持久性   把数据写在硬盘上,数据的持久化存储

 

21.事务的隔离级别

读未提交
读已提交
可重复读
可序列化

 

22.char和varchar的区别?

char 定长,速度快
varchar 变长,速度慢,节省空间(数据的头部,会有1-2个字符存储数据长度)

 

23.mysql中varchar与char的区别以及varchar(50)中的50代表的含义

varchar(50)代表最多存储50个字符

24.Mysql中delete和truncate的区别

delete 删除数据
truncate 重置表(删除数据,重置自增ID)

25.where子句中有a,b,c三个查询条件,创建一个组合索引abc(a,b,c),以下哪种会命中索引

(a)     命中
(b) 不行
(c) 不行
(a,b) 命中
(b,c) 不行
(a,c) 命中
(a,b,c) 命中

 

26.组合索引遵循什么原则才能命中索引?

最左前缀原则,条件不能使用范围,可以使用and
where a >1 and b =1 and c = 100 不能命中
where b =1 and c = 100 or a = 10 不能命中

 

27.列举mysql常见的函数

count
avg
concat
concat_ws
sum
min
max
user
now
databases

 

28.Mysql数据库导入、导出的命令有哪些

# 数据库的导出(退出数据库,才能导出数据库)
mysqldump -uroot -p密码 db1.tab1 > db1.tab1.sql

# 数据库的导入(进入到mysql,选择好数据库)
source "sql的路径"

29.什么是sql注入

通过注入一些特殊的字符,绕开sql的判断机制

30.简述left join和inner join的区别?

left join 左连接 以左表为主,右表为辅,完整查询左表所有数据,右表中不存在数据用null补充
inner join 内连接 查询左表右表共同存在的数据 select * from a,b where a.cid = b.id

31.SQL语句中having的作用

一般和group by连用,将分组之后的数据进行二次过滤用having

32.Mysql数据库中varchar和text最多能存储多少个字符?

varchar最多存储2**8 / 3个字符
text最多存储 2**8个字符

33.Mysql的索引方式有几种?

主键索引
联合索引
辅助索引

34.什么时候索引会失效(有索引但无法命中索引)

1.如果查询的是一个大范围内的数据
2.用了or关键字
3.索引字段参与运算
4.使用like以%开头,
5.联合索引中,不符合最左前缀原则

35.数据库优化方案?

1.分表
2.读写分离
3.合理优化数据类型

36.什么是Mysql慢日志?

设定一个时间阈值,执行sql的时间超过该阈值,把该sql记录到慢日志中

第二部分

1.什么是IO多路复用

内部的实现就是异步非阻塞,通过单个线程管理多个socket连接,而不是创建大量的多进程或多线程,节省资源,提升效率
这些网络io都会被selector暂时挂起,推入内存序列
此时服务端可以任意处理调度里面的网络io
当连接的socket有数据的时候,自然会把对应的socket进行读写,而不至于一直阻塞等待io

2.async/await关键字的作用

asyncio是密集型任务中,处理协程异步并发的工具模块,目的是加快通信的速度,减少阻塞等待
async def 关键字定义异步的协程函数
await 关键字加载需要等待的操作前,控制一个可能发生io阻塞任务的切入和切出

3.数据库中有表:t_table_date

id      tade_date
1 2018-1-2
2 2018-1-26
3 2018-2-8
4 2018-5-6
...
输出每个月最后一天ID

select id max(tade_date) from t_table_date group by month(tada_date)

 

posted @ 2020-02-27 11:52  徐-  阅读(166)  评论(0编辑  收藏  举报