說一下瀏覽器緩存:javascript
強緩存相關字段有expires,cache-control。若是cache-control與expires同時存在的話,cache-control的優先級高於expires。html
協商緩存相關字段有Last-Modified/If-Modified-Since,Etag/If-None-Matchjava
fetch發送2次請求的緣由:mysql
fetch發送post請求的時候,老是發送2次,第一次狀態碼是204,第二次才成功?
緣由很簡單,由於你用fetch的post請求的時候,致使fetch 第一次發送了一個Options請求,詢問服務器是否支持修改的請求頭,若是服務器支持,則在第二次中發送真正的請求。react
第一次是探域,至於跨域的狀況下才會發送兩次git
在地址欄裏輸入一個URL,到這個頁面呈現出來,中間會發生什麼?es6
TCP鏈接web
發送HTTP請求面試
服務器處理請求並返回HTTP報文redis
瀏覽器解析渲染頁面
鏈接結束
當瀏覽器接收到服務器相應來的HTML文檔後,會遍歷文檔節點,生成DOM樹,
CSSOM規則樹由瀏覽器解析CSS文件生成,
csrf和xss的網絡攻擊及防範
XSS:跨站腳本攻擊,是說攻擊者經過注入惡意的腳本,在用戶瀏覽網頁的時候進行攻擊,好比獲取cookie,或者其餘用戶身份信息,能夠分爲存儲型和反射型,存儲型是攻擊者輸入一些數據而且存儲到了數據庫中,其餘瀏覽者看到的時候進行攻擊,反射型的話不存儲在數據庫中,每每表現爲將攻擊代碼放在url地址的請求參數中,防護的話爲cookie設置httpOnly屬性,對用戶的輸入進行檢查,進行特殊字符過濾
描述一下XSS和CRSF攻擊?防護方法?
CSRF(Cross Site Request Forgery,跨站請求僞造),字面理解意思就是在別的站點僞造了一個請求。專業術語來講就是在受害者訪問一個網站時,其 Cookie 尚未過時的狀況下,攻擊者僞造一個連接地址發送受害者並欺騙讓其點擊,從而造成 CSRF 攻擊。
XSS防護的整體思路是:對輸入(和URL參數)進行過濾,對輸出進行編碼。也就是對提交的全部內容進行過濾,對url中的參數進行過濾,過濾掉會致使腳本執行的相關內容;而後對動態輸出到頁面的內容進行html編碼,使腳本沒法在瀏覽器中執行。雖然對輸入過濾能夠被繞過,可是也仍是會攔截很大一部分的XSS攻擊。
防護CSRF 攻擊主要有三種策略:驗證 HTTP Referer 字段;在請求地址中添加 token 並驗證;在 HTTP 頭中自定義屬性並驗證。
說一下對Cookie和Session的認知,Cookie有哪些限制?
2. cookie不是很安全,別人能夠分析存放在本地的COOKIE並進行COOKIE欺騙
考慮到安全應當使用session。
3. session會在必定時間內保存在服務器上。當訪問增多,會比較佔用你服務器的性能
考慮到減輕服務器性能方面,應當使用COOKIE。
4. 單個cookie保存的數據不能超過4K,不少瀏覽器都限制一個站點最多保存20個cookie。
什麼是BFC?什麼是IFC?
不要試圖去講解 BFC 的定義!!
如何說明 BFC ,舉例子!!不要試圖去講定義!!
格式化上下文(block formatting context)
當一個HTML元素知足下面條件的任何一點,均可以產生Block Formatting Context:
a、float的值不爲none
b、overflow的值不爲visible
c、display的值爲table-cell, table-caption, inline-block中的任何一個
d、position的值不爲relative和static
IFC(Inline Formatting Context)即行內格式化上下文。常規流(也稱標準流、普通流)是一個文檔在被顯示時最多見的佈局形態。
(塊級格式化上下文,用於清楚浮動,防止margin重疊等)
BFC區域不會與float box重疊
BFC是頁面上的一個獨立容器,子元素不會影響到外面
計算BFC的高度時,浮動元素也會參與計算
那些元素會生成BFC:
根元素
float不爲none的元素
position爲fixed和absolute的元素
display爲inline-block、table-cell、table-caption,flex,inline-flex的元素
overflow不爲visible的元素
畫一條0.5px的線
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
採用border-image的方式
採用transform: scale()的方式
.hairline-bottom { position: relative; border: none; } .hairline-bottom::after { content: ""; position: absolute; left: 0; bottom: 0; border-bottom: 1px solid #dddee3; width: 100%; -webkit-transform: scale(1, 0.5); transform: scale(1, 0.5); -webkit-transform-origin: center bottom; transform-origin: center bottom; z-index: 1; }
介紹一下盒模型
標準盒模型:一個塊的總寬度=width+margin(左右)+padding(左右)+border(左右)
怪異盒模型:一個塊的總寬度=width+margin(左右)(既width已經包含了padding和border值)
設置盒模型:box-sizing:border-box
對象深度克隆的簡單實現
function deepClone(obj){ var newObj= obj instanceof Array ? []:{}; for(var item in obj){ var temple= typeof obj[item] == 'object' ? deepClone(obj[item]):obj[item]; newObj[item] = temple; } return newObj; } ES5的經常使用的對象克隆的一種方式。注意數組是對象,可是跟對象又有必定區別,因此咱們一開始判斷了一些類型,決定newObj是對象仍是數組~
null == undefined爲何
要比較相等性以前,不能將null 和 undefined 轉換成其餘任何值,但 null == undefined 會返回 true 。ECMAScript規範中是這樣定義的。
簡單介紹一下symbol
Symbl確保惟一,即便採用相同的名稱,也會產生不一樣的值,咱們建立一個字段,僅爲知道對應symbol的人能訪問,使用symbol頗有用,symbol並非100%隱藏,有內置方法Object.getOwnPropertySymbols(obj)能夠得到全部的symbol。
也有一個方法Reflect.ownKeys(obj)返回對象全部的鍵,包括symbol。
因此並非真正隱藏。但大多數庫內置方法和語法結構遵循通用約定他們是隱藏的
NaN
NaN是JS中的特殊值,表示非數字,NaN不是數字,可是他的數據類型是數字,它不等於任何值,包括自身,在布爾運算時被當作false,NaN與任何數運算獲得的結果都是NaN,
redux裏經常使用方法
提供 dispatch(action) 方法更新 state;
經過 subscribe(listener) 註冊監聽器;
react的生命週期函數
初始化 1、getDefaultProps() 設置默認的props,也能夠用dufaultProps設置組件的默認屬性. 2、getInitialState() 在使用es6的class語法時是沒有這個鉤子函數的,能夠直接在constructor中定義this.state。此時能夠訪問this.props 3、componentWillMount() 組件初始化時只調用,之後組件更新不調用,整個生命週期只調用一次,此時能夠修改state。 4、 render() react最重要的步驟,建立虛擬dom,進行diff算法,更新dom樹都在此進行。此時就不能更改state了。 5、componentDidMount() 組件渲染以後調用,只調用一次。 更新 6、componentWillReceiveProps(nextProps) 組件初始化時不調用,組件接受新的props時調用。 7、shouldComponentUpdate(nextProps, nextState) react性能優化很是重要的一環。組件接受新的state或者props時調用,咱們能夠設置在此對比先後兩個props和state是否相同,若是相同則返回false阻止更新,由於相同的屬性狀態必定會生成相同的dom樹,這樣就不須要創造新的dom樹和舊的dom樹進行diff算法對比,節省大量性能,尤爲是在dom結構複雜的時候 8、componentWillUpdata(nextProps, nextState) 組件初始化時不調用,只有在組件將要更新時才調用,此時能夠修改state 9、render() 組件渲染 10、componentDidUpdate() 組件初始化時不調用,組件更新完成後調用,此時能夠獲取dom節點。 卸載 11、componentWillUnmount() 組件將要卸載時調用,一些事件監聽和定時器須要在此時清除。
setState以後的流程
在代碼中調用setState函數以後,React 會將傳入的參數對象與組件當前的狀態合併,而後觸發所謂的調和過程(Reconciliation)。 通過調和過程,React 會以相對高效的方式根據新的狀態構建 React 元素樹而且着手從新渲染整個UI界面。 在 React 獲得元素樹以後,React 會自動計算出新的樹與老樹的節點差別,而後根據差別對界面進行最小化重渲染。 在差別計算算法中,React 可以相對精確地知道哪些位置發生了改變以及應該如何改變,這就保證了按需更新,而不是所有從新渲染。
tcp三次握手過程
第二次握手:Server收到數據包後由標誌位SYN=1得知Client請求創建鏈接,Server將標誌位SYN和ACK都置爲1,ack=x+1,隨機產生一個值seq=y,並將該數據包發送給Client以確認鏈接請求,Server進入SYN-RCVD狀態,此時操做系統爲該TCP鏈接分配TCP緩存和變量;
第三次握手:Client收到確認後,檢查ack是否爲x+1,ACK是否爲1,若是正確則將標誌位ACK置爲1,ack=y+1,而且此時操做系統爲該TCP鏈接分配TCP緩存和變量,並將該數據包發送給Server,Server檢查ack是否爲y+1,ACK是否爲1,若是正確則鏈接創建成功,Client和Server進入ESTABLISHED狀態,完成三次握手,隨後Client和Server就能夠開始傳輸數據。
TCP和UDP的區別,爲何三次握手四次揮手
TCP和UDP之間的區別 OSI 和TCP/IP 模型在傳輸層定義兩種傳輸協議:TCP(或傳輸控制協議)和UDP(或用戶數據報協議)。 UDP 與TCP 的主要區別在於UDP 不必定提供可靠的數據傳輸。 事實上,該協議不能保證數據準確無誤地到達目的地。 爲何TCP要進行四次揮手呢? 由於是雙方彼此都創建了鏈接,所以雙方都要釋放本身的鏈接,A向B發出一個釋放鏈接請求,他要釋放連接代表再也不向B發送數據了,此時B收到了A發送的釋放連接請求以後,給A發送一個確認,A不能再向B發送數據了,它處於FIN-WAIT-2的狀態,可是此時B還能夠向A進行數據的傳送。此時B向A 發送一個斷開鏈接的請求,A收到以後給B發送一個確認。此時B關閉鏈接。A也關閉鏈接。 爲何要有TIME-WAIT這個狀態呢,這是由於有可能最後一次確認丟失,若是B此時繼續向A發送一個我要斷開鏈接的請求等待A發送確認,但此時A已經關閉鏈接了,那麼B永遠也關不掉了,因此咱們要有TIME-WAIT這個狀態。 固然TCP也並非100%可靠的。
Redis和 mysql
(1)類型上 從類型上來講,mysql是關係型數據庫,redis是緩存數據庫 (2)做用上 mysql用於持久化的存儲數據到硬盤,功能強大,可是速度較慢 redis用於存儲使用較爲頻繁的數據到緩存中,讀取速度快 (3)需求上 mysql和redis由於需求的不一樣,通常都是配合使用。
git 怎麼刪除一個遠程/本地分支
刪除遠程分支
git push origin --delete dev
刪除本地分支
git branch -d dev
查看分支狀況
git branch -a
兩個數組比較,判斷是否有相同元素
要判斷JS中的兩個數組是否相同,須要先將數組轉換爲字符串,再做比較。如下兩行代碼將返回true
<script type="text/javascript"> alert([].toString()== [].toString()); alert([].toString()===[].toString()); </script>
數組去重通常用什麼方法,數據量大又用什麼方法
/* * 速度最快, 佔空間最多(空間換時間) * * 該方法執行的速度比其餘任何方法都快, 就是佔用的內存大一些。 * 現思路:新建一js對象以及新數組,遍歷傳入數組時,判斷值是否爲js對象的鍵, * 不是的話給對象新增該鍵並放入新數組。 * 注意點:判斷是否爲js對象鍵時,會自動對傳入的鍵執行「toString()」, * 不一樣的鍵可能會被誤認爲同樣,例如n[val]-- n[1]、n["1"]; * 解決上述問題仍是得調用「indexOf」。*/ function uniq(array){ var temp = {}, r = [], len = array.length, val, type; for (var i = 0; i < len; i++) { val = array[i]; type = typeof val; if (!temp[val]) { temp[val] = [type]; r.push(val); } else if (temp[val].indexOf(type) < 0) { temp[val].push(type); r.push(val); } } return r; } var aa = [1,2,"2",4,9,"a","a",2,3,5,6,5]; console.log(uniq(aa));
const removeDuplicateItems = arr => [...new Set(arr)]; console.log(removeDuplicateItems([42, 'foo', 42, 'foo', true, true])); // => [42, "foo", true]
set和obj
數據量大就用排序方法去重唄
因爲0.1轉換成二進制時是無限循環的,因此在計算機中0.1只能存儲成一個近似值。
WebView和原生是如何通訊
== 和 ===的區別,什麼狀況下用相等==
兩個對象如何比較
https://www.jianshu.com/p/90ed8b728975
prototype和——proto——區別
JS爲何要區分微任務和宏任務
發佈-訂閱和觀察者模式的區別
for..in 和 object.keys的區別
獲取對象的屬性的方法
關於標題中方法和語句的基本用法能夠參閱以下兩篇文章:
(1).JavaScript Object.keys()一章節。
(2).JavaScript for in 語句一章節。
Object.keys方法對數組進行遍歷操做,能夠看到獲取的是數組的索引。
數組的索引都是數字,可是經過此方法獲取的都會被轉換爲字符串。
for in語句:
此語句能夠遍歷普通對象,也能夠遍歷數組,可是不建議使用它遍歷數組。
三.異同總結以下:
(1).均可以遍歷對象與數組。
(2).獲取的都是對象或者數組的鍵(數組的鍵就是元素索引),獲取的值都會被轉換爲字符串。
(3).獲取鍵的順序二者是徹底相同的。
(4).瀏覽器支持有所差別,Object.keys方法低版本IE瀏覽器不支持。
(5).Object.keys方法不會獲取原型鏈上的鍵,可是for in是能夠的。
react的理念是什麼(拿函數式編程來作頁面渲染)
JS是什麼範式語言(面向對象仍是函數式編程)
輸出下面的執行順序
setTimeout(function(){ console.log('1') }); new Promise(function(resolve){ console.log('2'); resolve(); }).then(function(){ console.log('3') }); console.log('4');
看一下宏任務和微任務
同步和異步任務分別進入不一樣的執行"場所",同步的進入主線程,異步的進入Event Table並註冊函數。當指定的事情完成時,Event Table會將這個函數移入Event Queue。主線程內的任務執行完畢爲空,會去Event Queue讀取對應的函數,進入主線程執行。上述過程會不斷重複,也就是常說的Event Loop(事件循環)。
而宏任務通常是:包括總體代碼script,setTimeout,setInterval。
微任務:Promise,process.nextTick。
記住就好了。
因此正確的執行結果固然是:
2,4,3,1。
由於settimeout是宏任務,雖然先執行的他,可是他被放到了宏任務的eventqueue裏面,而後代碼繼續往下檢查看有沒有微任務,檢測到Promise的then函數把他放入了微任務序列。等到主線進程的全部代碼執行結束後。先從微任務queue裏拿回掉函數,而後微任務queue空了後再從宏任務的queue拿函數。