1. 程式人生 > 實用技巧 >有質量的兩道面試題

有質量的兩道面試題

一、多層字典解析問題

原題目

{
  "Count":5,
  "Items":
  [
    {
          "name":{"string":"a"},
        "email":{"string":"[email protected]"},
        "friends":
          [
            {
              "friend1": {
                "name": {
                  "string": "name1"
                },
                "sex
": { "int": 1 }, "addr": { "string": "addr1" } } } ], "moreinfo":{ "Desc1":{"string":"aaaa"}, "Desc2":{"int":22}, "Desc3":{"list":["ddddd
","11111"]} } } ] }

將上面的json檔案,轉化為python內容,並且去掉不需要的資料例如(包含對應的資料型別如:string,int,list)之後變為

{
  "Count":5,
  "Items":
  [
    {
          "name":"a",
        "email":"[email protected]",
        "friends":
          [
            {
              "friend1": {
                "name": "name1"
                "
sex": 1 "addr": "addr1" } } ], "moreinfo":{ "Desc1":"aaaa", "Desc2":22, "Desc3":"ddddd","11111"} } } ] }

解題思路:使用遞迴解決多層字典的節點問題,子節點有列表和字典兩種表現形式,所以這兩種形式都是遞迴,

解題程式碼

import json

# 修改的函式
def modify(dic):
    # 確保傳進來的是一個字典,這裡我並沒有使用try-except做容錯,只是簡單的為了需求的實現
    if isinstance(dic,dict):
        # 變數字典的key和value
        for key,val in dic.items():
            # 這裡多層字典巢狀的話,子層主要是字典或者列表的方式,方式這裡主要針對子層是字典和列表兩種方式處理
            if isinstance(val,dict):
                # 如果val是一個字典,並且長度為1,說明是最內層的字典了,是需要做處理的地方了
                if len(val) == 1:
                    # 將內層字典的val賦值給上一層的key,即專案的需求
                    dic[key]=list(val.values())[0]
                # 如果不是最內層,繼續遞迴
                modify(val)
            # 內層資料是列表的情況
            elif isinstance(val,list):
                if len(val)>0:
                    for _dic in val:
                        # 列表裡面是字典繼續遞迴
                        modify(_dic)
                      
if __name__ == '__main__':

    with open('./test_json.json', 'r') as fp:
        json_str = fp.read()

    json_dic = json.loads(json_str)
    print('修改前列印*********************')
    print(json_dic)
    modify(json_dic)
    print('修改後列印*********************')
    print(json_dic)

列印結果

修改前列印*********************
{'Count': 5, 'Items': [{'name': {'string': 'a'}, 'email': {'string': '[email protected]'}, 'friends': [{'friend1': {'name': {'string': 'name1'}, 'sex': {'int': 1}, 'addr': {'string': 'addr1'}}}], 'moreinfo': {'Desc1': {'string': 'aaaa'}, 'Desc2': {'int': 22}, 'Desc3': {'list': ['ddddd', '11111']}}}]}
修改後列印*********************
{'Count': 5, 'Items': [{'name': 'a', 'email': '[email protected]', 'friends': [{'friend1': {'name': 'name1', 'sex': 1, 'addr': 'addr1'}}], 'moreinfo': {'Desc1': 'aaaa', 'Desc2': 22, 'Desc3': ['ddddd', '11111']}}]}

二、mongodb的基本使用

原題目:

Mongodb 查詢:
Db.msg.find()
{ "_id" : ObjectId("5f96ef6c1fb5b9e52cd23179"), "msgId" : 1696261644, "fromUserName" : "user1", "toUserName" : "user2", "msgType" : 1, "content" : "ufne", "newMsgId" : NumberLong("4690548300089373689"), "createTime" : 1603727095 }
{ "_id" : ObjectId("5f96ef6c1fb5b9e52cd2317a"), "msgId" : 1696261645, "fromUserName" : "user2", "toUserName" : "user1", "msgType" : 10002, "content" : "<sysmsg type=\"ClientCheckConsistency\"</ClientCheckConsistency></sysmsg>", "newMsgId" : NumberLong("4429536039473582128"), "createTime" : 1603727095 }
{ "_id" : ObjectId("5f96ef6c1fb5b9e52cd2317b"), "msgId" : 1696261647, "fromUserName" : "user1", "toUserName" : "user2", "msgType" : 1, "content" : "Hello", "newMsgId" : NumberLong("1453640785042681328"), "createTime" : 1603727109 }
{ "_id" : ObjectId("5f96ef6c1fb5b9e52cd2317c"), "msgId" : 1696261648, "fromUserName" : "user2", "toUserName" : "user1", "msgType" : 1, "content" : "gggg", "newMsgId" : NumberLong("4776642146216801785"), "createTime" : 1603727130 }
….

以user1,user2為例,需要獲取 user1, user2 相互聊天資訊中最後一條聊天的資訊。
構造一個方法,獲取查詢記錄中,指定使用者的最後一條聊天記錄。
Def get_last_msg(user:str) -> msg_dict:dict:

另外針對獲取最後一條資訊的場景,提出解決方案。

資料在mongodb中顯示為

程式碼為

import pymongo
# 連結mongodb
pymongo_client = pymongo.MongoClient('mongodb://root:[email protected]:27017')
# 連結資料庫
pymongo_db = pymongo_client['test_db']
# 連結表
pymongo_table = pymongo_db.test_table



def get_last_msg(user):
    # 管道條件
    pipeline = [
        # 根據傳遞過來的使用者進行搜尋
        {'$match':{'fromUserName':user}},
        # 因為要最後一條,所以倒敘更方便
        {'$sort': {'createTime': -1,}},
        # 倒敘後取出第一條
        {'$limit':1}
        
    ]
    # 插敘
    ret = pymongo_table.aggregate(pipeline)
    ret1 = [u for u in ret]
    # 返回結果
    return ret1[0]

msg = get_last_msg('user2')
# 列印驗證
print(msg)

列印結果

{'_id': ObjectId('5fce176c3dcc6560be446156'), 'msgId': 1696261648.0, 'fromUserName': 'user2', 'toUserName': 'user1', 'msgType': 1.0, 'content': 'gggg', 'newMsgId': '"4776642146216801785"', 'createTime': 1603727130}