2025面试题

66 阅读7分钟

中x动:

流式实现,中断 高亮 表格

iframe 跨域通信

css样式优先级

http长连接

权限控制

Vue2的页面未及时更新,vue3不会

DD岗

节流防抖

项目难点,上线后有问题

React 父子组件传值

父组件获取子组件的方法

defer async的区别,默认是哪个

computed watch

闭包宏任务 微任务

一个购物车功能,vuex里 拿到最新数据 

跨域

ajax

两个盒子,一个宽,另一个自适应宽度

快X手的题

1.axios ajax 2.闭包 3.跨域 (跨端) 4.性能优化:项目里以及webpack 5.代码题:class声明类,去添加用户信息,延时等待

image.png

function myPromiseAll(promises) {
  return new Promise((resolve, reject) => {
    if (!Array.isArray(promises)) {
      return reject(new TypeError("Argument must be an array"));
    }

    const result = [];
    let resolvedCount = 0;

    if (promises.length === 0) {
      return resolve([]);
    }

    promises.forEach((p, index) => {
      // 用 Promise.resolve 包装,防止非 Promise 值
      Promise.resolve(p)
        .then(value => {
          result[index] = value; // 保证顺序
          resolvedCount++;
          if (resolvedCount === promises.length) {
            resolve(result);
          }
        })
        .catch(err => {
          reject(err); // 一旦有一个失败,立即 reject
        });
    });
  });
}


const p1 = Promise.resolve(1);
const p2 = new Promise(res => setTimeout(() => res(2), 100));
const p3 = 3;

myPromiseAll([p1, p2, p3]).then(res => {
  console.log(res); // [1, 2, 3]
}).catch(err => {
  console.log(err);
});


const treeData = [
  {
    id: 1,
    name: '节点1',
    children: [
      {
        id: 2,
        name: '节点1-1',
        children: [
          { id: 3, name: '节点1-1-1' }
        ]
      },
      { id: 4, name: '节点1-2' }
    ]
  },
  { id: 5, name: '节点2' }
];
// [
//   { id: 1, name: '节点1', parentId: null},
//   { id: 2, name: '节点1-1', parentId: 1},
//   { id: 3, name: '节点1-1-1', parentId:2 },
//   { id: 4, name: '节点1-2', parentId: 1 },
//   { id: 5, name: '节点2', parentId: null }
// ]


function flattenTree(data,parentId=null){
  const result=[]
    for(const node of data){
      const {children , ...rest}=node
      result.push({...rest,parentId})
      if (children) {
        result.push(...flattenTree(children,node.id))
      }
    }
    return result
}

console.log(flattenTree(treeData))

// 二叉树路径求和
function pathSums(root){
  const result=[]
  function inner(node,sum){
    if(!node) {
      return
    }
    sum+= node.val
    if(!node.left && !node.right){
      result.push(sum)
      return
    }

      inner(node.left,sum)
      inner(node.right,sum)
  }
  inner(root,0)
  return result
}

美某团

基于项目,去问项目的细节。 vue2,vue3的区别 scoped怎么做到不被污染 代码题:最长公共前缀,ts写

image.png

其他业务组: 1.computed和watch的区别 2.异步监听数组

  1. 如果给data去push进去数据,页面会不会渲染 以及触发这个方法去改变里面的title值会不会渲染成a
<div>{{data}}</div>
data(){
return{
data:[]
}
},
methods:{
 way(){
 data[0].title='a'
 }
}

4.斐波那契数列 5.解构赋值 : abc. arr=[1,2,3,4] a为1,b为2,c为[3,4]

高某德:

流式渲染,为什么会出现proxy联调时,会细问,是什么层面的,是代理还是数据驱动 跨域代理:proxy是怎么代理,说一下正反向代理,和你细聊,以及什么方案,问的不是那边背的 iframe里的东西细问 node和你细聊 es6的导入导出以及 module 的区别 端和服务流式数据通过什么协议输出,怎么流式输出 Monaco编辑器的性能问题,非标准的数据展示标准的json,做的哪些处理 https,浏览器开发的请求参数和响应式数据为什么展示的是明文 vue defineproperty 有什么缺陷,proxy【区别】 遍历数组为什么加key vue新出的vapor模式 webpack的tree shank是怎么操作的 抓包,聊一聊 js为什么是单线程

weak 的map set

http2.0/http1.1区别

 安全性

-   **HTTP/1.1**:HTTPS是可选项

-   **HTTP/2**    -   主流实现强制使用TLS加密(虽然规范不强制)
    -   浏览器只支持HTTP/2 over TLS

### 性能对比示例

对于典型网页加载:

-   HTTP/1.1:可能需要建立6-8个TCP连接,每个连接串行请求资源
-   HTTP/2:单个连接并行传输所有资源,头部更小,无队头阻塞

### 兼容性注意

-   HTTP/2完全兼容HTTP/1.1的语义(方法、状态码、头部字段等)
-   如果HTTP/2不可用,自动回退到HTTP/1.1

1、在TypeScript中,any、never、unknown、null & undefined(通常表示为null | undefined)和void的区别。

any: 任何类型  **完全绕过类型检查**。
unknown:表示“未知类型” ,和any一样可以接受任何类型,但不能直接操作,要进行类型检测
never:永远不会发生的值,表示**永远不会有返回值**的函数,通常用于抛出异常或无限循环的函数
null | undefined:两个具体值的联合类型。“值不存在”或“未初始化“。**不能赋值给其他类型**,除非显式声明
void:表示“没有返回值”。用于函数**没有返回值**的情况。只能被赋值为 `undefined`(在严格模式下

2、js中去重的方式。 Set去重为什么不能去重对象。

### 1. 基本数据类型数组的去重(数字、字符串、布尔值、null、undefined、Symbol)
const numbers=[1,2,2,3,4,5]
const uniqueNumbers = [...new Set(numbers)];
console.log(uniqueNumbers); // [1, 2, 3, 4, 5]


const strings=['a','a','b','c','b']
const uniqueString=Array.from(new Set(strings))


二、filter+indexOf  filter返回为true的新数组,indexOf返回第一次的索引,否则为-1
const arr = [1, 2, 2, 3, 4, 4, 5];
const uniqueArr = arr.filter((item, index) => arr.indexOf(item) === index);
console.log(uniqueArr); // [1, 2, 3, 4, 5]

三、reduce
const arr = [1, 2, 2, 3, 4, 4, 5];
const uniqueArr = arr.reduce((acc, current) => {
  if (!acc.includes(current)) {
    acc.push(current);
  }
  return acc;
}, []);
console.log(uniqueArr); 
  
  
### 2. 对象数组的去重
方法一、reduce + some
const objects = [
  { id: 1, name: 'John' },
  { id: 2, name: 'Jane' },
  { id: 1, name: 'John' },
  { id: 3, name: 'Bob' }
];

const uniqueById = object.reduce((acc,current)=>{
if(!acc.some(item => item.id === current.id)){
  acc.push(current)
  }
  return acc
},[])

方法二、Map
const map = new Map()//可以存储键值对
object.forEach(item =>{
  if(!map.has(item.id)){
    map.set(item.id,item)
  }
})
const uniqueObjects = Array.from(map.values());

为什么 Set 不能去重对象?

根本原因:对象比较的是引用,而不是内容

const a = {};
const b = {};
const c = a;

console.log(a === b); // false - 不同的内存地址
console.log(a === c); // true - 同一个内存地址


### `Set` 的内部工作原理

`Set` 使用 `SameValueZero` 算法来判断值是否相等:

-
function deepEqual(obj1, obj2) {
  if (obj1 === obj2) return true;
  
  if (typeof obj1 !== 'object' || obj1 === null ||
      typeof obj2 !== 'object' || obj2 === null) {
    return false;
  }
  
  const keys1 = Object.keys(obj1);
  const keys2 = Object.keys(obj2);
  
  if (keys1.length !== keys2.length) return false;
  
  for (const key of keys1) {
    if (!keys2.includes(key) || !deepEqual(obj1[key], obj2[key])) {
      return false;
    }
  }
  
  return true;
}

function uniqueObjects(arr) {
  return arr.filter((item, index, self) => 
    index === self.findIndex(obj => deepEqual(obj, item))
  );
}

const objects = [
  { id: 1, name: 'John' },
  { id: 2, name: 'Jane' },
  { id: 1, name: 'John' },
  { id: 3, name: 'Bob' }
];

console.log(uniqueObjects(objects));
// [{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }, { id: 3, name: 'Bob' }]

3、http协议中的缓存有哪些,是如何工作的?

image.png

image.png

4、常用的react hooks有哪些?

5、react hook 是如何模拟生命周期的?

6、useContext是如何使用的?

7、基于JS 数组的forEach方法实现reduce方法。

8、用代码把 "get-element-by-id" 转化为 "getElementById"。

function kebabToCamelCase(str) {
  const parts = str.split('-');
  
  // 第一个单词全小写,后续单词首字母大写
  const camelCase = parts.map((word, index) => {
    if (index === 0) {
      return word.toLowerCase();
    }
    return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
  });
  
  return camelCase.join('');
}

9、[1,2,3].filter(n => n>1).map(n => n+1).reduce((a,b) => b-a) 说出输出的结果1。

快手-社会科学业务线(8.25预习)

1、act 实现倒计时

2、垂直居中:transform方案

3、实现 H5 的响应式布局

4、Axios 二次封装,都做了哪些事情?

  1. 「Token 自动管理」

    • 实现了 access token 过期时的自动刷新机制
    • 避免用户需要手动重新登录
  2. 「统一错误处理」

    • 对网络错误、业务错误、认证错误进行统一处理
    • 提供友好的用户提示
  3. 「请求预处理」

    • 自动添加认证信息、公共参数
    • 统一设置 baseURL、超时时间等
  4. 「响应后处理」

    • 统一解析响应数据格式
    • 处理分页数据等通用逻辑
  5. 「功能增强」

    • 请求取消、重试机制
    • Loading 状态管理
    • 请求缓存等

5、输出

var F = function() {};
Object.prototype.a = function() {
console.log('a');
};
Function.prototype.b = function() {
console.log('b');
}
var f = new F();
f.a();//a
f.b();//TypeError: f.b is not a function
F.a();//a
F.b()//b

6、输出: 1 2 4

const promise = new Promise((resolve, reject) => {
console.log(1);
console.log(2);
});
promise.then(() => {
console.log(3);
});
console.log(4);

7、在一个已排序的整数数组中查找目标值,如果找到则返回其索引,否则返回-1

function binarySearch(sortedArray, target) {
// 你的代码
  // 处理边界情况:空数组或无效输入
  if (!Array.isArray(sortedArray) || sortedArray.length === 0) {
    return -1;
  }
  
  let left = 0;
  let right = sortedArray.length - 1;
  
  while (left <= right) {
    // 计算中间索引,防止整数溢出
    const mid = Math.floor(left + (right - left) / 2);
    const midValue = sortedArray[mid];
    
    if (midValue === target) {
      return mid; // 找到目标值,返回索引
    } else if (midValue < target) {
      left = mid + 1; // 目标值在右半部分
    } else {
      right = mid - 1; // 目标值在左半部分
    }
  }
  
  return -1; // 未找到目标值
}

console.log(binarySearch([1, 3, 5, 7, 9], 5)); // 输出: 2

console.log(binarySearch([1, 3, 5, 7, 9], 2)); // 输出: -1

console.log(binarySearch([], 1)); // 输出: -1

8.手写promiss.all 、 手写一些数组方法、事件循环机制题

4. 事件循环执行规则总结

  1. 同步代码 > 微任务 > 宏任务
  2. 微任务: Promise.then/catch/finally、process.nextTick、MutationObserver
  3. 宏任务: setTimeout、setInterval、setImmediate、I/O操作、UI渲染
  4. async/await: async函数中,await之前的代码同步执行,await之后的代码相当于then回调(微任务)

1、Vue 2、V3 的响应式原理及区别

5、请实现 String.prototype.padStart 方法。