<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          每日十題 金三銀四面試題(五)

          共 7754字,需瀏覽 16分鐘

           ·

          2021-03-02 11:57

          一、快速排序(算法)

          參考解答:

          算法步驟如下:

          1. 從數(shù)列中挑出一個(gè)元素,稱為 “基準(zhǔn)”(pivot);
          2. 重新排序數(shù)列,所有元素比基準(zhǔn)值小的擺放在基準(zhǔn)前面,所有元素比基準(zhǔn)值大的擺在基準(zhǔn)的后面(相同的數(shù)可以到任一邊)。在這個(gè)分區(qū)退出之后,該基準(zhǔn)就處于數(shù)列的中間位置。這個(gè)稱為分區(qū)(partition)操作;
          3. 遞歸地(recursive)把小于基準(zhǔn)值元素的子數(shù)列和大于基準(zhǔn)值元素的子數(shù)列排序;

          遞歸的最底部情形,是數(shù)列的大小是零或一,也就是永遠(yuǎn)都已經(jīng)被排序好了。雖然一直遞歸下去,但是這個(gè)算法總會(huì)退出,因?yàn)樵诿看蔚牡╥teration)中,它至少會(huì)把一個(gè)元素?cái)[到它最后的位置去。


          function quickSort(arr, left, right) {    var len = arr.length,        partitionIndex,        left = typeof left != 'number' ? 0 : left,        right = typeof right != 'number' ? len - 1 : right;
          if (left < right) { partitionIndex = partition(arr, left, right); quickSort(arr, left, partitionIndex-1); quickSort(arr, partitionIndex+1, right); } return arr;}
          function partition(arr, left ,right) { // 分區(qū)操作 var pivot = left, // 設(shè)定基準(zhǔn)值(pivot) index = pivot + 1; for (var i = index; i <= right; i++) { if (arr[i] < arr[pivot]) { swap(arr, i, index); index++; } } swap(arr, pivot, index - 1); return index-1;}
          function swap(arr, i, j) { var temp = arr[i]; arr[i] = arr[j]; arr[j] = temp;}
          function partition2(arr, low, high) { let pivot = arr[low]; while (low < high) { while (low < high && arr[high] > pivot) { --high; } arr[low] = arr[high]; while (low < high && arr[low] <= pivot) { ++low; } arr[high] = arr[low]; } arr[low] = pivot; return low;}
          function quickSort2(arr, low, high) { if (low < high) { let pivot = partition2(arr, low, high); quickSort2(arr, low, pivot - 1); quickSort2(arr, pivot + 1, high); } return arr;}


          二、說一下 vue 組件之間的傳值通信

          參考解答:

          組件傳值可分為父子組件傳值和非父子組件傳值(兄弟組件傳值)

          1. 父組件給子組件傳值:使用props

          2. 子組件給父組件傳值:使用$emit觸發(fā)事件

          3. 兄弟組件:使用Bus.js, 兩個(gè)組件引入同一個(gè)Bus.js

          使用vuex可以處理上述情況的傳值問題。


          、說說 Vue 雙向綁定的原理

          參考解答:

          vue.js 是采用數(shù)據(jù)劫持結(jié)合發(fā)布者-訂閱者模式的方式,通過Object.defineProperty()來劫持各個(gè)屬性的setter,getter,在數(shù)據(jù)變動(dòng)時(shí)發(fā)布消息給訂閱者,觸發(fā)相應(yīng)的監(jiān)聽回調(diào)。

          • 當(dāng)把一個(gè)普通 Javascript 對(duì)象傳給 Vue 實(shí)例來作為它的 data 選項(xiàng)時(shí),Vue 將遍歷它的屬性,用 Object.defineProperty 都加上 setter和getter 這樣的話,給這個(gè)對(duì)象的某個(gè)值賦值,就會(huì)觸發(fā)setter,那么就能監(jiān)聽到了數(shù)據(jù)變化

          • compile解析模板指令,將模板中的變量替換成數(shù)據(jù),然后初始化渲染頁面視圖,并將每個(gè)指令對(duì)應(yīng)的節(jié)點(diǎn)綁定更新函數(shù),添加監(jiān)聽數(shù)據(jù)的訂閱者,一旦數(shù)據(jù)有變動(dòng),收到通知,更新視圖

          • Watcher訂閱者是Observer和Compile之間通信的橋梁,主要做的事情是: 1、在自身實(shí)例化時(shí)往屬性訂閱器(dep)里面添加自己 2、自身必須有一個(gè)update()方法 3、待屬性變動(dòng)dep.notice()通知時(shí),能調(diào)用自身的update()方法,并觸發(fā)Compile中綁定的回調(diào),則功成身退。

          • MVVM作為數(shù)據(jù)綁定的入口,整合Observer、Compile和Watcher三者,通過Observer來監(jiān)聽自己的model數(shù)據(jù)變化,通過Compile來解析編譯模板指令,最終利用Watcher搭起Observer和Compile之間的通信橋梁,達(dá)到數(shù)據(jù)變化 -> 視圖更新;視圖交互變化(input) -> 數(shù)據(jù)model變更的雙向綁定效果

          節(jié)選自: https://juejin.cn/post/6844903858804621325


          五、介紹下虛擬 DOM,對(duì)虛擬 DOM 的理解

          參考解答:

          我對(duì)Virtual DOM 的理解:

          首先對(duì)我們準(zhǔn)備插入文檔中的DOM樹結(jié)構(gòu)進(jìn)行分析,使用js對(duì)象數(shù)據(jù)類型表示出。Virtual DOM 算法是有三個(gè)核心實(shí)現(xiàn)。一是用JS對(duì)象模擬DOM樹,可以理解組合VNode。二是diff算法,比較新舊VNode的差異。三是打補(bǔ)丁patch,將差異應(yīng)用到真正的DOM樹上。


          六、談?wù)勀銓?duì) webpack 的看法

          參考解答:


          我認(rèn)為webpack的主要原理是將所有的資源都看成一個(gè)模塊,并且把頁面邏輯當(dāng)成一個(gè)整體,通過給定入口文件,找到所有依賴,將各個(gè)依賴經(jīng)過loader和plugins處理后,打包在一起,最后輸出瀏覽器可識(shí)別的js文件。

          webpack的核心概念:

          • Entry: 入口文件,Webpack 會(huì)從該文件開始進(jìn)行分析與編譯;

          • Output: 出口路徑,打包后創(chuàng)建 bundler 的文件路徑以及文件名;

          • Module: 模塊,在 Webpack 中任何文件都可以作為一個(gè)模塊,會(huì)根據(jù)配置的不同的 Loader 進(jìn)行加載和打包;

          • Chunk: 代碼塊,可以根據(jù)配置,將所有模塊代碼合并成一個(gè)或多個(gè)代碼塊,以便按需加載,提高性能;

          • Loader: 模塊加載器,進(jìn)行各種文件類型的加載與轉(zhuǎn)換;

          • Plugin: 拓展插件,可以通過 Webpack 相應(yīng)的事件鉤子,介入到打包過程中的任意環(huán)節(jié),從而對(duì)代碼按需修改;


          七、手寫一個(gè)Promise

          參考解答:


          const PENDING = "pending";const RESOLVED = "resolved";const REJECTED = "rejected";
          function MyPromise(fn) { // 保存初始化狀態(tài) var self = this;
          // 初始化狀態(tài) this.state = PENDING;
          // 用于保存 resolve 或者 rejected 傳入的值 this.value = null;
          // 用于保存 resolve 的回調(diào)函數(shù) this.resolvedCallbacks = [];
          // 用于保存 reject 的回調(diào)函數(shù) this.rejectedCallbacks = [];
          // 狀態(tài)轉(zhuǎn)變?yōu)?resolved 方法 function resolve(value) { // 判斷傳入元素是否為 Promise 值,如果是,則狀態(tài)改變必須等待前一個(gè)狀態(tài)改變后再進(jìn)行改變 if (value instanceof MyPromise) { return value.then(resolve, reject); }
          // 保證代碼的執(zhí)行順序?yàn)楸据喪录h(huán)的末尾 setTimeout(() => { // 只有狀態(tài)為 pending 時(shí)才能轉(zhuǎn)變, if (self.state === PENDING) { // 修改狀態(tài) self.state = RESOLVED;
          // 設(shè)置傳入的值 self.value = value;
          // 執(zhí)行回調(diào)函數(shù) self.resolvedCallbacks.forEach(callback => { callback(value); }); } }, 0); }
          // 狀態(tài)轉(zhuǎn)變?yōu)?rejected 方法 function reject(value) { // 保證代碼的執(zhí)行順序?yàn)楸据喪录h(huán)的末尾 setTimeout(() => { // 只有狀態(tài)為 pending 時(shí)才能轉(zhuǎn)變 if (self.state === PENDING) { // 修改狀態(tài) self.state = REJECTED;
          // 設(shè)置傳入的值 self.value = value;
          // 執(zhí)行回調(diào)函數(shù) self.rejectedCallbacks.forEach(callback => { callback(value); }); } }, 0); }
          // 將兩個(gè)方法傳入函數(shù)執(zhí)行 try { fn(resolve, reject); } catch (e) { // 遇到錯(cuò)誤時(shí),捕獲錯(cuò)誤,執(zhí)行 reject 函數(shù) reject(e); }}
          MyPromise.prototype.then = function(onResolved, onRejected) { // 首先判斷兩個(gè)參數(shù)是否為函數(shù)類型,因?yàn)檫@兩個(gè)參數(shù)是可選參數(shù) onResolved = typeof onResolved === "function" ? onResolved : function(value) { return value; };
          onRejected = typeof onRejected === "function" ? onRejected : function(error) { throw error; };
          // 如果是等待狀態(tài),則將函數(shù)加入對(duì)應(yīng)列表中 if (this.state === PENDING) { this.resolvedCallbacks.push(onResolved); this.rejectedCallbacks.push(onRejected); }
          // 如果狀態(tài)已經(jīng)凝固,則直接執(zhí)行對(duì)應(yīng)狀態(tài)的函數(shù)
          if (this.state === RESOLVED) { onResolved(this.value); }
          if (this.state === REJECTED) { onRejected(this.value); }};


          八、手寫一個(gè)觀察者模式

          參考解答:


          var events = (function() {  var topics = {};
          return { // 注冊(cè)監(jiān)聽函數(shù) subscribe: function(topic, handler) { if (!topics.hasOwnProperty(topic)) { topics[topic] = []; } topics[topic].push(handler); },
          // 發(fā)布事件,觸發(fā)觀察者回調(diào)事件 publish: function(topic, info) { if (topics.hasOwnProperty(topic)) { topics[topic].forEach(function(handler) { handler(info); }); } },
          // 移除主題的一個(gè)觀察者的回調(diào)事件 remove: function(topic, handler) { if (!topics.hasOwnProperty(topic)) return;
          var handlerIndex = -1; topics[topic].forEach(function(item, index) { if (item === handler) { handlerIndex = index; } });
          if (handlerIndex >= 0) { topics[topic].splice(handlerIndex, 1); } },
          // 移除主題的所有觀察者的回調(diào)事件 removeAll: function(topic) { if (topics.hasOwnProperty(topic)) { topics[topic] = []; } } };})();



          九、手寫一個(gè)jsonp

          參考解答:


          function jsonp(url, params, callback) {  // 判斷是否含有參數(shù)  let queryString = url.indexOf("?") === "-1" ? "?" : "&";
          // 添加參數(shù) for (var k in params) { if (params.hasOwnProperty(k)) { queryString += k + "=" + params[k] + "&"; } }
          // 處理回調(diào)函數(shù)名 let random = Math.random() .toString() .replace(".", ""), callbackName = "myJsonp" + random;
          // 添加回調(diào)函數(shù) queryString += "callback=" + callbackName;
          // 構(gòu)建請(qǐng)求 let scriptNode = document.createElement("script"); scriptNode.src = url + queryString;
          window[callbackName] = function() { // 調(diào)用回調(diào)函數(shù) callback(...arguments);
          // 刪除這個(gè)引入的腳本 document.getElementsByTagName("head")[0].removeChild(scriptNode); };
          // 發(fā)起請(qǐng)求 document.getElementsByTagName("head")[0].appendChild(scriptNode);}


          十、實(shí)現(xiàn)一個(gè)淺拷貝和一個(gè)深拷貝

          參考解答:


          // 淺拷貝的實(shí)現(xiàn);
          function shallowCopy(object) { // 只拷貝對(duì)象 if (!object || typeof object !== "object") return;
          // 根據(jù) object 的類型判斷是新建一個(gè)數(shù)組還是對(duì)象 let newObject = Array.isArray(object) ? [] : {};
          // 遍歷 object,并且判斷是 object 的屬性才拷貝 for (let key in object) { if (object.hasOwnProperty(key)) { newObject[key] = object[key]; } }
          return newObject;}
          // 深拷貝的實(shí)現(xiàn);
          function deepCopy(object) { if (!object || typeof object !== "object") return;
          let newObject = Array.isArray(object) ? [] : {};
          for (let key in object) { if (object.hasOwnProperty(key)) { newObject[key] = typeof object[key] === "object" ? deepCopy(object[key]) : object[key]; } }
          return newObject;}



          備注:解答僅供參考,如需了解更多,可自行搜索相應(yīng)問題。
          參考鏈接:https://github.com/CavsZhouyou/Front-End-Interview-Notebook/blob/master/JavaScript/JavaScript.md



          瀏覽 25
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  婷婷丁香四虎网 | 亚洲AV无码精品国产 | 翔田千里AV在线JAVA | 波多野结衣一区二区精品系列11 | 成人三级无码视频 |