前端面試核心篇 (附答案)

1.webpack和gulp區別(模塊化與流的區別)

答:

gulp強調的是前端開發的工作流程,我們可以通過配置一系列的task,定義task處理的事務(例如文件壓縮合並、雪碧圖、啓動server、版本控制等),然後定義執行順序,來讓gulp執行這些task,從而構建項目的整個前端開發流程。

webpack是一個前端模塊化方案,更側重模塊打包,我們可以把開發中的所有資源(圖片、js文件、css文件等)都看成模塊,通過loader(加載器)和plugins(插件)對資源進行處理,打包成符合生產環境部署的前端資源。

 

2.redux裏常用方法

答:

在組件化的應用中,會有着大量的組件層級關係,深嵌套的組件與淺層父組件進行數據交互,變得十分繁瑣困難。而redux,站在一個服務級別的角度,可以毫無阻礙地將應用的狀態傳遞到每一個層級的組件中。redux就相當於整個應用的管家。

提供 getState() 方法獲取 state;

提供 dispatch(action) 方法更新 state;

通過 subscribe(listener) 註冊監聽器;

等等

 

3.說說vue和react的區別

答:

參考:https://blog.csdn.net/caoyan0829/article/details/78275701

 

4.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()

組件將要卸載時調用,一些事件監聽和定時器需要在此時清除。

 

5.reactJs的組件交流

答:

1)父組件向子組件傳值:主要是利用props來進行交流

2)子組件向父組件傳值:子組件通過控制自己的state然後告訴父組件的點擊狀態。然後在父組件中展示出來,如圖:

3)沒有任何嵌套關係的組件之間傳值:如果組件之間沒有任何關係,組件嵌套層次比較深(個人認爲 2 層以上已經算深了),或者你爲了一些組件能夠訂閱、寫入一些信號,不想讓組件之間插入一個組件,讓兩個組件處於獨立的關係。對於事件系統,這裏有 2 個基本操作步驟:訂閱(subscribe)/監聽(listen)一個事件通知,併發送(send)/觸發(trigger)/發佈(publish)/發送(dispatch)一個事件通知那些想要的組件。

 

6.有了解過react的虛擬DOM嗎,虛擬DOM是怎麼對比的呢

答:

當然是使用的diff算法,diff算法有三種優化形式:

tree diff:將新舊兩顆DOM樹按照層級遍歷,只對同級的DOM節點進行比較,即同一父節點下的所有子節點,當發現節點已經不存在,則該節點及其子節點會被完全刪除,不會進一步比較

component diff:不同組件之間的對比,如果組件類型相同,暫不更新,否則刪除舊的組件,再創建一個新的組件,插入到刪除組件的位置

element diff:在類型相同的組件內,再繼續對比組件內部的元素,

參考:https://juejin.im/post/5a3200fe51882554bd5111a0

 

7.setState之後的流程

答:

在代碼中調用setState函數之後,React 會將傳入的參數對象與組件當前的狀態合併,然後觸發所謂的調和過程(Reconciliation)。 經過調和過程,React 會以相對高效的方式根據新的狀態構建 React 元素樹並且着手重新渲染整個UI界面。 在 React 得到元素樹之後,React 會自動計算出新的樹與老樹的節點差異,然後根據差異對界面進行最小化重渲染。 在差異計算算法中,React 能夠相對精確地知道哪些位置發生了改變以及應該如何改變,這就保證了按需更新,而不是全部重新渲染。

 

8.OSI七層模型

答:

osi七層模型可以說是面試必考基礎了

從上到下分別是:

應用層:文件傳輸,常用協議HTTP,snmp,FTP ,

表示層:數據格式化,代碼轉換,數據加密,

會話層:建立,解除會話

傳輸層:提供端對端的接口,tcp,udp

網絡層:爲數據包選擇路由,IP,icmp

數據鏈路層:傳輸有地址的幀

物理層:二進制的數據形式在物理媒體上傳輸數據

 

9.怎麼生成token,怎麼傳遞

答:

Token是服務端生成的一串字符串,以作客戶端進行請求的一個令牌,當第一次登錄後,服務器生成一個Token便將此Token返回給客戶端,以後客戶端只需帶上這個Token前來請求數據即可,無需再次帶上用戶名和密碼。

基於 Token 的身份驗證

使用基於 Token 的身份驗證方法,在服務端不需要存儲用戶的登錄記錄。流程是這樣的:

1)客戶端使用用戶名跟密碼請求登錄

2)服務端收到請求,去驗證用戶名與密碼

3)驗證成功後,服務端會簽發一個 Token,再把這個 Token 發送給客戶端

4)客戶端收到 Token 以後可以把它存儲起來,比如放在 Cookie 裏或者 Local Storage 裏

5)客戶端每次向服務端請求資源的時候需要帶着服務端簽發的 Token

6)服務端收到請求,然後去驗證客戶端請求裏面帶着的 Token,如果驗證成功,就向客戶端返回請求的數據

7)APP登錄的時候發送加密的用戶名和密碼到服務器,服務器驗證用戶名和密碼,如果成功,以某種方式比如隨機生成32位的字符串作爲token,存儲到服務器中,並返回token到APP,以後APP請求時,

8)凡是需要驗證的地方都要帶上該token,然後服務器端驗證token,成功返回所需要的結果,失敗返回錯誤信息,讓他重新登錄。其中服務器上token設置一個有效期,每次APP請求的時候都驗證token和有效期

token的優勢

1)無狀態、可擴展 :在客戶端存儲的Tokens是無狀態的,並且能夠被擴展。基於這種無狀態和不存儲Session信息,負載負載均衡器能夠將用戶信息從一個服務傳到其他服務器上。如果我們將已驗證的用戶的信息保存在Session中,則每次請求都需要用戶向已驗證的服務器發送驗證信息(稱爲Session親和性)。用戶量大時,可能會造成  一些擁堵。但是不要着急。使用tokens之後這些問題都迎刃而解,因爲tokens自己hold住了用戶的驗證信息。

2)安全性 :請求中發送token而不再是發送cookie能夠防止CSRF(跨站請求僞造)。即使在客戶端使用cookie存儲token,cookie也僅僅是一個存儲機制而不是用於認證。不將信息存儲在Session中,讓我們少了對session操作。token是有時效的,一段時間之後用戶需要重新驗證。我們也不一定需要等到token自動失效,token有撤回的操作,通過token revocataion可以使一個特定的token或是一組有相同認證的token無效。

3)可擴展性 :Tokens能夠創建與其它程序共享權限的程序。例如,能將一個隨便的社交帳號和自己的大號(Fackbook或是Twitter)聯繫起來。當通過服務登錄Twitter(我們將這個過程Buffer)時,我們可以將這些Buffer附到Twitter的數據流上(we are allowing Buffer to post to our Twitter stream)。使用tokens時,可以提供可選的權限給第三方應用程序。當用戶想讓另一個應用程序訪問它們的數據,我們可以通過建立自己的API,得出特殊權限的tokens。

4)多平臺跨域 :我們提前先來談論一下CORS(跨域資源共享),對應用程序和服務進行擴展的時候,需要介入各種各種的設備和應用程序。Having our API just serve data, we can also make the design choice to serve assets from a CDN. This eliminates the issues that CORS brings up after we set a quick header configuration for our application.只要用戶有一個通過了驗證的token,數據和資源就能夠在任何域上被請求到。Access-Control-Allow-Origin: *

5)基於標準 :創建token的時候,你可以設定一些選項。我們在後續的文章中會進行更加詳盡的描述,但是標準的用法會在JSON Web Tokens體現。最近的程序和文檔是供給JSON Web Tokens的。它支持衆多的語言。這意味在未來的使用中你可以真正的轉換你的認證機制。

參考:https://www.cnblogs.com/lufeiludaima/p/pz20190203.html

 

10.操作系統進程和線程的區別

答:

進程,是併發執行的程序在執行過程中分配和管理資源的基本單位,是一個動態概念,競爭計算機系統資源的基本單位。

線程,是進程的一部分,一個沒有線程的進程可以被看作是單線程的。線程有時又被稱爲輕權進程或輕量級進程,也是 CPU 調度的一個基本單位。

 

11.Linux查詢進程指令,查詢端口,殺進程

查詢進程:

ps 命令用於查看當前正在運行的進程。

grep 是搜索

例如: ps -ef | grep java

表示查看所有進程裏CMD是java的進程信息

ps -aux | grep java

-aux 顯示所有狀態

ps

殺死進程:

kill -9[PID]

 

12.Linux修改權限

答:

chgrp:  修改用戶組            chgrp  caoyan(存在的用戶組).文件名

chown:修改文件擁有者     chown caoyan .bashrc_test

chmod:  修改權限                chmod 777 .bashrc_test

 

13.把多維數組變成一維數組的方法

答:

法一:遞歸

function flatten(arr) {
    var result = [];
    for (var i = 0, len = arr.length; i < len; i++) {
        if (Array.isArray(arr[i])) {
            result = result.concat(flatten(arr[i]))
        }
        else {
            result.push(arr[i])
        }
    }
    return result;
}

法二:toString

function flatten(arr) {
    return arr.toString().split(',').map(function(item){
        return +item
    })
}

法三:reduce

function flatten(arr) {
    return arr.reduce(function(prev, next){
        return prev.concat(Array.isArray(next) ? flatten(next) : next)
    }, [])
}

法四:rest運算符

function flatten(arr) {
    while (arr.some(item => Array.isArray(item))) {
        arr = [].concat(...arr);
    }
    return arr;
}

 

14.幾種常見的排序算法,手寫

答:

不穩定: 一些快選堆   (希快選堆)

冒泡排序:重複地走訪過要排序的元素列,依次比較兩個相鄰的元素,如果他們的順序(如從大到小、首字母從A到Z)錯誤就把他們交換過來。走訪元素的工作是重複地進行直到沒有相鄰元素需要交換,也就是說該元素已經排序完成

var bubbleSort=function(arr){
    var temp;
	for(var i=0;i<arr.length-1;i++){
		for(var j=i+1;j<arr.length;j++){
			if(arr[i]>arr[j]){//如果前面的數據比後面的大就交換
				temp=arr[i];
				arr[i]=arr[j];
				arr[j]=temp;
			}
		}
	} 
	return arr;
}
console.log("The result is:"+bubbleSort(arr));

快速排序:通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然後再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列

var quickSort=function(arr){ 
	//如果數組長度小於等於1無需判斷直接返回即可
	if(arr.length<=1){
		return arr;
	}
	var midIndex=Math.floor(arr.length/2);//取基準點
	var midIndexVal=arr.splice(midIndex,1)[0];//取基準點的值,splice(index,1)函數可以返回數組中被刪除的那個數arr[index+1]
	var left=[];//存放比基準點小的數組
	var right=[];//存放比基準點大的數組
	//遍歷數組,進行判斷分配
	for(var i=0;i<arr.length;i++){
		if(arr[i]<midIndexVal){
			left.push(arr[i]);//比基準點小的放在左邊數組
		}
		else{
			right.push(arr[i]);//比基準點大的放在右邊數組
		}
	}
	//遞歸執行以上操作,對左右兩個數組進行操作,直到數組長度爲<=1;
	return quickSort(left).concat(midIndexVal,quickSort(right));
};
//console.log(quickSort(arr));

插入排序:插入排序的基本操作就是將一個數據插入到已經排好序的有序數據中,從而得到一個新的、個數加一的有序數據,算法適用於少量數據的排序,時間複雜度爲O(n^2)。是穩定的排序方法。

function insertSort(arr) {
    var len = arr.length;
    var temp;
    for (var i = 1;i < len;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;
}

選擇排序:從原始數組中找到最小的元素,並把該元素放在數組的最前面,然後再從剩下的元素中尋找最小的元素,放在之前最小元素的後面,直到排序完畢

function selectSort(arr){
      var min,temp;
      for(var i=0;i<arr.length-1;i++){
          min=i;
          for(var j=i+1;j<arr.length;j++){
              if(arr[j]<arr[min]){   //尋找最小的數 
                  min = j;    //保存最小數的索引 
              } 
          }
          temp=arr[i];    //值交換
          arr[i]=arr[min];
          arr[min]=temp;
      }
      return arr;
  }
//  console.log(selectSort([6,1,2,4,3,5])) 

 

15.常用的數組的去重方法

答:

1)es6去重(推薦)

let arr = [1,2,2,3,4,4,4];

let s = new Set(arr);   //結果:Set {1,2,3,4}

let newArr = Array.from(s);   //結果:[1,2,3,4],完成去重

2)indexOf去重

function uniq(array){
    var temp = []; //一個新的臨時數組
    for(var i = 0; i < array.length; i++){ //新建一新數組,遍歷傳入數組,值不在新數組就push進該新數組中
        if(temp.indexOf(array[i]) == -1){
            temp.push(array[i]);
        }
    }
    return temp;
}

 

 

前端面試基礎篇 二:https://blog.csdn.net/caoyan0829/article/details/89965445

前端面試基礎篇 一:https://blog.csdn.net/caoyan0829/article/details/89888629

此文章參考牛客面經彙總

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章