架构和产品的制衡——说说竞价拍卖那点事
2016年1月份,我們的產(chǎn)品上線版已經(jīng)是1.1.0,開(kāi)發(fā)版已經(jīng)做到1.2.0。這些版本之間除了UI上做了一些改動(dòng)(可以在我的產(chǎn)品分類文章里看到我為什么會(huì)做這些改動(dòng)),大部分是些底層的優(yōu)化,比如App端緩存架構(gòu)的修改,后臺(tái)Server的API優(yōu)化等等。第一個(gè)階段的產(chǎn)品規(guī)劃此時(shí)已經(jīng)進(jìn)入一個(gè)相對(duì)平緩的時(shí)期,這個(gè)平緩不是說(shuō)產(chǎn)品做完了,而是說(shuō)產(chǎn)品從無(wú)到有(0到1)之后,進(jìn)入2(大需求改動(dòng))之前一個(gè)節(jié)奏相對(duì)平衡的時(shí)期。在這個(gè)時(shí)候,我終于開(kāi)始騰出手來(lái)重點(diǎn)關(guān)注一個(gè)一直懸而未決的需求——線上競(jìng)價(jià)。
注:本文里競(jìng)價(jià)和拍賣代表一個(gè)概念。這里的競(jìng)價(jià)指的是傳統(tǒng)意義上的拍賣的線上版本,不是指像某些SP商提供的線上廣告位自動(dòng)競(jìng)價(jià)系統(tǒng)。兩者有一定區(qū)別。線上競(jìng)價(jià)這個(gè)概念,在有淘寶的今天,已經(jīng)不是什么新鮮事了。但是親手做一個(gè)完全模擬線下拍賣流程的在線競(jìng)價(jià)系統(tǒng),這樣的需求不會(huì)很多。這對(duì)我們團(tuán)隊(duì)對(duì)于我個(gè)人來(lái)說(shuō),即是一個(gè)機(jī)會(huì)也是一個(gè)挑戰(zhàn)。
好,怎么做呢?首先看看能不能借用別人的輪子,能不重復(fù)造當(dāng)然不要自己造??墒窃诰W(wǎng)上搜索一大圈,幾天下來(lái),能用的資料寥寥無(wú)幾??赡苁且粋€(gè)競(jìng)價(jià)系統(tǒng)太簡(jiǎn)單了,做的人都不屑于不好意思寫下來(lái);又或者是做的人實(shí)在是太少了,都沒(méi)來(lái)得及寫;也可能是凡是做競(jìng)價(jià)的都是商業(yè)需要,不能寫;還有可能我搜索技術(shù)太爛,找不到。不管怎樣,看起來(lái)我們又是得從零做起,而且我得寫點(diǎn)什么,好歹將來(lái)一無(wú)是處的時(shí)候給自己的子孫吹個(gè)NB說(shuō),“你爺爺曾經(jīng)做過(guò)競(jìng)價(jià)系統(tǒng)!”“啥破玩意?…”“……”
從頭做,還是得分幾步:
1. 首先要熟悉拍賣本身,至少得先懂;沒(méi)有太多的時(shí)間讓我一點(diǎn)點(diǎn)的完全熟悉拍賣這個(gè)市場(chǎng),于是我拉上運(yùn)營(yíng)部門里做過(guò)真實(shí)拍賣交易的人,不斷聊天了解概念,然后又親自和他們參加了幾場(chǎng)真實(shí)的現(xiàn)場(chǎng)拍賣會(huì),首先對(duì)真實(shí)線下情況混個(gè)八九成熟;
2. 分析競(jìng)品,了解別人都做了什么;拉上UI設(shè)計(jì)師一起,測(cè)試機(jī)器上裝上4,5個(gè)有相同功能的App,我們兩個(gè)人一起分析每一個(gè)頁(yè)面里的內(nèi)容和操作流程,互相討論;
3. 根據(jù)競(jìng)品和我們的實(shí)際需求,整理出基本的數(shù)據(jù)模型;在這個(gè)過(guò)程中,需要非常多得取舍決策,因?yàn)橐粋€(gè)完整的線下拍賣有太多的概念可以抽象到數(shù)據(jù),哪些真的需要用在產(chǎn)品里,哪些不重要,這個(gè)完全考察的是經(jīng)驗(yàn)和理解決策力;
4. 根據(jù)線下規(guī)則,競(jìng)品常態(tài)和我們的實(shí)際需求,設(shè)計(jì)我們自己的業(yè)務(wù)流程;這部分,有時(shí)間的話,我想在產(chǎn)品分類文章里分享下我是怎么設(shè)計(jì)我們的競(jìng)價(jià)產(chǎn)品的;
5. 根據(jù)流程,設(shè)計(jì)系統(tǒng)架構(gòu)。
6. 根據(jù)架構(gòu)原型實(shí)現(xiàn)中遇到的問(wèn)題,優(yōu)化細(xì)節(jié)。
下文將著重討論5,6這兩部分。
?
一、競(jìng)價(jià)的系統(tǒng)架構(gòu)
我們來(lái)看下常規(guī)狀態(tài)下,一個(gè)線下拍賣的核心模式。拍賣,簡(jiǎn)單來(lái)說(shuō),就是一個(gè)人吆喝賣,多個(gè)人搶著買,在賣的人規(guī)定的條件下(一般為時(shí)間限制),出價(jià)最高者得。好,那么整體模式可以概括成下面這張圖:
那我現(xiàn)在把這張圖,變化一下,只保留他們之間傳遞的信息,再看一下:
這像什么?對(duì)了,聊天室。整個(gè)拍賣過(guò)程在結(jié)構(gòu)上本質(zhì)上就是一個(gè)群聊。只不過(guò),普通的聊天室的實(shí)現(xiàn),服務(wù)器端只是單純的廣播消息,客戶端只是單純的收發(fā)消息;而競(jìng)價(jià)系統(tǒng),服務(wù)器端除了負(fù)責(zé)廣播消息之外,還需要對(duì)每一條消息進(jìn)行判定,并在最終聊天室關(guān)閉時(shí)(也就是競(jìng)價(jià)結(jié)束時(shí))對(duì)所有消息進(jìn)行一次綜合判定,而各個(gè)不同客戶端發(fā)出的消息時(shí),互相之間有依賴關(guān)系(后一次出價(jià)必定在前一次基礎(chǔ)之上)。
這樣做起來(lái)思路就相對(duì)清晰了:兩大模塊:聊天系統(tǒng)+判定邏輯。
俗話說(shuō),條條大路通羅馬。同樣的需求,做起來(lái)有不同的方法,只是不同的方法最后的效果可能不同。同樣是做巧克力,Teuscher的手工巧克力就是比超市里賣的廉價(jià)巧克力口感好,賣的價(jià)格高。就看具體的要求標(biāo)準(zhǔn)是什么。同理,做一個(gè)聊天系統(tǒng),可以是實(shí)時(shí)系統(tǒng),也可以是一個(gè)非實(shí)時(shí)系統(tǒng);可以用長(zhǎng)連接,也可以用短連接;可以用輪詢驅(qū)動(dòng),也可以用事件驅(qū)動(dòng)。關(guān)鍵看需求標(biāo)準(zhǔn)。
那么,回到我們的產(chǎn)品。最深層次的需求是:
- 客戶端能發(fā)起出價(jià)請(qǐng)求;
- 當(dāng)價(jià)格更新時(shí),所有參與出價(jià)的客戶端能夠看到最新價(jià)格;
- 系統(tǒng)功能要求遠(yuǎn)高于性能要求;
- 開(kāi)發(fā)周期緊。
擺在我們面前的,最明顯的有2種做法:
1) 非實(shí)時(shí)的polling:
所有客戶端的頁(yè)面定時(shí)向服務(wù)器發(fā)起更新請(qǐng)求,拉取最新價(jià)格和出價(jià)歷史列表。
2) 實(shí)時(shí)事件驅(qū)動(dòng):
所有價(jià)格更新以事件方式主動(dòng)更新到每一個(gè)激活客戶端。
兩種方式優(yōu)劣對(duì)比:
| ? | 非實(shí)時(shí)Polling | 實(shí)時(shí)事件驅(qū)動(dòng) |
| 優(yōu)勢(shì) | 簡(jiǎn)單。 后臺(tái)系統(tǒng)只需要設(shè)計(jì)最基本的REST接口即可,前端只需要增加一個(gè)定時(shí)刷新機(jī)制即可; 和已有Web系統(tǒng)的擴(kuò)展方法保持一致。 | 實(shí)時(shí);用戶體驗(yàn)好。 系統(tǒng)壓力線性穩(wěn)定,系統(tǒng)吞吐率高; 長(zhǎng)連接,可以基于事件做更多實(shí)時(shí)性效果。 |
| 劣勢(shì) | 定時(shí)間隔直接影響用戶體驗(yàn)和系統(tǒng)壓力: 增加定時(shí)間隔,用戶的基于過(guò)期的價(jià)格上而發(fā)出失效出價(jià)的概率增大; 縮短定時(shí)間隔,在競(jìng)價(jià)人數(shù)較少時(shí)將造成大量服務(wù)器無(wú)謂的請(qǐng)求; 而在競(jìng)價(jià)人數(shù)較多時(shí)又會(huì)造成服務(wù)器的壓力成倍數(shù)增大。 | 需要一個(gè)區(qū)別于已有Web系統(tǒng)的支持長(zhǎng)連接的事件驅(qū)動(dòng)的系統(tǒng)框架 |
?
?
?
?
?
?
?
到這肯定有人會(huì)有這樣的問(wèn)題:聊天系統(tǒng)想都不用想——很自然的應(yīng)當(dāng)選擇第二種直接上Node.js+socket.io啊??墒?#xff0c;我做任何設(shè)計(jì),總是喜歡考慮這些問(wèn)題:
我是不是非得用這種技術(shù),是否有其他更快的方法,“殺雞要不要用牛刀”,“我是不是只有一把刀”……
那么落到手頭的實(shí)際項(xiàng)目,我要考慮的是:
- 不能直接使用Node.js操作數(shù)據(jù)庫(kù),因?yàn)镹ode的ORM和系統(tǒng)的Django ORM不匹配
- 必須盡可能復(fù)用已有系統(tǒng)架構(gòu),在最短時(shí)間內(nèi)完成功能
- 必須顧及競(jìng)價(jià)系統(tǒng)可能存在的復(fù)雜功能的要求
- 用戶體驗(yàn)優(yōu)先級(jí)最高
這些東西已考慮下來(lái),最終就形成了現(xiàn)在的系統(tǒng)方案,方案1)和方案2)的結(jié)合:
我們利用原有系統(tǒng)架構(gòu)(圖中右下部框內(nèi)部分),使用Redis作為橋梁,直接讓Node服務(wù)器連接在Django服務(wù)器:
1)Node服務(wù)器負(fù)責(zé)維護(hù)WebSocket連接并且廣播消息,通知客戶端實(shí)時(shí)更新價(jià)格;
2)Django服務(wù)器負(fù)責(zé)響應(yīng)出價(jià)POST請(qǐng)求,直接操作數(shù)據(jù)庫(kù);然后通知Node服務(wù)器更新事件;
這樣,我們做出的權(quán)衡就是:
- 舍棄Node的高并發(fā)的能力,把系統(tǒng)壓力仍然嫁接在已有Server之上;
- 利用Node對(duì)WebSocket的優(yōu)秀支持,提升用戶的實(shí)時(shí)體驗(yàn);
- 復(fù)雜度上,增加客戶端(Web和App)支持WebSocket的能力,但是利用Redis隊(duì)列潤(rùn)滑系統(tǒng)整體框架,復(fù)用已有系統(tǒng)的處理邏輯和方式。
??
二、細(xì)節(jié)的打磨
上面提到的是競(jìng)價(jià)基礎(chǔ)架構(gòu)的設(shè)計(jì)思路,那么想要把一個(gè)聊天系統(tǒng)真正的變成一個(gè)競(jìng)價(jià)系統(tǒng),還得靠消息判定邏輯。
原本來(lái)說(shuō),來(lái)一個(gè)出價(jià)POST請(qǐng)求,通過(guò)App Server判斷價(jià)格是否生效,生效修改數(shù)據(jù)庫(kù)并通知,失效則拒絕。多個(gè)請(qǐng)求到來(lái)時(shí),FIFO排隊(duì),或者數(shù)據(jù)加鎖。
很簡(jiǎn)單,和普通的Web請(qǐng)求讀寫思路沒(méi)有太大區(qū)別。但是競(jìng)價(jià)系統(tǒng)在這里有一個(gè)不得不去考慮的特殊需求:代理出價(jià)。
在這里需要解釋一下代理出價(jià):代理出價(jià)就是“替你出價(jià),當(dāng)你不在場(chǎng)的時(shí)候”。相當(dāng)于一個(gè)自動(dòng)機(jī)器人,每當(dāng)別人的報(bào)價(jià)高于自己的報(bào)價(jià)則在價(jià)格到達(dá)自己限定的最高上限之前都會(huì)自動(dòng)加價(jià)后報(bào)價(jià)。比如,某件商品起拍價(jià)1000,加價(jià)幅度為100,我設(shè)定的代理出價(jià)額度為2000,那么只要價(jià)格低于2000,你無(wú)論出價(jià)多少,我都會(huì)自動(dòng)比你高100出價(jià)。你出1100,我出1200,你出1300,我出1400……這個(gè)過(guò)程中,我不必在線出價(jià),系統(tǒng)自動(dòng)幫我出價(jià)。
那這個(gè)代理出價(jià)的需求會(huì)帶來(lái)哪些新的問(wèn)題:
1) 驚群效應(yīng):在有多個(gè)代理人的情況下,因?yàn)樽詣?dòng)競(jìng)爭(zhēng),價(jià)格會(huì)在最短時(shí)間內(nèi)上升到最高上限。比如有3個(gè)人都設(shè)置了代理出價(jià),分別設(shè)定最高限額是M1,M2,M3。那么一旦競(jìng)價(jià)開(kāi)始價(jià)格將飚升至Max(Mi)。那么,系統(tǒng)要不要控制這個(gè)過(guò)程?
2) 如果M1=M2=M3,最終獲勝的應(yīng)該是誰(shuí)?
3) 如果把系統(tǒng)自動(dòng)出價(jià)的行為看做是一個(gè)后臺(tái)的機(jī)器人,那么這個(gè)機(jī)器人的“地位”如何?是把每一個(gè)設(shè)置代理出價(jià)的用戶都看做是單獨(dú)的機(jī)器人獨(dú)立出價(jià),還是由一位機(jī)器人統(tǒng)一負(fù)責(zé)協(xié)調(diào)所有的代理出價(jià)?
其中,前2個(gè)問(wèn)題是需求策略問(wèn)題,最后一個(gè)是技術(shù)實(shí)現(xiàn)問(wèn)題。
關(guān)于驚群的問(wèn)題,首先來(lái)看從產(chǎn)品的角度要不要“刻意”控制:系統(tǒng)刻意延緩這個(gè)“互相抬價(jià)”的過(guò)程,還是放任讓價(jià)格在很短的時(shí)間內(nèi)的飆漲到代理人群中的最高出價(jià)。開(kāi)發(fā)人員在第一版的設(shè)計(jì)里,是考慮了“用戶體驗(yàn)”,加入了一個(gè)定時(shí)機(jī)制,刻意延緩了整個(gè)代理“互相出價(jià)”的進(jìn)程,這樣還能讓手動(dòng)出價(jià)的用戶能夠在代理競(jìng)爭(zhēng)出價(jià)的“間隙”里也能有機(jī)會(huì)出價(jià),即時(shí)這個(gè)價(jià)格并沒(méi)有競(jìng)爭(zhēng)力。理由是:這樣看起來(lái)更像是大家坐在一起互相出價(jià),不然看起來(lái)“很假”。由于做這個(gè)設(shè)計(jì)的時(shí)候我正好休假,所以開(kāi)發(fā)人員并沒(méi)有和我溝通就直接把代碼寫完了。我回來(lái)以后,我的第一反應(yīng)是很開(kāi)心,因?yàn)橹辽僬f(shuō)明團(tuán)隊(duì)的開(kāi)發(fā)人員能“主動(dòng)思考用戶體驗(yàn)”,而且證明他做的很快,想到方案并快速原型實(shí)現(xiàn)是必須的。但是,我習(xí)慣性的問(wèn)了自己一個(gè)問(wèn)題:“真的有必要讓它看起來(lái)不那么假么?用戶真的在意出價(jià)過(guò)程中如果出現(xiàn)多個(gè)代理出價(jià)的情形,自己還必須要有機(jī)會(huì)出價(jià)么?”。要回答這個(gè)問(wèn)題,我們退一步,退回到線下拍賣的真實(shí)場(chǎng)景中:
現(xiàn)實(shí)拍賣中,拍賣公司或者組織者會(huì)給每一個(gè)有代理出價(jià)需求的客戶提前安排好專門的出價(jià)代表,并和現(xiàn)場(chǎng)其他到場(chǎng)客戶坐在一起舉牌。線上“驚群效應(yīng)”其實(shí)就是現(xiàn)實(shí)場(chǎng)景中,這些代表們爭(zhēng)先恐后的舉到自己代理的客戶承受的最高價(jià)才能力??蛻糇畲罂赡塬@得最終勝利。那么在這個(gè)過(guò)程中,現(xiàn)場(chǎng)其他的客戶很有可能沒(méi)有機(jī)會(huì)來(lái)的及舉牌,會(huì)在意么?我看不會(huì),為什么,因?yàn)楦?jìng)價(jià)不是“享受過(guò)程”,而是“獲得結(jié)果”!你們?cè)跔?zhēng)相舉牌,我沒(méi)機(jī)會(huì),但是我無(wú)所謂,因?yàn)楫?dāng)代理舉牌完畢后,只可能有兩種結(jié)果:當(dāng)前價(jià)格我還能再加,或者當(dāng)前價(jià)格已經(jīng)超過(guò)我的預(yù)期。那么這兩種情況都不會(huì)降低我的體驗(yàn),我想加我就等你們消停了我再舉牌,這個(gè)時(shí)候只要你們代理不修改代理價(jià)格,你們就都不是我的競(jìng)爭(zhēng)對(duì)手了;而如果當(dāng)前哄抬的價(jià)格已經(jīng)超過(guò)我的心理價(jià)位,前面我有沒(méi)有舉過(guò)牌對(duì)我來(lái)說(shuō)顯然一點(diǎn)意義都沒(méi)有,反正我肯定是拿不到這個(gè)拍品了。所以,我問(wèn)開(kāi)發(fā)“把這個(gè)定時(shí)器拿掉對(duì)你的代碼有多大改動(dòng)?”“不大”“好,拿掉。不需要增加額外復(fù)雜度?!?
所以這里我的權(quán)衡是:即使讓開(kāi)發(fā)翻工(當(dāng)然是在可以接受的范圍內(nèi)),也必須去掉過(guò)度的“結(jié)構(gòu)設(shè)計(jì)”。
第二個(gè)問(wèn)題,理解好線下拍賣對(duì)這個(gè)問(wèn)題的處理方式就比較好辦。線下的方法是:“拍賣師說(shuō)的算!”其實(shí)就是說(shuō),系統(tǒng)保留所有解釋權(quán)。那就好辦了,自己定義了一個(gè)規(guī)則就可以。
關(guān)于第三個(gè)問(wèn)題,字面上不太好理解,我們來(lái)看一個(gè)圖:
這就是描述第一種情況中的“機(jī)器人是作為獨(dú)立出價(jià)人單獨(dú)出價(jià)”,指的就是系統(tǒng)并不對(duì)代理出價(jià)者做特殊處理,每一個(gè)代理在接收到價(jià)格更新事件后都可以直接對(duì)競(jìng)價(jià)系統(tǒng)發(fā)起出價(jià)請(qǐng)求。這種設(shè)計(jì)優(yōu)劣如下:
- 優(yōu)點(diǎn):系統(tǒng)功能角色劃分清晰,每個(gè)代理可以享有獨(dú)立出價(jià)權(quán),更接近真實(shí)拍賣場(chǎng)景;
- 缺點(diǎn):因?yàn)槊總€(gè)代理都可以接收到更新事件,每個(gè)代理都可以發(fā)出新的出價(jià)請(qǐng)求,而這些出價(jià)請(qǐng)求又會(huì)被其他代理收到,再響應(yīng)出新的出價(jià)請(qǐng)求。所以必須額外增加一個(gè)機(jī)制,防止多個(gè)代理循環(huán)出價(jià)帶來(lái)監(jiān)聽(tīng)的“競(jìng)價(jià)事件”爆發(fā)問(wèn)題。
我們?cè)賮?lái)看看第二種可能的設(shè)計(jì):
在這里,所有的代理出價(jià)者被納入內(nèi)部的“Coordination System”中,而不再和外部的手動(dòng)出價(jià)人并列。當(dāng)任何一個(gè)出價(jià)事件發(fā)生時(shí),首先由這個(gè)“Coordinator”在眾多代理出價(jià)者中協(xié)調(diào)出一個(gè)最終勝者,然后再向競(jìng)價(jià)服務(wù)器發(fā)出一個(gè)最終競(jìng)價(jià)請(qǐng)求。Coordinator選出唯一勝者的同時(shí),也把所有其他的代理給淘汰掉了。也就是說(shuō),只需要1次出價(jià),就能夠把所有可能的代理者全部“洗清”,只剩一個(gè)最高代理者和其他手動(dòng)出價(jià)人競(jìng)爭(zhēng)。在這個(gè)“協(xié)調(diào)”過(guò)程中,忽略所有其他手動(dòng)出價(jià)。這種設(shè)計(jì)優(yōu)劣如下:
- 優(yōu)點(diǎn):系統(tǒng)實(shí)現(xiàn)清晰簡(jiǎn)單,不會(huì)產(chǎn)生“驚群”問(wèn)題;
- 缺點(diǎn):系統(tǒng)邏輯和真實(shí)場(chǎng)景有直觀上的差距;
這兩種都有明顯的優(yōu)缺點(diǎn),從模擬真實(shí)線下邏輯來(lái)說(shuō),第一種更優(yōu),理解起來(lái)也更容易;而從系統(tǒng)結(jié)構(gòu)實(shí)現(xiàn)角度來(lái)說(shuō),我更喜歡第二種,做起來(lái)更直接更簡(jiǎn)單。你會(huì)問(wèn)我第二種的話,如果用戶體驗(yàn)很差怎么辦?其實(shí)這種場(chǎng)景,用戶體驗(yàn)差只有一種情況,就是很多人真實(shí)在線出價(jià),同時(shí)有大量的人設(shè)置了代理出價(jià)。而這種情況對(duì)于我們目前的業(yè)務(wù)而言,顯然遙不可及。更何況,如果真的是這種大規(guī)模并發(fā)的場(chǎng)景,整個(gè)系統(tǒng)結(jié)構(gòu)都可能要做調(diào)整了。雖然我個(gè)人傾向第二種但是我們線上版本用的是第一種,因?yàn)椤谖倚菁倨陂g我們NB的開(kāi)發(fā)把第一種做完了!(攤手)。最后想來(lái)好像應(yīng)該怪我應(yīng)該提前把設(shè)計(jì)提前討論到這層再交給開(kāi)發(fā),但是仔細(xì)想想,以目前的情況看,這兩種并不會(huì)對(duì)產(chǎn)品本身有本質(zhì)影響。所以既然已經(jīng)做完了,那就先用。
至于使用第一種設(shè)計(jì),我們額外設(shè)計(jì)了附加的措施來(lái)解決具體的“驚群”問(wèn)題:
因?yàn)槲覀兪鞘褂帽闅v列表的方式掃描所有的出價(jià)代理的,那么當(dāng)某個(gè)代理成功發(fā)起出價(jià)請(qǐng)求后,在本次掃描循環(huán)周期內(nèi),后續(xù)的代理不再出價(jià),而只是掃描其設(shè)置的封頂價(jià)格是否失效,是則忽略,否則從列表中移除。而當(dāng)每個(gè)代理接收到價(jià)格更新事件時(shí),首先確認(rèn)此次出價(jià)是否為本人,是則忽略此次更新,否則繼續(xù)發(fā)起出價(jià)事件。
?
三、總結(jié)
本文主要記錄的是我在做產(chǎn)品的競(jìng)價(jià)功能的前后遇到的問(wèn)題和設(shè)計(jì)思路。我個(gè)人認(rèn)為,這是一個(gè)很好的關(guān)于產(chǎn)品需求和架構(gòu)設(shè)計(jì)之間互相權(quán)衡乃至制衡的例子。做互聯(lián)網(wǎng)產(chǎn)品的架構(gòu)師,不能只是掉在架構(gòu)的黑洞里鉆研架構(gòu)本身,而是應(yīng)該千方百計(jì)的用最合理的架構(gòu)用最快的時(shí)間去滿足產(chǎn)品的功能。我一直認(rèn)為,做產(chǎn)品和做架構(gòu)本身是不應(yīng)該分離的,我堅(jiān)持認(rèn)為研發(fā)出身的人如果去能做產(chǎn)品,應(yīng)該比其他人更有優(yōu)勢(shì),至少在產(chǎn)品本身的實(shí)現(xiàn)上,更有說(shuō)服力更有效。當(dāng)然,關(guān)于市場(chǎng)和運(yùn)營(yíng)本身的能力也是至關(guān)重要,但那是另外的話題了。
?
2016年2月25日,完稿于南京。
轉(zhuǎn)載于:https://www.cnblogs.com/wizardguy/p/how-to-design-a-auction-system.html
總結(jié)
以上是生活随笔為你收集整理的架构和产品的制衡——说说竞价拍卖那点事的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Yii2.0学习资源
- 下一篇: 遍历DOM元素的children属性遇到