Python面试重点(基础篇)

Posted tian-cai-1996

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python面试重点(基础篇)相关的知识,希望对你有一定的参考价值。

Python面试重点(基础篇)

第一部分 必答题

  1. 简述列举了解的编程语言及语言间的区别?

    python:解释型,简洁高效,容易上手
    java :混合型
    c
    c++
    c#
    go
    php
    ----------------------------------------------------------------
    编程语言分为解释型和编译型:
    解释型语言:   python
    在编写代码的时候不需要编译,在执行的时候,想要用专用的解释器对代码进行编译,全部编译后,才能执行代码
    编译型语言:   c c++   go
    每写一行代码,解释器就会编译一行,然后就可以执行了,编译后的代码不用再次编译
    java属于混合型语言
  1. 列举Python2和Python3的区别?

    -  python2 
    1.input 获取的就是数据本身
       2.源码不统一,重复代码
       3.除法的时候返回的是向下取整
       4.range()中打印返回的是一个列表
       5.int有整形和长整型
       6.二次编码用的是ascii
       7.只有 iter() next()
       8.python2中import包,如果包中没有__init__.py文件就报错
       9.多继承:全部都是经典类,经典类就是基类不继承object类
       10.python2中的不等于号可以是!=或者<>
    -  python3
    1.input获取的内容都是字符串
       2. 源码统一,不会出现重复代码.
       3. 除法返回的是浮点数
       4. range()中是一个可迭代对象,怎么输入就怎么打印
       5.int全部都是整数,但是增加了bytes
       6. 二次编码用的是:Unicode
       7.迭代器中知识:iter() __iter__()两个功能都有  next()__next__()
       8.python3中的import包 ,没有__init__.py文件也不会报错
       9.多继承:python2.2之前都是经典类,python2.2之后,经典类和新式类共存.新式类就是超类继承object类,经典类就是基类不继承object
       10.python3中的不等于号只有!=
  1. 看代码写结果:

    v1 = 1 or 2   -------->  1
    v2 = 3 and 7 or 9 and 0     -------> 7
    ?
    假的十种表达方式:
    0, 0.0, False, 0j, ‘‘, [], {} ,     set(),     None,   ()
    解析为:
    在没有()的情况下,优先级为:not > and > or
    整体为: () > not > and > or
    and运算: 两个都为真的时候 取后面的值
    两个都为假的时候 取前面的值
    一真一假的情况 就是取假
        or运算: 两个都为假的时候 or取后面
        两个都为真的时候 or取前面
        一真一假的时候   or取真的
  1. 比较以下值有什么不同?

    v1 = [1,2,3]
    v2 = [(1),(2),(3)]
    v3 = [(1,),(2,),(3,)]
    v1和v2 列表里元素是int
    v3 列表中的元素是元祖
  1. 用一行代码实现数值交换。

    a = 1
    b = 2
    a,b=b,a
  1. Python中单引号、双引号、三引号的区别?

    单引号:字符串
    双引号:字符串
    多引号:多行注释
    在互相嵌套的时候需要注意里外不能使用相同的引号
  1. is和==的区别?

    is:  比较内存地址是否相同
    ==: 比较数值是否相等
  2. python里如何实现tuple和list的转化?

    tuple(list)
    list(tuple)
  3. 如何实现字符串 name=‘老男孩‘的反转?

    1.name = name[::-1]
    2.name2=list(name)
    name2.revverse()
    name=‘‘.join(name2)
    3.from functools import reduce
    name = reduce(lambda x,y:y+x,name)
  4. 两个set如何获取交集、并集、差集?

    交集:  &   intersection
    并集: |   union
    差集: -   difference
    对称差集 : ^ symmetric_difference
  5. 那些情况下, y != x - (x-y)会成立?

    x,y  是两个不为子父关系的非空集合
  6. Python中如何拷贝一个对象?

    import copy
    =赋值,就是创建了对象的一个新的引用,修改其中任意一个变量都会影响到另一个.
    浅拷贝:创建一个新的对象,但他包含的是对原始对象中包含项的引用,只拷贝第一层元素的地址,只有修改和添加拷贝的数据第一层的时候源数据不受影响.给可变数据类型进行添加的时候源数据会受影响 针对于列表可以用[::]或者[:]表示.
    深拷贝:不可变数据类型内存地址公用,可变数据类型新开辟一个空间,不管嵌套多深,修改和添加和原来的就没有任何关系了,不影响
  7. 简述 赋值、浅拷贝、深拷贝的区别?

    赋值 : 指向同一个内存地址,将变量和值在内存中形成映射指向关系
    浅拷贝 : 只拷贝第一层元素的内存地址,copy.copy()
    深拷贝 : 浅拷贝只是对另外一个变量的内存地址的拷贝,这两个变量指向同一个内存地址的变量值。copy.deepcopy()
    浅拷贝的特点:
      共用一个值
      这两个变量的内存地址一样
      对其中一个变量的值改变,另外一个变量的值也会改变
      深拷贝是一个变量对另外一个变量的值拷贝
    深拷贝的特点:
      两个变量的内存地址不同
      两个变量各有自己的值,且互不影响
      对其任意一个变量的值的改变不会影响另外一个
    如果是不可变类型,则深浅拷贝只拷贝引用,如果是可变类型,浅拷贝只拷贝第一层引用,深拷贝无论多少层引用都拷贝
  8. pass的作用?

    pass  不做任何事情,一般用做占位语句。
    pass 空语句,是为了保持程序结构的完整性
  9. 阅读代码写结果。

    import copy
    a = [1,2,4,5,[‘b‘,‘c‘]]     [1,2,4,5,[‘b‘,‘c‘,‘d‘],5]
    b = a                       [1,2,4,5,[‘b‘,‘c‘,‘d‘],5]
    c = copy.copy(a)           [1,2,4,5,[‘b‘,‘c‘,‘d‘]]
    d = copy.deepcopy(a)       [1,2,4,5,[‘b‘,‘c‘]]
    ?
    a.append(5)
    a[4].append(‘d‘)
    ?
  10. 用Python实现9 * 9 乘法表。

    for i in range(1,10):
       for n in range(1,i+1):
           print(f‘{n}*{i}={i*n}‘,end=‘ ‘)
       print()
       
    把上面换成一行代码表示:
    print(‘ ‘.join([‘ ‘.join([‘{}*{}={}‘.format(x,y,x*y) for x in range(1,y+1)]) for y in range(1,10)]))
    ---------------------
    i = 1
    while i<=9:
       j=1
       while j<=i:
           print("%d*%d=%2d "  %(i,j,i*j),end=" ")
           j+=1
       print()
       i+=1
           
  11. 用Python显示一个斐波那契数列。

    lst = [1,1]
    for i in range(10):
      lst.append(lst[-1] + lst[-2])
    print(lst)
    --------------------
    a,b=0,1
    for i in range(10):
       print(b)
       a,b=b,a+b
    ------------------------
    def fib(n):
       if n<=2:
           return 1
       return fib(n-1) + fib(n-2)
    print(fib(6))
  12. 如何删除列表中重复的值?

    list(set(list))
  1. 一个大小为100G的文件etl_log.txt, 要读取文件中的内容, 写出具体过程代码?

    利用open()系统自带方法生成的迭代对象
    with open(‘etl_log.txt‘, ‘r‘,encoding = ‘utf-8‘) as f:
    for line in f:
    print(line.strip)
    for line in f 这种用法是把文件对象f当作迭代对象, 系统将自动处理IO缓冲和内存管理 如果没有空格 不会换行
  1. a = dict(zip(("a","b","c","d","e"),(1,2,3,4,5))) 请问a是什么?

    zip是拉链 , enumerate枚举
    字典
  1. lambda关键字的作用?

    匿名函数:用一句话表达只有返回值的无名函数
    lambda 参数 :返回值
    定义一个匿名函数
  1. *arg**kwarg`作用?

    *arg   接收多余位置参数
    *kwarg 接收多余关键字参数
  1. 如何在函数中设置一个全局变量 ?

    global 变量名
  1. filter、map、reduce的作用?

    filter -- 过滤、
    map -- 映射
        lst = [1,234,5,6]
        lst1 = [1,2,3,45,6]
        print(list(map(lambda x,y:x+y,lst,lst1)))
    reduce -- 累计算
      from functools import reduce
      print(reduce(lambda x,y:x*y, [1,2,3,4,5]))
  1. 什么是匿名函数?匿名函数有什么作用?

    lambda代表匿名函数
    当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便。
    用匿名函数有个好处,因为函数没有名字,不必担心函数名冲突。此外,匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数
  1. Python递归的最大层数?

    官方1000
    996 - 997
    -----------
    修改递归
    import sys
    sys.setrecursionlmit(9999)
  1. 什么是迭代器?什么是可迭代对象?

    具有__iter__() 和__next__() 就是一个迭代器
    具有__iter__() 是可迭代对象
  1. 什么是生成器?

    生成器的本质就是迭代器
    可以自定义迭代的逻辑
    具有yield关键字就是生成器
  1. 什么是装饰器及应用场景?

    装饰器本质就是闭包
    开放封闭原则:对扩展是开放的,对修改源码是封闭的.
    在不修改源代码的基础上,额外添加新的功能就是装饰器
    应用场景有:登陆认证,django框架,flask框架,property类等
  1. 什么是反射及应用场景?

    反射就是通过字符串去操作对象的属性和方法
    应用场景一般就是用户输入的多个选择的时候
  1. 写一个普通的装饰器。

    闭包:内函数使用了外函数的局部变量,外函数把内函数返回出来的过程叫做闭包,这个内函数叫做闭包函数
    def wrapper(func):
       def inner(*args,**kwargs):
           func(*args,**kwargs)
       return inner
  1. 写一个带参数的装饰器。

    def  auth(argv):
       def wrapper(func):
           def inner(*args,**kwargs):
               func(*args,**kwargs)
      return inner
       return wrapper
    ?
  1. 求结果

    def num():
     return [lambda x:i*x for i in range(4)]
    print([m(2) for m in num()])
    --------------------------------
    #[6,6,6,6]
    # [lambda x:x**i,lambda x:x**i,lambda x:x**i,lambda x:x**i]
    # def num():
    #     lst = []
    #     for i in range(4):
    #         def foo(x):
    #             return x**i
    #         lst.append(foo)
    #     return lst
    #     # lst.append(lambda x:x**i)
    # g=num()
    # print(g)   # [4个内存地址]
    # lst1=[]
    # for m in g:
    #     lst1.append(m(2))
    # print(lst1)
  1. def(a, b=[])这种写法有什么陷阱?

    默认参数的[]是可变数据类型
  1. 看代码写结果

    def func(a,b=[]):
       b.append(a)
    return b
    ?
    v1 = func(1)
    v2 = func(2,[10,20])
    v3 = func(3)
    print(v1,v2,v3)
    ----------------
    函数的默认参数(是一个列表或一个字典就有坑)陷阱: 默认参数绑死在那个位置.可以认为是在全局里的空列表理解
    #可变的列表/内存地址是一样的.一个变都变
    [1,3]
    2,[10,20]
    [1,3]
  1. 看代码写结果

    def func(a,b=[]):
       b.append(a)
    return b
    ?
    v1 = func(1)
    print(v1)
    v2 = func(2,[10,20])
    print(v2)
    v3 = func(3)
    print(v3)
    -----------
    [1]
    [10, 20, 2]
    [1, 3]
  1. 请编写一个函数实现将IP地址转换成一个整数。

    10.3.9.12 转换规则为:
           10            00001010
            3            00000011
            9            00001001
           12            00001100
           
    再将以上二进制拼接起来计算十进制结果:00001010 00000011 00001001 00001100 =
    ip = "10.3.9.12"
    strvar = ""
    for  i in ip.split("."):
    strvar += format(int(i),"08b")
    print(int(strvar,2))
    ----------------------------------
    ip = "10.3.9.12"
    strvar = ""
    for  i in ip.split("."):
       bin_str =  str(bin(int(i)))[2:]
       strvar +=bin_str.rjust(8,"0")
    print(strvar)
  1. 请查找一个目录下的所有文件(可能存在文件嵌套)。

    import os 
    os.walk()
  1. 求结果

    import math
    print (math.floor(5.5))
    -------------------
    5
  1. 是否使用过functools中的函数?其作用是什么?

    reduce  
    作用是累积计算
  1. re的match和search区别?

     match : 从开头进行匹配,匹配到一个就停止了
    search : 从任意位置进行匹配,匹配到一个就停止了
  1. 用Python匹配HTML tag的时候,<.>和<.?>有什么区别?

    .* 贪婪匹配
    .*? 非贪婪匹配 只匹配一次
  1. 如何生成一个随机数?

    random
  1. super的作用?

    super  按照mro的顺序继承父类的方法
  1. 双下划线和单下划线的区别?

    __a = 10  强制私有
    _b = 10 约定私有
  1. @staticmethod和@classmethod的区别?

    @staticmethod一个是静态方法, 
    @classmethod一个是类方法
  1. 实现一个单例模式(加锁)

    # class A(object):
    #
    #     def __init__(self,name): # 初识化
    #         self.name = name
    ?
    ?
      # def __new__(cls, *args, **kwargs):
      #     obj = object.__new__(A)   # 调用的是object类中的__new__ ,只有object类中的__new__能够创建空间
      #     return obj   #本质: obj == __init__()     return __init__() # 触发了__init__方法
      #     # print("先执行的是我")
      #     # return "宝元"
    ?
    ?
    # a = A("meet") # a是对象的内存地址
    # a1 = A("日魔") # a是对象的内存地址
    # a2 = A("朝阳") # a是对象的内存地址
    # print(a.name)
    # print(a1.name)
    # print(a2.name)
    ?
    ?
    # 先执行__new__方法在执行__init__方法
  1. 栈和队列的区别?

    区别与联系
    相同点:(1)栈和队列都是控制访问点的线性表;
    ?
            (2)栈和队列都是允许在端点处进行数据的插入和删除的数据结构;
    ?
    不同点:(1)栈遵循“后进先出(LIFO)”的原则,即只能在该线性表的一头进行数据的插入和删除,该位置称为“栈顶”,                        而另外一头称为“栈底”;根据该特性,实现栈时用顺序表比较好;
    ?
            (2)队列遵循“先进先出(FIFO)”的原则,即只能在队列的尾部插入元素,头部删除元素。根据该特性,在实现队                         列时用链表比较好
  1. 以下代码输出是什么? 请给出答案并解释。

    class Parent(object):
       x = 1
    ?
    class Child1(Parent):
       pass
    ?
    class Child2(Parent):
       pass
    ?
    print Parent.x, Child1.x, Child2.x
    ?
    Child1.x = 2
    print Parent.x, Child1.x, Child2.x
    ?
    Parent.x = 3
    print Parent.x, Child1.x, Child2.x
    ?
  1. 参考下面代码片段

    class Context:
       
       def __enter__(self):
           return self
       
       def __exit__(self, exc_type, exc_val, exc_tb)
      return 1
       
       def do_something(self):
           print(111)
    ?
    with Content() as ctx:
       print(ctx)
       ctx.do_something()
    请在Context类下添加代码完成该类的实现
    ?

第二部分 可选题

  1. 如何获取列表中第二大的值?

    第1种方式
    先max取最大值 在删除他 在取最大值
    ----------------------------------------------------------------
    第2种方式
    排序取第2个
  2. 简述Python内存管理机制。

    python内部使用引用计数,来保持追踪内存中的对象,Python内部记录了对象有多少个引用,即引用计数,当对象被创建时就创建了一个引用计数,当对象不再需要时,这个对象的引用计数为0时,它被垃圾回收。所有这些都是自动完成,不需要像C一样,人工干预,从而提高了程序员的效率和程序的健壮性
  3. 简述Python的垃圾回收机制

    垃圾回收机制
    内存管理,垃圾回收就是python,Java等语言管理内存的一种方式,就是清除无用的垃圾对象,c语言及C++中需要通过malloc来进行内存的申请,通过free而进行内存的释放,而python和Java中有自动的内存管理机制,不需要动态的释放内存,这种机制就是垃圾回收的机制
    python中对每一个对象通过引用计数法进行内存的管理的
  4. 请用两个队列来实现一个栈。

    class StackWithTwoQueues(object):
       def __init__(self):
           self._queue1 = []
           self._queue2 = []
    ?
       def push(self, x):
           if len(self._queue1) == 0:
               self._queue1.append(x)
           elif len(self._queue2) == 0:
               self._queue2.append(x)
           if len(self._queue2) == 1 and len(self._queue1) >= 1:
               while self._queue1:
                   self._queue2.append(self._queue1.pop(0))
           elif len(self._queue1) == 1 and len(self._queue2) > 1:
               while self._queue2:
                   self._queue1.append(self._queue2.pop(0))
    ?
       def pop(self):
           if self._queue1:
               return self._queue1.pop(0)
           elif self._queue2:
               return self._queue2.pop(0)
           else:
               return None
    ?
       def getStack(self):
           print("queue1", self._queue1)
           print("queue2", self._queue2)
    ?
    ?
    sta = StackWithTwoQueues()
    sta.push(1)
    sta.getStack()
    sta.push(2)
    sta.getStack()
    sta.push(3)
    sta.getStack()
    sta.push(4)
    sta.getStack()
    print(sta.pop())
    sta.getStack()
    print(sta.pop())
    sta.getStack()
    print(sta.pop())
    sta.getStack()
    ?
  5. 请用Python实现一个链表。

    # -*- coding:utf8 -*-
    #/usr/bin/env python
    
    class Node(object):
        def __init__(self, data, pnext = None):
            self.data = data
            self._next = pnext
    
        def __repr__(self):
            return str(self.data)
    
    class ChainTable(object):
        def __init__(self):
            self.head = None
            self.length = 0
    
        def isEmpty(self):
            return (self.length == 0)
    
        def append(self, dataOrNode):
            item = None
            if isinstance(dataOrNode, Node):
                item = dataOrNode
            else:
                item = Node(dataOrNode)
    
            if not self.head:
                self.head = item
                self.length += 1
    
            else:
                node = self.head
                while node._next:
                    node = node._next
                node._next = item
                self.length += 1
    
        def delete(self, index):
            if self.isEmpty():
                print "this chain table is empty."
                return
    
            if index < 0 or index >= self.length:
                print ‘error: out of index‘
                return
    
            if index == 0:
                self.head = self.head._next
                self.length -= 1
                return
    
            j = 0
            node = self.head
            prev = self.head
            while node._next and j < index:
                prev = node
                node = node._next
                j += 1
    
            if j == index:
                prev._next = node._next
                self.length -= 1
    
        def insert(self, index, dataOrNode):
            if self.isEmpty():
                print "this chain tabale is empty"
                return
    
            if index < 0 or index >= self.length:
                print "error: out of index"
                return
    
            item = None
            if isinstance(dataOrNode, Node):
                item = dataOrNode
            else:
                item = Node(dataOrNode)
    
            if index == 0:
                item._next = self.head
                self.head = item
                self.length += 1
                return
    
            j = 0
            node = self.head
            prev = self.head
            while node._next and j < index:
                prev = node
                node = node._next
                j += 1
    
            if j == index:
                item._next = node
                prev._next = item
                self.length += 1
    
        def update(self, index, data):
            if self.isEmpty() or index < 0 or index >= self.length:
                print ‘error: out of index‘
                return
            j = 0
            node = self.head
            while node._next and j < index:
                node = node._next
                j += 1
    
            if j == index:
                node.data = data
    
        def getItem(self, index):
            if self.isEmpty() or index < 0 or index >= self.length:
                print "error: out of index"
                return
            j = 0
            node = self.head
            while node._next and j < index:
                node = node._next
                j += 1
    
            return node.data
    
    
        def getIndex(self, data):
            j = 0
            if self.isEmpty():
                print "this chain table is empty"
                return
            node = self.head
            while node:
                if node.data == data:
                    return j
                node = node._next
                j += 1
    
            if j == self.length:
                print "%s not found" % str(data)
                return
    
        def clear(self):
            self.head = None
            self.length = 0
    
        def __repr__(self):
            if self.isEmpty():
                return "empty chain table"
            node = self.head
            nlist = ‘‘
            while node:
                nlist += str(node.data) + ‘ ‘
                node = node._next
            return nlist
    
        def __getitem__(self, ind):
            if self.isEmpty() or ind < 0 or ind >= self.length:
                print "error: out of index"
                return
            return self.getItem(ind)
    
        def __setitem__(self, ind, val):
            if self.isEmpty() or ind < 0 or ind >= self.length:
                print "error: out of index"
                return
            self.update(ind, val)
    
        def __len__(self):
            return self.length
    
    python链表
    
  6. 请用Python实现链表的逆转。

    class Node(object):
        def __init__(self, data, next=None):
            self.val = data
            self.next = next
     
    def fun4(head):
        if head == None:
            return None
        L,M,R = None,None,head
        while R.next != None:
            L = M
            M = R
            R = R.next
            M.next = L
        R.next = M
        return R
    #测试用例
    if __name__ == ‘__main__‘:
        l1 = Node(3)
        l1.next = Node(2)
        l1.next.next = Node(1)
        l1.next.next.next = Node(9)
        l = fun4(l1)
        print (l.val, l.next.val, l.next.next.val, l.next.next.next.val)
     

以上是关于Python面试重点(基础篇)的主要内容,如果未能解决你的问题,请参考以下文章

Python面试重点(基础篇)

Python面试重点(进阶篇)

Python面试重点(进阶篇)

Python面试重点(web篇)

Python面试重点(web篇)

Python面试重点(web篇)