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
者: Lefex 素燕
轉發鏈接:https://mp.weixin.qq.com/s/0klnoP6M90uU1g2g433swQ
源|https://segmentfault.com/a/1190000015288700
本篇文章整理總結了一些前端面試題,涵蓋面很廣,并且面的都是知名大廠,所以這些題還是很有代表性的,都掌握以后一面基礎面應該沒什么問題,二面也能應付大半,奉上:
1. 萬能居中
1.margin: 0 auto;水平
2.text-align: center;水平
3.行高,垂直
4.表格,center,middle;水平垂直
5.display:table-cell;模擬表格,all
6.絕對定位,50%減自身寬高
7.絕對定位,上下左右全0,margin:auto
8.絕對定位加相對定位。不需要知道寬高
9.IE6,IE7:給父元素設一個font-size:高度/1.14,vertical-align:middle
2. BFC優化
塊格式化上下文, 特性:
3. 和模型哪兩種模式?什么區別?如何設置
4. 常用清除浮動的方法,如不清除浮動會怎樣?
當父元素不給高度的時候,內部元素不浮動時會撐開, 而浮動的時候,父元素變成一條線, 造成塌陷.
5. 柵格化的原理
比如antd的row和col, 將一行等分為24份, col是幾就占幾份, 底層按百分比實現; 結合媒體查詢, 可以實現響應式
6. 純css實現三角形
// 通過設置border
.box
{
width:0px;
height:0px;
border-top:50px solid rgba(0,0,0,0);
border-right:50px solid rgba(0,0,0,0);
border-bottom:50px solid green;
border-left:50px solid rgba(0,0,0,0);
}
7. 高度不定,寬100%,內一p高不確定,如何實現垂直居中?
8. 至少兩種方式實現自適應搜索
9. 設置一段文字的大小為6px
10. css菊花圖
四個小圓點一直旋轉
// 父標簽
animation: antRotate 1.2s infinite linear;
// 子標簽
animation: antSpin 1s infinite linear;
@keyframe antSpin {
to {
opacity: 1
}
}
@keyframe antRotate {
to {
transform: rotate(405)
}
}
// animation-delay: 逐個延遲0.4s
11. 關于em
<p style="font-size: 20px">
123
<p style="font-size: 2em;width: 2em">456</p>
</p>
// 此時子元素的font-size為40px, 寬度為80px(還要乘以子元素font-size的系數)
12. 關于vh, vw
vw:viewpoint width,視窗寬度,1vw等于視窗寬度的1%。
vh:viewpoint height,視窗高度,1vh等于視窗高度的1%。
vmin:vw和vh中較小的那個。
vmax:vw和vh中較大的那個。
13. Flex布局
14. overflow原理
15. 實現自適應的正方形:
16. 標準模式和怪異模式
17. CSS3實現環形進度條
兩個對半矩形遮罩, 使用rotate以及overflow: hidden進行旋轉
18. css優先級
選擇器的特殊性值表述為4個部分,用0,0,0,0表示。
1. ES5和ES6繼承方式區別
2. Generator了解
ES6 提供的一種異步編程解決方案, Generator 函數是一個狀態機,封裝了多個內部狀態。
// 通過設置border.box { width:0px; height:0px; border-top:50px solid rgba(0,0,0,0); border-right:50px solid rgba(0,0,0,0); border-bottom:50px solid green; border-left:50px solid rgba(0,0,0,0); }
調用后返回指向內部狀態的指針, 調用next()才會移向下一個狀態, 參數:
hw.next()
// { value: 'hello', done: false }
hw.next()
// { value: 'world', done: false }
hw.next()
// { value: 'ending', done: true }
hw.next()
// { value: undefined, done: true }
3. 手寫Promise實現
var myPromise=new Promise((resolve, reject)=> {
// 需要執行的代碼
...
if (/* 異步執行成功 */) {
resolve(value)
} else if (/* 異步執行失敗 */) {
reject(error)
}
})
myPromise.then((value)=> {
// 成功后調用, 使用value值
}, (error)=> {
// 失敗后調用, 獲取錯誤信息error
})
4. Promise優缺點
function promise () {
this.msg='' // 存放value和error
this.status='pending'
var that=this
var process=arguments[0]
process (function () {
that.status='fulfilled'
that.msg=arguments[0]
}, function () {
that.status='rejected'
that.msg=arguments[0]
})
return this
}
promise.prototype.then=function () {
if (this.status==='fulfilled') {
arguments[0](this.msg)
} else if (this.status==='rejected' && arguments[1]) {
arguments[1](this.msg)
}
}
5. 觀察者模式
又稱發布-訂閱模式, 舉例子說明.
實現: 發布者管理訂閱者隊列, 并有新消息推送功能. 訂閱者僅關注更新就行
6. 手寫實現bind
Function.prototype.bind=function () {
// 保存原函數
var self=this
// 取出第一個參數作為上下文, 相當于[].shift.call(arguments)
var context=Array.prototype.shift.call(arguments)
// 取剩余的參數作為arg; 因為arguments是偽數組, 所以要轉化為數組才能使用數組方法
var arg=Array.prototype.slice.call(arguments)
// 返回一個新函數
return function () {
// 綁定上下文并傳參
self.apply(context, Array.prototype.concat.call(arg, Array.prototype.slice.call(arguments)))
}
}
7. 手寫實現4種繼承
<p style="font-size: 20px"> 123 <p style="font-size: 2em;width: 2em">456</p> </p>// 此時子元素的font-size為40px, 寬度為80px(還要乘以子元素font-size的系數)
8. css菊花圖
四個小圓點一直旋轉
// 父標簽
animation: antRotate 1.2s infinite linear;
// 子標簽
animation: antSpin 1s infinite linear;
@keyframe antSpin {
to {
opacity: 1
}
}
@keyframe antRotate {
to {
transform: rotate(405)
}
}
// animation-delay: 逐個延遲0.4s
9. http狀態碼
10. Object.create實現(原型式繼承,特點:實例的proto指向構造函數本身)
11. async和await:
12. 算法和數據結構:
13. 封裝JSONP
function jsonp ({url, param, callback}) {
return new Promise((resolve, reject)=> {
var script=document.createElement('script')
window.callback=function (data) {
resolve(data)
document.body.removeChild('script')
}
var param={...param, callback}
var arr=[]
for (let key in param) {
arr.push(`${key}=${param[key]}`)
}
script.src=`${url}?${arr.join('&')}`
document.body.appendChild(script)
})
}
14. 手動實現map(forEach以及filter也類似)
// for循環實現
Array.prototype.myMap=function () {
var arr=this
var [fn, thisValue]=Array.prototype.slice.call(arguments)
var result=[]
for (var i=0; i < arr.length; i++) {
result.push(fn.call(thisValue, arr[i], i, arr))
}
return result
}
var arr0=[1, 2, 3]
console.log(arr0.myMap(v=> v + 1))
// forEach實現(reduce類似)
Array.prototype.myMap=function (fn, thisValue) {
var result=[]
this.forEach((v, i, arr)=> {
result.push(fn.call(thisValue, v, i, arr))
})
return result
}
var arr0=[1, 2, 3]
console.log(arr0.myMap(v=> v + 1))
15. js實現checkbox全選以及反選
<body>
<button id="other">反選</button>
<input type="checkbox" id="all" />全選
<input type="checkbox" class="check" />1
<input type="checkbox" class="check" />2
<input type="checkbox" class="check" />3
<script>
var checkbox=document.getElementsByClassName('check')
var checkAll=document.getElementById('all')
var checkOther=document.getElementById('other')
checkAll.onclick=function() {
var flag=true
for (var i=0; i < checkbox.length; i++) {
if (!checkbox[i].checked) flag=false
}
if (flag) {
for (var i=0; i < checkbox.length; i++) {
checkbox[i].checked=false
}
} else {
for (var i=0; i < checkbox.length; i++) {
checkbox[i].checked=true
}
}
}
checkOther.onclick=function() {
for (var i=0; i < checkbox.length; i++) {
checkbox[i].checked=!checkbox[i].checked
}
}
</script>
</body>
16. 對原型鏈的理解?prototype上都有哪些屬性
17. 為什么使用繼承
通常在一般的項目里不需要,因為應用簡單,但你要用純js做一些復雜的工具或框架系統就要用到了,比如webgis、或者js框架如jquery、ext什么的,不然一個幾千行代碼的框架不用繼承得寫幾萬行,甚至還無法維護。
18. setTimeout時間延遲為何不準
單線程, 先執行同步主線程, 再執行異步任務隊列
19. 事件循環述,宏任務和微任務有什么區別?
20. let const var作用域
塊級作用域, 暫時性死區
21. 節流和防抖
// 函數節流 滾動條滾動
var canRun=true;
document.getElementById("throttle").onscroll=function(){
if(!canRun){
// 判斷是否已空閑,如果在執行中,則直接return
return;
}
canRun=false;
setTimeout(function(){
console.log("函數節流");
canRun=true;
}, 300);
};
// 函數防抖
var timer=false;
document.getElementById("debounce").onscroll=function(){
clearTimeout(timer); // 清除未執行的代碼,重置回初始化狀態
timer=setTimeout(function(){
console.log("函數防抖");
}, 300);
};
22. 實現一個sleep函數
// 這種實現方式是利用一個偽死循環阻塞主線程。因為JS是單線程的。所以通過這種方式可以實現真正意義上的sleep()。
function sleep(delay) {
var start=(new Date()).getTime();
while ((new Date()).getTime() - start < delay) {
continue;
}
}
function test() {
console.log('111');
sleep(2000);
console.log('222');
}
test()
23. 閉包
24. Immutable.js
Facebook出品, 倡導數據的不可變性, 用的最多就是List和Map.
25. js實現instanceof
// 檢測l的原型鏈(__proto__)上是否有r.prototype,若有返回true,否則false
function myInstanceof (l, r) {
var R=r.prototype
while (l.__proto__) {
if (l.__proto__===R) return true
}
return false
}
27. ES6的模塊引入和CommonJs區別
28. 嚴格模式
// 嚴格模式下, 隱式綁定丟失后this不會指向window, 而是指向undefined
'use strict'
var a=2
var obj={
a: 1,
b: function() {
// console.log(this.a)
console.log(this)
}
}
var c=obj.b
c() // undefined
29. fetch, axios區別
30. typescript缺點
31. 構造函數實現原理
// 模擬構造函數實現
var Book=function(name) {
this.name=name;
};
//正常用法
var java=new Book(‘Master Java’);
//使用代碼模擬,在非IE瀏覽器中測試,IE瀏覽器不支持
var python={};
python.__proto__=Book.prototype;
Book.call(python, 'Master Python');
32. for in 和 for of區別
33. JS實現并發控制:
使用消息隊列以及setInterval或promise進行入隊和出隊
34. ajax和axios、fetch的區別
35. promise.finally實現
Promise.prototype.finally=function (callback) {
let P=this.constructor;
return this.then(
value=> P.resolve(callback()).then(()=> value),
reason=> P.resolve(callback()).then(()=> { throw reason })
);
};
1. reflow(回流)和repaint(重繪)優化
2.一個頁面從輸入 URL 到頁面加載顯示完成,這個過程中都發生了什么?
3.localStorage 與 sessionStorage 與cookie的區別總結
4.瀏覽器如何阻止事件傳播,阻止默認行為
5.虛擬DOM方案相對原生DOM操作有什么優點,實現上是什么原理?
虛擬DOM可提升性能, 無須整體重新渲染, 而是局部刷新.
JS對象, diff算法
6.瀏覽器事件機制中事件觸發三個階段
7.什么是跨域?為什么瀏覽器要使用同源策略?你有幾種方式可以解決跨域問題?了解預檢請求嗎?
8.了解瀏覽器緩存機制嗎?
9.為什么操作 DOM 慢?
DOM本身是一個js對象, 操作這個對象本身不慢, 但是操作后觸發了瀏覽器的行為, 如repaint和reflow等瀏覽器行為, 使其變慢
10.什么情況會阻塞渲染?
11.如何判斷js運行在瀏覽器中還是node中?
判斷有無全局對象global和window
12.關于web以及瀏覽器處理預加載有哪些思考?
圖片等靜態資源在使用之前就提前請求
資源使用到的時候能從緩存中加載, 提升用戶體驗
頁面展示的依賴關系維護
13.http多路復用
14. http和https:
15. CSRF和XSS區別及防御
16. cookie可設置哪些屬性?httponly?
chrome控制臺的application下可查看:
17. 登錄后,前端做了哪些工作,如何得知已登錄
18. http狀態碼
19. # Http請求頭緩存設置方法
Cache-control, expire, last-modify
20. 實現頁面回退刷新
21. 正向代理和反向代理
(1)訪問原來無法訪問的資源,如google
(2) 可以做緩存,加速訪問資源
(3)對客戶端訪問授權,上網進行認證
(4)代理可以記錄用戶訪問記錄(上網行為管理),對外隱藏用戶信息
(1)保證內網的安全,可以使用反向代理提供WAF功能,阻止web攻擊大型網站,通常將反向代理作為公網訪問地址,Web服務器是內網。
(2)負載均衡,通過反向代理服務器來優化網站的負載
22. 關于預檢請求
在非簡單請求且跨域的情況下,瀏覽器會自動發起options預檢請求。
23. 三次握手四次揮手
24. TCP和UDP協議
25. 進程和線程的區別
1. 生命周期
2 .雙向數據綁定v-model。這個最好也是自己實現一下 理解更深
通過v-model
VUE實現雙向數據綁定的原理就是利用了 Object.defineProperty() 這個方法重新定義了對象獲取屬性值(get)和設置屬性值(set)的操作來實現的。
function* helloWorldGenerator() { yield 'hello'; yield 'world'; return 'ending';}var hw=helloWorldGenerator();
3.vue父子組件傳遞參數
4.vue傳遞參數方法
hw.next()// { value: 'hello', done: false }hw.next()// { value: 'world', done: false }hw.next()// { value: 'ending', done: true }hw.next()// { value: undefined, done: true }
5.vue自定義組件
可以使用獨立可復用的自定義組件來構成大型應用, 采用帕斯卡命名法或橫線連接, 通過以上方式進行組件間通信. 每一個組件都是Vue實例, 可以使用生命周期鉤子.
6. vue自定義指令
7.vuex組成和原理
8.vue-router的原理,例如hashhistory和History interface這些東西要弄明白。其實看一下源碼就好了,看不懂可以直接看解析的相關技術博客。
9.vue的seo問題
seo關系到網站排名, vue搭建spa做前后端分離不好做seo, 可通過其他方法解決:
10.預渲染和ssr
以上
11.生命周期內create和mounted的區別
12.監聽watch
對應一個對象,鍵是觀察表達式,值是對應回調。值也可以是methods的方法名,或者是對象,包含選項。在實例化時為每個鍵調用 $watch()
13.登錄驗證攔截(通過router)
var myPromise=new Promise((resolve, reject)=> { // 需要執行的代碼 ... if (/* 異步執行成功 */) { resolve(value) } else if (/* 異步執行失敗 */) { reject(error) }})myPromise.then((value)=> { // 成功后調用, 使用value值}, (error)=> { // 失敗后調用, 獲取錯誤信息error})
router.beforeEach((from, to, next)=> {
if (to.meta.requireAuth) { // 判斷跳轉的路由是否需要登錄
if (store.state.token) { // vuex.state判斷token是否存在
next() // 已登錄
} else {
next({
path: '/login',
query: {redirect: to.fullPath} // 將跳轉的路由path作為參數,登錄成功后跳轉到該路由
})
}
} else {
next()
}
})
14. v-for key值
不寫key值會報warning, 和react的array渲染類似. 根據diff算法, 修改數組后, 寫key值會復用, 不寫會重新生成, 造成性能浪費或某些不必要的錯誤
15. vue3.0的更新和defineProperty優化
15. vue使用this獲取變量
正常要通過vm.[圖片上傳失敗...(image-6d2f4e-1570591304185)]
root傳參取值
16. jQuery的優缺點,與vue的不同,vue的優缺點?
17. vue解除雙向綁定
function promise () { this.msg='' // 存放value和error this.status='pending' var that=this var process=arguments[0] process (function () { that.status='fulfilled' that.msg=arguments[0] }, function () { that.status='rejected' that.msg=arguments[0] }) return this}promise.prototype.then=function () { if (this.status==='fulfilled') { arguments[0](this.msg) } else if (this.status==='rejected' && arguments[1]) { arguments[1](this.msg) }}
18. vue異步組件
為了簡化,Vue 允許你以一個工廠函數的方式定義你的組件,這個工廠函數會異步解析你的組件定義。Vue 只有在這個組件需要被渲染的時候才會觸發該工廠函數,且會把結果緩存起來供未來重渲染
Vue.component(
'async-webpack-example',
// 這個 `import` 函數會返回一個 `Promise` 對象。
()=> import('./my-async-component')
)
19. MVC與MVVM
20. vue漸進式
小到可以只使用核心功能,比如單文件組件作為一部分嵌入;大到使用整個工程,vue init webpack my-project來構建項目;VUE的核心庫及其生態系統也可以滿足你的各式需求(core+vuex+vue-route)
1. 新舊生命周期
2. react核心
3. fiber核心(react 16)
4. 渲染一個react
5. 高階組件
高階組件就是一個函數,且該函數(wrapper)接受一個組件作為參數,并返回一個新的組件。
高階組件并不關心數據使用的方式和原因,而被包裹的組件也不關心數據來自何處.
6. hook(v16.7測試)
在無狀態組件(如函數式組件)中也能操作state以及其他react特性, 通過useState
7. redux和vuex以及dva:
8. react和vue的區別
9. react單向數據流怎么理解
React是單向數據流,數據主要從父節點傳遞到子節點(通過props)。如果頂層(父級)的某個props改變了,React會重渲染所有的子節點。
10. React算法復雜度優化
react樹對比是按照層級去對比的, 他會給樹編號0,1,2,3,4.... 然后相同的編號進行比較。所以復雜度是n,這個好理解。
關鍵是傳統diff的復雜度是怎么算的?傳統的diff需要出了上面的比較之外,還需要跨級比較。他會將兩個樹的節點,兩兩比較,這就有n^2的復雜度了。然后還需要編輯樹,編輯的樹可能發生在任何節點,需要對樹進行再一次遍歷操作,因此復雜度為n。加起來就是n^3了。
11. React優點
聲明式, 組件化, 一次學習, 隨處編寫. 靈活, 豐富, 輕巧, 高效
1. 移動端兼容適配
2. flexible如何實現自動判斷dpr
判斷機型, 找出樣本機型去適配. 比如iphone以6為樣本, 寬度375px, dpr是2
3. 為什么以iPhone6為標準的設計稿的尺寸是以750px寬度來設計的呢?
iPhone6的滿屏寬度是375px,而iPhone6采用的視網膜屏的物理像素是滿屏寬度的2倍,也就是dpr(設備像素比)為2, 并且設計師所用的PS設計軟件分辨率和像素關系是1:1。所以為了做出的清晰的頁面,設計師一般給出750px的設計圖,我們再根據需求對元素的尺寸設計和壓縮。
4. 如何處理異形屏iphone X
5. 移動端首屏優化
6. PWA全稱Progressive Web App,即漸進式WEB應用
一個 PWA 應用首先是一個網頁, 可以通過 Web 技術編寫出一個網頁應用. 隨后添加上 App Manifest 和 Service Worker 來實現 PWA 的安裝和離線等功能
解決了哪些問題?
7. 離線包方案
現在 web 頁面在移動端的地位越來越高,大部分主流 App 采用 native + webview 的 hybrid 模式,加載遠程頁面受限于網絡,本地 webview 引擎,經常會出現渲染慢導致的白屏現象,體驗很差,于是離線包方案應運而生。動態下載的離線包可以使得我們不需要走完整的 App 審核發布流程就完成了版本的更新
8. 自適應和響應式布局的區別
1. babel和polyfill
2. jpg, jpeg和png區別
3. git rebase和merge區別
1.JSBridge通信原理, 有哪幾種實現的方式?
JsBridge給JavaScript提供了調用Native功能,Native也能夠操控JavaScript。這樣前端部分就可以方便使用地理位置、攝像頭以及登錄支付等Native能力啦。JSBridge構建 Native和非Native間消息通信的通道,而且是 雙向通信的通道。
2.實現一個簡單的 JSBridge,設計思路?
1. 二分查找和冒泡排序
2. 快速排序
Function.prototype.bind=function () { // 保存原函數 var self=this // 取出第一個參數作為上下文, 相當于[].shift.call(arguments) var context=Array.prototype.shift.call(arguments) // 取剩余的參數作為arg; 因為arguments是偽數組, 所以要轉化為數組才能使用數組方法 var arg=Array.prototype.slice.call(arguments) // 返回一個新函數 return function () { // 綁定上下文并傳參 self.apply(context, Array.prototype.concat.call(arg, Array.prototype.slice.call(arguments))) }}
3. 最長公共子串
function Father () {}function Child () {}// 1\. 原型繼承Child.prototype=new Father()// 2\. 構造繼承function Child (name) { Father.call(this, name)}// 3\. 組合繼承function Child (name) { Father.call(this, name)}Child.prototype=new Father()// 4\. 寄生繼承function cloneObj (o) { var clone=object.create(o) clone.sayName=... return clone}// 5\. 寄生組合繼承// 6\. ES6 class extend繼承
4. 最長公共子序列(LCS動態規劃)
另一篇
// 父標簽animation: antRotate 1.2s infinite linear;// 子標簽animation: antSpin 1s infinite linear;@keyframe antSpin { to { opacity: 1 }}@keyframe antRotate { to { transform: rotate(405) }}// animation-delay: 逐個延遲0.4s
5. 數組去重,多種方法
6. 實現一個函數功能:sum(1,2,3,4..n)轉化為 sum(1)(2)(3)(4)…(n)
// 使用柯里化 + 遞歸
function curry ( fn ) {
var c=(...arg)=> (fn.length===arg.length) ?
fn (...arg) : (...arg1)=> c(...arg, ...arg1)
return c
}
7. 反轉二叉樹
var invertTree=function (root) {
if (root !==null) {
[root.left, root.right]=[root.right, root.left]
invertTree(root.left)
invertTree(root.right)
}
return root
}
8. 貪心算法解決背包問題
var items=['A','B','C','D']
var values=[50,220,60,60]
var weights=[5,20,10,12]
var capacity=32 //背包容積
greedy(values, weights, capacity) // 320
function greedy(values, weights, capacity) {
var result=0
var rest=capacity
var sortArray=[]
var num=0
values.forEach((v, i)=> {
sortArray.push({
value: v,
weight: weights[i],
ratio: v / weights[i]
})
})
sortArray.sort((a, b)=> b.ratio - a.ratio)
sortArray.forEach((v, i)=> {
num=parseInt(rest / v.weight)
rest -=num * v.weight
result +=num * v.value
})
return result
}
9. 輸入一個遞增排序的數組和一個數字S,在數組中查找兩個數,使得他們的和正好是S,如果有多對數字的和等于S,輸出兩個數的乘積最小的。
function FindNumbersWithSum(array, sum)
{
var index=0
for (var i=0; i < array.length - 1 && array[i] < sum / 2; i++) {
for (var j=i + 1; j < array.length; j++) {
if (array[i] + array[j]===sum) return [array[i], array[j]]
}
//index=array.indexOf(sum - array[i], i + 1)
// if (index !==-1) {
// return [array[i], array[index]]
//}
}
return []
10. 二叉樹各種(層序)遍歷
深度廣度遍歷
// 根據前序和中序重建二叉樹
/* function TreeNode(x) {
this.val=x;
this.left=null;
this.right=null;
} */
function reConstructBinaryTree(pre, vin)
{
var result=null
if (pre.length===1) {
result={
val: pre[0],
left: null,
right: null
}
} else if (pre.length > 1) {
var root=pre[0]
var vinRootIndex=vin.indexOf(root)
var vinLeft=vin.slice(0, vinRootIndex)
var vinRight=vin.slice(vinRootIndex + 1, vin.length)
pre.shift()
var preLeft=pre.slice(0, vinLeft.length)
var preRight=pre.slice(vinLeft.length, pre.length)
result={
val: root,
left: reConstructBinaryTree(preLeft, vinLeft),
right: reConstructBinaryTree(preRight, vinRight)
}
}
return result
}
// 遞歸
// 前序遍歷
function prevTraverse (node) {
if (node===null) return;
console.log(node.data);
prevTraverse(node.left);
prevTraverse(node.right);
}
// 中序遍歷
function middleTraverse (node) {
if (node===null) return;
middleTraverse(node.left);
console.log(node.data);
middleTraverse(node.right);
}
// 后序遍歷
function lastTraverse (node) {
if (node===null) return;
lastTraverse(node.left);
lastTraverse(node.right);
console.log(node.data);
}
// 非遞歸
// 前序遍歷
function preTraverse(tree) {
var arr=[],
node=null
arr.unshift(tree)
while (arr.length) {
node=arr.shift()
console.log(node.root)
if (node.right) arr.unshift(node.right)
if (node.left) arr.unshift(node.left)
}
}
// 中序遍歷
function middleTraverseUnRecursion (root) {
let arr=[],
node=root;
while (arr.length !==0 || node !==null) {
if (node===null) {
node=arr.shift();
console.log(node.data);
node=node.right;
} else {
arr.unshift(node);
node=node.left;
}
}
}
// 廣度優先-層序遍歷
// 遞歸
var result=[]
var stack=[tree]
var count=0
var bfs=function () {
var node=stack[count]
if (node) {
result.push(node.value)
if (node.left) stack.push(node.left)
if (node.right) stack.push(node.right)
count++
bfs()
}
}
bfs()
console.log(result)
// 非遞歸
function bfs (node) {
var result=[]
var queue=[]
queue.push(node)
while (queue.length) {
node=queue.shift()
result.push(node.value)
node.left && queue.push(node.left)
node.right && queue.push(node.right)
}
return result
}
11. 各種排序
// 插入排序
function insertSort(arr) {
var temp
for (var i=1; i < arr.length; i++) {
temp=arr[i]
for (var j=i; j > 0 && temp < arr[j - 1]; j--) {
arr[j]=arr[j - 1]
}
arr[j]=temp
}
return arr
}
console.log(insertSort([3, 1, 8, 2, 5]))
// 歸并排序
function mergeSort(array) {
var result=array.slice(0)
function sort(array) {
var length=array.length
var mid=Math.floor(length * 0.5)
var left=array.slice(0, mid)
var right=array.slice(mid, length)
if (length===1) return array
return merge(sort(left), sort(right))
}
function merge(left, right) {
var result=[]
while (left.length || right.length) {
if (left.length && right.length) {
if (left[0] < right[0]) {
result.push(left.shift())
} else {
result.push(right.shift())
}
} else if (left.length) {
result.push(left.shift())
} else {
result.push(right.shift())
}
}
return result
}
return sort(result)
}
console.log(mergeSort([5, 2, 8, 3, 6]))
// 二分插入排序
function twoSort(array) {
var len=array.length,
i,
j,
tmp,
low,
high,
mid,
result
result=array.slice(0)
for (i=1; i < len; i++) {
tmp=result[i]
low=0
high=i - 1
while (low <=high) {
mid=parseInt((high + low) / 2, 10)
if (tmp < result[mid]) {
high=mid - 1
} else {
low=mid + 1
}
}
for (j=i - 1; j >=high + 1; j--) {
result[j + 1]=result[j]
}
result[j + 1]=tmp
}
return result
}
console.log(twoSort([4, 1, 7, 2, 5]))
12. 使用尾遞歸對斐波那契優化
遞歸非常耗費內存,因為需要同時保存成千上百個調用幀,很容易發生“棧溢出”錯誤(stack overflow)。但對于尾遞歸來說,由于只存在一個調用幀,所以永遠不會發生“棧溢出”錯誤。
// 傳統遞歸斐波那契, 會造成超時或溢出
function Fibonacci (n) {
if ( n <=1 ) {return 1};
return Fibonacci(n - 1) + Fibonacci(n - 2);
}
Fibonacci(10) // 89
Fibonacci(100) // 超時
Fibonacci(500) // 超時
// 使用尾遞歸優化, 可規避風險
function Fibonacci2 (n , ac1=1 , ac2=1) {
if( n <=1 ) {return ac2};
return Fibonacci2 (n - 1, ac2, ac1 + ac2);
}
Fibonacci2(100) // 573147844013817200000
Fibonacci2(1000) // 7.0330367711422765e+208
Fibonacci2(10000) // Infinity
13. 兩個升序數組合并為一個升序數組
function sort (A, B) {
var i=0, j=0, p=0, m=A.length, n=B.length, C=[]
while (i < m || j < n) {
if (i < m && j < n) {
C[p++]=A[i] < B[j] ? A[i++] : B[j++]
} else if (i < m) {
C[p++]=A[i++]
} else {
C[p++]=B[j++]
}
}
return C
}
1. node的router是什么
2. 數據庫索引是啥
3. 瀏覽器的事件循環和node事件循環有什么區別?
以上就是前端面試題全面整理-帶解析 涵蓋(css、js、瀏覽器、vue、react、移動web、前端性能、算法、node)的詳細內容,更多請關注html中文網其它相關文章!
我是@半糖學前端 ,專注前端技術領域分享,一個前端從業者,關注我和我一起學習,共同進步!
對于八寶兩個字我們都不陌生,日常經常了解的應該屬八寶粥、臘八粥等,這些都是用一些對人體極好的營養物質來熬制成粥之后,在進行使用,既能夠滿足挑剔的味蕾,又能夠很好的強身健體,清淡的流失對于生病的人來說也是非常推薦的食物,因此,八寶成為了我們日常的常用品,不過除了上述所提到的八寶粥之外,龍井八寶茶也是非常有名的,今天小編就給大家介紹一下關于龍井八寶茶有哪些功效。
龍井八寶茶有哪些功效?
首先,想要了解龍井八寶茶,就要知道八寶茶有哪八寶,其實,八寶分別是龍井茶、陳皮、枸杞、干桂圓、紅棗、山楂、菊花以及冰糖,這八寶隨便拿出一樣來都是對人體能夠產生很多功效的滋補品,而將這八種食材相融合成為一道佳肴之后,便是偏向于保健的一類養生茶,但是雖然看著多,做起來卻是非常的簡單的。
八寶茶,用八種配料加入蓋碗之后,再用滾燙的水進行沖泡,然后讓配料在蓋碗中進行翻滾,讓配料慢慢與水融合,然后蓋上蓋,靜待幾分鐘之后,便可以進行享用了,因此,對于身體不好的人來說,常服用一些這樣的保健茶,對于身體是有很強大的功效的。
八寶茶在冬天飲用是最佳的時間,因為冬季寒冷干燥,對于身體不好的人來說,冬天會出現免疫力下降,手腳冰涼等癥狀,八寶茶中枸杞和紅棗都能起到一定的補充作用,而菊花能夠降火消暑,而龍井雖然只是這八分之一,卻仍舊是占據了很重要的位置,龍井的濃厚茶香,再配以冰糖的甜度可口,能夠中和八寶茶的口感,讓八寶茶更是一種飲用。
龍井八寶茶有哪些功效?
龍井八寶茶營養非常的豐富,而且功效也是非常的強大,能夠起到清火、降噪、養顏、固本保元的作用,特別是對于身體虛弱,四肢無力以及消化不良的人來說,在飯后飲一杯龍井八寶茶,可以說是一件非常幸福的事情了。
龍井八寶茶雖然看似簡單,食材也是非常容易買到,但是功效卻是普通茶飲料的好幾倍,不論春夏秋冬,都可以正常飲用,特別是在節日之后,因為節日之時人們都會暴飲暴食,難免造成消化不良等毛病,在飯后準備一杯龍井八寶茶,能夠疏通胃腸,促進胃功能,從而對身體進行一個補充。
因此,綜上所述,龍井八寶茶對于人們來說是非常有好處的,日常如果在家多時,可以學著做一做龍井八寶茶,五顏六色的色彩,也會讓人們的食欲大增,不過還是要特別注意,以上的食材有沒有自身的身體條件不適宜飲用的,如果有還是要特別留意一下的。
文章來源longjing100.com,本文鏈接http://www.longjing100.com/a/gongxiao/13616.html
*請認真填寫需求信息,我們會在24小時內與您取得聯系。