首页 > 秋招提前批字节抖音电商一面
头像
WaNgLu:)
编辑于 2021-08-08 20:47
+ 关注

秋招提前批字节抖音电商一面 内部员工回复

JS的数据类型以及判断方式

img

看代码说输出

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())

双等(==)比较时的转换

==允许在判断相等时进行强制类型转换

比较规则

  • 类型相同直接比较
  • 数字和字符串比较,将字符串转换成数字进行比较
  • 其他类型和布尔值比较,将布尔转成数字
  • undefined 和 null是一回事

具体可以看之前写过的一篇博客:https://blog.csdn.net/qq_44313091/article/details/108197229

事件捕获和事件冒泡

image-20210807173321915

闭包

原型链

只要把下面这张图搞明白就可以了

图片说明

事件循环

看代码说输出

async function async1() {
  console.log("1");
  await async2();
  console.log("2");
}

async function async2() {
  console.log("3");
}

console.log("4");

setTimeout(function () {
  console.log("5");
}, 0);

async1();

new Promise(function (resolve) {
  console.log("6");
  resolve();
}).then(function () {
  console.log("7");
});

console.log("8");

模块

Es module 和commonJS的区别

  • 区别一

    ES module 属于编译时加载,在编译的时候就能确定模块之间的关系;而CommonJS属于运行时加载,采用ES module的好处是可以做到tree sharking。ES module无法做到运行时加载,因此提出了import( )函数,完成运行时加载,和require( )的区别是,import( )是异步执行的,而require( )是同步执行的。

  • 区别二

    ES module可以加载到模块的部分内容,而CommonJS需要加载整个文件,然后在拿到其中的内容。

  • *区别三

    ES module输出的是值得引用,而CommonJS输出的是值的拷贝。

CDM 和 AMD

在这里顺便提一下AMD 和 CMD的区别吧

  1. 在定义模块时,对依赖的处理不同:AMD推崇依赖前置,在定义模块的时候要声明其依赖的模块;而CMD推崇就近依赖,只有在用到某个模块时才会进行require( )
  2. 对依赖模块执行时机的处理不同:AMD在依赖模块加载完成后直接执行依赖模块,依赖的执行顺序和属性顺序不一定一致。CMD在依赖模块加载完成后并不执行,只是下载。等到所有的依赖模块都加载好之后,进入回调的函数逻辑,遇到require语句的时候才执行对应的模块,这样模块的执行顺序就和我们书写的顺序保持一致了。

垃圾回收算法以及V8引擎是如何进行GC的

垃圾回收算法有哪些

标记清除算法

大多数的Javascrip引擎采用的都是标记清除算法,此算法分为 标记 和 清除两个阶段,标记阶段即为所有活动对象做上标记,清除阶段则把没有标记(也就是非活动对象)销毁。

优点:

它的优点就只有一个,那就是实现起来比较简单,它的状态无非就是标记和非标记2种,可以使用一位二进制表示即可(0或1)

缺点

它有一个很大的缺点,就是在清除之后,对象的内存位置是不变的,所以导致空闲的内存地址不连续,出现了内存碎片,并且由于剩余空闲内存不是一整块,它是由不同大小内存组成的内存列表,这就牵扯出了内存分配的问题。而标记整理算法就可以有效的解决内存碎片的问题。

引用计数法

如果有一个变量引用了这个对象就将引用次数记为1,没有则标记为0,目前很少使用这种算法,因为会有循环引用的问题,并且需要很多变量来保存引用次数,导致消耗内存也比较大。

优点:

引用计数算法的优点我们对比标记清除来看就会清晰很多,首先引用计数在引用值为 0 时,也就是在变成垃圾的那一刻就会被回收,所以它可以立即回收垃圾,而标记清除算法需要定时来执行清除,并且还需遍历堆中的所有对象来进行判断。

缺点:

它需要一个计数器,而此计数器需要占很大的位置,因为我们也不知道被引用数量的上限,还有就是无法解决循环引用无法回收的问题。

V8引擎是如何进行GC的

分代式的垃圾回收

V8引擎中主要采用了分代式的垃圾回收机制,分为新生代和老生代,并且采用了不同的算法。新生代中主要保存一些存活时间较短的对象,并且通常为1-8M,而老生代的对象为存活事件较长或常驻内存的对象,简单来说就是经历过新生代垃圾回收后还存活下来的对象,容量通常比较大。

新生代的垃圾回收

新生代将堆内存分为两部分: 使用区空闲区,新加入的对象都会被放入使用区,当使用区的内存快满时,执行垃圾回收,会对使用区的对象做标记,标记完成之后将使用区的活动对象复制进空闲区并进行排序,随后进入垃圾清理阶段,即将非活动对象占用的空间清理掉。最后进行角色互换,把原来的使用区变成空闲区,把原来的空闲区变成使用区。在这个过程中,会将经常标记的对象 和占用内存较大的对象放入老生代

老生代大的垃圾回收

老生代中主要采用了标记清除算法来将非活动对象直接删除,并且V8引擎中采用了标记整理来优化内存空间。

  • 另外,对于垃圾回收V8引擎还采用了并行回收的的概念,我们都知道,Javascript是单线程语言,所以在执行垃圾回收时,会将主线程挂起,将垃圾回收执行完成之后,才会继续执行主线程,我们称这个行为叫做全停顿。所以V8采用了并行回收,它指的是垃圾回收器在主线程上执行的过程中,开启多个辅助线程,同时执行同样的回收工作。V8引擎其实还做了很多优化,感兴趣的同学,可以继续深入了解。

浏览器渲染

在回答时,我主要提到了HTML解析器和CSS解析器,具体也可以参考我之前发布的一篇公众号。(https://mp.weixin.qq.com/s/wwSJ2V2iEpwbQe1OAjz-Fg)

canvas的点击事件

这块没get到面试官想考察的点

Vue的双向数据绑定

这个问题也是回答了vue2 以及vue3的双向数据绑定,面试官提到了proxy的缺点有哪些?

  • proxy的兼容性不好,无法在ie9以下进行使用
  • proxy的第一个参数必须是对象,无法代理基本数据类型
  • proxy的性能是一个很大的问题,衡量proxy带来的遍历和可能损耗的性能,进行合理的中和,来达到最佳的开发体验和用户体验

vuex

vuex的主要作用是什么

vuex能否在组件中直接使用

从输入url到页面展现发生了什么

这是一个最最最最常规的一个问题了
image-20210807162917641

浏览器的缓存

image-20210807163017349

image-20210807163044492

DNS

image-20210807163320367

DNS缓存

  1. 首先搜索浏览器自身的DNS缓存,如果存在,则域名解析到此完成。
  2. 如果浏览器自身的缓存里面没有找到对应的条目,那么会尝试读取操作系统的hosts文件看是否存在对应的映射关系,如果存在,则域名解析到此完成。
  3. 如果本地hosts文件不存在映射关系,则查找本地DNS服务器(ISP服务器,或者自己手动设置的DNS服务器),如果存在,域名到此解析完成。
  4. 如果本地DNS服务器还没找到的话,它就会向根服务器发出请求,进行递归查询.

进程和线程

  • 进程是执行中的一段程序,而一个进程中执行的每个任务为一个线程。
  • 一个线程只可以属于一个进程,而一个进程可以包含多个进程。
  • 线程无地址空间,它包含在进程的地址空间内
  • 线程的开销或代价比进程要小

这里问到了浏览器的进程有哪些

  • 浏览器进程:主要是负责界面显示、用户交互、子进程管理,同时提供存储等功能。
  • 网络进程:该进程主要负责页面的网络资源加载,比如在地址栏输入一个网页地址,网络进程会将请求后得到的资源交给渲染进程处理。
  • 渲染进程:核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页,排版引擎 Blink 和 JavaScript 引擎 V8 都是运行在该进程中,默认情况下,Chrome 会为每个 Tab 标签创建一个渲染进程。出于安全考虑,渲染进程都是运行在沙箱模式下。
  • GPU进程:Chrome 刚开始发布的时候是没有 GPU 进程的。而 GPU 的使用初衷是为了实现 3D CSS 的效果,只是随后网页、Chrome 的 UI 界面都选择采用 GPU 来绘制,这使得 GPU 成为浏览器普遍的需求。最后,Chrome 在其多
  • 插件进程:主要是负责插件的运行,因插件易崩溃,所以需要通过插件进程来隔离,以保证插件进程崩溃不会对浏览器和页面造成影响。

浏览器的存储方式以及它们的区别

cookies、localStorage、SesionStorage、token、indexedDB

堆和栈的区别

堆中存放的是对象,而栈中保存的是对象的引用地址

什么是跨域及解决方案

image-20210807170036864

发布订阅和观察者模式的区别

简单来说就是,发布订阅模式是针对某个主题来进行订阅,本人之前也写过俩篇文章。

https://blog.csdn.net/qq_44313091/article/details/116584875

https://blog.csdn.net/qq_44313091/article/details/116042804

TCP和UDP

问到了滑动窗口、三次握手、流量控制、拥塞控制等,以及UDP的使用场景。

http2做了哪些改进

image-20210807170545352

首屏渲染以及性能优化

  1. 图片懒加载
  2. 路由懒加载
  3. 第三方插件的按需加载
  4. DNS预解析
  5. 减少DOM操作和网络请求次数

前端路由和后端路由

webpack

webpack是怎么运行起来的

Webpack 的运行流程是一个串行的过程,从启动到结束会依次执行以下流程:

  • 初始化参数:从配置文件和 Shell 语句中读取与合并参数,得出最终的参数
  • 开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译
  • 确定入口:根据配置中的 entry 找出所有的入口文件
  • 编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理
  • 完成模块编译:在经过第4步使用 Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系
  • 输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会
  • 输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统

在以上过程中,Webpack 会在特定的时间点广播出特定的事件,插件在监听到感兴趣的事件后会执行特定的逻辑,并且插件可以调用 Webpack 提供的 API 改变 Webpack 的运行结果。

Plugin和loader的区别

  • Loader` 本质就是一个函数,在该函数中对接收到的内容进行转换,返回转换后的结果。 因为 Webpack 只认识 JavaScript,所以 Loader 就成了翻译官,对其他类型的资源进行转译的预处理工作。

  • Plugin 就是插件,基于事件流框架 Tapable,插件可以扩展 Webpack 的功能,在 Webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。

  • Loader 在 module.rules 中配置,作为模块的解析规则,类型为数组。每一项都是一个 Object,内部包含了 test(类型文件)、loader、options (参数)等属性。

  • Plugin 在 plugins 中单独配置,类型为数组,每一项是一个 Plugin 的实例,参数都通过构造函数传入。

问了flex布局 、rem、em、vh、vw

算法

有效的括号,力扣原题
image-20210807172718457

8月4晚上8点开始面试,大概持续了一个半小时左右,本来以为凉了,没想到第二天收到了二面通知,大家在学习的时候不要仅仅关注于表面,要向下挖掘,探究事物的本质,希望大家都能拿到满意的offer,最后也祝我面试顺利!!!!!!!!

更多模拟面试

全部评论

(4) 回帖
加载中...
话题 回帖

推荐话题

相关热帖

近期热帖

历年真题 真题热练榜 24小时
技术(软件)/信息技术类
查看全部

近期精华帖

热门推荐