😀 腾娱面试总结
📝 主旨内容
一面
1.如何实现前端埋点的
曝光: 商品 用户看见次数统计 getBoundingClientRect intersection Observe
两种方案
- getBoundingClientRect 浏览器支持不错, 简单易用但是可能存在性能问题。
- Intersection Observer API 没有性能问题, 但是存在一定兼容性。
好消息是我们可以使用polyfill 解决 Intersection Observer API 兼容性问题
它会在不支持的浏览器 使用 getBoundingClientRect 去重新实现一遍 Intersection Observer API。
注册自定义指令 isIntersecting判断是否可见
事件:商品等 点击 统计 注册自定义指令 点击事件
监听报错 visibilitychange
:解决 PC 端 浏览器 Tab 选项卡切换、 APP 切换应用等。
页面时长: 页面停留时间统计
上报:image sendBeacon post
2.如何在浏览器关闭时进行上报
navigator.sendBeacon
!cdn.liboqiao.top/markdown/im…
事件循环机制
当前任务在执行的过程中,一个script块(作为任务队列的第一个宏任务)开始执行,当同步任务执行完毕后会立刻检查所有微任务队列中的事件,微任务事件队列执行完毕之后,再去执行宏任务队列,一个宏任务执行完毕之后,检查微任务队列是否有任务,如果有就执行微任务,如果没有执行队列中的下一个宏任务,当前宏任务队列执行完成之后在执行下一个宏任务队列
项目优化的点 为什么要这么做
代码优化 项目结构优化 打包上线优化 git工作流优化
promise async await
Promise: Promise是一种表示异步操作最终完成(或失败)及其结果值的对象。Promise有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。一旦Promise被resolve(解析)或reject(拒绝),它的状态就不能再改变。
async: async函数是一个返回Promise的异步函数,它使得异步代码看起来像同步代码。当你在一个函数前加上async关键字,该函数就会返回一个Promise。如果在async函数中使用了await关键字,那么JavaScript引擎会等待该Promise解析完成后再继续执行后续代码。
await: await关键字只能在async函数内部使用。await表达式会暂停async函数的执行,并等待一个Promise解析完成,然后返回解析的结果。如果Promise被拒绝,await表达式会抛出一个异常。 示例:
// 假设有一个返回Promise的函数
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Data fetched!');
}, 1000);
});
}
// 使用async/await处理异步操作
async function getData() {
try {
const data = await fetchData();// 等待fetchData返回的Promise解析
console.log(data);// 输出: Data fetched!
} catch (error) {
console.error('Error fetching data:', error);
}
}
// 调用async函数
getData();
在上面的例子中,fetchData
是一个返回Promise的函数,它模拟了一个异步操作(通过setTimeout)。getData
是一个async函数,它使用await来等待fetchData
返回的Promise解析完成。
闭包是什么 场景 有什么坏处
闭包就是能够读取其他函数内部变量的函数。在编程中,闭包常被用于封装、函数式编程、定时器和事件处理、模块模式、回调函数、循环中的异步操作以及缓存等场景。具体来说,闭包在JavaScript中特别有用,因为它允许创建私有变量和函数,实现信息隐藏和封装,从而增强代码的安全性和可维护性。此外,闭包还可以用于创建高阶函数、延迟执行函数以及柯里化等功能,极大地丰富了编程的灵活性和表达能力。
然而,闭包也有一些坏处。首先,闭包会将外部函数的局部变量保存在内存中,即使外部函数已经执行完毕。如果闭包被频繁调用或者保存的数据量很大,可能会导致内存占用过高。其次,由于闭包需要在运行时维护外部函数的状态,因此会增加一定的性能损耗。相比于普通函数调用,闭包的执行效率可能会稍低。最后,闭包也可能使代码难以理解和调试,特别是当闭包嵌套过多或逻辑复杂时。
因此,在使用闭包时,需要权衡其带来的好处和潜在的坏处,根据具体场景和需求进行合理使用。
笔试题
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bug排查练习</title>
</head>
<body>
<div id="app">
<h1>{{ message }}</h1>
<button @click="changeMessage">Change Message<tton>
</div>
<script src="<https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js>"></script>
<script>
new Vue({
el: '#app',
data() {
return {
message: 'Hello World'
};
},
methods: {
changeMessage() {
const promise = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('New Message');
}, 1000);
});
promise.then(function(newMessage) {
this.message = newMessage;
});
}
}
});
</script>
</body>
<html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>indexOf</title>
</head>
<body>
<script>
String.prototype.indexOf = function(searchString,position){
// 完成该函数的实现
return -1;
}
const paragraph = "I think Ruth's dog is cuter than your dog!";
const searchTerm = 'dog';
const indexOfFirst = paragraph.indexOf(searchTerm);
console.log(`The index of the first "${searchTerm}" is ${indexOfFirst}`);
// Expected output: "The index of the first "dog" is 15"
console.log(
`The index of the second "${searchTerm}" is ${paragraph.indexOf(
searchTerm,
indexOfFirst + 1,
)}`,
);
</script>
</body>
<html>
二面
笔试题
输入:“10 + 2 * 30 - 0.5” 输出:69.5
const suanshu = (flag, index, result, num) => {
const pre = num[index] === null ? result : +num[index]
const next = num[index + 1] === null ? result : +num[index + 1]
switch (flag) {
case '+': return pre + next;
case '-': return pre - next;
case '*': return pre * next;
case '/': if (next === 0) throw new Error('除数不能为0');
return pre / next;
default: return 0;
}
}
const caculate = (str) => {
const flag = []
const num = []
let str1 = ""
const reg = ["*", "+", "-", "/"]
const precedence = { '+': 1, '-': 1, '*': 2, '/': 2 };
for (let i in str) {
const f = reg.findIndex(item => item === str[i])
if (f !== -1) {
flag.push(str[i])
num.push(str1.trim())
str1 = ""
} else {
str1 += str[i]
if (i == str.length - 1) {
num.push(str1.trim())
}
}
}
const flagSortArr = flag.map((item, index) => ({
name: item,
sortIndex: index
})
).sort((a, b) =>
precedence[b.name] - precedence[a.name]
)
let result = 0
const clear = (index1) => {
flag[index1] = null
num[index1] = null
num[index1 + 1] = null
}
for (flagItem of flagSortArr) {
result = suanshu(flagItem.name, flagItem.sortIndex, result, num)
clear(flagItem.sortIndex)
}
return result
}
const teststr = "10 - 20 * 30 / 10 +10"
console.log(caculate(teststr))//-40
🤗 总结归纳
笔试题相对以前 脑子很慢 还是转了一点 还是有所进步的