2021-04-21

30道大概率会考到的题( 5-10题)

本章内容
  • 1,浏览器从输入url到页面加载发生了什么?
  • 2,css常见布局(圣杯布局、双飞翼布局)
  • 3,vue 中 computed、watch 区别
  • 4,闭包
  • 5,forEach、for in、for of区别

1, 浏览器从输入url到页面加载发生了什么?

1, DNS解析(网址 -> IP地址)

计算机在整个互联网中的唯一标示是IP地址,所以DNS解析:从输入的url到寻找IP地址的一个过程

DNS缓存:先查看浏览器之前是否访问过该IP地址,如果访问过,会直接返回。如果没有访问过,会继续查找操作系统,操作系统如果还没有,会进行分级查询:先查找本地DNS服务器,没有的话会继续查找根域名服务器,再没有会继续查找COM顶级域名服务器,还没有会继续查找google.com域名服务器

2, TCP连接(三次握手) -> 为什么两次不可以?

第一次握手:客户端发送给服务端:发送一个SYN=1字段代表请求建立连接,还会发送一个seq=x(序列号);
第一次握手说明客户端具有发送信息的能力

第二次握手:服务端收到客户端的请求会回复客户端:SYN=1表明服务端同意建立连接,服务端表明收到了客户端的序列号会发送一个ask=x+1字段,ack字段表明确认收到客户端的seq字段,同时也会发送一个序列号(服务端序列号)即seq=n;
第二次握手说明服务端具有接受信息和发送信息的能力

第三次握手:客户端接收到服务端信息后会告诉服务端接收到信息,会发送SYN=0,SYN表明发送信息,并确认收到了ACK,并发送ack=n+1,还会发送seq=x+1;
第三次握手说明客户端具有接收信息的能力

TCP三次握手

3, 发送HTTP请求

4, 服务端处理请求,并返回HTTP报文

5, 浏览器解析和渲染页面

6, 终止TCP连接(四次挥手) 为什么3次不可以?

  • 第1次挥手:客户端发送一个FIN=x的参数,用来关闭客户端到服务端的数据传送
  • 第2次挥手:服务端收到客户端的请求(FIN报文),并会返回一个ACK报文,ack=客户端FIN序号+1。(和SYN一样,一个FIN报文占一个序号)
  • 第3次挥手:服务端关闭客户端的连接,发送一个FIN给客户端
  • 第4次挥手: 客户端发送ack报文确认,并将服务端发送的FIN序号+1


    TCP四次挥手

2,css常见布局(圣杯布局、双飞翼布局)

大致要求: header、footer固定高度;左右两边固定宽度,中间宽度自适应,中间部分的高度是三栏中最高的区域的高度

DOM结构
1,圣杯布局

先上完整代码

header
center

content

left
right
footer
header, footer { width: 100%; height: 60px; background-color: rgb(180, 180, 180); clear: both; } footer { background-color: rgb(148, 191, 248); } .left, .right { width: 200px; background-color: rgb(47, 238, 245); } .center { width: 100%; background-color: rgb(240, 101, 46); } .left { margin-left: -100%; position: relative; left: -200px; } .right { margin-left: -200px; position: relative; right: -200px; } main { padding: 0 200px; } main div { float: left; }

1,center设置为100%,left、right分别设置为width:200px, 此时宽不够,left、right被挤下去

image

2,left设置margin-left: -100%,right设置margin-left: -200px, 此时left上去并靠左,right上去并靠右,但是left挡住了center左侧部分

image

3, 此时设置main的padding: 0 200px, 左右让出200px给left、right, 但是left、right也跟着过去了

image

4,给left、right加相对定位,left设置-200px,right设置right: -200px

image
2,双飞翼布局

先上完整代码

header
center
left
right
footer
main>div { float: left; } .left, .right { width: 200px; background-color: rgb(47, 238, 245); } .center { width: 100%; background-color: rgb(240, 101, 46); } .left { margin-left: -100%; } .right { margin-left: -200px; } .inside { margin: 0 200px; }

left、right设置width: 200px, center设置100%,宽度不够,left、right被挤下去

image

left设置margin-left: -100%; right设置margin-left: -200px, 此时left会挡住center左侧部分

image

此时给center中的inside设置margin: 0 200px;给左、右留出空间

image
个人推荐使用双飞翼布局

3, vue 中 computed、watch 区别

computed(计算属性)

computed 1,支持缓存,只有依赖数据发生改变才会重新进行计算。 2,不支持异步,computed内有异步操作时无效,无法监听数据的变化。

{{ msg.split('').reverse().join('') }} // 在页面中需要使用大量的表达式去处理数据的话,对页面的维护会有很大的影响。这时就需要使用computed来处理。

以上代码用计算属性改写:

computed: {
  changeMsg () {
    return this.msg.split('').reverse().join('')
  }
},

computed属性值会默认走缓存,计算属性是基于他们的响应式依赖进行缓存的,也就是基于data中声明过的数据或父组件传递的props中的数据通过计算得到的值。

如果一个属性是由其他属性计算来的,这个属性依赖其他属性,是一对多或一对一,一般用computed

watch(侦听属性)

watch属性可以是字符串、函数、对象、数组, 拥有deep,immediate两属性。

watch 1,不支持缓存,数据变直接触发响应的操作。2,watch支持异步

watch: {
  obj: {
    handler(newName, oldName) {
      console.log('obj.a');
    },
    immediate: true, // immediate:组件加载理解触发回调函数执行
    deep: true  // deep:深度监听,如果监听的是一个对象,会同时监听其内部属性,就会导致性能开销大,优化:可以使用字符串的形式监听
  }
}

使用字符串的形式监听:

watch: {
  'obj.a': {
    handler(newName, oldName) {
      console.log('iiiii');
    },
    immediate: true,
    deep: true
  }
}

监听数据必须是data中声明过的或父组件传递的props中的数据

4,闭包

红宝书对其定义:闭包是指有权访问另一个函数作用域中的变量的函数。

闭包的特点:

1,函数嵌套函数
2,内部函数可以访问外部函数的参数和变量
3,参数和变量不会被垃圾回收机制回收(参数和变量长期驻扎在内存中)

常见的闭包结构:

function fn() {
  var num = 20
  return function fn1() {
      console.log(num)
  }
}
function fn() {
  var num = 100
  function fn1() {
    console.log(num)  // 100
  }
  return fn1
}
var foo = fn() // fn返回值是fn1, 此时foo就是fn1
foo() // foo() = fn1()  

常见的面试题:定时器问题

for (var i = 0; i <= 5; i++) {
  setTimeout(_ => {
      console.log(i)
  }, 1000)
}
// 1s后输出6个6
setTimeout(宏任务)在当前执行队列的最后执行,获取到的i是最外部作用域的i=6

以上代码改写成输出0~5:

for (let i = 0; i <= 5; i++) {
  setTimeout(_ => {
    console.log(i)
  }, 1000)
}
//1s后输出 0 1 2 3 4 5
由于闭包中的变量会保存下来,所以输出结果为012345

5,forEach、for in、for of区别

forEach是对数组的每一个元素执行一次给定的函数,返回值是undefined,不改变原数组

let arr = ['a', 'b', 'c', 'd']
let a = arr.forEach((item, idx, arr) => {
    item = 0
})
console.log(a)  // undefined
console.log(arr)  // ['a', 'b', 'c', 'd']

for in

for in循环遍历的值都是数据结构的健值,合适遍历对象。

let arr = ['a', 'b', 'c', 'd']
for (let i in arr) {
    console.log(i) // 0 1 2 3
}

for of

for of用来循环获取健值对中的值,不能对对象使用

// 遍历数组
let arr = ['a', 'b', 'c', 'd']
for (let i of arr) {
    console.log(i) // a b c d
}
// 遍历对象
let obj = {a: '1', b: '2', c: '3'}
for (let o of obj) {
  console.log(o);   // Uncaught TypeError: obj is not iterable
}

你可能感兴趣的:(2021-04-21)