面试题

169次阅读

共计 6780 个字符,预计需要花费 17 分钟才能阅读完成。

JavaScript 数据类型 Number  string undefined object symbol null boolean

闭包的定义 : 可以访问函数内变量的函数就是闭包
内存泄漏的原因: 闭包,setstate 两种写法

this.setState({xxx:})

this.setState((nextState)=>{
    return ({xxx:})
})


z-index : 层级  定位后确定元素的层级 越大层级越高

position 属性:

 fiexd-- 固定定位,相对于浏览器定位;static-- - 静态定位;relative-- - 相对定位;相对于自己本身的定位;absolute-- - 绝对定位;相对于父级元素的定位,如果没有父级元素时相对于窗口的定位;sticky-- - 粘性定位  必须指定 top、bottom、left、right4 个值之一

16.8React 新增特性
Pureconpoment: 代替 shouldcomponent 页面值没有发生变化 不会重新渲染页面

hook

lazy

异步加载

前台路由 后台路由区别
前台路由 跳转页面
后台路由 接口访问地址

ES6 模块与 CommonJS 模块的差异
CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。
CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。

XSS 的含义:跨站脚本攻击, 故将跨站脚本攻击缩写为 XSS。恶意攻击者往 Web 页面里插入恶意 Script 代码,当用户浏览该页之时,嵌入其中 Web 里面的 Script 代码会被执行,从而达到恶意攻击用户的目的。

## 做项目流程
* 项目流程 (购物车) 1 个月 -> 16 天 7 天
wiki: 在线文档 写他的需求
1. 需求评审: 前端 (FE) 后台(DEV) 测试(QA) 设计(UI) 产品(PM)
评审需求是否合理 砍掉不合理需求 和 实现难度大的需求

2. UI 出效果图 出完以后开始算 6.3

3. 前后端开始同时开发: 前端封装组件 和 页面
// mock 工具 阿里 RAP
// /abc/ddd {name: ‘ 小花 ’, age: 22}
// /mock/abc/ddd {name: 小白, age: 2}

4. 测试 master(上线分支) pre(预上线分支) dev(开发分支)
1) 测试环境 测试分支 dev
2) dev 完全没问题 代码合并到 master 分组 发布上线 master 分支
上线 都是上 master

5. 上线以后 回归测试 有 bug 改

diff 算法:
高效的 diff 算法能够保证进行对实际的 DOM 进行最小的变动
但是标准的的 Diff 算法复杂度需要 O(n^3)
这显然无法满足性能要求 要达到每次界面都可以整体刷新界面的目的
势必需要对算法进行优化
React 里结合 Web 界面的特点做出了两个简单的假设
使得 Diff 算法复杂度直接降低到 O(n)

1. 两个相同组件产生类似的 DOM 结构 不同的组件产生不同的 DOM 结构
2. 对于同一层次的一组子节点 它们可以通过唯一的 id 进行区分

不同节点类型的比较
为了在树之间进行比较 我们首先要能够比较两个节点 在 React 中即比较两个虚拟 DOM 节点
当两个节点不同时 应该如何处理 这分为两种情况
1. 节点类型不同
2. 节点类型相同 但是属性不同

节点类型不同 直接删除原节点 插入新节点。

虚拟 DOM (VDOM)是真实 DOM 在内存中的表示
UI 的表示形式保存在内存中 并与实际的 DOM 同步
这是一个发生在渲染函数被调用和元素在屏幕上显示之间的步骤 整个过程被称为调和

## event loop 事件循环机制
1. 先执行同步任务
2. 微任务调用栈 [resolve(1), resolve(2), resolve(3)]
3. 宏任务(macrotask): setTimeout setInterval I/O(异步操作) DOM 渲染

## react 事件机制
React 组件上声明的事件没有绑定在 React 组件对应的原生 DOM 节点上,而是绑定在 document 节点上,触发的事件是对原生事件的包装。

React 内部事件系统实现可以分为两个阶段:事件注册、事件触发,涉及的主要类如下:
ReactEventListener:负责事件注册和事件分发。React 将 DOM 事件全都注册到 document 节点上,事件分发主要调用 dispatchEvent 进行,从事件触发组件开始,向父元素遍历。
ReactEventEmitter:负责每个组件上事件的执行。
EventPluginHub:负责回调函数的存储

## B C
B: Business 企业 商家
C: Customer 个人 客户

B2B 和 C2C 都在第三方平台 B2C 则在自身运营平台

B2B: 企业与企业 阿里巴巴
B2C: 商家对个人 卓越 当当 京东
C2C: 个人对个人的 淘宝的小店铺

## async 原理
async === generator + 自动执行器
function spawn (genF) {
return new Promise(function(resolve, reject) {
const gen = genF()
function step(nextF) {
let next
try {
next = nextF()
} catch(e) {
return reject(e)
}
if(next.done) {
return resolve(next.value)
}
Promise.resolve(next.value).then(function(v) {
step(function() {return gen.next(v) })
}, function(e) {
step(function() {return gen.throw(e) })
})
}
step(function() {return gen.next(undefined) })
})
}

## PV UV
PV: 统计页面点击
作用: PM(产品统计页面上某个点击被点击的次数)
实现:
1. 创建一个 img
2. img.src = ‘1.gif?name=abc’
使用: 点击百度按钮 加 pv name=”abc”
1. pv.js <script src=”pv.js”> sendPv
2. sendPv({name: “abc”})

## MVVM 是 Model-View-ViewModel 的缩写

Model 代表数据模型,也可以在 Model 中定义数据修改和操作的业务逻辑。
View 代表 UI 组件,它负责将数据模型转化成 UI 展现出来。
ViewModel 监听模型数据的改变和控制视图⾏为、处理⽤户交互,简单理解就是⼀个同 步 View 和 Model 的对象,连接 Model 和 View
在 MVVM 架构下,View 和 Model 之间并没有直接的联系,⽽是通过
ViewModel 进⾏交互,Model 和 ViewModel 之间的交互是双向的,因 此 View 数据的变化会同步到 Model 中,⽽ Model 数据的变化也会⽴即反
应到 View 上。
ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,⽽
View 和 Model 之间的同步⼯作完全是⾃动的,⽆需⼈为⼲涉,因此开 发者只需关注业务逻辑,不需要⼿动操作 DOM,不需要关注数据状态的同 步问题,复杂的数据状态维护完全由 MVVM 来统⼀管理

## 浏览器渲染 html 的过程 https://www.cnblogs.com/whale…
解析 html
构建 dom 树
dom 树结合 css 文件,构建呈现树
布局
绘制

1. 解析 html 和构建 dom 树是同步进行的,这个过程就是逐行解析代码,包括 html 标签和 js 动态生成的标签,最终生成 dom 树。
2. 构建呈现树,就是把 css 文件和 style 标签的中的内容,结合 dom 树的模型,构建一个呈现树,写到内存,等待进一步生成界面。呈现树一定依赖 dom 树,呈现节点一定会有对应的 dom 节点,但是 dom 节点不一定会有对应的呈现节点,比如,被隐藏的一个 div。
3. 布局,这一步就是结合呈现树,把 dom 节点的大小、位置计算出来。虽然呈现节点已经附着在都没节点上,会有对元素大小、位置的定义,但是浏览器还需要根据实际窗口大小进行计算,比如对 auto 的处理。
4. 绘制,把 css 中有关颜色的设置,背景、字体颜色等呈现出来。

## 异步加载
## fetch 和 axios 的主要区别
1. fetch()返回的 promise 将不会拒绝 http 的错误状态 即使响应是一个 HTTP 404 或者 500
2. 在默认情况下 fetch 不会接受或者发送 cookies

## react 渲染机制:
React 整个的渲染机制就是在 state/props 发生改变的时候 重新渲染所有的节点 构造出新的虚拟 Dom tree 跟原来的 Dom tree 用 Diff 算法进行比较 得到需要更新的地方在批量造作在真实的 Dom 上
由于这样做就减少了对 Dom 的频繁操作 从而提升的性能

## Vue 实现数据双向绑定的原理:
vue 实现数据双向绑定主要是: 采⽤数据劫持结合发布订阅模式·的⽅式
通过 Object.defineProperty() 来劫持各个属性的 setter, getter 在数据变动时发布消息给订阅者, 触发相应监听回调. 整合 Observer, Compile 和
Watcher 三者, 通过 Observer 来监听⾃⼰的 model 的数据变化,通过 Compile 来解 析编译模板指令 (vue 中是⽤来解析 {{}}) 最终利⽤ watcher 搭起 observer 和
Compile 之间的通信桥梁, 达到数据变化 —> 视图更新; 视图交互变化 input —>
数据 model 变更双向绑定效果

## vue react 区别
没有双向绑定
vue MVVM
vue2 Object.defineProperty()

react diff 算法
react 丰富的插件库
react 上手难

## 调用 setState 发生了一些什么
在代码中调用 setState 函数之后,React 会将传入的参数对象与组件当前的状态合并,然后触发所谓的调和过程(Reconciliation)。经过调和过程,React 会以相对高效的方式根据新的状态构建 React 元素树并且着手重新渲染整个 UI 界面。在 React 得到元素树之后,React 会自动计算出新的树与老树的节点差异,然后根据差异对界面进行最小化重渲染。在差异计算算法中,React 能够相对精确地知道哪些位置发生了改变以及应该如何改变,这就保证了按需更新,而不是全部重新渲染。

## 链表:
* 单向链表: 单向链表包含两个域 一个是信息域 一个是指针域
* 双向链表: 每个节点有 2 个指针域 一个是指向前一个节点 另一个则指向后一个节点
* 循环链表: 循环链表就是首节点和末节点被连接在一起
循环链表中第一个节点之前就是最后一个节点
* 数组和链表的区别:
* 链表是链式的存储结构 数组是顺序的存储结构
* 链表通过指针来连接元素 数组则是把所有元素按次序依次存储
* 链表的插入删除元素相对数组较为简单 但是寻找某个元素较为困难
* 数组寻找某个元素较为简单 但插入与删除比较复杂

* 自我理解
* 数组便于查询和修改 但是不方便新增和删除
* 链表适合新增和删除 但是不适合查询

* 盒模型 content-box border-box 区别:
两者的盒子的宽度是否包含表框和内边距
content-box: 总共 width = width + padding + border
border-box 的 width 包括 padding 和 border

* 父传子, 子传父(context) react: 父 -> 子 props 子 -> 父 传递方法

* Redux 三大基本原则:
1. store 单一数据源
2. state 在页面里是只读的 触发 action -> 修改 state
3. state 只能在 reduce 里改 并且 reduce 必须是纯函数
https://blog.csdn.net/arvin_top/article/details/84963350

* react-router: 传参 获取
query: this.history.push({path: ‘/login?name=1’})
动态路由: <Link to=”/login/1″ /> 匹配 ‘/login/:id’ 路由

* 箭头函数指向: 箭头函数的 this 是在定义时就确定的 并且一旦确定就固定不变了
* let const 块级作用域 函数作用域
* Git merge rebase merage 之后会结构会发生什么变化

* react 新的生命周期 react 老的生命周期
* event 对象获取 绑定事件的元素 与 触发事件的元素
* react 中没有共同父组件的兄弟组件之间的传参
pubsub-js
使用发布订阅的方式
PubSub.subscribe(’MY TOPIC’, mySubscriber) 订阅
PubSub.publish(’MY TOPIC’,‘hello world!’) 发布

* async 与 await 没有使用过
* react 中 ref 的作用
拿取当前 DOM 节点
* Promise 函数有
* 如何通过 nodejs 做跨域:
* 箭头函数的作用
* webpack,babel-loader 配置
* async 与 await 在 function 前面写 async 的作用
* Promise.all,race,resolve,reject 是声明在 Promise 函数上的,还是 Promise.prototype
挂在 Promise 上的

* 最近的项目 擅长的技术栈
* rudux view -> action -> reduce
* 点击请求数据 把数据更新到 state 里 在哪请求 componentDidMount
* 同级路由 传数据 *
* 用过的 react 生命周期
* 子组件的 state 依赖父级 props 怎么更改 state 请求的时候怎么拿到正确的 props
当你的 render 函数需要有数据才能渲染的时候 就在 componentWillMount 做操作
当你的 render 不需要数据 先渲染 dom 结构 就在 componentDidMount 操作

* 同级组件 怎么传值
redux / 第一个公共的父组件

* es6 用过那些 解构数组第二项
* const 一个对象可以改变吗
基本类型 不能改
引用类型比较地址 不改变地址的情况 可以改

* 合并数组 数组方法
const arr = [1, 2, 3]
const arr2 = [3, [5], 6]

// 不改变原数组 返回新值
// arr.concat(arr2)

// push(参数 1, 参数 2)
// arr.push(…arr2)

// arr.push.apply(arr, [1, 2, 3])

// console.log([…arr, …arr2] )

// 线上出了个 bug 然后怎么解决 bug 正在写别的代码写了很多代码
* 自我介绍: 我叫什么 大学学的计算机 15 年开始工作 2 年
* 离职原因: 家里有事 回家 1 年
* 18 年 4 月 2 年 电商平台
具体项目介绍 axios 拦截 跨域 挺好
* react 学过吗
* v-if v-show 区别
*
怎么不被其他元素遮挡 z-index
0, 0 点 怎么生效
只写一个盒子 给一个 z-index 会生效吗?

* position 有哪些值: 新增的 粘性 (粘性布局单词我们要背下来)

* 组件化开发
设计弹窗组件: 只要说哪些接口 不要说具体实现
<Dialog
context=””
onOk
….
/>

div 父元素有个兄弟元素
考层级: 应该弹不出来
<div1>
<Dialog />
</div1>
<div2></div2>
弹窗插入到 body 顶层 react 和 vue 的实现
vue 实现插入到 body 里 -> js appendChild 插入
mounted () {

}

## 设计弹窗组件

## 原生的浏览器的事件
* 事件绑定
// 方法一 DOM1
el.onclick = function () {

}
// 方法二 DOM2
// false: 是指触发的事件是在冒泡阶段执行的
// true:
el.addEventListener(‘ 事件名 ’, function () {

}, false(默认) || true)

* 事件解绑
el.removeEventListener(‘ 事件名 ’, function () {
// 绑定解绑必须是同一个函数
})

* 事件传递方式:
DOM2 级事件规定的事件流包含 3 个阶段
// 第一阶段: 捕获 (从外往里) document -> html -> body -> div
// 第二阶段: 目标阶段
// 第三阶段: 冒泡阶段(从里往外) div -> body -> html -> doc
一个布尔值 代表是处于事件冒泡阶段处理还是事件捕获阶段
true 表示将事件绑定在捕获阶段触发(捕获)
false 表示将事件绑定在冒泡阶段触发(冒泡)

* 事件属性和方法
event
preventDefault() 取消事件的默认动作
stopPropagation()

* 怎么判断 this 指向: this 代表当前正在执行的对象
事件回调函数 this 指向
定义的时候没法知道 this 这是肯定的

* call bind apply 区别:
* a.bind(b).call(c) //

闭包的好处:
1. 希望一个变量长期保存内存中
2. 避免全局变量污染
3. 私有成员的存在
4. 能够实现封装和缓存等

闭包的缺点
1. 常驻内存, 增加内存使用量
2. 使用不当造成内存泄露

react 本身的性能优化
1. 定义方法时提出来
2. 使用 PureComponent shouldUpdate

正文完
 0