HTTP 1.0 与HTTP 1.1(应用层)
HTTP 1.0 最早在网页中的使用是在 1996 年,那个时候只是使用一些较为简单的网页和网络请求上,而 HTTP 1.1 则在 1999 年才开始广泛应用于现在的各大浏览器网络请求中,同时 HTTP 1.1 也是当前使用最为广泛的 HTTP 协议。
从下面几个维度来对比 HTTP 1.0 和 HTTP 1.1:
- 响应状态码
- 缓存处理
- 连接方式
- Host头处理
- 带宽优化
总结
- 连接方式 : HTTP 1.0 为短连接,HTTP 1.1 支持长连接。
- 状态响应码 : HTTP/1.1中新加入了大量的状态码。
- 缓存处理 : 在 HTTP1.0 中主要使用 header 里的 If-Modified-Since,Expires 来做为缓存判断的标准,HTTP1.1 则引入了更多的缓存控制策略例如 Entity tag,If-Unmodified-Since, If-Match, If-None-Match 等更多可供选择的缓存头来控制缓存策略。
- 带宽优化及网络连接的使用 :HTTP1.0 中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1 则在请求头引入了 range 头域,它允许只请求资源的某个部分,即返回码是 206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。
- Host头处理 : HTTP/1.1在请求头中加入了
Host
字段。
HTTP 和 HTTPS (应用层)
小结
- 端口号 :HTTP 默认是 80,HTTPS 默认是 443。
- URL 前缀 :HTTP 的 URL 前缀是
http://
,HTTPS 的 URL 前缀是https://
。 - 安全性和资源消耗 : HTTP 协议运行在 TCP 之上,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份。HTTPS 是运行在 SSL/TLS 之上的 HTTP 协议,SSL/TLS 运行在 TCP 之上。所有传输的内容都经过加密,加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。所以说,HTTP 安全性没有 HTTPS 高,但是 HTTPS 比 HTTP 耗费更多服务器资源。
- HTTPS 在内容传输的加密上使用的是对称加密,非对称加密只作用在证书验证阶段。
UDP
- UDP是无连接通信协议,即在数据传输时,数据的发送端和接收端不建立逻辑连接。简单来说,当一台计算机向另外一台计算机发送数据时,发送端不会确认接收端是否存在,就会发出数据,同样接收端在收到数据时,也不会向发送端反馈是否收到数据。
- 由于使用UDP协议消耗资源小,通信效率高,所以通常都会用于音频、视频和普通数据的传输例如视频会议都使用UDP协议,因为这种情况即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。
- 但是在使用UDP协议传送数据时,由于UDP的面向无连接性,不能保证数据的完整性,因此在传输重要数据时不建议使用UDP协议。
TCP
-
TCP协议是面向连接的通信协议,即在传输数据前,先在发送端和接收端建立逻辑连接,然后再传输数据,它提供了两台计算机之间可靠无差错的数据传输。
-
在TCP连接中,必须要明确客户端与服务器端,由客户端向服务端发出连接请求,每次连接的创建都需要经过“三次握手”,客户端与服务的断开时都要经过四次挥手。
JVM中为什么GC分代年龄默认15次
答: 由于对象头中分代年龄只有4bit存放数据, 15转换为2进制就是"1111", 所以最大也就15次了不能再调大只能调小
泛型擦除,官方名叫“类型擦除”。
Java 的泛型是伪泛型,这是因为 Java 在编译期间,所有的类型信息都会被擦掉。
也就是说,在运行的时候是没有泛型的。
例如这段代码,往一群猫里放条狗:
LinkedList<Cat> cats = new LinkedList<Cat>();
LinkedList list = cats; // 注意我在这里把范型去掉了,但是list和cats是同一个链表!
list.add(new Dog()); // 完全没问题!
因为Java的范型只存在于源码里,编译的时候给你静态地检查一下范型类型是否正确,而到了运行时就不检查了。上面这段代码在JRE(Java运行环境)看来和下面这段没区别:
LinkedList cats = new LinkedList(); // 注意:没有范型!
LinkedList list = cats;
list.add(new Dog());
为什么要类型擦除呢?
主要是为了向下兼容,因为JDK5之前是没有泛型的,为了让JVM保持向下兼容,就出了类型擦除这个策略。
count=count++与count=++count
int count = 0;
int num = 0;
for(int i=0;i<=100;i++) {
num=num+i;
count=count++;
}
System.out.println(num*count);
1
2
3
4
5
6
7
结果是0
int count = 0;
int num = 0;
for(int i=0;i<=100;i++) {
num=num+i;
count=++count;
}
System.out.println(num*count);
1
2
3
4
5
6
7
结果是510050
原因:
首先count++是个后自增,所以
JVM在运行的时候处理顺序是这样的:
1.执行count=count(此时count= 0),把count的值保留在临时变量区栈区;
2.再执行count++;
3.当count++运行完毕,存放在临时变量区的count=0的拷贝值又赋给了count。
所以最后结束,count还是原来的最初值。
有点类似于以下代码:
temp =count;
count=count++;
count=temp;
1
2
3
所以count一直为0;后缀加(i++),就会“先赋值(给临时变量)后自加1”。运算最终使用的,并不是变量本身,而是被赋了值的临时变量。
包装类的“==”运算在不遇到算术运算的情况下不会自动拆箱
包装类的equals()方法不处理数据转型(也就是说底层源码会有xxxinstanof xxx 只要类型不一致就不会进行比较)
存中…(img-ABpB4mYJ-1661692057298)]
包装类的“==”运算在不遇到算术运算的情况下不会自动拆箱
包装类的equals()方法不处理数据转型(也就是说底层源码会有xxxinstanof xxx 只要类型不一致就不会进行比较)