10/30 fb面经

来源:互联网 发布:软件研究所 导师 编辑:程序博客网 时间:2024/06/07 09:45

网页解析的全过程--输入url到展示页面

 (2016-06-16 09:50:15)
转载
标签: 

浏览器解析页面

 

页面解析全过程

 

输入url到展示页面

 

浏览器加载页面

分类: 前端性能
1.用户输入网址,浏览器发起DNS查询请求
用户访问网页,DNS服务器(域名解析系统)会根据用户提供的域名查找对应的IP地址。
域名解析服务器是基于UDP协议实现的一个应用程序,通常通过监听53端口来获取客户端的域名解析请求。DNS查找过程如下:
浏览器缓存 – 浏览器会缓存DNS记录一段时间。 有趣的是,操作系统没有告诉浏览器储存DNS记录的时间,这样不同浏览器会储存个自固定的一个时间(2分钟到30分钟不等)。

系统缓存 – 如果在浏览器缓存里没有找到需要的记录,浏览器会做一个系统调用(windows里是gethostbyname)。这样便可获得系统缓存中的记录。

路由器缓存 – 接着,前面的查询请求发向路由器,它一般会有自己的DNS缓存。

ISP DNS 缓存 – 接下来要check的就是ISP缓存DNS的服务器。在这一般都能找到相应的缓存记录。

递归搜索 – 你的ISP的DNS服务器从跟域名服务器开始进行递归搜索,从.com顶级域名服务器到Facebook的域名服务器。一般DNS服务器的缓存中会有.com域名服务器中的域名,所以到顶级服务器的匹配过程不是那么必要了。

2、建立TCP连接
浏览器通过DNS获取到web服务器真的IP地址后,便向web服务器发起tcp连接请求,通过TCP三次握手建立好连接后,浏览器便可以将HTTP请求数据通过发送给服务器了。

3、浏览器向 web 服务器发送一个 HTTP 请求
HTTP请求是一个基于TCP协议之上的应用层协议——超文本传输协议。一个http事务由一条(从客户端发往服务器的)请求命令和一个(从服务器发回客户端的)响应结果组成。
1
2
3
4
5
6
7
GET http://www.cricode.com/ HTTP/1.1
Host: www.cricode.com
Connection: keep-alive
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8

4、发送响应数据给客户端

Web服务器通常通过监听80端口,来获取客户端的HTTP请求。与客户端建立好TCP连接后,web服务器开始接受客户端发来的数据,并通过HTTP解码,从接受到的网络数据中解析出请求的url信息以前其他诸如Accept-Encoding、Accept-Language等信息。Web服务器根据HTTP请求头的信息,得到响应数据返回给客户端。一个典型的HTTP响应头数据报如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
HTTP/1.1 200 OK
Date: Fri, 24 Oct 2014 13:55:18 GMT
Server: Apache
X-Powered-By: PHP/5.4.32
Keep-Alive: timeout=5, max=10000
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
a0f6
<</span>!DOCTYPE HTML>
<</span>html>
<</span>head>
<</span>meta charset="UTF-8">
<</span>meta http-equiv="X-UA-Compatible" content="IE=10,IE=9,IE=8">
<</span>meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
<</span>title><</span>/title>
<</span>body class="home"><</span>/body>
<</span>/html>

至此,一个HTTP通信过程完成。web服务器会根据HTTP请求头中的Connection字段值决定是否关闭TCP链接通道,当Connection字段值为keep-alive时,web服务器不会立即关闭此连接。(这一步一开始也许还会有重定向及浏览器跟踪重定向地址等)。

5、浏览器解析http response

(1)html文档解析(DOM Tree)

在浏览器没有完整接受全部HTML文档时,它就已经开始显示这个页面了。生成解析树即dom树,是由dom元素及属性节点组成,树的根是document对象。

(2)浏览器发送获取嵌入在HTML中的对象

加载过程中遇到外部css文件,浏览器另外发出一个请求,来获取css文件。遇到图片资源,浏览器也会另外发出一个请求,来获取图片资源。这是异步请求,并不会影响html文档进行加载。

但是当文档加载过程中遇到js文件,html文档会挂起渲染(加载解析渲染同步)的线程,不仅要等待文档中js文件加载完毕,还要等待解析执行完毕,才可以恢复html文档的渲染线程。

(3)css解析(parser Render Tree

浏览器下载css文件,将css文件解析为样式表对象,并用来渲染dom tree。该对象包含css规则,该规则包含选择器和声明对象。

css元素遍历的顺序,是从树的低端向上遍历。

(4)js解析

浏览器UI线程:单线程,大多数浏览器(比如chrome)让一个单线程共用于执行javascrip和更新用户界面。

js阻塞页面:浏览器里的http请求被阻塞一般都是由js所引起,具体原因是js文件在下载完毕之后会立即执行,而js执行时候会阻塞浏览器的其他行为,有一段时间是没有网络请求被处理的,这段时间过后http请求才会接着执行,这段空闲时间就是所谓的http请求被阻塞。

js阻塞原因:之所以会阻塞UI线程的执行,是因为js能控制UI的展示,而页面加载的规则是要顺序执行,所以在碰到js代码时候UI线程会首先执行它

-----------------------------------------------------------------------------------------------------------------


首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资源。Client端接收到ACK报文后也向Server段发生ACK报文,并分配资源,这样TCP连接就建立了。


【注意】中断连接端可以是Client端,也可以是Server端。

假设Client端发起中断连接请求,也就是发送FIN报文。Server端接到FIN报文后,意思是说"我Client端没有数据要发给你了",但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以你先发送ACK,"告诉Client端,你的请求我收到了,但是我还没准备好,请继续你等我的消息"。这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。当Server端确定数据已发送完成,则向Client端发送FIN报文,"告诉Client端,好了,我这边数据发完了,准备好关闭连接了"。Client端收到FIN报文后,"就知道可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。“,Server端收到ACK后,"就知道可以断开连接了"。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了。Ok,TCP连接就这样关闭了!


 

浅谈Java中父类与子类的加载顺序详解

 1357人阅读 评论(1) 收藏 举报
 分类:
[html] view plain copy
  1. class Parent {  
  2.     // 静态变量  
  3.     public static String p_StaticField = "父类--静态变量";  
  4.     // 变量(其实这用对象更好能体同这一点,如专门写一个类的实例)  
  5.     
  6.     //如果这个变量放在初始化块的后面,是会报错的,因为你根本没有被初始化  
  7.     public String p_Field = "父类--变量";  
  8.     // 静态初始化块  
  9.     static {  
  10.         System.out.println(p_StaticField);  
  11.         System.out.println("父类--静态初始化块");  
  12.     }  
  13.     // 初始化块  
  14.     {  
  15.         System.out.println(p_Field);  
  16.         System.out.println("父类--初始化块");  
  17.     }  
  18.     // 构造器  
  19.     public Parent() {  
  20.         System.out.println("父类--构造器");  
  21.     }  
  22. }  
  23. public class SubClass extends Parent {  
  24.     // 静态变量  
  25.     public static String s_StaticField = "子类--静态变量";  
  26.     // 变量  
  27.     public String s_Field = "子类--变量";  
  28.     // 静态初始化块  
  29.     static {  
  30.         System.out.println(s_StaticField);  
  31.         System.out.println("子类--静态初始化块");  
  32.     }  
  33.     // 初始化块  
  34.     {  
  35.         System.out.println(s_Field);  
  36.         System.out.println("子类--初始化块");  
  37.     }  
  38.     // 构造器  
  39.     public SubClass() {  
  40.         //super();  
  41.         System.out.println("子类--构造器");  
  42.     }  
  43.     // 程序入口  
  44.     public static void main(String[] args) {  
  45.         System.out.println("*************in main***************");  
  46.         new SubClass();  
  47.         System.out.println("*************second subClass***************");  
  48.         new SubClass();  
  49.     }  
  50. }  

输出结果
父类--静态变量
父类--静态初始化块
子类--静态变量
子类--静态初始化块
*************in main***************
父类--变量
父类--初始化块
父类--构造器
子类--变量
子类--初始化块
子类--构造器
*************second subClass***************
父类--变量
父类--初始化块
父类--构造器
子类--变量
子类--初始化块
子类--构造器

java之连续子数组的最大和

原创 2015年07月26日 21:25:36

题目:输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组,求所有子数组的和的最大值。要求时间复杂度为O(n).

这个解法可以用动态规划来解。

其代码为:

[java] view plain copy
  1. package LinkList;  
  2.   
  3. public class FindMaxSumofSubArrayMain {  
  4.   
  5.     public static int maxSubSum(int[] a) {  
  6.         int maxSum = 0, thisSum = 0;  
  7.         if (a == null || a.length <= 0)  
  8.             return 0;  
  9.         for (int i = 0; i < a.length; i++) {  
  10.             thisSum += a[i];  
  11.             if (thisSum > maxSum)  
  12.                 maxSum = thisSum;  
  13.             else if (thisSum < 0)  
  14.                 thisSum = 0;  
  15.         }  
  16.         return maxSum;  
  17.   
  18.     }  
  19.   
  20.     public static void main(String[] args) {  
  21.         int a[] = { 1, -2310, -472, -5 };  
  22.         System.out.println(maxSubSum(a));  
  23.     }  
  24.   
  25. }  
算法:字符串去掉a,bc






原创粉丝点击