美文网首页SSM社区SSH社区java
关于Java面试,你应该准备这些知识点

关于Java面试,你应该准备这些知识点

作者: 美团Java | 来源:发表于2017-03-12 16:31 被阅读53782次

简书 占小狼
转载请注明原创出处,谢谢!
如果读完觉得有收获的话,欢迎点赞加关注

自天子以至于庶人,壹是皆以修身为本 《礼记·大学》


马老师说过,员工的离职原因很多,只有两点最真实:

  • ,没给到位
  • ,受委屈了

当然,我是想换个平台,换个方向,想清楚为什么要跳槽,如果真的要跳槽,想要拿到一个理想的offer,除了运气,基本功也要足够的扎实,希望下面的面试经验能给你们能够提供一些帮助。

项目经验

面试官在一开始会让你进行自我介绍,主要是想让你介绍一下自己做过的一些项目,看看你对这些项目的了解程度,因为很多人简历上写的项目并非都是从头到尾都参与的,有些只是参与并实现了其中的一些模块而已,或是接手维护别人的项目,所以在你简历上所写的和面试过程中所说的项目经验,你自己必须能够了解来龙去脉,因为面试官肯定会根据你的项目描述,对项目中的实现原理,或为什么要这样实现进行提问,这时不至于木讷住而不知如何作答,如此局面只会大大降低面试分。

场景对话:
面试官:(拿着简历)讲讲你最近做的这个项目

我:&……%¥#*&¥@%¥!,说了一大通(不知道面试官听进去多少,面试官会挑他会的进行提问)

面试官:你说这个项目中用到了netty,能大概讲讲netty的线程模型么?

我:(幸好我看过netty的源码)netty通过Reactor模型基于多路复用器接收并处理用户请求(能讲就多讲一点),内部实现了两个线程池,boss线程池和work线程池,其中boss线程池的线程负责处理请求的accept事件,当接收到accept事件的请求时,把对应的socket封装到一个NioSocketChannel中,并交给work线程池,其中work线程池负责请求的read和write事件(通过口述加画图的方式,把请求的执行过程大概描述了一遍,时间有限,也不可能把所有的细节都说完,挑重点讲,挑记忆深刻的讲)

面试官:嗯,理解的还挺深入的...那你在做这个项目时有没有遇到什么困难,或者是觉得有挑战的地方?

我:(这时面试官想让你自己出题自己回答了,所以一定要回答,不回答就突显不出你这个项目了,要是这个问题没有准备过,只能临时发挥了,当然我就是属于临时发挥的)稍微想一下,因为之前确实碰到了这个问题,当时做这个项目时,对netty的不过熟悉,把请求的业务逻辑放在work线程池的线程中进行处理,进行压测的时候,发现qps总是上不去,后来看了源码之后才发现,由于业务逻辑的处理比较耗时,完全占用了work线程池的资源,导致新的请求一直处于等待状态。

面试官:那最后是如何解决的?

我:最后把处理业务的逻辑封装成一个task提交给一个新建的业务线程池中执行,执行完之后由work线程池执行请求的write事件。

面试官:好的,你知道nio中selector可能触发bug么?

我:嗯,对的,selector的select方法,因为底层的epoll函数可能会发生空转,从而导致cpu100%。

面试官:那如何解决该问题?

我:这个问题在netty已经解决了,通过&%&$(把netty的解决方案说一遍)

面试官:嗯,对了,你们这个项目有给自己定指标么?

我:有的,&&…………¥¥##@,把自己项目的指标说了一通,如何进行AB实验,如何迭代优化指标

面试官:嗯,好的 ,项目的问题先到这里,我们来考察一下java的基本点吧。

如上只是本人所做的一个项目,当然了,具体项目具体分析,也不是每个面试官问的点都一样,如果面试官不懂netty,自然会挑别的问题进行提问,不过你也可以尝试着把问题往自己熟悉的方向去靠。

面试知识点

1、线程池

线程池的实现原理,这个知识点真的很重要,几乎每次面试都会被问到,一般的提问方式有如下几种:
1、“讲讲线程池的实现原理”
2、“线程池中的coreNum和maxNum有什么不同”
3、“在不同的业务场景中,线程池参数如何设置”

场景对话:
面试官:平时线程池用的多么?

我:嗯,我的***项目中就用到了

面试官:那好,你讲讲线程池的实现原理

我:(还好我之前看过源码,但是时间久远有点模糊了),能给我笔和纸么,我画图分析给你看看,&&¥&假设初始化一个线程池,核心线程数是5,最大线程数是10@@@

面试官:嗯,好的,你继续...

我:在纸上画了正方形,这个代表一个线程池,初始化的时候,里面是没有线程的

面试官:嗯,好的,你继续...

我:又画了一个细长的长方形,这个代表阻塞队列,一开始里面也是没有任务的

面试官:嗯,好的,你继续...

我:当来了一个任务时,在正方形中画了一个小圆圈,代表初始化了一个线程,如果再来一个任务,就再画一个圆圈,表示再初始化了一个线程,连续画了5个圆圈之后,如果第6个任务过来了...

面试官:嗯,好的,你继续...

我:这时会把第6个任务放到阻塞队列中..

面试官:嗯,然后呢?

我:现在线程池中不是有5个线程了么,如果其中一个线程空闲了,就会从阻塞队列中获取第6个任务,进行执行..

面试官:嗯,对的,那如果任务产生的速度比消费的速度快呢?

我:如果线程池的5个线程都在running状态,那么任务就先保存在阻塞队列中

面试官:如果队列满了,怎么办?

我:如果队列满了,我们不是设置了最大线程数是10么,而线程池中只有5个线程,这时会新建一个线程去执行不能保存到阻塞队列的任务,然后我又在正方形中画了5个圆圈。

面试官:那如果线程池中的线程数达到10个了,阻塞队列也满了,怎么办?

我:这种情况通过自定义reject函数去处理这里任务了,舒了一口去,以为问完了...

面试官:好的,那如果运行一段时间之后,阻塞队列中的任务也执行完了,线程池中的线程会怎么样?

我:...这个好像超过核心线程数的线程会在空闲一段时间内自动回收...因为有点不记得这个逻辑了,回答的有点虚...

面试官:好的,那这种情况在什么场景下会发生?

我:(有时候真是笨啊,很多东西都知道,但是在面试的时候一紧张,全忘记)这个...那个...我好像没有遇到过这样的情况

面试官:嗯,好的,你回去之后再好好想想

我:........

我居然忘记了秒杀这个场景

线程池分析的文章:
深入分析java线程池的实现原理

2、锁的实现

在关于锁的面试过程中,一般主要问Synchronized和ReentrantLock的实现原理,更有甚者会问读写锁。

场景对话:
面试官:都了解Java中的什么锁?

我:比如Synchronized和ReentrantLock...读写锁用的不多,就没研究了(我就怕被问读写锁,因为一直没去看)

面试官:那好,你先说说Synchronized的实现原理吧

我:嗯,Synchronized是JVM实现的一种锁,其中锁的获取和释放分别是monitorenter和monitorexit指令,该锁在实现上分为了偏向锁、轻量级锁和重量级锁,其中偏向锁在1.6是默认开启的,轻量级锁在多线程竞争的情况下会膨胀成重量级锁,有关锁的数据都保存在对象头中...&&@@#,(嗯,说了一大堆,面试官也没打断我)

面试官:哦,嗯,理解的还挺透彻,那你说说ReentrantLock的实现吧...

我:ReentrantLock是基于AQS实现的

面试官:什么是AQS?

我:在AQS内部会保存一个状态变量state,通过CAS修改该变量的值,修改成功的线程表示获取到该锁,没有修改成功,或者发现状态state已经是加锁状态,则通过一个Waiter对象封装线程,添加到等待队列中,并挂起等待被唤醒&&&$$(又说了一堆)

面试官:能说说CAS的实现原理么?

我:CAS是通过unsafe类的compareAndSwap方法实现的(心里得意的一笑)

面试官:哦,好的,那你知道这个方法的参数的含义的么?

我:(这是在逼我啊...努力的回想,因为我真的看过啊)我想想啊,这个方法看的时间有点久远了,第一个参数是要修改的对象,第二个参数是对象中要修改变量的偏移量,第三个参数是修改之前的值,第四个参数是预想修改后的值....(说出来之后都有点佩服自己,这个都记得,不过面试官好像还是不肯放过我...)

面试官:嗯,对的,那你知道操作系统级别是如何实现的么?

我:(我去你大爷...)我只记得X86中有一个cmp开头的指令,具体的我忘记了...

面试官:嗯,好,你知道CAS指令有什么缺点么

我:哦,CAS的缺点是存在ABA问题

面试官:怎么讲?

我:就是一个变量V,如果变量V初次读取的时候是A,并且在准备赋值的时候检查到它仍然是A,那能说明它的值没有被其他线程修改过了吗?如果在这段期间它的值曾经被改成了B,然后又改回A,那CAS操作就会误认为它从来没有被修改过。

面试官:那怎么解决?

我:(有完没完了啊...我的心里是崩溃的)针对这种情况,java并发包中提供了一个带有标记的原子引用类"AtomicStampedReference",它可以通过控制变量值的版本来保证CAS的正确性。

面试官:嗯,好的,这个问题到此为止,我们再看看别的

我:....我能喝口水么

关于锁分析的文章,希望对大家有用:
深入浅出java同步器AQS
java中的CAS
深入浅出synchronized
深入浅出ReentrantLock
java中的Unsafe
java volatile关键字解惑
深入分析Object.wait/notify实现机制
深入分析synchronized的JVM实现

3、ConcurrentHashMap

当考察数据结构时,面试官一开始会问HashMap的实现原理,当你说出HashMap并非线程安全之后,会让你自己引出ConcurrentHashMap,接着就可能开始如下的对话。

场景对话:
面试官:谈谈ConcurrentHashMap实现原理

我:@#¥@@基于分段锁的%%¥#@#¥,但是1.8之后改变实现方式了

面试官:1.8啥方式

我:把1.8的实现原理说了一通,其中提到了红黑树...

面试官:能讲下红黑树的概念吗

我:红黑树是一种二叉树,并且是平衡……%……¥……,

面试官:能讲下红黑树的。。。。。

我:打住,别问了,红黑树我只知道他是二叉树,比其他树多一个属性,其他的我都不知道
面试官:好的,那换个,你知道它的size方法是如何实现的么?

我:size方法?是想要得到Map中的元素个数么?

面试官:对的....

我:我记得好像size方法返回是不准确的,平时也不会用到这个方法...

面试官:如果你觉得size方法返回值不准确,那如果让你自己实现,你觉得应该怎么实现呢?

我:...@#¥@@...两眼一黑

我:等等,让我想想.....应该可以用AtomicInteger变量进行记录...嗯,对的,每次插入或删除的时候,操作这个变量,我得意的一笑...

面试官:哦,是么,那如果我觉得这个AtomicInteger这个变量性能不好,还能再优化么?

我:懵逼脸...(当时居然把volitile变量给忘记了)...好像没有了,我想不出来了...

面试官:哦,那回头你再看看源码吧,jdk中已经实现了...

我:哦,是么....

面试官:那今天的面试到此结束,我们后面会通知你。

我:..................

关于ConcurrentHashMap,本人也写过不少的分析文章,希望对大家有用:

深入浅出ConcurrentHashMap(1.8)
谈谈ConcurrentHashMap1.7和1.8的不同实现
ConcurrentHashMap的红黑树实现分析
深入分析ConcurrentHashMap1.8的扩容实现

相关文章

网友评论

  • 56d68d7eead9:看了之后我觉得我可以月入5万了
    56d68d7eead9:@李小振_9eec 我自己都不信
    李小振_9eec:我不信
  • 王虹凯:这个深度,阿里p8?
  • 年成:牛逼的一本
  • 332465dda43f:使用AtomicInteger来统计size没看懂,用volatile
    能提升性能吗?
    可能面试官想问的是分段加锁,每次只锁一段这样并发性能好吧
  • 7b68fbb83730:奇怪,JDK的size方法难道就准确么,很明显不准确吧
  • 延子木:写的挺清楚
  • hongrm:其实不应该局限于秒杀这个场景,对于突发的请求量飚增的情况应该都适用的。。。。。。每次看到这篇文章,你的自白的时候,我都笑了。。。。。:joy:
  • 6c75800b45cb:线程池那个 是什么场景 可否讲解下
    美团Java:@Lienson 秒杀场景吧,我有写
  • 3187f417bd7e:期待下一篇
    美团Java:@因为年轻_87b9 有下一篇
  • 5675283a4785:很像阿里的一面面试题
  • 3f973762f7d3:多谢分享
  • 我懒得取名::joy: 看了你的文章,觉得自己理解得还不够深入啊,面试容易被问懵逼。
  • 2ba07e9c88b0:不错 总结也不错 关联文章慢慢看
  • 0ccd048d238f:我想知道最后有没有被录用啊
    美团Java:@cf许我向你看 机智
    cf许我向你看:看楼上回复 楼主是最后没去。那就是录用了但是没去喽。
    美团Java:@攻城中坚大凤凰 哈哈,需要关注的是过程,不是结果啊:smiley:
  • bbcd5f7e4e70:楼主说的都研究过,就是时间有点久了,温习下了
  • RocWay:真有这么面的,估计是该公司是要自己实现一个JDK
  • RocWay:面之霸
  • 55ccbdd188f6:比AtomicInteger性能更好的是1.8jdk中的LongAdder
    美团Java:@淡漠wei :+1:
  • fb919fa2aa73:如果线程池的5个线程都在running状态,那么任务就先保存在阻塞(wait)队列中
    不是还有就绪(ready)队列.怎么保存到阻塞队列呢
    阻塞队列一般不是需要依赖于另一线程是才会阻塞吗
    小的刚出道才疏学浅求大神指教一下
    美团Java:@wwwfumeckcom 这里的阻塞队列是java层面的数据结构
  • Yyycc:有个疑问 工作线程 会处理队列中的任务么 还是只完成当前任务 然后结束
    美团Java:@Yyycc 工作线程一直会等待任务的提交
  • 老衲用清扬:三年经验,完全不知道这些,惭愧
  • 90bb5aacf3ff:最近在准备面试,这个看了好几次,看次笑一次 狼哥挺逗的,期望以后有更多的优秀博文
    美团Java:@䒕愺 哈哈,诙谐,幽默
  • 49567fe01c8d:netty面试那个能否些详细些?比如你画的图也画出来一下。还有一个问题想请教,客户端发送一条消息,服务端接收,并处理结果同步又返回结果。客户端是如何收到的。相当于一个rpc的同步方法调用,netty是如何实现的?
  • JerryDai:写的好好,请问一下楼主有多少年工作经验了?
    美团Java:@JerryDai 目前在上海
    JerryDai:@占小狼 表示惭愧,我工作了满满五年了,对于这些还是一知半解的。。。话说你在哪里上班?我在广州。哈哈
    美团Java:@JerryDai 快4年了
  • 9d000f677274:一般面试官水平有那么高么? 我去面试 都是同级员工来随便问我一些工具和日常编写习惯
    美团Java:@Franky木下 哈哈哈,虐一次就知道了
    Franky木下:同学一定没被阿里折腾过。
    美团Java:@Lazy_7db8 有的,看什么公司了
  • BennyTian:特别想请问以下: 这类面试题的话 一般都是什么级别的开发才会问啊? 高级开发? 高级架构 ? 我觉得中初级的没记得知道这些的吧 ?
    美团Java:@BennyTian :beer:
    BennyTian:好吧 原来是专家 我说呢 作为一个工作了N年的码农 既然对这些问题一知半解 备受打击 建议:在帖子中声明一下 要不然这面试题 会打击太多初中级的程序员了

    最后 文章写的真的超棒的 都是楼主的亲身经历与感受 让我知道自己未来的学习方向 真心感谢!
    美团Java:@BennyTian 资深->技术专家
  • a298dae82d66:水平不错,还面试啊
    美团Java:@yqf1991 :joy:
    a298dae82d66: 直接晒博客算了
  • 4e34bdcfcb25:大神可以写篇程序员网络小说一定畅销
    美团Java:@discoverX 哈哈哈
  • 白马王朗:你别喝口水,我们有瓶装水😂
    93eb7d0099af: @米有昵称 😂😂😂
    美团Java:@米有昵称 :joy:
  • 憩在河岸上的鱼丶:之前在阿里云论坛上见过这篇文章,,你面的是什么职位啊?最后进去了没?
    憩在河岸上的鱼丶:找不到那个链接了,也有可能是我记错了。。
    美团Java:@憩在河岸上的鱼丶 嗯,阿里论坛也有?最后我没去
  • 神灯的灯芯:很强势!
    美团Java:@林小柒_ 哈哈哈哈
  • 多喝水JS:大神,谢谢了,刚好要准备面试,好文章啊
    美团Java:@朝阳区尼克杨 :relieved:
  • justZero:小狼哥,你面试的什么岗啊?看完之后觉得自己太小看java了,还有这么多东西。
  • 花式造bug:楼主,我想问下上面的面试场景都是针对什么岗位的,感觉都是Java SE的基础知识,但是深度真的是让我一脸懵,好受打击:sob:
    美团Java:@阮_d45f 加油
  • 白马王朗:敢问楼主毕业多长时间,对于这些源码如何学习与记忆
  • ea8e3575a74f:狼哥,昨天面试我就是这样啊
    你知道hashmap和treemap的原理吗
    我,hashmap是hash,treemap是红黑树
    你说说红黑树的结构
    我,红黑树是基于平衡二叉树。。。。。
    你写一下红黑树的旋转方式
    我,我不是很懂红黑树啊,没怎么看过
    你说一下红黑树的时间复杂度,最差的情况,最好的情况
    我,思考了3分钟,说了一下ologn,然后说我真的不会红黑树啊
    很简单嘛。。。。。
    我,。。。。。
    美团Java:@科比8中8 哈哈,多面面多准备
    ea8e3575a74f:@占小狼 最后gg了🙄
    美团Java:@科比8中8 噗,居然让你写旋转算法,你可以让面试官当场写,不一定能写出来啊:smile:
  • c0af7cbb0ad5:经典问题
    美团Java:@青花瓷 是啊,好多面试都会问
  • 蚂蚁学Python:size方法,先计算两次大小,如果发现两次不一样,就对整个map加锁计算大小
    7b68fbb83730:@占小狼 是对各个段加锁吧,即使这样,算出来的还是不准确的
    美团Java:@麻神无易 嗯,这是1.7实现
  • zouzls:写的挺好的,不过有个疑问,在ConcurrentHashMap中用volitile变量来进行计数是行不通的吧?这感觉是典型的线程不安全计数。
    美团Java:@zouzls 后来想想确实,还是用cas
  • 我小时候可猛了_:楼主工作多久了啊?
  • e0e671e24011:狼神你好,觉得你写的非常棒,好多知识也是跟着你的文章入手一点一点学到的。谢谢分享。
    e0e671e24011:@占小狼 请问狼神有github或者自己的博客之类的么?除了简书平台之外的,想关注一下:smile:
    美团Java:@时无两丶 加油,共勉
  • 8455c3716768:我觉得基础的数据结构和算法的问题可以问问,但是问到这么细节的东西有点儿变态了。毕竟大部分应用开发都不用知道这么细节的东西,知道第三方发提供的东西有哪些功能有什么坑就够了,能把需求落地才是更重要的问题,像孔乙己一样知道茴字的四种写法貌似也没什么用。

    不过我的意思不是不赞成个人去学习这些,我是不赞成面试官这么去面试。
    美团Java:@MarkDong 嗯,理论加实践,如果没有理论就无法实践
    8455c3716768:@占小狼 但是我见过很多把这些背的熟熟的,但是却无法把现实中的概念合理抽象出来的程序员
    美团Java:@MarkDong 第一点,知道底层实现以后写出来的代码会更加好,第二点,如果线上出问题,知道底层实现可以快速定位问题,第三点,不知道底层实现,怎么做性能优化?
  • TS1023:挺好的
  • _lory:一脸懵逼,菜鸟只能膜拜了
    美团Java:@Aut丶落尘 加油
  • 蚂蚁学Python:膜拜!!
    美团Java:@麻神无易 :smile::smile:
  • ce5a182db8aa:写的真好,关注你,期待。要走的路还有很长很长
    美团Java:@辰夕小狼睡不醒 感谢肯定
  • ce5a182db8aa:您说的笨神?是谁?博主,能否告知一下
    石頭剪刀b_:@辰夕小狼睡不醒 你假笨
    美团Java:@辰夕小狼睡不醒 @追随哥 http://lovestblog.cn/
    美团Java:@辰夕小狼睡不醒 就是目前国内玩jvm比较溜的一个人
  • snowfox09:你好,感谢分享! 关于项目定指标这一块能详细说一下吗?我想了解一个web项目在定指标的时候都有哪些策略和方法,谢谢!
    美团Java:@snowfox09 定指标是一个长期的过程,不是一天两天就可以发现的,这需要经验,一些通用的指标可以共用,如系统可用率什么的,具体要什么指标还是看具体的项目
  • Demonnnn:膜拜下:scream:
    美团Java:@_Qwerty 面试的岗位不一样吧
    Demonnnn:@占小狼 我也刚面试完,画风完全不一样啊:joy:关注了,期待你的持续好文
    美团Java:@_Qwerty 都是一些java知识
  • 都是什么乱七八糟的:狼哥请教关于线程状态的问题,线程在竞争synchronized的锁时如果竞争失败了线程的状态是blocked,如果线程在竞争reentrantlock锁失败的是waiting状态还是blocked状态?
    靳刚:当线程初次获取锁失败时,会加到队列尾部,此时是blocked,然后会进行自旋操作,如果获取失败被挂起后,处于waiting状态,当被唤醒后又处于blocked,再进行自旋操作,如此反复,知道获取锁,或者是被中断后,抛异常退出.
  • 754c54f0ba62:大神,给跪了!学了点NIO,Tomcat的实现就以为自己很牛逼了,天下大可走一走了。。。。没想到我他么还差十万八千里,不说了还是好好学习吧。顺便问下博主:平时都是写一些spring框架下的业务代码,增删改查啥的,如果才能快速学习到这些深层原理呢?
    美团Java:@clearbug 一切精髓都在源码
    754c54f0ba62:@占小狼 嗯嗯谢谢!
    美团Java:@clearbug 可以多花点时间看点底层相关的源码实现,如果你用spring,也可以看看源码
  • 83430e07ccd9:可怕,要学的太多了。
    美团Java:@南桥北边 加油啊
  • 北京程序猿:卧槽,真给力,比我强,向你学习,自己理解的还是太肤浅了
    美团Java:@JasonQiang 加油
  • 33d31a1032df:明天就要面试了,才发现还有这么多知识点
  • b3f0a97277d3:狼哥厉害,学习膜拜了
  • 29679c0b5687:假设我线程池执行的都是一些持久的任务,当线程池 core 线程用完后,后续持久线程就不能在加入了吗?会在队列一直等待?(场景:前台可控制的 socket 通信,创建许多持久连接,这种情况下用线程池有么有问题?)
    美团Java:@abel533 嗯,如果这个时候cpu使用率不高的话,就需要调整core的大小了,只有队列满了才有再添加工作线程
  • 7f25725765be:完全不会。。
    7f25725765be: @占小狼 好的
    美团Java:@Sterben_Da 如果面试高级别岗位,这些肯定是会问的
  • 技术达人丶小强:同是搞java的,你这面试的知识点让我有点陌生啊!
    美团Java:@技术达人丶小强 :joy:
  • 658627198b7a:好厉害
    美团Java:@hah5656 :smile:
  • 仰望星空的张拭心:小狼工作几年了呢?:smiley:
    美团Java:@仰望星空的张拭心 哈哈,这个看个人能力的
    仰望星空的张拭心:@占小狼 想了解下这个难度是对应几年的:fearful:
    美团Java:@仰望星空的张拭心 为何问这个
  • Terror_Blade:这个难度是哪个厂的面试呢?
    美团Java:@Terror_Blade 我只是写了一点,后续还有蛮多的...加油,面试过程都是你来我往的
    Terror_Blade:@占小狼 感谢,一直想换份工作,感觉基础也差不多了,最纠结的就是项目经验这一块,感觉没啥特色。因为之前看过网上相关经验,感觉项目中所用的技术原理问的都比较深入,而这些又太庞杂了,就一直没去投简历。如果都是您这篇文章中的类似模式,感觉也可以尝试一下了
    美团Java:@Terror_Blade A场还有别的
  • chiweng2009:好棒
    期待下一篇:smile:
  • xingdong:好的
  • c55d781b7f8f:谢谢
    美团Java:@Chris_Andersen :smile:
  • jianshuhua:准备实习面试中,这篇来的正好,希望大神能马上出下篇~😀
    美团Java:@jianshuhua 会有下篇
  • 1c03edde03a9:狼哥是大神
    美团Java:@朝吻天下 :relaxed:
  • 16d23621bdc5:怎么把面试官带沟里?
    美团Java:@爱Lxn真好 你可以的

本文标题:关于Java面试,你应该准备这些知识点

本文链接:https://www.haomeiwen.com/subject/ucutnttx.html