python笔试题

1、常用的字符串格式化方法有哪些?并说明他们的区别

a. 使用%,语法糖

print("我叫%s,今年%d岁" % ("oxs", 18))    # 我叫oxs,今年18岁

b. 通过{}替代%,后面跟.forma()函数

print("我叫{},今年{}岁".format("oxs", 18))    # 我叫oxs,今年18岁
3、利用python打印前一天的本地时间,格式化为“2018-01-30”

先获取当前时间戳时间-(60*60*24),再转化为格式化时间strftime("%Y-%m-%d")【strftime("%Y-%m-%d %H:%M:%S")】

import time
print(time.strftime("%Y-%m-%d", time.localtime(time.time())))
4、python中re模块的search()和match()的区别

相同点:
都接收两个参数(正则表达式, 待匹配的字符串)
都只匹配一个符合条件的项
区别点:
search 根据所写的正则匹配符合条件的第一个
match 根据所写的正则 从头开始 匹配,相当于在正则表达式的开始位置加一个"^"
例子:匹配Hello
search 只要句中有Hello就能匹配上,aaasjhdHellokjasd
match Hello必须在句首才能匹配上,Helloaaasjhdkjasd

5、什么是lambda函数,有什么好处?

匿名函数:可以和内置函数合用,有效减少冗余代码

6、说明__init__和__new__的作用

__init__ :初始化方法 默认参数-self
__new__:构造方法 默认参数-cls 创建对象
__del__:析构方法 删除一个对象之前执行的方法

7、简述反射是怎么回事

用字符串数据类型的变量名或者是函数名来调用对应的属性
什么时候用反射:例--》A.b(A对象/模块/类.b属性/方法)==》getattr(A, 'b')

8、解释python中深浅拷贝的区别

深copy:不管一个数据类型有多少层,都另外开辟新的空间存储一份和原来一模一样的数据
浅copy:只是重新开辟一块空间来copy第一层的数据,涉及到容器类的数据类型,只存储它的内存地址

9、用最简洁的方式生成如题列表[4, 16, 32, 64, 128]
l = []
for i in range(2, 8):
    if i != 3:
        l.append(2**i)    # 或者是l.append(pow(2, 3))
10、python中如何实现随机数并打印,默认随机数范围是多少

random.random() 范围 0~1

11、新式类和经典类(旧式类)的区别

新式类(默认继承object):
- 在继承的过程中,寻找一个方法遵循广度优先
- 内置mro方法来标识广度优先的顺序
经典类:
- 在继承的过程中,寻找一个方法遵循深度优先

12、装饰器什么时候被执行

在被装饰的函数调用的时候(加载函数的时候被执行)
例子:用装饰器实现打印程序的运行时间

import time
def timmer(func):
    def inner(*args, **kwargs):
        start = time.time()
        ret = func(*args, **kwargs)
        print(time.time() - start)
        return ret
    return inner

# 相当于执行println = timmer(println)
@timmer
def println(): pass
13、什么是“并发”?什么是“并行”?

并发(多线程):在同一时间,只能有一个CPU在处理任务(看起来一起执行 GIL锁在同一时刻限制了多个线程只能有一个线程被CPU执行)
并行(多进程):是真正意义上的在同一时刻有多个CPU在处理任务(多线程在同一时刻可以占用多个CPU)

14、以个人理解描述Event的执行原理

有一个状态控制wait方法是否阻塞

15、什么是粘包,如何避免

TCP协议:面向连接的流传输,数据是无边界的。如何避免:自定义协议 struct模块
UDP协议:不存在粘包现象

16、什么是进程

运行中的程序 是最小的资源分配单位 为多个任务之间的数据安全和内存隔离做约束

17、什么是线程

cpu调度的最小单位 轻量级的进程 是进程的一部分 可以共享进程中的数据

18、简述你对管道、队列的理解

管道:双向通信的数据容器 多进程的IPC中用到了 数据不安全
队列:基于管道和锁实现的一个数据在线程/进程之间安全的容器 先进先出

21、使用python简单实现打印九九乘法表
# for循环的四种乘法表
print('=' * 33 + ' for 1' + '=' * 33)
for i in range(1, 10):
    for j in range(1, i + 1):
        print('{}*{}={:<2}'.format(j, i, j * i), end='\t')
    print()
print('=' * 33 + ' for 1' + '=' * 33)

print('=' * 33 + ' for 2' + '=' * 33)
for i in range(9, 0, -1):
    for j in range(1, i + 1):
        print('{}*{}={:<2}'.format(j, i, j * i), end='\t')
    print()
print('=' * 33 + ' for 2' + '=' * 33)

print('=' * 33 + ' for 3' + '=' * 33)
for i in range(1, 10):
    for j in range(9, 0, -1):
        if j <= i:
            print('{}*{}={:<2}'.format(j, i, j * i), end='\t')
        else:
            print('{:<6s}'.format(''), end='\t')
    print()
print('=' * 33 + ' for 3' + '=' * 33)

print('=' * 33 + ' for 4' + '=' * 33)
for i in range(9, 0, -1):
    for j in range(9, 0, -1):
        if j <= i:
            print('{}*{}={:<2}'.format(j, i, j * i), end='\t')
        else:
            print('{:<6s}'.format(''), end='\t')
    print()
print('=' * 33 + ' for 4' + '=' * 33)
# for循环的四种乘法表

# while循环的四种乘法表
print('=' * 32 + ' while 1' + '=' * 32)
i = 1
while i <= 9:
    j = 1
    while j <= i:
        print('{}*{}={:<2}'.format(j, i, j * i), end='\t')
        j += 1
    print()
    i += 1
print('=' * 32 + ' while 1' + '=' * 32)

print('=' * 32 + ' while 2' + '=' * 32)
i = 9
while i >= 1:
    j = 1
    while j <= i:
        print('{}*{}={:<2}'.format(j, i, j * i), end='\t')
        j += 1
    print()
    i -= 1
print('=' * 32 + ' while 2' + '=' * 32)

print('=' * 32 + ' while 3' + '=' * 32)
i = 1
while i <= 9:
    j = 9
    while j >= 1:
        if j <= i:
            print('{}*{}={:<2}'.format(j, i, j * i), end='\t')
        else:
            print('{:<6s}'.format(''), end='\t')
        j -= 1
    print()
    i += 1
print('=' * 32 + ' while 3' + '=' * 32)

print('=' * 32 + ' while 4' + '=' * 32)
i = 9
while i >= 1:
    j = 9
    while j >= 1:
        if j <= i:
            print('{}*{}={:<2}'.format(j, i, j * i), end='\t')
        else:
            print('{:<6s}'.format(''), end='\t')
        j -= 1
    print()
    i -= 1
print('=' * 32 + ' while 4' + '=' * 32)
# while循环的四种乘法表
22、简述python GIL的概念,以及它对python多线程的影响

GIL:全局解释器锁 属于Cpython解释器
用来在Cpython解释器解释一段多线程代码时,约束线程在同一时刻只能有一个线程访问CPU
它对python多线程的影响:在Cpython解释器下启动的多线程并不能真正实现并行

23、写一个单例模式
# ########### 单例类定义 ###########
class Foo(object):
 
    __instance = None
 
    @staticmethod
    def singleton():
        if Foo.__instance:
            return Foo.__instance
        else:
            Foo.__instance = Foo()
            return Foo.__instance
 
# ########### 获取实例 ###########
obj = Foo.singleton()
24、编程题:将以下list3的格式转换成list4格式

list3 = [
{"name": "alex", "hobby": "抽烟"}
{"name": "alex", "hobby": "喝酒"}
{"name": "alex", "hobby": "烫头"}
{"name": "alex", "hobby": "Massage"}
{"name": "egon", "hobby": "喊麦"}
{"name": "egon", "hobby": "街舞"}
]

如何把上面的列表转换成下方的列表

list4 = [
{"name": "alex", "hobby_list": ["抽烟", "喝酒", "烫头", "Massage"]}
{"name": "egon", "hobby_list": ["喊麦", "街舞"]}
]

list4 = []
for item in list3:
    for dic in list4:
        if item['name'] == dic['name']:
            dic['hobby'].append(item['hobby'])
            break
    else:
        list4.append({'name': item['name'], 'hobby_list': [item['hobby']]})
print(list4)
25、编程题

"""
一、定义一个学生类。有如下的类属性:
1 姓名
2 年龄
3 成绩(语文,数学,英语)[每科成绩的类型为整数]
类方法:
1 获取学生的姓名:get_name() 返回类型:str
2 获取学生的年龄:get_age() 返回类型:int
3 返回3门科目中最高分:get_course() 返回类型:int
写好类之后,可以定义2名学生测试
zm = Student('zhangming', 20, [69, 88, 100])
返回结果:
zhangming
20
100
"""

class Student():
    def __init__(self, name, age, score)
        self.name = name
        self.age = age
        self.score= score
    # isinstance函数判断一个对象是否是一个已知的类型,类似type
    def get_name(self):
        if isinstance(self.name, str):
            return self.name
    
    def get_age(self):
        if isinstance(self.age, int):
            return self.age
    
    def get_score(self):
        s = max(self.score)
        if isinstance(s, int):
            return s

zm = Student('zhangming', 20, [69, 88, 100])
print(zm.get_name())
print(zm.get_age())
print(zm.get_score())

"""
二、定义一个字典类:dictclass。完成下面的功能:
dict = dictclass({你需要操作的字典对象})
1 删除某个key,del_dict(key)
2 判断某个键是否在字典里,如果在返回键对应的值,不存在则返回"not found",get_dict(key)
3 返回键组成的列表:返回类型;(list),get_key()
4 合并字典,并且返回合并后字典的values组成的列表。返回类型:(list),update_dict({要合并的字典})
"""

class Dictclass():
    # 构造函数
    # 对当前对象的实例的初始化
    def __init__(self, class1):
        self.classs = class1

    def del_dict(self, key):
        if key in self.classs.keys():
            del self.classs[key]
            return self.classs
        return "不存在这个值,无需删除"

    def get_dict(self, key):
        if key in self.classs.keys():
            return self.classs[key]
        return "not found"

    def get_key(self):
        return list(self.classs.keys())

    def update_dict(self, dict1):
        # 方法1
        # self.classs.update(dict1)
        # 方法2,对于重复的key,B会覆盖A
        a = dict(self.classs, **dict1)
        return a


a = Dictclass({"姓名": "张三", "年龄": "18", "性别": "男"})
print(a.del_dict("年龄"))
print(a.get_dict("姓名"))
print(a.get_key())
print(a.update_dict({"年薪": 0}))

"""
三、定义一个列表的操作类:Listinfo
包括的方法:
1 列表元素添加: add_key(keyname) [keyname:字符串或者整数类型]
2 列表元素取值:get_key(num) [num:整数类型]
3 列表合并:update_list(list) [list:列表类型]
4 删除并且返回最后一个元素:del_key()
a = Listinfo([44,222,111,333,454,'sss','333'])
"""

class Listinfo():
    def __init__(self, my_list):
        self.listt = my_list

    def add_key(self, keyname):
        if isinstance(keyname, (str, int)):
            self.listt.append(keyname)
            return self.listt
        return "error"

    def get_key(self, num):
        if num >= 0 and num < len(self.listt):
            a = self.listt[num]
            return a
        return "超出取值范围"

    def update_list(self, list1):
        if isinstance(list1, list):
            self.listt.extend(list1)
            return self.listt
        return "类型错误"

    def del_key(self):
        a = self.listt.pop(-1)
        return a


a = Listinfo([44, 222, 111, 333, 454, 'sss', '333'])
print(a.add_key(1))
print(a.get_key(1))
print(a.update_list([1, 2, 3]))
print(a.del_key())

"""
定义一个集合的操作类:Setinfo
包括的方法:
1 集合元素添加: add_setinfo(keyname) [keyname:字符串或者整数类型]
2 集合的交集:get_intersection(unioninfo) [unioninfo :集合类型]
3 集合的并集: get_union(unioninfo)[unioninfo :集合类型]
4 集合的差集:del_difference(unioninfo) [unioninfo :集合类型]
set_info = Setinfo(你要操作的集合)
"""

class Setinfo():
    def __init__(self, my_set):
        self.sett = my_set

    def add_setinfo(self, keyname):
        if isinstance(keyname, (str, int)):
            self.sett.add(keyname)
            return self.sett

    def get_intersection(self, unioninfo):
        if isinstance(unioninfo, set):
            a = self.sett & (unioninfo)
            return a

    def get_union(self, unioninfo):
        if isinstance(unioninfo, set):
            a = self.sett | (unioninfo)
            return a

    def del_difference(self, unioninfo):
        if isinstance(unioninfo, set):
            a = self.sett - (unioninfo)
            return a


a = Setinfo({1, "a", 2, "b", 3, "c"})
print(a.add_setinfo(4))
print(a.get_intersection({1, 2, "a"}))
print(a.get_union({2, 3, 4, "c", "d"}))
print(a.del_difference({1, 2, 3, 4}))
27、什么是异步?什么是异步阻塞?

异步:在同一时间 可以同时做两件事情(多线程、多进程)
异步阻塞:在同一时刻各自的线程或者进程中存在IO操作 而不影响其他线程或进程

28、写一个程序,包含十个线程,子线程必须等待主线程sleep10秒钟之后才执行,并打印当前时间
from threading import Timer
def func():pass
for i in range(10):
    Timer(10, func).start()
29、你所了解的锁有哪些

互斥锁 在同一线程或者进程之间,当有两个acquire的时候,就会产生阻塞,造成死锁
递归锁 在同一线程或者进程之间,无论acquire多少次都不会产生阻塞

30、threading.Rlock和threading.Lock的区别

Rlock是递归锁
Lock是互斥锁

31、简述 生成器、迭代器、可迭代对象 以及应用场景?

生成器(generator):列表元素可以按照某种算法推算出来(有规律的数组),则可以在循环的过程中不断推算出后续的元素。这种方式就不必创建完整的list,可以节省大量的空间。python中,这种一边循环一边计算的机制,称为生成器:generator。

迭代器(Iterator):可以被next()函数调用并不断返回下一个值得对象称为迭代器(Iterator)。

可迭代对象(Iterable):可以直接作用于for循环的对象(其中包含集合数据类型:list\tuple\dict\set\str;还包含生成器表达式和生成器函数)。可以使用isinstance()判断一个对象是否是Iterable对象。

你可能感兴趣的:(python笔试题)