-
简述列举了解的编程语言及语言间的区别?
Python Python是一门解释型语言,弱类型语言,语法简洁开发效率高,有丰富的第三方库,但是相比编译型语言运行速度慢,代码不可加密
c语言 编译型语言,运行速度快,强类型语言
Java 混合型语言,运行速度快,强类型语言 -
列举Python2和Python3的区别?
- Python2中print是语句不需要括号即可输出,Python3print是函数需要
- Python2默认ASCII,Python3默认Unicode
- Python2中存在老式类和新式类,Python3中统一采用新式类
-
看代码写结果
v1 = 1 or 2
1
v2 = 3 and 7 or 9 and 0
7 -
比较以下值有什么不同?
v1 = [1,2,3]
v2 = [(1),(2),(3)]
v3 = [(1,),(2,),(3,)]
v1,v2列表中的元素类型是数字,v2中的元素是元组 -
用一行代码实现数值交换。
a = 1
b = 2
a,b=b,a -
Python中单引号、双引号、三引号的区别?
单引号和双引号中间是字符串,三引号中间是注释
单双引号没有区别,三引号可以支持跨行在互相嵌套时需注意:里外不能使用相同的引号 -
is和==的区别?
is 判断两边内存地址是否相同
== 是比较值是否相等 -
python里如何实现tuple和list的转化?
a= (1,2) a=list(a) a=tuple(a)
-
如何实现字符串 name='老男孩’的反转?
n = name[::-1]
-
两个set如何获取交集、并集、差集?
a ={1,2,3,4} b = {2,3,5,6} print(a&b) print(a|b) print(a-b)
-
那些情况下, y != x - (x-y)会成立?
“”“非空集合且不为子父关系的两个集合”""
y != x-(x-y)
x = {“a”,“b”,“c”}
y = {“b”,“d”}
if y != x-(x-y):
print(“ok”) -
Python中如何拷贝一个对象?
copy.copy() -
简述 赋值、浅拷贝、深拷贝的区别?
#赋值 : 将变量和值在内存中形成映射指向关系 #浅拷贝 : 只拷贝第一级里所有的元素 copy.copy #深拷贝 : 为所有层级的元素都单独开辟新空间 copy.deepcopy() (地址:原不可变数据只是暂时的指向,可变的数据独立开辟新空间) """ 可变数据: list set dict 不可变数据: int float bool complex str tuple """
-
pass的作用?
占位 -
阅读代码写结果。
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(d) [1,2,4,5,['b','c']]
-
用Python实现9 * 9 乘法表。
#1 for i in range(1,10): for j in range(1,i+1): print(str(j)+'*'+str(i)+'='+str(i*j),end=' ') print('\n') # 2 i = 1 while i<=9: # 这个位置写代码 j = 1 while j<= i: # "谁"*"谁"="谁" print("%d*%d=%2d" % (i,j,i*j),end=" ") j+=1 # 打印换行 print() i+=1 # 3 for i in range(1,10): for j in range(1,i+1): print("%d*%d=%2d" % (i,j,i*j),end=" ") print()
-
用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)) def func(a): if a<=1: return a return func(a-1)+func(a-2) for i in range(1,10): print(func(i))
-
如何删除列表中重复的值?
a = [1,1,2,3,4,4]
a = list(set(a)) -
一个大小为100G的文件etl_log.txt, 要读取文件中的内容, 写出具体过程代码?
with open("文件名","模式","编码集") as fp: fp.read()
-
a = dict(zip((“a”,“b”,“c”,“d”,“e”),(1,2,3,4,5))) 请问a是什么?
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
-
lambda关键字的作用?
匿名函数 -
*arg和**kwarg作用?
# *arg 普通收集参数 : 收集多余的没人要的普通实参# **kwarg 关键字收集参数: 收集多余的没人要的关键字实参 -
如何在函数中设置一个全局变量 ?
global -
filter、map、reduce的作用?
filter 过滤元素,返回一个迭代器对象
map 映射
reduce 会对元素进行累积 -
什么是匿名函数?匿名函数有什么作用?
使用lambda表示匿名函数
不需要显示的定义函数,方便 -
Python递归的最大层数?
官方说法1000 , 实际测试 994 ~ 1000
import sys
sys.setrecursionlimit(999999) # 修改递归的最大深度 -
什么是迭代器?什么是可迭代对象?
实现了iter和next()方法的对象都是迭代器
实现了iter方法的对象叫做可迭代对象 -
什么是生成器?
生成器的本质就是迭代器,可以自定义迭代的逻辑
创建方式两种:
(1)生成器表达式 (推导式) (i for i in range(3))
(2)生成器函数 (含有yield关键字) -
什么是装饰器及应用场景?
# 装饰器的本质就是闭包
# 在不修改原有代码的前提下,额外增加新功能就是装饰器
# 应用:登录认证,property类,框架(django,flask,@app.route("/",methdos=[“GET”,“POST”])) -
什么是反射及应用场景?
# 通过字符串去操作类对象 或者 模块中的属性方法
hasattr getattr setattr delattr
应用: 可以配合用户的操作或者输入,调用其中的成员,api接口中 -
写一个普通的装饰器。
def warpper(f):
def inner():
f()
return inner
@warpper
def func():
print("被装饰的函数")
- 写一个带参数的装饰器。
def outer(n):
def wrapper(func):
def inner1(*args,**kwargs):
res = func(*args,**kwargs)
print("我是大王")
return res
def inner2(*args,**kwargs):
res = func(*args,**kwargs)
print("大王叫我来巡山")
return res
if n == "alex":
return inner1
else:
return inner2
return wrapper
@outer("alex123") # outer("alex123") => wrapper =>@wrapper
def func():
print("i am fine 3q")
func()def warpper(func):
def inner(*args,**kwargs):
func(*args,**kwargs)
return inner
@warpper
def foo():
print("被装饰的函数")
- 求结果
def num():
return [lambda x:i*x for i in range(4)]
print([m(2) for m in num()])
# [6, 6, 6, 6]
-
def(a, b=[])这种写法有什么陷阱?
b身上的默认值是列表,如果使用原来默认的参数,调用func函数
会把几次调用的值都存放在同一个默认列表里
“”"
默认参数:
如果调用时,用户给实参了,那么使用用户的
如果调用时,用户没给实参,那么使用默认的(早已存在内存中的这个列表)默认值会提前在内存中驻留,在使用时,才能调取,在定义函数的时候就提前开辟了空间 """
-
看代码写结果
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]
- 看代码写结果
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]
-
请编写一个函数实现将IP地址转换成一个整数。
如 10.3.9.12 转换规则为:
10 00001010
3 00000011
9 00001001
12 00001100再将以上二进制拼接起来计算十进制结果:00001010 00000011 00001001 00001100 = ? # ljust 原字符串居左,填充符号 # rjust 原字符串居右,填充符号 # 方法一 ip = "10.3.9.12" strvar = "" for i in ip.split("."): bin_str = str(bin(int(i)))[2:] # 总长度是8 原字符串居右 strvar += bin_str.rjust(8,"0") print(strvar) # 把二进制字符串转换成十进制,默认转换时,是十进制 print(int(strvar,2)) # 方法二 ip = "10.3.9.12" strvar = "" for i in ip.split("."): # format 将整型转化成二进制,不够8位的拿0补位 strvar += format(int(i) , "08b") print(int(strvar,2))
-
请查找一个目录下的所有文件(可能存在文件嵌套)。
# 方法一 (递归写法) 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 # "E:\day2\test\1.txt" pathvar = r"E:\day2\test" res = getallsize(pathvar) # print(res) # 方法二 import os # os.walk() => 生成器 pathvar = r"E:\day2\test" gen = os.walk(pathvar) for root,dirs,files in gen: for name in files: pathvar = os.path.join(root,name) print(pathvar)
-
求结果
import math
print (math.floor(5.5))
# 5
-
是否使用过functools中的函数?其作用是什么?
from functools import reduce # 在装饰器中使用,如果想要保留原来函数的属性,加上wraps from functools import 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 3q") func() print(func)
-
re的match和search区别?
match : 必须从字符串的开头进行匹配
search: 从任意位置开始匹配,匹配到就返回只匹配一个 -
用Python匹配HTML tag的时候,<.>和<.?>有什么区别?
. 除了\n的任意字符
* 量词,代表匹配0次或者多次,任意个
.* 贪婪匹配
.*? 非贪婪匹配 -
如何生成一个随机数?
import randomrandom.random 随机获取 0<= x < 1
random.randrange 随机获取指定范围中的整数,用法上同
rangerandom.uniform 随机获取指定范围中的小数
-
super的作用?
# 用来解决多继承之间复杂的调用关系使用super 在多继承中,如果出现了多个同名方法 super在调用的时候,会按照mro列表的继承顺序依次调用
-
双下划线和单下划线的区别?
class MyClass():
__abc = 90
_ppp = 100
"""
封装: 公有public 私有private 受保护的protected
私有: 只能在当前这个类里面使用,不能再子类或者在类外使用
受保护的: 可以在当前这个类或者子类里使用,不能再类外使用
约定俗成在该变量前面加上一个下划线_ , 就表示受保护了
"""
-
@staticmethod和@classmethod的区别?
一个静态方法,一个类方法 一个静态方法:(无论是对象还是类,都可以调用,不会默认传递任何参数) 一个类方法 :(无论是对象还是类,都可以调用,会默认传递类这个参数)
-
实现一个单例模式(加锁)。
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
-
栈和队列的区别?
栈 先进后出,队列 先进先出 -
以下代码输出是什么? 请给出答案并解释。
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
-
参考下面代码片段
class Context: pass with Content() as ctx: ctx.do_something() 请在Context类下添加代码完成该类的实现 class Context(): def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): # 相当于在最后,执行了文件的关闭操作,fp.close() print("abc123") def do_something(self): print(1111) with Context() as ctx: ctx.do_something() print(ctx)
第二部分 可选题
-
如何获取列表中第二大的值?
先去重,在排序,取值 -
简述Python内存管理机制。
-
简述Python的垃圾回收机制。
计数器,垃圾回收,内存池
# 一.计数器
特点:引用技术如果是0,把这个值从内存中释放掉
a = 100
b = a
print(b)
del b
缺点:在维护引用计数时,又可能数据产生循环引用,造成数据不能删除,造成内存泄漏
lst1 = [1,2]
lst2 = [5,6]
lst1.append(lst2)
lst2.append(lst1)
del lst1
print(lst1)
print(lst2)
# print(lst1)
# print(lst2)
# 二.垃圾回收:引用计数为主,标记清除和分带回收为辅
标记清除 : 检测标记该对象,避免出现循环引用不能删除的现象
分带回收 :
把内存中的数据分成三个区域: 新生代0,老年代1,永久代2
新生代0数据超过700 , 或者老年代1,永久代2数据超过10,自动触发内存中的垃圾回收机制
新生代0触发将清除所有三代的区域
老年代1触发会清理1,2代
永久代2触发只会清理自己
# 三.内存池
# 在同一个文件当中 (python3.6)
# -->Number 部分
1.对于整型而言,-5~正无穷范围内的相同值 id一致
2.对于浮点数而言,非负数范围内的相同值 id一致
3.布尔值而言,值相同情况下,id一致
4.复数在 实数+虚数 这样的结构中永不相同(只有虚数的情况例外)
# -->容器类型部分
5.字符串 和 空元组 相同的情况下,地址相同
6.列表,元组,字典,集合无论什么情况 id标识都不同 [空元组例外]
# 在不同的文件当中
小数据池 ; 比如整型默认开辟 -5~256 这么多数据提前在内存中驻留
-
请用两个队列来实现一个栈。
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
-
请用Python实现一个链表。
-
请用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("<========>")
# 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)