牛客面经每日一总结(七)

196 阅读6分钟

闭包的输出题

    function inc(i){
        let value = 0;
        var Increment = function(){
            value += i;
            console.log(value);
            const message = `current value is ${value}`;
            return function(){
                console.log(message);
            }
        }
        return Increment;
    }

    let log = inc(1);//返回Increment函数
    let Inc = inc(1);
    log();//调用函数,外部value =0;输出1
    log();//2
    log();//3
    Inc();//1
    let func = Inc();//value=2
    func();//current value is 2

meta标签的属性,有什么用?

表示那些不能由其它 HTML 元相关(meta-related)元素(base,link,script,style,title)之一表示的任何元数据信息。

meta 元素定义的元数据的类型包括以下几种:

name

如果设置了 name 属性,meta 元素提供的是文档级别(document-level)的元数据,应用于整个页面。

name 和 content 属性可以一起使用,以名 - 值对的方式给文档提供元数据,其中 name 作为元数据的名称(keyword, description),content 作为元数据的值。

这个一般设置一些关键字,有利于seo。

http-equiv

如果设置了http-equiv属性,meta 元素则是编译指令,提供的信息与类似命名的 HTTP 头部相同。

  • content-security-policy 它允许页面作者定义当前页的内容策略(csp)。 内容策略主要指定允许的服务器源和脚本端点,这有助于防止跨站点脚本攻击。

  • content-type 如果使用这个属性,其值必须是"text/html; charset=utf-8"。注意:该属性只能用于 MIME type 为 text/html 的文档,不能用于 MIME 类型为 XML 的文档。

  • default-style 设置默认CSS 样式表组的名称。

  • x-ua-compatible 如果指定,则 content 属性必须具有值 "IE=edge"。用户代理必须忽略此指示。

  • refresh 这个属性指定:

    • 如果 content只包含一个正整数,则为重新载入页面的时间间隔 (秒);这里他会连续刷新。
    • 如果content 包含一个正整数,并且后面跟着字符串 ';url=' 和一个合法的 URL,则是重定向到指定链接的时间间隔 (秒)。这里只会跳转一次。

charset

  • 如果设置了 charset属性,meta 元素是一个字符集声明,告诉文档使用哪种字符编码。 只能设置"utf-8"。

itemprop

  • 如果设置了itemprop属性,meta 元素提供用户定义的元数据

float与fixed,absolute区别

相同点

  • 设置后,都会使行内元素支持宽高。
  • 都脱离文档流,不占原来的位置。
  • 块元素不设置宽度,默认由内容撑开。

不同点

  • float主要是可以让块级元素可以在同一行排列。fixed, absolute主要是对元素进行定位,移动元素的位置。
  • fixed不会随着视口滚动而移动。但是如果父元素设置transform, perspective 或 filter不为none时,那么它将相对于该父元素定位。
  • absolute如果不设置四个方向的偏移量,那么后者将覆盖在前者的上面。
  • float覆盖的元素中的文字不会被覆盖。但是absolute,fixed会全部覆盖元素的内容。
  • absolute, fixed可以通过z-index来改变层叠层级。

实现一个next的斐波拉切数列

    // 题目
    function fib(){
        return xxx
    }

    let a = fib()
    console.log(a.next())   //0
    console.log(a.next())   //1
    console.log(a.next())   //1
    console.log(a.next())   //2
    console.log(a.next())   //3
    console.log(a.next())   //5
    console.log(a.next())   //8
    console.log(a.next())   //13

实现

// 通过迭代器实现
    function* fib() {
      let fibArr = [0, 1]
      let i = 0
      while (true) {
        fibArr[i + 2] = fibArr[i] + fibArr[i + 1]
        yield fibArr[i]
        i++
      }
    }
    // 这个会有问题,输出的是0, 1, 2, 3
    function fib() {
      let prev = 0
      let nex = 0
      let total = 0
      // let fibArr = [0, 1]; fibArr[i] = fibArr[i - 2] + fibArr[i - 1]; i = 2开始
      return {
        next: () => {
          total = nex + prev
          prev = nex
          nex = nex == 0 ? 1 : total
          if (prev == 1) {
            return 1
          }
          return total
        }
      }
    }

keep-alive实现的原理

keep-alive 是 Vue.js 的一个 内置组件。它能够将不活动的组件实例保存在内存中,而不是直接将其销毁,它是一个抽象组件,不会被渲染到真实 DOM 中,也不会出现在父组件链中。简单的说,keep-alive用于保存组件的渲染状态,避免组件反复创建和渲染,有效提升系统性能。

max属性来表明最大的缓存数,如果超过了最大缓存数,那么就使用LRU算法,删除最近未使用的组件,然后加入新的组件。

vue中设置了一个缓存容器,将组件放在这个缓存容器中,而不是将其销毁,在创建。而是直接在容器中拿取。并通过isDeactivated来判断组件是否活跃。

具体请参考这里

一些不常用api的解释

URLSearchParams

解析一个url的query参数,返回一个map对象。所以我们可以通过Object.fromEntries()将其转为一个对象

    const params = new URLSearchParams('name=zh&age=20')

    console.log(params) // URLSearchParams { 'name' => 'zh', 'age' => '20' }

    const paramsObj = Object.fromEntries(params)

    console.log(paramsObj) //{ name: 'zh', age: '20' }

URL

解析一个完整的url。返回一个对象。

const url = 'http://localhost:8080/detail?id=1#header-8'

const params = new URL(url)

console.log(params)

URL {
  href: 'http://localhost:8080/detail?id=1#header-8',
  origin: 'http://localhost:8080',
  protocol: 'http:',
  username: '',
  password: '',
  host: 'localhost:8080',
  hostname: 'localhost',
  port: '8080',
  pathname: '/detail',
  search: '?id=1',
  searchParams: URLSearchParams { 'id' => '1' },
  hash: '#header-8'
}

多路复用中的流和帧

  • 帧是乱序收发的,但是他们只要有相同的流ID,那么他们就属于相同的流。

  • 在这个流中,帧不是乱序的,而是有着严格的先后顺序的。

  • 流就相当于http的一次请求应答,他是一个二进制帧的双向传输序列。

  • 帧首部的流标识符标识着流ID。接收方在乱序的帧里识别出相同的ID的帧,按顺序组装起来形成虚拟的流。

MVC, MVP, MVVM

  • MVP MVP是单词Model View Presenter的首字母的缩写,分别表示数据层、视图层、发布层,它是MVC架构的一种演变。

MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,presenter就相当于中间人。

因为 View 层与 Model 层没有关系,所以 View 层可以抽离出来做成组件,在复用性上比 MVC 模型好很多。 而在MVC中View会直接从Model中读取数据而不是通过 Controller。

  • MVC 分别表示:数据模型层,视图层,控制层。这种设计模式一般在后端用的比较多。
  • MVVM M: 数据模型层,V: 视图层,VM: vue。数据驱动视图的变化。

具体区别请看这里

面向对象的理解

面向过程:分析问题所需要的步骤,然后用函数把这些步骤一一实现,使用的时候一个个一次调用就可以了。

面向对象:把解决的问题按照一定规则划分为多个独立的对象,然后通过调用对象的方法来解决问题。

面向对象的特点:封装性,继承性,多态性。