操作類題目
- Python 交換兩個(gè)變量的值
答:在 Python 中交換兩個(gè)對(duì)象的值通過下面的方式即可
a , b = b ,a
但是需要強(qiáng)調(diào)的是這并不是元組解包,通過 dis 模塊可以發(fā)現(xiàn),這是交換操作的字節(jié)碼是 ROT_TWO,意思是在棧的頂端做兩個(gè)值的互換操作。
- 在讀文件操作的時(shí)候會(huì)使用 read、readline 或者 readlines,簡(jiǎn)述它們各自的作用
答:read() 每次讀取整個(gè)文件,它通常用于將文件內(nèi)容放到一個(gè)字符串變量中。如果希望一行一行的輸出那么就可以使用 readline(),該方法會(huì)把文件的內(nèi)容加載到內(nèi)存,所以對(duì)于對(duì)于大文件的讀取操作來說非常的消耗內(nèi)存資源,此時(shí)就可以通過 readlines 方法,將文件的句柄生成一個(gè)生產(chǎn)器,然后去讀就可以了。
- json 序列化時(shí),可以處理的數(shù)據(jù)類型有哪些?如何定制支持 datetime 類型?
答: 可以處理的數(shù)據(jù)類型是 str、int、list、tuple、dict、bool、None, 因?yàn)?datetime 類不支持 json 序列化,所以我們對(duì)它進(jìn)行拓展。
#自定義時(shí)間序列化
import json
from datetime import datetime, date
#JSONEncoder 不知道怎么去把這個(gè)數(shù)據(jù)轉(zhuǎn)換成 json 字符串的時(shí)候,它就會(huì)去調(diào) default()函數(shù),所以都是重寫這個(gè)函數(shù)來處理它本身不支持的數(shù)據(jù)類型,
# default()函數(shù)默#認(rèn)是直接拋異常的。
class DateToJson(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.strftime('%Y-%m-%d %H:%M:%S')
elif isinstance(obj, date):
return obj.strftime('%Y-%m-%d')
else:
return json.JSONEncoder.default(self, obj)
d = {'name': 'cxa', 'data': datetime.now()}
print(json.dumps(d, cls=DateToJson))
- json 序列化時(shí),默認(rèn)遇到中文會(huì)轉(zhuǎn)換成 unicode,如果想要保留中文怎么辦?
答:可以通過 json.dumps 的 ensure_ascii 參數(shù)解決,代碼示例如下:
import json
a=json.dumps({"name":"張三"},ensure_ascii=False)
print(a)
- 有兩個(gè)磁盤文件 A 和 B,各存放一行字母,要求把這兩個(gè)文件中的信息合并(按字母順序排列),輸出到一個(gè)新文件 C 中。
答:
#文件 A.txt 內(nèi)容為 ASDCF
#文件 B.txt 內(nèi)容為 EFGGTG
with open("A.txt") as f1:
f1_txt = f1.readline()
with open("B.txt") as f2:
f2_txt = f2.readline()
f3_txt = f1_txt + f2_txt
f3_list = sorted(f3_txt)
with open("C.txt", "a+") as f:
f.write("".join(f3_list))
輸出的文件 C 的內(nèi)容為 ACDEFFGGGST
- 如果當(dāng)前的日期為 20190530,要求寫一個(gè)函數(shù)輸出 N 天后的日期,(比如 N 為 2,則輸出 20190601)。
答:這個(gè)題目考察的是 datetime 里的 timedelta 方法的使用,參數(shù)可選、默認(rèn)值都為 0:datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0) 通過這個(gè)參數(shù)可以指定不同的日期類型進(jìn)行加減操作,這里我們需要改的是 days,代碼如下
import datetime
def datetime_operate(n: int):
now = datetime.datetime.now() # 獲取當(dāng)前時(shí)間
_new_date = now + datetime.timedelta(days=n) # 獲取指定天數(shù)后的新日期
new_date = _new_date.strftime("%Y%m%d") # 轉(zhuǎn)換為指定的輸出格式
return new_date
if __name__ == '__main__':
print(datetime_operate(4))
- 寫一個(gè)函數(shù),接收整數(shù)參數(shù) n,返回一個(gè)函數(shù),函數(shù)的功能是把函數(shù)的參數(shù)和 n 相乘并把結(jié)果返回。
答:這個(gè)題目考查了閉包的使用代碼示例如下,返回函數(shù)之類型是函數(shù)對(duì)象。
def mul_operate(num):
def g(val):
return num * val
return g
m = mul_operate(8)
print(m(5))
-
下面代碼會(huì)存在什么問題,如何改進(jìn)?
def strappend(num):
str=‘first’
for i in range(num):
str+=str(i)
return str
答: 首先不應(yīng)該使用 Python 的內(nèi)置類似 str 作為變量名這里我把它改為了 s,另外在Python,str 是個(gè)不可變對(duì)象,每次迭代都會(huì)生成新的存儲(chǔ)空間,num 越大,創(chuàng)建的 str 對(duì)象就會(huì)越多,內(nèi)存消耗越大。使用 yield 改成生成器即可, 還有一點(diǎn)就是命名規(guī)范的位置,函數(shù)名改為_分割比較好,完整的代碼如下:
def str_append(num):
s = 'first'
for i in range(num):
s += str(i)
yield s
if __name__ == '__main__':
for i in str_append(3):
print(i)
- 一行代碼輸出 1-100 之間的所有偶數(shù)。
答:可以通過列表生成式,然后使用與操作如果如 1 與之后結(jié)果為 0 則表明為偶數(shù),等于 1 則為奇數(shù)。
# 方法1
print([i for i in range(1, 101) if i & 0x1 == 0])
# 方法2:測(cè)試發(fā)現(xiàn)方法二效率更高
print(list(range(2, 101, 2)))
- with 語句的作用,寫一段代碼?
with 語句適用于對(duì)資源進(jìn)行訪問的場(chǎng)合,確保不管使用過程中是否發(fā)生異常都會(huì)執(zhí)行必要的“清理”操作,釋放資源,比如文件使用后自動(dòng)關(guān)閉、線程中鎖的自動(dòng)獲取和釋放等。
其他的內(nèi)容看下面我之前寫的代碼。
#一般訪問文件資源時(shí)我們會(huì)這樣處理:
f = open(
'c:\test.txt', 'r')
data = f.read()
f.close()
# 這樣寫沒有錯(cuò),但是容易犯兩個(gè)毛病:
# 1. 如果在讀寫時(shí)出現(xiàn)異常而忘了異常處理。
# 2. 忘了關(guān)閉文件句柄
#以下的加強(qiáng)版本的寫法:
f = open('c:\test.txt', 'r')
try:
data = f.read()
finally:
f.close()
#以上的寫法就可以避免因讀取文件時(shí)異常的發(fā)生而沒有關(guān)閉問題的處理了。代碼長(zhǎng)了一些。
#但使用 with 有更優(yōu)雅的寫法:
with open(r'c:\test.txt', 'r') as f:
data = f.read()
#with 的實(shí)現(xiàn)
class Test:
def __enter__(self):
print('__enter__() is call!')
return self
def dosomething(self):
print('dosomethong!')
def __exit__(self, exc_type, exc_value, traceback):
print('__exit__() is call!')
print(f'type:{exc_type}')
print(f'value:{exc_value}')
print(f'trace:{traceback}')
print('__exit()__ is call!')
with Test() as sample:
pass
#當(dāng)對(duì)象被實(shí)例化時(shí),就會(huì)主動(dòng)調(diào)用__enter__()方法,任務(wù)執(zhí)行完成后就會(huì)調(diào)用__exit__()方法,
#另外,注意到,__exit__()方法是帶有三個(gè)參數(shù)的(exc_type, exc_value, traceback),
#依據(jù)上面的官方說明:如果上下文運(yùn)行時(shí)沒有異常發(fā)生,那么三個(gè)參數(shù)都將置為 None,
#這里三個(gè)參數(shù)由于沒有發(fā)生異常,的確是置為了 None, 與預(yù)期一致.
# 修改后不出異常了
class Test:
def __enter__(self):
print('__enter__() is call!')
return self
def dosomething(self):
x = 1/0
print('dosomethong!')
def __exit__(self, exc_type, exc_value, traceback):
print('__exit__() is call!')
print(f'type:{exc_type}')
print(f'value:{exc_value}')
print(f'trace:{traceback}')
print('__exit()__ is call!')
return True
with Test() as sample:
- Python 字典和 json 字符串相互轉(zhuǎn)化方法
答:
在 Python 中使用 dumps 方法 將 dict 對(duì)象轉(zhuǎn)為 Json 對(duì)象,使用 loads 方法可以將 Json 對(duì)象轉(zhuǎn)為 dict 對(duì)象。
dic = {'a': 123, 'b': "456", 'c': "liming"}
json_str = json.dumps(dic)
dic2 = json.loads(json_str)
print(dic2)
打印:
'{"a": 123, "b": "456", "c": "liming"}'
{'a': 123, 'b': '456', 'c': 'liming'}
我們?cè)賮砜匆粋€(gè)特殊的例子
import json
dic = {'a': 123, 'b': "456", 'c': "liming"}
dic_str = json.loads(str(dic).replace("'", "\""))
print(dic_str)
下面我解釋下上面代碼是測(cè)試什么:
首先 json.loads(jsonstr) 這里面的參數(shù)只能是 jsonstr 格式的字符串.
當(dāng)我們使用 str 將字典 dic 轉(zhuǎn)化為字符串以后,得到的結(jié)果為:"{‘a(chǎn)’: 123, ‘b’: ‘456’, ‘c’: ‘liming’}"。
如果直接使用 json.loads(str(dic)) 你會(huì)發(fā)現(xiàn)出現(xiàn)錯(cuò)誤,原因就是,單引號(hào)的字符串不符合Json的標(biāo)準(zhǔn)格式所以再次使用了 replace("’", “”")。得到字典
其實(shí)這個(gè)例子主要目的是告訴大家 Json 的標(biāo)準(zhǔn)格式是不支持單引號(hào)型字符串的,否則會(huì)出現(xiàn)以下錯(cuò)誤。
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
60. 請(qǐng)寫一個(gè) Python 邏輯,計(jì)算一個(gè)文件中的大寫字母數(shù)量
答:
with open('A.txt') as fs:
count = 0
for i in fs.read():
if i.isupper():
count += 1
print(count)
61. 請(qǐng)寫一段 Python連接Mongo數(shù)據(jù)庫(kù),然后的查詢代碼。
答:
# -*- coding: utf-8 -*-
# @Author : 陳祥安
import pymongo
db_configs = {
'type': 'mongo',
'host': '地址',
'port': '端口',
'user': 'spider_data',
'passwd': '密碼',
'db_name': 'spider_data'
}
class Mongo():
def __init__(self, db=db_configs["db_name"], username=db_configs["user"],
password=db_configs["passwd"]):
self.client = pymongo.MongoClient(f'mongodb://{db_configs["host"]}:db_configs["port"]')
self.username = username
self.password = password
if self.username and self.password:
self.db1 = self.client[db].authenticate(self.username, self.password)
self.db1 = self.client[db]
def find_data(self):
# 獲取狀態(tài)為0的數(shù)據(jù)
data = self.db1.test.find({"status": 0})
gen = (item for item in data)
return gen
if __name__ == '__main__':
m = Mongo()
print(m.find_data())
- 說一說Redis的基本類型
答: Redis 支持五種數(shù)據(jù)類型: string(字符串) 、 hash(哈希)、list(列表) 、 set(集合) 及 zset(sorted set: 有序集合)。
- 請(qǐng)寫一段 Python連接Redis數(shù)據(jù)庫(kù)的代碼。
答:
from redis import StrictRedis, ConnectionPool
redis_url="redis:/[敲打]xx@112.27.10.168:6379/15"
pool = ConnectionPool.from_url(redis_url, decode_responses=True)
r= StrictRedis(connection_pool=pool)
- 請(qǐng)寫一段 Python連接Mysql數(shù)據(jù)庫(kù)的代碼。
答:
conn = pymysql.connect(host='localhost',
port=3306, user='root',
passwd='1234', db='user', charset='utf8mb4')#聲明mysql連接對(duì)象
cursor=conn.cursor(cursor=pymysql.cursors.DictCursor)#查詢結(jié)果以字典的形式
cursor.execute(sql語句字符串)#執(zhí)行sql語句
conn.close()#關(guān)閉鏈接
65.了解Redis的事務(wù)么
答: 簡(jiǎn)單理解,可以認(rèn)為 redis 事務(wù)是一些列 redis 命令的集合,并且有如下兩個(gè)特點(diǎn): 1.事務(wù)是一個(gè)單獨(dú)的隔離操作:事務(wù)中的所有命令都會(huì)序列化、按順序地執(zhí)行。事務(wù)在執(zhí)行的過程中,不會(huì)被其他客戶端發(fā)送來的命令請(qǐng)求所打斷。 2.事務(wù)是一個(gè)原子操作:事務(wù)中的命令要么全部被執(zhí)行,要么全部都不執(zhí)行。 一般來說,事務(wù)有四個(gè)性質(zhì)稱為ACID,分別是原子性,一致性,隔離性和持久性。 一個(gè)事務(wù)從開始到執(zhí)行會(huì)經(jīng)歷以下三個(gè)階段:
開始事務(wù)
命令入隊(duì)
執(zhí)行事務(wù) 代碼示例:
import redis
import sys
def run():
try:
conn=redis.StrictRedis('192.168.80.41')
# Python中redis事務(wù)是通過pipeline的封裝實(shí)現(xiàn)的
pipe=conn.pipeline()
pipe.sadd('s001','a')
sys.exit()
#在事務(wù)還沒有提交前退出,所以事務(wù)不會(huì)被執(zhí)行。
pipe.sadd('s001','b')
pipe.execute()
pass
except Exception as err:
print(err)
pass
if __name__=="__main__":
run()
66.了解數(shù)據(jù)庫(kù)的三范式么?
答: 經(jīng)過研究和對(duì)使用中問題的總結(jié),對(duì)于設(shè)計(jì)數(shù)據(jù)庫(kù)提出了一些規(guī)范,這些規(guī)范被稱為范式 一般需要遵守下面3范式即可: 第一范式(1NF):強(qiáng)調(diào)的是列的原子性,即列不能夠再分成其他幾列。 第二范式(2NF):首先是 1NF,另外包含兩部分內(nèi)容,一是表必須有一個(gè)主鍵;二是沒有包含在主鍵中的列必須完全依賴于主鍵,而不能只依賴于主鍵的一部分。 第三范式(3NF):首先是 2NF,另外非主鍵列必須直接依賴于主鍵,不能存在傳遞依賴。即不能存在:非主鍵列 A 依賴于非主鍵列 B,非主鍵列 B 依賴于主鍵的情況。
67.了解分布式鎖么
答: 分布式鎖是控制分布式系統(tǒng)之間的同步訪問共享資源的一種方式。 對(duì)于分布式鎖的目標(biāo),我們必須首先明確三點(diǎn):
任何一個(gè)時(shí)間點(diǎn)必須只能夠有一個(gè)客戶端擁有鎖。
不能夠有死鎖,也就是最終客戶端都能夠獲得鎖,盡管可能會(huì)經(jīng)歷失敗。
錯(cuò)誤容忍性要好,只要有大部分的Redis實(shí)例存活,客戶端就應(yīng)該能夠獲得鎖。 分布式鎖的條件 互斥性:分布式鎖需要保證在不同節(jié)點(diǎn)的不同線程的互斥 可重入性:同一個(gè)節(jié)點(diǎn)上的同一個(gè)線程如果獲取了鎖之后,能夠再次獲取這個(gè)鎖。 鎖超時(shí):支持超時(shí)釋放鎖,防止死鎖 高效,高可用:加鎖和解鎖需要高效,同時(shí)也需要保證高可用防止分布式鎖失效,可以增加降級(jí)。 支持阻塞和非阻塞:可以實(shí)現(xiàn)超時(shí)獲取失敗,tryLock(long timeOut) 支持公平鎖和非公平鎖
分布式鎖的實(shí)現(xiàn)方案 1、數(shù)據(jù)庫(kù)實(shí)現(xiàn)(樂觀鎖) 2、基于zookeeper的實(shí)現(xiàn) 3、基于Redis的實(shí)現(xiàn)(推薦)
68.用 Python 實(shí)現(xiàn)一個(gè) Reids 的分布式鎖的功能
答:REDIS分布式鎖實(shí)現(xiàn)的方式:SETNX + GETSET,NX是Not eXists的縮寫,如SETNX命令就應(yīng)該理解為:SET if Not eXists。 多個(gè)進(jìn)程執(zhí)行以下Redis命令:
SETNX lock.foo
如果 SETNX 返回1,說明該進(jìn)程獲得鎖,SETNX將鍵 lock.foo 的值設(shè)置為鎖的超時(shí)時(shí)間(當(dāng)前時(shí)間 + 鎖的有效時(shí)間)。 如果 SETNX 返回0,說明其他進(jìn)程已經(jīng)獲得了鎖,進(jìn)程不能進(jìn)入臨界區(qū)。進(jìn)程可以在一個(gè)循環(huán)中不斷地嘗試 SETNX 操作,以獲得鎖。
import time
import redis
from conf.config import REDIS_HOST, REDIS_PORT, REDIS_PASSWORD
class RedisLock:
def __init__(self):
self.conn = redis.Redis(host=REDIS_HOST, port=REDIS_PORT, password=REDIS_PASSWORD, db=1)
self._lock = 0
self.lock_key = ""
@staticmethod
def my_float(timestamp):
"""
Args:
timestamp:
Returns:
float或者0
如果取出的是None,說明原本鎖并沒人用,getset已經(jīng)寫入,返回0,可以繼續(xù)操作。
"""
if timestamp:
return float(timestamp)
else:
#防止取出的值為None,轉(zhuǎn)換float報(bào)錯(cuò)
return 0
@staticmethod
def get_lock(cls, key, timeout=10):
cls.lock_key = f"{key}_dynamic_lock"
while cls._lock != 1:
timestamp = time.time() + timeout + 1
cls._lock = cls.conn.setnx(cls.lock_key, timestamp)
# if 條件中,可能在運(yùn)行到or之后被釋放,也可能在and之后被釋放
# 將導(dǎo)致 get到一個(gè)None,float失敗。
if cls._lock == 1 or (
time.time() > cls.my_float(cls.conn.get(cls.lock_key)) and
time.time() > cls.my_float(cls.conn.getset(cls.lock_key, timestamp))):
break
else:
time.sleep(0.3)
@staticmethod
def release(cls):
if cls.conn.get(cls.lock_key) and time.time() < cls.conn.get(cls.lock_key):
cls.conn.delete(cls.lock_key)
def redis_lock_deco(cls):
def _deco(func):
def __deco(*args, **kwargs):
cls.get_lock(cls, args[1])
try:
return func(*args, **kwargs)
finally:
cls.release(cls)
return __deco
return _deco
@redis_lock_deco(RedisLock())
def my_func():
print("myfunc() called.")
time.sleep(20)
if __name__ == "__main__":
my_func()
69.寫一段 Python 使用 mongo 數(shù)據(jù)庫(kù)創(chuàng)建索引的代碼:
答:
# -*- coding: utf-8 -*-
# @Time : 2018/12/28 10:01 AM
# @Author : cxa
import pymongo
db_configs = {
'type': 'mongo',
'host': '地址',
'port': '端口',
'user': 'spider_data',
'passwd': '密碼',
'db_name': 'spider_data'
}
class Mongo():
def __init__(self, db=db_configs["db_name"], username=db_configs["user"],
password=db_configs["passwd"]):
self.client = pymongo.MongoClient(f'mongodb://{db_configs["host"]}:{db_configs["port"]}')
self.username = username
self.password = password
if self.username and self.password:
self.db1 = self.client[db].authenticate(self.username, self.password)
self.db1 = self.client[db]
def add_index(self):
"""
通過create_index添加索引
"""
self.db1.test.create_index([('name', pymongo.ASCENDING)], unique=True)
def get_index(self,):
"""
查看索引列表
"""
indexlist=self.db1.test.list_indexes()
for index in indexlist:
print(index)
if __name__ == '__main__':
m = Mongo()
m.add_index()
print(m.get_index())
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
