一般性知识
+profile:輪廓
repository:存儲庫
codespaces:碼空間
gists:要點
feature preview:功能預(yù)覽
一、元素類型
塊元素:、
、
…
、
- 、、、、、
1、支持全部的樣式
2、如果沒有設(shè)置寬度,默認(rèn)的寬度為父級的100%
3、占據(jù)一行
內(nèi)聯(lián)元素(行內(nèi)元素):a、span、em、b、strong、i
1、不支持寬、高、margin上下、padding上下
2、寬高由內(nèi)容決定
3、盒子并在一行
4、代碼換行,盒子之間會產(chǎn)生間隙
5、子元素是內(nèi)聯(lián)元素,父元素可以用text-align屬性設(shè)置子元素水平對方方式
內(nèi)聯(lián)塊元素(行內(nèi)塊元素):
用display屬性將塊元素或者內(nèi)聯(lián)元素轉(zhuǎn)化成這種元素
1、支持全部樣式
2、如果沒有設(shè)置寬高,寬高由內(nèi)容決定
3、盒子并在一起
4、代碼換行盒子會并在一起
5、用text-align屬性設(shè)置子元素水平對齊方式。
二、優(yōu)先級
- 千位: 如果聲明在 style 的屬性(內(nèi)聯(lián)樣式)則該位得一分。這樣的聲明沒有選擇器,所以它得分總是1000。
- 百位: 選擇器中包含ID選擇器則該位得一分。
- 十位: 選擇器中包含類選擇器、屬性選擇器或者偽類則該位得一分。
- 個位:選擇器中包含元素、偽元素選擇器則該位得一分。
三、自適應(yīng)(media響應(yīng)式布局)
四、BFC是什么?
BFC塊級格式化上下文,屬于定位方案中的普通流(標(biāo)準(zhǔn)流),具有 BFC 特性的元素可以看作是隔離了的獨(dú)立容器,容器里面的元素不會在布局上影響到外面的元素,并且 BFC 具有普通容器所沒有的一些特性。
觸發(fā) BFC 特性:
- body 根元素
- 浮動元素:float 除 none 以外的值
- 絕對定位元素:position (absolute、fixed)
- display 為 inline-block、table-cells、flex
- overflow 除了 visible 以外的值 (hidden、auto、scroll)
1. 同一個 BFC 下外邊距會發(fā)生折疊
如果想要避免外邊距的重疊,可以將其放在不同的 BFC 容器中。
2. BFC 可以包含浮動的元素(清除浮動)
3. BFC 可以阻止元素被浮動元素覆蓋(eg:文字環(huán)繞效果)
五、IEM、EM、是什么?
六、JavaScript中的常見六種繼承方式
1、原型鏈繼承
這種方式關(guān)鍵在于:子類型的原型為父類型的一個實例對象
JavaScript 對象有一個指向一個原型對象的鏈。當(dāng)試圖訪問一個對象的屬性時,它不僅僅在該對象上搜尋,還會搜尋該對象的原型,以及該對象的原型的原型,依次層層向上搜索,直到找到一個名字匹配的屬性或到達(dá)原型鏈的末尾。
特點:
- 父類新增原型方法/原型屬性,子類都能訪問到
- 簡單,易于實現(xiàn)
缺點:
- 無法實現(xiàn)多繼承
- 來自原型對象的所有屬性被所有實例共享
- 創(chuàng)建子類實例時,無法向父類構(gòu)造函數(shù)傳參
- 要想為子類新增屬性和方法,必須要在Student.prototype = new Person() 之后執(zhí)行,不能放到構(gòu)造器中
2、借用構(gòu)造函數(shù)繼承
這種方式關(guān)鍵在于:在子類型構(gòu)造函數(shù)中通過call()調(diào)用父類型構(gòu)造函數(shù)
特點:
- 解決了原型鏈繼承中子類實例共享父類引用屬性的問題
- 創(chuàng)建子類實例時,可以向父類傳遞參數(shù)
- 可以實現(xiàn)多繼承(call多個父類對象)
缺點:
- 實例并不是父類的實例,只是子類的實例
- 只能繼承父類的實例屬性和方法,不能繼承原型屬性和方法
- 無法實現(xiàn)函數(shù)復(fù)用,每個子類都有父類實例函數(shù)的副本,影響性能
3、原型鏈+借用構(gòu)造函數(shù)繼承
這種方式關(guān)鍵在于:通過調(diào)用父類構(gòu)造,繼承父類的屬性并保留傳參的優(yōu)點,然后通過將父類實例作為子類原型,實現(xiàn)函數(shù)復(fù)用。
優(yōu)點:
- 可以繼承實例屬性/方法,也可以繼承原型屬性/方法
- 不存在引用屬性共享問題
- 可傳參
- 函數(shù)可復(fù)用
缺點:
- 調(diào)用了兩次父類構(gòu)造函數(shù),生成了兩份實例
4、ES6中的class繼承
需要注意的是,class關(guān)鍵字只是原型的語法糖,JavaScript繼承仍然是基于原型實現(xiàn)的。
ES6中引入了class關(guān)鍵字,class可以通過extends關(guān)鍵字實現(xiàn)繼承,還可以通過static關(guān)鍵字定義類的靜態(tài)方法,這比 ES5 的通過修改原型鏈實現(xiàn)繼承,要清晰和方便很多。
ES5 的繼承,實質(zhì)是先創(chuàng)造子類的實例對象this,然后再將父類的方法添加到this上面(Parent.apply(this))。ES6 的繼承機(jī)制完全不同,實質(zhì)是先將父類實例對象的屬性和方法,加到this上面(所以必須先調(diào)用super方法),然后再用子類的構(gòu)造函數(shù)修改this。
七、判斷數(shù)組的方法
① instanceof 操作符判斷
arr instanceof Array②對象構(gòu)造函數(shù)的 constructor判斷
arr.constructor === Array③Array 原型鏈上的 isPrototypeOf
(Array.prototype.isPrototypeOf(arr)④Object.getPrototypeOf
Object.getPrototypeOf(arr) === Array.prototype⑤Object.prototype.toString
Object.prototype.toString.call(arr) === '[object Array]'⑥Array.isArray
Array.isArray(arr)八、隱式轉(zhuǎn)換
true == 1 // true
九、this指向
1、全局上下文
無論是否在嚴(yán)格模式下,在全局執(zhí)行環(huán)境中(在函數(shù)體外部),this都指向全局對象。
2、函數(shù)上下文
在函數(shù)內(nèi)部,this的值取決于函數(shù)被調(diào)用的方式,
因為下面的代碼不在嚴(yán)格模式下,且 this 的值不是由該調(diào)用設(shè)置的,所以 this 的值默認(rèn)指向全局對象,瀏覽器中就是 window。
function f1(){return this; } //在瀏覽器中: f1() === window; //在瀏覽器中,全局對象是window//在Node中: f1() === globalThis;然而,在嚴(yán)格模式下,如果進(jìn)入執(zhí)行環(huán)境時沒有設(shè)置 this 的值,this 會保持為 undefined,如下:
function f2(){"use strict"; // 這里是嚴(yán)格模式return this; }f2() === undefined; // true3、類上下文
this 在 類 中的表現(xiàn)與在函數(shù)中類似,因為類本質(zhì)上也是函數(shù),但也有一些區(qū)別和注意事項。
在類的構(gòu)造函數(shù)中,this 是一個常規(guī)對象。類中所有非靜態(tài)的方法都會被添加到 this 的原型中:
十、事件循環(huán)
JavaScript有一個基于事件循環(huán)的并發(fā)模型,事件循環(huán)負(fù)責(zé)執(zhí)行代碼、收集和處理事件以及執(zhí)行隊列中的子任務(wù)。
在 事件循環(huán) 期間的某個時刻,運(yùn)行時會從最先進(jìn)入隊列的消息開始處理隊列中的消息。被處理的消息會被移出隊列,并作為輸入?yún)?shù)來調(diào)用與之關(guān)聯(lián)的函數(shù)。
之所以稱之為 事件循環(huán),是因為它經(jīng)常按照類似如下的方式來被實現(xiàn):
while (queue.waitForMessage()) {queue.processNextMessage(); }queue.waitForMessage() 會同步地等待消息到達(dá)(如果當(dāng)前沒有任何消息等待被處理)。
“執(zhí)行至完成”
每一個消息完整地執(zhí)行后,其它消息才會被執(zhí)行。這為程序的分析提供了一些優(yōu)秀的特性,包括:當(dāng)一個函數(shù)執(zhí)行時,它不會被搶占,只有在它運(yùn)行完畢之后才會去運(yùn)行任何其他的代碼,才能修改這個函數(shù)操作的數(shù)據(jù)。這與C語言不同,例如,如果函數(shù)在線程中運(yùn)行,它可能在任何位置被終止,然后在另一個線程中運(yùn)行其他代碼。
這個模型的一個缺點在于當(dāng)一個消息需要太長時間才能處理完畢時,Web應(yīng)用程序就無法處理與用戶的交互,例如點擊或滾動。為了緩解這個問題,瀏覽器一般會彈出一個“這個腳本運(yùn)行時間過長”的對話框。一個良好的習(xí)慣是縮短單個消息處理時間,并在可能的情況下將一個消息裁剪成多個消息。
添加消息
在瀏覽器里,每當(dāng)一個事件發(fā)生并且有一個事件監(jiān)聽器綁定在該事件上時,一個消息就會被添加進(jìn)消息隊列。如果沒有事件監(jiān)聽器,這個事件將會丟失。所以當(dāng)一個帶有點擊事件處理器的元素被點擊時,就會像其他事件一樣產(chǎn)生一個類似的消息。
函數(shù) setTimeout 接受兩個參數(shù):待加入隊列的消息和一個時間值(可選,默認(rèn)為 0)。這個時間值代表了消息被實際加入到隊列的最小延遲時間。如果隊列中沒有其它消息并且棧為空,在這段延遲時間過去之后,消息會被馬上處理。但是,如果有其它消息,setTimeout 消息必須等待其它消息處理完。因此第二個參數(shù)僅僅表示最少延遲時間,而非確切的等待時ewq間。
十一、事件監(jiān)聽
十二、事件機(jī)制
十三、事件冒泡+捕獲
事件冒泡和捕捉是兩種機(jī)制,主要描述當(dāng)在一個元素上有兩個相同類型的事件處理器被激活會發(fā)生什么。
事件捕獲的思想是不太具體的節(jié)點應(yīng)該更早接收到事件,而最具體的節(jié)點應(yīng)該最后接收到事件。事件捕獲的用意在于在事件到達(dá)預(yù)定目標(biāo)之前就捕獲它。IE9+、Safari、Chrome、Opera和Firefox支持,且從window開始捕獲(盡管DOM2級事件規(guī)范要求從document)。由于老版本瀏覽器不支持,所以很少有人使用事件捕獲。
IE的事件流叫做事件冒泡(event bubbling),即事件開始時由最具體的元素(文檔中嵌套層次最深的那個節(jié)點)接收,然后逐級向上傳播到較為不具體的節(jié)點(文檔)。所有現(xiàn)代瀏覽器都支持事件冒泡,并且會將事件一直冒泡到window對象。
對于事件代理來說,在事件捕獲或者事件冒泡階段處理并沒有明顯的優(yōu)劣之分,但是由于事件冒泡的事件流模型被所有主流的瀏覽器兼容,從兼容性角度來說還是建議大家使用事件冒泡模型。
事件委托:
事件委托顧名思義:將事件委托給另外的元素。其實就是利用DOM的事件冒泡原理,將事件綁定到目標(biāo)元素的父節(jié)點。
如果要為大量的元素節(jié)點綁定事件,完美可以用事件委托完美解決,直接將事件綁定在這些元素的父節(jié)點上,只需要綁定一次,就可以在所有子節(jié)點觸發(fā)事件。
十四、argument用法
它是一個對象,包含函數(shù)運(yùn)行時的實參列表
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-Rcaix62f-1634800242306)(C:\Users\hzf\AppData\Roaming\Typora\typora-user-images\image-20210820193457604.png)]
arguments收集所有的實參,即使沒有與之對應(yīng)的形參
十五、promise
Promise 對象用于表示一個異步操作的最終完成 (或失敗)及其結(jié)果值。它讓我們能夠把異步操作最終的成功返回值或者失敗原因和相應(yīng)的處理程序關(guān)聯(lián)起來。 這樣使得異步方法可以像同步方法那樣返回值:異步方法并不會立即返回最終的值,而是會返回一個 promise,以便在未來某個時候把值交給使用者。
一個 Promise 必然處于以下幾種狀態(tài)之一:
- 待定(pending): 初始狀態(tài),既沒有被兌現(xiàn),也沒有被拒絕。
- 已兌現(xiàn)(fulfilled): 意味著操作成功完成。
- 已拒絕(rejected): 意味著操作失敗。
待定狀態(tài)的 Promise 對象要么會通過一個值被兌現(xiàn)(fulfilled),要么會通過一個原因(錯誤)被拒絕(rejected)。當(dāng)這些情況之一發(fā)生時,我們用 promise 的 then 方法排列起來的相關(guān)處理程序就會被調(diào)用。如果 promise 在一個相應(yīng)的處理程序被綁定時就已經(jīng)被兌現(xiàn)或被拒絕了,那么這個處理程序就會被調(diào)用,因此在完成異步操作和綁定處理方法之間不會存在競爭狀態(tài)。
[Promise的鏈?zhǔn)秸{(diào)用]
我們可以用 promise.then(),promise.catch() 和 promise.finally() 這些方法將進(jìn)一步的操作與一個變?yōu)橐亚枚顟B(tài)的 promise 關(guān)聯(lián)起來。這些方法還會返回一個新生成的 promise 對象,這個對象可以被非強(qiáng)制性的用來做鏈?zhǔn)秸{(diào)用,
鏈?zhǔn)秸{(diào)用中的 promise 們就像俄羅斯套娃一樣,是嵌套起來的,但又像是一個棧,每個都必須從頂端被彈出。鏈?zhǔn)秸{(diào)用中的第一個 promise 是嵌套最深的一個,也將是第一個被彈出的。
[創(chuàng)建Promise]
Promise 對象是由關(guān)鍵字 new 及其構(gòu)造函數(shù)來創(chuàng)建的。該構(gòu)造函數(shù)會把一個叫做“處理器函數(shù)”(executor function)的函數(shù)作為它的參數(shù)。這個“處理器函數(shù)”接受兩個函數(shù)——resolve 和 reject ——作為其參數(shù)。當(dāng)異步任務(wù)順利完成且返回結(jié)果值時,會調(diào)用 resolve 函數(shù);而當(dāng)異步任務(wù)失敗且返回失敗原因(通常是一個錯誤對象)時,會調(diào)用reject 函數(shù)。
十六、結(jié)構(gòu)解析(?)
1.順序結(jié)構(gòu)
順序結(jié)構(gòu)表示程序中的各操作是按照它們出現(xiàn)的先后順序執(zhí)行的。
2.選擇結(jié)構(gòu)(條件結(jié)構(gòu))
選擇結(jié)構(gòu)包括 if 與 else 還有switch和case這種搭配組合。
3.循環(huán)結(jié)構(gòu)
就是 for , for in , for of或者數(shù)組的遍歷方法就屬于循環(huán)結(jié)構(gòu)。
十七、數(shù)組扁平化處理
數(shù)組扁平化是將二維甚至多維數(shù)組轉(zhuǎn)化為一維數(shù)組的過程
利用reduce從左到右為每個數(shù)組元素執(zhí)行一次回調(diào)函數(shù),并把上次回調(diào)函數(shù)的返回值放在一個暫存器中傳給下次的回調(diào)函數(shù),并返回最后一次回調(diào)函數(shù)的返回值。
let arr=[[1,2,3],4,5,[6,7,[8,9]]];
function bianping(arr){
return arr.reduce((res,item) =>{
return res.concat(Array.isArray(item)?bianping(item):item)
},[])
}
console.log(bianping(arr));
十八、.es6的數(shù)組的幾個函數(shù)
遍歷數(shù)組
let arr = [1, 2, 3, 4, 5]for (let item of arr) {console.log(item) // item為正在處理的當(dāng)前元素 }arr.forEach((item, index) => {console.log(item, index) // item為正在處理的當(dāng)前元素,index為索引值 })map:返回一個由回調(diào)函數(shù)的返回值組成的新數(shù)組。
let arr = [1, 2, 3] let tpl = arr.map(item => `<span>${item}</span>`) console.log(tpl) // [ '<span>1</span>', '<span>2</span>','<span>3</span>' ]reduce:
從左到右為每個數(shù)組元素執(zhí)行一次回調(diào)函數(shù),并把上次回調(diào)函數(shù)的返回值放在一個暫存器中傳給下次的回調(diào)函數(shù),并返回最后一次回調(diào)函數(shù)的返回值。
let arr = [1, 2, 3] let sum = arr.reduce((previous, current, index) => { console.log(previous, current, index) return previous + current }) console.log(sum) // 6上面的代碼中的回調(diào)函數(shù)會執(zhí)行兩次,讓我們看一下 reduce 是如何運(yùn)行的
| 第1次 | 1 | 2 | 1 | 3 |
| 第2次 | 3 | 3 | 2 | 6 |
previous 是上一次回調(diào)函數(shù)的返回值,current 是當(dāng)前要處理的數(shù)值,
find:找到第一個滿足測試函數(shù)的元素并返回那個元素的值,如果找不到,則返回 undefined。
let arr = [1, 2, 3, 4, 5] let found = arr.find(item => item > 3) console.log(found) // 4findIndex
找到第一個滿足測試函數(shù)的元素并返回那個元素的索引,如果找不到,則返回 -1。
includes
判斷當(dāng)前數(shù)組是否包含某指定的值,如果是返回 true,否則返回 false。
let arr = [1, 2, 3, 4, 5] console.log(arr.includes(3)) // true console.log(arr.includes('2')) // falsejoin
連接所有數(shù)組元素組成一個字符串。
let arr = [1, 2, 3, 4, 5] console.log(arr.join('')) // '12345' console.log(arr.join('-')) // '1-2-3-4-5'concat
用于合并兩個或多個數(shù)組。此方法不會更改現(xiàn)有數(shù)組,而是返回一個新數(shù)組。
let arr1 = [1, 2, 3] let arr2 = [4, 5] let arr3 = arr1.concat(arr2) console.log(arr3) // [ 1, 2, 3, 4, 5 ]顛倒數(shù)組中元素的排列順序,即原先的第一個變?yōu)樽詈笠粋€,原先的最后一個變?yōu)榈谝粋€,該方法會改變原數(shù)組。
let arr = [1, 2, 3, 4, 5] arr.reverse() console.log(arr) // [ 5, 4, 3, 2, 1 ],原數(shù)組被改變push
在數(shù)組的末尾增加一個或多個元素,并返回數(shù)組的新長度
let arr = [1, 2, 3, 4, 5] console.log(arr.push(6)) // 6 console.log(arr.push(7, 8)) // 8 console.log(arr) // [ 1, 2, 3, 4, 5, 6, 7, 8 ]pop
刪除數(shù)組的最后一個元素,并返回這個元素。
let arr = [1, 2, 3, 4, 5] let item = arr.pop() console.log(item) // 5 console.log(arr) // [ 1, 2, 3, 4 ]sort
方法用用于對數(shù)組的元素進(jìn)行排序,并返回數(shù)組。默認(rèn)排序順序是在將元素轉(zhuǎn)換為字符串,然后比較它們的 UTF-16 代碼單元值序列時構(gòu)建的
let arr = ['b', 'd', 'a', 'c'] arr.sort() console.log(arr)我們可以通過傳入比較函數(shù),來自定義排序邏輯,比較函數(shù)會每次傳入兩個要比較的值 a 和 b,如果函數(shù)返回小于0,那么 a 會排列到 b 的前面,稱為升序排列,如果大于0,則會排到后面,稱為降序排列,如果等于0,則相對位置不變(并非標(biāo)準(zhǔn)行為)
let arr = [3, 5, 1, 4, 2] arr.sort((a, b) => { if (a < b) return -1 if (a > b) return 1 return 0 }) console.log(arr) // [ 1, 2, 3, 4, 5 ],升序 arr.sort((a, b) => { if (a < b) return 1if (a > b) return -1return 0 }) console.log(arr) // [ 5, 4, 3, 2, 1 ],降序十九、Array.prototype.some()
**some()** 方法測試數(shù)組中是不是至少有1個元素通過了被提供的函數(shù)測試。它返回的是一個Boolean類型的值。
二十、數(shù)組去重
let set = new Set() set = new Set([1, 2, 2, 3]) // 可以直接從一個數(shù)組初始化,重復(fù)元素會被去除 console.log(set) // Set(3) { 1, 2, 3 } let arr = [...set] // 可以將Set展開為一個數(shù)組 console.log(arr) // [ 1, 2, 3 ]// 迭代Set for (let item of set) { console.log(item) }二十一、箭頭函數(shù)、set、map
箭頭函數(shù)
ES6允許使用箭頭 => 來定義函數(shù)
如果箭頭函數(shù)不需要參數(shù)或者需要多個參數(shù),就使用一個圓括號代表參數(shù)部分
如果箭頭函數(shù)有多條語句,需要用大括號括起來,并且使用 return 語句返回
let sum = (num1, num2) => { let num = num1 + num2 return num }箭頭函數(shù)也可以直接返回一個對象,但是因為大括號會被當(dāng)成代碼塊來執(zhí)行,所以外面要加上小括號
let func = name => ({ name }) console.log(func('Frank')) // { name: 'Frank' }箭頭函數(shù)最常用的應(yīng)用場景是簡化回調(diào)函數(shù),例如
let arr = [1, 2, 3, 4, 5] let result = arr.map(item => item * 2)箭頭函數(shù)有幾個特性是和普通函數(shù)不同的,需要額外注意
-
箭頭函數(shù)沒有自己的 this,而是引用外層的 this
-
箭頭函數(shù)不能當(dāng)作構(gòu)造函數(shù),不可以使用 new 命令
-
箭頭函數(shù)沒有 arguments
set
ES6提供了新的數(shù)據(jù)結(jié)構(gòu),它類似于數(shù)組,但是成員的值都是唯一的,沒有重復(fù)的值。Set 本身是一個構(gòu)造函數(shù),用來生成 Set 數(shù)據(jù)結(jié)構(gòu)。
Map
ES6提供了 Map 數(shù)據(jù)結(jié)構(gòu),它類似于的對象,也是鍵值對的集合,但是“鍵”的范圍不限于字符串,各種類型的值都可以當(dāng)作鍵,也就是說,Object 提供了“字符串-值”的對應(yīng),Map 提供了“值-值”的對應(yīng),是一種更完善的Hash結(jié)構(gòu)。
Map 的遍歷會復(fù)雜一些,它提供了幾個迭代器可供我們使用
- keys():返回鍵名的遍歷器
- values():返回鍵值的遍歷器
- entries():返回所有成員的遍歷器
- forEach():遍歷所有成員
我們還可以使用擴(kuò)展運(yùn)算符 ... 來將 Map 展開為數(shù)組結(jié)構(gòu)
let map = new Map() map.set('age', 21) map.set('name','Frank') console.log([...map.keys()]) // [ 'age', 'name' ] console.log([...map.values()]) // [ 21, 'Frank' ] console.log([...map.entries()]) // [ ['age', 21], ['name', 'Frank'] ]二十二、javascript中各種循環(huán)
- for
- forEach
- do…while
- while
- for…in
- for…of
- for…in vs for…of
for
- 您可以使用break中斷for循環(huán)
- 您可以使用continue繼續(xù)for循環(huán)的下一次迭代
forEach
在ES5中引入。給定一個數(shù)組,您可以使用list.forEach()迭代其屬性:
const list = ['a', 'b', 'c'] list.forEach((item, index) => {console.log(item) //valueconsole.log(index) //index })//index is optional list.forEach(item => console.log(item))不過需要注意的是你無法擺脫這個循環(huán)。
for…in
迭代對象的所有可枚舉屬性,給出屬性名稱。
for (let property in object) {console.log(property) //property nameconsole.log(object[property]) //property value }for…of
ES2015引入了for循環(huán),它結(jié)合了forEach的簡潔性和破解能力:
//iterate over the value for (const value of ['a', 'b', 'c']) {console.log(value) //value }//get the index as well, using `entries()` for (const [index, value] of ['a', 'b', 'c'].entries()) {console.log(index) //indexconsole.log(value) //value }for…in VS FOR…OF
與for…in的區(qū)別在于:
- for…of 迭代屬性值
- for…in 迭代屬性名稱
二十三、如何獲得最多重復(fù)元素的序列號
基本思路:
1.將字符串中的每一項與其所出現(xiàn)的次數(shù)組成對象;
2.將獲得的對象按照值做對比,找出最大項;
二十四、垃圾回收機(jī)制
1、垃圾回收:
js代碼想要運(yùn)行,需要操作系統(tǒng)或者運(yùn)行時提供內(nèi)存空間,來存儲變量及它的值。在某些變量(例如局部變量)在不參與運(yùn)行時,就需要系統(tǒng)回收被占用的內(nèi)存空間,稱為垃圾回收
JavaScript垃圾回收的機(jī)制很簡單:找出不再使用的變量,然后釋放掉其占用的內(nèi)存
2、why
由于字符串、對象和數(shù)組沒有固定大小,所有當(dāng)他們的大小已知時,才能對他們進(jìn)行動態(tài)的存儲分配。JavaScript程序每次創(chuàng)建字符串、數(shù)組或?qū)ο髸r,解釋器都必須分配內(nèi)存來存儲那個實體。只要像這樣動態(tài)地分配了內(nèi)存,最終都要釋放這些內(nèi)存以便他們能夠被再用,否則,JavaScript的解釋器將會消耗完系統(tǒng)中所有可用的內(nèi)存,造成系統(tǒng)崩潰。
3、when
垃圾回收器周期性運(yùn)行,如果分配的內(nèi)存非常多,那么回收工作也會很艱巨,確定垃圾回收時間間隔就變成了一個值得思考的問題。
觸發(fā)條件不再是固定的,而是動態(tài)修改的,初始值和IE6相同,如果垃圾回收器回收的內(nèi)存分配量低于程序占用內(nèi)存的15%,說明大部分內(nèi)存不可被回收,設(shè)的垃圾回收觸發(fā)條件過于敏感,這時候把臨界條件翻倍,如果回收的內(nèi)存高于85%,說明大部分內(nèi)存早就該清理了,這時候把觸發(fā)條件置回。這樣就使垃圾回收工作職能了很多。
4、how
垃圾回收有兩種方法:標(biāo)記清除、引用計數(shù)。
引用計數(shù):
引用計數(shù)的含義是跟蹤記錄每個值被引用的次數(shù)。當(dāng)聲明了一個變量并將一個引用類型賦值給該變量時,則這個值的引用次數(shù)就是1。相反,如果包含對這個值引用的變量又取得了另外一個值,則這個值的引用次數(shù)就減1。當(dāng)這個引用次數(shù)變成0時,則說明沒有辦法再訪問這個值了,因而就可以將其所占的內(nèi)存空間給收回來。這樣,垃圾收集器下次再運(yùn)行時,它就會釋放那些引用次數(shù)為0的值所占的內(nèi)存。
引用計數(shù)有個最大的問題: 循環(huán)引用。
比如對象A有一個屬性指向?qū)ο驜,而對象B也有有一個屬性指向?qū)ο驛,這樣相互引用.
在這個例子中,objA和objB通過各自的屬性相互引用;也就是說這兩個對象的引用次數(shù)都是2。在采用引用計數(shù)的策略中,由于函數(shù)執(zhí)行之后,這兩個對象都離開了作用域,函數(shù)執(zhí)行完成之后,objA和objB還將會繼續(xù)存在,因為他們的引用次數(shù)永遠(yuǎn)不會是0。這樣的相互引用如果說很大量的存在就會導(dǎo)致大量的內(nèi)存泄露。
解決:手動解除引用
標(biāo)記清除:
這是javascript中最常用的垃圾回收方式。當(dāng)變量進(jìn)入執(zhí)行環(huán)境是,就標(biāo)記這個變量為“進(jìn)入環(huán)境”。從邏輯上講,永遠(yuǎn)不能釋放進(jìn)入環(huán)境的變量所占用的內(nèi)存,因為只要執(zhí)行流進(jìn)入相應(yīng)的環(huán)境,就可能會用到他們。當(dāng)變量離開環(huán)境時,則將其標(biāo)記為“離開環(huán)境”。
垃圾收集器在運(yùn)行的時候會給存儲在內(nèi)存中的所有變量都加上標(biāo)記。然后,它會去掉環(huán)境中的變量以及被環(huán)境中的變量引用的標(biāo)記。而在此之后再被加上標(biāo)記的變量將被視為準(zhǔn)備刪除的變量,原因是環(huán)境中的變量已經(jīng)無法訪問到這些變量了。最后。垃圾收集器完成內(nèi)存清除工作,銷毀那些帶標(biāo)記的值,并回收他們所占用的內(nèi)存空間。
二十五、閉包
一個函數(shù)和對其周圍狀態(tài)(lexical environment,詞法環(huán)境)的引用捆綁在一起(或者說函數(shù)被引用包圍),這樣的組合就是閉包(closure)。也就是說,閉包讓你可以在一個內(nèi)層函數(shù)中訪問到其外層函數(shù)的作用域。在 JavaScript 中,每當(dāng)創(chuàng)建一個函數(shù),閉包就會在函數(shù)創(chuàng)建的同時被創(chuàng)建出來。
閉包很有用,因為它允許將函數(shù)與其所操作的某些數(shù)據(jù)(環(huán)境)關(guān)聯(lián)起來。
用閉包模擬私有方法
編程語言中,比如 Java,是支持將方法聲明為私有的,即它們只能被同一個類中的其它方法所調(diào)用。
而 JavaScript 沒有這種原生支持,但我們可以使用閉包來模擬私有方法。私有方法不僅僅有利于限制對代碼的訪問:還提供了管理全局命名空間的強(qiáng)大能力,避免非核心的方法弄亂了代碼的公共接口部分。
a、變量的作用域
要理解閉包,首先必須理解Javascript特殊的變量作用域。
變量的作用域無非就是兩種:全局變量和局部變量。
Javascript語言的特殊之處,就在于函數(shù)內(nèi)部可以直接讀取全局變量。
b、如何從外部讀取局部變量?
在函數(shù)的內(nèi)部,再定義一個函數(shù)。
function f1(){
var n=999;
function f2(){
alert(n); // 999
}
}
在上面的代碼中,函數(shù)f2就被包括在函數(shù)f1內(nèi)部,這時f1內(nèi)部的所有局部變量,對f2都是可見的。但是反過來就不行,f2內(nèi)部的局部變量,對f1就是不可見的。這就是Javascript語言特有的"鏈?zhǔn)阶饔糜?#34;結(jié)構(gòu)(chain scope),子對象會一級一級地向上尋找所有父對象的變量。所以,父對象的所有變量,對子對象都是可見的,反之則不成立。
既然f2可以讀取f1中的局部變量,那么只要把f2作為返回值,我們不就可以在f1外部讀取它的內(nèi)部變量了嗎!
function f1(){
var n=999;
function f2(){
alert(n);
}
return f2;
}
var result=f1();
result(); // 999
c、閉包的概念
上一節(jié)代碼中的f2函數(shù),就是閉包。
我的理解是,閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)。
由于在Javascript語言中,只有函數(shù)內(nèi)部的子函數(shù)才能讀取局部變量,因此可以把閉包簡單理解成"定義在一個函數(shù)內(nèi)部的函數(shù)"。
所以,在本質(zhì)上,閉包就是將函數(shù)內(nèi)部和函數(shù)外部連接起來的一座橋梁。
d、閉包的用途
閉包可以用在許多地方。它的最大用處有兩個,一個是前面提到的可以讀取函數(shù)內(nèi)部的變量,另一個就是讓這些變量的值始終保持在內(nèi)存中。
function f1(){
var n=999;
nAdd=function(){n+=1}
function f2(){
alert(n);
}
return f2;
}
var result=f1();
result(); // 999
nAdd();
result(); // 1000
在這段代碼中,result實際上就是閉包f2函數(shù)。它一共運(yùn)行了兩次,第一次的值是999,第二次的值是1000。這證明了,函數(shù)f1中的局部變量n一直保存在內(nèi)存中,并沒有在f1調(diào)用后被自動清除。
為什么會這樣呢?原因就在于f1是f2的父函數(shù),而f2被賦給了一個全局變量,這導(dǎo)致f2始終在內(nèi)存中,而f2的存在依賴于f1,因此f1也始終在內(nèi)存中,不會在調(diào)用結(jié)束后,被垃圾回收機(jī)制(garbage collection)回收。
這段代碼中另一個值得注意的地方,就是"nAdd=function(){n+=1}"這一行,首先在nAdd前面沒有使用var關(guān)鍵字,因此nAdd是一個全局變量,而不是局部變量。其次,nAdd的值是一個匿名函數(shù)(anonymous function),而這個匿名函數(shù)本身也是一個閉包,所以nAdd相當(dāng)于是一個setter,可以在函數(shù)外部對函數(shù)內(nèi)部的局部變量進(jìn)行操作。
二十六、原型與原型鏈問題
在JavaScript中,每個函數(shù)都有一個prototype屬性,這個屬性指向函數(shù)的原型對象
原型的概念:每一個javascript對象(除null外)創(chuàng)建的時候,就會與之關(guān)聯(lián)另一個對象,這個對象就是我們所說的原型,每一個對象都會從原型中“繼承”屬性。
proto,這個屬性會指向該對象的原型。
補(bǔ)充說明:
絕大部分瀏覽器都支持這個非標(biāo)準(zhǔn)的方法訪問原型,然而它并不存在于 Person.prototype 中,實際上,它是來自于 Object.prototype ,與其說是一個屬性,不如說是一個 getter/setter,當(dāng)使用 obj.proto 時,可以理解成返回了 Object.getPrototypeOf(obj)。
每個原型都有一個constructor屬性,指向該關(guān)聯(lián)的構(gòu)造函數(shù)。
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-NGuk6kc5-1634800242308)(C:\Users\hzf\AppData\Roaming\Typora\typora-user-images\image-20210821133921224.png)]
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-7RLhIIgB-1634800242309)(C:\Users\hzf\AppData\Roaming\Typora\typora-user-images\image-20210821134025785.png)]
簡單的回顧一下構(gòu)造函數(shù)、原型和實例的關(guān)系:每個構(gòu)造函數(shù)都有一個原型對象,原型對象都包含一個指向構(gòu)造函數(shù)的指針,而實例都包含一個指向原型對象的內(nèi)部指針。那么假如我們讓原型對象等于另一個類型的實例,結(jié)果會怎樣?顯然,此時的原型對象將包含一個指向另一個原型的指針,相應(yīng)地,另一個原型中也包含著一個指向另一個構(gòu)造函數(shù)的指針。假如另一個原型又是另一個類型的實例,那么上述關(guān)系依然成立。如此層層遞進(jìn),就構(gòu)成了實例與原型的鏈條。這就是所謂的原型鏈的基本概念。
二十七、new運(yùn)算符的機(jī)制
二十八、堆棧
在介紹 JavaScript 之前,先介紹一下數(shù)據(jù)的類型
- 基本類型 (按值訪問) 包括:Number 、 String 、 Boolean、 Undefined、Null
- 引用類型 (按引用訪問) 包括:Object、 Array
棧 (stack) : 用來保存簡單的數(shù)據(jù)字段
堆 (heap) : 用來保存棧中簡單數(shù)據(jù)字段對指針的引用
如上圖所示,棧內(nèi)存中 關(guān)于 引用類型的數(shù)據(jù)的是通過指針(地址)來引用的,指針和地址指向堆內(nèi)存中的數(shù)據(jù)。
為啥為導(dǎo)致上述區(qū)別,是因為:
基本類型的數(shù)據(jù)簡單,所占用空間比較小,內(nèi)存由系統(tǒng)自動分配
引用類型數(shù)據(jù)比較復(fù)雜,復(fù)雜程度是動態(tài)的,計算機(jī)為了較少反復(fù)的創(chuàng)建和回收引用類型數(shù)據(jù)所帶來的損耗,就先為其開辟另外一部分空間——及堆內(nèi)存,以便于這些占用空間較大的數(shù)據(jù)重復(fù)利用。堆內(nèi)存中的數(shù)據(jù)不會隨著方法的結(jié)束立即銷毀,有可能該對象會被其它方法所引用,直到系統(tǒng)的垃圾回收機(jī)制檢索到該對象沒有被任何方法所引用的時候才會對其進(jìn)行回收
二十九、http和https協(xié)議區(qū)別
基本概念:
HTTP:是互聯(lián)網(wǎng)上應(yīng)用最為廣泛的一種網(wǎng)絡(luò)協(xié)議,是一個客戶端和服務(wù)器端請求和應(yīng)答的標(biāo)準(zhǔn)(TCP),用于從WWW服務(wù)器傳輸超文本到本地瀏覽器的傳輸協(xié)議,它可以使瀏覽器更加高效,使網(wǎng)絡(luò)傳輸減少。
HTTPS:是以安全為目標(biāo)的HTTP通道,簡單講是HTTP的安全版,即HTTP下加入SSL層,HTTPS的安全基礎(chǔ)是SSL,因此加密的詳細(xì)內(nèi)容就需要SSL。
區(qū)別:
HTTP協(xié)議傳輸?shù)臄?shù)據(jù)都是未加密的,也就是明文的,因此使用HTTP協(xié)議傳輸隱私信息非常不安全,為了保證這些隱私數(shù)據(jù)能加密傳輸,于是網(wǎng)景公司設(shè)計了SSL(Secure Sockets Layer)協(xié)議用于對HTTP協(xié)議傳輸?shù)臄?shù)據(jù)進(jìn)行加密,從而就誕生了HTTPS。簡單來說,HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進(jìn)行加密傳輸、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議,要比http協(xié)議安全。
HTTPS和HTTP的區(qū)別主要如下:
1、https協(xié)議需要到ca申請證書,一般免費(fèi)證書較少,因而需要一定費(fèi)用。
2、http是超文本傳輸協(xié)議,信息是明文傳輸,https則是具有安全性的ssl加密傳輸協(xié)議。
3、http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是80,后者是443。
4、http的連接很簡單,是無狀態(tài)的;HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進(jìn)行加密傳輸、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議,比http協(xié)議安全。
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-6boKt8ZK-1634800242311)(C:\Users\hzf\AppData\Roaming\Typora\typora-user-images\image-20210825012320866.png)]
三十、http消息狀態(tài)碼
100:消息
這一類型的狀態(tài)碼,代表請求已被接受,需要繼續(xù)處理。這類響應(yīng)是臨時響應(yīng)
200:成功
這一類型的狀態(tài)碼,代表請求已成功被服務(wù)器接收、理解、并接受。
200 OK
請求已成功,請求所希望的響應(yīng)頭或數(shù)據(jù)體將隨此響應(yīng)返回。出現(xiàn)此狀態(tài)碼是表示正常狀態(tài)。
201 Created
請求已經(jīng)被實現(xiàn),而且有一個新的資源已經(jīng)依據(jù)請求的需要而建立,且其 URI 已經(jīng)隨Location 頭信息返回。假如需要的資源無法及時建立的話,應(yīng)當(dāng)返回 ‘202 Accepted’。
202 Accepted
服務(wù)器已接受請求,但尚未處理。正如它可能被拒絕一樣,最終該請求可能會也可能不會被執(zhí)行。在異步操作的場合下,沒有比發(fā)送這個狀態(tài)碼更方便的做法了。
返回202狀態(tài)碼的響應(yīng)的目的是允許服務(wù)器接受其他過程的請求(例如某個每天只執(zhí)行一次的基于批處理的操作),而不必讓客戶端一直保持與服務(wù)器的連接直到批處理操作全部完成。在接受請求處理并返回202狀態(tài)碼的響應(yīng)應(yīng)當(dāng)在返回的實體中包含一些指示處理當(dāng)前狀態(tài)的信息,以及指向處理狀態(tài)監(jiān)視器或狀態(tài)預(yù)測的指針,以便用戶能夠估計操作是否已經(jīng)完成。
300:重定向
需要客戶端采取進(jìn)一步的操作才能完成請求
400:請求錯誤
這類的狀態(tài)碼代表了客戶端看起來可能發(fā)生了錯誤,妨礙了服務(wù)器的處理。除非響應(yīng)的是一個 HEAD 請求,否則服務(wù)器就應(yīng)該返回一個解釋當(dāng)前錯誤狀況的實體,以及這是臨時的還是永久性的狀況
400 Bad Request
1、語義有誤,當(dāng)前請求無法被服務(wù)器理解。除非進(jìn)行修改,否則客戶端不應(yīng)該重復(fù)提交這個請求。
2、請求參數(shù)有誤。
403 Forbidden
服務(wù)器已經(jīng)理解請求,但是拒絕執(zhí)行它。
404 Not Found
請求失敗,請求所希望得到的資源未被在服務(wù)器上發(fā)現(xiàn)。
三十一、存儲方式
Cookie 和 session 都可用來存儲用戶信息,cookie 存放于客戶端,session 存放于服務(wù)器端, 因為 cookie 存放于客戶端有可能被竊取,所以 cookie 一般用來存放不敏感的信息,比如 用戶設(shè)置的網(wǎng)站主題,敏感的信息用 session 存儲,比如用戶的登陸信息,session 可以 存放于文件,數(shù)據(jù)庫,內(nèi)存中都可以,cookie 可以服務(wù)器端響應(yīng)的時候設(shè)置,也可以客 戶端通過 JS 設(shè)置 cookie 會在請求時在 http 首部發(fā)送給客戶端,cookie 一般在客戶端有 大小限制,一般為 4K,
下面從幾個方向區(qū)分一下 cookie,localstorage,sessionstorage 的區(qū)別
1、生命周期: Cookie:可設(shè)置失效時間,否則默認(rèn)為關(guān)閉瀏覽器后失效 Localstorage:除非被手動清除,否則永久保存 Sessionstorage:僅在當(dāng)前網(wǎng)頁會話下有效,關(guān)閉頁面或瀏覽器后就會被清除
2、存放數(shù)據(jù): Cookie:4k 左右 Localstorage 和 sessionstorage:可以保存 5M 的信息
3、http 請求: Cookie:每次都會攜帶在 http 頭中,如果使用 cookie 保存過多數(shù)據(jù)會帶來性能問題 其他兩個:僅在客戶端即瀏覽器中保存,不參與和服務(wù)器的通信
4、易用性: Cookie:需要程序員自己封裝,原生的 cookie 接口不友好 其他兩個:即可采用原生接口,亦可再次封裝
5、應(yīng)用場景: 從安全性來說,因為每次 http 請求都回攜帶 cookie 信息,這樣子浪費(fèi)了帶寬,所以 cookie 應(yīng)該盡可能的少用,此外 cookie 還需要指定作用域,不可以跨域調(diào)用,限制很多,但是 用戶識別用戶登陸來說,cookie還是比storage好用,其他情況下可以用storage,localstorage 可以用來在頁面?zhèn)鬟f參數(shù),sessionstorage 可以用來保存一些臨時的數(shù)據(jù),防止用戶刷新 頁面后丟失了一些參數(shù)
三十二、盒子模型
所有HTML元素可以看作盒子,CSS盒模型本質(zhì)上是一個盒子,封裝周圍的HTML元素,它包括:邊距,邊框,填充,和實際內(nèi)容。
盒模型允許我們在其它元素和周圍元素邊框之間的空間放置元素。
- Margin(外邊距) - 清除邊框外的區(qū)域,外邊距是透明的
- Border(邊框) - 圍繞在內(nèi)邊距和內(nèi)容外的邊框。
- Padding(內(nèi)邊距) - 清除內(nèi)容周圍的區(qū)域,內(nèi)邊距是透明的。
- Content(內(nèi)容) - 盒子的內(nèi)容,顯示文本和圖像。
三十三、html5新增特性
HTML5的十大新特性 - Vicky_YU - 博客園 (cnblogs.com)
一、繪畫 canvas
HTML5 標(biāo)簽用于繪制圖像(通過腳本,通常是 JavaScript)。
二、用于媒介回放的video和audio元素
HTML5 DOM 為audio和video元素提供了方法、屬性和事件。
這些方法、屬性和事件允許您使用 JavaScript 來操作audio和video元素。
三、本地離線存儲localStorage長期存儲數(shù)據(jù),瀏覽器關(guān)閉后數(shù)據(jù)不丟失
localStorage :沒有時間限制的數(shù)據(jù)存儲
四、sessionStorage的數(shù)據(jù)在瀏覽器關(guān)閉后自動刪除
sessionStorage :針對一個session的數(shù)據(jù)存儲
五、語意化更好的內(nèi)容元素,比如 article、footer、header、nav、section
三十四、css3新增特性
顏色:新增 RGBA,HSLA 模式,新增透明度
文字陰影:(text-shadow)
邊框:
邊框圓角:(border-radius)
邊框陰影:(box-shadow)
邊框圖片:(border-image)
彈性盒子模型:(box-sizing:border-box;)
背景:
background-size :設(shè)置背景圖片的尺寸
background-origin :設(shè)置背景圖片的原點(定位、位置)
background-clip :設(shè)置背景圖片的裁切區(qū)域,以”,”分隔,可以設(shè)置多背景,用于自適應(yīng)布局。
漸變:
linear-gradient:(線性漸變)
radial-gradient :(徑向漸變)
過渡:transition,可實現(xiàn)動畫
自定義動畫 animation 定義動畫:@keyframes 動畫名稱
在 CSS3 中唯一引入的偽元素是 :selection
媒體查詢@media,多欄布局:
@media screen and (width:500px) {
body {
background-color: red;
}
}
1
2
3
4
5
2D 轉(zhuǎn)換:
transform:translate(x,y) 移動
rotate(x,y) 旋轉(zhuǎn)
skew(x,y) 翻轉(zhuǎn)
scale(x,y) 縮放
3D 轉(zhuǎn)換
字體圖標(biāo) : font-face
彈性布局 :flex
新增選擇器: nth-child(n)
三十五、tcp三次握手
syn(握手信息)
第一次握手
客戶主動(active open)去connect服務(wù)器,并且發(fā)送SYN 假設(shè)序列號為J,
服務(wù)器是被動打開(passive open)
第二次握手
服務(wù)器在收到SYN后,它會發(fā)送一個SYN以及一個ACK(應(yīng)答)給客戶,
ACK的序列號是 J+1表示是給SYN J的應(yīng)答,新發(fā)送的SYN K 序列號是K
第三次握手
客戶在收到新SYN K, ACK J+1 后,也回應(yīng)ACK K+1 以表示收到了,
然后兩邊就可以開始數(shù)據(jù)發(fā)送數(shù)據(jù)了
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-rrZazqm5-1634800242312)(C:\Users\hzf\AppData\Roaming\Typora\typora-user-images\image-20211011162110597.png)]
假設(shè)Client端發(fā)起中斷連接請求,也就是發(fā)送FIN報文。Server端接到FIN報文后,意思是說"我Client端沒有數(shù)據(jù)要發(fā)給你了",但是如果你還有數(shù)據(jù)沒有發(fā)送完成,則不必急著關(guān)閉Socket,可以繼續(xù)發(fā)送數(shù)據(jù)。所以你先發(fā)送ACK,“告訴Client端,你的請求我收到了,但是我還沒準(zhǔn)備好,請繼續(xù)你等我的消息”。這個時候Client端就進(jìn)入FIN_WAIT狀態(tài),繼續(xù)等待Server端的FIN報文。當(dāng)Server端確定數(shù)據(jù)已發(fā)送完成,則向Client端發(fā)送FIN報文,“告訴Client端,好了,我這邊數(shù)據(jù)發(fā)完了,準(zhǔn)備好關(guān)閉連接了”。Client端收到FIN報文后,"就知道可以關(guān)閉連接了,但是他還是不相信網(wǎng)絡(luò),怕Server端不知道要關(guān)閉,所以發(fā)送ACK后進(jìn)入TIME_WAIT狀態(tài),如果Server端沒有收到ACK則可以重傳。“,Server端收到ACK后,“就知道可以斷開連接了”。Client端等待了2MSL后依然沒有收到回復(fù),則證明Server端已正常關(guān)閉,那好,我Client端也可以關(guān)閉連接了。Ok,TCP連接就這樣關(guān)閉了!
三十六、tcp和udp的區(qū)別
1、TCP 是面向連接的,udp 是無連接的即發(fā)送數(shù)據(jù)前不需要先建立鏈接。
2、tcp提供可靠的服務(wù)、無差錯、不丟失;udp盡最大努力交付
3、tcp面向字節(jié)流;udp面向報文
4、tcp只能一對一;udp支持 1 對 1,1 對多。
5、TCP 的首部較大為 20 字節(jié),而 UDP 只有 8 字節(jié)
三十七、POST與GET兩種請求方式的區(qū)別
1、GET請求,請求的數(shù)據(jù)會附加在URL之后,以?分割URL和傳輸數(shù)據(jù),多個參數(shù)用&連接。URL的編碼格式采用的是ASCII編碼,而不是uniclde,即是說所有的非ASCII字符都要編碼之后再傳輸。
POST請求:POST請求會把請求的數(shù)據(jù)放置在HTTP請求包的包體中。上面的item=bandsaw就是實際的傳輸數(shù)據(jù)。
因此,GET請求的數(shù)據(jù)會暴露在地址欄中,而POST請求則不會。
2、傳輸數(shù)據(jù)的大小
在HTTP規(guī)范中,沒有對URL的長度和傳輸?shù)臄?shù)據(jù)大小進(jìn)行限制。但是在實際開發(fā)過程中,對于GET,特定的瀏覽器和服務(wù)器對URL的長度有限制。因此,在使用GET請求時,傳輸數(shù)據(jù)會受到URL長度的限制。
對于POST,由于不是URL傳值,理論上是不會受限制的,但是實際上各個服務(wù)器會規(guī)定對POST提交數(shù)據(jù)大小進(jìn)行限制,Apache、IIS都有各自的配置。
3、安全性
POST的安全性比GET的高。這里的安全是指真正的安全,而不同于上面GET提到的安全方法中的安全,上面提到的安全僅僅是不修改服務(wù)器的數(shù)據(jù)。比如,在進(jìn)行登錄操作,通過GET請求,用戶名和密碼都會暴露再URL上,因為登錄頁面有可能被瀏覽器緩存以及其他人查看瀏覽器的歷史記錄的原因,此時的用戶名和密碼就很容易被他人拿到了
三十八、tcp/ip如何保證數(shù)據(jù)的有效傳輸
對字節(jié)流分段并進(jìn)行編號然后通過 ACK 回復(fù)和超時重發(fā)這兩個機(jī)制來保證。
(1)為了保證數(shù)據(jù)包的可靠傳遞,發(fā)送方必須把已發(fā)送的數(shù)據(jù)包保留在緩沖區(qū);
(2)并為每個已發(fā)送的數(shù)據(jù)包啟動一個超時定時器;
(3)如在定時器超時之前收到了對方發(fā)來的應(yīng)答信息(可能是對本包的應(yīng)答,也可以是對本包后續(xù)包的應(yīng)答),則釋放該數(shù)據(jù)包占用的緩沖區(qū);
(4)否則,重傳該數(shù)據(jù)包,直到收到應(yīng)答或重傳次數(shù)超過規(guī)定的最大次數(shù)為止。
(5)接收方收到數(shù)據(jù)包后,先進(jìn)行CRC校驗,如果正確則把數(shù)據(jù)交給上層協(xié)議,然后給發(fā)送方發(fā)送一個累計應(yīng)答包,表明該數(shù)據(jù)已收到,如果接收方正好也有數(shù)據(jù)要發(fā)給發(fā)送方,應(yīng)答包也可方在數(shù)據(jù)包中捎帶過去
可靠的服務(wù)、無差錯、不丟失;udp盡最大努力交付
3、tcp面向字節(jié)流;udp面向報文
4、tcp只能一對一;udp支持 1 對 1,1 對多。
5、TCP 的首部較大為 20 字節(jié),而 UDP 只有 8 字節(jié)
三十七、POST與GET兩種請求方式的區(qū)別
1、GET請求,請求的數(shù)據(jù)會附加在URL之后,以?分割URL和傳輸數(shù)據(jù),多個參數(shù)用&連接。URL的編碼格式采用的是ASCII編碼,而不是uniclde,即是說所有的非ASCII字符都要編碼之后再傳輸。
POST請求:POST請求會把請求的數(shù)據(jù)放置在HTTP請求包的包體中。上面的item=bandsaw就是實際的傳輸數(shù)據(jù)。
因此,GET請求的數(shù)據(jù)會暴露在地址欄中,而POST請求則不會。
2、傳輸數(shù)據(jù)的大小
在HTTP規(guī)范中,沒有對URL的長度和傳輸?shù)臄?shù)據(jù)大小進(jìn)行限制。但是在實際開發(fā)過程中,對于GET,特定的瀏覽器和服務(wù)器對URL的長度有限制。因此,在使用GET請求時,傳輸數(shù)據(jù)會受到URL長度的限制。
對于POST,由于不是URL傳值,理論上是不會受限制的,但是實際上各個服務(wù)器會規(guī)定對POST提交數(shù)據(jù)大小進(jìn)行限制,Apache、IIS都有各自的配置。
3、安全性
POST的安全性比GET的高。這里的安全是指真正的安全,而不同于上面GET提到的安全方法中的安全,上面提到的安全僅僅是不修改服務(wù)器的數(shù)據(jù)。比如,在進(jìn)行登錄操作,通過GET請求,用戶名和密碼都會暴露再URL上,因為登錄頁面有可能被瀏覽器緩存以及其他人查看瀏覽器的歷史記錄的原因,此時的用戶名和密碼就很容易被他人拿到了
三十八、tcp/ip如何保證數(shù)據(jù)的有效傳輸
對字節(jié)流分段并進(jìn)行編號然后通過 ACK 回復(fù)和超時重發(fā)這兩個機(jī)制來保證。
(1)為了保證數(shù)據(jù)包的可靠傳遞,發(fā)送方必須把已發(fā)送的數(shù)據(jù)包保留在緩沖區(qū);
(2)并為每個已發(fā)送的數(shù)據(jù)包啟動一個超時定時器;
(3)如在定時器超時之前收到了對方發(fā)來的應(yīng)答信息(可能是對本包的應(yīng)答,也可以是對本包后續(xù)包的應(yīng)答),則釋放該數(shù)據(jù)包占用的緩沖區(qū);
(4)否則,重傳該數(shù)據(jù)包,直到收到應(yīng)答或重傳次數(shù)超過規(guī)定的最大次數(shù)為止。
(5)接收方收到數(shù)據(jù)包后,先進(jìn)行CRC校驗,如果正確則把數(shù)據(jù)交給上層協(xié)議,然后給發(fā)送方發(fā)送一個累計應(yīng)答包,表明該數(shù)據(jù)已收到,如果接收方正好也有數(shù)據(jù)要發(fā)給發(fā)送方,應(yīng)答包也可方在數(shù)據(jù)包中捎帶過去
總結(jié)
- 上一篇: Charles——Charles之htt
- 下一篇: “错误 D8016 “/ZI”和“/Gy