部分面试知识点梳理

移动端适配

响应式布局

一套css方案兼容多个终端,而不是为了每个特定终端重写css方案。

1,添加视口meta标签,重写默认视口

<meta name="viewport" content="width=device-width, initial-scale=1.0">

2,媒体查询

1
2
3
@media (max-width: 480px){...}
@media (max-width: 767px){...}
@media (min-width: 768px) and (max-width: 979px){...}

这里也有一个IE兼容性问题,IE不支持媒体查询,因此需要一个js解决方案。

1
2
3
<!–[if lt IE 9]>
<script src=”../../css3-mediaqueries.js”></script>
<![endif]–>

流式布局(百分比布局)

页面元素的宽度按照屏幕分辨率进行适配调整,但整体布局不变。 宽度使用百分比定义,但是高度和文字大小等大都是用px来固定 ,因此在大屏幕下不太协调。

rem布局(等比缩放、弹性布局)

rem和em的区别:rem,em都是顺应不同网页字体大小展现而产生的。其中,em是相对其父元素,在实际应用中相对而言会带来很多不便;而rem是始终相对于html大小,即页面根元素。

由于页面元素的大小单位换成了rem,而rem又基于html根字号计算,因此应先确定根字号的值。

使用淘宝flexible.js适配,在head标签中引入,不需设置meta标签重置默认视口,交给flexible.js自动处理。

除了font-size之外的尺寸均写成rem单位,根据设计稿大小和设计稿的基准字体换算。sass、less、sublime插件可以方便的在px和rem单位中转换。

性能优化

1,请减少HTTP请求 ,合并图片为精灵图,合并css和js文件,懒加载等。

2,重绘和回流。尽量使用class为页面元素变换属性,每设置一次style属性将导致一次回流,重新计算布局和大小等样式。无法避免回流时,使用DocumentFragment 缓存操作。

3,减少DOM操作。循环创建DOM时可将节点缓存在变量中,循环结束时一次性写入。使用DocumentFragment 缓存操作。

4,使用CDN加速(内容分发网络)。CDN系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。 引自百度百科。

5,页面缓存。通过manifest文件在客户端本地缓存一部分公共资源或者变动较少的资源,达到提升页面载入速度,降低服务器压力的效果。

6,减少DNS查找,减少重定向。浏览器可以并行下载,但多个主机名需要多次DNS查询,因此将主机名控制在2-4个之内。重定向将导致浏览器再次重复解析、请求的过程,因此尽量避免。

懒加载

作为服务器前端的优化,减少请求数或延迟请求数。

方式:

  • 使用setTimeOut或setInterval进行加载延迟.
  • 符合某些条件或者触发了某些事件才开始异步下载
  • 仅加载用户可以看到的区域,这个主要由监控滚动条来实现,一般会在距用户看到某图片前一定距离遍开始加载

补充:

1,屏幕可视区域大小

1
2
3
**原生方法**:         window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight 
**jQuery方法**:
$(window).height();

2,浏览器窗口顶端与文档顶部距离(滚动条滚动距离)

1
2
3
**原生方法**:     window.pagYoffset||document.documentElement.scrollTop||document.body.scrollTop 
**jQuery方法**:
$(document).scrollTop();

闭包

1,有权访问另一个函数作用域中的变量的的函数。

2,能够读取其他函数内部变量的函数。

3,函数和声明该函数的词法环境的组合。

4,当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行。

分析参见博客对闭包的理解

优点:

  • 保护函数内的变量安全,加强了封装性
  • 在内存中维持一个变量不被销毁,设计私有的方法和变量

缺点:

  • 常驻内存 ,易造成内存泄漏

原型链

在用构造函数构造对象时,构造出的对象每个都是相互独立的,既不互相影响,也都有自己属性和方法的副本,没有共享可言,也浪费了资源。为了解决这个问题,每个函数都有一个prototype属性,这里记录了 所有实例对象需要共享的属性和方法,而那些不需要共享的数据或者方法,则还放在构造函数中去。而实例对象一经创建,__proto__自动引用prototype中记录的属性和方法。 prototype像是实例对象的原型,实例则像是继承了prototype对象。 __proto__按照继承关系层层引用,形成一条原型链,最终指向null。

跨域

cors

cors支持post、get两种请求方式。支持cors的服务器对跨域请求响应时将添加Access-Control-Allow-Origin响应头 ,浏览器会分析该响应头中所标示的内容。如果其包含了当前页面所在的域,那么浏览器就将知道这是一个被允许的跨域访问,从而不再根据同源策略来限制用户对该数据的访问。

jsonp

JSONP通过在文档中嵌入一个<script>标记来从另一个域中返回数据。script标签的src属性不受同源策略限制,利用这一点可以实现跨域请求数据,由此而来的缺点也显而易见——仅支持get请求。

webpack

webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle

webpack.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
entry: __dirname + "/app/main.js", //入口文件
output: { //出口
path: __dirname + "/build",
filename: "bundle-[hash].js"
},
devtool: 'none',
devServer: {
contentBase: "./public", //本地服务器所加载的页面所在的目录
historyApiFallback: true, //不跳转
inline: true,
hot: true
},
module: {
rules: [{
test: /(\.jsx|\.js)$/,
use: {
loader: "babel-loader"
},
exclude: /node_modules/
}, {
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: [{
loader: "css-loader",
options: {
modules: true,
localIdentName: '[name]__[local]--[hash:base64:5]'
}
}, {
loader: "postcss-loader"
}],
})
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: __dirname + "/app/index.tmpl.html" //new 一个这个插件的实例,并传入相关的参数
}),
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin(),
new ExtractTextPlugin("style.css")
]
};
  • bable:编译JavaScript
  • devserver :开启一个本地服务环境
  • Loaders:调用外部的脚本或工具,实现对不同格式的文件的处理 (Sass - css)
  • Plugins:拓展Webpack功能,在整个构建过程中生效,执行相关的任务

前端存储

cookie是由服务器发给客户端的信息,以文本的形式保存在客户端本地,客户端每次发起请求时将在header里携带cookie一起发送到服务端。由此弥补了http协议无状态的缺陷,服务端可以得知用户的身份信息,跟踪会话。

cookie受同源策略限制,且存在有效期、路径、httponly(JavaScript不能读取httponly的cookie)、secure(只使用https协议发送,防止中间人攻击)等属性,JavaScript操作cookie需要自己封装函数。

此外,cookie的数量和大小也有限制,由于每次请求都会带上cookie,因此过多的cookie将导致性能下降。

sessionStorage

sessionStorage 是HTML5新增的一个会话存储对象,用于临时保存同一窗口(或标签页)的数据,在关闭窗口或标签页之后将会删除这些数据。 sessionStorage只在本地生效,不会随http请求发送到服务端,sessionStorage同样存在存储大小限制,5MB左右。sessionStorage适合用于SPA单页应用,在不同组件中传值。

sessionStorage有原生的操作方法,不需要自己动手封装。

1
2
3
4
sessionStorage.setItem(key , value);  //写入
sessionStorage.getItem(key); //读取
sessionStorage.removeItem(key); //移除
sessionStorage.clear(); //清除所有值

localStorage

localStorage也是html5新增的特性,实现本地存储。不同于cookie,localStorage的存储大小为5MB左右,与sessionStorage唯一不同的是,localStorage是永久的,会话结束也不会被销毁,其语法也与sessionStorage相似。

1
2
3
4
localStorage.setItem(key, value);
localStorage.getItem(key);
localStorage.removeItem(key);
localStorage.clear();

indexedDB & WebSql

实现了一个前端的持久化数据库。

BFC(块级格式化上下文)

一个独立的渲染区域,只有块级元素参与, 它规定了内部的块级元素如何布局,并且与这个区域外部毫不相干。

生成BFC

  • 根元素
  • 浮动元素
  • position为absolute或fixed
  • display为inline-block, table-cell, table-caption, flex, inline-flex
  • overflow不为visible

参考:http://www.cnblogs.com/lhb25/p/inside-block-formatting-ontext.html

Web攻击

XSS(跨站脚本攻击 )

攻击者向Web页面中插入恶意Script代码,当用户浏览该页时,嵌入其中的Script代码会被执行,从而达到恶意攻击用户的目的。

XSS是由于浏览器直接执行不可信的用户输入导致的,包括存储型和反射型两种,反射型XSS攻击没有将恶意代码保存到网站,通过引诱用户点击触发。存储型XSS将恶意代码保存在网站服务器中,每当用户访问网站时触发,因此危害更大。

防御方法:前端对用户表单提交的数据进行过滤,检测用户输入是否含有非法内容,如<>;&+等,同时后端应对前端的提交内容做进一步的转义处理,

CSRF(跨站请求伪造 )

XSS利用受信任的用户,恶意代码由攻击者提交,而CSRF利用受信任的网站,构造好恶意代码后由受害用户提交。CSRF漏洞允许攻击者利用正常用户的身份发起一个请求,达到恶意修改密码、修改绑定邮箱、代替支付等行为。

防御方法:为每个用户会话随机生成一个token,保存在session中,每次提交时验证服务端的session与客户端的token是否相同。

如果事先XSS拿到cookie,再去CSRF。。

服务端推送

ajax轮询

每隔一段时间发送一次ajax请求,直到接到数据为止。会对造成服务端压力,发送大量无用请求。

ajax长轮询

发送一次请求,若没有新消息则服务端将请求挂起,直到有新消息再返回。会造成服务端进程占用,资源不能即时释放。

WebSocket

先利用http协议握手,随后使用TCP连接,全双工通信。

———————–8月20日更新———————-

学历问题签合同的时候被某外包拒签。这个事情告诉我们不确定的事情尽量先处理完。。

此前面试通过4家公司,收到的反馈有对项目规范化流程不熟练,项目经验略少且偏向展示,没有复杂交互经验,有些细节知识掌握不到位,停留在死记硬背的水平上。电话面试的时候真应该录音,方便整理、查漏补缺,应对下一次面试。

————————补充部分面试经验——————–

实际上面试过程中,我前面整理的知识点都有问到,算作是基础的部分,但只是简单的梳理,对各部分知识的了解应该能自己阐述明白,做到条理清晰,用词规范准确最好。

ES6语法

几乎每次面试必问。。答出let,const声明变量、模板字符串、箭头函数、class声明类、对象扩展、数组扩展、promise、async(await)即可。

let、const声明变量

let声明变量产生块级作用域和暂时性死区,const声明常量不可更改其值,但const声明对象可更改对象的属性,答出其原理。

字符串扩展

可保留字符串内的回车换行,内嵌变量或者函数。

箭头函数

箭头函数和普通函数的区别,this指向问题。箭头函数的函数体中的this仍指向其所在的上下文环境,而普通函数内部的this指向将随函数的调用者的改变而改变。

class声明类

其原理仍然是js的原型链继承。阐述时理清prototype,__proto__,constructor等指针的指向和继承关系。

对象扩展

直接在对象中写变量,属性值为变量值,属性名为变量名。

数组扩展

...运算符实现数组或者对象的克隆、合并等等。这部分涉及到的浅拷贝和深拷贝的理解,理解为主。此外问到过数组的迭代map、foreach的区别,fliter方法等等。

promise

promise问的相当多,js实现异步是回调和promise,promise的思想和原理需要简单过目记忆,链式调用的原理,race方法和all方法使用的场景也有问到。

async & await

放在一起说,ES6用迭代函数generator实现了程序中断,在generator函数的内部使用yield和next等方法控制中断和恢复程序执行,async和await是generator函数的一套语法糖,合并了复杂的语法实现简化语法。理解不了的话这段话可以背一下。。

react

render在什么情况下会被触发

三个情况,props改变,state改变,父组件状态改变。父组件更新子组件会被重新render,在子组件的shouldComponentUpdate生命周期中返回false阻止回流,做一部分性能优化。

这里涉及一个纯组件的概念,通过继承一个特殊的类pureComponent来实现自动性能优化,在状态改变时对虚拟DOM做一层浅比较,然后自动判断是否需要重新渲染。详细原理可以自行百度。

connect函数

将组件的展示部分和逻辑部分链接起来,返回一个高阶组件。connect函数接受两个参数mapStateToProps和mapDispatchToProps分别将状态和dispatch函数映射到当前组件的props中,同时返回一个函数,这个函数接收当前组件为参数,最终返回一个将逻辑和展示组合在一起的高阶组件。高阶组件的本质是函数。理解不了可以背一背。

react-redux的流程

官网上的说明就不错。redux将所有需要管理的状态放在一个单一的store中,改变state的唯一方法是触发一个action,action是一个普通对象,描述了状态应该怎样改变,dispatch函数将action提交给reduce函数,reducer函数应该是一个纯函数,接收到action后将新状态与老状态合并,返回一个新的状态,触发组件的更新。理解不了可以背一背。

diff算法

react框架本身不知道哪个组件做了更改需要重新渲染,因此render函数需要靠setState或者接受新props来触发,通过diff算法在虚拟DOM中统计比较发生变化的组件,将需要重新渲染的组件标记为脏,然后根据更新后的虚拟DOM重新渲染发生变化的组件。觉得不够详细可以再自己整理。虚拟DOM什么的自己试着说两遍。

antd

antd可以着重去看它的表单控件和表格控件,做输入合法性验证和独立校验的方法,antd经常遇到的问题在于若和设计稿有不符,怎么去修改antd组件的样式。

主题方面,antd可以自己设计主题色调,圆角等,官方文档里有说明。第三方库styled-components也可以自定义antd组件样式。其他覆盖className的技巧有(mei)兴(shi)趣(gan)可以自己去segmentfault上找。

这部分结合自己的项目经验去找去看,问的还是相当多的。

git操作

必会的基础,git add 、commit、push、branch、checkout、merge、pull、status、log每个命令的作用,工作时提交的流程,合并分支出错的解决办法:根据报错找到错误位置手动合并。

项目具体

对自己简历上写的项目的业务逻辑,功能和技术要点要了然于胸,多看几个项目功能的具体实践甚至是github上去找几个项目实践来看看,比如登陆注册,web存储,redux应用,表单控件验证,表格操作,要通过看代码理清楚具体是怎么实现的,说出来才有可信度。

0%