成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

React 是怎樣煉成的

lijinke666 / 1336人閱讀

摘要:唯一不足的是,這種開發(fā)方式容易造成注入等安全問題。其中,最棘手的是如何再現(xiàn)中的更新機(jī)制。換句話來(lái)說(shuō),節(jié)點(diǎn)是包含狀態(tài)的。對(duì)于沒有改變的節(jié)點(diǎn),讓它保持原樣不動(dòng),僅僅創(chuàng)建并替換變更過的節(jié)點(diǎn)。是樹形結(jié)構(gòu),所以算法必須是針對(duì)樹形結(jié)構(gòu)的。

本文主要講述 React 的誕生過程和優(yōu)化思路。

內(nèi)容整理自 2014 年的 OSCON - React Architecture by vjeux,雖然從今天(2018)來(lái)看可能會(huì)有點(diǎn)歷史感,但仍然值得學(xué)習(xí)了解。以史為鑒,從中也可以管窺 Facebook 優(yōu)秀的工程管理文化。

字符拼接時(shí)代 - 2004

時(shí)間回到 2004 年,Mark Zuckerberg 當(dāng)時(shí)還在宿舍搗鼓最初版的 Facebook 。
這一年,大家都在用 PHP 的字符串拼接(String Concatenation)功能來(lái)開發(fā)網(wǎng)站。

$str = "
    "; foreach ($talks as $talk) { $str += "
  • " . $talk->name . "
  • "; } $str += "
";

這種網(wǎng)站開發(fā)方式在當(dāng)時(shí)看來(lái)是非常正確的,因?yàn)椴还苁呛蠖碎_發(fā)還是前端開發(fā),甚至根本沒有開發(fā)經(jīng)驗(yàn),都可以使用這種方式搭建一個(gè)大型網(wǎng)站。

唯一不足的是,這種開發(fā)方式容易造成 XSS 注入等安全問題。如果 $talk->name 中包含惡意代碼,而又沒有做任何防護(hù)措施的話,那么攻擊者就可以注入任意 JS 代碼。于是就催生了“永遠(yuǎn)不要相信用戶的輸入”的安全守則。

最簡(jiǎn)單的應(yīng)對(duì)方法是對(duì)用戶的任何輸入都進(jìn)行轉(zhuǎn)義(Escape)。然而這也帶來(lái)了其他麻煩,如果對(duì)字符串進(jìn)行多次轉(zhuǎn)義,那么反轉(zhuǎn)義的次數(shù)也必須是相同的,否則會(huì)無(wú)法得到原內(nèi)容。如果又不小心把 HTML 標(biāo)簽(Markup)給轉(zhuǎn)義了,那么 HTML 標(biāo)簽會(huì)直接顯示給用戶,從而導(dǎo)致很差的用戶體驗(yàn)。

XHP 時(shí)代 - 2010

到了 2010 年,為了更加高效的編碼,同時(shí)也避免轉(zhuǎn)義 HTML 標(biāo)簽的錯(cuò)誤,F(xiàn)acebook 開發(fā)了 XHP 。XHP 是對(duì) PHP 的語(yǔ)法拓展,它允許開發(fā)者直接在 PHP 中使用 HTML 標(biāo)簽,而不再使用字符串。

$content = 
    ; foreach ($talks as $talk) { $content->appendChild(
  • {$talk->name}
  • ); }

這樣的話,所有的 HTML 標(biāo)簽都使用不同于 PHP 的語(yǔ)法,我們可以輕易的分辨哪些需要轉(zhuǎn)義哪些不需要轉(zhuǎn)義。

不久的后來(lái),F(xiàn)acebook 的工程師又發(fā)現(xiàn)他們還可以創(chuàng)建自定義標(biāo)簽,而且通過組合自定義標(biāo)簽有助于構(gòu)建大型應(yīng)用。
而這恰恰是 Semantic Web 和 Web Components 概念的一種實(shí)現(xiàn)方式。

$content = ;
foreach ($talks as $talk) {
  $content->appendChild();
}

之后,F(xiàn)acebook 在 JS 中嘗試了更多的新技術(shù)方式以減小客戶端和服務(wù)端之間的延時(shí)。比如跨瀏覽器 DOM 庫(kù)和數(shù)據(jù)綁定,但是都不是很理想。

JSX - 2013

等到 2013 年,突然有一天,前端工程師 Jordan Walke 向他的經(jīng)理提出了一個(gè)大膽的想法:把 XHP 的拓展功能遷移到 JS 中。最開始大家都以為他瘋了,因?yàn)檫@與當(dāng)時(shí)大家都看好的 JS 框架格格不入。不過他最終還是執(zhí)著地說(shuō)服了經(jīng)理,允許他用 6 個(gè)月的時(shí)間來(lái)驗(yàn)證這個(gè)想法。這里不得不說(shuō) Facebook 良好的工程師管理哲學(xué)讓人敬佩,值得借鑒。

附:Lee Byron 談 Facebook 工程師文化:Why Invest in Tools

要想把 XHP 的拓展功能遷移到 JS ,首要任務(wù)是需要一個(gè)拓展來(lái)讓 JS 支持 XML 語(yǔ)法,該拓展稱為 JSX 。當(dāng)時(shí),隨著 Node.js 的興起,F(xiàn)acebook 內(nèi)部對(duì)于轉(zhuǎn)換 JS 已經(jīng)有相當(dāng)多的工程實(shí)踐了。所以實(shí)現(xiàn) JSX 簡(jiǎn)直輕而易舉,僅僅花費(fèi)了大概一周的時(shí)間。

const content = (
  
    { talks.map(talk => )}
  
);
React

自此,開始了 React 的萬(wàn)里長(zhǎng)征,更大的困難還在后頭。其中,最棘手的是如何再現(xiàn) PHP 中的更新機(jī)制。

在 PHP 中,每當(dāng)有數(shù)據(jù)改變時(shí),只需要跳到一個(gè)由 PHP 全新渲染的新頁(yè)面即可。
從開發(fā)者的角度來(lái)看的話,這種方式開發(fā)應(yīng)用是非常簡(jiǎn)單的,因?yàn)樗恍枰獡?dān)心變更,且界面上用戶數(shù)據(jù)改變時(shí)所有內(nèi)容都是同步的。
只要有數(shù)據(jù)變更,就重新渲染整個(gè)頁(yè)面。

雖然簡(jiǎn)單粗暴,但是這種方式的缺點(diǎn)也尤為突出,那就是它非常慢。

“You need to be right before being good”,意思是說(shuō),為了驗(yàn)證遷移方案的可行性,開發(fā)者必須快速實(shí)現(xiàn)一個(gè)可用版本,暫時(shí)不考慮性能問題。

DOM

取自于 PHP 的靈感,在 JS 中實(shí)現(xiàn)重新渲染的最簡(jiǎn)單辦法是:當(dāng)任何內(nèi)容改變時(shí),都重新構(gòu)建整個(gè) DOM,然后用新 DOM 取代舊 DOM 。

這種方式是可以工作的,但在有些場(chǎng)景下不適用。
比如它會(huì)失去當(dāng)前聚焦的元素和光標(biāo),以及文本選擇和頁(yè)面滾動(dòng)位置,這些都是頁(yè)面的當(dāng)前狀態(tài)。
換句話來(lái)說(shuō),DOM 節(jié)點(diǎn)是包含狀態(tài)的。

既然包含狀態(tài),那么記下舊 DOM 的狀態(tài)然后在新 DOM 上還原不就行了么?
但是非常不幸,這種方式不僅實(shí)現(xiàn)起來(lái)復(fù)雜而且也無(wú)法覆蓋所有情況。

在 OSX 電腦上滾動(dòng)頁(yè)面時(shí),會(huì)伴隨著一定的滾動(dòng)慣性。但是 JS 并沒有提供相應(yīng)的 API 來(lái)讀取或者寫入滾動(dòng)慣性。
對(duì)包含 iframe 的頁(yè)面來(lái)說(shuō),情況則更復(fù)雜。如果它來(lái)自其他域,那么瀏覽器安全策略限制根本不會(huì)允許我們查看其內(nèi)部的內(nèi)容,更不用說(shuō)還原了。
因此可以看出,DOM 不僅僅有狀態(tài),它還包含隱藏的、無(wú)法觸達(dá)的狀態(tài)

既然還原狀態(tài)行不通,那就換一種方式繞過去。
對(duì)于沒有改變的 DOM 節(jié)點(diǎn),讓它保持原樣不動(dòng),僅僅創(chuàng)建并替換變更過的 DOM 節(jié)點(diǎn)。
這種方式實(shí)現(xiàn)了 DOM 節(jié)點(diǎn)復(fù)用(Reuse)。

至此,只要能夠識(shí)別出哪些節(jié)點(diǎn)改變了,那么就可以實(shí)現(xiàn)對(duì) DOM 的更新。于是問題就轉(zhuǎn)化為如何比對(duì)兩個(gè) DOM 的差異。

Diff

說(shuō)到對(duì)比差異,相信大家馬上就能聯(lián)想到版本控制(Version Control)。它的原理很簡(jiǎn)單,記錄多個(gè)代碼快照,然后使用 diff 算法比對(duì)前后兩個(gè)快照,從而生成一系列諸如“刪除 5 行”、“新增 3 行”、“替換單詞”等的改動(dòng);通過把這一系列的改動(dòng)應(yīng)用到先前的代碼快照就可以得到之后的代碼快照。

而這正是 React 所需要的,只不過它的處理對(duì)象是 DOM 而不是文本文件。
難怪有人說(shuō):“I tend to think of React as Version Control for the DOM” 。

DOM 是樹形結(jié)構(gòu),所以 diff 算法必須是針對(duì)樹形結(jié)構(gòu)的。目前已知的完整樹形結(jié)構(gòu) diff 算法復(fù)雜度為 O(n^3) 。

假如頁(yè)面中有 10,000 個(gè) DOM 節(jié)點(diǎn),這個(gè)數(shù)字看起來(lái)很龐大,但其實(shí)并不是不可想象。為了計(jì)算該復(fù)雜度的數(shù)量級(jí)大小,我們還假設(shè)在一個(gè) CPU 周期我們可以完成單次對(duì)比操作(雖然不可能完成),且 CPU 主頻為 1 GHz 。這種情況下,diff 要花費(fèi)的時(shí)間如下:

整整有 17 分鐘之長(zhǎng),簡(jiǎn)直無(wú)法想象!

雖然說(shuō)驗(yàn)證階段暫不考慮性能問題,但是我們還是可以簡(jiǎn)單了解下該算法是如何實(shí)現(xiàn)的。

附:完整的 Tree diff 實(shí)現(xiàn)算法。

新樹上的每個(gè)節(jié)點(diǎn)與舊樹上的每個(gè)節(jié)點(diǎn)對(duì)比

如果父節(jié)點(diǎn)相同,繼續(xù)循環(huán)對(duì)比子樹

在上圖的樹中,依據(jù)最小操作原則,可以找到三個(gè)嵌套的循環(huán)對(duì)比。

但如果認(rèn)真思考下,其實(shí)在 Web 應(yīng)用中,很少有移動(dòng)一個(gè)元素到另一個(gè)地方的場(chǎng)景。一個(gè)例子可能的是拖拽(Drag)并放置(Drop)元素到另一個(gè)地方,但它并不常見。

唯一的常用場(chǎng)景是在子元素之間移動(dòng)元素,例如在列表中新增、刪除和移動(dòng)元素。既然如此,那可以僅僅對(duì)比同層級(jí)的節(jié)點(diǎn)。

如上圖所示,僅對(duì)相同顏色的節(jié)點(diǎn)做 diff ,這樣能把時(shí)間復(fù)雜度降到了 O(n^2) 。

key

針對(duì)同級(jí)元素的比較,又引入了另一個(gè)問題。
同層級(jí)元素名稱不同時(shí),可以直接識(shí)別為不匹配;相同時(shí),卻沒那么簡(jiǎn)單了。
假如在某個(gè)節(jié)點(diǎn)下,上一次渲染了三個(gè) ,然后下一次渲染變成了兩個(gè)。此時(shí) diff 的結(jié)果會(huì)是什么呢?

最直觀的結(jié)果是前面兩個(gè)保持不變,刪除第三個(gè)。
當(dāng)然,也可以刪除第一個(gè)同時(shí)保持最后兩個(gè)。
如果不嫌麻煩,還可以把舊的三個(gè)都刪除,然后新增兩個(gè)新元素。
這說(shuō)明,對(duì)于相同標(biāo)簽名稱的節(jié)點(diǎn),我們沒有足夠信息來(lái)對(duì)比前后差異。

如果再加上元素的屬性呢?比如 value ,如果前后兩次標(biāo)簽名稱和 value 屬性都相同,那么就認(rèn)為元素匹配中,無(wú)須改動(dòng)。但現(xiàn)實(shí)是這行不通,因?yàn)橛脩糨斎霑r(shí)值總是在變,會(huì)導(dǎo)致元素一直被替換,導(dǎo)致失去焦點(diǎn);;更糟糕的是,并不是所有 HTML 元素都有這個(gè)屬性。

那使用所有元素都有的 id 屬性呢?這是可以的,如上圖,我們可以容易的識(shí)別出前后 DOM 的差異??紤]表單情況,表單模型的輸入通常跟 id 關(guān)聯(lián),但如果使用 AJAX 來(lái)提交表單的話,我們通常不會(huì)給 input 設(shè)置 id 屬性。因此,更好的辦法是引入一個(gè)新的屬性名稱,專門用來(lái)輔助 diff 算法。這個(gè)屬性最終確定為 key 。這也是為什么在 React 中使用列表時(shí)會(huì)要求給子元素設(shè)置 key 屬性的原因。

結(jié)合 key ,再加上哈希表,diff 算法最終實(shí)現(xiàn)了 O(n) 的最優(yōu)復(fù)雜度。
至此,可以看到從 XHP 遷移到 JS 的方案可行的。接下來(lái)就可以針對(duì)各個(gè)環(huán)節(jié)進(jìn)行逐步優(yōu)化。

附:詳細(xì)的 diff 理解:不可思議的 react diff 。
持續(xù)優(yōu)化 Virtual DOM

前面說(shuō)到,React 其實(shí)實(shí)現(xiàn)了對(duì) DOM 節(jié)點(diǎn)的版本控制。
做過 JS 應(yīng)用優(yōu)化的人可能都知道,DOM 是復(fù)雜的,對(duì)它的操作(尤其是查詢和創(chuàng)建)是非常慢非常耗費(fèi)資源的??聪旅娴睦?,僅創(chuàng)建一個(gè)空白的 div,其實(shí)例屬性就達(dá)到 231 個(gè)。

// Chrome v63
const div = document.createElement("div");
let m = 0;
for (let k in div) {
  m++;
}
console.log(m); // 231

之所以有這么多屬性,是因?yàn)?DOM 節(jié)點(diǎn)被用于瀏覽器渲染管道的很多過程中。
瀏覽器首先根據(jù) CSS 規(guī)則查找匹配的節(jié)點(diǎn),這個(gè)過程會(huì)緩存很多元信息,例如它維護(hù)著一個(gè)對(duì)應(yīng) DOM 節(jié)點(diǎn)的 id 映射表。
然后,根據(jù)樣式計(jì)算節(jié)點(diǎn)布局,這里又會(huì)緩存位置和屏幕定位信息,以及其他很多的元信息,瀏覽器會(huì)盡量避免重新計(jì)算布局,所以這些數(shù)據(jù)都會(huì)被緩存。
可以看出,整個(gè)渲染過程會(huì)耗費(fèi)大量的內(nèi)存和 CPU 資源。

現(xiàn)在回過頭來(lái)想想 React ,其實(shí)它只在 diff 算法中用到了 DOM 節(jié)點(diǎn),而且只用到了標(biāo)簽名稱和部分屬性。
如果用更輕量級(jí)的 JS 對(duì)象來(lái)代替復(fù)雜的 DOM 節(jié)點(diǎn),然后把對(duì) DOM 的 diff 操作轉(zhuǎn)移到 JS 對(duì)象,就可以避免大量對(duì) DOM 的查詢操作。這種方式稱為 Virtual DOM 。

其過程如下:

維護(hù)一個(gè)使用 JS 對(duì)象表示的 Virtual DOM,與真實(shí) DOM 一一對(duì)應(yīng)

對(duì)前后兩個(gè) Virtual DOM 做 diff ,生成變更(Mutation)

把變更應(yīng)用于真實(shí) DOM,生成最新的真實(shí) DOM

可以看出,因?yàn)橐炎兏鼞?yīng)用到真實(shí) DOM 上,所以還是避免不了要直接操作 DOM ,但是 React 的 diff 算法會(huì)把 DOM 改動(dòng)次數(shù)降到最低。

至此,React 的兩大優(yōu)化:diff 算法和 Virtual DOM ,均已完成。再加上 XHP 時(shí)代嘗試的數(shù)據(jù)綁定,已經(jīng)算是一個(gè)可用版本了。
這個(gè)時(shí)候 Facebook 做了個(gè)重大的決定,那就是把 React 開源!

React 的開源可謂是一石激起千層浪,社區(qū)開發(fā)者都被這種全新的 Web 開發(fā)方式所吸引,React 因此迅速占領(lǐng)了 JS 開源庫(kù)的榜首。
很多大公司也把 React 應(yīng)用到生產(chǎn)環(huán)境,同時(shí)也有大批社區(qū)開發(fā)者為 React 貢獻(xiàn)了代碼。

接下來(lái)要說(shuō)的兩大優(yōu)化就是來(lái)自于開源社區(qū)。

批處理(Batching)

著名瀏覽器廠商 Opera 把重排和重繪(Reflow and Repaint)列為影響頁(yè)面性能的三大原因之一。

我們說(shuō) DOM 是很慢的,除了前面說(shuō)到的它的復(fù)雜和龐大,還有另一個(gè)原因就是重排和重繪。

當(dāng) DOM 被修改后,瀏覽器必須更新元素的位置和真實(shí)像素;
當(dāng)嘗試從 DOM 讀取屬性時(shí),為了保證讀取的值是正確的,瀏覽器也會(huì)觸發(fā)重排和重繪。
因此,反復(fù)的“讀取、修改、讀取、修改...”操作,將會(huì)觸發(fā)大量的重排和重繪。

另外,由于瀏覽器本身對(duì) DOM 操作進(jìn)行了優(yōu)化,比如把兩次很近的“修改”操作合并成一個(gè)“修改”操作。
所以如果把“讀取、修改、讀取、修改...”重新排列為“讀取、讀取...”和“修改、修改...”,會(huì)有助于減小重排和重繪的次數(shù)。但是這種刻意的、手動(dòng)的級(jí)聯(lián)寫法是不安全的。

與此同時(shí),常規(guī)的 JS 寫法又很容易觸發(fā)重排和重繪。
在減小重排和重繪的道路上,React 陷入了尷尬的處境。

最終,社區(qū)貢獻(xiàn)者 Ben Alpert 使用批處理的方式拯救了這個(gè)尷尬的處境。

在 React 中,開發(fā)者通過調(diào)用組件的 setState 方法告訴 React 當(dāng)前組件要變更了。

Ben Alpert 的做法是,調(diào)用 setState 時(shí)不立即把變更同步到 Virtual DOM,而是僅僅把對(duì)應(yīng)元素打上“待更新”的標(biāo)記。如果組件內(nèi)調(diào)用多次 setState ,那么都會(huì)進(jìn)行相同的打標(biāo)操作。

等到初始化事件被完全廣播開以后,就開始進(jìn)行從頂部到底部的重新渲染(Re-Render)過程。這就確保了 React 只對(duì)元素進(jìn)行了一次渲染。

這里要注意兩點(diǎn):

此處的重新渲染是指把 setState 變更同步到 Virtual DOM ;在這之后才進(jìn)行 diff 操作生成真實(shí)的 DOM 變更。

與前文提到的“重新渲染整個(gè) DOM ”不同的是,真實(shí)的重新渲染僅渲染被標(biāo)記的元素及其子元素,也就是說(shuō)上圖中僅藍(lán)色圓圈代表的元素會(huì)被重新渲染

這也提醒開發(fā)者,應(yīng)該讓擁有狀態(tài)的組件盡量靠近葉子節(jié)點(diǎn),這樣可以縮小重新渲染的范圍。

裁剪(Pruning)

隨著應(yīng)用越來(lái)越大,React 管理的組件狀態(tài)也會(huì)越來(lái)越多,這就意味著重新渲染的范圍也會(huì)越來(lái)越大。

認(rèn)真觀察上面批處理的過程可以發(fā)現(xiàn),該 Virtual DOM 右下角的三個(gè)元素其實(shí)是沒有變更的,但是因?yàn)槠涓腹?jié)點(diǎn)的變更也導(dǎo)致了它們的重新渲染,多做了無(wú)用操作。

對(duì)于這種情況,React 本身已經(jīng)考慮到了,為此它提供了 bool shouldComponentUpdate(nextProps, nextState) 接口。開發(fā)者可以手動(dòng)實(shí)現(xiàn)該接口來(lái)對(duì)比前后狀態(tài)和屬性,以判斷是否需要重新渲染。這樣的話,重新渲染就變成如下圖所示過程。

當(dāng)時(shí),React 雖然提供了 shouldComponentUpdate 接口,但是并沒有提供一個(gè)默認(rèn)的實(shí)現(xiàn)方案(總是渲染),開發(fā)者必須自己手動(dòng)實(shí)現(xiàn)才能達(dá)到預(yù)期效果。

其原因是,在 JS 中,我們通常使用對(duì)象來(lái)保存狀態(tài),修改狀態(tài)時(shí)是直接修改該狀態(tài)對(duì)象的。也就是說(shuō),修改前后的兩個(gè)不同狀態(tài)指向了同一個(gè)對(duì)象,所以當(dāng)直接比較兩個(gè)對(duì)象是否變更時(shí),它們是相同的,即使?fàn)顟B(tài)已經(jīng)改變。

對(duì)此,David Nolen 提出了基于不可變數(shù)據(jù)結(jié)構(gòu)(Immutable Data Structure)的解決方案。
該方案的靈感來(lái)自于 ClojureScript ,在 ClojureScript 中,大部分的值都是不可變的。換句話說(shuō)就是,當(dāng)需要更新一個(gè)值時(shí),程序不是去修改原來(lái)的值,而是基于原來(lái)的值創(chuàng)建一個(gè)新值,然后使用新值進(jìn)行賦值。

David 使用 ClojureScript 寫了一個(gè)針對(duì) React 的不可變數(shù)據(jù)結(jié)構(gòu)方案:Om ,為 shouldComponentUpdate 提供了默認(rèn)實(shí)現(xiàn)。

不過,由于不可變數(shù)據(jù)結(jié)構(gòu)并未被 Web 工程師廣為接受,所以當(dāng)時(shí)并未把這項(xiàng)功能合并進(jìn) React 。
遺憾的是,截止到目前,shouldComponentUpdate 也仍然未提供默認(rèn)實(shí)現(xiàn)。
但是 David 卻為廣大開發(fā)者開啟了一個(gè)很好的研究方向。

如果真想利用不可變數(shù)據(jù)結(jié)構(gòu)來(lái)提高 React 性能,可以參考與 React 師出同門的 Facebook Immutable.js,它是 React 好搭檔!

結(jié)束語(yǔ)

React 的優(yōu)化仍在繼續(xù),比如 React 16 中新引入 Fiber,它是對(duì)核心算法的一次重構(gòu),即重新設(shè)計(jì)了檢測(cè)變更的方法和時(shí)機(jī),允許渲染過程可以分段完成,而不必一次性完成。
受篇幅限制,本文不會(huì)深入介紹 Fiber ,有興趣的可以參考 React Fiber是什么 。

最后,感謝 Facebook 給開源社區(qū)帶來(lái)了如此優(yōu)秀的項(xiàng)目!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/107612.html

相關(guān)文章

  • [到codewars打怪獸]利潤(rùn)怎樣成的

    摘要:利潤(rùn)是怎樣煉成的怪獸的屬性怪獸的技能大木博士的圖鑒你是趙老爺家的算帳二狗子,趙家老爺想要學(xué)習(xí)一些理財(cái)知識(shí),就去詢問孔乙己。 [7 kyu]Money, Money, Money 利潤(rùn)是怎樣煉成的??2016.03.15 怪獸的屬性: showImg(http://ww2.sinaimg.cn/large/006m2mhTgw1f1xxc38fbqj30qa0s2q6f.jpg);sho...

    zhangyucha0 評(píng)論0 收藏0
  • 年薪50w+的軟件測(cè)試工程師怎么成的

    摘要:它讓傳統(tǒng)的測(cè)試工程師從簡(jiǎn)單,重復(fù),低效可替代性強(qiáng)的手工測(cè)試,變成了有技術(shù)難度和門檻的測(cè)試開發(fā)工作,也讓我們有更多的機(jī)會(huì)拿到更高的薪資。 隨著互聯(lián)網(wǎng)行業(yè)的迅速發(fā)展,軟件測(cè)試工程師的地位越來(lái)越高,公司招聘時(shí)的薪資也越來(lái)越高,那么市場(chǎng)上為什么還有大量的軟件測(cè)試工程師薪資只有5-6k呢?因?yàn)樗麄冇幸?..

    laznrbfe 評(píng)論0 收藏0
  • 一場(chǎng)穩(wěn)定、高清、流暢的大型活動(dòng)直播怎么成的

    摘要:據(jù)悉,高清直播已在阿里云的眾多游戲直播客戶中廣泛使用。這也是阿里云視頻云第四年支持雙貓晚網(wǎng)絡(luò)直播,從作戰(zhàn)室監(jiān)控的數(shù)據(jù)上來(lái)看,貓晚直播期間各項(xiàng)系統(tǒng)數(shù)據(jù)指標(biāo)運(yùn)轉(zhuǎn)平穩(wěn),一場(chǎng)穩(wěn)定高清流暢的大型活動(dòng)直播就就此實(shí)現(xiàn)。 雙11貓晚是家喻戶曉的綜藝晚會(huì),在今年的雙11,阿里集團(tuán)為2500萬(wàn)用戶提供了一場(chǎng)在線直播視覺盛宴。網(wǎng)友評(píng)價(jià)這是一場(chǎng)既穩(wěn)定流暢又高清的直播,當(dāng)然在這背后離不開阿里云的技術(shù)支持。 本次...

    mist14 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<