Java面试-基础篇Part*1

最近小编抽空汇总了一些Java面试一些基础和常用到的一些知识点,希望对即将要面试的大家提供一些帮助,后期这个专栏会不定期更新,大家敬请期待

  • 面向对象编程有哪些特征(面试率⭐⭐⭐   难度⭐⭐)

一、抽象

1.什么是抽象

抽象是面向对象编程的重要概念,它允许我们从一个类中提取共同的特征,并将其封装在一个抽象基类中,以便于代码的重用和扩展。抽象类和接口是实现抽象的两种方式,它们可以定义一些方法的声明,但没有方法的实现。抽象类是用于实例化对象的基类,而接口是只包含方法声明的一组规范。

2.抽象在代码中的具体体现

// 定义一个抽象基类Animal
abstract class Animal {
    String name;

    Animal(String n) {
        name = n;
    }

    abstract void makeSound();
    
    void eat() {
        System.out.println(name + " is eating.");
    }
}

// 定义一个继承自Animal的子类Dog
class Dog extends Animal {
    Dog(String n) {
        super(n);
    }

    void makeSound() {
        System.out.println(name + " says: 汪汪汪!");
    }
}
// 定义一个继承自Animal的子类Cat
class Cat extends Animal {
    Cat(String n) {
        super(n);
    }

    void makeSound() {
        System.out.println(name + " says: 喵喵喵!");
    }
}
public class AbstractExample {
    public static void main(String[] args) {
        Animal myDog = new Dog("Rufus");
        Animal myCat = new Cat("Whiskers");
        
        myDog.makeSound(); // 输出: Rufus says: 汪汪汪!
        myCat.makeSound(); // 输出: Whiskers says: 喵喵喵!
    }
}

在上面的示例代码中,Animal是一个抽象基类,它定义了一个抽象方法makeSound(),同时提供了一个非抽象方法eat()。Dog和Cat是继承自Animal的子类,它们分别实现了makeSound()方法,从而满足了抽象基类的要求。在AbstractExample类的main方法中,我们创建了一个Dog对象和一个Cat对象,并调用它们的makeSound()方法,输出了相应的声音。这展示了抽象类和接口可以提供一种可扩展的方式来组织和管理代码。

二、封装

1.什么是封装

封装是一种将数据和操作数据的方法打包在一个对象中的编程技术。它将数据和操作数据的方法封装在一个对象中,并对外部提供一种访问这些数据和方法的方式。这样可以隐藏实现细节,只暴露出需要对外部可见的内容,从而提高程序的安全性和可维护性。

2. 封装在代码中的具体体现

下面是一个用Java代码实现封装的例子:

public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

三、继承

1.什么是继承

继承是一种面向对象编程的重要概念,它允许一个类(称为子类或派生类)从另一个类(称为父类或基类)继承属性和方法。子类可以使用父类的属性和方法,而无需重新编写代码。这种关系使得代码可重用,提高了开发效率。

2.继承在代码中的具体体现

// 父类
class Animal {
    String name;
    
    public Animal(String name) {
        this.name = name;
    }
    
    public void eat() {
        System.out.println(name + " is eating.");
    }
}

// 子类
class Dog extends Animal {
    public Dog(String name) {
        super(name);
    }
    
    public void bark() {
        System.out.println(name + " is barking.");
    }
}

// 创建对象并调用方法
public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog("Buddy");
        dog.eat();   // 输出: Buddy is eating.
        dog.bark();  // 输出: Buddy is barking.
    }
}

在上面的代码中,Dog 类继承了 Animal 类。Dog 类添加了一个 bark 方法,并重写了 Animal 类的 eat 方法。在 Main 类中,创建了一个 Dog 对象并调用了方法,输出了相应结果。

四、多态

1.什么是多态

多态是面向对象编程的重要概念,它允许使用相同的接口访问不同类的对象。多态性可以通过重写父类的方法来实现,这样子类就可以以自己的方式实现父类的方法。多态性还可以通过重载函数来实现,这样可以根据参数的数量和类型来调用正确的函数。多态性可以提高代码的可扩展性和可维护性。

2.多态在代码中的具体体现

// 父类 Animal
public class Animal {
    public void makeSound() {
        System.out.println("The animal makes a sound");
    }
}

// 子类1:Dog
public class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("The dog barks");
    }
}

// 子类2:Cat
public class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("The cat meows");
    }
}

// 主函数
public static void main(String[] args) {
    Animal animal1 = new Dog();  // 创建一个Dog对象并赋值给Animal类型的变量
    Animal animal2 = new Cat();  // 创建一个Cat对象并赋值给Animal类型的变量
    
    animal1.makeSound();  // 调用Animal类型变量的makeSound方法,实际调用的是Dog类的makeSound方法
    animal2.makeSound();  // 调用Animal类型变量的makeSound方法,实际调用的是Cat类的makeSound方法
}

上述代码中,Animal类是一个父类,而Dog和Cat类是Animal类的子类。每个子类都重写了父类的makeSound方法,并实现了自己的声音。在主函数中,我们创建了两个Animal类型的变量,分别存储了Dog和Cat对象。当我们调用它们的makeSound方法时,实际上会调用各自子类的方法,输出不同的声音。这就是多态的体现,即使用共同的接口访问不同的类对象。

  • JDK和JRE的区别(面试率⭐⭐⭐   难度⭐⭐)

1.什么是JDK

JDK(Java Development Kit)是Java开发工具包,它包含了一系列用于开发和调试Java应用程序的工具,包括编译器、调试器、文档等。JDK还包含Java运行环境(JRE),用于支持Java的计算机系统上运行Java程序。此外,JDK还包含其他一些用于开发的工具如Java虚拟机(JVM)、Java核心类库和其他必要组件

2.什么是JRE

JRE(Java Runtime Enviroment)是Java运行环境,他是一套软件,用于在支持Java的计算机系统上运行Java程序。JRE包含了Java虚拟机(JVM)、Java核心嘞库和其他Java运行时必要的组件。它使得Java程序可以在不同的操作系统上运行,而无需修改代码

3.JDK和JRE的区别

JDK和JRE都是Java的软件开发工具包,但它们的功能不同。JDK包含了一系列用于开发和调试Java应用程序的工具,包括编译器、调试器、文档等。而JRE之包含Java虚拟机、Java核心类库和其他必要的组件,用于在支持Java的计算机系统上运行Java程序。因此,JDK比JRE多了一些用于开发的功能

  • Java中的关键字(面试率⭐  难度⭐)

Java中的关键字
关键字含义描述实例
import引用类用于导入其他类文件中的类。当我们使用import关键字时,它可以指定要导入的类的包名,这样我们就可以在代码中使用该类了。如果没有使用import关键字,我们需要指定完整的类名才能使用该类。import还可以导入整个包,这样我们就可以在代码中使用该包下的所有类了。
import java.util.*;

public class Main {
    public static void main(String[] args) {
        List<Integer> numbers = new ArrayList<>();
        
        numbers.add(1);
        numbers.add(2);
        numbers.add(3);
        
        System.out.println("The first element is: " + numbers.get(0));
    }
}

class       定义类类是一种自定义的数据类型,它可以封装数据和方法,用于描述现实世界中的对象。在Java中,我们可以使用class关键字来定义一个类,类中可以包含变量(成员变量)和方法(成员方法),也可以包含内部类、接口等。通过类,我们可以创建对象,实现面向对象编程。
public class HelloWorld {
   private String message;
   
   public HelloWorld(String msg) {
      this.message = msg;
   }
   
   public String getMessage() {
      return message;
   }
   
   public void setMessage(String msg) {
      this.message = msg;
   }
   
   public static void main(String[] args) {
      HelloWorld helloWorld = new HelloWorld("Hello, World!");
      System.out.println(helloWorld.getMessage());
   }
}

interface       定义接口接口(Interface)是Java中的一种抽象类型,它定义了一组方法和常量,但没有实现。接口可以用来为不同的类定义共同的行为,实现代码的复用。类可以实现一个或多个接口,通过实现接口中的方法来实现类的功能。接口还可以用来定义类之间的协议,规定类之间如何进行交互。通过使用接口,可以提高程序的可扩展性和可维护性。
public interface Shape {
    void draw();
}

public class Circle implements Shape {
    public void draw() {
        System.out.println("Drawing a circle");
    }
}

public class Square implements Shape {
    public void draw() {
        System.out.println("Drawing a square");
    }
}

abstract抽象类或抽象方法用于定义抽象方法和抽象类。抽象方法没有方法体,只有方法的声明,实现留给子类;抽象类不能被实例化,只能被子类继承。使用abstract关键字可以定义一个抽象方法,表示该方法的实现留给子类来实现。抽象类和抽象方法的目的是为了提供一个框架,要求子类必须实现其中的方法,以保证子类的行为符合预期。
abstract class Animal {
    abstract void makeSound();
}

class Dog extends Animal {
    void makeSound() {
        System.out.println("Woof!");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.makeSound();
    }
}

super引用父类用于引用父类的成员变量和方法。它可以用来调用父类的构造方法,访问父类的成员变量和方法,以及调用父类的静态方法。super还可以在子类中重写父类的方法时,用来引用父类的同名方法。在继承关系中,super是一个指向父类对象的引用
class Animal {
    void eat() {
        System.out.println("The animal is eating");
    }
}

class Dog extends Animal {
    public Dog() {
        super.eat();  // 调用父类的eat()方法
    }
}

extends继承类用于实现继承。它允许一个类(子类)继承另一个类(父类)的属性和方法。子类可以使用父类的属性和方法,同时还可以添加自己的属性和方法。通过继承,可以减少代码的重复,并且可以更好地组织和管理代码。
// 父类
class Animal {
    void eat() {
        System.out.println("The animal is eating");
    }
}

// 子类继承父类
class Dog extends Animal {
    void bark() {
        System.out.println("The dog is barking");
    }
}

// 创建子类对象并调用方法
public class Main {
    public static void main(String[] args) {
        Dog myDog = new Dog();
        myDog.eat();  // 调用父类方法
        myDog.bark(); // 调用子类方法
    }
}

implements实现接口用于实现接口。它用于声明类或接口如何实现某个特定的功能集合。当一个类使用implements关键字来实现一个或多个接口时,它必须实现接口中定义的所有方法。这样可以确保类具有特定的功能,并且可以与其他类进行正确的交互。
class MyDrawable implements Drawable {
    // 实现接口中的方法,这表示MyDrawable类实现了Drawable接口,并且必须实现Drawable接口中定义的所有方法,以便能够正确地绘制图形。
}

private私有权限

1.private是Java语言中访问修饰符的一种,用于限制类成员的访问权限。当一个成员变量或成员方法被声明为private时,它只能在类的内部被访问,无法被类的外部访问。

2.被private修饰的成员变量通常被称为私有成员变量,它们只能在类的内部进行赋值和访问。私有成员变量通常用于封装类的实现细节,隐藏实现的具体逻辑,只提供公共的接口给外部使用。

3.被private修饰的成员方法被称为私有方法,它们也只能在类的内部被访问。私有方法通常用于实现类的内部逻辑,不被类的外部直接调用

public class Person {
    private String name; // 私有成员变量

    private void sayHello() { // 私有方法
        System.out.println("Hello");
    }

    public String getName() { // 公共方法
        return name;
    }

    public void setName(String name) { { // 公共方法
        this.name = name;
    }

    public void sayHelloWorld() { // 公共方法
        System.out.println("Hello, " + name);
        sayHello(); // 调用私有方法
    }
}
//在上面的例子中,成员变量name和成员方法sayHello()被声明为private,只能在类的内部进行访问。类中提供了公共方法getName()、setName()和sayHelloWorld()来访问和修改私有成员变量name,并调用私有方法sayHello()。这样可以保证私有成员只能通过公共方法来访问和修改,提高了代码的安全性和封装性。

protected保护权限

1.protected是一个访问修饰符,它可以应用于类、方法和成员变量。 2. 当应用于类时,表示该类中的所有成员对于该类的子类和同一包中的类是可见的,但在其他包中则不可见。  

3.当应用于方法时,表示该方法对于该类的子类和同一包中的类是可见的,但在其他包中则不可见。  

4.当应用于成员变量时,表示该成员变量对于该类的子类和同一包中的类是可见的,但在其他包中则不可见。

public class BaseClass {
    protected String protectedVariable;

    protected void protectedMethod() {
        // 方法内容
    }

    public void publicMethod() {
        protectedMethod();
    }
}

public class SubClass extends BaseClass {
    public void test() {
        protectedVariable = "value";
        protectedMethod();
    }
}
//在上面的示例中,BaseClass是一个基类,它定义了一个protected成员变量protectedVariable和一个protected方法protectedMethod(),以及一个公共方法publicMethod()。  SubClass是BaseClass的子类,它能够访问BaseClass中所有protected成员变量和方法。在test()方法中,protectedVariable被设置为字符串"value",protectedMethod()被调用。  需要注意的是,protected成员变量和方法对于在同一包中的其他类也是可见的。这意味着如果BaseClass不在同一个包中,其他包中的类也可以访问protected成员变量和方法。但是,对于其他包中的类,必须在访问protected成员变量和方法时先声明依赖关系,即在类的声明上方添加对BaseClass的导入语句。

public公开权限

public是一个访问修饰符,在Java中使用。当一个成员(方法、属性、内部类等)被声明为public时,它可以从程序的任何地方访问到。 具体来说,public有以下几个特点:

1. 公共成员可以在当前类的所有方法和属性中使用。

2. 公共成员可以被其他类、其他包中的类访问。

3. 公共成员是强制性的,如果一个成员没有被声明为public、protected、private之一,默认就是private

public class MyClass {
    // 属性
    public String publicProperty;
    protected String protectedProperty;
    private String privateProperty;

    // 方法
    public void publicMethod() {
        // 方法体
    }

    protected void protectedMethod() {
        // 方法体
    }

    private void privateMethod() {
        // 方法体
    }
}
//在上面的示例中,MyClass中的publicProperty和publicMethod都可以被其他类访问和使用,protectedProperty和protectedMethod只能在当前包和子类中访问和使用,privateProperty和privateMethod只能在当前类中访问和使用

final不可继承、不可重写、常量在Java中,关键字final用于修饰类、方法和变量,用来表示不可变性,表示该类不能被继承,该方法不能被重写,该变量不能被重新赋值
//1. final修饰类:被final修饰的类不能被继承。
public final class MyClass {
    // ...
}

//2. final修饰方法:被final修饰的方法不能被子类重写。
public class MyClass {
    public final void myMethod() {
        // ...
    }
}

//3. final修饰变量:被final修饰的变量为常量,赋值后不能被修改。
public class MyClass {
    public static final int MY_CONSTANT = 10;
}

static静态属性static是Java中的一个关键字,它有以下几个作用:  1. 静态变量:使用static关键字声明的变量是类变量,被类的所有对象共享,而不是每个对象有一份独立的变量。静态变量可以在类的任何地方被访问,不需要创建类的对象。  2. 静态方法:使用static关键字声明的方法是类方法,可以直接通过类名调用,不需要创建类的对象。静态方法不能访问非静态方法和变量,也不能调用非静态方法。  3. 静态初始化块:使用static关键字声明的初始化块可以在类加载时执行一些初始化操作,优先于构造方法执行。  4. 静态导入:使用static关键字导入类中的静态成员,比如静态方法和静态变量。  5. 静态内部类:使用static关键字声明的内部类称为静态内部类,它可以在类外被访问,并且可以继承静态和非静态内部类的所有方法和成员。  6. 静态链接:使用static关键字加载类时,会先加载静态成员,然后再加载非静态成员。  7. 静态分析:使用static关键字可以在不创建对象的情况下对类进行分析,比如反射机制。  总之,static关键字用于声明与类相关联的成员,提供了一种更高效、更灵活的方式来访问类的成员。
public class Main {
    private int value;

    public Main(int value) {
        this.value = value;
    }

    public static Main createMain(int value) {
        return new Main(value);
    }

    public static void main(String[] args) {
        Main main = Main.createMain(100);
        System.out.println(main.value); // 输出:100

        // 创建另一个Main对象
        Main anotherMain = Main.createMain(200);
        System.out.println(anotherMain.value); // 输出:200

        // 创建静态方法
        public static int doubleValue(int num) {
            return num * 2;
        }

        int result1 = Main.doubleValue(10);
        System.out.println(result1); // 输出:20

        int result2 = anotherMain.doubleValue(20);
        System.out.println(result2); // 输出:40
    }
}
//在上面的代码中,Main类的构造方法使用了static修饰,因此可以通过类名直接创建Main对象,而无需使用new关键字。createMain方法用于创建Main对象,是静态方法,可以通过类名直接调用。  另外,上面的代码还演示了静态方法doubleValue的使用。静态方法是属于类的方法,而普通的成员方法是属于对象的方法。静态方法可以不通过对象直接调用,通过类名调用。在上面的代码中,doubleValue方法是静态方法,可以通过类名直接调用

synchronized线程同步synchronized关键字可以用来修饰类、方法或代码块,其作用是保证在特定的线程中只有一个线程可以访问被synchronized修饰的部分代码。  1. 当synchronized用来修饰类时,代表该类的方法都是同步的,即在任意时刻只有一个线程可以访问该类的方法。  2. 当synchronized用来修饰方法时,代表该方法中的代码都是同步的,即在任意时刻只有一个线程可以访问该方法。  3. 当synchronized用来修饰代码块时,可以在代码块前指定synchronized关键字,后面加上一个对象锁,代表该代码块是同步的,即在任意时刻只有一个线程可以访问该代码块,并且多个线程访问同一对象的不同代码块时是并发执行的。  synchronized可以用于解决多线程并发访问共享资源时出现的数据竞争、死锁等问题,通过保证同一时间只有一个线程可以访问共享资源,从而避免多个线程同时修改共享资源引发的不可预期的问题。
public class SynchronizedExample {
    private static final Object lock = new Object();

    public static void main(String[] args) {
        synchronized (lock) {
            // 代码块1
        }

        synchronized (SynchronizedExample.class) {
            // 代码块2
        }

        synchronized ("example") {
            // 代码块3
        }
    }
}
//以上代码展示了如何使用synchronized关键字来同步代码块。  1. 使用一个对象锁来同步代码块。当一个线程获得了对象锁后,其他线程需要等待该线程释放锁才能继续执行。  2. 使用类锁来同步代码块。当一个线程获得了类锁后,其他线程需要等待该线程释放锁才能继续执行。  3. 使用字符串锁来同步代码块。当一个线程获得了字符串锁后,其他线程需要等待该线程释放锁才能继续执行。  以上代码中的三个代码块分别使用不同的锁对象来实现同步,只有获得了锁的对象才能执行代码块内的逻辑。这样可以保证同一时间只有一个线程能够执行代码块内的逻辑,从而实现线程同步。

do-while循环do-while循环是一种循环结构,它会先执行一次循环体,然后再判断循环条件是否满足。与while循环不同,do-while循环至少会执行一次循环体
import java.util.Scanner;
//do-while循环的用法:
public class DoWhileExample {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int number;

        do {
            System.out.println("请输入一个数字");
            number = scanner.nextInt();
        } while (number < 0);

        System.out.println("您输入的数字是:" + number);
    }
}


//在这个示例中,do-while循环会先执行一次输入数字的语句,然后再判断输入的数字是否小于0。如果小于0,则继续执行循环体,即再次要求用户输入数字。如果大于等于0,则跳出循环,输出用户输入的数字。




import java.util.Scanner;
//while循环的判断条件会先于循环体执行:
public class WhileExample {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int number;

        while (true) {
            System.out.println("请输入一个数字");
            number = scanner.nextInt();

            if (number >= 0) {
                break;  // 如果输入的数字大于等于0,跳出循环
            }
        }

        System.out.println("您输入的数字是:" + number);
    }
}

//在这个示例中,while循环会先判断循环条件是否为true,如果为true,则执行循环体,即要求用户输入数字。如果输入的数字大于等于0,则使用break语句跳出循环,否则继续执行循环体。

switch-case-default选择结构switch-case是一种选择结构,用于根据一个表达式的值来执行不同的代码块。它的基本结构是,先对表达式进行匹配,然后根据不同的匹配结果执行相应的代码块
switch (表达式) {
    case 常量1:
        // 当表达式等于常量1时执行的代码块
        break;
    case 常量2:
        // 当表达式等于常量2时执行的代码块
        break;
    case 常量3:
        // 当表达式等于常量3时执行的代码块
        break;
    default:
        // 表达式与所有常量都不相等时执行的代码块
        break;
}
//当表达式的值与某个常量相等时,会跳转到对应case下的代码块并执行,然后执行完后会跳出switch语句。如果没有匹配的case,则会执行default下的代码块(可选)。break语句用于跳出switch语句。  switch-case适用于有多个可能的选择情况,且这些选择情况是已知的情况。它比多个if-else条件判断语句更加简洁和易读。

break/continue结束/继续循环
catch异常处理
finally最后处理
throw手动抛出一个异常
throws声明要抛出的异常

保留关键字
保留关键字含义
goto跳转
const常量
特殊关键字
特殊关键字含义
true
false
null空值

如有错误和不合适的地方欢迎大家在评论区留言指出!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值