Web常見前端面試題及答案

MarBirchell 8年前發布 | 106K 次閱讀 MVVM模式 CSS 前端技術 JavaScript

Web前端常見面試題及答案

1、盒子模型

盒子模型包括四部分:內容(content)、填充(padding)、邊框(border)、邊界(margin)

盒子模型可以分為兩種:IE盒子模型和W3C標準盒子模型

區別:兩者對于width的計算方式不同,前者width=border+padding+內容寬度,后者width=內容寬度。

2、position包含幾種屬性?absolute和relative的區別?

static:默認狀態、沒有定位、正常流

inherit:從父元素集成position屬性的值

fixed:生成絕對定位的元素(相對于瀏覽器窗口進行定位)

absolute:生成絕對定位的元素(相位與static定位以外的第一個父元素定位)

relative:生成相對定位的元素(相對于其正常位置定位)

absolute和relative區別:父元素的padding對relative的子元素布局有影響,absolute的子元素不受影響

3、前端性能優化

減少HTTP請求、使用內容發布網絡、壓縮組件、使用Expire頭、JS放底部、CSS放頂部、避免CSS表達式等。

4、JSONP是什么?它是如何實現跨域的?為什么它可以實現跨域?

JSONP(JSON with Padding)是一個非官方的協議,它允許在服務器端集成Script tags返回至客戶端,通過javascript callback的形式實現跨域訪問。

由于同源策略的限制,XmlHttpRequest只允許請求當前源(域名、協議、端口)的資源,為了實現跨域請求,可以通過script標簽實現跨域請求(因為同源策略不阻止動態腳本插入,并且將腳本看作是從提供 Web 頁面的域上加載的),然后在服務端輸出JSON數據并執行回調函數,從而解決了跨域的數據請求。

5、瀏覽器兼容問題

css兼容性問題:①不同瀏覽器的標簽默認的外補丁和內補丁不同,解決方案:用通配符*來設置各個標簽的內外補丁是0(即設置margin和padding為0);②div的垂直居中問題 vertical-align:middle;文字居中:將行距增加到和整個div一樣,高line-height=行高;③margin加倍問題:設置為float的div在ie下的margin會加倍。解決方案:為這個div設置樣式:display:inline;

js兼容性問題:①在標準的事件綁定中綁定事件的方法函數為addEventListener,而IE使用的是attachEvent;②事件處理中event屬性的獲取不同。標準瀏覽器是作為參數帶入,然后通過e.target獲取目標元素;而IE是通過window.event方式獲得,通過e.srcElement獲取目標元素;

6、JS和JAVA的作用域有什么區別

java是塊級作用域,js是函數作用域,沒有塊級作用域。

var name="global";  
if(true){  
    var name="local";  
    console.log(name)  
}  
console.log(name);

這段都輸出是“local",如果有塊級作用域,明顯if語句將創建局部變量name,并不會修改全局name,可是沒有這樣,所以Js沒有塊級作用域。

7、閉包問題

閉包:函數能被外部調用到,則該作用連上的所有變量都會被保存下來。

作用:①可以讀取函數內部的變量;②相當于劃出了一塊私有作用域,避免數據污染;③讓變量始終保存在內存中

使用全局變量被認為是不好的習慣,而且容易造成錯誤并且維護成本較高,所以js可以采用閉包的方式讀取函數的內部變量。但是如果大量使用閉包就會造成過多的變量始終保存在內存中,會造成內存泄漏。

一個簡單的閉包例子:

function f1(){
  var n=999;
  function f2(){
    alert(n);
  }
  return f2;
}
var result=f1();
result(); // 999

8、js中this的工作原理

①全局范圍內:指向全局對象;

this;

②函數調用:指向全局對象

foo();

③方法調用:this指向test對象

test.foo();

④調用構造函數:this指向新創建的對象

new foo();

⑤顯示的設置this:使用call或者apply方法時,this指向第一個參數

function foo(a, b, c) {}
var bar = {};
foo.apply(bar, [1, 2, 3]); // 數組將會被擴展,如下所示
foo.call(bar, 1, 2, 3); // 傳遞到foo的參數是:a = 1, b = 2, c = 3

9、模塊化編程

①AMD(異步模塊定義) requirejs

defined(id,deps,factory)
require([dependency],function(){})

異步加載,瀏覽器不會失去響應

它指定的回調函數,只有前面的模塊都加載完成后,才會運行,解決了依賴性問題

②CMD(通用模塊定義) seajs

模塊定義方式和模塊加載時機處理不同

defined(id,deps,factory)
function(require,exports,module)
module.exports = ______;

③區別:AMD依賴前置,在定義模塊的時候就要聲明其依賴的模塊;CMD就近依賴,只有在用到哪個模塊的時候再去require;

10、JS繼承與原型問題

Js所有的函數都有一個prototype屬性,這個屬性引用了一個對象,即原型對象,也簡稱原型。每一個對象都有原型,在瀏覽器中它體現在一個隱藏的 proto 屬性上。

當一個對象需要調用某個方法時,它回去最近的原型上查找該方法,如果沒有找到,它會再次往下繼續查找。這樣逐級查找,一直找到了要找的方法。 這些查找的原型構成了該對象的原型鏈條。原型最后指向的是null。我們說的原型繼承,就是將父對像的方法給子類的原型。子類的構造函數中不擁有這些方法和屬性。

11、少用float?

①使用float可能會造成兼容性問題,比如在ie6以下,float元素margin加倍問題;②使用float之后會影響左右元素,有可能造成錯位問題(float之后都要clear)

解決:可用display、position轉化

①無序鏈接(ul、li),設定li標簽屬性:display:inline

②div左右結構,比如在右側要放一個more(更多)來顯示更多信息的時候用到了float:right,可以用定位來做。給包裹more的div設定position:relative,然后more這個標簽right:0即可。結構更為清晰一點。

12、一個頁面從URL到加載顯示完成,都發生了什么?

①通過DNS將該地址解析成IP地址;

②發起網絡連接,進行http協議會話:客戶端發送報頭(請求報頭),服務端回饋報頭(響應報頭)

③返回一個頁面(根據頁面上的外鏈的URL重新發送請求獲取)

④接收文件完畢,對加載到的資源進行語法解析,以及相應的內部數據結構(網頁渲染)

13、隊列、堆、棧的區別?

隊列是先進先出:就像一條路,有一個入口和一個出口,先進去的就可以先出去。而棧就像一個箱子,后放的在上邊,所以后進先出。堆是在程序運行時,而不是在程序編譯時,申請某個大小的內存空間。即動態分配內存,對其訪問和對一般內存的訪問沒有區別。

棧(Stack)是操作系統在建立某個進程時或者線程為這個線程建立的存儲區域。在編程中,例如C/C++中,所有的局部變量都是從棧中分配內存空間,實際上也不是什么分配,只是從棧頂向上用就行,在退出函數的時候,只是修改棧指針就可以把棧中的內容銷毀,所以速度最快。

堆(Heap)是應用程序在運行的時候請求操作系統分配給自己內存,一般是申請/給予的過程。由于從操作系統管理的內存分配所以在分配和銷毀時都要占用時間,所以用堆的效率低的多!但是堆的好處是可以做的很大,C/C++對分配的Heap是不初始化的。

在Java中除了簡單類型(int,char等)都是在堆中分配內存,這也是程序慢的一個主要原因。但是跟C/C++不同,Java中分配Heap內存是自動初始化的。在Java中所有的對象(包括int的wrapper Integer)都是在堆中分配的,但是這個對象的引用卻是在Stack中分配。也就是說在建立一個對象時從兩個地方都分配內存,在Heap中分配的內存實際建立這個對象,而在Stack中分配的內存只是一個指向這個堆對象的指針(引用)而已。

14、如何居中div?如何居中一個浮動元素?

給div設置一個寬度,然后添加margin:0 auto;

div{
  width:200px;
  margin:0 auto;
}

居中一個浮動元素

div{
  width:500px;
  height:500px;
  magin:-150px 0 0 -250px;
  position:relative;
  left:50%;
  top:50%;
}

15、什么是線程?進程和線程的關系是什么?

線程可定義為進程內的一個執行單位,或者定義為進程內的一個可調度實體。 在具有多線程機制的操作系統中,處理機調度的基本單位不是進程而是線程。一個進程可以有多個線程,而且至少有一個可執行線程。

打個比喻:進程好比工廠(計算機)里的車間,一個工廠里有多個車間(進程)在運轉,每個車間里有一個或多個工人(線程)在協同工作,這些工人就可以理解為線程。

線程和進程的關系:

1.線程是進程的一個組成部分.

2.進程的多個線程都在進程地址空間活動.

3.系統資源是分配給進程的,線程需要資源時,系統從進程的資源里分配給線程.

4.處理機調度的基本單位是線程.

16、React為什么這么火?

17、CSS3中的transform屬性和transition屬性?

transform:

功能:使元素變形的屬性,其配合rotate(旋轉角度)、scale(縮放倍數)、skew(扭曲元素)等參數一起使用

語法:

transform:rotate(旋轉角度);//正數為順時針、負數為逆時針;

transform:rotate(30deg);//順時針旋轉30度

transform:rotate(-20deg);//逆時針旋轉20度

transform:scale(縮放倍數);

transform:scale(1.20);//放大1.2倍

transition:

功能:設置元素由樣式一變為樣式二所需要的一些變化效果

語法:transition: property duration timing-function delay ;

描述
transition-property 規定設置過渡效果的 CSS 屬性的名稱。
transition-duration 規定完成過渡效果需要多少秒或毫秒。
transition-timing-function 規定速度效果的速度曲線。
transition-delay 定義過渡效果何時開始。

注:使用這兩個屬性時應考慮到瀏覽器的兼容性,所以要針對不同的瀏覽器都添加一次樣式,如下:

-webkit-transform:rotate(0deg) scale(1.20); 
-moz-transform:rotate(0deg) scale(1.20); 
transform:rotate(0deg) scale(1.20);

18、什么是MVVM框架?

MVVM是Model-View-ViewModel的簡寫。

MVVM 是 Web 前端一種非常流行的開發模式,利用 MVVM 可以使我們的代碼更專注于處理業務邏輯而不是去關心 DOM 操作。目前著名的 MVVM 框架有 vue, avalon, angular 等,這些框架各有千秋,但是實現的思想大致上是相同的:數據綁定 + 視圖刷新。跟MVC一樣,主要目的是分離視圖(View)和模型(Model)。View可以獨立于Model變化和修改,一個ViewModel可以綁定到不同的"View"上,當View變化的時候Model可以不變,當Model變化的時候View也可以不變。

在MVVM中,數據是核心,由于VIewModel與View之間的雙向綁定,操作了ViewModel中的數據(當然只能是監控屬性),就會同步到DOM,我們透過DOM事件監控用戶對DOM的改動,也會同步到ViewModel。

<div id="mobile-list"> 
  <h1 v-text="title"></h1> 
  <ul> 
    <li v-for="item in brands"> 
      <b v-text="item.name"></b> 
      <span v-show="showRank">Rank: {{item.rank}}</span> 
    </li> 
  </ul>
</div>
var element = document.querySelector('#mobile-list');
var vm = new MVVM(element, { 
  'title' : 'Mobile List',
   'showRank': true,
   'brands' : [ 
    {'name': 'Apple', 'rank': 1}, 
    {'name': 'Galaxy', 'rank': 2},
    {'name': 'OPPO', 'rank': 3} 
  ]
});
vm.set('title', 'Top 3 Mobile Rank List'); // => <h1>Top 3 Mobile Rank List</h1>

以上這段如此簡潔的代碼,就是MVVM框架的一個簡單的實現效果。在HTML代碼里面,可能會嵌入很多自定義的屬性(標記),以此來實現數據的綁定,而且還可以進行一些簡單的邏輯處理,比如if和循環等。

react應該也算是MVVM框架,但是與傳統的MVVN框架不同的是,react默認數據綁定方式是單向綁定,而vue及angular都是雙向綁定;react使用虛擬DOM配合JSX,而vue及angular直接將數據通過屬性綁定在真實DOM上的。

MVVM框架的優點:

1、方便測試

在MVC下,Controller基本是無法測試的,里面混雜了個各種邏輯,而且分散在不同的地方。有了MVVM我們就可以測試里面的viewModel,來驗證我們的處理結果對不對。

2、便于代碼的移植

可以把一些視圖邏輯放在一個ViewModel里面,讓很多view重用這段視圖邏輯。比如iOS里面有iPhone版本和iPad版本,除了交互展示不一樣外,業務邏輯的model是一致的。這樣,我們就可以以很小的代價去開發另一個app。

3、獨立開發

開發人員可以專注于業務邏輯和數據的開發(ViewModel),設計人員可以專注于頁面設計,使用Expression Blend可以很容易設計界面并生成xml代碼。

19、利用@media screen實現網頁布局的自適應。

判斷媒體類型,執行不同的css樣式屬性

重要屬性:min-width:設置最小分辨率大小;max-width:設置最大分辨率大小。

①方式一:通過css

///1280分辨率以上(大于1200px)
@media screen and (min-width:1200px){

content{ width: 1100px; }

mian,.div1{width: 730px;}

secondary{width:310px;}

}</pre>

//1100分辨率(大于960px,小于1199px)
@media screen and (min-width: 960px) and (max-width: 1199px) {

content{ width: 960px; }

main,.div1{width: 650px;}

secondary{width:250px}

}</pre>

②方式二:通過link引入不同的css文件

//意思是當屏幕的寬度大于600小于800時,應用styleB.css
<link rel="stylesheet" type="text/css" href="styleB.css" media="screen and (min-width: 600px) and (max-width: 800px)">

優點:無需插件和手機主題,對移動設備友好,能夠適應各種窗口大小。只需在CSS中添加@media screen屬性,根據瀏覽器寬度判斷并輸出不同的長寬值。

20、使用原生js實現ajax

創建一個 XMLHttpRequest 對象。如果不支持創建該對象的瀏覽器,則需要創建 ActiveXObject,具體方法如下:

var xmlHttpRequest;
function createXmlHttpRequest(){
  if(window.XMLHttpRequest)//非IE
    xmlHttpRequest = new XMLHttpRequest();
  else if(window.ActiveObject)//IE6+
    xmlHttpRequest = new ActiveObject("Msxml2.XMLHTTP");
  else//IE6-
    xmlHttpRequest = new ActiveObject("Microsoft.XMLHTTP");
}

提交請求的方法:

open(method,url);//分別為提交的方法(GET或者POST)和提交的url
send(content);
onreadystatechange(){
  if(xmlHttpRequest.readyState == 4){
    if(xmlHttpRequest.state == 200){
      //請求成功
    }  
  }else{
    //請求失敗
  }
}

21、前端安全方面有沒有了解?XSS和CSRF如何攻防?

XSS(Cross Site Scripting)是跨站腳本攻擊,為了區分CSS,所以縮寫為XSS。惡意攻擊者往Web頁面里插入惡意Script代碼,當用戶瀏覽該頁之時,嵌入其中Web里面的Script代碼會被執行,從而達到惡意攻擊用戶的目的。

在網頁的一些公共區域(例如,建議提交表單或消息公共板的輸入表單)輸入一些文本,這些文本被其它用戶看到,但這些文本不僅僅是他們要輸入的文本,同時還包括一些可以在客戶端執行的腳本。如:

"/> <script>alert(document.cookie);</script><!--

在文本框中輸入以上代碼,然后點擊提交,就會把用戶的cookie彈出來。

XSS漏洞修復

1.將重要的cookies標記為HTTP ONLY。

2.只允許用戶輸入我們期望的數據。如年齡框只能輸入數字。

3.對數據進行HTTP Encode處理。

4.過濾或者移除特殊的HTML標簽。

5.過濾JS事件的標簽。

CSRF(Cross-site request forgery)是跨站請求偽造。XSS利用站點內的信任用戶,而CSRF則通過偽裝來自受信任用戶的請求來利用受信任的網站。其實就是攻擊者盜用了你的身份,以你的名義發送惡意請求。

CSRF攻擊的思想

用戶瀏覽并登陸信任網站A;通過驗證,在用戶處產生X的cookie;用戶在沒有登出X的時候,瀏覽危險網站B;B要求訪問第三方網站A,發出一個請求;根據這個請求,瀏覽器使用剛才產生的cookie直接訪問A。

一個簡單的實例

銀行網站A,它以GET請求來完成銀行轉賬的操作,如: http://www.mybank.com/Transfer.php?toBankId=11&money=1000

危險網站B,它里面有一段HTML的代碼如下:

<img src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>

首先,你登錄了銀行網站A,然后訪問危險網站B,噢,這時你會發現你的銀行賬戶少了1000塊......

CSRF的防御

1.在表單里增加Hash值,以認證這確實是用戶發送的請求,然后在服務器端進行Hash值驗證。

2.驗證碼:每次的用戶提交都需要用戶在表單中填寫一個圖片上的隨機字符串。

20、是否了解什么前沿的技術、或者你自己有什么技術特長、在哪方便有優勢?

持續更新中。。。

 

來自:http://www.jianshu.com/p/0e9a0d460f64

 

 本文由用戶 MarBirchell 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!