Java 基础知识点1 (含面试题)

发布时间:2024年01月07日

本次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());}
}

面试题

  1. 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

  1. 重载(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 的非线程安全版本,性能上更高一些。

  1. String str1 = new String(“abc”)和 String str2 = “abc” 和 区别?

在这里插入图片描述

11.==和 equals 的区别?

== :它的作?是判断两个对象的地址是不是相等。即,判断两个对象是不是同?个对象(基本数据类型 比较的是值,引?数据类型 比较的是内存地址)。

equals() : 它的作?也是判断两个对象是否相等。但是这个“相等”一般也分两种情况:
默认情况:类没有覆盖 equals() ?法。则通过 equals() 比较该类的两个对象时,等价于通过“ == ”比较这两个对象,还是相当于比较内存地址。
自定义情况:类覆盖了 equals() ?法。我们平时覆盖的 equals()方法一般是比较两个对象的内容是否相同,自定义了一个相等的标准,也就是两个对象的值是否相等。

  1. next() 与 nextLine() 区别

next:
1、一定要读取到有效字符后才可以结束输入。
2、对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。
3、只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。
next() 不能得到带有空格的字符串

nextLine():
1、以Enter为结束符,也就是说 nextLine()方法返回的是输入回车之前的所有字符。
2、可以获得空白。
如果要输入 int 或 float 类型的数据,在 Scanner 类中也有支持,但是在输入之前最好先使用 hasNextXxx() 方法进行验证,再使用 nextXxx() 来读取:

  1. 为什么要写成List a = new ArrayList()

因为List是一个接口,而ArrayList是一个类。
ArrayList继承并实现了List

  1. 构造方法有哪些特点?是否可被 override?

构造方法特点如下:名字与类名相同。没有返回值,**但不能用 void 声明构造函数。**生成类的对象时自动执行,无需调用。构造方法不能被 override(重写),但是可以 overload(重载),所以你可以看到一个类中有多个构造函数的情况。

  1. 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。
匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。

  1. 内部类的优点?

一个内部类对象可以访问创建它的外部类对象的内容,包括私有数据!
内部类不为同一包的其他类所见,具有很好的封装性;
内部类有效实现了“多重继承”,优化 java 单继承的缺陷。
匿名内部类可以很方便的定义回调。

文章来源:https://blog.csdn.net/QAZJOU/article/details/135432018
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。