前言
大家好,我是林三心,用最通俗易懂的話講最難的知識點是我的座右銘,基礎是進階的前提是我的初心,今天分享一個一年經驗的位元組抖音電商面經
一面
1、自我介紹?
略
2、問專案
略
3、leetcode第112題,《路徑總和》
const hasPathSum = (root, sum) => {
if (root == null) { // 遍歷到null節點
return false;
}
if (root.left == null && root.right == null) { // 遍歷到葉子節點
return sum - root.val == 0; // 如果滿足這個就返回true。否則返回false
}
// 不是上面的情況,則拆成兩個子樹的問題,其中一個true了就行
return hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val);
}
4、你知道哪些JS陣列的API?
方法 | 作用 | 是否影響原陣列 |
---|---|---|
push | 在陣列後新增元素,返回長度 | ✅ |
pop | 刪除陣列最後一項,返回被刪項 | ✅ |
shift | 刪除陣列第一項,返回被刪項 | ✅ |
unshift | 陣列開頭新增元素,返回長度 | ✅ |
reserve | 反轉陣列,返回陣列 | ✅ |
sort | 排序陣列,返回陣列 | ✅ |
splice | 擷取陣列,返回被擷取部分 | ✅ |
join | 將陣列變字串,返回字串 | ❌ |
concat | 連線陣列 | ❌ |
map | 相同規則處理陣列項,返回新陣列 | ❌ |
forEach | 遍歷陣列 | ❌ |
filter | 過濾陣列項,返回符合條件的陣列 | ❌ |
every | 每一項符合規則才返回true | ❌ |
some | 只要有一項符合規則就返回true | ❌ |
reduce | 接受上一個return和陣列下一項 | ❌ |
flat | 陣列扁平化 | ❌ |
slice | 擷取陣列,返回被擷取區間 | ❌ |
5、手寫reduce
Array.prototype.sx_reduce = function (callback, ...args) {
let start = 0, pre
if (args.length) {
pre = args[0]
} else {
pre = this[0]
start = 1
}
for (let i = start; i < this.length; i++) {
pre = callback(pre, this[i], i, this)
}
return pre
}
6、講一下HTTP快取?
7、談談vue和react的區別和優劣?
- vue2對ts支援較差,vue3時已解決
- vue2對jsx支援較差,vue3時已解決
- vue 和 react都是單向資料流
- vue多用模板 template,react多用 jsx
- vue和react都使用虛擬dom和diff演算法
- vue是雙向繫結,react是單向繫結
- vue和react都倡導元件化開發
- vue和react都支援服務端渲染
- vue2的狀態管理工具vuex,vue3用pinia,react用redux、mobx、recoil
- vue的diff演算法比react更高效
- react的寫法更貼近js原生
8、hooks用過嗎?聊聊react中class元件和函式元件的區別?
我的React比較菜。。
- class元件:state和props都是固定的地址
- 函式式元件:state和props每次都會跟著渲染更新而更新
9、前端效能優化你會怎麼做?
- 列表優化:懶載入、虛擬列表、分頁
- 重繪迴流:合併修改、requestAnimationFrame、will-change
- 提交優化:防抖
- 網路請求:控制併發量、取消重複請求、合併請求、http快取
- webpack優化:程式碼壓縮、gzip、CDN、程式碼分割、合理設定hash、圖片轉base64
10、反問環節
略
二面
1、自我介紹?
略
2、專案中遇到最複雜的是什麼?最有技術難度的是什麼?
略
3、演算法題
fn([['a', 'b'], ['n', 'm'], ['0', '1']])
=> ['an0', 'am0', 'an1', 'am1', 'bn0', 'bm0', 'bn1', 'bm0']
解答
const fn = (arr) => {
const length = arr.length
const res = []
const dfs = (items, str = '', index = 1) => {
if (index > length) {
res.push(str)
} else {
for (const item of items) {
dfs(arr[index], str + item, index + 1)
}
}
}
dfs(arr[0])
return res
}
4、手寫
u.console('breakfast').setTimeout(3000)
.console('lunch').setTimeout(3000)
.console('dinner')
解答
class U {
constructor() {
this.tasks = []
setTimeout(() => {
this.next()
})
}
next() {
const task = this.tasks.shift()
task && task()
}
console(str) {
const task = () => {
console.log(str)
this.next()
}
this.tasks.push(task)
return this
}
setTimeout(delay) {
const task = () => {
setTimeout(() => {
this.next()
}, delay)
}
this.tasks.push(task)
return this
}
}
5、事件代理是什麼?
當子元素都需要繫結同樣的事件的時候,這個時候可以把事件直接繫結在父元素上,並通過target物件來判斷執行不同的子元素操作,這樣可以大大減少繫結事件的數量,減少DOM操作,提高效能
6、e.target和e.currentTarget的區別?
e.target
:觸發事件的元素e.currentTarget
:事件所繫結的元素
7、寫一個事件代理函式,需要判斷child是parent的子節點?
function proxy(event, cb, parent, child) {
parent[event] = function (e) {
if (parent.contains(child) &&
e.target === child) {
cb.call(this)
}
}
}
8、看程式碼說結果?
var length = 10;
function fn() {
return this.length + 1;
}
var obj1 = {
length: 5,
test1: function () {
return fn()
}
}
obj1.test2 = fn;
obj1.test1.call() // 1
obj1.test1() // 11
obj1.test2.call() // 11
obj1.test2() // 6
9、從輸入Url到頁面渲染髮生了什麼?寫個提綱?
後面會單獨出一篇文章
- 網路階段:構建請求行、查詢強快取、DNS解析、建立TCP連線、傳送HTTP請求、響應請求
- 解析階段:解析html、構建dom樹、計算樣式、生成佈局樹
- 渲染階段:生成圖層樹、生成繪製列表、生成圖塊、優先選擇視口附近的圖塊生成點陣圖資料、展示內容
10、Tcp和Udp的區別?
- 1、基於連線與無連線
- 2、對系統資源的要求(TCP較多,UDP少)
- 3、UDP程式結構較簡單
- 4、流模式與資料包模式
- 5、TCP保證資料正確性,UDP可能丟包
- 6、TCP保證資料順序,UDP不保證
11、前端新技術瞭解哪些?說了PWA和electron,介紹了這兩個主要是用來做什麼?
- 新技術:微前端、低程式碼、Vue3、Vite
- PWA:不會
- Electron:使用JavaScript構建桌面端應用的框架
結語
我是林三心,一個熱心的前端菜鳥程式設計師。如果你上進,喜歡前端,想學習前端,那我們們可以交朋友,一起摸魚哈哈,摸魚群,加我請備註【思否】