python面试题 - Go语言中文社区

python面试题


用于python面试整理,主要来源于http://www.cnblogs.com/skiler/p/6952707.html,很感谢博主分享,欢迎指正交流。

Python面试200题(含爬虫)

面试题(一)【15】

1、现有两元祖  (('a'),('b'),('c'),('d') ) ,请使用Python中的匿名函数生成列表[ {'a':'c',{'c':'d'}]

答案:v = list(map(lambda x,y:{x:y},data[0:2],data[2:4]))

data = (('a'),('b'),('c'),('d') )

v = list(map(lambda x,y:{x:y},data[0:2],data[2:4]))

data[0:2] = ('a'),('b')

data[2:4] = ('c'),('d')

匿名函数传进去  参数(x,y)  返回{x:y}

map(func,iterable) #对于iterable依次传递给func,返回的是可迭代对象

2、看代码 写结果

def multipliters():

    return [lambda x:i * x for i in range(4)]

print([m(2) for m in multipliters()])


# 第一种是 将生成器对象生成的匿名函数转化成列表 ,匿名函数使用的是相同的内存空间。

# 转换成列表后,循环结束,命名空间里的i都为3

def multipliters():

    return [lambda x:i * x for i in range(4)]

print([m(2) for m in multipliters()])

# 以下是依次返回 生成器生成的每个匿名函数,每次调用i都在变化

def multipliters2():

    return (lambda x: i*x for i in range(4))

print([m(2) for m in multipliters2()])


3、1 or 2和1 and 2分别输出什么?


# 1    2 

# 0 "" [] {} set() None False放入判断表达式都为假

# or或  and与

# 整个式子 不断去向右查看,直到能确定为真就停下来


4、看代码 写结果

value = "B" and "A" or "C" 

print(value)

# A

# 整个式子 不断去向右查看,直到能确定为真就停下来


5、看代码写结果

v1 = [i % 2 for i in range(10)]

v2 = (i % 2 for i in range(10))

print(v1,v2)


# v1 = [i % 2 for i in range(10)]为列表生成式

# v2 = (i % 2 for i in range(10))为 at 0x00E4F990>为生成式


6、看代码,写结果

def extendList(val,li=[]):

    li.append(val)

    return li

list1 = extendList(10)

list2 = extendList(123,[])

list3 = extendList('a')

print(list1)

print(list2)

print(list3)


# [10, 'a']

# [123]

# [10, 'a']

# 参数变量在编译会生成,而且只会生成一次,其内存地址的指向不发生变化

# 所以会有默认的 []

# 1、3都会使用默认的 编译生成同一个[]

# 2新生成一个[] 


7、下面代码谁报错?

v1 = {}

v2 = {3:5}

v3 = {[11,23]:5}

v4 = {(11,23):5}

v3错误,字典元素的键不能为可变对象

8、输出以下结果

for i in range(5,0,1):

    print(i)

# range(起始元素,结束元素(不包含),每次的变化)

# 5 每次加1,啥时候能加到0,O(∩_∩)O哈哈~

9、请说出range和xrange的区别


# from collections import Iterable,Iterator

# Iterable可迭代对象

# Iterator迭代器 

# print(isinstance(xrange(10),Iterator))

# print(isinstance(xrange(10),Iterable))

# python2中range(start, stop[, step])和range(stop)会生成-> range object,,返回是列表,是可迭代对象,全部放在内存里

# python2中xrange(start, stop[, step])和range(stop)会生成-> xrange object,返回是可迭代对象,每次调用时才会生成

# python3 没有xrange,只有range,也是可迭代对象,每次调用时才会生成


10、请将"1,2,3",变成["1","2","3"]


"1,2,3".split(',')


11、一行代码生成[1,4,9,16,25,36,49,64,81,100]


[i*i for i in range(11)]


12、一行生成9 * 9乘法表


[ x                              for x in range(1,10)]

[ x*y for y in range(1,x+1)]

[ ([ x*y for y in range(1,x+1)]) for x in range(1,10)]

[ ([ '{}*{} = {}'.format(x,y,x*y) for y in range(1,x+1)]) for x in range(1,10)]

'n'.join([ str(x) for x in range(1,10)])

print('n'.join([ ' '.join( [ '{}*{} = {}'.format(x,y,x*y) for y in range(1,x+1)] ) for x in range(1,10)]) )


13、map(str,[1,2,3,4,5,6,7,8,9])输出什么?Python2和Python3输出的结果一样吗?


print(isinstance(map(str,[1,2,3,4,5,6,7,8,9]),Iterable))

print(isinstance(map(str,[1,2,3,4,5,6,7,8,9]),Iterator))

# python 3 是Iterator

# python 2 ['1', '2', '3', '4', '5', '6', '7', '8', '9'] ,是可迭代对象,但不是Iterator


14、Django如何在Model保存前做一定的固定操作,比如写一条日志


利用Django的Model的Signal Dispatcher,通过django.db.models.signals.pre_save()方法,在事件发生前,发射触发信号,这一切都被调度中的receiver方法深藏功与名的保存了。

信号的处理一般都写在Model中,举个例子:

import logging

from django.db import models

from django.db.models.signals import pre_save

from django.dispatch import receiver


class Order(models.Model):

    # ...


logger = logging.getLogger(__name__)


@receiver(pre_save, sender=Order)

def pre_save_handler(sender, **kwargs):


    #我们可以在Order这个Model保存之前尽情调戏了:)

    logger.debug("{},{}".format(sender, **kwargs))

参考:http://python.jobbole.com/81871/

15、1,2,3,4,5能组成多少个互不相同的无重复的三位数

5 * 4 * 3

建造者模式 【1】

一、内容

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建造者模式与抽象工厂模式相似,也用来创建复杂对象。主要区别是建造者模式着重一步步构造一个复杂对象,而抽象工厂模式着重于多个系列的产品对象。

二、角色

抽象建造者(Builder)

具体建造者(Concrete Builder)

指挥者(Director)

产品(Product)

三、优点

隐藏了一个产品的内部结构和装配过程

将构造代码与表示代码分开

可以对构造过程进行更精细的控制

四、适用场景

当创建复杂对象的算法(Director)应该独立于该对象的组成部分以及它们的装配方式(Builder)时

当构造过程允许被构造的对象有不同的表示时(不同Builder)。

五、实例

# coding : utf-8

# create by ztypl on 2017/5/25

from abc import abstractmethod, ABCMeta

#------产品------

class Player:

    def __init__(self, face=None, body=None, arm=None, leg=None):

        self.face = face

        self.arm = arm

        self.leg = leg

        self.body = body

    def __str__(self):

        return "%s, %s, %s, %s" % (self.face, self.arm, self.body, self.leg)

#------建造者------

class PlayerBuilder(metaclass=ABCMeta):

    @abstractmethod

    def build_face(self):

        pass

    @abstractmethod

    def build_arm(self):

        pass

    @abstractmethod

    def build_leg(self):

        pass

    @abstractmethod

    def build_body(self):

        pass

    @abstractmethod

    def get_player(self):

        pass

class BeautifulWomanBuilder(PlayerBuilder):

    def __init__(self):

        self.player = Player()

    def build_face(self):

        self.player.face = "漂亮脸蛋"

    def build_arm(self):

        self.player.arm="细胳膊"

    def build_body(self):

        self.player.body="细腰"

    def build_leg(self):

        self.player.leg="长腿"

    def get_player(self):

        return self.player

class PlayerDirector:

    def build_player(self, builder):

        builder.build_body()

        builder.build_arm()

        builder.build_leg()

        builder.build_face()

        return builder.get_player()

director = PlayerDirector()

builder = BeautifulWomanBuilder()

p = director.build_player(builder)

print(p)


六、UML图


面试题(二)【12】

1、什么是lambda函数?它有什么好处?另外python在函数编程方面提供了些什么函数和语法?

lambda是Python中的匿名函数。它语法简单,简化代码,不会产生命名冲突,污染命名空间。Python提供了map,reduce,filter等函数方法,提供了装饰器,闭包等语法

2、详细说说tuple、list、dict的用法,它们的特点;

tuple 元祖,固定长度不可变的顺序容器,访问效率高,是和存储一些常量数据,可以作为字典的键使用

list 列表,是长度可变有序的数据存储容器,。可以通过下标索引取到相应的数据

dict 字典,长度可变的hash字典容器。存储的方式为键值对,可以通过相应的键获取相应的值,key支持多种类型

3、说说python中装饰器、迭代器的用法;描述下dict的items()方法与iteritems()方法的不同;

装饰器是指对函数执行过程,做一些扩展,甚至可以更改本身函数的执行

迭代器是指遵循迭代器协议的对象,这类对象在被for循环时,每次迭代生成下一个项,不用一开始就生成整个列表

在python3中不存在iteritems,items方法返回可迭代对象

在python2中items()返回[(key,value)]的列表对象,iteritems()返回迭代器对象,iteritems()循环时不可以增删dict的内容

4、讲讲对unicode, gbk, utf-8等的理解,python2.x是如何处理编码问题?

unicode编码:为了解决各个国家的语言的存储,引进的unicode码,包括UCS2,UCS4,UTF-8,UTF-7等

gbk:和unicode不一样的编码方式,常用的为gbk-2312

utf-8: UTF-8 使用 1-4 个字节来存储单个字符,应该是目前最流行的字符集。Linux 默认字符集就是UTF-8。既解决了大多数语言的编码方式,又避免了简单字符存储对空间的浪费

python 2.x需要在文件上方声明文件的编码方式# -*- coding: utf8 -*-,可以通过str.decode/str.encode处理字符串的文本编码

保证 python 编辑器的编码正确,或使用 u’中文’保证被转换成 unicode 编码,推荐使用

sys.setdefaultencoding('utf-8')来保证我们的编码

5、Python 是如何进行内存管理的?python 的程序会内存泄露吗?说说有没有什么方面防止或检测内存泄露?

Python GC主要使用 引用计数 来跟踪和回收垃圾。在引用计数的基础上,通过“标记-清除”解决容器对象可能产生的循环引用问题。通过分代

以空间换时间的方法提高垃圾回收效率

1、引用计数: 每个对象中都有ob-refcnt来做引用计数。当一个对象...,ob-refcnt就会增加,当引用的对象删除,那么ob-refcnt就会减少当ob-refcnt为零,就会释放该对象的内存空间

2、标记清除: 解决循环引用的问题。先按需分配,等到没有空闲内存的时候,从寄存器和程序栈上的引用出发,遍历所有对象和引用把所有能访问的打标记,最后将没有标记的对象释放掉

3、分代技术: 提高效率,提高垃圾回收的效率,按照存活时间,分成不同的集合。将内存块按照其存活时间划分为不同的集合。每个集合就称为一个“代”,垃圾回收的频率随代的存活时间增大而减小。。Python默认定义分代对象集合,引用数越大,对象的存活时间越长

Python也会内存泄露,Python本身的垃圾回收机制无法回收重写了__del__的循环引用的对象

程序员管理好每个python对象的引用,尽量在不需要使用对象的时候,断开所有引用

尽量少通过循环引用组织数据,可以改用weakref做弱引用或者用id之类的句柄访问对象

通过gc模块的接口可以检查出每次垃圾回收有哪些对象不能自动处理,再逐个逐个处理

6、关于 python 程序的运行性能方面,有什么手段能提升性能?

1、使用多进程,充分利用机器的多核性能

2、对于性能影响较大的部分代码,可以使用C或C++编写

3、对于IO阻塞造成的性能影响,可以使用IO多路复用来解决

4、尽量使用python的内建函数

5、尽量使用局部变量

7、list对象alist [{'name':'a','age':20},{'name':'b','age':30},{'name':'c','age':25}],请按alist中元素的age由大到小排序;

def sort_by_age(list1):

    return sorted(alist,key=lambda x:x['age'],reverse=True)

8、两个list对象alist ['a','b','c','d','e','f'], blist ['x','y','z','d','e','f'],请用简洁的方法合并这两个list,并且list里面的元素不能重复;

alist = ['a','b','c','d','e','f']

blist = ['x','y','z','d','e','f']

def merge_list(*args):

    s = set()

    for i in args:

        s = s.union(i)

    return list(s)

9、打乱一个排好序的list对象alist;

import random

random.shuffle(alist)

10、简单实现一个stack

class Stack:

    def __init__(self):

        self.items = []

    def __iter__(self):

        return self.items.__iter__()

    def pop(self):

        return self.items.pop()

    def top(self):

        if len(self.items) > 0:

            return self.items[len(self.items) - 1]

    def push(self, item):

        self.items.append(item)

    def empty(self):

        self.items = []

    def size(self):

        return len(self.items)

11、输入某年某月某日,判断这一天是这一年的第几天?(可以用 python 标准库)

import datetime

def dayofyear():

    year = input("请输入年份:")

    month = input("请输入月份:")

    day = input("请输入天:")

    date1 = datetime.date(year=int(year),month=int(month),day=int(day))

    date2 = datetime.date(year=int(year),month=1,day=1)

    return (date1 -date2).days

12、将字符串:"k:1|k1:2|k2:3|k3:4",处理成python字典:{k:1, k1:2, ... }

str1 = "k:1|k1:2|k2:3|k3:4"

def str2dict(str1):

    dict1 = {}

    for iterms in str1.split('|'):

        key,value = iterms.split(':')

        dict1[key] = value

    return dict1


面试题(三)【1】

请完成一个程序,并能按步骤实现以下功能:

1.下载https://en.wikipedia.org/wiki/Machine_translation页面的内容并保存为mt.html

       需要编写代码来下载页面。

2.统计mt.html中

标签内下所有单词以及数目并存储到mt_word.txt中。

mt_word.txt有如下几点要求:

       a) 每个单词一行。单词在前,单词出现的次数在后,中间用Tab(t)进行分隔。

       b) 单词要按照单词数目从多到少的顺序进行排列。比如说单词a出现了100次,单词b出现了10次,则单词a要在单词b的前面。

3. 提取出mt.html中所有的年份信息(比如说页面中的1629, 1951这些的四位数字就是年份)存储到mt_year.txt中。

mt_year.txt有如下几点要求:

a)每个年份是一行。

       a) 年份需要从过去到现在的顺序进行排列。比如说文章中出现了2007和1997,则1997需要排在2007的前面。


要求:

1. 仅限python编程,而且仅仅可以使用python自带的函数或库。

2.提交可执行的程序以及mt.html, mt_word.txt, mt_year.txt。

3. 限定在一个小时内完成。

# 1.下载https://en.wikipedia.org/wiki/Machine_translation页面的内容并保存为mt.html需要编写代码来下载页面。

session = requests.session()

response = session.get(url="https://en.wikipedia.org/wiki/Machine_translation")

with open('mt.html','wb') as f:

    f.write(response.content)

# 2、统计mt.html中

标签内下所有单词以及数目并存储到mt_word.txt中

# 解析页面,拿到所有的p标签中的文本

soup = BeautifulSoup(response.text,features="lxml")

tag2 = soup.find_all(name='p')

list_p = []

for i in tag2:

    list_p.append(i.get_text())

# 将所有的文本合并成一个字符串

str_p = ' '.join(list_p)

word_set = set()

for word in str_p.split():

    word = word.strip(',.()""/; ')

    word_set.add(word)

# word_dict = {}

word_list = []

for word in word_set:

    if word == '':

        continue

    # word_dict[word] = str_p.count(word)

    dict2 = {word:str_p.count(word)}

    word_list.append(dict2)

# 将单词按照数目反序排列,然后写入文件

blist = sorted(word_list,key = lambda x:list(x.values())[0],reverse =True)

with open('mt_word.txt','w') as f:

    for item in blist:

        for k,v in item.items():

            line = k + 't' + str(v) + 'n'

            f.write(line)


# 3、提取出mt.html中所有的年份信息(比如说页面中的1629, 1951这些的四位数字就是年份)存储到mt_year.txt中

year = re.compile(r'd{4}')

years_list = re.findall(year,response.text)

years_list = sorted(list(set(years_list)))

with open('mt_year.txt','w') as f:

    for year in years_list:

        line = year + 'n'

        f.write(line)

答案

面试题(四)爬虫【16】

一、试列出至少三种目前流行的大型数据库的名称:________、_________、__________,其中您最熟悉的是__________,从__________年开始使用。

Oracle,Mysql,SQLServer  Oracle根据自己情况

二、有表List,并有字段A、B、C,类型都是整数。表中有如下几条记录:

ABC

279

564

3119

现在对该表一次完成以下操作:

查询出B和C列的值,要求按B列升序排列

写出一条新的记录,值为{7,9,8}

查询C列,要求消除重复的值,按降序排列

写出完成完成以上操作的标准的SQL语句,并且写出操作3的结果。

create table List2(A int ,B int,C int)

select B,C from List order by B

insert into List values(7,9,8)

select distinct(C) from List order by 1 desc;

9 8 4

三、请简要说明视图的作用

1. 数据库视图隐藏了数据的复杂性。

2. 数据库视图有利于控制用户对表中某些列的访问。

3. 数据库视图使用户查询变得简单。

四、列举您使用过的python网络爬虫所用到的网络数据包(最熟悉的在前):

requests、urllib、urllib2、httplib2

五、列举您使用过的python网络爬虫所用到的解析数据包(最熟悉的在前):

BeautifulSoup、pyquery、Xpath、lxml

六、列举您使用过的python中的编码方式(最熟悉的在前):

UTF-8,ASCII,gbk

七、python3.5语言中enumerate的意思是_______________________

对于一个可迭代的(iterable)/可遍历的对象(如列表、字符串),enumerate将其组成一个索引序列,利用它可以同时获得索引和值

enumerate多用于在for循环中得到计数

八、99的八进制表示是_______________________

143

九、请举出三种常用的排序算法

冒泡、选择、快速

十、列出比较熟悉的爬虫框架

Scrapy

十一、用4、9、2、7四个数字,可以使用+、-、*和/,每个数字使用一次,使表达式的结果为24,表达式是_____________________________

(9+7-4)*2

十二、     对你最有影响的或是您认为最有价值的软件方面的几本书是?

十三、您最熟悉的Unix环境是_____________.Unix下查询环境变量的命令是________,查询脚本定时任务的命令是____________________

1 AIX,env  crontab

十四、     写出在网络爬虫爬取数据的过程中,遇到的防爬虫问题的解决方案

 通过headers反爬虫:解决策略,伪造headers

 基于用户行为反爬虫:动态变化去爬取数据,模拟普通用户的行为

 基于动态页面的反爬虫:跟踪服务器发送的ajax请求,模拟ajax请求

十五、阅读以下Python程序

for i in range(5,0,-1):

      print(i)

请在下面写出打印结果

5 4 3 2 1

十六、在某系统中一个整数占用两个八位字节,使用Python按下面的要求编写完整程序。

接收从标准输入中依次输入的五个数字,将其组合成为一个整数,放入全局变量n中,随后在标准输出输出这个整数。(ord(char)获取字符ASCII值的函数)

面试题(五)爬虫 【14】

1、post、get有什么区别?

1. 根据HTTP规范,GET一般用于获取/查询资源信息,应该是安全的和幂等。而POST一般用于更新资源信息

2. get是在url中传递数据,数据放在请求头中。 post是在请求体中传递数据

3. get传送的数据量较小,只能在请求头上发送数据。post传送的数据量较大,一般被默认为不受限制。

5. get安全性非常低,post安全性较高。但是执行效率却比Post方法好。

建议:

1、get方式的安全性较Post方式要差些,包含机密信息的话,建议用Post数据提交方式;

2、在做数据查询时,建议用Get方式;而在做数据添加、修改或删除时,建议用Post方式;

2、http、https协议有什么区别?

http协议是超文本传输协议,被用于在web浏览器和网站服务器之间传递信息。http协议工作是以明文方式发送内容,不提供任何形式的数据加密,而这也是很容易被黑客利用的地方,如果黑客截取了web浏览器和网站服务器之间的传输信息,就可以直接读懂其中的信息,因此http协议不适合传输一些重要的、敏感的信息,比如信用卡密码及支付验证码等。

安全套接字层https协议就是为了解决http协议的这一安全缺陷而出生的,为了数据传输的安全,https在http的基础上加入了ssl协议,ssl依靠证书来验证服务器的身份,为浏览器和服务器之间的通信加密,这样的话即使黑客借去了发送过程中的信息,也无法破解读懂它,我们网站及用户的信息便得到了最大的安全保障。

https协议需要到ca申请证书,一般免费证书很少,需要费用。

http是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议

http和https使用的是完全不同的连接方式用的端口也不一样,前者是80,后者是443。

http的连接很简单,是无状态的, HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议 要比http协议安全

3、 域名和IP之间有什么关系,如何查看某个域名对应的所有IP?

国际互联网(Internet)上有成千百万台主机(host),为了区分这些主机,人们给每台主机都分配了一个专门的“地址”作为标识,称为IP地址

由于IP地址全是些的数字,为了便于用户记忆,Internet上引进了域名服务系统DNS(Domain Name System)。

当您键入某个域名的时候,这个信息首先到达提供此域名解析的服务器上,再将此域名解析为相应网站的IP地址。完成这一任务的过程就称为域名解析。

1.ping  2.nslookup 3.使用站长工具等

4、http协议头中,keep-alive字段有什么作用?

HTTP协议采用“请求-应答”模式,当使用普通模式,即非KeepAlive模式时,每个请求/应答客户和服务器都要新建一个连接,完成 之后立即断开连接(HTTP协议为无连接的协议);

当使用Keep-Alive模式(又称持久连接、连接重用)时,Keep-Alive功能使客户端到服 务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了建立或者重新建立连接。

通过使用keep-alive机制,可以减少tcp连接建立次数,也意味着可以减少TIME_WAIT状态连接,以此提高性能和提高httpd服务器的吞吐率(更少的tcp连接意味着更少的系统内核调用,socket的accept()和close()调用)。

5、robots协议是什么?

Robots协议(也称为爬虫协议、爬虫规则、机器人协议等)也就是robots.txt,网站通过robots协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取。

Robots协议是网站国际互联网界通行的道德规范,其目的是保护网站数据和敏感信息、确保用户个人信息和隐私不被侵犯。因其不是命令,故需要搜索引擎自觉遵守。

6、 列出几种常见的关系型数据库和非关系型数据库?(每种至少两个)

Oracle、Mysql、SQLServer、DB2          Redis MongoDB Cassandra

7、 内存泄露是什么?如何避免?

指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况。

内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,失去了对该段内存的控制,因而造成了内存的浪费。

导致程序运行速度减慢甚至系统崩溃等严重后果。

有 __del__() 函数的对象间的循环引用是导致内存泄漏的主凶。

不使用一个对象时使用:del object 来删除一个对象的引用计数就可以有效防止内存泄漏问题.

通过 Python 扩展模块 gc 来查看不能回收的对象的详细信息

可以通过 sys.getrefcount(obj) 来获取对象的引用计数,并根据返回值是否为 0 来判断是否内存泄漏

Python的内存管理机制

1.引用计数:通过引用计数来保持对内存中的变量跟踪,Python内部记录中所有在使用对象各有多少个引用。

Python中有个内部跟踪变量叫做引用计数器,每个变量有多少个引用,简称引用计数。当对象被创建时就创建了一个引用计数。

当某个对象的引用计数为0时,对象就不在需要,就列入了垃圾回收队列。

引用计数增加: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,或者窗口对象本身离开了作用域。

2.垃圾回收

1.引用计数: 每个对象中都有ob-refcnt来做引用计数。当一个对象...,ob-refcnt就会增加,当引用的对象删除,那么ob-refcnt就会减少当ob-refcnt为零,就会释放该对象的内存空间

2.标记清除: 解决循环引用的问题。先按需分配,等到没有空闲内存的时候,从寄存器和程序栈上的引用出发,遍历所有对象和引用把所有能访问的打标记,最后将没有标记的对象释放掉

3.分代技术: 提高效率,提高垃圾回收的效率,按照存活时间,分成不同的集合。将内存块按照其存活时间划分为不同的集合。每个集合就称为一个“代”,垃圾回收的频率随代的存活时间增大而减小。。Python默认定义分代对象集合,引用数越大,对象的存活时间越长

3.内存池机制

在Python中,大多数申请的都是小块的内存,会执行大量的malloc和free操作。Python引入了一个内存池机制,用于管理对小块内存的申请和释放,即Pymalloc机制。

它将不用的内存放到内存池而不是返回给操作系统。

1. 当申请的内存小于256字节时,PyObject_Malloc会在内存池中申请内存;当申请的内存大于256字节时,PyObject_Malloc的行为将蜕化为malloc的行为。当然,通过修改Python源代码,我们可以改变这个默认值,从而改变Python的默认内存管理行为。

2. 对于Python对象,如整数,浮点数和List,都有其独立的私有内存池,对象间不共享他们的内存池。也就是说如果你分配又释放了大量的整数,用于缓存这些整数的内存就不能再分配给浮点数。

8、 列举几个常用的dom解析项目、插件

xml、libxml2、lxml、xpath

9、 常见的反爬虫机制有哪些?

通过headers反爬虫:解决策略,伪造headers

基于用户行为反爬虫:动态变化去爬取数据,模拟普通用户的行为

基于动态页面的反爬虫:跟踪服务器发送的ajax请求,模拟ajax请求

10、如何提高爬取效率?

1. 爬取方面,利用异步io。

2.处理方面,利用消息队列做生产者消费者模型


11、楼梯问题

1.1、给一个楼梯,从最下面往上走,每次可以走1到n步,求总共有多少种走法?

1.2、给一个楼梯,从最下面往上走,每次可以走1步或2步,求总共有多少种走法?

1.3、给一个楼梯,从最下面往上走,每次可以走1步或2步或3步,求总共有多少种走法?

# 1、 给一个楼梯,从最下面往上走,每次可以走1或2步,求总共有多少种走法?

# 假设只有一个台阶,那么只有一种跳法,那就是一次跳一级,f(1)=1;如果有两个台阶,那么有两种跳法,第一种跳法是一次跳一级,第二种跳法是一次跳两级,f(2)=2。

# 如果有大于2级的n级台阶,那么假如第一次跳一级台阶,剩下还有n-1级台阶,有f(n-1)种跳法,假如第一次条2级台阶,剩下n-2级台阶,有f(n-2)种跳法。这就表示f(n)=f(n-1)+f(n-2)。

def walk_stairs(stairs):

    if stairs == 1:

        return 1

    if stairs == 2:

        return 2

    else:

        return walk_stairs(stairs-1) + walk_stairs(stairs-2)

# 2、给一个楼梯,从最下面往上走,每次可以走1到n步,求总共有多少种走法?

#上1个台阶1

#上2个台阶2

#上3个台阶4

#上4个台阶8

#上n个台阶2^(n-1)

# 3、给一个楼梯,从最下面往上走,每次可以走1步或2步或3步,求总共有多少种走法?

#上1个台阶2^(1-1)

#上2个台阶2^(2-1)

#上3个台阶2^(3-1)

# f(n) = f(n-1) + f(n-2) + f(n-3)

12、 给一个字符数组,字符包含a-z、1-9,比如:a b c 4 b 2 a c 1 1 3,求只出现一次的第一次出现的字符

str_list = ['a', 'b', 'c', 4, 'b', 2, 'a', 'c', 1, 1, 3]

def find_only_one(alist):

    for string in alist:

        count = alist.count(string)

        if count == 1:

            return string

    return None

13、 有一个html文本字符串,让我取出sflkj这个a标签里面的href的链接地址?

from bs4 import BeautifulSoup

text = "sflkj"

the_html = BeautifulSoup(text,features='lxml')

print(the_html.find('a').attrs['href'])

14、 下面是一个单线程的代码,请改写成多线程的:

start = "http://google.com"

queue = [start]

visited = {start}

while queue:

    url = queue.pop(0)

    print(url) 

    for next_url in extract_url(url):

        if next_url not in visited:

            queue.append(next_url)

        visited.add(next_url)


from concurrent.futures import ThreadPoolExecutor

start = "http://google.com"

queue = [start]

visited = {start}

pool = ThreadPoolExecutor(10)

def func(url):

    for next_url in extract_url(url):

        if next_url not in visited:

            queue.append(next_url)

        visited.add(next_url)

while queue:

    url = queue.pop(0)

    pool.submit(func,url)

pool.shutdown(wait=True)


面试题(六)[17]

1、 获取list的元素个数,向list的末尾追加元素所用的方法分别是( ),( )

count,append

2、 判断dict有没有某个key用的方法是( )

in

3、 L = range(100) ,取第一到第三个元素用(),取倒数第二个元素(),取后十个元素()

L[:3]

L[-2]

L[-10:]

4、 把L复制给L1用() 注意:非引用传递

L1 = L.copy()

5、d = {'a':1,'b':2,'c':3}请打印出key,value对

for k,v in d.items():

    print(k,v)

6、 如何判断一个变量是不是字符串

isinstance(a,str)

7、list和tuple有什么不同?

8、xrange和range有什么不同?

9、‘1,2,3’如何变成[‘1’,’2’,’3’] ?  [‘1’,’2’,’3’]如何变成[1,2,3]

s1 = "1,2,3"

s2 = list(s1.split(','))

s3 = list(map(int,s2))

10、请回答以下问题?

def add_end(L= []):

    L.append('END')

    return L

print(add_end()) #输出什么?

print(add_end()) #再次调用输出什么?为什么?

["END"] ["END",""END] 函数的默认参数在编译时,分配内存空间。没有给予参数都是使用默认的参数,是同一段内存地址的同一对象。

11、[36,5,12,9,21]怎么排序?

a = [36,5,12,9,21]

a.sort()

12、请回答以下问题:

def func(a,b,c=0,*args,**kwargs):

    pass

*args,**kwargs的作用是什么?

当函数的参数不确定时,可以使用*args 和**kwargs来 传递可变参数。

*args储存可变的位置参数,它会接收任意多个参数并把这些参数作为元组传递给函数。**kwargs存储可变的关键字参数,允许你使用没有事先定义的参数名,将接收到任意多个关键字参数作为字典传递给函数。

注意函数的参数的顺序:args必须在kwargs前面,调用函数传递参数也必须依照此顺序

13、is和==的区别是?

Python中的对象包含三要素:id、type、value

其中id用来唯一标识一个对象,type标识对象的类型,value是对象的值

is判断的是a对象是否就是b对象,是通过id来判断的

==判断的是a对象的值是否和b对象的值相等,是通过value来判断的

14、如何生成[1,4,9,16,25,36,49,64,81,100]?尽量用一行实现

[x*x for x in range(1,11)]

15、生成器是什么?有什么作用?请写出一个生成器

a = ( i for i in range(11))


16、map(str,[1,2,3,4,5,6,7,8,9])输出什么?

# 生成的是map对象

print(list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9])))

# ['1', '2', '3', '4', '5', '6', '7', '8', '9']

17、请写出log的实现(主要功能是打印函数名)

@log

def now():

    print('2013-12-25')

now()

# 输出:

# call now()

# 2013-12-25


import functools

def log(func):

    @functools.wraps(func)

    def inner():

        print('call '+ func.__name__ + '()')

        func()

    return inner


面试题(七)[13]

一、单项选择

1  以下叙述正确的是:

A continue语句的作用是结束整个循环的执行

B 只能在循环体内和switch语句体中使用break语句

C 在循环体内使用break语句或continue语句的 作用相同

D 从多层循环嵌套中退出时,只能使用goto语句

# B

2 Python如何定义一个函数( 3)

class ( arg1 , arg 2, ... , argN)

function (arg1 ,arg2 ,… , argN)

def (arg1 ,arg2 ,… , argN)

def ( arg1 , arg 2, ... , argN)

3 下面哪个函数能够在Linux环境下创建一个子进程:

os.popen

os.fork

os.system

os.link 

# 2


4已知x=43,ch = 'A' ,y = 1,则表达式(x > y and ch< ‘B’ and y)的值是

0

1

出错

True(“真”)

# 2

5 下面的语句哪个会无限循环下去

启动range函数原型为range([start],stop[,step])

1、for a in range(10):

                 time.sleep(10)

  2、while 1 < 10:

      time.sleep(10)

  3、while True:

      break;

  4、a = [3,-1, 5 , 7]

    for I in a[:]

  if a > 10:

  break;

# 2


6 下列表达式中返回为True的是:

         A. 3 > 2 >2

         B. ‘abc’ > ‘xyz’

         C. 0x56 < 56

         D. (3,2) < (‘a’,’b’)

# D

7 Python不支持的数据类型有

char

int

float

list

# 1

二、不定选项

8   下面的函数,那些会输出1,2,3三个数字

 for I in range(3)

    print i

  2. aList = [0,1,2]

          for I in aList:

                print i+1

  3. I = 1

  while I < 3:

         print i

         I = I +1

  4.for I in range(3):

    print I + 1

# 2,4


三、填空题

9  以下函数需要调用在其中引用一个全局变量k,请填写语句:

def func():

         ___________

         k = k +1

global k


10请把以下函数转化为Python lambda匿名函数

         def add(x,y):

                  return x+y

lambda x,y:x+y


11请简单解释Python中static method(静态方法)和class method(类方法)

请将以下代码填写完整


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()

# 调用 foo函数,参数传入1

a.foo(1)

#调用class_foo函数,参数传入1

a.class_foo(1)

A.class_foo(1)

# 调用静态方法,传入参数1

a.static_foo(1)

A.static_foo(1)


四、程序题

12、 请书写一个函数,用于替换某个字符串的一个或某几个字串

函数原型strreplace(str,oldString,newString);

例如:

pstr = “Hello World!”

afterReplaceStr = strreplace(pstr,”World”,”Tom”)

那么afterReplaceStr的值为”Hello Tom”

def strreplace(str,oldString,newString):

    return str.replace(oldString,newString)

13、 平衡点问题:

假如一个数组中的元素,其前面的部分等于后面的部分,那么这个点的位序就是平衡点

比如一个列表numbers = [1,3,20,2,18,6],2前面的总和为24,2后面的总和也是24,那么2就是平衡点

要求编写程序,寻找并返回任意一个列表的平衡点


def balance_num(numbers):

    for i in range(0,len(numbers)):

        if sum(numbers[:i]) == sum(numbers[i+1:]):

            return numbers[i]

    return None


面试题(八)【11】

1 Python如何实现单例模式?

2什么是lambda函数?

3 请写出一段Python代码实现删除list里面的重复元素?

4 如何用Python删除一个文件?

5 Python里面如何生成随机数?

6 请用Python写出一个获取用户输入数字,并根据数字大小输出不同信息的脚本?

7 range和xrange区别

8 解释生成器(generator)与函数的不同,并实现和使用简单generator

9输入一个字符串,返回倒序排列的结果;如’abcdef’,返回’fedcba’  str1 = 'abcdefg'

str2 = str1[::-1]

str3 = list(str1)

str3.reverse()

str4 = ''.join(str3)

10 请使用自己的算法,按升序合并如下两个list,并去除重复的元素:

  list1 = [2,3,8,4,9,5,6]

  list2 = [5,6,10,17,11,2]

11.Django如何在Model保存前做一定的固定操作,比如写一句日志

面试九【4】

1、浅谈你对python编码规范的认识,并写出你知道的编码规范

请点击 

Python编码规范和Python风格规范

一、原因

1、长期的工作中,发现大多数程序员的代码可读性差

2、不同的程序员之间的协作很重要,代码可读性必须很好

3、版本升级时,要基于源码升级

4、不友好的代码会影响python的执行效率

二、基于的规范

  1、PEP 8: Style Guide for Python Code---------Python的编码风格建议

  2、Google Python Style Guide--------------Goole Python编码风格建议

三、Python语言规范

1. imports 仅仅用做包和模块的导入,包的导入每个尽量独占一行

2. packages 导入模块尽量使用模块的全路径

  3. Exceptions必须小心使用

  4. Global variables避免使用全局变量

  5. Generator

6. lambda 函数仅仅适用于一行代码能实现的简单函数

  7. True or False尽量使用[],'',{},0,None来隐式表示False


四、Python风格规范

1、代码编排

1 缩进:4个空格实现缩进,尽量不使用Tab,禁止混用Tab和空格

2 行:每行最大长度不超过79,换行可以使用反斜杠()。最好使用圆括号将换行内容括起来,不建议使用“;”

3 空行:类和top-level函数定义之间空两行;类中的方法定义之间空一行;函数内逻辑无关段落之间空一行;其他地方尽量不要再空行。

4 空格:括号内的第一个位置,不要空格。紧靠右括号的位置也不要空格。冒号(:)、逗号(,)、分号(;)之前不要加空格。切片木有参数,不要加空格等

5 括号:对于单元素tuple一定要加,和括号

2、命名规范

    module_name

    package_name

    ClassName

    method_name

    ExceptionName

    function_name

    GLOBAL_CONSTANT_NAME

    global_var_name

    instance_var_name

    function_parameter_name

    local_var_name

3、注释规范

1.块注释,在一段代码前增加的注释。在‘#’后加一空格。段落之间以只有‘#’的行间隔。比如:

    # Description : Module config.    #    # Input : None    #    # Output : None

2. 行注释,在一句代码后加注释。比如:x = x + 1 # Increment x 但是这种方式尽量少使用。

3. 避免无谓的注释。

4、编程建议

1. 字符串拼接,尽量使用join。使用str的方法而不是内置方法。使用startswith或endswith拉检查前缀和后缀

2. 单例对象,尽量使用is 、is not,不要使用==

    3.使用is not而不是not is

4. 使用def来定义函数,而不是将匿名函数赋给某个变量

5. 尽量使代码整齐,简洁

    6.使用isinstance()来判断instance的类型

2、浅谈你对python安全编码的认识,并举例说明



1、图书管理系统是对图书进行录入、借阅的系统,请用django框架实现新增、查看图书的功能,分别写出model.py、urls.py、views.py的逻辑



2、设有一个背包能承受重量s(s>0),又有n(n>=1)件物品,其质量列表为 w = [w1,w2....,wn],要从物品中挑选若干件放入背包,使得放入的图书质量之和正好是s。请设计递归函数f(w,s,n):

当有解时,返回True,并显示所选物品是那些?无解时返回False。提示:[递归之处在于f(w,s-wn,n-1) or f(w,s,n-1)]

python面试题(十)【10】

Python中基本数据结构的操作

 元组列表字典集合

定义    

新增    

更改    

删除    

2.请尽可能列举python列表的成员方法,并给出一下列表操作的答案:

  (1)a=[1, 2, 3, 4, 5], a[::2]=?, a[-2:] =?

(1)1 3 5

(2)4 5


(2) 一行代码实现对列表a中的偶数位置的元素进行加3后求和?


sums = sum(map(lambda x: x + 3, a[1::2]))



  3.List = [-2, 1, 3, -6],如何实现以绝对值大小从小到大将List中内容排序。

sorted(list1,key = abs)

(1) 列表的sort方法和 sorted的区别是什么?


sort是list的方法,改变list对象的顺序,返回值为None

sorted是Python的内置方法,适用iterable对象,返回值是新列表,不影响原来的iterable的顺序


4.有一篇英文文章保存在 a.txt 中,请用python实现统计这篇文章内每个单词的出现频率,并返回出现频率最高的前10个单词及其出现次数(只考虑空格,标点符号可忽略)

from collections import Counter

    c = Counter()

with open('a.txt','r',encoding='utf-8') as f:

    for line in f.readlines():

        words = line.split()

        c1 = Counter(words)

        c.update(c1)

(1)追加需求:引号内元素需要算作一个单词,如何实现?

以"分割,转换成列表,取其奇数分割,其偶数不做处理


5.Python函数中经常有 *args,**kwargs 这两个参数,它们是什么意思,为什么要使用它们?


太简单,就不写啦,哈哈哈哈


6.Python中的变量作用域(变量查找顺序)。


LEGB

local局部变量--->enclosed闭包作用域----> Global全局---->built-in变量


7.下面这段代码的输出结果将是什么?请解释。


# 1 1 1 继承自父类的类属性x,所以都一样,指向同一块内存地址

# 1 2 1更改Child1,Child1的x指向了新的内存地址

# 3 2 3更改Parent,Parent的x指向了新的内存地址


8.描述Python GIL的概念, 以及它对python多线程的影响?编写一个多线程抓取网页的程序,并阐明多线程抓取程序是否可比单线程性能有提升,并解释原因。

Guido的声明:http://www.artima.com/forums/flat.jsp?forum=106&thread=214235

he language doesn't require the GIL -- it's only the CPython virtual machine that has historically been unable to shed it.

Python语言和GIL没有半毛钱关系。仅仅是由于历史原因在Cpython虚拟机(解释器),难以移除GIL。

GIL:全局解释器锁。每个线程在执行的过程都需要先获取GIL,保证同一时刻只有一个线程可以执行字节码。

线程释放GIL锁的情况:

在IO操作等可能会引起阻塞的system call之前,可以暂时释放GIL,但在执行完毕后,必须重新获取GIL

Python 3.x使用计时器(执行时间达到阈值后,当前线程释放GIL)或Python 2.x,tickets计数达到100

Python使用多进程是可以利用多核的CPU资源的。

多线程爬取比单线程性能有提升,因为遇到IO阻塞会自动释放GIL锁

9.Python中如何动态获取和设置对象的属性。

if hasattr(Parent,'x'):

    print(getattr(Parent,'x'))

    setattr(Parent,'x',3)

    print(getattr(Parent,'x'))

10.(前端基础)

(1)用CSS如何隐藏一个元素

dispaly:none

(2)一行CSS实现padding上下左右分别为1px,2px,3px,4px

padding:1 4 2 3

(3)    JavaScript(或jQuery)如何选择一个id为main的容器

$('#main')

(4)    JavaScript(或jQuery)如何选择一个class为menu的容器

$('.menu') 

python面试(十四)【4】 

map(lambda x:x*x,[y for y in range(3)])

[0, 1, 4]


2、下面代码会输出什么?

def f(x, l = [] )

  for i in range(x):

    l.append(i*i)

  print l

f(2)

f(3,[3,2,1])

f(3)

1、[0, 1]

2、[3, 2, 1, 0, 1, 4]

3、[0, 1, 0, 1, 4]

 之一,示例如下:

层级遍历:0 1 2 3 4 5 6 7 8 9

先序遍历:0 1 3 7 8 4 9 2 5 6

中序遍历:7 3 8  1 9 4 0 5 2 6

后序排列:7 8 3 9 4 1 5 6 2 0


class Node(object):

    def __init__(self, data, left=None, right=None):

        self.data = data

        self.left = left

        self.right = right

r为Node类型的根节点

实现函数traverse(r)输出先序遍历结果,输出部分使用print r.data即可

node7 = Node(7)

node8 = Node(8)

node9 = Node(9)

node3 = Node(3,node7,node8)

node4 = Node(4,node9)

node5 = Node(5)

node6 = Node(6)

node1 = Node(1,node3,node4)

node2 = Node(2,node5,node6)

node0 = Node(0,node1,node2)

def traverse(r):

    print(r.data)

    if r.left:

        traverse(r.left)

    if r.right:

        traverse(r.right)


4、有一个3G大小的文件,文件每行一个string,内容为酒店的id和一个图片的名字,使用“t”分割

示例:ht_1023134 + "t" + hidfadsfadsfdfadsf2r234523,jpg

表示的是一个酒店包含的一张图片,统计含有图片数量为[20,无穷大]的酒店id,含有图片数量为[10,20]的酒店id、含有图片数量为[10,5]的酒店id,含有图片数量为[0,5]的酒店id,并将结果输出到文件中

0-5 + “t” + id1 +  “t” + id2 + .....

5-10 + “t” + id1 +  “t” + id2 + .....

10-20 + “t” + id1 +  “t” + id2 + .....

20-无穷大+ “t” + id1 +  “t” + id2 + .....

from collections import Counter

count_dict = {}

cou = Counter()

with open('a.txt', encoding='utf-8') as f:

    for line in f:

        hotel, image = line.split()

        hotel_id = hotel.split('_')[1]

        cou.update({hotel_id,1})

        if hotel_id in count_dict:

            count_dict[hotel_id] += 1

        else:

            count_dict[hotel_id] = 1

del cou[1]

zero_five = ['0-5']

five_ten = ['5-10']

ten_twenty = ['10-20']

twenty_infinite = ['10-去穷大']

for hotel_id,count in count_dict.items():

    if count < 5 :

        zero_five.append(hotel_id)

    elif count < 10 :

        five_ten.append(hotel_id)

    elif count < 20:

        ten_twenty.append(hotel_id)

    else:

        twenty_infinite.append(hotel_id)

with open('b.txt','w',encoding='utf-8') as b:

    b.write('t'.join(zero_five))

    b.write('n')

    b.write('t'.join(five_ten))

    b.write('n')

    b.write('t'.join(ten_twenty))

    b.write('n')

    b.write('t'.join(twenty_infinite))

面试题(十五)【13】

1、请简要描述django-admin.py makemessages的作用

2、Python如何捕获异常,如何在程序执行过程中抛出异常机制?

Python中使用try ... except SomeException as e: ...来捕获异常

raise SomeException("Some Message")来抛出异常

3、什么是lambda函数?它有什么好处?

4、*args和**kwargs的使用方法,请简述一下?

5、简要介绍下python里面的装饰器?

6、Http请求中GET和POST有什么区别?Cookies和Session有什么区别?

7、a = 1,b = 2,不用中间变量交换a和b的值?

b, a = a, b

Python支持不使用中间变量交换两个变量的值


8、编写一个函数删除list里的重复元素,用两种方式实现?

9、请简要概括django测试工具?

10、如何扩展auth_user的字段

11、请给出Profile的实现实例

12、如何替换auth_user

13、django的继承的方式有哪些?


Python面试题(十六)【8】164 

1、取出两个升序数组中的最小的一半的元素组成一个新的升序数组。

map(lambda x, y: x if x < y else y, a, b)


2、用至少2种不同的方式删除一个list里面的重复元素

a = [1, 2, 2, 4, 34, 3, 4, 56, 65, 456, 5, 6456, 456, 54, 45, 6, 464, 564]

# 方法一

new_list3 = list(set(a))

# 方法二

new_list = []

for num in a:

    if num not in new_list:

        new_list.append(num)

# 方法三

dict1 = dict.fromkeys(a)

new_list2 = dict1.keys()


3、利用线程池(10个线程)实现一个并行打印10行信息的程序,打印This is thread xx.(注:xx为线程id)


4、关系型数据库的事务隔离级别有哪些,分别有什么影响?

1、未提交读(Read Uncommitted) 

    直译就是"读未提交",意思就是即使一个更新语句没有提交,但是别的事务可以读到这个改变.这是很不安全的。允许任务读取数据库中未提交的数据更改,也称为脏读。 

2、提交读(Read Committed) 

   直译就是"读提交",可防止脏读,意思就是语句提交以后即执行了COMMIT以后别的事务就能读到这个改变. 只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 

3、可重复读(Repeatable Read): 

   直译就是"可以重复读",这是说在同一个事务里面先后执行同一个查询语句的时候,得到的结果是一样的.在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读 

4、串行读(Serializable) 

   直译就是"序列化",意思是说这个事务执行的时候不允许别的事务并发执行. 完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞


四,隔离级别对事务并发的控制 

下表是各隔离级别对各种异常的控制能力:

丢失更新    脏读    非重复读    二类丢失更新(覆盖更新)    幻像读

未提交读    Y    Y    Y    Y    Y

提交读    N    N    Y    Y    Y

可重复读    N    N    N    N    Y

串行读    N    N    N    N    N


5、请用python编写函数find_string,从文本中搜索并打印内容,要求支持通配符星号和问号。

例子:

>>>find_string('hellonworldn','wor')

['wor']

>>>find_string('hellonworldn','l*d')

['ld']

>>>find_string('hellonworldn','o?')

['or']


6、请为find_string编写单元测试

7、已有一个字典列表,如下:

li = [

    {'id': '1.1', 'content': "14"},

    {'id': '1.2', 'content': "15"},

    {'id': '1.3', 'content': "16"},

    {'id': '1.4', 'content': "17"},

    {'id': '1.5', 'content': "18"},

]

请写一个类:

abc = x()

>>abc['1.1']

14

class x(UserDict):

    def __init__(self):

        super().__init__()

        for dic in li:

            # print(dic)

            self.data.update({dic['id']:dic['content']})

abc = x()

print(abc['1.1'])

8、如何快速对学生的成绩进行评级:(源自Fluent Python)

60分以下评为F

  60-70评为D

  ...

90分以上为A

import bisect

import sys

def grade(score, breakpoint=[60, 70, 80, 90], grades = 'FDCBA'):

    i = bisect.bisect(breakpoint, score)

    return grades[i]

if __name__ == '__main__':

    level = grade(64)

    print(level)


面试问题总结【25】

1、WebSocket相关问题

 请简单说明一下WebSocket的握手过程

1、client发送请求,请求头携带Sec-WebSocket-Key

2、server收到请求,解析请求头部信息,拿到Sec-WebSocket-Key

3、服务器端将magic_string(258EAFA5-E914-47DA-95CA-C5AB0DC85B11)和Sec-WebSocket-Key进行sha-1加密,将hash结果进行base64编码

4、将编码结果放在响应头部Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=,返回给客户端,连接完成

 Tornado如何处理WebSocket

1、Tornado的Controller匹配到响应的请求url,将其转发给处理的Handler,比如ChatHandler

2、ChatHandler需要继承tornado.websocket.WebSocketHandler

3、ChatHandler必须实现

open方法:客户端连接成功,需要执行的方法

on_message方法:客户端向服务端发送消息,执行的方法

on_close方法:客户端关闭时,执行的方法

2、能简单说说线程、进程和协程吗?

   1、线程:最小的调度单位

2、协程:用户自定义的线程切换

3、进程:

3、Http和Https的区别?

4、对于TCP/IP协议熟悉吗?三次握手,四次挥手?能简单说一下七层模型吗?

TCP/IP协议,是网络通信协议,又称传输控制协议/因特网互联协议。定义了电子设备如何连入互联网,以及数据如何在互联网相互传输的标准。


所谓三次握手就是建立TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立。

(1)第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。

  (2)第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。

  (3)第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。

所谓四次挥手,就是指断开一个TCP连接时,客户端和服务器总共发送4个包来确认连接的断开。 

由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭,上图描述的即是如此。

 (1)第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。

  (2)第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。

 (3)第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。

  (4)第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。

七层模型,即OSI(Open System Interconnect),开放式系统互联


5、能简单说一下你了解的socket吗?


6、Python的GIL(全局解释器锁)

7、Python的with语句?优点?如何实现?

8、Python的单例模式?

9、Python垃圾回收机制?

10、Python的生成器和迭代器?

11、python的装饰器?

12、Python的with语句的使用?

13、Python

版权声明:本文来源简书,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://www.jianshu.com/p/60ee510bf72b
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-01-09 08:31:35
  • 阅读 ( 1488 )
  • 分类:面试题

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢