面试问题总结

http响应状态码中301和302的区别是什么?

1、什么是301转向?什么是301重定向?

  301转向(或叫301重定向,301跳转)是当用户或搜索引擎向网站服务器发出浏览请求时,服务器返回的HTTP数据流中头信息(header)中的状态码的一种,表示本网页永久性转移到另一个地址。

2、什么是302重定向?

  302重定向又称之为302代表暂时性转移(Temporarily Moved ),英文名称:302 redirect。 也被认为是暂时重定向(temporary redirect),一条对网站浏览器的指令来显示浏览器被要求显示的不同的URL,当一个网页经历过短期的URL的变化时使用。一个暂时重定向是一种服 务器端的重定向,能够被搜索引擎蜘蛛正确地处理。

3、301重定向与302重定向的区别

  302重定向是暂时的重定向,搜索引擎会抓取新的内容而保留旧的网址。因为服务器返回302代码,搜索引擎认为新的网址只是暂时的。 SEO 302好于301

  301重定向是永久的重定向,搜索引擎在抓取新内容的同时也将旧的网址替换为重定向之后的网址。

如何爬取网页中js生成的数据

对于大多数的动态加载网页来讲,加载的内容都是可以直接获取到的,根本没有必要使用Selenium或者PhantomJS这种低效率的东西来模拟浏览器。

方法步骤非常非常简单,总结如下:
1.打开chrome 浏览器的审查元素功能,
Network 这一标签页。
2.让网页动态加载
3.在Network 中会出现被加载的数据。一般是json 格式的。
相对于scrapy,requests包最大的优势是什么?
scrapy是封装起来的框架,他包含了下载器,解析器,日志及异常处理,基于多线程, twisted的方式处理,
对于固定单个网站的爬取开发,有优势,但是对于多网站爬取 100个网站,并发及分布式处理方面,不够灵活,不便调整与括展。

request 是一个HTTP库, 它只是用来,进行请求,对于HTTP请求,他是一个强大的库,下载,解析全部自己处理,
灵活性更高,高并发与分布式部署也非常灵活,对于功能可以更好实现。
 
mysql数据库引擎的类型?

你能用的数据库引擎取决于mysql在安装的时候是如何被编译的。要添加一个新的引擎,就必须重新编译MYSQL。在缺省情况下,MYSQL支持三个引擎:ISAM、MYISAM和HEAP。另外两种类型INNODB和BERKLEY(BDB),也常常可以使用。

  ISAM

  ISAM是一个定义明确且历经时间考验的数据表格管理方法,它在设计之时就考虑到数据库被查询的次数要远大于更新的次数。因此,ISAM执行读取操作的速度很快,而且不占用大量的内存和存储资源。ISAM的两个主要不足之处在于,它不支持事务处理,也不能够容错:如果你的硬盘崩溃了,那么数据文件就无法恢复了。如果你正在把ISAM用在关键任务应用程序里,那就必须经常备份你所有的实时数据,通过其复制特性,MYSQL能够支持这样的备份应用程序。

  MYISAM

  MYISAM是MYSQL的ISAM扩展格式和缺省的数据库引擎。除了提供ISAM里所没有的索引和字段管理的大量功能,MYISAM还使用一种表格锁定的机制,来优化多个并发的读写操作。其代价是你需要经常运行OPTIMIZETABLE命令,来恢复被更新机制所浪费的空间。MYISAM还有一些有用的扩展,例如用来修复数据库文件的MYISAMCHK工具和用来恢复浪费空间的MYISAMPACK工具。

  MYISAM强调了快速读取操作,这可能就是为什么MYSQL受到了WEB开发如此青睐的主要原因:在WEB开发中你所进行的大量数据操作都是读取操作。所以,大多数虚拟主机提供商和INTERNET平台提供商只允许使用MYISAM格式。

  HEAP

  HEAP允许只驻留在内存里的临时表格。驻留在内存里让HEAP要比ISAM和MYISAM都快,但是它所管理的数据是不稳定的,而且如果在关机之前没有进行保存,那么所有的数据都会丢失。在数据行被删除的时候,HEAP也不会浪费大量的空间。HEAP表格在你需要使用SELECT表达式来选择和操控数据的时候非常有用。要记住,在用完表格之后就删除表格。

  INNODB和BERKLEYDB

  INNODB和BERKLEYDB(BDB)数据库引擎都是造就MYSQL灵活性的技术的直接产品,这项技术就是MYSQL++API。在使用MYSQL的时候,你所面对的每一个挑战几乎都源于ISAM和MYISAM数据库引擎不支持事务处理也不支持外来键。尽管要比ISAM和MYISAM引擎慢很多,但是INNODB和BDB包括了对事务处理和外来键的支持,这两点都是前两个引擎所没有的。如前所述,如果你的设计需要这些特性中的一者或者两者,那你就要被迫使用后两个引擎中的一个了。

其中MyISAM和InnoDB是两种最常用的数据库引擎,默认的引擎是MyISAM,性能最好,但不支持事务处理,只有InnoDB支持事务。

Python内存管理机制主要包括以下三个方面:

  • 引用计数机制

在Python中,整数和短小的字符,Python都会缓存这些对象,以便重复使用。赋值语句,只是创造了新的引用,而不是对象本身。长的字符串和其它对象可以有多个相同的对象,可以使用赋值语句创建出新的对象。每个对象都有存有指向该对象的引用总数,即引用计数(reference count)。 
可以使用sys.getrefcount()获得引用计数,需要注意的是,当使用某个引用作为参数,传递给getrefcount()时,参数实际上创建了一个临时的引用。因此,getrefcount()所得到的结果,会比期望的多1。

from sys import getrefcount

a = [1, 2, 3]
print(getrefcount(a)) # 2

b = a
print(getrefcount(b)) # 3
  • 引用计数增加 
    1.对象被创建:x=4 
    2.另外的别人被创建:y=x 
    3.被作为参数传递给函数:foo(x) 
    4.作为容器对象的一个元素:a=[1, x, ‘33’]

  • 引用计数减少 
    1.一个本地引用离开了它的作用域。比如上面的foo(x)函数结束时,x指向的对象引用减1。 
    2.对象的别名被显式的销毁:del x ;或者del y 
    3.对象的一个别名被赋值给其他对象:x=789 
    4.对象从一个窗口对象中移除:myList.remove(x) 
    5.窗口对象本身被销毁:del myList,或者窗口对象本身离开了作用域。

垃圾回收

  • 引用计数 
    引用计数也是一种垃圾收集机制,而且也是一种最直观,最简单的垃圾收集技术。当Python的某个对象的引用计数降为0时,说明没有任何引用指向该对象,该对象就成为要被回收的垃圾了。比如某个新建对象,它被分配给某个引用,对象的引用计数变为1。如果引用被删除,对象的引用计数为0,那么该对象就可以被垃圾回收。 
    不过如果出现循环引用的话,引用计数机制就不再起有效的作用了
a = []
b = []
a.append(b)
b.append(a)
print a  # [[[…]]]
print b  # [[[…]]]

循环引用可以使一组对象的引用计数不为0,然而这些对象实际上并没有被任何外部对象所引用,它们之间只是相互引用。这意味着不会再有人使用这组对象,应该回收这组对象所占用的内存空间,然后由于相互引用的存在,每一个对象的引用计数都不为0,因此这些对象所占用的内存永远不会被释放。 
Python又引入了其他的垃圾收集机制来弥补引用计数的缺陷:“标记-清除“,“分代回收”两种收集技术。

  • 标记清除 
    如果两个对象的引用计数都为1,但是仅仅存在他们之间的循环引用,那么这两个对象都是需要被回收的,也就是说,它们的引用计数虽然表现为非0,但实际上有效的引用计数为0。所以先将循环引用摘掉,就会得出这两个对象的有效计数。 
    在实际操作中,并不改动真实的引用计数,而是将集合中对象的引用计数复制一份副本,改动该对象引用的副本。对于副本做任何的改动,都不会影响到对象生命周期的维护。 
    这个计数副本的唯一作用是寻找root object集合(该集合中的对象是不能被回收的)。当成功寻找到root object集合之后,首先将现在的内存链表一分为二,一条链表中维护root object集合,成为root链表,而另外一条链表中维护剩下的对象,成为unreachable链表。之所以要剖成两个链表,是基于这样的一种考虑:现在的unreachable可能存在被root链表中的对象,直接或间接引用的对象,这些对象是不能被回收的,一旦在标记的过程中,发现这样的对象,就将其从unreachable链表中移到root链表中;当完成标记后,unreachable链表中剩下的所有对象就是名副其实的垃圾对象了,接下来的垃圾回收只需限制在unreachable链表中即可。

  • 分代回收 
    从前面“标记-清除”这样的垃圾收集机制来看,这种垃圾收集机制所带来的额外操作实际上与系统中总的内存块的数量是相关的,当需要回收的内存块越多时,垃圾检测带来的额外操作就越多,而垃圾回收带来的额外操作就越少;反之,当需回收的内存块越少时,垃圾检测就将比垃圾回收带来更少的额外操作。 
    举个例子来说明: 
    当某些内存块M经过了3次垃圾收集的清洗之后还存活时,我们就将内存块M划到一个集合A中去,而新分配的内存都划分到集合B中去。当垃圾收集开始工作时,大多数情况都只对集合B进行垃圾回收,而对集合A进行垃圾回收要隔相当长一段时间后才进行,这就使得垃圾收集机制需要处理的内存少了,效率自然就提高了。在这个过程中,集合B中的某些内存块由于存活时间长而会被转移到集合A中,当然,集合A中实际上也存在一些垃圾,这些垃圾的回收会因为这种分代的机制而被延迟。

  • 内存池机制
  • Python的内存机制呈现金字塔形状,-1,-2层主要有操作系统进行操作;
  • 第0层是C中的malloc,free等内存分配和释放函数进行操作;
  • 第1层和第2层是内存池,有Python的接口函数PyMem_Malloc函数实现,当对象小于256K时有该层直接分配内存;
  • 第3层是最上层,也就是我们对Python对象的直接操作;

Python在运行期间会大量地执行malloc和free的操作,频繁地在用户态和核心态之间进行切换,这将严重影响Python的执行效率。为了加速Python的执行效率,Python引入了一个内存池机制,用于管理对小块内存的申请和释放。 
Python内部默认的小块内存与大块内存的分界点定在256个字节,当申请的内存小于256字节时,PyObject_Malloc会在内存池中申请内存;当申请的内存大于256字节时,PyObject_Malloc的行为将蜕化为malloc的行为。当然,通过修改Python源代码,我们可以改变这个默认值,从而改变Python的默认内存管理行为。

内存溢出和内存泄露的区别:

内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。

内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。

memory leak会最终会导致out of memory!

内存溢出就是你要求分配的内存超出了系统能给你的,系统不能满足需求,于是产生溢出。 

    内存泄漏是指你向系统申请分配内存进行使用(new),可是使用完了以后却不归还(delete),结果你申请到的那块内存你自己也不能再访问(也许你把它的地址给弄丢了),而系统也不能再次将它分配给需要的程序。一个盘子用尽各种方法只能装4个果子,你装了5个,结果掉倒地上不能吃了。这就是溢出!比方说栈,栈满时再做进栈必定产生空间溢出,叫上溢,栈空时再做退栈也产生空间溢出,称为下溢。就是分配的内存不足以放下数据项序列,称为内存溢出.

常用的软件测试的工具有哪些?
测试工具一般可分为白盒测试工具、黑盒测试工具、性能测试工具,另外还有用于测试管理(测试流程管理、缺陷跟踪管理、测试用例管理)的工具,这些产品主要是MercuryInteractive(MI)、Segue、IBM Rational、 Compuware和Empirix等公司的产品,而MI公司的产品占了主流。
白盒测试工具
  白盒测试工具一般是针对代码进行测试,测试中发现的缺陷可以定位到代码级,根据测试工具原理的不同,又可以分为静态测试工具和动态测试工具。
  静态测试工具:直接对代码进行分析,不需要运行代码,也不需要对代码编译链接,生成可执行文件。静态测试工具一般是对代码进行语法扫描,找出不符合编码规范的地方,根据某种质量模型评价代码的质量,生成系统的调用关系图等。静态测试工具的代表有:Telelogic公司的Logiscope软件;PR公司的PRQA软件。
  动态测试工具:动态测试工具与静态测试工具不同,动态测试工具的一般采用"插桩"的方式,向代码生成的可执行文件中插入一些监测代码,用来统计程序运行时的数据。其与静态测试工具最大的不同就是动态测试工具要求被测系统实际运行。动态测试工具的代表有:Compuware公司的DevPartner软件;Rational公司的Purify系列等。
黑盒测试工具
  黑盒测试工具适用于黑盒测试的场合,黑盒测试工具包括功能测试工具和性能测试工具。黑盒测试工具的一般原理是利用脚本的录制(Record)/回放(Playback),模拟用户的操作,然后将被测系统的输出记录下来同预先给定的标准结果比较。黑盒测试工具可以大大减轻黑盒测试的工作量,在迭代开发的过程中,能够很好地进行回归测试。黑盒测试工具的代表有:Rational公司的TeamTest、Robot;Compuware公司的QACenter。
性能测试工具
  专用于性能测试的工具包括有:Radview公司的WebLoad;Microsoft公司的  WebStress等工具;针对数据库测试的TestBytes;对应用性能进行优化的EcoScope等工具。   MercuryInteractive的LoadRunner是一种适用于各种体系架构的自动负载测试工具,它能预测系统行为并优化系统性能。LoadRunner的测试对象是整个企业的系统,它通过模拟实际用户的操作行为和实行实时性能监测,来帮助您更快的查找和发现问题。
测试管理工具
  测试管理工具用于对测试进行管理。一般而言,测试管理工具对测试计划、测试用例、测试实施进行管理,并且,测试管理工具还包括对缺陷的跟踪管理。测试管理工具的代表有:Rational公司的Test Manager;Compureware公司的TrackRecord;Mercury Interactive公司的TestDirector等软件。
View Code

 

1.如何将一个嵌套列表转化为一个字典

list=[[2,'a'],[2,'b'],['c',3]]

print(dict(list))
自动去重

2.如何知道当前模块所在的文件的绝对路径
print(__file__)

ps:
os.getcwd() 或取当前工作目录
删除非空文件夹: import shutil
shutil.rmtree(path)

3。python内置方法里面的自省/反射?
通过字符串的形式操作对象相关的属性
列:Django的配置文件(内置与自定义相结合)

4。描述写一个注册页面的逻辑
form组件
是否已存在
验证码
两次输入密码

5 所用的python的版本,linux的系统和版本
python 3.5
Django 1.11
Ubuntu 16.04

6 你们团队几个人,如何一起开发(分配任务?)
3人团队:team leader 数据库设计,整体架构
后端 主要逻辑代码编写
前端 前端代码展示


7 django 如何实现跨域
方法一:jsonp 自己生成具有src属性的标签,向后台发送消息,浏览器的同源策略机制不会制约这样的请求
方法二:core跨域资源共享,由服务端给响应加响应头,使浏览器允许跨域访问
简单请求(1次)和复杂请求(2次)
首先会发送"预检"opption,请求,如果"预检"成功,则发送真实数据

8 CSRF 跨站请求伪造


9 常用的linux的命令有哪些?

systemctl stop/start/restart firemalld

硬盘:df -h -T
内存:free/top
进程:ps aux |grep firefox
kill -9 1545
文件:touch/ rm -rf/cat/cp /mkdir
网络:netstat -tunalp

10 进程,线程和协程的区别

 

11 自测工具
loadrunner 压力测试
单元测试 unittest模块


12 git reset回滚
三个区域:工作区 缓存区 远程仓库
git reset --soft
--hard
--mix

 


13 写一个二分查找

def func(li,val):
low=0
high=len(li)-1
while low<= high:
mid=(low+high)//2
if li[mid]==val:
return mid
elif li[mid]<val:
low=mid+1
else:
high=mid-1
else:
return 'not found'


14 设计一个算法,将2个有序数组合并成为一个数组(归并排序
时间复杂度和空间复杂度

15 PEP8规范有哪些
缩进 空行 模块导入 空格使用 注释 文档描述 命名规范 编码建议(is)

16 python中有哪些常用的package

time --获取当前时间
random --生成验证码
hashlib --加密
logging --生成日志
json --生成字符串传递
re --字符串处理

17 描述一下API安全认证

 为什么要做API验证?
        数据传输过程中,保证数据不被篡改
如何设计?
            --和Tornado中的加密Cookie类似
            --客户端创建动态key md5(key+time)|time
            --服务端 添加限制
                    -- 时间限制
                    -- 算法规则限制
                    -- 已访问记录 2s
                  ps :黑客窃取数据后,速度比正常汇报速度快,解决方法:数据加密 crypto模块 AES

 


18 你总共爬取了多少数据
4-5万条数据

19 如何反复的迭代一个序列
a=reversed(li)# a为迭代器

def test():
for i in range(1,len(li)+1):
yield li[-i]


20. sort 和sorted的区别,reverse和reversed的区别
sort在原有的基础上对列表进行排序
sorted对列表进行排序后生成了一个新的列表,原有的列表不变


reverse在原有的基础上对列表进行反序
reversed对列表进行反序后生成了一个新的迭代器,原有的列表不变


21 单例模式
class Singleton(object):
self._instance=None
def __new__(cls,*args,**kwargs):
if not hasattr(cls,'_instance'):
Singleton._instance=object.__new__()
return Singleton._instance

22 数据库提高并发的方法?
1 索引
2 读写分离
3 取消外键
4 sql优化
避免使用 select *
count(1)或count(列) 代替count(*)
创建表时尽量用char代替varchar
表的字段顺序按照固定长度的字段优先
组合索引代替多个单列索引(经常使用多个条件查询时)
尽量使用短索引 create index xxxx on userinfo(username(3)) 对username的前3个字符建立索引
连表时注意条件类型需一致

23 Django中提高数据库访问性能的方法?
select_related 一对多使用,查询主动做连表
prefetch_related 多对多或一对多的时候使用,不做连表,做多次查询

Django中如何提高并发的?
1利用redis,memcache等把常用的数据存到缓存
2 部署的时候用nginx+uwsig为django提供高并发,nginx的反向代理可以提供超过单台并发的能力,在纯静态的web服务中更是突出其优越
的地方,由于底层使用epoll异步IO模型进行处理。
3部署的时候用多进程或多线程
4 优化sql语句

24 如何提高memcache的命中率?
在配置文件中设置缓存超时时间

 

25 Django的请求流程

请求来到后先到uwsgi,把请求做一部分封装给到Django框架,然后经过中间件,路由系统,视图函数,模板渲染,最后返回给中间件,uwsgi,最
后返回给浏览器显示

26__new__和__init__的区别:
前者是一个静态方法,返回一个创建的实例,后者是一个实例方法,什么都不返回
只有在前者返回一个cls的实例时,后面的__init__才能被调用
创建一个新实例时用前者,初始化一个实例时用后者

27 深浅拷贝
浅拷贝只是增加了一个指针指向一个存在的地址,而深拷贝是增加一个指针并且开辟了一个新的内存空间,这和增加的指针指向这个新的内存
采用浅拷贝,释放内存,会释放同一内存,深拷贝就不会出现释放同一内存的错误

28.闭包
1.必须有一个内嵌函数
2.内嵌函数必须引用外部函数的变量(该函数包含对外作用域而不是全局作用域名字的引用)
3.外部函数的返回值必须是内嵌函数

29.迭代器与生成器
迭代可迭代对象对应_iter_(方法)和迭代器对应_next_(方法)的一个过程
生成器:包括含有yield这个关键字,生成器也是迭代器,调动next把函数变成迭代器

 

30,epoll,poll,select

select:本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理
缺点:1.单个进程可见识的fd数量被限制,即能监听端口的大小有限
cat /proc/sys/fs/file-max
2.对socket进行扫描时是线性扫描,即采用轮询的方法,效率较低
3.需要维护一个用来存放大量fd的数据结构,这样会使得用户空间和内核空间在传递该结构时复制开销大


poll:本质上和select没有区别,它将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态;其没有最大连接数的限制,原因是它是基于链表来存储的,但是同样有一个缺点:
1. 大量的fd的数组被整体复制于用户态和内核地址空间之间,而不管这样的复制是不是有意
2. poll还有一个特点是“水平触发”,如果报告了fd后,没有被处理,那么下次poll时会再次报告该fd

epoll:支持水平触发和边缘触发,最大的特点在于边缘触发,它只告诉进程哪些fd刚刚变为就需态,并且只会通知一次;使用"事件"的就绪通知方式,通过epoll_ctl注册fd,一旦该fd就绪,内核就会采用类似callback的回调机制来激活该fd,epoll_wait便可以收到通知

优点:
1.没有最大并发连接的限制,能打开的fd的上限远大于1024(1G的内存上能监听越10万个端口)
2.效率提升:非轮询的方式,不会随着fd数目的增加而效率下降;只有活跃可用的fd才会调用callback函数,即epoll最大的优点就在于它只管理"活跃"的连接,而跟连接总数无关
3. 内存拷贝,一用nmap() 文件映射内存加速与内核空间的消息传递;即epoll使用nmap减少复制开销
通过3个函数实现 最大连接数没有上限
第一个函数:创建epoll句柄,将所有的fd拷贝到内核空间,只需要拷贝一次
第二个函数 :回调函数 某一函数或者动作完成之后会触发的函数
为所有的fd绑定一个回调函数,一旦有数据访问则触发该回调函数
回调函数将fd放到链表中
第三个函数 判断链表是否为空

31python2和python3都有哪些区别

range和xrange
默认编码
经典类(深度优先)和新式类(广度优先)

posted @ 2017-11-01 12:56  柳姑娘  阅读(177)  评论(0编辑  收藏  举报