最近很久没有遇到技术瓶颈了,思考得天然少了,天天都是重复性的工做。java
阿里开始招实习,同窗问我要不要去申请阿里的实习,我说不去,我的对阿里的印象很差。程序员
记得去年阿里给我发了邮件,我很认真地回复,而后他不理我了。(最起码的尊重都没有,就算我菜你起码回复我一下啊?)算法
这种不尊重人的公司感受去了也不快乐,当程序员最重要的就是快乐,不快乐写什么代码?json
同窗很友好地分享了他的阿里电话面经验。浏览器
问的都是看功底的问题,和开发经验无关(估计写上个几年代码不写框架应该也不知道这个)。缓存
Java
中的HashMap
、transient
、volatile
、HTTP301/302
、生产者消费者算法。服务器
HashMap
都问烂了,问的是HashMap
的底层原理,我知道大家本身写过JDK
,请不要再问我HashMap
里的put
操做是怎么实现的了!多线程
问源码的真的很讨厌,有什么意义吗?看过的就能答上,没看过的就答不上。框架
transient
这并非第一次听到transient
这个词了,以前也用过,当咱们使用YunzhiService
进行综合查询时,咱们会在实体中构造不映射到数据表的属性用于查询。学习
对于这些不映射为数据表字段的属性,咱们使用@Transient
注解。
那Java
中被transient
修饰又是什么意思呢?
为何要有transient
?StackOverflow
的解释通俗易懂。
The transient keyword in Java is used to indicate that a field should not be part of the serialization (which means saved, like to a file) process.
Java
中的transient
关键字,意味着该字段不参与序列化,意味着不被保存,例如输出到文件中。
序列化?fastjson
应该用到了这个关键字。
厉害厉害,fastjson
开发团队基本功扎实。
volatile
这个关键字也不知道怎么能给你们通俗的讲出来,仍是从实际的小例子出发吧?
你们回忆一下咱们以前的单例模式,单例模式很经常使用,这个是必需要会的。
这是有问题的懒汉模式,多线程的时候就不能保持单例了。
public class Singleton { private static Singleton instance; private Singleton() { } public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
纠正一下以前博客中的一个问题,以前这样写虽然也能实现,可是效率极低,由于每次getInstance
的时候都会被synchronized
阻塞。
public class Singleton { private static Singleton instance; private Singleton() { } public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
为了效率,不能在方法上加锁,因此须要在新建单例的时候加锁,保证只要只有一个单例被new
出来。
看起来是没问题的,由于咱们想固然的觉得,一个线程new
出来的Singleton
,赋值给instance
,而后另外一个线程获取到的instance
就必定不是空。实际上呢?
CPU
结构让咱们来看Youtube
上的一张图:
在CPU
内部结构中,thread-1
和thread-2
运行在不一样的核心上,每一个核心有一个local cache
,两个线程执行时,会将变量从shared cache
读取到local cache
。
因此thread-1
把flag
内容改变了,可是thread-2
获取的flag
仍是从local cache
中获取的,因此仍是true
。
直到,thread-1
的flag
更新到shared cache
,而后再更新到thread-2
的local cache
,thread-2
才知道flag
变了。
因此咱们的单例也同样,线程A
新建了单例,而后其余线程再获取的时候,不必定是线程A
所建立的单例对象。
volatile
来拯救世界了。
private static volatile Singleton instance;
volatile
作了两件事,强制将local cache
写入到shared cache
,同时使其余核心中的local cache
对该数据的缓存无效。
因此,完整的单例应该是这样:
public class Singleton { private static volatile Singleton instance; private Singleton() { } public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
上面的讲解只是为了让你们了解Java
中volatile
的做用,实际的单例并不这样实现,而是使用私有静态内部类实现懒汉模式,当访问getInstance
方法时,才加载Holder
类,实例化单例。
public class Singleton { private static class Holder { private static Singleton instance = new Singleton(); } private Singleton() { } public static Singleton getInstance() { return Holder.instance; } }
呼,长出了一口气,两个晚上了,总算把volatile
本身学会而后讲明白了,这个应该是发生的几率很小很小,我为了让volatile
的验证让你们都看到,使用JDK
自带的线程池,模拟实际的多线程环境,分别执行本身的测试代码,但仍是没出现问题。
HTTP
301/302去火狐开发者文档看看:
301 Moved Permanently
永久重定向,请求的资源已经被移动到了由Location
头部指定的url
上,搜索引擎会根据该响应修正。
HTTP
升级到HTTPS
时应该能用到。
302 Found
临时重定向,请求的资源被暂时的移动到了由Location
头部指定的url
上。浏览器会重定向到这个url
,可是搜索引擎不会对该资源的连接进行更新。
可能会在某个后台服务瘫痪的时候再转给别的后台服务器时用到?
至于最后的生产者消费者算法问题,我以为意义不大,毕竟操做系统的课本出自七
位河北工业大学操做系统教师之手。
JDK
中有阻塞队列,用的就是生产者消费者模型。用到的时候再说吧。
每一个人都是优秀的人,每一个人都值得尊敬。
软件生而自由,不受世俗污染,不受凡尘打扰,我祝愿每一位软件工程师都能生活在自由、快乐之中。