JavaSE面试题

面试是我们就业最关键也是最简单的一步,如果面试都过不了何来就业?简单是因为它是通过平常的积累就可以获得这项技能,所以我们必须对它足够重视。综合实际情况,整理出面试中经常问到JavaSE面试题,这些题目有些需要大家去网上查资料然后用自己的思路总结,千万不要标准化,一定要有自己的想法。在查询这些资料的同时也会加深你对编程的理解,大家务必自己动手不要去借鉴其他同学的

JavaSE面试题

 

1. 抽象类和接口的区别

1、抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。

2、抽象类要被子类继承,接口要被类实现。

3、接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现

4、接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。

5、抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。

6、抽象方法只能申明,不能实现,接口是设计的结果 ,抽象类是重构的结果

7、抽象类里可以没有抽象方法

8、如果一个类里有抽象方法,那么这个类只能是抽象类

9、抽象方法要被实现,所以不能是静态的,也不能是私有的。

10、接口可继承接口,并可多继承接口,但类只能单根继承。

 

2. 重载和重写的区别

Java的方法重载,就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义。

调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法

每个类型成员都有一个唯一的签名。方法签名由方法名称和一个参数列表(方法的参数的顺序和类型)组成。只要签名不同,就可以在一种类型内定义具有相同名称的多种方法。当定义两种或多种具有相同名称的方法时,就称作重载

 

方法覆盖是说子类重新定义了父类的方法。方法覆盖必须有相同的方法名,参数列表和返回类型。覆盖者可能不会限制它所覆盖的方法的访问。

 

3. stringBufferstringBuilder的区别

StringBuilder:可变的字符序列,并且它的方法没有实现synchronized同步锁,是不同步的。

StringBuffer:线程安全的可变字符序列,方法实现了synchronized同步锁,是同步的,线程安全的。

 

每当用String操作字符串时,实际上是在不断的创建新的对象

 

当我们在字符串缓冲去被多个线程使用是,JVM不能保证StringBuilder的操作是安全的,虽然他的速度最快,但是可以保证StringBuffer是可以正确操作的。当然大多数情况下就是我们是在单线程下进行的操作,所以大多数情况下是建议用StringBuilder而不用StringBuffer的,就是速度的原因。

 

stringBuffer 效率相对于stringBuilder要低,但是在多线程的情况下的安全性要比stringBuilder .

 

总结:其实StringBuffer就是差不多在StringBuilder的方法的基础上都加上了同步锁,实现了线程安全,但是很明显的会在一定程度上降低效率

 

4.   集合的体系架构(单列集合和双列集合)

集合类主要分为两大类:Collection和Map

Collectio(单列集合)n是List、Set等集合高度抽象出来的接口,它包含了这些集合的基本操作。主要分为:List和Set。

:List接口,常用的实现类为ArrayList和LinkedList,还有不常用的Vector(已过时)。

二、Set集合:不允许包含重复的元素(通过hashcode和equals函数保证),不保证顺序,而且方法和Collection一致,set集合取出元素的方式只有一种:迭代器

   常用的实现类为HashSet和TreeSet

 

 

Map(双列集合):抽象类AbstractMap通过适配器模式实现了Map接口中大部分的函数,TreeMap、HashMap ,WeakHashMap等实现类都是通过继承AbstractMap来实现,另外,不常用的HashTable直接实现了Map接口.

特点:1、内部存储的都是key-value键值对

2、必须保证键的唯一性,value可以有多个相同的

 

另外在集合中还有两个工具类:Arrayscollections

Arrays:里面提供了很多方法用于操作数组,类中定义的都是静态工具方法。

比如数组复制.对数组排序

Collections:集合框架中用于操作集合对象的工具类,都是静态方法。

比如List集合排序,也可以二分查找

 

 

5.    ArrayListLinkedList的区别

ArrayList是基于索引的数据接口,它的底层是数组。它可以以O(1)时间复杂度对元素进行随机访问。与此对应,LinkedList是以元素列表的形式存储它的数据,每一个元素都和它的前一个和后一个元素链接在一起,在这种情况下,查找某个元素的时间复杂度是O(n)

 

相对于ArrayListLinkedList的插入,添加,删除操作速度更快,因为当元素被添加到集合任意位置的时候,不需要像数组那样重新计算大小或者是更新索引。

 

LinkedListArrayList更占内存,因为LinkedList为每一个节点存储了两个引用,一个指向前一个元素,一个指向下一个元素。

6.    hashMapHashTable的区别

HashMapHashtable都实现了Map接口,因此很多特性非常相似。但是,他们有以下不同点:

HashMap允许键和值是null,而Hashtable不允许键或者值是null

Hashtable是同步的,而HashMap不是。因此,HashMap更适合于单线程环境,而Hashtable适合于多线程环境。

HashMap提供了可供应用迭代的键的集合,因此,HashMap是快速失败的。另一方面,Hashtable提供了对键的列举(Enumeration)

一般认为Hashtable是一个遗留的类。

7.    javaGC机制的理解

GC是垃圾收集的意思(Garbage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法。 

    所以,Java的内存管理实际上就是对象的管理,其中包括对象的分配和释放。 

    对于程序员来说,分配对象使用new关键字;释放对象时,只要将对象所有引用赋值为null,让程序不能够再访问到这个对象,我们称该对象为"不可达的".GC将负责回收所有"不可达"对象的内存空间。 

    对于GC来说,当程序员创建对象时,GC就开始监控这个对象的地址、大小以及使用情况。通常,GC采用有向图的方式记录和管理堆(heap)中的所有对象。通过这种方式确定哪些对象是"可达的",哪些对象是"不可达的".当GC确定一些对象为"不可达"时,GC就有责任回收这些内存空间。

 

java中,程序员是不需要显示的去释放一个对象的内存的,而是由虚拟机自行执行。在JVM中,有一个垃圾回收线程,它是低优先级的,在正常情况下是不会执行的,只有在虚拟机空闲或者当前堆内存不足时,才会触发执行,扫面那些没有被任何引用的对象,并将它们添加到要回收的集合中,进行回收。

8.    说下finalfinallyfinalize有什么区别

final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。 

     内部类要访问局部变量,局部变量必须定义成final类型,例如,一段代码……

     finally是异常处理语句结构的一部分,表示总是执行。

     finalizeObject类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。JVM不保证此方法总被调用

 

无论是否抛出异常,finally代码块都会执行,它主要是用来释放应用占用的资源。

finalize()方法是Object类的一个protected方法,它是在对象被垃圾回收之前由Java虚拟机来调用的。

 

9.    ErrorException的区别,try{}里有一个return语句,那么紧跟在这个try后的finally{}里的代码会不会被执行,什么时候被执行,在return前还是后?

error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。 exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。 

会被执行,try语句中,当执行到return时要返回的结果已经准备好了,就在此时,程序转到finally里面去了,在转去之前,try要把返回的结果存到栈里面,执行完finally,再从中取出返回结果

 

10.  说说同步和异步的区别,多线程的几种实现方式,和run方法可以启动线程吗

同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去;异步是指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率。

多线程的几种实现方式

 1)java类继承Thread类

   继承Thread类是实现java多线程的一种方式,但是实际上Thread类本身实现了Runnable接口,它代表了线程的一个实例。

   启动线程唯一的方法就是调用Thread类的start()方法,这时候便开启了一个新的线程。然后线程会自动调用run方法,你可以重写run方法,在里面添上自己想要执行的代码。

 2)java类实现Runnable接口

有时候我们经常选择实现Runnable接口来实现多线程,原因是java只支持单继承,如果你的类已经继承了一个其他类,这时候你就要通过实现Runnable接口来实现多线程。

 

2.多线程中run方法和start方法的区别

       1) start:

start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行run()方法,这里方法

 

run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程随即终止。

       2) run:run()方法只是类的一个普通方法而已,如果直接调用Run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。

总结:调用start方法方可启动线程,而run方法只是thread的一个普通方法调用,还是在主线程里执行。这两个方法应该都比较熟悉,把需要并行处理的代码放在run()方法中,start()方法启动线程将自动调用 run()方法,这是由jvm的内存机制规定的。并且run()方法必须是public访问权限,返回值类型为void.。

 

两种方式的比较 实际中往往采用实现Runable接口,一方面因为java只支持单继承,继承了Thread类就无法再继续继承其它类,而且Runable接口只有一个run方法;另一方面通过结果可以看出实现Runable接口才是真正的多线程……

 

 

 

11.  说说你对线程的几种状态的了解

一个程序中可以有多条执行线索同时执行,一个线程就是程序中的一条执行线索,每个线程上都关联有要执行的代码,即可以有多段程序代码同时运行,每个程序至少都有一个线程,即main方法执行的那个线程。如果只是一个cpu,它怎么能够同时执行多段程序呢?这是从宏观上来看的,cpu一会执行a线索,一会执行b线索,切换时间很快,给人的感觉是a,b在同时执行,好比大家在同一个办公室上网,只有一条链接到外部网线,其实,这条网线一会为a传数据,一会为b传数据,由于切换时间很短暂,所以,大家感觉都在同时上网。 

     状态:就绪,运行,synchronize阻塞,waitsleep挂起,结束。wait必须在synchronized内部调用。

     调用线程的start方法后线程进入就绪状态,线程调度系统将就绪状态的线程转为运行状态,遇到synchronized语句时,由运行状态转为阻塞,当synchronized获得锁后,由阻塞转为运行,在这种情况可以调用wait方法转为挂起状态,当线程关联的代码执行完后,线程变为结束状态。 

 

12. 说说你对多线程锁机制的理解

在开发Java多线程应用程序中,各个线程之间由于要共享资源,必须用到锁机制。Java提供了多种多线程锁机制的实现方式,常见的有synchronized、ReentrantLock、Semaphore、AtomicInteger等。每种机制都有优缺点与各自的适用场景,必须熟练掌握他们的特点才能在Java多线程应用开发时得心应手。

目前我们学过的只有synchronized

使用它来实现多线程的同步操作是非常简单的,只要在需要同步的对方的方法、类或代码块中加入该关键字,它能够保证在同一个时刻最多只有一个线程执行同一个对象的同步代码,可保证修饰的代码在执行过程中不会被其他线程干扰

13.  反射获取class对象的方式有哪些,反射创建对象的方式有哪些。

1、通过类名.class方式获得,

2、通过Class.forName(“类的全路径”)方法获得

3、通过对象名.getClass()方法获取

总结:三种方式均能够获得Class对象,区别是方法一不执行静态块和动态构造块,方法二执行静态块、不执行动态构造块,方法三需要创建对象,静态块和动态构造块均会执行;

 

有两种方式通过反射创建对象
1.使用Class对象的newInstance()方法来创建该Class对象对应类的实例,这种方式要求该Class对象的对应类
  有默认构造器,而执行newInstance()方法时实际上是利用默认构造器来创建该类的实例。
2.先使用Class对象获取指定的Constructor对象再调用Constructor对象的newInstance方法来创建该Class
  对象对应的类的实例。

第二种方式需要有3个步骤:
1.获取该类的Class对象。
2.利用Class对象的getConstructor方法来获取指定的构造器
3.调用Constructor的newInstance()方法来创建java对象。

 

 

14.  Java常用的设计模式有哪些

单例模式

简单点说,就是一个应用程序中,某个类的实例对象只有一个,你没有办法去new,因为构造器是被private修饰的,一般通过getInstance()的方法来获取它们的实例。getInstance()的返回值是一个对象的引用,并不是一个新的实例,所以不要错误的理解成多个对象

观察者模式

对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新

工厂模式
简单工厂模式:一个抽象的接口,多个抽象接口的实现类,一个工厂类,用来实例化抽象的接口

15.  UDPTCP协议的区别

TCPTransmission Control Protocol,传输控制协议)是面向连接的协议,也就是说,在收发数据前,必须和对方建立可靠的连接TCP的三次握手和四次断开可以看出,TCP使用面向连接的通信方式,大大提高了数据通信的可靠性,使发送数据端
和接收端在数据正式传输前就有了交互,为数据正式传输打下了可靠的基础

 

UDP(User Data Protocol,用户数据报协议)
1) UDP是一个非连接的协议,传输数据之前源端和终端不建立连接,当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。由于传输数据不建立连接,因此也就不需要维护连接状态,包括收发状态等,因此一台服务机可同时向多个客户机传输相同的消息。

 

小结TCP与UDP的区别:
1.基于连接与无连接;
2.对系统资源的要求(TCP较多,UDP少);
5.TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证

16、说说你对面向对象的理解

现实世界中,随处可见的一种事物就是对象,对象是事物存在的实体,如人类、书桌、计算机、高楼大厦等。人类解决问题的方式总是将复杂的事物简单化,于是就会思考这些对象都是由哪些部分组成的。通常都会将对象划分为两个部分,即动态部分与静态部分。静态部分,顾名思义就是不能动的部分,这个部分被称为“属性”,任何对象都会具备其自身属性,如一个人,它包括高矮、胖瘦、性别、年龄等属性。然而具有这些属性的人会执行哪些动作也是一个值得探讨的部分,这个人可以哭泣、微笑、说话、行走,这些是这个人具备的行为(动态部分),人类通过探讨对象的属性和观察对象的行为了解对象。

类是封装对象的属性和行为的载体,反过来说具有相同属性和行为的一类实体被称为类。

封装是面向对象编程的核心思想,将对象的属性和行为封装起来,而将对象的属性和行为封装起来的载体就是类,类通常对客户隐藏其实现细节,这就是封装的思想。例如,用户使用电脑,只需要使用手指敲击键盘就可以实现一些功能,用户无须知道电脑内部是如何工作的,即使用户可能碰巧知道电脑的工作原理,但在使用电脑时并不完全依赖于电脑工作原理这些细节

17、如何避免死锁

 所谓死锁是指两个或两个以上的线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.(比如两个人过独木桥)

进程在运行过程中,请求和释放资源的顺序不当,也同样会导致死锁

 

避免死锁的三种方法:

· 1.加锁顺序(线程按照一定的顺序加锁)

当多个线程需要相同的一些锁,但是按照不同的顺序加锁,死锁就很容易发生。如果能确保所有的线程都是按照相同的顺序获得锁,那么死锁就不会发生。

· 2加锁时限(线程尝试获取锁的时候加上一定的时限,超过时限则放弃对该锁的请求,并释放自己占有的锁)另外一个可以避免死锁的方法是在尝试获取锁的时候加一个超时时间,这也就意味着在尝试获取锁的过程中若超过了这个时限该线程则放弃对该锁请求。若一个线程没有在给定的时限内成功获得所有需要的锁,则会进行回退并释放所有已经获得的锁,然后等待一段随机的时间再重试。这段随机的等待时间让其它线程有机会尝试获取相同的这些锁,并且让该应用在没有获得锁的时候可以继续运行

· 3.死锁检测每当一个线程获得了锁,会在线程和锁相关的数据结构中(mapgraph等等)将其记下。除此之外,每当有线程请求锁,也需要记录在这个数据结构中。当一个线程请求锁失败时,这个线程可以遍历锁的关系图看看是否有死锁发生

18、说说冒泡排序的原理,选择排序的原理,二分查找的原理

冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。

它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。

这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端,故名。

 

选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下。首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。简要的说就是先取出或假设一个最小或最大的数,之后在剩下的数里挑选一个最小或最大的,再和我们认为的最小或最大的数比较。满足条件就交换位置

三种排序效率最高的一种【插入排序】

插入排序(Insertion Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

 

二分查找,又称为折半查找法

前提:数组元素有序,这里的有序指的是提供的数组初始状态本身元素就是有序的。

1.将数组一分为二,并决定你需要寻找的元素是在数组的左边还是右边。
2.由于我们的数组是已经排序好的数组,所以你只需要将寻找的元素和得到中间数字进行大小比较。
3.确定好寻找的元素在哪边后,在新的数组里面继续一分为二,然后比较大小。
4.不断重复上述过程,直到我们找到这个元素在数组中的位置,或者当数组无法继续一分为二的时候,判断数组中不存在需要寻找的元素。

 

二分查找法一般都存在一个临界值BUG,即查找不到最后一个或第一个值。可以在比较到最后两个数时,再次判断到底是哪个值和查找的值相等。

 

19wait()sleep()的区别

 

sleepwait的区别有:
  1,这两个方法来自不同的类分别是ThreadObject
  2,最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
  3waitnotifynotifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在
    任何地方使用

20、为什么要使用泛型以及好处

1.在使用范型时.就规定了只有某种类型的数据才能放进集合里.你在集合中取数据时就不用进行强制转换.这样就提高了程序的性能

2.泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高代码的重用率。

泛型好处:

1类型安全 泛型的主要目标是提高 Java 程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设。没有泛型,这些假设就只存在于程序员的头脑中(或者如果幸运的话,还存在于代码注释中)。

2,消除强制类型转换 泛型的一个附带好处是,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。

 

 

21什么是java的序列化,如何实现java的序列化

我们有时候将一个java对象变成字节流的形式传出去或者从一个字节流中恢复成一个java对象,例如,要将java对象存储到硬盘或者传送给网络上的其他计算机,这个过程我们可以自己写代码去把一个java对象变成某个格式的字节流再传输,但是,jre本身就提供了这种支持,我们可以调用OutputStreamwriteObject方法来做,如果要让java 帮我们做,要被传输的对象必须实现serializable接口,这样,javac编译时就会进行特殊处理,编译的类才可以被writeObject方法操作,这就是所谓的序列化。需要被序列化的类必须实现Serializable接口,该接口是一个mini接口,其中没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的。 

 

22、hashSetTreeSet的区别

 

HashSet
HashSet有以下特点
Ø 不能保证元素的排列顺序,顺序有可能发生变化

 

TreeSet
TreeSetSortedSet接口的唯一实现类,TreeSet可以确保集合元素处于排序状态。

 

1TreeSet 是二差树实现的,Treeset中的数据是自动排好序的,不允许放入null值。 

2HashSet 是哈希表实现的,HashSet中的数据是无序的,可以放入null,但只能放入一个null,两者中的值都不能重复,就如数据库中唯一约束。 

3HashSet要求放入的对象必须实现HashCode()方法,放入的对象,是以hashcode码作为标识的,而具有相同内容的 String对象,hashcode是一样,所以放入的内容不能重复。但是同一个类的对象可以放入不同的实例 。

 

23、java中io流有哪些,各有什么特点和功能

 IO流分类:

        1,根据处理的数据类型不同:字节流和字符流。

        2,根据流向不同:输入流和输出流。

IO 体系所具备的基本功能就有两个:读 和 写。

    1,字节流:InputStream(读),OutputStream(写)。

    2,字符流:Reader(读),Writer(写)。

字符流:

Reader

--InputStreamReader

--FileReader:专门用于处理文件的字符读取流对象。

Writer

--OutputStreamWriter

--FileWriter:专门用于处理文件的字符写入流对象。

高效缓冲字符流

 BufferedWriter:

       特有方法:newLine():写一个换行符,跨平台的换行符。

 BufferedReader:

       特有方法:readLine():一次读一行,到行标记时,将行标记之前的字符数据作为字符串返 回。当读到末尾时,返回 null。不包含回车符。

字节流:

    字节流可以操作任何数据。

    抽象基类:InputStream,OutputStream。

 

1,打印流,

        PrintStream:字节打印流

      PrintWriter:字符打印流

 

转换流:

     特点 :  1,是字节流和字符流之间的桥梁。

             2,该流对象中可以对读取到的字节数据进行指定编码表的编码转换。

  1,InputStreamReader:字节到字符的桥梁。

  2,OutputStreamWriter:字符到字节的桥梁。

 

 

管道流:  PipedInputStream 和 PipedOutputStream

    特点:读取管道流和写入管道流可以进行连接。

序列流:也称为合并流.特点:可以将多个读取流合并成一个流。这样操作起来很方便。

 

 

24hashmap底层实现原理

HashMap的主干是一个Entry数组。Entry是HashMap的基本组成单元,每一个Entry包含一个key-value键值对。

25ArrayList底层实现原理

一、 ArrayList概述:  

ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存。

 

    ArrayList不是线程安全的,只能用在单线程环境下

  ArrayList实现了Serializable接口,因此它支持序列化

二、 ArrayList的实现:

   对于ArrayList而言,它实现List接口、底层使用数组保存所有元素。其操作基本上是对数组的操作

 

1) 私有属性:

   ArrayList定义只定义类两个私有属性:elementDatesize

2) 构造方法: 
   ArrayList提供了三种方式的构造器,可以构造一个默认初始容量为10的空列表、构造一个指定初始容量的空列表以及构造一个包含指定collection的元素的列表,这些元素按照该collection的迭代器返回它们的顺序排列的。

 

1、注意其三个不同的构造方法。无参构造方法构造的ArrayList的容量默认为10,带有Collection参数的构造方法,将Collection转化为数组赋给ArrayList的实现数组elementData。

    2、注意扩充容量的方法ensureCapacity。ArrayList在每次增加元素(可能是1个,也可能是一组)时,都要调用该方法来确保足够的容量。当容量不足以容纳当前的元素个数时,就设置新的容量为旧的容量的1.5倍加1,如果设置后的新容量还不够,则直接新容量设置为传入的参数(也就是所需的容量),而后用Arrays.copyof()方法将元素拷贝到新的数组(详见下面的第3点)。从中可以看出,当容量不够时,每次增加元素,都要将原来的元素拷贝到一个新的数组中,非常之耗时,也因此建议在事先能确定元素数量的情况下,才使用ArrayList,否则建议使用LinkedList。

3ArrayList基于数组实现,可以通过下标索引直接查找到指定位置的元素,因此查找效率高,但每次插入或删除元素,就要大量地移动元素,插入删除元素的效率低。

4、在查找给定元素索引值等的方法中,源码都将该元素的值分为null和不为null两种情况处理,ArrayList中允许元素为null

 

 

26说说你对java虚拟机的了解

程序计数器 
可以看作当前线程所执行的字节码的行号指示器。 
Java虚拟机栈 
Java虚拟栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至完成的过程,就对应着一个栈帧在虚拟机中从入栈到出栈的过程。 
本地方法栈 
本地方法栈与Java虚拟机栈所发挥的作用是非常相似的。它们之间的区别不过是虚拟机栈为虚拟机执行Java方法服务,而本地方法栈则为虚拟机使用到Native方法服务。 
Java堆 
存放对象实例 
方法区 
存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

 

在执行一个所谓的java程序的时候,真真正正在执行的是一个叫做Java虚拟机的进程,而不是我们写的一个个的class文件。这个叫做虚拟机的进程处理一些底层的操作,比如内存的分配和释放等等。我们编写的class文件只是虚拟机进程执行时需要的原料。这些原料在运行时被加载到虚拟机中,被虚拟机解释执行,以控制虚拟机实现我们java代码中所定义的一些相对高层的操作,比如创建一个文件等,可以将class文件中的信息看做对虚拟机的控制信息,也就是一种虚拟指令。

27、&和&&的区别

&和&&都是逻辑运算符,都是判断两边同时真则为真,否则为假;但是&&具有短路效果,当第一个条件不成之后,后面的条件都不执行了,而&则还是继续执行,直到整个条件语句执行完为止。

28、==和equals的区别

==用于基本数据类型的数值比较

equals用于引用数据类型的比较,Object类中的方法,所有的类都有这个方法,这个方法比较的是两个对象的地址值是否相同,

但是如果某个子类重写了这个方法,比如String,Integer,Date...就不是比较地址值了,而是比较具体的基本数据的值

29、String s = new String("xyz");创建了几个String Object? 二者之间有什么区别?

 两个或一个,”xyz”对应一个对象,这个对象放在字符串常量缓冲区,常量”xyz”不管出现多少遍,都是缓冲区中的那一个。New String每写一遍,就创建一个新的对象,它一句那个常量”xyz”对象的内容来创建出一个新String对象。如果以前就用过’xyz’,这句代表就不会创建”xyz”自己了,直接从缓冲区拿

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值