HTTP車是由蒂姆·伯納斯-李( TimBerners—Lee )于1989年在歐洲核子研究組織( CERN )所發起
其中最著名的是 1999 年 6 月公布的 RFC 2616 ,定義了 HTTP 協議中現今廣泛使用的一個版本—— HTTP 1.1
全稱:超文本傳輸協議( HyperText Transfer Protocol )
概念: HTTP 是一種能夠獲取像 HTML 、圖片等網絡資源的通訊協議( protocol )。它是在 web 上進行數據交換的基礎,是一種 client-server 協議
HTTP ——因特網的多媒體信使 ——《HTTP權威指南》。 HTTP 在因特網的角色:充當一個信使的角色,干的就是一個跑腿的活,在客戶端和服務端之間傳遞信息,但我們又不能缺少它。 HTTP 協議是應用層的協議,是與前端開發最息息相關的協議。平時我們遇到的 HTTP 請求、 HTTP 緩存、 Cookies 、跨域等其實都跟 HTTP 息息相關
也就是說, HTTP 依賴于面向連接的 TCP 進行消息傳遞,但連接并不是必須的。只需要它是可靠的,或不丟失消息的(至少返回錯誤)。
HTTP/1.0 默認為每一對 HTTP 請求/響應都打開一個單獨的 TCP 連接。當需要連續發起多個請求時,這種模式比多個請求共享同一個 TCP 鏈接更低效。為此, HTTP 1.1 持久連接的概念,底層 TCP 連接可以通過 connection 頭部實現。但 HTTP 1.1 在連接上也是不完美的,后面我們會提到。
HTTP 的組件系統包括客戶端、 web 服務器和代理
瀏覽器,特殊比如是工程師使用的程序,以及 Web 開發人員調試應用程序
由 Web Server 來服務并提供客戶端所請求的文檔。每一個發送到服務器的請求,都會被服務器處理并返回一個消息,也就是 response
在瀏覽器和服務器之間,有很多計算機和其他設備轉發了 HTTP 消息。它們可能出現在傳輸層、網絡層和物理層上,對于 HTTP 應用層而言就是透明的
有如下的一些作用
HTTP 有兩種類型的消息:
HTTP 消息由采用 ASCII 編碼的多行文本構成的。在 HTTP/1.1 以及更早的版本中,這些消息通過連接公開的發送。在 HTTP2.0 中,消息被分到了多個 HTTP 幀中。通過配置文件(用于代理服務器或者服務器), API (用于瀏覽器)或者其他接口提供 HTTP 消息
HTTP 請求和響應都包括起始行( start line )、請求頭( HTTP Headers )、空行( empty line )以及 body 部分,如下圖所示:
下面詳細說下請求 Path ,請求路徑( Path )有以下幾種:
1)一個絕對路徑,末尾跟上一個 ' ? ' 和查詢字符串。這是最常見的形式,稱為 原始形式 ( origin form ),被 GET , POST , HEAD 和 OPTIONS 方法所使用
POST / HTTP/1.1
GET /background.png HTTP/1.0
HEAD /test.html?query=alibaba HTTP/1.1
OPTIONS /anypage.html HTTP/1.0
復制代碼
2)一個完整的 URL 。主要在使用 GET 方法連接到代理的時候使用
GET http://developer.mozilla.org/en-US/docs/Web/HTTP/Messages HTTP/1.1
復制代碼
3)由域名和可選端口(以':'為前綴)組成的 URL 的 authority component ,稱為 authority form 。僅在使用 CONNECT 建立 HTTP 隧道時才使用
CONNECT developer.mozilla.org:80 HTTP/1.1
復制代碼
4)星號形式 ( asterisk form ),一個簡單的星號('*'),配合 OPTIONS 方法使用,代表整個服務器。
OPTIONS * HTTP/1.1
復制代碼
請求 Body 部分: 有些請求將數據發送到服務器以便更新數據:常見的的情況是 POST 請求(包含 HTML 表單數據)。請求報文的 Body 一般為兩類。一類是通過 Content-Type 和 Content-Length 定義的單文件 body 。另外一類是由多 Body 組成,通常是和 HTML Form 聯系在一起的。兩者的不同表現在于 Content-Type 的值。
1) Content-Type —— application/x-www-form-urlencoded 對于 application/x-www-form-urlencoded 格式的表單內容,有以下特點:
I.其中的數據會被編碼成以&分隔的鍵值對
II.字符以URL編碼方式編碼。
// 轉換過程: {a: 1, b: 2} -> a=1&b=2 -> 如下(最終形式)
"a%3D1%26b%3D2"
復制代碼
2) Content-Type —— multipart/form-data
請求頭中的 Content-Type 字段會包含 boundary ,且 boundary 的值有瀏覽器默認指定。例: Content-Type: multipart/form-data;boundary=----WebkitFormBoundaryRRJKeWfHPGrS4LKe 。
數據會分為多個部分,每兩個部分之間通過分隔符來分隔,每部分表述均有 HTTP 頭部描述子包體,如 Content-Type ,在最后的分隔符會加上--表示結束。
Content-Disposition: form-data;name="data1";
Content-Type: text/plain
data1
----WebkitFormBoundaryRRJKeWfHPGrS4LKe
Content-Disposition: form-data;name="data2";
Content-Type: text/plain
data2
----WebkitFormBoundaryRRJKeWfHPGrS4LKe--
復制代碼
響應 Body 部分:
1)由已知長度的單個文件組成。該類型 body 有兩個 header 定義: Content-Type 和 Content-Length
2)由未知長度的單個文件組成,通過將 Transfer-Encoding 設置為 chunked 來使用 chunks 編碼。
關于 Content-Length 在下面 HTTP 1.0 中會提到,這個是 HTTP 1.0 中新增的非常重要的頭部。
安全方法: HTTP 定義了一組被稱為安全方法的方法。 GET 方法和 HEAD 方法都被認為是安全的,這意味著 GET 方法和 HEAD 方法都不會產生什么動作 —— HTTP 請求不會再服務端產生什么結果,但這并不意味著什么動作都沒發生,其實這更多的是 web 開發者決定的
首先要了解下副作用和冪等的概念,副作用指的是對服務器端資源做修改。冪等指發送 M 和 N 次請求(兩者不相同且都大于 1),服務器上資源的狀態一致。應用場景上,get是無副作用的,冪等的。post 主要是有副作用的,不冪等的情況
技術上有以下的區分:
HTTP Headers
1.通用首部( General headers )同時適用于請求和響應消息,但與最終消息主體中傳輸的數據無關的消息頭。如 Date
2.請求首部( Request headers )包含更多有關要獲取的資源或客戶端本身信息的消息頭。如 User-Agent
3.響應首部( Response headers )包含有關響應的補充信息
4.實體首部( Entity headers )含有關實體主體的更多信息,比如主體長( Content-Length )度或其 MIME 類型。如 Accept-Ranges
詳細的 Header 見 HTTP Headers 集合
HTTP(HyperText Transfer Protocol) 是萬維網( World Wide Web )的基礎協議。 Tim Berners-Lee 博士和他的團隊在 1989-1991 年間創造出它?!綡TTP、網絡瀏覽器、服務器】
在 1991 年發布了 HTTP 0.9 版,在 1996 年發布 1.0 版,1997 年是 1.1 版,1.1 版也是到今天為止傳輸最廣泛的版本。2015 年發布了 2.0 版,其極大的優化了 HTTP/1.1 的性能和安全性,而 2018 年發布的 3.0 版,繼續優化 HTTP/2 ,激進地使用 UDP 取代 TCP 協議,目前, HTTP/3 在 2019 年 9 月 26 日 被 Chrome , Firefox ,和 Cloudflare 支持
單行協議,請求由單行指令構成。以唯一可用的方法 GET 開頭。后面跟的是目標資源的路徑
GET /mypage.html
復制代碼
響應:只包括響應文檔本身
<HTML>
這是一個非常簡單的HTML頁面
</HTML>
復制代碼
HTML
RFC 1945 提出了 HTTP1.0 , 構建更好可拓展性
媒體類型是一種標準。用來表示文檔、文件或者字節流的性質和格式。瀏覽器通常使用 MIME ( Multipurpose Internet Mail Extensions )類型來確定如何處理 URL ,因此 Web 服務器在響應頭中配置正確的 MIME 類型會非常的重要。如果配置不正確,可能會導致網站無法正常的工作。 MIME 的組成結構非常簡單;由類型與子類型兩個字符串中間用'/'分隔而組成。
HTTP 從 MIME type 取了一部分來標記報文 body 部分的數據類型,這些類型體現在 Content-Type 這個字段,當然這是針對于發送端而言,接收端想要收到特定類型的數據,也可以用 Accept 字段。
這兩個字段的取值可以分為下面幾類:
- text: text/html, text/plain, text/css 等
- image: image/gif, image/jpeg, image/png 等
- audio/video: audio/mpeg, video/mp4 等
- application: application/json, application/javascript, application/pdf, application/octet-stream
復制代碼
同時為了約定請求的數據和響應數據的壓縮方式、支持語言、字符集等,還提出了以下的 Header
1.壓縮方式:發送端: Content-Encoding (服務端告知客戶端,服務器對實體的主體部分的編碼方式) 和 接收端: Accept-Encoding (用戶代理支持的編碼方式),值有 gzip: 當今最流行的壓縮格式;deflate: 另外一種著名的壓縮格式;br: 一種專門為 HTTP 發明的壓縮算法
2.支持語言: Content-Language 和 Accept-Language (用戶代理支持的自然語言集)
3.字符集:發送端: Content-Type 中,以 charset 屬性指定。接收端: Accept-Charset (用戶代理支持的字符集)。
// 發送端
Content-Encoding: gzip
Content-Language: zh-CN, zh, en
Content-Type: text/html; charset=utf-8
// 接收端
Accept-Encoding: gzip
Accept-Language: zh-CN, zh, en
Accept-Charset: charset=utf-8
復制代碼
雖然 HTTP1.0 在 HTTP 0.9 的基礎上改進了很多,但還是存在這不少的缺點
HTTP/1.0 版的主要缺點是,每個 TCP 連接只能發送一個請求。發送數據完畢,連接就關閉,如果還要請求其他資源,就必須再新建一個連接。 TCP 連接的新建成本很高,因為需要客戶端和服務器三次握手,并且開始時發送速率較慢( slow start )。
HTTP 最早期的模型,也是 HTTP/1.0 的默認模型,是短連接。每一個 HTTP 請求都由它自己獨立的連接完成;這意味著發起每一個 HTTP 請求之前都會有一次 TCP 握手,而且是連續不斷的。
HTTP/1.1 在1997年1月以 RFC 2068 文件發布。
HTTP 1.1 消除了大量歧義內容并引入了多項技術
虛擬主機( virtual hosting )即共享主機( shared web hosting ),可以利用虛擬技術把一臺完整的服務器分成若干個主機,因此可以在單一主機上運行多個網站或服務。
舉個例子,有一臺 ip 地址為 61.135.169.125 的服務器,在這臺服務器上部署著谷歌、百度、淘寶的網站。為什么我們訪問 https://www.google.com 時,看到的是 Google 的首頁而不是百度或者淘寶的首頁?原因就是 Host 請求頭決定著訪問哪個虛擬主機。
2015年, HTTP2.0 面世。 rfc7540
HTTP 2.0 中的幀將 HTTP/1.x 消息分成幀并嵌入到流 ( stream ) 中。數據幀和報頭幀分離,這將允許報頭壓縮。將多個流組合,這是一個被稱為多路復用 ( multiplexing ) 的過程,它允許更有效的底層 TCP 連接。
也就是說,流用來承載消息,消息又是有一個或多個幀組成。二進制傳輸的方式更加提升了傳輸性能。 每個數據流都以消息的形式發送,而消息又由一個或多個幀組成。 幀是流中的數據單位。
HTTP 幀現在對 Web 開發人員是透明的。在 HTTP/2 中,這是一個在 HTTP/1.1 和底層傳輸協議之間附加的步驟。 Web 開發人員不需要在其使用的 API 中做任何更改來利用 HTTP 幀;當瀏覽器和服務器都可用時, HTTP/2 將被打開并使用。
之前我們提到,雖然 HTTP 1.1 有了長連接和管道化的技術,但是還是會存在 隊頭阻塞。而 HTTP 2.0 就解決了這個問題 HTTP/2 中新的二進制分幀層突破了這些限制,實現了完整的請求和響應復用:客戶端和服務器可以將 HTTP 消息分解為互不依賴的幀,然后交錯發送,最后再在另一端把它們重新組裝起來。
如上圖所示,快照捕捉了同一個連接內并行的多個數據流。 客戶端正在向服務器傳輸一個 DATA 幀(數據流 5),與此同時,服務器正向客戶端交錯發送數據流 1 和數據流 3 的一系列幀。因此,一個連接上同時有三個并行數據流。
將 HTTP 消息分解為獨立的幀,交錯發送,然后在另一端重新組裝是 HTTP 2 最重要的一項增強。事實上,這個機制會在整個網絡技術棧中引發一系列連鎖反應,從而帶來巨大的性能提升,讓我們可以: 1.并行交錯地發送多個請求,請求之間互不影響。 2.并行交錯地發送多個響應,響應之間互不干擾。 3.使用一個連接并行發送多個請求和響應。 4.消除不必要的延遲和提高現有網絡容量的利用率,從而減少頁面加載時間。 5.不必再為繞過 HTTP/1.x 限制而做很多工作(比如精靈圖) ...
連接共享,即每一個 request 都是是用作連接共享機制的。一個 request 對應一個 id ,這樣一個連接上可以有多個 request ,每個連接的 request 可以隨機的混雜在一起,接收方可以根據 request 的 id 將 request 再歸屬到各自不同的服務端請求里面。
HTTP 1.1 和 HTTP 2.0 的對比,可以參考這個 網站 demo 演示
HTTP 1.1 演示如下:
HTTP2.0 演示如下:
使用 HTTP/1.1 和 HTTP/2 對于站點和應用來說是透明的。擁有一個最新的服務器和新點的瀏覽器進行交互就足夠了。只有一小部分群體需要做出改變,而且隨著陳舊的瀏覽器和服務器的更新,而不需 Web 開發者做什么,用的人自然就增加了
HTTPS 也是通過 HTTP 協議進行傳輸信息,但是采用了 TLS 協議進行了加密
對稱加密就是兩邊擁有相同的秘鑰,兩邊都知道如何將密文加密解密。但是因為傳輸數據都是走的網絡,如果將秘鑰通過網絡的方式傳遞的話,一旦秘鑰被截獲就沒有加密的意義的
非對稱加密
公鑰大家都知道,可以用公鑰加密數據。但解密數據必須使用私鑰,私鑰掌握在頒發公鑰的一方。首先服務端將公鑰發布出去,那么客戶端是知道公鑰的。然后客戶端創建一個秘鑰,并使用公鑰加密,發送給服務端。服務端接收到密文以后通過私鑰解密出正確的秘鑰
TLS 握手的過程采用的是非對稱加密
強緩存主要是由 Cache-control 和 Expires 兩個 Header 決定的
Expires 的值和頭里面的 Date 屬性的值來判斷是否緩存還有效。 Expires 是 Web 服務器響應消息頭字段,在響應 http 請求時告訴瀏覽器在過期時間前瀏覽器可以直接從瀏覽器緩存取數據,而無需再次請求。 Expires 的一個缺點就是,返回的到期時間是服務器端的時間,這是一個絕對的時間,這樣存在一個問題,如果客戶端的時間與服務器的時間相差很大(比如時鐘不同步,或者跨時區),那么誤差就很大。
Cache-Control 指明當前資源的有效期,控制瀏覽器是否直接從瀏覽器緩存取數據還是重新發請求到服務器取數據。但是其設置的是一個相對時間。
指定過期時間: max-age 是距離請求發起的時間的秒數,比如下面指的是距離發起請求 31536000S 內都可以命中強緩存
Cache-Control: max-age=31536000
復制代碼
表示沒有緩存
Cache-Control: no-store
復制代碼
有緩存但要重新驗證
Cache-Control: no-cache
復制代碼
私有和公共緩存
public 表示響應可以被任何中間人(比如中間代理、 CDN 等緩存) 而 private 則表示該響應是專用于某單個用戶的,中間人不能緩存此響應,該響應只能應用于瀏覽器私有緩存中。
Cache-Control: private
Cache-Control: public
復制代碼
驗證方式:以下表示一旦資源過期(比如已經超過 max-age ),在成功向原始服務器驗證之前,緩存不能用該資源響應后續請求
Cache-Control: must-revalidate
復制代碼
Cache-control 優先級比 Expires 優先級高
以下是一個 Cache-Control 強緩存的過程:
Last-Modified 表示本地文件最后修改日期,瀏覽器會在 request header 加上 If-Modified-Since (上次返回的 Last-Modified 的值),詢問服務器在該日期后資源是否有更新,有更新的話就會將新的資源發送回來
但是如果在本地打開緩存文件,就會造成 Last-Modified 被修改,所以在 HTTP / 1.1 出現了 ETag
Etag 就像一個指紋,資源變化都會導致 ETag 變化,跟最后修改時間沒有關系, ETag 可以保證每一個資源是唯一的。 If-None-Match 的 header 會將上次返回的 Etag 發送給服務器,詢問該資源的 Etag 是否有更新,有變動就會發送新的資源回來
If-none-match 、 ETags 優先級高于 If-Modified-Since、Last-Modified
第一次請求:
第二次請求相同網頁:
協商緩存,假如沒有改動的話,返回 304 ,改動了返回 200 資源
現在的200 (from cache) 已經變成了 disk cache (磁盤緩存)和 memory cache (內存緩存)兩種
上面提到 HTTP 緩存相關,但是很多有時候,我們希望上線之后需要更新線上資源。
web 開發者發明了一種被 Steve Souders 稱之為 revving 的技術。不頻繁更新的文件會使用特定的命名方式:在 URL 后面(通常是文件名后面)會加上版本號。
弊端:更新了版本號,所有引用這些的資源的地方的版本號都要改變
web 開發者們通常會采用自動化構建工具在實際工作中完成這些瑣碎的工作。當低頻更新的資源( js/css )變動了,只用在高頻變動的資源文件( html )里做入口的改動。
HTTP Cookie (也叫 Web Cookie 或瀏覽器 Cookie )是服務器發送到用戶瀏覽器并保存在本地的一小塊數據,它會在瀏覽器下次向同一服務器再發起請求時被攜帶并發送到服務器上。
Set-Cookie 響應頭部和 Cookie 請求頭部
Set-Cookie: <cookie名>=<cookie值>
復制代碼
會話期Cookie是最簡單的 Cookie :瀏覽器關閉之后它會被自動刪除,也就是說它僅在會話期內有效。會話期 Cookie 不需要指定過期時間( Expires )或者有效期( Max-Age )。需要注意的是,有些瀏覽器提供了會話恢復功能,這種情況下即使關閉了瀏覽器,會話期 Cookie 也會被保留下來,就好像瀏覽器從來沒有關閉一樣
和關閉瀏覽器便失效的會話期 Cookie 不同,持久性 Cookie 可以指定一個特定的過期時間( Expires )或有效期( Max-Age )。
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
復制代碼
標記為 Secure 的 Cookie 只應通過被 HTTPS 協議加密過的請求發送給服務端。
標記為 Secure 的 Cookie 只應通過被 HTTPS 協議加密過的請求發送給服務端。但即便設置了 Secure 標記,敏感信息也不應該通過 Cookie 傳輸,因為 Cookie 有其固有的不安全性, Secure 標記也無法提供確實的安全保障
通過 JavaScript 的 Document.cookie API 是無法訪問帶有 HttpOnly 標記的 cookie 。這么做是為了避免跨域腳本攻擊( XSS )
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
復制代碼
Domain 和 Path 標識定義了 Cookie 的作用域:即 Cookie 應該發送給哪些 URL 。
Domain 標識指定了哪些主機可以接受 Cookie 。如果不指定,默認為當前的主機(不包含子域名)。如果指定了 Domain ,則一般包含子域名。
例如,如果設置 Domain=mozilla.org ,則 Cookie 也包含在子域名中(如 developer.mozilla.org )。
Path 標識指定了主機下的哪些路徑可以接受 Cookie (該 URL 路徑必須存在于請求 URL 中)。以字符 %x2F ("/") 作為路徑分隔符,子路徑也會被匹配。
例如,設置 Path=/docs ,則以下地址都會匹配:
/docs
/docs/Web/
/docs/Web/HTTP
復制代碼
SameSite Cookie 允許服務器要求某個 cookie 在跨站請求時不會被發送,從而可以阻止跨站請求偽造攻擊
Set-Cookie: key=value; SameSite=Strict
復制代碼
None Strict Lax
在新版本的瀏覽器( Chrome 80 之后)中, SameSite 的默認屬性是 SameSite=Lax 。換句話說,當 Cookie 沒有設置 SameSite 屬性時,將會視作 SameSite 屬性被設置為 Lax —— 這意味著 Cookies 將不會在當前用戶使用時被自動發送。如果想要指定 Cookies 在同站、跨站請求都被發送,那么需要明確指定 SameSite 為 None 。因為這一點,我們需要好好排查舊系統是否明確指定 SameSite ,以及推薦新系統明確指定 SameSite ,以兼容新舊版本 Chrome
更多 cookie 相關,可以查看我之前總結的一篇關于 cookie 的文章 前端須知的 Cookie 知識小結
跨域資源共享( CORS )是一種機制,它使用額外的 HTTP 頭告訴瀏覽器,讓運行在一個 origin ( domain ) 上的 web 應用被準許訪問來自不同源服務器上的指定的資源
跨域資源共享標準新增了一組 HTTP 首部字段,允許服務器聲明哪些源站通過瀏覽器有權限訪問哪些資源。
簡單請求(不會觸發 CORS 的預檢請求)需要同時滿足以下三點:
以下為一個簡單請求的請求報文以及響應報文
簡化以下:
請求首部字段 Origin 表明該請求來源于 http://foo.example
本例中,服務端返回的 Access-Control-Allow-Origin: * 表明,該資源可以被任意外域訪問。如果服務端僅允許來自 http://foo.example 的訪問,該首部字段的內容如下:
Access-Control-Allow-Origin: http://foo.example
復制代碼
Access-Control-Allow-Origin 應當為 * 或者包含由 Origin 首部字段所指明的域名。
規范要求,對那些可能對服務器數據產生副作用的 HTTP 請求方法。瀏覽器必須首先使用 OPTIONS 方法發起一個預檢請求( preflight request ),從而獲知服務端是否允許該跨域請求。
服務器確認允許之后,才發起實際的 HTTP 請求。在預檢請求的返回中,服務器端也可以通知客戶端,是否需要攜帶身份憑證(包括 Cookies 和 HTTP 認證相關數據)
預檢請求中同時攜帶了下面兩個首部字段:
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER, Content-Type
復制代碼
首部字段 Access-Control-Request-Method 告知服務器,實際請求將使用 POST 方法。首部字段 Access-Control-Request-Headers 告知服務器,實際請求將攜帶兩個自定義請求首部字段: X-PINGOTHER 與 Content-Type 。服務器據此決定,該實際請求是否被允許。
預檢請求的響應中,包括了以下幾個字段
Access-Control-Allow-Origin: http://foo.example
// 表明服務器允許客戶端使用 POST, GET 和 OPTIONS 方法發起請求
Access-Control-Allow-Methods: POST, GET, OPTIONS
// 表明服務器允許請求中攜帶字段 X-PINGOTHER 與 Content-Type
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
// 表明該響應的有效時間為 86400 秒,也就是 24 小時。在有效時間內,瀏覽器無須為同一請求再次發起預檢請求。
Access-Control-Max-Age: 86400
復制代碼
一般而言,對于跨域 XMLHttpRequest 或 Fetch 請求,瀏覽器不會發送身份憑證信息。如果要發送憑證信息,需要設置 XMLHttpRequest 的某個特殊標志位。比如說 XMLHttpRequest 的 withCredentials 標志設置為 true ,則可以發送 cookie 到服務端。
對于附帶身份憑證的請求,服務器不得設置 Access-Control-Allow-Origin 的值為“*”。 這是因為請求的首部中攜帶了 Cookie 信息,如果 Access-Control-Allow-Origin 的值為“*”,請求將會失敗。而將 Access-Control-Allow-Origin 的值設置為 http://foo.example ,則請求將成功執行。
CORS 涉及到的請求和響應頭如下: HTTP 響應首部字段
HTTP 請求首部字段
Origin
Access-Control-Request-Method
Access-Control-Request-Headers
有感興趣的朋友可以關注一下我的公眾號:前端維他命,不定時更新優秀文章。
項目上需要用到多語言,項目設計語言選擇是通過header傳遞的,如果直接用平時location.href下載并無法實現這個效果,然后在網上查閱了一些資料,可以通過流處理來實現下載,代碼如下
downloadFile(){
let timestamp = new Date().getTime(); //時間戳
let url =XXXXXXXXXXXX;
let xmlResquest = new XMLHttpRequest();
xmlResquest.open("GET", url, true);
xmlResquest.setRequestHeader("Authorization", "bearer" + this.token); //token驗證
xmlResquest.responseType = "blob";
xmlResquest.onload = function(oEvent) { //接口響應后的處理
var content = xmlResquest.response; // 組裝a標簽
let elink = document.createElement("a");// 設置下載文件名
elink.download = "track-kml-" + timestamp + ".kml";
elink.style.display = "none";
let blob = new Blob([content]);
elink.href = URL.createObjectURL(blob);
document.body.appendChild(elink);
elink.click();
document.body.removeChild(elink);
URL.revokeObjectURL(blob); //釋放對象
};
xmlResquest.send();
}
本著不懂就學的原則,查閱了部分不懂的方法,以下資料來源MDN
URL.createObjectURL() 靜態方法會創建一個 DOMString,其中包含一個表示參數中給出的對象的URL。這個 URL 的生命周期和創建它的窗口中的 document 綁定。這個新的URL 對象表示指定的 File 對象或 Blob 對象。
內存管理
在每次調用 createObjectURL() 方法時,都會創建一個新的 URL 對象,即使你已經用相同的對象作為參數創建過。當不再需要這些 URL 對象時,每個對象必須通過調用 URL.revokeObjectURL() 方法來釋放。瀏覽器會在文檔退出的時候自動釋放它們,但是為了獲得最佳性能和內存使用狀況,你應該在安全的時機主動釋放掉它們。
XMLHttpRequest.responseType 屬性是一個枚舉類型的屬性,返回響應數據的類型。它允許我們手動的設置返回數據的類型。如果我們將它設置為一個空字符串,它將使用默認的"text"類型。
在工作環境(Work Environment)中將responseType的值設置為"document"通常會被忽略. 當將responseType設置為一個特定的類型時,你需要確保服務器所返回的類型和你所設置的返回值類型是兼容的。那么如果兩者類型不兼容呢?恭喜你,你會發現服務器返回的數據變成了null,即使服務器返回了數據。還有一個要注意的是,給一個同步請求設置responseType會拋出一個InvalidAccessError 的異常。
responseType支持以下幾種值:
值 | 描述 |
"" | 將 responseType 設為空字符串與設置為"text"相同, 是默認類型 (實際上是 DOMString)。 |
"arraybuffer" | response 是一個包含二進制數據的 JavaScript ArrayBuffer 。 |
"blob" | response 是一個包含二進制數據的 Blob 對象 。 |
"document" | response 是一個 HTML Document 或 XML XMLDocument ,這取決于接收到的數據的 MIME 類型。請參閱 HTML in XMLHttpRequest 以了解使用 XHR 獲取 HTML 內容的更多信息。 |
"json" | response 是一個 JavaScript 對象。這個對象是通過將接收到的數據類型視為 JSON 解析得到的。 |
"text" | response 是包含在 DOMString 對象中的文本。 |
"moz-chunked-arraybuffer" | 與"arraybuffer"相似,但是數據會被接收到一個流中。使用此響應類型時,響應中的值僅在 progress 事件的處理程序中可用,并且只包含上一次響應 progress 事件以后收到的數據,而不是自請求發送以來收到的所有數據。 在 progress 事件處理時訪問 response 將返回到目前為止收到的數據。在 progress 事件處理程序之外訪問, response 的值會始終為 null 。 |
"ms-stream" | response 是下載流的一部分;此響應類型僅允許下載請求,并且僅受Internet Explorer支持。 |
近又快到了金三銀四的好日子了,有一天,小龍找到我說,小輝哥,我想跳槽了。原來公司加薪無望,目前只有 7.5k,12 薪,也沒有年終獎,想換個環境試試,但是好像今年疫情之下,招聘市場并沒有往年那么熱門,目前覺得自己還沒有辦法去大廠。
在自己努力無果之后,想讓我幫他操作一下,我咨詢了一下小龍目前的情況,然后幫他物色了5、6個崗位,然后讓他自己挑一個比較喜歡的:
小龍目前的情況:
1. 自考本科。
2. 24 歲。
3. 1 年多一點工作經驗(我改為了 1 年半)。
4. 目前薪資 7.5,加上年終和績效可以到 9.5。
5. 有 vue 一年多的使用經驗,全家桶基本會。
6. webpack 用過,但是不熟,都是別人幫弄好的。
7. 自我感覺良好,對于自己的學習能力覺得還算可以,js,css,es6基礎尚可。
8. nodejs 較弱,只停留在 CRUD 階段,玩過一下 express做 blog。
9. 平時使用 git ,不過公司使用 svn。
10. 對待 996 還算可以認可,不過最好還是希望不要 996
這是他挑選的目標公司職位的招聘 jd 如下:
月薪:12-20k·12薪
經驗要求:1-3年
學歷:本科
工作地區:廣州天河區 XXXX
工作職責:
1、負責web服務端,內部系統后端業務程序開發
2、負責web前端開發
3、參與現場調試
4、參與后端業務和底層模塊接口開發及調試
工作要求 1:
1、熟悉vue框架,熟悉elementUI界面控件庫
2、扎實的javascript語言,html,css基礎;
3、熟悉使用linux基本應用和nodejs;
4、有前后端分離的項目實踐經驗,能使用上述技術搭建豐富交互的前端界面并和后端進行http,tcp的通訊;
5、熟悉typescript優先。
工作要求2:
1、做事認真負責,有良好的編碼風格;
2、良好的溝通與表達能力,有團隊協作精神。
3、有良好的學習方法和較強的學習能力;
4、喜歡迎難而上,愛好挑戰困難;
5、有框架思維和多人合作編碼能力。
我跟小龍說,這個 jd 對你目前來說會有點難度,不過如果你真的很想達到的話,也是可以的,花點心思,努努力就行了。 他說,沒問題,成了請你吃飯哈~
接下來我會用詳細說明一下小龍到底經歷了什么。
第一步:先讓我們分析一下這個招聘要求jd
第二步:確定需要突破的求職目標
第三步:快速提升自身技能滿足要求
第四步:快速準備面試
第五步:如何高效投簡歷
第六步:如何優秀通過面試
第七步:獲得 offer
招聘要求也叫jd,英文是 job description,翻譯為工作描述也可以
一個 jd 其實不簡單:
一般一份工作是 1-3 年左右,所以說,你這是在選擇一份未來 1-3 年時間消費,一份工作不僅要工資待遇適合你,工作節奏也要適合你,而且最好要跟你未來職業規劃沾邊才行,這樣你的時間才會更有意義,你就可以用 1-3 年時間就可以頂別人 3-5 年了。
月薪:12-20k·12薪,一般能在招聘要求里面寫這么清晰的公司,素質都相對比較好,因為坦誠是一家公司很重要的一個品質。
漫天開價,落地還錢。我們拿一個最低的,再拿一個最高的,取一個平均值,(12+20)/2 =16,所以這個崗位的預期月薪工資一般都可以達到 16K,不過也要注意,他是 12 薪的,也就是說,一年只有 12 個月薪資,而有很多公司,一年可以發 13,14 甚至 16 個月,這里就是區別了。不過也可能對方沒寫出來,在現場面試的時候咨詢 hr 就行了。
總體來說也算不錯。要知道小龍之前是 7.5K 的。
但不排除有些公司不按套路出牌~
有句老話說,工作經驗寫 3 年,上班一年半,加班一年半,就是這么硬核,哈哈哈~
所以這里 1-3 年其實無傷大雅。只要不要偏離太夸張即可,例如你是應屆畢業生,寫工作 2 年,這樣很容易穿幫的,不建議。
小龍工作一年半了,寫 2 年也是非常合理的,如果準備充分,寫個 3 年也問題不大。
一般中小公司是不卡學歷,除非比較特殊要求的, 例如國企,事業單位,或者特殊崗位,例如算法,人工智能AI類。
有些時候,公司急用人,也可以從本科下降到大專, 這個也是可以理解的。
不過如果是大公司就不行,大公司必要的招聘考核指標就必須要本科,有些甚至是 985 以上的本科才行。
目前小龍雖然不是統招本科,但是好歹也是自考本科,也是國家承認的。
一般人很少留意這個公司地點,有些朋友雖然找到一個公司,待遇還不錯,但是離自己家十萬八千里遠,每次上下班都像坐長途車一樣,一天至少浪費了好幾個小時在通勤上,你以為你工資高了,就是賺錢了,但是其實不然,你只不過是犧牲了其他東西,例如時間,精力。
在《通往財富自由之路》里,李笑來老師提到一個概念,就是注意力>時間>金錢。錢,是價值相對較低的,如果能拿他換到時間(進而換到你的注意力,讓你可以在你關注的領域里得到成長),那才是真正有價值的。
我的建議就是,在財力允許的條件下,盡可能的讓工作的地方離家近一點。
小龍挑這個企業離他宿舍還不算遠,另外我發現這個軟件園位于市中心,附近有比較多的不同大大小小的互聯網企業,我建議他如果可以的話,就搬到這個軟件園附近來住,一方面上班更近,一方面萬一以后跳槽, 也不用折騰搬家多次,搬家的辛苦誰干誰知道~
一個是看公司是不是朝陽行業,另外一個是看公司業務是否跟時代脫節。
例如煤炭行業就是夕陽行業,不是朝陽行業。
例如柯達膠卷業務被數碼相機取代,nokia非智能手機被蘋果智能手機取代,這個就是公司業務根本時代脫節了。
一般來說,可以多留意一下社會龍頭企業關注的東西,例如華為,騰訊,阿里,還有就是關注以下國家政策,發展芯片,發展 5G,人工智能等等。
小龍挑的這個企業做的是智能制造業和醫療器械相關的,屬于今年國家重點推廣領域,起碼目前來看還可以,這些內容可以在企業官網找到。
一個公司的招聘 jd 的工作職責和工作要求寫的水平可以知道該公司的技術水平或者工作、職場氛圍不會太差,
例如工作要求就寫精通:
精通HTML5/CSS3/JS/TypeScript/Less/SVG/Canvas等前端技術
精通 Vue/Angular/React/BootStrap至少兩種前端框架
就算是阿里 p7 也不敢寫精通,外行看熱鬧,內行看門道。這種一看就是不懂技術的人寫湊數或者領導為了高大上而寫的。
而且如果職場政治氛圍(pmp)太壓抑,不利于新人成長。
再來看看小龍挑的這個公司,總體感覺還是比較實在,不會太過夸張,也沒有用精通的字樣:
工作職責:
1、負責web服務端,內部系統后端業務程序開發
2、負責web前端開發
3、參與現場調試
4、參與后端業務和底層模塊接口開發及調試
工作要求 1:
1、熟悉vue框架,熟悉elementUI界面控件庫
2、扎實的javascript語言,html,css基礎;
3、熟悉使用linux基本應用和nodejs;
4、有前后端分離的項目實踐經驗,能使用上述技術搭建豐富交互的前端界面并和后端進行http,tcp的通訊;
5、熟悉typescript優先。
工作要求2:
1、做事認真負責,有良好的編碼風格;
2、良好的溝通與表達能力,有團隊協作精神。
3、有良好的學習方法和較強的學習能力;
4、喜歡迎難而上,愛好挑戰困難;
5、有框架思維和多人合作編碼能力。
我們來分析一下:
經過分析之后,我們可以確認:
必須點滿足了是 12K,加分點滿足了是 16k。
這些就是我們需要短時間突破的目標。
由于考慮的是短時間突破,沒有算加分題的內容。
是不是突然有種,原來如此,不外如是的感覺,啊哈哈,戰略和戰術同樣重要的。
為了避免小龍擔心目標太大而完成不了,所以我將大目標拆分成小目標,這個小目標也是根據小龍自己覺得可以才定的,有些人 1 天可以看完一本書,有些人則需要 2 天,視乎每個人的情況。
這就是:拆分大目標,直至到你覺得可以快速完成的小目標級別為止
小目標還有一個好處,每次完成一個小目標,不會太難,可以給你形成正反饋,讓你可以漸進式進步,增強信心,從而堅持下。
同時小目標也是你的前進之路的地圖,每個小目標之間的聯系構成了大目標,只要沒有偏離小目標目標,大目標就不會偏離。
我再次跟小龍確認過,他目前的情況:
我幫他拆分了一下目標,當時做了一個xmind,方便全局的看。
這里是需要看的材料:
在一開始是沒辦法知道這個大目標需要多久能夠完成的,也不知道這個小目標需要多久才能完成。只能通過跟自己約定每天,每周的完成程度。
雖然說小龍自我感知每天晚上會有 2 小時,每周六日有 8 小時是可以學習的,但是時間這個量化指標不是很準,有時候走神了,或者狀態不好,時間到了,但是工作沒做好。
這里我跟小龍加了一個儀式,讓他每次完成一個小目標之前,發一個宣誓內容給我,內容如下:我是為了 XXX 而努力的,我會在 XXX 時間內,完成 XXX的學習,并且整理好筆記,我不糊弄自己,務必認真完成。
這是一種契約,跟自己的一個契約。契約的力量是很大的。
另外我需要他在日歷本上打鉤,記錄自己今天是否已經完成了學習。 這是同樣是一種契約。
不要過分高估自己的自律性,要客觀評價自己的拖延癥!
好記性不如爛筆頭,大腦的記憶需要多次反復刺激才會印象深刻,看一次,讀一次,想一次,思考一次,寫一次,你的記憶比別人就相當于高了 4 倍以上,因為一般人只會看一次而已。
筆記的內容不是簡單寫,會將某個知識點的的原理和實際例子都寫一遍,并且會問一下自己,是不是真的懂了,邏輯是不是真的通了。
小龍同學有一個好處就是,每次總結都有很長的筆記,大概3000 字一篇,不過不好的地方就是有時候筆記花費時間有點太長。
想想我自己以前上學,寫個 800 字文章都覺得天都塌了,偶買狗的!
筆記基本都是用 markdown 寫,自動排版,方便寫,方便看。如果過分追求格式和樣子,反而失去了本來記筆記的意義。
這是他寫過的筆記之一:
實際記錄到一共用了 20+10+6+10+6+6+6=64 個小時,而且這個是計算純時間,實際消耗的時間其實是大于 64 個小時的,因為人不能免俗,有時候計劃趕不上變化,按照公式,大概是80 個小時左右。
每天 2 小時,每個星期六和日是 8 小時,大概一個星期能花 26 個小時學習,當時我朋友的朋友學完并且在我檢查確認大體已經掌握知識的結果后,最終大概用了4 個星期左右(有些時候有特殊時期中斷了一下)。
不過也是需要建立在我強而有力的監督之下~啊哈哈哈。
毛時間vs純時間
毛時間:你所花在工作上的時間統稱為毛時間。
純時間:你真正專注于工作的時間稱為純時間。
一般來說,純時間=毛時間的 80%**
這是我補充之前的 xmind 圖的最終結果
至此,基本上小龍已經能夠觸達這個 offer 的門檻了,底氣不會那么虛了。
github 倉庫是一個優秀程序員的名片。 --BY 魯X
github 倉庫可以存放你的代碼或者你的 blog 學習心得筆記,比起虛無縹緲的說,能看得到的東西會更加讓人產生信任感。
一個有內涵的 github 倉庫或者 blog 可以讓你在面試官的第一印象里面加很多分的。
首因效應由美國心理學家洛欽斯首先提出的,也叫首次效應、優先效應或第一印象效應,指交往雙方形成的第一次印象對今后交往關系的影響,也即是“先入為主”帶來的效果。
如果一個人在初次見面時給人留下良好的印象,那么人們就愿意和他接近,彼此也能較快地取得相互了解,并會影響人們對他以后一系列行為和表現的解釋。
反之,對于一個初次見面就引起對方反感的人,即使由于各種原因難以避免與之接觸,人們也會對之很冷淡,在極端的情況下,甚至會在心理上和實際行為中與之產生對抗狀態。
這個倉庫不能只是一個單純的裝飾物,最好可以將一個你覺得有意思的項目代碼放進去,然后在面試的過程中給面試官邊看邊講解,更加容易讓對方認可你的能力。同理,blog 的文章也不能是全部轉載或者流水賬,要有體現出你認真 coding 的內味才行。
人靠衣裝,佛靠金裝。這個就是你的金裝之一。
可以看看阮老師早期的 github,都是寫了很多 demo 之類的。
網上有大量的面經和面試題分享,我們要找熱門的,因為面試官也是普通人,他不可能天天自己造題目,他也是參考網上的。
我們需要有題目和答案的是最好的,這樣方便我們對照。
刷題有一個技巧,就是不斷重復 3-5 遍,不斷加深印象。有時候刷題不一定要知道題目的前因后果,在有限的時間里面,盡最大可能的讓你大腦記憶多次才是王道。
另外我們這次先排除算法題,畢竟我們不是面向 1 線大廠,對算法要求不高,有選擇性放棄,集中戰斗力在其他更重要的地方。
刷題在面試前 2天來做即可。
最后我根據自己的經驗和小龍目前的情況,給他整理了適合他的題目,并且讓他至少刷 3 次,最后我通過抽查題目回答來確認他短期刷題的記憶已經足夠了。
一份優秀的簡歷是為了讓別人快速了解你的。如果你的簡歷寫不好,即使你是天才也會蒙塵,社會的規則就是這樣,人們知道的是用“是金子總會發光”來安慰自己,但往往忽略了你起碼要讓你的光進到別人的眼睛里面才行。
這是標準的簡歷格式:(記得不要搞亂順序)
例如這樣:
基本簡歷格式有了,但是不夠閃亮,那我們要怎么填充最主要的項目經驗內容來讓你的簡歷閃閃發光呢?
項目經驗貴精不貴多,一般一個最核心的項目就夠了, 如果一個都不能讓面試官覺得你很優秀,那么再來多一個也于事無補,這種時候不需要量變引起質變,除非你的能力可以在 2 個項目里面都分別突出你的優秀,不然寫一個就夠了。
阮一峰老師給出了一些指導意見:
我在這個基礎上補充了一下,結合鼎鼎大名的 STAR 方法來操作的。
STAR 法則其實是英文單詞的縮寫,完整的單詞應該為situation、task、action和result。對應的中文為情境、任務、行動和結果。 STAR 法則通過故事的形式,表現出自己分析闡述問題的清晰性、條理性和邏輯性。
Situation: 事情是在什么情況下發生
Task: 你是如何明確你的任務
Action: 針對這樣的情況分析,你采用了什么行動方式
Result: 結果怎樣,在這樣的情況下你學習到了什么
我們用這個大綱來寫:
一般人是這樣寫的:(平淡,索然無味,沒啥意思,千篇一律)
我負責的項目是一個xxx 電商平臺的后臺管理系統,使用的技術棧主vue框架全家桶系列和 egg 來做 bff 中間層,包括axios,router,vuex,element-ui框架開發,
大部分功能是基于element-ui進行業務邏輯組件的二次封裝,主要有訂單管理,微信退款,權限角色登陸等,接口部分又 egg 作為中間層進行代理處理。
這個項目前端和 nodejs方面由我負責,前端團隊成員是 3 人。
這是改寫后的:
項目標題:電商 xxx后臺管理系統前后端分離改造項目
項目簡介:
1. 這是一個負責年營業額五百萬的 xxx 業務的后臺管理系統。
2. 這個項目原來是純 jsp 的模式開發的后臺管理系統,隨著業務發展,系統變得越來越龐大,該系統開發周期長,上線后bug 很多,維護修復問題時間長,系統處理響應速度很慢,導致業務受到了很大影響。
3. 該項目原來并沒有自動化集成測試和自動化部署,都是人工手動測試和部署。
4. 在投入很多開發資源支持下,依然沒有辦法很好改善,與公司討論后決定將系統進行前后端架構分離,前端使用 vue 進行 spa 單頁面開發,并且使用 nodejs 作為 bff 層,后端只負責提供接口并且實行自動化集成開發,自動化集成測試和自動化部署模式。
項目成果:
1. 系統性能提高了:
a. 頁面響應速度從原來等待 5-6秒完成頁面打開到現在3 秒內完成。
b. 因為單頁面應用,很多邏輯表單處理可以合并到前端交互處理,業務人員操作系統的時間大大減少,例如以前往往需要 2-3 個頁面跳轉完成處理,現在在一個頁面即可完成,系統的易用性也大幅度提高,得到了業務部的一致好評。
2. 系統更穩定了:
a. 上線后 bug 的數量比之前減少了70%,原來單功能的 bug 數量在 10 -15 左右,現在單功能 bug 數量是 5 以下。
3. 開發資源的投入減少了,開發周期縮短了:
a. 原來后端開發人員 7 人,測試人員 3 人,現在只需要后端開發人員 2 個,測試人員 1 個,前端開發人員 2 個,nodejs 1 個。
b. 原來平均單功能上線周期是 10 天,現在為平均單功能上線周期是 3 天。
項目方案:
1. 采用vue 作為主要的 spa 單頁面架構模式,將頁面的功能改為模塊和組件來維護,基于 elementsUI 做基礎樣式和功能的條件下,設計和開發自己業務的組件和模塊,進行統一組件化,模塊化維護樣式和功能,避免重復開發。
2. 樣式使用 less 代替 stylus,less 在語法上更加標準,代碼結構更加清晰,在多人協作和復雜樣式情況下提高可維護性。
3. 采用 egg 做為 bff 層,主要是因為當時后端的接口質量相對較差,為了避免前端界面過多兼容接口邏輯處理而影響了性能和維護性的問題而加入的,另外在系統技術棧過渡的時候,采用局部業務邏輯分階段更新,保證系統平滑過渡而避免對業務造成影響。
4. 使用 jenkins +webpack 進行前端和 nodejs 的代碼自動化集成,自動化測試和自動化部署。
5. 改造時間歷時 3 個月,分 3 個階段完成:
a. 第一階段先建立自動化處理基礎建設,并且對項目組人員進行指導,首先讓團隊達成一致的想法,并且建立相對應的開發規范。
b. 第一階段先使用非重點業務功能來進行改造,目的是試驗 nodejs 和 vue 的開發模式被開發人員熟練,并且提前將實際落地的遇到的問題解決掉,為下一步核心業務過渡做準備。
c. 第二階段完成全平臺業務逐步過渡,每過渡一個業務都需要進行全面測試確認沒問題后,再開始進行下一個業務過渡。
我的職責:
我負責這個項目的前端架構設計,代碼的review,代碼和組件的規范設計,核心模塊的編寫,并且跟業務和產品進行溝通,管理和協調安排開發資源,帶來團隊成員有計劃進行項目開發工作。
項目技術棧:
vue 2.5 版本,axios、vue-router、vuex、elements-UI、echart,Mocha、co-mocha、webpack、egg
工作經歷其實就是項目經歷的省略版,只要寫好項目經歷,進行縮短簡略就可以得到工作經歷了。
專業技能,其實就是你項目經歷用到的技術棧在增加或者減少就行了。
因為我們是鎖定目標的投簡歷,我們知道這家公司,所以不需要海投。
但是我們要知道他們公司的 hr 是怎么篩選簡歷的,從而思考我們的簡歷怎么可以脫穎而出。
這里需要我們做一下假設,假設你是 hr,你會怎么收集簡歷,怎么過濾簡歷,怎么閱讀簡歷?
一般 hr 收集簡歷的操作:
一般招聘渠道有以下幾個:
一般 hr 過濾簡歷的操作:
一般 hr 閱讀簡歷的操作:
有見及此,可以大大提高簡歷被閱讀,并且約談面試的機會的:
如果是在 boss 直聘的話,需要先上傳附件簡歷,然后再跟 hr 聊的時候可以發送過去
如果選擇的是自己發送郵件的方式的話,郵件主題要注明清楚:“三年開發經驗應聘資深前端工程師_姓名”
郵件格式如下(注意對齊):
張先生,
您好,我是XXX。我對貴公司的 XXX 職位很有興趣,附件里面是我的簡歷,
如果您對我的個人履歷感興趣,可以隨時與我聯系。謝謝。
感謝您的閱讀,謝謝。
應聘者:XXX
2021 年 1 月 29 日
公司郵箱可以在對方官網里面找,例如這個:
那么,面試機會來了,你一般約面試要約 1 天之后,這樣讓你容易放松一些,避免一上來就約隔天面試,過度緊張導致影響發揮。
我讓小龍約面試是 2 天后。
一般來說,一個基本面試流程是這樣的:
大公司,例如人數往往超過 300 人以上的企業,流程基本一致,但是比較長??赡軙兴拿嫔踔廖澹娴那闆r:
中小型公司,人數往往低于 300人的企業,流程就比較簡:
中小公司比較注重實際實際項目技能,主要看你是否可以馬上開始工作,對于一些基礎知識并不太關注(不代表啥都不會),而主要關注你的項目細節,大公司,本身內部有比較完善培訓流程和分工,所以對基礎知識,算法都比較在意,雖然也會重視你的項目細節,但是他們更關注你的基礎。
小龍這個公司我定義為中廠,屬于中小廠類,所以我們將面試的重點放在項目細節上。
軍事領域里面有一個東西叫沙盤模擬,戰爭沙盤模擬推演通過紅、藍兩軍在戰場上的對抗與較量,發現雙方戰略戰術上存在的問題,提高指揮員的作戰能力,模擬推演跨越了通過實兵軍演檢驗與培養高級將領的巨大成本障礙和時空限制,受到世界各國的普遍運用。
而我們安排模擬面試的原因就是因為我們要提前演練,提前知道可能發生的任何情況,以便達到在真正面試現場減少出錯,達到成功獲得 offer 的終極目標。
我們現在來幫小龍模擬整個面試流程:
大概整個流程是這樣的,可能還有一些細節每個人有點區別。
這個模擬面試里面有很多地方需要注意或者提前準備,我這里挑一些比較重點的來說:
有些人會說,我們是跟面試官攀關系,要謙虛,要謙卑,要奉承對方,以此來換得對方的高興,從而增加通過的成功率。
我認為,謙虛謙卑是對的,但是如果只是說只有這些,是不足夠的,首先你要充滿自信,讓別人覺得你是有把握的,不能做賊心虛。
良好的自信心,一方面需要靠自身本事,另外一方面是靠自己的心理建設,要時刻跟自己說,這只是一個面試,僅僅是一個面試。
相信自己可以的,信任自己過往的努力和不放棄。
世界不曾虧欠每一個努力的人。
因為首因效應,我們需要有一個優秀的自我介紹去提升面試官對你的第一印象,而好的第一印象會貫穿你的整個面試過程,這是開門第一炮,必須打好。
這里每個人都不一樣,但是有些原則是要遵守的:
例如,這個自我介紹可能已經比很多人的都要好了,但是沒辦法大幅度增加面試官的第一印象,我覺得是不足夠的:
我有過2年前端開發經驗經驗,開發過的項目有A、B、C,這幾個項目里面我最有印象的是 c,這是一個 xxx 業務系統的子系統,承載了年營業額 500w 的系統,這里我用到技術棧是 vue,xxxx。
我稍微修改一下:
我有過2年前端開發經驗經驗,開發過的項目有A、B、C,這幾個項目里面我最有印象的是 c,這是一個 xxx 業務系統的子系統,本來只是一個小系統,沒人想維護,最終分到了我的頭上。
剛開始我發現它代碼耦合很嚴重,很多代碼都是是粗獷式開發,改一個地方,很多地方莫名其妙出錯了,一個小系統的維護居然花了我好幾天時間,然后我就生氣了。
我對代碼有些潔癖,通過幾天時間我梳理了這個系統的整個前端邏輯,然后通過封裝和模塊組合,分層和解耦強聯系業務邏輯,用一周時間,幾乎重寫了這個系統的前端,并且在重要的地方加入適量的注釋和文檔,整個系統的維護難度一下子就變得簡單了很多。
后來這個系統成長為了年營業額 500w 的主業務系統,得到了公司的重視,我順便還得了個xx年度最佳開發者獎。
另外還有一個技巧,我們可以通過自我介紹產生的第一印象去引導面試官的問題方向,這樣就更容易在自己熟悉的方向上進行問題回答,更容易增加面試成功的概率。
一般來說對方會根據你的面試題結果來咨詢你,然后會根據你簡歷上寫的項目信息來有選擇性發問。
在簡歷編寫期間,使用 STAR 方法可以更清楚的梳理你的價值。但是在實際面試的時候,你還要補充上 PDCA 方法來讓對方知道你的綜合價值。
面試官更希望知道你遇到這些問題時候是怎么思考和實踐的,因為這樣才能更全面的知道一個人是否可以獨立完成工作。
PDCA四個英文字母及其在PDCA循環中所代表的含義如下:
1、 P(Plan)--計劃,確定方針和目標,確定活動計劃;
2、 D(Do)--執行,實地去做,實現計劃中的內容;
3、 C(Check)--檢查,總結執行計劃的結果,注意效果,找出問題;
4、 A(Action)--行動,對總結檢查的結果進行處理,成功的經驗加以肯定并適當推廣、標準化;失敗的教訓加以總結,以免重現,未解決的問題放到下一個PDCA循環。
每一件事情先做計劃,計劃完了以后去實施,實施的過程中進行檢查,檢查結果以后,再把檢查的結果進行改進,進行實施,進行改善,這樣把沒有改善的問題又放到下一個循環里面去,就形成一個一個的PDCA循環。
例如:之前寫的xxx 電商平臺的后臺管理系統,對方根據 pdca 的方法來問,你是怎么做這個計劃的,怎么做階段完成,你印象最深刻的是哪個技術難點,然后你是怎么解決的?
這些都要準備好,才能百戰百勝。
有幾個原則可以參考一下:
領導面主要是看你這個人的工作態度,人品,還有就是是否能夠融入團隊,可塑性(容易管理)是否足夠強。
一些比較經典:
提前準備好對應的答案之余,還要準備一些反問對方,因為對方是領導,領導喜歡被別人請教,從而增加自己的虛榮感。
例如:
一些比較經典的:
提前準備好對應的答案就好了,例如:
需要注意的是,基本過了技術面之后,hr 這關比較容易,回答不能冒進,要中規中矩,不要以為過了技術面就穩了。
如果技術很喜歡你,但是 hr 不喜歡你,一樣也是過不了。
因為這樣既可以讓你知道多一些對方公司的事,方便你做最后的決策,另外還可以讓你對方感受到了你的認真態度,也可以讓對方更容易滿足(被人請教),從而提高獲得 offer 的概率。
第一次模擬面試,出錯百出,這很正常,太久沒面試或者沒怎么留意面試的工作的人都會這樣。小龍的第一次模擬面試,我發現他連身份證都沒準備~我給他一梭子之后他終于開始認真了~
把模擬面試遇到的問題進行復盤,記錄下來,然后再模擬多一次,一般模擬 3 次左右就效果最好了。
盡可能地減少失誤,如果遇到一個特別好的offer 的話,如果面試發揮失常是個人原因導致的,那就很傷感了。
萬事俱備,去面試咯。
到了面試那天,小龍還是有點緊張,不過他說比之前好多了,之前是超級緊張,現在心里面多少有點譜了,(畢竟模擬面試了幾次,套路都知道)
不過結果還不錯,成功斬獲了一個至少是 11k 的 offer,不過我覺得 12k 也很穩的。
其實拿 offer 也是很簡單的嘛~~啊哈哈哈
看到這里,必須雙手奉上相關文中提到過的資料,大家見好就收吧~
希望可以幫到你,我是小輝哥。
因為小時候不努力學編程,畢業去做了網管,以為跟互聯網 IT 沾邊,后來發現其實做開發才是,所以又努力掰了回來,期間刷過盤子,修過電腦,寫過 php,玩過 java,舞過前端開發,練過項目經理,弄過產品經理,官職最強上至技術總監,收入從月入 800 到50k,我發現,百萬年薪真的很難的,不過我畢竟也走到這里了,還不錯。
我聽說很多年輕(中青年)人對現在的環境感到很浮躁、很焦慮、很擔憂,所以我就來看看能不能幫上忙~
*請認真填寫需求信息,我們會在24小時內與您取得聯系。