Python社区的历年都包含在Tim Peters撰写的Python之禅中, 要获悉这些有关编写优秀Python代码的指导原则,只需在解释器中执行命令import this
下图就是一个docstring,使用三对双引号(或者单引号)来声明,通过方法名.__doc__来显示(partition.__doc__)
20.了解类型注解么?
如下,分别对x,y和返回值进行了定义。
21. 例举你知道 Python 对象的命名规范,例如方法或者类等
两种,分别是单行注释#和多行注释”””这是多行注释”””。
23.如何优雅的给一个函数加注释
打完方法的冒号后回车,按仨引号回车,打文档注释。
24.如何给变量加注释
但是我感觉这好乱啊哈哈哈还是喜欢在上面另起一行注释
25.Python代码缩进中是否支持Tab键和空格混用
不支持,很多编译器实际上是将tab转换为n个空格(可设置)。
26.是否可以在一句import中导入多个库?
可以,但不推荐(PEP8标准中 提过)
27.在给py文件命名的时候应该注意什么?
28.举几个python代码风格工具:
Pylint、Black等,主要功能类似于java的那个alibaba规范脚本,检查定义符不符合规范、定义的接口是否都被使用等,在安装之后右键又一个check即可检查错误。
29.列举Python中的基本数据类型:
再放送?这和第二题有啥区别
30.如何区别可变数据类型和不可变数据类型:
32.如何检测字符串中只含数字?
这句话其实看怎么定义‘数字’,科学技术法或者+5,-5算数字吗?如果都不算,那么下面这样就可以。
如果算,需要做的就是这样:
34. Python 中的字符串格式化方式你知道哪些?
35. 有一个字符串开头和末尾都有空格,比如“ adabdw ”,要求写一个函数把这个字符串的前后空格都去掉。
36. 获取字符串”123456“最后的两个字符。
37. 一个编码为 GBK 的字符串 S,要将其转成 UTF-8 编码的字符串,应如何操作?
39.(1)怎样将字符串转换为小写 (2)单引号、双引号、三引号的区别?
单引号双引号没有区别,但是有一点,就是单引号中双引号可以,但是再使用单引号需要转义,双引号同理。三引号是docstring和多行注释。
42. 给定两个 list,A 和 B,找出相同元素和不同元素
45 如何打乱一个列表的元素?
pop在删除后返回该元素的值,del直接删除,另外二者速度上没有去很大区别(尽管del相对pop有一丢丢优势)
47. 按照字典的内的年龄排序
49. 如何使用生成式的方式生成一个字典,写一段功能代码。
zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。
51. Python 常用的数据结构的类型及其特性?
52. 如何交换字典{“A”:1,”B”:2}的键和值?
54. 我们知道对于列表可以使用切片操作进行部分元素的选择,那么如何对生成器类型的对象实现相同的功能呢?
iterable[start : stop : step], 创建一个迭代器,跳过前start个项,迭代在stop所指定的位置停止,step指定用于跳过项的步幅。迭代默认将从0开始,步幅默认1 (是不是和切片很像?)
57. 下面的代码输出结果是什么?
58. 下面的代码输出的结果是什么?
(1,2,3,[2,5,6,7],8) 。虽然元组不能更改,但是元组内的数据类型如果可变类型是可以改的(int为不可变类型,list为可变类型)。
read是将文件中的数据以字符串的形式存出来,多行中用\n分割,但是对于较大文件需要很大的内存。
readlines是将文件行以列表的形式返回。
61.json 序列化时,可以处理的数据类型有哪些?如何定制支持 datetime 类型?
可以处理所有python的自带数据类型(或自动转换到可处理类型)
62. json 序列化时,默认遇到中文会转换成 unicode,如果想要保留中文怎么办?
63. 有两个磁盘文件 A 和 B,各存放一行字母,要求把这两个文件中的信息合并(按字母顺序排列),输出到一个新文件 C 中。
64. 如果当前的日期为 ,要求写一个函数输出 N 天后的日期,(比如 N 为 2,则输出 )。
65. 写一个函数,接收整数参数 n,返回一个函数,函数的功能是把函数的参数和 n 相乘并把结果返回。
66. 下面代码会存在什么问题,如何改进?
首先命名不规范,其次由于str是不可变类型,每次循环都产生新的对象浪费,应该列表转换。
67. 一行代码输出 1-100 之间的所有偶数。
68. with 语句的作用,写一段代码?
会自动调用close方法,不再需要手动调用(详见第三题)
70. 请写一个 Python 逻辑,计算一个字符串中的大写字母数量
现在电脑没有redis环境,以后补x。
事务提供了一种”将多个命令打包,一次性提交并按顺序执行”的机制,提交后在事务执行中不会中断。只有在执行完所有命令后才会继续执行来自其他客户的消息。
类似于批处理+资源锁。
76. 了解数据库的三范式么?
一范式: 任给关系R,如果R中每个列与行对应单元格的数据都是不可再分的基本元素,则R达到第一范式,简称1NF。 (最基本的范式)
二范式: 如果一个关系达到第一范式,且不存在任何非主属性对候选关键字的部分函数依赖,则称关系达到第二范式,2NF。 (其他项均与主键有关)
三范式: 如果一个关系达到第二范式且不存在非主属性对候选关键字的传递函数依赖,则称为达到第三范式,简称3NF。 (约束外键,通过外键查询信息)
77. 了解分布式锁么?
利用诸如zookeeper,redis等更高效的分布式组件来实现分布式锁,可以提供高可用的更强壮的锁特性,并且支持丰富化的使用场景。
80. 函数装饰器有什么作用?请列举说明?
装饰器本质上是一个 Python 函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。
它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。
有了装饰器,就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。
Python的垃圾回收机制十分类似于,但是Python的垃圾回收并没有java的那么多种,python只有引用计数器和分代回收、标记清除。
call的存在允许了对象当作方法来进行使用,比如下面的sum(),虽然sum的对象,但是依然会调用call来进行相关的操作。
83. 如何判断一个对象是函数还是方法?
使用上两种都可以使用类名.方法名来进行调用,但是calssmethod必须要有一个以上参数(cls), 这个参数表示自身类,可以用它来对方法内的方法进行调用。
但是需要注意的是接口的继承类必须复写所有方法,所以可能还不如继承好用。
反射是在只知道类名或者函数名的情况下调用其对应的函数。
metaclass允许父类对子类进行修改,一般用在框架开发。由于不推荐使用所以不做过多介绍。
常用在python的反射,86题全部用过这几种方法,移步86题。
89. 请列举你知道的 Python 的魔法方法及用途。
这取决于是什么类型,如果是可变类型就传递值,如果是不可变类型就传参。
元类就是生成类的工具,python最基础的元类是type(也就是可以用type来生成类),同样我们也可以通过复写 __metaclass__属性来使当前类变成元类。
any方法会监测这里面是否有非0(0、False、空),如果有返回True,如果没有返回False。
all方法检测是否全为0(0、False、空),如果全空返回True,反之False。
filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判,然后返回 True 或 False,最后将返回 True 的元素放到新列表。
95. 什么是猴子补丁?
在运行期间动态修改一个类或模块。
python使用了一个内存池叫做 pymalloc ,它对于那些小于512k以下的对象在pymalloc中分配空间,防止频繁的使用C语言的malloc和free造成的系统开销。对于大于512k的依然交给系统的malloc来处理。
然后利用引用计数器、标记-清除等算法进行垃圾处理。
97. 当退出 Python 时是否释放所有内存分配?
不会,会保留一部分全局变量空间。
99. 正则表达式匹配中(.)和(.?)匹配区别?
?代表非贪婪匹配。即可以匹配0次或者1次,而.只匹配一个任意字符。
100. 写一段匹配邮箱的正则表达式
空语句,当搭建整体架构或者确定要有这个方法(循环、判断等)但是具体实现还没想好或者当前可以跳过时。
input接受一个标准输入数据,返回string类型
is 比较地址(id),而==比较值,对于对象的比较,可以在类中重载__eq__来完成对==的重载。
105. 三元运算写法和应用场景?
思考下面两个等价示例:
在一些简短的判断语句中可以使用三元运算。
该函数他igong了将一个可遍历的对象组合一个索引返回。
108. 如何在函数中设置一个全局变量
用于pathlib中的Path类可以创建path路径对象, 属于比os.path更高抽象级别的对象
110. Python 中的异常处理,写一个简单的应用场景
一下子也想不出比较好的例子了,一般异常就是在文件开关、请求或者容易产生越界的地方使用
111. Python 中递归的最大次数,那如何突破呢?
递归次数最大为1000次,但是这并不是出于性能考虑的限制,而是出于防止无限递归造成崩溃。
使用下面代码就可以更改这个限制。
子类优于父类,自实现优于系统实现。对于多继承情况,根据类的不同(分为新式类和旧式类,区分旧式新式类显示继承Object),其中新式类采用广度优先遍历来查找方法,旧式类采用深度优先遍历来查找方法。详见116
获取对象的类型,主要用来确定类型是否是需要的类型或者根据对象选择不同的分支。
114. 什么是断言?应用场景?
assert,会检查assert后面的语句是否为真,为真继续执行,为假抛出异常。常用于debug中判断当前步结果是否在意料之中。
比如定义一个求两数和的方法:
常用于简单方法并且不需要重复调用的情况
116. 新式类和旧式类的区别
新式类都继承object,旧式类不需要。新式类的MRO采用广度优先搜索,而旧式类采用深度优先搜索。
执行顺序(深度优先):D-C-B-A
python2中默认旧式类,新式类要显式声明。
python3中都是新式类,旧式类被移除。
我们都知道python的对象分为可变对象和不可变对象,因此举个例子。
思考上面两个例子,其中对于列表中有可变类型时,深拷贝的浅拷贝的区别显现了出来。
因此,可以简单的理解为,浅拷贝只拷贝一层地址,而深拷贝会继续向下拷贝元素的子元素地址。
122. Python 中会有函数或成员变量包含单下划线前缀和结尾,和双下划线前缀结尾,区别是什么?
a+:可读可写,没有创建
sort是list的一个属性方法,改变原列表。
sorted不改变原列表,生成新列表。
125. 什么是负索引?
print()和pprint()都是python的打印模块,功能基本一样,唯一的区别就是pprint()模块打印出来的数据结构更加完整,每行为一个数据结构,更加方便阅读打印输出结果。特别是对于特别长的数据打印,print()输出结果都在一行,不方便查看,而pprint()采用分行打印输出,所以对于数据结构比较复杂、数据长度较长的数据,适合采用pprint()打印方式。当然,一般情况多数采用print()。
131. 怎样声明多个变量并赋值?
list的后台实现是列表,采用线性查找,因此时间复杂度为n;直接插入,时间复杂度1。
set的后台实现是字典,采用二叉树排序,时间复杂度lgn,建树插入,时间复杂度lgn。
python天然就是单例模式,因此只需要在类中新建自己的对象即可。更多单例模式方法感兴趣的自己查。
136. 找出列表中的重复数字
137. 找出列表中的单个数字
138. 写一个冒泡排序
139. 写一个快速排序
140. 写一个拓扑排序
142. 有一组“+”和“-”符号,要求将“+”排到左边,“-”排到右边,写出具体的实现方法。
144. 交叉链表求交点
145. 用队列实现栈
146. 找出数据流的中位数
147. 二叉搜索树中第 K 小的元素
大部分情况是没有区别的,其中:content返回的是字节码,而text是编码后的文本(猜测编码),因此在text猜错的情况下需要我们使用content.decode()来进行重新解码。
149. 简要写一下 lxml 模块的使用方法框架
Scrapy本身带有一个中间件进行去重,可以在scrapy的源码中找到一个 dupefilters.py 文件,同时又一个dont_fliter开关进行控制是否进行去重操作。
对于每一个url,根据url(处理)使用set进行去重。
152. scrapy 中间件有几种类,你用过哪些中间件
153. 你写爬虫的时候都遇到过什么?反爬虫措施,你是怎么解决的?
比较简单的就是各种.gov、.edu、这类网站的反爬,几乎没有,简单的requests就可以。
其次就是比如微博、知乎、CSDN这种本身就有大量匿名访问流量的公开网站。这种网站一般会在ip访问频率和登录状态上进行限制,这种只要加一个ip代理或者控制访问频率和携带cookie即可。
再就是例如淘宝这类网站可能有加密接口,没有办法直接找到接口,一般使用js解密或者使用测试框架。包括selenium等。
再高的比如淘宝,某些页面有图层遮挡、甚至有测试框架检测,除了应用小众测试框架以外水平有限,不知道怎么解决。
154. 为什么会用到代理?
由于访问迅速目标网站拒绝访问时,需要使用大量其他ip作为代理访问目标网站。
155. 代理失效了怎么处理?
维持代理池,心跳检测代理可用性。
157. 说一说打开浏览器访问 百度一下,你就知道 获取到结果,整个流程。
这里是考三次握手吗?首先浏览器向服务器发送询问请求,然后服务器返回ACK,然后浏览器返回ACK的ACK。然后将百度的主页发送到浏览器,解析给用户。
如果使用HTTP1.1,当你点击搜索时,向服务器发送请求并获取结果。(百度确实使用HTTP1.1)。
如果是HTTP1.0,则重复上述握手过程。
158. 爬取速度过快出现了验证码怎么处理
降速,或者处理验证码,不过现在很多公司都接入极验了,还是降速或者使用代理比较稳妥。
redis为内存数据库,具有很快的读写效率。
160. 分布式爬虫主要解决什么问题
目标服务器对ip的限制以及高速率要求的爬取。
161. 写爬虫是用多进程好?还是多线程好? 为什么?
多线程好,因为爬虫属于IO密集型。
162. 解析网页的解析器使用最多的是哪几个
163. 需要登录的网页,如何解决同时限制 ip,cookie,session(其中有一些是动态生成的)在不使用动态爬取的情况下?
164. 验证码的解决(简单的:对图像做处理后可以得到的,困难的:验证码是点击,拖动等动态进行的?)
selenium有js方法可以进行拖动。图片直接OCR或者类似处理后输入即可。
mysql传统数据库,关系型。mongodb非关系型数据库,支持字段更多,由于使用了内存优化也并不慢(相比mysql)。redis内存数据库,读取非常快,但是没办法永久存储。
167. 简要介绍三次握手和四次挥手
服务器:我收到你好了,你好。
客户端:我收到你的你好了,搞起。
168. 什么是粘包? socket 中造成粘包的原因是什么? 哪些情况会发生粘包现象?
沾包就是多个数据包被连续送入接收方的缓存中,无法判断出数据边界。
造成沾包的原因有很多,在发送方可能是因为TCP协议本身的限制,将很多小包打成大包后发送,因此可能造成沾包。
对于接收方,可能是进程接受数据不及时,导致缓存中滞留过多数据。