JavaSE基础知识笔记

news2024/11/25 3:52:49

​1、基础语法

  1. 在一个Java源文件中可以声明多个class,但是最多只有一个类可以被声名为public,而且被声名为public的类的类名必须与源文件名相同。

  2. 计算机底层都以补码的方式来存储数据!目的是为了简化计算机的结构设计,同时提升运算速度!

  3. 编译时,会生成一个或者多个字节码文件,字节码文件的文件名字与Java源文件中的类名相同。

  4. Java中针对不同数据类型获取长度的几种方法:

  • Java中的length属性是针对数组说的,比如说你声明了一个数组,想知道这个数组的长度则用到了length这个属性.

  • Java中的length()方法是针对字符串String说的,如果想看这个字符串的长度则用到length()这个方法.

  • Java中的size()方法是针对泛型集合说的,如果想看这个泛型有多少个元素,就调用此size()方法来查看。

4. 要注意的细节:数组的索引是字符串类型!

  1. 取模运算符最后的结果与被取模数的符号相同。

  2. 自增或者自减不会改变本身变量的数据类型

  3. 对于赋值运算符,+=、-=、*=等,其不改变变量本身的数据类型,比如char s,当执行s += 3,时,其char还是char的数据类型!对于赋值运算时,更喜欢这种操作!

  4. Java语言的程序流程控制只有三种:顺序结构、分支结构、循环结构

  5. break在switch-case语句中是可选的!且case语句是可以合并的,case语句里边只能是常量(byte、short、char、int、枚举类型(JDK5.0之后新增)、String类型(JDK7.0之后新增)),而不能是其他形式(如boolean判断类型等)!

在编程分支结构时,如果switch-case语句(且case情况不太多)和if-else语句都可以使用时,优先使用switch-case语句!原因:switch-case执行效率稍高!

  1. ==equals()的区别比较:

== 的作用:   基本类型:比较是否相等   引用类型:比较内存地址值是否相等

equals 的作用:   引用类型:默认情况下,比较内存地址值是否相等。可以按照需求逻辑,重写对象的equals方法。

  1. Java语言中在定义一个变量时,最好直接将其赋值,不然如果最后输出这个变量时会产生难以想到的后果(比如这个变量在程序运行时没有被赋值就会编译失败!)

  2. 对于嵌套循环,外侧循环表示的是行,内侧循环表示的是列,写代码时要找到行和列即ij之间的关系!

  3. 如何高效计算2*8?

  • 2<<3 : 2左移3个位置

  • 8<<1:8左移1个位置

  1. if-else语句执行时遵循就近原则

  2. 针对嵌套的双层for循环:(如果可视化的角度分析)

  • 外层循环控制行数

  • 内层循环控制列数

  1. 如果动态初始化一个数组时:int[] [] arr = new int[3] [4],此时如果输入一维数组的值时,其表示的是地址值,如:System.out.println(arr1[0])其表示的是地址。

  2. 匿名对象的概念:在创建对象时,没显式的赋给一个变量名。即为匿名对象。

    特点:匿名对象只能调用一次。

    new Phone().sendEmail();

  3. 怎么理解this关键字?怎么理解super关键字?

this就可以理解为当前的对象,或者正在创建的对象!

比如使用匿名对象时,其造的对象是新的一个对象,不符合自己想要的当前的这个对象,这个时候就可以用this来代之当前对象。

this后面可以跟属性、方法、构造器(this(添加相应的参数),如果这样写的话要放在第一行)

具体点,this调用构造器注意以下几点:

  • 在类的构造器中,可以显式的使用 “this(形参列表)” 方式,调用本类中指定的其他构造器

  • 构造器中不能通过 “this(形参列表)” 方式调用自己

  • 如果一个类中有 n 个构造器,则最多有 n - 1 个构造器中使用了 “this(形参列表)”

  • 规定,“this(形参列表)” 必须声明在当前构造器的首行

  • 构造器内部,最多只能声明一个 "this(形参列表)" ,用于调用其他构造器

super就可以理解为父类的,父类的对象

  • 我们可以在子类的方法或者构造器中,通过使用 ”super.属性“ 或者 ”super.方法“ 的方式,显示的调用父类中声明的属性或者方法,但是,通常情况下,我们习惯省略 "super."

  • 特殊情况下,当子类和父类中定义了同名的属性是,我们要想在子类中调用父类中声明的属性,则必须是显示的使用 "super.属性" 结构,则表明调用的是父类中声明的属性。

  • 特殊情况下,当子类重写了父类中的方法后,我们想在子类的方法中调用父类中被重写的方法时,则必须显示的使用 "super.方法" ,表明是父类中被重写的方法。

  • 与this一样,super也必须声明在首行。

  • 在类的构造器中,针对 "this(形参列表)" 或 "super(形参列表)" 只能二选一,不能同时出现

  • 在构造器首行,如果没有显示的声明 "this(形参列表)" 或 "super(形参列表)" ,则默认的是调用 "super(形参列表)" ,即默认调用的是父类的空参构造器

  • 在类的构造器中,至少有一个类的构造器中使用了 "super(形参列表)" ,调用父类中的构造器

  1. 在某些时候,引用数据类型,你就可以把它理解为一个类,所以在隐式定义引用类型后,需要先new好在使用,否则会报错,例如:private Customer[] customers; 如果不在构造函数中初始化这个对象数组时就会报错,应当在构造函数中加上一句:customers = newCustomer[10];

  2. 一个类中使用其他类作为引用数据类型时,这两个类构成关联关系。

  3. String的底层就是char!

  4. 针对语句while(i-- !=0):先执行判断语句,再执行i--语句。

  5. 一个容易出错的小知识:

     String s1 = "BB";
     String s2 = "BB";
     System.out.println(s1 == s2); //此处为true!!
     ​
     //注意:如果此处为Integer也是同理,常量池的缘故!范围为(-128~127)

    因为String虽然可以理解为是一个类,但它不是放在堆空间中的,而是放在常量池中的,常量池有一个特性就是:如果发现有相同的内容,其会进行复用!!所以此处是true。

  1. 回溯是很经典的一个算法,什么是回溯,回溯其实是一种暴力枚举的方式,为啥都暴力了还是很经典的一种方法呢,其实是因为有些问题我们能暴力出来就不错了,就别要其他自行车了。常见的回溯类问题:组合;排列;切割;子集;棋牌; 其实回溯算法就是常说的DFS,本质上是一种暴力枚举算法; 回溯算法常用于解决的问题: 组合 排列 切割 子集 棋盘

  2. 关于基本数据类型、包装类、String类之间的转化,JDK5.0之后有新特性:

    • 基本数据类型 <--> 包装类 : 自动装箱,自动拆箱

    • 基本数据类型、包装类 --> Sting类 : 调用String.valueOf(xxx)

    • Sring类 --> 基本数据类型、包装类:调用包装类的parserXxx(String str),类如Integer.paserInt(String str)

  3. 三元运算符会自动进行类型提升,运算结果的类型会提升至中间类型和右边类型的最高的那个。

  4. 怎么理解多态

    子类对象赋给父类引用(父类引用指向子类对象),编译看左边,运行看右边!

    Person p = new Man();

    多态使用前提:①存在子父类的继承 ②存在子类重写

    注意:对象的多态性,只适用于方法,不适用于属性(编译运行都看右边)

    多态是一个运行时行为!

  5. 理解向上转型和向下转型:

    向上转型:多态

    向下转型:编译时只调用了父类的属性和方法,子类的属性和方法不能调用,如何调用就用到了向下转型:使用强制类型转换符()! Man m = (Man) p;

    注意:可能会出现ClassCastException的异常,为避免异常,在向下转型时,先进行instanceof的判断,返回true就行了。

    instanceof的使用:a instanceof B : a为对象,B为类,即a时B的实例,当对象是右边类或者子类所创建的对象时,返回true。 与上面对应的话就是,p instanceof Man;

    其次,m instanceof Man/Person; 此时结果均为true,类只要是其父类,结果均是true

  6. 抽象类和接口肯定体现了多态性,因为抽象类和接口不能实例化。

  7. 数组也可以看成是特殊的类。

  8. 单元测试方法:满足无返回值,无形参 ,同时此类为public,此类提供公共无参构造器。

  9. static关键字

    使用static修饰属性,静态变量(或类变量)

    使用static修饰方法:

    注意: 开发中,如何确定一个属性是否要声明为static的?

    属性是可以被多个对象所共享的,不会随着对象的不同而不同 类中的常量也常常声明为staic 开发中,如何确定一个方法是否要声明为static的? 操作静态属性的方法,通常设置为static的 工具类中的方法,习惯上声明为static的。比如。Math、Arrays、collections,因为这样就可以节省了创建对象这个步骤!

    • 属性,按是否使用static修饰,又分为。静态属性 VS 非静态属性(实例变量)

      • 实例变量:我们创建了类的多个对象,每个对象都独立的拥有一套类中的非静态属性。当修改其中一个对象中的非静态属性时,不会导致其他对象中同样的属性值的修改。

      • 静态变量:我们创建了类的多个对象,多个对象共享同一个静态变量。当通过某一个对象修改静态变量时,会导致其他对象调用此静态变量时,是修改过了的。

    • static修饰属性的其他说明:

      • 静态变量随着类的加载而加载。可以通过 "类.静态变量" 的方式进行调用,静态变量的加载要早于对象的创建。

      • 由于类只会加载一次,则静态变量在内存中也只会存在一份。存在方法区的静态域中。

    • 举例:System.out, Math.PI

    • 使用static修饰方法:静态方法

    • 随着类的加载而加载,可以通过"类.静态方法"的方式进行调用

    • 静态方法中,只能调用静态的方法或属性 非静态方法中,既可以调用非静态的方法或属性,也可以调用静态的方法或属性 static注意点:

      • 在静态的方法内,不能使用this关键字、super关键字

      • 关于静态属性和静态方法的使用,大家都从生命周期的角度去理解。类的生命周期早于对象的生命周期,即静态方法/属性的生命周期早于非静态方法/属性的生命周期。

  1. final 关键字

    final可以用来修饰的结构。类、方法、变量 final用来修饰一个类:此类不能被其他类所继承。比如:String类、System类、StringBuffer类

    final用来修饰方法:表明此方法不可以被重写 比如:Object类中getClass();

    final用来修饰变量:此时的"变量"就称为是一个常量

    final修饰属性。可以考虑赋值的位置有,显式初始化、代码块中初始化、构造器中初始化 final修饰局部变量: 尤其是使用final修饰形参时,表明此形参是一个常量。当我们调用此方法时,给常量形参赋一个实参。一旦以后,就只能在方法体内使用此形参,但不能进行重新赋值。

    static final:用来修饰属性,全局常量

  2. abstract关键字

    abstract修饰类;抽象类

    此类不能实例化 抽象类中一定有构造器,便于子类实例化时调用(涉及。子类对象实例化的全过程) 开发中,都会提供抽象类的子类,让子类对象实例化,完成相关的操作 abstract修饰方法。抽象方法 抽象方法只有方法的声明,没有方法体 包含抽象方法的类,一定是一个抽象类。反之,抽象类中可以没有抽象方法的。 若子类重写了父类中的所有的抽象方法后,此子类方可实例化 若子类没有重写父类中的所有的抽象方法,则此子类也是一个抽象类,需要使用abstract修饰

    abstract使用上的注意点; 1.abstract不能用来修饰,属性、构造器等结构 2.abstract不能用来修饰私有方法、静态方法、final的方法、final的类

    抽象方法的理解:是模块使用的必须!

     抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式。
     解决的问题:
     >当功能内部一部分实现是确定的,一部分实现是不确定的。这时可以把不确定的部分暴露出去(即将不确定的方法调整为抽象方法),让子类去实现(即让子类继承重写父类中不确定功能的抽象方法)。
     >换句话说,在软件开发中实现一个算法时,整体步骤很固定、通用,这些步骤已经在父类中写好了。但是某些部分易变,易变部分可以抽
     象出来,供不同子类实现。这就是一种模板模式。

  3. 关于接口的注意事项

    1.接口中不能定义构造器,意味着接口不可以实例化!

    2.类可以实现多个接口--->这也弥补了Java单继承性的局限性!

    3.接口与接口之间可以继承,而且可以多继承

    4.接口本质上可以看作是一种规范!体现了多态性!

    5.接口中定义的静态方法,只能通过接口来调用!

    通过实现类的对象,可以调用接口中的默认方法!

  4. 关于内部类:

    创建静态的成员内部类:Person.Dog dog = new Person.dog();

    创建非静态的成员内部类:Person p = new Person(); Person.Bird bird = p.new Bird ();

  5. 异常处理:

    两种方式:try-catch-finally 与 throws

    在 Java 中所有异常类型都是内置类 java.lang.Throwable 类的子类,即 Throwable 位于异常类层次结构的顶层。Throwable 类下有两个异常分支 Exception 和 Error。

    • Exception 类用于用户程序可能出现的异常情况,它也是用来创建自定义异常类型类的类。

    • Error 定义了在通常环境下不希望被程序捕获的异常。一般指的是 JVM 错误,如堆栈溢出。

    针对try-catch-finally 的语句,像数据库连接,输入输出流、网络编程Socket等资源,JVM是不能自动的回收的,我们需要自己手动的进行资源的释放。此时的资源释放,就需要写在finally语句中。

    使用try-catch-finally 语句,目的使得程序在编译时不再报错,但是运行时还是有可能报错的。开发时,针对运行时异常,我们不再使用try-catch-finally 语句!

    体会:try-catch-finally:真正的将异常给处理掉了!

    throws的方式只是将异常给了方法的调用者,并没有真正的将异常给处理掉!

    注意:子类重写的方法抛出了异常要 不大于 父类被重写的方法抛出的异常类型!

问题:开发过程中什么时候用throws和try-catch-finally,具体可以看下边

    • 创建多线程的方式有哪些?

      比较经典的:继承Thread类和实现Runnable接口

    • 出现线程安全问题如何解决?

      采用同步,即加锁!

      方式一:同步代码块

       synchronized(同步监视器){  //同步监视器就是锁,任何一个类的对象都可以充当锁,但是多个线程必须共用同一把锁,
       //需要被同步的代码,在类中可以用 大类.class来充当锁。
       }
       ​
    • 死锁问题:不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死锁。出现死锁,所有线程没有提示,处于阻塞状态,程序无法继续。

    • 解决:改算法/尽量避免嵌套同步/尽量减少同步资源的定义

2、String、StringBuffer和StringBuilder类的区别

在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串。String 类是不可变类,即一旦一个 String 对象被创建以后,包含在这个对象中的字符序列是不可改变的,直至这个对象被销毁。

Java 提供了两个可变字符串类 StringBuffer 和 StringBuilder,中文翻译为“字符串缓冲区”。

StringBuilder 类是 JDK 1.5 新增的类,它也代表可变字符串对象。实际上,StringBuilder 和 StringBuffer 功能基本相似,方法也差不多。不同的是,StringBuffer 是线程安全的,而 StringBuilder 则没有实现线程安全功能,所以性能略高。因此在通常情况下,如果需要创建一个内容可变的字符串对象,则应该优先考虑使用 StringBuilder 类。

StringBuffer、StringBuilder、String 中都实现了 CharSequence 接口。CharSequence 是一个定义字符串操作的接口,它只包括 length()、charAt(int index)、subSequence(int start, int end) 这几个 API。

StringBuffer、StringBuilder、String 对 CharSequence 接口的实现过程不一样,如下图所示:

可见,String 直接实现了 CharSequence 接口,StringBuilder 和 StringBuffer 都是可变的字符序列,它们都继承于 AbstractStringBuilder,实现了 CharSequence 接口。

总结

  • String 是 Java 中基础且重要的类,被声明为 final class,是不可变字符串。因为它的不可变性,所以拼接字符串时候会产生很多无用的中间对象,如果频繁的进行这样的操作对性能有所影响。

  • StringBuffer 就是为了解决大量拼接字符串时产生很多中间对象问题而提供的一个类。它提供了 append 和 add 方法,可以将字符串添加到已有序列的末尾或指定位置,它的本质是一个线程安全的可修改的字符序列。

  • 在很多情况下我们的字符串拼接操作不需要线程安全,所以 StringBuilder 登场了。StringBuilder 是 JDK1.5 发布的,它和 StringBuffer 本质上没什么区别,就是去掉了保证线程安全的那部分,减少了开销。

线程安全:

StringBuffer:线程安全,执行速度慢 StringBuilder:线程不安全,执行速度快

速度:

一般情况下,速度从快到慢为 StringBuilder > StringBuffer > String,当然这是相对的,不是绝对的。

使用环境:

操作少量的数据使用 String。 单线程操作大量数据使用 StringBuilder。 多线程操作大量数据使用 StringBuffer。

3、Map和HashMap区别:

不能单独使用 Map 接口来保存数据,但是我们可以创建其实现类的对象,然后使用 Map 引用来保存对象。在这里,我们使用 HashMap 类来存储数据,并使用 Map 接口来保存该类的引用。请参见下面的示例。

 import java.util.HashMap;
 import java.util.Map;
 ​
 public class SimpleTesting{ 
     public static void main(String[] args) {
         Map<String, Integer> map = new HashMap<>();
         map.put("One", 1);
         map.put("Two", 2);
         map.put("Three", 3);
         System.out.println(map);
     }
 }
输出:

 {One=1, Two=2, Three=3}

HashMapMap 接口的一个实现类。因此,我们可以使用它来创建键值对的集合。请参见下面的示例。

 import java.util.HashMap;
 ​
 public class SimpleTesting{ 
     public static void main(String[] args) {
         HashMap<String, Integer> map = new HashMap<>();
         map.put("One", 1);
         map.put("Two", 2);
         map.put("Three", 3);
         System.out.println(map);
     }
 }
输出:

 {One=1, Two=2, Three=3}

Map接口:

  • Map提供了一种映射关系,其中的元素是以键值对(key-value)的形式存储,能够实现根据key快速查找value

  • Map中的键值对以Entry类型的对象实例形式存大

  • 键(key值)不可重复——value值可以

HashMap类:

  • HashMap是Map的一个重要实现类,也是最常用的,基于哈希表实现

  • HashMap中的Entry对象是无序排列的

  • Key值和value值都可以为null,但是一个HashMap只能有一个key值为null的映射(key不可重复)

HashMap与Map的关系如图:

4、内存解析结构

栈:放局部变量

堆:new出来的结构,对象、数组

5、Java参数的值传递机制

Java方法里的参数传递机制只有一种:值传递。即将实际参数值的复制品传入方法内,参数本身不受影响。

  • 形参是基本数据类型时,将实参基本数据类型变量的“数据值”复制并传递给形参。当调用结束时参数原来的值不受影响。

  • 形参时引用数据类型时,将实参引用数据类型变量的“地址值”传递给形参。当调用结束时参数之前的值会受影响。

方法参数传递的内存解析例子示意图:

6、方法的重载

定义:在同一个类当中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同和即可。即:同类,同方法名,不同参数列表。

7、方法重载和重写的区别

重载定义

在同一个类当中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同和即可。即:同类,同方法名,不同参数列表。

重写定义(overwrite / override):

子类继承父类之后,可以对父类中的同名同参的方法进行覆盖操作。在子类中可以根据需要对从父类中继承来的方法进行改造,也称为方法的重置、覆盖。在程序执行时,子类的方法将覆盖父类的方法。

规定:

①子类重写的方法的方法名和形参列表与父类被重写的方法的方法名和形参列表相同。

②子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符

特殊情况,子类不能重写父类中声明为private权限的的方法

③返回值类型

父类被重写的方法的返回值类型是void,则子类重写的方法的返回值类型只能是void

父类被重写的方法的返回值类型时A类型,则子类重写的方法的返回值类型可以是A类型或者A类得子类。

父类被重写的方法的返回值类型是基本数据类型(例如double),则子类重写的方法的返回值类型相同的类型

④子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型

注意:子类和父类中的同名同参数的方法要么都声明为非static的,要么都声明为static的。(不叫重写)

8、throws和throw区别

9、Collection和Collections的区别

10、final、finally、finalize区别

11、类封装性的体现

  • 将类的属性xxx私有化(private),同时,提供公共的(public)方法来获取(getXxx)和设置(setXxx)

  • 不会外暴露私有的方法

  • 单例模式

什么是单例模式?

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

注意:

  • 1、单例类只能有一个实例。

  • 2、单例类必须自己创建自己的唯一实例。

  • 3、单例类必须给所有其他对象提供这一实例。

意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

主要解决:一个全局使用的类频繁地创建与销毁。

何时使用:当您想控制实例数目,节省系统资源的时候。

如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。

关键代码:构造函数是私有的。

优点:

  • 1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。

  • 2、避免对资源的多重占用(比如写文件操作)。

缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。

以下为饿汉式的单例模式

步骤一:创建SingleObject类

 public class SingleObject {
  
    //创建 SingleObject 的一个对象
    private static SingleObject instance = new SingleObject();
  
    //让构造函数为 private,这样该类就不会被实例化!
    private SingleObject(){}
  
    //获取唯一可用的对象
    public static SingleObject getInstance(){
       return instance;
    }
  
    public void showMessage(){
       System.out.println("Hello World!");
    }
 }   

步骤二:从 singleton 类获取唯一的对象。

public class SingletonPatternDemo {
   public static void main(String[] args) {
 
      //不合法的构造函数
      //编译时错误:构造函数 SingleObject() 是不可见的
      //SingleObject object = new SingleObject();
 
      //获取唯一可用的对象
      SingleObject object = SingleObject.getInstance();
 
      //显示消息
      object.showMessage();
   }
}
输出结果:Hello World!

以下为懒汉式的单例模式

区分饿汉式和懒汉式

饿汉式:

坏处:对象加载时间过长。好处:饿汉式是线程安全的

懒汉式:

好处:延迟对象的创建。 目前的写法坏处:线程不安全。--->到多线程内容时,再修改

12、构造函数作用是什么?

作用:初始化对象(创建对象、初始化对象结构)

构造器说明:

  • 如果没有显示的定义类的构造器的话,则系统默认提供一个空参构造器

  • 定义构造器的格式,权限修饰符 类名(形参列表){}

  • 一个类中定义的多个构造器,彼此构成重载

  • 一旦我们显式的定义了类的构造器之后,系统就不再提供默认的空参构造器

  • 一个类当中至少有一个构造器

  • 默认情况下构造器权限修饰符和类的权限修饰符是一样的。

有什么用?

当你需要大批量的写对象的时候,就需要用到构造函数,它可以方便创建多个对象的实例,并且创建的对象可以被标识为特定的类型,可以通过继承扩展代码

构造函数与普通函数相比,有以下4个特点: 1.用new关键字调用,生成实例对象 2.函数内部使用this关键字,来指向即将要生成的实例对象 3.默认不用return返回值(构造函数不需要用return显式返回值,默认会返回this,也就是新的实例对象) 4.函数命名建议首字母大写,用来区分于普通函数(不是命名规范中的,但是建议这么写)

13、四种权限修饰符作用范围

权限大小排队:private < 缺省 < protected < public

private:仅作用于类内部

缺省:作用在同一个包下边

protected:作用在不同包的子类

public:作用在一个工程之下

使用范围:四种权限修饰可以用来修饰类的内部结构:属性、方法、构造器、类内部

注意:但是对于类class的权限修饰只可以用public和default(缺省)

14、构造器是否可以被重写?

不可以!

因为构造函数是不能被继承的,重写要求是子父类之间的,所以不能被重写。但是在同一个类中,构造器是可以被重载的。

构造器最大的用处就是在创建对象时执行初始化,当创建一个对象时,系统会为这个对象的实例进行默认的初始化。如果想改变这种默认的初始化,就可以通过自定义构造器来实现。

构造器说明:

  • 如果没有显示的定义类的构造器的话,则系统默认提供一个空参构造器

  • 定义构造器的格式,权限修饰符 类名(形参列表){}

  • 一个类中定义的多个构造器,彼此构成重载

  • 一旦我们显式的定义了类的构造器之后,系统就不再提供默认的空参构造器

  • 一个类当中至少有一个构造器

15、属性赋值的先后顺序

①默认初始化

②显式初始化

③构造器中赋值

④通过“对象.方法”或者“对象.属性”的方式进行赋值

16、什么是JavaBean?

  • 类是公共的

  • 有一个无参的公共的构造器

  • 有属性,且有对应的get、set方法

17、什么是MVC设计模式

M:model的缩写 V:view的缩写 C:control的缩写

C----->M------>V

|

V

SQL

18、import关键字

  • 一般的 import 关键字是导入某个类,其落脚点是某一个类/接口

  • 但是 import static 落脚点是类中的某一个静态结构(属性/方法)

  • 声明位置在包的位置和类的声明之间

  • 如果需要导入多个结构,则并列写出即可

  • 可以使用 “xxx.*" 的方式,表示导入xxx包中所有结构

  • 如果使用的类或接口是本包下定义的,则可以省略import结构

  • 如果使用的类或接口是java.lang包下定义的,则可以省略import结构

  • 如果在源文件中,使用了不同包下的同名的类,则必须至少有一个类需要以全类名(com.xxx.xxx)的方式显示。

  • 使用 ”xxx.*“ 方式表明可以调用xxx包下的所有结构,但是如果使用的是xxx子包下的结构,则仍需要显示具体的import结构

  • import static :导入指定类或接口中的静态结构:属性或方法。

19、继承性的理解

  1. 一旦子类A继承了父类B后,就继承来B中所有的属性和方法。特别的父类中声明的private的属性和方法,子类继承父类后,仍认为获取了父类中私有的结构。只是因为封装性的影响,使得子类不能直接调用父类的结构而已。

  2. 子类继承父类后,还可以声明自己特有的属性和方法,实现功能的扩展。

  3. 一个类可以被多个子类继承。

  4. 单继承性:一个类只能有一个父类

  5. 子父类时相对的概念

  6. 子类直接继承的父类称:直接父类,间接继承的父类称为:间接父类。

  7. 子类继承父类之后,就获取了直接父类以及间接父类中声明的属性和方法。

20、子类对象的实例化过程

1.从结果上看:(继承性)

子类继承父类之后,就获取了父类中声明的属性和方法

创建子类对象,在堆空间中,就会加载所有的父类中声明的属性

2.从过程上看:

当我们通过类的构造器创建子类对象时,我们一定会直接或间接的调用其父类的构造器,继而调用父类的父类的构造器,直到调用了java.lang.Object类中的空参的构造器为止,正因为加载了所有的父类的机构,所以才可以看到内存中有父类中的结构,子类对象才能考虑进行调用。

注意:虽然创建子类对象的时候,调用了父类的构造器,但是自始而终就创建了一个对象,即new的一个子类对象。

21、什么是多态(动态绑定),如何理解多态?

对象的多态性:父类的引用指向子类的对象,即Person p2 = new Man();, Person p2 = new Woman();----在这里多态可以理解为向上转型!

多态的使用:当调用父类同名同参数的方法时,实际执行的是子类重写父类的方法---虚拟方法调用。

总结:编译看左边,执行看右边!

多态性的使用前提:①类的继承要有 ②子类存在对父类方法的重写

注意:对象的多态性只适用于方法,不适用于属性!!!对于属性,执行和编译都看左边!


由于变量声明的为父类类型,导致编译时,只能调用父类中声明的属性和方法(方法实际上调用的是子类重写的方法),子类特有的属性和方法不能调用,那究竟如何调用子类特有的属性和方法呢?

Person p2 = new Man();
Man m2 = (Man)p2;  //前提是p2是类Man的实例化对象,不然会报ClassCastException异常

在这里可以理解为向下转型!

但是前提是p2是类Man的实例化对象,不然会报ClassCastException异常,这里就要用到 instanceof的关键词的使用!

a instanceof A:判断对象a是否是类A的实例,如果是返回True,否则返回False。

一道经典的多态面试题!

22、变量和实例变量的内存解析

23、类中代码块的理解

代码块的作用:用来初始化类、对象 代码块如果有修饰的话,只能使用static.

分类:静态代码块 VS 非静态代码块

静态代码块:

内部可以有输出语句 随着类的加载而执行,而且只执行一次

作用:初始化类的信息 如果一个类中定义了多个静态代码块,则按照声明的先后顺序执行

静态代码块的执行要优先于非静态代码块的执行 静态代码块内只能调用静态的属性、静态的方法,不能调用非静态的结构

非静态代码块:

内部可以有输出语句

随着对象的创建而执行 每创建一个对象,就执行一次非静态代码块

作用:可以在创建对象时,对对象的属性等进行初始化 如果一个类中定义了多个非静态代码块,则按照声明的先后顺序执行 非静态代码块内可以调用静态的属性、静态的方法,或非静态的属性、非静态的方法

25、开发过程中如何选择使用 try-catch-finally 还是使用throws?

①如果父类中被重写的方法没有throws方式处理异常,则子类重写的方法也不能用throws,意味着如果子类重写的方法中有异常,必须使用try-catch-finally的方式处理异常。

②在执行方法a中,先后又调用了另外的几个方法,这几个方法是递进方法执行的。我们建议这几个方法使用throws的方式进行处理,而执行的方法a可以考虑使用try-catch-finally方式进行处理。??

注意补充:throw和throws的区别理解?

  • throw是针对的异常对象的产生,是手动的生成一个异常对象,并抛出(throw)

  • throws是“抓取异常”,可以理解为异常的处理方式,有 try-catch-finally 和 throws 两种方法。

 

 

26.创建多线程的方式有哪些?比较他们区别

  1. 继承于Thread类

    ①创建一个继承于Thread类的子类

    ②重写Thread类中的 run() 方法 --> 将此线程执行的操作声名在 run() 中

    ③创建Thread类子类中的对象

    ④通过此对象调用 start()

  2. 实现Runnable接口

    ①创建一个实现 Runnable 接口的类

    ②实现类去实现 Runnable 中的抽象方法 :run()

    ③创建实现类的对象

    ④将此对象作为参数传递到Thread类中的构造器中,创建Thread类的对象

    ⑤通多Thread类的对象调用start() 方法

比较:

开发中,优先选择:实现 Runnable 接口的方式

原因:1. 实现的方式没有类的单继承性的局限性

           2. 实现的方式更适合来处理多个线程有共享数据的情况

联系:public class Thread implements Runnable()

相同点:两种方式都是重写了run() ,将线程执行逻辑声名在 run() 中。

27.浅拷贝和深拷贝有什么区别?

  • 浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存(分支)。

  • 深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象,是“值”而不是“引用”(不是分支)

28.看下面结果能过添加成功?

---不能添加成功!!

29.那些排序算法是稳定的?哪些不是稳定的?

稳定的:冒泡、直接插入、归并排序

不稳定:快排、选择排序、希尔排序、计数排序、桶排序

30.Redis 分布式锁是如何实现的呢?

  • Redis 利用setnx实现的分布式锁是不可重入的!

  • Redission 实现的分布式锁是可重入的(前提保证是同一个线程内),这样可以提高高并发场景下分布式锁的有效性!

Redission 实现的分布式锁底层使用的是setnx 和 lua脚本(保证原子性)

---------Redission实现分布式锁,如何控制锁的有效时长??

在Redission的分布式锁中,提供了一个WatchDog(看门狗),一个线程获取锁成功之后,WatchDog会给持有锁的线程续期(默认是每隔十秒续期一次)

---------Redission这个锁能够解决主从数据一致性的问题吗??

不能解决,但是可以用Redission提供的红锁(AP思想,即保证高可用性)来解决,但是这样的话性能太低了,如果业务中非要保证数据一致性问题,可以采用zookeeper(CP思想,即保证高一致性)实现分布式锁!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/624214.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何在Moonbeam设置多重签名钱包,加固资产安全

Moonbeam Safe是以太坊上Safe&#xff08;先前名为Gnosis Safe&#xff09;的分叉。Safe于2018年正式推出&#xff0c;并发展成为了以太坊上知名的去中心化托管协议和集体资产管理平台。 Moonbeam Safe可用于创建多重签名Safe钱包&#xff0c;通过配置一个多签&#xff08;mul…

02.Web大前端时代之:HTML5+CSS3入门系列~H5结构元素

Web大前端时代之&#xff1a;HTML5CSS3入门系列&#xff1a;Web大前端时代之&#xff1a;HTML5CSS3入门系列 - 毒逆天 - 博客园 1.结构元素 可以理解为语义话标记&#xff0c;比如&#xff1a;以前这么写<div id"nav"></div> 现在偷懒写&#xff1a;&l…

JavaWeb笔记_SpringBoot原理

JavaWeb笔记_SpringBoot原理 配置优先级Bean管理获取BeanBean作用域第三方Bean SpringBoot原理自动配置原理ComponentScan组件扫描Import导入源码跟踪Conditional自定义starter创建aliyun-oss-spring-boot-starter模块创建aliyun-oss-spring-boot-autoconfigure 来源 配置优先级…

opencv、dlib、paddlehub人脸检测

opencv、dlib、paddlehub检测效果对比。dlib和paddlehub的效果相对好一点。 说明&#xff1a;本文只做人脸检测不识别&#xff0c;找识别的不用看本文。 ## 部署说明 # 1. 安装python或conda # 2. 安装依赖&#xff0c;pip install -r requirements.txt # 3. 192.168.1.41 修…

Docker 基本使用

安装 Linux安装 # 1、查看当前Linux系统版本 Linux系统版本需要>3.0 [rootzjrs_test2_152 ~]# uname -a Linux zjrs_test2_152 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:39:32 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux [rootzjrs_test2_152 ~]# uname -r 3.10.0-957.el…

Baumer工业相机堡盟工业相机如何使用BGAPI SDK控制相机数据流的开启和关闭(C#)

Baumer工业相机堡盟工业相机如何使用BGAPI SDK控制相机数据流的开启和关闭&#xff08;C#&#xff09; Baumer工业相机Baumer工业相机BGAPI SDK的技术背景Baumer工业相机使用BGAPISDK控制相机数据流的方式1.引用合适的类文件2.使用BGAPISDK控制相机数据流的方式2.使用BGAPISDK控…

AOP--@DeclareParents--引入新功能

目录 引入 解析 示例 引入 Java不是动态语言&#xff1b;一旦类编译完成了&#xff0c;我们就很难再为该类添加新的功能了切面能够为现有的方法增加额外的功能&#xff0c;为什么不能为一个对象增加新的方法呢&#xff1f;实际上&#xff0c;利用被称为引入的AOP概念&#x…

从数据开始,构建值得信赖的生成式AI应用

生成式AI有望从根本上打开新世界机遇的大门&#xff1a;从能够个性化回复的对话式聊天机器人&#xff0c;到各种应用的代码&#xff0c;再到营销传播的定制化内容......生成式AI正在彻底改变企业的运作方式。越来越多的领先企业正在构建可信的生成式AI应用&#xff0c;让它们在…

信息共享、管理协作!工程劳务管理模板让企业内部更加通畅

随着建筑行业的快速发展&#xff0c;工程劳务管理变得越来越复杂&#xff0c;同时企业也需要更加高效地管理劳务人员的信息、工资、考勤等方面。因此&#xff0c;工程劳务管理系统应运而生&#xff0c;帮助企业解决这些问题。作为一款低代码开发平台&#xff0c;百数根据市面上…

面向 MSP 的IT管理

MSP&#xff08;管理服务提供商&#xff09;是通过建立自己的网络运作中心(NOC&#xff0c;Network Operating Center)来实施管理服务的。用户的网络通过WAN与MSP的NOC相连&#xff0c;并使用加密技术保证信息在网络上的传输安全。通过NOC&#xff0c;MSP可以实现远程的管理、实…

LVS负载均衡群集----DR部署

文章目录 一、数据包流向分析二、DR模式的特点三、LVS-DR中的ARP问题四、LVS单网段DR模式部署第一步配置负载调度器第二步设置两台节点服务器第三步设置DR 服务器第四步在本地查看调度服务器 一、数据包流向分析 &#xff08;1&#xff09;客户端发送请求到 Director Server&a…

前后端 java 对接海康威视监控-hls实现h5播放

海康的获取监控预览流的接口当中支持 rtsp、rtmp、hls等协议。 这篇文章主要是说hls协议的。 贴上海康的开发平台地址&#xff0c;其中有对应的API&#xff1a;海康开发平台 1、java层面代码 这里除了main方法之外&#xff0c;有两个方法&#xff0c;分别是&#xff1a; 1&am…

【Python】一文教你如何使用 Requests 库

作者主页&#xff1a;爱笑的男孩。的博客_CSDN博客-深度学习,活动,python领域博主爱笑的男孩。擅长深度学习,活动,python,等方面的知识,爱笑的男孩。关注算法,python,计算机视觉,图像处理,深度学习,pytorch,神经网络,opencv领域.https://blog.csdn.net/Code_and516?typeblog个…

审视自己再出发,在职读研从人民大学与加拿大女王大学金融硕士项目起航

有人说&#xff0c;人生并非一帆风顺。是的&#xff0c;在人生的道路上&#xff0c;总会出现各种各样的麻烦。或者认真学习不见成效&#xff0c;或是努力工作得不到赏识。人生中最困难的事情就是审视自己&#xff0c;当我们意识到自己需要提升时&#xff0c;往往是拥有强大能量…

【Linux】线程分离和线程互斥

终于到线程互斥了~ 文章目录 前言一、线程分离 如何理解线程库和线程ID二、线程互斥总结 前言 在上一篇文章中我们学习了线程控制&#xff0c;比如创建一个线程&#xff0c;取消一个线程以及等待线程&#xff0c;这篇文章我们讲两个非常重要的概念&#xff0c;一个是线…

CDH 之 hive 升级至 hive-3.1.3 完美踩坑过程

一、准备工作 1.1 前言 这是博主在升级过程中遇到的问题记录&#xff0c;大家不一定遇到过&#xff0c;如果不是 CDH 平台的话&#xff0c;单是 hive 服务升级应该是不会有这些问题的&#xff0c;且升级前博主也参考过几篇相关 CDH 升级 hive 服务的博文&#xff0c;前面的升级…

go语言操作以太坊智能合约

操作中要注意版本问题 geth版本、golang版本等 在remix环境中写好合约后&#xff0c;进行编译得到abi文件 简单举例 Hello.sol合约 // SPDX-License-Identifier: MIT pragma solidity ^0.8.0;contract Hello {string Msg;function setMsg(string memory _msg) public{Msg_msg…

SM2密码算法规范介绍

目录 1、SM2的密钥对 1.1、SM2公钥 1.2、SM2私钥 2、密钥数据格式 2.1、 GMT0009 2.2、 GMT0016 2.3、 GMT0018 3、加密数据格式 3.1、GMT0009 3.2、GMT0016 3.3、GMT0018 4、签名数据格式 4.1、GMT0009 4.2、GMT0016 4.3、GMT0018 1、SM2的密钥对 1.1、SM2公钥…

java版DVD影碟片出租赁系统C/S模式 java电影购票系统课程设计

系统采用c/s架构&#xff0c;当然&#xff0c;你可以服务端、客户端都在同一台电脑上运行&#xff1b; 也可以在同一局域网内服务端、客户端在其它不同电脑上运行&#xff1b; 如果你有云服务器&#xff0c;可将Service端代码部署至云服务器上&#xff0c;客户端在任何一台有…

不愧是阿里P8出手的并发编程笔记!颠覆了我以往“正确“的认知

对于一个Java程序员而言&#xff0c;能否熟练掌握并发编程是判断他优秀与否的重要标准之一。因为并发编程是Java语言中最为晦涩的知识点&#xff0c;它涉及操作系统、内存、CPU、编程语言等多方面的基础能力&#xff0c;更为考验一个程序员的内功。 那到底应该怎么学习并发编程…