# -*- coding:utf-8 -*-
"""
=============================
@author:_百草_
@file:interview_qa_001.py
@time:2020/11/17
=============================
110 道python面试笔试题目
"""
"""
1、 一行代码实现1-100之和
"""
print(sum(range(1, 101)))
"""
2、 如何在一个函数内修改全局变量
"""
a = 5
def edit_global_v():
global a # 利用global variable
a = 4
edit_global_v() # 调用函数,执行修改
print(a)
"""
3、 列出5个python的标准库
注:标准库是相对第三方库而言的,标准库无需额外按照包;包括内置函数、数据类型和异常,以及各种模块。
# math/cmath :数学处理
# random/numpy提供了生成随机数的工具。
# decimal 十进制定点和浮点运算
# os模块提供了不少与操作系统相关联的函数。
# time/datetime : 提供与时间相关的函数
# sys: 通常用于命令行参数
# re :正则表达式
# logging : 日志记录工具
# json :json 编码和解码器
# email : 电子邮件与MIME处理包
# base64 : 数据编码(如,登录时密码加密)
# urllib : URL处理器(如替代request请求)
#
"""
"""
4、字典如何删除键和合并2个字典
"""
dict1 = {1: 2, 3: 4, 5: 6}
dict2 = {"name": 123, "sex": "boy", "age": 12}
# del dict1[1] # 删除键值对
# dict1.update(dict2) # 合并字典
# print(dict1)
# # 合并字典2
# for k, v in dict2.items():
# dict1[k] = v
# print(dict1)
# 合并字典3
dict3 = dict(dict1, **dict2)
# dict3 = dict(**dict1, **dict2) # TypeError: keywords must be strings
print(dict3)
"""
5、谈下python的GIL
GIL是python的全局解释器锁,同一进程中假如有多个线程运行,一个线程在运行python程序的时候会霸占python解释器
(加了一把锁即GIL),使该进程内的其他线程无法运行,等该线程运行完成后其他线程才能运行。
若干线程运行过程中遇到耗时操作,则解释器锁解开,使其他线程运行。
所以在多线程中,线程的运行仍是有先后顺序的,并不是同时进行
多进程中因为每个进程都能被系统分配资源,相当于每个进程有了一个python解释器,
所以多进程可以实现多个进程的同时运行,缺点是进程系统资源开销大。
GIL[官网解释]
参见 global interpreter lock。
global interpreter lock -- 全局解释器锁
CPython 解释器所采用的一种机制,它确保同一时刻只有一个线程在执行 Python bytecode。此机制通过设置对象模型
(包括 dict 等重要内置类型)针对并发访问的隐式安全简化了 CPython 实现。给整个解释器加锁使得解释器多线程运行更方便,
其代价则是牺牲了在多处理器上的并行性。
不过,某些标准库或第三方库的扩展模块被设计为在执行计算密集型任务如压缩或哈希时释放 GIL。
此外,在执行 I/O 操作时也总是会释放 GIL。
创建一个(以更精细粒度来锁定共享数据的)“自由线程”解释器的努力从未获得成功,因为这会牺牲在普通单处理器情况下的性能。
据信克服这种性能问题的措施将导致实现变得更复杂,从而更难以维护。
"""
"""
6、python 实现列表去重的方法
"""
list1 = [1, 1, 2, 3, 4, 4, 5]
# a= list(set(list1)) # 方式1:集合去重
# print(a)
# 方式2:列表递推式
# 把普通的多行for循环压缩成一行代码
# 注意:这种方式只适合简单的场景,性能高于列表操作
# 过于复杂我们就不需要用了,可读性是我们追求的
b = []
# for i in list1:
# if i not in b:
# b.append(i)
# b = [i for i in list1 if i not in b] # error,未实现
print(b)
"""
7、fun(*arg,**kwargs)中*arg,**kwargs什么意思
*args和**kwargs主要用于函数定义。你可以将不定数量的参数传递给一个函数。
这里不定,即预先不知道函数使用者会传递多少参数给你,所以在这个场景下使用这两个关键字
*args是用来发送一个非键值对的可变数量的参数列表给一个函数
**kwargs允许不定长度的键值对,作为参数传递给一个函数。
故若想要在一个函数里处理带名字的参数,你应该使用**kwargs.
"""
# 例子
def demo1(**kwargs):
for k, v in kwargs.items():
print(k, v)
def demo2(*args):
for i in args:
print(i, end=' ')
print()
demo1(name='wlh', age=18, sex='boy', clas='3年级')
demo1(name='ha ha')
demo2(1, 2, 3, 4, 5)
demo2('wlh', 'grass', 'haha')
"""
8、python2和python3的range(100)的区别
python2 返回的是一个列表[0,1,2,3……99]
python3 返回的是一个range的对象,一个迭代器,可以节省内存
"""
print(range(100)) # 输出:range(100) 其type: <class 'range'>
"""
9、一句话解释什么样的语言能够用装饰器
函数可以作为参数传递的语言,都可以使用装饰器
注:数据驱动ddt,即使用的是装饰器
"""
"""
10、 python 内建数据类型有哪些
数值:int整型、float浮点型、bool布尔型
str字符串
list列表
tuple 元组
dict 字典
"""
"""
11、 简述面向对象中__new__和__init__区别
__init__是初始化方法,创建对象后,就立刻被默认调用了,可接收参数
__init__有一个参数self,就是这个__new__返回的实例,__init__在__new__的基础上可以完成一些其他初始化的动作,__init__不需返回值
__new__至少有一个参数cls,代表当前类,此参数在实例化时由Python解释器自动识别
__new__必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,可以返回return父类
(通过super 当前类名,cls)__new__出来的实例,或者直接时object的__new__出来的实例
若__new__创建的是当前类的实例,会自动调用__init__函数,通过return 语句里面调用的__new__函数
的第一个参数cls来保证是当前类实例;若是其他类的类名,那么实际创建返回的就是其他类的实例,其实就不会调用当前类的
__init__函数,也不会调用其他类的__init__函数
"""
class Student:
def __init__(self, name, grade): # 自动被调用,可以创建对象时接收参数
self.name = name
self.grade = grade
def study(self):
print(f"{self.name} is studying")
St = Student("baicao", 13) # 实例化
print(St.name, St.grade) # 只是打印了__init__方法执行结果,study方法未执行
# -------------------------------------------------
class NewStudent:
def __init__(self):
print("这是init方法:", self)
def __new__(cls, *args, **kwargs):
# 至少要有一个参数cls,否则报错:TypeError: object.__new__(): not enough arguments
print("这是cls的ID:", id(cls))
print("这是new方法:", object.__new__(cls))
return # object.__new__(cls) # 必须有返回值
NewStudent()
NewStudent.__new__(NewStudent)
print("这是类NewStudent的ID:", id(NewStudent))
# 返回信息,如下:
# 这是cls的ID: 18482616
# 这是new方法: <__main__.NewStudent object at 0x01197FB0>
# 这是init方法: <__main__.NewStudent object at 0x01197FB0>
# 这是类NewStudent的ID: 18482616
# 说明:
# cls和类ID一致,说明执行同一个类,也就是cls就是创建的实例类
# init方法中的self和new方法返回地址一样,说明__new__是返回的对象(代表当前类)
"""
12、简述with方法打开处理文件帮我们做了什么?
"""
file = r'E:\testing\python\Test37\py31_class\pycharm\py\__init__.py'
with open(file, mode='r', encoding='utf-8') as f:
fn = f.read()
print(fn)
# f = open(file, 'wb', encoding="utf-8")
# try:
# f.write("Hello")
# except:
# pass
# finally:
# f.close()
# 打开文件在进行读写的时候可能会出现一些异常状况,如果按照常规的f.open写法,我们需要
# try-except - finally,做异常判断,并且文件最终不管遇到什么情况,都要执行finally语句
# with方法帮我们实现了 finally中的f.close
"""
13、列表[1, 2, 3, 4, 5],请使用map()函数输出[1, 4, 9, 16, 25],并使用列表推导式提取出大于10的数,最终输出[16,25]
"""
list1 = [1, 2, 3, 4, 5]
def f(x):
return x * x
res = map(f, list1)
# map(func, *iterables)
# Make an iterator that computes the function using arguments from each of the iterables.
# map()函数使用,第一个参数是function,第2个参数一般是list,第三个参数可以是list,也可以不写
print(res) # <map object at 0x0282B0F0>
res = [i for i in res if i > 10]
print(res)
"""
14、python 中生成随机整数、随机小数、0-1之间的小数的方法
"""
import random
a = 1
b = 10000
s = random.randint(a, b) # a-b范围内的随机整数
f = random.random() # 0-1之间的小数
print(f'{a}与{b}之间的随机整数:{s}')
print(f"0-1之间的随机小数:{f}")
import numpy
n = 5 # 生成随机小数的数量
f2 = numpy.random.randn(n) # 生成n个随机小数,list类型返回
print(f"{n}个随机小数:{f2}")
"""
15、避免转义给字符串加那个字母白哦是原始字符串?
r, 表示需要原始字符串,不转义特殊字符
"""
s1 = '\123baicao\nw'
s2 = r'\123baicao\nw'
print(s1)
# s1输出如下:
# Sbaicao
# w
print(s2) # 输出:\123baicao\nw
网友评论