当前位置: 首页 > 面试经验 >

4399前端一面

优质
小牛编辑
67浏览
2024-04-16

4399前端一面

时长:22min 方式:腾讯会议

1. 自我介绍

2. 选择前端原因与时间

3. for in 和 for of 的区别

  • for...in:用于遍历对象的可枚举属性(包括原型链上的属性)。对于数组,for...in 循环将返回数组的索引(索引其实就是属性名,只不过它是数字。但for...in并不会按照数字的大小顺序来遍历这些属性,它的顺序更多的是按照这些属性在内存中存储的顺序,也就是说,它的顺序是不确定的;此外,for...in还会遍历数组的所有可枚举属性,包括从原型链上继承下来的属性)。故推荐使用 for...in 遍历对象,而非数组。
  • for...of:用于遍历拥有迭代器的集合(如Array,Map,Set,字符串等)。与 for...in 不同,for...of 返回的是遍历元素的值,而且它总是返回自身的值,而不会去遍历原型链上的值。
  1. for of可以遍历对象嘛?

在JavaScript中,for...of实际上是遍历集合的值,它需要被遍历的对象具有迭代器 (Iterator) 接口。在JavaScript中,内置的可迭代对象包括String,Array,TypedArray,Map 和 Set,所以它们都可以通过 for...of进行遍历。然而,普通的对象 (Object) 并没有默认的迭代器接口。所以,如果你直接使用 for...of 来遍历一个对象,将会抛出错误:“TypeError: XXXX is not iterable”。

  1. for in可以遍历map嘛?

不能!for...in 是用来遍历一个对象的可枚举属性的,但是 Map 对象的元素并不是以可枚举属性的形式存储。实际上,对于Map对象,for...in循环将不会产生任何输出。
这与对象的内部差异有关。 Map 对象内部持有一个迭代器,该迭代器知道如何访问对象的每一个元素。另一方面,普通对象没有这样的内置迭代器,取而代之的是存储其属性的内部表格,这就是 for...in 循环能遍历普通对象的原因。

4. 说两种 js 的继承方式比较优缺点

  • 原型链继承:主要通过设置原型对象实现继承。优点是写法简单,易于理解。缺点是所有实例共享同一个原型,如果原型对象上的属性值为引用类型,那么所有实例都将共享这些属性,一旦其中一个实例改变这个属性值,其他实例的该属性值也会跟着改变。
  • 类继承(ES6 class):ES6 引入了 class 关键字,更接近于传统的面向对象语言,它实际上是对原型链继承的一种语法糖。优点是语法更清晰,定义类和继承更加直观,对于面向对象背景的开发者来说更易理解,同时实例互不干扰。缺点是JavaScript 并非一门传统面向对象编程语言,使用 class 有一种误导性,可能让人误以为 JavaScript 有真正的类,其实它里面还是使用原型链方式实现的继承。
  1. 原型链这种方式修改一个子属性会不会改掉所有公用这个父类的属性?

会。在原型对象(父对象)上定义的属性是引用类型(如数组、对象等),那么所有通过原型链继承这个属性的实例(子对象)都会共享这个属性。因此,如果有一个实例修改了这个属性,那么所有其他实例看到的也会是修改后的属性。

  1. 在这种情况下不想让它修改该怎么办?
  • 构造函数继承:在子类的构造函数中调用父类的构造函数。问题是每次实例化时都会创建一遍父类的属性。
function Parent() {
    this.colors = ['red', 'blue', 'green'];
}

function Child() {
    Parent.call(this);
}

var child1 = new Child();
var child2 = new Child();

child1.colors.push('black');
console.log(child1.colors);  // Output: ['red', 'blue', 'green', 'black']
console.log(child2.colors);  // Output: ['red', 'blue', 'green']
  • 组合继承:组合继承是原型链和借用构造函数的组合。这种方式每个实例都有自己的属性(通过调用父类构造函数实现),同时又能继承父类的原型方法(通过原型链实现)。
function Parent() {
    this.colors = ['red', 'blue', 'green'];
}

Parent.prototype.getName = function() {
    return this.name;
}

function Child() {
    Parent.call(this);
}

Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;

var child1 = new Child();
var child2 = new Child();

child1.colors.push('black');
console.log(child1.colors);  // Output: ['red', 'blue', 'green', 'black']
console.log(child2.colors);  // Output: ['red', 'blue', 'green']

5. 浏览器与node的事件循环

6. CommonJS 与 ES Module 区别

  1. import A from B 是对 B 的引用还是拷贝?

当使用 ES6 模块(ESModule)的 import 语法导入一个模块时,所获取的是该模块 export 出的接口的引用。在原始模块的值改变时,这个改变也会反映在导入的那个模块接口中,这就是所谓的“实时绑定”或者叫做“动态引用”。

  1. const A = require B 呢?

使用 require 来加载另一个模块时,实际上是运行了那个模块,并把模块的 exports 或 module.exports 属性导出。这个过程中进行了一次浅拷贝,返回的是一个对象的复制值,而非引用值。

  1. require 可以在浏览器端中使用嘛?

在传统的浏览器环境中,是不能直接使用 require 的。如果想在浏览器环境下使用(require()),你需要使用像 Browserify 或者 webpack 这样的工具,将你的代码打包成适用于浏览器环境的文件。

  1. import 呢?需要做什么处理还是直接用?

import 是 ES6 的模块引入语法,现代的浏览器 Chrome,Firefox 等都开始支持 ES6 的模块引入语法。但是,对于一些老版本的浏览器或者一些不支持 ES6 的浏览器,仍然没法直接使用 import,仍然需要使用 Babel,webpack 等工具,将 import 编译成浏览器可以识别的 require 或者其他等效代码。

  1. vite 模块引用用的哪个?(ES Module)

7. 对分析多张图片在http1、1.1、2.0中是一张张加载、一批次加载、还是一次性全部加载?

HTTP/1.0、HTTP/1.1 中都是一张张加载图片的,而 HTTP/2.0 能够实现多张图片一次性并行加载。

  • 在 HTTP/1.0 中,会为每张图片创建一个新的 TCP 连接,请求并载入图片然后断开连接。缺点就是它会为每个请求创建和断开一次连接,带来额外的延迟,并且限制了同时并行多个请求的能力。
  • 在 HTTP/1.1 中,虽然还是一张张加载图片,但是它引入了持久连接。这意味着同一连接可以被多个请求复用,图片在相同的TCP连接上依次加载,避免了每次请求都建立和关闭连接的开销。但是,HTTP/1.1 仍然存在一种被称为“线头阻塞”(Head-of-line Blocking)的问题——每个连接上的请求仍然必须按顺序完成,即使其中的一些请求准备就绪也必须要等待前面的请求完成。
  • 在 HTTP/2.0 中,图片可以在同一个 TCP 连接上并行加载。通过在同一连接中分割多个消息流,允许并行发送请求和响应信息。每个消息流都有自己的ID,保证了数据包的有序到达和完整性。因此,可以在同一时间从服务器一起载入多张图片,不仅加快了网页的载入速度,也减少了服务器的压力。

8. 如何处理消息列表特别长卡顿的情况

9. 网页多开,每开一个建立一个 websocket 连接,如何优化

  • 共享 WebSocket 连接:如果浏览器的多个标签页或窗口之间可以共享一些状态信息,那么可以采用一种方式使这些页面共享同一个 WebSocket 连接。例如,可以使用 SharedWorker 和 Broadcast Channel 两个 API 实现 WebSocket 连接的共享。
  • 连接池:可以在服务器端实现 WebSocket 连接池,池中的每个连接可以服务于多个用户。这有助于减轻服务器的压力,但这种方法需要维护更复杂的代码和数据结构。
  • 使用 MQTT 协议:相较于 WebSocket,MQTT 是一个较轻量级的协议,适合需要频繁创建和断开连接的场景。MQTT 是基于发布/订阅模式的消息协议,可以方便地实现一对多或多对多的通信。
  1. 不同 tab 间信息通信如何实现?

LocalStorage 和 SessionStorage、Cookies、BroadcastChannel API、SharedWorker、window.postMessage

  1. 详细说一下 SharedWorker ?

SharedWorker 是 HTML5 提供的一种 Web Worker。它被设计为在多个执行环境间共享,可以在多个浏览器的 tab 或 window 页面之间共享和交换数据,这在普通的 web worker 中是无法实现的。这就解决了多个页面之间数据共享、同步等问题,也极大地降低了系统的复杂度。我们能够借助 SharedWorker 将一些计算密集型或需要保证数据一致性的操作放在独立的全局脚本中进行,从而不会阻塞用户的界面操作,提高了页面的响应速度和资源的利用效率。

10. interface 和 type 区别

11. react 中 setState 的执行是同步和还是异步

12. 介绍下 Vue 中的 reactive

  1. const B = reactive(A),修改 B 的属性会改到 A 嘛?

会。使用 reactive 函数创建的响应式对象是对原始对象的深层拷贝,并建立类似代理的机制能够在操作 reactive 对象时同步到原始对象上,所以对 reactive(A) 返回的对象 B 的任何修改,都会影响到原始对象 A。这是因为 reactive 函数的设计目标就是要创建一个响应式的版本,这个版本和原始对象是联动的。

  1. 直接修改 A 会触发视图的更新嘛?B 呢?

直接修改原始对象 A,它自身并不是响应式的,所以不会触发 Vue 的视图更新。reactive 给我们返回的新对象 B 才具有响应性,所以总是通过这个响应式对象 B 去操作数据,使得视图能够响应数据的变化更新。

13. uniapp+vue 编译原生微信小程序做了什么

  • 代码转译:Uni-app 会将 Vue.js 的代码转译成微信小程序可以理解的 JavaScript 和 WXML(微信小程序标记语言)代码。这包括 Vue.js 的模板、样式和脚本部分。例如,Vue.js 的模板部分会被编译成 WXML,Vue.js 的样式部分会被编译成 WXSS(微信小程序样式语言)。
  • 组件转换:Uni-app 会将 Vue.js 的组件转换为微信小程序的组件。例如,uni-app 自己的标签
  • API 整合:为了实现开发一次,发布到多个平台,uni-app 还需要将一些微信小程序特有的 API 整合成 uni-app API ,以便开发者能够在其他平台也能使用这些功能。
  • 目录结构映射:微信小程序的目录结构(pages、components)与 uni-app的目录结构不完全相同,所以需要转换。
  • 压缩和优化:对代码进行压缩,提高程序运行效率,减小程序体积,使得加载更快。
  1. 编译后是完全没有Vue了嘛?(对)

14. 反问

  1. 前端业务(看部门 h5、小程序、内部管理系统)
  2. 技术栈(看部门,Vue、React)

感受:追问扣的好细,顶不住>︿<

 类似资料: