python web的一些常见技术面试笔试题
阅读原文时间:2023年07月05日阅读:1

1、 三次握手四次挥手

tcp建立连接的过程是三次挥手,断开连接是4次挥手。

三次握手:建立连接时 a. 客户端发送syn=1 seq=k给服务器 b. 服务器接收到之后知道有客户端想建立连接,

为了确认, 发送 syn=1 seq=n ACK=1 ack=k + 1 c. 客户端收到后向服务器回复ACK=1 seq=k+1 ack=n+1确认 ,进入连接态,

服务器收到后进入连接态。

四次挥手: a. 主动方发送FIN=1 seq=n,进入结束等待1态 b. 被动方收到后回复ACK=1 ack=u+1 seq=v,进入等待关闭态

c. 主动方收到后进入结束等待2态 d. 被动方传输完数据后发送 FIN=1 ACK=1 ack=u+1 seq=w , 进入最后确认态 e. 主动收到

回复ACK=1, seq=u+1 ack=w+1 后进入时间等待态 f.被动方收到后关闭tcp, 主动方等待2个最长报文时间没有收到任何数据进入

tcp关闭状态

2. 进程、线程、协程的区别

进程:程序的启动就是一个进程,进程有独立的内存空间,相对比较稳定,但是创建、切换进程的时间开销大,

线程:线程是进程的最小单位,共享进程中的全部资源,上下文切换相对于进程来说很快,开销小,但是不稳定,容易丢失数据,python的多线程并不是真正的并发,不能真正使用多核cpu

协程:协程也可以叫做轻量级的线程,调度由用户自己控制,进程线程都是系统来进行调度,上下文切换非常快,没有内核切换的开销。

总结:如果计算密集型处理则采用多进程,如果是io密集型采用多线程或者多协程

3. 手写单例

a.

def singleton(cls):

    instanse = {}

    def get_single_ton(*args, **kwargs):

        if cls not in instances:

            instanse[cls] = cls(*args, **kwargs)

            return get_single_ton

@singleton

class MyClass():

    def foo(self):

        pass

b.

class SingleTon():

    def __new__(cls,):

        if cls not hasattr('ins'):

            cls.ins = super(SingleTon, cls).__new__(cls)

            return cls.ins

4. python常用的设计模式

单例、工厂、创造者、装饰器、生成器、适配器等

5. 深拷贝、浅拷贝

浅拷贝只是对另外一个变量的内存地址的拷贝,这两个变量指向同一个内存地址的变量值。

一个变量对另外一个变量的值拷贝。

6. 迭代器、生成器

a. 通过实现迭代器协议对应的__iter__()和next()方法,可以自定义迭代器类型。对于可迭代对象,for语句可以通过iter()方法获取迭代器,

并且通过next()方法获得容器的下一个元素。

b. 生成器是一种特殊的迭代器,内部支持了生成器协议,不需要明确定义__iter__()和next()方法。

c. 生成器通过生成器函数产生,生成器函数可以通过常规的def语句来定义,但是不用return返回,而是用yield一次返回一个结果,生成器是一种特殊的迭代器, 在函数中使用yield就是一个生成器, 只能遍历一次

7. 垃圾回收

应用计数 标记清除 分代回收

8. session cookie区别

a、cookie数据存放在客户的浏览器上,session数据放在服务器上。

b、cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session。

c、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用cookie。

d、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。

e、可以考虑将登陆信息等重要信息存放为session,其他信息如果需要保留,可以放在cookie中。

Cookie保存在客户端浏览器中,而Session保存在服务器上。

Cookie机制是通过检查客户身上的“通行证”来确定客户身份的话,

那么Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。Session相当于程序在服务器上建立的一份客户档案,

客户来访的时候只需要查询客户档案表就可以了。

9. 消息队列

为什么要用?

优点: 解耦、异步、消峰

缺点: mq一挂就崩 重复消息 数据不一致

redis: 是一个nosql数据库, 也支持mq功能。对于数据量小的场景性能很高,但数据超过10k就比较慢!

rabbitmq: 比较重量级,支持协议多, 对路由、负载均衡、数据持久化都有很好的支持

a. 由于erlang语言的特性,mq 性能较好,高并发;

b. 健壮、稳定、易用、跨平台、支持多种语言、文档齐全;

c. 有消息确认机制和持久化机制,可靠性高;

d. 高度可定制的路由;

e. 管理界面较丰富,在互联网公司也有较大规模的应用;

f. 社区活跃度高;

kafka:

a. 快速持久化,可以在O(1)的系统开销下进行消息持久化;

b. 高吞吐,在一台普通的服务器上既可以达到10W/s的吞吐速率;

c. 完全的分布式系统,Broker、Producer、Consumer都原生自动支持分布式,自动实现负载均衡;

d.支持同步和异步复制两种HA;

e. 支持数据批量发送和拉取;

f. zero-copy:减少IO操作步骤;

g. 数据迁移、扩容对用户透明;

h. 无需停机即可扩展机器;

总结: 广泛来说,电商、金融等对事务性要求很高的,可以考虑RabbitMQ和RocketMQ,对性能要求高,大数据实时性、日志采集等场景的可考虑Kafka。

10. restful

编写api的一套协议规范, 面向资源编程,给调用者一个url, 根据请求方法后端做不同的处理。如post put get delete

而no rest就是给调用者多个url.

常见请求头: User-Agent Host Cookie Connetion Accept Accept-Language Accept-Encoding等

幂等: 一个接口通过1次相同的访问,再对该接口进行N次相同的访问时候,对资源不造影响,那么就认为接口具有幂等

11. 队列

quene模块

quene.Quene 单向队列

quene.LifoQuene 后进先出

quene.PriorityQueue 优先级s

quene.deque 双端

12. 数据库

redis与mongodb

完全不同的东西。

mongodb:最像关系型数据库的nosql。相比redis,只是缓存了热点数据在内存

redis:in-memory;丰富的数据结构;一般作为缓存,提高了并发性;

什么是NoSQL数据库?在哪些情况下使用和不使用NoSQL数据库?

NoSQL是非关系型数据库,NoSQL = Not Only SQL。

1. 数据结构不同:关系型数据库采用的结构化的数据,NoSQL采用的是键值对的方式存储数据。两者是不同的数据存储结构。

2. 成熟度:在考虑数据库的成熟度;支持;分析和商业智能;管理及专业性等问题时,应优先考虑关系型数据库。

3. 结构化: 在处理非结构化/半结构化的大数据时;在水平方向上进行扩展时;随时应对动态增加的数据项时可以优先考虑使用NoSQL数据库。

(1)mongodb所负责部分以文档形式存储,能够有较好的代码亲和性,json格式的直接写入方便。(如日志之类)

(2) 海量数据存储

(3)地理位置(匹配需求越多越合适,学习、开发、运维)

(4)监控数据, 加字段不用修改表结构

(5)大数据不可预计的增长

(6)第三方数据抓取

redis mysql?

redis 是内存数据库,数据保存在内存中,速度快。

mysql 是关系型数据库,持久化存储,存放在磁盘里面,功能强大。检索的话,会涉及到一定的 IO,数据访问也就慢。

一般需要永久存储的数据使用MySQL,比如用户信息,文章等

而临时数据或者经常访问的数据就会使用redis,比如用户的session/排行榜/访问计数/Pub Sub 构建实时消息系统/缓存等

mongodb mysql 不同

1. 事务

2. 非关系

3. 内存 + 持久

4. 成熟度

5. 广泛度

mongodb 语句

>db.col.find({"likes": {$gt:50}, $or: [{"by": "菜鸟教程"},{"title": "MongoDB 教程"}]}).pretty()

{

"_id" : ObjectId("56063f17ade2f21f36b03133"),

"title" : "MongoDB 教程",

"description" : "MongoDB 是一个 Nosql 数据库",

"by" : "菜鸟教程",

"url" : "http://www.runoob.com",

"tags" : [

"mongodb",

"database",

"NoSQL"

],

"likes" : 100

}

use db_name

db.dropDatabase()

db.collection.drop()

db.createCollection(name, optinos)

db.col2.insert({'':''}) client[][].insert_one() ~.insert_many()

13. 打印目录

import os

for root, dirs, files in os.walk(".", topdown=False):

    for name in files:

        print(os.path.join(root, name))

        for name in dirs:

            print(os.path.join(root, name))

14. 统计单词

.统计一个文本中单词频次最高的10个单词?

import re

# 方法一

def test(filepath):

distone = {}

with open(filepath) as f:

for line in f:

line = re.sub("\W+", " ", line)

lineone = line.split()

for keyone in lineone:

if not distone.get(keyone):

distone[keyone] = 1

else:

distone[keyone] += 1

num_ten = sorted(distone.items(), key=lambda x:x[1], reverse=True)[:10]

num_ten =[x[0] for x in num_ten]

return num_ten

# 方法二

# 使用 built-in 的 Counter 里面的 most_common

import re

from collections import Counter

def test2(filepath):

with open(filepath) as f:

return list(map(lambda c: c[0], Counter(re.sub("\W+", " ", f.read()).split()).most_common(10)))

17. 闭包

def multi():

return [lambda x : i*x for i in range(4)]

print([m(3) for m in multi()])

正确答案是[9,9,9,9],而不是[0,3,6,9]产生的原因是Python的闭包的后期绑定导致的,这意味着在闭包中的变量是在内部函数被调用的时候被查找的,因为,最后函数被调用的时候,for循环已经完成, i 的值最后是3,因此每一个返回值的i都是3,所以最后的结果是[9,9,9,9]

18. http socket websocket

1,传输层的TCP是基于网络层的IP协议的,

2,而应用层的HTTP协议又是基于传输层的TCP协议的,

3,而Socket本身不算是协议,就像上面所说,它只是提供了一个针对TCP或者UDP编程的接口.

websocket 和socket区别

1,websocket是应用层的协议,而socket是传输控制层的协议.  

websocket 和http区别   

相同点:

   1,都是应用层的协议

   2,都是基于tcp,并且都是可靠的协议

不同点:

    1,websocket是持久连接的协议,而http是非持久连接的协议.

   2,websocket是双向通信协议,模拟socket协议,可以双向发送消息,而http是单向的.

    3,websocket的服务端可以主动向客服端发送信息,而http的服务端只有在客户端发起请求时才能发送数据,无法主动向客户端发送信息.

HTTPS和HTTP的区别主要为以下四点:

1、https协议需要到ca申请证书,一般免费证书很少,需要交费。

2、http是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议。

3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。

4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

19.长连接和短连接

1,长连接:在HTTP 1.1,客户端发出请求,服务端接收请求,双方建立连接,在服务端没有返回之前保持连接,当客户端再发送请求时,它会使用同一个连接。

这一直继续到客户端或服务器端认为会话已经结束,其中一方中断连接。

       优势:减少了连接请求,降低TCP阻塞,减少了延迟,实时性较好。

       劣势:可能会影响性能,因为它在文件被请求之后还保持了不必要的连接很长时间。

 2,短连接:在HTTP1.0中,客户端发送请求,服务器接收请求,双方建立连接,服务器响应资源,请求结束。

20. 加解密

具体过程是先由接收方创建RSA密钥对,接收方通过Internet发送RSA公钥到发送方,

同时保存RSA私钥。而发送方创建AES密钥,并用该AES密钥加密待传送的明文数据,

同时用接受的RSA公钥加密AES密钥,最后把用RSA公钥加密后的AES密钥同密文一起通过Internet传输发送到接收方。

当接收方收到这个被加密的AES密钥和密文后,首先调用接收方保存的RSA私钥,并用该私钥解密加密的AES密钥,得到AES密钥。最后用该AES密钥解密密文得到明文

21. 微服务

1. protobuf

google出品的一个序列化框架, 可以跨平台、跨语言使用,

扩展性良好,与xml json等序列化框架相同。广泛用于数据存储,网络传输,rpc

调用等环境!

2. http2

二进制而非文本格式

多路复用而非有序并阻塞,只需一个连接即可实现

报头压缩,降低开销

服务器推送

3. https

header body都加密

4. grpc

grpc主要使用场景:

低延时、高可用的分布式系统;

移动端与云服务端的通讯;

使用protobuf,独立于语言的协议,支持多语言之间的通讯;

可以分层扩展,如:身份验证,负载均衡,日志记录,监控等。

提升传输的效率,无用的报头

22. django flask

django:主要是用来搞快速开发的,他的亮点就是快速开发,节约成本,,如果要实现高并发的话,

就要对django进行二次开发,比如把整个笨重的框架给拆掉自己写socket实现http的通信,底层用纯c,c++写提升效率,

ORM框架给干掉,自己编写封装与数据库交互的框架,ORM虽然面向对象来操作数据库,但是它的效率很低,

使用外键来联系表与表之间的查询;

flask: 轻量级,主要是用来写接口的一个框架,实现前后端分离,提考开发效率,

Flask本身相当于一个内核,其他几乎所有的功能都要用到扩展(邮件扩展Flask-Mail,

用户认证Flask-Login),都需要用第三方的扩展来实现。比如可以用Flask-extension加入ORM、文件上传、身份验证等。

Flask没有默认使用的数据库,你可以选择MySQL,也可以用NoSQL。