问题一:对String=“abcd”,在不同的JVM里,他的hashcode一样么?
答案:String的hashCode算法只与字符串的内容有关,同时Integer、Double等对象的hashCode值也只与其value有关。
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
结论:OpenJDK8 默认hashCode的计算方法是通过和当前线程有关的一个随机数+三个确定值,运用Marsaglia's xorshift scheme随机数算法得到的一个随机数。和对象内存地址无关。
说hashcode就是对象在内存中的bulabula的,都是瞎话,说话得负责人哦!!!!
问题一:http1.0和1.1的区别,etag讲讲
你前端搞的少,http缓存还真就是屁都想不起来
这块是个坑,因为总想挖,总想填,总挖不完,总填不完,今晚一次性填完吧。
1.0和1.1区别
就集中5个点吧
(1)长连接和请求流水线,在一个tcp上可以传递多个http请求,但依然没有解决队头阻塞
(2)http缓存:
http缓存指的是: 当客户端向服务器请求资源时,会先抵达浏览器缓存,如果浏览器有“要请求资源”的副本,就可以直接从浏览器缓存中提取而不是从原始服务器中提取这个资源。
常见的http缓存只能缓存get请求响应的资源,对于其他类型的响应则无能为力,所以后续说的请求缓存都是指GET请求。
http缓存都是从第二次请求开始的。第一次请求资源时,服务器返回资源,并在respone header头中回传资源的缓存参数;第二次请求时,浏览器判断这些请求参数,命中强缓存就直接200,否则就把请求参数加到request header头中传给服务器,看是否命中协商缓存,命中则返回304,否则服务器会返回新的资源。
根据是否需要重新向服务器发起请求来分类,可分为(强制缓存,协商缓存) 根据是否可以被单个或者多个用户使用来分类,可分为(私有缓存,共享缓存) 强制缓存如果生效,不需要再和服务器发生交互,而协商缓存不管是否生效,都需要与服务端发生交互。下面是强制缓存和协商缓存的一些对比:
强制缓存在缓存数据未失效的情况下(即Cache-Control的max-age没有过期或者Expires的缓存时间没有过期),那么就会直接使用浏览器的缓存数据,不会再向服务器发送任何请求。强制缓存生效时,http状态码为200。这种方式页面的加载速度是最快的,性能也是很好的,但是在这期间,如果服务器端的资源修改了,页面上是拿不到的,因为它不会再向服务器发请求了。这种情况就是我们在开发种经常遇到的,比如你修改了页面上的某个样式,在页面上刷新了但没有生效,因为走的是强缓存,所以Ctrl + F5一顿操作之后就好了。 跟强制缓存相关的header头属性有(Pragma/Cache-Control/Expires)
当浏览器第一次向服务器发送请求时,会在响应头返回协商缓存的头属性:ETag和Last-Modified,其中ETag返回的是一个hash值,Last-Modified返回的是GMT格式的时间,标识该资源的最新修改时间;然后浏览器发送第二次请求的时候,会在请求头中带上与ETag对应的If-Not-Match,与Last-Modified对应的If-Modified-Since;服务器在接收到这两个参数后会做比较,会优先验证ETag,一致的情况下,才会继续比对Last-Modified;如果返回的是304状态码,则说明请求的资源没有修改,浏览器可以直接在缓存中读取数据,否则,服务器直接返回数据。
ETag/If-Not-Match是在HTTP/1.1出现的,主要是解决以下问题:
※ Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间
※ 如果某些文件被修改了,但是内容并没有任何变化,而Last-Modified却改变了,导致文件没法使用缓存
※ 有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形
※ ETag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识,ETag可以保证每一个资源是唯一的,资源变化都会导致ETag变化,ETag值的变更则说明资源状态已经被修改,ETag能够更加准确地控制缓存。Last-Modified是可以与ETag一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。
(3)带宽优化及网络连接的使用,HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。
(4)状态码的变更,在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。303,307我们之前提过
(5)Host头处理,在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。
1.1和2.0
(1)多路复用技术 HTTP2.0使用了多路复用的技术,做到同一个连接并发处理多个请求,而且并发请求的数量比HTTP1.1大了好几个数量级。HTTP1.1也可以多建立几个TCP连接,来支持处理更多并发的请求,但是创建TCP连接本身也是有开销的。
(2)头部数据压缩 在HTTP1.1中,HTTP请求和响应都是由状态行、请求/响应头部、消息主体三部分组成。一般而言,消息主体都会经过gzip压缩,或者本身传输的就是压缩过后的二进制文件,但状态行和头部却没有经过任何压缩,直接以纯文本传输。随着Web功能越来越复杂,每个页面产生的请求数也越来越多,导致消耗在头部的流量越来越多,尤其是每次都要传输UserAgent、Cookie这类不会频繁变动的内容,完全是一种浪费。
HTTP1.1不支持header数据的压缩,HTTP2.0使用HPACK算法对header的数据进行压缩,这样数据体积小了,在网络上传输就会更快。
(3)服务端推送:类websocket
(4)二进制分帧:HTTP/2在 应用层(HTTP/2)和传输层(TCP or UDP)之间增加一个二进制分帧层。在不改动 HTTP/1.x 的语义、方法、状态码、URI 以及首部字段的情况下, 解决了HTTP1.1 的性能限制,改进传输性能,实现低延迟和高吞吐量。在二进制分帧层中, HTTP/2 会将所有传输的信息分割为更小的消息和帧(frame),并对它们采用二进制格式的编码 ,其中 HTTP1.x 的首部信息会被封装到 HEADER frame,而相应的 Request Body 则封装到 DATA frame 里面。
巨人的肩膀