2018-python面试题

1.python中大文件是如何读取的?

(1)读取几个G的文件时,可以利用生成器generator。

(2)read(参数指定读取大小),readline(每一行读取),readlines(读取全部的行)模块linecache解决大文件的读取问题。

(3)对于可迭代对象的file,进行迭代遍历,会自动使用IO缓存,以及内存管理,很好的解决大文件读取问题。

With open(“filename”)as file:

for line in file;

    do_things(line)

2.简要说下迭代器和生成器的区别与联系?

(1)迭代器:首先判断是否是可以迭代,用isinstance()方法判断或者可以for循环的遍历的对象是可迭代对象,可以被next()函数调用,并不断返回下一个值得对象。

(2)生成器:自动创建了iter()和next()内置方法仅仅保存了一套生成数值的算法,调用时,才去计算然后返回一个值。生成器一定是迭代器,而迭代器不一定是生成器,一边循环一边计算的机制称为生成器,含有yield语句的函数,可以减少内存空间。

(3)装饰器:它的本质是还是函数,在闭包作为基础,装饰器用来修饰函数的,在不改变原有函数的代码块,新增其他功能时,就可以使用装饰器。有效的保护了原始代码的完整性,有利于维护。

3.线程,进程,协成的理解?

(1)线程:【同步机制】CPU处理器调度的基本单位,进程中的一个执行单位可调度的实体,占用系统资源很少,同一个进程中的多个线程可以共享全局变量,通信主要是共享进程内存,资源开销很小,不够稳定,易丢失数据。

(2)进程:是系统资源分配和调度的一个独立单位,每个进程都有自己的内存空间,占用内存资源比较多,上下文切换开销大,比较稳定和安全。

(3)协程:【异步机制】调度由用户控制,更加轻量级的线程,拥有自己的寄存器和上下文栈,开销小,切换上下文迅速。

3.简述一下同步,异步,阻塞和非阻塞的理解?

同步:好比煮水的过程(每隔一段时间要去观察)等待的过程就是堵塞。

异步:好比煮好的水,水壶给你一个信号,然后去处理开水,不需要循环的等待这个事件。

阻塞:在过程中,你不能干其他事,一直等待水开了,然后去做另外一件事。

非堵塞:在烧水的过程中可以干其他事,等这个水开了,然后收到这个信号,才去处理。

4.GIL对多线程的影响?

GIL是设计者遗留下的问题,全局解释器锁,为了数据安全所做的决定,在每个CPU同一时间只能执行一个线程(在单核CPU下的多线程其实都是并发的,不是并行的)。

并行:不管是宏观和微观上看同个时间一起发生的,比如一个排队打饭。

并发:宏观上感觉是同时进行的,微观协同交错一起执行工作。

线程之间共享全局变量的时候,出现了资源争夺,可能会出现数据的异常.

作用:每个进程都只有一个GIL锁,谁拿到锁谁就可以使用CPU资源。当遇到I/O耗时操作时,有空闲的操作的时候就会释放GIL锁,其他线程就开始竞争GIL锁。

5.线程的安全?

多线程的情况下,线程之间在共享全局变量时,会有争取和修改全局变量,为了保证数据的正确性,同一个时刻只有一个线程在存取。

6.什么是面向对象编程?

面向对象编程,是一种解决软件复用的设计的一种编程方法,它通过封装的思想,把功能函数交给一个对象去管理,用到的时候就可以直接创建对象,通过对象来调用实例方法。

7.面向对象的哪些技术?

类:用来描述相同属性和方法的一类事物,定义了该集合对象的共有特征。

方法重写:当子类继承父类的时候,父类的方法不能满足子类的要求时,子类会对其父类的方法重写,实现扩展功能,重写实质就是覆盖父类方法。

8.静态方法和类方法?

静态方法: 用@staticmethod修饰,不需要参数。

类方法: 用@classmethod修饰,第一个参数一般是cls,可以自定义,类对象所拥有的方法。可以通过类对象和实例对象就行调用来使用。

9.python的多进程和多线程的运行机制是什么?有什么区别?分别在再什么情况下用?

运行机制:(1)进程是一个具有独立功能的程序,系统资源和调度的一个基本单位。

      (2)线程是一个进程的一个实体,CPU调度的分配的单位,占有资源少,未处理的数据会在缓存区保存。

A:多进程稳定性好,单个进程出现问题不会影响其他进程的运行,缺点就是消耗资源太大,创建时代价大,系统调度会出现问题。

B:多线程效率要高效一些,缺点是,任何一个线程出现问题,会造成整个进程出现崩溃,共享内存资源。

10.python 中数组有哪些类型?字典中可以有序吗?

列表,字典,集合

from collections import OrderDict

dic = OrderDict()

11.python 是如何进行内存管理的?

  1. 垃圾回收:python 是动态语言,可以动态的对变量进行赋值,对变量的内存地址的分配是在运行时自动判断数据类型来对变量进行赋值。

2.引用计数:python采用类似windows内核对象的方式来对内存进行管理,每一个对象创建出来时,引用计数就会加1,系统会自动维护这些对象,会定时的进行扫描管理,当计数为0的时候,就会回收对象进行清理。

3.内存池机制:小整数对象池【-5-256】系统自动创建好的自动会分配相同的地址,用在同一个对象,字符一样。如果分配的内存在1-256字节直接会用自己的管理系统,否则会使用malloc,来负责分配地址,没每一块都是256的大块地址。

12.python 里面如何拷贝一个对象?

赋值:给对象创建一个新的引用,修改其中任意一个变量都会影响到另一个。

浅拷贝:单层非嵌套的可变类型的数据类型来说,深浅拷贝都是一样的拷贝了其内容。

    多层的嵌套可变类型的数据,它只是拷贝了一层的引用,没有拷贝其深层内容。

深拷贝:它拷贝是递归式的拷贝,拷贝的是目的对象的所有内容。

13.递归函数的停止条件?

条件:一般都定义在递归函数的内部,在递归前做一个判断。根据结果来选择继续调用自身。

终止:1.次数达到条件的限定时,就会return。

  2.运算的结果达到指定的范围,根据实际的设计来终止。

14.python常见的设计模式有哪些?

1.创建型模式:简单的工厂模式,抽象工厂,创建者模式,原始模式,单例模式

2.结构型模式:外观模式,装饰模型,组合模式,代理模式。

3.行为型模式:模板方法模式,观察者模式,访问者模式,解释器模式,迭代器模式,状态模式。

15.单例的应用场景?

1.网站的计数器 2.应用配置 3.多线程池 4.数据库配置。

16.什么是闭包?

闭包:2个函数的嵌套,内部函数可以使用外部函数变量的行为,外部函数的变了和数据不能立即销毁,而保留一段时间,内部调用完就可以销毁,外部函数返回值是内部函数,一般用在装饰器上。

17.软硬链接的区别?

软链接:windows下的快捷键,源文件删除不会受影响,只是删除了一个地址,当源文件位置变化或者不存在时,软链接就失效。

硬链接:可以理解源文件的别名,多个别名都是同一个源文件,当删除时,源文件的数目就会减1,当硬链接为0的时候,文件就是删除。

18.linux的管道作用?

一个命令的输出可以通过管道作为另一个命令的输入。

19.关系数据库的关系包括哪些类型?

foreignkey,一对多,将字段定义在多的一端中。

manytomanyfield,多对多,将字段定义两端中。

onetoonefield,一对一,将子段定义任意一端中。

20.查询集返回列表的过滤器有哪些?

all():返回所有数据。

filter:返回所有条件的数据。

exclude:返回满足条件之外的数据。

order_by:排序

exists():判断是否查询集有数据。

特性:惰性执行,缓冲,判断查询集中是否有数据,有的话直接获取,没有才会访问数据库,调用数据包括,迭代,序列化,与if和合用。

21.匿名函数的理解?

匿名函数:省略def声明的函数就是匿名函数,也可以称为lambda表达式,只能处理一些简单的逻辑。

函数名= lambda 参数列表:表达式(判断条件一定有返回值或者结果)

22.面向对象的三大特征?

封装:通用的属性和方法定义在类中,通过类例实化出对象,对象来调用属性和方法。封装的意义,保护数据的完整性,外界只能访问方法不能去修改里面的属性。

继承:子类需要复用父类的方法和属性时,就可以选择继承。

多态:同一个方法,不同对象调用,实现的不同功能的表现形式。

23.基本概念?

类:具有相同数据和方法的一组对象的描述和定义。

对象:类的实例,管理一系列函数的实体。

实例属性:一个对象就是一组属性的集合。

类属型:类对象所拥有的属性,实例对象也共有。

24.访问百度的详细过程?

1.解析web页面的url,得到web服务器的域名。

2.通过DNS服务器获取web服务器的IP地址。

3.获取PC的IP地址。

4.访问路由器建立的物理层连接

5.与web建立TCP连接3次握手,4次挥手的过程结束。

6.与web建立HTTP连接

7.从web服务器获取URL指定的文档

8.浏览器解析页面文档,显示到浏览器。

25.网络掩码的作用是什么?它的组成规律是什么?

判断IP地址是否在统一网段,ip地址与网络掩码与运算。

网络掩码:网络号都是[1] 主机号都是[0]

26.什么事视图?

通俗的讲就是:一条select语句执行后返回的结果集。

特点:视图是对若干张基本表的引用,一张虚表,查询执行的结果,不存在具体的数据。

27.集合去重?

1.使用集合去重

ids = [1,4,3,3,4,2,3,4,5,6,1]

news_ids = list(set(ids))

print(news_ids)

news_ids.sort(key= ids.index)

print(ids.index)

print(news_ids)

2.使用for循环和if判断去重

news_ids = []

for i in ids:

if i not in news_ids:

    news_ids.append(i)

print(news_ids)

ids = [1,4,3,3,4,2,3,4,5,6,1]

index 0 1 2 3 4 5 6 7 8 9 10

3.使用索引判断去重

list1 = [1, 55, 66, 85, 1, 22, 35, 55, 66, 86, 85]

new_list = list()

for key, value in enumerate(list1):

# 打印的是列表下标value多对应的值.

print(list1.index(value), end=" ")

if list1.index(value) == key:

    new_list.append(value)

print(new_list)

news_ids = []

for i,j in enumerate(ids):

    # index(2) ==3

if ids.index(j) == i:

    news_ids.append(j)

print(news_ids)

4.使用while循环count去重

news_ids = ids[:]

for i in ids:

while news_ids.count(i) > 1:

    del news_ids[news_ids.index(i)]

print(11111,news_ids)

news_ids.sort(key=ids.index)

print(news_ids)

Web框架的问题

1.跨域请求问题django怎么解决的原理?

启动中间件,post请求,验证码,表单中添加{%crsf token%}

2.请简述一下Django的框架?

MVT模式是django的特有的模式。

M :model是模型,负责和后台数据库的处理(包括对数据的增删查改),内嵌了ORM关系映射。

V :view是视图,负责处理后台逻辑函数处理,负责处理用户请求处理,然后把数据传给模板。

T :template是模板,负责处理html文件,渲染模板,显示数据到浏览器上。

3.django对数据查询的结果排序是怎么做?降序怎么做?查询大于某个字段怎么处理?

排序:order_by()方法实现。

降序:在排序字段名前面加一个负号-。

查询字段大于某个值时,可以用fileter(字段名_gt=值)来过滤。

4.说一下Django中的中间件的作用?

中间件:就是一道关卡,用户的reques和response之间的处理的过程必须经过中间件的检验,全局上来改变django的输入和输出。

5.你对django的认识?

• Django太重了,除了web框架,自带ORM和模板引擎,灵活和自由度不够高

• Django能开发小应用,但总会有“杀鸡焉用牛刀”的感觉

• Django的自带ORM非常优秀,综合评价略高于SQLAlchemy

• Django自带的模板引擎简单好用,但其强大程度和综合评价略低于Jinja

• Django自带ORM使Django与关系型数据库耦合度过高,如果想使用MongoDB等NoSQL数据,需要选取合适的第三方库。

• Django目前支持Jinja等非官方模板引擎

• Django自带的数据库管理app好评如潮

• Django非常适合企业级网站的开发,快速、靠谱、稳定。

• Django成熟、稳定、完善,但相比于Flask,Django的整体生态相对封闭

• Django是Python web框架的先驱,用户多,第三方库最丰富,最好的Python库,如果不能直接用到Django中,也一定能找到与之对应的移植

django:是一个重量级的框架,全自动的管理后台,只需要使用ORM关系映射做简单的对象的定义,通过迁移生成数据库结构,全功能的管理后台。

django的内置的ORM跟其他模块的耦合度高,django好比装修好的房子,只需要我们给里面添加其内容,家具进行充实和渲染。超高效率的开发的优势。但是扩展性就有所欠缺,耦合度高。适合中小型公司做大型网站的雏形的工具。

6.django的重定向怎么实现的?

HttpResponseRedirect redirect 和 reverse 状态吗302,301

7.nginx的正向代理和反向代理?

正向代理:它隐藏了真实的请求的客户端,服务端不知道真实的客户端是谁,客户端请求的服务端都被代理服务器代替来请求,翻墙类似正向代理。

反向代理:它隐藏了正式的服务端,好比访问百度,百度有上千万台服务器为我们服务,我们不须知道反向代理服务器是谁,反响代理就是会昂我们把请求转发到真实计算的服务器那里去,nginx就是反向代理的服务器用来做负载均衡。

区别:两者的区别的对象不一样,[正向代理]代理对象是客户端,[反向代理]代理的对象是服务端。

8.uWSGI是什么?

是一个web服务器,实现了http协议,uwsgi,UWSGI协议,uwsgi是uWSGI特有的协议,天定义传输数据的类型,以及传输的信息类型描述。

9.jieba分词?

精确模式:将句子划分成关键字,适合文本的查询。

全模式:句子中所有可以组成词语的抽取出来作为关键字索引。

搜索引擎模式:精确的模式上,在进行长词的细划分,提高了搜索的效率,whoosh引擎。

10.django哪里用到了进程,哪里用到了线程,哪里用到了协程?

1.django利用多线程增加异步处理任务,celery消息队列。

2.django中使用多线程发送邮件send_mail().

3.django原生就是单线程程序,第一个请求完成,第二个请求阻塞,直到第一个完成,第二个才会执行。使用uwsgi多鬓发,使用nginx+uwsgi提高鬓发,nginx并发提高。

4.django自带多线程模式。

11.django关闭浏览器,怎么清除cookie和session?

浏览器请求服务器是无状态的。无状态指一次用户请求时,浏览器、服务器无法知道之前这个用户做过什么,每次请求都是一次新的请求。无状态的应用层面的原因是:浏览器和服务器之间的通信都遵守HTTP协议。根本原因是:浏览器与服务器是使用Socket套接字进行通信的,服务器将请求结果返回给浏览器之后,会关闭当前的Socket连接,而且服务器也会在处理页面完毕之后销毁页面对象。

有时需要保持下来用户浏览的状态,比如用户是否登录过,浏览过哪些商品等。 实现状态保持主要有两种方式:

在客户端存储信息使用Cookie。

在服务器端存储信息使用Session。

cookie是有效期。默认是关闭浏览器就会清除cookie的值。SESSION_COOKIE_ACE秒(存活时间)。

session的过期时间默认是2周。 request.session.set_expiry(0)当浏览器关闭时,session失效

删除session:del request[key]

12.简述django下的内建的缓存机制?

django根据设置缓存方式,浏览器骑一次请求时,cache会缓存单个变量或者整个网页到磁盘或者内存,同时设置了response头部,第二次访问的时候,根据缓存时间的判断,将内容将缓存数据返回给客户端。

13.项目中使用什么调试?

python中unitit单位测试模块进行简单的测试。

14.项目怎么优化的?

web前端的性能优化:页面静态化的处理

应用服务器优化:缓存,异步,集群。

存储优化:缓存机制,数据频繁变化的存储在redis数据库,查询效率高。

Redis的7个应用场景

一:缓存——热数据

热点数据(经常会被查询,但是不经常被修改或者删除的数据),首选是使用redis缓存,毕竟强大到冒泡的QPS和极强的稳定性不是所有类似工具都有的,而且相比于memcached还提供了丰富的数据类型可以使用,另外,内存中的数据也提供了AOF和RDB等持久化机制可以选择,要冷、热的还是忽冷忽热的都可选。

结合具体应用需要注意一下:很多人用spring的AOP来构建redis缓存的自动生产和清除,过程可能如下:

Select 数据库前查询redis,有的话使用redis数据,放弃select 数据库,没有的话,select 数据库,然后将数据插入redis

update或者delete数据库钱,查询redis是否存在该数据,存在的话先删除redis中数据,然后再update或者delete数据库中的数据

上面这种操作,如果并发量很小的情况下基本没问题,但是高并发的情况请注意下面场景:

为了update先删掉了redis中的该数据,这时候另一个线程执行查询,发现redis中没有,瞬间执行了查询SQL,并且插入到redis中一条数据,回到刚才那个update语句,这个悲催的线程压根不知道刚才那个该死的select线程犯了一个弥天大错!于是这个redis中的错误数据就永远的存在了下去,直到下一个update或者delete。

二:计数器

诸如统计点击数等应用。由于单线程,可以避免并发问题,保证不会出错,而且100%毫秒级性能!爽。

命令:INCRBY

当然爽完了,别忘记持久化,毕竟是redis只是存了内存!

三:队列

相当于消息系统,ActiveMQ,RocketMQ等工具类似,但是个人觉得简单用一下还行,如果对于数据一致性要求高的话还是用RocketMQ等专业系统。

由于redis把数据添加到队列是返回添加元素在队列的第几位,所以可以做判断用户是第几个访问这种业务

队列不仅可以把并发请求变成串行,并且还可以做队列或者栈使用

四:位操作(大数据处理)

用于数据量上亿的场景下,例如几亿用户系统的签到,去重登录次数统计,某用户是否在线状态等等。

想想一下腾讯10亿用户,要几个毫秒内查询到某个用户是否在线,你能怎么做?千万别说给每个用户建立一个key,然后挨个记(你可以算一下需要的内存会很恐怖,而且这种类似的需求很多,腾讯光这个得多花多少钱。。)好吧。这里要用到位操作——使用setbit、getbit、bitcount命令。

原理是:redis内构建一个足够长的数组,每个数组元素只能是0和1两个值,然后这个数组的下标index用来表示我们上面例子里面的用户id(必须是数字哈),那么很显然,这个几亿长的大数组就能通过下标和元素值(0和1)来构建一个记忆系统,上面我说的几个场景也就能够实现。用到的命令是:setbit、getbit、bitcount

五:分布式锁与单线程机制

验证前端的重复请求(可以自由扩展类似情况),可以通过redis进行过滤:每次请求将request Ip、参数、接口等hash作为key存储redis(幂等性请求),设置多长时间有效期,然后下次请求过来的时候先在redis中检索有没有这个key,进而验证是不是一定时间内过来的重复提交

秒杀系统,基于redis是单线程特征,防止出现数据库“爆破”

全局增量ID生成,类似“秒杀”

六:最新列表

例如新闻列表页面最新的新闻列表,如果总数量很大的情况下,尽量不要使用select a from A limit 10这种low货,尝试redis的 LPUSH命令构建List,一个个顺序都塞进去就可以啦。不过万一内存清掉了咋办?也简单,查询不到存储key的话,用mysql查询并且初始化一个List到redis中就好了。

转载自:Super_Jason_one

没有更多推荐了,返回首页