《冲击名企,冲击架构师》

栏目:线程与并发 作者:admin 日期:2018-09-01 评论:0 点击: 284 次

注:2018年9月1日更新

市面上关于Java多线程开发的书很多,单以多线程为主题的书,有以下十本:
1、Java核心技术系列:Java多线程编程核心技术,高洪岩,2015-06-01
2、Java多线程编程实战指南(核心篇),黄文海,2017-04-01
3、图解Java多线程设计模式,结城浩,2017-08-01
4、Java线程与并发编程实践,Jeff Friesen,2017-02-01
5、Java多线程编程实战指南(设计模式篇),黄文海,2015-10-01
6、Java并发编程实战,Brian Goetz,2012-02-01
7、实战Java高并发程序设计,葛一鸣,2015-10-01
8、Java并发编程:核心方法与框架,高洪岩,2016-05-01
9、Java高并发编程详解:多线程与架构设计,汪文君,2018-05-01
10、Java并发编程的艺术,方腾飞,2015-07-01
另外,关于Java核心知识介绍、关于JVM介绍的书上也会有大篇介绍多线程的内容。可以对比一下MyBatis,市面上只有3本,通过这个数量的对比就能说明Java多线程的内容有多庞大了。这么多书通读一遍将花费大量的时间,再者,其实有些书就是API的罗列,质量层次不齐。你会的它上面有;你不会的,它没有;你迷惑的,它也没有讲清楚。操千曲而后晓声,观千剑而后识器,所以我每次都是广泛涉猎、看大量的书才自认为达到掌握的程度。可在现实生活中,很多人读书量其实少的可怜,没有足够多的阅读量怎么能建立起庞大的知识体系,怎么能悟道某些技术呢!

悟道多线程,就能站在开发的金字塔的尖端。这里说的不是了解,不是掌握,而是悟道。线程不仅仅是知识,更是一种思想。说它是知识,因为按照书上的介绍,任何人都可以学会线程和并发;说它是思想,是因为它区分不同的境界,有的人用的出神入化,而有的人就是照本宣科。
程序=数据结构+算法,那把多线程放在哪里呢?硬插进去,会破坏这个等式的美感。时代在发展,技术在变革,人们的思想再进步,现在谁还在写程序呢?现在大家都在构建服务,都在想着进大厂,挣大钱。所以不如换种形式,让它变形一下:优秀人才=多线程(思想)+数据结构+算法。
   
多线程如此重要,多线程又如此庞大,那如何才能理解->掌握->吃透呢?在我看来,极速学习才是一种最佳的方式。极速学习不等同于10小时学Java、21天精通Java这种快餐文化,极速学习针对的有一定基础和工作经验,是实现量变到质变的催化剂。极速学习,简单的说,就是在短时间里面掌握大量的知识点,让大脑迅速的建立起较多的知识点联系。

上文提到大量的知识点,也提到了知识点的联系,怎样才能更好的实现学习效果呢?其实,数据结构这门课程已经给出了最优的答案。数据结构上常见的数组、链表无一不是有序的,知识的学习皆是如此,有序的知识方能收放自如,这就是为什么这次公开课的知识点都是有编号、能串起来的出发点。数据结构很重要,它描述了数据的存储和关联,它是数学的分支,而数学是思维的工具,所以数据结构思想的领悟及其重要,它可以让人的思考、处事更有效。

现在名企越来越多,比如说:小米,今日头条,滴滴,美团,京东等等,名企越多,进名企的机会也就越大,这是一件好事。不过,每个企业都不有不同的要求,但是优秀才是核心竞争力。面试绝不是说在网上搜索一下几道题那么简单,关键在于对知识点的理解上面,同样的知识点,有的人理解的深,有的人理解的不深,这就是差距。

线程不仅仅是知识,更是一种思想。说它是知识,因为按照书上的介绍,任何人都可以学会线程和并发;说它是思想,是因为它区分不同的境界,有的人用的出神入化,而有的人就是照本宣科。

基于极速学习的理念,以后周末时间会开个《关于线程与并发的公开课》,时间是上午10点到晚上10点,总共涉及到100-200个知识点,这些知识点紧紧围绕线程和并发。可以说,一个人把线程和并发都掌握透彻了,不敢说能百分之百的进入名企,但是可以肯定的说,一定比其他人更有优秀。
   
公开课的价值在于集百家之长,融自身之悟。有上百个知识点,可谓“百家之长”,更有自己的独到见解,可谓“自身之悟”。厉害的人不一定会写书,文化圣人孔子就没有专著流传于世,流传的只是弟子收集下来的言行而已。在技术领域,这种现象依然存在,很多大牛都没有写书。很多人即使写了也是青涩年纪的冲动,真正成为了大牛很难再看到他们出的新书了,这样的例子比比皆是,例如网易云风等等。虽然我辈不能与这些大牛比肩,但是依然遵循这个简单的道理:厉害的人一般不会去写书的。我可以写博客,抒发某个新的发现;我可以开公开课做技术交流,但是我从没有写书的打算。2010年的时候,当时就想写本Java大全,一直到2017年,积累了四五十万字,最终付之一炬。这些笔记犹如负重前行,让我很难跑的更快,我只是像火箭升空一样,不断的汲取不断的抛掉,这样才能真正达到某种高度。

现在流行智商税,我只想静静旳写代码,只想安心的做研究,只想开几次公开课做些技术交流而已。为了避免让人产生征收智商税的怀疑,公开课做出了四项举措:(1)大量的知识点,让用户觉得值;(2)现场花费大量时间的讲解,让用户觉得值;(3)允许退费,让用户放心;(4)原创注明,让用户醍醐灌顶,觉得物超所值。

如果感兴趣,想找个好的工作,想成架构师,或者想成为CTO,都可以报名参加这个课程。时间是一天,费用暂时100元,报名人数太少了,也许就不开了。物超所值的课程,背后的八年的经验总结,感兴趣请联系QQ:3028063318,度秋。

下面抽出部分内容,以飨读者,郑重声明:本文所有内容,全部基于原创,任何人不得抄袭,不得转载。

1、CPU核心数、线程数的关系
2、CPU时间片轮转机制,设置多少毫秒是合理的?
这个问题本身就是有问题。CPU不应该是时间片来划分的。那到底以什么来划分呢?
3、什么是进程,什么是线程?
4、一个进程最多可以创建多少个线程?
5、用户单一进程同时可打开文件数量是多少?
6、什么是并行,什么是并发?
7、什么是同步,什么是异步,什么是堵塞,什么是非堵塞?
8、实现线程的三种方式?
9、线程的生命周期是什么?线程池的初始化的时候,池里面的线程处于生命周期的那个阶段?
10、什么是线程组?
11、ThreadLocal是用来解决共享资源的多线程访问的问题吗?
12、每次使用完ThreadLocal,都调用它的remove()方法,为什么呢?
13、volatile的作用?
14、run方法是否可以抛出异常?如果抛出异常,线程的状态如何?
15、什么是隐式锁?什么是显式锁?什么是无锁?
16、多线程之间的切换过程?
17、单例模式的几种写法?
18、Java的内存模型?
19、什么是原子操作?生成对象的过程是不是原子操作?
20、CopyOnWrite机制是什么?
21、什么是CAS?
22、什么是AQS?
23、Fail-Fast机制是多线程原因造成的吗?
24、为什么要用线程池?常见的线程池有哪些?
25、阻塞队列的常用方法?
26、为什么数组比链表随机访问速度会快很多呢?
26.1 数组是顺序存储,在内存中是一个整块;
26.2 数组元素的定位分为两步:第一步,计算下标i*数组元素大小求出偏移地址;第二步:数组首地址+偏移地址就是元素i的地址
26.3 链表的内存不是连续的,只能一个一个查找,速度自然慢很多了。
27、什么时候用定时器,什么时候用延时队列?
延时队列中的对象只能在其到期时才能从队列中取走,需要延迟随机时间的工作可以采用延时队列,例如不定时的广告上下线。
28、延时队列中的延时是如何实现的?
29、堵塞队列的add,offer,put的区别?
add,抛出异常;offer,不抛出异常;put,堵塞。简称:aop
30、线程的阻塞与挂起有什么区别?sleep的底层实现是什么技术?
共同点:都暂停执行;都释放CPU,都会涉及上下文切换
不同点:虽然都释放了CPU,但阻塞的线程仍处于内存中,而挂起的线程通过“对换”技术被换出到磁盘中。
31、sleep的时候,是否会释放已经获得到锁? 
32、yield的作用
与sleep类似,只是不能由用户指定暂停多长时间,并且yield方法只能让同优先级的线程有执行的机会。
33、join的作用?
线程就是一条链子,就是一种数据结构;其实线程也是树,都是分叉来的,线程A可以分叉出线程a,但是线程A还握着线程a的小辫子,可以给a说:你先跑,我等你跑完了我再跑。
33、sleep方法和yield方法的区别?
sleep方法会将线程转入阻塞状态,直到经过阻塞时间才会转入就绪状态;而yield不会将线程转入阻塞状态,它只是强制当前线程进入就绪状态,完全有可能某个线程调用yield方法暂停之后,立即再次获得处理器资源被执行。
33、InterruptedException是什么?
这种异常不同于普通的异常,甚至这个就不算是异常,这个是信号,不要看到异常就感觉是出问题了,这个是人畜无害的信号。java的创造者真是费尽心机啊,将信号融入了异常。
try 
{  
    TimeUnit.SECONDS.sleep(2);  

catch (InterruptedException e) 
{  
    //收到信号之后,可以做些其他的操作 

35、AtomicBoolean()初始化值是多少?public final void set(boolean newValue)的作用? 
34、如何设计一个利用无锁来实现线程的安全?
设计思路如下:
34.1 首先分析一下锁的流程。第一步:初始化锁,也就是未上锁。第二步:线程判断锁的状态。第三步:发现未上锁,线程则加锁;发现已上锁,线程则先等待再重试。第四步:加锁的线程,执行完则解锁。
34.2 将上述的流程抽象化:锁的状态分为未上锁,已上锁,就是0和1;加锁和解锁的状态改变,其实就是变量的赋值操作,即=操作
34.3 将上述的抽象化进行扩展:0和1,就两种状态,可以用Boolean变量来代替。
34.4 用Boolean变量加锁和解锁的逻辑是:
Boolean lock = false;
if(!lock)
{
lock = true;
//do something;
lock = false;
}
上述代码容易出现问题啊!就在if(!lock)处,如果两个线程同时走到这步,那么都会进入下面的逻辑,从而出现并发线程不安全问题。那如何改进呢?我们看,if(!lock)这个判断逻辑是重点关注的对象。如何把它变的更强大一点呢?
有无数的技术专家花费了大量的时间在细节上下功夫,从i=i+1衍生出i++,同样道理if(!lock)延伸出了compareAndSet。这也许才是CAS思想的初衷、根源吧。利用compareAndSet技术可以实现一个无锁的安全并发。
private static class Worker implements Runnable {  
  private static AtomicBoolean lock = new AtomicBoolean(false);  //初始化状态,未上锁
  private String name;  
  public Worker(String name) 
  {  
   this.name = name;  
  }  
  
  public void run() 
  {  
   if(lock.compareAndSet(false, true))//加锁 
   {  
    // do something    
    exists.set(false); //解锁 
   }
   else
   {  
    try 
    {  
     TimeUnit.SECONDS.sleep(2); //等待 
    } 
    catch (InterruptedException e) 
    {  
      run();  //重试
    } 
   }  
  }   
}  
注:上述代码代码是伪代码,重在说解决方案,细节错误请自行修订。

声明:
本文由金丝燕网原创编译,转载请保留链接: 《冲击名企,冲击架构师》
本站技术交流群,力争解决每一个问题:JAVA交流