• Python面试题练习


    1、实现1--100之和

    1 #解答一
    2 print sum(xrange(101))
    3 
    4 #解答二
    5 s=0
    6 for i in xrange(101):
    7     s = s + i
    8 print s
    View Code

    2、如何在一个函数内部修改全局变量

    #coding=utf-8
    name = "ryan"   #全局变量
    def fun():
        country = "China" #局部变量
        print name
        global name     #声明全局变量
        name = "joe"    #修改全局变量
        print name
    fun() 
    print name
    View Code

    3、谈下GIL

    GIL是python的全局解释器锁,同一进程中假如有多个线程运行,一个线程在运行python程序的时候会霸占python解释器(加了一把锁即GIL),使该进程内的其他线程无法运行,等该线程运行完后其他线程才能运行。如果线程运行过程中遇到耗时操作,则解释器锁解开,使其他线程运行。所以在多线程中,线程的运行仍是有先后顺序的,并不是同时进行。
    多进程中因为每个进程都能被系统分配资源,相当于每个进程有了一个python解释器,所以多进程可以实现多个进程的同时运行,缺点是进程系统资源开销大。
    View Code

    4、实现列表去重的方法

    #coding=utf-8
    #解答一:使用Set集合
    a = [1,2,3,3,4,4,4]
    a = list(set(a))
    
    #解答二
    a = [1,2,3,3,4,4,4]
    b=[]
    for i in a:
        if i not in b:
            b.append(i)
    a=b
    
    #解答三
    a = [1,2,3,3,4,4,4]
    c={}
    for i in a:
        if a.count(i) > 1:
            c.update({a.count(i):i})
    for i in c:
        for j in xrange(i-1):
            a.remove(c[i])
    View Code

     5、fun(*args,**kwargs)中的*args,**kwargs什么意思?

    #*args是用来发送一个非键值对的可变数量的参数列表给一个函数
    #**kwargs是用来发送一个不定长度的键值对的参数给一个函数
    View Code

    6、python2和python3的range(100)的区别

    #python2返回列表,python3返回迭代器,节约内存
    View Code

    7、一句话解释什么样的语言能够用装饰器?

    #函数可以作为参数传递的语言,可以使用装饰器
    View Code

    8、简述面向对象中__new__和__init__区别

    9、简述with方法打开处理文件帮我我们做了什么?

    10、if __name__ == '__main__' 如何正确理解?

    #coding=utf-8
    '''
    对于很多编程语言来说,程序都必须要有一个入口,比如 C,C++,以及完全面向对象的编程语言 Java,C# 等。如果你接触过这些语言,对于程序入口这个概念应该很好理解,C 和 C++ 都需要有一个 main 函数来作为程序的入口,也就是程序的运行会从 main 函数开始。同样,Java 和 C# 必须要有一个包含 Main 方法的主类来作为程序入口。
    而 Python 则有不同,它属于脚本语言,不像编译型语言那样先将程序编译成二进制再运行,而是动态的逐行解释运行。也就是从脚本第一行开始运行,没有统一的入口。
    一个 Python 源码文件除了可以被直接运行外,还可以作为模块(也就是库)被导入。不管是导入还是直接运行,最顶层的代码都会被运行(Python 用缩进来区分代码层次)。而实际上在导入的时候,有一部分代码我们是不希望被运行的。
    '''
    
    #举一个例子来说明一下,假设我们有一个 const.py 文件,内容如下:
    PI = 3.14
    def main():
        print "PI:", PI
    main()
    
    '''
    我们在这个文件里边定义了一些常量,然后又写了一个 main 函数来输出定义的常量,最后运行 main 函数就相当于对定义做一遍人工检查,看看值设置的都对不对。然后我们直接执行该文件(python const.py),输出:
    PI: 3.14
    '''
    
    '''
    现在,我们有一个 area.py 文件,用于计算圆的面积,该文件里边需要用到 const.py 文件中的 PI 变量,那么我们从 const.py 中把 PI 变量导入到 area.py 中:
    '''
    
    from const import PI
    def calc_round_area(radius):
        return PI * (radius ** 2)
    def main():
        print "round area: ", calc_round_area(2)
    main()
    
    '''
    运行 area.py,输出结果:
    PI: 3.14
    round area:  12.56
    可以看到,const 中的 main 函数也被运行了,实际上我们是不希望它被运行,提供 main 也只是为了对常量定义进行下测试。这时,if __name__ == '__main__' 就派上了用场。把 const.py 改一下:
    '''
    
    PI = 3.14
    def main():
        print "PI:", PI
    if __name__ == "__main__":
        main()
    
    '''
    然后再运行 area.py,输出如下:
    round area:  12.56
    再运行下 const.py,输出如下:
    PI: 3.14
    这才是我们想要的效果。
    if __name__ == '__main__' 就相当于是 Python 模拟的程序入口。Python 本身并没有规定这么写,这只是一种编码习惯。由于模块之间相互引用,不同模块可能都有这样的定义,而入口程序只能有一个。到底哪个入口程序被选中,这取决于 __name__ 的值。
    '''
    #https://www.cnblogs.com/yaohong/p/8660209.html
    View Code

     11、深浅拷贝的区别

    #Python的数据结构总体分为两类:
    #1、字符串和数字
    #2、列表、元组、字典等
    
    一、字符串和数字
      对于字符串和数字而言,赋值(=)、浅拷贝(copy)和深拷贝(deepcopy)其实都没有意义,因为它们都永远指向同一个内存地址。
    >>> import copy
    >>> a1 = 100
    >>> id(a1)
    1426656816   # a1的内存地址
     
    # 赋值
    >>> a2 = a1
    >>> id(a2)
    1426656816
     
    # 浅拷贝
    >>> a3 = copy.copy(a1)
    >>> id(a3)
    1426656816
     
    # 深拷贝
    >>> a4 = copy.deepcopy(a1)
    >>> id(a4)
    1426656816
    
    二、列表、元组、字典等
      对于列表、字典而言,进行赋值(=)、浅拷贝(copy)和深拷贝(deepcopy),其引起的变化是不一样的。
    2.1、赋值(=) 
    names = ['Angle', 'Zous', 'Athena', ['Banana', 'apple']]
    name2 = names
    names[1] = "Pear"
    print(names)
    print(name2)
    print("-----------------")
    names[3][1] = "Dog"
    print(names)
    print(name2)
    print(id(names))
    print(id(name2))
     
     
    # 输出
    ['Angle', 'Pear', 'Athena', ['Banana', 'apple']]
    ['Angle', 'Pear', 'Athena', ['Banana', 'apple']]
    -----------------
    ['Angle', 'Pear', 'Athena', ['Banana', 'Dog']]
    ['Angle', 'Pear', 'Athena', ['Banana', 'Dog']]
    1504387406536
    1504387406536
     
    # 可以看到names 的每一次变化,name2也会改变,因为他们的内存地址是一样的
    #这和字符串和数字是不一样的,当我们定义 a =1 ,b = a ,改变a时,b是不会有变化的。列表和字典等会跟着变化,因为他们的内存地址是一样的。  
    a = 1
    b = a 
    a = 100
    print(a)
    print(b)
     
    # 输出
     
    100
    1
    
    2.2、浅拷贝(copy) 
    import copy
     
    names = ['Angle', 'Zous', 'Athena', ['Banana', 'apple']]
    name2 = copy.copy(names)
    names[1] = "宙斯"
    print(names, "names的内存地址是{}".format(id(names)))
    print(name2, "name2的内存地址是{}".format(id(name2)))
     
    #输出
    ['Angle', '宙斯', 'Athena', ['Banana', 'apple']] names的内存地址是1764417452744
    ['Angle', 'Zous', 'Athena', ['Banana', 'apple']] name2的内存地址是1764416035080
     
    我们浅copy了一个name2,同时我们将names中的Zous的值改为中文,但是name2的没有改变。因为他们的内存地址是不一样的,改变其中一个不影响另外一个。
    我们接下来看:
    import copy
     
    names = ['Angle', 'Zous', 'Athena', ['Banana', 'apple']]
    name2 = copy.copy(names)
    names[1] = "宙斯"
    print(names, "names的内存地址是{}".format(id(names)))
    print(name2, "name2的内存地址是{}".format(id(name2)))
     
    names[3][1] = '苹果'
    print(names, id(names[3]))
    print(name2, id(name2[3]))
     
    # 输出
    ['Angle', '宙斯', 'Athena', ['Banana', 'apple']] names的内存地址是2306153560776
    ['Angle', 'Zous', 'Athena', ['Banana', 'apple']] name2的内存地址是2306152155528
    ['Angle', '宙斯', 'Athena', ['Banana', '苹果']] 2306153648968
    ['Angle', 'Zous', 'Athena', ['Banana', '苹果']] 2306153648968
     
    # 这次我们不仅改变了最外层的列表的值,还改变了列表中一个列表的值。
    # 这次的结果是  里层的列表跟着做了改变
     我们通过打印的内存地址可以明显看出,整个外层列表的内存地址是不一样的,但是里层的列表内存地址是一致的。
    总结:浅拷贝(copy.copy(x))只是将列表等数据类型的第一层copy了一下,内存地址改变了。但是对于里层的数据类型的内存地址没有改变。
    
    2.3、深拷贝(deepcopy)
    深拷贝(copy.deepcopy(x))其实就是重新开辟了一个新的内存地址,存储deepcopy后的数据,和原来数据的内存地址完全不一样了,包括里层数据类型的内存地址。 
    import copy
     
    names = ['Angle', 'Zous', 'Athena', ['Banana', 'apple']]
    name2 = copy.deepcopy(names)
    names[1] = "宙斯"
    print(names, "names的内存地址是{}".format(id(names)))
    print(name2, "name2的内存地址是{}".format(id(name2)))
     
    names[3][1] = '苹果'
    print(names, id(names[3]))
    print(name2, id(name2[3]))
     
    #输出
    ['Angle', '宙斯', 'Athena', ['Banana', 'apple']] names的内存地址是2379824216776
    ['Angle', 'Zous', 'Athena', ['Banana', 'apple']] name2的内存地址是2379824217160
    ['Angle', '宙斯', 'Athena', ['Banana', '苹果']] 2379824304968
    ['Angle', 'Zous', 'Athena', ['Banana', 'apple']] 2379824305032
     
    #可以看出,names不论是改变外层还是里层列表的数据,都不会影响到name2。
    View Code

    链接: https://www.cnblogs.com/bigberg/p/7246756.html

  • 相关阅读:
    ubuntu sudo 号令有效处理
    shell脚本的主笔、存储、实行
    Oracle 11gR1中细粒度访谒收集处事(4)
    Solaris效力经管工具 SMF快速入门指南(1)
    Solaris 10完成宁静Kerberos身份验证(2)
    高质量C /C编程指南第2章 程序的版式
    Solaris 10下设置EJB 3.0景遇(1)
    高质量C /C编程指南序言
    Java学习之路:不走弯路,就是捷径 www.51testing.com
    两个结构体可以直接赋值吗? 回复 "JohnsonAnother" 的问题
  • 原文地址:https://www.cnblogs.com/windyrainy/p/10658404.html
Copyright © 2020-2023  润新知