Java 基础理论知识

发布于:2023-02-09 ⋅ 阅读:(771) ⋅ 点赞:(0)

🐟什么是  JDK、JRE、JVM

JDK:
         Java 语言的软件开发工具包,是整个java开发的核心,它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具。没有JDK的话,无法编译Java程序(指java源码.java文件),如果想只运行Java程序(指class或jar或其它归档文件),要确保已安装相应的JRE。
JRE:
        Java运行环境,JRE可以让计算机系统运行Java应用程序。JRE的内部有一个Java虚拟机(Java Virtual Machine,JVM)以及一些标准的类别函数库(Class Library)。它包括Java虚拟机,Java核心类库和支持文件。它不包含开发工具(JDK)--编译器、调试器和其它工具。
JVM:
        Java虚拟机,本质上就是一个程序,当它在命令行上启动的时候,就开始执行保存在某字节码文件中的指令。Java语言的可移植性正是建立在Java虚拟机的基础上。任何平台只要装有针对于该平台的Java虚拟机,字节码文件(.class)就可以在该平台上运行。这就是“一次编译,多次运行”。


🐟什么是  javaSE、java EE、java ME

javaSE:Java平台标准版、开发电脑上运行的软件(针对桌面程序的开发)

javaEE:Java平台企业版、开发网站(针对企业级应用的开发)。

javaME:Java平台微型版、开发手机软件(APP,针对嵌入式设备软件的开发)。


🐟运行java代码的两个命令是什么

前提:java运行环境已配好,打开cmd,进入到.Java文件所在的文件夹下

编译:javac  名字.java

运行:java  名字


🐟java中变量标识符的命名规则有哪些

① 以数字,字母,下划线,美元符($)组成且不能以数字开头。

② 不能是关键字,保留字

③见名知意且区分大小写


🐟java中都有哪些数据类型


🐟java中的运算符都有哪些 


🐟java中进行类型转换的规则是什么 

①八种基本数据类型中,除 boolean 类型不能转换,剩下七种类型之间都可以 进行转换

②如果整数型字面量没有超出 byte,short,char 的取值范围,可以直接将其赋值。

③容量从小到大的排序为:byte < short(char) < int <long < float < double

④大容量转换成小容量(强制类型转换)必须添加“强制类型转换符”,否则可能出现精度损失;

⑤小容量转换成大容量(自动类型转换)其中 short和 char 都占用两个字节。

⑥多种数据类型混合运算,各自先转换成容量最大的那一种再做运算;

⑦byte,short,char 类型混合运算时,先各自转换成 int 类型再做运算;


🐟Scanner是在那个包下的类

Scanner  类在  java.util  包下,用于获取键盘输入(是一个基于正则表达式的文本扫描器),文件、字符串、输入流中解析出基本类型值和字符串值。”


🐟程序执行结构有哪些

1、顺序结构,程序中各个操作按照在源代码中的排列顺序,自上而下,依次执行;

2、选择结构,根据某个特定的条件进行判断后,选择其中一支执行;

3、循环结构,在程序中需要反复执行某个或某些操作,直到条件为假或为真时才停止循环。


🐟java中的分支语句是什么

①if:

if(条件语句){
    代码块;
}

②if  else:

if(条件语句){
    代码块1;
}else{
    代码块2;
}

③if  else if:

if(条件语句1){
    代码块1;
}else if(条件语句2){
    代码块2;
}
.
.
.else{
    代码块n;
}

④switch:

switch(分支标准){
    case 结果1:
        代码块1;
        break;
    caes 结果2:
        代码块2;
        break;
            .
            .   
            .
    default:
        代码块
}

🐟java中循环都有哪些

①while(先判断再执行)

while(循环终止条件){
    代码块;
}

②do while(先执行再判断)

do{
    代码块;
}while(循环终止条件);

③for

for(表达式一;循环终止条件;表达式二){
    代码块;
}

④foreach

for(变量类型 变量名:需要遍历的对象){
    代码块;
}

🐟在循环中,使用break和continue的作用是什么

break:终止循环体,结束当前循环和外层循环

continue:结束本次循环,继续下次循环


🐟在java中,什么是类,什么是对象

类是对象的集合,对象是类的实例

类:具备某些共同特征的实体的集合,是一种抽象的数据类型,它是对所具有相同特征实体的抽象

对象:是一类事物的具体体现,对象是类的一个实例,必然具备该类的事物的属性和行为


🐟定义类的时候,一般要定义哪些内容

定义类需要两个部分

一是属性(成员变量),二是行为(成员方法)


🐟面向对象编程的步骤是什么

一)抽象出类对象

二)抽象出类对象的属性和方法

三)根据类对象创建出实例对象

四)通过实例对象访问属性和方法


🐟java成员方法的6要素是什么,分别解释说明

一)访问权限修饰符:定义方法的访问权限

二)返回值类型:定义方法的返回值类型

三)方法名:定义方法的名字

四)形参:定义方法需要的形参,可不写,或多个,多个用逗号连接

五)方法体:方法执行代码块

六)返回值:方法的返回值


🐟什么是方法重载

一个类中,具有相同的方法名但参数类型与个数不同的方法之间叫做方法的重载


🐟访问修饰符都有哪些,区别是什么

①private(私有):只能当前类类中访问,不能修饰类

②default(默认):能在同一包或同一类中被访问

③protected(保护):其他包中不可调用,不能修饰类

④public(公有):能在同一项目下被使用,能修饰属性,方法,类


🐟static关键字的作用

修饰属性:

      则该属性就成为类属性(不依赖于某个对象而存在),所有该类的实例对象都共用这一个属性,任何一个实例改变了静态属性值,大家看到的都是修改过的值。

修饰方法: 

则该方法就成为静态方法,可以直接通过类名访问,一般在工具类中定义工具方法     


🐟数组的特点

数组长度已经创建不可修改

数组中存储数据为相同类型

占据内存空间是连续的

数组名代表的是数组在内存中的首地址


🐟冒泡排序口诀

外层循环 n-1 , 内层循环再减 i

for(int i=0;i<array.length-1;i++){
        for(int j=0;j<array.length-1-i;j++){
            if(array[j] > array[j+1]){
                int temp = array[j];
                array[j] = array[j+1];
                array[j+1] = temp;
            }
        }
    }

🐟什么是封装,如何实现封装

        封装从字面上来理解就是包装的意思,专业点就是信息隐藏,是指利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体,数据被保护在抽象数据类型的内部,尽可能地隐藏内部的细节,只保留一些对外接口使之与外部发生联系。系统的其他对象只能通过包裹在数据外面的已经授权的操作来与这个封装的对象进行交流和交互。也就是说用户是无需知道对象内部的细节,但可以通过该对象对外提供的接口来访问该对象。

实现:

第一步:属性私有化
第二步:1个属性对外提供两个set和get方法。外部程序只能通过set方法修改,只能通过get方法读取,可以在set方法中设立关卡来保证数据的安全性。
 


🐟继承的特点是什么,有什么作用

概念:

        多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。多个类可以称为子类,单独这个类称为父类、超类或者基类。子类可以直接访问父类中的非私有的属性和行为。通过 extends 关键字让类与类之间产生继承关系。

优点:提高代码复用性和维护性,多态的前提。

缺点:类的耦合性增强了,削弱了子类的独立性。

特点:

        ①Java中只支持单继承,即一个子类只能拥有一个父类。

        ②子类可以继承父类的方法,子类也可以拥有自己独立的方法。

        ③子类可以重写覆盖父类的方法


🐟方法重写的特征

1.发生方法重写的两个方法返回值、方法名、参数列表必须完全一致(子类重写父类的方法)

2.子类抛出的异常下不能超过父类相应方法抛出的异常(子类异常不能大于父类异常)

3.子类方法的访问级别不能低于父类相应方法的访问级别(子类访问级别不能低于父类访问级别)

4.方法的重写,不能发生在同类中,只能发生在子类中。


🐟super和this关键字的作用

this:

        是对象内部指代自身的引用,同时也是解决成员变量和局部变量同名问题;this 可以调用成员变量,不能调用局部变量;this 也可以调用成员 方法,但是在普通方法中可以省略 this,在构造方法中不允许省略,必须是 构造方法的第一条语句。,而且在静态方法当中不允许出现 this 关键字。
super :

        代表对当前对象的直接父类对象的引用,super 可以调用直接父类的成员变量(注意权限修饰符的影响,比如不能访问 private 成员) super 可以调用直接父类的成员方法(注意权限修饰符的影响,比如不能访 问 private 成员);super 可以调用直接父类的构造方法,只限构造方法中使用,且必须是第一条语句。


🐟什么是多态,如何实现多态,多态的作用是什么

多态是同一个行为具有多个不同表现形式或形态的能力。

多态就是同一个接口,使用不同的实例而执行不同操作。

实现条件:①继承②重写③父类引用子类对象

作用:

① 消除类型之间的耦合关系

②提高了代码的维护性(继承保证)

③提高了代码的扩展性(由多态保证)


🐟什么是向上转型和向下转型

向上转型:通过子类对象实例化父类对象,这属于自动转换。

        子类引用的对象转换为父类类型称为向上转型。向上转型后的父类引用只能调用父类的属性,若子类重写了父类的方法,则通过父类引用调用的是子类重写后的方法(即 override

向下转型:通过父类对象实例化子类对象,这属于强制转换。

        将一个父类类型的变量强制转换为子类类型的过程称为向下转型。但并不是所有的对象都可以向下转型,只有当这个对象原本就是子类对象通过向上转型得到的时候才能够成功转型,在向下转型前,通过instanceof 判断某对象是否是某类的实例。此外,大部分情况下,不推荐进行向下转型。


🐟抽象类的特点

1、抽象类和抽象方法都需要用abstract修饰;

2、抽象方法必须在抽象类中,抽象类中可以没有抽象方法;

3、抽象类不能直接创造对象(实例化);

4、抽象类的子类如果重写所有抽象方法,那么就是一个具体的类;

5、抽象类的子类不重写所有抽象方法,那么子类还是一个抽象类;

6、抽象类有构造方法,目的是让子类来调用构造方法初始化;


🐟抽象方法的特点

①抽象方法是一个不完整的方法,没有方法体,只有在子类重写后才有实际的方法体。

②抽象方法一定存在于抽象类当中。但抽象类中可以没有抽象方法。

③抽象方法必须被  abstract  修饰。


🐟接口的特点

(1)接口使用 interface关键字修饰

(2)接口不可以实例化

(3)实现类必须实现接口的所有方法(抽象类除外),如果没有全部实现该类则为抽象类

(4)实现类可以实现多个接口(java多继承)

(5)接口中的常量都是静态常量


🐟抽象类和接口的区别

①接口是对行为(方法)的抽象,是一种行为规范,抽象类是对类的抽象,是一种设计模板。

②接口中没有构造方法,抽象类中有构造方法,一般给子类使用。

③接口中只有方法的定义没有实现,jdk1.8后有default方法体,抽象类中有方法的定义和实现。

④接口可以多继承,抽象类只能单继承,接口强调特定功能的实现,而抽象类强调所属关系。


🐟请画出异常体系的框架结构图


🐟异常的关键字有哪些

 try:监听异常

catch:捕获异常

finally:总会被执行语句,常用于关闭系统资源

throw:用于抛出异常,用于方法体中

throws:用于抛出可能出现的异常,用于方法后


🐟throw和throws的区别

   throws 用于方法后声明抛出异常,而 throw 关键字用来人工引发异常,异常发生时,系统会生成一个异常对象,并将其抛出,但也可通过throw语句显式抛出。

相同:throw显式抛出的异常与系统生成并抛出的的异常在处理方式上没有区别,就是两种方法
:要么捕获自己处理,要么抛给上层调用者处理。

区别:

throws:跟在方法声明后面,后面跟的是异常类名 

     throw:用在方法体内代码块,后面跟的是异常类对象名  

throws:可以跟多个异常类名,用逗号隔开

     throw: 只能抛出一个异常对象名 

throws:表示抛出异常,由该方法的调用者来处理

     throw:表示抛出异常,由该方法体内的语句来处理

throws:表示有出现异常的可能性,并不一定出现这些异常

     throw:则是抛出了异常,执行throw一定出现了某种异常
 


🐟多重catch异常的时候需要注意什么问题

1、多个catch不能捕获同一个异常。

2、多个catch捕获的异常有继承关系的,子类异常应当写在上面,父类异常写在下面。


🐟如何自定义异常


//自定义异常类
//继承Execption异常父类
public class Exc extends Exception{
    //自定义异常类的构造
    public Exc(String err) {
        // 调用父类异常的有参构造,让父类维护异常信息
        super(err);
    }
}

🐟Log4j的使用步骤

导入 jar 包

配置文件log4j.properties(固定格式) 

#输出信息到控制台
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
#使用的输出对象
log4j.appender.stdout.Target=System.out
#设置输出内容格式类型
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
#设置格式的具体配置
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %M %F %p %m%n


#输出信息到指定文件
log4j.appender.log=org.apache.log4j.FileAppender
#指定文件地址
log4j.appender.log.File=D:/Z/IDEA/Demo/YZH/Aug/WBY0801/src/info
log4j.appender.log.layout=org.apache.log4j.PatternLayout
log4j.appender.log.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %l  %m%n

#第一个为输出优先级,只输出该类型及其以上的信息,
#后面则是输出源,stdout(控制台),log(自定义的输出文件)
log4j.rootLogger=debug,stdout,log

使用

//getLogger() 参数为当前类名
Logger logger=Logger.getLogger("LTest");
//级别低--高
logger.debug("debug");
logger.info("info");
logger.warn("warn");
logger.error("error");
logger.fatal("fatal");

🐟请画出集合框架的结构图

Collonection

Map 


🐟List接口的特点

①List 集合是有序集合,数据的添加次序和存储次序一致。

②List 可以添加重复的数据

③List 集合中的数据可以通过下标访问


🐟ArrayList的常用方法和扩容原理

常用方法:

①add():添加数据

②remove():删除数据

③contains():查询是否包含特定元素

④indexOf():获取指定元素第一次出现位置

⑤get():获取指定位置元素

⑥size():获取集合中元素个数

扩容原理:当集合长度不够时

        首先创建一个新的数据这个数组的长度是原来数组长度的1.5倍

        然后使用Arrays.copyOf方法把老数组里面的数据拷贝到新的数组里面


🐟Set接口的特点

①数据存储无序

②不允许有重复数据

③无法通过索引访问数据

④查找慢,数据增删改查快

⑤底层数据结构是哈希表、链表和红黑树

⑥Set集合使用equals()和hashCode()方法实现元素去重


🐟HashSet的使用方式

添加元素:add()、添加元素为对象时,判断是否相同的标准是对象地址,如果要判断数据则需重                     写hashCode()和equals()方法

删除元素:remove()

遍历元素:迭代器遍历

//创建迭代器对象
Iterator it=set.iterator();
//判断集合是否有元素
while (it.hasNext()){
     //输出元素
     System.out.println(it.next());
   }

🐟TreeSet的使用方式

添加:add()

添加元素是判断是否相同对于对象类型数据需要现Comparable接口并重写compareTo方法或者自定义排序类实现Comparator接口


🐟Map接口的特点

①以键值对的形式存储数据(Collection时单值集合)

②键不能重复,键重复时,后面的数据会覆盖前面的数据

③HashMap的鍵和值可以存储null。Hashtable不能存儲null值。

键值对数据无序


🐟HashMap的使用方式和底层原理

添加元素:以键值对的形式添加

public static void main(String[] args) {
        Map map=new HashMap();
        map.put("key1","value1");
        map.put("key1","value2");
        map.put("key2","value1");
        map.put("key3","value1");
        System.out.println(map);
    }

 删除元素:根据值删除

map.remove("key1");

 获取键集合,通过键集合遍历数据

//获取键集合
Set keySet=map.keySet();
//foreach遍历
for(Object key:keySet){
  System.out.println(map.get(key));
}

底层原理: 

hashmap的底层是 数组+链表
    在向hashMap存值时,会计算key的hash值,并根据数组的长度进行取模【默认是16】,从而确定将这个键值对放到数组的哪个位置,比如map.put("userName","zhangsan");这样就会计算userName的hash值,比如是18,接着用18和16取模,得2;那么就会在arr[2]的位置放入 userName:zhangsan这么一个键值对。
    hashmap中可能会出现hash冲突(hash碰撞)的情况,也就是两个key不一样,但他们的hash值一样,就会导致他们出现在数组的同一个地方,这个时候就可以通过链表的方式,将这个键值对放到数组元素对应的链表里。但使用链表可能会导致一个问题,就是链表长度过长,查询起来性能低,所以在jdk1.8的时候做了优化,就是当链表达到一定长度后就会把它转换为红黑树,从而提高查询性能。
    在get的时候,也是根据key计算hash值,和数组长度取模后,得到数组中的位置,如果发现这个位置挂了一个链表,那就根据key找到链表中和该key对应的键值对。
    hashmap的扩容,默认情况数组长度是16,负载因子是0.75,所以当数组中存入数组的长度达到12以后就会进行成倍扩容,从16变为32。扩容后就会对原有hashmap中的数据进行重新的hash取模运算,得到新的位置。所以可以根据数据量的多少,更改hashmap的默认容量,从而避免频繁扩容,导致性能降低。


 🐟请简单列举集合框架中用到的数据结构

线性表(ArrayList)、链表(LinkedList)、红黑树(treeSet)、哈希表(HashSet、HashMap)


🐟Java中如何获取某个目录下的所有文件信息

public class DisplayAll {
    public static void main(String[] args) {
        //遍历目录
        String path="d:/1";
        //遍历函数
        display(path);
    }
    public static void display(String path){
        //转为文件对象
        File file=new File(path);
        //不存在,则直接终止
        if(!file.exists()){
            return;
        }
        //为数据文件
        if (file.isFile()){
            System.out.println("数据文件-"+file.getName());
        }
        //为目录文件则深层遍历
        if(file.isDirectory()){
            //得到目录文件的所有目录对象
            File[] files=file.listFiles();
            for(int i=0;i<files.length;i++){
                if(files[i].isFile()){
                    System.out.println("数据文件-"+files[i].getName());
                }
                if (files[i].isDirectory()){
                    System.out.println("目录文件—"+files[i].getName());
                    display(files[i].getPath());
                }
            }
        }
    }
}

🐟InputStream和FileInputStream的区别是什么

        InputStream 是一个抽象类,定义了所有字节输入流类的 公用方法。FileInputStream类是它的子类,我们通过FileInputStream类,读取硬盘上的文件,存到内存中。


🐟请画出文件流的分类


🐟请列出你所熟悉的字节流

 


🐟一般使用哪种流处理对象数据

对象流(ObjectOutputStream、ObjectInputStream


🐟请列出常用的字符流


🐟请列出常用缓冲流有哪些


 🐟哪种流有格式化输出字符串的功能

打印流:PrintStream、OutputStream


🐟泛型的作用是什么

限定集合数据类型、方法参数,返回值类型等,方便数据的管理,限定类型必须是对象类型


🐟泛型通配符的作用是什么

在保证运行时类型安全的基础上,提高参数类型的灵活性。


🐟如何设置泛型上、下限

设置泛型对象的上限使用extends,表示参数类型只能是该类型或该类型的子类:

声明对象:类名<? extends 类> 对象名

定义类:类名<泛型标签 extends 类>{}

设置泛型对象的下限使用super,表示参数类型只能是该类型或该类型的父类:

声明对象:类名<? super 类> 对象名称

定义类:类名<泛型标签 extends类>{}

网站公告

今日签到

点亮在社区的每一天
去签到