前端面经 300条,背完这些就够了!
前沿
確實有些標題黨哈,但是確實是本人秋招之間總結的經驗,前端崗位,會很多也不行,有時候秋招就是面試官看你的知識廣度和深度,特別是前端的崗位,設計的方方面面太多了,只有提前準備好,理解好,然后背下來,才能夠在秋招中暢通無阻~
經驗之談:秋招 = 項目要好 + 基礎要牢(牢固 + 牢記,直接背誦就好了) + 深度(一些框架的原理,弄明白)+ 做題(算法題要會寫吧,刷題)
正文
東西太多,網頁端閱讀可能不方便,特提供以下方式:
① html 版本:免積分下載
② Anki 背誦版本:用 anki 軟件背誦的,這個導出挺麻煩的,需要的可以評論區告知。
1
flash和js通過什么類如何交互?
ExternalInterface
2
call和apply:
- apply傳入的是一個{{c1::參數數組}}。
- call傳入的則是直接的{{c1::參數列表}}
apply 數組
call 列表
3
路由懶加載、異步加載、React 文件加載有辦法解決嗎?
1、react-loadable:將js 拆分成若干個chunk.js
2、react-router 創建一個異步組件 AsyncComponent,然后使用AsyncComponent動態導入組件。
4
為什么瀏覽器要設置跨域的防范
假如我是A網的管理員,登錄了我的賬號,然后B網站被攻擊了,被植入了一個iframe,里面調用了我通過POST刪除用戶的接口,這樣我只要訪問了B網站被攻擊的頁面,就會刪除用戶,所以為了避免敏感信息接口被攻擊,需要設計為跨域。
5
image標簽把href寫成b.com,為什么不收到跨域的限制?為什么只對AJAX做限制,對圖片不做限制?圖片地址也可以寫一個api接口,為什么不做限制呢?
1、圖片是GET請求,我們設計API時不應用GET做敏感事情。
2、支持跨域的標簽還有:image、iframe、link、script
6
瀏覽器怎么知道允不允許跨域?我如果根據header的話,那就已經請求了一次,怎么解決?
如果同源,瀏覽器發送數據請求,否則發送跨域請求
瀏覽器收到跨域請求后,返回自身配置的是否含有Access-control-Allow-origin字段
瀏覽器收到這個header后,匹配看是否允許,允許的話則發送數據請求。
7
Promise直接resolve,和setTimeout 0,誰先執行?為什么?
Promise先執行
主線程從"任務隊列"中讀取事件,這個過程是循環不斷的,所以整個的這種運行機制又稱為Event Loop(事件循環)。
Promise.resolve() 是微任務,本輪事件循環結束時執行
setTimeout(fn,0)是宏任務,在下一輪“事件循環”event loop開始時執行
8
__proto__知道嗎?原型鏈,聲明一個object a, 然后讓 a.proto.b,js原來是面向過程的,但是es6/es7又支持了class,原來不支持class,是怎么模擬的?
prototype是函數才有的屬性,__proto__是每個對象都有的屬性
對象的__proto__等于生成這個對象的函數的prototype
ES6類的底層還是通過原型鏈構造函數去創建
9
React現在官方推薦使用Function組件,之前是class,他們兩個有什么區別?
function組件沒有state狀態,刪除了生命周期,速度會很快
class組件適合有狀態組件
10
解釋性語言一行一行執行怎么支持類的
1、解釋型是說不需要編譯,每次執行的時候,再去轉為機器語言運行。
2、而是否面向對象,說的是語言的模式,是面向過程還是面向對象的。所以這倆沒什么關聯,是不同的分法
11
JS的數據類型有哪些?
① JS有八種數據類型:Number、String、Boolean、Null、undefined、object、symbol、bigInt
② 其中除了object之外都是基本類型,而引用類型分為:Object、Array、RegExp、Date、Function。
③ 基本類型和引用類型有四點區別:
1、基本類型保存在棧中,引用類型保存在堆中。
2、基本類型按值訪問,引用類型按引用訪問。
3、基本類型的值不能改變,引用類型的值可以改變。
4、基本類型的比較是值的比較,引用類型的比較是引用的比較。
12
函數式編程
函數式編程的本質
1、函數式編程中的函數指的不是計算機里面的函數,而是數學中的函數,即自變量的映射
2、只要輸入是確定的,輸出就是確定的
函數式編程的好處
1、函數式編程引用透明,沒有副作用。
2、函數不依賴外部狀態,這樣寫的代碼不容易出錯。
3、不共享狀態就不會造成資源爭奪,也不需要鎖,也不會出現死鎖。
13
Babel/Webpack 分別講一下,在項目中用到過嗎?
1、Babel 是一個JS編譯器,用來轉換最新的JS語法,比如把ES6, ES7等語法轉化成ES5語法。提供了一些插件轉換最新的 api,如 babel-pilofill, 基于 core-js 和 regenerator. 也支持 React 的 JSX 語法。
2、Webpack 是一個打包工具,打包js文件,css文件,圖片,html等等,可以分析文件結構,確定文件依賴,合并壓縮js,加入hash,最終生成項目文件。
3、在使用過的飛冰框架ice-js和微信小程序框架taro中都有應用
14
瀏覽器渲染的過程
HTML 解析成 DOM 樹
CSS 構造成 CSS 對象模型
DOM 和 CSS 模型合并為渲染樹,渲染樹每個元素的內容都是計算好的 layout.
將渲染樹的節點繪制到屏幕上。
15
重排、重繪、合成
1、重排: 修改幾何屬性,如寬高度,會重新布局
2、重繪:修改繪制屬性,如背景顏色,直接進入繪制階段。
3、合成:更改一個既不要布局也不要繪制的屬性,渲染引擎會跳過布局和繪制,在非主線程上合成,如更改 transform屬性。
優化:
1、使用class
2、使用React的虛擬節點
3、避免使用table布局
4、使用硬件加速
5、帶動畫的元素position:absolute或fixed、不顯示的元素使用display: none
16
減少白屏的方式
script放在 body后面
script 加defer屬性
減少 head里的css資源
gzip壓縮文件體積
17
React Fiber 了解嗎?引入 React Fiber 的好處是什么?
1、React filber 是一種基于瀏覽器的單線程調度算法,將遞歸的diff拆分成無數個小任務,可以隨時停止與恢復。
2、React fiber優化了虛擬DOM的diff算法,將組件渲染拆分為無數個具有優先級的分片任務,防止瀏覽器在組件個數較多的時候后陷入假死卡頓狀態。
18
HTTP 請求方法
GET、POST、PUT、DELETE、PATCH
HEAD、CONECTION、OPTIONS、TRACE
19
HTTP 請求狀態碼
一共有五類:1是臨時響應,2是成功,3是重定向,4是客戶端錯誤,5是服務端錯誤。
1、100(繼續)、101(切換協議)
2、200(成功)、201(成功并創建資源)、204(成功但沒有返回內容)
3、301(永久移動)、302(臨時移動)、304(服務端已執行 GET, 但是文件未變化)
4、400(錯誤請求)、401(未授權)、403(禁止訪問)、404(未找到)、405(請求方法不支持)、408(請求超時)、410(已經刪除)
5、500(服務器內部錯誤)、501(網關錯誤)、503(服務不可用)、504(網關超時)
20
Webpack HMR 的原理詳細介紹一下
首先建立 WebSocket 連接
文件發生變化,Webpack Dev Server 通知應用程序
HMR Runtime 通過 HTTP 請求模塊更新清單
script 標簽下載模塊更新
插入新模塊、進行局部刷新。
21
webpack優化方式,如何提高 webpack 的構建速度
優化方式:https://www.cnblogs.com/wangjiachen666/p/11561186.html
Loader 縮小文件搜索范圍
對編譯文件使用緩存
多線程打包 happypack
image-webpack-loader 壓縮圖片
刪除無用的 css 樣式
CDN 加載資源
22
JS的深拷貝與淺拷貝
① 淺拷貝:Object.assign(obj), … 展開運算符
② 深拷貝:
1、JSON先stringify再parse.
2、遞歸實現一個深拷貝:clone函數里面判斷類型,如果是基本類型直接返回,如果是object,則定義一個空對象,然后用for key in 的方式遞歸調用clone來深拷貝每一個屬性。還可以用一個Map來避免循環引用。
3、jQuery.extend()
4、lodash.cloneDeep()
23
js判斷數據類型的方法,以及他們的優缺點?
① typeof:缺點是基本類型null返回的是object,引用類型中除了function外返回的都是object。
② constructor:缺點是無法判斷null和undefined,而且重寫prototype后也無法判斷。
③ Object.prototype.toString.call(value),默認返回當前對象的class,用中括號括起來的[object + 類名].
24
toString()方法返回的是什么東西?
返回的是當前對象的字符串形式。
25
new 操作發生了什么?如何實現一個 new?
假設構造函數為 Fun,接收參數為 args
① 根據構造函數的原型,創建一個新對象
let obj = Object.create(Fun.prototype)
② 對對象應用參數,改變 this 指向
let result = Fun.apply(obj, args)
③ 如果返回的是 object, 則返回這個 result,否則返回第一步創建的 obj
return typeof reuslt === ‘object’ ? result : obj
整體代碼如下:
function myNew (Fun, …args) {
let obj = Object.create(Fun.prototype)
let result = Fun.apply(obj, args)
return typeof reuslt === ‘object’ ? result : obj
}
26
函數的防抖與節流
1、函數防抖與節流都可以避免頻繁觸發事件。
2、函數防抖與節流都可以使用setTimeout實現,目標都是降低執行頻率。
3、函數防抖讓連續觸發的事件只執行最后一次,而函數節流側重于一段時間內只執行一次。
4、應用:加載更多、輸入框輸入、避免重復提交。
27
Promise的過程
Promise是一個具有三種狀態的狀態機:pending、resolved、rejected.初始是pendig,調用resolve變成resolved,調用rejected變成rejected.
28
實現一個Promise.all
1、Promise.all概述:返回一個Promise,參數內所有的Promise都resolved后回調一個結果數組,有一個rejected則會回調失敗。
2、實現:
① 輸入時一個數組,輸出new 一個 Promise.
② 函數內定義一個數組result,來存放最終結果。
③ 返回的Promise內使用for循環,把每一個Promise.then的結果放入result,如果發生了reject則直接reject,如果結果數組的長度等于輸入數組的長度,則resolve(result).
function isPromise(obj) {
return !!obj && (typeof obj === ‘object’ || typeof obj === ‘function’) && typeof obj.then === ‘function’;
}
const myPromiseAll = (arr)=>{
let result = [];
return new Promise((resolve,reject)=>{
for(let i = 0;i < arr.length;i++){
if(isPromise(arr[i])){
arr[i].then((data)=>{
result[i] = data;
if(result.length === arr.length){
resolve(result)
}
},reject)
}else{
result[i] = arr[i];
}
}
})
}
29
前端框架的MVVM模式
1、VM視圖模型層通過接口從后臺model層請求數據,然后VM層與view層實現數據的雙向綁定。
2、優點:促進了前后端分離,提升了前端開發效率。
30
VUE里面的數據劫持+發布訂閱模式,實現雙向數據綁定。
vue.js 是采用數據劫持結合發布者-訂閱者模式的方式實現MVVM的,VUE 2 使用的是Object.defineProperty()。
實現過程:
1.實現一個監聽器Observer,用來劫持并監聽所有屬性,如果有變動的,就通知訂閱者。
2.實現一個訂閱者Watcher,可以收到屬性的變化通知并執行相應的更新函數,從而更新視圖。
3.實現一個解析器Compile,可以掃描和解析每個節點的相關指令,并初始化模板數據以及訂閱器。
31
CSS 相對于父元素垂直居中
1、display:inline-block的時候可以vertical-align:middle
2、用display:flex和align-items: center;
3、inline-height 和父元素高度一樣。
4、transform: translateY(-50%)
32
BFC
① BFC 概念:塊格式化上下文,是一個獨立的布局環境。
② 適合類型:根元素、浮動元素、絕對定位元素、display: inline-block/flex/inline-flex/table-cell、overflow: 非visible。
③ 作用:清除浮動、BFC內部外邊距折疊、不同的BFC可以避免外邊距折疊。
33
響應式布局
使用百分比、rem、vw、flex、媒體查詢五種方式
① 使用百分比
② 使用媒體查詢對不同分辨率設置不同css樣式
③ 使用 rem:相對于html元素的font-size值
④ 使用 vw
⑤ 使用 flex
34
304 協商緩存
① 200是強緩存,直接從緩存中取。304是協商緩存,通過服務器告知緩存是否可用。
② 服務器上的資源不是一成不變的,如果我們還訪問本地緩存,那么對用戶來說,那就相當于資源沒有更新,用戶看到的還是舊的資源。
35
跨域的解決方案
① 服務器返回一個header:Access-Control-Allow-Origin
② jsonp跨域:利用script標簽的src屬性
③ 代理跨域
④ 設置 document.domain 解決一級域名相同,二級域名不同的情況。
其他的方式:
① hash 跨域通信:A 里面通過 iframe 嵌入了一個 B,然后 A 修改 B 的 url hash, B 里面通過 onhashchange 監聽到 hash 變化。
② postMessage:窗口 A 中 window.postMessage(數據,來源), 窗口 B 中 window.addEventListener(‘message’, event) 接收。
36
CSS 優先級
!important > 內聯樣式>ID選擇器 > 類選擇器 > 標簽 > 通配符 > 繼承 > 瀏覽器默認屬性
37
cookie的屬性,前端怎么設置cookie,可以設置cookie的哪些屬性
① cookie 屬性:expires 過期時間、domain/path 域名和路徑、secure 安全發送、httpOnly 只允許http訪問,不允許 js 訪問。
② 前端設置cookie 的方法:document.cookie=,一次只設置一個,多個需要多次。
③ 前端可以設置的 cookie:httpOnly不能設置,secure 在 https 時才能設置,其他都可以。
38
XSS攻擊
① 概念:XSS 中文是跨站腳本攻擊,指的是攻擊者向網頁植入惡意代碼,用戶瀏覽器會被控制或者導致隱私泄露。
② 分類: 分為反射型(如放置一個惡意跳轉鏈接)、存儲型(通過發表評論向數據庫注入js代碼,然后所有瀏覽該帖子的瀏覽器都會執行這段代碼)、基于DOM (通過惡意腳本修改頁面的 DOM 結構)
③ 防范:HttpOnly 防止截取 Cookie、輸入檢查、輸出檢查。
39
為什么第二個參數是[]時,只會在組件mount時執行
useEffect 源碼里面有一個if,說如果沒有依賴,或者依賴發生變化,則執行callback,而如果數組為空,依賴一直不變化,callback不會二次執行。
40
原型
① 是什么:prototype屬性是一個指針,指向一個對象。
② 用途:它包含該類型所有實例共享的屬性和方法,
③ proto和prototype的關系:每個實例對象的__proto__都指向這個構造函數/類的prototype屬性。
41
閉包
① 閉包簡單來說就是函數嵌套函數,詳細說就是閉包可以讓一個函數訪問并操作其聲明時的作用域中的變量和函數,并且,即使聲明時的作用域消失了,也可以調用。
② 內部函數引用來外部函數的變量,從而導致垃圾回收機制沒有把當前變量回收掉,這樣的操作帶來了內存泄漏的影響。
例子:
然后就能夠通過 counterRef.current 訪問這個 DOM 對象。
useRef 的第二個用法:跨渲染周期保存數據
// 首選創建一個 ref const timerID = useRef()// 初始的時候,給 timerID.current 設置一個定時器 useEffect(() => {timerID.current = setInterval(()=>{setCount(count => count + 1);}, 1000); }, []);//194
Object.is() 用來做什么?
比較基本類型,值相同。比較引用類型,引用相同。
195
為什么使用 React.Children.map(props.children, () => {}), 而不是直接 props.children.map(() => {})?
因為不能保證 props.children是一個數組,單個的話就是一個對象,多個才是數組,而React.Chilredn.map可以自動處理這兩種情況。
196
描述事件在 React 中的處理方式
① 事件處理程序通過合成事件 (SyntheticEvent) 的實例傳遞,SyntheticEvent 是瀏覽器原生事件跨瀏覽器的封裝。SyntheticEvent 是池化的,可以通過 e.persist() 對事件進行保留。但是在 React 17 中,移除了事件池,不需要主動保留了。
② React 沒有將事件附加在子節點本身,而是通過事件委托模式代理。
197
ES5 / ES6 的 React 有什么區別?
① 組件定義:ES5 使用 React.createClass, ES6 是繼承 Component 的一個 class。
② 默認 props: ES5 使用 getDefaultProps, ES6 使用 defaultProps
③ 初始 state: ES5 使用 getInitialState, ES6 使用 this.state = xxx
198
Object.assign() 的作用
① 用法:
Object.assign(target, …sources)
② 作用:將所有可枚舉屬性的值從一個或多個源對象復制到目標對象,并返回目標對象。
199
Reducer 文件里,對于要返回的結果,要注意什么問題?
需要使用 Object.assign({}, state, …newState)淺拷貝一份。
200
Vue 和 React 的區別
① 編寫方式:Vue 使用 HTML 模板文件,React 完全使用 JS 創建 DOM
② 數據綁定:Vue 是雙向綁定,React 是單向流動。
③ 狀態:React 中 state 是不能直接改變的,需要使用 setState,而 Vue 中 state 不是必須的,數據主要是在 data 屬性里,能直接修改。
201
副作用是什么?
函數式編程將那些與數據計算無關的操作,都稱為副作用 side effect。如生成日志、存儲數據、改變狀態等。
202
HTTP 管線化
管線化后,請求和響應不再是交替的順序。可以一次性發送多個請求,一次性接收多個響應。只支持 GET 與 HEAD。
203
HTTP 3
讓 HTTP 跑在 QUIC 上,而不是 TCP 上,QUIC 的特點有以下幾個方面:
① 基于 UDP, 實現快速握手。
② 在 UDP 的基礎上,實現了類似 TCP 的超時重傳、流量控制、擁塞控制等可靠性措施。
③ 集成了 TLS1.3,減少了握手時間。
④ 多路復用,同一條物理連接上可以有多個獨立的邏輯數據流,徹底解決 TCP 中隊頭阻塞的問題。
204
React.lazy() 用法
用途是動態調用 import(), 封裝的是組件的導入行為,需要配合 Suspence 使用,Suspence 有一個 fallback 屬性,用來在異步加載的時候,顯示一個 Loading
205
PureComponent 的使用、純組件與普通組件的區別
純組件的使用
① PureComponent 通過 props 和 state 的淺比較實現 shouldComponentUpdate
② 如果狀態更新涉及到一個對象內部的更新,則不應該使用 PureComponent.
純組件與普通組件的區別
① 純組件在 render 之前會進行淺比較,普通組件不會。
② 也不能濫用純組件,因為純組件多了一個淺比較的步驟,濫用反而拖累性能。
順便說一下,React 判斷類組件是否需要更新,只有兩個地方:
一是看有沒有shouldComponentUpdate方法,二就是這里的PureComponent判斷
206
useEffect 返回函數的作用是什么?
清除上一次副作用遺留下來的狀態。
207
useMemo、useCallback 的用法
① 使用 useMemo 可以避免無用方法的調用:一個函數直接寫在 render 中,當重新渲染的時候,就會又觸發一次這個函數。而如果使用 useMemo 包裹,則只當依賴變化的時候才會調用,渲染的時候不會主動觸發。
② useCallback: 相當于 useMemo 回調函數返回一個函數.
208
TS 都有哪些數據類型?
在 js 基礎上,增加了:
tuple 元祖
enum 枚舉
any, never 任意值
void 沒有返回值
209
webpack 的緩存機制,三種 hash?
① hash: 修改任何一個文件,所有文件的 hash 都會改變
② chunkhash: 根據不同的入口文件,生成對應的哈希值。將公共庫和程序入口文件分開,只要不改動公共庫的代碼,就可以保證其哈希值不會受到影響。
③ contenthash: chunkhash 有個問題,css 或 js 改變,與之關聯的文件的 hash 也會改變,哪怕其文件內容沒變。contenthash 能夠解決這個問題。
210
DOM 樹的構建過程
① Conversion 轉換:將 HTML 內容根據編碼轉換為字符流。
② Tokenizing 分詞: 根據 HTML 規范,將字符流解析為標記。
③ Lexing 語法分析: 將標記轉換為對象,并定義屬性和規則。
④ DOM 構建: 根據 HTML 標記關系,將對象組成 DOM 樹。
211
no-cache 指的是不緩存嗎?
不是,no-cache 指的是每次都向服務器驗證。no-store 才是不緩存。
212
DNS 預解析
① 自動解析:http 下碰到 a 標簽,會自動解析,https 為了安全默認不會。
② 手動解析:
link 標簽:
meta 標簽,可強制開啟 HTTPS 下的預解析:
213
Scope Hoisting
分析模塊之間的依賴關系,盡可能地把打包出來的模塊合并在一個函數中去,能減少代碼量,開啟方式是設置 optimization.concatenateModules 為 true
214
Object.create() 作用,實現
作用:創建一個新對象,使用現有的對象來提供新對象的 proto。
實現:創建一個空函數,然后函數的 prototype 等于 obj,然后再恢復 constructor,最后返回一個實例化
Object.prototype.myCreate = function (obj) {
function Fn () {}
// 這里直接指向 obj
Fn.prototype = obj
Fn.prototype.constructor = Fn
return new Fn()
}
215
React setState 是同步還是異步?
結論:既可能是同步的,也可能是異步的。
具體來說:在 React 內部機制能檢測到的地方,setState 就是異步的;在 React 檢測不到的地方,如 setInterval, setTimeout 里,setState 就是同步的。
再細節一點:本身并不異步,只是因為 React 的性能優化機制表現為異步。在 React 的生命周期函數或作用域下為異步,在原生的環境下為同步。
216
nodeJS 的事件循環
事件循環的順序
timers 階段:這個階段執行 timer(setTimeout、setInterval)的回調
I/O callbacks 階段:處理一些上一輪循環中的少數未執行的 I/O 回調
idle, prepare 階段:僅 node 內部使用
poll 階段:獲取新的 I/O 事件, 適當的條件下 node 將阻塞在這里
check 階段:執行 setImmediate() 的回調
close callbacks 階段:執行 socket 的 close 事件回調
process.nextTick
這個函數其實是獨立于 Event Loop 之外的,它有一個自己的隊列,當每個階段完成后,如果存在 nextTick 隊列,就會清空隊列中的所有回調函數,并且優先于其他 microtask 執行。
node 與瀏覽器端的不同
Node 端,microtask 在事件循環的各個階段之間執行
瀏覽器端,microtask 在事件循環的 macrotask 執行完之后執行
217
小程序的優化
① 減少請求次數
② setDate 不要太頻繁
③ wxss 能寫一行的不寫多行
④ 盡量使用緩存、刷新使用局部刷新
⑤ 開啟壓縮,降低代碼量
⑥ 資源控制,清除無用代碼、資源
⑦ 分包加載、分包預加載
⑧ 骨架屏
218
小程序的優缺點
優點
① 容易上手
② 兼容性問題相對來說少
③ 自帶統計
④ 支持插件開發、云開發
缺點
① 后端調試麻煩
② 模擬器和真機有時不一致,安卓和 iOS 有時不一致
③ native 組件存在遮擋問題
④ 能力上的限制:new Function,eval,Generator,沒有 cookie,沒有 DOM
219
vue 組件通信
① 父子通信:直接通過 props
② 子父通信:綁定事件,然后 $emit 傳值
③ Vuex 通信:通過 Store 通信。
220
TCP長連接和短連接的區別和應用場景是什么?
區別
① 長連接:在一個 TCP 連接上可以連續發送多個數據包,如果沒有數據包發送,需要雙方發送心跳包保活。
② 短連接:有數據交互時,就建立一個 TCP 連接,數據發送完成后,就斷開。
應用場景
① 長連接:頻繁讀寫,點對點,連接數少,如數據庫的連接使用長連接。
② 短連接:WEB 服務器,高并發使用短連接,否則的話連接太多。
221
小程序和普通網頁開發的區別
① 線程:網頁開發 JS 線程和渲染線程是互斥的,小程序是在不同的線程中的。
② DOM: 小程序的邏輯層和渲染層是分開的,沒有 DOM API,一些庫沒法使用。
③ 兼容:網頁開發需要兼顧各種瀏覽器、手機、電腦,小程序開發只需要考慮 Android 和 iOS
④ 開發流程:網頁開發只需要自己的服務器即可,小程序開發還需要賬號申請、審核、發布等流程。
222
小程序做不了,H5 能做的?
比方說想做一個在線運行 JS 的編輯器,小程序由于不能使用 eval,因此沒法直接使用,只能使用服務器中轉一下。
223
表單提交規則
分為以下幾個步驟:
① 識別所有的成功組件
② 為成功組件創建一個數據集合,包含 name 和 value 的鍵值對。
③ 按照編碼規則,對這些數據進行編碼。
④ 提交編碼后的數據。
成功組件如:
① 非 disabled
② 選中的 checkbox, radio, select, 選擇了文件的 file 上傳。
224
小程序的數據共享
① 利用頁面的 url 傳遞
② 利用 localStorage 傳遞
③ 通過一個全局變量,掛在 getApp() 上
225
DOCTYPE
① 作用:它是用來告知 Web 瀏覽器頁面使用了哪種 HTML 版本
② 版本:
1.0: (Strict, Transitional, Frameset)
4.01: (Strict, Transitional, Frameset)
5.0: 只有一種
③ 三種之間的區別:
Strict: 不允許過時標簽,不允許框架集。
Transitional: 允許過時標簽,不允許框架集
Frameset: 允許過時標簽,允許框架集
226
偽元素和偽類的區別,都有哪些?
區別:
① 本質:偽類本質上是為了彌補常規選擇器的不足,偽元素本質上是創建了一個有內容的虛擬容器。
② CSS3 中冒號的數量不同:偽類是一個,偽元素是兩個。
③ 數量:偽類可以有多個,偽元素同時只能使用一個。
偽類有:
① :hover
② :active
③ :firsr-child
④ :visited
偽元素有:
① :first-line
② :first-letter
③ :after
④ :before
單個冒號和兩個冒號的區別:
單個冒號是 CSS2 的寫法,兩個冒號是 CSS3 的寫法。
227
媒體查詢的原理
窗口的 onresize 事件,得到窗口大小,匹配對應的樣式修改。
228
localStorage 的最大存儲空間是多少
5Mb,超出會報錯:exceeded error
229
async/await 和 Promise 的區別
① async/await 函數前面多了一個 async 關鍵字
② async/await 更加簡潔
③ async/await 可以同時處理同步和異步錯誤
④ 調試的時候,如果多個 Promise 其中一個出現了錯誤,堆棧信息很亂很誤導人,而 async/await 直接給出行號。
230
Proxy 和 Reflect
Proxy 代理
① 作用:Proxy 就是操作對象的中間媒介,要操作對象的話,需要經過這個媒介同意。
② 例子:首先創建一個 obj,然后 new Proxy(obj, 代理行為),代理行為里面可以寫 get 和 set, 則在獲取、設置的時候,都會首先經過這樣的一層中間代理。
Reflect 反射
① 作用:Reflect 可以當做 object 的工具類來使用。
② 例子:
獲取屬性:Reflect.get(obj, ‘key’)
設置屬性:Reflect.set(obj, ‘key’, value)
231
小程序的運行環境
環境 邏輯層 視圖層
iOS JavaScriptCore WKWebView
Android V8 自研 XWeb 引擎,基于 Mobile Chrome 內核
開發者工具 NW.js Chromium Webview
232
上傳多個文件,其中可能會有失敗的,使用 Promise.all 的話,失敗的話就會直接 reject,怎么讓讓失敗的異步請求不影響其他成功的異步請求?
所有的 Promise 的 catch 中,直接返回一個 Promise.resolve()
const p1 = new Promise(resolve => {
const a =b;
resolve(a);
}).catch(()=>{
// 直接返回這個
return Promise.resolve(‘aaab’)
});
?
const p2 = new Promise(resolve => {
const a =1;
return resolve(a);
}).catch(()=>{
return Promise.resolve(‘aaa’)
});
Promise.all([p1,p2]).then((data)=>{
console.log(‘then 成功’,data);
}).catch((err)=>{
console.log(‘333’);
console.log(‘errr’,err);
})
實際上就是新出的 API :Promise.allSettled
其他還有實現:https://www.jianshu.com/p/c5c3c2595c98
233
redux-thunk
作用
實現異步,可以將 thunk 看做 dispatch 方法的封裝器,使用 redux-thunk 之前,只能 dispatch 一個 action 對象,使用之后可以 dispatch 一個函數,然后就可以在函數里面做一些邏輯處理工作。
使用
dispatch 里面填一個回調函數,參數還是 dispatch, 然后在這個函數內部進行一步請求,異步請求拿到結果后再 dispatch.
實現
function createThunkMiddleware(extraArgument) {
return ({ dispatch, getState }) => next => action => {
if (typeof action === ‘function’) {
return action(dispatch, getState, extraArgument);
}
?
return next(action);
};
}
?
const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;
?
export default thunk;
234
函數式編程的 compose
作用
把一系列的函數,組裝生成一個新的函數,并且從后往前,后面函數的執行結果,作為前一個函數的參數。
實現
// 從右到左
function compose() {
var fns = [].slice.call(arguments)
return function (initialArg) {
var res = initialArg
for (var i = fns.length - 1; i > -1; i–) {
res = fnsi
}
return res
}
}
?
// 從左到右
function pipe() {
var fns = [].slice.call(arguments)
return function (initialAgr) {
var res = initialAgr
for (var i = 0; i < fns.length; i++) {
res = fnsi
}
return res
}
}
?
// 測試
var greet = function (name) { return ‘hi:’ + name }
var exclaim = function (statement) { return statement.toUpperCase() + ‘!’ }
var transform = function (str) { return str.replace(/[dD]/, ‘DDDDD’) }
var welcome1 = compose(greet, exclaim, transform)
var welcome2 = pipe(greet, exclaim, transform)
console.log(welcome1(‘dot’))//hi:DDDDDOT!
console.log(welcome2(‘dolb’))//HI:DDDDDOLB!
235
怎么配置單頁應用?怎么配置多頁應用?
單頁應用可以理解為webpack的標準模式,直接在entry中指定單頁應用的入口即可,這里不再贅述
多頁應用的話,可以使用webpack的 AutoWebPlugin來完成簡單自動化的構建,但是前提是項目的目錄結構必須遵守他預設的規范。 多頁應用中要注意的是:
每個頁面都有公共的代碼,可以將這些代碼抽離出來,避免重復的加載。比如,每個頁面都引用了同一套css樣式表
隨著業務的不斷擴展,頁面可能會不斷的追加,所以一定要讓入口的配置足夠靈活,避免每次添加新頁面還需要修改構建配置
236
npm打包時需要注意哪些?如何利用webpack來更好的構建?
① 要支持 CommonJS 模塊化規范
② 打包結果應該上傳 ES5的,SourceMap 也要一塊上傳。
③ 包的大小應該盡可能小
④ 不打包所依賴的模塊,讓用戶自己去選擇是否安裝依賴。
⑤ UI 資源也要打包。
基于以上需要注意的問題,我們可以對于webpack配置做以下擴展和優化:
CommonJS模塊化規范的解決方案: 設置output.libraryTarget='commonjs2’使輸出的代碼符合CommonJS2 模塊化規范,以供給其它模塊導入使用
輸出ES5代碼的解決方案:使用babel-loader把 ES6 代碼轉換成 ES5 的代碼。再通過開啟devtool: 'source-map’輸出SourceMap以發布調試。
Npm包大小盡量小的解決方案:Babel 在把 ES6 代碼轉換成 ES5 代碼時會注入一些輔助函數,最終導致每個輸出的文件中都包含這段輔助函數的代碼,造成了代碼的冗余。解決方法是修改.babelrc文件,為其加入transform-runtime插件
不能將依賴模塊打包到NPM模塊中的解決方案:使用externals配置項來告訴webpack哪些模塊不需要打包。
對于依賴的資源文件打包的解決方案:通過css-loader和extract-text-webpack-plugin來實現
https://blog.csdn.net/duyujian706709149/article/details/97299339
237
webpack 如何在 vue 項目中實現按需加載?antd 如何實現按需加載?
① 組件庫現成的解決方案
名稱是:Element 的 babel-plugin-component, AntD 的 babel-plugin-import
原理是:將 import 的路徑具體化,比方說 import { Button } from ‘antd’, 替換成 import { Button } from ‘antd/lib/button’
缺點是:每一個按需加載的 chunk 中都單獨打包相關的模塊,導致每一個 chunk 的體積都比較大。
② 使用 webpack 的 externals 配置
原理是:配置之后,webpack 打包時會繞過這些引用
缺點是:會外部單獨引入一個 antd.min.js, 大約 1Mb
③ 最佳方案:使用 webpack 的 CommonsChunkPlugin 插件
原理是:CommonsChunkPlugin 能提取第三方庫和公共模塊,避免首屏加載的 bundle 文件或者按需加載的 bundle 文件體積過大。
238
兩欄布局、兩列布局
① 浮動:兩個 div,第一個浮動,設置固定寬度即可。
② 絕對定位:父元素 relative,兩個子元素 absolute,然后設置第二個子元素的 left 為左邊的寬度。
③ flex 布局:父元素 flex, 左邊固定寬度,右邊 flex: 1;
239
為什么在有 HTTPS 的情況下,還要使用 RSA 呢
HTTPS 防止中間人攻擊,RSA 驗證身份,缺一不可。
比如一個 HTTPS 接口,誰都可以調用,但是自己的公鑰加密的數據,就可以知道這是我自己的程序在調用接口。
240
Taro 的優缺點
優點
① React 方式組件開發
② 多端開發
缺點:核心就是架構問題
① 和 React DSL 強綁定
② JSX 適配工作量大、社區貢獻復雜
③ 使用靜態編譯的方式去處理動態的 JS 語言,稍微有一點變化,就可能會不適用。
④ React 新特性需要手動對接
⑤ 前端生態無法復用
⑥ 錯誤棧復雜,而且沒有 SourceMap
241
靜態編譯和動態編譯的優缺點,性能測試
優點
① 性能上:同等條件下,編譯時做的工作越多,運行時做的工作越少,性能更好。
② 可讀性:重編譯時,就保證了編譯之后代碼也具有可行性。
缺點
① 性能:長久來看,硬件性能剩余會越來越多,犧牲一點性能換取更大的開發靈活性會更好。
② 適配:需要適配很多的 JSX
其他缺點:
① 和 React DSL 強綁定
② JSX 適配工作量大、社區貢獻復雜
③ 使用靜態編譯的方式去處理動態的 JS 語言,稍微有一點變化,就可能會不適用。
④ React 新特性需要手動對接
⑤ 前端生態無法復用
⑥ 錯誤棧復雜,而且沒有 SourceMap
性能測試
taro-benchmark
242
在端上運行的程序,它的瓶頸主要在什么地方?
① 內存
② 大小
③ CPU 線程
243
JS 執行和渲染拆開后,有什么好處?雙線程有什么好處?
① 性能:UI渲染和 JS 腳本在一個單線程中執行,這就容易導致一些邏輯任務搶占UI渲染的資源
② 安全性:阻止開發者使用一些瀏覽器提供的開發性接口,諸如跳轉頁面、操作 DOM、動態執行腳本。
③ 方便基礎庫 BUG 修改:渲染層和邏輯層是兩個線程管理,兩個線程各自注入了基礎庫。可以單獨修復其中一個基礎庫的 BUG。
244
taro 的一些新的變化?背后的原理是什么?Taro 最新的架構?
https://mp.weixin.qq.com/s?__biz=MzU3NDkzMTI3MA==&mid=2247483770&idx=1&sn=ba2cdea5256e1c4e7bb513aa4c837834
新的變化:
沒有 DSL 限制:無論是是 React 還是 Vue 技術棧,都能夠使用 Taro 開發
模版動態構建:和之前模版通過編譯生成的不同,Taro Next 的模版是固定的,然后基于組件的 template,動態 “遞歸” 渲染整棵 Taro DOM 樹。
新特性無縫支持:由于 Taro Next 本質上是將 React/Vue 運行在小程序上,因此,各種新特性也就無縫支持了。
社區貢獻更簡單:錯誤棧將和 React/Vue 一致,團隊只需要維護核心的 taro-runtime。
基于 Webpack:Taro Next 基于 Webpack 實現了多端的工程化,提供了插件功能。
背后的原理:
① 前端的本質:無論是用什么框架,React 還是 Vue,最終代碼都是調用了瀏覽器那幾個 BOM/DOM 的 API
② Taro 的實現:
如何動態渲染出 DOM 樹
創建一個 taro-runtime 包,實現了一套高效、精簡的 BOM/DOM API
通過 Webpack 的 ProvidePlugin 插件,注入到小程序的邏輯層
React 精簡:React-DOM 含有大量瀏覽器兼容的代碼,去除了這部分的代碼。
React 三部分核心:核心 react-core, 與虛擬 DOM 有關的 react-reconciler, 與渲染有關的 Renderer,Taro 實現了 taro-react 包,替換掉 Renderer 用來連接 react-reconciler 和 taro-runtime.
具體這樣做:在 hostConfig 配置中調用Taro的 api,實現一個創建 DOM 樹的 render。
DOM 樹如何更新到頁面
基于組件模板,動態地遞歸渲染整棵樹。
245
remax 的短板,優缺點?
優點
基于真正 React 開發,無縫使用 Redux/Mobx 等狀態管理庫。
完全支持 TypeScript,為組件和 API 提供完整的類型支持。
跨平臺,使用一套代碼同時開發小程序和 H5 應用。
缺點
① 小程序編譯后,模板組件引入過多。有個 base.axml。但是支付寶不支持在 template 里引用小程序自定義組件。所以現在所有頁面里都包含了所有的 template,可以優化下如果頁面沒用到小程序自定義組件,那就引用 base.axml
② 原生混合開發會編譯兩次:原生寫法和 Remax 寫法同時依賴的模塊會被打包兩次。解決方案:把所有小程序頁面和自定義組件的 js 全部作為 entry 放入 webpack 的編譯流程,這樣公共模塊就能抽到 common chunk 里。
③ 性能問題:動態模板渲染的方式,將這部分工作放在了用戶手機上,對算力的要求更高。
https://remaxjs.org/guide/advanced/hybrid
246
云開發與普通開發的優點、缺點
優點:
① 規模經濟:利用云計算供應商提供的基礎設施,同在單一的企業內開發相比,開發者能夠提供更好,更便宜和更可靠的應用
② 配套齊全:直接提供了數據庫、存儲、云函數、用戶鑒別能力
缺點:
① 安全性:數據不在自己手上,可能會丟失數據。
② 數據備份機制:雖然有數據備份接口,但是可能會超出云函數20秒的時間限制,總之還是不靈活。
247
React context,如果有多個 context 怎么使用?
① 使用 React.createContext() 創建兩個 contextA, contextB
② 兩個 Provider 嵌套,兩個 Consumer 嵌套,即 contextA.Provider 點出來之后嵌套。
③ 順序不重要,要注意語法。
248
函數式組件比類組件有什么優勢?
① 代碼包大小:編譯后代碼更少
② 性能:沒有生命周期,不需要實例化,性能更好
249
React 組件如何防止無效渲染?
什么時候會渲染?
① state 發生變化
② props 發生變化
阻止無效渲染的方式:
① shouleComponentUpdate
② 使用 useMemo, useCallback 反之
③ 使用生產版本的 React,開發版本有時候會渲染兩次。
250
React 性能如何分析?
① 直接肉眼觀察某個組件是否閃爍,如果閃爍,說明重復渲染。
② 代碼中 log,看是否重復 log
③ 使用最新的 React DevTool 中的 Profiler 進行定量分析,可以查看每個組件渲染時間的火焰圖。
251
服務端渲染的過程?為什么前端還需要再渲染一次?
怎么做的
核心 api 是 renderToString
① 啟動一個 node 服務 ② 把 react 根組件用 reanderToString 渲染成字符串返回給前端 ③ 前端再渲染一次:恢復生命周期、給組件綁定事件以響應用戶操作
好處是什么
① SEO 收錄更好
② 減少白屏
③ 支持更多后端代碼模板的支持
252
TS 里面的抽象類,抽象類能有抽象屬性嗎?
抽象類
使用abstract關鍵字定義抽象類和抽象方法
抽象類不允許被實例化
抽象類中的抽象方法必須被實現
抽象類中可以有抽象屬性,如下面的寫法,是沒有報錯的
253
type 和 interface 的區別?
相同點
① 都可以描述一個屬性或函數
② 都允許拓展:interface 使用 extends, type 使用 &
不同點
① type 可以聲明基本類型、聯合類型、元祖類型,interface 不行。
基本類型: string
聯合類型:TypeA | TypeB
元祖類型:具體定位到每個位置的類型:[TypeA, TypeB]
② type 可以通過 typeof 獲取到實例的類型
③ interface 聲明能夠直接合并,同時寫多個同名的 interface
④ interface 可以被實現,type 不行
https://www.jianshu.com/p/8dff10ce3912
254
Taro 的架構
https://mp.weixin.qq.com/s?__biz=MzU3NDkzMTI3MA==&mid=2247483770&idx=1&sn=ba2cdea5256e1c4e7bb513aa4c837834
① 分為兩部分:編譯時 和 運行時
編譯時主要是將 Taro 代碼通過 Babel[11] 轉換成 小程序的代碼,如:JS、WXML、WXSS、JSON
運行時:生命周期、事件、data 等部分的處理和對接
② 編譯時具體的過程:使用 babel-parser[12] 將 Taro 代碼解析成抽象語法樹,然后通過 babel-types[13] 對抽象語法樹進行一系列修改、轉換操作,最后再通過 babel-generate[14] 生成對應的目標代碼。
③ 運行時:編譯后的代碼中,React 的核心 render 方法 沒有了。同時代碼里增加了 BaseComponent 和 createComponent ,它們是 Taro 運行時的核心。Taro 當前架構只是在開發時遵循了 React 的語法,在代碼編譯之后實際運行時,和 React 并沒有關系。
④ 總結:
整個 Taro 當前架構的特點是:
重編譯時,輕運行時:這從兩邊代碼行數的對比就可見一斑。
編譯后代碼與 React 無關:Taro 只是在開發時遵循了 React 的語法。
直接使用 Babel 進行編譯:這也導致當前 Taro 在工程化和插件方面的羸弱。
其他的 mpvue 架構的特點:
半編譯時,半運行時
WXML 模板通過編譯生成
將 Vue 運行在小程序上,實現 Vue@2.4.1 絕大部分特性
基于 wevpack
255
性能優化、audits、LightHouse、刑恩性能測試工具
性能測試工具
以前叫 audits, 現在叫 LightHouse.
有以下幾個方面:
① Performance性能
First Contentful Paint(FCP):第一次有內容繪制。
Time to Interactive (TTI):可交互時間
Speed Index (SI):頁面內容填充速度。 how quickly the contents of a page are visibly populated.
Total Blocking Time (TBT): 總阻塞時間
Largest Contentful Paint (LCP): 大內容繪制
Cumulative Layout Shift (CLS): 衡量可視窗口內元素的移動
給出建議:移除無用代碼、DNS 預解析、壓縮代碼、
② Accessibility 可訪問性
對比度
代碼可讀性
③ Best Practiveces 最佳實踐
HTTPS
跨域安全
JS 安全
④ SEO 檢查
各種標簽是否語義化等
⑤ PWA
速度是否夠快
256
CDN 原理
https://zhuanlan.zhihu.com/p/147571853?from_voters_page=true
簡要來說:
① 本地 DNS 解析,通過 CNAME 轉到 CDN 專用的 DNS 服務器
② DNS 服務器返回全局負載均衡的服務器 IP
③ 請求全局負載均衡 IP,返回局部負載均衡 IP
④ 請求局部負載均衡 IP,返回緩存服務器 IP
⑤ 請求緩存服務器 IP
具體來說:
資源上傳cdn之后,當用戶訪問cdn的資源地址之后會經歷下面的步驟:
首先經過本地的dns解析,請求cname指向的那臺cdn專用的dns服務器。
dns服務器返回全局負載均衡的服務器ip給用戶
用戶請求全局負載均衡服務器,服務器根據ip返回所在區域的負載均衡服務器ip給用戶
用戶請求區域負載均衡服務器,負載均衡服務器根據用戶ip選擇距離近的,并且存在用戶所需內容的,負載比較合適的一臺緩存服務器ip給用戶。當沒有對應內容的時候,會去上一級緩存服務器去找,直到找到資源所在的源站服務器,并且緩存在緩存服務器中。用戶下一次在請求該資源,就可以就近拿緩存了。
257
前端工程化
四化:模塊化、組件化、規范化、自動化
① 模塊化:將一個大文件拆分成相互依賴的小文件,再進行統一的拼裝和加載。只有這樣,才有多人協作的可能。
-
JS 模塊化:CommonJS --> AMD --> CMD,語言層面上使用 ES6,
-
用Webpack+Babel將所有模塊打包成一個文件同步加載,也可以打成多個chunk異步加載;
-
用SystemJS+Babel主要是分模塊異步加載;
-
用瀏覽器的
② 組件化:模塊化只是在文件層面上,對代碼或資源的拆分;而組件化是在設計層面上,對UI(用戶界面)的拆分。
③ 規范化:目錄結構的制定、編碼規范、前后端接口規范、文檔規范、組件管理、Git分支管理、Commit描述規范、定期CodeReview、視覺圖標規范
④ 自動化:前端工程化的很多臟活累活都應該交給自動化工具來完成。自動化構建、自動化部署、自動化測試。
258
在海量字符串中統計處出現頻率最高的單詞,有什么思路
1.使用newFixedThreadPool構建大小為5的線程池。讓線程分別讀取不同的文件。
2.使用ConcurrentHashMap對象hashmap作為共享變量,用于存放每個單詞出現的頻率。
3.采用最小堆在hashmap中找到頻率最高的100個數據單詞,并打印。
259
前端的發展路線
https://segmentfault.com/a/1190000020281750
260
webpack怎么做PWA
offline-plugin: https://segmentfault.com/a/1190000010669126
https://segmentfault.com/a/1190000011072073
261
webpack里面的拆包
https://segmentfault.com/a/1190000007649417
① JS 拆分:requre.ensure() 按需拆分
② CSS 拆分:使用 CSS MODULE 加載 CSS, 使用STYLE LOADER 將 CSS 插入到 STYLE 標簽中,然后使用 extract-text-webpack-plugin 拆分 CSS 為單個文件。
③ 第三方庫拆分:CommonsChunkPlugin
262
React 如何復用邏輯?
https://blog.csdn.net/neoveee/article/details/87619175
① 高階組件:參數為一個組件,返回一個新的組件。
② HOOKS:狀態邏輯本身就是獨立于組件的,可以實現邏輯復用。
263
高并發場景下前端的優化方案
① 減少請求
② 負載均衡
③ 高并發請求分時發送
④ 主動過濾部分的用戶的請求
⑤ 業務邏輯上只允許請求一次
264
socket.io是用了什么協議
① 支持多種協議,為了在每一種瀏覽器上支持實時通訊,Socket.IO 在運行中選擇最佳的傳輸方式,而不影響API。② 支持的方式為:WebSocket, Adobe Flash Socket, AJAX long polling, AJAX multipart streaming, Forever Iframe, JSONP Polling。
265
307 狀態碼
① http 307 Temporary Redirect 是臨時重定向
② http 307和302的區別在于:307要求客戶端不改變原先的請求方法,對在Location頭部中規定的URI進行訪問。對于302,很多客戶端的實現是,直接使用GET方式訪問重定向地址。
266
未來學習規劃
① 深入學習 node, 用 node 做幾個小項目
② 深入前端工程化
③ debugger 方面的知識也要學習,還是很有用的。
267
做項目的目的
① 滿足興趣
② 迎合需求
③ 傭金:外包、廣告平臺、商業變現
268
服務器最大tcp連接數
① 四元組 {原IP,原端口,目的IP,目的端口}。只有前兩個可變。由客戶端的ip+port來決定連接數的,對于ipv4地址2^32 ,port是2^16 ,所以理論的連接數最多是2^48
② 實際情況中這個和設備的內存,一條tcp連接占用的內存有關
③ 65535并不是單機服務器處理的連接數上限。單機情況下,可以通過設置虛擬ip來突破單機65535這個上限。
④ 實際上不經過配置的話,端口數最多只能到 28232,這是由于 linux 源碼里面限制的,設置了 sysctl_local_port_range,差值就是這個數。可以通過 sysctl 設置。https://blog.csdn.net/zhuizhuziwo/article/details/6926904
269
io設計模式 同步異步io poll/epoll io
IO 設計模式
① 阻塞IO:讀寫數據過程中會發生阻塞現象
② 非阻塞IO:發起 read,得到結果,結果為 error 就再次 read。結果不是 error 就返回。
③ 多路復用IO:一個線程不斷輪詢多個 io 的狀態
④ 信號驅動IO:發起 io,注冊函數,可以返回,內核準備好后,發送信號給用戶進程,然后用戶進程開始讀寫。
⑤ 異步 IO: 發起 io,直接返回,內核拷貝好數據后,通知用戶進程。
前 4 個都是同步 IO,最后一個是異步 IO.
異步 I/O 與信號驅動 I/O 的區別
異步 I/O 的信號是數據拷貝完成后通知應用進程 I/O 完成,而信號驅動 I/O 的信號是通知應用進程可以開始數據拷貝 I/O。
select/poll/epoll io
① select: 將文件描述符收集過來,交給內核,讓內核去判斷那個有數據。當里面任何一個或者多個有數據的時候,內核會返回,并且有數據的那個文件描述符fd會被標記置位。返回之后,遍歷集合,判斷那個fd有數據了,然后讀取數據并處理。
② poll: poll傳入一個 pollfd 結構體,也是阻塞的。當有數據時,會置位revents字段,后續讀取數據時,會重新置為0。可以重用。
struct pollfd{ int fd; // 文件描述符 short events; // 事件類型 讀 POLLIN、 寫 POLLOUT、讀和寫 short revents; // 默認值為0,當有數據時,該參數會被置位。 }
③ epoll: 有兩個重要函數 epoll_ctl 和 epoll_wait,首先創建一個 eventpoll對象,開辟內存。epoll_wait 中,傳入 eventpoll對象的id,進行監聽。eopll_wait也是處于阻塞狀態。返回一個 int類型, 0 表示沒有就緒,大于0表示有幾個就緒,-1表示異常。epoll_wait,傳入超時時間為0,就是非阻塞的,需要每次調用去檢查就緒的socket信息。event_poll 對象存放的socket集合,采用紅黑樹結構,因為經常的增刪查,時間復雜度 O(Log(n))
270
偏函數有哪些應用,說一下怎么實現
python 里面的函數:https://www.runoob.com/w3cnote/python-partial.html
就是函數生成函數,傳遞一些參數,作為函數的默認參數,返回已經具有默認參數的一個函數。
js 里面實現,指的就是柯里化,curry。
本質上是函數式編程 + 閉包,返回一個函數。
https://www.cnblogs.com/bonelee/p/6102535.html
271
用過echarts和d3,他們的原理
① echarts:canvas 或者 svg。https://echarts.apache.org/zh/tutorial.html#%E4%BD%BF%E7%94%A8%20Canvas%20%E6%88%96%E8%80%85%20SVG%20%E6%B8%B2%E6%9F%93
② d3:力引導算法:https://blog.csdn.net/wry2008wry/article/details/80812562
272
canvas和svg區別
① SVG 是多個節點,canvas 是單個節點。
② SVG 是矢量圖,不依賴分辨率。canvas 是位圖,依賴分辨率。
③ SVG 不適合游戲,canvas 適合游戲,因為前者過度使用了 DOM.
273
node 進程通信、多進程復用
專門的dataBus進程、Pandora.js對象、主子進程通信、借助Redis
Node.js 進程通信
Node進程間通信有4種方式:
通過stdin/stdout傳遞json:最直接的方式,適用于能夠拿到“子”進程handle的場景,適用于關聯進程之間通信,無法跨機器
Node原生IPC支持:最native(地道?)的方式,比上一種“正規”一些,具有同樣的局限性
通過sockets:最通用的方式,有良好的跨環境能力,但存在網絡的性能損耗
借助message queue:最強大的方式,既然要通信,場景還復雜,不妨擴展出一層消息中間件,漂亮地解決各種通信問題
https://www.cnblogs.com/rubyxie/articles/8949417.html
274
Node直出的優缺點?服務器渲染的優缺點?
優點:
① 前端耗時少,占用資源少
② 有利于 SEO
③ 后端靜態文件緩存,減少查詢數據庫的時間。
缺點:
① 不利于前后端分離
② 占用服務器資源
275
瀏覽器發起請求的方法?XHR、fetch的區別
方法
① img 標簽、new Image()
② 表單提交
③ websocket
④ AJAX: XHR, fetch
區別
https://www.cnblogs.com/mengff/p/12836039.html
① fetch是有兼容問題的:IE系列是完全不支持的,主流瀏覽器的早起版本也不支持,所以如果在項目中使用需要做兼容方案處理。
② fetch 不管請求處理成功還是失敗,都會觸發promise的resolve狀態回掉。fetch只有當網絡故障導致請求發送失敗或者跨域的時候才會觸發reject的邏輯。我們可以通過response 對象的ok是否是true來判斷是否是真正的成功。
③ fetch配置請求是否攜帶cookie和接受服務端寫入cookie是通過設置credentials
276
實現一個可以設置超時時間的fetch
使用setTimeout和Promise.reject實現的超時控制不能阻止請求過程繼續在后臺運行,造成了流量的浪費
Promise.race, setTimeout 配合使用。
https://www.cnblogs.com/yfrs/p/fetch.html
277
React中key的作用,具體的運作方式
每個key 對應一個組件,相同的key react認為是同一個組件,這樣后續相同的key對應組件都不會被創建
https://www.cnblogs.com/nanianqiming/p/11361364.html
278
雙向綁定的缺點
① 內存上:會涉及到引用計數的回收問題
② 體驗上:無法跟蹤局部狀態的變化,潛在的行為會導致 debug 難度的增加。
279
怎么設計一個餅圖
① CSS:https://www.cnblogs.com/liangjing-yy/p/9008998.html
② CANVAS: arc 繪制
③ SVG:https://blog.csdn.net/melovemingming/article/details/83057358
280
redis和MySQL區別
① 類型:MySQL 是關系型數據庫,redis 是非關系型數據庫。
② 存儲:MySQL 持久化在硬盤上,redis 做緩存。
③ 速度:MySQL 速度慢,redis 速度快。
④ 使用:MySQL 支持 SQL 語言,redis 是鍵值對。
281
Angular / React 的區別
① 編寫方式:angular 是 JS + HTML 模板,react 是純 jsx
② 類型:angular 是一個 MVC 框架,react 是 js 庫
③ 數據綁定:angular 是雙向數據綁定,react 是單向數據流。
④ 依賴:angular 自動管理依賴項,react 用其他工具管理。
⑤ 指令:augular 中有豐富的指令,react 中沒有指令。
⑥ DOM 操作:angular 直接操作真實 dom,react 是虛擬 dom。
282
分片上傳的實現
借助js的Blob對象FormData對象可以實現大文件分片上傳的功能
https://www.cnblogs.com/sghy/p/9143955.html
283
React的特性
① 虛擬 DOM 速度快
② 跨瀏覽器兼容
③ 組件化開發
④ 單向數據流
⑤ 純 JS 語法
284
React render setState
render 原理:
https://www.jianshu.com/p/cf4c044e4edd
① ReactDOM.render 將組件轉換成真實的 DOM 元素
② 轉變為調用 React.createElement(App)
③ createElement 將傳入的參數組裝 props,返回 ReactElement
④ ReactElement 返回最終創建的react對象
⑤ 通過 legacyRenderSubtreeIntoContainer 獲取 root,然后通過 createContainer 創建一個 fiber tree
⑥ 調用root.render(children, callback)方法把生成的fiber tree轉換成真實dom
setState 的原理
① setState在react生命周期和合成事件會批量覆蓋執行
② setstate在原生事件,setTimeout,setInterval,promise等異步操作中,state會同步更新
③ setState批量更新的過程:
在react生命周期和合成事件執行前后都有相應的鉤子,分別是pre鉤子和post鉤子,pre鉤子會調用batchedUpdate方法將isBatchingUpdates變量置為true,開啟批量更新,而post鉤子會將isBatchingUpdates置為false
https://www.jianshu.com/p/89a04c132270
285
Ant Design 設計理念,優缺點
概述
Ant Design 介于Material Design 和 Bootstrap之間:給出框架的同時,也給出了設計規范。
設計理念
Ant Design 介于Material Design 和 Bootstrap之間:給出框架的同時,也給出了設計規范。 與眾不同的是,Ant Design 不但追求『用戶』的使用體驗,還追求『設計者』和『開發者』的使用體驗,踐行『以人為本』的設計理念。微小,確定,幸福『不同』不一定『更好』,但是『更好』一定『不同』。不斷追求細節上的『更好』,使得我們的組件和同類產品都不一樣,自然而然的更好。
優點
① 明確了”后臺框架“的說法
② 給出框架的同時,也給出了設計規范
缺點
① 框架和設計不能分離,限制了靈活性。
286
localStorage沖突解決
為每一個 localStorage 的 key 使用唯一的前綴區分。
287
servlet生命周期
https://www.runoob.com/servlet/servlet-life-cycle.html
Servlet 通過調用 init () 方法進行初始化。
Servlet 調用 service() 方法來處理客戶端的請求。
Servlet 通過調用 destroy() 方法終止(結束)。
最后,Servlet 是由 JVM 的垃圾回收器進行垃圾回收的。
288
性能優化的量化評價
① 工具:Lighthouse
② 標準:
FP: 首次繪制
FCP: 首次有內容繪制
FMP: 首次有意義繪制
TTI: 可交互時間
289
FP, FCP, FMP, TTI
https://github.com/LuckyWinty/fe-weekly-questions/issues/56
https://juejin.im/post/6844904029936418824
FP
含義
FP(全稱“First Paint”,翻譯為“首次繪制”) 是時間線上的第一個“時間點”,它代表瀏覽器第一次向屏幕傳輸像素的時間,也就是頁面在屏幕上首次發生視覺變化的時間。
注意:FP不包含默認背景繪制,但包含非默認的背景繪制。
統計邏輯
通過performance.getEntriesByType('paint’),取第一個 paint 的時間
FCP
含義
FCP(全稱“First Contentful Paint”,翻譯為“首次內容繪制”),顧名思義,它代表瀏覽器第一次向屏幕繪制 “內容”。
注意:只有首次繪制文本、圖片(包含背景圖)、非白色的canvas或SVG時才被算作FCP。
統計邏輯
通過performance.getEntriesByType('paint’),取第二個pain的時間,或者通過Mutation Observer觀察到首次節點變動的時間
注意
FP與FCP這兩個指標之間的主要區別是:FP是當瀏覽器開始繪制內容到屏幕上的時候,只要在視覺上開始發生變化,無論是什么內容觸發的視覺變化,在這一刻,這個時間點,叫做FP。
相比之下,FCP指的是瀏覽器首次繪制來自DOM的內容。例如:文本,圖片,SVG,canvas元素等,這個時間點叫FCP。
FP和FCP可能是相同的時間,也可能是先FP后FCP。
FMP
含義
FirstMeaningfulPaint是頁面主要內容出現在屏幕上的時間, 這將是用戶感知加載體驗的主要指標。目前尚無標準化的定義, 因為很難以通用的方式去確定各種類型頁面的關鍵內容。實踐中,可以將頁面評分最高的可見內容出現在屏幕上的時間作為FirstMeaningfulPaint。
統計邏輯
Mutation Observer將會觀察頁面加載的前30S內頁面節點的變化, 將新增/移除的節點加入/移除Intersection Observer, 這樣可以得到頁面元素的可見時間點及元素與可視區域的交叉信息。
根據元素的類型進行權重取值, 然后取元素與可視區域的交叉區域面積、可見度、 權重值之間的乘積為元素評分。
根據上面得到的信息, 以時間點為X軸, 該時間點可見元素的評分總和為Y軸, 取最高點對應的最小時間為頁面主要內容出現在屏幕上的時間。
取Mutation Observer 與 Intersection Observer的瀏覽器兼容性交集, 則此估算方法支持Chrome 51以上版本、Firefox 55以上版本及Edge 15以上版本。
注意
目前沒有統一邏輯,阿里有個標準為最高可見增量元素,采用深度優先遍歷方法,詳細可見:https://zhuanlan.zhihu.com/p/44933789
290
prerender預渲染是什么原理呀
① prerender.io:使用 PhantomJS 無頭瀏覽器。
② prerender-spa-plugin,使用 Chrome 的無頭瀏覽器,具體是使用了 Puppeteer 無頭操作庫。
291
Vue如何解析template模板,diff算法兩者的不同是什么
React diff 和 Vue diff 的區別
https://segmentfault.com/a/1190000015432258
Vue如何解析template模板
① 模板編譯成 AST 語法樹
② 語法樹轉換成 render 函數
③ render 函數返回一個 VNode 虛擬節點
diff 算法兩者的不同:
① 判斷節點類型:元素類型相同,className 不同,Vue 判斷為不同元素刪除重建,React 判斷為相同元素,只是修改屬性。
② 列表對比:Vue 是兩端到中間,React 是從左到右。Vue 更加高效。
292
前端的動畫種類
六種:
javascript直接實現;
SVG(可伸縮矢量圖形);
CSS3 transition;
CSS3 animation;
Canvas動畫;
requestAnimationFrame;
https://www.cnblogs.com/zhaowy/p/8817944.html
293
Dart 語言
Dart 面試知識點:
http://www.cainiaoxueyuan.com/xcx/12417.html
Dart 教程:
https://www.dartcn.com/guides/language/language-tour
294
prerender-spa-plugin插件你用過?具體說一說吧
使用 Chrome 的無頭瀏覽器,具體是使用了 Puppeteer 無頭操作庫。
https://segmentfault.com/a/1190000018182165
295
從項目流程上說性能優化
① 設計優化:版本迭代、風格追隨前沿
② 編碼優化:代碼規范、自動生成文檔、接口自動化測試
③ 打包部署優化:自動打包 shell 腳本、自動部署 shell 腳本、webpack 優化措施
④ 上線體驗優化:Lighthouse 性能檢測、用戶行為埋點統計
296
use strict 嚴格模式
① 嚴格模式是在 ES5 中新增的字面量,表示代碼在嚴格模式下運行。
② 嚴格模式的限制:不允許使用未聲明的變量。
③ 嚴格模式的好處:消除不安全代碼、提高編譯器效率、為未來新版本的 JS 做好鋪墊。
297
長列表解決方案
① 滾動分頁加載。
② 在 requestAnimationFrame 回調中使用 createDocumentFragment 減少重排。
③ 滑動窗口做的虛擬滾動、無限滾動:Interp Observer + padding
利用 Interp Observer 來監測相關元素的滾動位置,異步監聽,盡可能得減少 DOM 操作,觸發回調,然后去獲取新的數據來更新頁面元素,并且用調整容器 padding 來替代了本該越來越多的 DOM 元素,最終實現列表滾動、無限下拉。
298
proxy和defineProperty區別
① 2.0 通過 Object.defineProperty 數據劫持實現,弊端是需要克隆一份對象,需要給每一個屬性都設置監聽
② 3.0 通過 ES6 的 Proxy 委托代理實現,不需要克隆,而且只需要對整個對象進行代理。
299
從原理上談ajax
核心是 XMLHttpRequest
① 瀏覽器發起 xhr 請求
② 瀏覽器去做其他事情
③ xhr 請求數據
④ 服務器給 xhr 返回數據
⑤ xhr 通知瀏覽器數據回來了
⑥ 瀏覽器渲染 xhr 的數據
300
Iterator的語法,它的作用是什么
ES6 中:
var arr = [‘a’, ‘b’, ‘c’, ‘d’, ‘e’];
var eArr = arrSymbol.iterator;
console.log(eArr.next().value); // a
console.log(eArr.next().value); // b
console.log(eArr.next().value); // c
console.log(eArr.next().value); // d
console.log(eArr.next().value); // e
迭代一個對象
作用:
301
Generator函數有哪些接口?Generator函數是異步的,Generator 跟 Promise有什么區別?
接口
① 新版:
next(): 返回 yield 生成的值
return():返回給定的值并結束生成器
throw(): 拋出一個錯誤
② 舊版:
next(): 新版的 next()
close(): 新版的 return
send(): 將值發送給生成器,用 yield 返回,對應于新版的 next(x)
throw(): 拋出錯誤,新版的 throw()
Generator 與 Promise 的區別
① 錯誤處理:Generator 可以 try/catch, Promise 只能 .catch(),如果不設置回調函數,Promise 錯誤無法反應到外部。
② 語法上:Generator 前面有一個 *,Promise 沒有
③ 邏輯上:Generator 是同步代碼異步化,更加靈活地控制代碼的行為,Promise 則是專門為異步設計的,解決異步回調地獄。
302
babel-loader離開webpack能單獨使用嗎
可以,比方說直接執行:
babel --plugins transform-react-jsx-source script.js
這是 babel 文檔上說的,可以直接 via CLI:
https://babeljs.io/docs/en/babel-plugin-transform-react-jsx-source/
303
electron 底層的通信機制
主線程到渲染線程:BrowerWindow.webContents.send()發送消息。
渲染線程到主線程:,借助ipcRender和ipcMain發送/接收消息。
304
fetch和axios的區別
axios 的特點
① 底層是 XHR, 支持 Promise
② 支持防止 CSRF, 提供并發接口
③ 支持請求和相應的攔截、轉換與取消
fetch 的缺點
① 報錯:只對網絡請求報錯,400、500都是成功
② cookie:默認不會攜帶 cookie,需要配置 credentials: ‘include’
③ 不支持取消,不支持超時控制。
④ 沒有辦法檢測請求的進度,而 XHR 可以。
305
前端的新技術關注過嗎?(Serverless、WebAssembly、GraphQL)
① Serverless:無服務器架構、云開發,讓全棧工程師真的能變成全棧工程師,而不是”全干工程師“,將底層環境、容器、網絡配置工作交給更加專業的人來做,開發者只需要聚焦于開發即可。
② WebAssembly:WebAssembly 是一種可以使用非 JavaScript 編程語言編寫代碼并且能在瀏覽器上運行的技術方案。文件更小、不需要解析成 AST、不需要重新優化、手動垃圾回收。
③ GraphQL:是一個用于 API 的查詢語言,最大的優點是前端對數據可控,想要什么數據就發送什么請求。
306
Object.defineProperty和vue3.0的proxy的區別,雙向數據綁定的區別
① 2.0 通過 Object.defineProperty 數據劫持實現,弊端是需要克隆一份對象,需要給每一個屬性都設置監聽
② 3.0 通過 ES6 的 Proxy 委托代理實現,不需要克隆,而且只需要對整個對象進行代理。
總結
以上是生活随笔為你收集整理的前端面经 300条,背完这些就够了!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 企业中Linux下软件的管理(yum仓库
- 下一篇: HTML 使用table标签制作个人简历