【面试题】腾讯面试查漏补缺

说明:只记录查漏补缺的

一面

1.JS精准地判断数据类型

判断数据类型的几种方式

typeof  其中数组、对象、null都会被判断为Object,其他判断都正确

instanceof 只能判断引用数据类型,不能判断基本数据类型

constructor 它有2个作用 一是判断数据的类型,二是对象实例通过constructor对象访问它的构造函数。需要注意的事情是如果创建一个对象来改变它的原型,constructor就不能来判断数据类型了

Object.prototype.toString.call()

1. typeof

typeof对于原始类型来说,除了null都可以显示正确的类型;对于对象来说,除了函数,其他都会显示object,所以typeof可以正确识别:Undefined、Boolean、Number、String、Symbol、Function 等类型的函数,但是对于其他的都会认为是object,比如Null、Date等,所以通过typeof来判断数据类型会不准确。

typeof 12;  //number
console.log(typeof 12 === "number");    //true
typeof typeof 12;   //String
typeof typeof typeof 12     //String

如果我们想判断一个对象的正确类型,可以考虑使用instanceof,因为内部机制是通过原型链来判断的。

2. instanceof

instanceof是用来判断一个对象在其原型链中是否存在一个构造函数的prototype属性,可以用来判断数组和对象,但不能用于基础数据类型。

a instanceof b:判断a是否为b的实例,可以用于继承关系中

b是c的父对象,a是c的实例,a instanceof b 与 a instanceof c 结果均为true

const Person = function () { }
const p1 = new Person()
console.log(p1 instanceof Person) //true

var str = 'hello world'
console.log(str instanceof String) //string

var str1 = new String('hello world')
console.log(str1 instanceof String) //true

对于原始类型来说,想直接通过instanceof来判断类型是不行的。

当然还可以使用对象的Symbol.hasInstance属性,指向一个内部方法,自定义 instanceof
操作符在某个类上的行为,让instanceof判断原始类型。

class MyClass {
    [Symbol.hasInstance](foo) {
        return foo instanceof Array;
    }
    static [Symbol.hasInstance](str) {
        return typeof str === 'string';
    }
}

var x = new MyClass();
console.log([1, 2, 3] instanceof new MyClass())//true
console.log(x[Symbol.hasInstance]([0, 0, 0]))//true
console.log('hello' instanceof MyClass)//true,调用static静态方法
console.log(MyClass[Symbol.hasInstance](2))//false,调用static静态方法
console.log(x instanceof MyClass)//false,因为修改了静态方法。x本身是MyClass类的实例,如果注释了静态方法就会返回true

当其他对象使用instanceof运算符,判断是否为该对象的实例时,会调用

3. Object.prototype.toString.call();
console.log(Object.prototype.toString.call("jerry"));   //[object String]
console.log(Object.prototype.toString.call(12));        //[object Number]
console.log(Object.prototype.toString.call(true));      //[object Boolean]
console.log(Object.prototype.toString.call(undefined)); //[object Undefined]
console.log(Object.prototype.toString.call(null));      //[object Null]
console.log(Object.prototype.toString.call({name: "jerry"}));//[object Object]
console.log(Object.prototype.toString.call(function(){}));//[object Function]
console.log(Object.prototype.toString.call([]));          //[object Array]
console.log(Object.prototype.toString.call(new Date));     //[object Date]
console.log(Object.prototype.toString.call(/\d/));        //[object RegExp]
function Person(){};
console.log(Object.prototype.toString.call(new Person));//[object Object]

封装

getTypeof(data){
    let dataType = Object.prototype.toString.call(data);
    //[object Array] [object Number] [object String] ……
    return DataType.slice(8, -1)
}

2.js 驼峰命名和下划线互换

面试官:如果有一个字符串,是下划线形式,怎么去把 下划线去掉并且下划线后面的首字母改成大写
面试官:如果有一个字符串,是大小写,怎么去把大写前面改成下划线

思路:正则

// 下划线转换驼峰
function toHump(name) {
    return name.replace(/\_(\w)/g, function(all, letter){
        return letter.toUpperCase();
    });
}
// 驼峰转换下划线
function toLine(name) {
  return name.replace(/([A-Z])/g,"_$1").toLowerCase();
}


// 测试
let a = 'a_b2_345_c2345';
console.log(toHump(a));

let b = 'aBdaNf';
console.log(toLine(b));



结果输出:
aB2345C2345
a_bda_nf

3. 浏览器的事件循环Event Loop

console.log(1);

setTimeout(() => {
  console.log(2);
  Promise.resolve().then(() => {
    console.log(3)
  });
});

new Promise((resolve, reject) => {
  console.log(4)
  resolve(5)
}).then((data) => {
  console.log(data);
})

setTimeout(() => {
  console.log(6);
})

console.log(7);

4.在地址栏里输入一个地址回车会发生哪些事情

1、解析URL:首先会对 URL 进行解析,分析所需要使用的传输协议和请求的资源的路径。如果输入的 URL 中的协议或者主机名不合法,将会把地址栏中输入的内容传递给搜索引擎。如果没有问题,浏览器会检查 URL 中是否出现了非法字符,如果存在非法字符,则对非法字符进行转义后再进行下一过程。
2、缓存判断:浏览器会判断所请求的资源是否在缓存里,如果请求的资源在缓存里并且没有失效,那么就直接使用,否则向服务器发起新的请求。
3、DNS解析: 下一步首先需要获取的是输入的 URL 中的域名的 IP 地址,首先会判断本地是否有该域名的 IP 地址的缓存,如果有则使用,如果没有则向本地 DNS 服务器发起请求。本地 DNS 服务器也会先检查是否存在缓存,如果没有就会先向根域名服务器发起请求,获得负责的顶级域名服务器的地址后,再向顶级域名服务器请求,然后获得负责的权威域名服务器的地址后,再向权威域名服务器发起请求,最终获得域名的 IP 地址后,本地 DNS 服务器再将这个 IP 地址返回给请求的用户。用户向本地 DNS 服务器发起请求属于递归请求,本地 DNS 服务器向各级域名服务器发起请求属于迭代请求。
4、获取MAC地址: 当浏览器得到 IP 地址后,数据传输还需要知道目的主机 MAC 地址,因为应用层下发数据给传输层,TCP 协议会指定源端口号和目的端口号,然后下发给网络层。网络层会将本机地址作为源地址,获取的 IP 地址作为目的地址。然后将下发给数据链路层,数据链路层的发送需要加入通信双方的 MAC 地址,本机的 MAC 地址作为源 MAC 地址,目的 MAC 地址需要分情况处理。通过将 IP 地址与本机的子网掩码相与,可以判断是否与请求主机在同一个子网里,如果在同一个子网里,可以使用 APR 协议获取到目的主机的 MAC 地址,如果不在一个子网里,那么请求应该转发给网关,由它代为转发,此时同样可以通过 ARP 协议来获取网关的 MAC 地址,此时目的主机的 MAC 地址应该为网关的地址。
5、TCP三次握手: 下面是 TCP 建立连接的三次握手的过程,首先客户端向服务器发送一个 SYN 连接请求报文段和一个随机序号,服务端接收到请求后向客户端发送一个 SYN ACK报文段,确认连接请求,并且也向客户端发送一个随机序号。客户端接收服务器的确认应答后,进入连接建立的状态,同时向服务器也发送一个ACK 确认报文段,服务器端接收到确认后,也进入连接建立状态,此时双方的连接就建立起来了。
6、HTTPS握手: 如果使用的是 HTTPS 协议,在通信前还存在 TLS 的一个四次握手的过程。首先由客户端向服务器端发送使用的协议的版本号、一个随机数和可以使用的加密方法。服务器端收到后,确认加密的方法,也向客户端发送一个随机数和自己的数字证书。客户端收到后,首先检查数字证书是否有效,如果有效,则再生成一个随机数,并使用证书中的公钥对随机数加密,然后发送给服务器端,并且还会提供一个前面所有内容的 hash 值供服务器端检验。服务器端接收后,使用自己的私钥对数据解密,同时向客户端发送一个前面所有内容的 hash 值供客户端检验。这个时候双方都有了三个随机数,按照之前所约定的加密方法,使用这三个随机数生成一把秘钥,以后双方通信前,就使用这个秘钥对数据进行加密后再传输。
7、返回数据: 当页面请求发送到服务器端后,服务器端会返回一个 html 文件作为响应,浏览器接收到响应后,开始对 html 文件进行解析,开始页面的渲染过程。
8、页面渲染: 浏览器首先会根据 html 文件构建 DOM 树,根据解析到的 css 文件构建 CSSOM 树,如果遇到 script 标签,则判端是否含有 defer 或者 async 属性,要不然 script 的加载和执行会造成页面的渲染的阻塞。当 DOM 树和 CSSOM 树建立好后,根据它们来构建渲染树。渲染树构建好后,会根据渲染树来进行布局。布局完成后,最后使用浏览器的 UI 接口对页面进行绘制。这个时候整个页面就显示出来了。
9、TCP四次挥手: 最后一步是 TCP 断开连接的四次挥手过程。若客户端认为数据发送完成,则它需要向服务端发送连接释放请求。服务端收到连接释放请求后,会告诉应用层要释放 TCP 链接。然后会发送 ACK 包,并进入 CLOSE_WAIT 状态,此时表明客户端到服务端的连接已经释放,不再接收客户端发的数据了。但是因为 TCP 连接是双向的,所以服务端仍旧可以发送数据给客户端。服务端如果此时还有没发完的数据会继续发送,完毕后会向客户端发送连接释放请求,然后服务端便进入 LAST-ACK 状态。客户端收到释放请求后,向服务端发送确认应答,此时客户端进入 TIME-WAIT 状态。该状态会持续 2MSL(最大段生存期,指报文段在网络中生存的时间,超时会被抛弃) 时间,若该时间段内没有服务端的重发请求的话,就进入 CLOSED 状态。当服务端收到确认应答后,也便进入 CLOSED 状态。

5.Vue的父子组件生命周期钩子函数执行顺序?

<!-- 加载渲染过程 -->
    <!-- 父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created ->
    子beforeMount -> 子mounted -> 父mounted -->
    <!-- 子组件更新过程 -->
    <!-- 父beforeUpdate -> 子beforeUpdate -> 子updaed -> 父updated -->
    <!-- 父组件跟新过程 -->
    <!-- 父beforeUpdate -> 父updated -->
    <!-- 销毁过程 -->
    <!-- 父beforeDestroy -> 子beforeDestroy -> 子destroyed ->父destroyed -->

6.CDN原理简单介绍

通俗原理(必须懂)
在这里插入图片描述
通过域名解析IP分析(加分)
在这里插入图片描述

  1. 当用户点击网站页面上的内容URL,经过本地DNS系统解析,DNS 系统会最终将域名的解析权交给 CNAME 指向的 CDN 专用 DNS 服务器。
  2. CDN 的 DNS 服务器将 CDN 的全局负载均衡设备 IP 地址返回用户。
  3. 用户向 CDN 的全局负载均衡设备发起内容 URL 访问请求。
  4. CDN 全局负载均衡设备根据用户 IP 地址,以及用户请求的内容URL,选择一台用户所属区域的区域负载均衡设备,告诉用户向这台设备发起请求。
  5. 基于以下这些条件的综合分析之后,区域负载均衡设备会向全局负载均衡设备返回一台缓存服务器的IP地址:
  6. 根据用户 IP 地址,判断哪一台服务器距用户最近;
  7. 根据用户所请求的 URL 中携带的内容名称,判断哪一台服务器上有用户所需内容;
  8. 查询各个服务器当前的负载情况,判断哪一台服务器尚有服务能力。
  9. 全局负载均衡设备把服务器的 IP 地址返回给用户。
  10. 用户向缓存服务器发起请求,缓存服务器响应用户请求,将用户所需内容传送到用户终端。如果这台缓存服务器上并没有用户想要的内容,而区域均衡设备依然将它分配给了用户,那么这台服务器就要向它的上一级缓存服务器请求内容,直至追溯到网站的源服务器将内容拉到本地。

DNS 服务器根据用户 IP 地址,将域名解析成相应节点的缓存服务器IP地址,实现用户就近访问。使用 CDN
服务的网站,只需将其域名解析权交给 CDN 的全局负载均衡(GSLB)设备,将需要分发的内容注入 CDN,就可以实现内容加速了。

7.webpack 做过哪些优化,开发效率方面、打包策略方面等等

  1. 缩小打包作用域(exclude/include (确定 loader 规则范围))
  2. 充分利用缓存提升二次构建速度:babel-loader
    2)优化 Webpack 的打包体积

压缩代码 提取页面公共资源:
Tree shaking
Scope
hoisting
图片压缩
动态Polyfill

二面

其实二面,就没有太多技术上面问题去问了
主要还是问一下你的项目思维和问题处理方式 遇到了问题怎么去处理 有哪些方向的思考
给你一个大的场景,你说下你的思路,这样子

7.你项目里遇到的难点是什么?如何解决的?

广泛性问题,从自己做的项目里面,去回忆,遇到了哪些问题,怎么处理的,就可以了 每个项目说一点都行

8.其他的就不写了,都是个人主观问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不停喝水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值