转载

云从科技Java一面面经

8 月 31 号晚上 8 点 30 视频面试的,面试官还可以,问的不算深,也都是基础知识。但是由于是第一次视频面试,有点紧张导致思路有点短路,有些关键点还是回答的不算好或者直接没回答上来,后面还要继续努力啊。。

  1. 先自我介绍,然后介绍一下最近做的项目,由于在实习,所以说的是实习中正在做的项目,项目中涉及到了 Netty,面试官对这个比较感兴趣,问我实习项目中 Netty 流量有多大,然而实际上我还没开始写 Netty 相关的业务…所以只能说不知道,目前还在看文档。面试官就没多问了,下面就是问 Java 基础。
  2. Java 基础你应该很了解吧,说说 Java 面向对象的三大特性?答封装、继承和多态,然后问你觉得多态的特点是什么?(ps:上次面试也问了我多态的原理)我说多态可以实现代码的可扩展性,具体举了个例子比如在一个已经交付的工程代码中,一个类的方法需要进行扩展,但是这时候改动这个类的源代码可能会引出意向不到的 BUG,这时候就可以先利用继承,对这个需要扩展的类实现一个子类继承它,然后在子类中增强父类的方法,最后在需要改动代码的地方(创建对象的地方,这里口述没有表达清楚)使用父类指向子类的引用,这样既不会改动太多源代码,又能很好的对现有类进行扩展。说完后可能意思表达有点欠缺,面试官追问这样的话多态和继承有什么区别呢,然后我说多态实现有三个条件,子类继承父类,子类重写父类的方法,父类指向子类的引用,最大的区别就是父类指向子类的引用这里,这里才是多态可扩展性的体现。这个问题我回答的不是很好,面试官可能更想听到对象不同行为不同这种观点吧…
  3. Java 容器你很清楚吧,那你说下 JDK1.8 后的 Map 的实现?我说既然是 Map,那就以最常用的 HashMap 举例, JDK1. 8后 HashMap 从数组+链表方法优化为数组+链表+红黑树的实现方式,链表长度默认超过 8 时会转化为红黑树,红黑树的搜索效率比长链表要高。然后他就问那你觉得红黑树相比其它树好在哪里,为什么采用红黑树?我说红黑树搜索效率高于普通二叉树,但是没有完全搜索二叉树效率高,应该是一种折中的体现吧(这里瞎掰了,回答是错误的,采用红黑树是因为红黑树的搜索、删除、插入最坏时间复杂度都为 O(logn))。那你说说容器中的 Map 使用的时候有哪些需要注意的地方?面试官这个问题提的有点突然,导致我也没完全想清楚,就按照能够想到的回答了,还是以 HashMap 为例,首先 HashMap 是线程不安全的,使用的时候需要注意单线程还是多线程环境,如果是多线程的话需要使用 ConcurrentHashMap 或者 Collections 类中的静态方法 synchronizedMap() 方法实现线程安全的 HashMap;第二点就是使用 HashMap 存储引用类型时,需要同时覆盖 equals 和 hashCode 方法。然后面试官说我第二点说的可以,一般人都想不到这点。。。但是事后我记起来我忘了说第三点,也是可以直接深入源码层面分析的,就是由于 HashMap 扩容机制的存在,使用前如果能大概知道容器存储的容量,在创建 Map 时就要指定容量,因为 HashMap 的 resize() 扩容机制效率是很影响性能的。。。不该啊。。
  4. JVM 你了解吗?我说了解一些,那你说说 1.8 后的 JVM 内存收集算法?我说 JDK1.8 后 HotSpot 虚拟机引入了 G1 收集器,即 G1 收集算法,然后他问那你说说 G1 算法的特点?我答 G1 算法主要是新生代区域和老年代区域之间不再物理隔离,而是将整个内存区域分为了一块块小的 region 区域,G1 主要是对这个 region 区域进行回收,并且由于细分了区域,可以实现优先回收价值较大的区域,这样可以达到一个可预测停顿时间(即 STW 时间)的效果。然后他问那你觉得 G1 算法和标记算法的区别是什么?我答标记算法主要分为两种:标记-清除和标记整理算法,标记清除算法会产生不连续的内存碎片,如果下一次放入大对象的话没有连续内存分配可能会提前触发Full-GC影响性能,标记整理算法会将空闲内存区域整理在一起,但是这样做效率比较低。而 G1 算法则是取二者的优点。
  5. 然后继续问你了解双亲委派机制吗?我说了解,他问那你说说双亲委派机制中有几个类加载器?我答有三个,一个是启动类加载器,一个应用程序类加载器,一个扩展类加载器。然后他继续问双亲委派机制的作用是什么?我说主要是为了维护 JDK 基础类的统一,比如我自定义一个 String 类,通过双亲委派机制是没有办法覆盖掉 JDK 中的 String 类的。然后他问那如何破坏双亲委派机制?这个问题我没有答上来,我想了一下说是通过自定义类加载器修改类加载条件进行破坏,面试官没有回答我说的是否正确。。。各位可以自己百度一下答案。
  6. 多线程你了解吧?我说了解,那你说说悲观锁和乐观锁?我说悲观锁就是线程在更新操作时总是认为会有其它线程来竞争,所以悲观锁会先进行加锁,如 Synchronized 和 ReentrantLock 都是乐观锁的实现,乐观锁就是线程在更新操作时总认为不会有其它线程跟自己竞争,那么这个线程在更新操作时会尝试去进行更新,如果更新成功就成功,如果失败就采取失败策略,常用的失败策略就是自旋,乐观锁的实现最常见的就是 CAS。
  7. 然后他问你知道数据库中如何实现乐观锁的吗?这个好像是面试常问题。。但是我还没复习完数据库。。仅凭记忆说了一下好像是使用 select xxx for update。。然后他说这是悲观锁。。。好吧丢人丢大发了。。。
  8. 然后又问了我数据库索引?我说常见的有哈希索引和 B+ 树索引,他问我什么时候使用哈希索引什么时候使用 B+ 树索引,我说哈希索引应该在数据量不是很大的时候用(这里就是瞎掰了,哈希计算应该是数据量越大越有效,事后看了一下 MySQL 中哈希索引是自适应的,不能人为干预哈希索引的创建),B+ 树索引主要是针对数据库 I/O 操作优化的索引结构,所以二者区别就在于 I/O 操作上。
  9. 回到多线程,那你说说原子类的实现原理?我说原子类中有原子更新基本类型、原子更新数组类型、原子更新引用类型等,最常用的就是 AtomicInteger 这个原子类,它的底层调用的 unsafe 类的 CompaerAndSwapInt() 方法,使用的 CAS 机制实现。
  10. 最后问了 IO,先问从 1.8 之后,JAVA 中的 IO 分为哪几类?我答分为传统的阻塞 IO 就是 BIO,非阻塞 IO 就是 BIO,异步非阻塞 IO 就是 AIO。然后问了一下 NIO 和 AIO 的区别?这个问题不难。。但是没答上来,我只说 NIO 是一个 Selector 轮询 Channel 通道,AIO 采用的是事件去驱动模型,具体的实现我答不上来,然后直接坦白说这方面我实在了解不多。。
  11. 最后问了我有什么需要问他的,我问了两个问题,一个是云从科技目前 Java 是在做什么方向,一个是我目前还有哪些地方需要加强,第二个问题面试官说从刚才的表现,有三个方面需要加强,一个是数据库方面,数据库的索引和锁机制需要熟悉(这个确实还没复习完。。。),一个是 IO 操作,最后一个是网络 Socket 编程,第二个和第三个可以说是一个问题,就是加强 NIO 和 AIO 的原理理解,如果能了解 Netty 框架原理更好。。
原文  https://bestzuo.cn/posts/3578976493.html
正文到此结束
Loading...