天天看點

位元組跳動前端實習生一面總結與反思一、自我介紹二、考官出題三、項目介紹

一面采用了視訊面試,面試過程如下,重點是考官出題

環節

  • 一、自我介紹
  • 二、考官出題
    • 1.CSS樣式
    • 2.算法題
    • 3.延遲問題
    • 4.Event Loop(JS事件循環機制)
    • 5.變量提升,作用域
    • 6.CSS樣式
    • 7.算法題
    • 8.算法題
  • 三、項目介紹

一、自我介紹

我主要介紹了自己在上一個實習經曆中的前端工作,用到的架構,做的工作内容。

但是我的上一個實習是Java開發,附帶一些前端,用到的架構,做的内容也很簡單,再加上我的表述不清晰,這個環節草草結束了。

反思:做的東西要學會總結,更要學會表達。

二、考官出題

1.CSS樣式

求下面兩種情況下container的高度

<div class="container">
    <div class="item"/ >
    <div class="item"/ >
</div>
.container { border: 1px }
.item { height: 10px; margin: 10px;}
           
<div class="container">
    <div class="item"/ >
    <div class="item"/ >
</div>
.container { border: 1px }
.item { height: 10px; margin: 10px; float: left;}
           

我回答都是20,錯誤。

我自己試了一下,第一種情況是30,第二種情況是0。

為了友善觀察,我給三個div加了顔色。

<html>
<head>
<title>情況1</title>
<style type="text/css">
	.container { border: 1px;}
	.item { height: 10px; margin: 10px;}
</style>
</head>
<body>
 <div class="container" style="background:blue;">
    <div class="item" style="background:red;"></div>
    <div class="item" style="background:orange;"></div>
</div>
</body>
</html>
           
位元組跳動前端實習生一面總結與反思一、自我介紹二、考官出題三、項目介紹

由圖可見,藍色div的高度是30,也就是說,兩個div的margin屬性起了作用。

原理:兩個豎直方向的盒子相遇時,其豎直方向的距離等于上方盒子的下外邊距和下方盒子的上外邊距中較大的一個。由于兩個div的margin值都是10,是以兩個div之間相距10,把外面的div撐到了30。

<html>
<head>
<title>情況2</title>
<style type="text/css">
	.container { border: 1px solid #333;}
	.item { height: 10px; margin: 10px; float: left;}
</style>
</head>
<body>
 <div class="container" style="background:blue;">
    <div class="item" style="background:red;border:1px solid #333;"></div>
    <div class="item" style="background:orange;border:1px solid #113;"></div>
</div>
</body>
</html>
           
位元組跳動前端實習生一面總結與反思一、自我介紹二、考官出題三、項目介紹

為了友善觀察,我給三個div加了邊框。按F12用開發者工具調試,發現兩個div的高是10,但寬都是0,外部的div高度為0。

原理:

  1. 如果一個容器中有多個子容器,如果給子容器設定了float為left,那麼我們就可以把所有子容器看作一個靠左對齊的文本。沿着父容器頂部向左推入容器,如果卡住推不動了,判斷目前位置能否全部顯示該子容器,如果能則完成,如果不能則往下走繼續找空檔往裡面推入容器,以此類推。這是兩個div排列在同一行左邊的原因。
  2. float屬性有一個著名的特性:會讓父元素的高度塌陷。導緻高度塌陷的原因是因為浮動元素脫離了正常的文檔流,則div.father認為其沒有子元素,是以産生了高度塌陷。這是外面的div高度為0的原因。

參考文章:

  1. 深入了解css中的margin屬性
  2. CSS 深入了解之 float 浮動

2.算法題

給定一個數組如 [1,23,4,6,4,3],實作一個函數 function foo() {},求數組最大最小值的差。

方法一:周遊查找最大最小值(我直接寫的就是這個)。

function foo(array) {
 	var result = 0;//儲存結果
 	var min = array[0],max = array[0];
 	if(array.length > 0){
 		for(var i = 1;i < array.length;i++){
 			if(array[i]>max)
 				max = array[i];
 			if(array[i]<min)
 				min = array[i];
 		}
 	}
 	result = max - min;
 	return result;
 }
           

方法二:面試官看了方法一,問有沒有簡單的方法,我說用JS自帶的排序函數。

function foo(array) {
 	var result = 0;//儲存結果
 	var tmp = array.sort();//排序
 	result = tmp[array.length-1] - tmp[0];
 	return result;
 }
           

方法三:面試官最後提到可以用max和min函數。JS的 Math.max(x…) 和 Math.min(x…) 可以求指定數的最大值和最小值。

function foo(array) {
 	var result = 0;//儲存結果
 	var max = Math.max.apply( Math, array);
 	var min = Math.min.apply( Math, array);
 	result = max - min;
 	return result;
 }
           

3.延遲問題

不改變這兩行代碼,如何使第二個輸出延遲一段時間。

log(1)
log(2)
           

我回答的是 setTimeout(" ",1000),這樣不對,setTimeout最後才執行。

  1. 第一次事件循環,整段代碼作為宏任務進入主線程執行。
  2. 遇到了 setTimeout ,就會等到過了指定的時間後将回調函數放入到宏任務的任務隊列中。
  3. 整個事件循環完成之後,會去檢測微任務的任務隊列中是否存在任務,存在就執行。這裡沒有(微任務比如Promise)
  4. 接着再到宏任務的任務隊列中按順序取出一個宏任務到棧中讓主線程執行,那麼在這次循環中的宏任務就是 setTimeout 注冊的回調函數。

面試官說用sleep,我說我也想到了,但以為sleep隻有背景語言才有,JS沒有,是以沒說。面試官說JS确實沒有,可以參考這種思想,用死循環實作。

while循環的方式,容易造成死循環

function sleep(ms){
   var start=Date.now(),expire=start+ms;
   while(Date.now()<expire);
   return;
}
console.log(1);
sleep(2000);
console.log(2);
           

4.Event Loop(JS事件循環機制)

下面兩種情況的輸出情況。

setTimeout(function() {log(1)})
log(2)
//輸出:2,1
setTimeout(function() {log(1)}, 0)
log(2)
//輸出:2,1
           

當時回答的是先2後1,回來又試了一下,确實是這樣。

位元組跳動前端實習生一面總結與反思一、自我介紹二、考官出題三、項目介紹
位元組跳動前端實習生一面總結與反思一、自我介紹二、考官出題三、項目介紹

浏覽器核心有多種線程在工作,其中,JS 引擎線程是單線程工作,負責解析運作 JavaScript 腳本。JS引擎一直等待着任務隊列中任務的到來,然後加以處理,浏覽器無論什麼時候都隻有一個JS線程在運作JS程式。

JavaScript 單線程中的任務分為 同步任務 和 異步任務 。同步任務 console.log(2) 會在調用棧中按照順序排隊等待主線程執行,異步任務 setTimeout 則會在異步有了結果後将注冊的回調函數添加到任務隊列(消息隊列)中等待主線程空閑的時候,也就是棧内被清空的時候,被讀取到棧中等待主線程執行。

setTimeout(fn,0) 的含義是,指定某個任務在主線程最早可得的空閑時間執行,也就是說,盡可能早得執行。它在"任務隊列"的尾部添加一個事件,是以要等到同步任務和"任務隊列"現有的事件都處理完,才會得到執行。

setTimeout(fn) 不寫第二個參數,浏覽器自動配置時間,在IE,FireFox中,第一次配可能給個很大的數字,100ms上下,往後會縮小到最小時間間隔,Safari,chrome,opera則多為10ms上下。

參考文章:

  1. JS浏覽器事件循環機制
  2. setTimeout時間設定為0詳細解析
  3. 你會用setTimeout嗎

5.變量提升,作用域

以下三種情況分别輸出什麼,三者有何不同。

//情況一
log(a);

//情況二
log(a);
var a;

//情況三
log(a);
var a;
function a () {};
           

我回答輸出undefined,其他就不清楚了,面試完自己試了一下。

位元組跳動前端實習生一面總結與反思一、自我介紹二、考官出題三、項目介紹
位元組跳動前端實習生一面總結與反思一、自我介紹二、考官出題三、項目介紹
位元組跳動前端實習生一面總結與反思一、自我介紹二、考官出題三、項目介紹

javascript代碼并不是一行一行往下執行的。

javascript執行分為2個步驟: 編譯(詞法解釋/預解釋) 和 執行。

第二種情況,var a 發生在編譯階段,var a會被提升到目前作用域的最前面。

log(a);
var a;
//經編譯後變成下面的情況
var a;
log(a);
//輸出undefined
           

第一種情況,編譯後目前作用域沒有變量a,是以報錯 Uncaught ReferenceError: a is not defined。

第三種情況,(1)函數聲明會被提升,函數表達式不會提升。(2) 當出現同名的函數聲明,變量聲明的時候, 函數聲明會被優先提升,變量聲明會被忽略。 (3)如果有同名的函數聲明,後面的會覆寫前面的。

log(a);
var a;
function a () {};
//經編譯後變成下面的情況
function a () {};
log(a);
//輸出ƒ a () {}
           

參考文章:最通俗易懂的javascript變量提升

6.CSS樣式

畫一個直徑10px的圓形,我不會。然後問,畫個正方形,我說給div設定寬和高,他說還有嗎,我說display設定成block。

畫圓:首先建個div,然後把div的寬高設定同樣大小,最後把div的邊框弧度設為50%。

<html>
<head>
<style type="text/css">
	.circle{  
    width: 10px;  
    height: 10px;  
    border-radius: 50%;  
	background-color: red;
}  
</style>
</head>
<body>
 <div class="circle">
 </div>
</body>
</html>
           

效果:

位元組跳動前端實習生一面總結與反思一、自我介紹二、考官出題三、項目介紹

7.算法題

//快速排序
public void quick(int []num){
	if(num.length > 0)
		quickSort(num,0,num.length);
}

public void quickSort(int []num,int low,int high){
	if(low<high){
		int md = getMiddle(num,low,high);分成兩部分
		quickSort(num,low,md);//排左邊
		quickSort(num,md+1,high);//排右邊
	}
}

public int getMiddle(int []num,int low,int high){
	int tmp = num[low;//中間
	while(low<=high){
		while(num[high]>tmp && high>=low)
			high--;
		num[low] = num[high];//小于tmp的數放在左邊
		while(num[low]<tmp && high>=low)
			low++
		num[high]=num[low];//大于tmp的數放在右邊
	}
	num[low] = tmp;//中間數
	return low;//中間的位置
}
           

8.算法題

實作一個函數 function flat (arr) {}

輸入arr = [1,2,3, [4, 5, [7, 8, 9]]]

return [1,2,3,4,5,6,7,8,9]

//思想:判斷數組的元素是否為數字,遞歸
function flat(arr){
    var array = new Array();
    for(var i =0;i<arr.length;i++){
        if(arr[i].isNaN()){
            var tmp = new Array();
            tmp = flat(arr[i]);
            array.concat(tmp);
        }
        else
            array.push(arr[i]);
    }
    return array;
}
           

三、項目介紹

依然是很簡單的項目,面試官問用什麼實作資料互動,我說用ajax,面試官問ajax的原理,我又不會。

ajax原理:ajax技術最核心的依賴是浏覽器提供的XMLHttpRequest對象,使得浏覽器可以發出HTTP請求與接收HTTP響應。

位元組跳動前端實習生一面總結與反思一、自我介紹二、考官出題三、項目介紹

參考文章:Ajax原理一篇就夠了

總結:

一面主要考察前端基礎和算法能力。

面試官說,我的邏輯思維和算法沒問題,但前端基礎薄弱,關于前端基礎的問題我的回答基本都是錯的。他人很好,把每一個知識點都标出來了,不然我都不知道我不會的是啥。

這次面試準備确實不充分,我對前端的知識沒有一個整體的把握,平時也很少動手練習,導緻對css樣式沒有直覺的了解,以後要多動手,多看别人的經驗總結。

下一篇:二面總結

繼續閱讀