java基础的面试问题(一)

1、Java基本数据类型

四种整数类型(byte、short、int、long)

两种浮点数类型(float、double)

一种字符类型(char)

一种布尔类型(boolean)

2、原始数据类型(基本类型)和封装类的区别

   1.基本类型,或者叫做内置类型,是JAVA中不同于类的特殊类型。

   2.封装类型就是java面向对象引入的数据类型,里面定义了一些常用的方法,是用new分配到堆内存上的。引入封装类型的主要目的是因为类能够提供必要的方法,用于实现基本数据类型的数值与可打印字符串之间的转换,以及一些其他的实用程序方法。Java为每个原始类型提供了封装类。

3、String、StringBuffer、StringBuilder区别

答:

1.首先说运行速度,或者说是执行速度,在这方面运行速度快慢为:StringBuilder > StringBuffer > String

  String最慢的原因:

  String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。

2.在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的

总结:

String:适用于少量的字符串操作的情况

StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况

StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

4、运行时异常和非运行时异常区别

答:

1.运行时异常是不需要捕获的,程序员可以不去处理,当异常出现时,虚拟机会处理。常见的运行时异常有空指针异常

2.非运行时异常就必须得捕获了,否则编译不过去

5、简述一下面向对象的特征,并举例说明你对面向对象的理解

答:封装:所谓的面向对象就是将我们的程序模块化,对象化,把具体事物的特性属性和通过这些属性来实现一些动作的具体方法放到一个类里面封装是我们所说的面相对象编程的特征之一。

多态:指相同对象收到不同消息或不同对象收到相同消息时产生不同的实现动作。

继承:也就是父类的相关的属性,可以被子类重复使用,子类不必再在自己的类里面重新定义一回,父类里有点我们只要拿过来用就好了。而对于自己类里面需要用到的新的属性和方法,子类就可以自己来扩展了。

6、正则表达式的用法

答:正则表达式是一种可以用于模式匹配和替换的规范,一个正则表达式就是由普通的字符(例如字符a到z)以及特殊字符(元字符)组成的文字模式,它 用以描述在查找文字主体时待匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。

7、Java 语言如何进行异常处理,关键字:throws、throw、try、catch、finally分别代表什么意义?finally代码是在return之后还是之前执行?

答:try块表示程序正常的业务执行代码。如果程序在执行try块的代码时出现了“非预期”情况,JVM将会生成一个异常对象,这个异常对象将会被后面相应的catch块捕获。

catch块表示一个异常捕获块。当程序执行try块引发异常时,这个异常对象将会被后面相应的catch块捕获。

throw用于手动地抛出异常对象。throw后面需要一个异常对象。

throws用于在方法签名中声明抛出一个或多个异常类,throws关键字后可以紧跟一个或多个异常类。

finally块代表异常处理流程中总会执行的代码块。

对于一个完整的异常处理流程而言,try块是必须的,try块后可以紧跟一个或多个catch块,最后还可以带一个finally块。

try块中可以抛出异常。

Try语句执行finally里面的语句才会执行

8、abstractclass和interface有什么区别?接口可以继承接口吗?接口可以继承抽象类吗,为什么?

1.有抽象方法的类一定是抽象类,但抽象类里可以没有抽象方法(当然也可以抽象方法+一般方法);



2.抽象类里可以构造方法,但当其他类继承(extends)时,子类必须用super() 继承父类的构造方法;



3.抽象类一旦被继承,抽象方法在子类必须全部实现(没有abstract修饰),但是当子类也为抽象类时,父类的抽象方法可以不用实现或者部分实现;



4.抽象类不能被实例(new  对象),只能实例化实现了抽象方法的子类

答:

1、抽象类可以包含非抽象的方法,而接口中的方法必须是抽象的。

2、继承抽象类在Java语言体系中体现一种继承关系,在合理的继承关系中,父类和派生类比如按存在is-a关系。而实现接口则体现一种has-a关系,实现者仅仅是实现了interface定义的契约而已。

3、抽象类中可以有成员变量,而接口中不能有成员变量。

4、抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的属性可以是任意的,而接口中的静态成员变量默认且必须是public static final。

5、接口中的抽象方法默认且必须都是public的,而抽象类中的抽象方法可以是public、protect或默认。

6、抽象类中可以有构造方法,但是不能实例化。

7、抽象类中可以有静态方法(非抽象的),而接口中不能有静态方法。

8、抽象类中的抽象方法不能用static、synchronized和native连用

9、构造器(constructor)是否可被重写(override)?

 答:Constructor(构造器)不能被继承,所以不能被override(重写),但是可以被overloading(重载)。

10、是否可以继承String类?

答:public final class String extends Object,里边有final关键字,所以不能被继承

11、Java 中的final关键字有哪些用法?

答:final关键字是我们经常使用的关键字之一,它的用法有很多,但是并不是每一种用法都值得我们去广泛使用。它的主要用法有以下四种:

1. 用来修饰数据,包括成员变量和局部变量,该变量只能被赋值一次且它的值无法被改变。对于成员变量来讲,我们必须在声明时或者构造方法中对它赋值;

2. 用来修饰方法参数,表示在变量的生存期中它的值不能被改变;

3. 修饰方法,表示该方法无法被重写;

4. 修饰类,表示该类无法被继承。

上面的四种方法中,第三种和第四种方法需要谨慎使用,因为在大多数情况下,如果是仅仅为了一点设计上的考虑,我们并不需要使用final来修饰方法和类

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

答:会执行,在return中间执行,什么叫做在return中间执行呢?
 就是在我们进return方法的时候,跳转到finally里面,但是里面的操作不影响return的返回值,因为结果已经决定

13、阐述final、finally、finalize的区别。

答:final:java中的关键字,修饰符。  
1.如果一个类被声明为final,就意味着它不能再派生出新的子类,不能作为父类被继承。因此,一个类不能同时被声明为absrtact抽象类的和final的类。

2.如果将变量或者方法声明为final,可以保证它们在使用中不被改变.

  2.1 被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。 

  2.2被声明final的方法只能使用,不能重载。



finally:java的一种异常处理机制。

finally是对Java 异常处理模型的最佳补充。finally 结构使代码总会执行,而不管有无异常发生。使用 finally 可以维护对象的内部状态,并可以清理非内存资源。特别是在关闭数据库连接这方面,如果程序员把数据库连接的close()方法放到finally中,就会大大降低程序出错的几率。



finalize:Java中的一个方法名。

Java技术使用finalize()方法在垃圾收集器将对象从内存中清除出去前,做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在Object类中定义的,因此所有的类都继承了它。子类覆盖finalize()方法以整理系统资源或者执行其他清理工作。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。

14、如何通过反射创建对象?

1、通过 Class.forName("类的全称")
例如:Class cl1= Class.forName("com.csdn.Test");
2、通过  类名.class
例如: Testtest=new Test();
             Class cl3= Test.class;

3、通过  类的对象.getClass()

例如: Class cl2=test.getClass();  



1.   getName()  获取类的全称(包括包名)
2.getSimpleName()  获取类的简称(不含类的路径)
3.getDeclaredConstructor() 返回指定参数,所有声明的(包含private)的构造函数
4.getContructor()  返回指定参数类型,具有public访问权限的构造函数
5.getDeclaredFields()  返回该类中的属性 Field[] fields

循环遍历后可以获取每一个Field  getName()获取该类中的属性名

15、Java8的新特性
答:一、Lambda表达式

Lambda表达式可以说是Java8最大的卖点,她将函数式编程引入了Java。Lambda允许把函数作为一个方法的参数,或者把代码看成数据。

一个Lambda表达式可以由用逗号分隔的参数列表、–>符号与函数体三部分表示。

Arrays.asList("p", "k", "u","f", "o","r","k").forEach( e -> System.out.println( e ) )

二、接口的默认方法与静态方法

我们可以在接口中定义默认方法,使用default关键字,并提供默认的实现。所有实现这个接口的类都会接受默认方法的实现,除非子类提供的自己的实现。例如:

接口的默认方法和静态方法的引入,其实可以认为引入了C++中抽象类的理念,以后我们再也不用在每个实现类中都写重复的代码了。

四、重复注解

在Java 5中使用注解有一个限制,即相同的注解在同一位置只能声明一次。Java 8引入重复注解,这样相同的注解在同一地方也可以声明多次。重复注解机制本身需要用@Repeatable注解。Java 8在编译器层做了优化,相同注解会以集合的方式保存,因此底层的原理并没有变化

五、扩展注解的支持

Java 8扩展了注解的上下文,几乎可以为任何东西添加注解,包括局部变量、泛型类、父类与接口的实现,连方法的异常也能添加注解

16、Java数组和链表的两种结构的操作效率

答:数组静态分配内存,链表动态分配内存; 
数组在内存中连续,链表不连续; 
数组元素在栈区,链表元素在堆区; 
数组利用下标定位,时间复杂度为O(1),链表定位元素时间复杂度O(n); 
数组插入或删除元素的时间复杂度O(n),链表的时间复杂度O(1)。 

17、Java的引用类型有哪几种

java将引用分为了强引用、软引用、弱引用、虚引用四种,引用强度一次减弱。

·        强引用:类似Object a=new Object()这类,永远不会被回收。

·        软引用:SoftReference,当系统快要发生内存溢出异常时,将会把这些对象列入回收范围进行二次回收,如果这次回收还是没有足够内存,则抛出内存溢出异常。

·        弱引用:比软引用更弱,活不过下一次gc。无论当前内存是否足够,下一次gc都会被回收掉。

·        虚引用:又叫幻引用,最弱,一个对象时候有虚引用的存在,不会对它的生存时间构成影响,唯一目的就是能在这对象被回收以后收到一个系统通知。。

二、多线程、IO、集合

1、ArrayList、Vector、LinkedList的存储性能和特性

1.   ArrayList 采用的是数组形式来保存对象的,这种方式将对象放在连续的位置中,所以最大的缺点就是插入删除时非常麻烦

2.   LinkedList 采用的将对象存放在独立的空间中,而且在每个空间中还保存下一个链接的索引 但是缺点就是查找非常麻烦 要丛第一个索引开始

3.   ArrayList和Vector都是用数组方式存储数据,此数组元素数要大于实际的存储空间以便进行元素增加和插入操作,他们都允许直接用序号索引元素,但是插入数据元素涉及到元素移动等内存操作,所以索引数据快而插入数据慢.

4.   Vector使用了sychronized方法(线程安全),所以在性能上比ArrayList要差些.

5.   LinkedList使用双向链表方式存储数据,按序号索引数据需要前向或后向遍历数据,所以索引数据慢,是插入数据时只需要记录前后项即可,所以插入的速度快.

arraylist和vector的区别? 
        1).同步性:Vector是线程安全的,也就是说是同步的,而ArrayList是线程不安全的,不是同步的 
        2).数据增长:当需要增长时,Vector默认增长为原来一培,而ArrayList却是原来的一半

2、List、Set、Map是否继承自Collection接口?

   答:List,Set是,Map不是。

3、List、Map、Set三个接口存取元素时,各有什么特点?

    答: List与Set都是单列元素的集合,它们有一个功共同的父接口Collection。

    Set里面不允许有重复的元素,

    存元素:add方法有一个boolean的返回值,当集合中没有某个元素,此时add方法可成功加入该元素时,则返回true;当集合含有与某个元素equals相等的元素时,此时add方法无法加入该元素,返回结果为false。

    取元素:没法说取第几个,只能以Iterator接口取得所有的元素,再逐一遍历各个元素。

    List表示有先后顺序的集合,

    存元素:多次调用add(Object)方法时,每次加入的对象按先来后到的顺序排序,也可以插队,即调用add(int index,Object)方法,就可以指定当前对象在集合中的存放位置。

    取元素:方法1:Iterator接口取得所有,逐一遍历各个元素

            方法2:调用get(index i)来明确说明取第几个。



    Map是双列的集合,存放用put方法:put(obj key,obj value),每次存储时,要存储一对key/value,不能存储重复的key,这个重复的规则也是按equals比较相等。

    取元素:用get(Object key)方法根据key获得相应的value。

        也可以获得所有的key的集合,还可以获得所有的value的集合,

        还可以获得key和value组合成的Map.Entry对象的集合。



List以特定次序来持有元素,可有重复元素。Set 无法拥有重复元素,内部排序。Map 保存key-value值,value可多值。

4、请说出与线程同步以及线程调度相关的方法。

    答:- wait():使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁;
    - sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要处理InterruptedException异常; 
    - notify():唤醒一个处于等待状态的线程,当然在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且与优先级无关;


    -notityAll():唤醒所有处于等待状态的线程,该方法并不是将对象的锁给所有线程,而是让它们竞争,只有获得锁的线程才能进入就绪状态;

    补充:Java 5通过Lock接口提供了显式的锁机制(explicit lock),增强了灵活性以及对线程的协调。Lock接口中定义了加锁(lock())和解锁(unlock())的方法,同时还提供了newCondition()方法来产生用于线程之间通信的Condition对象;此外,Java 5还提供了信号量机制(semaphore),信号量可以用来限制对某个共享资源进行访问的线程的数量。在对资源进行访问之前,线程必须得到信号量的许可(调用Semaphore对象的acquire()方法);在完成对资源的访问后,线程必须向信号量归还许可(调用Semaphore对象的release()方法)。

5、编写多线程程序有几种实现方式?

答: 1、继承Thread类实现多线程
继承Thread类的方法尽管被我列为一种多线程实现方式,但Thread本质上也是实现了Runnable接口的一个实例,它代表一个线程的实例,并且,启动线程的唯一方法就是通过Thread类的start()实例方法。start()方法是一个native方法,它将启动一个新线程,并执行run()方法。这种方式实现多线程很简单,通过自己的类直接extend Thread,并复写run()方法,就可以启动新线程并执行自己定义的run()方法。

2、实现Runnable接口方式实现多线程
如果自己的类已经extends另一个类,就无法直接extendsThread,此时,必须实现一个Runnable接口

3、使用ExecutorService、Callable、Future实现有返回结果的多线程 

6、简述synchronized和java.util.concurrent.locks.Lock的异同?

答:主要相同点:Lock能完成synchronized所实现的所有功能 
主要不同点:Lock有比synchronized更精确的线程语义和更好的性能。synchronized会自动释放锁,而Lock一定要求程序员手工释放,并且必须在finally从句中释放(因为如果不在finally中释放的情况,当抛出异常时,线程直接死掉,但是没有释放锁,使得其他相关线程无法执行。读者可以试试在定义一个数组,并访问越界区,使得程序抛出异常,但是释放锁并未在finally中)。

7、ArrayList和HsahSet的区别?

 答:arraylist有顺序,hashset没有顺序。set没有键值和属性值,那是map
HashTable和HashMap区别
    1、继承的父类不同
      Hashtable继承自Dictionary类,而HashMap继承自AbstractMap类。但二者都实现了Map接口。

      2、线程安全性不同
      javadoc中关于hashmap的一段描述如下:此实现不是同步的。如果多个线程同时访问一个哈希映射,而其中至少一个线程从结构上修改了该映射,则它必须保持外部同步
8、HashMap和HashTable区别     
答:HashMap和Hashtable都实现了Map接口,但决定用哪一个之前先要弄清楚它们之间的分别。主要的区别有:线程安全性,同步(synchronization),以及速度。

1.    HashMap几乎可以等价于Hashtable,除了HashMap是非synchronized的,并可以接受null(HashMap可以接受为null的键值(key)和值(value),而Hashtable则不行)。

2.    HashMap是非synchronized,而Hashtable是synchronized,这意味着Hashtable是线程安全的,多个线程可以共享一个Hashtable;而如果没有正确的同步的话,多个线程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的扩展性更好。

3.    另一个区别是HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以当有其它线程改变了HashMap的结构(增加或者移除元素),将会抛出ConcurrentModificationException,但迭代器本身的remove()方法移除元素则不会抛出ConcurrentModificationException异常。但这并不是一个一定发生的行为,要看JVM。这条同样也是Enumeration和Iterator的区别。

4.    由于Hashtable是线程安全的也是synchronized,所以在单线程环境下它比HashMap要慢。如果你不需要同步,只需要单一线程,那么使用HashMap性能要好过Hashtable。

5.    HashMap不能保证随着时间的推移Map中的元素次序是不变的

9、讲讲IO里面的常见类,字节流、字符流、接口、实现类、方法阻塞。

答:输入流就是从外部文件输入到内存,输出流主要是从内存输出到文件。我们用Eclipse开发小程序在控制台输入数据就属于输入流,即从控制台输入到内存。IO里面常见的类,第一印象就只知道IO流中有很多类,IO流主要分为字符流和字节流。字符流中有抽象类InputStream和OutputStream,它们的子类FileInputStream,FileOutputStream,BufferedOutputStream等。字符流BufferedReader和Writer等。都实现了Closeable, Flushable, Appendable这些接口。程序中的输入输出都是以流的形式保存的,流中保存的实际上全都是字节文件。



    java中的阻塞式方法是指在程序调用改方法时,必须等待输入数据可用或者检测到输入结束或者抛出异常,否则程序会一直停留在该语句上,不会执行下面的语句。比如read()和readLine()方法。

10、什么时候使用字节流,什么时候使用字符流

    答:所有的输入都是转换成字节流之后,然后在内存中变成字符流。所以一般建议使用字符流。但是遇到中文汉字,出现乱码的情况下,可以使用字节流。

    在所有的硬盘上保存文件或进行传输的时候都是以字节的方法进行的,包括图片也是按字节完成,而字符是只有在内存中才会形成的,所以使用字节的操作是最多的。我们建议尽量尝试使用字符流,一旦程序无法成功编译,就不得不使用面向字节的类库,即字节流。

猜你喜欢

转载自blog.csdn.net/godlk/article/details/80766839