Java Serial
1. Java基础问答
2. Java Generic
3. Latch VS Barrier
4. AtomicInteger, BlockingQueue and Fork/Join
5. ConcurrentHashMap, Executor, ThreadPool
Java基础问答
1. 进程vs线程
2. JVM同步交互机制介绍
3. Synchornized死锁示例
4. 线程状态转换图
5. static
a. 为什么要有静态变量?为什么要有静态方法?普通的成员变量/方法和静态的成员变量/方法含义上有什么区别?
b. 静态变量存在在什么区域?静态方法存放于什么区域?
c. 私有静态方法有什么用?多线程对静态变量有什么影响?
d. 为什么不推荐把对静态变量的访问放于synchronized 块内?
e. 为什么thread的sleep方法是static的?
6. final
a. final关键字的作用是什么?final关键字对于多线程有什么帮助,会造成什么不良的后果?
b. 为什么在多线程中,对final变量的取值要取两次?
c. 利用final static组合关键字来代替一些枚举类型有什么好处?为什么在很多项目里面,String类型的常量或者模板被统一声明为final static?
7. volatile
a. 为什么 private volatile Integer i = new Integer(2); public int fun() {return i * i;} 是错的?
b. final, volatile一起使用可以吗?
c. happens-before法则是什么?它跟volatile有什么关系
d. volatile是用来修饰变量,而不是方法, 为什么?
e. 为什么volatile无法代替锁?
f. synchronized和volatile的区别是什么?在什么时候可以使用volatile变量?
g. 应用volatile的一般场景可以有哪些?
8. Threadsafe
a. 一句话概括出线程安全的含义
b. 为了保证线程安全,我们需要注意什么事情?
c. 我们可以利用哪些手段来保证线程安全?
d. 利用synchronized直接锁住所有访问,有些时候太重了,有什么简单的办法可以即使用synchronized(因为它简单),有可以大幅提高读写性能?
9. synchronized
a. synchronized锁加在什么地方?对哪些部分的访问会被锁住?JVM如何保证只有一个线程在访问?锁的信息存放在哪里?
b. synchronized是否可以用到变量上?
c. synchronized太重了,有什么其他的锁来替换?偏向锁
d. 什么是死锁, 什么是活锁,如何避免死锁?出现线程死锁如何补救?
e. 为什么构造函数上不能用synchronized?
10. Threadlocal
a. 为什么多线程中使用Threadlocal生命对象可以保证线程安全?
b. Threadlocal如何保证key是唯一的?
c. 线程run方法里面声明的变量为什么不需要使用Threadlocal来保证线程安全?
d. 什么时候需要使用Threadlocal以保证线程安全?
11. fail-fast和fail-safe
a. 为什么不能对java collection一边遍历一边删除?
b. 为什么能对juc可以一边遍历一边删除?
Java generic
1. 泛型是什么
2. 泛型的作用
3. 泛型实现原理:编译器擦除
a. 泛型是编译器中的概念,JVM没有泛型这样的概念,编译器用擦除法实现泛型。
b. 擦除演示
c. 擦除引起的问题及解决方法(参考http://blog.csdn.net/lonelyroamer/article/details/7868820)
i. 类型擦除所带来的多态麻烦
ii. 泛型类型变量不能是基本数据类型
iii. 异常中使用泛型的问题
iv. 不能声明参数化类型的数组
v. 泛型类型的实例化
vi. 类型擦除后的冲突(比如equals方法)
d. 其它常见问题
i. 泛型中 参数化类型不考虑继承关系
ii. 参数化类型与原始类型的兼容
4. 存取原则和PECS(Producer Extends, Consumer Super)法则
a. 泛型中的”?”通配符
b. 泛型中的”?”通配符的扩展
c. PECS法则
i. 如果你想从一个数据类型里获取数据,使用 ? extends 通配符
ii. 如果你想把对象写入一个数据结构里,使用 ? super 通配符
iii. 如果你既想存,又想取,那就别用通配符。
5. 为什么Java的泛型伪泛型
Latch and Barrier
1. Latch
a. latch就像一把大锁,所有调用它的await方法的线程都会被阻塞在那里,直到有足够的线程调用它的countDown方法,那些被阻塞的线程才会继续运行。
b. latch最主要的方法有两个,一个是await,另一个是countDown。
i. 当一个线程调用await方法时,该线程会被阻塞起来。
ii. 当一个线程调用countDown方法时,该线程不会被阻塞,会继续运行下去。
iii. latch在实例化的时候,需要属于一个参数用于指明在阻塞线程被唤起之前,需要调用countDown方法的次数。
iv. latch的await还提供了一种方法await(long timeout, TimeUnit unit)用来设定线程的最大阻塞时间。如果线程阻塞时间超过这个时间设置,但countDown方法的调用次数依然没有达到被唤醒的条件,该线程会放弃阻塞,被唤醒。
c. LatchSample.java是一个简单的使用CountDownLatch的例子。
d. latch的实例化对象不可以被反复使用,去掉上面例子中main方法中的倒数第二第三行的注销,执行代码,可以看到当第二次使用时,打印"All end."这一句的方法并没有在其它线程执行完了以后才被执行。
2. barrier
a. barrier类似一个同步所有线程的栅栏,它让所有执行到特定行的线程同时等待,直到等待的线程数目达到一定的数目,所有线程再又同时开始执行。
b. 和latch不同的是,barrier是可以被反复使用的。
c. barrier最主要的就是一个方法await。
i. 当一个线程调用await方法时,该线程会被阻塞起来。
ii. barrier实例化的时候,需要属于一个参数用于指明在阻塞线程被唤起之前,需要调用await方法的次数。当await方法被调用次数达到该次数时,所有被阻塞的线程被唤醒开始运行,此时barrier对await方法调用次数的计数将重新开始。
iii. barrier在实例化的时候,传入一个实现Runnable接口的对象作为唤醒所有线程前被执行的回调函数。这个回调函数是通过run()方法执行的,而不是start()方法,所以它不是一个和其他线程并行执行的线程,这个回调函数的执行会阻塞其他所有被await阻塞的线程,直到这个回调函数被执行完了之后,其他被阻塞线程才能开始执行。所以尽量不要在这个回调函数中去执行计算时间比较长的方法。
d. BarrierSample.java是一个简单的使用CyclicBarrier的例子。在这个例子中,CyclicBarrier的一个实例化对象被连续使用了三次。
e. BarrierSample2.java是一个模拟三个运动员参加跑步比赛的例子。其中包含三个运动员和一个裁判。运动员从热身开始起到最后发完奖品离开,中间有几个特定的时间点需要等到所有的人都达到特定的状态,例如,只有当裁判检查完所有运动员以后才开始跑步,所有人跑完以后再进行统计成绩,统计统计完毕统一发奖等。
3. Practise:有一个很大的整数list, 需要求这个list里面的所有整数的和,实现一段充分利用多线程的代码,要求如下:
a. 自行初始化list
b. 求和计算要利用JAVA多线程实现,要求根据一开始输入的线程个数不同可自行调控线程个数
c. 要能输出最后的计算结果,无论是作为返回值,或者直接输出在console上都可以
d. 该list无法一次性load到内存中
AtomicIntergrer, BlockingQueue and Fork/Join
1. for(;;) {} 和 while(true) {} 的相同点和不同点在哪里?
a. 相同点: 两者都是在做死循环
b. 不同点: 前者只对应一条循环语句,后则需要对一个局部变量进行判断,前者执行效率更高
2. Atomic Integer
a. 当没有原子整数的时候,用什么方式可以使得对同一个整型引用的多线程加减修改是线程安全的?--- 加锁
b. 该做法有什么不好的地方? ----- 容易造成死锁
c. Atomic Integer 比 加锁 要快吗? ----- 加锁会快很多,数值计算比较多的地方最好不要使用Atomic Integer,会影响执行效率
d. Atomic Integer适合用在类似分配唯一ID号的地方
3. BlockingQueue
a. Blocking的好处是什么?
可以让线程阻塞,不占用CPU时间,利用阻塞线程等待消息,减少代码复杂度,提高执行效率
b. array, linked的特点分别是什么?
i. array内部是用固定大小的数组实现的,初始化时必须给定数组固定大小并初始化话这么大一个数组,效率更高
ii. linked内部用链表实现,初始化时可不给定大小,默认大小为MAX_INT,内存使用上更灵活
c. ReentrantLock, Condition, Atomic Integer (capacity)
i. ReentrantLock 通过lock和unlock方法实现加锁解锁
ii. Condition 类似于Object的wait和notify
iii. Atomic Integer 用于记录队列中元素个数,capacity 队列最大容纳元素个数
d. BlockingQueue最主要的接口
i. Take
ii. put
e. BlockingQueue的应用场景可以有哪些?
f. 谨慎包装BlockingQueue
防止死锁,尽可能通过队列来实现信号的传递
g. queue, deque, priority queue
4. Fork & Join
a. RecursiveTask -> ForkJoinTask -> Future
RecursiveAction -> ForkJoinTask -> Future
ForkJoinPool -> AbstractExecutorService
b. RecursiveTask, RecursiveAction : computer, fork, join
ForkJoinPool : submit
c. 调用
forkJoinPool = new ForkJoinPool();
Future<Object> result = forkJoinPool.submit(new RecursiveTask(...)/RecursiveAction(...));
result.get();
d. ForkJoinPool如何实现自适应线程数?
通过调用 System.Runtime中的方法直接获取核数
ConcurrentHashmap, Executor, ThreadPool
1. ConcurrentHashMap
a. 场景
高并发读写,实时性要求很高,IO量大。
b. HashMap为什么不行
写入更新操作涉及到的步骤太多
c. 让步
可以允许读到稍微早一点的过期数据,但是不能读到太久以前的过期数据
还有什么问题不能解决的?
d. 两级结构
Segment, HashEntry
e. 基本操作
i. get, put, remove
ii. size
2. ThreadPool
a. Executor -> ExecutorService -> AbstractExecutorService -> ThreadPoolExecutor
void execute(Runnable command);
b. Executors?
c. ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
corePoolSize: 线程池维护线程的最少数量
maximumPoolSize:线程池维护线程的最大数量
keepAliveTime: 线程池维护线程所允许的空闲时间
unit: 线程池维护线程所允许的空闲时间的单位
workQueue: 线程池所使用的缓冲队列
handler: 线程池对拒绝任务的处理策略
threadFactory: ?
d. 停止线程池ThreadPoolExecutor
shutdown()
shutdownNow()
e. 执行
Worker
3. Future and FutureTask
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
运行超时设定取得结果
4. 该线程池使用哪些范围
5. 哪些地方使用该线程池不合适,使用什么样的方式比较合适
相关推荐
【Java程序员年终总结】 作为一名Java程序员,我在2010年的经历让我深刻理解到学习的重要性。从初入职场的新鲜人,到能在公司独立完成项目的开发者,这段历程充满了挑战和成长。2010年,我有幸加入北京联合兴辰公司...
对于Java程序员来说,面试是他们职业生涯中的一个重要环节。本文将深入探讨标题和描述中提及的知识点,以及如何利用提供的压缩包文件进行自我提升。 首先,"程序员的七种武器"通常指的是编程者必备的技能和素质,...
从给定的信息来看,虽然部分内容存在乱码情况,但标题和描述为我们提供了一些关于JAVA程序员心得的关键信息。接下来,我们将围绕这些心得展开讨论,并尝试从中提取出对JAVA程序员有用的知识点。 ### JAVA程序员的...
【Java程序员面试交流项目经验】在面试中,Java程序员需要准备的不仅仅是技术知识,更重要的是如何将自己的项目经验、个人能力和职业潜力展现给面试官。以下是一些关键的面试技巧和项目经验分享: 1. 自我介绍:...
在工作中,她展现出严谨的态度和对IT领域的热情,具备敏锐的思考能力,能够积极发现问题并高效解决。她自学能力强,适应新知识和技术速度快,具备良好的职业道德和团队协作精神。 在技术方面,钱文彬精通Java编程,...
### Java程序员应该去的20个Java网站 对于Java开发者来说,互联网上有着丰富的资源,可以帮助他们提升技能、解决问题以及了解最新的技术趋势。本文将详细介绍20个对Java程序员非常有帮助的网站,并阐述每个网站的...
在Java 程序员辞职信中,我们也可以看到程序员辞职的过程是非常复杂的,需要程序员认真地思考和总结自己的辞职原因和感谢领导和同事的帮助和支持。同时,也需要领导和同事的理解和尊重,确保程序员的辞职过程是顺利...
"java程序员到架构师之路.pdf" 以下是对《java程序员到架构师之路.pdf》的详细解读: 一、Java 编程入门类 作为 Java 程序员,快速掌握 Java 基础语法和基本用法是非常重要的。在这个阶段,需要快速过一遍 Java ...
### Java程序员初学20道题知识点解析 #### 1. Java初学者习题20道 本部分内容涉及了Java编程的基础概念和技术要点,旨在帮助初学者系统地掌握Java编程的核心知识。 #### 2. 如何看待Java构造函数的执行 在Java中...
作者认为,职业规划是 Java 程序员的必备技能,需要思考自己的职业发展方向和技术成长路线图。作者总结出 Java 程序员的工作 2-5 年成长路线图,包括: 1. 三年:成为一名纯粹的 Coder,掌握基本的开发技术和团队...
Java程序员面试宝典是每一位Java开发者在求职过程中不可或缺的参考资料,它涵盖了广泛的Java技术知识点,旨在帮助应聘者准备各类面试和笔试。这份“Java程序员面试宝典+笔试题(最新)”显然是一份集合了诸多知名IT...
《Java程序员+上班那点事儿》是一本专为Java开发者量身打造的书籍,它不仅涵盖了Java编程的基础知识,还深入探讨了Java程序员在实际工作中可能遇到的各种问题和解决策略。这本书旨在帮助初入职场的Java新手更好地...
《Java程序员面试宝典》是一本为准备Java程序员面试者量身定制的参考资料,它涵盖了技术、基础、逻辑以及面试策略等多方面的内容。这本书旨在帮助求职者充分准备,提高面试成功率,确保在竞争激烈的IT行业中脱颖而出...
一个Java程序员的成长历程,如何成为一个Java程序员?
Java程序员职业规划是一个重要的主题,尤其对于初入行业或希望在技术道路上持续发展的专业人士来说。在Java这个全球广泛使用的开发语言领域,明确的职业规划能够帮助程序员制定目标,提升技能,并在竞争激烈的市场中...
这些内容不仅反映了Java程序员在面临职业决策时的思考过程,也揭示了他们在工作中遇到的实际问题和挑战。对于企业来说,这样的报告提供了改进管理、提高员工满意度的参考依据。而对于即将离职的程序员,这是一份表达...
- **问题解决**:培养独立思考和解决问题的能力,面对复杂问题能够冷静分析,找到最优解决方案。 - **时间管理**:合理安排工作和学习时间,提高效率,避免拖延。 成为一名优秀的Java程序员是一个长期的学习过程,...
【Java程序员的跳槽方法】对于Java程序员而言,跳槽不仅是更换工作,更是一个自我提升和职业发展的策略。跳槽的正确时机、目的和方式都至关重要。在职业生涯的早期,跳槽可以帮助程序员拓宽视野,积累不同公司的技术...
通过阅读这些资料,Java程序员不仅可以系统复习和巩固基础,还能了解面试中可能出现的热点问题,提高面试成功率。在准备面试的过程中,结合实际项目经验,理论与实践相结合,将更有利于提升个人竞争力。