# 18. 腾讯面试

# 一面(技术面)

小姐姐先介绍了下技术栈和公司业务,然后我自我介绍,然后问问题。

# 1. tcp三次握手

待更新

# 2.http和https区别

待更新

# 3.前端安全问题有哪些?

  1. SQL注入
  2. XSS
  3. CSRF
  4. 点击劫持
  5. 中间人攻击

https://segmentfault.com/a/1190000020683150?utm_source=tag-newest

# 4.ssl加密机制(非对称加密原理)

待更新

# 5.计算结果

async function async1() {
  console.log('async1 start');//2
  await async2();
  console.log('async1 end');//6
}

async function async2() {
  console.log('async2');//3
}

console.log('script start');//1

setTimeout(function() {
  console.log('setTimeout');//8
}, 0);

async1();

new Promise(function(resolve) {
  console.log('promise1');//4
  resolve();
}).then(function() {
  console.log('promise2');//7
});

console.log('script end');//5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 6.vue中组件通信

  1. props/$emit
  2. $parent/$children
  3. 中央事件Bus的$on/$emit
  4. $attrs/$listener
  5. 状态管理vuex
  6. .sync

# 7.vue中双向数据绑定

利用数据劫持配合发布者-订阅者模式的方式,通过Object.definerProperty()来劫持各个属性的setter和getter。在数据变动时,发布消息给依赖收集器,去通知观察者做出对应的回调函数去更新视图。

# 8.js防抖节流代码实现

```js
// 防抖函数
const debounce = (fn, delay) => {
  let timer = null;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, args);
    }, delay);
  };
};

// 节流函数
const throttle = (fn, delay = 500) => {
  let flag = true;
  return (...args) => {
    if (!flag) return;
    flag = false;
    setTimeout(() => {
      fn.apply(this, args);
      flag = true;
    }, delay);
  };
};
```

# 9.了解react吗?

因为我在工作中负责移动端项目的开发,用到过rn,所以学习过react。相比vue,react因为是基于jsx开发的,所以使用起来非常灵活,万物皆可js。react开源库也非常多,选择上也非常自由,但是对于选择困难症来说选择比较烦恼。vue虽然也有很多开源库,但是大方向上就是使用官方的库,不需要做过多的选择。

# 二面(产品经理面)

为什么找工作?公司业务你还有哪些想知道的?

  1. 想来大厂(能接触到新技术、牛人多、福利好)
  2. 工资方面想提升
  3. 离家远

# 1.代码实现轮播图

  1. 利用css的animation/@keyframe实现
<style>
.outer{
  width:500px;
  height:300px;
  overflow: hidden;
  position: relative;
}
.inner{
  position: absolute;
  left:0;
  height:100%;
  display:flex;
  animation: slide 7.5s infinite;
}
@keyframes slide {
  from{
    left:0;
  }
  20%{
    left:-500px;
  }
  40%{
    left:-1000px;
  }
  60%{
    left:-1500px;
  }
  80%{
    left:-2000px;
  }
  to{
    left:-2500px;
  }
}
.inner div{
  width:500px;
  height:100%;
}

</style>
<body>
  <div class="outer">
    <div class="inner">
      <div style="background:red">1</div>
      <div style="background:green">2</div>
      <div style="background:yellow">3</div>
      <div style="background:yellowgreen">4</div>
      <div style="background:pink">5</div>
      <div style="background:red">1</div>
    </div>
  </div>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
  1. 利用js中setIntval每隔一段时间切换img地址
  2. 利用js设置style.left值实现
<style>
.outer {
  width: 500px;
  height: 300px;
  overflow: hidden;
  position: relative;
}

.inner {
  position: absolute;
  left: 0;
  height: 100%;
  display: flex;
}

.inner div {
  width: 500px;
  height: 100%;
}
</style>

<body>
<div class="outer">
  <div class="inner">
    <div style="background:red">1</div>
    <div style="background:green">2</div>
    <div style="background:yellow">3</div>
    <div style="background:yellowgreen">4</div>
    <div style="background:pink">5</div>
    <div style="background:red">1</div>
  </div>
</div>
<script>
  let el = document.querySelector('.inner');
  let current = 0;
  let flag = null;
  let frame = null;
  /* 开始移动 */
  function move() {
    if (current >= el.children.length) {
      current = 1;
      el.style.left = '0px';
    }
    frame = requestAnimationFrame(animate)
  }
  /* 移动动画 */
  function animate() {
    let left = parseInt(getComputedStyle(el).left);
    if (left > current * -500) {
      el.style.left = left - 5 + 'px';
      frame = requestAnimationFrame(animate)
    }
  }
  /* 开启定时器 */
  function start() {
    if (flag) return;
    flag = setInterval(() => {
      current++;
      move();
    }, 3000);
  }

  function stop() {
    clearInterval(flag) //清除定时器
    flag = null;
  }
  start();
  /* 解决标签页切换导致定时器积累执行 */
  window.onfocus = start;
  window.onblur = stop;

  /* 触摸停止动画 */
  el.onmouseenter = function () {
    stop();
    cancelAnimationFrame(frame)
  };
  el.onmouseleave = function () {
    frame = null;
    move();
    start()
  };
</script>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

# 2.遇到过你觉得最难的项目

我在第一个公司参与过几个项目,大部分都是基于敏捷开发框架来开发的,语言也基本是js、jq。这种项目从技术上来说我觉得难的是理解框架的 结构,理解之后也就不难了。因为框架不需要做大的改动,所以开发业务上的难点基本都是表单的复杂度。

还有一个项目是用angular1.7开发的,是地图方面的。因为在那之前都是用敏捷开发框架,没接触过angular和模块化开发,所以刚开始时候是非常难得,因为要学习项目的结构和业务,这个过程中遇到angular不懂的语法还要查询资料。不过熟悉整个代码结构后,发现其实大部分还是用的js。之后难点就是学习地图插件openlayer3。

现在的公司一直是一个项目,在这个项目上每个季度加新的需求或者定制化需求,所以难点是怎么让以后更好的开发和维护,所以把需求里面常用到的功能组件化起来,以后遇到相同的需求直接用就行了。在领导身上也学习到了不少的知识,因为项目一直在迭代所以模块越来越多,代码量也越来越多,项目启动速度也越来越慢,所以参与了项目的拆分工作,把每个模块抽离出来,相当于船上面的集装箱,用到那个使用哪个就行了。提升了开发效率。

还负责了移动端项目的开发。学习了react和rn,了解了一些rn和react的区别,以及移动端和web端的区别。

# 3.charset编码有什么用,有哪些?UTF-8和GBK区别

首先来说明一下“utf-8”是一种字符编码。charset=”utf-8”是告知浏览器此页面属于什么字符编码格式,下一步浏览器做好“翻译”工作。常见的字符编码有:gb2312、gbk、unicode、utf-8。

各个字符编码含义:
gb2312:代表国家标准第2312条,其中是不包含繁体的(虽然咱们不怎么使用繁体了,但是台湾还在使用繁体啊。那怎么办呢?)。
gbk:国家标准扩展版(增加了繁体,包含所有亚洲字符集)。
unicode:万国码(字面意思你也懂的)。
utf-8:unicode的升级版。世界通用语言编码

# 4.html lang="en"有什么用?

简单来说,可能对于程序来说没有太大的作用,但是它可以告诉浏览器,搜索引擎,一些处理Html的程序对页面语言内容来做一些对应的处理或者事情。 比如可以:

  1. 根据根据lang属性来设定不同语言的css样式,或者字体
  2. 告诉搜索引擎做精确的识别
  3. 让语法检查程序做语言识别
  4. 帮助翻译工具做识别
  5. 帮助网页阅读程序做识别

en定义语言为英语
zh-CN定义语言为中文
更多可以参考:https://www.w3.org/International/questions/qa-lang-why (opens new window)

# 5.display:flex中元素如何居中显示?

justify-content: center; align-items: center;

absolute+transform

# 6.浮点数精度问题

console.log(0.1+0.1) //0.2
console.log(0.1+0.2) //0.30000000000000004(精度最高保留到17位)
查阅资料之后,发现是因为像 0.1+0.2这样的操作对于计算机来说转换为二进制之后将是两个无限循环的数。而对于计算机而言是不允许有无限的,进行四舍五入之后双精度浮点数保留53位,结果为0.0100 1100 1100 1100 1100 1100 1100 1100 1100 1100 1100 1100 1100转为十进制就是0.30000000000000004

十进制小数转换成二进制小数采用"乘2取整,顺序排列"法。具体做法如下:

用2乘十进制小数,可以得出积,将积的整数部分取出,再用2乘余下的小数部分,又得到一个积,再将积的整数部分取出,如此进行,直到积中的小数部分为零,或者达到所要求的精度为止。然后把取出的整数部分按顺序排列起来。

Number(3.1).toString(2) //"11.0001100110011001100110011001100110011001100110011001101"无限循环
1

0.1转为二进制:

Number(0.1).toString(2) //"0.0001100110011001100110011001100110011001100110011001101"无限循环
1

0.2转为二进制:

Number(0.2).toString(2) //"0.001100110011001100110011001100110011001100110011001101"无限循环
1

那为什么 x=0.1 能得到 0.1?
这是因为这个 0.1 并不是真正的0.1。这不是废话吗?别急,听我解释
JS精度范围。它最大可以表示2^53(9007199254740992), 长度是 16,所以可以使用 toPrecision(16) 来做精度运算,超过的精度会自动做凑整处理。
0.1.toPrecision(16) = "0.1000000000000000"
0.1.toPrecision(17) = "0.10000000000000001"

https://www.zhihu.com/question/26806477 (opens new window)

# 7.parseInt函数的了解

parseInt() 函数可解析一个字符串,并返回一个整数。

语法

parseInt(string, radix)
1
参数 描述
string 必需。要被解析的字符串。
radix 可选。表示要解析的数字的基数。该值介于 2 ~ 36 之间。如果省略该参数或其值为 0,则数字将以 10 为基础来解析。如果它以 “0x” 或 “0X” 开头,将以 16 为基数。如果该参数小于 2 或者大于 36,则 parseInt() 将返回 NaN。

如果字符串的第一个字符不能被转换为数字,那么 parseFloat() 会返回 NaN。 开头和结尾的空格是允许的。

# 8.es6中Symbol有什么用?

  1. 防止命名冲突
  2. 私有属性
  3. Symbol 作为属性名,遍历对象的时候,该属性不会出现在for...in、for...of循环中,也不会被Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回。
const obj = {};
const foo = Symbol('foo');

obj[foo] = 'bar';

for (let i in obj) {
  console.log(i); // 无输出
}


Symbol.for("bar") === Symbol.for("bar")
// true
Symbol("bar") === Symbol("bar")
// false

let s1 = Symbol.for("foo");
Symbol.keyFor(s1) // "foo"
let s2 = Symbol("foo");
Symbol.keyFor(s2) // undefined
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 10.除了a标签还有什么跳转标签?

<area> 标签定义图像映射内部的区域(图像映射指的是带有可点击区域的图像)。
<area> 元素始终嵌套在 <map> 标签内部。

<img src="planets.gif" width="145" height="126" alt="Planets" usemap="#planetmap">

<map name="planetmap">
  <area shape="rect" coords="0,0,82,126" alt="Sun" href="https://www.baidu.com">
  <area shape="circle" coords="95,58,3" alt="Mercury" href="mercur.htm">
  <area shape="circle" coords="124,58,8" alt="Venus" href="venus.htm">
</map>
1
2
3
4
5
6
7

# 11.安全方面有哪些了解?(开放性问题)

  1. SQL注入
  2. XSS
  3. CSRF
  4. 点击劫持
  5. 中间人攻击

https://segmentfault.com/a/1190000020683150?utm_source=tag-newest

# 12.html中嵌套的iframe有什么安全问题,如何预防?

点击劫持
https://blog.csdn.net/yanner_/article/details/81428965?utm_source=blogxgwz4

# 13.第三方库如何预防不安全的因素?(开放性问题)

  1. 尽量用大公司出名的库,并及时更新已有的库的版本
  2. 使用工具来监测代码的安全性,比如Snyk、JFrog Xray
  3. 全局写一些方法防止代码受到污染
  4. 如果你是大神也可以自己查看库源码

https://blog.csdn.net/qwe435541908/article/details/105409231

# 14.webpack在页面性能方面优化(针对客户方面的)?

# 15.除了我问的还有什么擅长的方面吗?

自我感觉比较擅长vue方面、解决问题能力较强。一般遇到问题,第一天怎么都想不来,回去想下第二天基本上都解决了。

# 最后我问有什么建议的吗?

基础原理和知识广度不够,vue方面可以。

# 总结

一面:得加强http方面和安全性方面的知识,了解下react。 二面:基础细节知识得加强,多看一些开放性技术问题。