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

    编程语言:C/C++/java/c#/PHP/GO/python
    编译方式:编译型语言:C/C++/GO
    		解释型语言:python/PHP
    		混合型语言:JAVA
    
  2. 列举python2和python3的区别?

    1.源码:python2源码不统一,源码重复(多人编写出现的现象)
    	   python3源码统一,源码不重复(龟叔一人编写)
    2.在除法显示:pyhton2返回的是整数(向下取整)
    			 Python3返回的是小数(浮点数)
    3.input:python2中input获取到的是数据本身
    	    Python3中input获取的是字符串
    4.整型:python2是整型、长整型(long)
    		python3全部都是整型
    5.range:Python2打印range获取到的是一个列表,列表元素是1-9
    	    Python3打印的是range本身
    6.编码:Python2默认ascii码
    		Python3默认是utf-8
    7.迭代器:Python2中__iter()和iter()都有,只有__next__()
    		 python3中__iter__()和iter()都有,__next__()和next()都有
    8.经典类和新式类:Python2:在py2.2之前,都是经典类,在py2.2之后,经典类和新式类共存,继承使用object的就是新式类,不继承使用object的就是经典类
    				pyhton3:只有新式类,不管继不继承都是新式类
    
  3. 看代码写结果

    v1 = 1 or 2             # 1 
    布尔值为假的情况:0,0.0,False,,"",[],{},(),set(),None,0j
    v2 = 3 and 7 or 9 and 0     # 7
    
  4. 比较以下值有什么不同?

    v1 = [1,2,3]     # 列表中是int,单列表
    v2 = [(1),(2),(3)]    # 列表中还是int
    v3 = [(1,),(2,),(3,)]   # 列表中是元组
    
    
  5. 用一行代码实现数值交换

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

    三者都是表示字符串格式
    单引号和双引号的区别:单引号需要加'\'来让编译器判断目前是转义字符,而双引号就可以直接使用
    三单引号和三个双引号:多行字符串/加注释
    
    ## 在互相嵌套时徐注意:里外不能使用相同的引号
    
  7. is和==的区别?

    is: 判断两边的内存地址是否相同
    == :判断两边的值是否相等
    
  8. pyhton里如何实现tuplelist的转化?

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

    name = name[::-1]
    
  10. 两个set如何获取交集、并集、差集?

    差集:set1 - set2
    并集:set1 | set2 
    交集:set1 & set2
    
  11. 那些情况下,y! = x - (x-y)会成立?

    x,y是两个不相等的非空集合
    # 非空集合且不为子父关系的两个集合
    
  12. python中如何拷贝一个对象?

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

    赋值:两个标签共用同一块内存地址,举例:一个列表用两个标签定义,其实操作的是同一个对象
    浅拷贝:就是只拷贝第一层的元素,对第一层进行修改和添加对元数据不会造成影响,对可变数据类型进行修改和添加会对源数据造成影响
    深拷贝:不可变数据类型共用一个内存地址,可变数据类型新开辟一个内存空间
    
  14. 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('d')
    
    print(b)     # [1,2,4,5,['b','c','d'],5]
    print(c)     # [1,2,4,5,['b','c','d']]
    print(a)     # [1,2,4,5,['b','c','d'],5]
    
  16. 用pyhton实现9*9乘法表

    for i in range(1, 10):
        for j in range(1, 10):
            if j == i:
                print(f"{j}*{i}={i * j}")
                break
            print(f"{j}*{i}={i*j}", end="\t")
        
        
    while循环:
    i = 1
    while  i<= 9:
    	j = 1
    	while j <= i:
    	print("%d%d=%2d" %(i,j,ij),end="")
    	j+=1
    
  17. 用python显示一个斐波那契数列

    方法一:
    num1 = 1
    num2 = 1
    sum = 0
    count = 2
    while num1 + num2 < 3:
    	sum = num1 + num2
    	num1 = num2
    	num2 = sum
    	count += 1
    print(num1,num2)
    
    方法二:
    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))
    
  18. 如何删除列表中重复的值?

    lst = [1,2,2,4,7,8,8,14,21]
    print(list(set(lst)))
    
  19. 一个大小为100G的文件etl_log.txt,要读取文件中的内容,写出具体过程代码

    with open('a3','r',encoding-'utf-8')as f1:
    	for  f  in f.read(10):
    		print(f,end="")
    # 一行一行读取,或者按固定字节读取
    
  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}
    
    # 枚举的作用如上:
    a = dict(enumerate(["a","b"]))  
    	# {1:"a",2:"b"}
    a = dict(enumerate(["a","b"],start=10))
    	# {10:"a",11:"b"}
    
  21. lambda关键字的作用?

    lambda:匿名函数,一行函数,只有返回值的无名函数
    格式:lambda  参数:返回值
    
  22. *args**kwargs作用

    *args:动态位置参数,接收额外的位置参数(实参)
    **kwargs:动态关键字参数,接收额外的关键字参数(形参)
    
  23. 如何在函数中设置一个全局变量?

    加关键字:global
    
  24. filtermapreduce的作用?

    filter:过滤,输出指定的内容   filter(func,iterable) => 可迭代对象
    map:映射:将可迭代对象中的每个元素执行指定的函数    map(func,iterable) => 可迭代对象
    reduce:累计算(累加、累乘)
    
  25. 什么是匿名函数?匿名函数有什么作用

    匿名函数:lambda
    作用:配合高阶函数一起使用
    
  26. python递归的最大层数?

    官方说明:1000层,实际998/997
    
  27. 什么是迭代器?什么是可迭代对象?

    具有__itre__()和__next__()两个方法的就是迭代器
    具有__iter__()方法的就是一个可迭代对象
    
  28. 什么是生成器?

    程序员自己编写的一种函数,函数体中出现yield代表要生成一个生成器,在获取生成器的内存地址,生成一个生成器,启动生成器等一系列的步骤
    
  29. 什么是装饰器及其应用场景?

    装饰器:在不修改源代码及调用调用方式时,对功能进行额外添加
    应用场景:登录认证、property类、框架(django/flask/@app.route)
    装饰器的本质是闭包
    
  30. 什么是反射及应用场景?

    反射:通过字符串操作对象的属性和方法
    场景:对象的角度、类的角度、当前模块的角度
    hasattr 
    getattr
    setattr
    delattr
    应用: 可以配合用户的操作或者输入,调用其中的成员,api接口中
    
  31. 写一个普通的装饰器

    def wrapper(func):
        def inner(*args,**kwargs):
            '''执行被装饰函数之前的操作'''
            ret = func
            '''执行被装饰函数之后的操作'''
            return ret
        return inner
        
    闭包:内函数使用了外函数的局部变量,外函数把内函数返回出来的过程就叫做闭包,这个内函数就叫做闭包函数
    特点:如果内函数使用了外函数的局部变量,那么该变量于内函数发生绑定,延长该变量的生命周期
    
  32. 写一个带参数的装饰器

    def auth2(func):
        def inner(*args, **kwargs):
            if login_status['status']:
                ret = func()
                return ret
            if 微信:
                username = input('请输入用户名:').strip()
                password = input('请输入密码:').strip()
                if username == '太白' and password == '123':
                    login_status['status'] = True
                    ret = func()
                    return ret
            elif 'qq':
                username = input('请输入用户名:').strip()
                password = input('请输入密码:').strip()
                if username == '太白' and password == '123':
                    login_status['status'] = True
                    ret = func()
                    return ret
        return inner
    
    @auth2
    def jitter():
        print('记录美好生活')
    
    
    @auth2
    def pipefish():
        print('期待你的内涵神评论')
    
  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=[])这种写法有什么陷阱?

    b身上的默认值是列表,如果使用原来默认的参数,调用func函数会把几次调用的值都存放在同一个默认列表里
    默认参数:
    如果调用时,用户给实参了,那么就使用用户的,如果调用时,用户没有给实参,那么就是用默认的(早已经存在内存中的这个列表)
    默认值会提前在内存中驻留,在使用时,才能调取,在定义函数的时候就提前开辟了空间
    
  35. 看代码写结果

    def fun(a,b=[]):
    	b.append(a)
    	return b 
    	
    v1 = func(1)             #[1,3] 
    v2 = func(2,[10,20])     #[10,20,2]
    v3 = func(3)             # [1,3]
    print(v1,v2,v3)
     
    
  36. 看代码写结果

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

    如10.3.9.12 转换规则为:
    	10  00001010
    	3   00000011
    	9   00001001
    	12  00001100
    再将以上二进制拼接起来计算十进制结果:00001010 00000011 00001001 00001100
    
    方法一:
    for i in ip.spilt('.'):
    	bin_str = str(bin(int(i)))[2:]   # 1010 11 1001 1100
    	strvar += bin_str.rjust(8,"0")    # rjust源字符串居右,填充符号
    								# ljust原字符串居左,填充符号
    print(strvar)
    
    方法二:
    strvar = ""
    for i in ip.split("."):
    	# format将证书转化成二进制,不够8位的拿0补位
    	strvar += format(int(i),"08b")
    print(int(strvar,2))
    
  38. 请查找一个目录下得所有文件(可能存在文件嵌套)

    方法一:递归写法
    import os
    def gettallsize(pathvar):
    	size = 0
    	lst = os.listdir(pathvar)
    	print(lst)
    	for i in lst;
        	pathvar2 = os.path.join(patgvar,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"D:\老男孩python25视频\学习资料\Linux"
    res = getallsise(pathvar)
    
    方法二:os.walk() => 生成器
    import os
    pathvar = r"D:\老男孩python25视频\学习资料\Linux"
    gen = os.walk(pathvar)
    
    for root,dirs,files in gen:
    	for name in files:
    		pathvar = os.path.join(root,name)
    		print(pathvar)
    
  39. 求结果

    import  math 
    print(math.floor(5.5))     
    
    # 补充
    floor:地板除   向下取整
    ceil:天花板除  向上取整
    round:四舍五入取整  round n.5 奇进偶不进(对n来说)
    	round(4.5) 4
    	round(5.5) 5
    	round(4.52) 5  按正常情况
    
  40. 是否使用过functools中的函数?其作用时什么?

    from functools import reduce    # 累计算
    from functools import wraps  
    # 在装饰器中使用,如果想要保留原来函数的属性,加上wraps
    def wrapper(func):
    	@wraps(func)
    	def inner(args,**kwargs):
    		res = func(args,**kwargs)
    		print("and you")
    		return res
    	return inner
    
    @wrapper
    def func():
    	print("i am fine  think you")
    
    func()
    print(func)
    
  41. rematchsearch区别?

    search:从任意位置开始查找
    match:从头开始查找,如果不符合就不继续查找了
    
  42. 用python匹配HTML tag的时候,<.><.?>有什么区别?

    <.>是匹配任意字符(除换行符)
    <.?>匹配0个或者1个任意字符
    
  43. 如何生成一个随机数?

    random模块
    random.random  随机范围 0 <= x < 1
    random.randrange  随机获取指定范围中的整数,用法上同range
    random.uniform    随机获取指定范围中的小数
    
  44. super的作用?

    用来解决多继承之间复杂的调用关系使用super
    在多继承中,如果出现了多个同名方法,super在调用的时候,会按照mro列表的继承顺序依次调用
    
    类.mro() => lst返回的是顺序列表     
    super里的类名是指定查找mro总类名的下一个类
    
  45. 双下划线和单下划线的区别?

    双下划线:私有对象 - 只能在当前这个类里使用,不能再子类或者类外使用
    单下划线:受保护的(强制继承) - 可以在当前这个类或者子类中使用,不能在类外使用
    
  46. @staticmethodclassmethod的区别

    @staticmethod:静态方法
    	无论是对象还是类,都可以调用,不会默认传递任何参数
    @classmethod:类方法
    	无论是对象还是类,都可以调用,会默认传递类这个参数
    
  47. 实现一个单例模式(加锁)

    单例模式:这个类无论实例化多少次,都有且只有只有一个对象
    import threading
    import time 
    class Singleton:
    	instance = None
    	lock = threading.Rlock()
    	
    	def __init__(self,name):
    		self.name = name
    	def __new__(cls,*args,**kwargs):
    		if cls.instance:
    			return cls.instance
    		with cls.lock:
    			if cls.instance:
    				return cls.instance
    			time.sleep(0.1)
    			cls.instance = object.__new__(cls)
    		return cls.instance
    
    def task():
    	obj = Singleton('x')
    	print(obj)
    for i in range(10):
    	t = threading.Thread(traget = task)
    	t.start()
    
    data = Singleton('adbABXJDK')
    print(data)
    
  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. 参考下面代码片段

    # 考察的是面向对象的上下文管理,with语法的具体实现
    clss Context:
    	pass
    with Context() as ctx:
    	ctx.do_something()
    请在Context类下添加代码完成该类的实现
    
    
    实现:
    clss Context:
    	def __enter__(self):
            return self
        def __exit__(self,exc_type,exc_val,exc_tb):
            # 相当于在最后执行了文件的关闭操作,fp.close()
            print("abc123")
         def do_something(self):
            print(111)
            
    with Context() as ctx:
    	ctx.do_something()            # do_something()是一个方法的调用
        print(ctx)
    

可选题

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

    # 所有的容器类型数据都可以通过sorted进行排序(sort只局限于列表进行排序)
    sorted_lst = set([lst])       # 对列表中的数据进行去重,防止有重复数据对结果有影响
    res = sorted(sorted_lst)
    res_new = res[-2]              # 默认是升序,取索引的倒数第二位
    print(res_new)
    
    
  2. 简述Python内存管理机制

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

    # 2.3以下讲解为一道
    内存管理机制:计数器、垃圾回收、内存池
    (1).计数器 
    # 当一个对象的引用被创建或者复制时,对象的引用计数+1;当一个对象的引用被销毁时-1;当一个对象引用计数为0时,就意味着对象已经没有被使用了,可以释放其内存了
    eg:a = 100
       b = a
       print(b)
       del b          # 删除b但是a的内存空间不会删除,a的内存指向100
    # 缺点:在维护引用计数时,又可能数据产生循环引用,造成数据不能删除,造成内存泄露
    lst1 = [1,2]
    lst2 = [5,6]
    lst1.append(lst2)
    lst2.append(lst1)          # 交叉循环使用
    del lst1
    print(lst1)         # 报错:显示lst1不存在,没有被定义
    print(lst2)         # lst2的列表信息可以显示
    
    
    (2)垃圾回收:引用计数为主,标记清除和分带回收为辅
    标记清除:检测标记该对象,避免出现循环引用不能删除的对象
    分带回收:把内存中的数据分成三个区域:新生代0、老年代1、永久代2
    	​	新生代0数据超过700 , 或者老年代1,永久代2数据超过10,自动触发内存中的垃圾回收机制
    ​	     新生代0触发将清除所有三代的区域
    ​	     老年代1触发会清理1,2代
    ​	     永久代2触发只会清理自己
    
    
    (3).内存池
    # 在同一个文件当中 (python3.6)
    # -->Number 部分
    1.对于整型而言,-5~正无穷范围内的相同值 id一致
    2.对于浮点数而言,非负数范围内的相同值 id一致
    3.布尔值而言,值相同情况下,id一致
    4.复数在 实数+虚数 这样的结构中永不相同(只有虚数的情况例外)
    # -->容器类型部分
    5.字符串 和 空元组 相同的情况下,地址相同
    6.列表,元组,字典,集合无论什么情况 id标识都不同 [空元组例外]
    # 在不同的文件当中
    小数据池 ; 比如整型默认开辟 -5~256 这么多数据提前在内存中驻留
    
  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())
    		
    		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")
    obj.push("d")      # 依次入栈
    
    print(obj.pop())   # d
    print(obj.pop())   # c
    print(obj.pop())   # b
    print(obj.pop())   # a
    
  5. 请用Python实现一个链表

    class Node():
    	def __init__(self,value,next):
    		self.value = value 
    		self.next = next
    		
    head = Node("头",None)
    last = head
    
    for i in range(5):
    	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)
    
  6. 请用Python实现链表的逆转

    def reverse_link_list(head):
    	if not head or not head.next:
    	# 要是空的,或者None,直接返回head
    		return head
    	prev_node = None             # 获取上一个节点对象
    	next_node = head.next         # 获取下一个节点对象
    	current_node = head           # 获取当前节点对象
    	
    	while True:
    		current_node.next = prev_node        # 修改next的指向
    		if not next_node:
    			break                           # 如果下一个阶段对象是None
    		
    		prev_node = current_node      # 重新弄获取上一个对象,即把当前指向单独存一份,已准备后面循环时插入next属性
    		current_node = next_node     # 重新获取当前对象,即把下一个对象单独存储起来
    		next_node = current_node.next    # 重新获取下一个对象,即把下一个对象单独存储起来,所指向的下一个新对象赋值给next_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)