小提示:当时直接回答不知道,确实Webpack我只会用,还没了解过内部的实现原理和构成。这个后续无论如何都要好好理解一下原理。
HTTP状态码206是干什么的
206 Partial Content:成功执行了一个部分或者Range请求,因为客户端可以通过一些特殊的手段来获取部分或者范围内的文档。响应报文中包含由 Content-Range 指定范围的实体内容。
小提示:工作中没有遇到过需要上传下载大型文件,所以这个问题当时老老实实回答不知道。具体应该和断点续传相关,可能也需要回答一些range的头部信息等。
React高阶组件的作用有哪些
作用1: 加入新的自定义属性和功能(装饰器)
作用2: 行为区域的变更(状态提升**)**
React和Vue的区别
Vue跟React的最大区别在于数据的reactivity,就是反应式系统上。Vue提供反应式的数据,当数据改动时,界面就会自动更新,而React里面需要调用方法SetState。
##文件上传的二进制具体是怎么处理的
二进制文件的结构
1、结构:头部信息 + 数据;
2、打开二进制文件
例:f = open(path, ‘rb’):以只读形式打开指定文件;
3、读取文件
f.read(size),读取的文件内容为字节;如:\x10\x00\x00\x01\x02\x0D等,一个\x10代表一个字节;
4、解析读取的字节数据
struct模块下的unpack方法
-
格式:struct.unpack(‘数据类型’, f.read(size)) -
数据类型:如下表,struct.unpack(‘h’, f.read(size)),表示解析成short类型;i,表示解析成int类型; -
f.read():表示需要被解析的字节类型的数据;
5、直接读取文件数据(存放到数组内),而不是再返回一个字符串
小提示:只知道上传的头信息是application/x-www-form-urlencoded,也可以对上传的文件的数据进行拦截处理,例如对上传文件的信息进行加密处理。
Vue响应式原理
什么是响应式原理?意思就是在改变数据的时候,视图会跟着更新。这意味着你只需要进行数据的管理,就给我们搬砖提供了很大的便利。React也有这种特性,但是React的响应式方式跟VUE完全不同。而VUE则是利用了Object.defineProperty的方法里面的setter 与getter方法的观察者模式来实现。
小结
其实这一次面试自己感觉面试的不是很好(尽管面试官问的确实比我上面列出的问题多),因为有好几个问题自己确实不清楚。这里再次建议大家不是不知道就是回答不知道,这样不会对面试官造成一些负面印象。这一次面试能够通过运气占了很大一部分。
阿里企业智能事业部(二面)
======================================================================
Vue在computed的整个实现原理
小提示:当时面试官问的蛮好玩的,他问从开始写一个.vue文件开始到DOM渲染到页面上,Vue做了哪些工作。然后我当时没理解面试官是要问vue-loader?DOM树的渲染过程?来来回回试探性的问了面试官几次,才理解原来面试官想知道Vue源码的整个实现过程。
大家如果想了解Vue源码实现的整个粗略过程,可以看下之前写的文章基于Vue实现一个简易MVVM/Vue的运行机制简述。
小提示:由于这边涉及到一些海康的设备(上下位机通信),面试官问我如何知道上位机软件给下位机设备发送了5次信息。这个其实大部分Web前端开发在工作上很难遇到类似的问题,幸亏我以前毕业设计中做过上下位机的TCP通讯。后来我从Leader面那里了解到二面面试官应该是做iot物联网开发这一块的。
通讯
小提示:由于这边涉及到一些海康的设备(上下位机通信),面试官问我如何知道上位机软件给下位机设备发送了5次信息。这个其实大部分Web前端开发在工作上很难遇到类似的问题,幸亏我以前毕业设计中做过上下位机的TCP通讯。后来我从Leader面那里了解到二面面试官应该是做iot物联网开发这一块的。
这里帧头使用2字节识别,校验可以采用CRC校验,帧序号用来识别发送了几次信息。
请求帧数据结构如下:
这里帧头使用2字节识别,校验可以采用CRC校验,帧序号用来识别发送了几次信息。
如何判断两个变量相等
小提示:这里需要分基本类型和引用类型,面试官在这里具体想问的是Object.is的实现原理。这是面试官问我的第一个问题,当时直接回答不知道,内心都觉得接下来要凉凉了。
Watch的运行原理
atch的内部原理解析
1、监听数据改变时, watch是如何工作的?
Vue会把数据设置响应式,即设置他的 get 和 set
当数据被读取,get被触发,然后收集到读取他的东西,保存到依赖收集器
当数据被改变,set被触发,然后通知曾经读取他的东西进行更新。
watch 在一开始初始化的时候,会 读取 一遍 监听的数据的值,于是,此时 那个数据就收集到 watch 的 watcher 了
然后 你给 watch 设置的 handler ,watch 会放入 watcher 的更新函数中
当 数据改变时,通知 watch 的 watcher 进行更新,于是 你设置的 handler 就被调用了.
2、设置了immediate , watch是如何工作的?
设置了 immediate 时,就不需要在数据改变的时候才会触发。
而是在 初始化 watch 时,在读取了 监听的数据的值 之后,便立即调用一遍你设置的监听回调,然后传入刚读取的值.
3、设置了deep , watch是如何工作的?
watch 有一个 deep 选项,是用来深度监听的,什么是深度监听呢?就是当你监听的属性的值是一个对象的时候,如果你没有设置深度监听,当对象内部变化时,你监听的回调是不会被触发的.
Vue的数据为什么频繁变化但只会更新一次
小提示:这里问的是Vue源码对于视图更新的优化。我这里的回答是乱糟糟的,希望有同学能够给出一个精准并且简短的回答。
Vue 异步执行 DOM 更新。只要观察到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据改变。如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作上非常重要。然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际 (已去重的) 工作。Vue 在内部尝试对异步队列使用原生的 Promise.then 和 MessageChannel,如果执行环境不支持,会采用 setTimeout(fn, 0) 代替。
另外,关于waiting变量,这是很重要的一个标志位,它保证flushSchedulerQueue回调($nextTick中执行)允许被置入callbacks一次。
因为Vue的事件机 制是通过事件队列来调度执行,会等主进程执行空闲后进行调度,所以先会去等待所有的同步代码执行完成之后再去一次更新。这样的性能优势很明显,比如:
现在有这样的一种情况,mounted的时候test的值会被循环执行++1000次。 每次++时,都会根据响应式触发setter->Dep->Watcher->update->run。 如果这时候没有异步更新视图,那么每次++都会直接操作DOM更新视图,这是非常消耗性能的。 所以Vue实现了一个queue队列,在下一个tick(或者是当前tick的微任务阶段)统一执行queue中Watcher的run。同时,拥有相同id的Watcher不会被重复加入到该queue中去,所以不会执行1000次Watcher的run。最终更新视图只会直接将test对的DOM的0变成1000。 保证更新视图操作DOM的动作是在当前栈执行完以后下一个tick(或者是当前tick的微任务阶段)的时候调用,大大优化了性能。
执行顺序update -> queueWatcher -> 维护观察者队列(重复id的Watcher处理) -> waiting标志位处理(保证需要更新DOM或者Watcher视图更新的方法flushSchedulerQueue只会被推入异步执行的 n e x t T i c k 回 调 数 组 一 次 ) ? > 处 理 nextTick回调数组一次) -> 处理 nextTick回调数组一次)?>处理nextTick(在为微任务或者宏任务中异步更新DOM)->
- Vue是异步更新Dom的,Dom的更新放在下一个宏任务或者当前宏任务的末尾(微任务)中进行执行
由于VUE的数据驱动视图更新是异步的,即修改数据的当下,视图不会立刻更新,而是等同一事件循环中的所有数据变化完成之后,再统一进行视图更新。在同一事件循环中的数据变化后,DOM完成更新,立即执行nextTick(callback)内的回调。
vue和react一样,对dom的修改都是异步的。它会在队列里记录你对dom的操作并进行diff操作,后一个操作会覆盖前一个,然后更新dom。
Event Loop
绝对定位
-
一旦给元素加上absolute或float就相当于给元素加上了display:block -
absolute元素覆盖正常文档流内元素(不用设z-index,自然覆盖) -
可以减少重绘和回流的开销(如absolute+ top:-9999em,或absolute + visibility:hidden,将动画效果放到absolute元素中)
属性介绍
static,默认值。位置设置为static的元素,它始终会处于文档流给予的位置。
-
inherit,规定应该从父元素继承 position 属性的值。但是任何的版本的 Internet Explorer (包括 IE8)都不支持属性值 “inherit”。 -
fixed,生成绝对定位的元素。默认情况下,可定位于相对于浏览器窗口的指定坐标。元素的位置通过 “left”, “top”, “right” 以及 “bottom” 属性进行规定。不论窗口滚动与否,元素都会留在那个位置。但当祖先元素具有transform属性且不为none时,就会相对于祖先元素指定坐标,而不是浏览器窗口。 -
absolute,生成绝对定位的元素,相对于距该元素最近的已定位的祖先元素进行定位。此元素的位置可通过 “left”、”top”、”right” 以及 “bottom” 属性来规定。 -
relative,生成相对定位的元素,相对于该元素在文档中的初始位置进行定位。通过 “left”、”top”、”right” 以及 “bottom” 属性来设置此元素相对于自身位置的偏移。
浮动、绝对定位和固定定位会脱离文档流,相对定位不会脱离文档流,绝对定位相对于该元素最近的已定位的祖先元素,如果没有一个祖先元素设置定位,那么参照物是body层。
绝对定位相对于包含块的起始位置:
问答题:
-
定位的元素的起始位置为父包含块的内边距(不会在border里,除非使用负值,会在padding里) -
定位的元素的margin还是能起作用的 -
background属性是会显示在border里的 -
z-index是有层叠层级的,需要考虑同一个层叠上下文的层叠优先级 -
z-index是负值不会覆盖包含块的背景色(但是如果有内容,会被包含块的内容覆盖) -
z-index的值影响的元素是定位元素以及flex盒子 -
上面一个定位元素,下面一个正常流的元素,定位元素会覆盖在正常流元素之上,除非给z-index是负值 -
页面根元素html天生具有层叠上下文,称之为“根层叠上下文”
小结
-
定位的元素的起始位置为父包含块的内边距(不会在border里,除非使用负值,会在padding里) -
定位的元素的margin还是能起作用的 -
background属性是会显示在border里的 -
z-index是有层叠层级的,需要考虑同一个层叠上下文的层叠优先级 -
z-index是负值不会覆盖包含块的背景色(但是如果有内容,会被包含块的内容覆盖) -
z-index的值影响的元素是定位元素以及flex盒子 -
上面一个定位元素,下面一个正常流的元素,定位元素会覆盖在正常流元素之上,除非给z-index是负值 -
页面根元素html天生具有层叠上下文,称之为“根层叠上下文”
小结
|