如果你應(yīng)聘微信產(chǎn)品經(jīng)理,怎么回答這道面試題?
問題源自知乎問題,感興趣可以知乎搜索「關(guān)于微信的產(chǎn)品面試題,產(chǎn)品經(jīng)理來答答?」,我從中選取了一個問題,加了一點自己的思考,發(fā)出來探討一下。
朋友圈的基本數(shù)據(jù)結(jié)構(gòu)設(shè)計是怎么樣的?既能做到完美的閱讀權(quán)限設(shè)置,又能兼顧性能?
題目本身給出了兩個重點,「閱讀權(quán)限」和「性能」,考察產(chǎn)品經(jīng)理思考問題的全面性和對技術(shù)的了解程度。
首先梳理一下朋友圈的幾個功能特點:
- (0)基礎(chǔ)存儲功能,可發(fā)布視頻、鏈接、純文本、圖文消息。
- (1)異步發(fā)布,即時用戶交互行為反饋。在網(wǎng)絡(luò)情況較差時可以先提交任務(wù)(如發(fā)布朋友圈、點贊、評論),無需等待任務(wù)完成。
- (2)可選擇部分用戶可見,也就是題目中說到的權(quán)限。
- (3)對某些用戶可見的權(quán)限,除了用戶主動選擇的,還有系統(tǒng)層面的過濾器,比如某些違反微信運(yùn)營規(guī)定的活動鏈接可被系統(tǒng)限制在朋友圈中傳播(也就是你發(fā)了之后只有你自己能看到,別人看不到)
- (4)新消息通知主動push,無需刷新界面,新消息可自動push;新朋友圈需要刷新才能看到。
問題(0)和(1)與閱讀權(quán)限設(shè)置沒有多大關(guān)系,與性能有一點點關(guān)系,但并不是本文討論的重點。這個面試題我們可以圍繞「閱讀權(quán)限」和「性能」這兩個基本點,對(2)、(3)、(4)三個點進(jìn)行探討。
回答問題(2)時,我們可以從微信提供的功能上找到一些設(shè)置閱讀權(quán)限的蛛絲馬跡。
1)互為好友關(guān)系,是好友關(guān)系才能看到對方朋友圈,這是第一前提。
微信的朋友與朋友之間的關(guān)系雖然是雙向的,如A和B要成為朋友,A需要給B發(fā)送好友申請,當(dāng)B通過A的申請時A才能看到B的朋友圈。
此時,A與B雖然存在好友關(guān)系,但彼此有一份獨立的通訊錄,互不干擾。比如A把B從朋友圈刪除時,B會在A的通訊錄列表里消失,但A不會在B的通訊錄列表里消失,當(dāng)B給A發(fā)信息時才能發(fā)現(xiàn)雙方已非友好關(guān)系。
2)不在黑名單內(nèi),才能給對方發(fā)送消息并且能看到對方的朋友圈。
黑名單是介于「關(guān)系正?!购汀竸h除」之間的一種關(guān)系,雙方的好友關(guān)系還被保留,比如A把B拉黑了,有如下表現(xiàn):
B無法給A發(fā)送消息,也看不到對方朋友圈的任何內(nèi)容。
因為A主動拉黑B,A可以看到B的歷史朋友圈,但看不到拉黑后更新的內(nèi)容。
3)申請加為好友時,選擇「不讓他看我的朋友圈」開啟或關(guān)閉。
不讓看朋友圈是介于黑名單和正常關(guān)系之間的一個狀態(tài),如果互相加為好友時,被選擇了「不讓看朋友圈」,你是不能看到對方朋友圈的更新的。
4)通訊錄朋友標(biāo)簽化。
我們可以在微信提供的功能上找到「標(biāo)簽」,這個標(biāo)簽除了對朋友屬性進(jìn)行標(biāo)記(如你可以把某個微信聯(lián)系人標(biāo)記為老板、同事)外,還可以在發(fā)布朋友圈時選擇帶某標(biāo)簽的朋友可見或不可見。
微信基于此構(gòu)建了朋友圈和通訊錄的權(quán)限體系,那在具體技術(shù)實現(xiàn)上是什么場景呢?
我認(rèn)為,微信朋友圈的權(quán)限是在朋友關(guān)系和朋友圈內(nèi)容有寫操作的時候進(jìn)行下發(fā)的,也就是當(dāng)用戶發(fā)布內(nèi)容或?qū)﹃P(guān)系進(jìn)行修改時,就會下發(fā)朋友圈的內(nèi)容可見狀態(tài),按照權(quán)限優(yōu)先級分為三種下發(fā)情況:
- 非好友、黑名單關(guān)系是實時觸發(fā)的。一經(jīng)修改,所有內(nèi)容實時生效。
- 標(biāo)簽關(guān)系也是實時觸發(fā)的,但不會因為修改標(biāo)簽的動作而對已發(fā)布內(nèi)容是否可見產(chǎn)生變化。比如你發(fā)了一條朋友圈,對打了標(biāo)簽的A和B兩個好友可見,C當(dāng)時還不在可見標(biāo)簽內(nèi)。發(fā)布完成之后修改C的標(biāo)簽為可見,C仍然看不到這條朋友圈。除刪除狀態(tài)和取消點贊,朋友圈是不具備修改、編輯功能的。
- 對于違規(guī)的朋友圈內(nèi)容,微信會限制內(nèi)容在朋友圈傳播,這個限制是系統(tǒng)限制,是異步進(jìn)行的。比如你發(fā)布了一個受限的鏈接,發(fā)布之后在很短的時間內(nèi)(1-2分鐘內(nèi))朋友是可以看到這條鏈接的,但隨后這條鏈接馬上會被屏蔽,這樣異步處理的初衷大概是 “把部分復(fù)雜的但不是最高優(yōu)先級的權(quán)限計算發(fā)送到閑散的客戶端或機(jī)器資源上去做”,保證核心的閱讀體驗不會受到影響。
以上便是一些權(quán)限處理上的策略,接下來我們來討論一下,用什么樣的技術(shù)手段或者存儲方式,來支持這些復(fù)雜的權(quán)限下發(fā)和閱讀權(quán)限控制。
在timeline(時間流)或feeds流的產(chǎn)品技術(shù)實現(xiàn)上常用到一個算法叫「混排算法」,顧名思義就是結(jié)合了一系列的影響因子,把用戶發(fā)布的狀態(tài)/信息 實時分發(fā)到好友關(guān)系鏈里,感興趣的朋友們可以使用谷歌學(xué)術(shù)搜索timelime cache等關(guān)鍵字自行檢索。
這些存儲計算使用的技術(shù)肯定不是我們平時說的數(shù)據(jù)庫,而多用一些分布式存儲、持久緩存技術(shù)作為工具,比如Memcached、Redis等。
我們大膽猜想微信朋友圈的實現(xiàn)也使用了Redis,或者類似Redis系統(tǒng)的Key-Value鍵值對存儲系統(tǒng)。
一條條的朋友圈狀態(tài)在用戶的權(quán)限列表里是以key-value的形式存在的,每個用戶的 timeline 是由一個 Redis list 來維護(hù), Redis list 存放著經(jīng)過上面權(quán)限策略過濾之后可見好友發(fā)布的朋友圈的 ID。每當(dāng)一個用戶發(fā)布朋友圈時, 會把這條朋友圈的 ID 推到有權(quán)限閱讀的好友的timeline 中(也就是存儲到Redis list 里)。當(dāng)用戶刷新自己的朋友圈時,只需要到自己的Redis list 里拉取到對應(yīng)的朋友圈列表,然后再比對本地緩存,決定該朋友圈是否要顯示或重新請求。數(shù)據(jù)格式大概如下:#{user_id}/#{post_id}(發(fā)布朋友圈的用戶ID/該朋友圈的ID)”
Redis_List = [“10010/100111”, “10020/103111”, “10030/140111”, “100210/100786”, “100233/100444”]
同樣的,點贊數(shù)、評論數(shù)、自己是否點贊等與某條朋友圈的關(guān)系,也是存儲在Redis List里。
雖然朋友圈內(nèi)容是不會變的,但是點贊數(shù)和評論數(shù)目可是實時變化的喲。每一條朋友圈都會要獲取這條動態(tài)獲得了多少贊、有多少條評論、自己是否點贊。而這三個屬性都是從 Redis 中讀取出來的。也就是說如果這個接口返回了 20 條動態(tài)的話, 我們需要調(diào)用20*3次= 60 次 Redis。這似乎也是不可以接受的,特別是有一些人好友比較多、互動比較頻繁的,有時候還需要主動給用戶推小紅點提醒有新消息更新,這些人所在的機(jī)器性能就會告急。
所以,微信的這道面試題提到了「性能」這個點。
這里,可以可以考慮使用時間戳來標(biāo)記上一次動態(tài)更新的時間。比如,當(dāng)用戶在發(fā)布新的朋友圈信息時,如果跟當(dāng)前用戶有新的互動(比如回復(fù)了你的評論、給你點贊了),上一次更新的時間戳就會發(fā)生變化,并主動更新到用戶相關(guān)的各個Redis List里。當(dāng)發(fā)現(xiàn)客戶端發(fā)現(xiàn)上次更新的時間戳和本地時間戳不一樣時,可以主動更新獲取信息,否則保持不動。
調(diào)整對象結(jié)構(gòu)為 用戶ID=>[狀態(tài),上次更新時間戳]
{ ‘10010’ => [‘200101′,’123453454’], ‘10011’ => [‘200102’, ‘12345345435’], ‘10021’ => [‘200103′,’12345345435’], ‘10031’ => [‘200104′,’12345345435’]}
額,講到這里,很多同學(xué)沒看懂?
看吧,產(chǎn)品經(jīng)理懂一些技術(shù)還是好一點的吧。^_^
好了,以上是一位產(chǎn)品經(jīng)理作為旁觀者對微信朋友圈數(shù)據(jù)結(jié)構(gòu)設(shè)計的一些思考,希望對大家思考有所幫助。許久不寫技術(shù)文章,如有錯誤,歡迎留言指正。
本文系作者@歪 (微信公眾號:程序員和產(chǎn)品經(jīng)理)授權(quán)發(fā)布,未經(jīng)許可,不得轉(zhuǎn)載。
如果對方開了陌生人可以瀏覽10條朋友圈,有些內(nèi)容還是可以看到的
后面基本上看不懂,尷尬
路過糾正一下:在微信平臺,非好友關(guān)系也能看到對方的朋友圈。這也是權(quán)限范圍的功能
發(fā)現(xiàn)看不懂,但學(xué)到了微信這種機(jī)制思想 ??
這是產(chǎn)品分享還是技術(shù)分享
沒看懂?dāng)?shù)據(jù)結(jié)構(gòu) 講技術(shù)沒有多全面
你是開發(fā)轉(zhuǎn)產(chǎn)品吧,有點深奧。
果然任何一個牛逼的產(chǎn)品都不是簡單實現(xiàn)的??????
分析很深入很全面,微信的產(chǎn)品邏輯好深奧呀
1.
表示看不懂代碼,不明覺厲,厲害了,我的大神
贊一個,微信的產(chǎn)品邏輯恰到好處。不過后面的一部分有點炫技了
?? ?? ?? ??
留個腳印來看看
贊同,微信的緩存設(shè)計結(jié)構(gòu)理念,有點類似新浪微博。嘗試一下看看,做個REDIS數(shù)據(jù)結(jié)構(gòu),來設(shè)計微信朋友圈。轉(zhuǎn)產(chǎn)品中,不過碼農(nóng)的老本忘得快差不多了,哈哈
有點扯
1、這個點上怎么可能成為性能瓶頸?性能問題取決于實現(xiàn)模型,騰訊用的肯定是分布式計算,在服務(wù)端的鑒權(quán)如何會引起性能問題
2、這個點上關(guān)注的應(yīng)該是權(quán)限的業(yè)務(wù)模型,不要零碎的場景化,而應(yīng)該有一個貫穿始終的“權(quán)限主線”
我也覺得
厲害,數(shù)據(jù)結(jié)構(gòu)都忘的差不多了
?? ?? ??