Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
99IT數(shù)據(jù)中心微信賬戶(hù):i199IT
編譯:房ny_nicole
大數(shù)據(jù)發(fā)展至今已被推上了時(shí)代的風(fēng)口浪尖,社會(huì)對(duì)其的評(píng)價(jià)褒貶不一。雖然它給我們帶來(lái)了很多好處,但也有人會(huì)發(fā)出這樣的聲音:“ 大數(shù)據(jù)的人快離開(kāi)我的地盤(pán)! ”
即便如此 ,Scott Brinker仍相信,若大數(shù)據(jù)被正確運(yùn)用,它將會(huì)在現(xiàn)代市場(chǎng)營(yíng)銷(xiāo)領(lǐng)域產(chǎn)生無(wú)可估量的積極影響。在數(shù)字化時(shí)代,單純依靠直覺(jué)和經(jīng)驗(yàn)而做出的營(yíng)銷(xiāo)決策往往是不可信的。因此,企業(yè)若希望占據(jù)市場(chǎng)有利地位,就要在客觀數(shù)據(jù)分析和人類(lèi)直覺(jué)判斷中找到均衡點(diǎn)。
Gord Hotchkiss,一名市場(chǎng)營(yíng)銷(xiāo)專(zhuān)欄作家,他近期寫(xiě)了一篇文章 《在中間地帶的市場(chǎng)營(yíng)銷(xiāo)》( Marketing in the Middle ) ,表明他也支持該論點(diǎn)——在中間地帶找均衡點(diǎn)。
“市場(chǎng)營(yíng)銷(xiāo)沒(méi)有所謂的絕對(duì)。我們需要那些有大構(gòu)想、執(zhí)行力強(qiáng)、敢于堅(jiān)持的人去鍥而不舍地去實(shí)施我們的構(gòu)想,將我們的營(yíng)銷(xiāo)手段發(fā)揮到極致。但我們也需要那些善于變通的、有許多奇思妙想的人去引導(dǎo)我們穿過(guò)那些灰暗的中間地帶。實(shí)際上,我在市場(chǎng)營(yíng)銷(xiāo)領(lǐng)域中鉆研的時(shí)間越長(zhǎng),我對(duì)中間地帶的理解越明了——我們所有動(dòng)作實(shí)際上都是在中間地帶發(fā)生的,無(wú)論是質(zhì)量和數(shù)量的抉擇,策略和大數(shù)據(jù)的選擇,品牌創(chuàng)意和直接營(yíng)銷(xiāo)的取舍,甚至是科學(xué)和藝術(shù)之間的權(quán)衡。”
那么,我們?cè)趺醋霾拍軐?shù)據(jù)有效地利用起來(lái)呢?在此,Scott將為大家提供一些14條使用數(shù)據(jù)的經(jīng)驗(yàn)法則,讓大家開(kāi)始學(xué)會(huì)用數(shù)據(jù)驅(qū)動(dòng)營(yíng)銷(xiāo),同時(shí)也避免淪為數(shù)據(jù)主義或使用不實(shí)數(shù)據(jù)進(jìn)行營(yíng)銷(xiāo)。
1. 用戶(hù)驅(qū)動(dòng)優(yōu)于數(shù)據(jù)驅(qū)動(dòng)
數(shù)據(jù)驅(qū)動(dòng)營(yíng)銷(xiāo)固然是好事。但是我們要牢記在心,營(yíng)銷(xiāo)的目的是獲取并保有用戶(hù),因此“用戶(hù)驅(qū)動(dòng)”更有利于達(dá)到營(yíng)銷(xiāo)目的。話雖如此,“數(shù)據(jù)驅(qū)動(dòng)”和“用戶(hù)驅(qū)動(dòng)”并非相互排斥。相反,二者為過(guò)程與結(jié)果的關(guān)系,前者為過(guò)程而后者為結(jié)果。該條法則意在提醒我們,在運(yùn)用數(shù)據(jù)的時(shí)候,記得思考:“該舉措是否有利于為公司贏得用戶(hù)?”
2. 引用準(zhǔn)確和相關(guān)的數(shù)據(jù)
當(dāng)我們?cè)谟懻撘粋€(gè)絕對(duì)真理的時(shí)候,引用數(shù)據(jù)是說(shuō)服他人的最佳手段。然而,在大數(shù)據(jù)時(shí)代,各種數(shù)據(jù)應(yīng)有盡有,任何一方都可以搜集相應(yīng)數(shù)據(jù),并“合理”地運(yùn)用該數(shù)據(jù)去說(shuō)服對(duì)方。在這種情況下,數(shù)據(jù)的相關(guān)性和準(zhǔn)確性顯得尤為重要。因此,人們往往以為大數(shù)據(jù)可以讓市場(chǎng)營(yíng)銷(xiāo)人員更好地去了解用戶(hù),然而真相是,其實(shí)他們也許對(duì)用戶(hù)一無(wú)所知。因此,我們不僅要引用數(shù)據(jù),還要引用最為精確及相關(guān)的數(shù)據(jù)。
3. 數(shù)據(jù)只能體現(xiàn)過(guò)去發(fā)生的事實(shí)
毫無(wú)爭(zhēng)議地,數(shù)據(jù)能夠體現(xiàn)過(guò)去發(fā)生的事實(shí),然而其對(duì)未來(lái)發(fā)展是否意義則有待考究。誠(chéng)然,我們可以從過(guò)去的數(shù)據(jù)中推斷出未來(lái)趨勢(shì)(有時(shí)候甚至非常精確)。然而,現(xiàn)今社會(huì)是瞬息萬(wàn)變的,過(guò)去是過(guò)去,它不一定能夠告訴我們未來(lái)的日子將會(huì)發(fā)生什么變化,有時(shí)候我們的預(yù)測(cè)會(huì)出現(xiàn)與預(yù)期完全相反的結(jié)果,正如歷史上數(shù)次發(fā)生的 黑天鵝事件 ,往往具有意外性,且無(wú)法被人為預(yù)測(cè)和解釋。
4. 數(shù)據(jù)總是不完整的
在某個(gè)特定集合內(nèi)的數(shù)據(jù)是完整的,如過(guò)去三年每個(gè)季度的銷(xiāo)售額。然而并非所有事物都可以歸納到一個(gè)特定的集合內(nèi)的,因此,每當(dāng)我們?cè)谧鰶Q策的時(shí)候,會(huì)發(fā)現(xiàn)僅引用已有數(shù)據(jù)是遠(yuǎn)遠(yuǎn)不夠的,我們還需要引用更多的數(shù)據(jù),因?yàn)樗鼈兌己臀覀円龅臎Q策息息相關(guān)。于是你會(huì)發(fā)現(xiàn),數(shù)據(jù)的引用是個(gè)巨大的黑洞,因?yàn)槟阌肋h(yuǎn)也無(wú)法將所有的數(shù)據(jù)收入囊中。因此,盡管我們?cè)诖髷?shù)據(jù)的支持下為企業(yè)做出了一個(gè)決策,但這個(gè)決策往往如同印象派的畫(huà)作一般,只描繪出了個(gè)大概,和真實(shí)情況仍相距甚遠(yuǎn)。
5. 數(shù)據(jù)是客觀的,但千萬(wàn)個(gè)讀者就有千萬(wàn)種解釋
沒(méi)錯(cuò),數(shù)據(jù)是客觀的,如一張凈推薦值(Net Promoter Score)表格中,顯示的凈推薦值均為7。然而除此之外,其他內(nèi)容都是主觀的。一方面,其主觀性體現(xiàn)在過(guò)程中——收集信息的內(nèi)容不同,收集信息的時(shí)間地點(diǎn)不同,甚至采訪對(duì)象的選擇也有因人而異。另一方面,主觀性也體現(xiàn)在結(jié)果中——相同的數(shù)據(jù),每個(gè)人的解讀方式也不一樣。詳情案例可參閱 《Hidden biases in big data》 。
6. 數(shù)據(jù)可以讓故事變得更具有說(shuō)服力
市場(chǎng)營(yíng)銷(xiāo)人員往往是一個(gè)講故事的人。我們?cè)谥v故事的時(shí)候引用相關(guān)數(shù)據(jù),將會(huì)使得我們的故事更為動(dòng)聽(tīng)及具有說(shuō)服力。然而,正因?yàn)閿?shù)據(jù)的解讀具有主觀性,我們可以更加自如的將符合我們期望值、具有說(shuō)服力的故事說(shuō)給用戶(hù)聽(tīng)。盡管如此如何運(yùn)用數(shù)據(jù)由我們說(shuō)了算,但在講述故事的時(shí)候,我們?nèi)砸侠淼睾拓?fù)責(zé)任地運(yùn)用相關(guān)數(shù)據(jù)。
7. 好的數(shù)據(jù)支持我們做明智的選擇
決策為企業(yè)和個(gè)人做選擇提供一個(gè)框架,而數(shù)據(jù)則有利于為做選擇提供相應(yīng)信息。好的數(shù)據(jù)將會(huì)引導(dǎo)人們做出明智的選擇。反之,不好的數(shù)據(jù)將會(huì)成為我們成功道路上的絆腳石。
8. 用實(shí)驗(yàn)來(lái)證實(shí)數(shù)據(jù)之間的因果關(guān)系
大數(shù)據(jù)時(shí)代一個(gè)非常重要的詞語(yǔ)是“相關(guān)性”,然而我們要清楚,相關(guān)性并非因果關(guān)系。作為市場(chǎng)營(yíng)銷(xiāo)人員,在了解到企業(yè)行為和消費(fèi)者行為之間相關(guān)關(guān)系后,我們接下來(lái)應(yīng)當(dāng)考察該關(guān)系是否為因果關(guān)系——做實(shí)驗(yàn)。保持其他變量不變,檢驗(yàn)相關(guān)變量去證實(shí)或證偽我們的猜想。谷歌每年都會(huì)進(jìn)行超過(guò)一萬(wàn)次的實(shí)驗(yàn),其實(shí)驗(yàn)產(chǎn)生了巨大的數(shù)據(jù)量為谷歌服務(wù),也因此說(shuō)明了, 大量的實(shí)證實(shí)驗(yàn)優(yōu)于純粹以數(shù)量取勝的數(shù)據(jù) 。
9. 平衡數(shù)據(jù)與用戶(hù)體驗(yàn)之間的關(guān)系
Gord曾用過(guò)一個(gè)非常生動(dòng)形象的比喻: “營(yíng)銷(xiāo)如同開(kāi)車(chē),儀表盤(pán)則如同營(yíng)銷(xiāo)過(guò)程中所產(chǎn)生的各種數(shù)據(jù)(如營(yíng)業(yè)額等),擋風(fēng)玻璃則如同用戶(hù)體驗(yàn)。” 顯然在行車(chē)時(shí),儀表盤(pán)上的數(shù)字和擋風(fēng)玻璃外的世界,我們二者都要兼顧。同理,在營(yíng)銷(xiāo)過(guò)程中數(shù)據(jù)和用戶(hù)體驗(yàn)均很重要。
10. 數(shù)據(jù)具有時(shí)效性
隨時(shí)間推移,當(dāng)下數(shù)據(jù)的保留價(jià)值越來(lái)越低。例如,在我想買(mǎi)車(chē)的時(shí)候,車(chē)商視我為目標(biāo)客戶(hù),定期向我推送相關(guān)信息。然而,在我買(mǎi)車(chē)后的六個(gè)月,他們就開(kāi)始對(duì)我不理不睬。這個(gè)例子在一定程度上說(shuō)明,數(shù)據(jù)是具有時(shí)效性的,因而掌握有效和準(zhǔn)確的數(shù)據(jù)對(duì)于運(yùn)用數(shù)據(jù)的市場(chǎng)營(yíng)銷(xiāo)人員來(lái)說(shuō)至關(guān)重要。
11. 數(shù)據(jù)運(yùn)用的“是什么”和“為什么”
在運(yùn)用數(shù)據(jù)做營(yíng)銷(xiāo)決策的時(shí)候,我們需要考慮到這些數(shù)據(jù)“是什么”(confirmation)和“為什么”會(huì)得出這些數(shù)據(jù)(exploration)。當(dāng)我們?cè)诳紤]“是什么”的時(shí)候,會(huì)了解到:事物是否發(fā)生,或發(fā)展到什么程度了;而當(dāng)我們?cè)诳紤]“為什么”的時(shí)候,我們想要去尋求新的發(fā)展模式,新的事業(yè)和新的偉大構(gòu)想。另,同樣的數(shù)據(jù),我們不僅可以用它去探討“是什么”,同樣可以探討“為什么”,這取決于市場(chǎng)營(yíng)銷(xiāo)人員所要研究的命題。
12. 擁有兩塊手表并不能準(zhǔn)確的判斷時(shí)間,反而會(huì)制造混亂
手表定律 是每個(gè)市場(chǎng)營(yíng)銷(xiāo)人員都需要掌握的定律之一。這個(gè)世界被各種矛盾的數(shù)據(jù)充斥著,用不一樣的數(shù)據(jù)或研究方法去討論同一個(gè)問(wèn)題可能會(huì)得出截然不同的答案。面對(duì)這種情況我們可以做的有兩件事,一件是既然數(shù)據(jù)已經(jīng)不一樣,那么我們就去了解是什么因素讓數(shù)據(jù)呈現(xiàn)出兩種不同的結(jié)果,通過(guò)此舉我們往往會(huì)有意想不到的新發(fā)現(xiàn);另外,不要為一分一毫的數(shù)據(jù)偏差而過(guò)于糾結(jié),我們需要的不是完美的數(shù)據(jù),而是利于我們做出明智決策的、準(zhǔn)確地恰如其分的數(shù)據(jù)。
13. 模型并非現(xiàn)實(shí)
模型并非現(xiàn)實(shí),它充其量是現(xiàn)實(shí)的反映,有時(shí)候它甚至?xí)崆爽F(xiàn)實(shí)。一名哲學(xué)家兼科學(xué)家Alfred Korzybski曾經(jīng)說(shuō)過(guò):“地圖并非實(shí)際地形。”偉大的科學(xué)家George E.P. Box也曾說(shuō)過(guò):“所有模型都是錯(cuò)誤的,只有一些是有用的。”。因此,在實(shí)際運(yùn)用當(dāng)中,我們要正確看待數(shù)據(jù),不能“唯數(shù)據(jù)主義”,除了數(shù)據(jù),我們?nèi)詰?yīng)對(duì)其它信息保持高度的警惕,特別是那些體現(xiàn)現(xiàn)實(shí)生活的信息。正如同Swiss Army Aphorism所說(shuō):“如果地圖和實(shí)際地形不符,選擇地形。(畢竟地圖沒(méi)有辦法完全顯示出那懸崖峭壁。)”
14. 數(shù)據(jù)可視化是把雙刃劍
數(shù)據(jù)可視化(包括但不限于圖形和表格)是一把雙刃劍。就目前來(lái)說(shuō),數(shù)據(jù)可視化在數(shù)據(jù)運(yùn)用中發(fā)揮著積極的作用——使人們更加直觀地讀懂?dāng)?shù)據(jù),方便做決策。然而,無(wú)論是有意或無(wú)心,它可以為我們呈現(xiàn)有效的信息,同樣也可以為我們呈現(xiàn)無(wú)效的信息,其弊端也許日后會(huì)日益顯現(xiàn)。若想要了解更多有關(guān)數(shù)據(jù)可視化的內(nèi)容并掌握這門(mén)技巧,可參閱 Stephen Few , Kaiser Fung , Edward Tufte , Nathan Yau , and Fernanda Viégas and Martin Wattenberg
總的來(lái)說(shuō),雖然大數(shù)據(jù)發(fā)展已久,但 數(shù)據(jù)運(yùn)用也許在當(dāng)今市場(chǎng)營(yíng)銷(xiāo)領(lǐng)域中仍欠缺開(kāi)發(fā)利用 。因此,我們應(yīng)正視數(shù)據(jù)的作用,并開(kāi)始有效的利用它。
『 WeMedia 』自媒體聯(lián)盟覆蓋千萬(wàn)人群,『199IT-互聯(lián)網(wǎng)數(shù)據(jù)中心』為其成員。( 賬戶(hù):i199IT)
者 | Adrien Joly
譯者 | 張衛(wèi)濱
策劃 | 丁曉昀
有時(shí)候,JavaScript(甚至帶有類(lèi)型檢查的 TypeScript)會(huì)因?yàn)槠洳豢深A(yù)測(cè)的特性和缺乏約定而遭到批評(píng)。對(duì)于那些知道 JavaScript 是為 web 瀏覽器設(shè)計(jì)的腳本語(yǔ)言的人來(lái)說(shuō),這就不足為奇了。
但是,現(xiàn)在它已經(jīng)成為開(kāi)發(fā)全棧 web 的首選語(yǔ)言,也是跨平臺(tái)移動(dòng)應(yīng)用的熱門(mén)方案。那么,當(dāng)開(kāi)發(fā)人員的 JavaScript/TypeScript 代碼庫(kù)開(kāi)始老化,由此帶來(lái)的復(fù)雜性痛苦地增長(zhǎng)時(shí),他們?cè)摬扇∈裁葱袆?dòng)才能最大限度地減少資源浪費(fèi)并保持工作滿(mǎn)意度呢?
本文將基于我 10 多年來(lái)編寫(xiě) JavaScript 代碼的經(jīng)驗(yàn)和 5 年多拯救 JS/TS 項(xiàng)目的經(jīng)歷,向讀者介紹如下內(nèi)容:
在開(kāi)發(fā)下一個(gè)特性時(shí),每個(gè)警告、類(lèi)型錯(cuò)誤或非正常的測(cè)試都會(huì)讓開(kāi)發(fā)人員浪費(fèi)時(shí)間、精力和專(zhuān)注度。
代碼警告尤其令人討厭,因?yàn)殚_(kāi)發(fā)人員會(huì)習(xí)慣性地忽略它們,“只要一切按預(yù)期運(yùn)行就好”。因此,它們會(huì)迅速累積,當(dāng)我們遇到缺陷、事故或系統(tǒng)的意外行為時(shí),就很難將其作為有用的線索。
類(lèi)型錯(cuò)誤就是一個(gè)很好的樣例。當(dāng)我們的用戶(hù)遵循“快樂(lè)路徑(happy path)”時(shí),這些錯(cuò)誤似乎無(wú)關(guān)緊要,因?yàn)檐浖坪跄軌虬凑疹A(yù)期運(yùn)行。所以,我們可能會(huì)使用@ts-ignore、any或類(lèi)型斷言來(lái)暫時(shí)忽略它們。但是,這樣做的話,就意味著如果有一天用戶(hù)選擇不同的路徑,就會(huì)面臨運(yùn)行時(shí)錯(cuò)誤。
這樣的話,開(kāi)發(fā)人員就需要調(diào)查、重現(xiàn)和修復(fù)一個(gè)新的缺陷,而這個(gè)缺陷恰恰是他們幾個(gè)月前允許走捷徑所造成的。如果你的代碼被各種警告和/或暫時(shí)忽略這些警告削弱了質(zhì)量,那么找到這個(gè)捷徑將耗費(fèi)大量的時(shí)間。
當(dāng)生產(chǎn)環(huán)境的數(shù)據(jù)庫(kù)因“內(nèi)存不足”錯(cuò)誤而崩潰時(shí),該警告可能會(huì)幫助開(kāi)發(fā)人員找到崩潰的原因
警告和類(lèi)型錯(cuò)誤是查找缺陷和事故的線索。我們累積(或忽略)的警告和錯(cuò)誤越多,開(kāi)發(fā)人員就會(huì)花費(fèi)越多的時(shí)間去調(diào)查。如果代碼是他們很久以前編寫(xiě)的,那情況就會(huì)更糟糕了。
類(lèi)型檢查器認(rèn)為缺少一個(gè)預(yù)期的屬性。忽略這個(gè)錯(cuò)誤將意味著要承擔(dān)持久化不一致數(shù)據(jù)的風(fēng)險(xiǎn),在幾個(gè)月之后,你可能需要花費(fèi)幾天的時(shí)間來(lái)調(diào)查和解決這個(gè)問(wèn)題
有許多靜態(tài)代碼分析工具可供使用,最常用的包括:
警告也可能來(lái)自其他工具:依賴(lài)安裝器(如npm和yarn)、打包器(如webpack)、代碼處理器(babel、scss)和執(zhí)行環(huán)境(CI 運(yùn)行器)。不要忽視它們!
如果遵循這些建議會(huì)讓你的代碼變得非常冗長(zhǎng)和/或復(fù)雜(比如防御式代碼),你可以需要對(duì)其進(jìn)行重新設(shè)計(jì)。
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"lint:errors": "eslint . --quiet",
"lint:typescript": "tsc --noEmit --skipLibCheck",
"lint:jsdoc-typing": "tsc --noEmit --allowJs `find ./ -name '*.js' -name '*.d.ts'`"
},
復(fù)制代碼
借助靜態(tài)代碼分析器和 npm 腳本,能夠讓開(kāi)發(fā)人員輕松快速地探測(cè)有問(wèn)題的代碼
安裝和配置靜態(tài)代碼分析工具是一個(gè)良好的開(kāi)端,但這還不夠。
要想取得持續(xù)的成功,要確保開(kāi)發(fā)團(tuán)隊(duì)做到如下幾點(diǎn):
如下幾種策略可能會(huì)提供幫助:
當(dāng)某項(xiàng)職責(zé)沒(méi)有人負(fù)責(zé)時(shí),集體責(zé)任往往會(huì)被其他“優(yōu)先事項(xiàng)”所取代(比如,本周多交付一個(gè)特性,但是代價(jià)是忽略一個(gè)警告)。
定期輪換角色,確保每個(gè)人都能參與其中并保持積極性。
現(xiàn)在,我們有了一支致力于保持代碼庫(kù)整潔的團(tuán)隊(duì),我們相信用戶(hù)很少會(huì)遇到編程錯(cuò)誤。
但是,業(yè)務(wù)邏輯中的錯(cuò)誤該怎么辦呢?
例如,如果一個(gè)新添加的功能破壞了另一個(gè)功能該怎么辦?如果開(kāi)發(fā)人員從一開(kāi)始就誤解了該功能的預(yù)期行為,又該怎么辦?如果這樣的錯(cuò)誤最終導(dǎo)致了嚴(yán)重的收入損失又該如何處理?
與編程錯(cuò)誤類(lèi)似,業(yè)務(wù)邏輯問(wèn)題可能會(huì)在生產(chǎn)環(huán)境由用戶(hù)發(fā)現(xiàn),但我們更希望盡早發(fā)現(xiàn)它們。因此,定期測(cè)試軟件非常重要,這個(gè)過(guò)程可以使用自動(dòng)化和/或手動(dòng)測(cè)試。
從業(yè)務(wù)角度看,測(cè)試有兩個(gè)作用:
確保功能性測(cè)試(也稱(chēng)為“驗(yàn)收測(cè)試”)涵蓋大多數(shù)關(guān)鍵業(yè)務(wù)特性,單元測(cè)試或集成測(cè)試涵蓋大多數(shù)關(guān)鍵技術(shù)組件。此外,確保持續(xù)集成在任何測(cè)試失敗時(shí)都能向開(kāi)發(fā)人員提供可執(zhí)行的反饋。
對(duì)于有些開(kāi)發(fā)人員來(lái)說(shuō),將測(cè)試工作委托給其他人(如產(chǎn)品負(fù)責(zé)人或 QA 團(tuán)隊(duì))是很有誘惑力的做法。在每個(gè)新特性完成后,進(jìn)行一次這樣的委托測(cè)試,以確保特性實(shí)現(xiàn)符合功能性需求,并進(jìn)行協(xié)作迭代,這樣做可能是合理的。
但是,委托他人進(jìn)行回歸檢測(cè)并不是一個(gè)好主意,原因包括:
回歸測(cè)試是一項(xiàng)痛苦且可能代價(jià)高昂的負(fù)擔(dān),尤其是需要不同角色(如產(chǎn)品負(fù)責(zé)人和開(kāi)發(fā)人員)必須協(xié)作的情況下。從長(zhǎng)遠(yuǎn)來(lái)看,回歸測(cè)試自動(dòng)化意味著可以節(jié)省大量的時(shí)間,而且開(kāi)發(fā)人員具有編寫(xiě)自動(dòng)化測(cè)試的技能,所以,開(kāi)發(fā)人員首先要承擔(dān)起檢測(cè)回歸的責(zé)任,而不必讓其他角色參與進(jìn)來(lái),這符合他們的利益。
從最關(guān)鍵的業(yè)務(wù)特性開(kāi)始。要找出這些特性,你可以問(wèn)自己:“就收益和/或減少成本而言,在生產(chǎn)環(huán)境中可能發(fā)生的最糟糕的事情是什么?”
例如,電子商務(wù)網(wǎng)站的回答可能是如下的特性:
基于這些業(yè)務(wù)關(guān)鍵的用例,從它們開(kāi)始編寫(xiě)端到端的自動(dòng)化測(cè)試肯定就是非常有意義的。
在每次代碼更新或添加到代碼庫(kù)之時(shí),在將其部署到生產(chǎn)環(huán)境之前。
借助git hook,在每次提交時(shí)運(yùn)行測(cè)試可能就足夠了,因?yàn)樗芸煽康剡\(yùn)行,而且其持續(xù)時(shí)間不會(huì)導(dǎo)致開(kāi)發(fā)人員編寫(xiě)更少的測(cè)試。
不管是否使用git hook,都要確保每次推送可用于生產(chǎn)環(huán)境的代碼時(shí),測(cè)試能在某處運(yùn)行(例如,最好是在持續(xù)集成環(huán)境中)。
在持續(xù)集成環(huán)境中,每次提交都會(huì)運(yùn)行代碼檢查和自動(dòng)化測(cè)試。
需要優(yōu)化的變量包括:
如果你的團(tuán)隊(duì)在編寫(xiě)自動(dòng)化測(cè)試和/或可測(cè)試代碼方面經(jīng)驗(yàn)不足,那么可以從一些端到端測(cè)試開(kāi)始。然后,逐步增加對(duì)范圍更小的代碼單元的測(cè)試。這樣做可以激勵(lì)開(kāi)發(fā)人員編寫(xiě)易于測(cè)試的代碼。例如,通過(guò)隔離責(zé)任、減少耦合和/或?qū)I(yè)務(wù)邏輯寫(xiě)成純函數(shù)。遵循依賴(lài)注入架構(gòu)是實(shí)現(xiàn)這一目標(biāo)的好方法。(參見(jiàn)六邊形架構(gòu)或簡(jiǎn)潔架構(gòu))
自動(dòng)化測(cè)試(如本文所述)的目的是探測(cè)團(tuán)隊(duì)的功能性范圍內(nèi)的回歸,而不是第三方的功能。基于這一點(diǎn),在測(cè)試中 Mock 第三方是合理的。
也就是說(shuō):
探測(cè)自己的代碼中的問(wèn)題和第三方 API 中的問(wèn)題并不遵循相同的生命周期:
你需要持續(xù)監(jiān)控第三方提供商是否能夠正常運(yùn)行并達(dá)到預(yù)期效果。但是,第三方錯(cuò)誤不一定能夠在發(fā)生之時(shí)就探測(cè)到,因此最好是定期監(jiān)控,而不是在開(kāi)發(fā)人員每次推送代碼變更的時(shí)候進(jìn)行監(jiān)控。
所以,需要搭建兩個(gè)專(zhuān)門(mén)的流水線:
為了編寫(xiě)長(zhǎng)期最有用、最健壯的測(cè)試,我建議遵循F.I.R.S.T.原則。確保開(kāi)發(fā)人員不會(huì)濫用mock。
假設(shè)你的代碼庫(kù)已經(jīng)或者將要開(kāi)發(fā)數(shù)年的時(shí)間,那么隨著時(shí)間的推移,它很可能會(huì)在代碼風(fēng)格和質(zhì)量方面失去內(nèi)聚力。更糟糕的是,由于技術(shù)債務(wù)、缺乏測(cè)試或意外復(fù)雜性的積累,某些組成部分的維護(hù)可能會(huì)變得很復(fù)雜。
在這種情況下,要像上文所建議的那樣,在整個(gè)代碼庫(kù)中對(duì)代碼實(shí)現(xiàn)一致的內(nèi)聚預(yù)期可能會(huì)變得很復(fù)雜。不過(guò),這也沒(méi)有關(guān)系。
你不希望看到的是期望值降低到一個(gè)最低的平均水準(zhǔn)。這樣的話,你可以把代碼劃分為不同的范圍,并為每個(gè)范圍設(shè)置不同的期望水平。
例如,考慮一個(gè)即將為電子商務(wù)網(wǎng)站實(shí)現(xiàn)新特性的團(tuán)隊(duì)。他們希望這個(gè)新特性能夠比代碼庫(kù)中的其他特性更健壯、更易于維護(hù)。為了實(shí)現(xiàn)這一點(diǎn),他們?cè)谂渲渺o態(tài)代碼分析工具(如 ESLint 和 TypeScript)時(shí)采用比代碼庫(kù)的其他部分更嚴(yán)格的規(guī)則,并針對(duì)專(zhuān)門(mén)為該特性而創(chuàng)建的目錄使用覆蓋的方式啟用更多的規(guī)則。通過(guò)這種方式,團(tuán)隊(duì)可以提高新代碼的質(zhì)量,而不必急于對(duì)代碼庫(kù)中“遺留”的部分進(jìn)行現(xiàn)代化處理。
"rules": {
"prettier/prettier": "error",
"deprecation/deprecation": "warn"
},
"overrides": [
{
// Tolerate warnings on non critical issues from legacy JavaScript files
"files": ["*.js"],
"rules": {
"prefer-const": "warn",
"no-inner-declarations": ["warn", "functions"],
"@typescript-eslint/ban-ts-comment": "warn",
"@typescript-eslint/no-var-requires": "off"
}
},
{
// Enforce stricter rules on domain / business logic
"files": ["app/domain/**/*.js", "app/domain/**/*.ts"],
"extends": ["async", "async/node", "async/typescript"],
"rules": {
"prefer-const": "error",
"no-async-promise-executor": "error",
"no-await-in-loop": "error",
"no-promise-executor-return": "error",
"max-nested-callbacks": "error",
"no-return-await": "error",
"prefer-promise-reject-errors": "error",
"node/handle-callback-err": "error",
"node/no-callback-literal": "error",
"node/no-sync": "error",
"@typescript-eslint/await-thenable": "error",
"@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/no-misused-promises": "error",
"@typescript-eslint/promise-function-async": "error"
}
}
]
復(fù)制代碼
通過(guò)配置覆蓋,我們可以為不同的部分設(shè)置不同的 ESLint 規(guī)則
與之類(lèi)似,如果要對(duì)整個(gè)代碼庫(kù)進(jìn)行現(xiàn)代化改造,也要循序漸進(jìn)。你可以創(chuàng)建一個(gè)具有更嚴(yán)格規(guī)則的專(zhuān)用目錄,并逐漸將遺留代碼遷移至該目錄,同時(shí)修復(fù)代碼的警告和類(lèi)型錯(cuò)誤。
有種方式是逐步將功能范圍中陳舊的部分遷移到更好的設(shè)計(jì)中。例如,選擇一個(gè)難以編寫(xiě)自動(dòng)化測(cè)試的特性,并將它的實(shí)現(xiàn)遷移到六邊形架構(gòu)中,將業(yè)務(wù)/領(lǐng)域邏輯根據(jù)輸入命令(即“API”)和副作用(即“SPI”)分離開(kāi)來(lái)。通過(guò)編寫(xiě)自動(dòng)化測(cè)試來(lái)指導(dǎo)遷移,并將新的實(shí)現(xiàn)放在具有更嚴(yán)格靜態(tài)代碼分析規(guī)則的專(zhuān)用目錄中。
import { makeFeatures }=from './domain/features';
import { userCollection } from './infrastructure/mongodb/UserCollection';
import { ImageStorage } from './infrastructure/ImageStorage.js';
/** @type {import('./domain/api/Features').Features} Features*/
const features=makeFeatures({
userRepository: userCollection,
imageRepository: new ImageStorage(),
});
routes.post('/avatar', (request, response)=> {
features
.setAvatar(request.session.userId, request.files[0])
.then(
()=> response.json({ ok: true },
(error)=> response.json({ ok: false })
);
});
復(fù)制代碼
setAvatar特性經(jīng)過(guò)了重新設(shè)計(jì),由于采用了依賴(lài)反轉(zhuǎn),使其易于單獨(dú)進(jìn)行測(cè)試。下面是我們遷移另一項(xiàng)特性的過(guò)程,即播放列表刪除
如果你決定遵循這一路徑,如下是一些建議:
在遷移完每個(gè)限界上下文之后,你將會(huì)得到一個(gè)代碼庫(kù),在代碼庫(kù)中 100%的代碼都應(yīng)按照更嚴(yán)格的規(guī)則進(jìn)行檢查。
盡管使用了靜態(tài)分析工具來(lái)檢測(cè)缺陷,使用了自動(dòng)化測(cè)試來(lái)探測(cè)回歸,但用戶(hù)還是會(huì)在生產(chǎn)環(huán)境中發(fā)現(xiàn)問(wèn)題。這是無(wú)法避免的。但是,有一種方法可以降低出現(xiàn)此類(lèi)問(wèn)題的概率,并縮短團(tuán)隊(duì)修復(fù)問(wèn)題的時(shí)間:
簡(jiǎn)約版答案:因?yàn)镈ORA研究項(xiàng)目發(fā)現(xiàn),大多數(shù)執(zhí)行團(tuán)隊(duì)每天都在進(jìn)行部署,或者每天部署多次。
詳盡版答案:
在生產(chǎn)環(huán)境中出現(xiàn)意料之外的行為是可以的。在有些情況下,這甚至是一件好事。
當(dāng)意料之外的行為給企業(yè)和/或開(kāi)發(fā)團(tuán)隊(duì)帶來(lái)巨大損失時(shí)(例如,網(wǎng)站中斷,導(dǎo)致幾個(gè)小時(shí)無(wú)法使用),開(kāi)發(fā)人員應(yīng)該采取措施防止類(lèi)似的事件再次發(fā)生。
有多種方式可以探測(cè)生產(chǎn)環(huán)境中的問(wèn)題:
無(wú)論是哪種情況,開(kāi)發(fā)人員都需要以下信息:?jiǎn)栴}是什么、問(wèn)題的具體表現(xiàn)(如錯(cuò)誤信息)、如何重現(xiàn)問(wèn)題(如環(huán)境+過(guò)程),以及用戶(hù)的初衷和期望是什么。
但是,如何在最糟糕的情況下獲得這些數(shù)據(jù)呢?這就是錯(cuò)誤監(jiān)控工具(如Sentry)的用武之地了。通過(guò)將它們注入到生產(chǎn)環(huán)境中運(yùn)行的產(chǎn)品中,它們就能像探針一樣檢測(cè)運(yùn)行時(shí)錯(cuò)誤,并將它們匯總到已知錯(cuò)誤的列表中,直到每個(gè)錯(cuò)誤都被開(kāi)發(fā)人員修復(fù)為止。此外,它們還會(huì)獲取有關(guān)錯(cuò)誤上下文的數(shù)據(jù)(如用戶(hù)代理、所使用軟件的版本、操作系統(tǒng)、確切的時(shí)間戳等),以幫助開(kāi)發(fā)人員重現(xiàn)錯(cuò)誤。
但令人遺憾的是,與靜態(tài)代碼分析器類(lèi)似,這些工具并不能解決問(wèn)題。因此,與警告和類(lèi)型錯(cuò)誤一樣,要確保盡快處理每個(gè)錯(cuò)誤。團(tuán)隊(duì)讓錯(cuò)誤累積得越多,使用這些工具的動(dòng)力和效率就會(huì)越低。
此外,在使用這類(lèi)監(jiān)控工具時(shí),請(qǐng)確保個(gè)人和/或機(jī)密數(shù)據(jù)不會(huì)從系統(tǒng)中泄露出去。
從戰(zhàn)術(shù)上講,有許多方法可供選擇。你可以讓一名開(kāi)發(fā)人員負(fù)責(zé)修復(fù)生產(chǎn)環(huán)境的錯(cuò)誤,并將其作為最優(yōu)先的事項(xiàng)。這個(gè)角色可以定期輪換(比如每天),這樣可以激勵(lì)每個(gè)人都編寫(xiě)更健壯的代碼。或者,也可以在每天的會(huì)議上將新錯(cuò)誤單獨(dú)分派給志愿開(kāi)發(fā)人員。
不必慌張!當(dāng)生產(chǎn)環(huán)境中發(fā)生事故時(shí),都要遵守如下程序:
避免重蹈覆轍的關(guān)鍵在于上述程序的最后一步。
這也是經(jīng)常被忽視的過(guò)程。大多數(shù)情況下,是因?yàn)闆](méi)人覺(jué)得自己有責(zé)任這樣做。很多時(shí)候,是因?yàn)楫a(chǎn)品負(fù)責(zé)人(或產(chǎn)品團(tuán)隊(duì))向開(kāi)發(fā)人員施壓,要求他們優(yōu)先完成開(kāi)發(fā)計(jì)劃中的特性,而不是保護(hù)現(xiàn)有代碼和/或調(diào)整開(kāi)發(fā)流程。有時(shí),開(kāi)發(fā)人員自己也會(huì)決定開(kāi)發(fā)更多的特性,而不是避免再次犯錯(cuò)。
調(diào)查事故根本原因時(shí)的注意事項(xiàng)
在這個(gè)方面,“5 個(gè)為什么(5 WHY)”技巧是很有用的。例如:
在本例中,根本原因是整個(gè)網(wǎng)站都依賴(lài)于遺留的會(huì)話管理后端,這使得導(dǎo)航難以預(yù)測(cè),有時(shí)還會(huì)導(dǎo)致生產(chǎn)環(huán)境崩潰。因此,除非團(tuán)隊(duì)修復(fù)傳統(tǒng)的會(huì)話管理后端,否則類(lèi)似的崩潰很可能很快就會(huì)在生產(chǎn)環(huán)境中再次發(fā)生。團(tuán)隊(duì)現(xiàn)在應(yīng)該修復(fù)遺留的會(huì)話管理后端嗎?也許不用。但是他們應(yīng)該努力制定一個(gè)能夠?qū)崿F(xiàn)該目標(biāo)的補(bǔ)救計(jì)劃。
讓一位開(kāi)發(fā)人員負(fù)責(zé)確保盡快發(fā)現(xiàn)生產(chǎn)中的意外行為(如運(yùn)行時(shí)錯(cuò)誤、缺陷、事故……),盡快修復(fù),并采取措施防止今后再次發(fā)生各類(lèi)問(wèn)題。
通過(guò)這種方式,開(kāi)發(fā)人員能夠感受到有能力在良好的條件下開(kāi)展工作。例如,在生產(chǎn)過(guò)程中設(shè)置恰當(dāng)?shù)谋O(jiān)控和日志,確保撰寫(xiě)有用的事后報(bào)告,并采取預(yù)防措施。
當(dāng)信心達(dá)到良好水平時(shí),逐步增加部署頻率。
此時(shí),開(kāi)發(fā)人員就具備了編寫(xiě)高質(zhì)量軟件,并盡快發(fā)現(xiàn)缺陷的能力。這些缺陷最好是在設(shè)計(jì)或?qū)崿F(xiàn)時(shí)發(fā)現(xiàn),而不是在生產(chǎn)環(huán)境中。他們能夠快速發(fā)現(xiàn)并修正生產(chǎn)環(huán)境的錯(cuò)誤,不會(huì)重復(fù)犯同樣的錯(cuò)誤。他們對(duì)自己的代碼和開(kāi)發(fā)流程充滿(mǎn)信心,因此每天都能在生產(chǎn)中實(shí)現(xiàn)改善。而且,他們?cè)趯?duì)軟件功能化范圍進(jìn)行預(yù)期改善的同時(shí),也會(huì)逐步改善代碼庫(kù)中最古老部分的設(shè)計(jì)和質(zhì)量,使其保持健康、穩(wěn)健并易于長(zhǎng)期維護(hù)。
但是,令人遺憾的是,這種平衡很快就可能被瓦解。舉例來(lái)說(shuō):
防止或解決這類(lèi)情況可能會(huì)非常困難,因?yàn)檫@需要良好的領(lǐng)導(dǎo)力和/或軟技能。
一個(gè)常見(jiàn)的錯(cuò)誤是培養(yǎng)某種思維定式,即開(kāi)發(fā)人員應(yīng)該主要致力于實(shí)現(xiàn)優(yōu)先的、計(jì)劃好的和設(shè)計(jì)好的特性。
這樣做是有問(wèn)題的,因?yàn)椋?/span>
下面是一些關(guān)于如何避免上述陷阱的建議:
JavaScript 語(yǔ)言及其不斷變化的軟件包和實(shí)踐組成的生態(tài)系統(tǒng)會(huì)使代碼庫(kù)迅速變得難以維護(hù)。正如我們?cè)诒疚乃懻摰哪菢樱瑹o(wú)需從頭重寫(xiě)所有的內(nèi)容,也無(wú)需暫停新特性的開(kāi)發(fā),就可以避免由此造成的開(kāi)發(fā)速度和/或代碼質(zhì)量的下降。
關(guān)于如何在 TypeScript 和 JavaScript 項(xiàng)目中應(yīng)用這些推薦做法的更多實(shí)用建議,我建議你參考Yoni Goldberg的最佳實(shí)踐列表。它們是為 Node.js(后端)項(xiàng)目編寫(xiě)的,但其中很多也適用于前端代碼庫(kù)。
原文鏈接:前端老手10年心得,JavaScript/TypeScript項(xiàng)目保養(yǎng)實(shí)用指南_架構(gòu)/框架_InfoQ精選文章
聞 法 訊
(第16期)
法訊回歸,如聞為您帶來(lái)最新法律動(dòng)態(tài)~
一、法律動(dòng)態(tài)
1. 2023年9月20日,國(guó)家金融監(jiān)督管理總局發(fā)布《保險(xiǎn)銷(xiāo)售行為管理辦法》(“《辦法》”),將于2024年3月1日。《辦法》共6章50條,重點(diǎn)對(duì)銷(xiāo)售人員資質(zhì)、跨區(qū)域展業(yè)、產(chǎn)品分級(jí)制度、產(chǎn)品宣傳、離職后責(zé)任等方面進(jìn)行了細(xì)化性規(guī)范。《辦法》旨在完善行為監(jiān)管制度體系、構(gòu)建保險(xiǎn)銷(xiāo)售行為監(jiān)管框架,全文刊載于國(guó)家金融監(jiān)督管理總局網(wǎng)站:http://www.cbirc.gov.cn/cn/view/pages/rulesDetail.html?docId=1129945&itemId=4214&generaltype=1
2.2023年9月25日,最高人民法院發(fā)布《最高人民法院關(guān)于優(yōu)化法治環(huán)境促進(jìn)民營(yíng)經(jīng)濟(jì)發(fā)展壯大的指導(dǎo)意見(jiàn)》(“《指導(dǎo)意見(jiàn)》”)。《指導(dǎo)意見(jiàn)》從六個(gè)方面對(duì)審判執(zhí)行工作提出了明確要求,重點(diǎn)對(duì)保護(hù)民營(yíng)企業(yè)產(chǎn)權(quán)和企業(yè)家合法權(quán)益、嚴(yán)厲打擊惡意“維權(quán)”侵犯民營(yíng)企業(yè)合法權(quán)益的行為、對(duì)中小微民營(yíng)企業(yè)的融資、股東不當(dāng)行為等給予司法保障等,提出了相關(guān)意見(jiàn)。《指導(dǎo)意見(jiàn)》全文刊載于最高人民法院網(wǎng)站:https://www.court.gov.cn/zixun/xiangqing/413942.html
3. 2023年10月16日,國(guó)務(wù)院發(fā)布了《未成年人網(wǎng)絡(luò)保護(hù)條例》(“《條例》”),將于2024年1月1日實(shí)施。《條例》從提升未成年人網(wǎng)絡(luò)素養(yǎng)、加強(qiáng)網(wǎng)絡(luò)信息內(nèi)容規(guī)范、拒絕網(wǎng)絡(luò)欺凌、預(yù)防和干預(yù)未成年人沉迷網(wǎng)絡(luò)、保護(hù)未成年人信息以及對(duì)未成年人網(wǎng)絡(luò)消費(fèi)數(shù)額進(jìn)行限制等六個(gè)方面,提出了規(guī)范要求。《條例》是我國(guó)出臺(tái)的第一步專(zhuān)門(mén)性的未成年人網(wǎng)絡(luò)保護(hù)綜合立法,旨在進(jìn)一步完善互聯(lián)網(wǎng)領(lǐng)域治理體系,為健全青少年健康成長(zhǎng)提供重要的法治保障。《條例》全文刊載于中國(guó)政府網(wǎng):https://www.gov.cn/zhengce/zhengceku/202310/content_6911289.htm
4. 2023年11月10日,香港特別行政區(qū)政府確認(rèn)《關(guān)于內(nèi)地與香港特別行政區(qū)法院相互認(rèn)可和執(zhí)行民商事案件判決的安排》(“《安排》”)將于2024年1月29日生效并實(shí)施。《安排》在管轄判定、適用范圍、具體認(rèn)可和執(zhí)行的判斷標(biāo)準(zhǔn)和程序等方面的規(guī)定,較現(xiàn)行有效的《最高人民法院關(guān)于內(nèi)地與香港特別行政區(qū)法院相互認(rèn)可和執(zhí)行當(dāng)事人協(xié)議管轄的民商事案件判決的安排》更加完善,有效擴(kuò)大互相認(rèn)可和執(zhí)行判決的民商事?tīng)?zhēng)議范圍、遏制惡意規(guī)避法院執(zhí)行判決的行為。《安排》全文刊載于最高人民法院網(wǎng)站:https://www.court.gov.cn/fabu-xiangqing-139501.html
5. 2023年11月15日,最高人民法院發(fā)布《最高人民法院關(guān)于綜合治理類(lèi)司法建議工作若干問(wèn)題的規(guī)定》(“《規(guī)定》”)。《規(guī)定》旨在落實(shí)“抓前端、治未病”的重要指示精神,對(duì)提出司法建議的名義、事前溝通、協(xié)同落實(shí)、文書(shū)規(guī)范等進(jìn)行規(guī)定,以規(guī)范司法建議工作,引導(dǎo)人民法院結(jié)合審判執(zhí)行工作依法能動(dòng)履職。《規(guī)定》全文刊載于最高人民法院網(wǎng)站:http://courtapp.chinacourt.org/zixun/xiangqing/417752.html
6. 2023年11月21日,司法部發(fā)布《行政復(fù)議普通程序聽(tīng)取意見(jiàn)辦法(征求意見(jiàn)稿)》和《行政復(fù)議普通程序聽(tīng)證辦法(征求意見(jiàn)稿)》并向社會(huì)公開(kāi)征求意見(jiàn)。相關(guān)文件系為規(guī)范行政復(fù)議普通程序聽(tīng)取意見(jiàn)和聽(tīng)證工作,進(jìn)一步提高行政復(fù)議工作質(zhì)效,更好的保護(hù)公民、法人、其他組織的合法權(quán)益。意見(jiàn)反饋截止日期為2023年11月30 日,意見(jiàn)征求公告及草案刊載于司法部官網(wǎng):http://www.moj.gov.cn/pub/sfbgwapp/zwgk/tzggApp/202311/t20231121_490029.html
作者 陳曉燕
責(zé)編 高萍
往期推薦
01
知網(wǎng)被罰8760萬(wàn),“知識(shí)壟斷”不可為
02
案外人提出異議后,還能另行提起確權(quán)之訴嗎?
03
雙語(yǔ)|一文讀懂新婦保法,企業(yè)該做些什么?(下)
特別聲明
掃碼關(guān)注我們
上海如聞律師事務(wù)所
《金剛經(jīng)》卷首語(yǔ):“如是我聞”,如聞律師事務(wù)所藉此得名。“盛世法,如聞人”是本所之銘。法律的精神在于維護(hù)社會(huì)的公平與正義。但,“徒法不足以自行”。法律的正確實(shí)施,公平價(jià)值得以實(shí)現(xiàn),離不開(kāi)一位好律師來(lái)為您的權(quán)益保駕護(hù)航。愿我們能和您一起,在這個(gè)新時(shí)代里,追逐夢(mèng)想,實(shí)現(xiàn)夢(mèng)想。所有的如聞人,以鉆研精神,飽含著無(wú)限熱情,踐行著法律者的初心,為所有如聞的朋友們,做好專(zhuān)業(yè)的服務(wù)。
我們的精神就是:如你所需,如聞?dòng)肋h(yuǎn)和你在一起。
*請(qǐng)認(rèn)真填寫(xiě)需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。