參加阿里巴巴前端實習生在線比試是15年三月底的事情,做的時候偷偷截圖了,現在有時間了拿出來分享給大家,並且附上自己的思路,如果有錯誤歡迎大家指出!
1.考慮以下程序輸出的結果:
var x='a'; function printX(){ console.log(x); var x='b'; console.log(x); } printX(); var y='c'; function printY(){ console.log(y); y='d'; console.log(y); } printY();
A a b c d B b b d d C undefined b undefined d D undefined b c d
在printX函數中,由於再次聲明了var x='b',x為函數內的局部變量,由於聲明提升,第一次打印時x的值為undefined。
2.請選擇結果為真的表達式:
A null instanceof Object B null==undefined C NaN==NaN D false==undefined
null是JavaScript基本類型Null的唯一值,它並非以Object為原型創建出來的,所以null insranceof Object返回的是false,但是需要注意typeof null返回的是“object”。
Table — typeof Operator Results
Type of val | Result |
---|---|
Undefined | "undefined" |
Null | "object" |
Boolean | "boolean" |
Number | "number" |
String | "string" |
Object (native and does not implement [[Call]]) | "object" |
Object (native or host and does implement [[Call]]) | "function" |
Object (host and does not implement [[Call]]) | Implementation-defined except may not be "undefined" , "boolean" , "number ", or "string". |
上表摘自ECMAScript-5規范,The typeof Operator。
ESMAScript中對相等操作有以下說明:
這里有上面規則的中文翻譯:詳解一下 javascript 中的比較。
對於選項B,直接跳入第2步返回true;對於選項C,由於typeof NaN返回“number”,依次進入 1-c-i 返回false;對於選項D,首先進入第6步,返回“0==undefined”,然后進入第10步,返回false。雖然Boolean(false)和Boolean(undefined)都為false,但是他們兩者並不相等。
3.下面代碼的執行結果是哪個?
function foo(a){ var a; return a; } function bar(a){ var a = 'bye'; return a; } [foo('hello'),bar('hello')]
A ["hello","hello"] B ["hello","bye"] C ["bye","bye"] D 都不是
在JavaScript的函數中,參數是由數組形勢傳遞的,但也可以顯式地使用命名參數,命名參數可以理解成此函數運行時的局部變量,變量的值為傳遞來的值,如果未傳遞,則值為undefined。
根據變量聲明提升的規則,題目中的foo("hello")和bar("hello")可以理解為:
function foo(){ var a; var a;//僅聲明,未賦值。不影響原值。 a = "hello"; return a; } function bar (){ var a; var a;//聲明提升 a = "hello"; a = "bye";//新值將原值覆蓋。 return a; }
這也是為什么在JavaScript中沒有函數重載的原因:
function a(){return 1;} function a(){return 2;} //等價於 var a = function(){return 1;} var a = function(){return 2;} //變量聲明提升 var a;var a; a = function(){return 1;} a = function(){return 2;}//新值將原值覆蓋 =>> a();// 2
4.下面哪些是ES6的新特性?
A var[a,b]=[1,2]; B const a={};
C var a='foo${a}bar'; D [1,2,3].map(function(item){return item<3;});
阮一峰博士對ES6有深刻的認識,他的著作《ECMAScript6入門》是一本開源的JavaScript語言教程,全面介紹ECMAScript 6新引入的語法特性。網址:ECMAScript6入門。
5.下面哪些是HTML5新標簽?
A audio B address C optgroup D progress
6.通常HTML標簽都需要特別的書寫來閉合,例如<a>標簽的閉合就是</a>,那么下列哪些標簽不需要類似的閉合?
A <br> B <hr> C <command> D <meta>
我們根據已有的編程經驗可以選出正確的答案,但是現在我們要考慮這樣一個問題:為什么有的標簽有閉合,而有的沒有?
簡單來說就是無內容元素(Void Elements)不需要閉合,比較常見的無內容元素有:<br>
<hr>
<img>
<input>
<link>
<meta>,
不太常見的無內容元素有:<area>
<base>
<col>
<command>
<embed>
<keygen>
<param>
<source>
<track>
<wbr>。
伯樂在線上的這篇譯文《HTML標簽,閉合還是不閉合?》 對此有更深入的探討。
7.你的博客或GitHub地址?(略)
8.使用HTML+CSS實現以下圖形(不能用圖片)
如上圖,做題的時候我一直以為最右側的插入圖片是個功能按鈕,出題人真的好奸詐啊!后來我才發現,題目就是讓實現這樣一個圖標,多么痛的領悟!
我在上篇博客CSS十問——好奇心+刨根問底=CSSer提到過使用CSS繪制圖標,我試着用一個標簽還原這個圖標,不過結果差強人意。感興趣的可以看此DEMO:圖片圖標。如果你有更好的思路,不妨留言我們一起討論。
9.通過代碼或偽代碼實現如下要求:
已知x="3.1415926..."(圓周率前10萬位),查詢你手機號碼后4位在“x”字符串中所在的位置。盡可能提升查詢效率,可以優化原始數據的數據結構,讓重復查詢效率提高。
//遞歸調用原生JS方法進行查找
var str="3.1415926...",result=[]; function getAllIndex(test,from){ var index=str.indexOf(test,from); if(index!=-1){ result.push(index); from=index+1; getAllIndex(test,from); } } getAllIndex("9823",0); console.info(result);
PI是一個無限不循環小數,那么它的原始結構並沒有任何規律可言。當我們需要多次檢索這個10萬位的字符串時,必須要對其數據結構進行優化。最常用的優化就是排序,這樣在查找時就可以使用更加高效的方法。每個人都會有很多想法,我也有一個並不周到的設想:
//排序 PI="1415926……"//共10萬項 =>>每4項生成一個鍵值對,分別為4位數數字和起始索引。//{1415:1},{4159:2},{1592:3}……共99997項 =>>根據大小對4位數數字進行排序 形成有序列表orderList// ……{1415,1}……{1592:3}……{4159:2}……共99997項 //查找 假如要查找的字符串為"9823" =>>轉為整型9823 =>>使用折半查找等方法查找orderList。 =>>查出N個滿足條件項 {9823:?}…… =>>從這些鍵值對中得到索引位置
10.請先閱讀如下代碼:
function fn(input){ input=parseInt(input,10); return isPrime(input)?"is prime":"not prime"; }
請實現上面代碼中調用的isPrime這個函數,判斷傳入參數是否為質數(也叫素數)。
function isPrime(num){if(num <= 3) return num > 1;//特殊值處理 if(num > 3){ for(var i = 2,j = Math.sqrt(num);i <= j;i++){//減少循環次數 if(num % i === 0) return false; } return true; } return false; }
11.背景:
a.對象A直接調用對象B的某個方法,實現交互邏輯。但是導致的問題是A和B緊密耦合,修改B可能導致A調用B的方法失效。
b.為了解決耦合導致的問題,我們可以設計成:
對象A生成消息->將消息通知給一個事件消息處理器(Observable)->消息處理器將消息傳遞給B
具體調用過程變成:A.emit('message',data); B.on('message',function(data){});
請實現這一事件消息代理功能
//請將事件消息功能補充完整
function EventEmitter(){ ... }
在設計模式中,這是一個典型的觀察者模式。這道題對我來說有點抽象,我也不在各位面前班門弄斧了,湯姆大叔對觀察者模式有精彩的講解,大家可以圍觀一下:深入理解JavaScript系列(32):設計模式之觀察者模式。
12.請完成以下三個cookie操作,分別為設置、獲取和刪除cookie。
$.cookie.set('name','你的名字');
$.cookie.get('name');
$.cookie.del('name');
(function(globle){ function getCookie(key){//得到一個cookie var cookies=document.cookie,len=cookies.length; if (len > 0) { var c_start = cookies.indexOf(key + "="); if (c_start != -1) { c_start = c_start + key.length + 1; var c_end = cookies.indexOf(";", c_start); if (c_end == -1) c_end = len; return cookies.substring(c_start, c_end); } } return null; } //設置一個cookie @days:保留期限,不設置則默認為會話結束時刪除。 function setCookie(key,value,days){ var exdate = new Date(); exdate.setDate(exdate.getDate() + days||0); document.cookie = key + "=" + value + (!Boolean(days) ? "" : ";expires=" + exdate.toGMTString()); } function deleCookie(key){//刪除一個cookie setCookie(key,"",-1); } globle["$"]={ cookie:{ get:getCookie, set:setCookie, del:deleCookie } } })(window);
13.
<style> .a,.b,.c{position: relative;} </style> <div class="a"> A<div class="c">C</div> </div> <div class="b">B</div>
請補全上面代碼中的CSS部分,讓三個圖層的層級為C>B>A。
在我之前一篇博客《使用CSS3的box-shadow實現雙透明遮罩層對話框》中,曾經探討過z-index。z-index是一個拼爹的屬性,要想滿足C>B>A,那么A無論如何都不能創建新的層疊上下文,因為C是A的子元素,一旦A有了層疊上下文,當B>A時,C的z-index無論設置多大也不可能再超過B了。請看Demo:z-index不可跨越的鴻溝。
不為定位元素顯式指定z-index,則不會創建新的層疊上下文。下面這段代碼可以滿足題目要求:
.a,.b,.c{ position: relative;} .b{z-index:1;} .c{z-index:2;}
但是正如之前的博客中提到的,這種寫法在IE6-7下會產生bug——B會擁有最高的層級。一個簡單的修復方法是讓元素A恢復標准流。戳我查看Demo。
總結
筆試一共13道題,不知道大家是否盡興了?如果意猶未盡,TimTsang在他的GitHub上向我們分享了20道阿里巴巴的在線筆試題,我和他參加的應該是同一次筆試,其中會有幾個重復的題目。這里是博客的地址:2015阿里巴巴前端實習生在線筆試題。
我當時答的很差,稀里糊塗就進面試了,現在回過頭認認真真做一遍真的感覺受益匪淺。同時也希望這篇博客能對大家有所幫助。
PS:我的上一篇博客CSS十問——好奇心+刨根問底=CSSer進入了博客園精華區,很意外。我個人水平真的一般,只是樂於把自己的知識和體會分享給大家。假如發現文中不妥,請您務必評論指正,非常感謝!如果你對於文中觀點持不同意見,我們可以在評論區多多交流,讓更多的人感受到知識的魅力。
(完)