江辰

博客

大厂面试题

发布于 # 前端面试

掌学

一面

自我介绍

  1. 讲讲项目中如何减少 Webpack 打包体积

  2. JS 有哪些基本数据类型

Undefined、Null、Boolean、Number 和 String、Object

- 通过什么方式可以判断出 Object 和 Array(引申到 instanceof 的源码实现)
- Object.prototype.toString.call 为什么是 Object.prototype 而不是 Object.toString.call
    首先你要明白 Object 是 js 中所有其他数据类型的父类。意思是所有的数据类型都继承了 Object,但是无论是 string 还是 array 都是会重写这个 tostring 方法的。从此处就可以说你用的两者就完全不同。

3. 递归是什么?

  • 递归的定义
  • 递归有什么缺点,如何解决?(引申出尾递归优化和迭代)
  1. 讲讲闭包是什么?

    • 闭包引申的垃圾回收机制
  2. var、let、const 的区别

    • var 有什么缺陷?
    • 为什么引入 let 、const?
    • 引申到 JS 源码词法环境上讲
  3. es5 如何实现继承

    • 原型继承方式(这里要注意下,很有可能让你手写)

          function Person() {
              this.name = '123';
          }
      
          Person.prototype.getName = function() {
              console.log(this.name);
          }
      
          function Child() {};
      
          Child.prototype = new Parent();
      
          var child = new Child();
          child.getName();
      
    • 寄生组合继承

          function Person(name) {
              this.name = name;
          }
      
          Person.prototype.getName = function() {
              console.log(this.name);
          }
      
          function Child(age, name) {
              this.age = age;
              Person.apply(this, name);
          };
      
          Child.prototype = new Person();
      
      
          var child1 = new Child(18, 'Faker');
          child1.getName();
      
    • 引申到 es6 的 Class 语法糖

  4. es6 有哪些新的特性

    • 讲讲箭头函数和普通函数的区别
    • 箭头函数可以修改 this 指向吗?
  5. map 和 waekMap 的区别

    • map 和 set 的应用场景
  6. JS 中 this 指向

  7. 讲讲 setTimeout 和 setInterval 的差异

    • setInterval 如果漏写销毁,则会存在内存泄露问题(内存泄露和内存溢出有什么区别?内存溢出,坑满了,没有坑,内存泄露:有人占着茅坑不拉屎)
    • 例举了一个具体例子,比如 setInterval 的不准确性,200ms 插入一个 700ms 同步任务,此时队列栈为空,下一个定时任务多久执行,会导致 setInterval 执行不准确问题,使用 setTimeout 递归解决
  8. CSS 重绘和重排如何理解

  9. 用过函数节流和防抖吗?

  10. localStorage, sessionStorage, Cookie 之间的区别

    • 作用域不同,localStorage 所有窗口,sessionStorage 当前窗口
    • 大小不同,localStorage、sessionStorage 5M, Cookie 5kb 左右
    • 生命周期不同,localStorage 页面销毁,也有效,sessionStorage 页面销毁,消失
  11. 讲讲 React Fiber 架构

  12. 讲讲深浅 Copy

    • 如何实现一个深 Copy
  13. 讲讲对 diff 的理解

  14. 讲讲对 Hooks 的理解

  15. 讲讲 Class 生命周期

二面

  1. 反转二叉树的实现

  2. 一个迷宫,最短路径生成 我大概想了下,暴力解决法

  3. 聊聊业务上的事?

  4. 聊聊最复杂的业务如何处理的?

  5. 如何做性能优化?

HR 面

聊聊期望薪资,达不到,后续就没下文了

泛为科技

  1. JS 有哪些基本数据类型

  2. 下面宽高各是多少

    <style>
        .box {
            width: 100px;
            height: 100px;
            padding: 10px;
            margin: 10px;
            background-color: #f00;
            box-sizing: content-box;
        }
    </style>
    <body>
        <div class="box">12312312</div>
    </body>
1.1 如果 box-sizing 改成 border-box,宽高各是多少
1.2 讲讲盒模型的内容

结果:

  • content-box:宽高 120

  • border-box: 宽高 100

  1. 下面输出结果是什么?
    var count = 100;
    var obj = {
        count: 200,
        getCount: function() {
            console.log(this.count);
        }
    }

    const c = obj.getCount;
    obj.getCount();
    c();

结果:200, 100

这题可以注意下演变:

    let count = 100;
    var obj = {
        count: 200,
        getCount: function() {
            console.log(this.count);
        }
    }

    const c = obj.getCount;
    obj.getCount();
    c();

结果:200, undefined

  1. 下面输出结果是什么?
    var obj1 = { a: 100 };
    var obj2 = Object.assign({}, obj1);
    var obj3 = obj2;
    obj3.a = 200;
    console.log(obj1);
    console.log(obj2);

结果:200,100

  1. span 标签在浏览器中偏移量是多少
    <style>
        .test {
            margin: 20px;
        }
    </style>
    <body>
        <div>
            <span class="test"></span>
        </div>
    </body>
  1. 下面打印结果是多少
    var p1 = new Promise((resolve) => {
        resolve(1);
    });
    var p2 = new Promise((resolve) => {
        setTimeout(() => {
            resolve(2);
        }, 0);
    });
    var p3 = new Promise((resolve) => {
        resolve(3);
    });
    Promise.all([p1, p2, p3]).then((res) => {
        console.log(res);
    });
  1. 下面打印结果是多少
    async function promise2() {
        function p1() {
            return new Promise((resolve) => {
                resolve(1);
            });
        }

        function p2() {
            return new Promise((resolve, reject) => {
                reject(2);
            });
        }

        function p3() {
            return new Promise((resolve, reject) => {
                resolve(3);
            });
        }

        try {
            var p11 = await p1();
            var p22 = await p2();
            var p33 = await p3();
            console.log(p11);
            console.log(p22);
            console.log(p33);
        } catch(e) {};
    }
  1. es5 的继承如何实现

彩云科技

  1. 在横线出补全代码,打印 hello
function fun() {
    return new Promise((resolve, reject) => {
        setTimeout(function() {
            -------
       });
    })
}

fun().then(res  => {
    console.log(res);
});
  1. 下面打印结果是多少
var obj1 = {
    name: '123',
    say: function() {
       console.log(this.name);
    }
}

var obj2 = {
    name: '456',
    say: obj1.say
}

obj2.say();
  1. 下面打印结果是多少
function fun() {
  temp = 0;
}
fun();
  1. 下面打印结果是多少
var obj = {
    name: '张三'
}

function fun(o) {
    o.name = '李四';
}

fun(obj);

console.log(obj.name);
  1. 下面横线出请补全代码,以实现继承
function a() {
    this.name = '张三';
}

a.prototype.say = function() {
    console.log('我的名字' + this.name);
}

function b() {
    this.age = 18;
}

b.prototype = _____;
  1. 请描述下 new 的执行原理
function _new() {
    var obj = new Object();
    consturctor.prototype = arguments;
    obj._proto_ = consturctor.prototype;
    var res = obj.apply(this, arguments);
    return typeof res == 'object' ? res : obj;
}
  1. 为什么 Object.prototype.toString.call 可以判断出变量,而不是通过 Object.toString.call ?

这是因为 toString 为 Object 的原型方法,而 Array ,function 等类型作为 Object 的实例,都重写了 toString 方法。不同的对象类型调用 toString 方法时,根据原型链的知识,调用的是对应的重写之后的 toString 方法(function 类型返回内容为函数体的字符串,Array 类型返回元素组成的字符串…),而不会去调用 Object 上原型 toString 方法(返回对象的具体类型),所以采用 obj.toString()不能得到其对象类型,只能将 obj 转换为字符串类型;因此,在想要得到对象的具体类型时,应该调用 Object 上原型 toString 方法。

二面

  1. 自我介绍

  2. 聊聊前端脚手架

  3. 带团队中有哪些难点 3.1 如何培养实习生,系统的介绍了

  4. 浏览器缓存原理

  5. 聊聊迭代流程

  6. 你有什么想问我的吗

拿到 offer

兴盛优选

一面

  1. 聊聊 vite 和 webpack 的区别

    • vite 是通过访问到特定的执行环境,而编译相关的文件,导致它的编译速度带来了显著的提升
    • webpack 重编译,轻运行,在编译过程中会去通过 babel 递归遍历所有的文件(深度遍历),进行转换,导致在编译阶段的时间很长
  2. 为什么 marign 0 auto 无法垂直居中

  3. 控制 z-index 的规则有哪些

  4. 元素替换概念有了解吗?

  5. 模块化有了解吗,讲讲 import 和 require 的区别?

    • import
      • import 是值 copy
      • 必须写在函数的顶层
      • 导出整个
    • require
      • 地址引用
      • 可以写在任何地方
      • 可以对象式导出
  6. 移动端 1px 像素如何解决?

    1. viewport + rem 实现
  7. 单页应用如何提高加载速度?

    • 讲了下骨架屏,骨架屏的原理是什么?
  8. 讲讲 Vue 的 nextTick 原理

    • 本质上通过 微观任务进行拦截掉下一帧的渲染时间
  9. 一个元素隐藏有几种方式?

    • opacity: 0
    • display: none
    • js if
    • 围绕着这几种属性又讲了下 重排和重绘
    • 重排和重绘的产生原因有哪集中以及解决方案有几种
  10. 讲讲 BFC

    • bfc 产生的条件
    • bfc 的解决方案
  11. 讲讲闭包

    • 闭包的应用场景有哪些
  12. webpack 的原理

    • loader 和 plugin 的区别
    • 多 thunk 如何生成
  13. Git 如何覆盖某次 commit

  14. 讲讲 GC 原理

  15. 实际业务场景题,讲讲你的思路

    • 这里就不展开了,公司的具体场景
  16. JS 如何解决数值精度问题

  17. 讲讲事件循环

二面

  1. css 选择器

  2. display 有哪些属性

  3. 长列表滚动,你怎么优化的

    • 由于业务中的经验没有涉及到这块,只能浅显的讲了讲虚拟滚动
  4. 聊聊你做的性能优化

    • 这里聊了很久,面试官也跟我探讨了如何处理,有没有更好的思路,主要围绕着 STAR 法则讲述即可
    • 聊到 web-view 的时候,又牵扯到了 web-view 的小程序架构
  5. 你工作中最有成就感的一件事,除了上面的,还有吗?

    • 我是按简历中写的来,这里也聊了很久

众安保险

一面

自我介绍

  1. 讲讲 JS 有哪些类型

    • 基本类型
    • 复杂类型

1.1 JS 有哪些方法可以判断类型

  1. 讲讲箭头函数和普通函数区别

  2. JS 异步处理是如何演进的

    • aync/await 有什么缺点 无法暂停 报错,后面的代码就无法执行
  3. 居中有那些方式

  4. 三列布局如何实现

  5. setState 原理

  6. hooks 为何有一些规则使用条件

  7. 算法题,如何实现单向链表反转

  8. 讲讲 ts 的泛型

  9. 讲讲事件循环

二面

  1. 实际场景算法题

  2. TS 的应用场景

  3. Mobx 和 Redux 的原理

  4. 函数式组件特点,和 HOC 区别

字节

一面

自我介绍

  1. CSS 栅格布局

  2. flex: 0 1 auto 的含义

    flex-grow:定义元素在一个空间内放大的比例,默认为 0 flex-shrink:定义元素在剩余空间内缩小的比例,默认为 1 flex-basis:定义元素初始化宽度,这个指不可为负数,如果不使用 box-sizing 改变盒模型的话,那么这个属性就决定了 flex 元素的内容盒(content-box)的尺寸

  3. 聊了下项目上的东西,如何衡量项目的价值

  4. JS 的输出,this 指向

var length = 10;
function fn() {
    return this.length + 1;
}
var obj = {
    length: 5,
    test1: function() {
        return fn();
    }
};
obj.test2 = fn;

//下面代码输出是什么
console.log(obj.test1())
console.log(fn()===obj.test2())
  1. 订阅发布和观察者模式和什么之间的区别,实现一个订阅发布者模式

  2. 柯里话函数的实现

  3. 算法题:twoSum 得到两个数的之后等于 target

xTransfer

一面

自我介绍

  1. 实现一个函数 calc

function calc() {

}

  • 对于任意参数,实现累乘功能
  • 对于两次同样的参数,结果缓存,比如 (1, 2, 3)、(3, 1, 2)
  • 对缓存优化(这里使用 LRU 算法进行缓存优化)

七牛云

一面

自我介绍

  1. 介绍下项目

  2. Fiber 架构原理

  3. Mobx 和 Redux 区别

  4. 针对项目上的功能,介绍了下,提出了问题,如何解决

  5. 实现一个 apply

  6. 说下事件循环的打印结果

  7. 针对深 Copy,变种的题目

二面

  1. 聊聊 React 事件机制原理

  2. 深度聊项目 对于项目要充分了解,MVC 和 MVVM 框架原理

  3. 谈谈摇树的概念

  4. 对微前端有了解吗

  5. 性能优化有哪些点,例举下 对性能优化,围绕着项目上做过的性能优化详细举例下

  6. 阐述下项目背景,带来多大的收益

  7. 聊聊团队管理

  8. 聊聊项目规范如何落地

  9. 聊聊开发效率如何提升的

  10. Webpack 热更新机制原理

三面

产品经理面试,主要聊了聊项目上的情况, 团队管理,印象中最深的事等

年后推进进度,挂

坚果云

一面

随便聊了聊基础

二面

明确需求,明确功能

使用到哪些技术:React、Redis(缓存消息)、MySQL(存储离线消息)、NoSQL(维护一个用户关系图)、MQ(消息队列,读扩散,写扩散)

如果我们要做一个聊天功能,怎么做?(你可以放飞自我,想怎么实现都行)

天壤智能

一面

自我介绍

  1. 讲讲 JS 基本数据类型

  2. 讲讲闭包

  3. 讲讲原型链

  4. 讲讲 es6 特性

    • 讲讲 Proxy
  5. 讲讲引用类型 Copy 问题

  6. 讲讲 promise 原理

  7. 讲讲 redux 中间件

  8. 讲讲 React 15 生命周期

  9. 讲讲 useCallBack 和 useMemo 的区别

    • 还有用到其他 hooks 吗
  10. 讲讲 useRef 和 ref 的区别

  11. 印象中最深的一件事

二面

部门总监面的,问题很尖锐

  1. useMemo 和 useCallBack 有什么本质上的区别 都是对象 1.1 如果只用一个,哪个替换哪个? 用 useMemo 替换 useCallBack,函数和值都是对象

  2. 页面缓存如何做 后端来配置 http 请求头相关字段

  3. 前端路由原理 本人菜鸡,直接回答不知道

  4. 项目中用到哪些 NPM 包

    • 面试官想了解下你的项目复不复杂
  5. 用过 Canvas 吗

HR 面

聊聊期望薪资

掌门

一面

自我介绍

  1. JS 基本数据类型

    • 注意下 typeof NaN 输出什么(输出 number)
    • 列举了下 es5 的数据类型,以及 es6 的数据类型(set 和 map 也是),以及区分方法、type、instanceof、Obect.prototype.toString.call、Array.isArray、利用 constructor 判断是数组还是对象
    • symbol 是用来干啥的 ES5 的对象属性名都是字符串,这容易造成属性名的冲突。比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin 模式),新方法的名字就有可能与现有方法产生冲突。如果有一种机制,保证每个属性的名字都是独一无二的就好了,这样就从根本上防止属性名的冲突。这就是 ES6 引入 Symbol 的原因
    • map 和 set 的区别 这里强调下,map 和 set 本质上不是新的类型,而是一种数据结构 引申到 weakMap 和 weakSet 的区别
  2. var、let、const 区别

    - 围绕着 var 的缺陷,介绍了下 let 和 const 的优点
    - 讲了下词法作用域来形成 let 和 const 的快级作用于
    - Object.freeze 冻结的对象是浅冻结还是深冻结
        const aaa = Object.freeze({ name: { bbb: '123' } });
        aaa.name.bbb = '456';
        这会修改,第一层不会,比如 aaa.name = '456';
        实现深冻结
        ```
        // 深冻结函数.
        function deepFreeze(obj) {
    
            // 取回定义在 obj 上的属性名
            var propNames = Object.getOwnPropertyNames(obj);
    
            // 在冻结自身之前冻结属性
    
            propNames.forEach(function(name) {
                var prop = obj[name];
    
                // 如果prop是个对象,冻结它
                if (typeof prop == 'object' && prop !== null)
                    deepFreeze(prop);
            });
    
            // 冻结自身(no-op if already frozen)
            return Object.freeze(obj);
        }
    ```
    
  3. 箭头函数和普通函数的区别

  4. 数组上有哪些属性

    • length、concat、find、findIndex、flat、join、sort、map、forEach、reduce、pop、push、shift、slice、splice
    • forEach、Map、Reduce 之间的区别
    • 面试官问 for of 和 for in 的区别 for of 用来编译迭代器,一个数据结构只要部署了 Symbol.iterator 属性,就被视为具有 iterator 接口,就可以用 for…of 循环遍历它的成员。也就是说,for…of 循环内部调用的是数据结构的 Symbol.iterator 方法。 for of 不可遍历不可迭代对象,for of 遍历的是值, for in 遍历的是 key
  5. 什么是递归函数

    • 讲了讲尾递归
    • 递归遇到内存溢出如何解决 通过尾递归解决或改成迭代
  6. 以下代码输出结果是什么

6.1

    var obj = {
            say: function() {
                console.log(this);
            },
            say2: () => {
                console.log(this);
        }
    }

6.2

    var obj = {
            say: function() {
                console.log(this);
            },
            say2: () => {
                console.log(this);
        }
    }
    var fn = obj.say;
    fn();
  1. 以下代码输出结果是什么
    var name = '123';
    function test() {
        console.log(name);
        var name = '456';
    }
    test();

    // undefined,因为 JS 是分声明阶段和编译阶段

  1. CSS 实现居中有哪几种方式

    • 元素定宽高实现的方式,通过绝对定位 + display: table-cell; vertical-align: middle; text-align: center;
    • 元素不定宽高,通过绝对定位 + flex
  2. setState 更新原理

    • 引申到合并更新 batchUpdate 关键字命中以及同步和异步讲讲
    • 引申到 render 阶段和 commit 阶段
  3. 常用的 hooks 有哪些

    • 性能问题如何解决
  4. React 组件传递状态有哪几种方式

  5. 讲讲 React Fiber 架构

    • STAR 法则讲述,之前的问题,解决了什么问题,怎么解决的,带来了性能上的好处

二面

  1. 为什么辞职

  2. 工作经历中碰到哪些挑战

  3. 开发流程是咋样的

  4. 团队管理上如何带的

  5. 性能优化如何做的

  6. 二叉树的反转实现

  7. 最短路径的实现

  8. 期望薪资多少

  9. 你有什么想问的

  10. 你对下份工作的期望是什么

HR 面

已拿 offer

微盟

一面

自我介绍

  1. 介绍下最有成就感的项目

  2. 项目上的架构如何设计,围绕着 MVC 层介绍

  3. 实现一个 ajax

//封装一个ajax请求
function ajax(options) {
    //创建XMLHttpRequest对象
    const xhr = new XMLHttpRequest();

    //初始化参数的内容
    options = options || {};
    options.type = (options.type || 'GET').toUpperCase();
    options.dataType = options.dataType || 'json';
    const params = options.data;

    //发送请求
    if (options.type === 'GET') {
        xhr.open('GET', options.url + '?' + params, true);
        xhr.send(null);
    } else if (options.type === 'POST') {
        xhr.open('POST', options.url, true);
        xhr.send(params);

    //接收请求
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
            let status = xhr.status;
            if (status >= 200 && status < 300) {
                options.success && options.success(xhr.responseText, xhr.responseXML);
            } else {
                options.fail && options.fail(status);
            }
        }
    }
}
- 在实现的 ajax 基础上实现调用所有请求,等到所有请求结果成功之后,再返回结果
- 在实现的 ajax 基础上实现请求顺序调用,第一个调用成功之后,再调用第二个,以此类推
  这里实现有问题,没有跟面试官沟通好,下次注意,手写题目,一定要跟面试沟通好

帷幄匠心

一面

自我介绍

实现一个 repeat 函数,根据传入的参数,间隔时间,打印次数,来输出 log

function repeatPrint(msg) {
    console.log(msg);
}

repeat(func, inteval, times){ … }

const r = repeat(repeatPrint, 10, 10);

r("hello world");

function repeat(fn, interval, timers) {
    return function(message) {
        for(let i = 0; i < timers; i++) {
            (function() {
                setTimeout(function() {
                    fn(message);
                }, i * 1000);
            })();
        }
    }
}

二面

自我介绍

  1. 用最精炼的代码实现数组非零非负最小值的索引 index
// 例如:[10,21,0,-7,35,7,9,23,18] 输出索引 5, 数值 7 最小
function getIndex(arr) {
    let index = null;
    ...
    return index;
}


function getIndex(arr) {
    return arr.reduce((pre, cur, index) => {
        return cur > 0 && cur < pre['val'] ? { val: cur, i: index } : pre;
    }, { val: Infinity, i: 0})
}

  1. 该代码输出结果是什么?
const list = [1, 2, 5]
const square = num => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(num * num)
        }, 1000)
    })
}

function test() {
    list.forEach(async x => {
        const res = await square(x)
        console.log(res)
    })
}
test()
  1. H5 和小程序如何计算首屏加载时间

HR 面

已拿 offer

乐言科技

一面

自我介绍

  1. 实现一个 promise.all

  2. event-loop 的执行结果

  3. 根据场景,实现一个 hooks

  4. 场景题, 执行多个 hooks, 渲染出来的结果

一面答的其实很垃圾,居然进入了二面

二面

自我介绍

  1. 简单讲讲项目

  2. 做一道题,手写一唯数组转换树节点

var array = [
    {pid: 4, id: 6617, name: "a",subNode:[]},
    {pid: 5, id: 666, name: "a",subNode:[]},
    {pid: 4, id: 6616, name: "a",subNode:[]},
    {pid: 6616, id: 66161, name: "a",subNode:[]},
    {pid: -1, id: 0, name: "a",subNode:[]},
    {pid: 0, id: 4, name: "a",subNode:[]},
    {pid: 0, id: 5, name: "a",subNode:[]},
    {pid: 4, id: 10, name: "a",subNode:[]},
    {pid: 10, id: 451, name: "a",subNode:[]},
    {pid: 0, id: 98, name: "a",subNode:[]},
    {pid: 98, id: 23, name: "a",subNode:[]},
    {pid: 98, id: 523, name: "a",subNode:[]}
];

var toTree = function(tarArray) {
	let obj = {};
	tarArray.map((item,index) => {
		obj[item.id] = item;
	});
	let newArr = [];
	for(let i = 0;i < tarArray.length; i++){
		var item = tarArray[i];
		var parent = obj[item.pid];
		if (parent) {
			if(parent.subNode) {
				parent.subNode.push(item);
			} else {
				parent.subNode = []
				parent.subNode.push(item);
			}
		} else {
			newArr.push(item);
		}
	}
	console.log(newArr);

    return newArr;
}

toTree(array);

手写题没做出来,挂

网易

自我介绍

一面

  • 围绕着简历上讲了很多

二面

  • 围绕这简历上讲了讲项目

三面

简单介绍下自己

  1. 你在智慧展业项目中碰到的挑战是什么?

    • 这个性能优化,之前没有测试过吗?
  2. 在智慧展业项目上,以你现在的角度来看,有哪些改进点?

  3. 你认为网易严选这款产品,在前端这侧需关注什么?

    • 用户体验
    • 安全保障
    • 界面友好
  4. 如果你入职网易严选团队,最想做哪部分的工作?

    • 工程化方向
  5. 你在以往的工作经历中,有什么主动去解决的一些内容吗?

  6. 你对自己未来规划是怎样的?

    • 能举个例子,展开讲一下,你认为前端技术专家应该是怎样的?
  7. 你觉得自己的优点是什么?

  8. 你有什么想问我的?

字节

线索中台部

一面

自我介绍

  • 介绍下如何搞工程化
  • session 和 cookie 的区别
    • session 用于在服务端记录用户信息的唯一标识
    • cookie 存储在客户端,由于 http 请求是无状态协议,所以通过 cookie 来进行上报用户唯一标识
  • ts 有用过吗? 你对 ts 怎么理解?
  • redux 怎么理解?
  • mobx 怎么理解?
  • Taro 源码如何实现的? Taro 2.x 和 Taro 3 最大区别是什么?
  • 场景题 1
const [input, setInput] = useState('');
const setValue = useCallback(() => {
  console.log(input);
}, input);

render() {
    <>
        <div>input</div>
        <button onClick={setValue}></button>
    </>
}

问1:input 输出什么
问2:如何更改,使得 input 获取最新的值
  • 场景题 2 根据伪代码,实现一个观察者模式
  • 算法题,返回只在字符串出现一次的字符 例:‘abcdert’,输出 a

二面

  1. Mobx 是如何实现数据监听的?

  2. Vite 原理是什么?

    • Vite 一个页面 1000 多个依赖,如何优化?(通过 esbuild 预构建依赖)
  3. Webpack 如何实现 HMR 的?

    • 前端如何实现在某个文件更新之后,打印 console.log(通过 module.hot 来监听文件的更新)
  4. Webpack 原理是什么?

    • Webpack 如何实现 A 打包 B 的?
  5. Taro 原理是什么?

    • 小程序没有删除、更新、添加,哪么 Taro3.x 是如何自己实现的?(小程序的框架支持自定义组件,我是不是可以做一个通用的自定义组件,让它根据传入的参数不同,变成不同的小程序内置组件。而且自定义组件还支持在自己的模板中引用自己,那么我只需要一个这个通用组件,然后从逻辑层用代码去控制当前组件应该渲染成什么内置组件,再根据它是否有子节点去递归引用自己进行渲染就可以了)
    • 如何自己实现一个 Taro
  6. 微信小程序原理是什么?

    • 为什么微信小程序不支持删除、更新、添加 DOM(因为双线程模型)
  7. 前端如何实现大文件上传?

    • Blob.prototype.slice 生成切片,上传到服务端,还要记住顺序,这里通过客户前传入切片的 hash ,给到后端,做合并处理

    • 断点续传,提到断点续传,前端是怎么实现断点续传的? 断点续传的原理在于前端/服务端需要记住已上传的切片,这样下次上传就可以跳过之前已上传的部分,有两种方案实现记忆的功能 前端使用 localStorage 记录已上传的切片 hash 服务端保存已上传的切片 hash,前端每次上传前向服务端获取已上传的切片

      第一种是前端的解决方案,第二种是服务端,而前端方案有一个缺陷,如果换了个浏览器就失去了记忆的效果,所以这里选取后者

  8. ts 有了解过吗? 没有

  9. 前端如何实现截图?

    • 我的回答是 canvas 和 svg,但面试官说针对 HTML 来实现
    • 还有一种方案 headless chrome 实现
  10. css position absolute 是对谁定位的

    • position fixed 是对谁定位的,怎样能让它不针对窗口定位
  11. css 如何实现一个正方形盒子(随父元素)自适应

    • 通过 width 百分比和宽 vw 百分比 来实现(例子:width:)
  12. 编程题 实现一个 retry 函数,实现 fn 请求失败,针对 count 重试,对于重试的 retry,超过 timeout 请求时间,则抛错

        function retry(fn, count, timeout) {};
    
  13. 其他,聊了聊项目上的东西

  14. 你有什么想问我的吗? 问:对于本次面试,你有什么建议给我? 答:面试评价是中级前端工程师,比初级厉害一点,需要深入研究技术,研究的更细,对于很多问题可以深入