😀 腾娱面试总结

118 阅读5分钟

😀 腾娱面试总结

📝 主旨内容

一面

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

navigator.sendBeacon

!cdn.liboqiao.top/markdown/im…

事件循环机制

当前任务在执行的过程中,一个script块(作为任务队列的第一个宏任务)开始执行,当同步任务执行完毕后会立刻检查所有微任务队列中的事件,微任务事件队列执行完毕之后,再去执行宏任务队列,一个宏任务执行完毕之后,检查微任务队列是否有任务,如果有就执行微任务,如果没有执行队列中的下一个宏任务,当前宏任务队列执行完成之后在执行下一个宏任务队列

blog.csdn.net/qq_63534905…

项目优化的点 为什么要这么做

代码优化 项目结构优化 打包上线优化 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

🤗 总结归纳

笔试题相对以前 脑子很慢 还是转了一点 还是有所进步的