2022年3月16日复盘

143 阅读7分钟

1.typescript有什么深度使用?

  • 使用类型扩展(接口interface和类型别名type)

    • 区别:interface可以重复声明,ts内部会进行合并;type重复声明会报错
    • 二者可以相互继承
  • 使用.d.ts文件能够声明全局变量

    • 有些第三方库或文件没有.d.ts文件,我们可以自己新建一个.d.ts文件通过declare关键字进行声明模块或变量等
  • typescript支持JS的新特性,能够放肆使用

  • typescript类的定义运行private、public和protected进行成员修饰

  • 类型断言 as

  • 常量枚举

2.你会用threeJS做什么?怎么做的?

  • 基本构建:场景、相机、渲染器;添加自定义:几何体,点,平面,坐标轴,控制器,dat.gui,gsap,几何体的转换(position,scale)配合animate()请求动画帧requestAnimateFrame 和 render函数。

  • 进阶使用:光线,射线,材质,纹理贴图,gltf模型导入,cannon物理引擎,shader着色器,Blender建模

  • threeJS实现

    1. 动态页面滚动:滚动scrolltop和相机的坐标进行绑定关系
    2. 纹理贴图:创建加载器和纹理加载对象,通过load函数加载对应图片,给材质的map属性赋值为对应的贴图对象
    3. 环境贴图:环境其实就是一个盒子,给盒子六个面贴上对应的图片就能够实现
    4. 光源和阴影
    5. glsl实现动态物体效果:旗帜,水波,烟花等

3.vue2和vue3的响应式原理?

  • vue2主要依赖于Object.defineProperty方法,通过set和get方法将对象的属性劫持(缺点:新增的属性无法实现双向绑定,通过$set)

    • new Vue对象时,会传入对象的options(包括data)和$el(当前容器的选择器)属性
    • 执行Observer函数遍历对象属性,将属性放入订阅池中并通过Object.defineProperty劫持对象,执行set方法的时候监听数据变化,然后告诉订阅池进行更新,触发他的update函数更新对应元素属性
    • 订阅池watcher里面是通过update将元素节点属性和data属性进行绑定,某个触发更新时,将data该属性赋值给绑定的元素属性,实现更新
    • compile解析器通过传入的$el属性对选中的节点进行递归遍历,里面每个节点进行解析,存在属性绑定的指令或者是模板语法,创建watcher对象将该属性和data的属性进行绑定,如果是v-model的话就绑定该节点对应的函数触发事件,触发时就将节点更新的值赋值给绑定的data的属性值。
  • vue3通过proxy代理,对整个对象进行劫持,存在属性值发生改变就会触发对应的set方法

    • 使用proxy代理,在获取数据是使用get方法,将属性添加到dep收集依赖(通过map映射关系)中
    • 使用set方法会更新dep依赖的值,通知dep依赖执行更新

3.跨域是什么?服务器就能够跨域吗?

跨域是基于浏览器同源策略(协议,域名,端口都需一致),不能在一个域下面去请求另一个域下面的资源。服务器不存在同源策略,就没有跨域了。

解决跨域的方案:

  • jsonp:通过添加script标签引入对应资源js文件,解析js的时候能够执行内部的代码,不过需要和后端配合执行的函数名,拿到对应的信息。
  • iframe + window.domain:设置主域名
  • iframe + window.name:同一窗口下window使用一个
  • 后端设置CORS允许访问的路径
  • 服务器代理(例如:webpack的devServer)

4.说一下浏览器输入url后网络做了什么?

  1. 输入url后使用dns进行域名解析,因为网络标准规定Url只能是字符和数字加上一些特殊符号,如不进行解析转义会出现歧义,查到IP后进行http协议的三次握手

  2. 三次握手:

    1. 第一次握手客户端发送位码给服务器并随机产生一个确认号
    2. 第二次握手服务器收到请求后,想客户端发送客户端确认号+1的tcp包
    3. 第三次握手客户端收到确认号和位码无误后确认建立连接成功后,开始请求HTML文件
  3. 请求文件的时候发现文件在浏览器缓存里面,则直接从缓存中直接拿,否则就去服务端拿

  4. 缓存:

    1. 首次加载资源成功状态码是200,此时浏览器不仅下载了资源,还将响应的header信息一起缓存了

    2. 缓存分为强缓存和协商缓存(内存缓存memory,硬盘缓存disk)

      1. 从缓存中加载资源首先经过强缓存的处理,其中涉及到两个信息,cache-control和expires用来确定缓存是否过期,cache-control优先级更高(没有cache-control去expires的值),先去找它的max-age=xx比较上次请求和当前请求时间是否超过当前时间戳,没超过则命中缓存,在缓存中获取资源,过期的话则去找协商缓存
      2. 协商缓存阶段header信息中带有if-modified-since,如果该值和服务端最近文件改动时间一直则命中协商缓存,返回304,不一致则返回一个新的last-modified和文件状态码为200

5.DNS具体是怎么实现的?

www.baidu.com为例

  • 浏览器中输入url后,首先会从浏览器缓存中查找是否有记录,存在的话会将对应的ip返回
  • 浏览器缓存中没有,会从本地的dns解析器中查找,再从计算机配置的dns上看是否有缓存
  • 上述都没找到的话,就去根DNS服务器寻找,判断.com由哪个服务器管理,在找.baidu.com服务器能否解析,知道查到www.baidu.com的IP地址

6.引用类型前面加一个加号,这其中涉及到js哪些操作?

我回答到类型转换的规则,可并不是面试官想要的答案。

可参考该文章

其中涉及到 valueOftoString 这两个方法,在特定场合下自行调用

  • valueOf()方法返回指定对象的原始值,一般都是会被js自动调用
  • toString()方法返回一个表示该对象的字符串,当对象表示为文本或以字符串的方式应用时,该方法会被自动调用。

优先查询 valueOf() 方法,在 valueOf() 方法返回的是非原始类型的情况下或valueOf()方法不存在再查询 toString() 方法。

如果只改写 valueOf() 或是 toString() 其中一个,会优先调用被改写了的方法,而如果两个同时改写,和正常的一样。

7.vuex是什么?平常用来干嘛?

这个主要介绍平常用到哪些属性和各个属性的用法

8.你项目中遇到过什么困难?怎么解决的?

这个就具体情况具体回答了

9.keep-alive是干什么的?vue在其中帮忙做了什么?

keep-alive使用来缓存组件的,让包裹的在内的白名单组件不被销毁。

keep-alive是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在父组件链中;使用keep-alive包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。

一般vue组件的渲染都是通过渲染函数转化成vnode,然后通过patch对比渲染成真实dom;

而keepalive只会在第一次像vue组件一样渲染,他在render之后会将当前vnode进行缓存到当前keepalive的内置缓存集合中,下次渲染直接从缓存中拿对应的vnode并刷新其位置,因为keepalive会将超过缓存数量上限的vnode清除掉。