网页设计网站图片,centos7系统做网站,企业免费网站制作比较好的,网页设计动态效果怎么制作转载自 JAVA后端面试100 QA之第一篇
1. synchronized和reentrantlock异同
相同点
都实现了多线程同步和内存可见性语义都是可重入锁
不同点
实现机制不同 synchronized通过java对象头锁标记和Monitor对象实现 reentrantlock通过CAS、ASQ#xff08;AbstractQueuedSy…转载自 JAVA后端面试100 QA之第一篇
1. synchronized和reentrantlock异同
相同点
都实现了多线程同步和内存可见性语义都是可重入锁
不同点
实现机制不同 synchronized通过java对象头锁标记和Monitor对象实现 reentrantlock通过CAS、ASQAbstractQueuedSynchronizer和locksupport用于阻塞和解除阻塞实现 synchronized依赖jvm内存模型保证包含共享变量的多线程内存可见性 reentrantlock通过ASQ的volatile state保证包含共享变量的多线程内存可见性使用方式不同 synchronized可以修饰实例方法锁住实例对象、静态方法锁住类对象、代码块显示指定锁对象 reentrantlock显示调用trylock()/lock()方法需要在finally块中释放锁功能丰富程度不同 reentrantlock提供有限时间等候锁设置过期时间、可中断锁lockInterruptibly、condition提供await、signal等方法等丰富语义 reentrantlock提供公平锁和非公平锁实现 synchronized不可设置等待时间、不可被中断interrupted2. concurrenthashmap为何读不用加锁
jdk1.7
1HashEntry中的key、hash、next 均为final 型只能表头插入、删除结点 2HashEntry类的value域被声明为volatile型 3不允许用null作为键和值当读线程读到某个HashEntry的 value域的值为null时便知道产生了冲突——发生了重排序现象put设置新value对象的字节码指令重排序需要加锁后重新读入这个value值 4volatile变量count协调读写线程之间的内存可见性写操作后修改count读操作先读count根据happen-before传递性原则写操作的修改读操作能够看到
jdk1.8
1Node的val和next均为volatile型 2tabAt和casTabAt对应的unsafe操作实现了volatile语义 3. ContextClassLoader线程上下文类加载器的作用
越过类加载器的双亲委派机制去加载类如serviceloader实现使用线程上下文类加载器加载类要注意保证多个需要通信的线程间的类加载器应该是同一个防止因为不同的类加载器导致类型转换异常(ClassCastException)4. tomcat 类加载机制 不同应用使用不同的 webapp类加载器实现应用隔离的效果webapp类加载器下面是jsp类加载器不同应用共享的jar包可以放到Shared类加载器/shared目录下5. osgi类加载机制 osgi类加载模型是网状的可以在模块Bundle间互相委托osgi实现模块化热部署的关键是自定义类加载器机制的实现每个Bundle都有一个自己的类加载器当需要更换一个Bundle时就把Bundle连同类加载器一起换掉以实现代码的热替换当收到类加载请求时osgi将按照下面的顺序进行类搜索
1将以java.*开头的类委派给父类加载器加载 2否则将委派列表名单配置文件org.osgi.framework.bootdelegation中定义内的类委派给父类加载器加载 3否则检查是否在Import-Package中声明如果是则委派给Export这个类的Bundle的类加载器加载 4否则检查是否在Require-Bundle中声明如果是则将类加载请求委托给required bundle的类加载器 5否则查找当前Bundle的ClassPath使用自己的类加载器加载 6否则查找类是否在自己的Fragment Bundle中如果在则委派给Fragment Bundle的类加载器加载 7否则查找Dynamic Import-PackageDynamic Import只有在真正用到此Package的时候才进行加载的Bundle委派给对应Bundle的类加载器加载 8否则类查找失败 6. sleep和wait异同
wait需要组合synchronized使用wait时会释放掉拿到的synchronized锁sleep只会交出cpu不会交出锁二者都有可能被interrupt7. 如何结束一个一直运行的线程
使用退出标志这个flag变量要多线程可见使用interrupt结合isInterrupted()使用8. threadlocal使用场景及问题
threadlocal并不能解决多线程共享变量的问题同一个 threadlocal所包含的对象在不同的thread中有不同的副本互不干扰用于存放线程上下文变量方便同一线程对变量的前后多次读取如事务、数据库connection连接在web编程中使用的更多问题 注意线程池场景使用threadlocal因为实际变量值存放在了thread的threadlocalmap类型变量中如果该值没有remove也没有先set的话可能会得到以前的旧值问题 注意线程池场景下的内存泄露虽然threadlocal的get/set会清除keykey为threadlocal的弱引用value是强引用导致value不释放为null的entry但是最好remove9. 线程池从启动到工作的流程
刚创建时里面没有线程调用 execute() 添加任务时
1如果正在运行的线程数量小于核心参数corePoolSize继续创建线程运行这个任务 2否则如果正在运行的线程数量大于或等于corePoolSize将任务加入到阻塞队列中 3否则如果队列已满同时正在运行的线程数量小于核心参数maximumPoolSize继续创建线程运行这个任务 4否则如果队列已满同时正在运行的线程数量大于或等于 maximumPoolSize根据设置的拒绝策略处理 5完成一个任务继续取下一个任务处理 6没有任务继续处理线程被中断或者线程池被关闭时线程退出执行如果线程池被关闭线程结束 7否则判断线程池正在运行的线程数量是否大于核心线程数如果是线程结束否则线程阻塞。因此线程池任务全部执行完成后继续留存的线程池大小为corePoolSize 10. 阻塞队列BlockingQueue take和poll区别
poll(time)取走BlockingQueue里排在首位的对象,若不能立即取出则可以等time参数规定的时间取不到时返回nulltake()取走BlockingQueue里排在首位的对象若BlockingQueue为空阻塞直到BlockingQueue有新的对象被加入11. 如何从FutureTask不阻塞获取结果
get(long timeout,TimeUnit unit)超时则返回轮询先通过isDone()判断是否结束然后调用get()12. blockingqueue如果存放了比较关键的数据系统宕机该如何处理
开放性问题欢迎讨论将队列持久化比较麻烦需要将生产数据持久化到磁盘持久化成功才返回消费者线程从磁盘加载数据到内存阻塞队列中维护消费offset启动时根据消费offset从磁盘加载数据加入消息队列保证消息不丢失生成序列号消费幂等根据消费进程决定系统重启后的生产状态13. NIO与传统I/O的区别
节约线程NIO由原来的每个线程都需要阻塞读写变成了由单线程即Selector负责处理多个channel注册register的兴趣事件SelectionKey集合底层借助操作系统提供的epoll()netty bossgroup处理accept连接没看明白为什么bossgroup设置多个thread的必要性workergroup处理具体业务流程和数据读写NIO提供非阻塞操作传统I/O 以流的方式处理数据而 NIO 以块的方式处理数据NIO提供bytebuffer分为堆内和堆外缓冲区读写时均先放到该缓冲区中然后由内核通过channel传输到对端堆外缓冲区不走内核提升了性能14. list中存放可重复字符串如何删除某个字符串
调用iterator相关方法删除倒删防止正序删除导致的数组重排index跳过数组元素问题15. 有哪些GC ROOTS跟日常开发比较相关的是和此相关的内存泄露
所有Java线程当前活跃的栈帧里指向GC堆里的对象的引用因此用不到的对象及时置null提升内存回收效率静态变量引用的对象因此减少静态变量特别是静态集合变量的大小集合存放的对象覆写euqls()和hashcode()防止持续增长本地方法JNI引用的对象方法区中的常量引用的对象因此减少在长字符串上调用String.intern()classloader加载的class对象因此自定义classloader无效时及时置null并且注意类加载器加载对象之间的隔离jvm里的一些静态数据结构里指向GC堆里的对象的引用...
未完待续java、算法、spring、redis、dubbo、kafka、zookeeper等广告点一波