成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

2019秋招知識(shí)盲點(diǎn)總結(jié)

Doyle / 2856人閱讀

摘要:實(shí)際上是一個(gè)讓出線程的標(biāo)志遇到會(huì)立即返回一個(gè)狀態(tài)的。一個(gè)簡(jiǎn)單的防抖函數(shù)如果定時(shí)器存在則清除重新開(kāi)始定時(shí)執(zhí)行缺點(diǎn)只能在最后執(zhí)行,不能立即被執(zhí)行,在某些情況下不適用。假設(shè)壓入棧的所有數(shù)字均不相等。接收數(shù)據(jù)不受同源政策限制。

開(kāi)始

盡管秋招還沒(méi)有拿到offer(好難過(guò)),但是一些知識(shí)點(diǎn)還是要總結(jié)的,既然自己選了這條路,那就一定要堅(jiān)定不移的走下去......

注意 new 運(yùn)算符的優(yōu)先級(jí)
function Foo() {
    return this;
}
Foo.getName = function () {
    console.log("1");
};
Foo.prototype.getName = function () {
    console.log("2");
};

new Foo.getName();   // -> 1
new Foo().getName(); // -> 2       

通過(guò)這段代碼可以看出:new Foo() 的優(yōu)先級(jí)高于 new Foo.

對(duì)于代碼1 來(lái)說(shuō):是將 Foo.getName 當(dāng)成一個(gè)構(gòu)造函數(shù)來(lái)執(zhí)行,執(zhí)行構(gòu)造函數(shù)所以輸出為1.

對(duì)于代碼2來(lái)說(shuō):通過(guò) new Foo() 創(chuàng)建了一個(gè)Foo的實(shí)例,通過(guò)實(shí)例訪問(wèn)其原型鏈上的 方法所以輸出為2.

注意非匿名的立即執(zhí)行函數(shù)
var foo = 1;
 
// 有名立即執(zhí)行函數(shù)
(function foo() {
    foo = 10;
    console.log(foo);
})();

// 執(zhí)行這段代碼會(huì)輸出什么呢?

// -> ? foo() { foo = 10 ; console.log(foo) }

// 再去訪問(wèn) foo 的值
foo
// -> 1

當(dāng)JS執(zhí)行器遇到非匿名的立即執(zhí)行函數(shù)時(shí),會(huì)創(chuàng)建一個(gè)輔助的特定對(duì)象,然后將函數(shù)名稱作為這個(gè)對(duì)象的屬性,因此行數(shù)內(nèi)部才可以訪問(wèn)到 foo ,但這個(gè)值是只讀的,所以對(duì)其重新賦值不會(huì)生效,所以打印結(jié)果還是這個(gè)函數(shù),并且外部的值也沒(méi)有發(fā)生改變。

關(guān)于對(duì)象的深拷貝

可以使用 JSON.stringifyJSON.parse 這個(gè)兩個(gè)方法

優(yōu)點(diǎn):簡(jiǎn)單

缺點(diǎn):會(huì)忽略掉 undefined ; 不能序列化函數(shù) ; 不能解決循環(huán)引用的對(duì)象

function clone(obj) {
    return JSON.parse(JSON.stringify(obj));
}

使用遞歸循環(huán)賦值的方式

優(yōu)點(diǎn):可以處理 undefined、函數(shù)等各種情況

缺點(diǎn):實(shí)現(xiàn)相對(duì)麻煩,效率不高

function clone(obj) {
    if(!obj || typeof obj !== "object") {
        return;
    }
    var _obj = obj.constructor === Object ? {} : [];
    for(let key in obj) {
        if(typeof obj[key] === "object") {
            _obj[key] = clone(obj[key]);
        } else {
            _obj[key]  = obj[key];
        }
    }
    return _obj;
}

// 或者

function clone(obj) {
    if(!obj || typeof obj !== "object")
        throw new TypeError("params typeError");
    let _obj = obj.constructor === Object ? {} : [];
    Object.getOwnPropertyNames(obj).forEach(name => {
        if(typeof obj[name] === "object") {
            _obj[name] = clone(obj[name]);
        } else {
            _obj[name] = obj[name];
        }
    });
    return _obj;
}

使用內(nèi)置 MessageChannel 對(duì)象

優(yōu)點(diǎn):是內(nèi)置函數(shù)中處理深拷貝性能最快的

缺點(diǎn):不能處理函數(shù)(會(huì)報(bào)錯(cuò))

function clone(obj) {
    return new Promise(resolve => {
        let {port1, port2} = new MessageChannel();
        port2.onmessage = ev => resolve(ev.data);
        port1.postMessage(obj);
    });    
}

clone(obj).then(console.log);

關(guān)于async/await , promise 異步執(zhí)行順序
想解決這個(gè)問(wèn)題,就必須知道 `await` 做了什么?
剛開(kāi)始以為 await 會(huì)一直等待表達(dá)執(zhí)行的執(zhí)行結(jié)果,之后才會(huì)執(zhí)行后面的代碼。實(shí)際上 await 是一個(gè)讓出線程的標(biāo)志(遇到 await 會(huì)立即返回一個(gè) pending 狀態(tài)的promise)。await后面的函數(shù)會(huì)先執(zhí)行一遍,然后就會(huì)跳出整個(gè) async 函數(shù)來(lái)執(zhí)行后面js代碼。等本輪事件循環(huán)執(zhí)行完又跳回到 async 函數(shù)中等待await后面表達(dá)式的返回值,如果返回值為非 promise 則繼續(xù)執(zhí)行async后面的代碼,否則將 promse 加入隊(duì)列。

且看一道面試題(分析代碼執(zhí)行 順序):

async function async1() {
    console.log("async1 start");
    await async2();
    console.log("async1 end");
}

async function async2() {
   console.log("async2");
}

console.log("script start");

setTimeout(function () {
    console.log("settimeout");
},0);

async1();

new Promise(function (resolve) {
    console.log("promise1");
    resolve();
}).then(function () {
    console.log("promise2");
});

console.log("script end");

OK,那接下來(lái)具體分析執(zhí)行過(guò)程:

首先輸出 "script start" ,然后立即將定時(shí)器加入異步事件隊(duì)列。執(zhí)行 async1() ,輸出 "async1 start" ,進(jìn)入 async2() ,輸出 "async2" ,跳出整個(gè) async1() 函數(shù)來(lái)執(zhí)行后面js代碼,執(zhí)行promise執(zhí)行器中的內(nèi)容,輸出 "promise1" ,執(zhí)行resolve()回調(diào),將then函數(shù)中的內(nèi)容加入異步事件隊(duì)列,接著輸出 "script end" ?;氐?async1() 的await等待 async2() 函數(shù)的返回值,因?yàn)榉祷刂凳且粋€(gè)promise實(shí)例,將promise加入異步事件隊(duì)列。此時(shí)的同步代碼執(zhí)行完畢,輪詢并從隊(duì)列拿出代碼放入主線程執(zhí)行,所以輸出 "promise2" ,繼續(xù)執(zhí)行 async1() 中的后續(xù)內(nèi)容,輸出 "async1 end" ,最后取出定時(shí)器中的內(nèi)容并執(zhí)行,輸出 "settimeout" 。

綜上所述:

script start
async1 start
async2
promise1
script end
promise2
async1 end
settimeout

那么再看一個(gè)例子應(yīng)該會(huì)簡(jiǎn)單很多:

function testFunc() {
    console.log("testFunc..."); // 2
    return "testFunc";
}

async function testAsync() {
    console.log("testAsync...");  // 7
    return Promise.resolve("hello testAsync");
}

async function foo() {
    console.log("test start..."); // 1
    const v1 = await testFunc();
    connsole.log("hello world."); // 5
    console.log(v1);              // 6 testFunc
    const v2 = await testAsync();
    console.log(v2);              // 9 hello testAsync
}

foo();

var promise = new Promise(resolve => { 
    console.log("promise start..");  // 3
    resolve("promise"); 
});
promise.then(val => console.log(val)); // 8 promise

console.log("test end..."); // 4
防抖和節(jié)流

防抖:如果用戶多次調(diào)用且間隔小于wait值,那么就會(huì)被轉(zhuǎn)化為一次調(diào)用。

節(jié)流:多次執(zhí)行函數(shù)轉(zhuǎn)化為,每隔一定時(shí)間(wait)調(diào)用函數(shù) 。

一個(gè)簡(jiǎn)單的防抖函數(shù):

function debounce(func, wait) {
    let timer = null;
    return function(...params) {
        // 如果定時(shí)器存在則清除
        if(timer){
            clearTimeout(timer);
        }
        // 重新開(kāi)始定時(shí)執(zhí)行
        timer = setTimeout(() => {
            func.apply(this, params);
        }, wait);
    }
}

缺點(diǎn):只能在最后執(zhí)行,不能立即被執(zhí)行,在某些情況下不適用。

改進(jìn)...

function debounce(func, wait, immediate) {
    
    let timer, context, args;
    
    // 定時(shí)器
    let later = function() {
        return setTimeout(() => {
            timer = null;
            if(!immediate) {
                func.apply(context, args);
            }
        }, wait);
    }
    
    return function(...params) {
        if(!timer) {
            timer = later();
            
            // immediate 為 true,則立即執(zhí)行
            // 否則 緩存上下文 和 參數(shù)
            if(immediate) {
                func.apply(this, params);
            } else {
                context = this;
                args = params;
            }
        } else {
            clearTimeout(timer);
            timer = later();
        }           
    }
}

一個(gè)簡(jiǎn)單的節(jié)流函數(shù):

// 節(jié)流函數(shù)
// 快速的多次執(zhí)行,轉(zhuǎn)化為等待wait時(shí)間再去執(zhí)行
function throttle(func, wait) {
    var timer = null;
    var context = null;
    return function(...args) {
        context = this;
        if(!timer) {
            timer = setTimeout(function() {
                timer = null;
                func.apply(context, args);
            }, wait);
        }
    }
}

// 如果想讓第一次調(diào)用立即執(zhí)行也非常簡(jiǎn)單
僅需要將  func.apply(context, args) 提到定時(shí)器外邊即可。

節(jié)流函數(shù)除了可以使用定時(shí)器實(shí)現(xiàn)以外,當(dāng)然也可以有其他方式:

// 第一次調(diào)用會(huì)被立即執(zhí)行
function throttle(func, wait) {
    var prev = 0;
    var context = null;
    return function(...args) {
        var now = +new Date();
        context = this;
        if(now -prev > wait) {
            func.apply(context,args);
            prev = now;
        }    
    }
}
call、apply和bind

怎么去模擬一個(gè)call函數(shù)呢?

思路:call一個(gè)非常重要的作用就是改變上下文環(huán)境也就是this,我們可以給用戶傳入的上下文對(duì)象上添加一個(gè)函數(shù),通過(guò)這個(gè)上下文對(duì)象去執(zhí)行函數(shù),然后將這個(gè)函數(shù)刪除,返回結(jié)果就可以了。

Function.prototype.myCall = function(context, ...args) {
    context = context || window;
    // 給上下文對(duì)象上添加這個(gè)函數(shù)
    context.fn = this;
    // 通過(guò)這個(gè)上下文對(duì)象去執(zhí)行函數(shù)
    let result = context.fn(...args);
    // 將這個(gè)函數(shù)刪除
    delete  context.fn;
    return result;
}

call既然都實(shí)現(xiàn)了,那么apply也是類似的,只不過(guò)傳入的參數(shù)是一個(gè)數(shù)組而已。

Function.prototype.myApply = function(context, arr) {
    context = context || window;
    arr = arr || [];
    let type = {}.toString.call(arr).slice(8,-1);
    if(type !== "Array")
        throw new TypeError("CreateListFromArrayLike called on non-object");
    context.fn = this;
    let result = context.fn(...arr);
    delete context.fn;
    return result;
}

模擬bind函數(shù),bind函數(shù)應(yīng)該返回一個(gè)新的函數(shù)。

Function.prototype.myBind  = function(context, ...args) {        
    // 保存當(dāng)前的函數(shù)
    let func = this;
    return function F(...params) {
        if(this instanceof F) {
            return new func(...args, ...params);
        }
        return func.apply(context,[...args,...params]);
    }    
}
數(shù)組降維
function flattenDeep(arr) {
    if(!Array.isArray(arr))
        return [arr];
    return arr.reduce((prev,cur) => {        
        return [...prev, ...flattenDeep(cur)];
    },[]);
}

flattenDeep([1, [[2], [3, [4]], 5]]);
棧的壓入和彈出

輸入兩個(gè)整數(shù)序列,第一個(gè)序列表示棧的壓入順序,請(qǐng)判斷第二個(gè)序列是否可能為該棧的彈出順序。假設(shè)壓入棧的所有數(shù)字均不相等。例如序列1,2,3,4,5是某棧的壓入順序,序列4,5,3,2,1是該壓棧序列對(duì)應(yīng)的一個(gè)彈出序列,但4,3,5,1,2就不可能是該壓棧序列的彈出序列。

function IsPopOrder(pushV,popV){
    if(pushV.length === 0) return false;
    var stack = []; // 模擬棧
    for(var i = 0, j = 0; i < pushV.length;){
        stack.push(pushV[i]);
        i += 1;
        // 壓入棧的值需要被彈出
        while(j < popV.length && stack[stack.length-1] === popV[j]){
            stack.pop();
            j++;
            if(stack.length === 0) break;
        }
    }
    return stack.length === 0;
}
利用棧模擬隊(duì)列

思路:

對(duì)棧A添加數(shù)據(jù)。

如果棧B為空,循環(huán)將棧A中內(nèi)容彈出放入棧B,并彈出棧B最后一項(xiàng)

如果棧B不為空,則直接彈出棧B的最后一項(xiàng)

var stackA = [];
var stackB = [];

function push(node){
    stackA.push(node);
}
function pop(){
    if(!stackB.length){
        while(stackA.length){
            stackB.push(stackA.pop());
        }
    }
    return stackB.pop();
}
Fetch和ajax之間的區(qū)別

fetch

Fetch API是基于Promise設(shè)計(jì)的

容易同構(gòu)(前后端運(yùn)行同一套代碼)

語(yǔ)法簡(jiǎn)潔,更加語(yǔ)義化

原生支持率不高,可以用polyfill兼容IE8+瀏覽器

fetch(url).then(function(response){
    return response.json();
}).then(function(data){
    console.log(data);
}).catch(function(err){
    console.log(err);
});

ajax

設(shè)計(jì)粗糙,不關(guān)注分離原則

基于事件的異步模型,不夠友好

var xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.responseType = "json";

xhr.onload = function(){
    console.log(xhr.response);
}
xhr.onerror = function(){
    console.log("error");
}

xhr.send();
Fetch常見(jiàn)坑

fetch請(qǐng)求默認(rèn)是不帶cookie的,需要設(shè)置 fetch(url, {credentials: "include"})

服務(wù)器返回400,500錯(cuò)誤碼時(shí)不會(huì)reject,只有網(wǎng)絡(luò)錯(cuò)誤導(dǎo)致不能完成時(shí),才會(huì)reject。

IE8, 9 的 XHR 不支持 CORS 跨域。

歸并排序

將一個(gè)完整的數(shù)組分成兩部分,分別對(duì)其排序,然后將兩部分merge在一起即可。

function merge(left, right) {
    var temp = [];
    while(left.length && right.length) {        
        if(left[0] < right[0])
            temp.push(left.shift());
        else
            temp.push(right.shift());        
    }
    return temp.concat(left,right);
}

function mergeSort(arr) {
    if(arr.length === 1)
        return arr;
    var mid = (arr.length/2)|0;
    var left = arr.slice(0,mid);
    var right = arr.slice(mid);    
    return merge(mergeSort(left), mergeSort(right));
}
箭頭函數(shù)的this原理

this 指向固定化,并不是因?yàn)榧^函數(shù)內(nèi)部有綁定 this 的機(jī)制,實(shí)際原因是箭頭函數(shù)沒(méi)有自己的 this ,導(dǎo)致內(nèi)部的this就是外層代碼的 this ,也正是因?yàn)闆](méi)有 this ,所以箭頭函數(shù)不能用作構(gòu)造函數(shù)。

js相關(guān)尺寸

BFC原理

在BFC垂直方向元素邊距會(huì)發(fā)生重疊

不會(huì)與浮動(dòng)元素的box重合

獨(dú)立的容器,里外互不影響

浮動(dòng)元素參與計(jì)算

自定義事件

  var content = document.querySelector(".content");
    // 自定義事件
    var evt = new Event("custom");
    var customEvt = new CustomEvent("customEvt", {
        // 通過(guò)這個(gè)屬性傳遞參數(shù)
        detail: {
            name: "tom",
            age: 12
        }
    });
    content.addEventListener("custom", (e) => {
        console.log("自定義事件被觸發(fā),無(wú)參數(shù)...");
        console.log(e);
    });
    content.addEventListener("customEvt", (e) => {
        console.log("自定義事件被觸發(fā),有參數(shù)...");
        console.log(e);
        console.log(e.detail);
    });
    // 點(diǎn)擊時(shí)觸發(fā)這個(gè)自定義事件
    content.addEventListener("click", (e) => {
        content.dispatchEvent(evt);
        content.dispatchEvent(customEvt);
    });
變量提升
var foo = 3; // 不在同一個(gè)作用域

function hoistVariable() {
    // 內(nèi)部變量提升導(dǎo)致 foo 的初始值為undefined
    // 所以 foo = 5;
    var foo = foo || 5;
    console.log(foo); // 5
}

hoistVariable();

上邊的比較簡(jiǎn)單,看一個(gè)函數(shù)和變量同名,關(guān)于變量提升的小問(wèn)題。

var a = 6;
function b(){
    console.log(a); // @1
    var a = 4;
    function a(){
        alert(4);
    }
    console.log(a); //@2
}
b();

因?yàn)镴avaScript中的函數(shù)是一等公民,函數(shù)聲明的優(yōu)先級(jí) 最高(高于變量提升),會(huì)被提升至當(dāng)前作用域最頂端,所以在 @1 輸出的是 function a(){alert(4);}

接下來(lái)執(zhí)行 a=4; 這一句,重新對(duì) a 進(jìn)行賦值。

函數(shù)已被提升,所以不考慮,所以在 @2 這里自然會(huì)輸出 4

如果還不能理解?且看預(yù)編譯后的代碼:

var a;
a = 6;
function b(){
    var a; 
    a = function a(){ // 函數(shù)先提升
        alert(4);
    }
    console.log(a); // @1
    a = 4;
    console.log(a); // @2    
}
b(); // 結(jié)果已經(jīng)非常明了了
POST和GET的區(qū)別

POST對(duì)請(qǐng)求參數(shù)的長(zhǎng)度沒(méi)有限制,而GET如果請(qǐng)求參數(shù)過(guò)長(zhǎng),會(huì)被瀏覽器截?cái)唷?/p>

GET請(qǐng)求參數(shù)會(huì)直接暴露在URL上,所以不適合用來(lái)傳遞敏感信息。

GET請(qǐng)求可以被瀏覽器主動(dòng)緩存,而POST請(qǐng)求不可以,除非手動(dòng)設(shè)置。

GET請(qǐng)求在瀏覽器回退時(shí)是無(wú)害的,而POST會(huì)再次提交請(qǐng)求。

GET請(qǐng)求產(chǎn)生的URL可以被瀏覽器緩存,而POST不可以。

通信類

1. 前后端如何通信?

ajax

WebSocket

CORS

2. 如何創(chuàng)建ajax?

// 創(chuàng)建xhr對(duì)象
var xhr = XMLHttpRequest ? new XMLHttpRequest() : new window.ActiveXObject("Microsoft.XMLHTTP");

// GET 請(qǐng)求
xhr.open("GET",url,true);
xhr.send();

// POST 請(qǐng)求
xhr.open("POST",url,true);
// 表單數(shù)據(jù) , 也可以提交json數(shù)據(jù),相應(yīng)的content-Type: application/json
xhr.setRequestHeader("content-Type", "application/x-www-from-urlencoded");
xhr.send(dataArr.join("&"));

xhr.onload = function() {
    if(xhr.status === 200 || xhr.status === 304) {    
        var data = xhr.responseText;
        // 拿到數(shù)據(jù)
    } else {
        // 出問(wèn)題了
    }
}

3. 跨域通信的幾種方式?

JSONP:利用 script 標(biāo)簽的跨域能力,服務(wù)返回一個(gè)js函數(shù)調(diào)用,數(shù)據(jù)作為函數(shù)的一個(gè)參數(shù)來(lái)傳遞。

var script = document.createElement("script");
script.type = "text/javascript";
script.src = url; // 跨域地址
document.head.appendChild(script);

//有能耐把我這輩子都安排了,不然少他媽扯淡。
setTimeout(function() {
    document.head.removeChild(script);
    script = null;
});

// 接收數(shù)據(jù)
function jsonpCallback(data) {
    console.log(data);
}

WebSocket:不受同源政策限制。

var ws = new WebSocket("wss://echo.websocket.org");
ws.onopen = function(e) {
    ws.send("hello...");
}
ws.onmessage = function(e) {
    var data = e.data;
}
ws.onclose = function() {
    console.log("close...");
}

Hash:利用 location.hash 來(lái)傳值。 缺點(diǎn):數(shù)據(jù)直接暴露在url中,大小、類型都有限制。

1、父窗體可以把信息寫(xiě)在子窗體的href的hash上,子窗口通過(guò)監(jiān)聽(tīng)hashchange事件獲取信息。

2、子窗體改變父窗體的hash值,那么就要借助第三個(gè)子窗體,第三個(gè)子窗體是第二個(gè)子窗體的子窗體。(第三個(gè)子窗體要與父窗體同源)

3、第二個(gè)子窗體把信息設(shè)置在第三個(gè)子窗體的hash值上,然后第三個(gè)子窗體改變父窗體的hash值,從而實(shí)現(xiàn)跨域。

// 父窗體
var son = document.getElementByTagName("iframe");
son.src = son.src + "#" + data;

// 子窗體
window.onhashchange = function() {
    var data = window.location.hash;
}

postMessage :語(yǔ)法:window.postMessage(msg,targetOrigin)

// 窗口A 發(fā)送
BWindow.postMessage("發(fā)送的數(shù)據(jù)", "http://B.com");

// 窗口B 接收
window.addEventListener("message", (event) => {
   event.origin: // http://A.com
   event.source; // AWindow
   event.data;   // "發(fā)送的數(shù)據(jù)" 
});

CORS: 跨域資源共享。

fetch(url, {
    method: "get",
    // 頭信息配置
}).then(() => {});

安全類

CSRF,跨站請(qǐng)求偽造(Cross-site request forgery)

防御措施:

Token驗(yàn)證(請(qǐng)求必須攜帶Token)

Referer 驗(yàn)證(驗(yàn)證請(qǐng)求的來(lái)源是否可信)

XSS(cross-site scripting 跨站腳本攻擊)

原理:注入腳本

防御措施:對(duì)用戶的輸入做驗(yàn)證

渲染機(jī)制類

1. 什么是DOCTYPE及作用?

用來(lái)聲明文檔類型和DTD規(guī)范的。

DTD(document type definition)文檔類型定義,是一系列的語(yǔ)法規(guī)則,用來(lái)聲明XML或(X)HTML的文件類型,瀏覽器會(huì)使用它來(lái)決定文檔類型,決定使用何種協(xié)議來(lái)解析,以及切換瀏覽器模式。

2. 常見(jiàn)的doctype有哪些?

HTML5

HTML4.01 Strict 嚴(yán)格模式 (不包含展示性或棄用的元素)

HTML4.01 Transitional 傳統(tǒng)(寬松)模式(包含展示性或棄用的元素)

頁(yè)面性能類

提升頁(yè)面性能的方式?

資源壓縮合并,減少HTTP請(qǐng)求

非核心代碼異步加載

異步加載方式:

動(dòng)態(tài)腳本加載

defer (HTML解析完順序執(zhí)行)

async (加載完立即執(zhí)行)

利用瀏覽器緩存

使用CDN

預(yù)解析DNS


錯(cuò)誤監(jiān)控

前端錯(cuò)誤分類:代碼(運(yùn)行)錯(cuò)誤 資源加載錯(cuò)誤

錯(cuò)誤捕獲方式

運(yùn)行錯(cuò)誤捕獲:(1)try...catch (2)window.onerror

資源加載錯(cuò)誤 :(1)object.onerror(資源錯(cuò)誤不冒泡) (2)performance.getEntries() (3)Error事件捕獲(在事件流捕獲階段處理錯(cuò)誤)

跨域js運(yùn)行錯(cuò)誤也是可以捕獲的,捕獲的錯(cuò)誤:script error

上報(bào)錯(cuò)誤原理

利用Image對(duì)象上報(bào)

// 利用Image標(biāo)簽上報(bào)錯(cuò)(簡(jiǎn)單、不需要借助其他庫(kù))
(new Image()).src = "http://www.baidu.com/test?error=xxx";

二分法查找
function binarySearch(arr,val,leftIndex,rightIndex) {
    if(leftIndex > rightIndex){ return; }
    var midIndex = (leftIndex + rightIndex) / 2 | 0;
    var midVal = arr[midIndex];
    if(val > midVal) {
        return binarySearch(arr,val,midIndex+1,rightIndex);
    }else if(val < midVal) {
        return binarySearch(arr,val,leftIndex,midIndex-1);
    }else{
        return midIndex;
    }
}
連續(xù)最長(zhǎng)不重復(fù)字符串

在一個(gè)字符串中找出連續(xù)的不重復(fù)的最大長(zhǎng)度的字符串,解決這類問(wèn)題的思路:

利用循環(huán)疊加字符串,直到出現(xiàn)重復(fù)為止

每一次疊加,記錄下來(lái)最大長(zhǎng)度的字符串

// 連續(xù)最長(zhǎng)不重復(fù)字符串
function getMaxLenStr(str) {
    var cur = [];
    var maxLenStr = "";
    for(var i = 0; i < str.length; i++) {
        if(!cur.includes(str[i])) {
            cur.push(str[i]);
        } else {
            cur = []; // 置為空
            cur.push(str[i]);
        }
        
        // 存儲(chǔ)最大長(zhǎng)度的字符串
        if(maxLenStr.length < cur.length) {
            maxLenStr = cur.join("");
        }        
    }
    return maxLenStr;
}

getMaxLenStr("ababcabcde"); // abcde

和上面這道題有一樣思路的是:求一個(gè)數(shù)組當(dāng)中,連續(xù)子向量的最大和。

無(wú)非是將 對(duì)比字符串的長(zhǎng)度 改為 對(duì)比值大小

function FindGreatestSumOfSubArray(arr) {
    let sum = arr[0];
    let max = arr[0];
    for(let i = 1; i < arr.length; i++) {
        if(sum < 0) {
            sum = arr[i];
        }else{
            sum += arr[i];
        }
        // 記錄最大值
        if(max < sum) {
            max = sum;
        }
    }
    return max;
} 
面試題:解碼字符串并輸出

阿里的一道面試題:給定一個(gè)編碼字符,按編碼規(guī)則進(jìn)行解碼,輸出字符串

編碼規(guī)則:coount[letter] ,將letter的內(nèi)容count次輸出,count是0或正整數(shù),letter是區(qū)分大小寫(xiě)的純字母。

實(shí)例:

const s= 3[a]2[bc]; decodeString(s); // 返回 ‘a(chǎn)aabcbc’

const s= 3[a2[c]]; decodeString(s); // 返回 ‘a(chǎn)ccaccacc’

const s= 2[ab]3[cd]ef; decodeString(s); // 返回 ‘a(chǎn)babcdcdcdef’

解題過(guò)程...

思路:

使用棧這種數(shù)據(jù)結(jié)構(gòu),如果push的內(nèi)容為‘]’,則循環(huán)pop字符,直到碰到’[‘,然后將pop

出來(lái)的字符串按規(guī)則整理后,重新push進(jìn)棧中,最后將棧內(nèi)的內(nèi)容拼接成字符串輸出即可。

代碼:

const s = "2[a2[c]]ef";
function decodeString(str) {
    let stack = []; // 存儲(chǔ)字符串的棧
    for (let i = 0; i < str.length; i++) {
        let cur = str[i];
        if (cur !== "]") {
            stack.push(cur);
        } else { // 彈出
            let count = 0;
            let loopStr = [];
            let popStr = "";
            while ((popStr = stack.pop()) !== "[") {
                loopStr.unshift(popStr);
            }
            count = stack.pop();
            // 添加結(jié)果
            let item = "";
            for (let i = 0; i < count; i++) {
                item += loopStr.join("");
            }
            stack.push(...(item.split("")));
        }
    }
    return stack.join("");
}
console.log(decodeString(s)); // accaccef

排序算法時(shí)間復(fù)雜度

元素的移動(dòng)次數(shù)與關(guān)鍵字的初始排列次序無(wú)關(guān)的是:基數(shù)排列。

元素的比較次數(shù)與初始序列無(wú)關(guān)是:選擇排序。

算法的時(shí)間復(fù)雜度與初始序列無(wú)關(guān)的是:選擇排序。

BOM和DOM

BOM 即瀏覽器對(duì)象模型,BOM沒(méi)有相關(guān)標(biāo)準(zhǔn),BOM的核心對(duì)象是window對(duì)象。

DOM即文檔對(duì)象模型,DOM是W3C標(biāo)準(zhǔn),DOM的最根本對(duì)象是document(window.document), 這個(gè)對(duì)象實(shí)際上是window對(duì)象的屬性,這個(gè)對(duì)象的獨(dú)特之處是唯一一個(gè)既屬于BOM有屬于DOM的對(duì)象。

http和WebSocket的區(qū)別:

相同點(diǎn):

都是建立于tcp連接之上,通過(guò)tcp協(xié)議來(lái)傳輸數(shù)據(jù)。

不同點(diǎn):

HTTP是一種單向的協(xié)議,即客戶端只能向服務(wù)器端請(qǐng)求信息。request永遠(yuǎn)等于response,并且這個(gè)response是被動(dòng)的,不能主動(dòng)發(fā)起。一旦有一個(gè)任務(wù)超時(shí),就會(huì)阻塞后續(xù)的任務(wù)(線頭阻塞)。

HTTP協(xié)議是無(wú)狀態(tài)的,如使用輪詢、long poll都需要將身份鑒別信息上傳。

WebSocket真正的全雙工通信,只需要一次連接,這樣就避免了HTTP的無(wú)狀態(tài)性,服務(wù)器端可以主動(dòng)推送消息到達(dá)客戶端。

http2.0

二進(jìn)制分幀

多路復(fù)用,這樣就避免了線頭阻塞

服務(wù)器端推送,客戶端請(qǐng)求HTML,服務(wù)器可以主動(dòng)推送js、css那些客戶端可能會(huì)用到的東西,這樣就避免了重復(fù)發(fā)送請(qǐng)求

頭壓縮

O(n)復(fù)雜度去重
function unique(arr) {
    let obj = {};
    let ret = [];
    for(let i = 0; i < arr.length; i++) {
        let cur = `${typeof arr[i]}-${arr[i]}`;
        if(!obj[cur]) {
            ret.push(arr[i]);
            obj[cur] = true;
        }
    }        
    return ret;
}

var arr = [1, "1", 3, 3, 4];
unique(arr);
// [1, "1", 3, 4]
判斷是否相同
function isSame(a, b) {
    if(a === b) return true;
    if(typeof a !== typeof b) return false;
    
    // 如果均為object類型,判斷屬性個(gè)數(shù)是否相同
    if(typeof a === "object" && typeof b === "object") {
        let aLen = Object.getOwnPropertyNames(a).length;
        let bLen = Object.getOwnPropertyNames(b).length;
        if(aLen !== bLen) return false;
    }
    return Object.getOwnPropertyNames(a).every(key => {
        if(typeof a[key] === "object") {
            return isSame(a[key], b[key]);
        }
        return a[key] === b[key];
    });
}  

后記一波:

付出了總歸是有回報(bào)的。

電話面試拿到了百度云事業(yè)部實(shí)習(xí)生的offer。

南京現(xiàn)場(chǎng)面試獲得了上海微盟的offer。

參加北京的面試得到了迅雷的offer。簽約那天剛好是中秋節(jié)(2018/9/24),可能是一份最棒的中秋大禮了吧

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/97597.html

相關(guān)文章

  • 【Java】廣州三本秋招經(jīng)歷

    摘要:具體的時(shí)間線從月中旬,我開(kāi)始關(guān)注??途W(wǎng)的秋招內(nèi)推信息。直至十月中下旬結(jié)束秋招。之前也寫(xiě)過(guò)自己在廣州找實(shí)習(xí)的經(jīng)歷,那次把面試的過(guò)程都具體貼出來(lái)了。我今年就完美錯(cuò)過(guò)了春招實(shí)習(xí)經(jīng)歷。 前言 只有光頭才能變強(qiáng) 離上次發(fā)文章已經(jīng)快兩個(gè)月時(shí)間了,最近一直忙著秋招的事。今天是2018年10月22日,對(duì)于互聯(lián)網(wǎng)行業(yè)來(lái)說(shuō),秋招就基本結(jié)束了。我這邊的流程也走完了(不再筆試/面試了),所以來(lái)寫(xiě)寫(xiě)我的秋招經(jīng)歷...

    qqlcbb 評(píng)論0 收藏1
  • 資深前端面試官的建議,助你走進(jìn)阿里

    摘要:適當(dāng)引導(dǎo)面試官。如果有機(jī)會(huì)來(lái)實(shí)習(xí),如何最有效的快速成長(zhǎng)淘寶技術(shù)部前端內(nèi)部有針對(duì)新同學(xué)的前端夜校,有專門的老師授課。 阿里巴巴2019前端實(shí)習(xí)生招聘還剩最后兩周,面向2019年11月1日至2020年10月31日之間畢業(yè)的同學(xué),在這里分享下阿里前端面試考核的關(guān)鍵點(diǎn): Q:在面試過(guò)程中,前端面試官如何考核面試者?A:會(huì)看同學(xué)為什么選擇前端行業(yè)?是因?yàn)樗惴ㄌy?Java、C++太難?還是因?yàn)闊?..

    Pluser 評(píng)論0 收藏0
  • 計(jì)算機(jī)秋招必備!杭州互聯(lián)網(wǎng)大廠企業(yè)整理清單!

    摘要:截至年月日零時(shí),杭州市常住人口為萬(wàn)人。年,杭州市實(shí)現(xiàn)地區(qū)生產(chǎn)總值億元。阿里巴巴對(duì)杭州的影響巨大,一線的七個(gè)企業(yè)中,有四個(gè)企業(yè)都是阿里巴巴大集團(tuán)下的。 歡迎持續(xù)關(guān)注我...

    morgan 評(píng)論0 收藏1
  • 求職攻略 | Datawhale助力秋招最強(qiáng)戰(zhàn)甲

    摘要:秋招變夏招,還沒(méi)準(zhǔn)備好團(tuán)隊(duì)成員收割機(jī)牽頭,帶領(lǐng)名成員歷時(shí)個(gè)月,整理了一份機(jī)器學(xué)習(xí)算法工程師求職面經(jīng)。但如果之前并沒(méi)有意識(shí)到這一問(wèn)題也沒(méi)關(guān)系,為你呈現(xiàn)一份小而美的面經(jīng)。這部分內(nèi)容包含了邏輯題目及概率題目?jī)煞矫娴膬?nèi)容。 秋招變夏招,還沒(méi)準(zhǔn)備好?Datawhale團(tuán)隊(duì)成員offer收割機(jī)牽頭,帶領(lǐng)14名成員歷時(shí)2個(gè)月,整理了一份機(jī)器學(xué)習(xí)算法工程師求職面經(jīng):Daily-interview。一份...

    CKJOKER 評(píng)論0 收藏0
  • [知識(shí)盲點(diǎn)] 為function添加值為function的屬性

    摘要:理論上來(lái)說(shuō),里是對(duì)象,給對(duì)象添加屬性是可以的。很明顯,這就是在或者函數(shù)上加了一個(gè)屬性,屬性值是函數(shù),作用是截取前后空格。要習(xí)慣的把中的一切看作對(duì)象,只要是對(duì)象,就是屬性的集合,屬性是鍵值對(duì)的形式。 今天在某個(gè)js交流群里看到這樣一個(gè)問(wèn)題: 親們,如果我定義一個(gè)function A() { } 可以給這個(gè)函數(shù)添加一個(gè)方法嗎?例如:A.use = function() { } ...

    Rango 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<