标签:
浏览器解析页面页面解析全过程输入url到展示页面浏览器加载页面 |
分类: 前端性能 |
系统缓存 – 如果在浏览器缓存里没有找到需要的记录,浏览器会做一个系统调用(windows里是gethostbyname)。这样便可获得系统缓存中的记录。
路由器缓存 – 接着,前面的查询请求发向路由器,它一般会有自己的DNS缓存。
ISP DNS 缓存 – 接下来要check的就是ISP缓存DNS的服务器。在这一般都能找到相应的缓存记录。
递归搜索 – 你的ISP的DNS服务器从跟域名服务器开始进行递归搜索,从.com顶级域名服务器到Facebook的域名服务器。一般DNS服务器的缓存中会有.com域名服务器中的域名,所以到顶级服务器的匹配过程不是那么必要了。
|
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
|
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连接就这样关闭了!
- class Parent {
- // 静态变量
- public static String p_StaticField = "父类--静态变量";
- // 变量(其实这用对象更好能体同这一点,如专门写一个类的实例)
- //如果这个变量放在初始化块的后面,是会报错的,因为你根本没有被初始化
- public String p_Field = "父类--变量";
- // 静态初始化块
- static {
- System.out.println(p_StaticField);
- System.out.println("父类--静态初始化块");
- }
- // 初始化块
- {
- System.out.println(p_Field);
- System.out.println("父类--初始化块");
- }
- // 构造器
- public Parent() {
- System.out.println("父类--构造器");
- }
- }
- public class SubClass extends Parent {
- // 静态变量
- public static String s_StaticField = "子类--静态变量";
- // 变量
- public String s_Field = "子类--变量";
- // 静态初始化块
- static {
- System.out.println(s_StaticField);
- System.out.println("子类--静态初始化块");
- }
- // 初始化块
- {
- System.out.println(s_Field);
- System.out.println("子类--初始化块");
- }
- // 构造器
- public SubClass() {
- //super();
- System.out.println("子类--构造器");
- }
- // 程序入口
- public static void main(String[] args) {
- System.out.println("*************in main***************");
- new SubClass();
- System.out.println("*************second subClass***************");
- new SubClass();
- }
- }
输出结果
父类--静态变量
父类--静态初始化块
子类--静态变量
子类--静态初始化块
*************in main***************
父类--变量
父类--初始化块
父类--构造器
子类--变量
子类--初始化块
子类--构造器
*************second subClass***************
父类--变量
父类--初始化块
父类--构造器
子类--变量
子类--初始化块
子类--构造器
java之连续子数组的最大和
题目:输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组,求所有子数组的和的最大值。要求时间复杂度为O(n).
这个解法可以用动态规划来解。
其代码为:
- package LinkList;
- public class FindMaxSumofSubArrayMain {
- public static int maxSubSum(int[] a) {
- int maxSum = 0, thisSum = 0;
- if (a == null || a.length <= 0)
- return 0;
- for (int i = 0; i < a.length; i++) {
- thisSum += a[i];
- if (thisSum > maxSum)
- maxSum = thisSum;
- else if (thisSum < 0)
- thisSum = 0;
- }
- return maxSum;
- }
- public static void main(String[] args) {
- int a[] = { 1, -2, 3, 10, -4, 7, 2, -5 };
- System.out.println(maxSubSum(a));
- }
- }