https://www.nowcoder.com/discuss/5941
https://www.nowcoder.com/discuss/5949
2. volatile关键字
给大家推荐两本书:《Java多线程实战》和《Java并发编程的艺术》,这会儿已经三点了,脑子有点乱书名可能未必无误。对Java实现多线程描述的非常详细。现场跟面试官老师扯了很多,我在这里挑主要的说
volatile关键字是Java并发的最轻量级实现,本质上有两个功能,在生成的汇编语句中加入LOCK关键字和内存屏障
作用就是保证每一次线程load和write两个操作,都会直接从主内存中进行读取和覆盖,而非普通变量从线程内的工作空间(默认各位已经熟悉Java多线程内存模型)
但它有一个很致命的缺点,导致它的使用范围不多,就是他只保证在读取和写入这两个过程是线程安全的。如果我们对一个volatile修饰的变量进行多线程下的自增操作,还是会出现线程安全问题。根本原因在于volatile关键字无法对自增进行安全性修饰,因为自增分为三步,读取-》+1-》写入。中间多个线程同时执行+1操作,还是会出现线程安全性问题。
3. synchronized
锁的优化:偏向锁、轻量级锁、自旋锁、重量级锁
锁的膨胀模型,以及锁的优化原理,为什么要这样设计
与Concurrent包下的Lock的区别和联系
Lock能够实现synchronized的所有功能,同时,能够实现长时间请求不到锁时自动放弃、通过构造方法实现公平锁、出现异常时synchronized会由JVM自动释放,而Lock必须手动释放,因此我们需要把unLock()方法放在finally{}语句块中
4. concurrentHashMap
两个hash过程,第一次找到所在的桶,并将桶锁定,第二次执行写操作。
而读操作不加锁,JDK1.8中ConcurrentHashMap从1600行激增到6000行,中间做了很多细粒度的优化,大家可以查一下。
5. 锁的优化策略
① 读写分离
② 分段加锁
③ 减少锁持有的时间
④ 多个线程尽量以相同的顺序去获取资源
等等,这些都不是绝对原则,都要根据情况,比如不能将锁的粒度过于细化,不然可能会出现线程的加锁和释放次数过多,反而效率不如一次加一把大锁。这部分跟面试官谈了很久
在项目部分,可能是我整个阿里面试过程中最提心吊胆的,缓存的使用,如果现在需要实现一个简单的缓存,供搜索框中的ajax异步请求调用,使用什么结构?我回答ConcurrentHashMap,可是内存中的缓存不能一直存在,用什么算法定期将搜索权重较低的entry去掉?我说先按热度递减放进一个CopyOnWriteArrayList中,保留前多少个然后再存回ConcurrentHashMap中,面试官说效率过低,有没有更高效的算法,我假装冥思苦想(用假装其实是因为,确实想不到方法)
后来面试官说其实这个问题有点难了,换一个,又跟我扯到线程的问题,大体就跟一面面试官问的差不多,就不赘述了。这部分感觉面试官还比较满意,就问题TCP如何保证安全性,我说三次握手、四次回收、超时重传、保序性、奇偶校验、去重、拥塞控制。还讲了滑动窗口模型。
后面又考了一些红黑树的问题,问到B+数,还有JDK1.8中对HashMap的增强,如果一个桶上的节点数量过多,链表+数组的结构就会转换为红黑树。
面试官问我项目中使用的单机服务器,如果将它部署成分布式服务器?我当时心里一惊,这个问题确实没有准备过,眼看就要被问死了,临时抖了个机灵,说有一次跟一个师兄尝试这么做的时候,遇到了session共享问题,然后成功地把面试官引向了session共享的问题,跟他讨论了10分钟左右的分布式系统中如何做到session共享。后面面试官可能也觉得我这部分
手写一个线程安全的单例模式,经典的不能再经典,没什么好说的,懒汉饿汉随便选一个。
还有一些MySQL的常见优化方式、定为慢查询等,回答的七七八八,之前面试总结的问题还有印象,所以感谢自己有面试完及时总结的习惯。
最后问了问我平时都如何学习、最近都在看什么书,来实习的话学校的考试如何解决等等。
面试官告诉我他的问题已经问完了,我看没有让我提问的意思,所以我起身跟面试官握了个手(我在参加现场面试的时候有这样的习惯,握手的同时跟面试官强调,“我很珍惜这次面试机会”)
最后HR问我作为非计算机专业学生,什么专业课没有学到最让我遗憾?我回答网络基础、操作系统、计算机组成原理和系统的数据库知识体系。虽然侥幸拿到了阿里巴巴的offer,但这一次的面试让我深深地看到了自己差距。跟二面面试官交流的时候,他考我项目,我就拼命想把他往框架上拉,想解释hibernate和Spring还有mybatis,结果面试官一次也没有上当。每当我说这些的时候,面试官就会打断我,说我不用解释框架,我们就建立在这些东西都双方都清楚的基础上。所以真心劝各位准备面试的朋友们,多重视基础。基础能够决定学习能力和思维方式,而学习能力和思维方式最终决定一个程序员能走多远
https://www.nowcoder.com/discuss/5949