Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

拉勾前端测试Part.1 #33

Open
janeLLLL opened this issue Nov 16, 2020 · 0 comments
Open

拉勾前端测试Part.1 #33

janeLLLL opened this issue Nov 16, 2020 · 0 comments

Comments

@janeLLLL
Copy link
Owner

  1. 已知如下对象,请基于es6的proxy方法设计一个属性拦截读取操作的例子,要求实现去访问目标对象example中不存在的属性时,抛出错误:Property “$(property)” does not exist (2018 今日头条)
const man = {
    name:'jscode',
    age:22
}

const proxy = new Proxy(man,{
    get(target, property){
        //目标对象,访问的属性名
        return property in target ? target[property] : 'default'
        //访问属性,判断是否存在该属性名
    },
    set(target, property, value){
        //代理目标对象,要写入的属性名称,写入的属性值
        if(!target[property]){
            //如果属性不存在,抛出错误
            throw new TypeError(`Property “${property}” does not exist`)
        }
        target[property] = value
    }
})

proxy.name = "jscode"
proxy.age = 22
proxy.location = 1
  1. 红灯三秒亮一次,绿灯一秒亮一次,黄灯2秒亮一次;如何让三个灯不断交替重复亮灯?(用Promse实现)

https://blog.csdn.net/weixin_33859504/article/details/90623213

function red(){
    console.log('red');
}
function green(){
    console.log('green');
}
function yellow(){
    console.log('yellow');
}

function red(){
    console.log('red');
}
function green(){
    console.log('green');
}
function yellow(){
    console.log('yellow');
}

var promise = function(timer, cb) {
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            console.log(cb)
            resolve(1)
        },timer)
    })
}

//使用Generator减少回调地狱
function * gen() {
    yield promise(3000, 'red')//yield暂停函数执行,实现异步方案
    yield promise(1000, 'green')
    yield promise(2000, 'yellow')
}

var iterator = gen()

var step = function (gen, iterator) {
    var s = iterator.next()
    if(s.done){
        step(gen, gen())//递归调用
    }else{
        s.value.then(function () {
            step(gen, iterator)
        })
    }
}

step(gen, iterator)
  1. 以下代码的结果:
var User = {
    count:1,
    action:{
        getCount:function () {
            return this.count
        }
    }
}

var getCount = User.action.getCount
setTimeout(() => {
    console.log('1',User.action.getCount())
})
console.log('2',this)

https://www.nowcoder.com/questionTerminal/c076230d85f845078f82a427701d4e14?orderByHotValue=1&page=1&onlyReference=false

result2 undefined
result1 undefined
  1. 简答题

    • typescript和JavaScript区别

      1.JavaScript的超集
      2.功能更强大,生态健全,完善
      3.解决JavaScript类型系统问题(JavaScript是弱类型)
      4.提高代码可靠度
      
    • typescript有哪些类型

      Object,Array<number>=[],元组类型(明确元素数量和元素类型),枚举类型,函数类型
      typescript不会对any类型检查
      断言
      接口,类
      
    • typescript中type和interface区别

      interface:
      1.描述一类具体事物的抽象特征
      2.用来描述一类具体对象的抽象成员
      3.ES6开始
      4.在类里初始化成员一定要赋值
      
  2. 分析async/await内部原理

    async 函数返回一个 Promise 对象,当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再接着执行函数体内后面的语句

    sync/await语法糖就是使用Generator函数+自动执行器来运作的

  3. async/await如果右边方法执行出错怎么办

    使用try...catch处理内部逻辑,期望出错后能够直接停止函数,需要在原函数内部加上错误处理机制

  4. event loop处理过程?promise定义时传入的函数什么时候执行?

    事件循环监听调用栈和消息队列,如果调用栈里的任务执行结束,事件循环会从消息队列中取出第一个回调函数,压入调用栈。

    EventLoop中每次执行栈中的任务,每次执行栈中的任务执行完毕后都会去检查并执行事件队列里面的任务,而事件队列中的任务又分为微队列和宏队列

    在new操作时执行

  5. 防抖函数的应用场景,实现方式?

    https://blog.csdn.net/weixin_40599109/article/details/108464837

    应用场景:

    • 高频触发的事件监听回调:比如onscroll, onresize, oninput, touchmove等
    • 用户名,手机号,邮箱输入验证时的输入框搜索自动补全事件,搜索框搜索输入,只需用户最后一次输入完,再发送请求;
    • 频繁操作点赞和取消点赞;
    • 浏览器窗口大小改变后,只需窗口调整完成后,再执行resize事件中的代码,防止重复渲染

    实现方式:

    • 防抖函数主要利用了闭包、高阶函数、定时器等特性
    • 首先我们可以定义一个高阶函数debounce,接受一个回调函数和延迟时间,在函数内部定义一个定时器变量,用于记录当前的定时器
    • debounce内部我们返回一个函数,函数执行的时候会检查当前是否有定时器,有的话会清除当前的定时器,重新赋值一个新的定时器给定时器变量,并设置定时器执行时间为用户传入的第二个参数
    • 定时器内部通过apply调用用户传入的函数,并传入执行上下文和arguments
    • 这样就能保证在规定时间内,不会高频的触发回调函数
  6. V8垃圾回收机制

    • 一款主流的JavaScript执行引擎
    • 采用即时编译:源码=>机器码
    • 内存有限制:64位不超过1.4g,有垃圾回收的机制
    • 基于分代回收思想实现垃圾回收
    • 内存分为新生代和老生代

    新生代回收:

    • 回收过程采用复制算法 + 标记整理
    1. 新生代内存区分为二个等大小空间
    2. 使用空间为From,空闲空间为To
    3. 活动对象存储于From空间
    4. 标记整理后将活动对象拷贝至To
    5. From与To交换空间完成释放

    老生代:采用标记清除 + 标记整理 + 增量标记算法

    1. 使用标记清除完成垃圾空间的回收
    2. 采用标记整理进行空间优化(晋升触发)
    3. 采用增量标记进行效率优化
  7. performanceAPI中什么指标可以衡量首屏时间

    navigationStart:同一个浏览器上一个页面卸载结束时的时间戳
    redirectStart:该值的含义是第一个http重定向开始的时间戳
    redirectEnd:最后一个HTTP重定向完成时的时间戳
    domainLookupStart:DNS域名查询开始的时间
    domainLookupEnd:DNS域名查询完成的时间
    responseStart:开始接收到响应的时间
    domLoading:开始解析渲染DOM树的时间
    domComplete:DOM树解析完成,且资源也准备就绪的时间
    loadEventEnd:load事件的回调函数执行完毕的时间
    
  8. EcmaScript新特性,暂时性死区有什么作用

    ES6中let/const会在作用域中被提升,ES6 规定暂时性死区和let、const语句不出现变量提升,主要是为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为

  9. 观察者模式和发布订阅模式的区别标题

    发布/订阅模式存在“信号中心”,某任务执行完成,向信号中心“发布”一个信号,其它任务可以向信号中心“订阅”这个信号,从而知道什么时候自己可以开始执行

    观察者模式没有事件中心;并且发布者需要知道订阅者的存在

  10. gulp构建流程

    1.安装项目所需依赖
    2.在gulpfile.js中,构建任务需要有创建文件读取流-转换流-写入流这一过程
     创建几个编译转换任务实现项目的自动化构建:
     样式编译任务
     编译脚本文件
     编译html文件
     图片 / 字体文件转换
     其它文件转换
     文件清除
     useref插件处理html的构建注释
     开发服务器:Browsersync能让浏览器实时、快速响应您的文件更改(html、js、css、sass、less等),并自动刷新页面
    3.将以上任务导出
    4.重新规划构建过程
    
  11. package-lock.json有什么作用,如果项目中没有它会怎么样,举例说明

    作用:是将使用的库的版本锁定,如果下次再安装依然使用这些版本的库

    举例:有些库更新后不兼容当前使用的场景:和别的库冲突、调用api变化、和当前开发环境不兼容

  12. webpack常用配置有哪些,说明用途

    entry:打包的入口文件,一个字符串或者一个对象

    output:配置打包的结果,一个对象

    fileName:定义输出文件名,一个字符串

    path:定义输出文件路径,一个字符串

    module:定义对模块的处理逻辑,一个对象

    loaders:定义一系列的加载器,一个数组

  13. webpack css-loader的作用和原理

    默认不解析css文件,需要用适当的加载器loader去处理此类型资源文件,使得css文件转换成一个js模块

    像 Browserify, 但是将应用打包为多个文件. 如果单页面应用有多个页面, 那么用户只从下载对应页面的代码. 当访问到另一个页面, 不需要重新下载通用的代码.
    在很多地方能替代 Grunt 跟 Gulp 因为能够编译打包 CSS, 做 CSS 预处理, 编译 JS 方言, 打包图片, 还有其他一些.
    它支持 AMD 跟 CommonJS, 以及其他一些模块系统, (Angular, ES6). 如果不知道用什么, 就用 CommonJS.

  14. webpack中loader和plugin的区别是什么

    对于loader,它是一个转换器,将A文件进行编译形成B文件,这里操作的是文件,单纯的文件转换过程

    plugin是一个扩展器,它丰富了webpack本身,针对是loader结束后,webpack打包的整个过程,它并不直接操作文件,而是基于事件机制工作,会监听webpack打包过程中的某些节点,执行广泛的任务

  15. webpack、rollup、parcel优劣

    • webpack适⽤于⼤型复杂的前端站点构建: webpack有强⼤的loader和插件⽣态,打包后的⽂件实际上就是⼀个⽴即执⾏函数,这个⽴即执⾏函数接收⼀个参数,这个参数是模块对象,键为各个模块的路径,值为模块内容。⽴即执行函数内部则处理模块之间的引⽤,执⾏模块等,这种情况更适合⽂件依赖复杂的应⽤开发.
    • rollup适⽤于基础库的打包,如vue、d3等: Rollup 就是将各个模块打包进⼀个⽂件中,并且通过 Tree-shaking 来删除⽆⽤的代码,可以最⼤程度上降低代码体积,但是rollup没有webpack如此多的的如代码分割、按需加载等⾼级功能,其更聚焦于库的打包,因此更适合库的开发.
    • parcel适⽤于简单的实验性项⽬: 他可以满⾜低⻔槛的快速看到效果,但是⽣态差、报错信息不够全⾯都是他的硬伤,除了⼀些玩具项⽬或者实验项⽬不建议使⽤
  16. babel.config.js和.babelrc有什么区别

    baberc 的加载规则是按目录加载的,是只针对自己的代码。config的配置针对了第三方的组件和自己的代码内容。babel.config.js 是一个项目级别的配置,一般有了babel.config.js 就不会在去执行.babelrc的设置

  17. webpack中tree shaking的用途和原理是什么?

    一个模块可能有多个⽅法,只要其中的某个⽅法使⽤到了,则整个⽂件都会被打到 bundle ⾥⾯去,tree shaking 就是只把⽤到的⽅法打⼊ bundle ,没⽤到的⽅法会在 uglify 阶段被擦除掉。

    原理:利⽤ ES6 模块的特点:

    • 只能作为模块顶层的语句出现
    • import 的模块名只能是字符串常量
    • import binding 是 immutable(不可改变的) 的
  18. eventbus原理,讲述eventbus在vue中的实践

    EventBus是消息传递的一种方式,基于一个消息中心,订阅和发布消息的模式,称为发布订阅者模式。可以把eventBus当成一个管道,这个管道两端可以接好多组件,两端的任何一个组件都可以进行通信。其实这个管道就是Vue实例,实例中的$on, $off, $emit方法来实现此功能

  19. vue-loader实现原理是什么

    vue-loader是用于webpack的加载器,允许你用叫做Single-File Components单文件组件的格式来写Vue组件。

    vue-loader不是简单的源转换器。它用自己专用的加载链(你可以认为每个块是虚拟的模块)处理SFC(Single-file Component 单文件组件)内部的每个语言块,最后将这些块组成最终的模块

@janeLLLL janeLLLL changed the title 面试试题(一) 拉勾前端测试Part.1 Nov 23, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant