【面試初體驗】今日頭條前端實習生

回國半個月的準海帶,今天體驗了一下第一場技術面試。首先是一套題目,30分鐘左右的時間根據本身的水平選難題回答,答完以後以後才進行面試。面試官問了不少基礎問題,也不少沒能回答上。略受打擊。。。php


後悔試題沒拍照,根據回憶整理:css

CSS題目

1.上下左右居中html

這個題面試前纔看過,但問到仍是不能說清楚,仍是基礎有硬傷
思路爲絕對定位,在寬高必定的狀況下,上下設置爲50%。以後設置margin爲負值,margin-top和margin-left爲自身高度和寬度的一半,將位置拉回中間。css3

.content{
    position: absolute;
    width:400px;
    height:400px;
    top:50%;
    left:50%;
    margin:-200px 0 0 -200px;
    border:1px solid #008800;
}

2.兩欄,左邊固定100px,右邊自適應git

其實作佈局這個用的最多最多見,我也說的蠻自信的,惋惜我把兩個思路的屬性說混了。
第一個思路是左邊用float:left,右邊用margin-left爲左欄的寬度。github

*{
    margin: 0;
    padding: 0;
}
.left{
    float:left;
    width:100px;
    border: solid #999 1px;
}
.right{
    margin-left: 100px;
    border: solid #777 1px;
}

第二個思路略複雜,右欄width:100%,float:left,可是這樣就會超出屏幕的寬度,因而用負值margin拉回來。但這就出現另外一個問題,因爲右欄縮到左欄裏,因此左欄會遮蓋右欄的一部分,因此在右欄內部再鑲嵌一層,margin-left爲左欄的寬度web

*{
    margin: 0;
    padding: 0;
}
.left{
    float:left;
    width:100px;
    border: solid #999 1px;
    margin-right: -100%;
}
.right{
    float:left;
    width:100%;
    border: solid #777 1px;
}
.content{
    margin-left: 100px;
}

補充:第三種方式是在整理下面題目的時候發現的,用display:table-cell的自適應。
思路仍是,由於table-cell的自適應,將右欄設的儘量的大。面試

*{
    margin: 0;
    padding: 0;
}
.left{
    float:left;
    width:100px;
    border: solid #999 1px;
}
.right{
    display: table-cell;
    width:3000px;
    border: solid #777 1px;
}

3.盒模型算法

盒模型能夠幫助塊級元素的定位和計算面積,簡單來講W3C的盒模型包括content、padding、border。而IE得盒模型則有些不一樣,表如今設置寬高的時候,W3C模型下只包含content區域,而IE包括全部區域。
這樣,在IE下,設置了寬高以後能夠很放心的設定padding,可是對於W3C模型下,設置了寬高以後還要計算padding和border的區域。所以有一個方法叫作box-sizing:border-box。border-box將border和padding區域一同算進設定的寬高內。這樣的話添加以下代碼,就能夠設定padding而用不擔憂超出設置區域。編程

div{
    box-sizing:border-box;
    -moz-box-sizing:border-box; /* Firefox */
    -webkit-box-sizing:border-box; /* Safari */
}

4.幾種方法生成三個並排的大小相等的元素

這個問題讓我有點蒙,首先想到的是三個元素都用百分比控制

*{
    margin: 0;
    padding: 0;
}
.left,.right,.middle{
    float:left;
    width:33.3%
}

其實還有能夠用display:inline-block。回家之後嘗試了一下,發現問題是若是這幾個元素沒有在代碼裏寫在一行,那麼最後展示出來的是最後一個元素會被擠到下面一行。
大神男朋友告訴我hack方法爲:

margin-right: -4px//能夠按照實際調整。

關於inline-block縫隙,推薦一篇文章:去除間距

還有一個方法爲tabel-cell,這種方法就是將每個元素設置的儘量的大,但因爲自適應的特性,這三個元素仍是會乖乖地等分的排在一行裏。

*{
    margin: 0;
    padding: 0;
}
.left,.middle, .right{
    display:table-cell;
    width:3000px;
}

接着昨天的繼續補充

5.CSS3的新特性用過哪些

對於我來講最經常使用固然是border-radius,讓圓角成爲方便的存在。
然而他問第二個問題:怎樣將方的經過圓角變成圓的?
其實只要

border-radius:50%;

就行了。惋惜當時我怕這個不能用百分比,因而說若是50的寬高,半徑爲25就好。其實這個也沒錯啦,但也看的出我基礎不紮實。

除此以外,box-shadow也是咱經常使用的屬性之一。設置水平、垂直的位移,陰影的模糊、尺寸還有顏色,就能夠爲元素添加陰影。

box-shadow: 2px 2px 3px #777;

而後我也提了一下border-image這個好用又漂亮的屬性。經過設置圖片路徑,圖片的切割方式、還有邊框的寬度、溢出,以及平鋪或拉伸等呈現方式,能夠作出一個漂亮精緻的邊框。

border-image: url(border-image.png) 30/10px/10px round;

關於border-image的每一項屬性的用法和限制,能夠參考我大神男朋友的文章CSS 3 border-image 屬性詳解

面試官還問到了動畫:transition、transform和animation的區別?
惋惜我目前並無用CSS作過動畫【攤手。。
他專門問到了這個問題,說明CSS3的動畫是應用較多的,回來馬上學習。

transform是指轉換,能夠將元素移動、旋轉、傾斜、拉伸。

translate(),從當前位置移動到由給定left和top值的位置。這個例子中,div向右下移動,若是想要往左上移動,則要設置爲負值。

div{
    transform: translate(50px,100px);
    -ms-transform: translate(50px,100px);        /* IE 9 */
    -webkit-transform: translate(50px,100px);    /* Safari and Chrome */
    -o-transform: translate(50px,100px);        /* Opera */
    -moz-transform: translate(50px,100px);        /* Firefox */
}

rotate(),將元素旋轉到給定角度,單位爲deg(degree角度),在這個例子中爲順時針30度。負值的話爲逆時針旋轉。

div{
    transform: rotate(30deg);
    -ms-transform: rotate(30deg);        /* IE 9 */
    -webkit-transform: rotate(30deg);    /* Safari and Chrome */
    -o-transform: rotate(30deg);        /* Opera */
    -moz-transform: rotate(30deg);        /* Firefox */
}

skew() ,將元素傾斜到給定角度,單位也是deg,分別圍繞着X軸和Y軸翻轉。這個例子中,在X軸順時針翻轉30度,Y軸順時針翻轉20度,負值爲逆時針翻轉。

div{
    transform: skew(30deg,20deg);
    -ms-transform: skew(30deg,20deg);    /* IE 9 */
    -webkit-transform: skew(30deg,20deg);    /* Safari and Chrome */
    -o-transform: skew(30deg,20deg);    /* Opera */
    -moz-transform: skew(30deg,20deg);    /* Firefox */
}

scale(),將元素拉伸到指定的倍數,一樣設定了X與Y兩個方向。這個例子中把寬度拉伸2倍,高度拉伸4倍。有意思的是,負值不是縮小,而是翻轉,既水平翻轉和垂直翻轉。

div{
    transform: scale(2,4);
    -ms-transform: scale(2,4);    /* IE 9 */
    -webkit-transform: scale(2,4);    /* Safari 和 Chrome */
    -o-transform: scale(2,4);    /* Opera */
    -moz-transform: scale(2,4);    /* Firefox */
}

transform並無變化的過程,而是直接生成最終效果。transform還有3D方法,就是多了一個Z軸(Opera不支持)

  • transition是指過渡,能夠動畫般顯示出一個從樣式到樣式之間的過渡。

上面說過transform沒有變化的過程,這樣一來就能夠動畫顯示出各類酷炫的效果。
transform的屬性包括一個你設定過渡的CSS屬性,持續時間,時間曲線還有過渡開始的時間。

比較麻煩的寫法,每一項屬性單獨寫:

div{
    transition-property: width;
    transition-duration: 1s;
    transition-timing-function: linear;
    transition-delay: 2s;
    /* Firefox 4 */
    -moz-transition-property:width;
    -moz-transition-duration:1s;
    -moz-transition-timing-function:linear;
    -moz-transition-delay:2s;
    /* Safari 和 Chrome */
    -webkit-transition-property:width;
    -webkit-transition-duration:1s;
    -webkit-transition-timing-function:linear;
    -webkit-transition-delay:2s;
    /* Opera */
    -o-transition-property:width;
    -o-transition-duration:1s;
    -o-transition-timing-function:linear;
    -o-transition-delay:2s;
}

簡單的寫法就是將屬性都寫在transition中。下面例子中包括了以前咱們將transform的旋轉,效果比較酷炫。(背景用色有點小私心,不過過渡很漂亮

div{
    width:100px;
    height:100px;
    background:lavender;
    transition:width 2s, height 2s, background 2s;
    -moz-transition:width 2s, height 2s, -moz-transform 2s; /* Firefox 4 */
    -webkit-transition:width 2s, height 2s, -webkit-transform 2s, background 2s; /* Safari and Chrome */
    -o-transition:width 2s, height 2s, background 2s, -o-transform 2s; /* Opera */
}
        
div:hover{
    width:200px;
    height:200px;
    background:LightSeaGreen;
    transform:rotate(180deg);
    -moz-transform:rotate(180deg); /* Firefox 4 */
    -webkit-transform:rotate(180deg); /* Safari and Chrome */
    -o-transform:rotate(180deg); /* Opera */
}
  • animation,用@keyframes規則作動畫效果。

若是說transition是過渡中的動畫效果,那麼animation就是專門作動畫的。transition是animation的簡化,是當屬性發生變化的時候,觸發過渡動畫。就是上面例子中hover的時候,css的屬性變化了,那麼在transition裏面綁定過得屬性動畫過渡過去。
animation就複雜多了:@keyframes能夠有from to,也能夠是百分比表示時間幀。

from-to

@keyframes myfirst{
    from {background: lavender;}
    to {background: LightSeaGreen;}
}

百分比

@keyframes myfirst{
    0%   {background: purple;}
    25%  {background: lavender;}
    50%  {background: cyan;}
    75% {background: LightSeaGreen;}
    100% {background:purple;}
}

而後再將這個@keyframes綁定到一個元素上。
animation提供了更多屬性,包括@keyframes名字、持續時間、速度曲線、開始時間、播放次數等。

div{
    animation: myfirst 5s linear 2s infinite alternate;
    /* Firefox: */
    -moz-animation: myfirst 5s linear 2s infinite alternate;
    /* Safari 和 Chrome: */
    -webkit-animation: myfirst 5s linear 2s infinite alternate;
    /* Opera: */
    -o-animation: myfirst 5s linear 2s infinite alternate;
}

有了這幾個屬性,css能夠在不少時候取代flash和動圖了。


JavaScript題目

可能由於筆試中JS題目較多,因此面試的時候沒有問太多。

1.優化代碼,事件委託

筆試的題目上給了一段代碼讓我優化。具體代碼記不清,大概是獲取的元素,而後循環爲每個添加mouseover和mouseout事件。

var elementList=document.querySelectorAll("a");
var listLen=elementList.length;
function handler (element,color){
    return function(){
        element.style.color=color;
    };
}
//添加事件方法
function addEvent(element,type,handler){
    if(element.addEventListener){
        element.addEventListener(type,handler,false);
    }
    else if(element.attachEvent){
        element.attachEvent("on"+type,handler);
    }
}
//循環爲元素添加事件
for(i=0;i<listLen;i++){
    addEvent(elementList[i],"mouseover",handler(elementList[i],"red"));
    addEvent(elementList[i],"mouseout",handler(elementList[i],"black"));
}

而後面試官又問我爲何事件委託效率更高

仍是基礎硬傷,我只是大概知道什麼是事件委託,對於原理還不瞭解。因而回來又查參考書《Javascript高級程序設計》

???????????事件委託利用了事件冒泡,指定??????一個事件處理程序,就能夠管理某一個類型的全部事件。

書上解釋,在DOM樹中儘可能高的層次上添加一個事件處理程序。那麼在他的子孫元素中的事件,最終都會冒泡到這個層次中。例如,列表裏有兩個項目,咱們不要分別設置每個項目點擊時的事件,而是在上層中創建事件委託。

<ul id="link">
    <li id="home">首頁</li>
       <li id="resume">簡歷</li>
</ul>
var link = document.querySelector("#link");
//添加事件
function addEvent(element,type,handler){
    if(element.addEventListener){
        element.addEventListener(type,handler,false);
    }
    else if(element.attachEvent){
        element.attachEvent("on"+type,handler);
    }
}
//獲取事件對象,由於奇葩的IE,事件對象要用window.event
function getEvent(event){
    return event ? event : window.event;
}
//獲取事件目標
function getTarget(event){
    return event.target || event.srcElement;
}
//爲外層ul添加事件委託
addEvent(link,"click",function(event){
    event = getEvent(event);
    var target = getTarget(event);
    //爲每個li添加事件
       switch(target.id){
           case "home":
               target.innerHTML="首頁,<a href='http://myj.name/'>Welcome to my home</a>"
        break;
        case "resume":
            location.href = "http://katherina-miao.github.io/resume/";
        break;
     }
})

2.添加一個相似email中checklist的雙向聯動

起初,個人心裏是崩潰的。。。
這個題剛開始都沒搞清楚是作什麼的,一直到作完整個卷子我才又回頭看了看這個題。時間有限,都沒來得及想就往紙上寫。
其實這個題是讓我作一個相似email裏選擇發件人的東西,勾選的時候添加到發件人,取消勾選的時候從發件人裏面刪除。因爲是雙向聯動,所以要在發件人裏點擊的時候能夠刪除,而且取消勾選。好像說的有點亂,看下面代碼。

其實主要仍是事件綁定,而後添加節點,改變屬性。

<div class="container">
    <div class="showbox"></div>
    <input type="checkbox" name="email" value="i@myj.name">Kathy</input>
    <input type="checkbox" name="email" value="i@zjy.name">Visper</input>
</div>
var emails=document.querySelectorAll("[name=email]");
var showBox=document.querySelector(".showbox");
var length=emails.length;
//添加事件
function addEvent(element,type,handler){
    if(element.addEventListener){
        element.addEventListener(type,handler,false);
    }
    else if(element.attachEvent){
        element.attachEvent("on"+type,handler);
    }
}
//循環,爲每一個checkbox添加事件
for(var i=0;i<length;i++){
    addEvent(emails[i],"click",function(){
        //判斷是否被選中
        if(this.checked){
            var Emailvalue = this.value;
            var newBtn=document.createElement("input");
            newBtn.setAttribute("type","button");
            
            newBtn.value=Emailvalue;
            showBox.appendChild(newBtn);
        }
        //若取消勾選,則刪除相應的button
        else{
            var Emailvalue = this.value;
            var emailBtn=document.querySelector("[type=button][value='"+Emailvalue+"']");
            showBox.removeChild(emailBtn);
        }
        //每次從新調用以更新button
        startBtn();
    })
}
//獲取button列表,爲button添加事件
function startBtn(){
    var emailBtn=document.querySelectorAll("[type=button]");
    if(emailBtn.length){
        for(var i=0;i<emailBtn.length;i++){
            addEvent(emailBtn[i],"click",function(){
                var btnvalue=this.value;
                var cancelChoose=document.querySelectorAll("[value='"+btnvalue+"']");
                //刪除button並取消勾選相應checkbox
                for(var j=0;j<cancelChoose.length;j++){
                    if(cancelChoose[j].getAttribute("type")=="button"){
                        showBox.removeChild(cancelChoose[j]);
                    }
                    else if(cancelChoose[j].getAttribute("type")=="checkbox"){
                        cancelChoose[j].checked=false;
                    }
                }
            })
        }
    }
}

3.Array的方法

面試官問到Array有幾種方法,這個我在面試前曾經簡單整理過,因此感受回答也比較滿意。

isArray(),判斷是否爲Array類型。
join(),將Array類型轉換爲字符串類型,並用join內的符號間隔開。

隊列,棧的用法
push(),將數據項放到數組的後面。
pop(),將數組的最後一項刪除並返回。
shift(),將數組的第一項刪除並返回。
unshift(),將數據項放到數組的前面。

重排序的方法
reverse(),將數組逆序排列。
sort(),將數組由小到大排列。默認是按照字符串比較,也就是說15比5小。要按照數字排列的話,要設定方法:

var numlist = [0, 5, 15, 20, 10];
function compare (value1, value2){
    value2-value1;
}
var listsort = numlist.sort(compare);
alert( listsort );//0, 5, 10, 15, 20 按照數值從小到大

操做Array的方法
concat(),在原有meat數組上建立新數組
slice(),截取從指定位置開始到結束爲止(不包含結束位置)的數組項賦給新數組,若是沒有第二個參數,則截取從指定位置開始到結束的數組項賦給新數組
splice(),從指定位置(第一個參數)刪除指定個數(第二個參數)並插入指定項目(’第三個參數」)

位置方法
indexOf(),從前向後查找位置索引。
lastIndexOf(),從後向前查找位置索引。
這兩個方法支持第二個參數,既指定位置而後按照方法向前或向後查找位置。

遍歷方法
every()中,每一項運行給定函數,每一項都返回true,??則返回true。
filter()中,每一項運行給定函數,返回true的項。
forEach()中,每一項運行給定函數,無返回。
map()中,每一項運行給定函數,返回調用結果組成的數組。
some()中,每一項運行給定函數,任意一項返回true,?則返回true。

????????歸併方法
reduce()?和reduceRight()都接受四個參數:前一個值,當前值,索引和數組對象。
reduce()是從左向右歸併,當第一個值和第二個值運行過以後,結果將做爲下一次運行的前一個值。
reduceRight()則是從右向左,歸併方式與reduce()同樣。??


算法題

算法題就一個,給定字符串「abcba」,處理獲得第一個不重複字母。

對算法實在只是瞭解個皮毛,因此這個問題估計最後仍是寫錯了。回來後本身寫了一個,能夠獲得答案,但也不知道是否是最優。
思路是首先將字符轉換成數組,而後從小到大排序,而後循環對每個數組項比較先後。由於曾經排序,若是是不重複的那麼先後應該都與它不一樣。

var letterString="abcba";
var letterArray=Array.prototype.slice.apply(letterString);
var arrayLen=letterArray.length;
var sortArray=letterArray.sort();
for(var i=0;i<arrayLen;i++){
    if(sortArray[i]!=sortArray[i+1]&&sortArray[i]!=sortArray[i-1]){
        alert(sortArray[i]);
    }
}

HTTP

1.AJAX過程,AJAX中如何區分get和post,get和post的區別

面試官在這個方面一氣兒問了三個問題,可能由於我沒一個問題都沒能答的全面。

AJAX算是聽人說的最多的一個技術,無需加載整個頁面的狀況下進行局部更新。
再用AJAX技術與服務器交換數據時,首先建立一個XMLHttpRequest對象,在特立獨行的IE裏是ActiveXObject。

接着咱們用open()方法和send()方法,使用get和post會有些區別。而後,請求會發送給服務器,服務器會響應觸發onreadystatechange事件,當readyState=4(請求完成)且status=200時,說明服務器已經就緒。而後用responseText或responseXML屬性去得到字符串或XML格式的數據。

var xmlhttp;
if (window.XMLHttpRequest){
    xmlhttp=new XMLHttpRequest();
}
else{
    //奇葩的IE五、6
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("GET","response.php",true);
xmlhttp.send();

xmlhttp.onreadystatechange=function(){
    if (xmlhttp.readyState==4 && xmlhttp.status==200){
        document.getElementById("showBox").innerHTML=xmlhttp.responseText;
    }
  }

在AJAX中區別get和post,就要詳談open()方法和send()方法。

get請求經常使用於向服務器查詢信息。

在get請求中,open()的第一個參數爲「get」,第二個參數爲URL,第三個參數爲是否爲異步。因爲get請求的URL中一般帶有參數,這些參數必需要使用encodeURIComponent()方法進行編碼,不然會有格式錯誤。這樣send()方法內部的參數能夠傳入null,傳入的參數也會轉到URL中。

post請求經常使用於向服務器提交信息。

在post請求中,open()的第一個參數爲「post」,URL中不含有參數,第三個參數同樣。post請求的send()方法中須要傳入提交數據,可使用XML或者字符串。在提交表單時,首先要設定請求頭部的Content-Type爲 application/x-www-form-urlencoded。

xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

而後將傳入的表單信息序列化,方便後端的程序獲取數據。對於表單數據序列化,FormData對象能夠直接放入send()內:

<form id=「user-info」>
    用戶名:<input type="text" name="username"/>
    年齡:<input type="text" name="年齡"/>
</form>
var form = document.getElementById("user-info");
xhr.send(new FormData(form));

前面提過,get方式中url包含參數,而post中url是「乾乾淨淨」的。由於用處不一樣,post在提交內容的時候沒有大小限制。並且post在發送時有內容體,那些提交的信息放在內容體內。


2.JSONP 跨域的特性

說實話我只在用JQuery的時候用過JSONP,只知道能夠跨域,但不知道爲何能夠。因此在被問到的時候,腦子又是一蒙。

因爲跨域安全策略,XMLHttpRequest不能跨域請求,這是AJAX的一個主要限制。
JSONP是經過<script>元素。由於咱們知道,<script>能夠跨域引用js文件。返回的數據格式爲JSON,建立一個回調函數來相應返回的數據。

var script = document.createElement("script");

script.src = "http://pvoutput.org/service2v?Apikey=123&SystemID=123&callback=handler」;
document.body.appendChild(script);

//回調函數
function handler(response){
    var responseContent={
        diatotime:response.datetime,
        usedEnergy:response.used.Energy,
        …
    }
    return responseContent;
}

除了JSONP,用img標籤也能夠跨域通訊。

var img = new Image();
img.src = "http://www.example.com/id=123」;

CORS是跨域請求的另外一個方法。在IE瀏覽器中爲XDomainRequest對象,而在其餘瀏覽器中則繼續用XMLHttpRequest。區別在於,XDomainRequest對象的open()只有兩個參數:請求類型和URL,由於都是異步執行。而其餘瀏覽器在使用open()時,URL要使用絕對路徑,既能夠跨域請求。

3.提升網頁性能的方法

由於剛剛問完AJAX,因此首先反應的是使用AJAX部分刷新。而後我想到了CSS精靈,將小圖片放在一塊兒減小HTTP請求。而後想到將script和css從外部引入,而後script放在文檔底部。

除此以外,總結一下:在內容上壓縮,在請求上減小。壓縮圖片、腳本和CSS,使用CSS精靈,優化圖片,儘可能使用<link>引用CSS。在請求上避免重定向,儘可能使用AJAX儘可能使用GET請求。

在優化性能方面,我沒什麼研究,仍是因爲對底層原理不熟【汗。。


此次的面試經歷整理了一天多,一是由於實在是基礎差,每一題都要查資料,編程題要本身試,二是要激勵本身。由於本身是很懶的人,不喜歡上網找文章資料。此次面試算是一個鞭策,將本身漏洞補起來。

但願各路大神評論補充!!本菜鳥道謝~~

相關文章
相關標籤/搜索