你遇到过哪些质量很高的 Java 面试?
姊妹问题:
你遇到过哪些高质量的C++面试?
--20230606第五次更新
这篇帖子最初是在2019新年期间在家编辑的,现在阿里已经待了四年,在这四年中面试、内推了很多员工,对java后端面试在之前基础上已有了全新的认识,今天重新编辑下此贴,相信可以帮助到大家!
以前的内容我全部保留,此帖只添加内容。
本次编辑列出大厂java后端面试需要的内容,很全面,后面根据互动情况还会更新本帖!
面试中要体现以下的能力:
做正确的事而不仅是正确的做事: 比如chatGPT出来后,有人说:以后效果图可以不用人工做了,直接人工智能可以快速做出,但是人工智能可以精准将东西推给用户,还需要效果图干什么!
做高价值的事情,能出成绩的事,能被上级认可的事情,怎样衡量需求是否有价值,看自己上级、上上级的OKR,制定计划时和他们对齐,然后严格按照OKR执行。
作为技术,需求从源头开始跟进,弄清需求为啥提出来,为了解决什么问题,有没有更好的方案;当自己工作中特别忙、杂事多、缺乏成就感的时候,就得考虑这件事是不是该做或者该换个做法。
2.基础知识:
这是很多人都会犯的错误,我们做的是应用科学,是做后端服务的,我们的基础知识不是计算机科学的基础知识,是以工作为中心,相关的知识为基础知识。
比如编译原理,我们学习顺序就可以往后放一下,甚至短期内不用学习,先学mysql、jvm、并发编程之类。具体的科目学习也有讲究,比如jvm,它的内存区域、GC算法是基础知识,但作为后端,jvm的源码对我们就不是基础知识。
总之不要上来学习那么多无关的东西,搞得身心疲惫,关键工作中还用不上。
3.算法:
我知道很多人都认为,算法工作中真的用不上,但算法怎么说呢,就像高考中数学一样,在面试中起到筛选的作用,有一票否决权,特别想进大公司,算法是很好的敲门砖,可以说是必不可少的。
4.业务能力:
了解业务有具体的方法论,比如需要了解2C业务,可以使用 5W1H8C1D 分析法快速入门
5W 包括 When(何时)、Where(何地)、Who(何人)、What(何事)和 Why(何因),代表需求产生的背景和功能上线后的运行环境;H 是指 How(如何),代表业务需求的处理逻辑。8C 包括性能、成本、时间、技术、可靠性、安全性、合规性、兼容性,代表保证质量符合要求的约束条件(Constraint)。D 是指 Data(数据),反映了业务上线之后的效果,包括业务效果和系统效果。5.工作流程:
了解下瀑布式开发,敏捷式开发,提高工作效率,工作中有很多细节,说了就很简单,但如果没有大量实践经验,没有相应的场景是没法很好掌握的,有很多的流程是在吃过无数的亏后总结出来的。
流程可以保证职责边界清晰、需求推进丝滑
例如:
整个开发流程,大约7成时间精力应该放在编码前,有问题及早沟通,解决不了向上反馈,问题抛出一定要前置。沟通一定不能光口头沟通,需要落下痕迹,不然对方记不起来沟通内容,你怎么解释。比如需求取消,让产品自己取消,我曾经沟通完取消了需求,但产品想不起来,最后还是我自己背责任。需求在上线后开灰度之前,需要业务方自己验收,验收通过才能上线,验收上线后出现问题,业务方自己责任,对方推迟不验收,技术催促,但由此造成的延期也是由业务方来背。流程问题有很多细节,需要在工作中用心体会、总结,这里不一一列举。
6.如何保证线上稳定性:
这是一个非常高逼格的问题,我敢保证很少有人能回答这个问题,更别说系统的回答上来,估计面试官也很少能回答好!
先说一下我们的方案带来的稳定性结果:整个2022年本人线上一个问题也没有(代码量是2021的两倍多),这套方案完全是本人总结出来的,我说一下提纲:
从架构上解决稳定性问题。流程化规范化相关人员的素质 在架构设计上,降级限流做好,产品上不要给使用者开放太多修改权限;流程化规范化是最重要的,一个项目整个生命周期最主要的几个环节:系分、评审、CR、自测、验收 这几个环节一定要做好,尤其是CR环节必不可少,上线后保证可灰度、可回滚。
7.线上故障处理流程:
稳定性三板斧:可降级、可灰度、可回滚,发现问题(靠监控,预警,我个人用过的最好的监控是Emonitor)如果是自身服务首先考虑回滚止血,然后修复自身问题再重新发布。
如果不是自己服务的问题,那么看是否对自身服务产生影响,根据影响程度考虑:降级、限流...
8.如何保证工程进度:
一个项目整个生命周期最主要的几个环节:系分、评审、CR、自测、验收,这几个环节中,每个环节可能遇到的问题就那么多,将这些问题总结一下,形成一套方法论,做到这些,基本就能保证工程进度。
其他还有很多,如果有问题欢迎留言,也可以咨询我,相信一定会对大家有帮助!
给大家推荐一本好书,也是我自己入手java后端以来不断学习的书籍:
《从零开始学架构》
这本书是从高级程序员走向架构的入门书籍,非常值得一看!!!
--2020.03.26更新
,结合自己近一年在工作上又有些新的领悟,决定在原文章基础上增添一些内容,和大家分享下,如有时间再单独写一篇罢。
技术上深度与广度兼顾,计算机核心课程:计算机网络、数据结构、计算机组成原理、计算机操作系统,这几门课需要深入理解(重点),jdk源码、挑一些框架深入看一下(如Spring,Netty)、常用设计模式、一些中间件,如MQ、ES 、数据库:mysql、redis等,以上说的这些都是基本功,学习时可先实践,然后反向去看下相关理论知识,把这些东西搞得明明白白,并在工程上变现。业务相关 你当下在做的东西技术栈怎样?其中优缺点?如果从零开始,能不能重新将其实现?当前系统的使用方是谁?用户量多大?用户集中使用的时间点?系统落下了哪些数据?这些数据的使用方是谁?系统依赖方是谁?这些最好自己能从技术、产品、业务角度去画下相关流程图,不然无论是面试还是平时工作,和不同方去对需求、乃至从技术去实现相关功能等,方方面面都会非常被动。和不同角色打交道注重技巧 这一点自己也在总结之中,和产品、业务、运营、技术打交道,要知道自己职责边界,弄清楚哪些是需要自己做的,哪些是该其它方做的,交流起来不卑不亢。这一点涉及核心竞争力,哪天单独写一篇吧!近来一直在面试,但半年时间,部门只进了三个人,和其它同事交流,总结下这些面试者一些共性,最想和他们讲的一句话就是:好好的把基础东西看看!过去在其它公司,主要注重的是工程业务能力,可以这么说:将业务代码写好绩效说不定就可以了,但在阿里是远远不够的,写好业务代码,绩效只能及格,其它KPI就看业务之外做了什么?据说Dubbo框架就是阿里员工为了KPI做出来的(只是听说)
太晚,有时间接着写。
未完待续...
--我觉得自己可以在头部再加上一句,一年时间,从java零基础到某一线互联网公司java资深工程师,回头一定和大家好好分享下学习路线。
--2019/3/1更新
因为本回答阅读量较大,作者觉得很有必要在开始加上一段话:下面写的内容(原回答)只是java非常基础的部分,java只是一个工具,作为工程师,要对整个计算机体系有相当程度掌握;其次要立足于工程需求,思考解决方案,即使面试java岗位,脱离java要问的还有很多:数据结构(数组,链表,树,图,排序...)、算法、缓存应用、mysql数据库底层原理、spring源码(至少AOP和IOC部分)、消息队列设计与使用,以及分布式环境下这些中间件的部署问题...
以上都熟悉后,还要认识到:科学分为基础科学和应用科学,工程师要深入理解应用的技术底层实现原理,其实从个人发展来说,应用必不可少,但是基础是远远重于应用的,只是对于公司来讲需要迅速产出,在互联网发展的风口,一般公司都首选熟练工,但以后,其实这段时间寒冬已经看出来了,招人比以前严格多了,公司更加注重面试者的基础知识,预计以后对基础知识考察会越来越严格。
上面的话就是为了提醒大家:java只是一个工具;应用必不可少,但是基础知识是安身立命以及决定自己上限的东西。
--以下为原回答
自己当初找工作时参加过众多一线互联网公司的Java研发面试,这段时间处于寒冬,然而前几天跳槽找工作,两天面了3家,已经拿了两个offer,觉得可以和大家分享下:
下面为拼多多、饿了么、蚂蚁金服、哈啰出行、携程、饿了么、2345、百度等公司给我留下较深印象的一些java面试题
private修饰的方法可以通过反射访问,那么private的意义是什么Java类初始化顺序对方法区和永久区的理解以及它们之间的关系一个java文件有3个类,编译后有几个class文件局部变量使用前需要显式地赋值,否则编译通过不了,为什么这么设计ReadWriteLock读写之间互斥吗Semaphore拿到执行权的线程之间是否互斥写一个你认为最好的单例模式B树和B+树是解决什么样的问题的,怎样演化过来,之间区别写一个生产者消费者模式写一个死锁cpu 100%怎样定位String a = "ab"; String b = "a" + "b"; a == b 是否相等,为什么 int a = 1; 是原子性操作吗可以用for循环直接删除ArrayList的特定元素吗?可能会出现什么问题?怎样解决 新的任务提交到线程池,线程池是怎样处理AQS和CAS原理synchronized底层实现原理volatile作用,指令重排相关AOP和IOC原理Spring怎样解决循环依赖的问题dispatchServlet怎样分发任务的mysql给离散度低的字段建立索引会出现什么问题,具体说下原因其它经常问的HashMap底层实现原理,常规的多线程问题考的太多了,没什么新意就不写了
平时不能光抱着应用Java的目的去学习,要深入了解每个知识点背后底层实现原理,为什么这么设计,比如问烂的HashMap 既然有hash进行排位还需要equals()作用是什么?就这个问题照样能问倒一些人,所以一定要抠细节,真的把每个知识点搞懂
一时记起来的就是这23个吧,其它想起来后续补充,答案我这几天写个大纲吧
--2019.1.23更新(加上了:写在前面的话;问题解答大纲;一些新面试题;)
转载请注明出处,今天发现居然有人复制我的题目到其他网站,这本倒是没什么,关键是复制的题目当时我还没作答,看到里面存在明显错误的解答,这可能会给初学者带来困扰。
感谢各位知友的关注,尤其感谢有人在评论区还作出有心的回答!
写在前面的话:
1.面试主要分为两块:一块是考查工程师对基础知识(包括了技术广度、深度、对技术的热情度等)的掌握程度,因为基础知识决定了一个技术人员发展的上限;另一块是考察工程师的工程能力,比如:做过哪些项目?遇到最难的问题怎样解决的?说说最有成就感的一项任务?工程能力是考察工程师当下能为公司带来的利益。其它考核方面:抗压性、合作能力...暂且不说。
2.Java只是一门语言,即使是Java工程师也不能局限于Java,要从面向对象语言本身,甚至从整个计算机体系,从工程实际出发看Java。
3.很多知识在一般公司的开发中是用不到的,常有人戏称:“面试造火箭,工作拧螺丝”,但这只是通常情况下公司对程序员的标准——迅速产出,完成任务。个人观点:工程师为了自己职业的发展不能局限于公司对自己的要求,不能停留在应用层面,要能够很好地掌握基础知识,要多看源码,自己多实践,学成记得产出,比如多为开源社区贡献代码,帮助初学者指路等。
有没有发现一个有意思的事情:“面试造火箭,工作拧螺丝”的背后其实是考察者内心深处普遍都认可基础知识的重要性(这一点仅为个人观点,不展开讲哈)。
--以下为解答大纲,部分作了扩展
1. 这题是一道思想题目,天天会碰到private,有没有想过这个问题?谈谈对java设计的认识程度,主要抓住两点:1.java的private修饰符并不是为了绝对安全性设计的,更多是对用户常规使用java的一种约束;2.从外部对对象进行常规调用时,能够看到清晰的类结构。
2. 先说结论: 基类静态代码块,基类静态成员字段(并列优先级,按照代码中出现的先后顺序执行,且只有第一次加载时执行)——>派生类静态代码块,派生类静态成员字段(并列优先级,按照代码中出现的先后顺序执行,且只有第一次加载时执行)——>基类普通代码块,基类普通成员字段(并列优点级,按代码中出现先后顺序执行)——>基类构造函数——>派生类普通代码块,派生类普通成员字段(并列优点级,按代码中出现先后顺序执行)——>派生类构造函数
代码验证:
控制台结果输出:
第2题之前的回答欠妥,现已改正,在此非常感谢提出质疑的知友!
3. 方法区是jvm规范里要求的,永久区是Hotspot虚拟机对方法区的具体实现,前者是规范,后者是实现方式。jdk1.8作了改变。本题看看对方在思想层面对jvm的理解程度,很基础的一个题目。
4. 文件中有几个类编译后就有几个class文件。
5. 成员变量是可以不经初始化的,在类加载过程的准备阶段即可给它赋予默认值,但局部变量使用前需要显式赋予初始值,javac不是推断不出不可以这样做,而是没有这样做,对于成员变量而言,其赋值和取值访问的先后顺序具有不确定性,对于成员变量可以在一个方法调用前赋值,也可以在方法调用后进行,这是运行时发生的,编译器确定不了,交给jvm去做比较合适。而对于局部变量而言,其赋值和取值访问顺序是确定的。这样设计是一种约束,尽最大程度减少使用者犯错的可能(假使局部变量可以使用默认值,可能总会无意间忘记赋值,进而导致不可预期的情况出现)。
6. ReadWriteRock 读写锁,使用场景可分为读/读、读/写、写/写,除了读和读之间是共享的,其它都是互斥的,接着会讨论下怎样实现互斥锁和同步锁的, 想了解对方对AQS,CAS的掌握程度,技术学习的深度。
7. Semaphore拿到执行权的线程之间是否互斥,Semaphore、CountDownLatch、CyclicBarrier、Exchanger 为java并发编程的4个辅助类,面试中常问的 CountDownLatch CyclicBarrier之间的区别,面试者肯定是经常碰到的, 所以问起来意义不大,Semaphore问的相对少一些,有些知识点如果没有使用过还是会忽略,Semaphore可有多把锁,可允许多个线程同时拥有执行权,这些有执行权的线程如并发访问同一对象,会产生线程安全问题。
8. 写一个你认为最好的单例模式, 这题面试者都可能遇到过,也算是工作中最常遇到的设计模式之一,想考察面试者对经常碰到的题目的理解深度,单例一共有几种实现方式:饿汉、懒汉、静态内部类、枚举、双检锁,要是写了简单的懒汉式可能就会问:要是多线程情况下怎样保证线程安全呢,面试者可能说双检锁,那么聊聊为什么要两次校验,接着会问光是双检锁还会有什么问题,这时候基础好的面试者就会说了:对象在定义的时候加上volatile关键字,接下来会继续引申讨论下原子性和可见性、java内存模型、类的加载过程。
其实没有最好,枚举方式、静态内部类、双检锁都是可以的,就想听下对不同的单例写法认识程度,写个双检锁的方式吧:
9. B树和B+树,这题既问mysql索引的实现原理,也问数据结构基础,首先从二叉树说起,因为会产生退化现象,提出了平衡二叉树,再提出怎样让每一层放的节点多一些来减少遍历高度,引申出m叉树,m叉搜索树同样会有退化现象,引出m叉平衡树,也就是B树,这时候每个节点既放了key也放了value,怎样使每个节点放尽可能多的key值,以减少遍历高度呢(访问磁盘次数),可以将每个节点只放key值,将value值放在叶子结点,在叶子结点的value值增加指向相邻节点指针,这就是优化后的B+树。然后谈谈数据库索引失效的情况,为什么给离散度低的字段(如性别)建立索引是不可取的,查询数据反而更慢,如果将离散度高的字段和性别建立联合索引会怎样,有什么需要注意的?
10. 生产者消费者模式,synchronized锁住一个LinkedList,一个生产者,只要队列不满,生产后往里放,一个消费者只要队列不空,向外取,两者通过wait()和notify()进行协调,写好了会问怎样提高效率,最后会聊一聊消息队列设计精要思想及其使用。
11. 写一个死锁,觉得这个问题真的很不错,经常说的死锁四个条件,背都能背上,那写一个看看,思想为:定义两个ArrayList,将他们都加上锁A,B,线程1,2,1拿住了锁A ,请求锁B,2拿住了锁B请求锁A,在等待对方释放锁的过程中谁也不让出已获得的锁。
12. cpu 100%怎样定位,这题是一个应用性题目,网上搜一下即可,比较常见,说实话,把这题放进来有点后悔。
13. String a = "ab"; String b = "a" + "b"; a ,b 是相等的(各位要写代码验证一下,我看到有人写了错误答案)。常规的问法是new一个对象赋给变量,问:这行表达式创建了几个对象,但这样的题目太常见。
14. int a = 1; 是原子性操作。
15. for循环直接删除ArrayList中的特定元素是错的,不同的for循环会发生不同的错误,泛型for会抛出 ConcurrentModificationException,普通的for想要删除集合中重复且连续的元素,只能删除第一个。
错误原因:打开JDK的ArrayList源码,看下ArrayList中的remove方法(注意ArrayList中的remove有两个同名方法,只是入参不同,这里看的是入参为Object的remove方法)是怎么实现的,一般情况下程序的执行路径会走到else路径下最终调用faseRemove方法,会执行System.arraycopy方法,导致删除元素时涉及到数组元素的移动。针对普通for循环的错误写法,在遍历第一个字符串b时因为符合删除条件,所以将该元素从数组中删除,并且将后一个元素移动(也就是第二个字符串b)至当前位置,导致下一次循环遍历时后一个字符串b并没有遍历到,所以无法删除。针对这种情况可以倒序删除的方式来避免
解决方案:用 Iterator。
将本问题扩展一下,下面的代码可能会出现什么问题?
--2019.2.7更新(写了16 - 23题解答大纲)
16. 第一步 :线程池判断核心线程池里的线程是否都在执行任务。如果不是,则创建一个新的工作线程来执行任务。如果核心线程池里的线程都在执行任务,则执行第二步。
第二步 :线程池判断工作队列是否已经满。如果工作队列没有满,则将新提交的任务存储在这个工作队列里进行等待。如果工作队列满了,则执行第三步。
第三步 :线程池判断线程池的线程是否都处于工作状态。如果没有,则创建一个新的工作线程来执行任务。如果已经满了,则交给饱和策略来处理这个任务。
17. 抽象队列同步器AQS(AbstractQueuedSychronizer),如果说java.util.concurrent的基础是CAS的话,那么AQS就是整个Java并发包的核心了,ReentrantLock、CountDownLatch、Semaphore等都用到了它。AQS实际上以双向队列的形式连接所有的Entry,比方说ReentrantLock,所有等待的线程都被放在一个Entry中并连成双向队列,前面一个线程使用ReentrantLock好了,则双向队列实际上的第一个Entry开始运行。AQS定义了对双向队列所有的操作,而只开放了tryLock和tryRelease方法给开发者使用,开发者可以根据自己的实现重写tryLock和tryRelease方法,以实现自己的并发功能。
比较并替换CAS(Compare and Swap),假设有三个操作数:内存值V、旧的预期值A、要修改的值B,当且仅当预期值A和内存值V相同时,才会将内存值修改为B并返回true,否则什么都不做并返回false,整个比较并替换的操作是一个原子操作。CAS一定要volatile变量配合,这样才能保证每次拿到的变量是主内存中最新的相应值,否则旧的预期值A对某条线程来说,永远是一个不会变的值A,只要某次CAS操作失败,下面永远都不可能成功。
CAS虽然比较高效的解决了原子操作问题,但仍存在三大问题。
循环时间长开销很大。只能保证一个共享变量的原子操作。ABA问题。18. synchronized (this)原理:涉及两条指令:monitorenter,monitorexit;再说同步方法,从同步方法反编译的结果来看,方法的同步并没有通过指令monitorenter和monitorexit来实现,相对于普通方法,其常量池中多了ACC_SYNCHRONIZED标示符。
JVM就是根据该标示符来实现方法的同步的:当方法被调用时,调用指令将会检查方法的 ACC_SYNCHRONIZED 访问标志是否被设置,如果设置了,执行线程将先获取monitor,获取成功之后才能执行方法体,方法执行完后再释放monitor。在方法执行期间,其他任何线程都无法再获得同一个monitor对象。
这个问题会接着追问:java对象头信息,偏向锁,轻量锁,重量级锁及其他们相互间转化。
19. 理解volatile关键字的作用的前提是要理解Java内存模型,volatile关键字的作用主要有两点:
多线程主要围绕可见性和原子性两个特性而展开,使用volatile关键字修饰的变量,保证了其在多线程之间的可见性,即每次读取到volatile变量,一定是最新的数据代码底层执行不像我们看到的高级语言—-Java程序这么简单,它的执行是Java代码–>字节码–>根据字节码执行对应的C/C++代码–>C/C++代码被编译成汇编语言–>和硬件电路交互,现实中,为了获取更好的性能JVM可能会对指令进行重排序,多线程下可能会出现一些意想不到的问题。使用volatile则会对禁止语义重排序,当然这也一定程度上降低了代码执行效率从实践角度而言,volatile的一个重要作用就是和CAS结合,保证了原子性,详细的可以参见java.util.concurrent.atomic包下的类,比如AtomicInteger。
20. AOP 和 IOC是Spring精华部分,AOP可以看做是对OOP的补充,对代码进行横向的扩展,通过代理模式实现,代理模式有静态代理,动态代理,Spring利用的是动态代理,在程序运行过程中将增强代码织入原代码中。IOC是控制反转,将对象的控制权交给Spring框架,用户需要使用对象无需创建,直接使用即可。AOP和IOC最可贵的是它们的思想。
21. 什么是循环依赖,怎样检测出循环依赖,Spring循环依赖有几种方式,使用基于setter属性的循环依赖为什么不会出现问题,接下来会问:Bean的生命周期。
22. 上一张图,从这张图去理解
具体流程:
1). 用户发请求-->DispatcherServlet,前端控制器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制。
2).DispatcherServlet-->HandlerMapping,HandlerMapping将会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器,多个HandlerInterceptor拦截器)。
3).DispatcherServlet-->HandlerAdapter,HandlerAdapter将会把处理器包装为适配器,从而支持多种类型的处理器。
4).HandlerAdapter-->处理器功能处理方法的调用,HandlerAdapter将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理,并返回一个ModelAndView对象(包含模型数据,逻辑视图名)
5).ModelAndView的逻辑视图名-->ViewResolver,ViewResoler将把逻辑视图名解析为具体的View。
6).View-->渲染,View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构
7).返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户。
23. 先上结论:重复性较强的字段,不适合添加索引。mysql给离散度低的字段,比如性别设置索引,再以性别作为条件进行查询反而会更慢。
一个表可能会涉及两个数据结构(文件),一个是表本身,存放表中的数据,另一个是索引。索引是什么?它就是把一个或几个字段(组合索引)按规律排列起来,再附上该字段所在行数据的物理地址(位于表中)。比如我们有个字段是年龄,如果要选取某个年龄段的所有行,那么一般情况下可能需要进行一次全表扫描。但如果以这个年龄段建个索引,那么索引中会按年龄值根据特定数据结构建一个排列,这样在索引中就能迅速定位,不需要进行全表扫描。为什么性别不适合建索引呢?因为访问索引需要付出额外的IO开销,从索引中拿到的只是地址,要想真正访问到数据还是要对表进行一次IO。假如你要从表的100万行数据中取几个数据,那么利用索引迅速定位,访问索引的这IO开销就非常值了。但如果是从100万行数据中取50万行数据,就比如性别字段,那你相对需要访问50万次索引,再访问50万次表,加起来的开销并不会比直接对表进行一次完整扫描小。
当然如果把性别字段设为表的聚集索引,那么就肯定能加快大约一半该字段的查询速度了。聚集索引指的是表本身数据按哪个字段的值来进行排序。因此,聚集索引只能有一个,而且使用聚集索引不会付出额外IO开销。当然你得能舍得把聚集索引这么宝贵资源用到性别字段上。
可以根据业务场景需要,将性别和其它字段建立联合索引,比如时间戳,但是建立索引记得把时间戳字段放在性别前面。
感谢各位知友,作者这段时间在构思写一个Java知识精要系列,将java知识点全部串起来,适用于各个层次的java学习者,有兴趣可以关注下。
后加
jvm gc 复制算法是怎样实现的注解的原理进程间通信的方式有哪些ReentrantLock 是可重入锁,什么是可重入锁线程执行过程中遇到异常会发生什么,怎样处理HashMap put()元素产生冲突,为什么用LinkedList(拉链法)而不用ArrayList解决,产生冲突时key值不等,新元素怎样加入链表,为什么这么设计(jdk1.8之前)双检锁写一个单例模式,为什么要用volatile修饰对象,Object object = new Object(); object为null吗?为什么Object object = new Object(); 初始化的顺序是什么在jvm各区域做了什么线程怎样按顺序执行true or false ?11. 修饰类的锁和修饰方法的锁的区别
12. 下面代码中的method()方法会互斥访问吗,为什么
13. synchronized在1.7以后的版本作了什么优化提升效率
14.CAS底层是怎样实现原子性的
15.java线程池实现的原理
16. 算法题:各大排序算法(尤其是快排和堆排序),查找(二分),树的遍历,DFS和BFS...
后加的16个题目只能说是常规题型,网上解答都有,在此不写答案了,腾出时间最近一直想写个java知识精要系列。
参考资料:
《java编程思想》
《Effective Java 第三版》
《深入理解java虚拟机》
《高性能Mysql》
《Spring实战》
《数据结构-使用C++语言描述》
回答私信我的问题: 我是从2017/10开始接触java的,特别喜欢专研技术
关注我吧 Mingdeng Yue