java学习中的一些问题

  1. 为什么在java中的50个关键字中,const和goto是不被推荐使用的?
    因为在java中,const和goto这两个关键字继承至C/C++。天然落后。
    const完全可以被final关键字代替,而goto即便是在C中也不推荐使用。
  2. 逻辑运算符严格与&和短路与&&在连接两个逻辑表达式A和B的区别?
    为什么我强调连接两个逻辑表达式?因为逻辑运算符既可以连接逻辑表达式,也可以连接两个基本数据类型,在连接两个基本数据类型时,这两个符号之间没有区别,都是按位与。但是在连接两个逻辑表达式的时候,A&B将A和B仍然进行按位与运算,而A&&B先检验A的真假,若A为假,则无需比较B。提高了效率。
    可见在连接逻辑表达式时,都应当使用A&&B。
  3. instanceof关键字的用法?
    instanceof关键字用于程序在运行时检验某个变量的运行时类型,比如变量a在编译时的类型是String
Object,但是在运行时的类型是String,可以被检验出来。
Object a = "example"; if(a instanceof String{ system.out.println("a是一个String类型的对象"): }
Object a = "example";
if(a instanceof String{
    system.out.println("a是一个String类型的对象"):
}
  1. 什么是向上转型?
    用父类的引用指向子类的对象,这就叫向上转型。
  2. 什么是java的三大特性继承、封装、多态?
    继承是一种泛化关系,说白了就是java具备继承父类和实现接口的特点。
    封装是指java编程过程中要遵循的一种原则,即我们编写的每个类的属性对其他类应当是封装的,其他类只能通过它提供的外部接口(也就是它的成员方)间接地访问和修改它的属性。避免误操作造成意想不到的问题。
    多态指我们上面所说的向上转型,比如在一个不确定的位置用一个一般性的名词占位,在运行时再分配具体值。比如用“车辆”来充当声明,在运行时,给车辆分配具体对象,是小汽车、三轮车还是卡车。
  3. 对象之间的泛化、实现、聚合、组合、关联、依赖关系和对象之间的耦合之间有什么联系?
    哈哈,这是软件工程这堂课上的内容。看到这里,你一定想到了里氏替换原则、开闭原则等等,是的,软件设计的相关原则和设计模式存在的目的是相似的,都是为了减少耦合。
    泛化(实线三角)、实线(虚线三角)、聚合(空白菱形)、组合(实心菱形)、关联(实线)、依赖(虚线箭头)这六种关系表述了各种类之间的关系。
    耦合度是一个度量,用于衡量对象之间的耦合程度,好的java程序应当尽可能地减少对象之间的耦合度。
  4. 对象之间的耦合存在哪几种方式?
    对象之间的耦合可以划分为结构耦合和逻辑耦合
    结构耦合:
    结构耦合即静态耦合,关注的是代码编写层面上,类与类之间通过结构进行互相连接。它主要表现在以下方面:
    继承耦合:一个类继承另一个类,子类对父类产生了依赖,也就产生了耦合。
    接口耦合:当一个类实现了一个接口,那就与接口产生了接口耦合。
    属性耦合:当一个类包含另一个类的对象作为属性,那就产生了属性耦合。
    参数耦合:当一个类的方法接收另一个类的对象作为参数,那就存在参数耦合。
    局部变量耦合:当一个类的成员方中实例化了另一个类,那就产生了局部变量耦合。
    全局变量耦合:当多个类共享全局变量时,这些类之间就存在了全局变量耦合。
    逻辑耦合:
    逻辑耦合指的是在运行时,类的行为相互依赖,也就是说,某个类的行为会影响到另一个类的行为,这样的耦合通常更难检测和解耦。主要有两种形式:
    时间耦合:即一个类必须在另一个类之前或之后执行,他们之间的调用顺序不能修改。
    条件耦合:即一个类在某个条件下依赖另一个类,在其他条件下可能不依赖。这种耦合通常存在于复杂的条件判断及流程控制中。
  5. 泛化、实现、聚合、组合、关联、依赖,这六种联系的符号表示如何记忆?
    继承父类用实线,实现接口用虚线,虚线代表一种抽象和不具体,这正符合接口内部都是抽象方法的特征。与之相对继承的父类里面有很多具体方法,所以继承用实现。
    组合和聚合很好记忆,组合关系整体没了部分也没了,所以是实心菱形,表示不可分割。
    聚合是空心的,因为聚沙成搭,塔没了沙还在,所以是空心菱形。
    依赖之所以是虚线箭头,就是因为这种关系是不稳定的。
    泛化和实现对应的耦合是继承耦合和实现耦合。
    组合和聚合对应的耦合是属性耦合。
    依赖对应的耦合是参数耦合和局部变量耦合。
  6. 什么是自动装箱和自动拆箱?
    所谓的自动装箱和自动拆箱就是指:在java的8个基本数据类型和对应的对象之间的转换是自动进行的,是由jvm自动实现的。
  7. 辨析= =和equal()方法功能的异同?
    = =用于检验两个引用所指向的内存单元是否是同一个。
    .equal()这个方法查看源代码的话,它是Object的一个方法,String类已经重写了.equal()方法,所以我们常常可以使用它来比较两个字符串的值是否相等。但是我们自定义的类不能使用它,因为未经重写的equals等价于= =,比较不了数据值本身。
  8. HotSpot是什么?
    是一种java虚拟机。
  9. 浅拷贝和深拷贝有什么区别?如何实现?
    浅拷贝就是调用clone方法,这种操作下,基本类型被复制了一份,对象的引用被复制了一份,但对象本身没有被复制。
    深拷贝需要在浅拷贝的基础上,遍历所有旧对象,创建新对象,重新赋值。然而,如果一个对象中包含了太多的对象属性,那么这时手动复制过于复杂,要使用序列化技术。
import java.io.Serializable;
public class Person implements Serializable {
    private String name;
    private int age;

    // 其他getter、setter方法和构造函数
}
import java.io.*;

public class DeepCloneDemo {
    public static void main(String[] args) {
        try {
            Person original = new Person("Tom", 18);

            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream out = new ObjectOutputStream(bos);
            out.writeObject(original);

            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream in = new ObjectInputStream(bis);
            Person copy = (Person) in.readObject();

            System.out.println(original == copy);  // 打印 false
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

对于这段流操作,可以这样理解,bos是发送时的箱子,out是装入设备,original是放在发送箱内的货物,bis是接收箱,in是取出设备copy是从接收箱里取出的货物。所以copy和original当然是一模一样的复制品,但不是同一个,他们是两个不同的对象,这样就完成了深拷贝。
Serializable接口和cloneable接口一样都是一个标识性的接口,这两个接口没有具体的方法需要被重写。但是却是实现相应功能所必不可少的。如果一个类没有实现Serializable接口,在调用序列化方法时会报错。另外值得注意的是,不是所有的类都能序列化。如果我们希望自己编写的类能被序列化,那么要保证这个类中的每一个属性所属的类都可以被序列化。

  1. 既然clone方法是Object中定义的方法,被所有的类继承(也就是说clone方法是继承自Object类的成员方法,而不是来自于cloneable接口的抽象方法),那么为什么当我们调用clone方法进行浅拷贝时,还要实现cloneable接口?
    这里使用cloneable接口是标识作用,没有这个接口,当前的类中如果重写了clone方法的话在编译时就会报出一个异常。
  2. jar的全称是什么?
    Java Archive java档案。
    JAR文件的主要用途是将Java的class文件和相关的库、资源集中在一起,方便存储和分发。可以把它看作是Java应用的容器。
  3. StringBuffer和StringBuilder之间有什么区别?
    StringBuffer的多数方法是线程安全的,而StringBuilder不安全,因此在多线程编程的情况下,更多地使用StringBuffer。
  4. 匿名类和lambda表达式之间的关系?
    首先,匿名类是对正常情况下“实现接口、重写方法”操作的一种简化,而lambda表达式则是对匿名类的一种简化。
    例如:
//实现接口
class MyRunnable implements Runnable {
	@override
    public void run(){
        System.out.println("Running in a regular class");
    }
}
Runnable r = new MyRunnable();
new Thread(r).start();
//使用匿名类
Runnable r = new Runnable(){
    public void run(){
        System.out.println("Running in an anonymous class");
    }
};
new Thread(r).start();
//使用lambda表达式
Runnable r = () -> {
	System.out.println("Running in an anonymous class");
};
new Thread(r).start();

你看,匿名类省略了implement关键字,省略了为了继承Runnable接口所定义的类名;
lambda相对于匿名类省略了接口名和函数名,只保留了要重写的那个函数的参数列表和函数内的代码块。
当然,这个lambda表达式是不包含返回值的,如果是包含返回值的lambda表达式,就可以省略return关键字:

import java.util.function.Function;
public class Main {
    public static void main(String[] args) {
        Function<Integer, Double> half = number -> number / 2.0;
        System.out.println(half.apply(10)); // Prints: 5.0
    }
}

如果又有操作,又有返回值的话,就也要使用return关键字:

import java.util.function.Function;
public class Main {
    public static void main(String[] args) {
        Function<Integer, Double> function = number -> {
            if (number == 0) {
                throw new IllegalArgumentException("Cannot divide by zero");
            }
            double half = number / 2.0;
            return half;
        };
        System.out.println(function.apply(10)); // Prints: 5.0
    }
}
  1. java中的comparator类和comparable接口可以用于进行对象之间的排序。我们先看comparable接口。
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
class Student implements Comparable<Student>{
    private String name;
    private int age;
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public int compareTo(Student s) {
        return this.age - s.age;
    }
    String getName(){
        return this.name;
    }
    int getAge(){
        return this.age;
    }
    public static void main(String[] args) {
        List<Student> students=new ArrayList<Student>();
        students.add(new Student("Amy",18));
        students.add(new Student("Bob",20));
        students.add(new Student("Tom",24));
        students.add(new Student("Tony",15));
        Collections.sort(students);
        for (Student s : students) {
            System.out.println(s.getName() +" "+ s.getAge());
        }
    }
}
//输出的结果:Tony 15、Amy 18、Bob 20、Tom 24

我在这里重写了compareTo方法,为什么我要这么做?因为我之后要调用collection.sort方法来对student序列进行排序,而这个sort方法将会用到compareTo方法,在具体的sort方法中,将会出现A.compareTo(B)的情景,这是在比较A和B的“大小”关系,并且通过判断A和B的大小关系来判定A和B的先后顺序(因为sort方法使用了归并排序)。因此,如果我们需要升序排列,就要这样设计compareTo方法,达到这样的一种效果:
A>B,则A.compareTo(B) > 0
A = B,则A.compareTo(B) = 0
A < B,则A.compareTo(B) < 0
如果我们需要降序排列,那么我们需要这样设计:
A < B,则A.compareTo(B) > 0
A = B,则A.compareTo(B) = 0
A > B,则A.compareTo(B) < 0
只有对compareTo函数进行这样的设计,sort方法才能正常工作。本例中的this.age-s.age就是这样设计的,可以看出是按照年龄排序,这时若A的年龄大于B的年龄,返回值是正值,不等号的方向相同,所以是升序排列。

  1. 字符串的intern方法怎么用?
    如果字符串池中已经存在一个等于此字符串的字符串(根据equals(Object)方法比较),那么池中现有的字符串的引用将被返回。否则,此字符串将被添加到字符串池中,并且返回此字符串的引用。
  2. var关键字除了用于定义类型不定的局部变量之外还有什么作用?
    没有了,var只能用来定义类型不定的局部变量。
  3. 谈谈你对泛型的理解。
    泛型,就是广泛的类型,就是引入一种不定类型。使用这种不定类型来替代多种类型。
    泛型的核心是用变量来表示数据类型,避免了对不同类型的数据的分类讨论,也减少了因类型转换导致的错误。泛型的引入提高了代码的复用性、概括性、抽象程度。和接口、抽象类有一定的相似之处。
    之前经常用的泛型是在创建集合对象时用泛型来约束元素类型,但这不是泛型的一般用法。泛型的一般用法是用变量来表示数据的类型,从而使得一段代码可以操作多种不同类型的数据。
    泛型类用变量来代替内部属性的类型,泛型方法用变量来代替方法的参数列表和返回值。
    java泛型是一种“伪泛型”,因为在编译阶段,所有的泛型都会被转化为对应的真实数据类型。
  4. java集合类似乎很多而且他们之间有相当复杂的内部继承和实现关系,那么如何才能正确的掌握这些集合类的用法,并且在不同情况下,选择最适当的集合类实现我们的需求呢?
    JAVA的集合类有很多,但可以分成这么5种:List、Stack、Set、Queue、Map。
    List:包括linklist、arraylist、vector,线性存储元素,支持按下标存取元素。
    Set:包括HashSet和TreeSet,特点是内部没有重复元素,hashset内部用哈希表实现,TreeSet内部使用红黑树实现。哈希表的查找快,但是数据存储无序,在数据遍历、数据排序时不如红黑树。
    Map:包括HashMap和TreeMap,特点是按值存取元素,内部实现也是哈希表和红黑树。
  • 20
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值