(1)@staticmethod和@classmethod
Python其实有3个方法,即静态方法(staticmethod),类方法(classmethod)和实例方法,如下:
class A(object):
def foo(self,x):
print "executing foo(%s,%s)"%(self,x)
@classmethod
def class_foo(cls,x):
print( "executing class_foo(%s,%s)"%(cls,x))
@staticmethod
def static_foo(x):
print ("executing static_foo(%s)"%x)
a=A()
对于静态方法其实和普通的方法一样,不需要对谁进行绑定,需要通过修饰器@staticmethod来进行修饰,静态方法不需要多定义参数,唯一的区别是调用的时候需要使用a.static_foo(x)或者A.static_foo(x)来调用.
类方法就是供类使用的变量,是类对象所拥有的方法,需要用修饰器@classmethod,对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数
实例方法就是供实例使用的.
(2)实例属性
类属性 直接在类中定义的,与方法平齐,不在方法里的属性就是 类属性
实例属性 在方法里通过self.属性 都是实例属性
(3)垃圾回收
1标记-清除:解决容器对象可能产生的循环引用问题
2引用计数 :来跟踪和回收垃圾
3分代收集:以空间换时间的方法提高垃圾回收效率
Python中的垃圾回收是以引用计数为主,分代收集为辅。引用计数的缺陷是循环引用的问题。在Python中,如果一个对象的引用数为0,Python虚拟机就会回收这个对象的内存。
(4)动态语言和静态语言
动态语言:可以在运行的过程中,修改代码。静态语言:编译时已经确定好代码,运行过程中不能修改
(5)面向对象
面向对象:把一组数据结构和处理它们的方法组成对象, 把相同行为的对象归纳为类,通过类的封装(encapsulation)隐藏内部细节,通过继承inheritance)实现类的特化泛化(generalization),通过多态polymorphism)实现基于对象类型的动态分派(dynamic dispatch)。通俗来说就是 "你办事我放心"一句话概括。
就是使我们分析、设计 和实现一个系统的方法尽可能地接近我们认识一个系统的方法。
面向对象编程先确定数据结构,再确定算法;而面向对象程序员则构造对象模型,将数据 与方法组织在一起。
面向对象的特点:封装,继承和派生,多态,抽象。
面向对象的优点:可重用,可扩展,可管理。
(6)闭包
在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包
(内部函数调用外部函数) 闭包也具有提高代码可复用性的作用。
建一个闭包必须满足以下几点:
- 必须有一个内嵌函数
- 内嵌函数必须引用外部函数中的变量
- 外部函数的返回值必须是内嵌函数
(7)Iterable 类型
凡是可作用于 for 循环的对象都是 Iterable 类型;
凡是可作用于 next() 函数的对象都是 Iterator 类型
集合数据类型如 list 、 dict 、 str 等是 Iterable 但不是 Iterator ,不过可以通过 iter() 函数获得一个 Iterator 对象。
目的是在使用集合的时候,减少占用的内存。
(8)迭代器
迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。一类是集合数据类型,如 list 、 tuple 、 dict 、 set 、 str 等; 一类是 generator ,包括生成器和带 yield 的generator function。 这些可以直接作用于 for 循环的对象统称为可迭代对象: Iterable 。
(9)生成器
生成器的特点:1.节约内存 22.迭代到下一次的调用时,所使用的参数都是第一次所保留下的,即是说,在整个所有函数调用的参数都是第一次所调用时保留的,而不是新创建的。
只要把一个列表生成式的 [ ] 改成 ( ) ,使用next 就能得到G的值,但是基本上永远不会调用 next() ,而是通过 for 循环来迭代它,并且不需要关心 StopIteration 异常。
总结 :在Python中,这种一边循环一边计算的机制,称为生成器:generator。可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator
(10)Python自省
自省就是面向对象的语言所写的程序在运行时,所能知道对象的类型.简单一句就是运行时能够获得对象的类型.比如type(),dir(),getattr(),hasattr(),isinstance().
(11) *args and **kwargs
当你不确定你的函数里将要传递多少参数时你可以用*args.例如,它可以传递任意数量的参数;相似的,**kwargs允许你使用没有事先定义的参数名;你也可以混着用.命名参数首先获得参数值然后所有的其他参数都传递给*args和**kwargs.命名参数在列表的最前端。
(12)Python中重载
函数重载主要是为了解决:可变参数类型和可变参数个数
(13)新式类和旧式类
新式类是广度优先,旧式类是深度优先
(14)__new__和__init__的区别
- __new__是一个静态方法,而__init__是一个实例方法.
- __new__方法会返回一个创建的实例,而__init__什么都不返回.
- 只有在__new__返回一个cls的实例时后面的__init__才能被调用.
- 当创建一个新实例时调用__new__,初始化一个实例时用__init__.
(15)单例模式
单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例,而这一模式的目的是使得类的一个对象成为系统中的唯一实例
1.使用__new__方法
class Singleton(object):
def __new__(cls, *args, **kw):
if not hasattr(cls, '_instance'):
orig = super(Singleton, cls)
cls._instance = orig.__new__(cls, *args, **kw)
return cls._instance
class MyClass(Singleton):
a = 1
2 共享属性
class Borg(object):
_state = {}
def __new__(cls, *args, **kw):
ob = super(Borg, cls).__new__(cls, *args, **kw)
ob.__dict__ = cls._state
return ob
class MyClass2(Borg):
a = 1
3 装饰器版本
def singleton(cls, *args, **kw):
instances = {}
def getinstance():
if cls not in instances:
instances[cls] = cls(*args, **kw)
return instances[cls]
return getinstance
@singleton
class MyClass:
(16) GIL线程全局锁
线程全局锁(Global Interpreter Lock),即Python为了保证线程安全而采取的独立线程运行的限制,说白了就是一个核只能在同一时间运行一个线程.
(17)协程
简单点说协程是进程和线程的升级版,进程和线程都面临着内核态和用户态的切换问题而耗费许多切换时间,而协程就是用户自己控制切换的时机,不再需要陷入系统的内核态.Python里最常见的yield就是协程的思想!
(18)lambda函数
其实就是一个匿名函数,为什么叫lambda?因为和后面的函数式编程有关.
(19)Python的is 和 == 区别
is是对比地址,==是对比值
(20)read,readline和readlines
- read 读取整个文件
- readline 读取下一行,使用生成器方法
- readlines 读取整个文件到一个迭代器以供我们遍历
(21)到底什么是Python?
- Python是一种解释型语言。这就是说,与C语言和C的衍生语言不同,Python代码在运行之前不需要编译。其他解释型语言还包括PHP和Ruby。
- Python是动态类型语言,指的是你在声明变量时,不需要说明变量的类型。你可以直接编写类似x=111和x="I'm a string"这样的代码,程序不会报错。
- Python非常适合面向对象的编程(OOP),因为它支持通过组合(composition)与继承(inheritance)的方式定义类(class)。Python中没有访问说明符(access specifier,类似C++中的public和private),这么设计的依据是“大家都是成年人了”。
- 在Python语言中,函数是第一类对象(first-class objects)。这指的是它们可以被指定给变量,函数既能返回函数类型,也可以接受函数作为输入。类(class)也是第一类对象。
- Python代码编写快,但是运行速度比编译语言通常要慢。好在Python允许加入基于C语言编写的扩展,因此我们能够优化代码,消除瓶颈,这点通常是可以实现的。numpy就是一个很好地例子,它的运行速度真的非常快,因为很多算术运算其实并不是通过Python实现的。
- Python用途非常广泛——网络应用,自动化,科学建模,大数据应用,等等。它也常被用作“胶水语言”,帮助其他语言和组件改善运行状况。
- Python让困难的事情变得容易,因此程序员可以专注于算法和数据结构的设计,而不用处理底层的细节。
(22)“猴子补丁”(monkey patching)指的是什么?这种做法好吗?
“猴子补丁”就是指,在函数或对象已经定义之后,再去改变它们的行为。
(23)介绍一下except的用法和作用?
try…except…except…[else…][finally…]
执行try下的语句,如果引发异常,则执行过程会跳到except语句。对每个except分支顺序尝试执行,如果引发的异常与except中的异常组匹配,执行相应的语句。如果所有的except都不匹配,则异常会传递到下一个调用本代码的最高层try代码中。
try下的语句正常执行,则执行else块代码。如果发生异常,就不会执行
如果存在finally语句,最后总是会执行。
目的是跳出异常,可以使代码不因某种错误而停止运行,
(24)Python中pass语句的作用是什么?
pass表示占位
(25)介绍一下Python下range()函数的用法?
列出一组数据,经常用在for in range()循环中
(26)如何用Python来进行查询和替换一个文本字符串?
可以使用re模块中的sub()函数或者subn()函数来进行查询和替换,
格式:sub(replacement, string[,count=0])(replacement是被替换成的文本,string是需要被替换的文本,count是一个可选参数,指最大被替换的数量)
(27)Python里面match()和search()的区别?
re模块中match(pattern,string[,flags]),检查string的开头是否与pattern匹配。
re模块中research(pattern,string[,flags]),在string搜索pattern的第一个匹配值。
(28)用Python匹配HTML tag的时候,<.*>和<.*?>有什么区别?
术语叫贪婪匹配( <.*> )和非贪婪匹配(<.*?> )
(29)Python里面如何生成随机数?
random模块
(30)有没有一个工具可以帮助查找python的bug和进行静态的代码分析?
PyChecker是一个python代码的静态分析工具,它可以帮助查找python代码的bug, 会对代码的复杂度和格式提出警告
Pylint是另外一个工具可以进行codingstandard检查
(31)如何在一个function里面设置一个全局的变量?
解决方法是在function的开始插入一个global声明:def f() global x
(32)单引号,双引号,三引号的区别
单引号和双引号是等效的,如果要换行,需要符号(\),三引号则可以直接换行,并且可以包含注释
(33)数据库 事务
数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。
(34)数据库索引
索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。索引分为聚簇索引和非聚簇索引两种,聚簇索引 是按照数据存放的物理位置为顺序的,而非聚簇索引就不一样了;聚簇索引能提高多行检索的速度,而非聚簇索引对于单行的检索很快。
(35)乐观锁和悲观锁
悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作
乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。
(36)网络
1 三次握手
- 客户端通过向服务器端发送一个SYN来创建一个主动打开,作为三路握手的一部分。客户端把这段连接的序号设定为随机数 A。
- 服务器端应当为一个合法的SYN回送一个SYN/ACK。ACK 的确认码应为 A+1,SYN/ACK 包本身又有一个随机序号 B。
最后,客户端再发送一个ACK。当服务端受到这个ACK的时候,就完成了三路握手,并进入了连接创建状态。此时包序号被设定为收到的确认号 A+1,而响应则为 B+1。
2四次挥手
CP的连接的拆除需要发送四个包,因此称为四次挥手(four-way handshake)。客户端或服务器均可主动发起挥手动作,在socket编程中,任何一方执行close()操作即可产生挥手操作。
(1)客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送。
(2)服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。
(3)服务器B关闭与客户端A的连接,发送一个FIN给客户端A。
(4)客户端A发回ACK报文确认,并将确认序号设置为收到序号加1。
(37) ARP协议
地址解析协议(Address Resolution Protocol): 根据IP地址获取物理地址的一个TCP/IP协议
(38) urllib和urllib2的区别
- urllib提供urlencode方法用来GET查询字符串的产生,而urllib2没有。这是为何urllib常和urllib2一起使用的原因。
- urllib2可以接受一个Request类的实例来设置URL请求的headers,urllib仅可以接受URL。这意味着,你不可以伪装你的User Agent字符串等。
(39)Post和Get区别
GET后退按钮/刷新无害,POST数据会被重新提交(浏览器应该告知用户数据会被重新提交)。
GET书签可收藏,POST为书签不可收藏。
GET能被缓存,POST不能缓存 。
GET历史参数保留在浏览器历史中。POST参数不会保存在浏览器历史中。
GET对数据长度有限制,当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符)。POST无限制。
GET只允许 ASCII 字符。POST没有限制。也允许二进制数据。
与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分。在发送密码或其他敏感信息时绝不要使用 GET !POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中。
GET的数据在 URL 中对所有人都是可见的。POST的数据不会显示在 URL 中。
(40)Cookie和Session
|
Cookie |
Session |
储存位置 |
客户端 |
服务器端 |
目的 |
跟踪会话,也可以保存用户偏好设置或者保存用户名密码等 |
跟踪会话 |
安全性 |
不安全 |
安全 |
(41) apache和nginx的区别
nginx 相对 apache 的优点:
- 轻量级,同样起web 服务,比apache 占用更少的内存及资源
- 抗并发,nginx 处理请求是异步非阻塞的,支持更多的并发连接,而apache 则是阻塞型的,在高并发下nginx 能保持低资源低消耗高性能
- 配置简洁
- 高度模块化的设计,编写模块相对简单
- 社区活跃
apache 相对nginx 的优点:
- rewrite ,比nginx 的rewrite 强大
- 模块超多,基本想到的都可以找到
- 少bug ,nginx 的bug 相对较多
- 超稳定
(42) HTTP和HTTPS
HTTPS(全称:Hypertext Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。 它是一个URI scheme(抽象标识符体系),句法类同http:体系。用于安全的HTTP数据传输。
https:URL表明它使用了HTTP,但HTTPS存在不同于HTTP的默认端口及一个加密/身份验证层(在HTTP与TCP之间)。这个系统的最初研发由网景公司进行,提供了身份验证与加密通讯方法,现在它被广泛用于万维网上安全敏感的通讯,例如交易支付方面。
(43)XSRF和XSS
- CSRF(Cross-site request forgery)跨站请求伪造
- XSS(Cross Site Scripting)跨站脚本攻击
CSRF重点在请求,XSS重点在脚本
(44)Ajax
AJAX,Asynchronous JavaScript and XML(异步的 JavaScript 和 XML), 是与在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术。
(45)解释下Http协议
HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。
1.支持客户/服务器模式。
2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
3.灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
4.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
5.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
(46)解释下Http请求头和常见响应状态码
Accept:指浏览器或其他客户可以接爱的MIME文件格式。可以根据它判断并返回适当的文件格式。
Accept-Charset:指出浏览器可以接受的字符编码。英文浏览器的默认值是ISO-8859-1.
Accept-Language:指出浏览器可以接受的语言种类,如en或en-us,指英语。
Accept-Encoding:指出浏览器可以接受的编码方式。编码方式不同于文件格式,它是为了压缩文件并加速文件传递速度。浏览器在接收到Web响应之后先解码,然后再检查文件格式。
Cache-Control:设置关于请求被代理服务器存储的相关选项。一般用不到。
Connection:用来告诉服务器是否可以维持固定的HTTP连接。HTTP/1.1使用Keep-Alive为默认值,这样,当浏览器需要多个文件时(比如一个HTML文件和相关的图形文件),不需要每次都建立连接。
Content-Type:用来表名request的内容类型。可以用HttpServletRequest的getContentType()方法取得。
Cookie:浏览器用这个属性向服务器发送Cookie。Cookie是在浏览器中寄存的小型数据体,它可以记载和服务器相关的用户信息,也可以用来实现会话功能。
状态代码有三位数字组成,第一个数字定义了响应的类别
(47)列举您使用过的python网络爬虫所用到的解析数据包
BeautifulSoup、pyquery、Xpath、lxml
(48)列举您使用过的python中的编码方式(最熟悉的在前):
UTF-8,ASCII,gbk
(49)列出比较熟悉的爬虫框架
Scrapy
(50)写出在网络爬虫爬取数据的过程中,遇到的防爬虫问题的解决方案
通过headers反爬虫:解决策略,伪造headers
基于用户行为反爬虫:动态变化去爬取数据,模拟普通用户的行为
基于动态页面的反爬虫:跟踪服务器发送的ajax请求,模拟ajax请求