以下是《互联网大厂 Java 求职者面试三轮问答及答案》:
第一轮: 面试官:请你说说 Java 中的基本数据类型有哪些? 王铁牛:有 byte、short、int、long、float、double、char、boolean 这几种。 面试官:不错,那你说说它们各自的取值范围是多少呢? 王铁牛:(思考片刻)byte 的取值范围是 -128 到 127,short 是 -32768 到 32767,int 是 -2147483648 到 2147483647,long 是 -9223372036854775808 到 9223372036854775807,float 是单精度浮点数,double 是双精度浮点数,char 是 16 位 Unicode 字符,boolean 只有 true 和 false 两个值。 面试官:回答得很清晰,很准确,继续下一个问题,你了解 Java 中的面向对象特性吗? 王铁牛:了解,有封装、继承、多态。 面试官:能具体说说它们的作用吗? 王铁牛:封装可以隐藏对象的内部实现细节,提高代码的安全性和可维护性;继承可以实现代码的复用,子类可以继承父类的属性和方法;多态可以使同一个操作作用于不同的对象时可以有不同的表现形式。
第二轮: 面试官:在 Java 中,多线程的实现方式有哪些? 王铁牛:有继承 Thread 类和实现 Runnable 接口这两种方式。 面试官:那它们有什么区别呢? 王铁牛:(稍微犹豫)继承 Thread 类方式比较简单,但如果要继承多个类就不行了;实现 Runnable 接口方式更灵活,可以避免单继承的局限性。 面试官:很好,那你说说线程的生命周期有哪些状态? 王铁牛:有新建、就绪、运行、阻塞、死亡这几种状态。 面试官:能详细说说每种状态的特点吗? 王铁牛:新建状态就是刚创建但还未启动的线程;就绪状态是线程已经准备好可以运行,但还没有被调度;运行状态就是线程正在执行代码;阻塞状态是线程因为某些原因暂停执行,比如等待锁或 I/O 操作;死亡状态就是线程执行完毕或出现异常结束。
第三轮: 面试官:你对 Java 中的集合框架了解吗?比如 ArrayList 和 HashMap。 王铁牛:知道,ArrayList 是数组列表,适合随机访问元素;HashMap 是哈希表,用于存储键值对。 面试官:那它们的底层实现原理是什么呢? 王铁牛:(开始慌乱)这个……不太清楚。 面试官:(失望)没关系,今天的面试就到这里,你可以回家等通知。
答案:
- Java 中的基本数据类型及其取值范围:
- byte:占 1 个字节,取值范围是 -128 到 127。
- short:占 2 个字节,取值范围是 -32768 到 32767。
- int:占 4 个字节,取值范围是 -2147483648 到 2147483647。
- long:占 8 个字节,取值范围是 -9223372036854775808 到 9223372036854775807。
- float:占 4 个字节,单精度浮点数。
- double:占 8 个字节,双精度浮点数。
- char:占 2 个字节,16 位 Unicode 字符。
- boolean:只有 true 和 false 两个值。
- Java 中的面向对象特性及作用:
- 封装:通过将数据和操作封装在类中,隐藏对象的内部实现细节,只对外提供公共的接口,提高了代码的安全性和可维护性。例如,在一个学生类中,可以将学生的姓名、年龄等属性封装起来,只提供获取和设置这些属性的方法,外部代码不能直接访问这些属性,从而避免了对属性的随意修改。
- 继承:子类继承父类的属性和方法,实现了代码的复用。子类可以根据自己的需求对父类的方法进行重写,以实现不同的功能。例如,动物类有一个 eat 方法,猫类继承自动物类,也有 eat 方法,但猫类的 eat 方法可能会有自己的特殊实现,比如吃猫粮。
- 多态:同一个操作作用于不同的对象时可以有不同的表现形式。多态性可以提高代码的灵活性和可扩展性。例如,定义一个接口动物,其中有一个 move 方法,猫类和狗类都实现了这个接口,在使用这个接口的地方可以根据具体的对象类型来调用不同的 move 方法,而不需要为每个具体的对象类型都编写一个相同的方法。
- Java 中多线程的实现方式及区别:
- 继承 Thread 类:这种方式比较简单,只需要创建一个继承自 Thread 类的子类,并重写 run 方法即可。在子类的构造函数中可以传递线程的名称等参数。使用这种方式创建线程时,子类本身就是一个线程对象,可以直接调用 start 方法启动线程。但是,如果要继承多个类,就只能选择实现 Runnable 接口。
- 实现 Runnable 接口:这种方式更灵活,因为 Java 只支持单继承,如果一个类已经继承了其他类,就不能再继承 Thread 类了,此时可以实现 Runnable 接口来创建线程。实现 Runnable 接口的类需要实现 run 方法,然后创建一个 Thread 对象,并将实现了 Runnable 接口的对象作为参数传递给 Thread 的构造函数,最后调用 start 方法启动线程。
- Java 中的集合框架及底层实现原理:
- ArrayList:底层是基于数组实现的。它可以动态地调整数组的大小,当添加元素时,如果数组已满,会创建一个新的更大的数组,并将原数组中的元素复制到新数组中。ArrayList 适合随机访问元素,因为可以通过索引直接访问数组中的元素,时间复杂度为 O(1)。但是在插入和删除元素时,需要移动数组中的元素,时间复杂度为 O(n)。
- HashMap:底层是基于哈希表实现的。哈希表是一种通过哈希函数将键映射到值的数据结构。在 HashMap 中,通过将键的哈希值作为数组的索引,将键值对存储在数组中。当插入一个键值对时,首先计算键的哈希值,然后根据哈希值找到数组中的位置,如果该位置已经有元素,就需要通过链表或红黑树来解决哈希冲突。HashMap 查找元素的时间复杂度为 O(1),但是在哈希冲突比较严重的情况下,查找效率会降低。
希望以上内容对你有所帮助,祝你在求职过程中顺利!