No1 ,实战面试题!

145 阅读18分钟

    1。对于mvvm框架的了解。

mvvm框架的话,就是视图层和数据层通过viewmidel来进行修改绑定。具有 底耦合,自动同步数据,可复用,可独立开发的特点。 自动同步数据就是数据双向绑定原理,可以更具体的说说

2,react和vue的区别。

第一点框架不同,Vue本质是MVVM框架,由MVC发展而来;

React是前端组件化框架,由后端组件化发展而来。

第二点监听数据变化不同。Vue通过 getter/setter以及一些函数的劫持,能精确知道数据变化。React默认是通过比较引用的方式(diff)进行的,如果不优化可能导致大量不必要的VDOM的重新渲染。

第三点渲染方式不同。Vue可以更快地计算出Virtual DOM的差异,这是由于它在渲染过程中,会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树。React在应用的状态被改变时,全部子组件都会重新渲染。通过shouldComponentUpdate这个生命周期方法可以进行控制,但Vue将此视为默认的优化。

3。关于路由勾子函数。

beforeRouteEnter (to, from, next) {

// 在渲染该组件的对应路由被 confirm 前调用 },

beforeRouteUpdate (to, from, next) {

// 在当前路由改变,但是该组件被复用时调用

beforeRouteLeave (to, from, next) {

// 导航离开该组件的对应路由时调用

全局路由,组件路由守卫,路由独享守卫。

4,v-for 与v-if的优先级,v-for。所以最好不要一起使用,可以ul --li。

5,关于原型链。

1、所有的引用类型(数组、函数、对象)可以自由扩展属性(除null以外)。

2、所有的引用类型都有一个’_ _ proto_ _'属性(也叫隐式原型,它是一个普通的对象)。

3、所有的函数都有一个’prototype’属性(这也叫显式原型,它也是一个普通的对象)。

4、所有引用类型,它的’_ _ proto_ _'属性指向它的构造函数的’prototype’属性。

5、当试图得到一个对象的属性时,如果这个对象本身不存在这个属性,那么就会去它的’_ _ proto_ _'属性(也就是它的构造函数的’prototype’属性)中去寻找。

6,关于原型链污染?

原型污染是指将属性注入现有JavaScript语言构造原型(如对象)的能力。

JavaScript允许更改所有Object属性,包括它们的神奇属性,如_proto_,constructor和prototype。

在一个应用中,如果攻击者控制并修改了一个对象的原型,那么将可以影响所有和这个对象来自同一个类、父祖类的对象,所有JavaScript对象通过原型链继承,都会继承Object.prototype上的属性,这种攻击方式就是原型链污染。

7,关于 keep- alive。

keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。

8,Rem , em , px , % , vw 之间的区别

PX: px像素(Pixel)。相对长度单位。像素px是相对于显示器屏幕分辨率而言的。

em: 1,子元素字体大小的em是相对于父元素字体大小

2,元素的width/height/padding/margin用em的话是相对于该元素的font-size

rem:rem是全部的长度都相对于根元素

%: font-size: 200% 和font-size: 2em 一样, width: 100%表示自己content的宽度等于父亲content宽度的1倍,line-height: 200% 表示行高是自己字体大小的2倍

vw: 1vw代表浏览器视口宽度的1%。

9, 输入URL后都发生了什么?

1,DNS解析,将域名解析成IP,

2,HTTP请求,TCP连接

3,处理请求,返回报文

4,浏览器GUI渲染线程执行页面渲染,生成CSSOM和DOM合成渲染树;

10,用Electron解决了什么问题?

Electron 是一个跨平台的桌面应用程序 , 它解决了浏览器不能调系统硬件的问题 , saving应用需要调用CPU进行一个挖矿的操作!

11 , 讲一讲微信免登的整体流程。

微信登录遵循协议Aouth2.0中的授权码模式

我们来看一下Aouth2.0中的授权码模式是怎么定义的:

授权码模式(authorization code)是功能最完整、流程最严密的授权模式。它的特点就是通过客户端的后台服务器,与”服务提供商”的认证服务器进行互动。

它的步骤如下:

(A)用户访问客户端,后者将前者导向认证服务器。

(B)用户选择是否给予客户端授权。

(C)假设用户给予授权,认证服务器将用户导向客户端事先指定的”重定向URI”(redirection URI),同时附上一个授权码。

(D)客户端收到授权码,附上早先的”重定向URI”,向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。

(E)认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token);

微信登录的官方文档将微信登录分为3个步骤:

第一步.请求code

1 @...用这段代码向微信开放平台请求授权码code,可拉起微信并打开授权登录页(前提是你安装了微信应用并已登录,未登录的会引导你先登录)

2 @客户端收到授权码后,向自己的服务器发起登录请求,并附带收到的授权码。

3 @服务端收到登录请求,向微信开放平台请求获取access_token,微信开放平台返回Json字符串:

第二步:通过code获取access_token(在自己服务器端做)

1, @...服务端收到返回的access_token,将access_token,expires_in,access_token是否有效 等数据返回给客户端,客户端成功登录

2 @....客户端可利用已有的access_token获取微信用户信息

第三步:通过access_token调用接口

获取access_token后,进行接口调用,有以下前提:

  1. access_token有效且未超时;
  2. 微信用户已授权给第三方应用帐号相应接口作用域(scope)。

其中snsapi_base属于基础接口,若应用已拥有其它scope权限,则默认拥有snsapi_base的权限。使用snsapi_base可以让移动端网页授权绕过跳转授权登录页请求用户授权的动作,直接跳转第三方网页带上授权临时票据(code),但会使得用户已授权作用域(scope)仅为snsapi_base,从而导致无法获取到需要用户授权才允许获得的数据和基础功能。

微信重复登录

假设用户已经获得授权,则下次登录时只需要验证access_token是否有效,无效则重新获取授权,有效则无需重新获得授权。

1.用户向自己的服务器请求登录,登录方式为微信登录,附带上次登录返回的的access_token

2.服务器收到用户的登录请求,向微信开放平台发送access_token是否有效的验证请求如下:

3.服务端获取到新的access_token等信息,并返回给客户端,客户端成功登录或者重新获取授权。

www.cnblogs.com/panxuejun/p…;

12,对ES6 中 set 的理解 ?

它没有键,是个类数组而且里面的值是唯一的, 是一个值得集合,应用场景有 数组去重!

13,京东购物页数据结构设计?

总结:

我们设计了几张表

分类表: tb_category

品牌表: tb_brand

分类品牌表:tb_category_brand

规格组表: tb_spec_group

规格参数表:tb_spec_param

SPU表: tb_spu

SPU详情表: tb_spu_detail

SKU表: tb_sku

关系:

一个分类有多个品牌,一个品牌属于多个分类,所以是多对多

一个分类有多个规格组,一个规格组有多个规格参数,所以是一对多

一个分类下有多个SPU,所以是一对多

一个品牌下有多个SPU,所以是一对多

一个SPU下有多个SKU,所以是一对多;

比如:

Nova 5,白色,3GB,16GB:0_0_0

Nova 5,金色,3GB,16GB:1_0_0

Nova 5,玫瑰金,3GB,16GB:2_0_0

这些特有属性进行排列组合就会有三种,如果在可选项中再添加其他的,排列组合的方式就会更多,所以我们就可以记录每组可选项的下表进行标记,这样可以做到当用户点击哪一个可选项,我们就可以快速定位到SKU。

14,vue 与 React d的区别。

第一点框架不同,Vue本质是MVVM框架,由MVC发展而来;

React是前端组件化框架,由后端组件化发展而来。

第二点监听数据变化不同。Vue通过 getter/setter以及一些函数的劫持,能精确知道数据变化。React默认是通过比较引用的方式(diff)进行的,如果不优化可能导致大量不必要的VDOM的重新渲染。

第三点渲染方式不同。Vue可以更快地计算出Virtual DOM的差异,这是由于它在渲染过程中,会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树。React在应用的状态被改变时,全部子组件都会重新渲染。通过shouldComponentUpdate这个生命周期方法可以进行控制,但Vue将此视为默认的优化。。

15,event Bus 和 Vuex两者做全局状态管理的优缺点 ?

使用EventBus的好处在于:

可全局使用

订阅和发布都很灵活,代码量少

跨组件通信,无需使用缓存

相对于状态管理,缺点也很明显:

订阅和发布必须成对出现,不然就没有意义

由于在页面使用里的灵活性,一旦事件多了后,难以对事件进行维护

在订阅事件的组件里,必须手动销毁监听,否则会引发多次执行

对于一些包含业务逻辑的通信,复用性差,需要在多个地方重复写逻辑

中大型项目都不推荐用EventBus,建议用vuex做状态管理,方便日后维护。

小型项目,涉及到多处跨组件通信的情况,可以考虑使用。

16,使用webPack 的 plugins 做过哪些事情 loader 呢 ?

简单列出一些

  • style-loader 将css添加到DOM的内联样式标签style里
  • css-loader 允许将css文件通过require的方式引入,并返回css代码
  • less-loader 处理less
  • sass-loader 处理sass
  • postcss-loader 用postcss来处理CSS
  • autoprefixer-loader 处理CSS3属性前缀,已被弃用,建议直接使用postcss
  • file-loader 分发文件到output目录并返回相对路径
  • url-loader 和file-loader类似,但是当文件小于设定的limit时可以返回一个Data Url
  • html-minify-loader 压缩HTML
  • babel-loader 用babel来转换ES6文件到ES5

loader特性

  • loader 从右到左地取值(evaluate)/执行(execute)

  • loader 支持链式传递,链中的每个 loader 会将转换应用在已处理过的资源上

  • loader 也可以内联显示指定

  • loader 可以是同步的,也可以是异步的

  • loader 运行在 Node.js 中,并且能够执行任何 Node.js 能做到的操作

  • loader 可以通过 options 对象配置

  • 除了常见的通过 package.json 的 main 来将一个 npm 模块导出为 loader,还可以在 module.rules 中使用 loader 字段直接引用一个模块

  • loader 能够产生额外的任意文件

在plugin有哪些hooks呢?我们也简单列举一下

  • entry-option 初始化 option

  • run

  • compile 真正开始的编译,在创建 compilation 对象之前

  • compilation 生成好了 compilation 对象

  • make 从 entry 开始递归分析依赖,准备对每个模块进行 build

  • after-compile 编译 build 过程结束

  • emit 在将内存中 assets 内容写到磁盘文件夹之前

  • after-emit 在将内存中 assets 内容写到磁盘文件夹之后

  • done 完成所有的编译过程

  • failed 编译失败的时候

html-webpack-plugin可以根据模板自动生成html代码,并自动引用css和js文件

extract-text-webpack-plugin 将js文件中引用的样式单独抽离成css文件

DefinePlugin 编译时配置全局变量,这对开发模式和发布模式的构建允许不同的行为非常有用。

HotModuleReplacementPlugin 热更新

optimize-css-assets-webpack-plugin 不同组件中重复的css可以快速去重

webpack-bundle-analyzer 一个webpack的bundle文件分析工具,将bundle文件以可交互缩放的treemap的形式展示。

compression-webpack-plugin 生产环境可采用gzip压缩JS和CSS

happypack:通过多进程模型,来加速代码构建

17,对vue-route 实现的理解 ?

hash 模式的实现原理

1 早期的前端路由的实现就是基于 location.hash 来实现的。其实现原理很简单,location.hash 的值就是 URL 中 # 后面的内容。比如下面这个网站,它的 location.hash 的值为 '#search’

hash 路由模式的实现主要是基于下面几个特性:

URL 中 hash 值只是客户端的一种状态,也就是说当向服务器端发出请求时,hash 部分不会被发送;

hash 值的改变,都会在浏览器的访问历史中增加一个记录。因此我们能通过浏览器的回退、前进按钮控制hash 的切换;

可以通过 a 标签,并设置 href 属性,当用户点击这个标签后,URL 的 hash 值会发生改变;或者使用 JavaScript 来对 loaction.hash 进行赋值,改变 URL 的 hash 值;

我们可以使用 hashchange 事件来监听 hash 值的变化,从而对页面进行跳转(渲染)。

history 模式的实现原理

HTML5 提供了 History API 来实现 URL 的变化。其中做最主要的 API 有以下两个:history.pushState() 和 history.repalceState()。这两个 API 可以在不进行刷新的情况下,操作浏览器的历史纪录。唯一不同的是,前者是新增一个历史记录,后者是直接替换当前的历史记录,如下所示:

window.history.pushState(null, null, path);

window.history.replaceState(null, null, path);

pushState 和 repalceState 两个 API 来操作实现 URL 的变化

我们可以使用 popstate 事件来监听 url 的变化,从而对页面进行跳转(渲染);

history.pushState() 或 history.replaceState() 不会触发 popstate 事件,这时我们需要手动触发页面跳转(渲染)。

18,一段纯文本,用p标签包裹和div标签包裹哪个更适合, 为什么 ?

通常情况下文章段落是使用P标签的,P本身就是段落的意思,而div更多的是指内容模块,比如说调用最新文章这个内容模块。整篇文章可以使用div包裹,但是文章里面的段落则需要使用P标签。

19,reduce 的用法和实际应用场景?

reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。

应用场景: 数组求和 => 将二维数组转化为一维 => 计算数组中每个元素出现的次数 => 按属性对object分类 => 数组去重

20. 对Vue 中solt 的 应用 与理解 ?

首先,插槽分两类,默认插槽和具名插槽;通俗理解就是默认插槽是没有名称的插槽,具名插槽是有名称的插槽。

1、slot(插槽) 是vue提出的一个概念,插槽用于决定需要携带的内容,可以指定插入的位置。

2、插槽的显示的内容由父组件去决定,显示的位置由子组件进行控制

3、通俗的理解,插槽就是一个“占位置”,在子组件中占好了位置后,内容由父组件决定。

21,精通CSS3 与 HTML5 ??? 。

H5:一、语义标签

二、增强型表单

三、视频和音频

四、Canvas绘图

五、SVG绘图

六、地理定位

七、拖放API

八、WebWorker

九、WebStorage

十、WebSocket

css3:1.过渡 transition: CSS属性,花费时间,效果曲线(默认ease),延迟时间(默认0)复制代码

2.动画 animation:动画名称,一个周期花费时间,运动曲线(默认ease),动画延迟(默认0),播放次数(默认1),是否反向播放动画(默认normal),是否暂停动画(默认running)

3.阴影 box-shadow: 水平阴影的位置 垂直阴影的位置 模糊距离 阴影的大小 阴影的颜色 阴影开始方向(默认是从里往外,设置inset就是从外往里);复制代码

4.边框 border-image: 图片url 图像边界向内偏移 图像边界的宽度(默认为边框的宽度) 用于指定在边框外部绘制偏移的量(默认0) 铺满方式--重复(repeat)、拉伸(stretch)或铺满(round)(默认:拉伸(stretch));

5.背景 background-clip 制定背景绘制(显示)区域 background-origin background-size

6.渐变

22,浏览器的执行机制。

渲染进程 => js引擎线程,GUI渲染线程,js事件触发线程,定时触发线程,异步请求线程 => 同步任务 => 异步微任务 => 宏任务:

23,(非对称加密)RSA 加密规则详解 ?

RSA缺陷

RSA被人们普遍认为是目前最优秀的公钥方案之一。

  然而,虽然RSA的安全性依赖于大数的因子分解,但并没有从理论上证明破译RSA的难度与大数分解难度等价。即RSA的重大缺陷是无法从理论上把握它的保密性能如何。

此外,RSA的缺点还有:

A)产生密钥很麻烦,受到素数产生技术的限制,因而难以做到一次一密。

B)分组长度太大,为保证安全性,n 至少也要 600 bits 以上,使运算代价很高,尤其是速度较慢,较对称密码算法慢几个数量级;且随着大数分解技术的发展,这个长度还在增加,不利于数据格式的标准化。因此,使用RSA只能加密少量数据,大量的数据加密还要靠对称密码算法。

RSA加密过程: (来自维基)

1.爱丽丝与鲍勃事先互不认识,也没有可靠安全的沟通渠道,但爱丽丝现在却要通过不安全的互联网向鲍勃发送消息。

  • 2.爱丽丝撰写好原文,原文在未加密的状态下称之为明文x。

  • 3.鲍勃使用密码学安全伪随机数生成器产生一对密钥,其中一个作为公钥c,另一个作为私钥d.

  • 4.鲍勃可以用任何方法发送公钥c给爱丽丝,即使伊夫在中间窃听到c也没关系。

  • 5.爱丽丝用公钥c把明文x进行加密,得到密文c(x).

  • 6.爱丽丝可以用任何方法传输密文c(x)给鲍勃,即使伊夫在中间窃听到密文c(x)也没问题。

  • 7.鲍勃收到密文,用自己的私钥d对密文进行解密d(c(x)),得到爱丽丝撰写的明文x.

  • 8.由于伊夫没有得到鲍勃的私钥d,所以无法得知明文x.

  • 9.如果爱丽丝丢失了她自己撰写的原文x,在没有得到鲍勃的私钥d的情况下,她的处境将等同伊夫,既无法通过鲍勃的公钥c和密文c(x)重新得到原文x.

对称加密AES

  • 对称加密算法

加密和解密用到的密钥是相同的,这种加密方式加密速度非常快,适合经常发送数据的场合。缺点是密钥的传输比较麻烦。

  • 非对称加密算法

加密和解密用的密钥是不同的,这种加密方式是用数学上的难解问题构造的,通常加密解密的速度比较慢,适合偶尔发送数据的场合。优点是密钥传输方便。常见的非对称加密算法为RSA、ECC和EIGamal。

24,内存 与 指针 的区别 和 定义 ?

在JavaScript中,引用类型(对象、数组、正则、Date、函数)的比较,实际上是比较指针是否指向存储器中的同一段地址,只有指向同样的地址才能相等。

var o1={b:1}实现了在堆内存中创建了一个对象{b:1},o1则存储了该对象在堆内存中的地址,即o1是一个指针,指向{b:1};

同理,var o2={b:1}也在堆内存中创建了一个对象{b:1},o2存储了该对象在堆内存中的地址,即o2也是一个指针,指向{b:1};

并且,由于两个相同的对象{b:1}是先后创建,在堆内存中也不是存储在相同的地址

显然,o1这个指针指向堆内存中创建的第一个对象{b:1};

o2指针则指向堆内存中创建的第二个对象{b:1};

但两个对象相对独立,并不是同一个对象,故o1和o2并没有指向同样的堆内存地址,故而并不相等。

25,原型与原型链 ?

chil.__proto__ === Children.prototype;

chil.__proto__.__proto__ === Person.prototype;

chil.__proto__.__proto__.__proto__ === Object.prototype;

chil.__proto__.__proto__.__proto__.__proto__ === null;

Object.getPrototypeOf(chil) === chil.__proto__;

// 首先定义一个类

class Person {

constructor(name,age) {

this.name = name;

this.age = age;

this.autoSay();

}

autoSay() {

console.log(`我是this.name,今年{this.name},今年{this.age}岁了`)

}

sayHello() {

console.log('hell word')

}

};

class Children extends Person {

constructor(lastname) {

super('children','super');

this.lastname = lastname;

console.log(`我是children${this.lastname}`);

}

}

let peto = new Person('xiao姜','26');

let chil = new Children('姜东');

// 我是xiao姜,今年26岁了

// 我是children,今年super岁了

// 我是children姜东

26,判断数据类型的几种常见方法 ?

1, typeof 判断基本数据类型

2, instanceof 所以此方法常用在判断中,只需要判断d是否为Array数据类型即可。

3,Object.prototype.toString.call() 万能法