zoukankan      html  css  js  c++  java
  • 基础篇--【python】面试题汇总

    1.尽可能多的列举PEP8规范有哪些?

    1.   不要在行尾加分号,也不要用分号将两条命令放在一行
    2.   每行不超过80个字符
    3.   不要使用反斜杠连接行
    4.   在注释中,如果有必要,将长的url放在一行
    5.   除非用于实现行连接,否则不要在返回语句或条件语句中使用括号
    6.   用4个空格代替代码缩进,不要使用TAB
    7.   顶级定义之间空2行,方法定义之间空1行

    2.ascii,unicode,utf-8,gbk的区别

      ascii 8位 一个字节

      unicode A:32位,四个字节  中文:32位,四个字节

      utf-8 A:8位,一个字节    中文:16位,两个字节

      gbk A:8位,一个字节   中文:16位,两个字节

      区别:

        1.各个编码之间的二进制是不能互相识别的

        2.文件的存储,传输,不能是unicode,只能是utf-8,gbk,ascii

      转换:

        encode str > bytes 编码

        decode bytes > str 解码

    3.python递归的最大层数是多少以及如何修改

      python默认递归最大数为1000,用于防止无限递归造成内存溢出奔溃

      修改方法:

        import sys

        sys.setrecursionlimit(1500)  

    4.字节码和机器码的区别

      字节码是一种中间状态的二进制代码,需要直译器转译后才能成为机器码

    5.三元运算符是什么

      三元运算符就是在赋值变量的时候,可以直接加判断

      res = a if a > b else b

    6.列举python2和python3的区别

      print : 2print语句,3print函数

      输入函数:2 input_raw() ,3 input()

      super(): 2 必须显示的在参数中写上基类,3直接无参数调用即可

      没有了int和long的区别

      编码:2 默认ascii,3默认utf-8

      字符串:

        2.unicode表示字符串序列,str表示字节序列

        3.str表示字符串序列,byte类型表示字节序列

      true和false:

        2.可以赋值和操作

        3.不可变

      迭代器:

        2.当中许多返回列表的方法,如range,字典对象的dict.keys(),dict.values()方法,map,filter,zip:并且迭代器必须实现next方法

        3.将返回列表的方法改为了返回迭代器对象,内置了__next__,不用特意去实现next

    7.用一行代码实现数值交换

      a,b = b,a

    8.xrange和range的区别

      range和xrange都是在循环中使用,输出结果一样

      range返回一个list对象,xrange返回一个生成器对象

      xrange每次调用返回其中的一个值,内存占用少,性能好

    9.字符串,列表,元组,字典各自常用的方法

    string:
        去掉空格和特殊符号:
        name1 = name.strip() #去掉两边空格
        name2 = name.lstrip() #去掉左边空格
        name3 = name.rstrip() #去掉右边空格
        搜索和替换:
        name.count("e") #查找某个字符在字符串中出现的次数
        name.capitalize() #首字母大写
        name.center(100,"-") #把字符串放中间,两边用-补齐到100
        name.find("a") #找到这个字符返回下标,存在多个返回第一个,不存在返回-1
        name.index("a") #找到这个字符返回下标,存在多个返回第一个,不存在报错
        print(name.replace(name,"123"))  #字符串的替换
        name.replace("abc","123") #返回一个替换后的字符串
        验证和替换函数:
        name.startswith("abc") #是否以abc开头
        name.endswith("abc") #是否以abc结尾
        name.isalnum() #是否全十字母和数字,并且至少包含一个字符
        name.isalpha() #是否全是字母,并且至少包含一个字符
        name.isdigit() #是否全是数字,并且至少包含一个字符
        name.isspace() #是否全是空白字符,并且至少包含一个支付
        name.islower() #是否全是小写
        name.isupper() #是否全是大写
        name.istitle() #是否首字母大写
        字符串的分割:
        name.split('') #默认按照空格进行分割,从前往后
        name.rsplit() #从后往前分割
    
        连接字符串:
        '.'.join(name) #用.号将一个可迭代的序列拼接起来
    
        切片:
    
        name1 = name[0:3] #截取第一位到第三位的字符
        name2 = name[:] #截取全部字符
        name3 = name[6:] #截取第6个字符到结尾
        name4 = name[:-3] #截取从开头到最后一个字符之前
        name5 = name[-1] #截取最后一个字符
        name6 = name[::-1] #创造一个与原字符串顺序相反的字符串
        name7 = name[:-5:-1] #逆序截取
    
    列表:
        列表的特性:
        有序集合,通过偏移来索引,从而读取数据,支持嵌套,可变类型
        
        创建列表:
        list1 = ["1","2","3","4"] #方法1
        list2 = list("1234") #方法2
    
        添加元素:
        末尾追加:
            list1.append(5)
        指定位置前面插入:
            list1.insert(2,6) #下标为2的前面插入6
        追加一个列表:
            list1.extend([7,8,9])
    
        遍历列表:
        直接遍历:
            for i in list1:
                print(i)
        带索引遍历:
            for index,i in enumerate(list1):
                print(i,index)
    
        通过下标取值:
        print(list1[2])
    
        删除元素:
        list1.remove() #参数object,删除靠前的重复元素,无重复返回None
        list1.pop() #可选参数 index,删除指定位置的元素,默认为最后一个元素
        del list1[1] #删除列表或者指定元素或者切片,删除后无法访问
    
        排序和反转代码:
        list1.reverse() #反转列表
        list1.sort() #排序
    
    字典:
        字典是无序的可变序列
        
        创建:
        空字典:
            dict1 = {} 
            dict2 = dict()
        值为None的字典:
            dict3 = dict.fromkeys(['a','b','c'])  ==> {'a':None,'b':None,'c':None}
        通过zip函数构建字典
            dict4 = dict(zip(keyslist,valueslist))
        通过赋值表达式元组构造字典
            dict5 = dict(name='bob',age=22) ==> {'name':'bob','age':22}
        成员关系:
        字典的成员关系只判断key,与value无关
        列出所有的健,值,键值对:
        dict6.keys() #键 返回的是可迭代对象
        dict7.values() #值 返回的是可迭代对象
        dict8.items() #键值对 返回的是可迭代对象
        拷贝一个字典的副本:
         dict9 = dict8.copy() #浅拷贝
         dict10 = dict8.deepcopy() #深拷贝
        根据键获取值,默认值default
              dict11 = dict12.get(key,default)
        合并更新字典
              dict13.updat(dict12)
        删除字典
              d.pop(key)
        新增或者修改键对应的值
              D[2] = value #如果存在则修改,不存在则创建
        获取字典键的列表,值的列表
              list(D.keys())
              list(D.values())
        字典推导式
              D = [x:x**2 for x in range(10) if x %2 == 0]
        字典使用事项
              序列运算无效,字典是映射机制
              对新索引的赋值会添加新的键值对
              键不一定总是字符串,但总是不可变对象
    
    元组:
        概述:
            任意对象的有序集合,可以通过序列取值
            元组不可变的序列的操作类型
            固定长度,异构,嵌套(元组里也可以包含元组)
        创建:
            空元组
                t1 = ()
                t2 = tuple()
            单个元素要加,
                x = (40,) ==>一个元组,具有一个元素的值是40
    
            多元素元组的表达方式
                t = (1,2,3) 
                t1 = 1,2,3 #括号可以省略
    
            用一个可迭代对象生产元组
                t = tuple('abc')
    
            元组的访问
                t[i] t[i][j]
    
            合并和重复
                t1 + t2
                t1 * 3
    
            迭代和成员关系
                for x in T:
                    print(x)
                'spam' in T
    
            对元组进行排序
                对元组排序,通常先得将它转换为列表并使得它成为一个可变对象,或者使用sorted方法,它接收任何序列对象
    
                T = ('c','a','b','d')
                tmp = list(T)
                tmp.sort() ==> ['a','b','c','d']
    
                T = tunple(tmp)
                sorted(T)
    
            为何有了列表还要用元组
                元组可以看成是简单得对象组合,而列表是随着时间而改变得数据集合
                元组得不可变性提供了某种完整性,这样可以确保元组不会被另外一个引用来修改
                元组类似其他语言中的常数声明
    
    集合
        创建:
            a = set()
            b = set(iterable) #用可迭代对象创建一个集合
        集合的运算:
                & 生成两个集合的交集 s3 = s1 & s2
                | 生成两个集合的并集 s3 = s1 | s2
                - 生成两个集合的补集 s3 = s1 - s2
                ^ 对称补集 s3 = s1 ^ s2 (只能属于s1或者s2,也就是去除掉s1和s2重合的部分)

    10.lambda表达式格式以及应用场景?    

      举例:
            from functools import reduce
            add = lambda x,y:x+y
            print(add(1,2)) # 输出3

        与map和用,遍历序列,对序列中每个元素进行操作,获取最终的新序列
            x = [11,22,33]
            print(list(map(lambda x:x=100,x))) #[111,122,133]

        与filter和用,对序列中的元素进行筛选,最终获取符合条件的序列
            x2 = [11,22,33]
            print(list(filter(lambda x:x>20,x)))

        与reduce和用,对序列内所有元素进行累计操作
            x3 = [1,2,3,4]
            print(reduce(lambda x1,x2:x1+x2,x3))

    11.*arg和**kwarg作用?    

      *arg和**kwarg都是用来传不固定个数的参数到函数中的    

      *arg :可以理解为只有一列的元组,长度不固定
         **kwarg:可以理解为字典,长度不固定。

        二者可以单独使用,或者组合使用,一起使用的时候,*arg要放在**kwarg之前。

    12.is和==的区别    

      python中对象包含的三个基本要素,分别是:
              id(身份标识)
              type(数据类型)
              value(值)
          对象之间判断是否相等就需要用到is 或者 ==:

            is 判断两个对象的id值是否相等,即两个对象是否指向同一个内存地址
            == 判断两个对象的值是否相等

    13.Python的赋值,深浅拷贝以及应用场景?

        import copy
        浅拷贝:copy.copy()
        深拷贝:copy.deepcopy()
        对于数字和字符串而言,赋值,深拷贝和浅拷贝无意义,因为其始终指向同一个内存地址。
        赋值:简单的拷贝对象的引用,两个对象的id相同
        浅拷贝指的是创建一个新的对象,仅仅拷贝数据集合的第一层数据,在内存中共享子对象
        深拷贝指的是创建一个新的组合对象,与原对象完全无关,真正独立。

    14.Python垃圾回收机制?

        python垃圾回收算法GC算法,分为以下三点:
            引用计数/标记-清除/分代回收

            引用计数
                对象在被方法引用的时候会自动计数加1,当引用该对象的对象被删除的时候,那么该对象的引用计数就会减少,一直到它的引用计数变为0,垃圾回收机制就会自动回收。

                优点:
                    简单实用
                缺点:
                    维护性高,需要占用额外的资源
                    不能解决循环引用的问题

                    循环引用:两个列表相互引用

            标记-清除
                标记-清除就是用来解决循环引用的问题的。
                未来追踪容器对象,需要每个容器对象维护两个额外的指针,root链表和unreachable链表。

                因为unreachable可能存在被root链表引用的可能,所以要在标记过程中发现并将其从unreachable链表中转移到root链表中,然后剩下的才做真正的回收。

            分代回收

                理论上讲,创建量应该与释放数量相等,但是如果存在循环引用,创建量就会大于释放量,如果这个差值超出了GC的阈值,那么分代回收机制就会启动。
                分代回收将对象分为三代:
                    0代表幼年对象
                    1代表青年对象
                    2代表老年对象

                如果在第0代的gc垃圾回收中存活下来,就会进入第1代,第2代同理;
                然后如果在上一次检查之后,第N代垃圾回收次数大于第N+1代,那么第N+1代就会做垃圾回收检查。

    15.一行代码实现9*9乘法表

        print (' '.join([' '.join(['%s*%s=%-2s' % (y,x,x*y) for y in range(1,x+1)]) for x in range(1,10)]))

    16.列举常见的内置函数?

        反射相关,总共4个
            hasattr 根据字符串的形式 , 去判断对象中是否有成员
            getattr 根据字符串的形式,去对象中找成员
            setattr 根据字符串的形式 , 动态的设置一个成员(在内存中)
            delattr 用于删除属性
                delattr(x, 'foobar') 相等于 del x.foobar
        基础数据类型相关,总共38个
            bool,int,float,complex(复数),bin(整型转换为二进制),oct(整型转换为八进制),hex(整型转换为十六进制),abs(求绝对值),divmod(除,余数),round(值,小数后几位),pow(幂运算),sum,max,min,list,tuple,reversed,slice,str,format,bytes,bytearry,memoryview,ord,chr,ascill,repr,dict,set(),frozenset,len,sorted,enumerate,all,any,zip,filter,map
        作用域相关
            locals 获取执行本方法所在命名空间内的局部变量的字典
            globals 获取全局变量的字典

        面向对象相关
            type 元类,类的最高层
            object
            classmethod  类方法,用来修改类变量
            staticmethod 类方法,用来处理一些和操作类无关的事
            propery    可以像调用一个变量一样调用一个方法
            vars
            super    在多继承中,可以保证顶层父类只被调用一次 ,用 _ _mro_ _ 查看多继承规律时,遵循深度优先原则
            issubclass    检查第一个参数是否是第二个参数的子子孙孙类  
            isinstance    检查第一个参数(对象) 是否是第二个参数(类及父类)的实例.
        迭代/生成器相关
            next
            iter
            range    range 是一个生成器,他只用来存储数据的生成方式,而不直接存储数据

        其他
            eval    将字符串类型的代码执行并返回结果
            exec    将自字符串类型的代码执行
            compile
            input
            print
            id
            hash
            open
            __import__
            help
            callable     检测一个对象能否被调用
            dir 查看内置属性和方法

    17.如何安装第三方模块?以及用过哪些第三方模块?

        pip install django  #通过pip安装
        pip install -i https://pypi.douban.com/simple django  #通过豆瓣源加速安装
        python setup.py build # 源码下载解压
        python setup.py install

        #常用第三方库
        pillow #图像相关的处理库
        Scrapy # 一个快速,高级的屏幕抓取以及web爬虫框架
        requests #一个关于http请求的优秀开源库
        beautifulsoup # xml和html的解析库,比较慢,效率很低

    18.re的match和search区别?

        match()函数只检测RE是不是在string的开始位置匹配,search()会扫描整个string查找匹配;

    19.什么是正则的贪婪匹配?

        总是尝试匹配尽可能多的字符,对应格式:xx*xx

    20.def func(a,b=[]) 这种写法有什么坑?

        函数的第二个默认参数是一个list,当第一次指向的时候实例化了一个list,第二次执行还是用第一次执行的时候实例化的地址存储。,默认参数应该设置为None

  • 相关阅读:
    3. 无重复字符的最长子串
    24. 两两交换链表中的节点
    2. 两数相加
    23. 合并K个排序链表
    synergy配置 Ubuntu作Server, Win 7作client
    ros与下位机通信常用的c++ boost串口应用
    tar
    发布里程计传感器信息
    ROS TF——learning tf
    在linux终端下打开pdf文件
  • 原文地址:https://www.cnblogs.com/bk770466199/p/12660098.html
Copyright © 2011-2022 走看看