zoukankan      html  css  js  c++  java
  • python面试题

    Python面试(基础篇)

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

    我了解python,java和c和go

    简单的说,python省去了java和c 的大括号,分号

    python使用时更加简洁,方便,和易阅读

    python是解释型语言,不需要编辑,java和c 需要编译,但是开发周期长,python使用起来效率比java和c低,但如果不是特别注重延迟的项目,用python更加合适

    python是开源的,应用广泛,可移植性强,是可嵌入的解释型编程语言

    2.列举Python2和Python3的区别?

    python3不兼容python2,但是python2.7都兼容

    首先python2不支持中文用的是ASCII,python3支持,用的是utf8

    python2和python3的range不同,2中返回一个列表,3中返回一个迭代器,更加节省内存

    2中print不加括号,3中加括号

    2中的raw_input函数是3中的input函数

     

    3.看代码写结果

    v1 = 1 or 2
    v2 = 3 and 7 or 9 and 0

    1
    0

    布尔值为假的情况:0,0.0,false,[],(),set(),{},None,'',0j

    4.比较一下值有什么不同?

    v1 = [1,2,3]
    v2 = [(1),(2),(3)]
    v3 = [(1,),(2,),(3,)]

    v1 = v2
    v3 是列表中套了三个元组

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

    a = 1
    b = 2
    a,b = b,a

    c = a
    a = b
    b = c

    6.Python中单引号、双引号、三引号的区别?

    单引号 == 双引号,里面写字符串内容

    三引号里面写函数注释、文档注释,也可以是多行的字符串

    7.is和==的区别?

    is代表的是两个比较的数据内存地址相同

    ==代表的两个数值相同

    8.python里如何实现tuple和list的转化?

    tuple(list列表)

    list(tuple列表)

    9.如何实现字符串name=老男孩的反转?

    print(name[::-1])

    10.两个set如何获取交集、并集、差集?

    set1 = {1,2,3}
    set2 = {3,4,5}

    # 交集
    set = set1 & set2
    # 并集
    set = set1|set2
    # 差集
    set = set1 - set2
    # 对称差集
    set = set1 ^ set2
    对称差集是除去相同的所有不同的

    11.哪些情况下,y != x-(x-y)会成立?

    非空集合且不为子父关系的两个集合

    12.python中如何拷贝一个对象

    import copy

    name = '老男孩'
    name1 = copy.deepcopy(name)

    13.简述赋值、浅拷贝、深拷贝的区别?

    赋值就是一个变量对一个对象的映射关系

    浅拷贝就是对一个对象的第一层的拷贝

    深拷贝就是对一个对象的全部拷贝,独立于源数据

    14.pass的作用

    当写一个函数或者写一个类的时候,没有想好内部如何写,就用pass占位

    15.阅读代码写结果

    import copy
    a = [1,2,4,5,['b','c']]
    b = a
    c = copy.copy(a)
    d = copy.deepcopy(a)

    a.append(5)
    a[4].append('b')

    print(b)
    print(c)
    print(a)

    a = [1,2,4,5,['b','c','b'],5]
    b = [1,2,4,5,['b','c','b'],5]
    c = [1,2,4,5,['b','c','b']]
    d = [1,2,4,5,['b','c']]

    16.用python实现9*9乘法表

    for i in range(1,10):
    for j in range(1,10):
    print('{}{}={}'.format(i,j,i*j),end=' ')
    print()

     

    17.用python显示一个斐波那契数列

    def func(n):
    if n <= 2:
    return 1
    return func(n-1) + func(n-2)

    lst = [1,1]
    for i in range(10):
    lst.append(lst[-1] + lst[-2])
    print(lst)

    def fib(n):

    if n <= 2:
    return 1

    return fib(n-1) + fib(n-2)

    18.如何删除列表中重复的值

    list = [1,1,1,2]
    set_list = set(list)

     

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

    with open('etl_log.txt',r,encoding='utf-8')as f:
    print(f.readline())

     

    20.a = dict( zip( ('a','b','c','d','e') ,(1,2,3,4,5) ) )请问a是什么

    a = {'a':1,'b':2,'c':3,'d':4,'e':5}

    21.lambda关键字的作用?

    lambda是匿名函数,用于一次性使用的函数

    22.*args和**kwargs的作用?

    *args用来接收剩余的位置参数

    **kwargs用来接收剩余的关键字参数

    23.如何在函数中设置一个全局变量

    global 变量名

    24.filter,map,reduce的作用

    filter:过滤数据

    map:映射函数,处理映射数据,将可迭代对象中的每个元素执行相应的操作

    reduce:计算数据

    from functools import reduce

     

    25.什么是匿名函数,匿名函数有什么作用?

    匿名函数,顾名思义就是没有名字的函数,由于一些场景,只需要一次性使用函数,如果定义一个函数,会造成资源的浪费,所以需要使用一个匿名函数,用完之后就自动回收了

    26.python递归的最大层数?

    1000

    27.什么是迭代器?什么是可迭代对象?

    只要具有__iter__()方法的是就是一个可迭代对象
    具有__iter__()和__next__()两个方法的才是迭代器

     

    28.什么是生成器?

    迭代器python内置的

    生成器是程序员写的一种迭代器

    生成器有两种编写方式,一种是推导式方式和函数编写

     

    29.什么是装饰器及应用场景?

    装饰器的本质就是闭包

    遵循开放封闭原则

    • 1.对扩展功能是开放的

    • 2.对修改源代码是封闭的

    应用:验证用户登录,property类,框架内

    在不修改源代码和调用方式的情况下,对函数进行扩展

     

    30.什么是反射及应用场景?

    反射通过字符串直接操作类对象,或者模块中的属性方法

    hasattr getattr setattr delattr

    应用:可以配合用户的操作或者输入,调用其中的成员

     

    31.写一个普通的装饰器

    def times(func):
      def foo():
          print('装饰001')
          func()
          print('装饰002')
      return foo

    @times
    def func1():
      print("被装饰的函数1")

    32.写一个带参数的装饰器

    def outer(n):
    def wrapper(func):
    def inner1(*args,**kwargs):
    ret = func(*args, **kwargs)
    print('装饰器----')
    return ret

    def inner2(*args,**kwargs):
    ret = func(*args,**kwargs):
    print('装饰器-----')
    return ret

    if n == 'i':
    return inner1
    else:
    return inner2
    return wrapper

    @outer('i')
    def func():
    print('我是原本的功能,我被修饰了')

    func()

    33.求结果

    def num():
    return [lambda x:i*x for i in range(4)]
    print([m(2) for m in num()])

    6 6 6 6

     

    34.def(a,b=[])这种写法有什么陷阱

    开发中不这么写,如果没有特殊需求,这么写直接开掉

    35.看代码写结果

    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]
    [10,20,2]
    [1,3]

     

    36.看代码写结果

    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]

    37.请编写一个函数实现将ip地址转换成一个整数

    如 10.3.9.12 转换规则为:
    10 00001010
    3 00000011
    9 00001001
    12 00001100

    再将以上二进制拼接起来计算十进制结果:00001010   00000011   00001001 00001100 = ?

    str_ip = ''
    for i in ip.split('.'):
    bin_str = str(bin(int(i)))[2:]
    str_ip += bin_str.format(8,'0')
    str_ip += ' '
    print(str_ip)

    38.请查找一个目录下的所有文件(可能存在文件嵌套)。

    import os
    def getallsize(pathvar):
    size = 0
    lst = os.listdir(pathvar)
    print(lst)
    for i in lst:
    pathvar2 = os.path.join(pathvar,i)
    print(pathvar2)

    # 判断是否是文件
    if os.path.isfile(pathvar2):
    size += os.path.getsize(pathvar2)
    # 判断是否是文件夹
    elif os.path.isdir(pathvar2):
    size += getallsize(pathvar2)

    print(size)
    return size

    pathvar = r"路径"
    res = getallsize(pathvar)
    # print(res)

    39.求结果

    import math
    print(math.floor(5.5))

    5

     

    40.是否使用过functools中的函数?其作用是什么?

    用过functools中的reduce,wraps
    reduce是计算数值的高阶函数
    wraps在装饰器中使用,如果需要保留函数原本的属性,就加上wraps

     

    41.re的math和search的区别?

    search 从任意位置开始查找,查找到结束,没有则返回空列表

    match 从头开始查看,如果不符合就不继续查找了
    import re

    findall 返回的是列表


    大小w:[每个元素都是字符串的形式]
    # w 字母.数字.下划线.中文   ***
    print(re.findall("w","宝元-alex_dsb123日魔吃D烧饼"))
    # W 不是字母.数字.下划线.中文 ***
    print(re.findall("W","宝元-alex_dsb123日魔吃D烧饼"))  


    大小d:[每个元素都是字符串的形式]
    # d 匹配数字     ***
    print(re.findall("d","十10⑩"))
    #D 匹配非数字     ***
    print(re.findall("D","十10⑩"))


    判断str的开头结尾,查找不到,返回空列表
    # 以什么开头 ***
    print(re.findall("^a","alex"))
    # 以什么结尾 ***
    print(re.findall("x$","alex"))


    [每个元素都是字符串的形式]
    # . 匹配任意一个字符串( 除外),加re.DOTALL可以显示 ***
    print(re.findall("a.c","abc,aec,a c,a,c"))
    print(re.findall("a.c","abc,aec,a c,a,c",re.DOTALL))


    [每个元素都是字符串的形式]
    # 区间
    print(re.findall('[0-9]',"alex123,日魔dsb,小黄人_229")) ***
    print(re.findall('[a-z]',"alex123,日魔DSB,小黄人_229"))
    print(re.findall('[A-Z]',"alex123,日魔DSB,小黄人_229"))
    [0-9] # 取0-9之前的数字
    [^0-9] # 取非 0-9之间的数字
    print(re.findall("[^0-9a-z]","123alex456"))   ***


    # 匹配*左侧字符串0次或多次 贪婪匹配 ***
    print(re.findall("a*","alex,aa,aaaa,bbbbaaa,aaabbbaaa"))


    # 匹配左侧字符串一次或多次 贪婪匹配     ***
    print(re.findall("a+","alex,aa,aaaa,bbbbaaa,aaabbbaaa"))


    # 匹配?号左侧0个或1个 非贪婪匹配       ***
    print(re.findall("a?","alex,aa,aaaa,bbbbaaa,aaabbbaaa"))  


    # 指定查找的元素个数 ***
    print(re.findall("[0-9]{11}","18612239999,18612239998,136133333323"))
    3~8这个区间
    print(re.findall("a{3,8}","alex,aaaabbbaaaaabbbbbbaaa,aaaaaaaaabb,ccccddddaaaaaaaa"))


    # 分组***
    print(re.findall("<a>(.+)</a>","<a>alex</a> <a>wusir</a>"))                          
    # 控制贪婪匹配***
    print(re.findall("<a>(.+?)</a>","<a>alex</a> <a>wusir</a>"))                          

    # '查找的元素' 返回的就是这个元素,查不到返回空列表
    print(re.findall(" ","alex wusir"))
    print(re.findall(" ","alex wusir"))


    print(re.findall("s","alex dsbrimocjb"))# s 匹配空格
    print(re.findall("S","alex dsbrimocjb"))# s 匹配非空格


    面试题:
    # search 和 match 区别
    # search 从任意位置开始查找,查找到结束,没有则返回空列表
    # match 从头开始查看,如果不符合就不继续查找了
    # group()进行查看

    split -- 分割 # [多个分割,需要用列表把分割符号括起来]
    print(re.split("[:;,.!#]","alex:dsb#wusir.djb"))

    sub -- 替换
    s = "alex:dsb#wusir.djb"
    print(re.sub("d","e",s,count=1)) # count 计数,控制替换数量
    print(re.sub("d","e",s)) # 默认全部替换


    compile 定义匹配规则
    s = re.compile("w")
    print(s.findall("alex:dsb#wusir.djb"))


    返回的就是一个迭代器
    s = re.finditer("w","alex:dsb#wusir.djb")
    print(next(s).group())
    print(next(s).group())
    for i in s:
      print(i.group())

    . 没有任意的功能了


    装逼网站:http://tool.chinaz.com/regex/

     

    42.用python匹配html tag的时候,<.>和<.?>有 什么区别?

    . 除了
    的任意字符
    * 量词 代表匹配0次或者任意个
    .* 贪婪匹配
    .? 非贪婪匹配

     

    43.如何生成一个随机数?

    import random
    print(random.random())

    44.super的作用?

    super用来调用父类的方法或属性

    解决多继承之间复杂的调用关系使用

    45.双下划线和单下划线的区别?

    双下划线的是私有变量、方法、或者函数
    单下划线是程序员约定俗成的私有方法或变量,不允许修改,但可以继承使用

     

    单下划线的是私有变量

    46.@staticmethod 和@classmethod的区别?

    一个是静态方法,一个是类方法

    静态方法可以被对象和类调用,不需要传递参数
    类方法可以被对象和类调用,默认传递参数,调用的这个类

     

    47.实现一个单例模式(加锁)

    class obj():
    __obj = None
    lock = Lock()
    def __new__(cls,*args,**kwargs):
    with lock():
    if not __obj:
    cls.__obj = object.__new__(cls)
    return __obj

    48.栈和队列的区别?

     队列先进先出,栈先进后出。 

    49.以下代码输出是什么?请给出答案和解释。

    class Parent(object):
    x = 1
    class Child1(Parent):
    pass

    class Child2(Parent):
    pass

    print Parent.x, Child1.x, Child2.x
    1 1 1

    Child1.x = 2
    print Parent.x, Child1.x, Child2.x
    1 2 1

    Parent.x = 3
    print Parent.x, Child1.x, Child2.x
    3 2 3

     

    50.参考下面代码片段

    class Context:
    pass

    def do_something(self):
    print('我不做任何事情')

    def __exit__(self,*args,**kwargs):
    pass

    def __enter__(self,*args,**kwargs):
    pass

    with Content() as ctx :
    ctx.do_something()
    请在Context类下添加代码完成该类的实现

     

    进阶篇

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

    使用sorted排序后,取倒数第二个值

    用max函数算出最大值,pop,然后在max一次

    2.简述python内容管理机制

    计数器,垃圾回收,内存池
    计数器就是一个变量的使用次数被记录,当变量的计数为零时,就会被从内存中释放
    垃圾回收使用 分代回收、计数器、标记清除
    分代回收就是分为三代
    每一代的变量都会有一个阈值,当达到阈值的时候,会被从内存中释放
    标记清除就是当一个变量出现自我循环的时候,会被直接清理
    内存池就是同一个文件中,有一些初始化就放在内存中的数据,不需要删除

    3.简述python的垃圾回收机制

    垃圾回收使用 分代回收、计数器、标记清除
    分代回收就是分为三代
    每一代的变量都会有一个阈值,当达到阈值的时候,会被从内存中释放
    标记清除就是当一个变量出现自我循环的时候,会被直接清理
    内存池就是同一个文件中,有一些初始化就放在内存中的数据,不需要删除

     

    4.请用两个队列来实现一个栈

    """
    栈   : 先进后出,后进先出
    队列 : 先进先出,后进后出
    """
    from queue import Queue

    class Stack():
    def __init__(self):
    self.master_queue = Queue()
    self.minor_queue = Queue()

    def push(self,val):
    # 入栈
    self.master_queue.put(val)

    def pop(self):
    # 出栈
    # 如果队列中没有任何值,直接返回None
    if self.master_queue.qsize() == 0 :
    return None

    while True:
    # 当队列总长度为1的时候,循环终止,把最后一个元素拿出来,为了满足栈后进先出的特点
    if self.master_queue.qsize() == 1:
    value = self.master_queue.get()
    break

    # 剩下还没有拿出来的元素,暂时放在2号队列中存储
    self.minor_queue.put(self.master_queue.get())
    """
    minor_queue(1)
    master_queue(2 3 4)

    minor_queue(2)
    master_queue(3 4)

    minor_queue(3)
    master_queue(4)
    """
    # 交换队列,重新循环,继续去最后一个值,如法炮制
    self.master_queue,self.minor_queue = self.minor_queue,self.master_queue
    return value

    obj = Stack()
    obj.push("a")
    obj.push("b")
    obj.push("c")

    print(obj.pop()) # c
    print(obj.pop()) # b
    print(obj.pop()) # a
    print(obj.pop()) # a



    [a,b,c]
    [a,b]
    [a]
    []

     

    5.请用python实现一个链表

    # 线性表: 相当于一条直线,没有分支

    # ### (1) 创建链表
    class Node():
    def __init__(self, value, next):
    self.value = value
    self.next = next


    head = Node("头", None)
    last = head

    for i in range(5): # v0 v1 v2 v3 v4
    node = Node("v%s" % i, None)
    last.next = node
    last = node

    # 查看链表的关系
    print(head.value)
    print(head.next.value)
    print(head.next.next.value)
    print(head.next.next.next.value)
    print(head.next.next.next.next.value)
    print(head.next.next.next.next.next.value)


    # print(head.next)
    print("<========>")

     

    6.请用python实现链表的逆转

    # 2.链表的逆转
    def reverse_link_list(head):
    # 要是空的,或者None,直接返回head
    if not head or not head.next:
    return head

    # 获取上一个节点对象
    prev_node = None
    # 获取下一个节点对象
    next_node = head.next
    # 获取当前节点对象
    current_node = head

    while True:
    # 修改next,所指向的对象
    current_node.next = prev_node
    # 如果下一个阶段对象是None
    if not next_node: # not None
    break

    # 重新获取上一个对象,即把当前丢向单独存一份,以准备第二次循环时插进next属性中
    prev_node = current_node
    # 重新获取当前对象 , 即把下一个对象单独存储起来(下个)
    current_node = next_node
    # 重新获取下一个对象,即把下一个对象单独存储起来,所指向的下个新对象赋值给next_node(下下个)
    next_node = current_node.next
    return current_node


    head = reverse_link_list(head)

    print(head.value)
    print(head.next.value)
    print(head.next.next.value)
    print(head.next.next.next.value)
    print(head.next.next.next.next.value)
    print(head.next.next.next.next.next.value)

     

    重点:

    正则,递归

  • 相关阅读:
    HTML CSS 特殊字符表
    vscode代码统计——Vscode counter
    js数组方法整理
    CSS-界面滚动时不显示滚动条
    Vue Loader 作用域CSS(scoped)——/deep/ 深入组件选择器
    PHP模板引擎,Smarty定义
    mysql触发器trigger 实例详解
    mysql关于数据库表的水平拆分和垂直拆分
    关于数据库表的水平拆分和垂直拆分
    使用Merge存储引擎实现MySQL分表
  • 原文地址:https://www.cnblogs.com/xuyuwei/p/12366413.html
Copyright © 2011-2022 走看看