国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Webkit 渲染基礎與硬件加速

ivan_qhz / 2765人閱讀

摘要:網頁的渲染方式主要有兩種軟件渲染和硬件加速渲染。而使用合成化的渲染技術,以使用軟件繪圖的合成化渲染為例,對于使用繪制的層,其結果保存在內存中,之后傳輸到中進行合成。

Webkit 渲染基礎與硬件加速

當瀏覽器加載一個 html 文件并對它進行解析完畢后,內核就會生成一個極為重要的數據結構即 DOM 樹,樹上每一個節點都對應著網頁里面的某一個元素,并且開發人員也可以通過 JavaScript 操作這棵 DOM 樹動態改變它的結構,但是 DOM 樹本身并不能直接用于排版和渲染。

瀏覽器中頁面的渲染過程可以簡化為以下五個步驟:

從 DOM 到 RenderObject

在 DOM 樹構建完成之后,Webkit 所要做的事情就是為 DOM 樹節點構建 RenderObject 樹,一個 RenderObject 對象保存為繪制 DOM 節點所需要的各種信息,從以下這些規則出發會為 DOM 樹節點創建 RenderObject 對象:

DOM 樹的 document 節點

DOM 樹中的可視節點

某些情況下 Webkit 需要建立匿名的 RenderObject 節點,這樣的節點不對應于 DOM 樹中的任何節點,而是 Webkit 處理上的需要,典型的例子就是匿名用于表示塊元素的 RenderBlock 節點

雖然 Javascript 無法訪問影子節點,但是需要為其創建并渲染 RenderObject

Tip:由此可見,網上有人說瀏覽器渲染的步驟中包含“將 DOM 樹和 CSSOM 樹合并為 Render 樹”的說法是有些問題的。CSSOM(CSS 對象模型)是用于提供方法可以讓開發者自定義一些腳本來操作其樣式狀態的,它的思想是在 DOM 中的一些節點接口中加入獲取和操作 CSS 屬性或者接口的 Javascript 接口,便于 Javascript 可以動態操作 CSS 樣式。

由此我們可以知道 RenderObject 樹和 DOM 樹不是一一對應的!我們可以簡單的認為,RenderObject 是銜接瀏覽器排版引擎和渲染引擎之間的橋梁,它是排版引擎的輸出和渲染引擎的輸入。當 Webkit 創建 RenderObject 對象之后,每個對象是不知道自己的位置、大小等信息的,Webkit 根據框模型來計算它們的位置、大小等信息的過程稱為布局計算

Tip:從整個網頁的加載和渲染過程來看,CSS 解釋器和規則匹配處于 DOM 樹建立之后,RenderObject 樹建立之前,CSS 解釋器解釋后的結果會保存起來,然后 RenderObject 樹基于該結果來進行規范匹配和布局計算。

既然已經實現繪制每個 DOM 節點的方法,那是不是可以開辟一段位圖空間,然后 DFS 遍歷這個 RenderObject 樹執行繪制方法,就像“蓋章”一樣把每個 RenderObject 的內容一個個的蓋到“畫布上”,是不是就足夠完成繪制?

如果沒有層疊上下文,到這兒就可以結束了!

實際上是如果沒有 Positioning,Clipping,Overflow Scroll,CSS Transform/Opacity/Animation/Filter,Mask or Reflection,Z Indexing etc. 到這兒就可以結束了……

從 RenderObject 到 RenderLayer

Webkit 會為網頁的層次創建相應的 RenderLayer 對象,當某些類型的 RenderObject 的節點或者具有某些 CSS 樣式的 RenderObject 節點出現的時候,Webkit 就會為這些節點創建 RenderLayer 對象,一般來說某個 RenderObject 節點的后代都屬于該節點的 RenderLayer,除非 Webkit 根據規則為某個后代 RenderObject 節點創建一個新的 RenderLayer 對象,以下是 RenderObject 節點需要建立新的 RenderLayer 節點的規則:

DOM 樹的 document 節點對應的 RenderView 節點

DOM 樹中 document 的子女節點,即 html 節點對應的 RenderBlock 節點

顯示指定 CSS 位置的 RendrObject 節點

有透明效果的 RenderObject 節點

節點有溢出(overflow)、alpha 或者反射等效果的 RenderObject 節點

適用 canvas 2d 或者 3d(WebGL)技術的 RenderObject 節點

video 節點對應的 RenderObject 節點

由此我們可以知道,RenderLayer 節點和 RenderObject 節點不是一一對應的,而是一對多的關系。

具體來說,根據創建 RenderLayer 的原因不同可以將其分為常見的 3 類:

NormalPaintLayer

根元素(html)

有明確的定位屬性(relative、fixed、sticky、absolute)

透明的(opacity 小于 1)

有 CSS 濾鏡(fliter)

有 CSS mask 屬性

有 CSS mix-blend-mode 屬性(不為 normal)

有 CSS transform 屬性(不為 none)

backface-visibility 屬性為 hidden

有 CSS reflection 屬性

有 CSS column-count 屬性(不為 auto)

有 CSS column-width 屬性(不為 auto)

當前有對于 opacity、transform、fliter、backdrop-filter 的應用動畫

OverflowClipPaintLayer

overflow 不為 visible

NoPaintLayer

不需要 paint 的 RenderLayer:比如一個沒有視覺屬性(背景、顏色、陰影等)的空 div

上文中講解的從 DOM 到 RenderObject 以及從 RenderObject 到 RenderLayer 可以歸納如下圖:

軟件渲染和硬件加速渲染

在 Webkit 中繪圖操作被定義為一個抽象層即繪圖上下文,所有繪圖操作都是在該上下文中進行,可以分為兩種類型:2d 圖形上下文和 3d 圖形上下文。其中 2d 圖形上下文的具體作用就是提供基本繪圖單元的繪制接口以及設置繪圖的樣式,繪圖接口包括畫點、畫線、畫圖片、畫多邊形、畫文字 etc.,繪圖樣式包括顏色、線寬、字號大小、漸變 etc.,而RenderObject 對象知道自己需要畫什么樣的點,什么樣的圖片。3d 繪圖上下文的主要用處是支持 CSS3D、WebGL etc.。

網頁的渲染方式主要有兩種:軟件渲染和硬件加速渲染。每個 RenderLyaer 對象都可以被想象成一個層,各個層一同構成一個圖像,在渲染過程中,每個層對應網頁中的一個或者一些可視元素,這些元素都繪制內容到該層上,如果這些繪圖操作由 CPU 萊完成則稱之為軟件繪圖,如果這些繪圖操作由 GPU 來完成則稱之為硬件加速繪圖。理想情況下,每個層都有繪制的存儲區域來保存繪圖的結果,最后需要將這些層的內容合并到同一個圖像中的過程稱為合成(compositing),使用合成技術的渲染叫做合成化渲染

對于軟件渲染機制,Webkit 需要使用 CPU 來繪制每層的內容,然而該機制是沒有合成階段的:在軟件渲染中通常其結果就是一個位圖(Bitmap),繪制每一層時都使用同一個位圖,區別在于繪制的位置看你不一樣,每一層都按照從后到前的順序。而使用合成化的渲染技術,以使用軟件繪圖的合成化渲染為例,對于使用 CPU 繪制的層,其結果保存在 CPU 內存中,之后傳輸到 GPU 中進行合成。

對于常見的 2d 繪圖操作,使用 GPU 來繪圖不一定比使用 CPU 繪圖在性能上有優勢,原因是 CPU 使用緩存機制有效減少重復繪制得開銷,而且不需要 GPU 的并行,并且 GPU 的內存資源相對 CPU 的內存資源更加緊張。
什么是位圖

在繪制出一個圖片我們應該怎么做,顯然首先是把這個圖片表示為一種計算機能理解的數據結構:用一個二維數組,數組的每個元素記錄這個圖片中的每一個像素的具體顏色。所以瀏覽器可以用位圖來記錄它想在某個區域繪制的內容,繪制的過程也就是往數組中具體的下標里填寫像素而已。

什么是紋理

紋理其實就是 GPU 中的位圖,存儲在 GPU video RAM 中。前面說的位圖里的元素存什么我們自己定義好就行(是用3字節存256位rgb還是1個bit存黑白自己定義即可),但紋理是 GPU 專用的,需要有固定格式便于兼容與處理,所以一方面紋理的格式比較固定,如 R5G6B5、A4R4G4B4 等像素格式, 另外一方面 GPU 對紋理的大小有限制,比如長/寬必須是2的冪次方,最大不能超過2048或者4096等。

什么是光柵化

在紋理里填充像素不是那么簡單的自己去遍歷位圖里的每個元素然后填寫這個像素的顏色即可,光柵化的本質是坐標變換、幾何離散化,然后再填充

同時,光柵化從早期的 Full-screen Rasterization 基本都進化到現在的 Tile-Based Rasterization,也就是不對整個圖像做光柵化,而是把圖像分塊后再對每個 tile 多帶帶光柵化。光柵化完成后將像素填充進紋理,再將紋理上傳至 GPU,
原因一方面如上文所說,紋理大小有限制,即使整屏光柵化也是要填進小塊小塊的紋理中,不如事先根據紋理大小分塊光柵化后再填充進紋理里;另一方面是為了減少內存占用(整屏光柵化意味著需要準備更大的buffer空間)和降低總體延遲(分塊柵格化意味著可以多線程并行處理)。

每秒60幀的動效里,每次變動都重繪整個位圖是很恐怖的性能開銷!
非合成加速的渲染架構,所有的 RenderLayer 都沒有自己獨立的緩存,它們都按照先后順序被繪制到同一個緩存里面,所以只要這個 RenderLayer 觸發重繪,變化區域的緩存就需要重新生成,此時不但需要繪制發生變化的 RenderLayer,跟變化區域(Damage Region)相交的其它 RenderLayer 也需要被繪制。

瀏覽器本身并不能直接改變屏幕的像素輸出,它需要通過系統本身的 GUI Toolkit,所以一般來說瀏覽器會將一個要顯示的網頁包裝成一個 UI 組件,通常叫做 WebView,然后通過將 WebView 放置于應用的 UI 界面上,從而將網頁顯示在屏幕上。

默認的情況下 UI 組件沒有自己獨立的位圖緩存,構成 UI 界面的所有 UI 組件都直接繪制在當前的窗口緩存上,所以 WebView 每次繪制就相當于將它在可見區域內的 RenderLayer/RenderObject 逐個繪制到窗口緩存上。上述的渲染方式有一個很嚴重的問題,用戶拖動網頁或者觸發一個慣性滾動時,網頁滑動的渲染性能會十分糟糕:這是因為即使網頁只移動一個像素,整個 WebView 都需要重新繪制。

要提升網頁滑屏的性能,一個簡單的做法就是讓 WebView 本身持有一塊獨立的緩存,而 WebView 的繪制就分成了兩步: 1) 根據需要更新內部緩存,將網頁內容繪制到內部緩存里面 2) 將內部緩存拷貝到窗口緩存上。第一步我們通常稱為繪制(Paint)或者光柵化(Rasterization),它將一些繪圖指令轉換成真正的像素顏色值,而第二步我們一般稱為合成(Composite),它負責緩存的拷貝,同時還可能包括位移(Translation),縮放(Scale),旋轉(Rotation),Alpha 混合等操作。

從 RenderLayer 到 GraphicsLayer

在現實情況中,由于硬件能力和資源有限,為了節省 GPU 的內存資源,硬件加速機制在 RenderLayer 樹建立之后需要做三件事情來完成網頁的渲染:

Webkit 決定將哪些 RendeLayer 對象組合在一起,形成一個由后端存儲(一般指 GPU 內存)的新層,對于一個 RenderLayer 對象來說,如果它沒有后端存儲的新層,那么就使用其父親所使用的合成層

將每個合成層包含的 RenderLayer 內容繪制在其后端存儲中,這里的繪制可以是軟件繪制,也可以是硬件加速繪制

由合成器將多個合成層合成起來,形成網頁的最終可視化結果(實際就是一張圖片)

一個 RenderLayer 對象如果需要后端存儲,它會創建一個 RenderLayerBacking 對象,負責 RenderLayer 對象所需要的各種存儲,每個 RenderLayer 對象都可以創建自己的后端存儲,然而不是所有 RenderLayer 對象都有自己的 RenderLayerBacking,如果一個 RenderLayer 對象被 Webkit 按照一定的規則創建后端存儲,那么該層被稱為合成層,后端存儲可能需要管理多個存儲空間,使用 GraphicsLayer 類來表示。

每個 GraphicsLayer 都擁有一個 GraphicsContext,用于為該 GraphicsLayer 開辟一段位圖,也就意味著每個 GraphicsLayer 都擁有一個獨立的位圖,GraphicsLayer 負責將自己的 RenderLayer 及其所包含的 RenderObject 繪制到位圖里,然后將位圖作為紋理交給 GPU 進行合成。如果一個 RenderLayer 對象具有以下特征之一,那么它就是合成層:

RenderLayer 具有 CSS3D 屬性或者 CSS 透視效果

RenderLayer 包含 video 節點對應的 RenderObject 節點

RenderLayer 包含使用 canvas 2d 或者 3d(WebGL)技術的 RenderObject 節點

RenderLayer 使用 CSS 透明效果的動畫或者 CSS 變換動畫

RenderLayer 使用硬件加速的 CSS Filters 技術

RenderLayer 使用裁剪或者反射屬性,并且其后代包含合成層

RenderLayer 有一個 Z 坐標比自己小的兄弟節點,且該兄弟節點是一個合成層

直接原因

硬件加速的 iframe 元素(比如 iframe 嵌入的頁面中有合成層)

video 元素

覆蓋在 video 元素上的視頻控制欄

3D 或者 硬件加速的 2D Canvas 元素

硬件加速的插件:比如 flash etc.

在 DPI 較高的屏幕上 fix 定位的元素會自動地被提升到合成層中;但在 DPI 較低的設備上卻并非如此:因為這個渲染層的提升會使得字體渲染方式由子像素變為灰階

有 3D transform

backface-visibility 為 hidden

對 opacity、transform、fliter、backdropfilter 應用 animation 或者 transition(需要是 active 的 animation 或者 transition,當 animation 或者 transition 效果未開始或結束后,提升合成層也會失效)

will-change 設置為 opacity、transform、top、left、bottom、right(其中 top、left 等需要設置明確的定位屬性:比如 relative etc.)

后代元素原因

有合成層后代同時本身有 transform、opactiy(小于 1)、mask、fliter、reflection 屬性

有合成層后代同時本身 overflow 不為 visible(如果本身是因為明確的定位因素產生的 SelfPaintingLayer,則需要 z-index 不為 auto)

有合成層后代同時本身 fixed 定位

有 3D transfrom 的合成層后代同時本身有 preserves-3d 屬性

有 3D transfrom 的合成層后代同時本身有 perspective 屬性

重疊原因

重疊或者說部分重疊在一個合成層之上,最常見和容易理解的就是元素的 border box(content + padding + border) 和合成層的有重疊,其他的還有一些不常見的情況,也算是同合成層重疊的條件如下:

filter 效果同合成層重疊

transform 變換后同合成層重疊

overflow scroll 情況下同合成層重疊

假設重疊在一個合成層之上,其實也比較好理解,比如一個元素的 CSS 動畫效果在運行期間,元素有可能和其他元素發生重疊的情況,需要注意的是該原因下,有一個很特殊的情況:如果合成層有內聯的 transform 屬性,會導致其兄弟渲染層假設重疊從而提升為合成層。

基本上常見的一些合成層的提升原因如上所說,我們會發現:由于重疊的原因可能隨隨便便就會產生出大量合成層來,而每個合成層都要消耗 CPU 和內存資源,豈不是嚴重影響頁面性能?!

層壓縮

這一點瀏覽器也考慮到,因此就有層壓縮(Layer Squashing)的處理。如果多個渲染層同一個合成層重疊時,這些渲染層會被壓縮到一個 GraphicsLayer 中,以防止由于重疊原因導致可能出現的“層爆炸”。

當然,瀏覽器的自動層壓縮也不是萬能的,在很多特定情況下,瀏覽器是無法進行層壓縮的,而這些情況也是我們應該盡量避免的(以下情況都是基于重疊原因而言):

無法進行會打破渲染順序的壓縮

video 元素的渲染層無法被壓縮,同時也無法將別的渲染層壓縮到 video 所在的合成層上

iframe、plugin 的渲染層無法被壓縮,同時也無法將別的渲染層壓縮到其所在的合成層上

無法壓縮有 reflection 屬性的渲染層

無法壓縮有 blend mode 屬性的渲染層

當渲染層同合成層有不同的裁剪容器時,該渲染層無法壓縮

相對于合成層滾動的渲染層無法被壓縮

當渲染層同合成層有不同的具有 opacity 的祖先層(一個設置 opacity 且小于 1 一個沒有設置 opacity 也算是不同)時,該渲染層無法壓縮

當渲染層同合成層有不同的具有 transform 的祖先層時,該渲染層無法壓縮

當渲染層同合成層有不同的具有 filter 的祖先層時,該渲染層無法壓縮

當覆蓋的合成層正在運行動畫時,該渲染層無法壓縮,只有在動畫未開始或者運行完畢以后,該渲染層才可以被壓縮

多線程

進一步來說,瀏覽器還可以使用多線程的渲染架構,將網頁內容繪制到緩存的操作放到另外一個獨立的線程(繪制線程),而原來線程對 WebView 的繪制就只剩下緩存的拷貝(合成線程),繪制線程跟合成線程之間可以使用同步,部分同步,完全異步等作業模式,讓瀏覽器可以在性能與效果之間根據需要進行選擇。

Main thread or WebKit/Blink thread

內核線程 - 負責解析,排版,Render 樹繪制,JavaScript 執行等任務,它有可能執行真正的網頁內容的光柵化,也有可能只是紀錄繪制指令,由獨立的光柵化線程執行

Rasterize thread

光柵化線程 - 如果內核線程只負責將網頁內容轉換為繪圖指令列表,則真正的光柵化(執行繪圖指令計算出像素的顏色值)由獨立的光柵化線程完成

Compositor thread

合成線程 - 負責將網頁內部位圖緩存/紋理輸出到窗口的幀緩存,從而把網頁顯示在屏幕上,但是在使用 GPU 合成的情況下,也有可能只是產生 GL 繪圖指令,然后將繪圖指令的緩存發送給 GPU 線程執行

GPU thread

GPU 線程 - 如果使用 GPU 合成,則由 GPU 線程負責執行 GL 繪圖指令,訪問 GPU,可能跟合成線程是同一個線程,也有可能是獨立的線程(合成線程產生GL指令 GPU 線程執行)

Browser UI thread

瀏覽器 UI 線程,如果跟 GPU 線程不是同一個線程,則只負責外殼的繪制,如果跟 GPU 線程是同一個線程,則同時負責繪制外殼的UI界面,和網頁的合成輸出,到窗口幀緩存

重排&重繪

重排和重繪是老生常談的東西,大家也應該非常熟悉,但在這里可以結合瀏覽器機制順帶講一遍。

重排

首先,如果你改變一個影響元素布局信息的 CSS 樣式:比如 width、height、left、top etc.(transform除外),那么瀏覽器會將當前的 Layout 標記為 dirty,這會使得瀏覽器在下一幀執行重排,因為元素的位置信息發生改變將可能會導致整個網頁其他元素的位置情況都發生改變,所以需要執行 Layout 全局重新計算每個元素的位置。

需要注意到,瀏覽器是在下一幀、下一次渲染的時候才重排,并不是 JS 執行完這一行改變樣式的語句之后立即重排,所以你可以在 JS 語句里寫 100 行修改 CSS 的語句,但是只會在下一幀的時候重排一次。

會觸發重排的屬性和方法如下:

Element

clientHeight, clientWidth, clientTop, clientLeft, focus(), getBoundingClientRect(), getClientRects(), innerText, offsetHeight, offsetLeft, OffsetParent, offsetTop, offsetWidth, outerText, scrollByLines(), scrollByPages(), scrollHeight, scrollIntoView(), scrollIntoViewIfNeeded(), scrollLeft, scrollTop, scrollWidth

Frame, Image

height, width

Range

getBoundingClientRect(), getClientRects()

SVGLocatable

computeCTM(), getBBox()

SVGTextContent

getCharNumAtPosition(), getComputedTextLength(), getEndPositionOfChar(), getExtentOfChar(), getNumberOfChars(), getRotationOfChar(), getStartPositionOfChar(), getSubStringLength(), selectSubString()

SVGUse

instanceRoot

window

getComputedStyle(), scrollBy(), scrollTo(), scrollX, scrollY, webkitConvertPointFromNodeToPage(), webkitConvertPointFromPageToNode()

強制重排

如果你在當前 Layout 被標記為 dirty 的情況下訪問 offsetTop、scrollHeight 等屬性,那么瀏覽器會立即重新 Layout,計算出此時元素正確的位置信息,以保證你在 JS 里獲取到的 offsetTop、scrollHeight 等是正確的。

這一過程被稱為強制重排 Force Layout,強制瀏覽器將本來在渲染流程中才執行的 Layout 過程提前至 JS 執行過程中,每次當我們在 Layout 為 dirty 時訪問會觸發重排的屬性都會 Force Layout,這會極大延緩 JS 的執行效率

另外,每次重排或者強制重排后,當前 Layout 就不再 dirty,這時再訪問 offsetWidth 之類的屬性并不會再觸發重排。

重繪

重繪也是相似的,一旦你更改某個元素的會觸發重繪的樣式,那么瀏覽器就會在下一幀的渲染步驟中進行重繪(也即一些介紹重繪機制中說的 invalidating),JS 更改樣式導致某一片區域的樣式作廢,從而在一下幀中重繪 invalidating 的區域。

但是!有一個非常關鍵的行為就是:重繪是以合成層為單位的,也即 invalidating 的既不是整個文檔也不是單個元素,而是這個元素所在的合成層。當然這也是將渲染過程拆分為 Paint 和 Compositing 的初衷之一:

Since painting of the layers is decoupled from compositing, invalidating one of these layers only results in repainting the contents of that layer alone and recompositing.
使用 transform 或者 opacity 來實現動畫效果

修改一些 CSS 屬性如 width、float、border、position、font-size、text-align、overflow-y etc. 會觸發重排、重繪和合成,修改另一些屬性如 color、background-color、visibility、text-decoration etc. 則不會觸發重排,只會重繪和合成。

接下來很多文章里就會說,修改 opacity、transform 這兩個屬性僅僅會觸發合成,不會觸發重繪,所以一定要用這兩個屬性來實現動畫,沒有重繪重排,效率很高……然而事實并不是這樣,只有一個元素在被提升為合成層之后,上述情況才成立
最后一句話:合成層提升并非銀彈!

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/93297.html

相關文章

  • 瀏覽器之硬件加速機制

    摘要:書接上文瀏覽器內核之渲染基礎硬件加速基礎概念硬件加速技術是指使用的硬件能力為幫助渲染網頁,在為的作用主要是用來繪制圖形并且性能特別好。包含的節點表示的是使用硬件加速的元素或者技術。 showImg(https://segmentfault.com/img/remote/1460000016348971); 微信公眾號:愛寫bugger的阿拉斯加如有問題或建議,請后臺留言,我會盡力解決你...

    mengera88 評論0 收藏0
  • 瀏覽器內核之WebKit 架構模塊

    摘要:多線程的主要目的就是為了保持用戶界面的高響應度,保證線程進程中的主線程不會被任何其他費用時的操作阻礙從而影響了對用戶操作的響應。 showImg(https://segmentfault.com/img/remote/1460000016113034); 微信公眾號:愛寫bugger的阿拉斯加如有問題或建議,請后臺留言,我會盡力解決你的問題。 前言 此文章是我最近在看的【WebKit ...

    The question 評論0 收藏0
  • 面試的信心來源于過硬的基礎

    摘要:避免在頁面的主體布局中使用,要等其中的內容完全下載之后才會顯示出來,顯示比布局慢。實現多行文本溢出顯示效果實現方法適用范圍因使用了的擴展屬性,該方法適用于瀏覽器及移動端 在過去的一年很多人不滿于公司沒有福利、人際關系不好相處、沒有發展前途的境遇等等,想著在開年來換一份工作來重新開始自己,那么 你 準備好了嗎? 下面是本人整理的一份面試材料,本想自己用的,但是新年第一天 公司突然給了我個...

    Ashin 評論0 收藏0
  • 面試的信心來源于過硬的基礎

    摘要:避免在頁面的主體布局中使用,要等其中的內容完全下載之后才會顯示出來,顯示比布局慢。實現多行文本溢出顯示效果實現方法適用范圍因使用了的擴展屬性,該方法適用于瀏覽器及移動端 在過去的一年很多人不滿于公司沒有福利、人際關系不好相處、沒有發展前途的境遇等等,想著在開年來換一份工作來重新開始自己,那么 你 準備好了嗎? 下面是本人整理的一份面試材料,本想自己用的,但是新年第一天 公司突然給了我個...

    ISherry 評論0 收藏0

發表評論

0條評論

ivan_qhz

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<