【前端面试分享】-2019“银十”面试题记录(下)

本文涉及的产品
云解析DNS,个人版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 由于不可抗逆之因素,在金九银十的后半段开始求职。 面试的确可以驱动学习,驱动知识的归类整理。 以此文记录面试过程中遇到的题目,仅供分享,不喜勿喷。

vue



双向绑定原理


简答:


Vue内部通过Object.defineProperty方法属性拦截的方式,把data对象里每个数据的读写转化成getter/setter,当数据变化时通知视图更新。

具体说一下Object.defineProperty:


Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。

Object.defineProperty(obj, prop, descriptor)
obj:要在其上定义属性的对象。
prop:要定义或修改的属性的名称。
descriptor:将被定义或修改的属性描述符。


进一步:

Object.defineProperty()具体实现:

//这段代码太重要了,请记住!
let hr={
    skill:'',
    experience:''
}
Object.defineProperty(hr, 'skill', {
    get(){
        console.log('必备技能:')
        return '不放鸽子'
    },
    set(newVal){
        console.log('经验要求:')
    }
})
//读:
console.log(hr.skill)
//写:
hr.skill='五年起步'
控制台打印
必备技能:
不放鸽子
经验要求:
"五年起步"


发布订阅模式

现在已经可以检测到数据的读和写,然后就需要通知视图的更新了.

这里是典型的发布订阅模式,在这个模式下:数据是发布者(Observer),依赖对象是订阅者(Watcher),他们需要一个中间人来传递,那就是订阅器(Dep)


总结:实现数据的双向绑定,首先要对数据进行劫持监听,所以我们需要设置一个监听器Observer,用来监听所有属性。如果属性发生变化了,就需要告诉订阅者Watcher看是否需要更新。因为订阅者Watcher是有很多个,所以我们需要有一个消息订阅器Dep来专门收集这些订阅者,然后在监听器Observer和订阅者Watcher之间进行统一管理。


附:从这张生命周期图看数据和视图在何时双向更新


参考链接:

Object.defineProperty() -MDN

通俗易懂了解Vue双向绑定原理及实现

vue生命周期


推荐阅读:

发布者-订阅者模式-Microsoft Azure


v-for key


简答:

  1. 在写v-for的时候,都需要给元素加上一个key属性
  2. key的主要作用就是用来提高渲染性能的!
  3. key属性可以避免数据混乱的情况出现 (如果元素中包含了有临时数据的元素,如果不用key就会产生数据混乱)


特注:

当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级,这意味着 v-if 将分别重复运行于每个 v-for 循环中。 所以,不推荐v-if和v-for同时使用!


$nextTick


$nextTick 是在下次 DOM 更新循环结束之后执行延迟回调用,在修改数据之后使用nextTick,则可以在回调中获取更新后的


怎么理解:看下面这个例子就豁然开朗

DOM:

初始化数据:点击事件:


触发changeMsg后:


可以看到,msg已经变成了Hello world,在changeMsg()方法中,先修改msg的值成为‘Hello world’,然后通过拿到dom的值再依次修改msg1、msg2、msg3的值,此时修改得到的msg1依然是‘hello vue’,this.$nextTick中修改得到的msg2则是‘hello world’,msg3依然是‘hello vue’,也就是说,在changeMsg()方法触发后,修改了msg的值,但是此时再通过dom取到的值还未改变,所以可以知道:


vue响应式的改变一个值以后,此时的dom并不会立即更新,如果需要在数据改变以后立即通过dom做一些操作,可以使用$nextTick获得更新后的dom。


参考链接:


虚拟DOM


简答:

虚拟 DOM 的实现原理主要包括以下 3 部分:

用 JavaScript 对象模拟真实 DOM 树,对真实 DOM 进行抽象; diff 算法 — 比较两棵虚拟 DOM 树的差异; pach 算法 — 将两个虚拟 DOM 对象的差异应用到真正的 DOM 树。


推荐阅读

《深入剖析:Vue核心之虚拟DOM》


浏览器



浏览器缓存


简答:

浏览器的缓存是为了性能的优化,通过重复调用本地缓存,减少Http请求这样的方式,达到减少延迟减少带宽降低网络负荷的作用。


  • 过程:浏览器发请求,访问缓存,无缓存结果,发起HTTP请求,返回结果和缓存,存放缓存

image.png

  • 缓存类型有:cookie、LocalStorage、sessionStorage

进一步:

  • CDN 缓存


客户端直接从源站点获取数据,当服务器访问量大时会影响访问速度,进而影响用户体验,且无法保证客户端与源站点间的距离足够短,适合传输数据。


CDN解决的正是如何将数据快速可靠地从源站点传递到客户端,通过CDN对数据的分发,用户可以从一个距离较近的服务器获取数据,而不是源站点,从而达到快速访问、且能减少源站点负载压力的目的。



参考链接:

深入理解浏览器的缓存机制

谈谈关于CDN缓存


从输入URL到页面加载发生了什么


简答:

1.DNS解析 2.TCP连接 3.发送HTTP请求 4.服务器处理请求并返回HTTP报文 5.浏览器解析渲染页面 6.连接结束


性能优化



简答:


优化方法,结合雅虎军规35条标准,可以大致分为这么6类(非严格,有按自己的理解整理):

分类名 内容
网络 1.减少请求大小和次数;2.减少DNS查找,避免重定向;3.是异步请求可缓存;4.预加载、延迟加载、按需加载;5.减少Dom数量等;
服务 1.使用CDN;2.Gzip组件压缩;3.配置Etag;4.尽早刷新Buffer等;
缓存 1.减小Cookie;2.CDN缓存;
CSS/JavaScript 1.Css放上面,Js放下面,避免阻塞;2.压缩Css、Js;3.减少Dom访问操作;4.减少重绘,避免回流;
图片 1.压缩图片;2.用iconfont;3.用雪碧图;
其它 1.控制组件大小;2.使用预编译语言,打包成模块,按需加载;


参考链接:

雅虎军规


前端安全



简答:

xss: 跨站脚本攻击(Cross Site Scripting)是最常见和基本的攻击 WEB 网站方法,攻击者通过注入非法的 html 标签或者 javascript 代码,从而当用户浏览该网页时,控制用户浏览器。


csrf:跨站点请求伪造(Cross-Site Request Forgeries),也被称为 one-click attack 或者 session riding。冒充用户发起请求(在用户不知情的情况下), 完成一些违背用户意愿的事情(如修改用户信息,删初评论等)。

防范:同源检测、双重cookie检测等。


Css布局



布局方式


简答:

名称 内容
静态布局(static layout) 不管浏览器尺寸具体是多少,网页布局始终按照最初写代码时的布局来显示。
流式布局(Liquid Layout) 栅栏系统(网格系统):代表:bootstrap
自适应布局(Adaptive Layout) 屏幕分辨率变化时,页面里面元素的位置会变化而大小不会变化。
响应式布局(Responsive Layout) 每个屏幕分辨率下面会有一个布局样式,即元素位置和大小都会变。
弹性布局(rem/em布局) rem/em区别:rem是相对于html元素的font-size大小而言的,而em是相对于其父元素。

进一步: rem与px的转换

假设设计稿宽度为750px,查看750px宽度的页面对应的html{font-size:XXXpx}.

假设页面宽750px,html{font-size:100px},即100px=1rem。此时想要设置一个按钮的宽度,在设计稿中按钮为200px90px,那么转换之后的按钮即为2rem.9rem

html{//750的屏幕
   font-size=10px;
   /*font-size=62.5% //这里就是10/16x100%=62.5% 也就是默认10px的字号*/
}
@media screen and (min-width: 640px){
  html{
    font-size: ?;
  }
}
问号里的值是多少?
解:
750/640=10/x
复制代码


布局实例


需求: 只用css实现,一个div分上下两部分,上部分高度不固定,下面部分自动填满剩余高度


方法一:用flex 布局

.wrapper{
    display:flex;
    flex-direction: column;  //竖轴方向
}
.body{
    flex:auto;      //自动铺满剩余空间
}


方法二:用绝对定位,然后在dom中增加一块高度占位的盒子


节流防抖



推荐阅读:


算法



手写二分法


要求手写!

function binary_search(arr,target) {
    let min=0
    let max=arr.length-1
    while(min<=max){
      let mid=Math.ceil((min+max)/2)
      if(arr[mid]==target){
        return mid
      }else if(arr[mid]>target){
        max=mid-1
      }else if(arr[mid]<target){
        min=mid+1
      }
    }
  return "null"
}
console.log(binary_search([1,5,7,19,88],19))//3


冒泡排序


var arr=[10,20,50,100,40,200];
    for(var i=0;i<arr.length-1;i++){
        for(var j=0;j<arr.length-1-i;j++){
        if(arr[j]>arr[j+1]){
            var temp=arr[j]
            arr[j]=arr[j+1]
            arr[j+1]=temp
        }
    }
    }
    console.log(arr)


去重


1.不考虑Set()

2.不考虑双层for循环,性能太差

利用对象的属性不重复:


function distinct(arr) {
    let result = []
    let obj = {}
    for (let i of arr) {
        if (!obj[i]) {
            result.push(i)
            obj[i] = 1
        }
    }
    return result
}


相关文章
|
2天前
|
算法 Java 调度
《面试专题-----经典高频面试题收集四》解锁 Java 面试的关键:深度解析并发编程进阶篇高频经典面试题(第四篇)
《面试专题-----经典高频面试题收集四》解锁 Java 面试的关键:深度解析并发编程进阶篇高频经典面试题(第四篇)
7 0
|
9天前
|
存储 Java
java面试题大全带答案_面试题库_java面试宝典2018
java面试题大全带答案_面试题库_java面试宝典2018
|
9天前
|
SQL 前端开发 Java
2019史上最全java面试题题库大全800题含答案(面试宝典)(4)
2019史上最全java面试题题库大全800题含答案(面试宝典)
|
9天前
|
存储 设计模式 Java
java实习生面试题_java基础面试_java面试题2018及答案_java面试题库
java实习生面试题_java基础面试_java面试题2018及答案_java面试题库
|
9天前
|
SQL 算法 安全
java面试宝典_java基础面试_2018java面试题_2019java最新面试题
java面试宝典_java基础面试_2018java面试题_2019java最新面试题
|
9天前
|
算法 安全 网络协议
java高级面试题_java面试题大全带答案_线程面试题_java面试宝典2019
java高级面试题_java面试题大全带答案_线程面试题_java面试宝典2019
|
9天前
|
安全 算法 Java
java线程面试题_2019java面试题库
java线程面试题_2019java面试题库
|
9天前
|
前端开发 Dubbo Java
spring面试题_spring mvc面试题_springboot面试题库
spring面试题_spring mvc面试题_springboot面试题库
|
2天前
|
XML Java 数据库连接
面试必备!Java核心技术100+面试题
面试必备!Java核心技术100+面试题
|
3天前
|
存储 缓存 前端开发
谈谈前端面试中遇到的问题(一)
谈谈前端面试中遇到的问题(一)