2020年4月大廠騰訊前端面經分享
前言
本人很榮幸參加了一次騰訊大廠的一面,雖然結果不理想,但是總歸是檢測了一下自己,發現了自己的不足地方,以此督促自己加強學習。
本次面試共分為筆試題一個小時和麵試一個小時。
一、程式設計題(請用es6實現編碼):
1、 二分查詢
給定一個 n 個元素有序的(升序)整型陣列 nums 和一個目標值 target ,寫一個函式二分查詢 nums 中的 target,如果目標值存在返回下標,否則返回 -1。
let arr = [1, 3, 5, 7, 9]; function search(nums, target) { let left = 0; let right = nums.length - 1; while(left <= right) { let mid = (right + left) / 2; if (nums[mid] == target) { return mid; } else if (nums[mid] < target) { left = mid + 1; } else { right = mid -1; } } return -1; } console.log(search(arr, 7));
2、 編寫一個非同步查詢等待結果的輪詢元件
元件具體輸入如下:
- 查詢執行方法
- 輪詢間隔
- 超時時長
- 最多輪詢次數
元件輸出: - 返回一個promise物件
- 查詢方法執行無異常,則輪詢結束,返回查詢結果
解答:
// vue程式碼 data() { return { data: {}, // 請求結果 remainTime: 0, // 剩餘限制時長 start: 0, // 開始時間 end: 0, // 請求得到資料的時間 } } mounted () { // 請求之前計時 start this.start = Math.floor(new Date().getTime()/1000); this.query(50, 2, 10); }, methods: { // 只要輪詢次數和最大限制時長任何一個達到閾值 就 停止輪詢 query(num, interval, limitTime=60) { // 引數num:輪詢次數 interval:定時器時間(s) l imitTime:最大限制時長(s) let timer; if (num > 1) { return new Promise((resolve, reject) => { let postParams = { id: this.$route.params.id } Api.getArticleOne(postParams).then(res => { this.data = res.data.data.content; // 這個只是介面返回的資料結構 this.end = Math.floor(new Date().getTime()/1000); }, err => { reject(err); }).catch(err => { console.log(err) }); if (this.end !== 0) { // 如果拿到資料了,就用當前的 剩餘限制時長 - (結束時間 - 開始時間) this.remainTime = limitTime - (this.end - this.start); } else { // 如果還沒拿到介面資料 這個時候 end就為0 需要繼續 輪詢 這個時候的剩餘時間還是 傳過來的 限制時長 this.remainTime = limitTime; } if (this.remainTime <= 0) { // 如果剩餘時間小於等於 0 或者 迴圈次數 為 1 就結束定時器 clearTimeout(timer); return; } else { // 輪詢一次 num就減少一次 num--; this.remainTime = this.remainTime - interval; // 當前剩餘時長 = 當前剩餘時長 - 定時器 timer = setTimeout(() => { this.query(num, interval, this.remainTime)}, interval * 1000); } }).catch(err => { console.log(err) }) } else { clearTimeout(timer); return; } }, }
3、 邏輯題
共有60塊磚,60人搬,男搬5,女搬3,兩個小孩搬1塊,一次搬完,需要小孩、男人、女人各多少人,有幾種組合方案?
解答:
function solution() { let x, y, z; for(x =1; x < 12; x++) { for(y = 1; y < 20; y++) { z = 60 - x - y; if (z%2 == 0) { if (5*x + y*3 + z/2 == 60) { console.log(x, y, z, '搬磚組合'); // 5 3 52 } } } } } solution();
答案:只有一種方案:男人:5 ;女人: 3 ;小孩:52
二、問答題
1-5題
1. 請寫出下面程式碼輸出結果以及原因
var myname = "小明";
function showName(){
console.log(myname); // undefined
if(0){ var myname = "小紅" }
console.log(myname); // undefined
}
showName();
2. 請寫出下面程式碼輸出結果以及原因
function letTest() {
let x = 1;
if (true) {
let x = 2;
console.log(x); // 2
}
console.log(x); // 1
}
letTest();
3. 請寫出下面程式碼輸出結果以及原因?並且用箭頭函式實現
function bar() {
console.log(myName)
}
function foo() {
var myName = "騰訊1"
bar()
}
var myName = "騰訊2"
foo();// 騰訊2
箭頭函式:var foo = () => () => {
console.log(myName);
}
4. 請寫出下面程式碼輸出結果以及原因
var myObj = {
name : "騰訊1",
showThis: function(){
console.log(this);
var self = this;
function bar(){
self.name = "騰訊2";
}
bar()
}
}
myObj.showThis(); // myObject物件
console.log(myObj.name); // 騰訊2
console.log(window.name); // undefined
5. 請寫出以下this指向情況:
// 情況1
function foo() {
console.log(this.a) //1
}
var a = 1
foo();
this指向window全域性
// 情況2
function fn(){
console.log(this);
}
var obj = {fn: fn};
obj.fn(); // this => obj this指向obj物件
// 情況3
function CreateJsPerson(name,age){
// this是當前類的一個例項p1
this.name=name; // => p1.name = name
this.age=age; // => p1.age = age
}
var p1=new CreateJsPerson("尹華芝",48);
// 情況4
function add(c, d){
return this.a + this.b + c + d;
}
var o = {a: 1, b: 3};
add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16 this指向o物件
add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34 this指向o物件
// 情況5
<button id="btn1">箭頭函式this</button>
<script type="text/javascript">
let btn1 = document.getElementById('btn1');
let obj = {
name: 'kobe',
age: 39,
getName: function () {
btn1.onclick = () => {
console.log(this);//obj
};
}
};
obj.getName();
this指向obj,因為箭頭函式的this是在外層函式定義的時候就指定了
6. 說一說你最近了解的你覺得在前端比較新的技術,並寫寫你的見解
(開放性題)
node V8引擎,非同步I/O,事件機制
Typescript 對變數型別的指定,解除javascript的弱型別的詬病
服務端渲染(vue-ssr、nuxt、next):利於seo,更快時間到達,需要伺服器支援,加重伺服器負載。
7. webpack相關
webpac預設的入口檔案是index.js
預設輸出目錄是dist
如何修改webpack的預設輸出目錄。需要用到webpack命令是webpack
Webpack 常見名詞解釋,請解釋下面名詞:
entry
專案入口
module
模組,對於webpack來說,所有的資源(.js、.css、.png)都是module
chunk
打包過程中被操作的模組檔案叫做chunk
bundle
最後打包後的檔案,最終輸出的chunk在使用者端,被稱之為bundle;一般一個chunk對應一個bundle,只有在配置了sourcemap時,才會出現一個chunk對應多個bundle的情況;
loader
它就是一個轉換器, loader讓webpack能夠處理不同的檔案。loader可以將所有型別的檔案轉換為webpack能夠處理的有效模組,然後利用webpack的打包能力,對他們進行處理。
plugins
它就是一個擴充套件器,它豐富了wepack本身,針對是loader結束後,webpack打包的整個過程,它並不直接操作檔案,而是基於事件機制工作,會監聽webpack打包過程中的某些節點,執行廣泛的任務。
8. Node 如何進行快取
強制快取和協商快取,跟瀏覽器快取差不多吧
9. 瀏覽器的js迴圈機制和nodejs迴圈機制的差別?
[圖片上傳失敗...(image-22e8bf-1586703310728)]
巨集任務:setTimeout,setInterval,
微任務:promise的回撥
js的事件迴圈機制比較簡單
先執行主執行緒程式碼,執行完畢後,清空微任務佇列,然後取出一個巨集任務,然後清空微任務佇列,如此迴圈
Node的事件迴圈比較複雜
Node的事件迴圈分為六個階段
(1)timers計時器 執行setTimeout、setInterval的回撥函式
(2)I/0 callbacks 執行I/O callback被延遲到下一階段執行;
(3)idle, prepare 佇列的移動,僅內部使用
(4)poll 輪詢階段 這個階段是用來執行和 IO 操作有關的回撥的,Node會向作業系統詢問是否有新的 IO 事件已經觸發,然後會執行響應的事件回撥。幾乎所有除了 定時器事件、 setImmediate() 和 close callbacks 之外操作都會在這個階段執行。
(5)check 這個階段會執行 setImmediate() 設定的任務
(6)close 執行close事件的callback,例如socket.on("close",func) 如果一個 socket 或 handle(控制代碼) 突然被關閉了,例如通過 socket.destroy() 關閉了,close事件將會在這個階段發出。
10. VUE響應式原理解釋
監聽器 Observer
:用來劫持並通過Object.defineProperty監聽所有屬性(轉變成setter/getter形式),如果屬性發生變化,就通知訂閱者。
訂閱器 Dep
:用來收集訂閱者,對監聽器 Observer
和 訂閱者 Watcher
進行統一管理。
訂閱者 Watcher
:監聽器Observer
和解析器Compile
之間通訊的橋樑;如果收到屬性的變化通知,就會執行相應的方法,從而更新檢視。
解析器 Compile
:可以解析每個節點的相關指令,對模板資料和訂閱器進行初始化。
主要做的事情是:
- 在自身例項化時往屬性
訂閱器(dep)
裡面新增自己。 - 自身有一個update()方法。
- 待屬性變動dep.notice()通知時,能呼叫自身的update()方法,並觸發
解析器(Compile)
中繫結的回撥。
總結:vue.js 是採用資料劫持結合釋出者-訂閱者模式的方式,通過Object.defineProperty()來劫持各個屬性的setter,getter,在資料變動時釋出訊息給訂閱者,觸發相應的監聽回撥。
Vue3.0的Proxy相比於defineProperty的優勢
Object.defineProperty() 的問題主要有三個:
- 不能監聽陣列的變化
- 必須遍歷物件的每個屬性
- 必須深層遍歷巢狀的物件
Proxy 在 ES2015 規範中被正式加入,它有以下幾個特點:
針對物件: 針對整個物件,而不是物件的某個屬性,所以也就不需要對 keys 進行遍歷。這解決了上述 Object.defineProperty() 第二個問題。
支援陣列: Proxy 不需要對陣列的方法進行過載,省去了眾多 hack,減少程式碼量等於減少了維護成本,而且標準的就是最好的。
11. HTTP/2、https 有什麼新特性
HTTP/2:
HTTP/2 更簡單,高效,強大。
它在傳輸層解決了以前我們HTTP1.x中一直存在的問題。使用它可以優化我們的應用。HTTP/2 的首要目標是通過完全的請求,響應多路複用,頭部的壓縮頭部域來減小頭部的體積,添加了請求優先順序,服務端推送。為了支援這些特性,他需要大量的協議增加頭部欄位來支援,例如新的流量控制,差錯處理,升級機制.而這些是每個web開發者都應該在他們的應用中用到的。
HTTP/2並沒有在應用中改變HTTP的語義,而是通過在客戶端和服務端傳輸的資料格式(frame)和傳輸.它通過在新的二進位制幀層控制整個過程以及隱藏複雜性,而這不需要改變原來有的東西就可以實現。
詳情參考=>
https:
一、HTTPS協議需要到證書頒發機構CA申請證書,HTTP不用申請證書;
二、HTTP是超文字傳輸協議,屬於應用層資訊傳輸,HTTPS 則是具有SSL加密傳安全性傳輸協議,對資料的傳輸進行加密,相當於HTTP的升級版;
三、HTTP和HTTPS使用的是完全不同的連線方式,用的埠也不一樣,前者是80,後者是443。
四、HTTP的連線很簡單,是無狀態的;HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網路協議,比HTTP協議安全。
12. TCP/ip5層模型,並且解釋每層的作用
TCP/IP“五層模型”分為:物理層、網際網路層、網路層(IP層)、傳輸層(TCP/UDP層)、應用層。
各層網路協議
應用層(Application): 應用程式閘道器(application gateway)
Telnet: 遠端登入 (在應用層連線兩部分應用程式)
FTP(File Transfer Protocol):檔案傳輸協議
HTTP(Hyper Text Transfer Protocol):超文字傳輸協議
SMTP(Simple Mail Transter Protocol):簡單郵件傳輸協議
POP3(Post Office Ptotocol):郵局協議
SNMP(Simple Network Mangement Protocol):簡單網路管理協議
DNS(Domain Name System):域名系統
傳輸層(Transport): 傳輸閘道器(transport gateway)
TCP(Transmission Control Potocol):傳輸控制協議 (在傳輸層連線兩個網路)
UDP(User Data Potocol):使用者資料協議
網路層(Internet): 多協議路由器(multiprotocol router)
IP(Internet Protocol):網路協議 (在異構網路間轉發分組)
ARP(Address Resolution Protocol):地址解析協議
RARP(Reverse Address Resolution Protocol) :逆地址解析協議
ICMP(Internet Control Message Protocol):因特網控制訊息協議
IGMP(Internet Group Manage Protocol):因特網組管理協議
BOOTP (Bootstrap):可選安全啟動協議
網際網路層 即 資料鏈路層(Data Link): 網橋(bridge)交換機(switcher)
HDLC(High Data Link Control):高階資料鏈路控制 (在LAN之間儲存-轉發資料鏈路針)
SLIP(Serial Line IP):序列線路IP
PPP(Point-to-Point Protocol):點到點協議
802.2等
物理層(Physical): 中繼器(repeater) 集線器(hub)
無 (放大或再生弱的訊號,在兩個電纜段之間複製每一個位元)
應用層
:應用程式間溝通的層,如簡單電子郵件傳輸(SMTP)、檔案傳輸協議(FTP)、網路遠端訪問協議(Telnet)等。
傳輸層
:在此層中,它提供了節點間的資料傳送服務,如傳輸控制協議(TCP)、使用者資料報協議(UDP)等,TCP和UDP給資料包加入傳輸資料並把它傳輸到下一層中,這一層負責傳送資料,並且確定資料已被送達並接收。
資料鏈路層
: O S I 模型的第二層,它控制網路層與物理層之間的通訊。它的主要功能是如何在不可靠的物理線路上進行資料的可靠傳遞。為了保證傳輸,從網路層接收到的資料被分割成特定的可被物理層傳輸的幀。幀是用來移動資料的結構包,它不僅包括原始資料,還包括髮送方和接收方的網路地址以及糾錯和控制資訊。其中的地址確定了幀將傳送到何處,而糾錯和控制資訊則確保幀無差錯到達。
資料鏈路層的功能獨立於網路和它的節點和所採用的物理層型別,它也不關心是否正在執行 Wo r d 、E x c e l 或使用I n t e r n e t 。有一些連線裝置,如交換機,由於它們要對幀解碼並使用幀資訊將資料傳送到正確的接收方,所以它們是工作在資料鏈路層的。
網路層
: O S I 模型的第三層,其主要功能是將網路地址翻譯成對應的實體地址,並決定如何將資料從傳送方路由到接收方。
網路層通過綜合考慮傳送優先權、網路擁塞程度、服務質量以及可選路由的花費來決定從一個網路中節點A 到另一個網路中節點B 的最佳路徑。由於網路層處理路由,而路由器因為即連線網路各段,並智慧指導資料傳送,屬於網路層。在網路中,“路由”是基於編址方案、使用模式以及可達性來指引資料的傳送。
物理層
: O S I 模型的最低層或第一層,該層包括物理連網媒介,如電纜連線聯結器。物理層的協議產生並檢測電壓以便傳送和接收攜帶資料的訊號。在你的桌面P C 上插入網路介面卡,你就建立了計算機連網的基礎。換言之,你提供了一個物理層。儘管物理層不提供糾錯服務,但它能夠設定資料傳輸速率並監測資料出錯率。網路物理問題,如電線斷開,將影響物理層。
13. 從前端的角度,如何系統性的提升大型 Web 應用的可用性?可從你認為的可用性維度、監控手段和改善措施等方面闡述。
一、前端使用者性意義與現狀
什麼是前端可用性?
前端可用性是從使用者的角度出發,檢測整個系統的可用性,系統任何一個環節的缺失都會對體驗造成影響。
前端可用性現狀
- 頁面功能和互動複雜度增加
- 前端功能測試侷限性
- 各種前端渲染框架的引入
- 運營線上問題反饋
前端可用性建設意義
前端可用性評估指標
- 關鍵指標白屏時間6s
前端可用性保障系統設計
可用性系統要求:實時性, 全面性
1. 資料採集:請求異常、資源異常、渲染異常、互動異常。
請求狀態嗎異常,請求超時,返回資料格式錯誤。(AJAX監控)
資源載入失敗(CDN監控)
渲染異常(DOM檢查)
互動異常(JS錯誤監控)
2. 監控預警:實時監控、閾值報警。
海量資料儲存讀取、視覺化資料展現、多維度資料查詢。
設定合理閾值、郵件簡訊報警
3. 兜底容災:容錯機制、快速降級。
非同步渲染機制出錯跳轉同步頁、友好的錯誤使用者提示。
重要機制新增降級開關、迅速(3min內)完成降級
前端可用性優化思路
前端可用性展望
面試總結
主要就是結合簡歷上的一個一個詳細地問,只要簡歷上寫了就會問到原理性的東西,然後就是問了專案中你負責哪塊,前端規劃之類的。
然後針對前端重複頁面的編寫探討了一下,面試官小姐姐給我解答了,他們後臺有自己的元件庫,純的元件,前端要用,就直接引用下載,開始不以為然,到下來自己去查了一下,大概就是npm發包的那種吧。
小感慨:關於這次面試的總結,我想我還是加強寫部落格吧,就像有人說前端兩三年有一個瓶頸期,就是什麼都會一點,但是歸根到底還是基礎不夠牢固,而尤其是針對我這種非科班的,想很多計算機原理都還是一知半解,瀏覽器快取,伺服器相關還是懂的少,主要就是工作中為涉獵,這也是死我為什麼要搞一個自己的部落格網站(https://www.jscwwd.com)的原因。然後我自己也買了三本書“深入淺出nodejs”、"學習Javascript的資料結構與演算法"、“深入理解Typescript”,今年就準備把基礎重新過一遍,期待來年與騰訊等大廠的會面!
以上就是本人這次一面的筆試題,當時答得不好,然後也沒了後來,然後自己下來找了一些資料總結了一下,希望對大家有用!歡迎對題目中有其他答案的,歡迎交流或在下方評論!
個人部落格網站文章地址https://www.jscwwd.com/article/5e92d61b2c6a7805a4569