那些年你踩過的坑,都在這裏了~| 掘金技術徵文

前言

      前段時間面試(包括阿里巴巴的電話面試),遇到過一些試題,且面試中出現機率較高的提問/筆試,有些答的不是很好掛掉了,今天終於有時間整理出來分享給你們,內容主要分爲兩部分:面試中遇到的、在複習過程當中看到認爲值得加深鞏固的; 若有理解的錯誤或不足之處,歡迎留言糾錯、斧正,@IT·平頭哥聯盟∙首席填坑官,我是蘇南(South·Su) ^_^~javascript

HTML

一、什麼是盒子模型?

    有些面試官會問你對盒子模型的理解,在咱們平時看到的網頁中,內部的每個標籤元素它都是有幾個部分構成的:內容(content)、外邊距(margin)、內邊距(padding)、邊框(border),四個部分組成,當你說完這些面試官是不會滿意這個答案的,由於還有一個重點(IE盒模型和標準盒模型的區別)———IE盒模型的content包括border、paddingcss


二、頁面導入樣式時有幾種方法,它們之間有區別?
  • link標籤引入,也是當下用的最多的一種方式,它屬於XHTML標籤,除了能加載css外,還能定義rel、type、media等屬性;
  • @import引入,@import是CSS提供的,只能用於加載CSS;
  • style 嵌入方式引入,減小頁面請求(優勢),但只會對當前頁面有效,沒法複用、會致使代碼冗餘,不利於項目維護(缺點),此方式通常只會項目主站首頁使用(騰訊、淘寶、網易、搜狐)等大型網站主頁,以前有看到過都是這種方式,但後來有些也捨棄了;

  小結:link頁面被加載的時,link會同時被加載,而@import引用的CSS會等到頁面被加載完再加載,且link是XHTML標籤,無兼容問題; link支持動態js去控制DOM節點去改變樣式,而@import不支持,html

三、簡單講述一下塊元素、內聯元素、空元素有哪些,它們之間的區別?
  • 行內元素有:a、b、span、img、input、select、textarea、em、img、strong(強調的語氣);
  • 塊級元素有:ul、ol、li、dl、dt、dd、h一、h二、h三、h4…p、section、div、form等;
  • <br>、<hr>、<input type="hidden">、<link>、<meta>;

  小結:塊元素老是獨佔一行,margin對內聯元素上下不起做用; java

四、說說 cookies,sessionStorage 、 localStorage 你對它們的理解?
  • cookie是網站爲了標示用戶身份而儲存在用戶本地終端上的數據(一般通過加密),cookie數據始終在同源的http請求中攜帶,記會在瀏覽器和服務器間來回傳遞。 
  • sessionStorage和localStorage不會自動把數據發給服務器,僅在本地保存。
  • 大小: cookie數據大小不能超過4k。 sessionStorage和localStorage 雖然也有存儲大小的限制,但比cookie大得多,能夠達到5M或更大。
  •  時效: localStorage 存儲持久數據,瀏覽器關閉後數據不丟失除非用戶主動刪除數據或清除瀏覽器/應用緩存; sessionStorage 數據在當前瀏覽器窗口關閉後自動刪除。 cookie 設置的cookie過時時間以前一直有效,即便窗口或瀏覽器關閉
  • 部分面試官可能還會再深刻一些:

1)、如何讓cookie瀏覽器關閉就失效?——不對cookie設置任何正、負或0時間的便可;node

2)、sessionStorage在瀏覽器多窗口之間 (同域)數據是否互通共享? ——不會,都是獨立的,localStorage會共享;
css3

3)、能讓localStorage也跟cookie同樣設置過時時間?答案是能夠的,在存儲數據時,也存儲一個時間戳,get數據以前,先拿當前時間跟你以前存儲的時間戳作比較 詳細可看我以前寫的另外一篇分享(小程序項目總結)。
git


五、簡述一下你對HTML語義化的理解 ?
  • 語義化是指根據內容的類型,選擇合適的標籤(代碼語義化),即用正確的標籤作正確的事情; 
  • html語義化讓頁面的內容結構化,結構更清晰,有助於瀏覽器、搜索引擎解析對內容的抓取; 
  • 語義化的HTML在沒有CSS的狀況下也能呈現較好的內容結構與代碼結構; 
  • 搜索引擎的爬蟲也依賴於HTML標記來肯定上下文和各個關鍵字的權重,利於SEO;

CSS

一、position的static、relative、absolute、fixed它們的區別?
  • absolute:絕對定位,元素會相對於值不爲 static 的第一個父元素進行定位(會一直往父級節點查找),且它是脫離正常文檔流、不佔位的; fixed:一樣是絕對定位,但元素會相對於瀏覽器窗口進行定位,而不是父節點的position (IE9如下不支持); 
  • relative:相對定位,元素相對於自身正常位置進行定位,屬於正常文檔流;
  • static: position的默認值,也就是沒有定位,當元素設置該屬性後( top、bottom、left、right、z-index )等屬性將失效; 
  • inherit:貌似沒用過,查了一下文檔「規定從父元素繼承 position 屬性的值」;
一、如何讓一個元素垂直/水平(垂直水平)都居中,請列出你能想到的幾種方式?
  • 水平垂直居中 —— 方式一

<div class="div-demo"></div>
<style>
	.div-demo{
		width:100px;
		height:100px;
		background-color:#06c;
		margin: auto;
		position:absolute;
		top: 0;
		left: 0;
		bottom: 0;
		right: 0;
	}
</style>複製代碼
  • 水平垂直居中 —— 方式二
<style>
	.div-demo{
		width:100px;
		height:100px;
		background-color:#06c;
		margin: auto;
		position:absolute;
		top: 50%;
		left: 50%;
		transform: translate(-50%,-50%);
		-webkit-transform: translate(-50%,-50%);
	}
</style>複製代碼

<body class="container">
	<div class="div-demo"></div>
	<style>

		html,body{
			height:100%;
		}
		.container{
			display: box;
			display: -webkit-box;
			display: flex;
			display: -webkit-flex;
			-webkit-box-pack: center;
			-webkit-justify-content: center;
			justify-content: center;
			-webkit-box-align: center;
			-webkit-align-items: center;
			align-items: center;
		}
		.div-demo{
			width:100px;
			height:100px;
			background-color:#06c;
		}
	</style>

</body>複製代碼
三、項目中有用純CSS樣式寫過 三角形icon嗎?

<body class="container">
	<div class="div-angles"></div>
	<div class="div-angles right"></div>
	<div class="div-angles bottom"></div>
	<div class="div-angles left"></div>
	<style>

		html,body{
			height:100%;
		}
		.container{
			display: box;
			display: -webkit-box;
			display: flex;
			display: -webkit-flex;
			-webkit-box-pack: center;
			-webkit-justify-content: center;
			justify-content: center;
			-webkit-box-align: center;
			-webkit-align-items: center;
			align-items: center;
		}
		.div-angles{
			width: 0;
			height: 0;
			border-style: solid;
			border-width:30px;
			width:0px;
			height:0px;
			border-color: transparent transparent #06c transparent;
		}
		.right{
			border-color: transparent transparent transparent #06c ;
		}
		.bottom{
			border-color: #06c transparent transparent ;
		}
		.left{
			border-color: transparent #06c transparent transparent;
		}
	</style>

</body>
複製代碼


四、什麼是外邊距合併,項目中是否有遇到過?
  • 有,外邊距合併指的是,當兩個垂直元素的都設置有margin外邊距相遇時,它們將造成一個外邊距。 合併後的外邊距的高度等於兩個發生合併的外邊距的值中的較大那個。
五、:before 和 :after兩僞元素,平時都是使用雙冒號仍是單冒號? 有什麼區別?以及它們的做用:
  • 單冒號(:)用於CSS3僞類,雙冒號(::)用於CSS3僞元素。(僞元素由雙冒號和僞元素名稱組成) ;
  • 雙冒號是在當前規範中引入的,用於區分僞類和僞元素。不過瀏覽器須要同時支持舊的已經存在的僞元素寫法, 好比:first-line、:first-letter、:before、:after等, 而新的在CSS3中引入的僞元素則不容許再支持舊的單冒號的寫法;
  • 想讓插入的內容出如今其它內容前,使用::before,以後則使用::after; 
  • 在代碼順序上,::after生成的內容也比::before生成的內容靠後。 若是按堆棧視角,::after生成的內容會在::before生成的內容之上; 
六、Chrome、Safari等瀏覽器,當表單提交用戶選擇記住密碼後,下次自動填充表單的背景變成黃色,影響了視覺體驗是否能夠修改?

input:-webkit-autofill, textarea:-webkit-autofill, select:-webkit-autofill {
  background-color: #fff;//設置成元素本來的顏色
  background-image: none;
  color: rgb(0, 0, 0);
}
//方法2:由掘金大神 (licongwen )補充
input:-webkit-autofill {
    -webkit-box-shadow: 0px 0 3px 100px #ccc inset; //背景色
}複製代碼
七、瀏覽器的最小字體爲12px,若是還想再小,該怎麼作?

  • 用圖片:若是是展現的內容基本是固定不變的話,能夠直接切圖兼容性也完美(不到萬不得已,不建議);
  • 找UI設計師溝通:爲了兼容各大主流瀏覽器,避免後期設計師來找你撕逼,主動找TA溝通,講明緣由 ————注意語氣,好好說話不要激動,更不能攜刀相逼;
  • CSS3:css3的樣式transform: scale(0.7),scale有縮放功能;
  • 又去找chrome複習了一下,說是 「display:table;display: table-cell;」 能夠作到,沒用過。
八、移動端的邊框0.5px,你有幾種方式實現?
  • devicePixelRatio:它是window對象中有一個devicePixelRatio屬性,設備物理像素和設備獨立像素的比例,也就是 devicePixelRatio = 物理像素 / 獨立像素;這種方式好麻煩,js檢測,再給元素添加類名控制,難維護; 
  • 切圖:直接.5px的切圖,這種方式太low,建議仍是別用了,特別難維護,高清屏就糊了,更重要的是被同行看到會以爲大家很渣渣~;
  • image背景:css3的background-image:linear-gradient,缺點就是:樣式多,遇到圓角這個方案就杯劇了; 
  • box-shadow:網上看到說使用box-shadow模擬邊框,box-shadow: inset 0px -1px 1px -1px #06c;沒用過,不過多評論,建議本身百度; 
  • 僞類縮放:如今用的比較多的方式之一 :after 1px而後transform: scale(0.5);基本能知足全部場景,對於圓角的處理也很方便 
  • 貼上三、5兩方案代碼,也是目前公司一直在用的:

//三、css3的background-image
@mixin border($top:1, $right:1, $bottom:1, $left:1, $color:#ebebf0) {
  background-image:linear-gradient(180deg, $color, $color 50%, transparent 50%), 
                  linear-gradient(90deg, $color, $color 50%, transparent 50%), 
                  linear-gradient(0deg, $color, $color 50%, transparent 50%),
                  linear-gradient(90deg, $color, $color 50%, transparent 50%);
  background-size: 100% $top + px, $right + px 100%, 100% $bottom + px, $left + px 100%;
  background-repeat: no-repeat;
  background-position: top, right top, bottom, left top ;
}

@mixin borderTop($top:1, $color:#ebebf0) {
  @include border($top, 0, 0, 0, $color);
}
@mixin borderRight($right:1, $color:#ebebf0) {
  @include border(0, $right, 0, 0, $color);
}
@mixin borderBottom($bottom:1, $color:#ebebf0) {
  @include border(0, 0, $bottom, 0, $color);
}
@mixin borderLeft($left:1, $color:#ebebf0) {
  @include border(0, 0, 0, $left, $color);
}
@mixin borderColor($color:#ebebf0) {
  @include border(1, 1, 1, 1, $color);
}

//五、css3的transform:scale,首席填坑官∙蘇南的專欄,梅斌的專欄
@mixin borderRadius($width:1,$style:solid,$color:#ebebf0,$radius:2px) {
  position:relative;
    &:after{
       left:0px;
       top:0px;
       right:-100%;
       bottom:-100%;
       border-radius:$radius;
       border-style: $style;
       border-color: $color;
       border-width: $width+ px;
       position:absolute;
       display:block;
       transform:scale(0.5);
       -webkit-transform:scale(0.5);
       transform-origin:0 0;
       -webkit-transform-origin:0 0;
       content:'';
    }
}複製代碼

Javascript

一、請將下列b函數進行修改,保證每次調用a都能+1(考閉包):

function b(){
	var a=1;
};

function b(){
	var a=1;
	return ()=>{
		a++;
		return a;
	}
};
let c = b();
c(); //2
c(); //3
c(); //4複製代碼
二、js有哪些基本數據類型:
   ECMAScript 標準定義有7種數據類型: 
  •  Boolean 
  •  Null 
  •  Undefined 
  •  Number 
  •  String 
  •  Symbol :(ECMAScript 6 新定義 ,Symbol 生成一個全局惟1、表示獨一無二的值)
  •  Object :(ArrayFunctionObject
三、用js將 386485473.88 轉換爲 386,485,473.88(千位分割符):

//方法1:首席填坑官∙蘇南的專欄,梅斌的專欄
var separator=(num)=>{
	if(!num){
		return '0.00';
	};
	let str = parseFloat(num).toFixed(2);
	return str && str
		.toString()
		.replace(/(\d)(?=(\d{3})+\.)/g, function($0, $1) {
			return $1 + ",";
		});
}

separator(386485473.88) //"386,485,473.88"

//方法2:
(386485473.88).toLocaleString('en-US')  // "386,485,473.88" 由掘金大神 (sRect)補充 複製代碼
四、js的 for 跟for in 循環它們之間的區別?
  • 遍歷數組時的異同: for循環 數組下標的typeof類型:number, for in 循環數組下標的typeof類型:string

var southSu = ['蘇南','深圳','18','男'];
for(var i=0;i<southSu.length;i++){
	console.log(typeof i); //number
	console.log(southSu[i]);// 蘇南 , 深圳 , 18 , 男
}
var arr = ['蘇南','深圳','18','男','帥氣'];
for(var k in arr){
	console.log(typeof k);//string
	console.log(arr[k]);// 蘇南 , 深圳 , 18 , 男 , 帥氣
}
複製代碼
  • 遍歷對象時的異同:for循環 沒法用於循環對象,獲取不到obj.length; for in 循環遍歷對象的屬性時,原型鏈上的全部屬性都將被訪問,解決方案:使用hasOwnProperty方法過濾或Object.keys會返回自身可枚舉屬性組成的數組 

Object.prototype.test = '原型鏈上的屬性';//首席填坑官∙蘇南的專欄,梅斌的專欄
var southSu = {name:'蘇南',address:'深圳',age:18,sex:'男',height:176};
for(var i=0;i<southSu.length;i++){
	console.log(typeof i); //空
	console.log(southSu[i]);//空
}


for(var k in southSu){
	console.log(typeof k);//string
	console.log(southSu[k]);// 蘇南 , 深圳 , 18 , 男 , 176 , 原型鏈上的屬性
} 複製代碼

五、給table表格中的每一個td綁定事件,td數量爲1000+,寫一下你的思路(事件委託題):

<body class="container">
	<table id="table">
		<tr><td>1</td><td>3</td><td>3</td><td>4</td><td>5</td></tr>
		<tr><td>1</td><td>3</td><td>3</td><td>4</td><td>5</td></tr>
		<tr><td>1</td><td>3</td><td>3</td><td>4</td><td>5</td></tr>
		…………
	</table>
<script>
	let table =document.querySelector("#table");
	table.addEventListener("click",(e)=>{
		let {nodeName} = e.target;
		if(nodeName.toUpperCase() === "TD"){
			console.log(e.target);//<td>N</td>
		}
	},false);

</script>
</body> 複製代碼

五、js把一串字符串去重(能統計出字符重複次數更佳),列出你的思路(兩種以上):

<script>
	let str = "12qwe345671dsfa233dsf9876ds243dsaljhkjfzxcxzvdsf";
	let array = str.split("");

	//方案一:
	array = [...new Set(array)].join("");
	array = ((a)=>[...new Set(a)])(array).join("");
	console.log(array);//12qwe34567dsfa98ljhkzxcv  只能過濾,不會統計

	//方案二:
	function unique (arr) {
		const seen = new Map()
		return (arr.filter((a) => !seen.has(a) && seen.set(a, 1))).join("");
	}
	console.log(unique(array)) // 12qwe34567dsfa98ljhkzxcv

	//方案三:
	function unique (arr) {
		let arrs=[];
		var news_arr = arr.sort();//排序能減小一次循環
		for(var i=0;i<news_arr.length;i++){
				if(news_arr[i] == news_arr[i+1] && news_arr[i]!= news_arr[i-1] ){
						arrs.push(arr[i]);
				};
 
		};
		return arrs.join("");
	}
	console.log(unique(array)) // 12qwe34567dsfa98ljhkzxcv

	//方案四:
	function unique (arr) {
		let obj={};
		for(var i=0;i<arr.length;i++){
			let key = arr[i];
			if(!obj[key] ){
					obj[key]=1;
			}else{
				obj[key]+=1;
			}
 
		};
		return obj;
	}
	console.log(unique(array)) // object 對應每一個key以及它重複的次數 

</script> 複製代碼

六、項目上線前,大家作過哪些性能優化:
  • 圖片預加載,css樣式表放在頂部且link鏈式引入,javascript放在底部body結束標籤前;
  • 使用dns-prefetch對項目中用到的域名進行 DNS 預解析,減小 DNS 查詢,如: <link rel="dns-prefetch" href="//github.com"/>; 
  • 減小http請求次數:圖片靜態資源使用CDN託管;API接口數據設置緩存,CSS Sprites/SVG Sprites(若有疑惑:該如何以正確的姿式插入SVG Sprites?這篇說的很詳細), JS、CSS源碼壓縮、圖片大小控制合適,使用iconfont(字體圖標)或SVG,它們比圖片更小更清晰,網頁Gzip壓縮;
  • 減小DOM操做次數,優化javascript性能;
  • 減小 DOM 元素數量,合理利用:after、:before等僞類;
  • 避免重定向、圖片懶加載;
  • 先後端分離開發,資源按需加載,最好能作到首屏直出(即服務端渲染); 
  • 避免使用CSS Expression(css表達式)又稱Dynamic properties(動態屬性) ;
  • 多域名分發劃份內容到不一樣域名,解決瀏覽器域名請求併發數問題,同時也解決了請求默認攜帶的cookie問題;
  • 儘可能減小 iframe 使用,它會阻塞主頁面的渲染; 
  • 對全部資源壓縮 JavaScriptCSS 、字體、圖片等,甚至html;
  • 只想到這些,歡迎補充……
七、你對重繪、重排的理解?
  • 首先網頁數次渲染生成時,這個可稱爲重排; 
  • 修改DOM、樣式表、用戶事件或行爲(鼠標懸停、頁面滾動、輸入框鍵入文字、改變窗口大小等等)這些都會致使頁面從新渲染,那麼從新渲染,就須要從新生成佈局和從新繪製節點,前者叫作"重排",後者"重繪"; 
  • 減小或集中對頁面的操做,即屢次操做集中在一塊兒執行; 
  • 總之能夠簡單總結爲:重繪不必定會重排,但重排必然爲會重繪。
  •  更詳細的能夠看阮老師分析
八、有用過promise嗎?請寫出下列代碼的執行結果,並寫出你的理解思路:

setTimeout(()=>{
		console.log(1);
}, 0);

new Promise((resolve)=>{
		console.log(2);
		for(var i = 1; i < 200; i++){
				i = 198 && resolve();
		}
		console.log(3);
}).then(()=>{
		console.log(4);
});
console.log(5);

// 結果:二、三、五、四、1;複製代碼
  • 首先要講一下,js是單線程執行,那麼代碼的執行就有前後; 
  • 有前後,那就要有規則(排隊),否則就亂套了,那麼如何分前後呢?大致分兩種:同步、異步; 
  • 同步很好理解,就不用多說了(我就是老大,大家都要給我讓路); 
  • 異步(定時器[setTimeout setInterval]、事件、ajaxpromise等),說到異步又要細分宏任務、微任務兩種機制,
  •   宏任務:js異步執行過程當中遇到宏任務,就先執行宏任務,將宏任務加入執行的隊列(event queue),而後再去執行微任務;
  •   微任務:js異步執行過程當中遇到微任務,也會將任務加入執行的隊列(event queue),可是注意這兩個queue身份是不同的,不是你先進來,就你先出去的(就像宮裏的皇上選妃侍寢同樣,不是你先進宮(或先來排隊)就先寵幸的 ),真執行的時候是先微任務裏拿對應回調函數,而後才輪到宏任務的隊列回調執行的; 
  • 理解了這個順序,那上面的結果也就不難懂了。
setTimeout 是異步,不會當即執行,加入執行隊列; 
new Promise 會當即執行 輸出 二、3,而在二、3之間執行了resolve 也就是微任務;
再到console.log(5)了,輸出5;
而後異步裏的微任務先出,那就獲得4;
最後執行宏任務 setTimeout 輸出 1,
若有錯誤歡迎糾正!
九、new SouthSu() 在這個過程當中都作了些什麼?

function SouthSu(){
 		this.name = "蘇南";
 		this.age = 18;
 		this.address = "深圳";
};

 let South = new SouthSu();
 console.log(South,South.__proto__ === SouthSu.prototype) //true 

執行過程:
建立一個空的對象
 let p1 = new Object();


設置原型鏈
	p1.__proto__ = SouthSu.prototype;

讓 構造函數 的this 指向 p1 這個空對象

	let funCall = SouthSu.call(p1);

處理 構造函數 的返回值:判斷SouthSu的返回值類型,若是是值類型則返回obj,若是是引用類型,就返回這個引用類型的對象; 複製代碼

十、工做中若是讓你使用js實現一個持續的動畫,你會怎麼作(好比轉盤抽獎)??
  • js來實現動畫,第一時間想到的就是定時器(setTimeoutsetInterval); 
  • 後面想起來js有個 window.requestAnimationFrame ,當時只是說了記得有這麼一個API,具體的細節沒能答上,面試官直言想聽的就是這個API的使用,好吧是我準備的不夠充分,但願其餘同窗再也不犯一樣錯誤;
window.requestAnimationFrame() 方法告訴瀏覽器您但願執行動畫並請求瀏覽器在下一次重繪以前調用指定的函數來更新動畫。該方法使用一個回調函數做爲參數,這個回調函數會在瀏覽器重繪以前調用,回調的次數一般是每秒60次,是大多數瀏覽器一般匹配 W3C 所建議的刷新頻率。在大多數瀏覽器裏,當運行在後臺標籤頁或者隱藏的< iframe> 裏時, requestAnimationFrame() 會暫停調用以提高性能和電池壽命。
小結:以往項目開發中大數人可能都是第一時間選擇JS定時器 setInterval 或者 setTimeout 來控制的動畫每隔一段時間刷新元素的狀態,來達到本身所想要的動畫效果,可是這種方式並不能準確地控制動畫幀率,由於這是開發者主動要求瀏覽器去繪製,它這可能會由於動畫控制的時間、繪製的頻率、瀏覽器的特性等而致使丟幀的問題; requestAnimationFrame 是瀏覽器何時要開始繪製了瀏覽器它本身知道,經過 requestAnimationFrame告訴咱們,這樣就不會出現重複繪製丟失的問題。

//一個持續旋轉的正方形,
<div class="angle-div"></div>
<script>
	let timer = null;
	let Deg = 0;
	let distance = 360;
	var _requestAnimationFrame_ = window.requestAnimationFrame || window.webkitRequestAnimationFrame;
	let angleDiv = document.querySelector(".angle-div");
	cancelAnimationFrame(timer);
	let fn = ()=>{
		if(Deg < distance){ 
			Deg++;
		}else{
			Deg=0;
		};
		angleDiv.style.transform = `rotateZ(${Deg}deg) translateZ(0)`; 
		angleDiv.style.WebkitTransform = `rotateZ(${Deg}deg) translateZ(0)`;
		timer = _requestAnimationFrame_(fn);
	}
	timer = _requestAnimationFrame_(fn);
</script>
複製代碼



十一、如何設置http緩存?

1)、Expires github

  • Expires的值爲服務端返回的到期時間,響應時告訴瀏覽器能夠直接從瀏覽器緩存中讀取無需再次請求。 缺點:返回的是服務端的時間,比較的時間是客戶端的時間,若是時間不一致有可能出現錯誤。  

2)、Cache-Controlweb

  • Cache-Control可設置的字段有:
  • private:客戶端能夠緩存
  • public:客戶端和代理服務器均可以緩存
  • max-age=xxx:緩存內容在xxx秒後失效
  • no-cache:須要用另外一種緩存策略來驗證緩存(ETag,Last-Modified)
  • no-store:不進行緩存
  • Last-Modified:瀏覽器請求得到文件後,服務器返回該文件的最後修改時間Last-Modified,下一次請求會帶上If-Modified-Since標識,若是If-Modified-Since等於服務器的文件修改時間,則表示文件沒有修改,返回304狀態碼,瀏覽器從瀏覽器緩存中讀取文件。若是If-Modified-Since小於服務端的文件修改時間,則瀏覽器會從新發送請求獲取文件,返回狀態碼200。
  • ETag:服務器文件的一個惟一標識,例如對文件內容取md5值做爲ETag的字段返回給瀏覽器。當文件變化時ETag的值也會發生變化。下次請求會帶上If-None-Match即瀏覽器保留的ETag值,若是發送了變化,則文件被修改,須要從新請求,返回200狀態碼。反之瀏覽器就從緩存中讀取文件,返回304狀態碼。

總結:——幾者之間的關係
  • Cache-Control設置爲max-age=xx而且同事設置Expires時,Cache-Control的優先級更高
  • ETagLast-Modified同時存在時,服務器先會檢查ETag,而後再檢查Last-Modified,最終決定返回304仍是200 
  • 該題由 本文由平頭哥聯盟-成員(ZodiacSyndicate )補充


十二、隨機打亂一個數組

  • 思路:從數組的最後一項開始,隨機選擇前面的一個元素進行交換,而後一步步往前交換

//該題由 本文由平頭哥聯盟-成員(ZodiacSyndicate )補充
const shuffle = arr => {
  let end = arr.length - 1
  while(end) { // 當end爲0時不須要交換
    const index = Math.floor(Math.random() * (end + 1))
    [arr[index], arr[end]] = [arr[end], arr[index]]
    end -= 1
  }
  return arr
}
複製代碼

1三、用React實現一個顯示鼠標位置的高階組件

//該題由 本文由平頭哥聯盟-成員(ZodiacSyndicate )補充
const mousePosition = Component => class extends React.Component {
  state = {
    x: 0,
    y: 0,
  }

  handleMouseMove = e => {
    this.setState({
      x: e.clientX,
      y: e.clientY
    })
  }

  render() {
    const { x, y } = this.state
    return (
      <>
        <div onMouseMove={this.handleMouseMove}>
          <Component {...this.props} />
        </div>
        <span>x: {x}</span>
        <span>y: {y}</span>
      </>
    )
  }
}
複製代碼


js的部份內容還在整理中,將會持續更新面試



特別鳴謝: licongwensRect 、ZodiacSyndicate等掘金大神的補充;

  最近纔在開始嘗試寫博客,新手上路中,若是文章中有不對之處,煩請各位大神斧正。若是你以爲這篇文章對你有所幫助,請記得點贊哦~,想了解我更多?歡迎關注下方公衆號。



做者:蘇南 - 首席填坑官
交流羣:912594095,公衆號: honeyBadger8
本文原創,著做權歸做者全部。商業轉載請聯繫 @IT·平頭哥聯盟得到受權,非商業轉載請註明原連接及出處。


本次徵文活動的連接👉秋招求職時,寫文就有好禮相送|掘金技術徵文

相關文章
相關標籤/搜索