Python必问面试题

Python中赋值 浅拷贝和深拷贝的区别

1、赋值:简单地拷贝对象的引用,两个对象的id相同。
2、浅拷贝:创建一个新的组合对象,这个新对象与原对象共享内存中的子对象。
3、深拷贝:创建一个新的组合对象,同时递归地拷贝所有子对象,新的组合对象与原对象没有任何关联。

虽然实际上会共享不可变的子对象,但不影响它们的相互独立性

浅拷贝和深拷贝的不同仅仅是对组合对象来说,所谓的组合对象就是包含了其它对象的对象,如列表,类实例。而对于数字、字符串以及其它“原子”类型,没有拷贝一说,产生的都是原对象的引用。

Python中 == 和is的区别

is和 == 都可以对两个对象进行比较,而且它们的返回值都是布尔类型。

is和 == 比较的对象的内容时不同的,即:is比较的是两个对象的地址值,也就是说两个对象是否为同一个实例对象;而 ==比较的是对象的值是否相等,其调用了对象的__eq__()方法。

线程如何在Python 中实现

线程
在程序里一个执行路线就叫做线程,线程是程序执行的最小单位.

多线程
多线程类似于同时执行多个不同程序。
多线程运行有如下优点:

使用线程可以把占据长时间的程序中的任务放到后台去处理。 程序的运行速度可能加快在一些等待的任务实现上如用户输入、文件读写和网络收发数据等。
在这种情况下我们可以释放一些珍贵的资源如内存占用等等。

threading模块实现多线程

threading提供了如下方法:

  • run(): 用以表示线程活动的方法。
  • start():启动线程活动。
  • join([time]): 等待至线程中止。
  • isAlive(): 返回线程是否活动的。
  • getName(): 返回线程名。
  • setName(): 设置线程名。

Python中使用线程有两种方式:函数或者用类来包装线程对象。

函数方式:

导入threading包
对象名= threading.Thread(target = 函数名) 创建线程对象
对象名.start() 创建线程

注:由于代码执行过快,为了显示效果,使用sleep延时执行。
继承方式:

导入threading包
创建一个类继承Thread类,重写run方法
创建类对象,调用start()方法创建线程

注:由于代码执行过快,为了显示效果,使用sleep延时执行。

在这里插入图片描述

Python中 负值索引

1、python中正索引从左到右0,1,2… 负索引从右到左-1,-2,-3…
2、高维数组难以直观理解,所以负索引提供了一种从高维到低维的查找方式
3、numpy中高级索引,花式索引可将数组作为索引变量,解决手写迭代的繁琐

类里面的new 和init的区别

__init__ 方法通常用在初始化一个类实例的时候。
但__init__其实不是实例化一个类的时候第一个被调用 的方法。当使用 Persion(name, age) 这样的表达式来实例化一个类时,最先被调用的方法 其实是 new 方法。
__new__方法接受的参数虽然也是和__init__一样
但__init__是在类实例创建之后调用,而 __new__方法正是创建这个类实例的方法。

大数据的文件读取

利用生成器generator
迭代器进行迭代遍历:for line in file

迭代器和生成器的区别

迭代器是一个更加抽象的概念,任何对象,如果它的类有next方法和iter方法返回自身。

对于string、list、dict、tuple等这类容器对象,使用for循环遍历是很方便的。
在后台for语句对容器对象调用iter()函数,iter()是Python的内置函数。
iter()会返回一个定义了next()方法的迭代器对象,它在容器中逐个访问容器内元素,next()也是python的内置函数。
在没有后续元素时,next()会抛出一个StopIterration的异常。

生成器(Generator)是创建迭代器的简单而强大的工具。

它们写起来就像是正规的函数,只是在返回数据的时候需要使用yield语句。
每次next()被调用时,生成器会返回它脱离的位置(它记忆语句最后一次执行的位置和所有的数据值)
在这里插入图片描述

装饰器的作用和功能

引入日志
函数执行时间统计
执行函数钱预备处理
执行函数后的清理功能
权限校验等场景
缓存

如何提高python的运行效率

使用生成器;
关键代码使用外部功能包(Cython,pylnlne,pypy,pyrex);
针对循环的优化–尽量避免在循环中访问变量的属性

Python是如何进行内存管理的

一、垃圾回收:

python不像C++,Java等语言一样,他们可以不用事先声明变量类型而直接对变量进行赋值。对python语言来讲,对象的类型和内存都是在运行时确定的。

二、引用计数:
python采用了类似windows内核对象一样的方式来对内存进行管理。每一个对象,都维护这一个对指向该对象的引用的计数。

三、内存池机制
python的内存机制成金字塔形:

 第-1,-2层主要有操作系统进行操作; 第0层是C中的malloc,free等内存分配和释放函数进行操作;
 第1层和第2层是内存池,有python的接口函数PyMem_Malloc函数实现,当对象小于256字节时由该层直接分配内存;
 第三层是最上层,也就是我们对python对象的直接操作;

描述数组、链表、队列、堆栈的区别?

数组和链表是数据存储方式的概念,数组在连续的空间中存储数据,而链表可以在非连续的空间中存储数据;

队列和堆栈是描述数据存取方式的概念,队列是先进先出,而堆栈是后进先出;队列和堆栈可以用数组来实现,也可以用链表实现。

跨域请求问题django怎么解决的(原理)

启用中间件

post请求

验证码

表单中添加{%csrf_token%}标签

请解释或描述一下Django的架构

对于Django框架遵循MVC设计,并且有一个专有的名词:MVT

M全拼为Model,与MVC中的M功能相同,负责数据处理,内嵌了ORM框架

V全拼为View,与MVC中的C功能相同,接收HttpRequest,业务处理,返回HttpReponse

T全拼为Template,与MVC中的V功能相同,负责封装构造要返回的html,内嵌了模板引擎

说一下Django,MIDDLEWARES中间件的作用?

中间件是介于request和response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变Django的输入和输出

谈谈对Django的认识?

Django是走大而全的方向,它最出名的是全自动化的管理后台;只需要使用ORM,做简单的对象定义,它就能自动生成数据库结构、以及全功能的管理后台。

Django内置的ORM跟框架内的其他模块耦合程度高

应用程序必须使用Django内置的ORM,否则就不能享受到框架内提供的种种基于其ORM的便利。理论上可以切换掉其ORM模块,但这就相当于要把装修完毕的房子拆除重新装修,倒不如一开始就去毛坯房做全新的装修。

Django的卖点是超高的开发效率,其性能扩展有限;采用Django的项目,在流量达到一定规模后,都需要对其进行重构,才能满足性能的要求。

Django适用的是中小型的网站,或者是作为大型网站快速实现产品雏形的工具。

Django模板的设计哲学是彻底的将代码、样式分离; Django从根本上杜绝在模板中进行编码、处理数据的可能。

Django重定向你是如何实现的?用的什么状态码?

使用HttpResponseRedirect

redire和reverse

状态码:302,301

ngnix的正向代理与反向代理?

正向代理

是一个位于客户端和原始服务器(origin
server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端必须要进行一些特别的设置才能使用正向代理。

反向代理

对于客户端而言它就像是原始服务器,并且客户端不需要进行任何特别的设置。客户端向反向代理的命名空间中的内容发送普通请求,接着反向代理将判断向何处(原始服务器)转交请求,并将获得的内容返回给客户端,就像这些内容原本就是它自己的一样。

常见的HTTP状态码有哪些?

1**:请求收到,继续处理
2**:操作成功收到,分析、接受
3**:完成此请求必须进一步处理
4**:请求包含一个错误语法或不能完成
5**:服务器执行一个完全有效请求失败

100——客户必须继续发出请求
101——客户要求服务器根据请求转换HTTP协议版本

200——服务器成功返回网页
201——提示知道新文件的URL
202——接受和处理、但处理未完成
203——返回信息不确定或不完整
204——请求收到,但返回信息为空
205——服务器完成了请求,用户代理必须复位当前已经浏览过的文件
206——服务器已经完成了部分用户的GET请求

300——请求的资源可在多处得到
301——删除请求数据
302——在其他地址发现了请求数据
303——建议客户访问其他URL或访问方式
304——客户端已经执行了GET,但文件未变化
305——请求的资源必须从服务器指定的地址得到

400——错误请求,如语法错误
401——请求授权失败
402——保留有效ChargeTo头响应
403——请求不允许
404——请求的网页不存在
405——用户在Request-Line字段定义的方法不允许
406——根据用户发送的Accept拖,请求资源不可访问

500——服务器产生内部错误
501——服务器不支持请求的函数
502——服务器暂时不可用,有时是为了防止发生系统过载
503——服务器超时过载或暂停维修
504——关口过载,服务器使用另一个关口或服务来响应用户,等待时间设定值较长
505——服务器不支持或拒绝支请求头中指定的HTTP版本

Post和get区别?

GET请求

请求的数据会附加在URL之后,以?分割URL和传输数据,多个参数用&连接。
URL的编码格式采用的是ASCII编码,而不是unicode,即是说所有的非ASCII字符都要编码之后再传输。

POST请求

POST请求会把请求的数据放置在HTTP请求包的包体中。
上面的item=bandsaw就是实际的传输数据。
因此,GET请求的数据会暴露在地址栏中,而POST请求则不会。

cookie 和session 的区别?

1、cookie数据存放在客户的浏览器上,session数据放在服务器上。

2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗考虑到安全应当使用session。

3、session会在一定时间内保存在服务器上。当访问增多,会比较占用服务器的性能考虑到减轻服务器性能方面,应当使用COOKIE。

4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。

建议: 将登陆信息等重要信息存放为SESSION 其他信息如果需要保留,可以放在COOKIE中

你用过的爬虫框架或者模块有哪些?谈谈他们的区别或者优缺点?

Python自带:urlliburllib2

第 三 方:requests

框 架:Scrapy

urllib和urllib2模块都做与请求URL相关的操作,但他们提供不同的功能。

urllib2.:

urllib2.urlopen可以接受一个Request对象或者url,(在接受Request对象时候,并以此可以来设置一个URL
的headers),urllib.urlopen只接收一个url

urllib

有urlencode,urllib2没有,因此总是urllib,urllib2常会一起使用的原因

scrapy

是封装起来的框架,他包含了下载器,解析器,日志及异常处理,基于多线程, twisted的方式处理,对于固定单个网站的爬取开发,有优势,但是对于多网站爬取100个网站,并发及分布式处理方面,不够灵活,不便调整与括展。

request

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

Scrapy优缺点:

优点:

scrapy 是异步的

采取可读性更强的xpath代替正则

强大的统计和log系统

同时在不同的url上爬行

支持shell方式,方便独立调试

写middleware,方便写一些统一的过滤器

通过管道的方式存入数据库

缺点:

基于python的爬虫框架,扩展性比较差

基于twisted框架,运行中的exception是不会干掉reactor,并且异步框架出错后是不会停掉其他任务的,数据出错后难以察觉。

你常用的mysql引擎有哪些?各引擎间有什么区别?

主要 MyISAM 与 InnoDB 两个引擎,其主要区别如下:

一、InnoDB 支持事务,MyISAM 不支持,这一点是非常之重要。事务是一种高级的处理方式,如在一些列增删改中只要哪个出错还可以回滚还原,而 MyISAM就不可以了;

二、MyISAM 适合查询以及插入为主的应用,InnoDB 适合频繁修改以及涉及到安全性较高的应用;

三、InnoDB 支持外键,MyISAM 不支持;

四、MyISAM 是默认引擎,InnoDB 需要指定;

五、InnoDB 不支持 FULLTEXT 类型的索引;

六、InnoDB 中不保存表的行数,如 select count() from table 时,InnoDB;需要扫描一遍整个表来计算有多少行,但是 MyISAM 只要简单的读出保存好的行数即可。注意的是,当 count()语句包含 where 条件时 MyISAM 也需要扫描整个表;

七、对于自增长的字段,InnoDB 中必须包含只有该字段的索引,但是在 MyISAM表中可以和其他字段一起建立联合索引;

八、清空整个表时,InnoDB 是一行一行的删除,效率非常慢。MyISAM 则会重建表;

九、InnoDB 支持行锁(某些情况下还是锁整表,如 update table set a=1 where user like ‘%lee%’

什么是关联查询,有哪些?

将多个表联合起来进行查询

内连接、左连接、右连接、全连接(外连接)

数据库的优化?

  1. 优化索引、SQL 语句、分析慢查询;

  2. 设计表的时候严格根据数据库的设计范式来设计数据库;

  3. 使用缓存,把经常访问到的数据而且不需要经常变化的数据放在缓存中,能节约磁盘IO;

  4. 优化硬件;采用SSD,使用磁盘队列技术(RAID0,RAID1,RDID5)等;

  5. 采用MySQL 内部自带的表分区技术,把数据分层不同的文件,能够提高磁盘的读取效率;

  6. 垂直分表;把一些不经常读的数据放在一张表里,节约磁盘I/O;

  7. 主从分离读写;采用主从复制把数据库的读操作和写入操作分离开来;

  8. 分库分表分机器(数据量特别大),主要的的原理就是数据路由;

  9. 选择合适的表引擎,参数上的优化;

  10. 进行架构级别的缓存,静态化和分布式;

  11. 不采用全文索引;

  12. 采用更快的存储方式,例如 NoSQL存储经常访问的数据

常见的反爬虫和应对方法?

1.通过Headers反爬虫

从用户请求的Headers反爬虫是最常见的反爬虫策略。很多网站都会对Headers的User-Agent进行检测,还有一部分网站会对Referer进行检测(一些资源网站的防盗链就是检测Referer)。如果遇到了这类反爬虫机制,可以直接在爬虫中添加Headers,将浏览器的User-Agent复制到爬虫的Headers中;或者将Referer值修改为目标网站域名。对于检测Headers的反爬虫,在爬虫中修改或者添加Headers就能很好的绕过。

2.基于用户行为反爬虫

还有一部分网站是通过检测用户行为,例如同一IP短时间内多次访问同一页面,或者同一账户短时间内多次进行相同操作。
大多数网站都是前一种情况,对于这种情况,使用IP代理就可以解决。
可以专门写一个爬虫,爬取网上公开的代理ip,检测后全部保存起来。
这样的代理ip爬虫经常会用到,最好自己准备一个。
有了大量代理ip后可以每请求几次更换一个ip,这在requests或者urllib2中很容易做到,这样就能很容易的绕过第一种反爬虫。

对于第二种情况,可以在每次请求后随机间隔几秒再进行下一次请求。
有些有逻辑漏洞的网站,可以通过请求几次,退出登录,重新登录,继续请求来绕过同一账号短时间内不能多次进行相同请求的限制。

3.动态页面的反爬虫

上述的几种情况大多都是出现在静态页面,还有一部分网站,我们需要爬取的数据是通过ajax请求得到,或者通过JavaScript生成的。
首先用Fiddler对网络请求进行分析。
如果能够找到ajax请求,也能分析出具体的参数和响应的具体含义,我们就能采用上面的方法,直接利用requests或者urllib2模拟ajax请求,对响应的json进行分析得到需要的数据。

结尾给大家推荐一个非常好的学习教程,希望对你学习Python有帮助!

有什么疑惑欢迎来交流圈互动:690577709【别忘记备注:编学小屋】

Python基础入门教程推荐:更多Python视频教程-关注B站:编学小屋

Web前端开发-筑基十四式

爬虫是干嘛的?看完你会发现新大陆!

猜你喜欢

转载自blog.csdn.net/m0_63325818/article/details/121243841