黑马Java基础理论知识点问答

面试问答标准答案

java原理类

(1)解释java的跨平台性原理
答:java程序并不能直接运行,java编译器把程序编译成与平台无关的字节码文件(.class文件),然后通过下载不同操作系统的jvm虚拟机,将字节码文件编译为.java程序。
(2)JVM,JRE,JDK是什么?以及它们的包含关系。
答:JVM是java虚拟机
JRE是java运行环境,包含JVM和java核心类库
JDK是java开发工具,包含了jre和开发工具。
(3)JDK的安装目录中各部分成员的说明。
在这里插入图片描述(4)常用DOS命令。
在这里插入图片描述(5)为什么要配置环境变量:
开发中我们设计的java程序需要用到的命令放在jvm的bin文件夹下面,如果不配置则命令只能在该文件目录下执行。所以配置环境变量的作用就是让bin文件夹下的java相关命令可以在任意文件夹下面执行
其中JAVA_HOME是告诉操作系统jdk的安装位置,Path是告诉操作系统jdk的bin文件夹下面的命令安装到哪个位置。

基本语法类

(1)多行注释和文档注释的区别

/*
  可能这就是爱
*/

/**
  这是文档注释
  */

(2)计算机底层用(数字电路)来实现,开表示0,关表示1.数据在底层采用(二进制)存储,我们认为计算机的一个开关称为一位。(字节)是计算机数据的最小单位,计算机存储的最小信息单元称为(位),计算机最基本的存储单元叫(字节)
(3)java的基本数据类型包含什么:
在这里插入图片描述1. 定义long类型的变量时,需要在整数的后面加L(大小写均可,建议大写)。因为整数默认是int类型,整数太大可能超出int范围。
2. 定义float类型的变量时,需要在小数的后面加F(大小写均可,建议大写)。因为浮点数的默认类型是double, double的取值范围是大于float的,类型不兼容。

(4)解释类型转换
1.自动类型转换:类型范围小的变量可以直接赋值给类型范围大的变量。表达式中小类型的变量会自动转换为较大范围的类型再去进行运算.在表达式中,byte、short、char 是直接转换成int类型参与运算的。

2.强制类型转换:类型范围大的变量,不能直接赋值给类型小的变量,会报错,必须强制转换。

double num1=5.5;
int num2=(int) num1;

Note:

char类型的数据转换为int类型是按照码表中对于的int值进行计算的。

int a = 'a';
System.out.println(a); // 将输出97

整数默认是int,byte,short和char类型的数据参与运算都会自动转换为int类型。

byte b1 = 10;
byte b2 = 20;
byte b3 = b1 + b2; 
// 第三行代码会报错,b1和b2会自动转换为int类型,计算结果为int,int赋值给byte需要强制类型转换。
// 修改为:
int num = b1 + b2;
// 或者:
byte b3 = (byte) (b1 + b2);

boolean类型不能和其他数据类型相互转换。

(5)字符和字符串的“+”操作:

char类型参与算术运算使用的是底层对应的十进制数值(’a’–97 ‘A’–65 ‘0’–48)
在程序开发中我们很少使用byte或者short类型定义整数。也很少会使用char类型定义字符,而使用字符串类型,更不会使用char类型做算术运算。

// 可以通过使用字符与整数做算术运算,得出字符对应的数值是多少
char ch1 = 'a';
System.out.println(ch1 + 1); // 输出98,97 + 1 = 98

char ch2 = 'A';
System.out.println(ch2 + 1); // 输出66,65 + 1 = 66

char ch3 = '0';
System.out.println(ch3 + 1); // 输出49,48 + 1 = 49

字符串中的“+”是字符串连接符

System.out.println(1 + 99 + "年黑马"); // 输出:199年黑马
System.out.println(1 + 2 + "itheima" + 3 + 4); // 输出:3itheima34
// 可以使用小括号改变运算的优先级 
System.out.println(1 + 2 + "itheima" + (3 + 4)); // 输出:3itheima7

(6)方法易考点:

  • 每个方法在被调用执行的时候,都会进入栈内存,并且拥有自己独立的内存空间,方法内部代码调用完毕之后,会从栈内存中弹栈消失。
  • 基本数据类型的参数,形式参数的改变,不影响实际参数。引用数据类型的传参,传入的是地址值,内存中会造成两个引用指向同一个内存的效果,所以即使方法弹栈,堆内存中的数据也已经是改变后的结果
  • 方法不能嵌套定义。

面向对象

(1)多个对象在堆内存中,都有不同的内存划分,成员变量存储在各自的内存区域中,成员方法多个对象共用的一份。只要有任何一个对象修改了内存中的数据,随后,无论使用哪一个对象进行数据获取,都是修改后的数据。

(2)成员变量和局部变量的区别:

  • 类中位置不同:成员变量(类中方法外)局部变量(方法内部或方法声明上)
  • 内存中位置不同:成员变量(堆内存)局部变量(栈内存)
  • 生命周期不同:成员变量(随着对象的存在而存在,随着对象的消失而消失)局部变量(随着方法的调用而存在,随着方法的调用完毕而消失)
  • 初始化值不同:成员变量(有默认初始化值)局部变量(没有默认初始化值,必须先定义,赋值才能使用)

(3)封装的好处与原则
将类的某些信息隐藏在类的内部(private只允许类内访问),不允许外部程序直接访问,而是通过该类提供的方法实现对隐藏信息的操作和访问。
好处:通过方法控制成员变量的操作,提高代码的安全性。把代码用方法封装,提高代码复用性。

(4)this主要是用于指代成员变量,区分成员变量和局部变量的重名问题。方法的形参如果与成员变量同名,不带this修饰的变量指的是形参,而不是成员变量.

(5)static:
1.static修饰的成员变量表示该变量只在内存中存储一份,可以被共享访问修改。静态成员变量属于类,实例变量属于对象。

类名.成员变量(推荐)

在这里插入图片描述在这里插入图片描述
2.工具类定义的都是一些静态方法,每个方法以完成一个功能为目的。以来可以调用方便,二来可以提高代码的复用性。建议把工具类的构造器私有,工具类无法创建对象。里面都是静态方法,直接用类名访问即可。

3.静态方法中是不可以出现this关键字的。

(6)继承
1.子类可以继承父类的属性和行为,但是子类不能继承父类的构造器。子类可以继承父亲的私有成员变量,但是不能直接访问。

子类中所有的构造器默认都会先访问父类中无参的构造器,再执行自己.默认是super()

如果父类中没有无参数构造器,只有有参构造器,会报错。因为子类默认是调用父类无参构造器的。
子类构造器中可以通过书写 super(…),手动调用父类的有参数构造器

super调用父类构造器的作用:通过调用父类有参数构造器来初始化继承自父类的数据

2.在子类方法中访问成员(成员变量、成员方法)满足:就近原则。先子类局部范围找,然后子类成员范围找,然后父类成员范围找,如果父类范围还没有找到则报错。
3.如果子父类中出现了重名的成员变量,优先访问子类的,如果想访问父类用super调用。
(7)方法重写:在继承体系中,子类出现了和父类中一模一样的方法声明,我们就称子类这个方法是重写的方法

  • 情况:当子类需要父类的功能,但父类的该功能不完全满足自己的需求时。子类可以重写父类中的方法。
  • @Override重写注解
    @Override是放在重写后的方法上,作为重写是否正确的校验注解。加上该注解后如果重写错误,编译阶段会出现错误提示。建议重写方法都加@Override注解,代码安全。
  • 重写方法的名称、形参列表必须与被重写方法的名称和参数列表一致。私有方法不能被重写。子类重写父类方法时,访问权限必须大于或者等于父类 (暂时了解 :缺省 < protected < public).子类不能重写父类的静态方法,如果重写会报错的。

(8)多态
1.同类型的对象,执行同一个行为,会表现出不同的行为。

父类类型 对象=new 子类构造器;
接口 对象=new 实现类构造器;

2.多态中成员访问特点
方法调用:编译看左边,运行看右边。
变量调用:编译看左边,运行也看左边。
3.多态的前提
有继承/实现关系;有父类引用指向子类对象;有方法重写。
4.多态优点:使用父类型作为参数,可以接受这父类的一切子类对象+右边对象可以实现解耦合便于维护。
5.自动类型转换(从子到父):子类对象赋值给父类类型的变量指向。
强制类型转换(从父到子)

子类 对象变量 = (子类)父类类型的变量

作用:可以解决多态下的劣势,可以实现调用子类独有的功能。
注意: 如果转型后的类型和对象真实类型不是同一种类型,那么在转换的时候就会出现ClassCastException

(9)内部类

名称 属性 特点
静态内部类 外部类名.内部类名 对象名=new 外部类名.内部构造器(); 可以访问外部类静态成员,不能访问外部类实例成员
成员内部类 外部类名.内部类名 对象名 = new 外部类构造器.new 内部类构造器(); 可以访问外部类静态成员,可以访问外部类实例成员
局部内部类 放在方法,代码块,构造器等执行体中
匿名内部类 方便创建子类对象 是没有名字的内部类。会产生一个匿名内部类的对象。对象类型是当前new的那个的类型的子类类型。

(10)包
1.包是用来分门别类管理不同类的(类似于文件夹)
2.建包的语法:package 公司域名倒写.技术名称
3.导包:使用不同包下的类:import 包名.类名
4.如果一个类中需要用到俩个相同名字的不同类,默认只导入一个类,另外一个要带包名访问。

(11)枚举
1.枚举是java中的一种特殊类型,枚举的作用是“为做信息的标志和信息的分类”。

修饰符 enum 枚举名称{
    
    
  第一行都是罗列枚举类实例的名称
  }

2.特征:
(1)枚举继承了枚举类型:java.long.Enum
(2) 枚举都是最终类,不能被继承
(3) 枚举类不能对外创建对象
3.优点:枚举用作信息标志和分类的好处(入参约束严谨,代码优雅,是最好的信息分类技术)

API

String类

(1)特点:字符串不可变,它们的值在创建后不能被更改。虽然 String 的值是不可变的,但是它们可以被共享。字符串效果上相当于字符数组( char[] ),但是底层原理是字节数组( byte[] )
(2)String字符串的创建:

String s=new String();
String s=new String(chs);//字符数组
String s=new String(bys);//字节数组
//通过 new 创建的字符串对象,每一次 new 都会申请一个内存空间,虽然内容相同,但是地址值不同
String s="abc";
//直接赋值的字符串,只要字符序列相同(顺序和大小写),无论在程序代码中出现几次,JVM 都只会建立一个 String 对象,并在字符串池中维护

(3)==:比较基本数据类型比较的值,比较引用数据类型比较的是对象的地址值。
equals比较的是值是否相同,去扽大小写。

(4)String类常用方法:

public boolean equals(Object anObject) 比较字符串的内容,严格区分大小写(用户名和密码)
public char charAt(int index) 返回指定索引处的 char 值
public int length() 返回此字符串的长度

ArrayList类

public boolean remove(Object o):删除指定的元素,返回删除是否成功
System.out.println(array.remove("world"));

public E remove(int index):删除指定索引处的元素,返回被删除的元素System.out.println(array.remove(1))public E set(int index,E element):修改指定索引处的元素,返回被修改的元素    System.out.println(array.set(1,"javaee"));

public E get(int index):返回指定索引处的元素

public int size():返回集合中的元素的个数
  System.out.println(array.size());

在这里插入图片描述

Object类

toString() 返回当前对象在堆内存中的地址信息:类的权限名@内存地址 父类的toString()是为了被子类重写,以便于返回对象的内容信息
equals 默认是返回一个对象和另一个对象地址是否相等 让子类重写来定制比较规则

StringBuilder

(1)定义:可变的字符串类,我们可以把它看成一个对象容器。
(2)作用:提高字符串的拼接效率,例如拼接,修改等。

StringBuilder s=new StringBuilder(String str);
append(任意类型):添加数据并且返回本身
reverse():反转对象的内容
length():返回对象长度
toString():StringBuilder转换为String

Math

在这里插入图片描述

System

在这里插入图片描述计算机认为时间是有起点的,起始时间: 1970年1月1日 00:00:00
时间毫秒值:指的是从1970年1月1日 00:00:00走到此刻的总的毫秒数,应该是很大的。 1s = 1000ms。

BigDecimal作用

用于解决浮点型运算精度失真的问题.
在这里插入图片描述

Date类

在这里插入图片描述在这里插入图片描述

SimpleDataFormat类

完成日期时间的格式化操作。

在这里插入图片描述

Calendar

在这里插入图片描述在这里插入图片描述在这里插入图片描述

Array

操作数组的API.
在这里插入图片描述在这里插入图片描述

易错知识点

(1)扩展赋值运算符隐含强制转换

short s = 10;
s = s + 10; // 此行代码报出,因为运算中s提升为int类型,运算结果int赋值给short可能损失精度

s += 10; // 此行代码没有问题,隐含了强制类型转换,相当于 s = (short) (s + 10);

基础编程题目

1.使用三目运算符比较三个数字大小

public class OperatorTest02 {
    
    
public static void main(String[] args) {
    
     
  Scanner sc=new Scanner(System.in);
  int[] arr=new int[3];
  for(int i=0;i<=3;i++)
    arr[i]=sc.nextInt();
 int tempHeight=a[0]>a[i]?a[0]:a[1];
 int maxHeight=a[2]>tempheight?a[2]:tempheight;
  System.out.println(maxHeight);
  }
 }   

2.求n位的水仙花数

public class ForTest04 {
    
    
 public static void main(String[] args) {
    
    
   Scanner sc=new Scanner(System.in);
   int n=sc.nextInt();
   for(int i=Math.pow(10,n-1);i<Math.pow(10,n);i++)
   {
    
    
     int sum=0;
     while(i!=0)
     {
    
    
       sum+=Math.pow(i%10,3);
       i/=10;
     }
     if(sum==i)
     System.out.println(sum);
   }
}

3.调用random猜测数字

public class RandomTest {
    
    
	public static void main(String[] args) {
    
    
//要完成猜数字的游戏,首先需要有一个要猜的数字,使用随机数生成该数字,范围1到100
		Random r = new Random();
		int number=r.nextInt(100)+1;
		while(true) {
    
    
			//使用程序实现猜数字,每次均要输入猜测的数字值,需要使用键盘录入实现
			Scanner sc = new Scanner(System.in);
			System.out.println("请输入你要猜的数字:");
			int guessNumber = sc.nextInt();
			
			//比较输入的数字和系统产生的数据,需要使用分支语句。
			if(guessNumber > number) {
    
    
				System.out.println("你猜的数字" + guessNumber + "大了");
			} else if(guessNumber < number) {
    
    
				System.out.println("你猜的数字" + guessNumber + "小了");
			} else {
    
    
				System.out.println("恭喜你猜中了");
				break;
       }
		}
	}

4.利用方法重载的思想,设计比较俩个整数是否相同。(方法在同一个类中,名字相同,但是参数类型,个数,参数本身不同)

public class MethodTest {
    
    
    public static void main(String[] args) {
    
    
        //调用方法
        System.out.println(compare(10, 20));
        System.out.println(compare((byte) 10, (byte) 20));
        System.out.println(compare((short) 10, (short) 20));
        System.out.println(compare(10L, 20L));
    }

    //int
    public static boolean compare(int a, int b) {
    
    
        System.out.println("int");
        return a == b;
    }

    //byte
    public static boolean compare(byte a, byte b) {
    
    
        System.out.println("byte");
        return a == b;
    }

    //short
    public static boolean compare(short a, short b) {
    
    
        System.out.println("short");
        return a == b;
    }

    //long
    public static boolean compare(long a, long b) {
    
    
        System.out.println("long");
        return a == b;
    }

}

5.设计一个方法用于数组遍历,要求遍历的结果是在一行上的

System.out.println(“内容”); 输出内容并换行
System.out.print(“内容”); 输出内容不换行
System.out.println(); 起到换行的作用

public class MethodTest01{
    
    
public static void main(String[] args) {
    
    
//定义一个数组,用静态初始化完成数组元素初始化
 int[] arr = {
    
    11, 22, 33, 44, 55};
//调用方法
 printArray(arr);
}
public static void main(String[] arr){
    
    
  System.out.print("[");
  for(int i=0;i<arr.length;i++)
  {
    
    
    if(i==arr.length-1)
     System.out.println(arr[i]);
   else
     System.out.println(arr[i]+",");
 }
   System.out.println("]");
   }
}   

6.我国古代数学家张丘建在《算经》一书中提出的数学问题:鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一。百钱买百鸡,问鸡翁、鸡母、鸡雏各几何?

public class Test05 {
    
    
    public static void main(String[] args) {
    
    
//第1层循环,用于表示鸡翁的范围,初始化表达式的变量定义为 x=0,判断条件是x<=20
   for(int x=0; x<=20; x++) {
    
    
//第2层循环,用于表示鸡母的范围,初始化表达式的变量定义为 y=0,判断条件是y<=33
     for(int y=0; y<=33; y++) {
    
    
      //这个时候,用于表示鸡雏的变量 z = 100 – x – y
     int z = 100 - x - y;
     //判断表达式 z%3==0 和表达式 5*x + 3*y + z/3 = 100 是否同时成立
           if(z%3==0 && 5*x+3*y+z/3==100) {
    
    
                System.out.println(x+","+y+","+z);
                }
            }
        }
    }
}

7.有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子, 假如兔子都不死,问第二十个月的兔子对数为多少?

public class Test04 {
    
    
    public static void main(String[] args) {
    
    
    //为了存储多个月的兔子对数,定义一个数组,用动态初始化完成数组元素的初始化,长度为20
        int[] arr = new int[20];
//因为第1个月,第2个月兔子的对数是已知的,都是1,所以数组的第1个元素,第2个元素值也都是1
        arr[0] = 1;
        arr[1] = 1;
//用循环实现计算每个月的兔子对数
        for(int x=2; x<arr.length; x++) {
    
    
            arr[x] = arr[x-2] + arr[x-1];
        }
//输出数组中最后一个元素的值,就是第20个月的兔子对数
        System.out.println("第二十个月兔子的对数是:" + arr[19]);
    }
}

8.已知用户名和密码,模拟用户登录,总共给三次机会。

public class StringTest01 {
    
    
public static void main(String[] args) {
    
    
//已知用户名和密码,定义两个字符串表示即可
        String username = "itheima";
        String password = "czbk";
 for(int i=0;i<3;i++)
 {
    
    
    Scanner sc=new Scanner(System.in);
    System.out.println("请输入用户名:");
    String name = sc.nextLine();
	System.out.println("请输入密码:");
    String pwd = sc.nextLine();

   if(name.equals(username)&&pwd.equals(passwprd)){
    
    
        System.out.println("登录成功");
           break;}
    } else {
    
    
            if(2-i == 0) {
    
    
                  =System.out.println("你的账户被锁定,请与管理员联系");
                } else {
    
    
                    System.out.println("登录失败,你还有" + (2 - i) + "次机会");
                }
            }
        }
    }
}

9.反向输出字符串

public static String reverse(String s)
{
    
    
  String ss="";
  for(i=s.length()-1;i>=0;i--)
  {
    
    
    ss+=s.charSt(i);
  }
  return ss;
}

10.统计字符出现的次数

public class StringTest03 {
    
    
public static void main(String[] args) {
    
    
//键盘录入一个字符串,用 Scanner 实现
Scanner sc = new Scanner(System.in);
 System.out.println("请输入一个字符串:");
String line = sc.nextLine();
//要统计三种类型的字符个数,需定义三个统计变量,初始值都为0
        int bigCount = 0;
        int smallCount = 0;
        int numberCount = 0;

 //遍历字符串,得到每一个字符
for(int i=0; i<line.length(); i++) {
    
    
      char ch = line.charAt(i);
//判断该字符属于哪种类型,然后对应类型的统计变量+1
     if(ch>='A' && ch<='Z') {
    
    
             bigCount++;
           } else if(ch>='a' && ch<='z') {
    
    
             smallCount++;
            } else if(ch>='0' && ch<='9') {
    
    
             numberCount++;
            }
        }

        //输出三种类型的字符个数
 System.out.println("大写字母:" + bigCount + "个");
 System.out.println("小写字母:" + smallCount + "个");
 System.out.println("数字:" + numberCount + "个");
    }
}

11.ArrayList存储学生对象并且遍历

public class ArrayListTest {
    
    
public static void main(String[] args) {
    
    
//创建集合对象
Array<Student> array=new Arraylist<>();
 //为了提高代码的复用性,我们用方法来改进程序
     addStudent(array);
     addStudent(array);
     addStudent(array);

//遍历集合,采用通用遍历格式实现
 for (int i = 0; i < array.size(); i++) {
    
    
       Student s = array.get(i);
       System.out.println(s.getName() + "," + s.getAge());
        }
    }

 
public static void addStudent(ArrayList<Student> array) {
    
    
 //键盘录入学生对象所需要的数据
Scanner sc = new Scanner(System.in);
String name = sc.nextLine();
String age = sc.nextLine();
//创建学生对象,把键盘录入的数据赋值给学生对象的成员变量
Student s = new Student();
s.setName(name);
s.setAge(age);
//往集合中添加学生对象
array.add(s);
    }
}

红黑树

在这里插入图片描述红黑树是一种自平衡的二叉查找树(平衡二叉B树)
(1)每一个节点可以是红或者黑,红黑树不是通过高度平衡的,而是通过红黑规则来实现。
(2)红黑规则:
1)根节点必定是黑色
2)如果某一个节点是红色,子节点必然是黑色
3)对于每一个节点来说,从该节点到其后所有后代叶节点的简单路径上,均包含相同数目的黑色节点。
在这里插入图片描述添加原则
(1)每一个节点或是红色的,或者是黑色的,根节点必须是黑色
(2)如果一个节点没有子节点或者父节点,则该节点相应的指针属性值为Nil,这些Nil视为叶节点,每个叶节点(Nil)是黑色的;
(3)如果某一个节点是红色,那么它的子节点必须是黑色(不能出现两个红色节点相连的情况)
(4)对每一个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点。

hashset底层实现:

在这里插入图片描述在这里插入图片描述在这里插入图片描述

Treeset

默认排序规则:
(1)对于数值类型:Integer , Double,官方默认按照大小进行升序排序。
(2)对于字符串类型:默认按照首字符的编号升序排序。
(3)对于自定义类型如Student对象,TreeSet无法直接排序。
法(一):让自定义的类(如学生类)实现Comparable接口重写里面的compareTo方法来定制比较规则。
法(二):TreeSet集合有参数构造器,可以设置Comparator接口对应的比较器对象,来定制比较规则。

猜你喜欢

转载自blog.csdn.net/m0_63203388/article/details/124176241