Java 基础知识点1 (含面试题)
本次Java 知识点主要是关于SE的相关基础,同时也包含了数据结构中的一些API,例如Set,List,Map等,最后也附上了相关重要的面试题,可供大家学习与参考!
重要知识点
Java 是一门面向对象的编程语言,不仅吸收了 C++语言的各种优点,还摒弃了 C++里难以理解的多继承、指针等概念,因此 Java 语言具有功能强大和简单易用两个特征。Java 语言作为静态面向对象编程语言的优秀代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程 。
基本格式,主要分为类
public class TestCo {
// 访问修饰符 关键字 返回类型 方法名 字符串数组
public static void main(String[] args) {
System.out.println("123");
}
}
# 运行方法:
$ javac HelloWorld.java
$ java HelloWorld
Hello World
比较突出的特点:
面向对象(封装,继承,多态);
平台无关性,平台无关性的具体表现在于,Java 是“一次编写,到处运行(Write Once,Run any Where)”的语言,因此采用 Java 语言编写的程序具有很好的可移植性,而保证这一点的正是 Java 的虚拟机机制。在引入虚拟机之后,Java 语言在不同的平台上运行不需要重新编译。
支持多线程。C++ 语言没有内置的多线程机制,因此必须调用操作系统的多线程功能来进行多线程程序设计,而 Java 语言却提供了多线程支持;
编译与解释并存;
面向对象特性:
封装
封装把?个对象的属性私有化,同时提供?些可以被外界访问的属性的?法。
继承
继承是使?已存在的类的定义作为基础创建新的类,新类的定义可以增加新的属性或新的方法,也可以继承父类的属性和方法。通过继承可以很方便地进行代码复用。
多态
所谓多态就是指程序中定义的引?变量所指向的具体类型和通过该引?变量发出的?法调?在编程时并不确定,?是在程序运?期间才确定,即?个引?变量到底会指向哪个类的实例对象,该引?变量发出的?法调?到底是哪个类中实现的?法,必须在由程序运?期间才能决定。
继承(多个?类对同??法的重写)和接?(实现接?[都是抽象方法]并覆盖接?中同??法)。
构造方法:
public class Puppy{
public Puppy(){
}
public Puppy(String name){
// 这个构造器仅有一个参数:name
}
}
多态:
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。
多态的好处:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。
class Shape {
void draw() {}
}
class Circle extends Shape {
void draw() {
System.out.println("Circle.draw()");
}
}
接口:
一个接口可以有多个方法
/* 文件名 : Animal.java */
interface Animal {
public void eat();
public void travel();
}
# 实现:
public class MammalInt implements Animal
输入Scanner:
Scanner s = new Scanner(System.in);
// 判断是否还有输入
if (scan.hasNext()) {
String str1 = scan.next();
//String str2 = scan.nextLine();
System.out.println("输入的数据为:" + str1);
}
scan.close();
数据结构API
数组(Arrays)
数组(Arrays)是一种基本的数据结构,可以存储固定大小的相同类型的元素。
int[] array = new int[5];
列表 Lists:
List<String> arrayList = new ArrayList<>();
List<Integer> linkedList = new LinkedList<>();
ArrayList<E> objectName =new ArrayList<>(); // 初始化
sites.sort(Comparator.naturalOrder()); // 升序
sites.sort(Comparator.reverseOrder()); // 降序
Collections.sort(sites); // 字母排序
sites.get(i) // 得到elem
sites.set(i,elem); // 修改
sites.add(elem);
sites.removes(i);// 删除
// 遍历:
for (int i = 0; i < sites.size(); i++) {
System.out.println(sites.get(i));
}
for( Integer i : a){
System.out.println(i);
}
ArrayList:
特点: 动态数组,可变大小。
优点: 高效的随机访问和快速尾部插入。
缺点: 中间插入和删除相对较慢。
LinkedList:
特点: 双向链表,元素之间通过指针连接。
优点: 插入和删除元素高效,迭代器性能好。
缺点: 随机访问相对较慢。
HashSet:
HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合。
HashSet 允许有 null 值。
HashSet 是无序的,即不会记录插入的顺序。
HashSet 实现了 Set 接口
// 引入 HashSet 类
import java.util.HashSet;
public class RunoobTest {
public static void main(String[] args) {
HashSet<String> sites = new HashSet<String>();
sites.add("Google");
sites.add("Runoob");
sites.add("Taobao");
sites.add("Zhihu");
sites.add("Runoob"); // 重复的元素不会被添加
System.out.println(sites);
// 是否包含?
sites.contains("Taobao")
}
}
HashMap:
HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。
HashMap 实现了 Map 接口,根据键的 HashCode 值存储数据,具有很快的访问速度,最多允许一条记录的键为 null,不支持线程同步。
HashMap 是无序的,即不会记录插入的顺序。
// 引入 HashMap 类
import java.util.HashMap;
public class RunoobTest {
public static void main(String[] args) {
// 创建 HashMap 对象 Sites
HashMap<Integer, String> Sites = new HashMap<Integer, String>();
// 添加键值对
Sites.put(1, "Google");
Sites.put(2, "Runoob");
Sites.put(3, "Taobao");
Sites.put(4, "Zhihu");
System.out.println(Sites);
//输出key :
// 输出 key 和 value
for (Integer i : Sites.keySet()) {
System.out.println("key: " + i + " value: " + Sites.get(i));
}
// 返回所有 value 值
for(String value: Sites.values()) {
// 输出每一个value
System.out.print(value + ", ");
}
}
}
Iterator
// 获取迭代器
Iterator<String> it = sites.iterator();
// 输出集合中的第一个元素
System.out.println(it.next());
// 循环
while(it.hasNext()) {
System.out.println(it.next());}
}
面试题
- JVM、JDK 和 JRE 有什么区别?
JVM:Java Virtual Machine,Java 虚拟机,Java 程序运行在 Java 虚拟机上。针对不同系统的实现(Windows,Linux,macOS)不同的 JVM,因此 Java 语言可以实现跨平台。
**JRE: Java 运?时环境。**它是运?已编译 Java 程序所需的所有内容的集合,包括 Java 虚拟机(JVM),Java 类库,Java 命令和其他的?些基础构件。但是,它不能?于创建新程序。
JDK: Java Development Kit,它是功能?全的 Java SDK。它拥有 JRE 所拥有的?切,还有编译器(javac)和?具(如 javadoc 和 jdb)。它能够创建和编译程序。
2.什么是字节码?采用字节码的好处是什么?
所谓的字节码,就是 Java 程序经过编译之类产生的.class 文件,字节码能够被虚拟机识别,从而实现 Java 程序的跨平台性。
Java 程序从源代码到运行主要有三步:
编译:将我们的代码(.java)编译成虚拟机可以识别理解的字节码(.class)
解释:虚拟机执行 Java 字节码,将字节码翻译成机器能识别的机器码
执行:对应的机器执行二进制机器码
Java源代码---->编译器---->jvm可执行的Java字节码(即虚拟指令)---->jvm---->jvm中解释器----->机器可执行的二进制机器码---->程序运行。
3.float f=3.4,对吗?
不正确。3.4 是双精度数,将双精度型(double)赋值给浮点型(float)属于下转型(down-casting,也称为窄化)会造成精度损失,因此需要强制类型转换float f =(float)3.4;或者写成float f =3.4F
- 重载(overload)和重写(override)的区别?
都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。
重载发生在一个类中,同名的方法如果有不同的参数列表**(参数类型不同、参数个数不同或者二者都不同)则视为重载**;
重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。
5.访问修饰符 public、private、protected、以及不写(默认)时的区别?
default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。可以修饰在类、接口、变量、方法。
private : 在同一类内可见。可以修饰变量、方法。注意:不能修饰类(外部类)
public : 对所有类可见。可以修饰类、接口、变量、方法
protected : 对同一包内的类和所有子类可见。可以修饰变量、方法。注意:不能修饰类(外部类)。
6.this 关键字有什么作用?和super 区别?
this 是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针。
三种方法:
普通的直接引用,this 相当于是指向当前对象本身
形参与成员变量名字重名,用 this 来区分:
super(参数):调用父类中的某一个构造函数(应该为构造函数中的第一条语句)。
this(参数):调用本类中另一种形式的构造函数(应该为构造函数中的第一条语句)。
7.final 关键字有什么作用?
final 表示不可变的意思,可用于修饰类、属性和方法:
被 final 修饰的类不可以被继承被 final 修饰的方法不可以被重写
被 final 修饰的变量不可变,
被 final 修饰的变量必须被显式第指定初始值,还得注意的是,这里的不可变指的是变量的引用不可变,不是引用指向的内容的不可变。
8.Java 是值传递,还是引用传递?
值传递。Java 语言的方法调用只支持参数的值传递。
JVM 的内存分为堆和栈,其中栈中存储了基本数据类型和引用数据类型实例的地址,也就是对象地址。
而对象所占的空间是在堆中开辟的,所以传递的时候可以理解为把变量存储的对象地址给传递过去,因此引用类型也是值传递。
9.String 和 StringBuilder、StringBuffer 的区别?
String:String 的值被创建后不能修改,任何对 String 的修改都会引发新的 String 对象的生成。
StringBuffer:跟 String 类似,但是值可以被修改,使用 synchronized 来保证线程安全。
StringBuilder:StringBuffer 的非线程安全版本,性能上更高一些。
- String str1 = new String(“abc”)和 String str2 = “abc” 和 区别?
11.==和 equals 的区别?
== :它的作?是判断两个对象的地址是不是相等。即,判断两个对象是不是同?个对象(基本数据类型 比较的是值,引?数据类型 比较的是内存地址)。
equals() : 它的作?也是判断两个对象是否相等。但是这个“相等”一般也分两种情况:
默认情况:类没有覆盖 equals() ?法。则通过 equals() 比较该类的两个对象时,等价于通过“ == ”比较这两个对象,还是相当于比较内存地址。
自定义情况:类覆盖了 equals() ?法。我们平时覆盖的 equals()方法一般是比较两个对象的内容是否相同,自定义了一个相等的标准,也就是两个对象的值是否相等。
- next() 与 nextLine() 区别
next:
1、一定要读取到有效字符后才可以结束输入。
2、对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。
3、只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。
next() 不能得到带有空格的字符串。
nextLine():
1、以Enter为结束符,也就是说 nextLine()方法返回的是输入回车之前的所有字符。
2、可以获得空白。
如果要输入 int 或 float 类型的数据,在 Scanner 类中也有支持,但是在输入之前最好先使用 hasNextXxx() 方法进行验证,再使用 nextXxx() 来读取:
- 为什么要写成List a = new ArrayList()
因为List是一个接口,而ArrayList是一个类。
ArrayList继承并实现了List。
- 构造方法有哪些特点?是否可被 override?
构造方法特点如下:名字与类名相同。没有返回值,**但不能用 void 声明构造函数。**生成类的对象时自动执行,无需调用。构造方法不能被 override(重写),但是可以 overload(重载),所以你可以看到一个类中有多个构造函数的情况。
- Oracle JDK 和 OpenJDK 的对比
Oracle JDK版本将每三年发布一次,而OpenJDK版本每三个月发布一次;
OpenJDK 是一个参考模型并且是完全开源的,而Oracle JDK是OpenJDK的一个实现,并不是完全开源的;
Oracle JDK 比 OpenJDK 更稳定。OpenJDK和Oracle JDK的代码几乎相同,但Oracle JDK有更多的类和一些错误修复。因此,如果您想开发企业/商业软件,我建议您选择Oracle JDK,因为它经过了彻底的测试和稳定。某些情况下,有些人提到在使用OpenJDK 可能会遇到了许多应用程序崩溃的问题,但是,只需切换到Oracle JDK就可以解决问题;
在响应性和JVM性能方面,Oracle JDK与OpenJDK相比提供了更好的性能;
Oracle JDK不会为即将发布的版本提供长期支持,用户每次都必须通过更新到最新版本获得支持来获取最新版本;
Oracle JDK根据二进制代码许可协议获得许可,而OpenJDK根据GPL v2许可获得许可。
16.java 数据类型图
17.static 作用?
static关键字还有一个比较关键的作用就是 用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
为什么说static块可以用来优化程序性能,是因为它的特性:只会在类加载的时候执行一次。因此,很多时候会将一些只需要进行一次的初始化操作都放在static代码块中进行。
静态只能访问静态。 2、非静态既可以访问非静态的,也可以访问静态的。
18.内部类的分类有哪些?
成员内部类、局部内部类、匿名内部类和静态内部类。
静态内部类:
定义在类内部的静态类,就是静态内部类。
public class Outer {
private static int radius = 1;
static class StaticInner {
public void visit() {
System.out.println("visit outer static variable:" + radius);
}
}
}
成员内部类
定义在类内部,成员位置上的非静态类,就是成员内部类。
public class Outer {
private static int radius = 1;
private int count =2;
class Inner {
public void visit() {
System.out.println("visit outer static variable:" + radius);
System.out.println("visit outer variable:" + count);
}
}
}
局部内部类
定义在方法中的内部类,就是局部内部类
public class Outer {
private int out_a = 1;
private static int STATIC_b = 2;
public void testFunctionClass(){
int inner_c =3;
class Inner {
private void fun(){
System.out.println(out_a);
System.out.println(STATIC_b);
System.out.println(inner_c);
}
}
Inner inner = new Inner();
inner.fun();
}
public static void testStaticFunctionClass(){
int d =3;
class Inner {
private void fun(){
// System.out.println(out_a); 编译错误,定义在静态方法中的局部类不可以访问外部类的实例变量
System.out.println(STATIC_b);
System.out.println(d);
}
}
Inner inner = new Inner();
inner.fun();
}
}
匿名内部类
匿名内部类就是没有名字的内部类,日常开发中使用的比较多。
public class Outer {
private void test(final int i) {
new Service() {
public void method() {
for (int j = 0; j < i; j++) {
System.out.println("匿名内部类" );
}
}
}.method();
}
}
//匿名内部类必须继承或实现一个已有的接口
interface Service{
void method();
}
除了没有名字,匿名内部类还有以下特点:
匿名内部类必须继承一个抽象类或者实现一个接口。
匿名内部类不能定义任何静态成员和静态方法。
当所在的方法的形参需要被匿名内部类使用时,必须声明为 final。
匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。
- 内部类的优点?
一个内部类对象可以访问创建它的外部类对象的内容,包括私有数据!
内部类不为同一包的其他类所见,具有很好的封装性;
内部类有效实现了“多重继承”,优化 java 单继承的缺陷。
匿名内部类可以很方便的定义回调。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!