后端面试知识点整理
网络
Tcp三次握手和四次挥手
Client端发送请求报文syn,server端接受连接后回复ACK+syn报文,并为这次连接分配资源。Client端收到ACK报文后也向Server端发送ACK报文,并分配资源。
Client端发起中断连接请求,即发送FIN报文,server收到FIN报文后,表示Client不会继续发送数据了,但是server还可以发送数据给Client,因此先发一个ACK表示收到client的请求。当server发送完成后,再发送FIN给client,client再发送ACK给server。当client等待2MSL后没有收到回复,则证明server端正常关闭,client端也可以关闭连接了。
Get和post的区别
http和https的区别
浏览器访问服务器过程
常用的端口及对应服务
21 FTP
22 SSH
80 HTTP
443 HTTPS
3306 MySQL
6379 Redis
常见状态码
100 继续
200 请求成功
301 永久移动
302 临时移动
403 服务器拒绝
404 找不到网页
502 尝试执行请求时,从上游服务器接收到无效的响应
504 未能及时从上游服务器或者辅助服务器收到响应
C/S 客户端/服务器 B/S 浏览器/服务器
多进程
密集CPU任务,通信成本高,切换开销大
多线程
密集I/O任务,使用多线程合适
协程
在单线程上执行多个任务,用函数切换,开销极小
池的功能是限制启动的进程数或线程数。当并发的任务数远远超过了计算机的承受能力时,即无法一次性开启过多的进程数或线程数时,就应该用池的概念将开启的进程数或线程数限制在计算机可承受的范围内。
网络的七层:
物理层 集线器
没有寻址概念
数据链路层 以太网
交换机通过mac地址转发数据,逻辑链路控制
网络层 定义一个逻辑的寻址,选择最佳路径传输,路由数据包
设备:路由器 实现寻址 典型协议 ip
传输层 提供可靠和尽力而为的传输
典型协议:tcp udp port 负责网络传输和会话建立
会话层 控制会话,建立管理终止应用程序会话
典型协议:sql,php,jsp,nfs,windows
表示层 格式化数据 典型协议:ascii, png, mp3, avi, wav
可以提供加密服务
应用层 控制应用程序 为应用提供网络服务
典型协议: telnet, ssh, ftp, http, smtp, rip
重要协议:
Tcp/ip
TCP/IP 是供已连接因特网的计算机进行通信的通信协议。
TCP/IP 指传输控制协议/网际协议(Transmission Control Protocol / Internet Protocol)。
TCP/IP 定义了电子设备(比如计算机)如何连入因特网,以及数据如何在它们之间传输的标准。
Tcp用于从应用程序到网络的数据传输控制,tcp负责在数据传送之前将他们分割为ip包,然后在他们到达的时候将他们重组。
Ip负责计算机之间的通信,ip负责在因特网上发送和收割数据包
Tcp/udp
Tcp面向连接,udp面向无连接
Tcp可靠,udp不保证交付
Tcp面向字节流,udp面向报文
Tcp点到点,udp多对多交互通信
Tcp首部开销20字节,udp的首部开销小,只有8字节
Tcp的逻辑通信通道是全双工的可靠信道,udp则是不可靠信道
Cookie是客户端保存用户信息的机制,session是保存在服务端的一个数据结构
I/O执行的两个阶段
(1)等待数据准备好,到达内核缓冲区;
(2)从内核向进程复制数据。
同步 异步 阻塞 非阻塞
同步在发出一个功能调用得到结果前不返回,异步就是调用者不能立即得到结果,实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。这两者是针对于消息通知机制而言的。
阻塞是调用结果返回之前,当前线程会被挂起,函数只有在得到结果之后才会返回。非阻塞就是在不能立即得到结果之前,该函数不会阻塞当前线程,而会立刻返回。这两者是针对等待消息通知时的状态而言。
I/O多路复用 IO 多路复用的好处就在于单个进程就可以同时处理多个网络连接的IO。它的基本原理就是不再由应用程序自己监视连接,取而代之由内核替应用程序监视文件描述符。IO复用机制可以同时监控多个描述符,当某个描述符就绪(读或写就绪),则立即通知相应程序进行读或写操作。但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的。select/poll/epoll都是采用I/O多路复用机制的,其中select/poll是采用无差别轮询方式,而epoll是采用最小的轮询方式。
转存失败重新上传取消
数据库
Varchar和char
char长度固定为创建表时声明的长度,长度可以为0-255的任意值,varchar列中的值为可变长字符串。在检索的时候,char列删除了尾部的空格,而varchar则保留空格。
Delete truncate drop
delete删除一行,并且同时将该行的删除操作作为事务记录在日志中保存以便进行进行回滚操作。truncate则一次性地从表中删除所有的数据并不把单独的删除操作记录记入日志保存,删除行是不能恢复的。并且在删除的过程中不会激活与表有关的删除触发器。执行速度快。drop语句将表所占用的空间全释放掉。有外键和索引的表truncate不行。
存储引擎
MyISAM
不支持事务,不支持外键,访问速度快,(原因:myisam只缓存索引块,直接记录文件的offset,定位更快)对事务完整性没有要求或者以select、insert为主的应用基本上都可以使用这个引擎来创建表,但只有表锁,保存表的具体行数,非聚集索引,数据文件是分离的,索引保存的是数据文件的指针,系统崩溃之后恢复困难,适用于对并发、事务完整性要求不高的时候
InnoDB
提供了具有提交、回滚、崩溃恢复能力的事务安全,支持自动增长列,支持外键,具有行锁,不保存表的具体行数,聚集索引,数据文件和索引绑在一起,必须有主键,大量的delete、update应该考虑这个,删除时不会建立新表,而是一行一行的删除
索引
MyISAM和InnoDB默认都是B+TREE索引,MyISAM支持全文本索引,memory存储引擎使用HASH索引。
适用场景:
Hash索引只能用于=或<>的比较,优化器不能用hash索引加速order by,不能确定两个值之间大概有多少行,只能使用整个关键字来搜索一行。
B+树和B树
B+树只有叶子节点存储数据,所有叶子节点增加了一个链指针,B树每个节点都存储数据,叶子节点之间无指针相邻。单条数据查询B树更好,但是不适合遍历操作,B+树适合范围查询。
聚集索引:数据行的物理顺序与列值的顺序相同,索引的叶子节点就是对应的数据节点,可以直接获取到对应的全部列的数据,频繁改变聚集索引的值写入性能并不好。而非聚集索引在索引没有覆盖到对应的列的时候需要进行二次查询。聚集索引的速度往往更占优势。
ACID
原子性:事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生
一致性:事务前后数据库的完整性必须保持一致
隔离性:多个用户并发访问,各用户的事务不能互相干扰
持久性:一个事务一旦提交,对数据库的改变就是永久性的
三种数据不一致性:
丢失修改:R
不可重复读:R
读脏数据:W
三级封锁协议:
1级封锁协议:加X长锁,可防止丢失修改
2级封锁协议:加S短锁,可防止丢失修改和读脏数据
3级封锁协议:加S长锁,可防止丢失修改和读脏数据和不可重复读
两段锁协议:
两阶段提交:
准备阶段:全局协调者询问相关节点是否能保证原子性
提交阶段:如果所有都说能,协调者就让事务发起者提交事务,发送给所有站点,否则事务发送失败
Python
Encode decode
Encode把字符串转为byte,decode把byte转为字符串
一行打印9*9乘法表
print('\n'.join([' '.join(['%d*%d=%-2d' % (i, j, i * j) for i in range(1, j + 1)]) for j in range(1, 10)]))
正则表达式匹配邮箱
^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$
python内存问题
Python的内存管理是由私有heap空间管理的。所有的Python对象和数据结构都在一个私有heap中。程序员没有访问该heap的权限,只有解释器才能对它进行操作。为Python的heap空间分配内存是由Python的内存管理模块进行的,其核心API会提供一些访问该模块的方法供程序员使用。Python有自带的垃圾回收系统,它回收并释放没有被使用的内存,让它们能够被其他程序使用。
引用计数降为0,回收。但是会有循环引用问题,所以需要分代回收-标记-清除,标记活动对象。
小内存用内存池,大内存用malloc和free
当退出 Python 时是否释放所有内存分配?
答案是否定的。那些具有对象循环引用或者全局命名空间引用的变量,在 Python 退出是往往不会被释放。另外不会释放 C 库保留的部分内容。
什么是猴子补丁?
在运行时动态修改类和模块
*args和*kargs
当我们想传递一个列表或一个元组值时,就可以使用*args,当我们不知道将会传入多少关键字参数时,使用**kwargs 会收集关键字参数。
异常处理:
Try/except/else/finally
raise主动触发异常
Assert 断言 检查表达式是否为真,否则抛出异常
面向对象
__init__()方法是一种特殊的方法,被称为类的构造函数或初始化方法,当创建了这个类的实例时就会调用该方法。
__new__()创建实例时会调用,在__init__()之前,单例模式时用来创建唯一对象
__del__()析构函数
__call__()把实例对象作为函数调用
定义一个特殊的__slots__变量,来限制该class实例能添加的属性
Super解决多重继承问题
类的私有方法:
__private_method:两个下划线开头,声明该方法为私有方法,不能在类的外部调用。在类的内部调用 self.__private_methods
类的保护方法:
_foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import *
self代表类的实例,而非类
cls表示类名
类中普通的方法,通过self调。
在def前面加上@classmethod,这种类方法的一个特点就是可以通过类名去调用,但是也必须传递一个参数,一般用cls表示class,表示可以通过类直接调用。
在def前面加上@staticmethod,这种类方法是静态的类方法,类似于c++的静态函数,他的一个特点是参数可以为空,同样支持类名和对象两种调用方式。
在def前面加上一个@property,表示属性方法
Generator 生成器
一边循环一边计算,节省大量的存储空间
Next()可以获得下一个返回值
如果一个函数包含yield关键字,就是一个generator
装饰器
本质是一个函数或类,返回值也是函数或类。