阿里面试官的 "说一下从url输入到返回请求的过程" 问的难度就是不一样!

点击上方 好好学java ,选择 星标 公众号

重磅资讯,干货,第一时间送达
今日推荐:推荐19个github超牛逼项目!个人原创100W +访问量博客:点击前往,查看更多

来源:juejin.cn/post/6928677404332425223

前言

年前准备换工作,总结了一波面试最频繁的面试问题跟大家交流。此文章是关于浏览器的常见问题,大概面试10家遇到6家提问类似问题(主要是大厂和中厂)。(面试的部分内容已经忘了,为了串联成一个完整的故事,增加可读性,20%的内容为虚构),目前入职滴滴出行成都团队。

问题: 从浏览器地址栏输入url到请求返回发生了什么

你一看这种烂掉牙的问题,小case,但996面试大佬由此延展的问题已经远远超越了这个问题本身了,不信你就接着看。

我回答了首先会进行 url 解析,根据 dns 系统进行 ip 查找。

话音刚落,此时一位喜欢修福报的公司的大佬打断了我,说url为啥要解析,dns查询规则是什么?我一听就心里想,不按套路出牌啊,网上一般都没问这两个问题,心里再一想,俗话说,万事开头难,扛过这一波,答出来,就是阳光明媚,万物骚动的春天!

先说为什么url要解析(也就是编码)

我回答大概内容是:因为网络标准规定了URL只能是字母和数字,还有一些其它特殊符号(-_.~ ! * ' ( ) ; : @ & = + $ , / ? # [ ],特殊符号是我下来查的资料,实在背不住这么多,比较常见的就是不包括百分号和双引号),而且如果不转义会出现歧义,比如http:www.baidu.com?key=value,假如我的key本身就包括等于=符号,比如ke=y=value,就会出现歧义,你不知道=到底是连接key和value的符号,还是说本身key里面就有=。

大佬接着毒打我说,那url编码的规则是什么呢,我说utf-8

大佬接着穷追不舍,为啥是utf-8呢,所有浏览器都是这样吗?中文的话用gb2312编码吗,还有就是万一浏览器不是你说的这样统一用utf-8,你怎么保证都是utf-8的编码?

我支支吾吾的说,我了解的大概是这样,不太清楚, 应该和html本身的编码格式有关,然后怎么保证utf-8的编码,我觉得可以用encodeURIComponent

大佬说encodeURIComponent比encodeURI有什么区别?

区别就是encodeURIComponent编码范围更广,适合给参数编码,encodeURI适合给URL本身(locaion.origin)编码,当然项目里一般都是用qs库去处理

然后说说dns解析流程,并且html如何做dns优化

首先dns这个属于很久以前在计算机网络谢希仁版看到过了,有一些细节忘了,但是大致流程是记得的。比如说查询一个网址为:www.baidu.com

1、器中输入www.baidu.com 域名,操作系统会先查hosts件是否有记录,有的话就会把相对应映射的IP返回。

2、hosts文件没有就去查本地dns解析器有没有缓存。(这个我没答上来)

3、然后就去找我们计算机上配置的dns服务器上有或者有缓存,就返回

4、还没有的话就去找根DNS服务器(全球13台,固定ip地址),然后判断.com域名是哪个服务器管理,如果无法解析,就查找.baidu.com服务器是否能解析,直到查到www.baidu.com的IP地址

注:后面查资料才发现dns查询有两种模式,一种是转发模式,一种是非转发模式,我上面说的4是非转发模式。

前端的dns优化,可以在html页面头部写入dns缓存地址,比如

<meta http-equiv="x-dns-prefetch-control" content="on" />
<link rel="dns-prefetch" href="http://bdimg.share.baidu.com" />

终于抗过了第一轮的猛问,接着我继续说从浏览器地址栏输入url到请求返回发生了什么

查找到IP之后,就是http协议的三次握手(以及后面会涉及到四次分手)

我刚恢复节奏,准备侃侃而谈,修福报的大佬再次打断了我,说三次握手,为啥两次不行,顺便说一下3次握手发生了什么。

我去,大意了,没有闪,这是不是说我每说一句都要夹杂着各种问题,太难了啊!!!

没有办法,继续回答大佬,我说我先回答三次握手发生的事情吧,简答来说:

  • 第一次握手:主机A发送位码为SYN=1的TCP包给服务器,并且随机产生一个作为确认号(这是tcp包的一部分),主机B收到SYN码后直到A要求建立连接;

  • 第二次握手:主机B收到请求后,向A发送确认号(主机A的seq+1),syn=1,seq = 随机数 的TCP包;

  • 主机A收到后检查确认号是否正确,即第一次A发送的确认号是否+1了,以及位码ack是否为1,若正确,主机A会再发送确认号(主机B的seq+1),ack=1,主机B收到后确认seq值与ack=1则连接建立成功。

接着补上小问题为什么两次握手不行,因为第二次握手,主机B还不能确认主机A已经收到确认请求,也是说B认为建立好连接,开始发数据了,结果发出去的包一直A都没收到,那攻击B就很容易了,我专门发包不接收,服务器很容易就挂了。(搜索公众号Java知音,回复“2021”,送你一份Java面试题宝典)

接着,大佬说出个加分题,我看你不是科班出身,能答多少是多少。问题是,从网卡把数据包传输出去到服务器发生了什么,提示我OSI参考模型

我一听,好嘛,这不是计算机网络的知识吗,幸亏之前看过书,但也是好久以前看过了,只能凭借自己的理解解答了。

  • 我说,先从局域网把数据发送到公司的交换机(如果交换机没有缓存本地mac地址和IP地址的映射,此时会通过ARP协议来获得),交换机的好处是可以隔离冲突域(因为以太网用的是CSMA/CD协议,这个协议规定网线上同一时刻只能有一台机器发送数据),这样就可以不仅仅同一时刻只有一台机器发送网络包了

  • 然后交换机再将数据发送到路由器,路由器相当于公司网关(我们公司小),路由器具有转发和分组数据包的功能(路由器通过选定的路由协议会构造出路由表,同时不定期的跟相邻路由器交换路由信息),然后这算是经过了物理层,数据链路层(以太网),开始到网络层进行数据转发了

  • 然后路由器转发IP数据报,一般公司的IP地址都会经过NAT转换,让内网的ip也能够访问外网,我们公司我注意了一下是192.168打头的内网ip地址。通过路由器的分组传输,所有数据到达服务器。

  • 然后服务器的上层协议传输层协议开始发挥作用,根据tcp包里的端口号,让服务器特定的服务来处理到来的数据包,并且tcp是面向字节流的(tcp有四大特性,可靠传输、流量控制、拥塞控制、连接管理),所以我们node的request对象,它的监听事件data事件为什么要用字符串一起拼接起来呢(buffer),就是因为tcp本身就是字节流,request对象使用的data(http层面)是tcp传来的数据块。

  • 最后数据由传输层转交给应用层,也就是http服务(或者https),后端经过一系列逻辑处理,返回给前端数据。

答完这里,我说大佬我只知道大概的流程,具体细节我不是很清楚,但自己后面会补上。。。

大佬让我继续,我就接着3次握手之后接着说道,建立完链接,就该请求html文件了,如果html文件在缓存里面浏览器直接返回,如果没有,就去后台拿

刚说到缓存,立马就有一种不详的预感,果不其然大佬先让把缓存解释一下。缓存这种问烂的问题,本以为能轻松应对,结果还是被问了个满头包。。。。

我说的大概意思是:

  • 浏览器首次加载资源成功时,服务器返回200,此时浏览器不仅将资源下载下来,而且把response的header(里面的date属性非常重要,用来计算第二次相同资源时当前时间和date的时间差)一并缓存;

  • 下一次加载资源时,首先要经过强缓存的处理,cache-control的优先级最高,比如cache-control:no-cache,就直接进入到协商缓存的步骤了,如果cache-control:max-age=xxx,就会先比较当前时间和上一次返回200时的时间差,如果没有超过max-age,命中强缓存,不发请求直接从本地缓存读取该文件(这里需要注意,如果没有cache-control,会取expires的值,来对比是否过期),过期的话会进入下一个阶段,协商缓存

  • 协商缓存阶段,则向服务器发送header带有If-None-Match和If-Modified-Since的请求,服务器会比较Etag,如果相同,命中协商缓存,返回304;如果不一致则有改动,直接返回新的资源文件带上新的Etag值并返回200;

  • 协商缓存第二个重要的字段是,If-Modified-Since,如果客户端发送的If-Modified-Since的值跟服务器端获取的文件最近改动的时间,一致则命中协商缓存,返回304;不一致则返回新的last-modified和文件并返回200;

果不其然,大佬问了一些缓存不常问的,首先就是问我知道什么是from disk cache和from memory cache吗,什么时候会触发?

我说强缓存会触发,这两种,具体什么行为不知道,大概内容如下:

  1. 先查找内存,如果内存中存在,从内存中加载;

  2. 如果内存中未查找到,选择硬盘获取,如果硬盘中有,从硬盘中加载;

  3. 如果硬盘中未查找到,那就进行网络请求;

  4. 加载到的资源缓存到硬盘和内存;

接着大佬又问知道什么是启发式缓存吗,在什么条件下触发?

这个问题给我的感觉就两个字,懵逼!然后如实回答不知道。(查了下资料大概如下)

启发式缓存:

如果响应中未显示Expires,Cache-Control:max-ageCache-Control:s-maxage,并且响应中不包含其他有关缓存的限制,缓存可以使用启发式方法计算新鲜度寿命。通常会根据响应头中的2个时间字段 Date 减去 Last-Modified 值的 10% 作为缓存时间。

// Date 减去 Last-Modified 值的 10% 作为缓存时间。
// Date:创建报文的日期时间, Last-Modified 服务器声明文档最后被修改时间
  response_is_fresh =  max(0,(Date -  Last-Modified)) % 10

接着回答,我说返回html之后,会解析html,这部分知识我提前准备过,但是答的不是很详细,大概意思就是cssom + domTree = html,然后布局和绘制

  • 构建DOM树(DOM tree):从上到下解析HTML文档生成DOM节点树(DOM tree),也叫内容树(content tree);

  • 构建CSSOM(CSS Object Model)树:加载解析样式生成CSSOM树;

  • 执行JavaScript:加载并执行JavaScript代码(包括内联代码或外联JavaScript文件);

  • 构建渲染树(render tree):根据DOM树和CSSOM树,生成渲染树(render tree);

  • 渲染树:按顺序展示在屏幕上的一系列矩形,这些矩形带有字体,颜色和尺寸等视觉属性。

  • 布局(layout):根据渲染树将节点树的每一个节点布局在屏幕上的正确位置;

  • 绘制(painting):遍历渲染树绘制所有节点,为每一个节点适用对应的样式,这一过程是通过UI后端模块完成;

接着面试官问我一些页面渲染层的一些优化手段,大概如下:

页面渲染优化

  • HTML文档结构层次尽量少,最好不深于六层;

  • 脚本尽量后放,放在前即可;

  • 少量首屏样式内联放在标签内;

  • 样式结构层次尽量简单;

  • 在脚本中尽量减少DOM操作,尽量缓存访问DOM的样式信息,避免过度触发回流;

  • 减少通过JavaScript代码修改元素样式,尽量使用修改class名方式操作样式或动画;

  • 动画尽量使用在绝对定位或固定定位的元素上;

  • 隐藏在屏幕外,或在页面滚动时,尽量停止动画;

  • 尽量缓存DOM查找,查找器尽量简洁;

  • 涉及多域名的网站,可以开启域名预解析

最后面试官问我,如何诊断页面渲染时各个性能指标,我大概说了,通过chrome浏览器的工具,比如看网络请求情况的network,还有看页面渲染情况的perfermance,面试下来自己查了一些资料,比如知乎的这篇文章,我觉得写的很详细,以下是摘抄部分,我打算以后有机会自己总结一篇。

https://zhuanlan.zhihu.com/p/105561186

推荐文章
更多项目源码
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
<p style="color:#666666;"> <span style="font-size:14px;">本门课程重实战,将基础知识拆解项目里,让你在项目情境里学知识。</span> </p> <p style="color:#666666;"> <span style="font-size:14px;">这样学习方式能让你保持兴趣、充满动力,时刻知道学东西能用在哪、能怎么用。</span> </p> <p style="color:#666666;"> <span style="font-size:14px;">平时明白知识点,放在项目里去理解就恍然大悟了。</span> </p> <p style="color:#666666;"> <span></span> </p> <p style="color:#666666;"> <span style="font-size:14px;"> </span> </p> <p style="color:#666666;"> <span style="color:#FF0000;font-size:14px;"><strong>一、融汇贯通</strong></span> </p> <p style="color:#666666;"> <span style="font-size:14px;">本视频采用了前后端分离开发模式,前端使用Vue.js+Element UI实现了Web页面呈现,后端使用Python Django框架实现了数据访接口,前端通过Axios访后端接口获得数据。在学习完本章节后,真正理解前后端各自承担工作。</span> </p> <p style="color:#666666;"> <span style="font-size:14px;"> </span> </p> <p style="color:#666666;"> <span style="color:#FF0000;font-size:14px;"><strong>二、贴近实战</strong></span> </p> <p style="color:#666666;"> <span style="font-size:14px;">本系列课程为练手项目实战:学生管理系统v4.0开发,项目包含了如下几个内容:项目总体介绍、基本功能演示、Vuejs初始化、Element UI使用、在Django中实现针对数据增删改查接口、在Vuejs中实现前端增删改查调用、实现文件上传、实现表格分页、实现导出数据Excel、实现通过Excel导入数据、实现针对表格批量化操作等等,所有功能都通过演示完成、贴近了实战</span> </p> <p style="color:#666666;"> <span style="font-size:14px;"> </span> </p> <p style="color:#666666;"> <span style="color:#FF0000;font-size:14px;"><strong>三、课程亮点</strong></span> </p> <p style="color:#666666;"> <span style="font-size:14px;">在本案例中,最大亮点在于前后端做了分离,真正理解前后端各自承担工作。前端如何和后端交互</span> </p> <p style="color:#666666;"> <span style="font-size:14px;"> </span> </p> <p style="color:#666666;"> <span style="color:#FF0000;font-size:14px;"><strong>适合人群:</strong></span> </p> <p style="color:#666666;"> <span style="font-size:14px;">1、有Python语言基础、web前端基础,想要深入学习Python Web框架朋友;</span> </p> <p style="color:#666666;"> <span style="font-size:14px;">2、有Django基础,但是想学习企业级项目实战朋友;</span> </p> <p style="color:#666666;"> <span style="font-size:14px;">3、有MySQL数据库基础朋友</span> </p> <p style="color:#666666;"> <span style="font-size:14px;"> </span> </p> <p style="color:#666666;"> <span style="font-size:14px;"><img alt="" src="https://img-bss.csdnimg.cn/202009070752197496.png" /><br /> </span> </p> <p style="color:#666666;"> <span style="font-size:14px;"><br /> </span> </p>
<div style="color:rgba(0,0,0,.75);"> <span style="color:#4d4d4d;"> </span> <div style="color:rgba(0,0,0,.75);"> <span style="color:#4d4d4d;"> </span> <div style="color:rgba(0,0,0,.75);"> <div style="color:rgba(0,0,0,.75);"> <span style="color:#4d4d4d;">当前课程中商城项目实战源码是我发布在 GitHub 上开源项目 newbee-mall (新蜂商城),目前已有 6300 多个 star,</span><span style="color:#4d4d4d;">本课程是一个 Spring Boot 技术栈实战类课程,课程共分为 3 大部分,前面两个部分为基础环境准备和相关概念介绍,第三个部分是 Spring Boot 商城项目功能讲解,让大家实际操作并实践上手一个大型线上商城项目,并学习一定开发经验以及其中开发技巧。<br /> 商城项目所涉及功能结构图整理如下:<br /> </span> </div> <div style="color:rgba(0,0,0,.75);">   </div> <div style="color:rgba(0,0,0,.75);"> <p style="color:#4d4d4d;"> <img alt="modules" src="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9uZXdiZWUtbWFsbC5vc3MtY24tYmVpamluZy5hbGl5dW5jcy5jb20vcG9zdGVyL3N0b3JlL25ld2JlZS1tYWxsLXMucG5n?x-oss-process=image/format,png" /> </p> </div> <p style="color:rgba(0,0,0,.75);"> <strong><span style="color:#e53333;">课程特色</span></strong> </p> <p style="color:rgba(0,0,0,.75);">   </p> <div style="color:rgba(0,0,0,.75);">   </div> <div style="color:rgba(0,0,0,.75);"> <ul> <li> 对新手开发者十分友好,无需复杂操作步骤,仅需 2 秒就可以启动这个完整商城项目 </li> <li> 最终实战项目是一个企业级别 Spring Boot 大型项目,对于各个阶段 Java 开发者都是极佳选择 </li> <li> 实践项目页面美观且实用,交互效果完美 </li> <li> 教程详细开发教程详细完整、文档资源齐全 </li> <li> 代码+讲解+演示网站全方位保证,向 Hello World 教程拜拜 </li> <li> 技术栈新颖且知识点丰富,学习后可以提升大家对于知识理解和掌握,可以进一步提升你市场竞争力 </li> </ul> </div> <p style="color:rgba(0,0,0,.75);">   </p> <p style="color:rgba(0,0,0,.75);"> <span style="color:#e53333;">课程预览</span> </p> <p style="color:rgba(0,0,0,.75);">   </p> <div style="color:rgba(0,0,0,.75);">   </div> <div style="color:rgba(0,0,0,.75);"> <p style="color:#4d4d4d;"> 以下为商城项目页面和功能展示,分别为: </p> </div> <div style="color:rgba(0,0,0,.75);"> <ul> <li> 商城首页 1<br /> <img alt="" src="https://img-bss.csdnimg.cn/202103050347585499.gif" /> </li> <li> 商城首页 2<br /> <img alt="" src="https://img-bss.csdn.net/202005181054413605.png" /> </li> <li>   </li> <li> 购物车<br /> <img alt="cart" src="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9uZXdiZWUtbWFsbC5vc3MtY24tYmVpamluZy5hbGl5dW5jcy5jb20vcG9zdGVyL3Byb2R1Y3QvY2FydC5wbmc?x-oss-process=image/format,png" /> </li> <li> 订单结算<br /> <img alt="settle" src="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9uZXdiZWUtbWFsbC5vc3MtY24tYmVpamluZy5hbGl5dW5jcy5jb20vcG9zdGVyL3Byb2R1Y3Qvc2V0dGxlLnBuZw?x-oss-process=image/format,png" /> </li> <li> 订单列表<br /> <img alt="orders" src="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9uZXdiZWUtbWFsbC5vc3MtY24tYmVpamluZy5hbGl5dW5jcy5jb20vcG9zdGVyL3Byb2R1Y3Qvb3JkZXJzLnBuZw?x-oss-process=image/format,png" /> </li> <li> 支付页面<br /> <img alt="" src="https://img-bss.csdn.net/201909280301493716.jpg" /> </li> <li> 后台管理系统登录页<br /> <img alt="login" src="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9uZXdiZWUtbWFsbC5vc3MtY24tYmVpamluZy5hbGl5dW5jcy5jb20vcG9zdGVyL3Byb2R1Y3QvbWFuYWdlLWxvZ2luLnBuZw?x-oss-process=image/format,png" /> </li> <li> 商品管理<br /> <img alt="goods" src="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9uZXdiZWUtbWFsbC5vc3MtY24tYmVpamluZy5hbGl5dW5jcy5jb20vcG9zdGVyL3Byb2R1Y3QvbWFuYWdlLWdvb2RzLnBuZw?x-oss-process=image/format,png" /> </li> <li> 商品编辑<br /> <img alt="" src="https://img-bss.csdnimg.cn/202103050348242799.png" /> </li> </ul> </div> </div> </div> </div>
©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值