01-11

  1. 京东小程序Taro,开发小程序
  2. 微信小程序 —主流 —花时间写写
  • navigateTo, redirectTo 只能打开非 tabBar 页面。
  • switchTab 只能打开 tabBar 页面。
  • reLaunch 可以打开任意页面。
  • 页面底部的 tabBar 由页面决定,即只要是定义为 tabBar 的页面,底部都有 tabBar。
  • 调用页面路由带的参数可以在目标页面的onLoad中获取。

    3-22

    1.JavaScript垃圾回收机制的了解

    4-15PLAY

    1.Vue2.0 源码解析
    2.vue核心+vue-router+vuex+axios+elementUI+Antd
    3.JS+es6+js核心
    4.项目—work+gitee
    5.阿里云云服务器
    6.JAVA基础
    7.SpingBoot
    8.微信小程序
    9.数据可视化
    10.你不知道的JS 上中下
    11.面试题
    12.

    4-19

    1.缓存
    强缓存和协商缓存
    2.js深浅拷贝
    深拷贝的思路就是递归调用刚刚的浅拷贝,把所有属于对象的属性类型都遍历赋给另一个对象即可。我们直接来看一下 Zepto 中深拷贝的代码:
    // 内部方法:用户合并一个或多个对象到第一个对象
    // 参数:
    // target 目标对象 对象都合并到target里
    // source 合并对象
    // deep 是否执行深度合并
    function extend(target, source, deep) {
    for (key in source)
    if (deep && (isPlainObject(source[key]) || isArray(source[key]))) {
    // source[key] 是对象,而 target[key] 不是对象, 则 target[key] = {} 初始化一下,否则递归会出错的
    if (isPlainObject(source[key]) && !isPlainObject(target[key]))
    target[key] = {}

    1. // source[key] 是数组,而 target[key] 不是数组,则 target[key] = [] 初始化一下,否则递归会出错的<br /> if (isArray(source[key]) && !isArray(target[key]))<br /> target[key] = []<br /> // 执行递归<br /> extend(target[key], source[key], deep)<br /> }<br /> // 不满足以上条件,说明 source[key] 是一般的值类型,直接赋值给 target 就是了<br /> else if (source[key] !== undefined) target[key] = source[key]<br /> }

    // Copy all but undefined properties from one or more
    // objects to the target object.
    $.extend = function(target){
    var deep, args = slice.call(arguments, 1);

    1. //第一个参数为boolean值时,表示是否深度合并<br /> if (typeof target == 'boolean') {<br /> deep = target;<br /> //target取第二个参数<br /> target = args.shift()<br /> }<br /> // 遍历后面的参数,都合并到target上<br /> args.forEach(function(arg){ extend(target, arg, deep) })<br /> return target<br /> }<br />**3.作用域链**:当访问一个变量时,解释器会首先在当前作用域查找标示符,如果没有找到,就去父作用域找,直到找到该变量的标示符或者不在父作用域中,这就是作用域链。

    5-21

    问题一:vue项目中为什么要在列表组件中写key?作用是什么?
    答案:key是给每一个vnode的唯一id,可以依靠key,更准确, 更快的拿到oldVnode中对应的vnode节点.
    vue和react都是采用diff算法来对比新旧虚拟节点,从而更新节点。在vue的diff函数中(建议先了解一下diff算法过程)。在交叉对比中,当新节点跟旧节点头尾交叉对比没有结果时,会根据新节点的key去对比旧节点数组中的key,从而找到相应旧节点(这里对应的是一个key => index 的map映射)。如果没找到就认为是一个新增节点。而如果没有key,那么就会采用遍历查找的方式去找到对应的旧节点。一种一个map映射,另一种是遍历查找。相比而言。map映射的速度更快。

    1. 更准确

    因为带key就不是就地复用了,在sameNode函数a.key === b.key对比中可以避免就地复用的情况。所以会更加准确。

    2. 更快

    利用key的唯一性生成map对象来获取对应节点,比遍历方式更快。(这个观点,就是我最初的那个观点。从这个角度看,map会比遍历更快。)
    就我的使用来说(Vue)key的作用是为了在数据变化时强制更新组件,以避免“原地复用”带来的副作用。另外,某些情况下不带key可能性能更好.
    主要是为了提升diff【同级比较】的效率。自己想一下自己要实现前后列表的diff,如果对列表的每一项增加一个key,即唯一索引,那就可以很清楚的知道两个列表谁少了谁没变。而如果不加key的话,就只能一个个对比了。
    问题二:[‘1’, ‘2’, ‘3’].map(parseInt)what & why ?
    答案:[1, NaN, NaN]
    var new_array = arr.map(function callback(currentValue[, index[, array]]) { // Return element for new_array }[, thisArg])
    callback一共可以接收三个参数,其中第一个参数代表当前被处理的元素,而第二个参数代表该元素的索引。
    parseInt(string, radix)
    问题三:什么是防抖和节流?有什么区别?如何实现?
    答案:防抖:触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。
    每次触发事件时都取消之前的延时调用方法
    function debounce(fn) {
    let timeout = null; // 创建一个标记用来存放定时器的返回值
    return function () {
    clearTimeout(timeout); // 每当用户输入的时候把前一个 setTimeout clear 掉
    timeout = setTimeout(() => { // 然后又创建一个新的 setTimeout, 这样就能保证输入字符后的 interval 间隔内如果还有字符输入的话,就不会执行 fn 函数
    fn.apply(this, arguments);
    }, 500);
    };
    }
    function sayHi() {
    console.log(‘防抖成功’);
    }
    var inp = document.getElementById(‘inp’);
    inp.addEventListener(‘input’, debounce(sayHi)); // 防抖
    节流:高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率
    每次触发事件时都判断当前是否有等待执行的延时函数
    function throttle(fn) {
    let canRun = true; // 通过闭包保存一个标记
    return function () {
    if (!canRun) return; // 在函数开头判断标记是否为true,不为true则return
    canRun = false; // 立即设置为false
    setTimeout(() => { // 将外部传入的函数的执行放在setTimeout中
    fn.apply(this, arguments);
    // 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。当定时器没有执行的时候标记永远是false,在开头被return掉
    canRun = true;
    }, 500);
    };
    }
    function sayHi(e) {
    console.log(e.target.innerWidth, e.target.innerHeight);
    }
    window.addEventListener(‘resize’, throttle(sayHi));
    问题四:介绍下 Set、Map、WeakSet 和 WeakMap 的区别?
    答案:
    Set1.成员不能重复2.只有健值,没有健名,有点类似数组。3. 可以遍历,方法有add, delete,has
    weakSet

  1. 成员都是对象
  2. 成员都是弱引用,随时可以消失。 可以用来保存DOM节点,不容易造成内存泄漏
  3. 不能遍历,方法有add, delete,has

Map

  1. 本质上是健值对的集合,类似集合
  2. 可以遍历,方法很多,可以干跟各种数据格式转换

WeakMap

  1. 直接受对象作为健名(null除外),不接受其他类型的值作为健名
  2. 健名所指向的对象,不计入垃圾回收机制
  3. 不能遍历,方法同get,set,has,delete

问题五:介绍下深度优先遍历和广度优先遍历,如何实现?
答案: https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/9
问题六:ES5/ES6 的继承除了写法以外还有什么区别?
答案:

  1. class 声明不会提升,但不会初始化赋值。Foo 进入暂时性死区,类似于 let、const 声明变量。
  2. class 声明内部会启用严格模式。
  3. class 的所有方法(包括静态方法和实例方法)都是不可枚举的。
  4. class 的所有方法(包括静态方法和实例方法)都没有原型对象 prototype,所以也没有[[construct]],不能使用 new 来调用。
  5. 必须使用 new 调用 class。
  6. class 内部无法重写类名。

ES5 和 ES6 子类 this 生成顺序不同。ES5 的继承先生成了子类实例,再调用父类的构造函数修饰子类实例,ES6 的继承先生成父类实例,再调用子类的构造函数修饰父类实例。这个差别使得 ES6 可以继承内置对象。
问题七:setTimeout、Promise、Async/Await 的区别
答案:settimeout的回调函数放到宏任务队列里,等到执行栈清空以后执行。
promise.then里的回调函数会放到相应宏任务的微任务队列里,等宏任务里面的同步代码执行完再执行。
async函数表示函数里面可能会有异步方法,await后面跟一个表达式,async方法执行时,遇到await会立即执行表达式,然后把表达式后面的代码放到微任务队列里,让出执行栈让同步代码先执行。
问题八:Async/Await 如何通过同步的方式实现异步
答案:
问题九:Promise 构造函数是同步执行还是异步执行,那么 then 方法呢?
答案:Promise new的时候会立即执行里面的代码 then是微任务 会在本次任务执行完的时候执行 setTimeout是宏任务 会在下次任务执行的时候执行
看过 Event Loop 基础原理的就明白,Promise构造函数是同步执行,而 .then .catch .啥啥的是异步(还有process.nextTick等等,大家可以查),
而且放到了微队列中,async/await 中,await 前面的是同步,await 后面的是异步,写法上是这样,但是其实是 语法糖,最后还会转为 Promise.then的形式
问题十:如何实现一个new?
答案:
问题十一:有以下 3 个判断数组的方法,请分别介绍它们之间的区别和优劣Object.prototype.toString.call() 、 instanceof 以及 Array.isArray()
答案:
Object.prototype.toString.call()
每一个继承 Object 的对象都有 toString 方法,如果 toString 方法没有重写的话,会返回 [Object type],其中 type 为对象的类型。但当除了 Object 类型的对象外,其他类型直接使用 toString 方法时,会直接返回都是内容的字符串,所以我们需要使用call或者apply方法来改变toString方法的执行上下文。
这种方法对于所有基本的数据类型都能进行判断,即使是 null 和 undefined 。
Object.prototype.toString.call(‘An’) // “[object String]”
Object.prototype.toString.call(1) // “[object Number]”
Object.prototype.toString.call(Symbol(1)) // “[object Symbol]”
Object.prototype.toString.call(null) // “[object Null]”
Object.prototype.toString.call(undefined) // “[object Undefined]”
Object.prototype.toString.call(function(){}) // “[object Function]”
Object.prototype.toString.call({name: ‘An’}) // “[object Object]”

Object.prototype.toString.call() 常用于判断浏览器内置对象时。
instanceof()
Object.prototype.toString.call() 常用于判断浏览器内置对象时。
使用 instanceof判断一个对象是否为数组,instanceof 会判断这个对象的原型链上是否会找到对应的 Array 的原型,找到返回 true,否则返回 false。
但 instanceof 只能用来判断对象类型,原始类型不可以。并且所有对象类型 instanceof Object 都是 true。
[] instanceof Array; // true
[] instanceof Object; // true
Array.isArray()

  • 功能:用来判断对象是否为数组

当检测Array实例时,Array.isArray 优于 instanceof ,因为 Array.isArray 可以检测出 iframes
Array.isArray()是ES5新增的方法,当不存在 Array.isArray() ,可以用 Object.prototype.toString.call() 实现
问题十二:介绍下重绘和回流(Repaint & Reflow),以及如何进行优化?
答案:
问题十三:介绍下观察者模式和订阅-发布模式的区别,各自适用于什么场景?
答案:
观察者模式:观察者模式中主体和观察者是互相感知的
订阅-发布模式:发布-订阅模式是借助第三方来实现调度的,发布者和订阅者之间互不感知
问题十四:浏览器和Node 事件循环的区别?
答案:
问题十五:

  • 讲讲js数据类型?基本和引用的区别?symbol和bigint讲一讲应用场景?
  • 判断数据类型的方法?instanceof原理?判断空对象? typeof null?typeof NaN?
  • var/let/const 区别?暂时性死区?块级作用域?const a = {}; a.x = 1 能不能修改?
  • 说说你对函数式编程的理解?函数柯里化的理解?平时的使用场景?
  • 防抖、节流的含义,使用场景?手写一下?
  • call、apply、bind区别?bind实现?bind之后还能修改this指向吗?为什么?
  • 闭包概念,最主要的还是问闭包的场景?
  • 用es5实现es6类的继承?各种继承问的挺多的
  • 深拷贝与浅拷贝?常用方法?手写一个深拷贝函数?
  • 说说你知道的JavaScript设计模式?观察者和发布订阅的区别?手写一个发布订阅?我真的写了
  • 说说对你对JavaScript异步编程的理解?
  • ES Module与 CommonJS 模块的差异?两者互相加载的方式?一般会扯到AMD
  • Promise.all、race、allSettled 概念、手写?很多手写题都会用到,比如用promise实现请求并发个数限制?

答案:
问题十六:

  • 水平垂直居中?兼容性?不知道宽高情况下?
  • BFC概念?作用?常用场景?
  • Flex?注意flex:1的含义,一般会给你个场景题
  • 盒模型概念,如何切换盒模型?
  • 实现1px边框?1px线条?
  • 伪类和伪元素区别?使用场景?

答案:
问题十七:

  • 浏览器缓存?http缓存? 主要要讲一讲强缓存、协商缓存、preload、prefetch、Service Worker等,304的含义?协商缓存e-tag是怎么生成的?Last-Modified是基于什么生成的?两者对比一下?优先级哪个高?
  • 什么是跨域?什么情况下会跨域?浏览器根据什么字段判断是否允许跨域?跨域的解决方案有哪些?options请求了解过吗?说说CORS中的简单请求和复杂请求?form表单提交会跨域吗?
  • 讲一讲浏览器事件循环Event Loop?node 事件循环描述一下?
  • http2有哪些新特性?http2还有哪些缺陷?http3的一些了解?
  • 从输入 URL 到页面加载完成的过程,一般要很详细的描述:包括DNS查询,缓存查询,3次握手,4次挥手,浏览器渲染进程等,面试官会从里面再挑几个问题深入问,比如为什么是3次握手4次挥手?渲染进程中的GUI渲染线程、JS引擎线程、事件触发线程等等?可能会问到进程线程的区别?浏览器为什么是多进程?js为什么是单线程?怎么支持多线程?等等
  • https加密原理?主要是讲对称加密和非对此加密结合使用的一个过程。什么是中间人攻击?和http区别?

答案:
问题十八:

  • 生命周期?那个生命周期可以获取到真实DOM?修改data里面的数据,会触发什么生命周期?
  • 组件data为什么是一个函数?
  • vue 组件通信?一般说了vuex,就会问vuex用法?action和mutations区别?实现原理等?
  • vue 导航守卫,分全局和组件的,一般用于权限控制,这个就可能扯到项目中的一些鉴权问题。
  • $nextTick 作用?实现原理?微任务向宏任务的降级处理,经常被问到说出几种宏任务,微任务。
  • vue响应式原理?基本都会问
  • vue scoped属性作用?实现原理?
  • vue router有几种模式?实现方式?
  • key的作用?没有key的情况,vue会怎么做?会引出diff的问题
  • vue diff过程,和react diff区别?
  • vue 2.x defineProperty缺陷?业务代码里面怎么处理?$set原理?vue是怎么重写数组方法的?考察你是不是真的看过源码
  • vue 3.0 proxy优缺点?怎么处理vue3不支持IE?
  • computed 和 watch 的区别和运用的场景?除了基本的,看你能不能说出三种watcher的区别

答案:
问题十九:React题目

  • 生命周期详细描述一下?官方为什么改变?
  • 说说你对虚拟DOM的理解?直接全量更新和diff哪个快(这个问题要分情况)?
  • 什么是HOC?React里面用过哪些?可能让你实现一个add(1)(2)(3)的函数
  • Fiber干了什么事情?requestIdleCallback了解多少?
  • react性能优化?
  • hooks出现的意义?类组件和函数组件之间的区别是什么?
  • 为什么不要在循环、条件语句或者嵌套函数中调用hooks?记住官网的一句话,Not Magic, just Arrays
  • setState 同步还是异步?比较常问,问的可能也比较深入
  • 如何避免组件的重新渲染?memo/useMemo、PureComponent?useMemo和useCallback区别?

答案:
问题二十:node+webpack

  • 常用的一些模块,fs/path/http等等
  • EventEmitter 概念,使用场景,错误捕获
  • Stream 概念?使用场景?常见的Stream?

webpack基本也是必问,得系统学习一下

  • webpack 构建流程?打包原理?
  • 项目中做的一些优化?
  • loader和plugin的区别?有没有写过?常用哪些loader和plugin
  • webpack热跟新原理?
  • tree-shaking?对于 CommonJS,tree shaking怎么办?
  • webpack loader的执行顺序?从左到右?从上到下?

答案:
问题二十一:

  • 项目做过的一些性能优化,基本必问
  • 长列表渲染怎么优化?
  • 各种懒加载的实现原理?路由?图片?
  • Typescript 中的 interface 和 type 到底有什么区别

答案:
问题二十二:

  1. 关于Html
  • html语义化标签的理解; 结构化的理解; 能否写出简洁的html结构; SEO优化
  • h5中新增的属性; 如自定义属性data, 类名className等, 新增表单元素, 拖拽Drag
  • h5中新增的API, 修改的API, 废弃的API 稍作了解 (离线存储, audio, video)
  1. 关于CSS
  • CSS选择器( 三大特性 )
  • BFC机制
  • 盒模型
  • CSS模块化开发(封装); SCSS和LESS的使用
  • 屏幕适配 以及 页面自适应
  • CSS3中新增的选择器
  • CSS3中新增的属性, transform trasition animation等…
  1. 关于布局
  • 标准文档流(padding + margin + 负margin) + 浮动float + 定位
  • 百分比布局(流式布局): px单位 用 %num代替, 占父级元素的百分比
  • flex弹性布局: 主轴 辅助轴的几个属性
  • grid栅格布局: 使用框架中的类名来替代: 本质上还是百分比布局
  1. 关于JS基础
  • 变量数据类型及检测: 基本 + 引用
  • 运算符: 算术 + 条件 + 逻辑 + 位 + 短路, 隐式转换等
  • 条件, 循环, 异常处理 if switch(){case xxx:} try catch finally throw
  • 函数定义, 调用方式(apply, call, 直接调用), 传参: 实参给形参赋值
  • 字符串, 数组, 对象常用API,
  • 正则表达式
  1. 关于JS高级
  • 作用域, 作用域链, 闭包
  • 原型, 原型链, 继承
  • 函数上下文, this指向
  • js的运行机制, 事件队列和循环
  • 同步, 异步编程
  1. 关于网络协议
  • HTTP协议
  • cookie, session, token
  1. 关于ES6语法
  • 字符串, 数组, 对象 扩展的api
  • 变量扩展: let const 解构赋值 块级作用域
  • 函数扩展: 箭头函数 默认参数, rest参数
  • 展开运算符, 模板字符串
  • set 和 map数据结构
  • 迭代器和生成器函数 next 和 yield的理解
  • proxy对象 属性代理器: 属性的读取(get)和设置(set)相关操作
  • promise对象, 异步编程的解决方案
  • async + await: 异步编程的终极方案 promise + generator的语法糖
  • class语法 构造函数的语法糖
  • 模块化编程 export + import 的 导出和导入
  1. VUE基础
  • 基本指令
  • 实例的属性和方法
  • 实例的生命周期
  • 组件基础: 创建,注册,添加属性方法,套用等…
  • 组件通信传值 父子, 兄弟, 跨级
  • 插槽slot等…
  1. VUE高级
  • vue-router: 搭建SPA
  • 路由,组件的配置
  • 路由间的传值
  • 路由跳转
  • 路由的导航守卫
  • 记住在router.js 和 组件页面中的使用方式
  • vuex: 状态管理: 数据仓库store
  • 实例化仓库的5大属性的使用state, getters, mutations, actions, modules
  • 辅助函数mapState等…, 仓库中计算属性的映射, 方便操作
  • 记住在 store.js 和 组件中 使用方式
  1. VUE深入, 源码阅读
  • 数据响应式原理
  • virtual dom
  • diff 算法
  • nextTick等等…
  • vue2和vue3的数据绑定
  • vue3的componest API
  • vite的用法

    DOM

    掌握原生的DOM操作

    增删查改

    熟悉node和element对象

    事件关于事件的机制
  • 冒泡和捕获

  • 事件委托
  • 自定义事件
  • Event对象
  • 面向对象

    了解面向对象的思想,能够以面向对象的思想构建应用。比如封装一个日历组件,设计对象所需的属性值和方法。
  • new方法

  • 继承,派生
  • 原型和原型链

    函数
  • 熟悉Array,String等的方法

  • call和apply方法的使用
  • 链式调用
  • this

    工程化

  1. 掌握gulp
  2. 索引行考察手写gulp任务
  3. 掌握模块化
  • CMD标准
  • commonjs
  • ES6模块
  • babel如何使用
  • webpack打包方案
  • 异步加载
  • 打包多个文件
  1. 掌握webpack
  • 阅读webpack文档
  • 理解配置文件结构
  • 合并,注入生效代码部分
  • 热更新
  1. CSS
    命名策略
    嵌套
    变量
    函数
    了解nodeJS对于前端岗位,nodejs的使用主要集中在自动化和搭建简单的数据服务器两个方面。
  • 是否上传过npm包
  • 断点调试法
  • express
  • 插件
  • 中间件
  • 路由原理
  • HTTP协议
  • 数据库查询
  • HTML模板(ejs,pug)

    了解ES6
  • promise

  • Generator
  • 花括号作用域
  • class
  • 数组遍历(ES5)
  • 严格模式(ES5)
  • 模块系统

    框架专题

    通用
  • MVC

  • 双向数据绑定
  • 单项数据流
  • 组件化
  • 生命期
  • 路由

    前端模板
  • 横向对比,所用模板的优点

  • 至少使用过两种以上的前端模板

    工程能力考察:

  1. 项目能力
  • vue-cli脚手架搭建和功能配置 vue.config.js
  • vite的使用和搭建等
  • webpack的常用配置
  • 项目构建 打包
  1. 熟悉各类框架的文档…
  • UI框架: Bootstrap, MUI, Element-ui等
  • 常用的插件整理, 整理一个自己插件库, 封装自己的方法库,组件库
  1. 常用的工具熟练度
  • PC端和移动端开发注意事项和兼容性
  1. 经验总结: 如何快速确定项目的技术选型
  2. 坑点总结
  • 项目遇到坑坑坑!!!
  • 如何处理,如何提出issue并且合作处理
  1. git或者svn等使用情况
  2. 项目中的性能优化记录 ( 都是细节点…多记录 )
  3. 需求文档的理解, 可以结合 项目流程图, UML图
  4. 问题解决能力: (bug定位调试, 查找文档, 寻求他人…)
  5. 平常有记录的习惯吗。

    模块化, 组件化开发能力

  • 项目分类; 各类文件整理,分类
  • 各类功能封装
  • 组件和功能模块的抽离, 解耦, 复用

    内功考察:

  1. 面向对象的编程思想
  • 类的抽象
  • 对象的封装, 继承
  • 为了更好的去管理数据, 分类数据 实现高内聚, 低
  1. 设计模式
  • 设计模式感觉也是
  • 将面向对象思想 再度抽象成现实中 某些特定模式
  1. 数据结构和算法
  • 学习常用的排序搜索算法, 顺序表,链表,栈,队列,树,堆 结构等等…
  • 考验你的 抽象思维 和 数学功底了
  • 将现实需求 抽象成 计算机代码 的思维能力

    附加技能考察:

  1. 学习能力
  • 持续学习的态度–博客, 笔记记录
  • 技术论坛活跃度高, 问答多
  • GitHub开源项目参与
  1. 了解一门后端语言
  • node.js, python, php等…
  • 数据库mysql,redis,mongodb. sql的操作语句, mongo的操作语句, redis操作语句
  • node + express 搭建本地服务等
  • python + django + request + scrapy
  1. 系统编程
  • Linux命令行操作, 系统文件管理
  • 多任务, 多线程, 多进程, 协程, 并发, 并行, 串行, 同步, 异步等概念的理解

问题二十三:
答案:
问题二十四:
答案:
问题二十五:
答案:
问题二十六:
答案:
问题二十七:
答案:
问题二十八:
答案:
问题二十九:
答案:
问题三十:
答案:
问题三十一:
答案:
问题三十二:
答案:
问题三十三:
答案:
问题三十四:
答案:
问题三十五:
答案:
问题三十六:
答案:
问题三十七:
答案:
问题三十八:
答案:
问题三十九:
答案:
问题四十:
答案: