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
avaScript 可以說是交互之王,它作為腳本語言加上許多 Web Api 進一步擴展了它的特性集,更加豐富界面交互的可操作性。這類 API 的例子包括WebGL API、Canvas API、DOM API,還有一組不太為人所知的 CSS API。
由于JSX和無數JS框架的出現,使通過JS API與DOM交互的想法真正流行起來,但是在 CSS 中使用類似技術似乎并沒有很多。當然,存在像CSS-in-JS這類解決方案,但是最流行的解決方案還是基于轉譯(transpilation),無需額外運行即可生成 CSS。這肯定對性能有好處,因為CSS API的使用可能導致額外的重繪,這與DOM API的使用一樣。但這不是咱們想要的。如果哪天公司要求咱們,既要操縱 DOM 元素的樣式和 CSS 類,還要像使用 HTML 一樣使用 JS 創建完整的樣式表,該怎么辦?
內聯樣式
在咱們深入一些復雜的知識之前,先回來顧一下一些基礎知識。例如,咱們可以通過修改它的.style屬性來編輯給定的HTMLElement的內聯樣式。
const el = document.createElement('div') el.style.backgroundColor = 'red' // 或者 el.style.cssText = 'background-color: red' // 或者 el.setAttribute('style', 'background-color: red')
直接在.style對象上設置樣式屬性將需要使用駝峰式命名作為屬性鍵,而不是使用短橫線命名。如果咱們需要設置更多的內聯樣式屬性,則可以通過設置.style.cssText屬性,以更加高效的方式進行設置 。
我自己是一名從事了多年開發的web前端老程序員,目前辭職在做自己的web前端私人定制課程,今年年初我花了一個月整理了一份最適合2019年學習的web前端學習干貨,各種框架都有整理,送給每一位前端小伙伴,想要獲取的可以關注我的頭條號并在后臺私信我:前端,即可免費獲取
請記住,給cssText設置后原先的css樣式被清掉了,因此,要求咱們一次死一堆樣式 。
如果這種設置內聯樣式過于繁瑣,咱們還可以考慮將.style與Object.assign()一起使用,以一次設置多個樣式屬性。
// ... Object.assign(el.style, { backgroundColor: "red", margin: "25px" })
這些“基本知識”比咱們想象的要多得多。.style對象實現CSSStyleDeclaration接口。這說明它帶還有一些有趣的屬性和方法,這包括剛剛使用的.cssText,還包括.length(設置屬性的數量),以及.item()、.getPropertyValue()和.setPropertyValue()之類的方法:
// ... const propertiesCount = el.style.length for(let i = 0; i < propertiesCount; i++) { const name = el.style.item(i) // 'background-color' const value = el.style.getPropertyValue(name) // 're' const priority = el.style.getPropertyPriority(name) // 'important' if(priority === 'important') { el.style.removeProperty() } }
這里有個小竅門-在遍歷過程中.item()方法具有按索引訪問形式的備用語法。
// ... el.style.item(0) === el.style[0]; // true
CSS 類
接著,來看看更高級的結構——CSS類,它在檢索和設置時具有字符串形式是.classname。
// ... el.className = "class-one class-two"; el.setAttribute("class", "class-one class-two");
設置類字符串的另一種方法是設置class屬性(與檢索相同)。但是,就像使用.style.cssText屬性一樣,設置.className將要求咱們在字符串中包括給定元素的所有類,包括已更改和未更改的類。
當然,可以使用一些簡單的字符串操作來完成這項工作,還有一種就是使用較新的.classList屬性,這個屬性,IE9 不支持它,而 IE10 和 IE11 僅部分支持它。
classlist屬性實現了DOMTokenList,有一大堆有用的方法。例如.add()、.remove()、.toggle()和.replace()允許咱們更改當前的 CSS 類集合,而其他的,例如.item()、.entries()或.foreach()則可以簡化這個索引集合的遍歷過程。
// ... const classNames = ["class-one", "class-two", "class-three"]; classNames.forEach(className => { if(!el.classList.contains(className)) { el.classList.add(className); } });
Stylesheets
一直以來,Web Api 還有一個StyleSheetList接口,該接口由document.styleSheets屬性實現。document.styleSheets 只讀屬性,返回一個由 StyleSheet 對象組成的 StyleSheetList,每個 StyleSheet 對象都是一個文檔中鏈接或嵌入的樣式表。
for(styleSheet of document.styleSheets){ console.log(styleSheet); }
通過打印結果咱們可以知道,每次循環打印的是 CSSStyleSheet 對象,每個 CSSStyleSheet 對象由下列屬性組成:
屬性描述media獲取當前樣式作用的媒體。disabled打開或禁用一張樣式表。href返回 CSSStyleSheet 對象連接的樣式表地址。title返回 CSSStyleSheet 對象的title值。type返回 CSSStyleSheet 對象的type值,通常是text/css。parentStyleSheet返回包含了當前樣式表的那張樣式表。ownerNode返回CSSStyleSheet對象所在的DOM節點,通常是<link>或<style>。cssRules返回樣式表中所有的規則。ownerRule如果是通過@import導入的,屬性就是指向表示導入的規則的指針,否則值為null。IE不支持這個屬性。
** CSSStyleSheet對象方法: **
方法描述insertRule()在當前樣式表的 cssRules 對象插入CSS規則。deleteRule()在當前樣式表刪除 cssRules 對象的CSS規則。
有了StyleSheetList的全部內容,咱們來CSSStyleSheet本身。在這里就有點意思了, CSSStyleSheet擴展了StyleSheet接口,并且只有這種只讀屬性,如.ownerNode,.href,.title或.type,它們大多直接從聲明給定樣式表的地方獲取?;叵胍幌录虞d外部CSS文件的標準HTML代碼,咱們就會明白這句話是啥意思:
<head> <link rel="stylesheet" type="text/css" href="style.css" title="Styles"> </head>
現在,咱們知道HTML文檔可以包含多個樣式表,所有這些樣式表都可以包含不同的規則,甚至可以包含更多的樣式表(當使用@import時)。CSSStyleSheet有兩個方法:、.insertrule()和.deleterule() 來增加和刪除 Css 規則。
// ... const ruleIndex = styleSheet.insertRule("div {background-color: red}"); styleSheet.deleteRule(ruleIndex);
.insertRule(rule,index):此函數可以在cssRules規則集合中插入一個指定的規則,參數rule是標示規則的字符串,參數index是值規則字符串插入的位置。
deleteRule(index):此函數可以刪除指定索引的規規則,參數index規定規則的索引。
CSSStyleSheet也有自己的兩個屬性:.ownerRule和.cssRule。雖然.ownerRule與@import相關,但比較有趣的是.cssRules。簡單地說,它是CSSRuleList的CSSRule,可以使用前面提到的.insertrule()和.deleterule()方法修改它。請記住,有些瀏覽器可能會阻止咱們從不同的來源(域)訪問外部CSSStyleSheet的.cssRules屬性。
那么什么是 CSSRuleList?
CSSRuleList是一個數組對象包含著一個有序的CSSRule對象的集合。每一個CSSRule可以通過rules.item(index)的形式訪問, 或者rules[index]。這里的rules是一個實現了CSSRuleList接口的對象, index是一個基于0開始的,順序與CSS樣式表中的順序是一致的。樣式對象的個數是通過rules.length表達。
對于CSSStyleRule對象:
每一個樣式表CSSStyleSheet對象可以包含若干CSSStyleRule對象,也就是css樣式規則,如下:
<style type="text/css"> h1{color:red} div{color:green} </style>
在上面的代碼中style標簽是一個CSSStyleSheet樣式表對象,這個樣式表對象包含兩個CSSStyleRule對象,也就是兩個css樣式規則。
CSSStyleRule對象具有下列屬性:
1.type:返回0-6的數字,表示規則的類型,類型列表如下:
0:CSSRule.UNKNOWN_RULE。
1:CSSRule.STYLE_RULE (定義一個CSSStyleRule對象)。
2:CSSRule.CHARSET_RULE (定義一個CSSCharsetRule對象,用于設定當前樣式表的字符集,默認與當前網頁相同)。
3:CSSRule.IMPORT_RULE (定義一個CSSImportRule對象,就是用@import引入其他的樣式表)
4:CSSRule.MEDIA_RULE (定義一個CSSMediaRule對象,用于設定此樣式是用于顯示器,打印機還是投影機等等)。
5:CSSRule.FONT_FACE_RULE (定義一個CSSFontFaceRule對象,CSS3的@font-face)。
6:CSSRule.PAGE_RULE (定義一個CSSPageRule對象)。
2.cssText:返回一個字符串,表示的是當前規則的內容,例如:
div{color:green}
3.parentStyleSheet:返回所在的CSSStyleRule對象。
4.parentRule:如果規則位于另一規則中,該屬性引用另一個CSSRule對象。
5.selectorText:返回此規則的選擇器,如上面的div就是選擇器。
6.style:返回一個CSSStyleDeclaration對象。
// ... const ruleIndex = styleSheet.insertRule("div {background-color: red}"); const rule = styleSheet.cssRules.item(ruleIndex); rule.selectorText; // "div" rule.style.backgroundColor; // "red"
實現
現在,咱們對 CSS 相關的 JS Api有了足夠的了解,可以創建咱們自己的、小型的、基于運行時的CSS-in-JS實現。咱們的想法是創建一個函數,它傳遞一個簡單的樣式配置對象,生成一個新創建的CSS類的哈希名稱供以后使用。
實現流程很簡單,咱們需要一個能夠訪問某種樣式表的函數,并且只需使用.insertrule()方法和樣式配置就可以運行了。先從樣式表部分開始:
function createClassName(style) { // ... let styleSheet; for (let i = 0; i < document.styleSheets.length; i++) { if (document.styleSheets[i].CSSInJS) { styleSheet = document.styleSheets[i]; break; } } if (!styleSheet) { const style = document.createElement("style"); document.head.appendChild(style); styleSheet = style.sheet; styleSheet.CSSInJS = true; } // ... }
如果你使用的是ESM或任何其他類型的JS模塊系統,則可以在函數外部安全地創建樣式表實例,而不必擔心其他人對其進行訪問。但是,為了演示例,咱們將stylesheet上的.CSSInJS屬性設置為標志的形式,通過標志來判斷是否要使用它。
現在,如果如果還需要創建一個新的樣式表怎么辦? 最好的選擇是創建一個新的<style/>標記,并將其附加到HTML文檔的<head/>上。這會自動將新樣式表添加到document.styleSheets列表,并允許咱們通過<style/>標記的.sheet屬性對其進行訪問,是不是很機智?
function createRandomName() { const code = Math.random().toString(36).substring(7); return `css-${code}`; } function phraseStyle(style) { const keys = Object.keys(style); const keyValue = keys.map(key => { const kebabCaseKey = key.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(); const value = `${style[key]}${typeof style[key] === "number" ? "px" : ""}`; return `${kebabCaseKey}:${value};`; }); return `{${keyValue.join("")}}`; }
除了上面的小竅門之外。自然,咱們首先需要一種為CSS類生成新的隨機名稱的方法。然后,將樣式對象正確地表達為可行的CSS字符串的形式。這包括駝峰命名和短橫線全名之間的轉換,以及可選的像素單位(px)轉換的處理。
function createClassName(style) { const className = createRandomName(); let styleSheet; // ... styleSheet.insertRule(`.${className}${phraseStyle(style)}`); return className; }
完整代碼如下:
HTML
<div id="el"></div>
JS
function createRandomName() { const code = Math.random().toString(36).substring(7); return `css-${code}`; } function phraseStyle(style) { const keys = Object.keys(style); const keyValue = keys.map(key => { const kebabCaseKey = key.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(); const value = `${style[key]}${typeof style[key] === "number" ? "px" : ""}`; return `${kebabCaseKey}:${value};`; }); return `{${keyValue.join("")}}`; } function createClassName(style) { const className = createRandomName(); let styleSheet; for (let i = 0; i < document.styleSheets.length; i++) { if (document.styleSheets[i].CSSInJS) { styleSheet = document.styleSheets[i]; break; } } if (!styleSheet) { const style = document.createElement("style"); document.head.appendChild(style); styleSheet = style.sheet; styleSheet.CSSInJS = true; } styleSheet.insertRule(`.${className}${phraseStyle(style)}`); return className; } const el = document.getElementById("el"); const redRect = createClassName({ width: 100, height: 100, backgroundColor: "red" }); el.classList.add(redRect);
運行效果:
總結
正如本文咱們所看到的,使用 JS 操作CSS 是一件非常有趣的事,咱們可以挖掘很多好用的 API,上面的例子只是冰山一角,在CSS API(或者更確切地說是API)中還有更多方法,它們正等著被揭開神秘面紗。
原文:https://css-tricks.com/an-introduction-and-guide-to-the-css-object-model-cssom/
者:kevinylzhao,騰訊音樂前端開發工程師
瀏覽器緩存策略對于前端開發同學來說不陌生,大家都有一定的了解,但如果沒有系統的歸納總結,可能三言兩語很難說明白,甚至說錯,尤其在面試過程中感觸頗深,很多候選人對這類基礎知識竟然都是一知半解,說出幾個概念就沒了,所以重新歸納總結下,溫故而知新。
瀏覽器緩存一般分為兩類:強緩存(也稱本地緩存)和協商緩存(也稱弱緩存)。
瀏覽器發送請求前,會先去緩存里查看是否命中強緩存,如果命中,則直接從緩存中讀取資源,不會發送請求到服務器。否則,進入下一步。
當強緩存沒有命中時,瀏覽器一定會向服務器發起請求。服務器會根據 Request Header 中的一些字段來判斷是否命中協商緩存。如果命中,服務器會返回 304 響應,但是不會攜帶任何響應實體,只是告訴瀏覽器可以直接從瀏覽器緩存中獲取這個資源。如果本地緩存和協商緩存都沒有命中,則從直接從服務器加載資源。
按照本地緩存階段和協商緩存階段分類:
上述代碼的作用是告訴瀏覽器當前頁面不被緩存,事實上這種禁用緩存的形式用處很有限:
a. 僅有 IE 才能識別這段 meta 標簽含義,其它主流瀏覽器僅識別“Cache-Control: no-store”的 meta 標簽。
b. 在 IE 中識別到該 meta 標簽含義,并不一定會在請求字段加上 Pragma,但的確會讓當前頁面每次都發新請求(僅限頁面,頁面上的資源則不受影響)。
在 HTTP 請求和響應的消息報頭中,常見的與緩存有關的消息報頭有:
上圖中只是常用的消息報頭,下面來看下不同字段之間的關系和區別:
a. Last-Modified 標注的最后修改只能精確到秒級,如果某些文件在 1 秒鐘以內,被修改多次的話,它將不能準確標注文件的新鮮度;
b. 某些文件也許會周期性的更改,但是它的內容并不改變(僅僅改變的修改時間),但 Last-Modified 卻改變了,導致文件沒法使用緩存;
c. 有可能存在服務器沒有準確獲取文件修改時間,或者與代理服務器時間不一致等情形。
瀏覽器可以在內存、硬盤中開辟一個空間用于保存請求資源副本。我們經常調試時在 DevTools Network 里看到 Memory Cache(內存緩存)和 Disk Cache(硬盤緩存),指的就是緩存所在的位置。請求一個資源時,會按照優先級(Service Worker -> Memory Cache -> Disk Cache -> Push Cache)依次查找緩存,如果命中則使用緩存,否則發起請求。這里先介紹 Memory Cache 和 Disk Cache。
200 from memory cache
表示不訪問服務器,直接從內存中讀取緩存。因為緩存的資源保存在內存中,所以讀取速度較快,但是關閉進程后,緩存資源也會隨之銷毀,一般來說,系統不會給內存分配較大的容量,因此內存緩存一般用于存儲較小文件。同時內存緩存在有時效性要求的場景下也很有用(比如瀏覽器的隱私模式)。
200 from disk cache
表示不訪問服務器,直接從硬盤中讀取緩存。與內存相比,硬盤的讀取速度相對較慢,但硬盤緩存持續的時間更長,關閉進程之后,緩存的資源仍然存在。由于硬盤的容量較大,因此一般用于存儲大文件。
下圖可清晰看出差別:
200 from prefetch cache
在 preload 或 prefetch 的資源加載時,兩者也是均存儲在 http cache,當資源加載完成后,如果資源是可以被緩存的,那么其被存儲在 http cache 中等待后續使用;如果資源不可被緩存,那么其在被使用前均存儲在 memory cache。
CDN Cache
以騰訊 CDN 為例:X-Cache-Lookup:Hit From MemCache 表示命中 CDN 節點的內存;X-Cache-Lookup:Hit From Disktank 表示命中 CDN 節點的磁盤;X-Cache-Lookup:Hit From Upstream 表示沒有命中 CDN。
從上圖能感受到整個流程,比如常見兩種刷新場景:
IndexedDB 就是瀏覽器提供的本地數據庫,能夠在客戶端存儲可觀數量的結構化數據,并且在這些數據上使用索引進行高性能檢索的 API。
異步 API 方法調用完后會立即返回,而不會阻塞調用線程。要異步訪問數據庫,要調用 window 對象 indexedDB 屬性的 open() 方法。該方法返回一個 IDBRequest 對象 (IDBOpenDBRequest);異步操作通過在 IDBRequest 對象上觸發事件來和調用程序進行通信。
常用異步 API 如下:
在 16 年曾基于 IndexDB 做過一整套緩存策略,有不錯的優化效果:
SW 從 2014 年提出的草案到現在已經發展很成熟了,基于 SW 做離線緩存,讓用戶能夠進行離線體驗,消息推送體驗,離線緩存能力涉及到 Cache 和 CacheStorage 的概念,篇幅有限,不展開了。
localStorage 屬性允許你訪問一個 Document 源(origin)的對象 Storage 用于存儲當前源的數據,除非用戶人為清除(調用 localStorage api 或者清除瀏覽器數據), 否則存儲在 localStorage 的數據將被長期保留。
sessionStorage 屬性允許你訪問一個 session Storage 對象,用于存儲當前會話的數據,存儲在 sessionStorage 里面的數據在頁面會話結束時會被清除。頁面會話在瀏覽器打開期間一直保持,并且重新加載或恢復頁面仍會保持原來的頁面會話。
通過了解瀏覽器各種緩存機制和存儲能力特點,結合業務制定合適的緩存策略,善用緩存是基本功,可以用于時常審查負責的業務,可能就會發現個別業務并沒有運用到位,共勉。
近又快到了金三銀四的好日子了,有一天,小龍找到我說,小輝哥,我想跳槽了。原來公司加薪無望,目前只有 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 人以上的企業,流程基本一致,但是比較長??赡軙兴拿嫔踔廖?,六面的情況:
中小型公司,人數往往低于 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小時內與您取得聯系。