我給出的一份前端面試題


因為公司招人的關系,需要我出一份Web前端開發的面試題,現在招聘工作結束了,把題目記錄在這里,供大家參考。

 

第一部分 考察項目經歷

這一部分的套路就是給出一個topic,讓面試者給出較為詳細的說明,進而問一些更為深入的問題,達到考察的目的。

1 自我介紹。

2 介紹一個印象最深的項目,使用何種技術,解決何種問題?

3 迄今為止遇到的最大的一個技術挑戰?是如何解決的?

 

第二部分 定點考察知識點 

 

計算機基礎

這一部分主要考察對計算機基礎知識的掌握。根據我面試的經驗,如果你所在的是一家逼格不是特別高的創業公司的話,那么來面你這個web前端職位的人,大部分會是非計算機專業轉過來的,所以這部分他們大概率會掌握的不是很好。。所以沒有必要考察太深。

1 簡述線程與進程的區別?

進程由線程組成,線程是CPU調度的基本單元。

 

2請從插入刪除與查詢的效率角度,對鏈表與數組進行比較。

鏈表插入刪除的效率高,為常量時間復雜度O(1),但查詢效率低,為線性時間復雜度O(n);

數組查詢效率高,為常量時間復雜度O(1),但插入刪除效率低,為線性時間復雜度O(n)

             

3 簡述棧和隊列的區別?

棧是先入后出,隊列是先入先出。

 

HTML 

基礎

div, span, a, strong, form, em, label, p, h1, input, ol, ul ,select, textarea, img, table

上述中哪些是inline tags(默認)?  span, a(link), strong(加粗), em, label, input(輸入框), select, textarea, img

上述中哪些是block tags(默認)?  div, form, p(段落), h1, ol, ul , table

 

塊元素與內聯元素的區別?

塊元素一般都從新行開始,它可以容納內聯元素和其他塊元素,常見塊元素是段落標簽'P". 如果沒有css的作用,塊元素會順序以每次另起一行的方式一直往下排。而有了css以后,我們可以改變這種html的默認布局模式,把塊元素擺放到你想要 的位置上去。而不是每次都愚蠢的另起一行。

內聯元素(inline element)一般都是基於語義級(semantic)的基本元素。內聯元素只能容納文本或者其他內聯元素,常見內聯元素 “a”。 

inline-block的元素特點:將對象呈遞為內聯對象,但是對象的內容作為塊對象呈遞。旁邊的內聯對象會被呈遞在同一行內,允許空格。(准確地說,應用此特性的元素呈現為內聯對象,周圍元素保持在同一行,但可以設置寬度和高度地塊元素的屬性)

 

<b> <strong>的區別?

strong是web標准中xhtml的標簽,strong的意思是“強調”;b是html的,b的意思是bold(粗體)。為什么用strong代替b?其實這個問題不妨改問:xhtml和html有什么不同,為什么要用xhtml代替html?

簡單地說:web標准主張xhtml不涉及具體的表現形式,“強調”可以用加粗來強調,也可以用其它方式來強調,比如下划線,比如字體加大,比如紅色,等等,可以通過css來改變strong的具體表現,這就是為什么b要改為strong

strong代表其中內容文字的意義。b代表其中文字的樣式是粗體。 在html規范中二者的區別基本上看不出來。在xhtml中由於強調“樣式與內容的分離”所以代表樣式的b被掏汰了。取而代之的是其它標簽。注意,不是strong代替了b。strong代表強調,你可以自定義任何樣式來代表強調。只是strong的默認樣式與b相同而已。

Html的發展歷史是:Html4 xhtml html5。

 

H5的新特性有哪些?

用於繪畫的 canvas 元素 Websocket, <video> <audio>  <header> <footer> 正則表達式

 HTML5添加了許多新新的語法特征,其中包括<video>、<audio>和<canvas>元素,同時集成了SVG內容。

 

寫html代碼題

1 按照下面的樣子布局:

 

2  如何使用原生的create/add/remove/move/copy/search DOM中的元素?(寫出代碼)

1 var para=document.createElement("p");  // 創建
2 var element=document.getElementById("div1"); // 查找
3 getElementByTagName 
4 getElementByName
5 element.appendChild(para); //追加 add
6 parent.removeChild(child); //刪除

 

如何選取特定的HTML元素:

1 element = document.getElementById(id);

 

Document 對象:每個載入瀏覽器的 HTML 文檔都會成為 Document 對象。Document 對象使我們可以從腳本中對 HTML 頁面中的所有元素進行訪問。

提示:Document 對象是 Window 對象的一部分,可通過 window.document 屬性對其進行訪問。

HTML DOM 定義了多種查找元素的方法,除了 getElementById() 之外,還有 getElementsByName() 和 getElementsByTagName()和Document.getElementByClassName();。不過,如果您需要查找文檔中的一個特定的元素,最有效的方法是 getElementById()。

 

如需替換 HTML DOM 中的元素,請使用 replaceChild() 方法。

cloneNode(deepBoolean)
復制並返回當前節點的復制節點,復制節點是一個孤立節點,它復制了原節點的屬性,在把這個新節點加入到document前,根據需要修改ID屬性確保其ID的唯一。

Move:

1 var divs = document.getElementsByTagName("div");   // order: first, second, third
2 divs[0].parentNode.appendChild(divs[0]);           // order: second, third, first
3 divs[1].parentNode.insertBefore(divs[0], divs[1]); // order: third, second, third

 

 
        

appendChild() 方法:可向節點的子節點列表的末尾添加新的子節點。語法:appendChild(newchild)

insertBefore() 方法:可在已有的子節點前插入一個新的子節點。語法 :insertBefore(newchild,refchild)

相同之處:插入子節點

 

什么是DOM,DOM使用了什么數據結構?

HTML DOM 定義了訪問和操作獲取、修改、添加或刪除 HTML 元素的標准方法。DOM 將 HTML 文檔表達為樹結構。

可通過 JavaScript (以及其他編程語言)對 HTML DOM 進行訪問。

 

  

CSS

1 如何理解CSS中的盒子模型? Margin和Padding的區別是什么?

邊框border 內邊距 外邊距。

Margin是外邊距,padding是內邊距。

 

 

http://www.w3school.com.cn/css/css_boxmodel.asp

 

2 如何驗證(validate)一個 HTML文件和CSS文件?

一般sublime這樣的編輯器,都會對html和css文件進行語法驗證。

http://validator.w3.org/

http://jigsaw.w3.org/css-validator/

 

3 解釋在這個CSS 選擇器(selector)中發生了什么:

[role=navigation] > ul a:not([href^=mailto]) {
}

定義了role屬性,並且值為navigation的任何元素,其子元素列表下的除郵箱鏈接之外的所有鏈接元素。

 

在 CSS 中,選擇器是一種模式,用於選擇需要添加樣式的元素。上述css 選擇器主要使用了下面的三種模式:

[attribute=value]

[target=_blank]

選擇 target="_blank" 的所有元素

 

element>element

div>p

選擇父元素為 <div> 元素的所有 <p> 元素。

 

:not(selector)

:not(p)

選擇非 <p> 元素的每個元素。

 

 

什么是LESS? <LESS>(選做)

Less 擴充了 CSS 語言,增加了諸如變量、混合(mixin)、運算、函數等。 Less 既可以運行在服務器端(Node.js 和 Rhino 平台)也可以運行在客戶端(瀏覽器)。Sass、LESS和Stylus是CSS預處理器。他是CSS上的一種抽象層。他們是一種特殊的語法/語言編譯成CSS。

 

JavaScript

基礎

如何理解JS是單線程這一說法?為什么不會卡住?
Javascript除了一個主線程外,還配有一個代碼隊列,這個隊列用以存放定時器、HTTP請求、事件響應的回調。

 

什么是瀏覽器事件模型?請描述js的事件冒泡和捕獲(event bubble and capturing), 如何停止冒泡(bubble)?

 

瀏覽器事件模型與js事件模型是同一個概念。

假設你在一個元素中又嵌套了另一個元素

-----------------------------------
| element1                        |
|   -------------------------     |
|   |element2               |     |
|   -------------------------     |
|                                 |
-----------------------------------

:並且兩者都有一個onClick事件處理函數(event handler)。如果用戶單擊元素2,則元素1和元素2的單擊事件都會被觸發。但是哪一個事件先被觸發?哪一個事件處理函數會被首先執行?換句話說,事件的發生順序到底如何?

  兩種模型

  不出所料,在那些“不堪回首”(瀏覽器大戰)的日子里,Netscape和微軟有兩種截然不同的處理方法:

  • Netscape主張元素1的事件首先發生,這種事件發生順序被稱為捕獲型
  • 微軟則保持元素2具有優先權,這種事件順序被稱為冒泡型

 

W3c明智的在這場爭斗中選擇了一個擇中的方案。任何發生在w3c事件模型中的事件,首是進入捕獲階段,直到達到目標元素,再進入冒泡階段

                 | |  / \
-----------------| |--| |-----------------
 
| element1       | |  | |                |
|   -------------| |--| |-----------     |
|   |element2    \ /  | |          |     |
|   --------------------------------     |
|        W3C event model                 |
------------------------------------------

  為一個web開發者,你可以選擇是在捕獲階段還是冒泡階段綁定事件處理函數,這是通過addEventListener()方法實現的,如果這個函數的最后一個參數是true,則在捕獲階段綁定函數,反之false,在冒泡階段綁定函數

(如何選擇在哪個階段綁定事件處理函數?)

 

如何取消冒泡?

在微軟的模型中,你必須設置事件的cancelBubble的屬性為true:

1 window.event.cancelBubble = true

 

在w3c模型中你必須調用事件的stopPropagation()方法:

1 e.stopPropagation()

 

這會阻止所有冒泡向外傳播。

 

 js中我們為什么需要event delegation簡要描述一下事件委托?

如今的JavaScript技術界里最火熱的一項技術應該是‘事件委托(event delegation)’了。使用事件委托技術能讓你避免對特定的每個節點添加事件監聽器;相反,事件監聽器是被添加到它們的父元素上。事件監聽器會分析從子元素冒泡上來的事件,找到是哪個子元素的事件。 也就是說把監聽子元素上的事件監聽函數放在它的父元素上來。

 

 

Ajax

Ajax的全稱?原理?優點?

全稱:Asynchronous  js and xml

原理:Ajax的原理簡單來說通過XmlHttpRequest對象來向服務器發異步請求,從服務器獲得數據,然后用javascript來操作DOM而更新頁面。

把服務器端看成一個數據接口(只負責吐數據),它返回的是一個純文本流,當然,這個文本流可以是XML格式,可以是Html,可以是Javascript代碼,也可以只是一個字符串。這時候,XMLHttpRequest向服務器端請求這個頁面,服務器端將文本的結果寫入頁面,這和普通的web開發流程是一樣的,不同的是,客戶端在異步獲取這個結果后,不是直接顯示在頁面,而是先由javascript來處理,然后再顯示在頁面。

優點: 局部刷新,避免重新刷新整個頁面。

 

什么是XMLHTTPRequest對象?

XMLHttpRequest是ajax的核心機制,是JavaScript的一個內置對象。它是在IE5中首先引入的,是一種支持異步請求的技術。簡單的說,也就是javascript可以及時向服務器提出請求和處理響應,而不阻塞用戶。達到無刷新的效果。

 

1 if (window.XMLHttpRequest)
2   {// code for all new browsers
3   xmlhttp=new XMLHttpRequest(); 4 }

 

 

Js讀代碼題

多項選擇題:下列哪一項會返回‘true’?

  1. null == undefined
  2. Boolean( “true” )
  3. Boolean( 0 )
  4. isNaN( 10 )
  5. isNaN( “10” )
  6. NaN === NaN

 

AB.

A 擴展問題:null == undefined如果是null === undefined,那是真是假? Nullundefined的區別是什么?

undefined 表示一個變量聲明但未賦值:

1  var TestVar;
2  alert(TestVar); //shows undefined
3  alert(typeof TestVar); //shows undefined

 

undefined is a type itself (undefined) while null 是一個對象。

總所周知:null == undefined

但是:null !== undefined

null這是一個對象,但是為空。因為是對象,所以 typeof null  返回 'object' 。

同樣,當我們定義一個變量但未賦予其初始值,例如:

    var aValue;

這時,JavaScript在所謂的預編譯時會將其初始值設置為對window.undefined屬性的引用,

 

Undefined Null 區別?  

typeof 返回的是字符串,有六種可能:"number"、"string"、"boolean"、"object"、"function"、"undefined"

ECMAScript 有 5 種原始類型(primitive type),即 Number 、 String、Boolean、Undefined、Null。

 

Number 對象是原始數值的包裝對象。

創建 Number 對象的語法:

1 var myNum=new Number(value);
2 var myNum=Number(value);

 

 

1 <script type=text/javascript>
2 var a = 123;
3 alert(typeof(a)); 4 </script>

 

typeof 一個函數的返回值是function,如果把這個function賦給一個var,則typeof的返回值是object。

 

==和===的區別是什么?

javaScript has two sets of equality operators: === and !==, and their evil twins == and !=. The good ones work the way you would expect.

如果兩個操作數有相同的類型,並具有相同的值 then === produces true and !== produces false.

The evil twins do the right thing when the operands are of the same type, but if they are of different types, they attempt to coerce the values. the rules by which they do that are complicated and unmemorable. 

==和!=在兩個操作數類型相同的時候,會根據值是否相等來判斷。 如果類型不相同,那就邪惡了。。

 

C: 對於不等於1的整數,為false;

DEF:A NaN按照定義永遠不等於它自己。. 在任何語言中都是這樣。. 在js中NaN是為一個一個不等於它自身的東東。

 

之所以Nan不等於它本身,是為了實現bool IsNaN(number) 函數:

1 function isNaN(x)
2 { 
3     return x != x; 
4 }

 

 

3 讀代碼,並寫出代碼的執行結果:

1 var t = true;
2 window.setTimeout(function (){
3     t = false;
4 },1000);
5 while (t){}
6 alert('end');

 

Output: 沒有輸出,死循環。

分析:

確實是死循環導致setTimeout不執行,也導致alert不執行。
js是單線程是對的,所以會先執行while(t){}再alert,但這個循環體是死循環,所以永遠不會執行alert。
至於說為什么不執行setTimeout,是因為js的工作機制是:當線程中沒有執行任何同步代碼的前提下才會執行異步代碼,setTimeout是異步代碼,所以setTimeout只能等js空閑才會執行,但死循環是永遠不會空閑的,所以setTimeout也永遠不會執行。

 

深入理解js單線程:

JavaScript引擎是單線程運行的,瀏覽器無論在什么時候都只且只有一個線程在運行JavaScript程序。

一、瀏覽器的內核是多線程的,它們在內核制控下相互配合以保持同步,一個瀏覽器至少實現三個常駐線程:javascript引擎線程,GUI渲染線程,瀏覽器事件觸發線程。

1. javascript引擎是基於事件驅動單線程執行的,JS引擎一直等待着任務隊列中任務的到來,然后加以處理,瀏覽器無論什么時候都只有一個JS線程在運行JS程序。

2. GUI渲染線程負責渲染瀏覽器界面,當界面需要重繪(Repaint)或由於某種操作引發回流(reflow)時,該線程就會執行。但需要注意 GUI渲染線程與JS引擎是互斥的,當JS引擎執行時GUI線程會被掛起,GUI更新會被保存在一個隊列中等到JS引擎空閑時立即被執行。

3. 事件觸發線程,當一個事件被觸發時該線程會把事件添加到待處理隊列的隊尾,等待JS引擎的處理。這些事件可來自JavaScript引擎當前執行的代碼塊如setTimeOut、也可來自瀏覽器內核的其他線程如鼠標點擊、AJAX異步請求等,但由於JS的單線程關系所有這些事件都得排隊等待JS引擎處理。(當線程中沒有執行任何同步代碼的前提下才會執行異步代碼)

 

       什么是遞歸? (遞歸是一個通用的概念。不僅限於js)

       什么是閉包?   

   在js中,如果你在一個function中使用了另外一個function關鍵字,你就創建了一個閉包。 

1 function say667() {
2     // Local variable that ends up within closure
3     var num = 42; 4 var say = function() { console.log(num); } 5 num++; 6 return say; 7 } 8 var sayNumber = say667(); 9 sayNumber(); // logs 43

 閉包(上述代碼中的匿名函數)中,保存的是outter函數的local變量的一個引用。

Output:43

分析: 閉包。1.函數嵌套函數2.函數內部可以訪問到外部的變量或者對象3.避免了垃圾回收。

 

 

 

js在處理對象時,永遠使用引用reference。 比如說,你使用foo調用了一個對象,那么返回的閉包將引用那個原始的對象。 

 

 1 function foo(x) {
 2   var tmp = 3; 3 4 return function (y) { 5 console.log(x + y + tmp); 6 x.memb = x.memb ? x.memb + 1 : 1; 7  console.log(x.memb); 8  } 9 } 10 11 var age = new Number(2); 12 var bar = foo(age); // bar is now a closure referencing age. 13 bar(10);

 

 

As expected, each call to bar(10) will increment x.memb. What might not be expected, is that xis simply referring to the same object as the age variable! After a couple of calls to barage.memb will be 2! This referencing is the basis for memory leaks with HTML objects.

 

http://stackoverflow.com/questions/111102/how-do-javascript-closures-work      

 

 

1 <script>
2   function sayAlice() {
3      var say = function() { alert(alice); }
4      var alice = 'Hello Alice';
5      return say;
6   }
7   sayAlice()();
8 </script>

 OutputHello Alice

分析:如果把sayAlice()();改為sayAlice()會怎么樣?

 

 1 <script>
 2   function foo(x) {
 3     var tmp = 3;
 4     return function (y) {
 5       alert(x + y + (++tmp));
 6     }
 7   }
 8   var bar = foo(2);
 9   bar(10);
10 </script>

 Output:16

分析:閉包。

 

1 <script>
2   var a = 10;
3   function test() {
4     alert(a); 
5     alert(b); 
6   }
7   var b = 6;
8   test();
9 </script>

 Output10 6

分析:跟viriable hoisting 什么區別?這也是一個閉包嗎?

 When a JavaScript function is invoked, a new execution context is created. Together with the function arguments and the parent object, this execution context also receives all the variables declared outside of it (in the above example, both 'a' and 'b').

上述代碼,如果使用c語言實現,會輸出什么結果??

上述代碼,如果使用Java實現,

 

 1 <script>
 2   function foo(x) {
 3     var tmp = 3;
 4     return function (y) {
 5       alert(x + y + tmp);
 6       x.memb = x.memb ? x.memb + 1 : 1;
 7       alert(x.memb);
 8     }
 9   }
10   var age = new Number(2);
11   var bar = foo(age); // bar is now a closure referencing age.
12   bar(10);
13 </script>

 Output: 15 1

 

 

1 <script>
2     var foo = {}; 
3      foo.bar = 'hello'; 
4      alert(foo.length);
5 </script>

  Output:undefined

 

 
1 <script> 
2    function hi(){
3    var a;
4    alert(a);
5   }
6   hi();
7 </script>

 Output:undefined

問題: 與不使用hi 函數什么區別? 也形成了閉包,但是a不是在Outter space定義的。

 

1 function addTen(num) {
2     num += 10;
3     return num;
4 }
5 
6 var count = 20;
7 var result = addTen(count);
8 alert(count); 
9 alert(result);

 output : 20 30 考察js的參數傳遞

js與java類似,本質上都是值傳遞,但是引用是地址,值傳遞時拷貝了引用值的副本,但兩個引用指向的還是同一個內存地址。

 

1 function setName(obj) {
2     obj.name = "Nicholas";
3     obj = new Object();
4     obj.name = "Greg";
5 }
6 var person = new Object();
7 setName(person);
8 alert(person.name)

 output:Nicholas

分析: 主要考察引用傳遞。

JavaScript 是面向對象的語言,但 JavaScript 不使用類。

在 JavaScript 中,不會創建類,也不會通過類來創建對象(就像在其他面向對象的語言中那樣)。

 

 
1 var city = "Rome"+function() {
2     console.log(city);
3     var city = "Paris";
4 }();

 output undefined

分析:為什么?

(variable hoisting) 在Js中,變量被移動到腳本的頂部,然后執行。但是這種說法並不准確。在下面的代碼中:

1 console.log(a);
2 var a = 'Hello World!';

 

會輸出 undefined, 並不是 'Hello World', 所以上述代碼等效於下面的代碼:

1 var a;
2 console.log(a);
3 a = 'Hello World!';

 

而不是下面的代碼:

1 var a = 'Hello World!';
2 console.log(a);

 

實際上,js並沒有移動任何代碼,你需要理解js的執行上下文(context):  context分為兩個階段:創建階段和執行階段。 在創建階段,為這些變量和函數創建內存空間,人們往往把這個階段與variable hoisting混淆起來。 對於變量的賦值,是在執行上下文的執行階段進行的。當你對變量a賦值“Hello World”的時候,js引擎只有在執行階段才知道a的值,在創建階段,js只是把一個undefined的占位符放在那里,所以所有的變量都是被初始化為undefined的。 所以建議永遠把變量聲明和函數放在你的代碼的頂部。

 

 1 var name = "The Window";
 2 var object = {
 3     name: "My Object",
 4     getNameFunc: function () {
 5         return function () {
 6             return this.name;
 7         };
 8     }
 9 };
10 alert(object.getNameFunc()());  

 output: The Window

分析: 閉包?

 

 1 var name = "The Window";
 2 var object = {
 3     name: "My Object",
 4     getNameFunc: function () {
 5         var that = this;
 6         return function () {
 7             return that.name;
 8         };
 9     }
10 };
11 alert(object.getNameFunc()());

 output: My Object

分析:this指的是調用函數的那個對象
 

當點擊button#2的時候,console中會打印什么?

1 var nodes = document.getElementsByTagName('button');
2 // assume there is totally 5 nodes
3 for (var i = 0; i < nodes.length; i++) {
4     nodes[i].addEventListener('click', function() {
5         console.log('You clicked element #' + i);
6     });
7 }

 Output: you clicked element #5

分析: 閉包?

 
        
1 element.addEventListener('click', function() { /* do stuff here*/ }, false);

 

最后一個參數決定這個linstener如何響應bubbling事件。

 

<input id="File1" type="file" name="up1"/>
<input id="File2" type="file" name="up1" />
<input id="File3" type="file" name="up2" />

 
選做:
 1 function Mammal(name) {
 2     this.name = name;
 3     this.offspring = [];
 4 }
 5 Mammal.prototype.haveABaby = function () {
 6     var newBaby = new Mammal("Baby " + this.name);
 7     this.offspring.push(newBaby);
 8     return newBaby;
 9 }
10 
11 Mammal.prototype.toString = function () {
12     return '[Mammal "' + this.name + '"]';
13 };     // 到目前為止,這  是一個Mammal對象的實現。
14 
15  
16 
17 // 將Employee的原型指向Person的一個實例
18 
19 // 因為Person的實例可以調用Person原型中的方法, 所以Employee的實例也可以調用Person原型中的所有屬性。
20 Cat.prototype = new Mammal();
21 
22 //修正constructor
23 Cat.prototype.constructor = Cat;
24 function Cat(name) {
25     this.name = name;
26 }
27 
28 Cat.prototype.toString = function () {
29     return '[Cat "' + this.name + '"]';
30 }  // 到目前為止,這是Mammal的一個子類Cat。
31 
32 
33 var someAnimal = new Mammal('Mr. Biggles');
34 var myPet = new Cat('Felix');
35 alert(someAnimal);   
36 alert(myPet);        
37 
38 myPet.haveABaby();
39 alert(myPet.offspring.length);      
40 alert(myPet.offspring[0]);           

 Output: 

[Mammal “Mr. Biggles”]
[Cat, “Felix”]
1

[Mammal “Baby Felix”]

進一步問題:什么是prototype?什么是原型鏈?

 

1 console.log("New york");
2 setTimeout(function () {
3     console.log("Vienne");
4 }, 1000);
5 setTimeout(function () {
6     console.log("London");
7 });
8 console.log("Ottawa");

 Output:  New York, Ottawa,Landon,Vienne。

分析:setTimeout異步函數。

 

js寫代碼題

1 嘗試實現下面的需求:

(1)      測試array numbers中是不是每一個元素都比2大

E.G.

1 var numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1];
2 var everyResult = numbers.every(function (item, index, array) {
3     return (item > 2);
4 });
5 alert(everyResult); //false

 

分析:對數組中的每個元素都執行一次指定的函數(callback),直到此函數返回 false,如果發現這個元素,every 將返回 false,如果回調函數對每個元素執行后都返回 true every 將返回 true

 

(2)      得到新的array,其中的元素是numbers中所有比2大的元素。

var numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1];

 

 1 <script>
 2   var numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1];
 3   var numbersLargerThan2 = [];
 4   for(i in numbers){ // i has some problems here.
 5      if(numbers[i]>2) {
 6        numbersLargerThan2.push(numbers[i]);
 7      }
 8   }
 9   for(i in numbersLargerThan2) {
10     alert(numbersLargerThan2[i]);
11   }
12   // push pop
13 </script>

 

 (3)      一個新的array,其中的每一個元素都比numbers中的元素大1

var numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1];

 

 1 //一個新的array,其中的每一個元素都比numbers中的元素大1
 2 <script>
 3   var numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1];
 4   var numbersAfterAdd1 = [];
 5   for(i in numbers) {
 6      numbersAfterAdd1.push(numbers[i]+1);
 7   }
 8 
 9   for(i in numbersAfterAdd1) {
10      alert(numbersAfterAdd1[i]);
11   }
12 </script>

 

2列出js中創建對象的方法,並寫出一個js中的繼承關系的實現。

應該知道4種常見創建對象的方法:

1 用{}  , 對象字面量。

 

 先創建再添加:

1 //創建一個簡單對象字面量
2 var person = {};   
3 // 加入屬性和方法
4 person.name = 'ifcode';
5 person.setName = function(theName) {
6    person.name = theName;
7 }

 

 

2  JS good parts中推薦這種寫法:

1 var person = {
2     name: 'ifcode', 3     setName: function(theName) {
4         this.name = theName;
5     }
6 }

 

 

 1 var clock={
 2    hour:12,  3    minute:10,
 4    second:10,
 5    showTime:function(){
 6       alert(this.hour+":"+this.minute+":"+this.second);
 7    }
 8 }
 9 clock.showTime();//調用
10 //var m = new myObj(); //不支持

 

 上述兩種方式只存在於一個實例的對象,也就是單例模式。

 

 下面是可以創建多個實例的方式:

  

3 構造函數一般都符合factory pattern,根據默認的規則,構造函數應當首字母大寫

1 Person = function(defaultName) {
2     this.name = defaultName;
3     this.setName = function(theName) {
4         this.name = theName;
5     }
6 }
7 person = new Person('ifcode');  // new是調用構造函數

 

利用構造函數就可以方便地創建多個對象實例了。

 

4 利用 prototype的構造函數:

1 Person = function(defaultName) {
2     this.name = defaultName;
3 }
4  
5 
6 Person.prototype.setName = function(theName) {
7     this.name = theName;
8 }

 

所有創建在prototype上得屬性和方法,都將被所有對象實例分享。

 一般在創建單例的時候,用2 在創建多個對象的時候,使用4.

 

----------------------------------

2.創建Object實例

1  var clock = new Object();
2  clock.hour=12;
3  clock.minute=10;
4  clock.showHour=function(){alert(clock.hour);};
5 
6  clock.showHour();//調用

 

由此可見 屬性是可以動態添加,修改的

 

3 function 關鍵字模擬 class

上述兩種。。。

http://www.cnblogs.com/lucas/archive/2009/03/17/1411656.html

http://www.jianshu.com/p/f9a1203e33d0

 

js中繼承關系的實現:

JavaScript中要實現繼承,其實就是實現三層含義:
1、子類的實例可以共享父類的方法;
2、子類可以覆蓋父類的方法或者擴展新的方法;
3、子類和父類都是子類實例的“類型”。

 

 

什么是prototype? 原型

什么是原型鏈?

JavaScript 是基於原型的語言。當我們調用一個對象的屬性時,如果對象沒有該屬性,JavaScript 解釋器就會從對象的原型對象上去找該屬性,如果原型上也沒有該屬性,那就去找原型的原型。這種屬性查找的方式被稱為原型鏈(prototype chain)。

 

ES6 並沒有改變 JavaScript 基於原型的本質,只是在此之上提供了一些語法糖。class 就是其中之一。其他的還有 extendssuper 和 static 。它們大多數都可以轉換成等價的 ES5 語法。

       javascript是面向對象的,怎么體現javascript的繼承關系?使用prototype來實現。

       ES6中啟用了class關鍵字,如何使用該關鍵字實現繼承關系?

 1 // ES6 中啟用了關鍵字 class
 2 class Person {
 3 constructor(name, gender, age) { 4 this.name = name; 5 this.gender = gender; 6 this.age = age; 7 } 8 tellAge() { 9 console.log(this.age); 10 } 11 } 12 13 var puya = new Person('PuYart', 'male', '21'); 14 puya.tellAge();

 

CLASS繼承      

 1 /*
 2 *class:ES6及ES6以上才有該方法。
 3 *class的出現將原型繼承簡化了很多,class的目的就是讓定義類更簡單。
 4 *extends來繼承對象,中間的原型之類的就可以免去,就可以繼承擴展class
 5 */
 6 //用class創建對象
 7 class Leader{
 8     constructor(name){//constructor構造函數
 9         this.name=name; 10 } 11 hello(){//定義在原型上的函數 12 alert('Hello, '+this.name+'!'); 13 } 14 } 15 var liyi= new Leader('liyi'); 16 liyi.name;//輸出'liyi' 17 liyi.hello();//輸出'Hello, liyi!' 18 //用extends繼承擴展 19 class extendLeader extends Leader{ 20 constructor(name,grade,skill){//若是不擴展Leader的構造函數,就可以將constructor這一步省去 21 super(name); 22 this.grade=grade; 23      this.skill=skill; 24   } 25   run(){ 26     console.log(this.name+'職位:'+this.grade+' 技能:'+this.skill); 27   } 28 } 29 var liyi=new extendLeader('liyi','研發經理','精通各種技術'); 30 liyi.name;//'liyi' 31 liyi.grade;//'研發經理' 32 liyi.skill;//'精通各種技術' 33 liyi.hello;//'Hello, liyi!' 34 liyi.run();//'liyi職位:研發經理 技能:精通各種技術'

 

 

Two awesome javascript inheritance libraries that come to mind are klass and selfish.js (I've used both, they're amazing.)

 http://www.cnblogs.com/sanshi/archive/2009/07/08/1519036.html

 

知不知道ES6 中的classextends關鍵字,如何使用上述關鍵字實現一個繼承關系。

 1 function Person(name) {
 2   this.name = name;
 3 }
 4 
 5 Person.prototype = {
 6   getName: function() {
 7     return this.name;
 8   }
 9 }
10 
11 function Employee(name, employeeID) {
12   this.name = name;
13   this.employeeID = employeeID;
14 }
15 
16 // 這是不好的。
17 Employee.prototype = new Person();
18 Employee.prototype.getEmployeeID = function() {
19   return this.employeeID;
20 };
21 
22 var zhang = new Employee("ZhangSan", "1234");
23 console.log(zhang.getName()); // "ZhangSan" 

 

  

 1 function Employee(name, employeeID) {
 2   this.name = name;
 3   this.employeeID = employeeID;
 4 }
 5 // 創建Employee時實例化Person是不合適的
 6 Employee.prototype = new Person();
 7 Employee.prototype.constructor = Employee;
 8 Employee.prototype.getEmployeeID = function() {\
 9     return this.employeeID;
10 };
11 
12 var zhang = new Employee("ZhangSan", "1234");
13 console.log(zhang.constructor === Employee); // true
14 console.log(zhang.constructor === Object); // false

 

 提供一個原型方法(比如init)來初始化數據。

 1 // 空的構造函數
 2 function Person() {
 3 }
 4 
 5 Person.prototype = {
 6   init: function(name) {
 7     this.name = name;
 8   },
 9 
10   getName: function() {
11     return this.name;
12   }
13 }
14 
15 // 空的構造函數
16 function Employee() {
17 }
18 
19 // 創建類的階段不會初始化父類的數據,因為Person是一個空的構造函數
20 Employee.prototype = new Person();
21 Employee.prototype.constructor = Employee;
22 Employee.prototype.init = function(name, employeeID) {
23   this.name = name;
24   this.employeeID = employeeID;
25 };
26 
27 Employee.prototype.getEmployeeID = function() {
28   return this.employeeID;
29 };

 

這種方式下,必須在實例化一個對象后手工調用init函數,如下:

1 var zhang = new Employee();
2 zhang.init("ZhangSan", "1234");
3 console.log(zhang.getName()); // "ZhangSan"

 

必須達到兩個效果,構造類時不要調用init函數和實例化對象時自動調用init函數。看來我們需要在調用空的構造函數時有一個狀態標示。

 

可以用 call 來實現繼承: 

 1 function Class1() { 
 2     this.showTxt = function(txt) { 
 3         alert(txt); 
 4     } 
 5 } 
 6 function Class2() { 
 7     Class1.call(this); 
 8 } 
 9 var c2 = new Class2(); 
10 c2.showTxt("cc"); 

 

這樣 Class2 就繼承Class1了,Class1.call(this) 的 意思就是使用 Class1 對象代替this對象,那么 Class2 中不就有Class1 的所有屬性和方法了嗎,c2 對象就能夠直接調用Class1 的方法以及屬性了,執行結果就是:alert(“cc”); 

 

Framework

變化太快。

JQuery作為基礎。

1 如何使用JQuery選取一個ID為myDivId的元素?如何選取一組class為myCssClass的元素?寫出代碼。

1 $( "#myDivId" );
2 $( ".myDivId" );

 

 

3 簡述你使用過的前端框架,並介紹其優缺點?

JQuery/Query Mobile

Dojo/Dojo Mobile

zepto.js是一個專為mobile WebKit瀏覽器(如:Safari和Chrome), 語法借鑒並兼容JQuery。

Node.js

angularJS

bootstrap 是一套html css和js的框架。

React.js(React)是 Facebook 推出的一個用來構建用戶界面的 JavaScript 庫.

 

Slider 滑動條控件。(不算一個框架)

 

 

(選做)如果熟悉angularJS, 請選擇(1), 如果熟悉React, 請選擇(2):

(1)      描述angular中的數據綁定(data-binding),描述angular依賴注入(dependency injection)

在angular中,model和view組件之間的Data Binding是可以自動同步數據的。angular實現Data Binding的方法可以讓你確信在你的應用中model是single-source-of-truth,view僅僅是model的投影。當model改變時,view跟着改變,反之亦然。

angular的模板系統則不同,template是被瀏覽器去編譯的,編譯這步會產生一個live的view。對view進行的任何更改會立即反映到model中,對model進行的更改也會立即反映到view中。model是應用程序的single-source-of-truth,極大地簡化了開發人員的編程模型,你僅僅把view當成model的瞬間投影即可。

Angular JS框架與Spring類似,都實現了DI。

 

(2)      virtual DOM的優勢是什么?解釋FLUX中的數據流

來人們使用了 MVC、MVP 的架構模式,希望能從代碼組織方式來降低維護這種復雜應用程序的難度。但是 MVC 架構沒辦法減少你所維護的狀態,也沒有降低狀態更新你需要對頁面的更新操作(前端來說就是DOM操作),你需要操作的DOM還是需要操作,只是換了個地方。

相對於 DOM 對象,原生的 JavaScript 對象處理起來更快,而且更簡單。DOM 樹上的結構、屬性信息我們都可以很容易地用 JavaScript 對象表示出來。

既然狀態改變了要操作相應的DOM元素,為什么不做一個東西可以讓視圖和狀態進行綁定,狀態變更了視圖自動變更,就不用手動更新頁面了。這就是后來人們想出了 MVVM 模式。

 

React 標榜自己是 MVC 里面 V 的部分,那么 Flux 就相當於添加 M 和 C 的部分。

Flux 是 Facebook 使用的一套前端應用的架構模式。

一個 Flux 應用主要包含四個部分:

the dispatcher

處理動作分發,維護 Store 之間的依賴關系

the stores

數據和邏輯部分

the views

React 組件,這一層可以看作 controller-views,作為視圖同時響應用戶交互

the actions

提供給 dispatcher 傳遞數據給 store

 

Flux 的核心“單向數據流“怎么運作的:

Action -> Dispatcher -> Store -> View

更多時候 View 會通過用戶交互觸發 Action,所以一個簡單完整的數據流類似這樣:

 

 

(選做)什么是npm, 你可以如何使用它?

npm是Node.js 的包管理工具,用來安裝各種 Node.js 的擴展。

 

test/build等雜項

請描述Gitmergerebase的區別(選做)

git merge和git rebase從最終效果來看沒有任何區別,都是將不同分支的代碼融合在一起,但是生成的代碼樹就稍微有些不同。rebase操作不會生成新的節點,是將兩個分支融合成一個線性的提交。而merge操作生成的代碼樹會顯得比較亂。

 

 

什么是mock? (選做)

mock測試就是在測試過程中,對於某些不容易構造或者不容易獲取的對象,用一個虛擬的對象來創建以便測試的測試方法。

延伸問題:什么是冒煙測試(smoke test?

冒煙測試源自硬件行業,對一個硬件或者硬件組件改動后,直接給設備加電,看看設備會不會冒煙,沒冒煙,就表示待測組件是通過了測試。    在軟件開發過程中,一直有高內聚,低耦合這樣的說法,各個功能模塊之間的耦合還是存在的,因此一個功能的改動,還是會影響到其他功能模塊。    因此在開發人員修復了先前測試中發現的bug后,想知道這個bug的修復是否會影響到其他功能模塊,需要做的就是冒煙測試。

 

列出你知道的前端的build/test automation/unit test/的工具/框架,以及你知道的其他工具,並給出簡要描述。(選做

靜態代碼檢查工具JSLint。 JSHint跟JSLint非常像,都是Javascript代碼驗證工具

前端的測試框架很多,像QUnit、jasmine、mocha、jest、intern等

QUnit誕生之初是為了jquery的單元測試

 

Bower 包管理 包依賴

 

Yeoman 快速構建

 

Build工具:

Grunt能做什么:
1、合並,壓縮JS,CSS。
2、單元測試(Qunit)。
3、驗證(JSHint)。
4、初始化一個Project。

 

Build工具:

Gulp + Webpack


 

服務器端相關

HTTP

這一部分主要考察對網絡協議,主要是HTTP協議的理解。

 

HTTP請求共有幾種類型?給出你常用的類型,並結合你給出的類型描述HTTP請求的冪等性。

8 種類型: GET POST PUT DELETE OPTION HEAD等等。

列出常見的HTTP請求的返回狀態(Status Code),並簡述其含義?

 

如何解決HTTP的無狀態性所帶來的問題?(選做)

 

如何理解HTTP是無連接的? (選做)

TCP是有連接的,而HTTP是無連接的。無連接:服務器處理完客戶的請求,並收到客戶的應答后,即斷開連接。

 

什么是長連接?

 

HTTP響應碼 1 2 3 4 5 的各種含義

 

什么是RESTful風格?

 

常見HTTP報頭的含義:

Via

Keep-alive

 

是否熟悉抓包工具,平時都使用什么抓包工具? 比如Fiddler?

什么是Proxy? 什么是反向代理?

 

雜項

簡述什么是MVC ?(選做)

 

什么是websocket?什么是REST?什么樣的需求(使用場景)會需要websocket和REST?(選做)

 

  

其他問題:

 

期望薪資;

如何看待加班,婚育情況,住址,何時到崗;

是否有問題需要提問?

 

備選題

計算機基礎

快排的主要思想?時間復雜度? 如何避免最差的時間復雜度?(選做)

6二叉樹有哪些遍歷算法? 如何從遞歸算法構造非遞歸算法?使用什么輔助數據結構?(選做)

4 什么是平衡二叉樹?常見的平衡二叉樹有哪些?(選做)

 

HTML

如何選取特定的HTML元素?

 

Js

5 javascript的方法可以分為哪幾類?

類方法(靜態方法),對象方法(實例方法),原型方法

javascript的方法可以分為三類:

a 類方法

b 對象方法

c 原型方法

例子:

 

 1 function People(name)
 2 { 3 this.name=name; 4 //對象方法 5 this.Introduce=function(){ 6 alert("My name is "+this.name); 7  } 8 } 9 //類方法 10 People.Run=function(){ 11 alert("I can run"); 12 } 13 //原型方法 14 People.prototype.IntroduceChinese=function(){ 15 alert("我的名字是"+this.name); 16 } 17 18 19 20 //測試 21 22 var p1=new People("Windking"); 23 24 p1.Introduce(); 25 26 People.Run(); 27 28 p1.IntroduceChinese(); 

 

 1 什么是document對象?如何通過Window對象訪問document對象?

 

 

9 是否熟悉抓包工具,平時都使用什么抓包工具?

 

8 列出常見的HTTP報頭的字段,並簡述其含義?

 Keep-alive什么是長連接?

 

10 什么是Proxy? 什么是反向代理?

 

1      <script>
2         var foo = []; 
3         foo.push(1); 
4         foo.push(2); 
5         alert(foo.length);
6      </script> 

 

Output:2

 

               什么是平衡二叉樹?常見的平衡二叉樹有哪些?()AVL 紅黑。

算法:

快排的思想,時間復雜度? 如何避免最差的時間復雜度?

        二叉樹的遍歷算法? 如何從遞歸算法構造非遞歸算法,使用什么輔助數據結構?

 

 

5.  js中的3種彈出式消息提醒(警告窗口,確認窗口,信息輸入窗口)的命令是什么?
alert
confirm
prompt

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM