美文网首页
2020-02-23

2020-02-23

作者: 前端技师胡帅博 | 来源:发表于2020-02-26 23:05 被阅读0次

可能问到的问题

Vue 相关的面试题

  1. 路由拦截:登录的时候用路由拦截,beforeEach(to, from, next) 这个函数进行判断,如果用户有登录,那就会更新 vuex 里的数据,在拦截函数里面通过vuex state获取当前的token是否存在
  2. http 拦截器:没带上 token 就返回 401,让用户登录
  • vue-router 钩子
全局
router.beforeEach((to, from, next) => {})
router.afterEach((to, from) => {})

组件上的配置
beforeRouteEnter
beforeRouteUpdate
beforeRouteLeave
  • vue-router 原理
    利用 hash #,window.addEventListener("hashchange", funcRef, false)
    HTML5 的 History.pushstate()

  • history 和 hash
    我用原生 js 实现过这两种方式的 spa 路由,都是放置一个空的 div 标签作为路由出口

  • hash 模式是监听 haschange 事件,或者监听 a 标签的点击事件,通过 location.hash 去拿到 url 里的路径和和 hash 值,在解析之后将对应的 dom 内容插入到路由出口

  • history 模式是也可以通过 a 标签的点击事件,事件里面要用 preventDefault 取消跳转行为,通过 history.pushState 将要跳转的路径存入 path 参数,通过 location.pathname 取 path,location.search 取url 里的参数,解析之后返回对应 dom 内容,插入到路由出口
    1.绑定 a 标签事件
    2.取 path 和 参数
    3.将内容插入到路由出口

  • 怎么实现自定义指令
    全局自定义指令
Vue.directive('focus', {
  // 当被绑定的元素插入到 DOM 中时……
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})

局部自定义指令

directives: {
  focus: {
    // 指令的定义
    inserted: function (el) {
      el.focus()
    }
  }
}
  • v-for 为什么要用 key
    key 是每一个vnode的唯一id,添加 key 之后可以更快更准的进行虚拟 dom 的比较, 加快性能

  • vue 数组是怎么实现双向绑定的
    defineProperty 不能监听数组, vue 采用的方法是重写了 数组的几个常用的api
    以及vue 的 set api

  • vue 3 是怎么解决这个问题的?
    使用 es6 提供的 Proxy 的 api,优势是直接对对象的操作进行一个监控, 不需要 defineProperty 对每个属性都做一次 getter setter的设定. 同时 Proxy 也支持对数组的监听

  • 有了解过 slot, vue 2.6+ 添加的新的 slot api 有使用过?
    在创建公共组件的时候, 经常使用slot. slot 是一个插槽, 主要在公共组件使用中, 通过设置slot, 在不同的部分显示不同的内容. 2.6的提供新的语法糖, 在项目中我没有用过, 但是我可以简单说一下这个语法糖的特点是, 把 slot 和 slot-scope 的组合在一起的用法

  • 使用过 vue 的 mixin 操作, 这个有什么缺点可以说说?
    A: 使用过, mixin 是 vue 里面的继承功能, 例如一个 js 文件定义了 methods 属性, 里面有5个方法, 在一个新的 vue 文件中, mixin 这个文件, vue 文件就会继承了这 5 个方法了, mixin 的缺点有, vue 文件可以覆盖之前的方法属性, 第二个是使用了 mixin 的方法后, ide 不能提示相应的方法

  • 公共组件怎么编写的

  1. 计好与父组件的通信
  2. 符合 UI 要求,并且留好后续定制 UI 展示的空间
  3. 写好使用文档
    写公共组件我会先想好父子组件之间的通信,如果子组件里面要改变父组件的数据,比如一个短信验证码的输入框组件,我会用 sync 修饰符,然后在子组件里面用 watch 监听这个传入的属性,在监听函数里面把 update 时间 emit 出去。然后是按照 UI 要求去写样式,设置默认样式,然后留好灵活设置的余地,最后是写好使用文档,不仅是代码文件里写注释,word 文档里面也有记录,就是组件的截图,以及名称,这样新人一来,在接到需求的时候可以快速查阅使用。

HTML 5

  • DOM API document.querySelector()
  • Storage
  • 语义化标签、图形标签 svg canvas、多媒体标签 video audio source
  • 新增的input的type类型和属性

CSS3

  • 两栏布局
    float 和 flex

  • 清除浮动
    浮动元素的父元素后面加一个 伪元素 after,display block,content '',clear: both

  • 画三角形
    width: 0;height: 0; border: 40px solid; border-color: transparent transparent red transparent transparent;

  • 居中:
    1.用 flex, align-items:center,content-justfy: center
    2.css3 的 transform,translateX(-50%), translateY(-50%)

  • 最常用的一个构造函数

function Person(a,b,c) {
    this.a = a
    this.b = b
    this.c = c
    this.friends = [1,2,3]
}
Person.prototype = {
    constructor: Person,
    sayName: function() {
        console.log(this.a)
    },
}
  • 最常用的继承
function Man(a,b,c,d) {
    Person.call(this, a, b, c)
    this.d = d
}
Man.prototype = new Person()
Man.constructor = Man
Man.prototype.logD = function() {
    console.log(this.d)
}
  • class
// 定义类
class Point {
    // 构造函数
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
    get prop() { // Point.prop 的 getter 函数,调用时返回值
        // do something
        return 'hahaha'
    }
    set prop(value) { // Point.prop 的 setter 函数,在赋值的同时执行
        console.log('设置 prop 为' + value)
    }
    static method1() {
        // 一个静态方法,不会被实例获取的,但是会被子类继承调用
        console.log('静态函数 method1,可被类调用,不可被实例调用')
    }
    method2() {
        console.log('这里是 method 2,可被实例调用,可被子类继承')
        return '(' + this.x + ', ' + this.y + ')';
    }
}
// 继承类
class ColorPoint extends Point {
    constructor(x, y, color) {
        super(x, y) // 调用父类的constructor(x, y)
        this.color = color
    }
    method3() {
        return this.color + ' ' + super.method2(); // 调用父类的toString()
    }
}
  • 性能优化
  1. 压缩图片大小,以及文件大小
  2. 合并请求,一个接口能做完的事不要用两个接口
  3. 静态资源使用缓存策略(强制缓存和协商缓存)、使用 cdn
  4. 预判用户行为,对资源进行预加载(查看用户协议)
  5. 传统的:如果是不使用框架的原生js项目, 就是js文件放底部,使用雪碧图、尽量减少 dom 操作,使用事件委托
  • 地址栏输入地址浏览器发生了什么
    https://zhuanlan.zhihu.com/p/23155051

  • script async deffer
    浏览器在渲染一个页面的时候,遇到 <script> 标签就会先下载然后执行,如果资源文件比较大或者文件下载了下来之后执行时间比较长,页面响应就会比较慢,影响用户体验。使用这两个属性可以使 js 文件的执行阻塞页面的情况得到优化,区别是 deffer 是立即下载,然后在文档解析之后执行,async 是异步加载,加载之后立即执行,所以如果 js 文件有依赖关系,应该避免使用 async ,因为有可能因为找不到依赖而报错

  • 闭包
    我个人的理解是,cpu 在执行函数的时候,会在内存里给这个函数分配一块栈空间,传入这个函数的参数以及在函数内定义的变量都会存入这个栈空间,当函数执行完毕的时候,变量被销毁,栈空间被还原。但是如果在这个函数里再定义一个函数,并且这个函数用到了外层传入的参数或者变量,在外层函数执行完之后,内部函数用到的变量并不会被销毁,而是依旧保存在栈空间中。所以过度使用闭包,会导致栈溢出,也就是stackoverflow

网络安全

  • xss
    常见的就是在发布评论的时候提交恶意 js 代码,如果没有进行过滤或者转义,其他用户在访问页面的时候这些恶意 js 代码就会执行
    防范:HttpOnly 防止劫取 Cookie,前端进行输入检查,后端进行输出检查

  • xsrf
    窃取 cookie 信息,冒充用户伪造请求,删帖、转帐、改密码、发邮件全都可以伪造
    防范:验证码(手机短信、滑动图片),加 token

ES6 直接看笔记

  • 浏览器的渲染过程
    浏览器下载完所有页面组件(html,css,js,图片)后会生成两个内部数据结构:
    1.DOM 树,表示页面结构
    2.渲染树,表示 DOM 节点该如何显示(对应到 css 就是盒子模型)

高程笔记

https://github.com/theLongGoodbye/read-GaoJiChengXuSheJi

http

  • http1.0 和 1.1 的区别
    keep-alive,更多的缓存控制策略,支持断点续传

  • keep-alive 为什么可以节省资源
    http1.0的时候, 每次请求资源都要, 经历创建tcp连接, 发送数据, 销毁tcp连接, http 1.1增加了keep-alive ,重复使用一个tcp连接, 节省资源, 加快访问数据

  • http 缓存的功能
    客户端和服务端通过 请求和响应 的报文来实施缓存策略,分为:
    1.强制缓存,当缓存数据库中已有所请求的数据时,直接从缓存数据库获取数据
    2.协商缓存(对比缓存),浏览器会先发请求问服务器这个缓存的资源有没有变,没变就是304,变了就重新获取资源
    报文字段包括:http1.0 时期的 Expires,http1.1 的 Cache-Control,Last-Modified - If-Modified-Since、Etag - If-None-Match

  • 三次握手

  • 说一下 cors 是什么?
    A: cors 是一个跨域的解决方案, 在访问跨域资源的时候,浏览器会会添加头信息,如果是简单请求(get post head或content-type 是 text/plain multipart/form-data),会加上 origin(域名端口协议),非简单请求先发送optings检测服务器是否能跨域,返回200再返送后面的http 请求,服务器接收到这些字段之后,决定是否正常响应这次请求,如果同意,响应报文里会有 Access-Control-Allow-Origin 字段

  • cors可以带上cookie?

A: 可以, 前端需要设置 withCredential 为 true, 后端的 Access-Control-Allow-Origin 的内容是具名的地址, 不能是 *

  • websocket
    基于TCP传输协议,某些业务场景下,要求客户端和服务器能同时向对方发送消息,如果用其他的方法比如用 ajax 轮询非常消耗资源,而且轮询的时间并不可靠,所以出现了 websocket,大致的做法是,在客户端创建一个socket实例并且提供要连接的服务端的IP地址和端口,然后在服务端创建另一个socket实例并绑定本地端口进行监听,两端连接之后双方建立了一个端对端的TCP连接,实现双向通讯
  • 冒泡排序
function sort(element){
      for(var i = 0;i<element.length-1;i++) {
            for(var j = 0;j<element.length-i-1;j++){
                if(element[j]>element[j+1]){
                    let temp= element[j];
                    element[j] = element[j+1];
                    element[j+1] = temp;
                }
            }
        }
  • 爬楼梯
const climbStairs = function(n) {
    if(n == 1) return 1;
    if(n == 2) return 2;
    return climbStairs(n-1) + climbStairs(n-2);
};

const climbStairs = function(n) {
    let a = b = 1;
    for (let i = 0; i < n; i++) {
        [a, b] = [b, a + b];
    }
    return a;
};

为什么离职

自我介绍
你好,我来自江西,在广州工作7年了,其中3年是前端开发
大学毕业之后做的是文案策划,后来在工作中因为接触到了前端这一块的工作内容
经过学习和了解之后觉得编程很有意思,然后互联网的发展前景也更大,就决定自学转行
自学了一年多觉得各方面技能都差不多了就转行了
到现在做了3年前端,目前是在广发银行研发总部给他们的手机银行App开发各种需求
我虽然是半路转行,也不是科班,但因为工作这些年一直持续的学习、练习和追赶
前端开发工作中需要掌握的技能我都掌握的很好,擅长使用的框架是 vue 、angular 和 jQuery
我做事注重习惯和规范,所以开发效率很高,质量也有保障
我的情况大概就是这样

为什么离职

1.公司项目进入成熟稳定期,所以想看看有没有技术挑战更大一些的工作机会

你有什么优点

编码效率高
当自己的事

工作中碰到什么难题

相关文章

网友评论

      本文标题:2020-02-23

      本文链接:https://www.haomeiwen.com/subject/zwodqhtx.html