本地数据查询,10000条数据的中进行模糊查询,如何提高查询效率?
- 实现表分区
- 模糊字段建立索引
- 提供硬件性能
对重绘和回流有了解过?怎么在实际项目中减少上述的事件的发生
答案解析:
回流: 是指当render树的全部或者一部分元素因改变了布局位置、自身宽高或者显示、隐藏等属性 而导致页面需要重新构建的时候,回流则产生了。
重绘: 当元素的外观样式发生变化时则会触发重绘。
两者之间的关系:发生了回流一定会发生重绘,但是发生重绘不一定会发生回流。原因可根据浏览器的渲染html页面的过程进行分析
优化页面性能、减少回流、重绘:
- 对于频繁变化的元素添加transform:translateZ(0)的形式来创建图层。(元素只在自己的图层中发生回流和重排,通过创建新的图层的方式可以减少浏览器的计算量)
- 使用transform的相关属性来代替margin-top、left 这些位移的属性
- 减少table布局的使用,因为其中一个单元格的变化会触发·整个table表格的重新布局。
- 利用虚拟dom的方法减少dom更新渲染的频率
- 如果是需要对某个dom节点执行多次操作,可先使得其脱离文本流之后再执行多次操作
- 动画使用window.requestAnimationFrame()这个方法调节重新渲染(这个方法作用:告诉浏览器我们需要执行一个动画,需要在浏览器进行重绘之前执行一个回调函数);
- js操作对某个元素样式变化时,使用className一次性更新
前后端分离你怎么看?
概念
前后端分离是一种分层解耦的思想,前端开发调用后端提供的api,实现前端页面的交互逻辑;后端主要处理业务逻辑,提供api,使得静态资源和动态资源分离,提高了性能和扩展性。
优点
- 对前端而言:只需要对API提供的资源以及对资源操作进行封装抽象,以满足页面在UI的特异性
- 对后端而言:后端和视图层无关,能够实现多个终端对接一套后端设计,实现通用性
移动端适配中viewport的作用是什么? rem、em、px的区别?
- viewport是meta标签中name的一个属性值,针对移动网页优化过页面的标签大致如下
<meta name = 'viewport' content='width=device-width,initial-scale = 1,maximum-scale = 1'></meta>
可以用来设置初始缩放比例,也就是页面第一次load的时候缩放比例,以及通过设置user-scalable
设置用户是否可以手动缩放
首页白屏问题怎么解决
源头: 页面渲染是需要先从服务器获取需要渲染的内容,浏览器在基于自己的渲染引擎开始自上而下加载渲染的代码
页面渲染步骤:
- HTML解析器解析HTML文件,形成dom树
- 将请求完的css文件按照导入顺序,依次进行渲染,最后生成css 树
- 将dom树和css树结合在一起,生成渲染树
- 浏览器再按照渲染树,在页面中j进行渲染和解析
步骤1)计算元素在设备视口中的大小和位置
步骤2)将元素的样式绘制渲染上去
性能优化
- HTML层级不要太深,使用标签语义化。能够有效的减少dom和css树的渲染时间
- 合并资源文件、图片懒加载、使用css雪碧图减少http请求次数
- 将css放在页面开始位置(请求资源减少使用@import)
- 可以快速生成一套loading渲染树(前端骨架屏)
- js放在在页面底部,尽可能defer或者script(前者是等到页面渲染完成以后在按照顺序加载,后者是异步加载,不知道顺序)
- 利用当前浏览器的预处理机制html-preload-scanner,在页面渲染前,把src、link属性需要请求的资源 进行发送,找到外部资源后进行预加载,避免资源加载等待时间
- 按照页面或者组件分块进行懒加载
- 服务端使用gzip减少网络传输的流量大小
为什么利用多个域名来存储网站资源会更加有效
- CDN缓存更加方便
- 突破浏览器并发限制
- 节约主域名的连接速度,优化页面的响应速度
- 防止不必要的安全问题
- 节约cookie带宽
移动前端自适应适配布局解决方案和比较
- 动态设置meta 的viewport,初始化页面加载时的缩放比例
- 像素尽量使用rem
- 布局的时候考虑使用flexbox弹性布局
- 设置宽高的时候使用百分比
- 使用css3的@media媒体查询
前端路由 hash和history两种模式区别
前端路由可以这么理解:在浏览器没有请求服务器的情况下,将页面状态和url一一关联起来的这种模式叫做前端路由
- hash模式的原理是通过window.onhashchange事件监听url的变化,并且hash发生变化的url会被浏览器记录下来。
- history模式可以分为两大功能:修改和切换,切换历史状态包括back、forward、go三个方法,修改历史状态通过pushState、replaceState这两个函数。
区别:
history相对于hash模式去除了#字符、但是一旦刷新页面会直接去请求服务器。
首屏和白屏时间的计算
白屏: 是指浏览器从响应用户输入网址到浏览器开始显示内容的时间
白屏时间 = 地址输入网址后回车 - 浏览器出现的第一个元素
首屏: 浏览器开始渲染到浏览器页面完全渲染结束
怎么使用axios停止请求
答案解析:
axios提供一个CancelToken构造函数,可以用来取消接口请求,里面自带取消请求的函数,直接调用就可以取消接口请求
扩展:在Ajax中可以调用对象的abort()函数终止请求
const ajaxObj = $.ajax({
type:'get',
url:'xxx',
successLfunction(){},
error:function(){}
})
$('.cancel').click(function(){
if(ajaxObj){
ajaxObj.abort() // 会终止请求
}
})
跨域Ajax请求时是否带Cookie的设置
使用Ajax实现跨域请求
- 客户端设置
crossDomain : true
- 服务端通过在响应的header中设置
Access-Control-Allow-Origin
以及相关一系列参数
response.setHeader("Access-Control-Allow-Origin", "*"); //设置*来允许来自所有域的跨域请求访问,或者可以设置指定特定域名
设置带Cookie的跨域请求
- 客户端设置
withCredentials : true
,则发送Ajax请求时,请求头会携带cookie信息 - 服务端设置
Access-Control-Allow-Credentials
来运行客户端携带证书式访问,通过该设置参数Credentials
还能保证跨域Ajax时的cookie。
服务端Access-Control-Allow-Crendentails = true 时,不可以设置Access-Control-Allow-Orign的值*
模块化CommonJs、AMD、CMD的优缺点
CommonJs规范
核心思想:是允许模块通过
require方法
来同步加载所要加载的其他模块,然后通过exports
或者module.exports来导出暴露的接口
优点
- npm已经支持20多万个模块包
- 服务器模块便于重用
缺点
- 同步的模块加载方式不适合在浏览器环境中
- 不能非阻塞的并行加载多个模块
AMD(异步模块定义 RequireJS)
AMD是为了浏览器环境而定义的,是一套js模块依赖异步加载标准,来解决同步加载的问题。主要通过
define
接口,在声明模块的时候指定所有的依赖,对依赖的模块提前执行,依赖前置
优点
- 适合在浏览器中异步加载模块
- 可以并行加载多个模块
缺点
- 提高了开发成本,代码阅读和书写比较困难
CMD
规范和AMD相似,同时对CommonJs和Node.js的modules规范b保持了很大的兼容性
优点
- 依赖就近,延迟执行
url从输入到页面的显示经历了那些过程
答案解析:
- 用户输入url,浏览器获取url地址
- 浏览器向DNS服务器发送域名请求解析IP地址(若输入的ip地址则跳过此步骤)
- 浏览器获取IP地址+端口号,向对应服务器发送http请求
- 请求到达传输层,进行TCP三次握手操作,成功建立起连接,再依次进入网络层、数据链路层。
- 接收方通过数据的层层传递,获取请求报文, 服务器响应请求并且返回HTML文件
- 浏览器解析响应数据,对页面进行渲染呈现给用户,如若需要其他资源,例如图片、js、css文件再依次发起请求,获取资源
前端性能优化
答案解析:
前端性能优化从7个方面考虑:减少请求、减少资源大小、优化资源加载、减少回流重绘、webpack构建过程优化、api性能优化、优化网络连接
1) 减少请求
- 使用css的雪碧图结合背景贴图定位减少图片的资源数量请求
- 合理利用浏览器缓存
- 公共部分文件合并,其他页面组件按需分配
- 避免使用空的src和href
2)优化网络连接
- 使用CDN分发,内容网络分发,能够根据网络的流量、各节点连接请求以及负载请求和响应时间等综合因素将用户网络导向最合适的网络节点中,减少网络解析时间
- 使用DNS预解析,根据浏览器定义规则,提前解析可能会用到的域名,并且将解析结果缓存在系统缓存中,减少网络解析时间
- 使用keep-alive建立持久缓存,降低时延以及连接开销
3)减少资源大小
- 在web服务端时延GZIP压缩技术,当有人访问网页内容压缩到40%再进行传输
4)优化资源加载
- 资源加载位置:css放在head中,js不涉及到页面布局的放置在body标签底部,涉及页面布局放置head中,或者是可以使用
asyn=true
,使得js异步加载
说一下前端工程化的思想
答案解析:
工程化是一个思想, 主要目的是为了提供效率和降低成本,即提供开发过程中的开发效率,减少不必要的重复工作。需要考虑的因素是:模块化、组件化、规范化、自动化这几个方面去考虑
-
模块化
模块化就是把一个大的文件拆分成多个相互依赖的小文件,按照一个个模块进行划分。 -
组件化
把页面上的东西都可以看做是组件,页面是一个大型组件,可以拆分成若干个小组件 -
规范化
目录结构的定制、编码规范、前后端接口的规范、git分支管理等待 -
自动化
可以将简单重复工作交给自动化工具去执行,比如说自动化部署、构建这些。
实现用户登录以及用户信息认证
- 第一次登录的时候,前端调后端的登陆接口,发送用户名和密码
- 后端收到请求,验证用户名和密码,验证成功,则返回前端token用户认证信息
- 前端获取到请求信息后,将token存储在本地存储localStorage,并且在请求拦截中将需要用户认证的token放在header请求头中,进行用户认证。
- 后端判断请求头中无token,有token进行用户认证,认证成功则返回数据,验证失败返回401 状态码
前后端分离,跨域的方法
跨域是指从一个域名的网页去请求另一个域名资源时,域名、端口、协议任一不同,都是属于跨域。跨域问题来源于js的同源策略,即只有协议 + 主机名 + 端口号 相同时,则允许相互访问,同源策略的目的是为了保护用户信息安全,防止恶意的网站窃取数据。
- jsonp实现跨域
利用<script></script>标签不受同源策略的,可以载入任意地方的js文件,不要求同源。也需要和服务端约定好返回函数,将需要的内容返回给我们的回调函数。
特点: 只支持get请求
- Core实现跨域请求
一种跨域访问机制,让AJAX实现跨域访问。
特点:
- 需要服务器设置Access-Control-Allow-Origin 的http响应头,去允许浏览器执行跨域请求。
- 支持get、post、delete等请求类型
- window.name + iframe 实现跨域
利用window.name的值可以在不同页面甚至是不同域名加载后仍然存在的特点以及在跨域页面使用一个隐藏的iframe充当中间人角色,获取其他域页面的信息,再传递回来
- websocket实现跨域
websocket是一种浏览器的API,它的目标是在一个单独的持久连接上提供全双工、双向通信。并且同源策略对web socket是无效的
关于for循环嵌套setTimeout,执行顺序和结果的理解
for(var i = 0 ; i < 10 ;i++){
setTimeout(fn(),1)
}
//输出10次10
解析:setTimeout是异步任务,js会从上到下 优先执行完同步代码,将异步代码放在任务队列中等待,直到同步任务执行完成,再去依次加载执行任务队列中的异步代码
数组为什么下标是从0开始的
数组是一种线性表数据结构,用一组连续的内存空间去存储一组相同类型的数据。
从数组中存储的数据模型来考虑,下标最精确的意思是“偏移量”,a[0]的偏移量是0,即为首地址,a[i]的偏移量是i
移动像素1px问题
1px是指移动端在不同屏幕中,不同手机的像素m密度不同导致显示效果不一致。
解决方案
- 伪元素 + transform实现
原先元素的border去掉,利用:before或者:after重做border,并transform的scale缩小一半,原先元素相对定位,新的border绝对定位
- viewport + rem实现
- 使用box-shadow模拟边框
使用css的box-shadow对阴影的方式实现border的效果
预骨屏架的组件封装原理
骨架屏的生成方法可以利用预渲染的方式生成静态骨架屏,主要原理是使用工具预渲染页面,获取到dom节点和样式,保留页面结构,生成灰色块盖在原有文本、图片等节点上,最后生成html+css打包出来,就是带有骨屏架的页面。利用webpack工具将生成的骨架插入到html中。
防抖和节流
- 防抖:触发高频事件后会从最后第一次触发事件开始计数然后在n秒后执行函数,如果在n秒内高频事件又被触发,则会重新计时
可应用在输入搜索框搜索内容触发函数、以及用户的拖拽事件触发函数。
- 节流:高频事件触发,预定的函数会在一个固定时间n秒内只执行一次,所以节流的作用是用来稀释函数的执行频率
淘宝抢购限量热卖商品的情况
- 区别:防抖是多次执行变为最后一次执行,节流是将多次执行变成每隔一段时间执行。
MVC开发模式
MVC是一种架构式模型,全名模型-视图-控制器的缩写,一种软件设计典型,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集在一个部件里面,在改进和个性化定制界面和用户交互的同时,不需要重新编写业务逻辑。
- M(模型):是应用程序中用于处理应用程序数据逻辑的部分
- V(视图):是应用程序中处理数据显示的部分
- Controller(控制器):是应用程序中处理用户交互的部分
面向对象的特性
面向对象的三大特性:封装、继承、多态。其中封装和继承的目的都是为了代码重用,多态是为了接口重用。
对函数式编程的理解
- 纯函数
对于相同的输入,永远会得到相同输出,也不会依赖外部环境的状态。
- 函数的柯里化
传递函数的一部分参数来调用它,让它返回一个函数去处理剩下的参数。实际上,柯里化是一种“预加载 ”函数的方法,通过传递较少的参数,得到一个记住了这些参数的新函数,某种意义上讲,是一种对参数的“缓存”,是一种非常高效的编写函数的方法。
//ES6写法,也是比较正统的函数式写法
var add = x => (y => x + y);
//试试看
var add2 = add(2);
console.log(add2(3))
import和require的区别
import的require都是被模块化所使用
遵循规范
- require是AMD规范的引入方式
- import是es6的一个标准,如果要兼容浏览器则需要转化成es5语法
调用时间
- require是运行时调用,所以require理论可以运用在代码的任何地方
- import是编译时调用,所以必须放在文件开头
本质
- require是赋值过程,其实结果是对象、数字、字符串、函数等,再把require的结果赋值给某个变量,但是引入的过程是属于数据浅拷贝。
- import 是解构过程,并且目前所有的引擎还没有实现import,node环境的bable去将import语法转码为require
实现图片懒加载
懒加载是指在页面首次加载时优先加载可视区域的内容,其他部分的图片则等到进入可视区域再加载,用来提高性能。
原理: 一张图片就是一个<img>
标签,浏览器是否发起请求图片是根据<img>
的src属性,所以实现懒加载的关键是,在图片没有进入到可视区域时,先不给<img>
的src赋值,这样就不会发起请求
懒加载思路与实现
- 加载loading图片
- 判断图片距离顶部的距离的高度是否小于等于可视图区域和滚动区域高度之和。
- 新建一个img对象,隐形加载图片,等到加载完成再替换到真图片中。
模块化的标准
模块化的意思是指在解决问题时,采用分类的思想把问题进行系统性的分解,从而解决问题的方式。目前js的广泛使用的模块化规划包括,commonJs规范、AMD规范、CMD规范。
- Commonjs规范
commonjs出现背景和js的函数式编程有关,提供很多普通应用程序使用的API,模块化的规范
- 提供require引入模块,提供export导出模块属性方法,exports代表模块本身
- AMD规范
异步模块加载
- 所有模块都是进行异步加载
- 提供全局define函数去定义模块,require引入模块,exports导出模块
什么是响应式布局?
响应式布局是一个网站能够兼容多个终端,不是为某一个终端做一个特定版本。响应式布局可以为不同终端的用户提供更加舒适的界面和更好用户体验。
- Meta标签定义,目的是声明在移动设备上设置原始大小显示和是否缩放屏幕。
<meta name='viewport' content='width=device-width;initial-scale = 1.0' ></meta>
viewport的content的属性
-
width
可视窗口宽度 -
height
可视窗口高度 -
initial-scale
初始化缩放比例 -
user-scalable
用户可缩放比例
- 使用CSS3的新特性媒介查询@media功能,根据终端设备宽度的范围,执行对应的css样式。
- 高分辨率下的1px border
在不同移动端的手机像素都是有差异的,所以导致在视觉显示上有差异,那么这个时候可以通过box-shadow属性实现
git常用操作
-
git revert
: 是通过复制了一个目标版本(某个想要回退到的历史版本)加在当前分支的最前端 -
git reset
: 是将HEAD指针跳到目标版本,并且将目标版本之后的内容删除了 -
git checkout branch_name
: 切换分支 -
git merge branch_name
:合并目标分支到当前分支
JS设计模式
- 单例模式
提供了一种将代码组织为一个逻辑单元的手段,这个逻辑单元中的代码可以通过单一变量进行访问。
特点:
- 可以用来划分命名空间,减少全局变量的数量
- 可以被实例化,且实例化一次
- 使用单例模式可以使组织更为一致,使得代码更加容易阅读和维护
- 工厂模式
为了解决多个类似对象声明的问题,为了解决实例化对象产生重复的问题。将其成员对象的实例化推迟到子类,子类可以重写父类接口方法以便创建的时候指定自己的对象类型。
- 代理模式
代理是一个对象,可以用来控制对本体对象的访问,它与本体对象实现了同样的接口,代理对象会把所有的调用方法传递给本体对象,代理模式最基本的形式就是对访问进行控制,而本体对象则负责执行所分派的那个对象的函数或者类。简单来说,本地对象是注重的去执行页面上的代码,代理则控制本地对象为何被实例化,何时被使用。
特点
- 代理对象可以代替本体被实例化,并使其可以被远程访问
- 可以推迟实例化对象
- 策略模式
是指定义了一系列算法,并且把它封装起来,但也不仅仅是只封装算法,还可以用来封装一系列目标一致的业务规则。
- 发布订阅模式
又可称为观察者模式,定义了对象间的一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知。
特点
- 支持简单的广播通信,当对象状态发生变化时,则自动通知已经订阅过的对象。
- 发布者和订阅者耦合性降低,发布者无需关心订阅者如何使用,订阅者也只需要监听发布者事件名。
怎么判断一个单链表是否有环?
- 使用快慢指针的方法,如果单链表有环,则快慢指针一定会相遇,如果没有环,则快指针会先到null
怎么实现一个圆形的点击区域?
document.onclick = function(e){
var r = 50; //圆的半径
var x1 = 100, y1 = 100;
var x2 = e.clientX,
y2 = e.clientY;
var len=Math.abs(Math.sqrt(Math.pow(x2-x1,2)+Math.pow(y2-y1,2)));
if(len<=50){
console.log("Inner");
}else{
console.log("Outer");
}
}