Python常见面试题汇总(根据面试总结)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liuskyter/article/details/80472819

Redis:

Redis缓存击穿、缓存雪崩、缓存重建

回答参考:

缓存击穿:

    当一个连接访问缓存数据库中不存在的数据时,会直接通过缓存数据库到后端数据库中查找数据,但如果有大量连接在查询一个不存在的数据,就会有大量连接直接访问到后端数据库,给后端服务器造成巨大压力,可能导致后台服务器崩溃的情况。  解决方案:当查询一个不存在的缓存数据时,访问数据库,如果发现后端数据库也不存在这个文件,将这个查询的key在缓存中保存为None。下次再有连接请求这个key时直接从缓存中返回。

缓存雪崩:

    缓存数据一般会设置过期时间,当所有的缓存数据几乎在同一时间过期时,会有大量数据直接访问到后端数据库,导致后端数据库瞬间承受访问压力过大,可能导致后端数据库崩溃。并且当数据库重启后,仍会有大量连接访问到数据库,可能导致再次崩溃。  解决方案:采用缓存重建或缓存预热。

缓存重建:

    Redis支持持久化操作,比如缓存之类不重要的数据可以使用RDB持久化,可以恢复大部分缓存内容到缓存数据库汇总,减少直接访问后端数据库的次数。

缓存预热:

    系统上线时手动加载一部分数据到缓存数据库,同样也是为了减少缓存数据库中没有数据,导致连接直接穿透到后端数据库的情况。

Redis应用场景

回答参考:

    Redis是非关系型内存数据库,要根据自己项目业务方向去思考Redis的应用场景,电商系统可以作为缓存数据库和订单队列,爬虫系统可以作为URL队列和去重。但毕竟Redis也是数据库的一种,直接作为数据库使用也是可以的。

Redis订阅发布机制

Redis提供了发布订阅功能,可以用于消息的传输,Redis的发布订阅机制包括三个部分,发布者,订阅者和Channel 
发布者和订阅者都是Redis客户端,Channel则为Redis服务器端,发布者将消息发送到某个的频道,订阅了这个频道的订阅者就能接收到这条消息。Redis的这种发布订阅机制与基于主题的发布订阅类似,Channel相当于主题。

 

详细介绍:

https://www.cnblogs.com/yitudake/p/6747995.html

https://blog.csdn.net/clh604/article/details/1975493


Redis集群

回答参考:

    Redis集群主要有主从集群和哨兵集群,主从集群就是将多台Redis服务器配置Master-Slave,以达到分摊访问压力的目的,但有时候主服务器也会有崩溃,断电或其他导致宕机的情况发生。这时候就可以使用哨兵集群配置。 也就是当Master服务器宕机时,其他的Slave服务器通过投票选出一台Slave服务器晋升为Master,替代原Master服务器的工作,保证整个集群的高可用性。

详细介绍:Redis哨兵集群

https://www.cnblogs.com/PatrickLiu/p/8444546.html

秒杀场景如何解决?

详细介绍:

https://blog.csdn.net/zhanjianshinian/article/details/53342730

使用Redis队列,设定队列最大数量,有新的订单直接加入队列,当超过最大数量时直接返回产品暂时售空,请稍后尝试,期间依次处理Redis队列中的订单请求,如果订单均成功,提示剩余用户秒杀结束,这样也可以一定程度的避免超卖情况。具体介绍看链接。


MySQL:

MySQL索引的原理

索引详细介绍:

https://blog.csdn.net/iefreer/article/details/15815455

B+数详细介绍:

https://www.zhihu.com/question/30527705

使用的MySQL版本号是多少?

MySQL常用版本号为5.6 / 5.7 / 5.8

最新的MySQL版本号为8.0

拓展: MySQL 4 - 5.6版本区别

http://www.jb51.net/article/121638.htm

拓展: MySQL 8.0 新特性

http://www.jb51.net/article/137123.htm

MySQL与Redis的区别

回答参考:

MySQL是关系型数据库,数据保存在硬盘上

Redis是非关系型数据库,数据保存在内存上

但两种数据库都支持事物,支持持久化(Redis的AOF和RDB)

Redis速度优于MySQL,常见于缓存或作为队列使用

MySQL不用模糊搜索,建立索引这些方法,如何降低一个数据量非常大的表的查询压力?

数据库是如何进行查询的,数据量大的时候有没有什么优化方案?

回答参考:

初期优化可以尝试建立索引,读写分离,更换硬盘,比如机械更换成固态,PCIE固态更换为更快的NVME固态,如果数据量达到一定级别时,就要考虑优化SQL查询语句等等;

数据库优化漏斗原则:

1、 减少磁盘访问(减少磁盘访问)

2、 返回更少数据(减少网络传输或磁盘访问)

3、 减少交互次数(减少网络传输)

4、 减少服务器CPU开销(减少CPU及内存开销)

5、 利用更多资源(增加资源)

拓展:SQL优化总结

https://blog.csdn.net/u011277123/article/details/72627011

数据库表增加了新字段更新问题

回答参考:

MySQL增加了新字段后,如果设置了字段默认值,则原先所有数据在该字段的值更新为默认值。

就像在更新MySQL字段后,在Django中执行Migrate操作必须要对新字段设置默认值一样。

Django、Nginx:

 

Django中如何连接多个数据库?

连接多个数据库是Django1.2版本后新特性

详细配置:

https://code.ziqiangxuetang.com/django/django-multi-database.html

RESTful API设计规范

详细信息:

https://www.cnblogs.com/EasonJim/p/7770711.html

URI规范

不要用大写

单词间使用下划线'_'

不使用动词,资源要使用名词复数形式,如:user、rooms、tickets

层级 >= 三层,则使用'?'带参数

users/1/address/2/citys (bad) /citys?users=1&address=2; (good)

Method

GET:查询资源

POST:创建资源

PUT/PATCH

PUT:全量更新资源(提供改变后的完整资源)

PATCH:局部更新资源(仅提供改变的属性)

DELETE:删除资源

nginx的原理是什么?

Nginx由内核和模块组成,其中,内核的设计非常微小和简洁,完成的工作也非常简单,仅仅通过查找配置文件将客户端请求映射到一个location block(location是Nginx配置中的一个指令,用于URL匹配),而在这个location中所配置的每个指令将会启动不同的模块去完成相应的工作。

 

Nginx的模块从功能上分为如下三类。

Handlers(处理器模块)。此类模块直接处理请求,并进行输出内容和修改headers信息等操作。Handlers处理器模块一般只能有一个。

Filters (过滤器模块)。此类模块主要对其他处理器模块输出的内容进行修改操作,最后由Nginx输出。

Proxies (代理类模块)。此类模块是Nginx的HTTP Upstream之类的模块,这些模块主要与后端一些服务比如FastCGI等进行交互,实现服务代理和负载均衡等功能。

Python:

协程是什么

协程,又称为微线程,看上去像是子程序,但是它和子程序又不太一样,它在执行的过程中,可以在中断当前的子程序后去执行别的子程序,再返回来执行之前的子程序,但是它的相关信息还是之前的。

优点:

极高的执行效率,因为子程序切换而不是线程切换,没有了线程切换的开销;

不需要多线程的锁机制,因为只有一个线程在执行;

py3的生成器和列表有什么区别

生成器格式最外层是一个(),而列表解析格式最外层是一个[]

生成器是将数据不用一次读取,而列表解析是一次读取所有数据(耗内存)

生成器返回的是一个生成器对象(不能直接循环),而列表解析返回的是一个新列表

进程池、线程池、连接池

池的概念

池可以分为多种,常见的有内存池、进程池、线程池和连接池。

由于服务器的硬件资源“充裕”,那么提高服务器性能的一个很直接的方法就是以空间换时间,即“浪费”服务器的硬件资源,以换取其运行效率。这就是池的概念。池是一组资源的集合,这组资源在服务器启动之初就完全被创建并初始化,这称为静态资源分配。当服务器进入正是运行阶段,即开始处理客户请求的时候,如果它需要相关的资源,就可以直接从池中获取,无需动态分配。很显然,直接从池中取得所需资源比动态分配资源的速度要快得多,因为分配系统资源的系统调用都是很耗时的。当服务器处理完一个客户连接后,可以把相关的资源放回池中,无需执行系统调用来释放资源。从最终效果来看,池相当于服务器管理系统资源的应用设施,它避免了服务器对内核的频繁访问。

详细介绍:

https://blog.csdn.net/walkerkalr/article/details/37729323

https://blog.csdn.net/sjyttkl/article/details/75577178

全局变量和单例模式有什么区别

(1)全局变量是对一个对象的静态引用,全局变量确实可以提供单例模式实现的全局访问功能,但是它并不能保证应用程序只有一个实例;编码规范也明确的指出应该要少使用全局变量,因为过多的使用全局变量会造成代码难读;全局变量并不能实现继承。

(2)、单例模式虽然在继承上不能很好的处理,但是还是可以实现继承的;单例模式在类中保存了它的唯实例这个类,可以保证只能创建一个实例,同时它还提供了一个访问该唯一实例的全局访问点。

一个列表a,用一行代码求出偶数位置的值加3,再求和

sum([x+3 for y,x in enumerate(a) if not y&1])

爬虫:

都使用了什么爬虫技术?应用方向是什么?

都爬了什么网站

回答参考:

如果是普通公司,寻找跟公司业务有关系的,比如金融公司是金融数据、股票数据或者其他可以促进公司业务发展的比如各地企业信息,微博舆情舆论等。

如果是小型外包公司,可以说爬了一些房产数据,招聘数据,淘宝、京东等有一些商业价值的数据,但是提前了解这些类型的数据都有什么网站,比如房产的房天下、链家、我爱我家,招聘的智联、拉勾、直聘,电商类的还有苏宁国美等等。

总而言之,要避免说一些斗图网啊、豆瓣TOP250这些商业价值少的,就是反向思考,如果一个数据无法为公司带来价值,那么为什么要去爬取它。

每天爬取量多少

回答参考:

爬取量根据网站的不同,爬虫所在设备性能的不同以及爬虫所在网络的出入带宽以及所爬网站的自身限制均有关系;挂匿名IP代理池,阿里云1M带宽2G内存爬拉勾,每爬一条更换一次IP,大概一天8万左右的数据量。

像是淘宝、京东、知乎,在超过一定频率的访问后,会出现各种类型的验证码,淘宝是滑动解锁,京东和知乎是字符验证码。

爬虫遇到验证码怎么处理

回答参考:

验证码基本借助于第三方打码平台解决,常见的有打码超人,打码兔等等,字符类的大概0.02元一次。

如果遇到遮盖变形较少的验证码,可以使用tesseract三方库进行OCR识别解决。

语言验证码和短信验证码也可以使用接码平台解决,常见的有星辰码,易码,爱码族等等,语音一般1元一条,短信一般0.1元一条。

User-Agent如何判断浏览器类型,火狐怎么显示,Chrome怎么显示

一般为Mozilla开头 + 设备识别号 + 浏览器核心版本号

切记! 所有User-Agent 均为Mozilla开头;Mozilla是Netscape的吉祥物,也是Netscape Navigator浏览器使用的内部开发代号。由于Netscape早期的影响力,直到今天,所有浏览器包括IE,向Web服务器报告自己的浏览器标识的 时候,都以 “Mozilla”开头,表明自己是Mozilla兼容的。

chrome

Mozilla/5.0 (Windows NT 5.2) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.122 Safari/534.30

Firefox

Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0

Git:

Git的提交、克隆、合并?

Git分支的实现原理是什么

https://gitee.com/progit/3-Git-%E5%88%86%E6%94%AF.html

 

Git如何解决分支提交冲突?

 

Linux:

当一个进程出错,先于线程关闭,如何判断进程内的线程是否存活

回答参考:

线程依托于进程,当进程出错关闭后,线程也会关闭

但是进程内的进程不会关闭,可能会产生孤儿进程

详细介绍:

https://www.cnblogs.com/Anker/p/3271773.html

软连接与硬链接

ln是linux中又一个非常重要命令,它的功能是为某一个文件在另外一个位置建立一个同步的链接,分为软链接、硬链接。软链接相当于windows的快捷方式

软链接:

1.软链接,以路径的形式存在。类似于Windows操作系统中的快捷方式

2.软链接可以 跨文件系统 ,硬链接不可以

3.软链接可以对一个不存在的文件名进行链接

4.软链接可以对目录进行链接

硬链接:

1.硬链接,以文件副本的形式存在。但不占用实际空间。

2.不允许给目录创建硬链接

3.硬链接只有在同一个文件系统中才能创建

 

gz/ tar / bz2 三种压缩包的解压缩命令

tar命令

  解包:tar zxvf FileName.tar

打包:tar czvf FileName.tar DirName

gz命令

    解压:tar zxvf filename.tar.gz

压缩:tar zcvf filename.tar.gz dirname

bz2命令

解压:tar jxvf filename.tar.bz2
      
压缩:tar jcvf filename.tar.bz2 dirname


网络协议:

url的格式是什么?

Uniform Resource Locator / 统一资源定位符

协议://用户名:密码@子域名.域名.顶级域名:端口号/目录/文件名.文件后缀?参数=值#标志

 

拓展:

URL又分为绝对URL和相对URL:

绝对URL(absolute URL)显示文件的完整路径,这意味着绝对URL本身所在的位置与被引用的实际文件的位置无关

相对URL(relative URL)以包含URL本身的文件夹的位置为参考点,描述目标文件夹的位置。

 请求头里都可以得到什么内容

请求头: 

Accept: text/html,image/*(浏览器可以接收的类型) 

Accept-Charset: ISO-8859-1(浏览器可以接收的编码类型) 

Accept-Encoding: gzip,compress(浏览器可以接收压缩编码类型) 

Accept-Language: en-us,zh-cn(浏览器可以接收的语言和国家类型) 

Host: www.it315.org:80(浏览器请求的主机和端口) 

If-Modified-Since: Tue, 11 Jul 2000 18:23:51 GMT(某个页面缓存时间) 

Referer: http://www.it315.org/index.jsp(请求来自于哪个页面) 

User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)(浏览器相关信息) 

Cookie:(浏览器暂存服务器发送的信息) 

Connection: close(1.0)/Keep-Alive(1.1)(HTTP请求的版本的特点) 

Date: Tue, 11 Jul 2000 18:23:51 GMT(请求网站的时间) 

项目题:

项目上线后出现Bug如何调试?

算法题:

1、 讲一个字符串逆序,不要使用反转函数

2、 一个数组,存放着无序的10个数[8,5,3,0,7,1,2,6,4,9],请编程实现这10个数由小到大的排序,找出效率最优的方式

3、 一本书100页,一次可以看一页,一次也可以看两页,有多少种解法

4、 不使用任何库函数,将给定字符串按单词反转,输入格式是“this is a string”,输出格式是“string a is this”,不使用额外的空间就地旋转

5、 找出数组中出现次数最多的数字,输入样例:[ 1,1,2,3,4 ] 输出样例: 1 ,如果都出现一次的话,返回其中最大值,数值均为整数类型,如果有多次多个的情况,返回其中最大值

6、 给一个整形数组,将其中所有的0元素移动到数组尾部,并保证其中非零元素的顺序不变; 输入样例: [ 0, 1, 0,3, 12 ]  输出样例: [1, 3, 12, 0, 0 ]

7、 有一个人A要去B公司上班,这个人有一个要求就是每7天中必须休息两天,公司实行排班制,排班表格式如:“1 1 0 1 1 0 0 1 1 1 1 0 1 1 1 1 0 1 1 0 1 1 0 0 1 1”,其中1为工作,0为休息,请编写一个函数,接收一个排班表,返回这个人最大连续工作天数。(30分钟思路,15分钟代码)

8、 手写数组二分查找,给一个排序数组,一个搜索值K,如果找到返回K,找不到返回-1;不能使用递归

微软:

1. 完成一个函数:defAdd(num1, num2):其中,两个输入都是数字,都是字符串(如:“12345678986543210123456789”),要求计算两个数字的和,返回一个字符串,不能使用内置函数,如int,long等。例如,输入两个数字是:“1000000000000000”和“-1”,返回“999999999999999”。

2. 给定一个数组nums,然后对其排序,使得排序结果满足nums[0] < nums[1] > nums[2] < nums[3]…。 例如给定数组nums=[1,2,3,4,5,6,7,8,9],其中一个满足条件的结果是1<6>2<7>3<8>4<9>5.给出一个结果即可(可能无解)。最优解法是O(n)时间复杂度和O(1)空间复杂度。

3. 写一个函数,输入是两个int数组A和B。要求从A和B中分别取出一个数,使他们的和为20。打印出所有的组合。要求数字在数组中的位置和数字本身。比如输入为 A = [18, 2, 7, 8, 3], B = [17, 1, 19],输出为 3 (A4) + 17 (B0) = 20,表示A的第4个元素是3,B的第0个元素是17

4. 写一个函数,输入一个随机的01序列,打印出这个序列中最长的01交替出现的序列的起始位置和结束位置。例如:输入“0001010101101”,输出起始位置2, 结束位置10

5. 逆转一个单链表。

6. 实现一个类,用于表示一个大小无限制的整数,要求可以用任何进制的形式初始化,并提供方法打印成任何进制的形式,并实现加减法(或四则运算),实现repr

7. 给一个数n,给出可以由多少种方法用正整数来累加成该数。例如给一个数3,那么一共有三种:1+1+1,1+2,3

8. 将两个有序整数序列合并为一个大的有序整数序列,输出,然后反转,再输出。自己实现,不能调用sort方法和reverse方法

编程题:

1、 定义一个基本图形Shape类,定义属性长、宽,顶一个一个计算周长getPerimeter的方法,再分别定义长方形(Rectangle),正方形(Square)两个类继承Shape类,实现方法的重载和重写。

给定一个文件handler.py 里面一个handler函数,会接受一个字符串,并进行处理,然后返回一个result值,有一个文件为a.csv,以python test.py a.csv执行,请编写一个test.py文件,读取每一行传入函数进行处理,并打印出结果,请考虑所有异常情

猜你喜欢

转载自blog.csdn.net/liuskyter/article/details/80472819