赞
踩
人生苦短
我用 Python
芝麻开门!
python 进阶 1
python 经典面试题 9
python 面试 100 例 21
python 面试题总结 101
python 进阶
1
1:Python 如何实现单例模式?
Python 有两种方式可以实现单例模式,下面两个例子使用了不同的方式实现单
例模式:
1.
class Singleton(type):
def init(cls, name, bases, dict):
super(Singleton, cls).init(name, bases, dict)
cls.instance = None
def call(cls, *args, **kw):
if cls.instance is None:
cls.instance = super(Singleton, cls).call(*args, **kw)
return cls.instance
class MyClass(object):
metaclass = Singleton
print MyClass()
print MyClass()
2. 使用 decorator 来实现单例模式
def singleton(cls):
instances = {}
def getinstance():
if cls not in instances:
instances[cls] = cls()
return instances[cls]
return getinstance
@singleton
class MyClass: …
2:什么是 lambda 函数?
Python 允许你定义一种单行的小函数。定义 lambda 函数的形式如下:labmda 参
数:表达式 lambda 函数默认返回表达式的值。你也可以将其赋值给一个变量。
lambda 函数可以接受任意个参数,包括可选参数,但是表达式只有一个:
g = lambda x, y: x*y
g(3,4)
12g = lambda x, y=0, z=0: x+y+z
g(1)
1
10g(3, 4, 7)
14
也能够直接使用 lambda 函数,不把它赋值给变量:(lambda x,y=0,z=0:x+y+z)(3,5,6)
14
如果你的函数非常简单,只有一个表达式,不包含命令,可以考虑 lambda 函数。
否则,你还是定义函数才对,毕竟函数没有这么多限制。
3:Python 是如何进行类型转换的?
Python 提供了将变量或值从一种类型转换成另一种类型的内置函数。int 函数能
够将符合数学格式数字型字符串转换成整数。否则,返回错误信息。int(”34″)
34int(”1234ab”) #不能转换成整数
ValueError: invalid literal for int(): 1234ab
函数 int 也能够把浮点数转换成整数,但浮点数的小数部分被截去。int(34.1234)
34int(-2.46)
-2
函数°oat 将整数和字符串转换成浮点数:float(”12″)
12.0float(”1.111111″)
1.111111
函数 str 将数字转换成字符:str(98)
‘98′str(”76.765″)
‘76.765′
整数 1 和浮点数 1.0 在 python 中是不同的。虽然它们的值相等的,但却属于不
同的类型。这两个数在计算机的存储形式也是不一样。
4:Python 如何定义一个函数
函数的定义形式如
下:
def (arg1, arg2,… argN):
函数的名字也必须以字母开头,可以包括下划线“ ”,但不能把 Python 的
关键字定义成函数的名字。函数内的语句数量是任意的,每个语句至少有
一个空格的缩进,以表示此语句属于这个函数的。缩进结束的地方,函数
自然结束。
下面定义了一个两个数相加的函数:
11def add(p1, p2):
print p1, “+”, p2, “=”, p1+p2add(1, 2)
1 + 2 = 3
函数的目的是把一些复杂的操作隐藏,来简化程序的结构,使其容易
阅读。函数在调用前,必须先定义。也可以在一个函数内部定义函数,内
部函数只有在外部函数调用时才能够被执行。程序调用函数时,转到函数
内部执行函数内部的语句,函数执行完毕后,返回到它离开程序的地方,
执行程序的下一条语句。
5:Python 是如何进行内存管理的?
Python 的内存管理是由 Python 得解释器负责的,开发人员可以从内存管理事务中解放出来,
致力于应用程序的开发,这样就使得开发的程序错误更少,程序更健壮,开发周期更短
6:如何反序的迭代一个序列?how do I iterate over a sequence in reverse order
如果是一个 list, 最快的解决方案是:
list.reverse()
try:
for x in list:
“do something with x”
finally:
list.reverse()
如果不是 list, 最通用但是稍慢的解决方案是:
for i in range(len(sequence)-1, -1, -1):
x = sequence[i]
7:Python 里面如何实现 tuple 和 list 的转换?
函数 tuple(seq)可以把所有可迭代的(iterable)序列转换成一个 tuple, 元素
不变,排序也不变。
例如,tuple([1,2,3])返回(1,2,3), tuple(’abc’)返回(’a’.’b’,’c’).
如果参数已经是一个 tuple 的话,函数不做任何拷贝而直接返回原来的对象,所
以在不确定对象是不是 tuple 的时候来调用 tuple()函数也不是很耗费的。
函数 list(seq)可以把所有的序列和可迭代的对象转换成一个 list,元素不变,
排序也不变。
例如 list([1,2,3])返回(1,2,3), list(’abc’)返回[‘a’, ‘b’, ‘c’]。如果
参数是一个 list, 她会像 set[:]一样做一个拷贝
12
8:Python 面试题:请写出一段 Python 代码实现删除一个 list 里面的重复元素
可以先把 list 重新排序,然后从 list 的最后开始扫描,代码如下:
if List:
List.sort()
last = List[-1]
for i in range(len(List)-2, -1, -1):
if last==List[i]: del List[i]
else: last=List[i]
9:Python 文件操作的面试题
server = smtplib.SMTP(’localhost’)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()
12:Python 里面如何拷贝一个对象?
一般来说可以使用 copy.copy()方法或者 copy.deepcopy()方法,几乎所有的对
象都可以被拷贝
一些对象可以更容易的拷贝,Dictionaries 有一个 copy 方法:
newdict = olddict.copy()
13:有没有一个工具可以帮助查找 python 的 bug 和进行静态的代码分析?
有,PyChecker 是一个 python 代码的静态分析工具,它可以帮助查找 python 代
码的 bug, 会对代码的复杂度和格式提出警告
Pylint 是另外一个工具可以进行 coding standard 检查。
14:如何在一个 function 里面设置一个全局的变量?
解决方法是在 function 的开始插入一个 global 声明:
def f()
global x
14:有两个序列 a,b,大小都为 n,序列元素的值任意整形数,无序;要求:通过
交换 a,b 中的元素,使[序列 a 元素的和]与[序列 b 元素的和]之间的差最小。
class MyClass():
… def init(self):
… self.__superprivate = “Hello”
… self._semiprivate = “, world!”
…mc = MyClass()
print(mc.__superprivate)
Traceback (most recent call last):
File “”, line 1, in
AttributeError: myClass instance has no attribute ‘__superprivate’print(mc._semiprivate)
25
12
13
14
, world!print mc.dict
{’_MyClass__superprivate’: ‘Hello’, ‘_semiprivate’: ‘, world!’}
foo :一种约定 ,Python 内部的名字 ,用来区别其他用户自定义的命名 ,以防冲突 .
_foo :一种约定 ,用来指定变量私有 .程序员用来指定私有变量的一种方式 .
__foo :这个有真正的意义 :解析器用 _classname__foo 来代替这个名字 ,以区别和其
他类相同的命名 .
详情见 :
http://www.zhihu.com/question/19754941
8 字符串格式化 :%和.format
.format 在许多方面看起来更便利 .对于 %最烦人的是它无法同时传递一个变量和元
组.你可能会想下面的代码不会有什么问题 :
Python:
“hi there %s” % name
但是 ,如果 name 恰好是 (1,2,3), 它将会抛出一个 TypeError 异常 .为了保证它总是正
确的 ,你必须这样做 :
“hi there %s” % (name,) # 提供一个单元素的数组而不是一个参数
9 迭代器和生成器
在 Python 中,这种一边循环一边计算的机制,称为生成器: generator 。
可以被 next() 函数调用并不断返回下一个值的对象称为迭代器: Iterator 。
26
这个是 stackoverflow 里 python 排名第一的问题 ,值得一看 :
http://stackoverflow.com/questions/231767/what-does-the-yield-keyword
-do-in-python
10 args and **kwargs
用args 和**kwargs 只是为了方便并没有强制使用它们 .
当你不确定你的函数里将要传递多少参数时你可以用 *args .例如 ,它可以传递任意
数量的参数 :
1
2
3
4
5
6
7
8def print_everything(*args):
for count, thing in enumerate(args):
… print ‘{0}. {1}’.format(count, thing)
…print_everything(‘apple’, ‘banana’, ‘cabbage’)
def table_things(**kwargs):
… for name, value in kwargs.items():
… print ‘{0} = {1}’.format(name, value)
…table_things(apple = ‘fruit’, cabbage = ‘vegetable’)
cabbage = vegetable
apple = fruit
你也可以混着用 .命名参数首先获得参数值然后所有的其他参数都传递给 *args 和
**kwargs .命名参数在列表的最前端 .例如 :
1 def table_things(titlestring, kwargs)
*args 和kwargs 可以同时在函数的定义中 ,但是 *args 必须在 kwargs 前面 .
当调用函数时你也可以用 * 和 语法 .例如 :
27
1
2
3
4
5
6
7def print_three_things(a, b, c):
… print ‘a = {0}, b = {1}, c = {2}’.format(a,b,c)
…mylist = [‘aardvark’, ‘baboon’, ‘cat’]
print_three_things(*mylist)
a = aardvark, b = baboon, c = cat
就像你看到的一样 ,它可以传递列表 (或者元组 )的每一项并把它们解包 .注意必须与
它们在函数里的参数相吻合 .当然,你也可以在函数定义或者函数调用时用 *.
http://stackoverflow.com/questions/3394835/args-and-kwargs
11 面向切面编程 AOP 和装饰器
这个 AOP 一听起来有点懵 ,同学面试的时候就被问懵了…
装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插
入日志、性能测试、事务处理等。装饰器是解决这类问题的绝佳设计,有了装饰器,
我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的
讲, 装饰器的作用就是为已经存在的对象添加额外的功能。
这个问题比较大 ,推荐 :
http://stackoverflow.com/questions/739654/how-can-i-make-a-chain-of-fu
nction-decorators-in-python
中文 :
http://taizilongxu.gitbooks.io/stackoverflow-about-python/content/3/REA
DME.html
28
12 鸭子类型
“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就
可以被称为鸭子。”
我们并不关心对象是什么类型,到底是不是鸭子,只关心行为。
比如在 python 中,有很多 file-like 的东西, 比如 StringIO,GzipFile,socket 。它们
有很多相同的方法,我们把它们当作文件使用。
又比如 list.extend() 方法中 ,我们并不关心它的参数是不是 list, 只要它是可迭代的 ,所
以它的参数可以是 list/tuple/dict/ 字符串 / 生成器等 .
鸭子类型在动态语言中经常使用,非常灵活,使得 python 不想 java 那样专门去弄
一大堆的设计模式。
13 Python 中重载
引自知乎 :http://www.zhihu.com/question/20053359
函数重载主要是为了解决两个问题。
classMy_Singleton(object):
deffoo(self):
pass
my_singleton=My_Singleton()
frommysingleton importmy_singleton
my_singleton.foo()
17 Python 中的作用域
Python 中,一个变量的作用域总是由在代码中被赋值的地方所决定的。
32
当 Python 遇到一个变量的话他会按照这样的顺序进行搜索:
本地作用域( Local )→当前作用域被嵌入的本地作用域( Enclosing locals )→全
局/模块作用域( Global )→内置作用域( Built-in )
18 GIL 线程全局锁
线程全局锁 (Global Interpreter Lock), 即 Python 为了保证线程安全而采取的独立
线程运行的限制 ,说白了就是一个核只能在同一时间运行一个线程 .
解决办法就是多进程和下面的协程 (协程也只是单 CPU,但是能减小切换代价提升性
能).
19 协程
简单点说协程是进程和线程的升级版 ,进程和线程都面临着内核态和用户态的切换
问题而耗费许多切换时间 ,而协程就是用户自己控制切换的时机 ,不再需要陷入系统
的内核态 .
Python 里最常见的 yield 就是协程的思想 !可以查看第九个问题 .
20 闭包
闭包 (closure) 是函数式编程的重要的语法结构。闭包也是一种组织代码的结构,它
同样提高了代码的可重复使用性。
33
当一个内嵌函数引用其外部作作用域的变量 ,我们就会得到一个闭包 . 总结一下 ,创
建一个闭包必须满足以下几点 :
a=[1,2,3,4,5,6,7]
b=filter(lambdax:x>5,a)
printb
[6,7]
map 函数是对一个序列的每个项依次执行函数, 下面是对一个序列每个项都乘以 2:a=map(lambdax:x*2,[1,2,3])
list(a)
[2,4,6]
reduce 函数是对一个序列的每个项迭代调用函数,下面是求 3 的阶乘:reduce(lambdax,y:x*y,range(1,4))
6
23 Python 里的拷贝
引用和 copy(),deepcopy() 的区别
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
importcopy
a=[1,2,3,4,[‘a’,‘b’]] # 原始对象
b=a #赋值,传对象的引用
c=copy.copy(a) # 对象拷贝,浅拷贝
d=copy.deepcopy(a) # 对象拷贝,深拷贝
a.append(5) #修改对象 a
a[4].append(‘c’) # 修改对象 a 中的 [‘a’, ‘b’] 数组对象
print’a = ',a
print’b = ',b
print’c = ',c
print’d = ',d
输出结果:
a= [1,2,3,4,[‘a’,‘b’,‘c’],5]
b= [1,2,3,4,[‘a’,‘b’,‘c’],5]
c= [1,2,3,4,[‘a’,‘b’,‘c’]]
35
20 d= [1,2,3,4,[‘a’,‘b’]]
24 Python 垃圾回收机制
Python GC 主要使用引用计数( reference counting )来跟踪和回收垃圾。在引用
计数的基础上,通过“标记 - 清除”( mark and sweep )解决容器对象可能产生的
循环引用问题,通过“分代回收”( generation collection )以空间换时间的方法
提高垃圾回收效率。
1 引用计数
PyObject 是每个对象必有的内容,其中 ob_refcnt 就是做为引用计数。当一个对
象有新的引用时,它的 ob_refcnt 就会增加,当引用它的对象被删除,它的
ob_refcnt 就会减少 .引用计数为 0 时,该对象生命就结束了。
优点 :
答案
def print_directory_contents(sPath):
import os
for sChild in os.listdir(sPath):
sChildPath = os.path.join(sPath,sChild)
if os.path.isdir(sChildPath):
print_directory_contents(sChildPath)
else:
print sChildPath
特别要注意以下几点:
命名规范要统一。如果样本代码中能够看出命名规范,遵循其已有的规范。
递归函数需要递归并终止。 确保你明白其中的原理, 否则你将面临无休无止的调用栈 (c
allstack )。
41
我们使用 os 模块与操作系统进行交互,同时做到交互方式是可以跨平台的。你可以把
代码写成 sChildPath = sPath + ‘/’ + sChild ,但是这个在 Windows 系统上会出错。
熟悉基础模块是非常有价值的,但是别想破脑袋都背下来,记住 Google 是你工作中的
良师益友。
如果你不明白代码的预期功能,就大胆提问。
坚持 KISS 原则!保持简单,不过脑子就能懂!
为什么提这个问题 :
说明面试者对与操作系统交互的基础知识
递归真是太好用啦
31 阅读下面的代码,写出 A0 ,A1 至 An 的最终值。
A0 = dict(zip((‘a’,‘b’,‘c’,‘d’,‘e’),(1,2,3,4,5)))
A1 = range(10)
A2 = [i for i in A1 if i in A0]
A3 = [A0[s] for s in A0]
A4 = [i for i in A1 if i in A3]
A5 = {i:ii for i in A1}
A6 = [[i,ii] for i in A1]
答案
A0 = {‘a’: 1, ‘c’: 3, ‘b’: 2, ‘e’: 5, ‘d’: 4}
A1 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
42
A2 = []
A3 = [1, 3, 2, 5, 4]
A4 = [1, 2, 3, 4, 5]
A5 = {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
A6 = [[0, 0], [1, 1], [2, 4], [3, 9], [4, 16], [5, 25], [6, 36], [7, 49], [8, 64], [9, 81]]
为什么提这个问题 :
列表解析 (list comprehension )十分节约时间, 对很多人来说也是一个大的学习障碍。
如果你读懂了这些代码,就很可能可以写下正确地值。
其中部分代码故意写的怪怪的。因为你共事的人之中也会有怪人。
32 下面代码会输出什么:
def f(x,l=[]):
for i in range(x):
l.append(i*i)
print(l)
f(2)
f(3,[3,2,1])
f(3)
答案:
[0, 1]
43
[3, 2, 1, 0, 1, 4]
[0, 1, 0, 1, 4]
呃?
第一个函数调用十分明显, for 循环先后将 0 和 1 添加至了空列表 l 中。 l 是变量的名字,
指向内存中存储的一个列表。第二个函数调用在一块新的内存中创建了新的列表。 l 这时指
向了新生成的列表。之后再往新列表中添加 0、1 和 4。很棒吧。第三个函数调用的结果就
有些奇怪了。它使用了之前内存地址中存储的旧列表。这就是为什么它的前两个元素是 0
和 1 了。
33 你如何管理不同版本的代码?
答案 :
版本管理! 被问到这个问题的时候, 你应该要表现得很兴奋, 甚至告诉他们你是如何使用 Git( 或
是其他你最喜欢的工具)追踪自己和奶奶的书信往来。我偏向于使用 Git 作为版本控制系统
(VCS),但还有其他的选择,比如 subversion (SVN )。
为什么提这个问题 :
因为没有版本控制的代码, 就像没有杯子的咖啡。 有时候我们需要写一些一次性的、 可以随手扔
掉的脚本, 这种情况下不作版本控制没关系。 但是如果你面对的是大量的代码, 使用版本控制系
统是有利的。版本控制能够帮你追踪谁对代码库做了什么操作;发现新引入了什么 bug ;管理
你的软件的不同版本和发行版; 在团队成员中分享源代码; 部署及其他自动化处理。 它能让你回
滚到出现问题之前的版本,单凭这点就特别棒了。还有其他的好功能。怎么一个棒字了得!
44
34 “猴子补丁”(monkey patching )指的是什么?
这种做法好吗?
答案 :
“猴子补丁”就是指,在函数或对象已经定义之后,再去改变它们的行为。
举个例子:
import datetime
datetime.datetime.now = lambda: datetime.datetime(2012, 12, 12)
大部分情况下,这是种很不好的做法 - 因为函数在代码库中的行为最好是都保持一致。打“猴
子补丁”的原因可能是为了测试。 mock 包对实现这个目的很有帮助。
为什么提这个问题 ?
答对这个问题说明你对单元测试的方法有一定了解。 你如果提到要避免“猴子补丁”, 可以说明
你不是那种喜欢花里胡哨代码的程序员(公司里就有这种人,跟他们共事真是糟糕透了), 而是
更注重可维护性。还记得 KISS 原则码?答对这个问题还说明你明白一些 Python 底层运作的方
式,函数实际是如何存储、调用等等。
另外:如果你没读过 mock 模块的话,真的值得花时间读一读。这个模块非常有用。
35 阅读下面的代码,它的输出结果是什么?
class A(object):
def go(self):
print “go A go!”
45
def stop(self):
print “stop A stop!”
def pause(self):
raise Exception(“Not Implemented”)
class B(A):
def go(self):
super(B, self).go()
print “go B go!”
class C(A):
def go(self):
super(C, self).go()
print “go C go!”
def stop(self):
super(C, self).stop()
print “stop C stop!”
class D(B,C):
def go(self):
super(D, self).go()
print “go D go!”
46
def stop(self):
super(D, self).stop()
print “stop D stop!”
def pause(self):
print “wait D wait!”
class E(B,C): pass
a = A()
b = B()
c = C()
d = D()
e = E()
a.go()
b.go()
c.go()
d.go()
e.go()
47
a.stop()
b.stop()
c.stop()
d.stop()
e.stop()
a.pause()
b.pause()
c.pause()
d.pause()
e.pause()
答案
输出结果以注释的形式表示:
a.go()
b.go()
c.go()
48
d.go()
e.go()
a.stop()
b.stop()
c.stop()
49
d.stop()
e.stop()
a.pause()
b.pause()
c.pause()
d.pause()
e.pause()
50
为什么提这个问题 ?
因为面向对象的编程真的真的很重要。不骗你。答对这道问题说明你理解了继承和 Python 中
super 函数的用法。
36 阅读下面的代码,它的输出结果是什么?
class Node(object):
def init(self,sName):
self._lChildren = []
self.sName = sName
def repr(self):
return “<Node ‘{}’>”.format(self.sName)
def append(self,*args,**kwargs):
self._lChildren.append(*args,**kwargs)
def print_all_1(self):
print self
for oChild in self._lChildren:
oChild.print_all_1()
def print_all_2(self):
def gen(o):
lAll = [o,]
while lAll:
51
oNext = lAll.pop(0)
lAll.extend(oNext._lChildren)
yield oNext
for oNode in gen(self):
print oNode
oRoot = Node(“root”)
oChild1 = Node(“child1”)
oChild2 = Node(“child2”)
oChild3 = Node(“child3”)
oChild4 = Node(“child4”)
oChild5 = Node(“child5”)
oChild6 = Node(“child6”)
oChild7 = Node(“child7”)
oChild8 = Node(“child8”)
oChild9 = Node(“child9”)
oChild10 = Node(“child10”)
oRoot.append(oChild1)
oRoot.append(oChild2)
oRoot.append(oChild3)
oChild1.append(oChild4)
52
oChild1.append(oChild5)
oChild2.append(oChild6)
oChild4.append(oChild7)
oChild3.append(oChild8)
oChild3.append(oChild9)
oChild6.append(oChild10)
oRoot.print_all_1()
oRoot.print_all_2()
答案
oRoot.print_all_1() 会打印下面的结果:
<Node ‘root’>
<Node ‘child1’>
<Node ‘child4’>
<Node ‘child7’>
<Node ‘child5’>
<Node ‘child2’>
<Node ‘child6’>
<Node ‘child10’>
<Node ‘child3’>
53
<Node ‘child8’>
<Node ‘child9’>
oRoot.print_all_1() 会打印下面的结果:
<Node ‘root’>
<Node ‘child1’>
<Node ‘child2’>
<Node ‘child3’>
<Node ‘child4’>
<Node ‘child5’>
<Node ‘child6’>
<Node ‘child8’>
<Node ‘child9’>
<Node ‘child7’>
<Node ‘child10’>
为什么提这个问题 ?
因为对象的精髓就在于组合( composition )与对象构造( object construction )。对象需要
有组合成分构成, 而且得以某种方式初始化。 这里也涉及到递归和生成器 (generator )的使用。
生成器是很棒的数据类型。 你可以只通过构造一个很长的列表, 然后打印列表的内容, 就可以取
得与 print_all_2 类似的功能。生成器还有一个好处,就是不用占据很多内存。
有一点还值得指出,就是 print_all_1 会以深度优先( depth-first )的方式遍历树 (tree), 而
print_all_2 则是宽度优先( width-first )。有时候,一种遍历方式比另一种更合适。但这要
看你的应用的具体情况。
54
36. 介绍一下 except 的用法和作用?
答:try …except …except …[else …][finally …]
执行 try 下的语句,如果引发异常,则执行过程会跳到 except 语句。对每个
except 分支顺序尝试执行, 如果引发的异常与 except 中的异常组匹配, 执行相
应的语句。如果所有的 except 都不匹配,则异常会传递到下一个调用本代码的
最高层 try 代码中。
try 下的语句正常执行,则执行 else 块代码。如果发生异常,就不会执行
如果存在 finally 语句,最后总是会执行。
37.Python 中 pass 语句的作用是什么?
答: pass 语句不会执行任何操作,一般作为占位符或者创建占位程序,
whileFalse:pass
38. 介绍一下 Python 下 range() 函数的用法?
答:列出一组数据,经常用在 for in range() 循环中
39. 如何用 Python 来进行查询和替换一个文本字符
串?
答:可以使用 re 模块中的 sub() 函数或者 subn() 函数来进行查询和替换,
格式:sub(replacement, string[,count=0]) (replacement 是被替换成的文本,
55
string 是需要被替换的文本, count 是一个可选参数,指最大被替换的数量)
import re
p=re.compile( ‘blue|white|red ’)
print(p.sub( ‘colour ’,'blue socks and red shoes ’))
colour socks and colourshoesprint(p.sub( ‘colour ’,'blue socks and red shoes ’,count=1))
colour socks and redshoes
subn() 方法执行的效果跟 sub() 一样,不过它会返回一个二维数组,包括替换后
的新的字符串和总共替换的数量
40.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 ’))
Noneprint(re.search( ‘super ’, ‘superstition ’).span())
(0, 5)
56print(re.search( ‘super ’, ‘insuperable ’).span())
(2, 7)
cProfile.run(‘f1(lIn)’)
4 function calls in 0.045 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.009 0.009 0.044 0.044 :1(f1)
1 0.001 0.001 0.045 0.045 :1()
1 0.000 0.000 0.000 0.000 {method ‘disable’ of
‘_lsprof.Profiler’ objects}
1 0.035 0.035 0.035 0.035 {sorted}cProfile.run(‘f2(lIn)’)
4 function calls in 0.024 seconds
61
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.008 0.008 0.023 0.023 :1(f2)
1 0.001 0.001 0.024 0.024 :1()
1 0.000 0.000 0.000 0.000 {method ‘disable’ of
‘_lsprof.Profiler’ objects}
1 0.016 0.016 0.016 0.016 {sorted}cProfile.run(‘f3(lIn)’)
4 function calls in 0.055 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.016 0.016 0.054 0.054 :1(f3)
1 0.001 0.001 0.055 0.055 :1()
1 0.000 0.000 0.000 0.000 {method ‘disable’ of
‘_lsprof.Profiler’ objects}
1 0.038 0.038 0.038 0.038 {sorted}
62
为什么提这个问题?
定位并避免代码瓶颈是非常有价值的技能。 想要编写许多高效的代码, 最终都要
回答常识上来——在上面的例子中,如果列表较小的话,很明显是先进行排序
更快,因此如果你可以在排序前先进行筛选, 那通常都是比较好的做法。 其他不
显而易见的问题仍然可以通过恰当的工具来定位。因此了解这些工具是有好处
的。
defswapPairs(self,head):
ifhead!=Noneandhead.next!=None:
next=head.next
head.next=self.swapPairs(next.next)
next.next=head
returnnext
returnhead
7 创建字典的方法
1 直接创建
1 dict={‘name’:‘earth’,‘port’:‘80’}
2 工厂方法
1
2
3
items=[(‘name’,‘earth’),(‘port’,‘80’)]
dict2=dict(items)
dict1=dict(([‘name’,‘earth’],[‘port’,‘80’]))
82
3 fromkeys() 方法
1
2
3
4
dict1={}.fromkeys((‘x’,‘y’),-1)
dict={‘x’:-1,‘y’:-1}
dict2={}.fromkeys((‘x’,‘y’))
dict2={‘x’:None,‘y’:None}
8 合并两个有序列表
知乎远程面试要求编程
尾递归
def_recursion_merge_sort2(l1,l2,tmp):
iflen(l1)==0orlen(l2)==0:
tmp.extend(l1)
tmp.extend(l2)
returntmp
else:
ifl1[0]<l2[0]:
tmp.append(l1[0])
dell1[0]
else:
tmp.append(l2[0])
dell2[0]
return_recursion_merge_sort2(l1,l2,tmp)
defrecursion_merge_sort2(l1,l2):
return_recursion_merge_sort2(l1,l2,[])
循环算法
defloop_merge_sort(l1,l2):
tmp=[]
whilelen(l1)>0andlen(l2)>0:
ifl1[0]<l2[0]:
tmp.append(l1[0])
dell1[0]
else:
tmp.append(l2[0])
dell2[0]
83
tmp.extend(l1)
tmp.extend(l2)
returntmp
9 交叉链表求交点
去哪儿的面试 ,没做出来 .
classListNode:
def__init__(self,x):
self.val=x
self.next=None
defnode(l1,l2):
length1,lenth2=0,0
whilel1.next:
l1=l1.next
length1+=1
whilel2.next:
l2=l2.next
length2+=1
iflength1>lenth2:
for_inrange(length1-length2):
l1=l1.next
else:
for_inrange(length2-length1):
l2=l2.next
whilel1 andl2:
ifl1.nextl2.next:
returnl1.next
else:
l1=l1.next
l2=l2.next
10 二分查找
defbinarySearch(l,t):
low,high=0,len(l)-1
whilelow<high:
printlow,high
84
mid=(low+high)/2
ifl[mid]>t:
high=mid
elifl[mid]<t:
low=mid+1
else:
returnmid
returnlow ifl[low]telseFalse
if__name__‘main’:
l=[1,4,12,45,66,99,120,444]
printbinarySearch(l,12)
printbinarySearch(l,1)
printbinarySearch(l,13)
printbinarySearch(l,444)
11 快排
1
2
3
4
5
6
7
8
9
10
11
12
defqsort(seq):
ifseq[]:
return[]
else:
pivot=seq[0]
lesser=qsort([xforxinseq[1:]ifx<pivot])
greater=qsort([xforxinseq[1:]ifx>=pivot])
returnlesser+[pivot]+greater
if__name__‘main’:
seq=[5,6,78,9,0,-1,2,3,-65,12]
print(qsort(seq))
12 找零问题
def coinChange(values,money,coinsUsed):
#values T[1:n] 数组
#valuesCounts 钱币对应的种类数
#money 找出来的总钱数
#coinsUsed 对应于目前钱币总数 i 所使用的硬币数目
forcents inrange(1,money+1):
minCoins=cents #从第一个开始到 money 的所有情况初始
forvalue invalues:
ifvalue<=cents:
temp=coinsUsed[cents-value]+1
85
iftemp<minCoins:
minCoins=temp
coinsUsed[cents]=minCoins
print(’ 面值为: {0} 的最小硬币数目为: {1} '.format(cents,coinsUsed[cents]))
if__name__‘main’:
values=[25,21,10,5,1]
money=63
coinsUsed={i:0foriinrange(money+1)}
coinChange(values,money,coinsUsed)
13 广度遍历和深度遍历二叉树
给定一个数组,构建二叉树,并且按层次打印这个二叉树
classNode(object):
def__init__(self,data,left=None,right=None):
self.data=data
self.left=left
self.right=right
tree=Node(1,Node(3,Node(7,Node(0)),Node(6)),Node(2,Node(5),Node(4)))
deflookup(root):
stack=[root]
whilestack:
current=stack.pop(0)
printcurrent.data
ifcurrent.left:
stack.append(current.left)
ifcurrent.right:
stack.append(current.right)
defdeep(root):
ifnotroot:
return
printroot.data
deep(root.left)
deep(root.right)
if__name__‘main’:
86
lookup(tree)
deep(tree)
17 前中后序遍历
深度遍历改变顺序就 OK 了
18 求最大树深
1
2
3
4
defmaxDepth(root):
ifnotroot:
return0
returnmax(maxDepth(root.left),maxDepth(root.right))+1
19 求两棵树是否相同
1
2
3
4
5
6
7
defisSameTree(p,q):
ifpNoneandqNone:
returnTrue
elifpandq:
returnp.valq.val andisSameTree(p.left,q.left)andisSameTree(p.right,q.right)
else:
returnFalse
20 前序中序求后序
defrebuild(pre,center):
ifnotpre:
return
cur=Node(pre[0])
index=center.index(pre[0])
cur.left=rebuild(pre[1:index+1],center[:index])
cur.right=rebuild(pre[index+1:],center[index+1:])
returncur
defdeep(root):
ifnotroot:
return
deep(root.left)
deep(root.right)
87
printroot.data
21 单链表逆置
classNode(object):
def__init__(self,data=None,next=None):
self.data=data
self.next=next
link=Node(1,Node(2,Node(3,Node(4,Node(5,Node(6,Node(7,Node(8,Node(9)))))))))
defrev(link):
pre=link
cur=link.next
pre.next=None
whilecur:
tmp=cur.next
cur.next=pre
pre=cur
cur=tmp
returnpre
root=rev(link)
whileroot:
printroot.data
root=root.next
Python Web 相关
解释一下 WSGI 和 FastCGI 的关系?
CGI 全称是“公共网关接口” (CommonGateway Interface) ,HTTP 服务器与你的
或其它机器上的程序进行 “交谈”的一种工具,其程序须运行在网络服务器上。 CGI
可以用任何一种语言编写,只要这种语言具有标准输入、输出和环境变量。如
php,perl,tcl 等。
88
FastCGI 像是一个常驻 (long-live) 型的 CGI,它可以一直执行着,只要激活后,不
会每次都要花费时间去 fork 一次 (这是 CGI 最为人诟病的 fork-and-execute 模式 )。
它还支持分布式的运算 , 即 FastCGI 程序可以在网站服务器以外的主机上执行并
且接受来自其它网站服务器来的请求。
FastCGI 是语言无关的、 可伸缩架构的 CGI 开放扩展, 其主要行为是将 CGI 解释器
进程保持在内存中并因此获得较高的性能。 众所周知,CGI 解释器的反复加载是 CGI
性能低下的主要原因, 如果 CGI 解释器保持在内存中并接受 FastCGI 进程管理器调
度,则可以提供良好的性能、伸缩性、 Fail- Over 特性等等。
WSGI 的全称为: PythonWeb Server Gateway Interface v1.0 (Python Web 服
务器网关接口),
它是 Python 应用程序和 WEB 服务器之间的一种接口。
它的作用,类似于 FCGI 或 FASTCGI 之类的协议的作用。
WSGI 的目标,是要建立一个简单的普遍适用的服务器与 WEB 框架之间的接口。
Flup 就是使用 Python 语言对 WSGI 的一种实现,是可以用于 Python 的应用
开发中的一种工具或者说是一种库。
Spawn-fcgi 是一个小程序,这个程序的作用是管理 fast-cgi 进程,那么管理 wsgi
进程也是没有问题的,功能和 php-fpm 类似。
89
故,简单地说, WSGI 和 FastCGI 都是一种 CGI,用于连接 WEB 服务器与应用程
序,而 WSGI 专指 Python 应用程序。而 flup 是 WSGI 的一种实现, Spawn-fcgi
是用于管理 flup 进程的一个工具,可以启动多个 wsgi 进程,并管理它们。
解释一下 Django 和 Tornado 的关系、差别
Django 源自一个在线新闻 Web 站点,于 2005 年以开源的形式被释放出来。
Django 框架的核心组件有:
用于创建模型的对象关系映射为最终用户设计的完美管理界面一流的 URL 设计设
计者友好的模板语言缓存系统等等
它鼓励快速开发 ,并遵循 MVC 设计。 Django 遵守 BSD 版权,最新发行版本是
Django
1.4,于 2012 年 03 月 23 日发布 .Django 的主要目的是简便、 快速的开发数据库驱
动的网站。 它强调代码复用 ,多个组件可以很方便的以 “插件” 形式服务于整个框架,
Django 有许多功能强大的第三方插件,你甚至可以很方便的开发出自己的工具包。
这使得 Django 具有很强的可扩展性。它还强调快速开发和 DRY(Do Not
RepeatYourself) 原则。
Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的
开源版本。 这个 Web 框架看起来有些像 web.py 或者 Google 的 webapp ,不
过为了能有效利用非阻塞式服务器环境,这个 Web 框架还包含了一些相关的有用
工具和优化。
90
Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明
显的区别:它是非阻塞式服务器,而且速度相当快。得利于其 非阻塞的方式和对
epoll 的运用, Tornado 每秒可以处理数以千计的连接,这意味着对于实时 Web
服务来说, Tornado 是一个理想的 Web 框架。我们开发这个 Web 服务器的主
要目的就是为了处理 FriendFeed 的实时功能 ——在 FriendFeed 的应用里每
一个活动用户都会保持着一个服务器连接。 (关于如何扩容 服务器, 以处理数以千
计的客户端的连接的问题。
解释下 django-debug-toolbar 的使用
使用 django 开发站点时,可以使用 django-debug-toolbar 来进行调试。在
settings.py 中添加’ debug_toolbar.middleware.DebugToolbarMiddleware ’
到项目的 MIDDLEWARE_CLASSES 内。
解释下 Django 使用 redis 缓存服务器
为了能在 Django 中使用 redis ,还需要安装 redis for Django 的插件。然后在
Django 的 settings 中配置了。现在连接和配置都已经完成了,接下来是一个简单
的例子:
from django.conf import settings
from django.core.cache import cache
#read cache user id
def read_from_cache(self,user_name):
key=‘user_id_of_’+user_name
value=cache.get(key)
ifvalue==None:
data=None
else:
91
data=json.loads(value)
returndata
#write cache user id
def write_to_cache(self,user_name):
key=‘user_id_of_’+user_name
cache.set(key,json.dumps(user_name),settings.NEVER_REDIS_TIMEOUT)
如何进行 Django 单元测试
Django 的单元测试使用 python 的 unittest 模块,这个模块
使用基于类的方法来定义测试。 类名为 django.test.TestCase,
继承于 python 的 unittest.TestCase 。
from django.test import TestCase
from myapp.models import Animal
classAnimalTestCase(TestCase):
def setUp(self):
Animal.objects.create(name=“lion”,sound=“roar”)
Animal.objects.create(name=“cat”,sound=“meow”)
def test_animals_can_speak(self):
“”“Animals that can speak are correctly identified”""
lion=Animal.objects.get(name=“lion”)
cat=Animal.objects.get(name=“cat”)
self.assertEqual(lion.speak(),‘The lion says “roar”’)
self.assertEqual(cat.speak(),‘The cat says “meow”’)
执行目录下所有的测试 (所有的 test*.py 文件 ):运行测试的时候,测试程序会在所
有以 test 开头的文件中查找所有的 test cases(inittest.TestCase 的子类 ),自动建立
测试集然后运行测试。
1 $python manage.py test
92
执行 animals 项目下 tests 包里的测试:
$python manage.py testanimals.tests
执行 animals 项目里的 test 测试:
1 $python manage.py testanimals
单独执行某个 test case :
1 $python manage.py testanimals.tests.AnimalTestCase
单独执行某个测试方法:
1 $python manage.py testanimals.tests.AnimalTestCase.test_animals_can_speak
为测试文件提供路径:
1 $python manage.py testanimals/
通配测试文件名:
1 $python manage.py test–pattern=“tests_*.py”
93
启用 warnings 提醒:
1 $python-Wall manage.py test
解释下 Http 协议
HTTP 是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分
布式超媒体信息系统。
HTTP 协议的主要特点可概括如下:
1.支持客户 / 服务器模式。
2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用
的有 GET、HEAD 、POST。每种方法规定了客户与服务器联系的类型不同。由于
HTTP 协议简单,使得 HTTP 服务器的程序规模小,因而通信速度很快。
3.灵活: HTTP 允许传输任意类型的数据对象。正在传输的类型由 Content-Type
加以标记。
4.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请
求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
5.无状态: HTTP 协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。
缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次
连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
94
解释下 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 是在浏览器中寄存的小
型数据体,它可以记载和服务器相关的用户信息,也可以用来实现会话功能。
95
状态代码有三位数字组成,第一个数字定义了响应的类别,且有五种可能取值:
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 // 服务器当前不能处理客户端的请求, 一段时间后可能恢
复正常
96
eg :HTTP/1.1 200 OK (CRLF)
爬虫
一、试列出至少三种目前流行的大型数据库的名称 :________、
、_, 其中您最熟悉的是 __________, 从__________年开
始使用。
Oracle ,Mysql ,SQLServer Oracle 根据自己情况
二、有表 List,并有字段 A、B、C,类型都是整数。表中有如下几条
记录:
A B C
2 7 9
5 6 4
3 11 9
现在对该表一次完成以下操作:
查询出 B 和 C 列的值,要求按 B 列升序排列
写出一条新的记录,值为 {7,9,8}
查询 C 列,要求消除重复的值,按降序排列
写出完成完成以上操作的标准的 SQL 语句,并且写出操作 3 的结果。
create table List(A int,B int,C int)
97
Select B,C from List order by B
Insert into List values(7,9,8)
Select distinct© from List order by desc;
984
三、请简要说明视图的作用
1.数据库视图隐藏了数据的复杂性。
2.数据库视图有利于控制用户对表中某些列的访问。
3.数据库视图使用户查询变得简单。
四、列举您使用过的 python 网络爬虫所用到的网络数据包(最熟悉
的在前):
requests 、urllib 、urllib2 、httplib2
五、列举您使用过的 python 网络爬虫所用到的解析数据包(最熟悉
的在前):
BeautifulSoup 、pyquery 、Xpath 、lxml
六、列举您使用过的 python 中的编码方式(最熟悉的在前):
UTF-8 ,ASCII,gbk
七、python3.5 语言中 enumerate 的意思是 _______________________
98
对于一个可迭代的( iterable )/可遍历的对象(如列表、字符串),
enumerate 将其组成一个索引序列,利用它可以同时获得索引和值
enumerate 多用于在 for 循环中得到计数
八、99 的八进制表示是 _______________________
143
九、请举出三种常用的排序算法
冒泡、选择、快速
十、列出比较熟悉的爬虫框架
Scrapy
十一、用 4、9、2、7 四个数字,可以使用 + 、-、
*和/ ,每个数字使
用 一 次 , 使 表 达 式 的 结 果 为 24 , 表 达 式 是
(9+7-4 )*2
十二、对你最有影响的或是您认为最有价值的软件方面的几本书是?
十三、您最熟悉的 Unix 环境是 _____________.Unix下查询环境变量的
命令是 ________,查询脚本定时任务的命令是 ____________________
1AIX ,envcrontab
十四、写出在网络爬虫爬取数据的过程中, 遇到的防爬虫问题的解决
方案
通过 headers 反爬虫:解决策略,伪造 headers
基于用户行为反爬虫:动态变化去爬取数据,模拟普通用户的行为
99
基于动态页面的反爬虫:跟踪服务器发送的 ajax 请求,模拟 ajax 请
求
十五、阅读以下 Python 程序
foriinrange(5,0,-1):
print(i)
请在下面写出打印结果
54321
十六、在某系统中一个整数占用两个八位字节,使用 Python 按下面
的要求编写完整程序。
接收从标准输入中依次输入的五个数字, 将其组合成为一个整数, 放
入全局变量 n 中,随后在标准输出输出这个整数。( ord(char) 获取
字符 ASCII 值的函数)
人,从刚出生来到这个世界,便开始探索这个世界。累了就歇会,精
神了就继续探索,直至死亡。
100
python 面试题总结
101
1.Python 线程池原理?
我理解为线程池是一个存放很多线程的单位,同时还有一个对应的任务队列。
整个执行过程其实就是使用线程池中已有有限的线程把任务队列中的任务做完。
这样做的好处就是你不需要为每个任务都创建一个线程,因为当你创建第 100
个线程来执行第 100 个任务的时候,可能前面已经有 50 个线 程结束工作了。
超过最大值的线程可以排队, 但他们要等到其他线程完成后才启动 。因此重复利
用线程来执行任务,减少系统资源的开销。
2.Python 合并字典,相同 key 的 value 如何相加?
利用 collections.Counter可轻松办到
x = { ‘apple’: 1, ‘banana’: 2 }
y = { ‘banana’: 10, ‘pear’: 11 }
from collections import Counter
X,Y = Counter (x), Counter(y)
z = dict( X+Y)
z
{‘apple’: 1, ‘banana’: 12, ‘pear’: 11}
另一种写法from collections import Counter
dict( Counter (x)+Counter(y))
( 合并两个字典的方法
方法 1:
dictMerged1=dict(dict1.items()+dict2.items())
方法 2:
dictMerged2=dict(dict1, **dict2)
方法 2 等同于:
dictMerged=dict1.copy()
dictMerged.update(dict2)
或者
dictMerged=dict(dict1)
dictMerged.update(dict2)
3.解释 GUI 和 GPL?
GUI图形用户 界面(Graphical User Interface ,简称 GUI,又称图形 用户
接口 )是指采用图形方式显示的计算机操作用户 界面。
102
GPL(GNU通用公共许可证 )
GPL 同其它的自由软件许可证一样,许可社会公众享有:运行、复制软件的自
由,发行传播软件的自由, 获得软件源码的自由, 改进软件并将自己作出的改进
版本向社会发行传播的自由。
4.简述爬虫的基本步骤和流程?
网络爬虫的基本工作流程如下:
1.首先选取一部分精心挑选的 URL;
2.将这些 URL 放入待抓取 URL 队列;
3.从待抓取 URL 队列中取出待抓取在 URL,(解析 DNS,并且得到主机的 ip,)
并将 URL 对应的网页下载下来, 存储进已下载网页库中。 此外,将这些 URL 放
进已抓取 URL 队列。
4.分析已抓取 URL 队列中的 URL 和其中的有价值的数据,将新的 URL,放
入待抓取 URL 队列,将数据存储起来,从而进入下一个循环。
5.你们公司的业务中,并发能达到多少?
print 1.2-1.0 == 0.2
False
A. The realization of Python error #Python的实现错误
B. Float could not be accurately expressed #浮点数不能准确表达
C. Boolean operation can not be used for floating-data type compar
#布尔运算不能用于浮点数据类型进行了
D. Python will be non-zero number as False
#Python 将非零数字是错误的
111
27.what would the following code yield? ()
( 下面的代码会产生什么 )word = ,abcdefghij?
print word[:3] + word[3:]
abcdefghij
28.Create a new list that converts the following list(num_string) of number string to a
list of number?
(创建一个新的列表,将列表( num_string)数的字符串列表的数字 )
Note:Please use List Comprehension Expression
(注意:请使用列表理解表达式 )num_strings = [,1?,?21?,?53?,?84?,?50?,?66?,?7?,?38?,?9?]
New_num = [ int(i) for i in num_strings ]
29.what will be the output of the following?
(写出下面的输出 )def func(x,*y,**z) :
Print zfunc(1,2,3)
答:{}
30.How to import method A and B from module M.
(如何从模块 M 导入方法 A 和 B)
from M import A , B
31.How to print “This program can print hello world on screen. ”
(如何打印出 “This program can print hello world on screen. ”)
def printHello():
,??This program can print hello world on screen???
Print “helloworld ”
答:printHello.doc
32.建立一个用于下载文件的线程池,活动线程数为 5.
112
Download_urls = [
“http://test.com/test1.txt ”,
“http://test.com/test2.txt ”,
“http://test.com/test3.txt ”,
]
33.有多少种设计模式,实现其中一个设计模式?
设计模式 共 23 种 分三类
设计模式主要分三个类型 :创建型、结构型和行为型。
其中
创建型 有:
一、 Singleton ,单例模式:保证一个类只有一个实例,并提供一个访问它的全局访问点
二、 Abstract Factory ,抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,而无须指
定它们的具体类。
三、 Factory Method ,工厂方法:定义一个用于创建对象的接口,让子类决定实例化哪一个类,
Factory Method 使一个类的实例化延迟到了子类。
四、 Builder ,建造模式:将一个复杂对象的构建与他的表示相分离,使得同样的构建过程可以
创建不同的表示。
五、 Prototype ,原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型来创建新
的对象。
行为型 有:
六、 Iterator ,迭代器模式:提供一个方法顺序访问一个聚合对象的各个元素,而又不需要暴露
该对象的内部表示。
七、 Observer ,观察者模式:定义对象间一对多的依赖关系,当一个对象的状态发生改变时,
所有依赖于它的对象都得到通知自动更新。
八、 Template Method ,模板方法:定义一个操作中的算法的骨架,而将一些步骤延迟到子类
中, TemplateMethod 使得子类可以不改变一个算法的结构即可以重定义该算法得某些特定步
骤。
九、Command ,命令模式:将一个请求封装为一个对象,从而使你可以用不同的请求对客户进
行参数化,对请求排队和记录请求日志,以及支持可撤销的操作。
十、 State ,状态模式:允许对象在其内部状态改变时改变他的行为。对象看起来似乎改变了他
的类。
十一、 Strategy ,策略模式:定义一系列的算法,把他们一个个封装起来,并使他们可以互相替
换,本模式使得算法可以独立于使用它们的客户。
113
十二、 China of Responsibility ,职责链模式:使多个对象都有机会处理请求,从而避免请求的
送发者和接收者之间的耦合关系
十三、 Mediator ,中介者模式:用一个中介对象封装一些列的对象交互。
十四、 Visitor ,访问者模式:表示一个作用于某对象结构中的各元素的操作,它使你可以在不
改变各元素类的前提下定义作用于这个元素的新操作。
十五、 Interpreter ,解释器模式: 给定一个语言, 定义他的文法的一个表示, 并定义一个解释器,
这个解释器使用该表示来解释语言中的句子。
十六、 Memento ,备忘录模式:在不破坏对象的前提下,捕获一个对象的内部状态,并在该对
象之外保存这个状态。
结构型 有:
十七、 Composite ,组合模式:将对象组合成树形结构以表示部分整体的关系, Composite 使
得用户对单个对象和组合对象的使用具有一致性。
十八、Facade ,外观模式: 为子系统中的一组接口提供一致的界面, fa?ade 提供了一高层接口,
这个接口使得子系统更容易使用。
十九、 Proxy ,代理模式:为其他对象提供一种代理以控制对这个对象的访问
二十、 Adapter, 适配器模式:将一类的接口转换成客户希望的另外一个接口, Adapter 模式使得
原本由于接口不兼容而不能一起工作那些类可以一起工作。
二十一、 Decrator ,装饰模式:动态地给一个对象增加一些额外的职责,就增加的功能来说,
Decorator 模式相比生成子类更加灵活。
二十二、 Bridge ,桥模式:将抽象部分与它的实现部分相分离,使他们可以独立的变化。
二十三、 Flyweight ,享元模式: 使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽
可能多的相似物件; 它适合用于当大量物件只是重复因而导致无法令人接受的使用大量内存。 通
常物件中的部分状态是可以分享。 常见做法是把它们放在外部数据结构, 当需要使用时再将它们
传递给享元。
代理模式 ,Python 实现:
class Interface :
def Request(self):
return 0
class RealSubject(Interface):
def Request(self):
print “Real request.”
class Proxy(Interface):
def Request(self):
self.real = RealSubject()
self.real.Request()
if name == “main” :
p = Proxy()
114
p.Request()
34.用匿名函数写一个功能?
print (lambda x:x*x)(4)
a = [1,2,3,4,5,6,7]
b = filter(lambda x: x > 5, a)
print b
[6,7]
map 函数是对一个序列的每个项依次执行函数,下面是对一个序列每个项都乘以 2:a = map(lambda x:x*2,[1,2,3])
list(a)
[2, 4, 6]
reduce 函数是对一个序列的每个项迭代调用函数,下面是求 3 的阶乘:reduce(lambda x,y:xy,range(1,4))
6
Python 里的拷贝
引用和 copy(),deepcopy() 的区别
import copy
a = [1, 2, 3, 4, [‘a’, ‘b’]] #原始对象
b = a #赋值,传对象的引用
c = copy.copy(a) #对象拷贝,浅拷贝
d = copy.deepcopy(a) #对象拷贝,深拷贝
a.append(5) #修改对象 a
a[4].append(‘c’) #修改对象 a 中的 [‘a’, ‘b’] 数组对象
print 'a = ', a
print 'b = ', b
print 'c = ', c
print 'd = ', d
输出结果:
122
a = [1, 2, 3, 4, [‘a’, ‘b’, ‘c’], 5]
b = [1, 2, 3, 4, [‘a’, ‘b’, ‘c’], 5]
c = [1, 2, 3, 4, [‘a’, ‘b’, ‘c’]]
d = [1, 2, 3, 4, [‘a’, ‘b’]]
Python 垃圾回收机制
Python GC 主要使用引用计数( reference counting )来跟踪和回收垃圾。在引用计数
的基础上,通过 “标记 -清除 ”(mark and sweep )解决容器对象可能产生的循环引用问
题,通过 “分代回收 ”(generation collection )以空间换时间的方法提高垃圾回收效率。
1 引用计数
PyObject 是每个对象必有的内容,其中 ob_refcnt 就是做为引用计数。当一个对象有新
的引用时,它的 ob_refcnt 就会增加,当引用它的对象被删除,它的 ob_refcnt 就会减
少.引用计数为 0 时,该对象生命就结束了。
优点 :
简单
实时性
缺点 :
维护引用计数消耗资源
循环引用
标记 -清除机制
基本思路是先按需分配, 等到没有空闲内存的时候从寄存器和程序栈上的引用出发,遍
历以对象为节点、以引用为边构成的图,把所有可以访问到的对象打上标记,然后清扫
一遍内存空间,把所有没标记的对象释放。
分代技术
123
分代回收的整体思想是: 将系统中的所有内存块根据其存活时间划分为不同的集合,每
个集合就成为一个 “代 ”,垃圾收集频率随着 “代”的存活时间的增大而减小,存活时间通
常利用经过几次垃圾回收来度量。
Python 默认定义了三代对象集合,索引数越大,对象存活时间越长。
举例: 当某些内存块 M 经过了 3 次垃圾收集的清洗之后还存活时,我们就将内存块 M
划到一个集合 A 中去,而新分配的内存都划分到集合 B 中去。当垃圾收集开始工作时,
大多数情况都只对集合 B 进行垃圾回收,而对集合 A 进行垃圾回收要隔相当长一段时
间后才进行,这就使得垃圾收集机制需要处理的内存少了,效率自然就提高了。在这个
过程中, 集合 B 中的某些内存块由于存活时间长而会被转移到集合 A 中,当然,集合 A
中实际上也存在一些垃圾,这些垃圾的回收会因为这种分代的机制而被延迟。
Python 的 is
is 是对比地址 ,== 是对比值
HTTP 和 HTTPS
状态码 定义
1xx 报告 接收到请求,继续进程
2xx 成功 步骤成功接收,被理解,并被接受
3xx 重定向 为了完成请求 ,必须采取进一步措施
4xx 客户端出错 请求包括错的顺序或不能完成
5xx 服务器出错 服务器无法完成显然有效的请求
403: Forbidden 404: Not Found
Ajax
AJAX,Asynchronous JavaScript and XML (异步的 JavaScript 和 XML ), 是与在不重
新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术
去除列表中的重复元素
124
用集合
list(set(l))
用字典
l1 = [‘b’,‘c’,‘d’,‘b’,‘c’,‘a’,‘a’]
l2 = {}.fromkeys(l1).keys()
print l2
用字典并保持顺序
l1 = [‘b’,‘c’,‘d’,‘b’,‘c’,‘a’,‘a’]
l2 = list(set(l1))
l2.sort(key=l1.index)
print l2
列表推导式
l1 = [‘b’,‘c’,‘d’,‘b’,‘c’,‘a’,‘a’]
l2 = []
[l2.append(i) for i in l1 if not i in l2]
Linux Shell 笔试题
1.How to enable debug mode in shell scripts? (B)
(如何在 shell 脚本中启用调试模式 )
A. set + x
B. set - x
C. set debug
D. set –
注:set -x 与 set +x 指令
用于脚本调试。 set 是把它下面的命令打印到屏幕
set -x 是开启 set +x 是关闭 set -o 是查看 (xtrace) ,set 去追中一
段代码的显示情况。
执行 set -x 后,对整个脚本有效。
2.Display all lines that begin with the letter “A” from a file (B)
( 显示所有行开头字母 “ A”从一个文件中 )
A. Is A
125
B. Cat file|grep ^A
C. Cat file|grep A$
D. More |grep A*
3.What does this sign mean in the Shell script “$#”(B)
( 这个标志是什么意思在 Shell 脚本 ” KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲)(# 添加到 Shell 的参数个数 )
A. The return value of last command
#最后一个命令的返回值
B. The number of script arguments
#脚本参数的个数
C. All of the arguments values
#所有参数值
D. The script itself
#脚本本身
4.Which does console get after run following script command :(B)
(控制台获取在运行以下脚本命令后 )
echo -n Red && echo -n Go || echo -n Hat
A. RedHat
B. RedGo
C. RedHatGo
D. GoHat
5.Which of the following statements assign the name of the current directory to variab
le var? A C
(下列哪个陈述当前目录的名称分配给变量 var ? )
A. var=pwd
B. var= p w d C . v a r = {pwd} C. var= pwdC.var=(pwd)
D. var=@pwd
6.Which of the following answers state string s is of zero length?
A. [, s ? = “ ” ] B . [ “ s? = “”] B. [ “ s?=“”]B.[“s -eq””]
C. [!-n “ s ” ] D . [ − z “ s”] D. [ -z “ s”]D.[−z“s”]
7.Given a log file as follows:(A)
$cat a.log
1 5
2 6
126
3 7
4 8
What would the output of following command?
$awk ,{y=x+$0;x=$0};END{p rint y+NR}? a.log
A. 9
B. 11
C. 14
D. 30
Web 笔试
1.Javascript 的基本数据类型?
标签的
D.相邻选择器 h1 + p {margin-top:60px} 选择紧邻 h1后面的 p 元素
E.子选择器 h1 > p {} 选择 h1 的子元素 p
F.后代选择器 h1 em {} h1 元素中的所有 em 元素
G.通配符选择器 * {} 所有的元素
H.属性选择器 a[href] {color:red;}
2.display如下值的含义?
A.block 此元素为块级元素,此元素前后会带有换行符
B.none 此元素不会被显示
C.inline-block 行内块元素。
D.list-item 此元素会作为列表显示
3.postion如下值的含义?
A.absolute 生成绝对定位元素,相对于 static定位之外第一个父元素进行定位
B.fixed 生成绝对定位的元素,相对于浏览器窗口进行定位。
C.relative 生成相对定位的元素,相对其正常元素进行定位。
D.static 默认值,没有定位。
E.inherit 规定应该从父类继承 position 属性的值。
4.分别居中 div 和浮动元素
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。