模拟面试-线程向

来源:互联网 发布:人工智能湖南论坛 编辑:程序博客网 时间:2024/06/06 01:25

设计模式切入?

1,设计模式为了实现什么功能

设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码让代码更容易被他人理解保证代码可靠性
2,了解设计模式的六大原则么

  • 开闭原则(对扩展开放,对修改关闭)
  • 里氏替换原则(任何有基类存在的地方,子类一定可以出现)
  • 依赖倒置原则(针对接口编程,依赖于抽象而不是依赖于具体)
  • 接口隔离原则(能用多个接口咱不用一个接口实现功能)
  • 迪米特法则(一个实体应该尽量与其他实体少发生相互作用)
  • 合成复用法则(尽量使用聚合/组合的方式,不使用继承)

3,说说常见的几种设计模式

单例模式http://blog.csdn.net/sinat_33087001/article/details/77774298
因为要确保系统里对象的唯一性,例如打印程序和打印任务,必须一个一个打。

工厂模式http://blog.csdn.net/sinat_33087001/article/details/77775151
适配器模式http://blog.csdn.net/sinat_33087001/article/details/77776712
观察者模式http://blog.csdn.net/sinat_33087001/article/details/77776922

4,单例模式有哪些类型。类型的优缺点
懒汉(非线程安全,线程安全(方法加同步),双重检查,静态内部类),饿汉
5,手写一个双重检查的单例模式
6,这个设计模式有没有可能出错呢

怎么避免出错

1,谈谈volatile修饰怎么避免出现错误

2,volatile怎么实现可见性和有序性
3,并发编程还有哪些特性
4,synchronized是怎么实现这三个性质的

  • jMM内存模型提供了lock和unlock两种操作,体现在指令上就是moniterenter和moniterexit,体现在java代码块儿上就是synchronized同步块儿。所以java同步块儿能实现原子性。
  • 对一个变量执行unlock之前一定要将当前值同步到主内存中去(store and write)
    read—load—use–assign—store—-write

  • 一个变量在同一时刻只能被一条线程lock,同步块之间是串行进入

5,synchronized的原理
怎么实现三个性质的
6,volatile和synchronized有哪些区别,应用场景

  • volatile轻量级的同步机制,但不能保证原子性,synchronized可以保证原子性
  • volatile只能使用在变量级别,synchronized可使用在方法级别
  • volatile不会造成线程的阻塞,而synchronized可能会造成线程的阻塞.

锁的状态

1,既然synchronized可以实现并发编程的三个特性,那么它是万能的么?缺点是什么
频繁的挂起和执行需要系统调用,而系统调用的代价相当高,需要再用户态和内核态中来回切换。其次,每个轻量级进程都需要一个内核线程的支持,因此会消耗内核的资源。
2,java是通过什么方式减少获得锁和释放锁所带来的性能消耗?哪三种状态切换
偏向锁—-轻量级锁—-重量级锁
3,为什么使用这三种状态。
http://blog.csdn.net/sinat_33087001/article/details/77849575
三种状态的使用场景
4,还有哪些优化方案。
锁的自旋和自适应自旋,锁粗化和锁消除(逃逸分析的数据支持,如果一段代码中,堆上所有的数据都不会逃逸出去从而被其它线程访问到,那就可以把它们当做栈上的数据对待,可以认为是线程私有的,那么就可以消除代码内部的同步),而锁粗化(是如果对同一个对象反复加锁和解锁,那么即使没有线程竞争,也会带来不必要的性能损耗)
http://blog.csdn.net/sinat_33087001/article/details/77644441
5,既然说到锁,就谈谈为什么会发生死锁。怎么避免死锁
6,了不了解happens-before

  • 程序次序规则(Program Order Rule):在一个线程内,按照程序代码顺序,书写在前面的操作先行发生于书写在后面的操作。准确地说,应该是控制流顺序而不是程序代码顺序,因为要考虑分支、循环等结构。
  • 传递性(Transitivity):如果操作A先行发生于操作B,操作B先行发生于操作C,那就可以得出操作A先行发生于操作C的结论。
  • 对象终结规则(Finalizer Rule):一个对象的初始化完成(构造函数执行结束)先行发生于它的finalize()方法的开始。
  • 管程锁定规则(Monitor Lock Rule):一个unlock操作先行发生于后面对同一个锁的lock操作。这里必须强调的是同一个锁,而“后面”是指时间上的先后顺序。
  • volatile变量规则(Volatile Variable Rule):对一个volatile变量的写操作先行发生于后面对这个变量的读操作,这里的“后面”同样是指时间上的先后顺序。
  • 线程启动规则(Thread Start Rule):Thread对象的start()方法先行发生于此线程的每一个动作。
  • 线程终止规则(Thread Termination Rule):线程中的所有操作都先行发生于对此线程的终止检测,我们可以通过Thread.join()方法结束、Thread.isAlive()的返回值等手段检测到线程已经终止执行
  • 线程中断规则(Thread Interruption Rule):对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生,可以通过Thread.interrupted()方法检测到是否有中断发生。

http://blog.csdn.net/sinat_33087001/article/details/77621189#t21