赞
踩
1.Python****是如何进行内存管理的?
答:从三个方面来说,一对象的引用计数机制,二垃圾回收机制,三内存池机制
一、对象的引用计数机制
Python内部使用引用计数,来保持追踪内存中的对象,所有对象都有引用计数。
引用计数增加的情况:
1,一个对象分配一个新名称
2,将其放入一个容器中(如列表、元组或字典)
引用计数减少的情况:
1,使用del语句对对象别名显示的销毁
2,引用超出作用域或被重新赋值
sys.getrefcount( )函数可以获得对象的当前引用计数
多数情况下,引用计数比你猜测得要大得多。对于不可变数据(如数字和字符串),解释器会在程序的不同部分共享内存,以便节约内存。
二、垃圾回收
1,当一个对象的引用计数归零时,它将被垃圾收集机制处理掉。
2,当两个对象a和b相互引用时,del语句可以减少a和b的引用计数,并销毁用于引用底层对象的名称。然而由于每个对象都包含一个对其他对象的应用,因此引用计数不会归零,对象也不会销毁。(从而导致内存泄露)。为解决这一问题,解释器会定期执行一个循环检测器,搜索不可访问对象的循环并删除它们。
三、内存池机制
Python提供了对内存的垃圾收集机制,但是它将不用的内存放到内存池而不是返回给操作系统。
1,Pymalloc机制。为了加速Python的执行效率,Python引入了一个内存池机制,用于管理对小块内存的申请和释放。
2,Python中所有小于256个字节的对象都使用pymalloc实现的分配器,而大的对象则使用系统的malloc。
3,对于Python对象,如整数,浮点数和List,都有其独立的私有内存池,对象间不共享他们的内存池。也就是说如果你分配又释放了大量的整数,用于缓存这些整数的内存就不能再分配给浮点数。
2.什么是lambda函数?它有什么好处?
答:lambda 表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数
lambda函数:首要用途是指点短小的回调函数
lambda [arguments]:expression
>>> a=lambdax,y:x+y
>>> a(3,11)
3.Python里面如何实现tuple和list****的转换?
答:直接使用tuple和list函数就行了,type()可以判断对象的类型
4.请写出一段Python代码实现删除一个list****里面的重复元素
答:
1,使用set函数,set(list)
2,使用字典函数,
>>>a=[1,2,4,2,4,5,6,5,7,8,9,0]
>>> b={}
>>>b=b.fromkeys(a)
>>>c=list(b.keys())
>>> c
3,使用if语句
a=[1,1,2,2,3,4]
b=[]
for x in a:
if x not in b:
b.append(x)
5.编程用sort****进行排序,然后从最后一个元素开始判断
a=[1,2,4,2,4,5,7,10,5,5,7,8,9,0,3]
a.sort()
last=a[-1]
for i inrange(len(a)-2,-1,-1):
if last==a[i]:
del a[i]
else:last=a[i]
print(a)
6.Python****里面如何拷贝一个对象?(赋值,浅拷贝,深拷贝的区别)
答:赋值(=),就是创建了对象的一个新的引用,修改其中任意一个变量都会影响到另一个。
浅拷贝:创建一个新的对象,但它包含的是对原始对象中包含项的引用(如果用引用的方式修改其中一个对象,另外一个也会修改改变){1,完全切片方法;2,工厂函数,如list();3,copy模块的copy()函数}
深拷贝:创建一个新的对象,并且递归的复制它所包含的对象(修改其中一个,另外一个不会改变){copy模块的deep.deepcopy()函数}
1.垃圾回收机制有那些?
答:引用计数、标记-清除、标记-缩并、节点拷贝、分代回收
2.迭代器和生成器是怎么实现的?
答:迭代器是一个带有状态的对象,在调用next()方法的时候返回容器中的下一个值,然后等待下一次被调用;生成器是一种特殊的迭代器,必须包含yeild语句,yeild语句返回一个生成器对象,只有显示或隐式的调用next()方法时,才会真正执行生成器中的代码。
7.介绍一下except****的用法和作用?
答:try…except…except…[else…][finally…]
执行try下的语句,如果引发异常,则执行过程会跳到except语句。对每个except分支顺序尝试执行,如果引发的异常与except中的异常组匹配,执行相应的语句。如果所有的except都不匹配,则异常会传递到下一个调用本代码的最高层try代码中。
try下的语句正常执行,则执行else块代码。如果发生异常,就不会执行
如果存在finally语句,最后总是会执行。
8.Python中pass****语句的作用是什么?
答:pass语句不会执行任何操作,一般作为占位符或者创建占位程序,whileFalse:pass
**9.介绍一下Python下range()**函数的用法?
答:列出一组数据,经常用在for _ in range()循环中
10.如何用Python****来进行查询和替换一个文本字符串?
答:可以使用re模块中的sub()函数或者subn()函数来进行查询和替换,
格式:sub(replacement, string[,count=0])(replacement是被替换成的文本,string是需要被替换的文本,count是一个可选参数,指最大被替换的数量)
>>> import re
>>>p=re.compile(‘blue|white|red’)
>>>print(p.sub(‘colour’,'blue socks and red shoes’))
colour socks and colourshoes
>>>print(p.sub(‘colour’,'blue socks and red shoes’,count=1))
colour socks and redshoes
subn()方法执行的效果跟sub()一样,不过它会返回一个二维数组,包括替换后的新的字符串和总共替换的数量
**11.Python里面match()和search()**的区别?
答:re模块中match(pattern,string[,flags]),检查string的开头是否与pattern匹配。
re模块中research(pattern,string[,flags]),在string搜索pattern的第一个匹配值。
>>>print(re.match(‘super’, ‘superstition’).span())
(0, 5)
>>>print(re.match(‘super’, ‘insuperable’))
None
>>>print(re.search(‘super’, ‘superstition’).span())
(0, 5)
>>>print(re.search(‘super’, ‘insuperable’).span())
(2, 7)
**12.用Python匹配HTML tag的时候,<.*>和<.*?>**有什么区别?
答:术语叫贪婪匹配( <.> )和非贪婪匹配(<.?> )
例如:
test
<.*> :
test
<.*?> :
13.Python****里面如何生成随机数?
答:random模块
随机整数:random.randint(a,b):返回随机整数x,a<=x<=b
random.randrange(start,stop,[,step]):返回一个范围在(start,stop,step)之间的随机整数,不包括结束值。
随机实数:random.random( ):返回0到1之间的浮点数
random.uniform(a,b):返回指定范围内的浮点数。
14.有没有一个工具可以帮助查找python的bug****和进行静态的代码分析?
答:PyChecker是一个python代码的静态分析工具,它可以帮助查找python代码的bug, 会对代码的复杂度和格式提出警告
Pylint是另外一个工具可以进行codingstandard检查
15.如何在一个function****里面设置一个全局的变量?
答:解决方法是在function的开始插入一个global声明:
def f()
global x
**16.**单引号,双引号,三引号的区别
答:单引号和双引号是等效的,如果要换行,需要符号(),三引号则可以直接换行,并且可以包含注释
如果要表示Let’s go 这个字符串
单引号:s4 = ‘Let\’s go’
双引号:s5 = “Let’s go”
s6 = ‘I realy like“python”!’
这就是单引号和双引号都可以表示字符串的原因了
17**、Python中核心的数据类型?**
答:数值型(整形int,浮点型,float,bool类型,空值None),字符串,列表,元组,字典,集合
其中可变的:列表,字典,集合
不可变的:数值型,字符串,元组
18**、一行代码实现对列表a中的偶数位置元素进行加3后求和?**
答:sums = sum(map(lambda x : x+3, a[1::2]))
19**、List = [-2, 1, 3, -6],如何实现以绝对值大小从小到大将** List 中内容排序**。**
答:sorted(List,key=abs)
追加需求:列表的sort方法和sorted的区别是什么?
答:sort()是list的方法,改变list对象的顺序, 默认从小到大排序, 默认属性 reverse=Flase
sorted是Python的内置方法,使用iterable对象,返回值是新列表,不影响原来的iterable的顺序
20**、Python中的变量作用域****(变量查找顺序)****?**
答:LEGB
local局部变量–>enclosed闭包作用域—>Global全局变量—>built-in变量
21**、描述Python GIL的概念,以及它对Python多线程的影响?**
答: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锁
22**、用CSS如何隐藏一个元素?**
答、dispaly:none
23**、模块有很多属性和方法,现用一句话打印出os模块下所有的方法名**
答:Import os
Dir(os)
24**、****a = {“name”:”jack”,”age”:30,”skill”:”python”}**现在需要生成字符串:
name=jack|age=30|skill=python
请用一行代码实现:
答:s = ‘|’.join([str(x)+’=’+str(a[x]) for x in a])
25**、mysql查询大小写敏感吗?**
不区分关键字大小写
26**、NOW() **和**CURRENT_DATE()**有什么区别?
Now()获取当前时期+时间
CURRENT_DATE()获取当前日期
27**、说一说你知道的HTTP的状态码?**
答:
2开头 (请求成功)表示成功处理了请求的状态代码。
· 200 (成功) 服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。
· 201 (已创建) 请求成功并且服务器创建了新的资源。
· 202 (已接受) 服务器已接受请求,但尚未处理。
· 203 (非授权信息) 服务器已成功处理了请求,但返回的信息可能来自另一来源。
· 204 (无内容) 服务器成功处理了请求,但没有返回任何内容。
· 205 (重置内容) 服务器成功处理了请求,但没有返回任何内容。
· 206 (部分内容) 服务器成功处理了部分 GET 请求。
3开头 (请求被重定向)表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。
· 300 (多种选择) 针对请求,服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。
· 301 (永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
· 302 (临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
· 303 (查看其他位置) 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。
· 304 (未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。
· 305 (使用代理) 请求者只能使用代理访问请求的网页。 如果服务器返回此响应,还表示请求者应使用代理。
· 307 (临时重定向) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
4开头 (请求错误)这些状态代码表示请求可能出错,妨碍了服务器的处理。
· 400 (错误请求) 服务器不理解请求的语法。
· 401 (未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。
· 403 (禁止) 服务器拒绝请求。
· 404 (未找到) 服务器找不到请求的网页。
· 405 (方法禁用) 禁用请求中指定的方法。
· 406 (不接受) 无法使用请求的内容特性响应请求的网页。
· 407 (需要代理授权) 此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。
· 408 (请求超时) 服务器等候请求时发生超时。
· 409 (冲突) 服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息。
· 410 (已删除) 如果请求的资源已永久删除,服务器就会返回此响应。
· 411 (需要有效长度) 服务器不接受不含有效内容长度标头字段的请求。
· 412 (未满足前提条件) 服务器未满足请求者在请求中设置的其中一个前提条件。
· 413 (请求实体过大) 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。
· 414 (请求的 URI 过长) 请求的 URI(通常为网址)过长,服务器无法处理。
· 415 (不支持的媒体类型) 请求的格式不受请求页面的支持。
· 416 (请求范围不符合要求) 如果页面无法提供请求的范围,则服务器会返回此状态代码。
· 417 (未满足期望值) 服务器未满足”期望”请求标头字段的要求。
5开头(服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。
· 500 (服务器内部错误) 服务器遇到错误,无法完成请求。
· 501 (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。
· 502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。
· 503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。
· 504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。
· 505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。
28**、简述http和https的区别****?**
答:https就是http和TCP之间有一层SSL层,这一层的实际作用是防止钓鱼和加密。防止钓鱼通过网站的证书,网站必须有CA证书,证书类似于一个解密的签名。另外是加密,加密需要一个密钥交换算法,双方通过交换后的密钥加解密。
HTTPS和HTTP的区别:
https协议需要到ca申请证书,一般免费证书很少,需要交费。
http是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议。
http和https使用的是完全不同的连接方式用的端口也不一样,前者是80,后者是443。
http的连接很简单,是无状态的。
HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全。
29**、你正在开发注册页面,用户会输入一个邮箱,请写出校验邮箱合法性的正则表达式**
答:
1+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+$
30**、***args,*kwargs***是什么意思?
答:*args表示任何多个无名参数,它是一个tuple
**kwargs表示关键字参数,它是一个dict
31**、多进程中如果有一个进程死掉,怎么发现和处理**
答,用log日志模块,监控,或在每个进程下面判断用print打印。
32**、写一个生成器** 简单的生成器函数
defrev_str(my_str):
length=len(my_str)
fori in range(length-1,-1,-1):
yieldmy_str[i]
for char in rev_str(“hello”):
print(char) #olleh
33**、MySQL mongodbredis数据库的端口都是什么?**
答:MySQL:3306 mongodb:28017 redis:6379
34、git和svn****之间的区别
答:
(1).GIT是分布式的,SVN不是:
这是GIT和其它非分布式的版本控制系统,例如SVN,CVS等,最核心的区别。如果你能理解这个概念,那么你就已经上手一半了。需要做一点声明,GIT并不是目前第一个或唯
一的分布式版本控制系统。还有一些系统,例如Bitkeeper, Mercurial等,也是运行在分布式模式上的。但GIT在这方面做的更好,而且有更多强大的功能特征。
GIT跟SVN一样有自己的集中式版本库或服务器。但,GIT更倾向于被使用于分布式模式,也就是每个开发人员从中心版本库/服务器上chect out代码后会在自己的机器上克隆
一个自己的版本库。可以这样说,如果你被困在一个不能连接网络的地方时,就像在飞机上,地下室,电梯里等,你仍然能够提交文件,查看历史版本记录,创建项目分支,
等。对一些人来说,这好像没多大用处,但当你突然遇到没有网络的环境时,这个将解决你的大麻烦。
同样,这种分布式的操作模式对于开源软件社区的开发来说也是个巨大的恩赐,你不必再像以前那样做出补丁包,通过email方式发送出去,你只需要创建一个分支,向项目
团队发送一个推请求。这能让你的代码保持最新,而且不会在传输过程中丢失。GitHub.com就是一个这样的优秀案例。
(2).GIT把内容按元数据方式存储,而SVN是按文件:
所有的资源控制系统都是把文件的元信息隐藏在一个类似.svn,.cvs等的文件夹里。如果你把.git目录的体积大小跟.svn比较,你会发现它们差距很大。因为,.git目录是处于
你的机器上的一个克隆版的版本库,它拥有中心版本库上所有的东西,例如标签,分支,版本记录等。
(3).GIT分支和SVN的分支不同:
分支在SVN中一点不特别,就是版本库中的另外的一个目录。如果你想知道是否合并了一个分支,你需要手工运行像这样的命令svnpropgetsvn:mergeinfo,来确认代码是否
被合并。感谢Ben同学指出这个特征。所以,经常会发生有些分支被遗漏的情况。
然而,处理GIT的分支却是相当的简单和有趣。你可以从同一个工作目录下快速的在几个分支间切换。你很容易发现未被合并的分支,你能简单而快捷的合并这些文件。
(4).GIT没有一个全局的版本号,而SVN有:
目前为止这是跟SVN相比GIT缺少的最大的一个特征。你也知道,SVN的版本号实际是任何一个相应时间的源代码快照。我认为它是从CVS进化到SVN的最大的一个突破。因为GIT
和SVN从概念上就不同,我不知道GIT里是什么特征与之对应。如果你有任何的线索,请在评论里奉献出来与大家共享。
更新:有些读者指出,我们可以使用GIT的SHA-1来唯一的标识一个代码快照。这个并不能完全的代替SVN里容易阅读的数字版本号。但,用途应该是相同的。
(5).GIT的内容完整性要优于SVN:
GIT的内容存储使用的是SHA-1哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏。这里有一个很好的关于GIT内容完整性的讨论
35**、Django采用的是什么框架模式****?**
答:django是一种重量级的python web框架,采用的mtv框架模式
Tornado 是一种轻量级的框架,处理高并发,其拥有异步非阻塞IO的处理方式。
36**、简单说一下IO多路复用**
答:多路复用IO也是阻塞IO,只是阻塞的方法是select/poll/epoll。select/epoll的好处就在于单个process就可以同时处理多个网络连接的IO。它的基本原理是select/epoll这
个函数会不断轮询所负责的IO操作,当某个IO操作有数据到达时,就通知用户进程。然后由用户进程去操作IO
37**、对Flask的了解?**
Flask 是一种具有平缓学习曲线和庞大社区支持的微框架,利用它可以构建大规模的web应用。是搭建社区平台的神器之一。
利用它可以构建大规模的web应用。学习上手Flask非常轻松,但要深入理解却并不容易。
使用MVC(模型-视图-控制器)架构
37**、C语言下的int占多少字节?64位呢?**
64位系统下C语言中int还是占4字节,32位,与32位系统中没有区别!
38**、怎么判断session过期**
(1).session其实就是一个Map,键=值对,通过session.getAttribute(“name”);获得session中设置的参数
(2).session的过期时间是从什么时候开始计算的?是从一登录就开始计算还是说从停止活动开始计算?
答:从session不活动的时候开始计算,如果session一直活动,session就总不会过期。
从该Session未被访问,开始计时; 一旦Session被访问,计时清0;
(3).设置session的失效时间
(4).request.getSeesion(boolean)方法,一下子让我恍然大悟。这个方法里面传了一个boolean值,这个值如果是true,那么如果当前的request的session不可用,那么就
创建新的会话,如果存在就返回当前的会话。如果参数是false,那么在request的当前会话不存在的时候就返回null。
39**、什么是进程,什么是线程?**
进程:是资源分配的最小单位,创建和销毁开销较大,程序文件的一次执行;
线程:是CPU调度的最小单位,开销小,切换速度快;
计算CPU密集型程序推荐使用多进程
IO密集型程序适合使用多线程
40**、Mysql可以有哪些优化**
* 增加索引
* 少用 * in not in
* 选择合适的引擎INNODB 写操作 MYISAM读操作
* 尽量避免使用null 条件判断尽量少or
(1)、选取最适用的字段属性
MySQL可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快。因此,在创建表的时候,为了获得更好的性能,我们可以将表
中字段的宽度设得尽可能小。
(2)、使用连接(JOIN)来代替子查询(Sub-Queries)
(3)、使用联合(UNION)来代替手动创建的临时表
(4)、事务
BEGIN; INSERT INTO salesinfo SET CustomerID=14; UPDATE inventory SET Quantity=11 WHERE item=‘book’; COMMIT;
事务的另一个重要作用是当多个用户同时使用相同的数据源时,它可以利用锁定数据库的方法来为用户提供一种安全的访问方式,这样可以保证用户的操作不被其它的用户所
干扰。
(5)、锁定表
LOCK TABLE inventory WRITE SELECT Quantity FROM inventory WHERE Item=‘book’;
…
UPDATE inventory SET Quantity=11 WHERE Item=‘book’; UNLOCKTABLES
(6)、使用外键
(7)、使用索引
索引是提高数据库性能的常用方法,它可以令数据库服务器以比没有索引快得多的速度检索特定的行,尤其是在查询语句当中包含有MAX(),MIN()和ORDERBY这些命令的时候,
性能提高更为明显。
(8)、优化的查询语句
41.Python中split和Join 函数的用法与区别
答:
.join()
join将 容器对象 拆分并以指定的字符将列表内的元素(element)连接起来,返回字符串(注:容器对象内的元素须为字符类型)
1 2 3 4 | >>> a = [‘no’,‘pain’,‘no’,‘gain’] >>> '_ '.join(a) ‘no_pain_no_gain’ >>> |
---|---|
注:容器对象内的元素须为字符类型
1 2 3 4 5 6 7 | >>> b = [‘I’,‘am’,‘no’,1] >>> ‘’.join(b) Traceback (most recent call last): File “<pyshell#32>”, line 1, in '’.join(b) TypeError: sequence item 3: expected string, int found >>> |
---|---|
dict是以Key值作连接
1 2 3 4 | >>> L = {‘p’:‘P’,‘y’:‘Y’,‘t’:‘T’,‘h’:‘H’,‘o’:‘O’,‘n’:‘N’} >>> ‘_’.join(L) ‘h_o_n_p_t_y’ #dict 的无序性,使元素随机连接。set 同理 >>> |
---|---|
.split()
与join相反,split以指定的字符将字符串分割为单个元素(字符类型)并加入list中,返回一个List
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | >>> a = ‘no_pian_no_gain’ >>> a.split(’’) [‘no’, ‘pian’, ‘no’, ‘gain’] >>> split是可以设定切割多少个字符的 >>> a = ‘no_pian_no_gain’ >>> a.split(’’,2) [‘no’, ‘pian’, ‘no_gain’] >>> a.split(’’,1) [‘no’, ‘pian_no_gain’] >>> a.split(’’,0) [‘no_pian_no_gain’] >>> a.split(’_’,-1) [‘no’, ‘pian’, ‘no’, ‘gain’] >>> |
---|---|
可见split(’’)与split(’’,-1)返回的结果是一致的
42、Python的核心数据类型?
答:数值型(整型,浮点型,复数,布尔型(bool))
字符串str
列表list
元组 tuple
集合 set
字典 dict
不可变的数据类型: 数值型,字符串,元组
可变的类型: 列表 字典 集合
43、简述pass语句,return语句,break语句,continue语句?
答:pass语句,用来填充语法空白
return语句,结束当前函数的执行,返回到函数调用的地方,同时返回一个对象的引用关系
break语句,用于循环中,用来终止当前循环语句的执行
continue 用于循环语句中,不再执行本次循环内continue之后的语句,重新开始下一次循环
**44、**简述深拷贝和浅拷贝的区别?
答:
1、浅拷贝:
使用copy.copy,它可以进行对象的浅拷贝(shallow copy),它复制了对象,但对于对象中的元素,依然使用引用(换句话说修改拷贝对象元素,则被拷贝对象元素也被修改
2、深拷贝:
使用copy.deepcopy,它可以进行深拷贝,不仅拷贝了对象,同时也拷贝了对象中的元素,获得了全新的对象,与被拷贝对象完全独立,但这需要牺牲一定的时间和空间。
45、如何在function****中设置一个全局变量
答:使用global修饰变量名
46**、描述yield使用场景****?**
答:带有yield的函数不再是一个普通的函数,Python解释器会其视为一个 generator,所以yield的作用就是把一个函数变成一个生成器
46、生成1-10****之间的随机整数
答: import random
random.randint(1, 11)
47、什么是单例,怎么理解单例?
答:最简单的单例就是一个模块:
Class foo(object):
def fin(self):
Pass
A=foo()
单例模式(SingLetonPattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在,当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场
把你的单例的代码保存在一个py文件当中,要使用时,直接在本文件中导入其他文件的对象,这个对象即是单例模式的对象
**48、**什么是多态?
答:多态性是指具有不同功能的函数可以使用相同的函数名,这样就可以用一个 函数名调用不同内容的函数,在面对对象方法中一般是这样表述多态性:向 不同的对象发送同一条消息,不同的对象在接收时会产生不同的行为(即方 法)。也就是说,每个对象可以用自己的方式去响应共同的消息。所谓消息, 就是调用函数,不同的行为就是指不同的实现,即执行不同的函数
**49、**用自己的话来讲述什么是面向对象编程
答:面向对象的程序设计语言必须有描述对象及其相互之间关系的语言成分。这 些程序设计语言可以归纳为以下几类:系统中一切事物皆为对象;对象是属性及其操作的封装体;对象可按其性质划分为类,对象成为类的实例;实例 关系和继承关系是对象之间的静态关系;消息传递是对象之间动态联系的唯 一形式,也是计算的唯一形式;方法是消息的序列。
**50、**python2 和 python3 的区别
答:Py3.0运行 pystone benchmark的速度比Py2.5慢30%。Guido认为Py3.0有极大的优化 空间,在字符串和整形操作上可
以取得很好的优化结果。
Py3.1性能比Py2.5慢15%,还有很大的提升空间。
2.编码
Py3.X源码文件默认使用utf-8编码,这就使得以下代码是合法的:
>>> 中国 = ‘china’
>>>print(中国)
china
\3. 语法
1)去除了<>,全部改用!=
2)去除``,全部改用repr()
3)关键词加入as 和with,还有True,False,None
4)整型除法返回浮点数,要得到整型结果,请使用//
5)加入nonlocal语句。使用noclocal x可以直接指派外围(非全局)变量
1、类方法,静态方法区别
答:一、先是在语法上面的区别:
1、静态方法不需要传入self参数,类成员方法需要传入代表本类的cls参数;
2、静态方法是无妨访问实例变量和类变量的,类成员方法无法访问实例变量但是可 以访问类变量
二、使用的区别:
由于静态方法无法访问类属性,实例属性,相当于一个相对独立的方法,跟类其实并 没有什么关系。这样说来,静态方法就是在类的作用域里的函数而已。
2、登录一个网站发生的过程,越详细越好,
1、利用DNS协议进行域名解析
2、建立tcp协议三次握手过程
3、?客户端发出访问网站相应页面请求(发出http协议请求报文)
4、系统架构部署情况
5、服务端发出响应访问页面的请求信息(发出http协议响应报文)
6、断开tcp协议四次挥手过程
5 说一下HTTP协议
答:HTTP协议,全称HyperText Transfer Protocol,中文名为超文本传输协议,是互联网中最常用的一种网络协议。HTTP的重要应用之一是WWW服务。设计HTTP协议最初目的
就是提供一种发布和接收HTML(一种页面标记语言)页面的方法(请求返回)。
HTTP协议是互联网上常用的通信协议之一。它有很多的应用,但最流行的就是用于Web浏览器和Web服务器之间的通信,即WWW应用或称Web应用。
WWW,全称World Wide Web,常称为Web,中文译为“万维网”。它是目前互联网上最受用户欢迎的信息服务形式。HTTP协议的WWW服务应用的默认端口为80(端口的概念),
另外的一个加密的WWW服务应用https的默认端口为443,主要用于网银,支付等和钱相关的业务。当今,HTTP服务,WWW服务,Web服务三者的概念已经混淆了,都是指当下最常见的网站服务应用。
6 MySQL如何优化
1.优化索引、SQL语句、分析慢查询;
2.设计表的时候严格按照数据库的设计范式来设计数据库;
3.我们还可以将我们的业务架构进行缓存,静态化和分布式;
4.不用全文索引,使用Xunsearch,ES或者云服务器上的索引;
5.如果效率还是不够好,可以采用主从方式将数据读写分离;
6.可以加上memcached缓存,将经常被访问到但不经常变化的数据放至memcached缓存服务器里面,这样的话能够节约磁盘I/O;
7.还可以优化硬件,在硬件层面,我们可以使用更好的一些硬盘(固态硬盘),使用一些磁盘阵列技术(raid0,raid1,raid5)?
- raid0:最简单的(两块硬件相加100G+100G=200G)?
- raid1:镜像卷,把同样的数据下两份。可以随即从A/B里面读取,效率更高,硬盘坏了一块数据也不会丢失;?
- raid5:3块硬盘,坏了一块,另外两块也能工作。
8.如果还是慢,先不要切分表,可以使用MySQL内部自带的表分区技术,将数据分成不同的文件,这样能够让磁盘在读取的时候效率更高;
9.可以做垂直分表,将不经常用读的数据放到另外一个表里去(节约磁盘I/O);
10.数据量特别大,我们优化起来会很困难,这时可以使用数据库中间件的方式,将数据进行分库分表分机器。(原理:数据路由);
11.此外,还可以采用一些更快的存储方式,例如NoSQL存储一些我们需要经常访问到的数据(数据库取出来后,再到NoSQL中取出一些其他数据);
12.此外还有一些表引擎选择,参数优化还有些相关的小技巧都是优化MySQL的方式;
一、选择题
\1. 下列哪个语句在Python中是非法的?(B)
A.x=y=z=1 B. x=(y=z+1)
C. x,y=y,x D. x+=y
\2. 下面哪个不是Python合法的标识符(B)
A . int32 B. 40XL C.self D. name
3 python不支持的数据类型(A)
A .char B.int C.float D. list
\4. python序列类型不包括(C)
A.列表 B.字符串 C.字典 D.元组
\5. 下列不是元组类型的是(C)
A.a=(1,2) B. a=tuple([1,2]) C . a=(1) D. a=”1”,”2”,”3”,”4”
\6. 下列等式中输出为False的是(C)
A. 1+1 is 2 B. 999+1 is 1000 C. 2.03.0 ==3.02.0 D. type(bool)==type(int)
\7. 有两个元祖t1=(1,2),t2=(3,[4]),下列操作有误的是(B)
A. t3=t1+t2 B. t2[0]=5 C. t2[1].append(5) D. t1[:5]
8.下列哪种捕获异常的方式是错误的(D)
A. try….exxept…else B. try….finally…
C. try….exxept… D. try….raise
二、填空题
9.请填写下列方法运行的代码:
def f(x,l=[]):
fori in range(x):l.append(i*i)
print(l)
print(f(3,[3,2,1]))的结果是[3, 2, 1, 0, 1, 4]
None
print(f(3))的结果是[0, 1, 4]
None
10.如何将字符串str=”hello world”反向输出,请用最简单最简洁的语句输出:str[::-1]
11.有一个列表a=[i for i in range(10)]请写出下列代码的输出结果
sums=sum(map(lambda x: x+3,a[1::2]))
print(sums)—40
12.写出下列函数调用结果:
my_list=[lambda:i for i in range(5)]
for l in my_list:print(l())
结果是(换行用\t)4\t4\t\4\t4\t4
13.有一个列表b=[2,4,5,6]执行了下列操作
fori in b:
if not i%2:
b.remove(i)
print(b)结果是[4,5]
三、简答题
14.详细说说tuple、list、dict的用法,它们的特点
列表,元组,字典,都是可迭代对象
列表和元组都是序列,列表是可变的序列, 元组是不可变的序列;列表可以通过索引改变列表的元素,元组不可以;列表可以通过切片赋值插入和删除数据,也可以改变数据,元组不可以
字典是可变的容器,字典可以存储任意类型的数据;字典中的数据都是用键进行索引的;字典的存储是无序的;字典中的数据是以键-值(key-value)对的形式进行存储的;字典的键不能重复,且只能用不可变类型作为字典的键。
15.用自己的话说明迭代器和生成器,它们之间的关系
迭代器:指的是一个重复的过程,每一次重复称为一次迭代,并且每一次重复的结果是下一次重复的初始值
生成器:只要在函数体内出现yield关键字,那么再执行函数就不会执行函数代码,会得到一个结果,该结果就是生成器
16.什么是lambda函数?它有什么好处
lambda 表达式(又称匿名函数)
作用:创建一个匿名函数对象,同def类似,但不提供函数名
语法说明:
\1. lambda 只是一个表达式 ,它用来创建一个函数对象
\2. 当lambda表达式执行时,返回的是冒号(:)后的表达式的值
\3. lambda表达式创建的函数只能包含一条语句
\4. lambda比函数简单,且可以随时创建和销毁,有利于减少程序的偶合度
17.Python里赋值(=),浅拷贝,深拷贝的区别
答:赋值(=),就是创建了对象的一个新的引用,修改其中任意一个变量都会影响到另一个。浅拷贝:创建一个新的对象,但它包含的是对原始对象中包含项的引用(如果用引用的方式修改其中一个对象,另外一个也会修改改变){1,完全切片方法;2,工厂函数,如 list();3,copy 模块的 copy()函数} 深拷贝:创建一个新的对象,并且递归的复制它所包含的对象(修改其中一个,另外一个不会改变){copy 模块的deep.deepcopy()函数}
18.观察输出,用自己的话解释*args,**kwargs这两个参数是什么意思,我问为什么使用它?
def func(*args,**kwargs):
print(args,kwargs)
l=[1,2,3]
t=(4,5,6)
d={‘a’:7,‘b’:8,‘c’:9}
func(1,2,3)#(1, 2, 3) {}
func(a=1,b=2,c=3)#() {‘a’: 1, ‘c’: 3, ‘b’: 2}
func=(1,2,3,a=1,b=2,c=3) #(1,2,3) {‘a’:1,‘c’:3,‘b’:2}
func(*l,**d)#(1, 2, 3) {‘a’: 7, ‘c’: 9, ‘b’: 8}
func(l,2,*t)#([1, 2, 3], 2, 4, 5, 6) {}
func(q=‘winning’,**d)#() {‘a’: 7, ‘c’: 9, ‘b’: 8, ‘q’: ‘winning’}
答案:如果我们不确定要往函数中传入多少个参数,或者我们想往函数中以列表和元组的形式传参数时,那就使要用args;如果我们不知道要往函数中传入多少个关键词参数,或者想传入字典的值作为关键词参数时,那就要使用**kwargs。args和kwargs这两个标识符是约定俗成的用法,你当然还可以用bob和**billy,但是这样就并不太妥。
四、编程题
19.将一个正整数分解质因数。例如输入90,打印90=233*5
n = num = int(input(‘请输入一个数字:’)) #用num保留初始值
f = [] #存放质因数的列表
for j in range(int(num/2)+1): #判断次数仅需该数字的一半多1次
fori in range(2, n):
t = n % i #i不能是n本身
if t == 0: #若能整除
f.append(i) #则表示i是质因数
n = n//i #除以质因数后的n重新进入判断,注意应用两个除号,使n保持整数
break #找到1个质因数后马上break,防止非质数却可以整除的数字进入质因数列表
if len(f) == 0: #若一个质因数也没有
print(‘该数字没有任何质因数。’)
else: #若至少有一个质因数
f.append(n) #此时n已被某个质因数整除过,最后一个n也是其中一个质因数
f.sort() #排下序
print(’%d=%d’ % (num, f[0]), end=’’)
fori in range(1,len(f)):
print(’*%d’ % f[i], end=’’)
20.编写一个队列类Queue(先进先出),实现队列enqueue,出列dequeue,
队列有多少个元素size,添加一个队列extend,清空队列clear
是否为空isEmpty,打印全部元素等方法showinfo(该队列可以初始时赋值)
1、 解释什么是栈溢出,在什么情况下可能出现
2、 简述CPython的内存管理机制
答:从三个方面来说,一对象的引用计数机制,二垃圾回收机制,三内存池机制一、对象的引用计数机制 Python 内部使用引用计数,来保持追踪内存中的对象,所有对象都有引用计数。引用计数增加的情况: 1,一个对象分配一个新名称 2,将其放入一个容器中(如列表、元组或字典)引用计数减少的情况: 1,使用 del 语句对对象别名显示的销毁 2,引用超出作用域或被重新赋值sys.getrefcount( )函数可以获得对象的当前引用计数多数情况下,引用计数比你猜测得要大得多。对于不可变数据(如数字和字符串),解释器会在程序的不同部分共享内存,以便节约内存。二、垃圾回收 1,当一个对象的引用计数归零时,它将被垃圾收集机制处理掉。 2,当两个对象 a 和 b 相互引用时,del 语句可以减少 a 和 b 的引用计数,并销毁用于引用底层对象的名称。然而由于每个对象都包含一个对其他对象的应用, Python 开发学院整理-面试题 18-AID 因此引用计数不会归零,对象也不会销毁。(从而导致内存泄露)。为解决这一问题,解释器会定期执行一个循环检测器,搜索不可访问对象的循环并删除它们。三、内存池机制 Python 提供了对内存的垃圾收集机制,但是它将不用的内存放到内存池而不是返回给操作系统。 1,Pymalloc机制。为了加速 Python 的执行效率,Python 引入了一个内存池机制,用于管理对小块内存的申请和释放。 2,Python 中所有小于 256 个字节的对象都使用pymalloc实现的分配器,而大的对象则使用系统的malloc。 3,对于 Python 对象,如整数,浮点数和 List,都有其独立的私有内存池,对象间不共享他们的内存池。也就是说如果你分配又释放了大量的整数,用于缓存这些整数的内存就不能再分配给浮点数。
3、 列举你知道的Python的魔法方法及用途
new(cls[, …]) | 1. new 是在一个对象实例化的时候所调用的第一个方法 2. 它的第一个参数是这个类,其他的参数是用来直接传递给 init 方法 3. new 决定是否要使用该 init 方法,因为 new 可以调用其他类的构造方法或者直接返回别的实例对象来作为本类的实例,如果 new 没有返回实例对象,则 init 不会被调用 4. new 主要是用于继承一个不可变的类型比如一个 tuple 或者 string |
---|---|
init(self[, …]) | 构造器,当一个实例被创建的时候调用的初始化方法 |
del(self) | 析构器,当一个实例被销毁的时候调用的方法 |
call(self[, args…]) | 允许一个类的实例像函数一样被调用:x(a, b) 调用x.call(a, b) |
len(self) | 定义当被len() 调用时的行为 |
repr(self) | 定义当被repr() 调用时的行为 |
str(self) | 定义当被str() 调用时的行为 |
getattr(self, name) | 定义当用户试图获取一个不存在的属性时的行为 |
getattribute(self, name) | 定义当该类的属性被访问时的行为 |
setattr(self, name, value) | 定义当一个属性被设置时的行为 |
delattr(self, name) | 定义当一个属性被删除时的行为 |
len(self) | 定义当被len() 调用时的行为(返回容器中元素的个数) |
getitem(self, key) | 定义获取容器中指定元素的行为,相当于self[key] |
setitem(self, key, value) | 定义设置容器中指定元素的行为,相当于self[key] = value |
delitem(self, key) | 定义删除容器中指定元素的行为,相当于 del self[key] |
iter(self) | 定义当迭代容器中的元素的行为 |
reversed(self) | 定义当被 reversed() 调用时的行为 |
contains(self, item) | 定义当使用成员测试运算符(in 或 not in)时的行为 |
重载运算……
4、 已知以下list:
list1=[{‘mm’:2},{‘mm’:1},{‘mm’:4},{‘mm’:3},{‘mm’:3}]
1. 把list1中的元素按mm的值排序
2. 获取list1中第一个mm的值等于x的元素
3. List1[::4]输出的是什么
[{‘mm’: 2}, {‘mm’: 3}]
5、 简述你对GIL的理解
线程全局锁(Global Interpreter Lock),即 Python 为了保证线程安全而采取的独立线程运行的限制,说白了就是一个核只能在同一时间运行一个线程.
6、 简述以下内置函数的用法
7、 简述多线程,多进程,协程之间的区别
进程:是资源分配的最小单位,创建和销毁开销较大;
线程:是CPU调度的最小单位,开销小,切换速度快;
协程:轻量级的线程,又称之为纤程,是一种用户态的轻量级线程,实际上只有一个单线程完成。
操作系统将CPU时间片分配给多个线程,每个线程在指定放到时间片内完成。操作系统不断从一个线程切换到另一个线程执行,宏观上看就好像是多个线程一起执行。
Python中由于全局锁 (GIL)的存在导致,同一时间只有一个获得GIL的线程在跑,其他线程则处于等待状态,这导致了多线程只是在做分时切换,并不能利用多核。
多线程与多进程的区别:(1)多进程中同一个变量各自有一份拷贝在每个进程中,互不影响;(2)多线程中,所有变量都由所有线程共享,任何一个变量都可被任何一个线程修改。线程之间共享数据的最大危险在于多个线程同时更改一个变量,把内容改乱。
协程优点:创建协程资源消耗非常少,协程的优点是可以用作IO高并发处理
无需上下文切换的开销,没有临界资源的争夺,保证对数据的原子操作,缺点是无法利用多核。
进程拥有自己独立的堆和栈,既不共享堆,也不共享栈,进程由操作系统调度
线程拥有自己独立的栈,和共享的堆,不共享栈,线程也是由操作系统调度
协程和线程一样共享堆,不共享栈,协程由程序员在协程的代码里显示调度
协程避免了无意义的调度,由此可以提高性能,但也因此,程序员必须自己承担调度的责任,同时,协程也失去了标准线程使用多cpu的能力
说协程是进程和线程的升级版,进程和线程都面临着内核态和用户态的切换问题而耗费许多切换时间,而协程就是用户自己控制切换的时机,不再需要陷入系统的内核态.
8、 简述COOKIE和SESSION的区别与联系
cookie 和session 的区别:
1、cookie数据存放在客户的浏览器上,session数据放在服务器上。
2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,考虑到安全应当使用session。
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用COOKIE。
4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
cookie 和session 的联系:
session是通过cookie来工作的
session和cookie之间是通过
C
O
O
K
I
E
[
′
P
H
P
S
E
S
S
I
D
′
]
来
联
系
的
,
通
过
_COOKIE['PHPSESSID']来联系的,通过
COOKIE[′PHPSESSID′]来联系的,通过_COOKIE[‘PHPSESSID’]可以知道session的id,从而获取到其他的信息
9、 简述什么是浏览器的同源策略
所谓同源是指,域名,协议,端口相同。不同源的客户端脚本在没有明确授权的情况下,不能读写对方的资源
10.git commit –amend有何用处
比方说,你的代码已经提交到git库,leader审核的时候发现有个Java文件代码有点问题,于是让你修改,通常有2种方法:方法1:leader 将你提交的所有代码 abandon掉,然后你回去通过git reset …将代码回退到你代码提交之前的版本,然后你修改出问题的Java文件,然后git add xx.java xxx.java -s -m “Porject : 1.修改bug…”
最后通过git push origin HEAD:refs/for/branches方法2:leader不abandon代码,你回去之后,修改出问题的Java文件,修改好之后,git add 该出问题.java
然后git commit –amend –no-edit,
最后git push origin HEAD:refs/for/branches
11.git如何查看某次提交修改的内容
我们首先可以git log显示历史的提交列表:
之后我们用git show 便可以显示某次提交的修改内容
同样 git show filename 可以显示某次提交的某个内容的修改信息
12.git如何比较两个commit的区别
git diff commit-id-1 commit-id-2 > d:/diff.txt
结果文件diff.txt中:
"-"号开头的表示 commit-id-2 相对 commit-id-1 减少了的内容。
"+"号开头的表示 commit-id-2 相对 commit-id-1 增加了的内容。
13.git如何把分支A上某个commit应用到分支B上
\1. 执行git log -3 --graph A,查看A分支下的commit: 注:commit 后面的hash值代表某个commit,这里把”82f1fb7138c5860cc775b4b5ea71c5d19c4e6497“这个commit提交到B。
\2. 执行git checkout B,切换到B分支;
\3. 执行git cherry-pick 82f1fb7138c5860cc775b4b5ea71c5d19c4e6497,该commit便被提交到了B分支;
\4. git push //注:将该commit推到远程服务器
14.如何查看linux系统的启动时间,磁盘使用量,内存使用量
top
HTTP****协议
1、 请列举常见的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是在浏览器中寄存的小型数据体,它可以记载和服务器相关的用户信息,也可以用来实现会话功能。
2、 请列举常见的HTTP状态码响应码及其意义
状态代码有三位数字组成,第一个数字定义了响应的类别,且有五种可能取值:
1xx:指示信息–表示请求已接收,继续处理
2xx:成功–表示请求已被成功接收、理解、接受
3xx:重定向–要完成请求必须进行更进一步的操作
4xx:客户端错误–请求有语法错误或请求无法实现
5xx:服务器端错误–服务器未能实现合法的请求
常见状态代码、状态描述、说明:
200 OK //客户端请求成功
400 Bad Request //客户端请求有语法错误,不能被服务器所理解
401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
403 Forbidden //服务器收到请求,但是拒绝提供服务
404 Not Found //请求资源不存在,eg:输入了错误的URL
500 Internal Server Error //服务器发生不可预期的错误
503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常
3、 请简述对REST API设计规范的理解
REST API是使用统一资源标识符(url)来搜寻资源有七大设计原则:
\1. url结尾不应包含(/)
\2. 正斜杠分隔符(/)必须用来指示层级关系
\3. 应使用连字符(-)来提高url的可读性
\4. 不得在url中使用下划线(_)
\5. url路径中首选小写字母
\6. 文件扩展名中不应包含在url中
\7. 端点名称是单数(但是实际上为了保持url格式的一致性建议使用复数形式)
正在构建的服务中的每个资源将至少有一个url标识它,这个url最好是有意义的,且能充分藐视资源。url应遵循可预测的层次结构,用来提高其可理解性,可用性:可预测的意义在于他们是一致的,他的层次结构在数据关系上时有意义的。
REST API是使用者编写的,url的名称和结构应该能够向使用者传达更清晰的含义。通过遵循上述规则,您将创建一个更清晰的REST API与更友好的客户端。
4、 请简述HTTP缓存机制
简单来说就是把一个已经请求过的 Web 资源(如 html 页面,图片,js,数据等)拷贝一份副本储存在浏览器中。缓存会根据进来的请求保存输出内容的副本。当下一个请求来到的时候,如果是相同的 URL,缓存会根据缓存机制决定是直接使用副本响应访问请求,还是向源服务器再次发送请求。比较常见的就是浏览器会缓存访问过网站的网页,当再次访问这个 URL 地址的时候,如果网页没有更新,就不会再次下载网页,而是直接使用本地缓存的网页。只有当网站明确标识资源已经更新,浏览器才会再次下载网页
好处:
减少请求次数,减小服务器压力,本地数据读取速度更快,让页面不会空白几百毫秒,在无网络的情况下提供数据。
其他
1、 请列举经常访问的技术网站或博客
知乎 http://www.zhihu.com/
博客园 http://www.cnblogs.com/
开源中国社区 http://www.oschina.net/
红黑联盟 http://www.2cto.com/
2、 请列举最近关注的一些技术
3、 请列举你认为不懂得一些技术书籍和你最近在看的书籍(不限于技术)
4、 请列举你阅读过源码的一些项目
5、 请给出你对这份笔试题的看法
一、Python****题
1.请列举你所知道的Python代码检测工具及它们之间的区别
Flake8 是由Python官方发布的一款辅助检测Python代码是否规范的工具,相对于目前热度比较高的Pylint来说,Flake8检查规则灵活,支持集成额外插件,扩展性强。Flake8是对下面三个工具的封装:
1)PyFlakes:静态检查Python代码逻辑错误的工具。
2)Pep8:静态检查PEP8编码风格的工具。
3)NedBatchelder’s McCabe script:静态分析Python代码复杂度的工具。
不光对以上三个工具的封装,Flake8还提供了扩展的开发接口
Pylint是一个 Python 代码分析工具,它依据的标准是Guido van Rossum的PEP8。它分析 Python 代码中的错误,查找不符合代码风格标准和有潜在问题的代码。目前Pylint的最新版本是 pylint-0.18.1。
Pylint是一个 Python 工具,除了平常代码分析工具的作用之外,它提供了更多的功能:如检查一行代码的长度,变量名是否符合命名标准,一个声明过的接口是否被真正实现等等。
Pylint的一个很大的好处是它的高可配置性,高可定制性,并且可以很容易写小插件来添加功能。
如果运行两次Pylint,它会同时显示出当前和上次的运行结果,从而可以看出代码质量是否得到了改进。
2.请简述你对单元测试的理解并列举Python单元测试相关的工具和库
在编写代码的时候,所有的错误都可以通过对代码的仔细测试检查出来,Unittesting特指在一个分隔的代码单元中的测试。一个单元可以是整个模块,一个单独的类或者函数,或者这两者间的任何代码。然而,重要的是,测试代码要与我们没有测试到的其他代码相互隔离,因为其他代码本身有错误的话会因此混淆测试结果,因此便有了单元测试的概念,单元测试的重要性就不多说了,python中有太多的单元测试框架和工具,什么unittest, testtools, subunit, coverage, testrepository, nose, mox, mock, fixtures, discover,再加上setuptools, distutils等等这些,先不说如何写单元测试,光是怎么运行单元测试就有N多种方法,再因为它是测试而非功能,是很多人没兴趣触及的东西。但是作为一个优秀的程序员,不仅要写好功能代码,写好测试代码一样的彰显你的实力。
3.请给出下面代码片段的输出并阐述涉及的Python相关机制
def dict_updater(k,v,dic={}):
dic{k} = v
print(dic)
dict_updater(“one”,1)
dict_updater(“two”,2)
dict_updater(“three”,3,{})
**5.**以下操作的时间复杂度是多少?
list.index
dict.get
x in set(…)
**6.**解释以下输出的原因
>>> ‘(:0.2f)’.format(0.135)
‘0.14’
>>> ‘(:0.2f)’.format(0.145)
‘0.14’
**7.**简述代码抛出以下异常的原因
IndexError:超出对象索引的范围时抛出的异常
AttributeError:当访问的对象属性不存在的时候抛出的异常
AssertionError:当assert断言条件为假的时候抛出的异常
NotImplementedError:尚未实现的方法
StopIteration:迭代器没有更多的值
TypeError:类型错误,通常是不通类型之间的操作会出现此异常
**10.**参考下面代码片段
1|class Context:
2| #TODO
3| pass
4|
5|with Context() as ctx:
6| ctx.do_something()
请在context类下添加代码完成该类的实现.
二、 MySQL
1.请列举常见的MySQL存储引擎
MyISAM存储引擎、InnoDB存储引擎、MEMORY存储引擎、MERGE存储引擎。
2.InnoDB****有哪些特性
特性:插入缓存(insert buffer)、两次写(double write)、自适应哈希(Adaptive Hash index)、异步IO(Async IO)、刷新邻接页(Flush Neighbor Page)等。
3.请列出一些MySQL数据库查询优化的技巧
①、对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引;
②、应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描;
③、应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描;
④、应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描;
⑤、in 和 not in 也要慎用,否则会导致全表扫描;
⑥、在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。等等。
1**.如何快速计算两个list****的交集、并集**
简单的方法:
1 a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
2 b = [2, 5, 8, 11, 0]
3 # 交集(intersection)
4 intersection = [v for v in a if v in b]
5 # 并集( union)
6 union = b.extend([v for v in a])
高效的方法:
1 # 交集(intersection)
2 intersection = list(set(a).intersection(set(b)))
3 # 并集(union)
4 union = list(set(a).union(set(b)))
**2.**翻转一个字符串s = "abcdef"
3.谈一谈你对list、tuple**、set****、dict****的理解和区别**
4.举出几个Python自省的例子
python自省是python具有的一种能力,使程序员面向对象的语言所写的程序在运行时,能够获得对象的类python型。Python是一种解释型语言。为程序员提供了极大的灵活性和控制力。
Python中常用的自省函数
1、help() 用来查看很多Python自带的帮助文档信息。
2、dir() 可以列出对象的所有属性。
3、type()返回对象的类型。
4、id()返回对象的“唯一序号”。对于引用对象来说,返回的是被引用对象的id()。
5、hasattr()和getattr()分别判断对象是否有某个属性及获得某个属性值。
6、callable()判断对象是否可以被调用。
7、isinstance()可以确认某个变量是否有某种类型。
**5.**说说你对迭代器和生成器的理解
迭代器是一个带状态的对象,它能在你调用next()方法的时候返回容器中的下一个值,任何实现了inter和next()(Python2中实现next())方法的对象都是迭代器,iter返回迭代器自身,next返回容器的下一个值,如果容器中没有更多的元素了,则抛出Stopiteration异常,至于它们到底是如何实现的并不重要。正是因为他是通过next()来返回迭代器中的元素,所以它是一种延迟计算方式返回对象,这种特点对于大数据量元素进行遍历时具有明显优势,他不会一次性把所有元素载入内存,而是遍历一个载入一个,大大降低了内存的占用。
生成器,简单来说就是使用了yield关键字的函数,都叫做生成器。例如:
yield的作用是发起当前执行的函数,并返回,直到调用next(),继续执行后续指令,直到再次遇到yield或者抛出StopIteration异常。上面的例子第一次运行生成器f,需要首先调用f.next()启动生成器。
生成器的优点:代码实现更加简洁,可以提高代码的可读性。同时当然也具有迭代器的优点,大量数据遍历时内存占用少。
需要注意的是:生成器一定是迭代器,但是迭代器不一定是生成器,因为创建一个迭代器只需要实现iter和next()方法就可以了,并不一定要使用yield实现。生成器的唯一注意事项就是:生成器只能遍历一次。
**6.**实现一个二分查找
二分查找:在一段数字内,找到中间值,判断要找的值和中间值大小的比较。
如果中间值大一些,则在中间值的左侧区域继续按照上述方式查找。
如果中间值小一些,则在中间值的右侧区域继续按照上述方式查 找。
直到找到我们希望的数字。
Python实现二分查找算法,代码如下:
7.实现一个装饰器,用于鉴权(已经有鉴权函数user_auth(user_id,token))
补充注释:内存中存在的pool也只有一个
9.用一条命令关掉所有的Python进程
quit() exit() 执行到此命令时,程序终止。
如果是程序陷入死循环,想强制结束,则按Ctrl + C
10.在用git提交中,如何避免提交pyc****文件
一般来说每个Git项目中都需要一个“.gitignore”文件,这个文件的作用就是告诉Git哪些文件不需要添加到版本管理中。实际项目中,很多文件都是不需要版本管理的,比如Python的.pyc文件和一些包含密码的配置文件等等。这个文件的内容是一些规则,Git会根据这些规则来判断是否将文件添加到版本控制中。
有两种方法可以实现过滤掉Git里不想上传的文件:
针对单一工程排除文件,这种方式会让这个工程的所有修改者在克隆代码的同时,也能克隆到过滤规则,而不用自己再写一份,这就能保证所有修改者应用的都是同一份规则,而不是张三自己有一套过滤规则,李四又使用另一套过滤规则,个人比较喜欢这个。配置步骤如下:
在工程根目录下建立.gitignore文件,将要排除的文件或目录写到.gitignore这个文件中,其中有两种写入方法。
a) 使用命令行增加排除文件
排除以.class结尾的文件 echo “*.class” >.gitignore (>>是在文件尾增加,>是删除已经存在的内容再增加),之后会在当前目录下生成一个.gitignore的文件。
排除bin目录下的文件 echo “bin/” >.gitignore
b)最方便的办法是,用记事本打开,增加需要排除的文件或目录,一行增加一个,例如:
2)第二种方法
全局设置排除文件,这会在全局起作用,只要是Git管理的工程,在提交时都会自动排除不在控制范围内的文件或目录。这种方法对开发者来说,比较省事,只要一次全局配置,不用每次建立工程都要配置一遍过滤规则。但是这不保证其他的开发者在克隆你的代码后,他们那边的规则跟你的是一样的,这就带来了代码提交过程中的各种冲突问题。
配置步骤如下:
a)像方法(1)一样,也需要建立一个.gitignore文件,把要排除的文件写进去。
b)但在这里,我们不规定一定要把.gitnore文件放到某个工程下面,而是任何地方,比如我们这里放到了Git默认的Home路径下,比如:/home/wangshibo/hqsb_ios
c)使用命令方式可以配置全局排除文件gitconfig --global core.excludesfile /.gitignore,你会发现在/.gitconfig文件中会出现excludesfile = /home/wangshibo/hqsb_ios/.gitignore。
说明Git把文件过滤规则应用到了Global的规则中。
**1.**你对新的工作是怎么考虑的,就是为什么来北京了呢
**2.**找工作侧重于哪方面,什么行业或者说公司主营的方向自研软件还是外包
3.一个TXT****文件,不打开,想往里面插入一条命令
**4.**用户注册用户名时,如何做一些控制(如何防止注入攻击)
程序开发过程中不注意规范书写sql语句和对特殊字符进行过滤,导致客户端可以通过全局变量POST和GET提交一些sql语句正常执行。产生Sql注入。下面是防止办法:
a. 过滤掉一些常见的数据库操作关键字,或者通过系统函数来进行过滤。
b. 在PHP配置文件中将Register_globals=off;设置为关闭状态
c. SQL语句书写的时候尽量不要省略小引号(tab键上面那个)和单引号
d. 提高数据库命名技巧,对于一些重要的字段根据程序的特点命名,取不易被猜到的
e. 对于常用的方法加以封装,避免直接暴漏SQL语句
f. 开启PHP安全模式:Safe_mode=on;
g. 打开magic_quotes_gpc来防止SQL注入
h. 控制错误信息:关闭错误提示信息,将错误信息写到系统日志。
i. 使用mysqli或pdo预处理。
**5.**你做的是前端还是后端,前后端之间的接口是怎么规定的,比如前端是用什么写的,后端是用什么写的,
**6.**项目有几个人,前端几个,后端几个
7.怎么从request****判断是哪个用户发来的
会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。
8.request****有几种类型的请求
请求类型:
>>>r = request.post(‘https://httpbin.org/post’)
>>>r = request.put(‘http://httpbin.org/put’)
>>>r = request.delete(‘http://httpbin.org/delete’)
>>>r = request.head(‘http://httbin.org/head’)
>>>r = request.options(‘http://httpbin.org/options’)
9.post****请求发送成功返回的状态码
2XX是请求正常处理完毕的意思,表示成功状态码
分为三类:
200 ok表示从客户端发来的请求在服务器被正常处理了。
204 no content 表示从客户端发来的请求在服务器被正常处理了,但在返回的响应报文中不含实体的主体部分。
206 partial content 表示客户端进行了范围请求,而服务器成功执行了这部分的GET请求。
10.mysql****设计了几张表
11.pycharm****装在哪里(服务器还是个人主机)
12.如何把项目导入pycharm****里
13.django服务起来的时候,有那几个框架,比如wsgi**,ngix一起启动,ngix和wsgi之间还有什么**
14.Linux熟悉到什么程度,知道很多servers****都放在哪里吗
15.vi****用的多吗
比较常用,编辑代码的工具一般就是vi和sublime。
16.Linux****装在哪里,个人电脑上吗?
linux版本很多,看自己的需求,常见的有suse,fedora,centos,ubantu,红帽等。个人使用,建议使用suse,fedora,图形界面的建议使用ubantu
可以装在个人电脑上,linux跟Windows一样都是操作系统,只不过在操作系统之上应用软件多少罢了,而且不像以前linux只能安装在特殊架构的机器上,并不是咱们用的这种X86平台上的。你可以在windows上装个虚拟机软件
面试问题
1**、Linux和windows的区别**
价格和开源
在中国,windows和linux都是免费的,至少对个人用户是如此,但是Windows盗版比较严重,如果严打,对Linux来说就是一大好处。
开源就是指对外部开放软件源代码。
windows平台:数量和质量的优势,不过大部分为收费软件;由微软官方提供重要支持和服务。
linux平台:大都为开源自由软件,用户可以修改定制和再发布,由于基本免费没有资金支持,部分软件质量和体验欠缺。
2**、用户用登陆注册页面时报错400****,403****,500****怎样排查出来错误**
400错误:由于语法格式有误,服务器无法理解此请求。不作修改,客户程序就无法重复此请求。
403错误:
403.1 禁止:禁止执行访问
如果从并不允许执行程序的目录中执行 CGI、ISAPI或其他执行程序就可能引起此错误。
如果问题依然存在,请与 Web 服务器的管理员联系。
403.2 禁止:禁止读取访问
如果没有可用的默认网页或未启用此目录的目录浏览,或者试图显示驻留在只标记为执行
脚本权限的目录中的HTML 页时就会导致此错误。
如果问题依然存在,请与 Web 服务器的管理员联系。
403.3 禁止:禁止写访问
如果试图上载或修改不允许写访问的目录中的文件,就会导致此问题。
如果问题依然存在,请与 Web服务器的管理员联系。
403.4 禁止:需要 SSL
此错误表明试图访问的网页受安全套接字层(SSL)的保护。要查看,必须在试图访问的地址前输入https:// 以启用 SSL。
如果问题依然存在,请与 Web服务器的管理员联系。
403.5 禁止:需要 SSL 128
此错误消息表明您试图访问的资源受 128位的安全套接字层(SSL)保护。要查看此资源
需要有支持此SSL 层的浏览器。
请确认浏览器是否支持 128 位 SSL安全性。如果支持,就与 Web服务器的管理员联系,并报告问题。
403.6 禁止:拒绝 IP 地址
如果服务器含有不允许访问此站点的 IP地址列表,并且您正使用的 IP地址在此列表中,
会导致此问题。
如果问题依然存在,请与 Web服务器的管理员联系。
403.7 禁止:需要用户证书
当试图访问的资源要求浏览器具有服务器可识别的用户安全套接字层(SSL)证书时就会
致此问题。可用来验证您是否为此资源的合法用户。
请与 Web服务器的管理员联系以获取有效的用户证书。
403.8 禁止:禁止站点访问
如果 Web服务器不为请求提供服务,或您没有连接到此站点的权限时,就会导致此问题。
请与 Web 服务器的管理员联系。
403.9 禁止访问:所连接的用户太多
如果 Web太忙并且由于流量过大而无法处理您的请求时就会导致此问题。请稍后再次连接。
如果问题依然存在,请与 Web 服务器的管理员联系。
403.10 禁止访问:配置无效
此时 Web 服务器的配置存在问题。
如果问题依然存在,请与 Web服务器的管理员联系。
403.11 禁止访问:密码已更改
在身份验证的过程中如果用户输入错误的密码,就会导致此错误。请刷新网页并重试。
如果问题依然存在,请与 Web服务器的管理员联系。
403.12 禁止访问:映射程序拒绝访问
拒绝用户证书试图访问此 Web 站点。
请与站点管理员联系以建立用户证书权限。如果必要,也可以更改用户证书并重试。
500错误:
500 服务器的内部错误
Web 服务器不能执行此请求。请稍后重试此请求。
如果问题依然存在,请与 Web服务器的管理员联系。
3**、算法(二叉树)等**
二叉树是有限个元素的集合,该集合或者为空,或者有一个称为根节点的元素及两个互不相交的、分别被称为左子树和右子树的二叉树组成。
1> 二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。
2> 二叉树的第i层至多有2^{i-1}个结点
3> 深度为k的二叉树至多有2^k-1个结点;
4> 对任何一棵二叉树T,如果其终端结点数为N0,度为2的结点数为N2,则N0=N2+1
4**、nginx****部署具体操作**
Nginx的特点:静态资源的高并发,反向代理加速,支持FastCGI,运行SSL、TSL
环境部署:
1:安装编译环境
yum install -y gcc gcc-c++ opensslopenssl-devlepcrepcre-devel make get curl
pcre-devel兼容正则表达式
2:创建安装目录,下载资源
mkdir -p /Application/tools
wgethttp://nginx.org/download/nginx-****.tar.gz
3 解压文件,并进入安装文件目录
tar zxf nginx-.tar.gz && cd nginx-
4:创建用户
创建一个没有家目录的且不能登录的用户nginx
sudo useraddnginx -s /sbin/nologin -M
sudo id nginx
uid=501(nginx) gid=501(nginx) groups=501(nginx)
5配置
./configure --user=nginx --group=nginx --prefix=/Application/nginx-** --with-http_sub_module
指定运行软件的用户名运行软件的组指定安装路径启用Nginx运行状态模块
6编译并安装
make && make install
7测试安装结果
7.1:查看进程
ps -ef |grep nginx |grep -v grep
root 2232 1 0 11:14 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx 9451 2232 0 13:58 ? 00:00:00 nginx: worker process
7.2:查看端口
netstat -antulp |grep nginx
tcp 0 0 0.0.0.0:80 0.0.0.0: LISTEN 2232/nginx
7.3:文本工具测试
7.3.1:curl 127.0.0.1
Welcome access www.52linux.club
7.3.2:www.52linux.club
8:创建软链接
1.用于版本升级中,代码的固定安装位置或参数的引用
2.ln -s /Application/nginx-1.12.1 /usr/loacl/nginx
lrwxrwxrwx 1 root root 25 Mar 16 15:49 nginx -> /Application/nginx-1.12.1
5**、正则表达式的符号代表的意思**
6**、uwsgi****用的哪个版本**
2.0.9
Python面试题目
\1. 单引号,双引号,三引号的区别
单引号里可以包含双引号和转义字符,但不能包含单引号。
双引号里可以包含单引号和转义字符,但不能包含双引号。
三引号里可以包含单引号和双引号,另外还有换行,注释功能。
\2. Python的参数传递是值传递还是引用传递?
python中的一切事物皆为对象,并且规定参数的传递都是对象的引用
\3. 什么是lambda函数?它有什么好处?
概念:lambda函数是一个可以接收任意多个参数(包括可选参数)并且返回单个表达式值的函数。
好处:
加精简。
使用lambda不需要考虑命名的问题。
\4. Python是如何进行内存管理的?
python内部使用引用计数,来保持追踪内存中的对象,Python内部记录了对象有多少个引用,即引用计数,当对象被创建时就创建了一个引用计数,当对象不再需要时,
这个对象的引用计数为0时,它被垃圾回收。
\5. 说出下面list1,list2,list3的输出值
defextendList(val, list=[]):
list.append(val)
returnlist
list1 =extendList(10)
list2 =extendList(11,[])
list3 =extendList(‘b’)
print(“list1 = %s”%list1)
print"list2 = %s"%list2)
print"list3 = %s"%list3)
list1 = [10, ‘b’]
list2 = [11]
list3 = [10, ‘b’]
\6. 用你认为最Pythonic的代码实现对下面文档的websocket接口数据(Partial Book Depth Streams)的采集,支持symbol、levels可动态配置;接口地址:https://github.com/binance-exchange/binance-official-api-docs/blob/master/web-socket-streams.md
1.python常用的数据结构的类型及特性
答:数字型(整数型(int),浮点数型,复数型,布尔数型):
特性:1、只能存放一个值 2、一经定义,不可更改 3、直接访问
字符串型:
特性:1、用来存储文本信息的容器 2、不可变数据类型 3、序列
列表:
特性:1、可存放多个值 2、可变数据类型3、序列4、表内元素直接无联系
元祖:
特性:1、可存放多个值 2、不可变数据类型3、序列4、表内元素直接无联系
字典:
特性:1、可存放多个值2、以键值对方式存储3、无序4、可变数据类型 5、键是唯一的
集合:
特性:1、可存放多个值 2、元素唯一 3、无序 4、可变数据类型 5、可用作字典的键
字节型:存储以字节为单位的数据
特性:1、只能存放一个值 2、不可变数据类型 3、有序
2.已知Alist = [1,2,3,1,2],对Alist 列表元素去重,写出具体过程
答:Alist= list(set(Alist))
3.选出一下表达式表述正确的选项:
A:{1:0,2:0,3:0}
B : {‘a’ :0,’b’:0,’c’:0}
C : {{1,2}:0,{2,3}:0}
D:{[1,3]:0,[2,3]:0}
E :{(1,3):0,(2,5)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。