Java基础扫盲

Java概述

1. JVM、JRE和JDK的关系

JVM
Java Virtual Machine是Java虚拟机,Java程序需要运行在虚拟机上,不同的平台有自己的虚拟机,因此Java语言可以实现跨平台。
JRE
Java Runtime Environment包括Java虚拟机和Java程序所需的核心类库等。核心类库主要是java.lang包:包含了运行Java程序必不可少的系统类,如基本数据类型、基本数学函数、字符串处理、线程、异常处理类等,系统缺省加载这个包
如果想要运行一个开发好的Java程序,计算机中只需要安装JRE即可。
JDK
Java Development Kit是提供给Java开发人员使用的,其中包含了Java的开发工具,也包括了JRE。所以安装了JDK,就无需再单独安装JRE了。其中的开发工具:编译工具(javac.exe),打包工具(jar.exe)等
在这里插入图片描述

2. Java与C#的区别与联系

相同点:都是面向对象编程的语言,都能够实现面向对象的思想(封装,继承,多态);都具有垃圾自动回收机制;Java站在C++的肩膀上,而C#站在了Java的肩膀上。
不同点:
语法特性: Java抛弃了指针,使用了包(package)的概念,导入包使用import语句;C#没有完全抛弃指针(在unsafe状态下还可以操作指针),对于类的管理采用了名称空间(namespace)的概念,并且还使用了out、ref等关键字,便于从一个方法返回多个结果。
功能方面:C#有一些由编译器提供的特性,如:委托、属性、真正的泛型等,在Java中实现起来有点麻烦,同样Java中也有C#不具备的功能,如匿名内部类,动态代理等,另外Java实现了真正的跨平台性,而C#的跨平台性是建立在跨windows平台的基础上的。

3. Oracle JDK和OpenJDK的对比

OpenJDk版本每三个月发布一次,而OracleJDK每三年发布一次;
OpenJDK是一个参考模型并且完全开源,而OracleJDK是OpenJDK的一个实现,并不是完全开源的;
OracleJDK比OpenJDK更稳定,性能更好

基础语法

1、 switch能否作用在byte上,是否能作用在long上,是否能作用在String上?

在 Java 5 以前,switch(expr)中,expr 只能是 byte、short、char、int。从 Java5 开始,Java 中引入了枚举类型,expr 也可以是 enum 类型,从 Java 7 开始,expr 还可以是字符串(String),但是长整型(long)在目前所有的版本中都是不可以的。

原因是switch在编译时被编译成对应的两个实现方式的指令,而这两个指令只支持int类型。

2、Java语言采用何种编码方式,有什么特点?

Java语言采用Unicode编码标准,Unicode(标准码),它为每个字符制订了一个唯一的数值,因此在任何的语言,平台,程序都可以放心的使用。

Unicode 编码共有三种具体实现,分别为utf-8,utf-16,utf-32,其中utf-8占用一到四个字节,utf-16占用二或四个字节,utf-32占用四个字节

3、 super关键字的用法

super可以理解为是指向自己超(父)类对象的一个指针。
A:可以利用super关键字代表父类对象访问父类的属性和方法;
super.属性 ----> 访问父类的属性
super.方法名()---- > 调用父类的方法
B:可以使用super关键字调用父类的构造函数,必须出现在构造函数的第一行;
C:super不能和static混用,因为super指的是对象,而static代表的是类。

4、static关键字的意义

主要意义是在于创建独立于具体对象的域变量或者方法,以至于即使没有创建对象,也能使用属性和调用方法!
另外还可以用来形成静态代码块用来优化程序性能,因为static块在类加载的时候仅会执行一次,所以可以将一些只需要进行一次的初始化操作都放在static代码块中进行;

利用static实现单例模式:

public class Singleton{
	private static class SingletonHolder{
		private static final Singleton INSTANCE = new Singleton();
	}

	private TestSingleton(){
	}
	
	public static final Singleton getInstance(){
		return SingletonHolder.INSTANCE;
	}
}

面向对象

1、面向对象和面向过程的区别

面向过程注重的是性能,因为面向对象万物皆对象,而类调用时需要实例化,开销比较大,比较消耗资源;
面向对象易维护,易复用,易扩展,主要是得益于面向对象的封装,继承,多态特性,可以设计出低耦合的系统;

继承是通过重写父类的同意方法的几个不同子类来体现的,

2、什么是多态机制?Java中是如何实现多态的?

对于面向对象而言,多态分为编译时多态和运行时多态,其中编译时多态是静态的,主要是指方法的重载,它是根据参数列表的不同来区分不同的函数,而运行时多态是动态的,通过动态绑定来实现,多态性就是相同的消息使得不同的类做出不同的响应。
多态性体现在父类中定义的属性和方法被子类继承后,可以具有不同的属性或表现方式,多态性允许一个接口被多个同类使用,弥补了单继承的不足。

Java的多态是通过继承、重写、重载来实现的。

3、面向对象的五大基本原则?

单一职责原则:类的功能要单一
开放封闭原则:对扩展开放,对修改关闭
里氏替换原则:子类可以替换父类出现在父类能够出现的地方
依赖倒置原则:高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象
接口分离原则:设计时采用多个与特定客户类有关的接口比采用一个通用的接口要好

4、对象实例和对象引用有什么不同?

对象实例存储在堆上,对象引用存储在栈中,要访问对象实例可以通过对象引用来访问。

5、成员变量和局部变量的区别有哪些?

作用域
成员变量:针对整个类有效
局部变量:只在某个范围内有效
存储位置
成员变量:存储在堆中
局部变量:存储在栈内存中
生命周期
成员变量:随着对象的创建而存在,随着对象的消失而消失
局部变量:当方法调用完,或者语句结束后,就自动释放
初始值
成员变量:有默认初始值
局部变量:没有默认初始值,使用前必须赋值

6、在Java中定义一个不做事且没有参数的构造方法的作用

Java程序在执行子类的构造方法之前,如果没有用super()来调用父类特定的构造方法,则会调用父类中“没有参数的构造方法”,因此,如果父类中只定义了有参数的构造方法,而在子类中的构造方法中又没有用super()来调用父类中特定的构造方法,则会在编译时发生错误。

7、在调用子类构造方法之前会先调用父类没有参数的构造方法,其目的是什么

帮助子类做初始化工作,因为子类拥有弗雷德成员变量和成员方法,如果不调用,则从父类继承而来的成员变量和成员方法得不到正确的初始化。

8、构造方法有哪些特性?

方法名和类名相同
没有返回值,但不能用void声明构造函数
生成类的对象时自动执行,无需调用

9、静态变量、实例变量的区别

静态变量:静态变量不属于任何实例对象,而属于类,所以在内存中只会存在一份,在类的加载过程中,JVM只为静态变量分配一次内存空间;
实例变量:每次创建对象,都会为每个对象分配成员变量内存空间,实例变量属于实例对象,在内存中创建几次对象,就会有几份成员变量

10、内部类的优点?有哪些应用场景

优点
一个内部类对象可以访问创建它的外部类对象的内容,包括私有数据
内部类不为同一包的其他类所见,具有很好的封装性
内部类有效实现了“多重继承”,优化Java单继承的缺陷
匿名内部类可以很方便的实现回调

应用场景
一些多算法场合
解决一些非面向对象的语句块
适当使用内部类,使得代码更加灵活和富有扩展性
当某个类除了它的外部类,不再被其他的类使用时

11、匿名内部类

public class Outer {

    private void test(final int i) {
        new Service() {
            public void method() {
                for (int j = 0; j < i; j++) {
                    System.out.println("匿名内部类" );
                }
            }
        }.method();
    }
 }
 //匿名内部类必须继承或实现一个已有的接口 
 interface Service{
    void method();
}

特点

  • 匿名内部类必须继承一个抽象类或者实现一个接口
  • 匿名内部类不能定义任何静态成员和静态方法
  • 当所在的方法的形参需要被匿名内部类使用时,必须声明为final
  • 匿名内部类不能是抽象的,它必须要实现继承的类或者实现接口的所有方法

11、局部内部类和匿名内部类访问局部变量的时候,为什么变量必须要加final

用final修饰实际上是为了保护数据的一致性,因为如果局部变量发生变化后,匿名内部类或局部内部类是不知道的(因为它只是拷贝了局部变量的值,并不是直接使用的局部变量),如果过了一段时间后局部变量的值指向另外一个对象,或是值发生了改变,那么程序运行的结果和预期的会不一致。
在这里插入图片描述
JDK1.8中虽然局部变量不需要用final修饰符修饰,但是我们在试图改变这个局部变量的时候会提示编译出错。

12、重载的方法能否根据返回类型进行区分

重载发生在同一个类中,方法名相同但参数列表不同(参数类型不同、个数不同、顺序不同),与方法返回值和访问修饰符无关。

13、hashcode和equals

这个问题应该是有个前提,就是你需要用到 HashMap、HashSet 等 Java 集合,用不到哈希表的话,其实仅仅重写 equals() 方法也可以。而工作中的场景是常常用到 Java 集合,所以 Java 官方建议重写 equals() 就一定要重写 hashCode() 方法。
对于对象集合的判重,如果一个集合含有 10000 个对象实例,仅仅使用 equals() 方法的话,那么对于一个对象判重就需要比较 10000 次,随着集合规模的增大,时间开销是很大的。但是同时使用哈希表的话,就能快速定位到对象的大概存储位置,并且在定位到大概存储位置后,后续比较过程中,如果两个对象的 hashCode 不相同,也不再需要调用 equals() 方法,从而大大减少了 equals() 比较次数。

hashCode()与equals()的相关规定:
1、如果两个对象相等,则 hashCode 一定也是相同的;
2、两个对象相等,对两个对象分别调用 equals 方法都返回 true;
3、两个对象有相同的 hashCode 值,它们也不一定是相等的;
4、因此,equals 方法被覆盖过,则 hashCode 方法也必须被覆盖;
5、hashCode() 的默认行为是对堆上的对象产生独特值。如果没有重写 hashCode(),则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)。

14、当一个对象被当作参数传递到一个方法后,此方法可改变整个对象的属性,并返回变化后的结果,那么这里到底是值传递还是引用传递

是值传递。Java语言的方法调用只支持参数的值传递。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的属性可以在被调用过程中被改变,但对对象引用的改变是不会影响到调用者的,也就是说这个引用还是会指向之前的对象,而不会指向其他对象。之所以能修改引用数据是因为它们同时指向了一个对象。

15、值传递和引用传递的区别

所谓的按值调用表示方法接收的是调用者提供的值,而按引用调用则表示方法接收的是调用者提供的变量地址,一个方法可以修改传递引用所对应的变量值,而不能修改传递值调用所对应的变量值。

16、import java和javax有什么区别

实际上java和javax没有区别。这都是一个名字。

IO流

1.同步、异步、阻塞、非阻塞的区别

同步和异步
同步:同步就是发起一个调用后,被调用者未处理完请求之前,调用不返回。
异步:异步就是发起一个调用后,立刻得到被调用者的回应表示已接收到请求,但此时结果并没有返回,此时调用者可以处理其他的请求,被调用者通常依靠事件、回调等机制来通知调用者其返回结果。
同步和异步最大区别在于异步的话不需要等待处理结果,被调用者会通过回调等机制来通知调用者其返回结果

阻塞和非阻塞
阻塞:阻塞就是发起一个请求,调用者一直等待请求结果返回,也就是当前线程会被挂起,无法从事其他任务,只有当条件就绪才能继续
非阻塞:非阻塞就是发起一个请求,调用者不用一直等着结果返回,可以先去干其他事情。

同步和异步关注的是消息通信机制
所谓同步,就是在发出一个调用时,在没有得到结果之前,该调用就不返回。但是一旦调用返回,就得到返回值了。换句话说,就是由调用者主动等待这个调用的结果。而异步则是相反,调用在发出之后,这个调用就直接返回了,所以没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在调用发出后,被调用者通过状态、通知来通知调用者,或通过回调函数处理这个调用。

比如说:
你打电话问书店老板有没有《分布式系统》这本书,如果是同步通信机制,书店老板会说,你稍等,”我查一下",然后开始查啊查,等查好了(可能是5秒,也可能是一天)告诉你结果(返回结果)。而异步通信机制,书店老板直接告诉你我查一下啊,查好了打电话给你,然后直接挂电话了(不返回结果)。然后查好了,他会主动打电话给你。在这里老板通过“回电”这种方式来回调。

阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态
阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。

还是上面的例子,你打电话问书店老板有没有《分布式系统》这本书,你如果是阻塞式调用,你会一直把自己“挂起”,直到得到这本书有没有的结果,如果是非阻塞式调用,你不管老板有没有告诉你,你自己先一边去玩了, 当然你也要偶尔过几分钟check一下老板有没有返回结果。

2.BIO、NIO、AIO有什么区别

BIO:同步阻塞I/O模型,数据的读取写入必须阻塞在一个线程内等待其完成

采用BIO通信模型的服务端,通常由一个独立的Acceptor线程负责监听客户端的连接,我们一般通过在while(true)循环中服务端会调用accept()方法等待接收客户端的连接的方式监听请求,请求一旦接收到一个连接请求,就建立通信套接字来进行读写操作,如果要让BIO通信模型能够同时处理多个客户端的请求,就必须使用多线程,也就是说它在接收到客户端连接请求之后为每个客户端创建一个新的线程进行链路处理。为了减少线程创建和销毁带来的开销,可以采用线程池的方式来管理线程。

NIO:同步非阻塞的I/O模型

Java NIO使我们可以进行非阻塞IO操作,比如单线程从通道读取数据到buffer,同时可以继续做别的事情,当数据读取到buffer中后,线程在继续处理数据,写数据同样如此。
NIO类库中加入了Buffer对象,在NIO库中,所有数据都是用缓冲区处理的,每种Java基本类型(除了Boolean)都对应一种缓冲区。
Channel(通道):NIO通过Channel进行读写,通道是双向的,可读也可写,而IO中的流是单向的,Channel只能和Buffer交互,因为Buffer,通道可以异步地读写。
Selector(选择器):选择器用于使用单个线程处理多个通道。
在这里插入图片描述

AIO:异步IO

步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。

3.Files常用方法有哪些

Files. exists():检测文件路径是否存在。
Files. createFile():创建文件。
Files. createDirectory():创建文件夹。
Files. delete():删除一个文件或目录。
Files. copy():复制文件。
Files. move():移动文件。
Files. size():查看文件个数。
Files. read():读取文件。
Files. write():写入文件。

反射

什么是反射机制

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

反射机制的优缺点

优点:可以动态执行,在运行期间根据业务功能动态执行方法、访问属性,最大限度发挥了java的灵活性。
缺点:对性能有影响,这类操作总是慢于直接执行java代码;使内部暴露,破坏封装;反射技术要求程序必须在一个没有安全限制的环境中运行。

反射机制的应用场景

在使用JDBC连接数据库时使用Class.forName()通过反射加载数据库的驱动程序;
Spring框架也用到很多反射机制,最经典的就是xml的配置模式;
Web服务器中利用反射调用了Sevlet的服务方法。
IDEA等开发工具利用反射动态剖析对象的类型与结构,动态提示对象的属性和方法。

Java获取反射的三种方法

1.通过new对象实现反射机制 2.通过路径实现反射机制 3.通过类名实现反射机制

public class Get {
    //获取反射机制三种方式
    public static void main(String[] args) throws ClassNotFoundException {
        //方式一(通过建立对象)
        Student stu = new Student();
        Class classobj1 = stu.getClass();
        System.out.println(classobj1.getName());
        //方式二(所在通过路径-相对路径)
        Class classobj2 = Class.forName("fanshe.Student");
        System.out.println(classobj2.getName());
        //方式三(通过类名)
        Class classobj3 = Student.class;
        System.out.println(classobj3.getName());
    }
}

public class Student {
    private int id;
    String name;
    protected boolean sex;
    public float score;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值