java 超详细面经整理(持续更新)2019.12.18

目录

  • Java SE
    • 请你谈谈Java中是如何支持正则表达式操作的?
    • 请你简单描述一下正则表达式及其用途。
    • 请你比较一下Java和JavaSciprt?
    • 在Java中如何跳出当前的多重嵌套循环?
    • 讲讲&和&&的区别?
    • int和Integer有什么区别?什么是自动拆装箱?
    • 请你讲讲如何输出一个某种编码的字符串?如iso8859-1等
    • 请你说明string和stringBuffer,stringBuilder的区别
    • 请你谈谈大O符号(big-O notation)
    • 请你讲讲数组(Array)和列表(ArrayList)的区别?什么时候应该使用Array而不是ArrayList?
    • 请你解释什么是值传递和引用传递?
    • 请你解释为什么会出现4.0-3.6=0.40000001这种现象?
    • 请你说说Lamda表达式的优缺点。
    • Java 中的 ==, equals 与 hashCode 的区别与联系
      • 请你说明符号“==”比较的是什么?
      • 请你阐述下equals()方法
      • 请你阐述下hashCode方法
      • 重写equals和hashcode方法
      • 请解释hashCode()和equals()方法有什么联系?
      • 小节
    • 请你解释Object若不重写hashCode()的话,hashCode()如何计算出来的?

准备2020年春招的苦逼研究生的备战之第1版

Java SE

请你谈谈Java中是如何支持正则表达式操作的?

Java中的String类提供了支持正则表达式操作的方法,包括:matches()、replaceAll()、replaceFirst()、split()。此外,Java中可以用Pattern类表示正则表达式对象,它提供了丰富的API进行各种正则表达式操作,如:

import java.util.regex.Matcher;
import java.util.regex.Pattern;
class RegExpTest {
    public static void main(String[] args) {
        String str = "成都市(成华区)(武侯区)(高新区)";
        Pattern p = Pattern.compile(".*?(?=\\()");
        Matcher m = p.matcher(str);
        if(m.find()) {
            System.out.println(m.group());
        }
    }
}

请你简单描述一下正则表达式及其用途。

在编写处理字符串的程序时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。计算机处理的信息更多的时候不是数值而是字符串,正则表达式就是在进行字符串匹配和处理的时候最为强大的工具。

请你比较一下Java和JavaSciprt?

JavaScript 与Java是两个公司开发的不同的两个产品。Java 是原Sun Microsystems公司推出的面向对象的程序设计语言,特别适合于互联网应用程序开发;而JavaScript是Netscape公司的产品,为了扩展Netscape浏览器的功能而开发的一种可以嵌入Web页面中运行的基于对象和事件驱动的解释性语言。JavaScript的前身是LiveScript;而Java的前身是Oak语言。
下面对两种语言间的异同作如下比较:

  • 基于对象和面向对象:Java是一种真正的面向对象的语言,即使是开发简单的程序,必须设计对象;JavaScript是种脚本语言,它可以用来制作与网络无关的,与用户交互作用的复杂软件。它是一种基于对象(Object-Based)和事件驱动(Event-Driven)的编程语言,因而它本身提供了非常丰富的内部对象供设计人员使用。
  • 解释和编译:Java的源代码在执行之前,必须经过编译。JavaScript是一种解释性编程语言,其源代码不需经过编译,由浏览器解释执行。(目前的浏览器几乎都使用了JIT(即时编译)技术来提升JavaScript的运行效率)
  • 强类型变量和类型弱变量:Java采用强类型变量检查,即所有变量在编译之前必须作声明;JavaScript中变量是弱类型的,甚至在使用变量前可以不作声明,JavaScript的解释器在运行时检查推断其数据类型。
  • 代码格式不一样。

在Java中如何跳出当前的多重嵌套循环?

在最外层循环前加一个标记如A,然后用break A;可以跳出多重循环。
(Java中支持带标签的break和continue语句,作用有点类似于C和C++中的goto语句,但是就像要避免使用goto一样,应该避免使用带标签的break和continue,因为它不会让你的程序变得更优雅,很多时候甚至有相反的作用,所以这种语法其实不知道更好)

讲讲&和&&的区别?

&运算符有两种用法:(1)按位与;(2)逻辑与。&&运算符是短路与运算。
&&之所以称为短路运算是因为,如果&&左边的表达式的值是false,右边的表达式不会进行运算。

例子:
例如在验证用户登录时判定用户名不是null而且不是空字符串,应当写为:username != null &&!username.equals(""),二者的顺序不能交换,更不能用&运算符,因为第一个条件如果不成立,根本不能进行字符串的equals比较,否则会产生NullPointerException异常。

int和Integer有什么区别?什么是自动拆装箱?

Java是一个近乎纯洁的面向对象编程语言,但是为了编程的方便还是引入了基本数据类型,但是为了能够将这些基本数据类型当成对象操作,Java为每一个基本数据类型都引入了对应的包装类型(wrapper class),int的包装类就是Integer,从Java5开始引入了自动装箱/拆箱机制,使得二者可以相互转换。

自动装箱是Java编译器在基本数据类型和对应的对象包装类型之间做的一个转化。比如:把int转化成Integer,double转化成Double,等等。反之就是自动拆箱。

请你讲讲如何输出一个某种编码的字符串?如iso8859-1等

Public String translate (String str) {
     String tempStr = “”;
     try {
     tempStr = new String(str.getBytes(“ISO-8859-1″), “GBK”);
     tempStr = tempStr.trim();
     }
     catch (Exception e) {
     System.err.println(e.getMessage());
     }
     return tempStr;
 }

请你说明string和stringBuffer,stringBuilder的区别

  • String类的内容一旦声明后是不可改变的,改变的只是其内存的指向,而StringBuffer类的对象内容是可以改变的。String类是不可变类,任何对String的改变都会引发新的String对象的生成;
  • 对于StringBuffer,不能像String那样直接通过赋值的方式完成对象实例化,必须通过构造方法的方式完成。
  • StringBuffer的在进行字符串处理时,不生成新的对象,在内存使用上要优于串类。所以在实际使用时,如果经常需要对一个字符串进行修改,例如插入,删除等操作,使用StringBuffer要更加适合一些。
  • StringBuilder,StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的
  • StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类,然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。

请你谈谈大O符号(big-O notation)

大O符号表示性能在渐进意义(n-->无穷)下的最坏情况。
大O描述当数据结构中的元素增加时,算法的规模和性能在最坏情景下有多好。
一般可以描述一个算法的时间复杂度和空间复杂度。

请你讲讲数组(Array)和列表(ArrayList)的区别?什么时候应该使用Array而不是ArrayList?

Array和ArrayList的不同点:

  • Array可以包含基本类型和对象类型,ArrayList只能包含对象类型。
  • Array大小是固定的,ArrayList的大小是动态变化的。
  • ArrayList提供了更多的方法和特性,比如:addAll(),removeAll(),iterator()等等。
  • 对于基本类型数据,集合使用自动装箱来减少编码工作量。但是,当处理固定大小的基本数据类型的时候,这种方式相对比较慢。

故如果元素数量不确定,使用ArrayList;
如果元素数量固定,且是基本数据类型,使用数组可以速率更快,不需要自动装箱和拆箱。

请你解释什么是值传递和引用传递?

值传递是对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量.
引用传递一般是对于对象型变量而言的,传递的是该对象地址的一个副本, 并不是原对象本身。 所以对引用对象进行操作会同时改变原对象.

请你解释为什么会出现4.0-3.6=0.40000001这种现象?

原因简单来说是这样:2进制的小数无法精确的表达10进制小数,计算机在计算10进制小数的过程中要先转换为2进制进行计算,这个过程中出现了误差。

请你说说Lamda表达式的优缺点。

优点:

  1. 简洁。
  2. 非常容易并行计算。
  3. 可能代表未来的编程趋势。

缺点:

  1. 若不用并行计算,很多时候计算速度没有比传统的for循环快。(并行计算有时需要预热才显示出效率优势)
  2. 不容易调试。
  3. 若其他程序员没有学过 lambda 表达式,代码不容易让其他语言的程序员看懂。

Java 中的 ==, equals 与 hashCode 的区别与联系

参考博客:https://blog.csdn.net/justloveyou_/article/details/52464440

请你说明符号“==”比较的是什么?

“==”对比两个对象的内存地址,如果两个对象的引用完全相同(指向同一个地址)时,该操作符将返回true。

“==”如果两边是基本类型,就是比较数值是否相等。

所以如果要比较2个字符串是否相同时,要使用equal()方法。

请你阐述下equals()方法

对一个类不重写,它的equals()方法比较的是对象的地址。

1,来源  
    equals方法是基类Object中的实例方法,因此对所有继承于Object的类都会有该方法。   
    Object类中equals方法的实现:
    public boolean equals(Object obj) {
        return (this == obj);
    }
    很显然,在Object类中,equals方法是用来比较两个对象的引用是否相等,即是否指向同一个对象。
2,equals方法的作用
    初衷 : 判断两个对象的 content 是否相同
    必要的时候,我们需要重写该方法,避免违背本意,且要遵循一些原则
    例子:String 类重写了 equals 方法
    使用equals方法,内部实现分为三个步骤:
        先 比较引用是否相同(是否为同一对象),
        再 判断类型是否一致(是否为同一类型),
        最后 比较内容是否一致
    Java 中所有内置的类的 equals 方法的实现步骤均是如此,特别是诸如 Integer,Double 等包装器类。
    
    要遵循的原则:
    对称性: 如果x.equals(y)返回是“true”,那么y.equals(x)也应该返回是“true” ;
    自反性: x.equals(x)必须返回是“true” ;
    类推性: 如果x.equals(y)返回是“true”,而且y.equals(z)返回是“true”,那么z.equals(x)也应该返回是“true” ;
    一致性: 如果x.equals(y)返回是“true”,只要x和y内容一直不变,不管你重复x.equals(y)多少次,返回都是“true” ;
    对称性: 如果x.equals(y)返回是“true”,那么y.equals(x)也应该返回是“true”。
    任何情况下,x.equals(null)【应使用关系比较符 ==】,永远返回是“false”;x.equals(和x不同类型的对象)永远返回是“false”

请你阐述下hashCode方法

1、hashCode 的来源 
  hashCode 方法是基类Object中的实例native方法,因此对所有继承于Object的类都会有该方法。 
   
  在 Object类 中的声明(native方法暗示这些方法是有实现体的,但并不提供实现体,
  因为其实现体是由非java语言在外面实现的):
  
    public native int hashCode();

2、hashCode 简述 
    在 Java 中,由 Object 类定义的 hashCode 方法会针对不同的对象返回不同的整数。
    (这是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧)。
    
    要想进一步了解 hashCode 的作用,我们必须先要了解Java中的容器,因为 HashCode
    只是在需要用到哈希算法的数据结构中才有用,比如 HashSet, HashMap 和 Hashtable。
    
    数组+链表的结构下:
    先调用这个元素的 hashCode 方法,然后根据所得到的值计算出元素应该在数组的位置。
    如果这个位置上没有元素,那么直接将它存储在这个位置上;
    如果这个位置上已经有元素了,那么调用它的equals方法与新元素进行比较:相同的话就不存了,
    否则,将其存在这个位置对应的链表中(Java中HashSet,HashMap和Hashtable的实现总将元素放到链表的表头)。

重写equals和hashcode方法

前提: 谈到hashCode就不得不说equals方法,二者均是Object类里的方法。由于Object类是所有类的基类,所以一切类里都可以重写这两个方法。

  • 原则 1 : 如果 x.equals(y) 返回 “true”,那么 x 和 y 的 hashCode() 必须相等 ;
  • 原则 2 : 如果 x.equals(y) 返回 “false”,那么 x 和 y 的 hashCode() 有可能相等,也有可能不等 ;
  • 原则 3 : 如果 x 和 y 的 hashCode() 不相等,那么 x.equals(y) 一定返回 “false” ;
  • 原则 4 : 一般来讲,equals 这个方法是给用户调用的,而 hashcode 方法一般用户不会去调用 ;
  • 原则 5 : 当一个对象类型作为集合对象的元素时,那么这个对象应该拥有自己的equals()和hashCode()设计,而且要遵守前面所说的几个原则。

String类重写了hashCode()方法,即对象的hash地址不一定是实际的内存地址。

请解释hashCode()和equals()方法有什么联系?

➀相等(相同)的对象必须具有相等的哈希码(或者散列码)。
➁如果两个对象的hashCode相同,它们并不一定相同。

小节

  • hashcode是系统用来快速检索对象而使用
  • equals方法本意是用来判断引用的对象是否一致
  • 重写equals方法和hashcode方法时,equals方法中用到的成员变量也必定会在hashcode方法中用到,只不过前者作为比较项,后者作为生成摘要的信息项,本质上所用到的数据是一样的,从而保证二者的一致性

请你解释Object若不重写hashCode()的话,hashCode()如何计算出来的?

Object 的 hashcode 方法是本地方法,也就是用 c 语言或 c++ 实现的,该方法直接返回对象的 内存地址。

你可能感兴趣的:(java 超详细面经整理(持续更新)2019.12.18)