java基础习题集_Java基础经典题集

Java基础经典题集

2019-7-23

777

0

java的垮平台原理

为什么要跨平台使用?其实说白了就是个操作系统支持的指令集是不一样的。我们的程序需要再不同的操作系统上运行这些代码。

但是不要说jvm是跨平台的,而真正跨平台的是 Java 程序,而不是 JVM。JVM 是用 C/C++ 开发的,是编译后的机器码,不能跨平台,不同平台下需要安装不同版本的 JVM

答:我们编写的 Java 源码,编译后会生成一种 .class 文件,称为字节码文件。Java 虚拟机(JVM)就是负责将字节码文件翻译成特定平台下的机器码然后运行,也就是说,只要在不同平台上安装对应的 JVM,就可以运行字节码文件,运行我们编写的 Java 程序。而这个过程,我们编写的 Java 程序没有做任何改变,仅仅是通过 JVM 这一 “中间层” ,就能在不同平台上运行,真正实现了 “一次编译,到处运行” 的目的。

JVM由哪些部分组成?

JVM 的结构基本上由 4 部分组成:

类加载器,在 JVM 启动时或者类运行时将需要的 class 加载到 JVM 中

执行引擎,执行引擎的任务是负责执行 class 文件中包含的字节码指令,相当于实际机器上的 CPU

内存区,将内存划分成若干个区以模拟实际机器上的存储、记录和调度功能模块,如实际机器上的各种功能的寄存器或者 PC 指针的记录器等

本地方法调用C 或 C++ 实现的本地,调用方法的代码返回结果

类加载器是有了解吗?

答:顾名思义,类加载器(class loader)用来加载 Java 类到 Java 虚拟机中。一般来说, Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。

类加载器负责读取 Java 字节代码,并转换成 java.lang.Class类的一个实例。每个这样的实例用来表示一个 Java 类。通过此实例的 newInstance()方法就可以创建出该类的一个对象

Java 虚拟机是如何判定两个 Java 类是相同的?

答:Java 虚拟机不仅要看类的全名是否相同,还要看加载此类的类加载器是否一样。只有两者都相同的情况,才认为两个类是相同的。即便是同样的字节代码,被不同的类加载器加载之后所得到的类,也是不同的。比如一个 Java 类 com.example.Sample,编译之后生成了字节代码文件 Sample.class。两个不同的类加载器 ClassLoaderA和 ClassLoaderB分别读取了这个 Sample.class文件,并定义出两个 java.lang.Class类的实例来表示这个类。这两个实例是不相同的。对于 Java 虚拟机来说,它们是不同的类。试图对这两个类的对象进行相互赋值,会抛出运行时异常 ClassCastException。

双亲委派模型(Parent Delegation Model)

该模型要求除了顶层的 Bootstrap class loader 启动类加载器外,其余的类加载器都应当有自己的父类加载器。子类加载器和父类加载器不是以继承(Inheritance)的关系来实现,而是通过组合(Composition)关系来复用父加载器的代码。每个类加载器都有自己的命名空间(由该加载器及所有父类加载器所加载的类组成,在同一个命名空间中,不会出现类的完整名字(包括类的包名)相同的两个类;在不同的命名空间中,有可能会出现类的完整名字(包括类的包名)相同的两个类)

双亲委派模型的工作过程?

1.当前 ClassLoader 首先从自己已经加载的类中查询是否此类已经加载,如果已经加载则直接返回原来已经加载的类。

每个类加载器都有自己的加载缓存,当一个类被加载了以后就会放入缓存,

等下次加载的时候就可以直接返回了。

2.当前 ClassLoader 的缓存中没有找到被加载的类的时候,委托父类加载器去加载,父类加载器采用同样的策略,首先查看自己的缓存,然后委托父类的父类去加载,一直到 bootstrap ClassLoader.

当所有的父类加载器都没有加载的时候,再由当前的类加载器加载,并将其放入它自己的缓存中,以便下次有加载请求的时候直接返回。

为什么这样设计呢?

解析:这是对于使用这种模型来组织累加器的好处

答:主要是为了安全性,避免用户自己编写的类动态替换 Java 的一些核心类

同时也避免了重复加载,因为 JVM 中区分不同类,不仅仅是根据类名,相同的 class 文件被不同的 ClassLoader 加载就是不同的两个类,如果相互转型的话会抛java.lang.ClassCaseException.

装箱和拆箱:有了基本的数据类型,我们为什么还要有包装类型。

就是体现面向对象的思想

自动装箱是jdk1.5以后增加的功能。装箱:就是把基本数据类型转化成对应的包装类型。

总结一下:Java是一个面向对象的语言,而基本的数据类型,不具备面向对象的特性。

讲一下java中的集合

Java集合分为两种,一个是value类型的,另一个就是key.value (Map)两种

List是有序的,可以重复的

Set是无序的,不可以重复的(根据equals和hashcode来判断。)也就是说如果一个对象要存储到set当中,就必须要重写我们的equals和hashcode的方法。

Map就是key.value的类型数据。

Hashmap存储原理

API中的常用的属性

Hashmap、默认四个构造方法

Hash碰撞  ,桶的概念

Entry,next属性

ArrayList 和LinkedList的区别

ArrayList底层使用的是数组,LinkedList底层使用的是链表

数组查询的时候具有查询特定元素比较快。而插入和删除和修改比较慢(数组在内存当中是一块联系的内存,如果插入或者删除是需要移动内存的)

链表不要求内存是连续的,当查询的时候,需要从头部一个一个的找,所以查询效率低,而插入的时候不需要移动内存,只需要改变引用的指向。

应用场景:ArrayList使用在查询比较多,答案是插入和删除比较少的情况,而LinkedList使用在查询比较少而插入和删除比较多的情况

HashMap和HashTable的区别

相同点:都可以用来存储Key.value型数据

区别:

1、    hashMap是可以把null作为可以key或者value,而hashtable不可以

2、    HashMap是线程不安全的,效率较高,而hashtable是线程安全的,效率较低

我想线程安全我又想效率比较高?????what?????

原理—》就是把整个map分为N个segment(类似于hashtable),可以提供相同的线程安全,但是效率提升N。默认提升的16倍。

线程的的实现方式?怎么启动线程?怎么区分线程?

1. 实现方式

a)    常用的通过继承Thread类来实现一个线程

b)    通过实现Runnable接口来实现一个线程。

c)    通过实现Callable接口来实现一个线程

2. 怎么启动

我们通过

Thread thread=new Thread(继承了thread类的对象\或者把实现了runnable接口的对象)

thread.start();

启动线程的时候用的是start()方法,然后执行线程的时候用的是run()方法;

3. 怎么样区分线程???

a)    在一个系统当中我们有很多线程,每个系统都会打印日志,我想区分一下到底是哪个系统打印的???

thread.setName(设置一个线程的名称),这是一个规范,你们将来在开发的时候写完多线程一定要及记得设置线程名称。

线程并发库和线程池的作用

Jdk1.5的时候增加了Doug Lea的并发库,大大的增加了便利性。

Java.util.current包提供了对线程的优化,包括管理的各项操作。--》线程池的创建,以及线程的生命周期的管理。

Java通过Executors提供四个静态方法来创建四种线程 池:

newCachedThreadPool,可缓存的线程池

newFixedThreadPool,创建一个定长线程池

newScheduledThreadPool,创建一个定长线程池,支 持定时以及周期性任务

newSingleThreadExcutor,创建一个单线程化的线程池

线程池的作用

限定了线程的个数,不会导致由于线程过多导致系统运行缓慢或崩溃

节约资源,我们不会去关心它的创建于销毁。

您可能还会对下面的文章感兴趣:

我要评论

昵称

邮箱

网址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值