【面试】:刷题总结

不点 阅读:249 2021-05-02 13:43:31 评论:0

面试题

1、到底什么是Python?

  • Python是一种解释型语言。这就是说,与C语言和C的衍生语言不同,Python代码在运行之前不需要编译(一边编写一边执行,先把代码转化成字节码,然后python虚拟机去执行)。其他解释型语言还包括PHP和Ruby
  • Python非常适合面向对象的编程(OOP),因为它支持通过组合(composition)与继承(inheritance)的方式定义类(class)
  • Python代码编写快,但是运行速度比编译语言通常要慢。好在Python允许加入基于C语言编写的扩展,因此我们能够优化代码,消除瓶颈,这点通常是可以实现的
  • Python用途非常广泛——网络应用,自动化,科学建模,大数据应用,爬虫等等。它也常被用作“胶水语言”,帮助其他语言和组件改善运行状况
  • Python让困难的事情变得容易,因此程序员可以专注于算法和数据结构的设计,而不用处理底层的细节

 2、补充缺失的代码

def print_directory_contents(sPath): 
    ''' 
   输入文件夹的路径(绝对和相对均可) 
   打印文件夹里面包含的所有文件名(子子孙孙,带完整的路径) 
    ''''
1 def print_directory_contents(sPath): 
2     import os 
3     for sChild in os.listdir(sPath): 
4         sChild = os.path.join(sPath,sChild) 
5         if os.path.isdir(sChild): 
6             print_directory_contents(sChild) 
7         else: 
8             print(sChild)
答案.

3、阅读下面的代码,写出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:i*i for i in A1}
  • A6 = [[i,i*i] 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] 
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]]
答案.

4、Python和多线程(multi-threading)。这是个好主意码?列举一些让Python代码以并行方式运行的方法

Python并不支持真正意义上的多线程。Python中提供了多线程包,但是如果你想通过多线程提高代码的速度,使用多线程包并不是个好主意。Python中有一个被称为Global Interpreter Lock(GIL)的东西,它会确保任何时候你的多个线程中,只有一个被执行。线程的执行速度非常之快,会让你误以为线程是并行执行的,但是实际上都是轮流执行。经过GIL这一道关卡处理,会增加执行的开销。这意味着,如果你想提高代码的运行速度,使用threading包并不是一个很好的方法。

不过还是有很多理由促使我们使用threading包的。如果你想同时执行一些任务,而且不考虑效率问题,那么使用这个包是完全没问题的,而且也很方便。但是大部分情况下,并不是这么一回事,你会希望把多线程的部分外包给操作系统完成(通过开启多个进程),或者是某些调用你的Python代码的外部程序(例如Spark或Hadoop),又或者是你的Python代码调用的其他代码(例如,你可以在Python中调用C函数,用于处理开销较大的多线程工作)。

为什么提这个问题

因为GIL就是个混账东西(A-hole)。很多人花费大量的时间,试图寻找自己多线程代码中的瓶颈,直到他们明白GIL的存在。

5、下面代码会输出什么:

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]
答案.

6、“猴子补丁”(monkey patching)指的是什么?这种做法好吗?

“猴子补丁”就是指,在函数或对象已经定义之后,再去改变它们的行为。

举个例子:

import datetime 
datetime.datetime.now = lambda: datetime.datetime(2012, 12, 12)

大部分情况下,这是种很不好的做法 - 因为函数在代码库中的行为最好是都保持一致。打“猴子补丁”的原因可能是为了测试。mock包对实现这个目的很有帮助。

7、这两个参数是什么意思:*args**kwargs?我们为什么要使用它们

如果我们不确定要往函数中传入多少个参数,或者我们想往函数中以列表和元组的形式传参数时,那就使要用*args;如果我们不知道要往函数中传入多少个关键词参数,或者想传入字典的值作为关键词参数时,那就要使用**kwargsargskwargs这两个标识符是约定俗成的用法,你当然还可以用*bob**billy,但是这样就并不太妥

8、阅读下面的代码,它的输出结果是什么?

class A(object): 
    def go(self): 
        print "go A go!" 
    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!" 
    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() 
 
a.stop() 
b.stop() 
c.stop() 
d.stop() 
e.stop() 
 
a.pause() 
b.pause() 
c.pause() 
d.pause() 
e.pause() 
输出结果以注释的形式表示: 
 
a.go() 
# go A go! 
 
b.go() 
# go A go! 
# go B go! 
 
c.go() 
# go A go! 
# go C go! 
 
d.go() 
# go A go! 
# go C go! 
# go B go! 
# go D go! 
 
e.go() 
# go A go! 
# go C go! 
# go B go! 
 
a.stop() 
# stop A stop! 
 
b.stop() 
# stop A stop! 
 
c.stop() 
# stop A stop! 
# stop C stop! 
 
d.stop() 
# stop A stop! 
# stop C stop! 
# stop D stop! 
 
e.stop() 
# stop A stop! 
 
a.pause() 
# ... Exception: Not Implemented 
 
b.pause() 
# ... Exception: Not Implemented 
 
c.pause() 
# ... Exception: Not Implemented 
 
d.pause() 
# wait D wait! 
 
e.pause() 
# ...Exception: Not Implemented
答案

9、阅读下面的代码,它的输出结果是什么?

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: 
                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) 
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() 
 1 oRoot.print_all_1()会打印下面的结果: 
 2  
 3 <Node 'root'> 
 4 <Node 'child1'> 
 5 <Node 'child4'> 
 6 <Node 'child7'> 
 7 <Node 'child5'> 
 8 <Node 'child2'> 
 9 <Node 'child6'> 
10 <Node 'child10'> 
11 <Node 'child3'> 
12 <Node 'child8'> 
13 <Node 'child9'> 
14 oRoot.print_all_1()会打印下面的结果: 
15  
16 <Node 'root'> 
17 <Node 'child1'> 
18 <Node 'child2'> 
19 <Node 'child3'> 
20 <Node 'child4'> 
21 <Node 'child5'> 
22 <Node 'child6'> 
23 <Node 'child8'> 
24 <Node 'child9'> 
25 <Node 'child7'> 
26 <Node 'child10'>
答案.

10、简要描述Python的垃圾回收机制(garbage collection) 

  • Python在内存中存储了每个对象的引用计数(reference count)。如果计数值变成0,那么相应的对象就会小时,分配给该对象的内存就会释放出来用作他用。
  • 偶尔也会出现引用循环(reference cycle)。垃圾回收器会定时寻找这个循环,并将其回收。举个例子,假设有两个对象o1o2,而且符合o1.x == o2o2.x == o1这两个条件。如果o1o2没有其他代码引用,那么它们就不应该继续存在。但它们的引用计数都是1。
  • Python中使用了某些启发式算法(heuristics)来加速垃圾回收。例如,越晚创建的对象更有可能被回收。对象被创建之后,垃圾回收器会分配它们所属的代(generation)。每个对象都会被分配一个代,而被分配更年轻代的对象是优先被处理的。

  

  


标签:javaPython
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

发表评论
搜索
排行榜
KIKK导航

KIKK导航

关注我们