小闫辛苦码了 3464 个字
文章可能占用您 9 分钟
欢迎关注「全栈技术精选」
今日分享
小闫同学pythonnote.cn
查看:13144回复:541
You are never too old to set another goal or to dream a new dream.—— Les Brown
受疫情影响,让互联网的寒冬更加寒冷,金三银四也凄凄惨惨戚戚。但在这几个月小闫发现,虽然初中级工程师岗位变少,但是高级工程师岗位却依然火爆,丝毫不受影响。让小闫不经想起大四实习时,总经理曾说「社会缺少的并不是人,而是人才。如何提升自己的核心竞争力才是破局之道,强者从不受寒冬影响」当然原话已经记不清,大概就是这么个意思,你懂的 ~更多精彩文章请关注公众号『Pythonnote』或者『全栈技术精选』
言归正传,今天为大家再带来一些面试题,祝大家事随人愿。
前情回顾
面试题
1.通过装饰器装饰的函数如何不改变其自身相关信息
答:可以使用模块 functools
中的 wraps
装饰器来装饰自定义装饰器的内函数。(有点绕口,下面查看示例)正常情况下被装饰的函数,虽然可以使用原函数名进行调用,但实际上此时的函数名指向了装饰器的内函数,可以通过打印 __name__
以及 __doc__
属性来验证。使用 wraps
后,被装饰的函数相关信息就会全部保留。更多精彩文章请关注公众号『Pythonnote』或者『全栈技术精选』
from functools import wraps # <-- 导入模块
# 定义一个装饰器
def eg_decorator(func):
@wraps(func) # <-- 使用装饰器
def wrapper(*args, **kwds):
"""内函数"""
print('我是装饰器啊...')
return func(*args, **kwds)
return wrapper
# 使用定义的装饰器装饰函数
@eg_decorator
def noname():
"""
函数自身
:return: 无返回
"""
print('我是示例函数噻...')
# 调用函数
noname()
# 打印函数的 __name__ 属性
print(noname.__name__)
# 打印函数的文档字符串
print(noname.__doc__)
然后查看输出结果进行验证:
我是装饰器啊...
我是示例函数噻...
noname
函数自身
:return: 无返回
2.手写一个类,可以连接 redis 并实现 get 和 set 方法
import redis
class RedisTest(object):
def __init__(self, ip: str, port: int):
self.conn = redis.Redis(host=ip, port=port, decode_responses=False)
def get(self, key: str) -> str:
return self.conn.get(key)
def set(self, key, value):
self.conn.set(key, value)
redis_obj = RedisTest('127.0.0.1', 6379)
redis_obj.set('name', 'ethanyan')
name = redis_obj.get('name')
print(name) # b'ethanyan'
3.elasticsearch 二次查询
答:elasticsearch
中可以通过 terms lookup
(跨索引查询)实现二次查询。例如查询某个用户关注列表中所有用户发表的主帖,如果是拆开查询,需要两步:先查出关注列表,再查询发表的主帖。而使用 terms lookup
查询只需要一步即可。更多精彩文章请关注公众号『Pythonnote』或者『全栈技术精选』
POST my-index-post/_search
{
"query": {
"bool": {
"must": [
{
"terms": {
"user_item_id": {
"index": "my-index-user",
"type": "user",
"id": "0f42d65be1f5287e1c9c26e3728814aa",
"path": "friends"
}
}
}
]
}
}
}
此示例来源于
https://www.playpi.org/2019060601.html
。
分析一下上面的 DSL
语句,它先利用 id
查询用户索引my-index-user/user
,返回关注列表 friends
中的所有 item_id
;然后利用上一步骤中返回的 itemt_id
列表,去匹配主帖的 user_item_id
字段,从而查询所有的主帖。
4.语法糖 property
答:python
中提供了一个装饰器 property
,在使用对象的私有属性时,可以不再使用属性的函数的调用方式,而像普通的公有属性一样去使用属性。简单进行举例,假设一个类中有一些私有属性,我们可以通过 set/get
方法,专门来为这些私有属性提供访问接口以及设置属性时的校验操作,增加程序的健壮性和安全性,但这样操作后接口调用比较繁琐,使用装饰器 property
后,再去设置或访问私有属性时,如同正常公有属性一样实现无感操作。
如果需要设计一个「银行账户类」,只需提供姓名和余额的访问与设置操作即可。首先看一下传统的 set/get
方法:
class Account(object):
def __init__(self, name, money):
# 为了安全性考虑,不能向外部直接暴露私密信息
self.__name = name # 帐户人姓名
self.__balance = money # 帐户余额
def get_name(self):
return self.__name
def set_balance(self, money):
if isinstance(money, int):
if money >= 0:
self.__balance = money
else:
raise ValueError('输入的金额不正确')
else:
raise ValueError('输入的金额不是数字')
def get_balance(self):
return self.__balance
如果需要设置账户的余额,就需要调用方法 set_balance
,而使用装饰器后,则大大进行了简化:
class Account(object):
def __init__(self, name, money):
self.__name = name # 帐户人姓名
self.__balance = money # 帐户余额
# property 只能对获取方法装饰,并且获取方法不需要再写 get
@property
def name(self):
return self.__name
# 如果 property 装饰的属性还有 set 方法,需要写到 get方法后定义
@property
def balance(self):
return self.__balance
# 实现 set 方法, 格式: @xxx.setter ,xxx 要和property装饰的方法名一致
@balance.setter
def balance(self, money):
if isinstance(money, int):
if money >= 0:
self.__balance = money
else:
raise ValueError('输入的金额不正确')
else:
raise ValueError('输入的金额不是数字')
# 可以像共有属性一样进行访问与设置
ac = Account('tom', 10)
print(ac.name)
print(ac.balance)
ac.balance = 1000
print(ac.balance)
5.简单介绍一下 with 语句
答:with
语句是一种简化的语法,适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的「清理」操作,释放资源。比如在连接数据库并进行相关操作后可以自动关闭,无需手动调用。其原理为自动调用了上下文管理器中的关闭语句,内部主要有两个方法构成 __enter__
和 __exit__
。__enter__
方法会在执行 with
后面的语句时执行,一般用来处理操作前的内容。比如一些创建对象,初始化等。__exit__
方法会在 with
内的代码执行完毕后执行,一般用来处理一些善后收尾工作,比如文件的关闭,数据库的关闭等。更多精彩文章请关注公众号『Pythonnote』或者『全栈技术精选』
排版:小闫
图片素材:小闫
文案:小闫
长按扫描下方二维码即刻关注小闫