天天看點

前端面試題集錦

 記憶體

棧記憶體:存儲值類型,變量。

堆記憶體:複雜類型的資料,對象等。其中放棧記憶體中的變量存儲的是在堆記憶體中的位址,進而指向堆記憶體。

div元素水準垂直居中的方法

第一種:

<style>
        .a {
            height: 300px;
            background-color: hotpink;
            position: relative;
        }
        
        .b {
            width: 100px;
            height: 100px;
            background-color: lawngreen;
            position: absolute;
            top: 0;
            bottom: 0;
            left: 0;
            right: 0;
            margin: auto;
        }
</style>
<body>
    <div class="a">
        <div class="b"></div>
    </div>
</body>
           

第二種:

<style>
        .a {
            height: 300px;
            background-color: hotpink;
            position: relative;
        }
        
        .b {
            width: 100px;
            height: 100px;
            background-color: lawngreen;
            position: absolute;
            margin: auto;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
        }
</style>
           

cookie和session 、sessionstorage和localstorage

cookie:Cookie是一段不超過4KB的小型文本資料,由一個名稱(Name)、一個值(Value)和其它幾個用于控制Cookie有效期、安全性、使用範圍的可選屬性組成。

cookie資料存放在客戶的浏覽器上。cookie不是很安全,别人可以分析存放在本地的cookie并進行cookie欺騙。Cookie的maxAge決定着Cookie的有效期,機關為秒(Second)。Cookie中通過getMaxAge()方法與setMaxAge(int maxAge)方法來讀寫maxAge屬性。

session:session,伺服器為了儲存使用者狀态而建立的一個特殊的對象。當浏覽器第一次通路伺服器時,伺服器建立一個session對象(該對象有一個唯一的id,一般稱之為sessionId),伺服器會将sessionId以cookie的方式發送給浏覽器。當浏覽器再次通路伺服器時,會将sessionId發送過來,伺服器依據sessionId就可以找到對應的session對象。

session資料放在伺服器上。session會在一定時間内儲存在伺服器上。當通路增多,會比較占用你伺服器的性能。

sessionstorage和localstorage的差別:

localStorage生命周期是永久,除非使用者清除localStorage資訊,否則這些資訊将永遠存在;

sessionStorage生命周期為目前視窗或标簽頁,一旦視窗或标簽頁被永久關閉了,那麼所有通過它存儲的資料也就被清空了。

localStorage和sessionStorage一樣都是用來存儲用戶端臨時資訊的對象。

詳細請見轉載:cookie、sessionStorage和localStorage的差別_浮生離夢的部落格-CSDN部落格(寫的很好!!!)

http緩存:常見的http緩存隻能緩存get請求響應的資源

消除數組中的重複元素

var b = [1, 2, 1, 2, 3, 5, "q", "q", [1],[1, 2],[1]];

var resualt = new Set(b);//将數組中重複元素删除,并以對象形式傳回

resualt = Array.from(resualt);//将對象轉換為數組

console.log(resualt);
           

結果:

前端面試題集錦

将數組進行全排列,生成一個新數組

例:["a,b,c"]

全排序為["a,b,c","a,c,b","b,a,c","b,c,a","c,a,b","c,b,a"]

function Allsort1(arr) {
    var arr1 = arr[0].split(",");

    function swap(arr, i, j) {
        if (i != j) {
            var temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    }
    var Arr = [];
    //此方法最主要是交換的思路
    function perm(arr) {
        (function fn(n) { //為第n個位置選擇元素 
            for (var i = n; i < arr.length; i++) {
                swap(arr, i, n);
                if (n + 1 < arr.length - 1) //根據下标a(b+1) 不是最後一項,判斷數組中剩餘的待全排列的元素是否大于1個 
                    fn(n + 1); //從第n+1個下标進行全排列 
                else {
                    Arr.push(arr.toString());
                }
                swap(arr, i, n);
            }
        })(0);
    }
    perm(arr1);
    return Arr;
}
           

React的四種hook

useState():狀态鈎子。

純函數沒有狀态,useState() 用于為函數元件引入狀态。

useContext():共享狀态鈎子。

作用就是可以做狀态的分發,在React16.X以後支援,避免了react逐層通過Props傳遞資料。

useReducer():Action鈎子。

在使用React的過程中,如遇到狀态管理,一般會用到Redux,而React本身是不提供狀态管理的。而useReducer()提供了狀态管理。首先,關于redux我們都知道,其原理是通過使用者在頁面中發起action,進而通過reducer方法來改變state,進而實作頁面和狀态的通信。而Reducer的形式是(state, action) => newstate。它接受reducer函數和狀态的初始值作為參數,傳回一個數組,其中第一項為目前的狀态值,第二項為發送action的dispatch函數。

useEffect():副作用鈎子。

可以用來更好的處理副作用,如異步請求等,Hooks 的 useEffect()也是為函數元件提供了處理副作用的鈎子。

全局狀态管理

vue 裡通過 vuex實作全局狀态管理,在react裡可以通過redux或者mobx也可以實作全局狀态管理。

js的資料類型

JavaScript的基本資料類型:

值類型 (基本類型) :字元串(String)、數字 (Number)、布爾 (Boolean)、對空(Null)、未定義(Undefined)、Symbol。

引用資料類型 :對象 (Object)、數組 (Array)、函數 (Function)。.

幾種内部基本排序

插入排序

        直接插入排序:

        折半插入排序:

        希爾排序:

交換排序

        冒泡排序:

        快速排序:

選擇排序

        簡單選擇排序:

        堆排序:

歸并排序:

基數排序:

浏覽器的核心

浏覽器的核心是指支援浏覽器運作的最核心的程式,分為兩個部分的,一是渲染引擎,另一個是JS引擎。

主流浏覽器

IE/Edge(Trident),Chrome(Webkit,blink ),Safari(Webkit),Opera(Presto,Webkit,blink ),Firefox(Mosaic)。

IE/Edge:微軟的IE浏覽器浏覽器更新至IE10後,伴随着WIN10系統的上市,遷移到了全新的浏覽器Edge。除了JS引擎沿用之前IE9就開始使用的查克拉(Chakra),渲染引擎使用了新的核心EdgeHTML(本質上不是對Trident的完全推翻重建,而是在Trident基礎上删除了過時的舊技術支援的代碼,擴充和優化了對新的技術的支援,是以被看做是全新的核心)

Safari:Safari自2003年面世,就一直是蘋果公司的産品自帶的浏覽器,它使用的是蘋果研發和開源的Webkit引擎。Webkit引擎包含WebCore排版引擎及JavaScriptCore解析引擎,均是從KDE的KHTML及KJS引擎衍生而來。Webkit2釋出于2010年,它實作了元件的抽象畫,提高了元件的重複利用效率,提供了更加幹淨的網頁渲染和更高效的渲染效率。另外,Webkit也是蘋果Mac OS X系統引擎架構版本的名稱,主要用于Safari、Dashboard、Mail。

Chrome:提到Chrome浏覽器,一般人會認為使用的Webkit核心,這種說法不完全準确。Chrome釋出于2008年,使用的渲染核心是Chromium,它是fork自Webkit,但把Webkit梳理得更有條理可讀性更高,效率提升明顯。2013年,由于Webkit2和Chromium在沙箱設計上的沖突,谷歌聯手Opera自研和釋出了Blink引擎,逐漸脫離了Webkit的影響。是以,可以這麼認為:Chromium擴充自Webkit止于Webkit2,其後Chrome切換到了Blink引擎。另外,Chrome的JS引擎使用的V8引擎,應該算是最著名和優秀的開源JS引擎,大名鼎鼎的Node.js就是選用V8作為底層架構。

Firefox:火狐的核心Gecko也是開源引擎,任何程式員都能為其提供擴充和建議。火狐的JS引擎曆經SpiderMonkey、TraceMonkey到現在的JaegerMonkey。其中JaegerMonkey部分技術借鑒了V8、JSCore和Webkit,算是集思廣益。

Opera:Opera在2013年V12.16之前使用的是Opera Software公司開發的Presto引擎,之後連同谷歌研發和選擇Blink作為Opera浏覽器的排版核心。

題目1:

牛牛有一個隻由字元'1'到'9'組成的長度為 n 的字元串 s ,現在牛牛可以截取其中一段長度為 k 的子串并且将該子串當作十進制的正整數,如對于子串"123",其對應的十進制數字就是123 。

牛牛想讓這個正整數盡可能的大,請你幫助牛牛計算該正整數。

函數傳入一個長度為 n  的字元串 s 和一個正整數 k ,請你傳回答案。

輸入例子1:

"321",2
      

輸出例子1:

32
      
function maxValue(s, k) {
            // write code here
            var max = s[0];
            var x = 0;
            var Arr = [];
            var resualt = 0;
            for (var i = 0; i < s.length - 1; i++) {
                max = Math.max(max, s[i + 1]);
            }
            for (var i = 0; i < s.length; i++) {
                if (s[i] == max) {
                    x = i;
                    Arr.push(s.slice(x, x + k));
                }
            }
            max = Arr[0];
            for (var i = 0; i < Arr.length - 1; i++) {
                max = Math.max(max, Arr[i + 1]);
            }
            resualt = parseInt(max);
            return resualt;

        }
module.exports = {
    maxValue : maxValue
};
           

 補充知識點:*數組的各種用法(js)

建立數組

var array-name = [item1, item2, ...];      
var cars = ["Saab", "Volvo", "BMW"];
           

注:不要最後一個元素之後寫逗号

使用 JavaScript 關鍵詞 new

var cars = new Array("Saab", "Volvo", "BMW");
           

通路數組元素

通過引用索引号(下标号)來引用某個數組元素。

var name = cars[0];
           

數組索引從 0 開始。

數組是對象

數組是一種特殊類型的對象。在 JavaScript 中對數組使用 typeof 運算符會傳回 "object"。

可以使用Array.isArray()判斷是否為數組。

可以在數組儲存對象。可以在數組中儲存函數。甚至可以在數組中儲存數組:

myArray[0] = Date.now;
myArray[1] = myFunction;
myArray[2] = myCars;
           

數組屬性和方法

length 屬性

傳回數組的長度(數組元素的數目)。

周遊數組

for循環、Array.foreach() 函數:

var fruits, text;
fruits = ["Banana", "Orange", "Apple", "Mango"];

text = "<ul>";
fruits.forEach(myFunction);
text += "</ul>";

function myFunction(value) {
  text += "<li>" + value + "</li>";
}
           

添加或删除數組元素

pop() 方法從數組中删除最後一個元素,傳回“被彈出”的值:

var fruits = ["Banana", "Orange", "Apple", "Mango"];
var x = fruits.pop();    // 從 fruits 删除最後一個元素("Mango"),x 的值是 "Mango"
           

push() 方法(在數組結尾處)向數組添加一個新的元素,傳回新數組的長度:

var fruits = ["Banana", "Orange", "Apple", "Mango"];
var x =  fruits.push("Kiwi");   //  向 fruits 添加一個新元素,x 的值是 5
           

shift() 方法會删除首個數組元素,并把所有其他元素“位移”到更低的索引,傳回被“位移出”的字元串。

unshift() 方法(在開頭)向數組添加新元素,并“反向位移”舊元素,傳回新數組的長度。

也可以使用 length 屬性向數組添加新元素:

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits[fruits.length] = "Lemon";
           

 既然 JavaScript 數組屬于對象,其中的元素就也可以使用 JavaScript delete 運算符來删除:

var fruits = ["Banana", "Orange", "Apple", "Mango"];
delete fruits[0];           // 把 fruits 中的首個元素改為 undefined
           

但是使用 delete 會在數組留下未定義的空洞,是以推薦使用pop()或shift()。

把數組轉換為字元串

toString() 把數組轉換為數組值(逗号分隔)的字元串。

var fruits = ["Banana", "Orange", "Apple", "Mango"];
document.getElementById("demo").innerHTML = fruits.toString();
           

結果:

Banana,Orange,Apple,Mango
           

join() 方法也可将所有數組元素結合為一個字元串,還可以規定分隔符。

var fruits = ["Banana", "Orange","Apple", "Mango"];
document.getElementById("demo").innerHTML = fruits.join(" * "); 
           

結果:

Banana * Orange * Apple * Mango
           

拼接數組

splice() 方法可用于向數組添加新項,傳回一個包含已删除項的數組:

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.splice(2, 0, "Lemon", "Kiwi");
           

第一個參數(2)定義了應添加新元素的位置(拼接)。

第二個參數(0)定義應删除多少元素。

其餘參數(“Lemon”,“Kiwi”)定義要添加的新元素。

能夠使用 splice() 在數組中不留“空洞”的情況下移除元素:

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.splice(0, 1);        // 删除 fruits 中的第一個元素
           

合并(連接配接)數組

concat() 方法通過合并(連接配接)現有數組來建立一個新數組,不會更改現有數組,傳回一個新數組:

var myGirls = ["Cecilie", "Lone"];
var myBoys = ["Emil", "Tobias", "Linus"];
var myChildren = myGirls.concat(myBoys);   // 連接配接 myGirls 和 myBoys
           

可以使用任意數量的數組參數:(三個數組)

var arr1 = ["Cecilie", "Lone"];
var arr2 = ["Emil", "Tobias", "Linus"];
var arr3 = ["Robin", "Morgan"];
var myChildren = arr1.concat(arr2, arr3);   // 将arr1、arr2 與 arr3 連接配接在一起
           

也可以将值作為參數:

var arr1 = ["Cecilie", "Lone"];
var myChildren = arr1.concat(["Emil", "Tobias", "Linus"]); 
           

裁剪數組

slice() 方法用數組的某個片段切出新數組,建立一個新數組,不會從原數組中删除任何元素。

var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
var citrus = fruits.slice(1); 
           

可接受兩個參數,比如 (1, 3)。

該方法會從開始參數選取元素,直到結束參數(不包括)為止。

如果結束參數被省略,比如第一個例子,則 slice() 會切出數組的剩餘部分。

自動 toString()

如果需要原始值,則 JavaScript 會自動把數組轉換為字元串。下面兩個例子将産生相同的結果:

var fruits = ["Banana", "Orange", "Apple", "Mango"];
document.getElementById("demo").innerHTML = fruits.toString(); 
           
var fruits = ["Banana", "Orange", "Apple", "Mango"];
document.getElementById("demo").innerHTML = fruits; 
           

數組排序

sort() 方法以字母順序對數組進行排序:

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.sort();            // 對 fruits 中的元素進行排序
           

反轉數組

reverse() 方法反轉數組中的元素,可以使用它以降序對數組進行排序:

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.sort();            // 對 fruits 中的元素進行排序
fruits.reverse();         // 反轉元素順序
           

數字排序

當 sort() 函數比較兩個值時,會将值發送到比較函數:function(a, b){return a-b},并根據所傳回的值(負、零或正值)對這些值進行排序。

通過一個比值函數讓sort() 函數按照數字順序對值進行排序:

var points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return a - b}); 
           

使用相同的技巧對數組進行降序排序:

var points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return b - a}); 
           

以随機順序排序數組

var points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return 0.5 - Math.random()}); 
           

查找最高(或最低)的數組值

在對數組進行排序之後,您能夠使用索引來獲得最高或最低值。

也可以使用 Math.max.apply 來查找數組中的最高值:

function myArrayMax(arr) {
    return Math.max.apply(null, arr);
}
           

Math.max.apply([1, 2, 3]) 等于 Math.max(1, 2, 3)。

可以使用 Math.min.apply 來查找數組中的最低值:

function myArrayMin(arr) {
    return Math.min.apply(null, arr);
}
           

Math.min.apply([1, 2, 3]) 等于 Math.min(1, 2, 3)。

排序對象數組

JavaScript 數組經常會包含對象:

var cars = [
{type:"Volvo", year:2016},
{type:"Saab", year:2001},
{type:"BMW", year:2010}];
           

即使對象擁有不同資料類型的屬性,sort() 方法仍可用于對數組進行排序。

解決方法是通過比較函數來對比屬性值:

cars.sort(function(a, b){return a.year - b.year});
           

數組疊代

Array.forEach()

forEach() 方法為每個數組元素調用一次函數(回調函數)。

var txt = "";
var numbers = [45, 4, 9, 16, 25];
numbers.forEach(myFunction);

function myFunction(value, index, array) {
  txt = txt + value + "<br>"; 
}
           

三個參數: 

  • 項目值
  • 項目索引
  • 數組本身

Array.map() 

map() 方法通過對每個數組元素執行函數來建立新數組,不會對沒有值的數組元素執行函數,不會更改原始數組。

這個例子将每個數組值乘以2:

var numbers1 = [45, 4, 9, 16, 25];
var numbers2 = numbers1.map(myFunction);

function myFunction(value, index, array) {
  return value * 2;
}
           

Array.filter()

filter() 方法建立一個包含通過測試的數組元素的新數組。

這個例子用值大于 18 的元素建立一個新數組:

var numbers = [45, 4, 9, 16, 25];
var over18 = numbers.filter(myFunction);

function myFunction(value, index, array) {
  return value > 18;
}
           

Array.reduce()

reduce() 方法在每個數組元素上運作函數,以生成(減少它)單個值,在數組中從左到右工作,不會減少原始數組。

這個例子确定數組中所有數字的總和:

var numbers1 = [45, 4, 9, 16, 25];
var sum = numbers1.reduce(myFunction);

function myFunction(total, value, index, array) {
  return total + value;
}
           

此函數接受 4 個參數: 

  • 總數(初始值/先前傳回的值)
  • 項目值
  • 項目索引
  • 數組本身

reduce() 方法能夠接受一個初始值:

var sum = numbers1.reduce(myFunction, 100);
           

 Array.reduceRight()

reduceRight() 方法在每個數組元素上運作函數,以生成(減少它)單個值,在數組中從右到左工作,不會減少原始數組。

這個例子确定數組中所有數字的總和:

var numbers1 = [45, 4, 9, 16, 25];
var sum = numbers1.reduceRight(myFunction);

function myFunction(total, value, index, array) {
  return total + value;
}
           

Array.every()

every() 方法檢查所有數組值是否通過測試。

這個例子檢查所有數組值是否大于 18,傳回true或false:

var numbers = [45, 4, 9, 16, 25];
var allOver18 = numbers.every(myFunction);

function myFunction(value, index, array) {
  return value > 18;
}
           

 Array.some()

some() 方法檢查某些數組值是否通過了測試。

這個例子檢查某些數組值是否大于 18,隻要有一個滿足就是true:

var numbers = [45, 4, 9, 16, 25];
var someOver18 = numbers.some(myFunction);

function myFunction(value, index, array) {
  return value > 18;
}
           

Array.indexOf()

indexOf() 方法在數組中搜尋元素值并傳回其位置。

注釋:第一個項目的位置是 0,第二個項目的位置是 1,以此類推。

檢索數組中的項目 "Apple":

var fruits = ["Apple", "Orange", "Apple", "Mango"];
var a = fruits.indexOf("Apple");
           

文法:array.indexOf(item, start)。

item 必需。要檢索的項目。
start 可選。從哪裡開始搜尋。負值将從結尾開始的給定位置開始,并搜尋到結尾。

如果未找到項目,Array.indexOf() 傳回 -1。

如果項目多次出現,則傳回第一次出現的位置。

Array.lastIndexOf()

Array.lastIndexOf() 與 Array.indexOf() 類似,但是從數組結尾開始搜尋。

檢索數組中的項目 "Apple":

var fruits = ["Apple", "Orange", "Apple", "Mango"];
var a = fruits.lastIndexOf("Apple");
           

Array.find()

find() 方法傳回通過測試函數的第一個數組元素的值。

這個例子查找(傳回)大于 18 的第一個元素的值:

var numbers = [4, 9, 16, 25, 29];
var first = numbers.find(myFunction);

function myFunction(value, index, array) {
  return value > 18;
}
           

Array.findIndex()

findIndex() 方法傳回通過測試函數的第一個數組元素的索引。

這個例子查找大于 18 的第一個元素的索引:

var numbers = [4, 9, 16, 25, 29];
var first = numbers.findIndex(myFunction);

function myFunction(value, index, array) {
  return value > 18;
}
           

數組 Const

用 const 聲明的數組不能重新指派,const 變量在聲明時必須指派:

const cars = ["Saab", "Volvo", "BMW"];
cars = ["Toyota", "Volvo", "Audi"];    // ERROR
           

關鍵字 const 有一定誤導性。

它不定義常量數組。它定義的是對數組的常量引用。

是以,我們仍然可以更改常量數組的元素。

// 您可以建立常量數組:
const cars = ["Saab", "Volvo", "BMW"];

// 您可以更改元素:
cars[0] = "Toyota";

// 您可以添加元素:
cars.push("Audi");
           

用 const 聲明的數組具有塊作用域。

在塊中聲明的數組與在塊外聲明的數組不同。

繼續閱讀