腾讯一面面经

腾讯一面总结( 1 h 30 m i n 1h30min 1h30min)

笔试题(1h)

1、实现一个格式化数字的函数 addComma,给数字添加千位分隔符
做法一:把每一位拆出来然后加上分隔符

function addComma(num) {
    var ans = [];
    var flag = 0;
    var res="";
    if(num==0){
        res+="0";
    }
    else{
        if(num<0) num=-num,flag=1;
        while (num > 0) {
            ans.push(num % 10);
            num = Math.floor(num/10);
        }
        var temp = [];
        var len = ans.length;
        for (let i = len - 1; i >= 0; i--) temp.push(ans[i]);
        var cnt = 0;
        var res = "";
        if (flag == 1) res+='-';
        for (let i = 0; i < len; i++) {
            res+=temp[i];
            cnt++;
            if (cnt == 3&&i!=len-1){
                res+=',';
                cnt=0;
            }
        }
    }
    console.log(res);
}

做法二
正则表达式

function addComma(num) {
    var reg=/\d{1,3}(?=(\d{3})+$)/g; 
    console.log((num + '').replace(reg, '$&,'));
}

做法三
巧妙做法

function addComma(num) {
    num = num.toLocaleString(); 
    console.log(num);
}

2、实现一个解析url参数的函数
做法一:暴力循环拆数

function parseUrl(urlStr) {
    var res = [{}];
    var len = urlStr.length;
    var id = -1;
    for (let i = 0; i < len; i++) {
        if (urlStr[i] == '?') {
            id = i;
            break;
        }
    }
    if (id != -1) {
        for (let i = id + 1; i < len; i++) {
            var name = "";
            while (i<len&&urlStr[i] != '=') {
                name += urlStr[i];
                i++;
            }
            i++;
            var val = "";
            while (i<len&&urlStr[i] != '&') {
                val += urlStr[i];
                i++;
            }
            res[0][name]=val;
        }
    }
    console.log(res[0]);
}

做法二

function parseUrl(urlStr) {
    var pattern = /(\w+)=(\w+)/ig;//定义正则表达式
    var parames = {};//定义数组
    urlStr.replace(pattern, function(a, b, c){parames[b] = c;});
    console.log(parames);
    return parames;
}

parseUrl(‘https://cloud.tencent.com?a=1&b=2&c=3’);
// 返回 {a: 1, b: 2, c: 3}

3、用 js 实现,假设有一个地级市的列表(数据未定,可能列表很长),要求获取所有地级市的基本信息
地级市信息的接口为:
url: /api/city/info
method: get
入参:id
出参:
{
code: number; // 200 表示成功
success: boolean; // true:成功
data: object; // 获取到的数据
}

要求:
1、使用队列的思维实现,同时支持自定义并发数
2、考虑容错处理
3、注意代码规范,用你认为最优雅的方式实现

还不是特别会,感觉本质是实现一个任务队列。

面试题(30min)

算法题

求距离终点为 k 的节点。
要求1:时间复杂度 O(n),空间复杂度 O(1)
要求2:时间复杂度 O(min(n,k)) 空间复杂度 O(n)
要求3: js或ts实现


基础知识题

1.渲染流程(渲染流水线)

构建DOM树
1. 输入:HTML 文档;
2. 处理:HTML 解析器解析;
3. 输出:DOM 数据解构。

样式计算:
1. 输入:CSS 文本;
2. 处理:属性值标准化,每个节点具体样式(继承、层叠);
3. 输出:styleSheets(CSSOM)。

布局(DOM 树中元素的计划位置)
1. DOM & CSSOM 合并成渲染树;
2. 布局树(DOM 树中的可见元素);
3. 布局计算。


分层
1. 特定节点生成专用图层,生成一棵图层树(层叠上下文、Clip,类似 PhotoShop 里的图层);
2. 拥有层叠上下文属性(明确定位属性、透明属性、CSS 滤镜、z-index 等)的元素会创建单独图层;
3. 没有图层的 DOM 节点属于父节点图层;
4. 需要剪裁的地方也会创建图层。

绘制指令
1. 输入:图层树;
2. 渲染引擎对图层树中每个图层进行绘制;
3. 拆分成绘制指令,生成绘制列表,提交到合成线程;
4. 输出:绘制列表。

分块
合成线程会将较大、较长的图层(一屏显示不完,大部分不在视口内)划分为图块(tile, 256*256, 512*512)。

光栅化(栅格化)
1. 在光栅化线程池中,将视口附近的图块优先生成位图(栅格化执行该操作);
2. 快速栅格化:GPU 加速,生成位图(GPU 进程)。

合成绘制
1. 绘制图块命令——DrawQuad,提交给浏览器进程;
2. 浏览器进程的 viz 组件,根据DrawQuad命令,绘制在屏幕上。

2.前缓冲区和后缓冲区

双缓冲机制。
前缓冲区:用来显示图像的缓冲区。
后缓冲区:用来暂时存储绘制完的图像。
当后缓冲区图像写入完成后,直接对调前后缓冲区来把图像传给显示器。

3.颜色在计算机的表示方法

1.rgb()
2.英文名称
3.16进制数
4.hsv

具体讲讲rgb怎么实现显示颜色?

这其实是三个数字,说明了每种原色的相对份额。如果用0到255的数字表示一种元素的份额,那么0表示这种颜色没有参与,255表示它完全参与其中。
RGB值的概念引出了三维“色空间”。
用于表示颜色的数据量称为色深度,通常用表示颜色的位数来表示色深度。
增强彩色指色深度为16位的颜色,RGB值中的每个数字由5位表示,剩下的一位有时用于表示透明度。
真彩色指色深度为24位的颜色,RGB值中的每个数字由8位表示,即每个数所属的范围是0~255,这样能够生成1670万种以上的颜色。

4.提高页面渲染速度

1.减小关键资源个数——将js和css设置为内联,没有对DOM或CSSOM树操作的js代码加上async。
2.减小关键资源大小——压缩css和js文件大小,移除注释。
3.减少RTT次数——CDN。
4.CSS放在头部,JS放到尾部。
5.图片懒加载

5.node.js
6.事件冒泡,事假捕获和事件委托

事件冒泡:
结构上(非视觉上)嵌套关系的元素,会存在冒泡的功能,即同一事件,自子元素冒泡向父元素。(自底向上)

事件捕获:
结构上(非视觉上)嵌套关系的元素,会存在事件捕获的功能,即同一事件,自父元素捕获至子元素(事件源元素)。(自顶向下)(ie没有捕获事件)

事件委托:

利用事件冒泡和事件源对象进行处理
优点:
1、性能 不需要循环所有的元素一个个绑定事件
2、灵活 当有新的子元素时不需要重新绑定事件

7.addEventListener 第三个参数

可选。布尔值,指定事件是否在捕获或冒泡阶段执行。

可能值:
true - 事件句柄在捕获阶段执行
false- false- 默认。事件句柄在冒泡阶段执行

8.宏任务和微任务 举例

Macrotask(宏任务):script(整体代码)、setTimeout、setInterval、I/O、UI交互事件、postMessage、MessageChannel
Microtask(微任务):Promise.then、Object.observe

9.状态码

按第一个数字分类:
1表示信息,
2表示成功,
3表示重定向,
4表示客户端错误,
5表示服务器错误

200 
OK	
请求成功。一般用于get和post请求

301 
Moved Permanently	永久移动。请求的信息已经被移动到新的URI,会返回新的URI
302 
Found	临时移动。资源只是临时被移动,客户端继续使用原URI

304 
Not Modified	未修改。所请求的资源未修改,服务器返回此状态码,不会返回任何资源

400 
Bad Request	客户端请求的语法错误,服务器无法理解(产生原因:前端提交的数据在后台找不到与之相对应的实体)

401 
Unauthorized	当前请求需要用户验证

403 
Forbidden	服务器已经收到请求,但拒绝执行

404 
Not Found	服务器无法根据用户的请求找到资源

500 
Internal Server Error	服务器内部错误,无法完成请求

10.http2

基于HTTPS天然具有安全性
二进制分帧层:将所有传输信息分割成更小的信息或帧,并进行二进制编码(http2.0性能增强核心)
允许多路复用:基于二进制分帧层,在共享TCP连接的基础上,同时发送请求和响应。HTTP消息被分解为独立的帧,而不破坏消息本身的语义,交错发送出去,最后在另一端根据流ID和首部将他们重新组合起来

设置请求优先级:
我们知道浏览器中有些数据是非常重要的,但是在发送请求时,重要的请求可能会晚于那些不怎么重要的请求,如果服务器按照请求的顺序来回复数据,那么这个重要的数据就有可能推迟很久才能送达浏览器,这对于用户体验来说是非常不友好的。

服务器推送:
服务端根据客户端的请求,提前返回多个响应,推送额外的资源给客户端,支持缓存(遵循同源策略;基于客户端的请求响应来确定的

头部压缩:
无论是 HTTP/1.1 还是 HTTP/2,它们都有请求头和响应头,这是浏览器和服务器的通信语言。
HTTP/2 对请求头和响应头进行了压缩,你可能觉得一个 HTTP 的头文件没有多大,压不压缩可能关系不大,但你这样想一下,在浏览器发送请求的时候,基本上都是发送 HTTP 请求头,很少有请求体的发送,通常情况下页面也有 100 个左右的资源,如果将这 100 个请求头的数据压缩为原来的 20%,那么传输效率肯定能得到大幅提升。

11.XSS攻击

跨站脚本攻击

XSS 攻击是指黑客往 HTML 文件中或者 DOM 中注入恶意脚本,从而在用户浏览页面时利用注入的恶意脚本对用户实施攻击的一种手段。

1.可以窃取 Cookie 信息。恶意 JavaScript 可以通过“document.cookie”获取 Cookie 信息,然后通过 XMLHttpRequest 或者 Fetch 加上 CORS 功能将数据发送给恶意服务器;恶意服务器拿到用户的 Cookie 信息之后,就可以在其他电脑上模拟用户的登录,然后进行转账等操作。

2.可以监听用户行为。恶意 JavaScript 可以使用“addEventListener”接口来监听键盘事件,比如可以获取用户输入的信用卡等信息,将其发送到恶意服务器。黑客掌握了这些信息之后,又可以做很多违法的事情。

3.可以通过修改 DOM 伪造假的登录窗口,用来欺骗用户输入用户名和密码等信息。

4.还可以在页面内生成浮窗广告,这些广告会严重地影响用户体验。

类型:
1.存储型 XSS 攻击
(1)首先黑客利用站点漏洞将一段恶意 JavaScript 代码提交到网站的数据库中;
(2)然后用户向网站请求包含了恶意 JavaScript 脚本的页面;
(3)当用户浏览该页面的时候,恶意脚本就会将用户的 Cookie 信息等数据上传到服务器。

2.反射型 XSS 攻击
在一个反射型 XSS 攻击过程中,恶意 JavaScript 脚本属于用户发送给网站请求中的一部分,
随后网站又把恶意 JavaScript 脚本返回给用户。
当恶意 JavaScript 脚本在用户页面中被执行时,黑客就可以利用该脚本做一些恶意操作。

防御XSS攻击的策略

1.服务器对输入脚本进行过滤或转码

2.充分利用 CSP
(1)限制加载其他域下的资源文件,这样即使黑客插入了一个 JavaScript 文件,这个 JavaScript 文件也是无法被加载的;
(2)禁止向第三方域提交数据,这样用户数据也不会外泄;
(3)禁止执行内联脚本和未授权的脚本;
(4)还提供了上报机制,这样可以帮助我们尽快发现有哪些 XSS 攻击,以便尽快修

3.使用 HttpOnly 属性
顾名思义,使用 HttpOnly 标记的 Cookie 只能使用在 HTTP 请求过程中,所以无法通过 JavaScript 来读取这段 Cookie。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值