【java基础问题】
本文根据javaGuide 基础知识(上)编写 建议阅读本文之前看下原文的目录
原文链接:https://javaguide.cn/java/basis/java-basic-questions-01/#
1. java有哪些特点?
像跨平台”一次编写到处运行“这些就不罗嗦了,看点能详细展开的。
1.面向对象(封装,继承,多态)
2.编译与解释共存
3.只有值传递(复制值而不是引用地址)
1.要知道编译过后形成字节码文件也就是 .class类文件
2.要知道jit可以取代解释器完成字节码到机器码的过程,并且jit还保存了机器码
图解:
需要格外注意的是 .class->机器码 这一步。在这一步 JVM 类加载器首先加载字节码文件,然后通过解释器逐行解释执行,这种方式的执行速度会相对比较慢。而且,有些方法和代码块是经常需要被调用的(也就是所谓的热点代码),所以后面引进了 JIT(just-in-time compilation) 编译器,而 JIT 属于运行时编译。当 JIT 编译器完成第一次编译后,其会将字节码对应的机器码保存下来,下次可以直接使用。而我们知道,机器码的运行效率肯定是高于 Java 解释器的。这也解释了我们为什么经常会说 Java 是编译与解释共存的语言 。
2.java与c++有哪些区别?
都是面向对象的语言,都支持封装、继承和多态
下面是区别
- Java 不提供指针来直接访问内存,程序内存更加安全
- Java 的类是单继承的,C++ 支持多重继承;虽然 Java 的类不可以多继承,但是接口可以多继承。
- Java 有自动内存管理垃圾回收机制(GC),不需要程序员手动释放无用内存。
- C ++同时支持方法重载和操作符重载,但是 Java 只支持方法重载(操作符重载增加了复杂性,这与 Java 最初的设计思想不符)。
3.字符常量与字符串?
字符char占两个字节
注意形式:字符常量是单引号引起的一个字符,字符串常量是双引号引起的 0 个或若干个字符
4.注释有哪几种?注释越多越好吗?
Java 中的注释有三种:
单行注释
多行注释
文档注释。
5.关键字
特殊的标识符就是关键字
6.循环中断
continue :指跳出当前的这一次循环,继续下一次循环。
break :指跳出整个循环体,继续执行循环下面的语句。
7.静态方法为什么不能调用非静态成员?
这个需要结合 JVM 的相关知识,主要原因如下:
静态方法在类加载的时候就会分配内存,可以通过类名直接访问。而非静态成员属于实例对象,只有在对象实例化之后才存在,需要通过类的实例对象去访问。
在类的非静态成员不存在的时候静态成员就已经存在了,此时调用在内存中还不存在的非静态成员,属于非法操作。
8.重载和重写的区别?
重载:同名方法不同传参
重写是子对父类方法重写,要求方法参数一致
9.== 和 equals() 的区别?
equals只能用于对象而不是基本数据类型,等价于通过“==”比较这两个对象。
因为 Java 只有值传递,所以,对于 == 来说,不管是比较基本数据类型,还是引用数据类型的变量,其本质比较的都是值,只是引用类型变量存的值是对象的地址
10.hashCode() 与 equals()
面试官可能会问你:“你重写过 hashCode() 和 equals()么?为什么重写 equals() 时必须重写 hashCode() 方法?”
下面的hashset可以换为hashmap
当你把对象加入 HashSet 时,HashSet 会先计算对象的 hashCode 值来判断对象加入的位置,同时也会与其他已经加入的对象的 hashCode 值作比较,如果没有相符的 hashCode,HashSet 会假设对象没有重复出现。但是如果发现有相同 hashCode 值的对象,这时会调用 equals() 方法来检查 hashCode 相等的对象是否真的相同。如果两者相同,HashSet 就《不会让其加入操作成功》。如果不同的话,就会重新散列到其他位置。。这样我们就大大减少了 equals 的次数,相应就大大提高了执行速度。 其实, hashCode() 和 equals()都是用于比较两个对象是否相等。
注意点:
1.要知道hashcode方便我们进行查找操作进而去比较。
2.要知道上述过程的顺序:先比较hash值,不一样在比较equals,还不一样说明两者完全不同那就会发生二次散列。
那为什么两个对象有相同的 hashCode 值,它们也不一定是相等的?
因为 hashCode() 所使用的哈希算法也许刚好会让多个对象传回相同的哈希值。越糟糕的哈希算法越容易碰撞,但这也与数据值域分布的特性有关(所谓哈希碰撞也就是指的是不同的对象得到相同的 hashCode )。 总结下来就是 :
如果两个对象的hashCode 值相等,那这两个对象不一定相等(哈希碰撞)。
如果两个对象的hashCode 值相等并且equals()方法返回 true,我们才认为这两个对象相等。
如果两个对象的hashCode 值不相等,我们就可以直接认为这两个对象不相等。
重写 equals() 时没有重写 hashCode() 方法的话就可能会导致 equals 方法判断是相等的两个对象,hashCode 值却不相等。这样hashset当中就会重复加入equals的对象了。
11.基本数据类型有哪些?
参见https://javaguide.cn/java/basis/java-basic-questions-01/#%E5%9F%BA%E6%9C%AC%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B
Java 中有 8 种基本数据类型,分别为:
6 种数字类型 :byte、short、int、float、long、double
1 种字符类型:char
1 种布尔型:boolean。
基本类型 位数 字节 默认值
byte 8 1 0
short 16 2 0
int 32 4 0
float 32 4 0f
long 64 8 0L
double 64 8 0d
char 16 2 ‘u0000’
boolean 1 false
包装类型不赋值就是 Null 包装类型就是对象
要注意String不是基本类型。 String是引用类型。
看一道面试题:
Integer i1 = 40;
Integer i2 = new Integer(40);
System.out.println(i1==i2);
123Integer i1=40 这一行代码会发生装箱,也就是说这行代码等价于 Integer i1=Integer.valueOf(40) 。因此,i1 直接使用的是常量池中的对象。而Integer i2 = new Integer(40) 会直接创建新的对象。 因此,答案是 false 。你答对了吗?
所有整型包装类对象之间值的比较,全部使用 equals 方法比较
12拆装箱?
装箱其实就是调用了 包装类(引用类型)的valueOf()方法,拆箱其实就是调用了 xxxValue()方法
装箱:将基本类型用它们对应的引用类型包装起来;
拆箱:将包装类型转换为基本数据类型;