zoukankan      html  css  js  c++  java
  • JAVA基础题

    转载:https://www.cnblogs.com/gaopengfirst/p/7237263.html

    1.super()和this()的区别:

      a).super()是出现在子类调用父类的构造方法,this()是出现在同一个类中调用其他方法;

      b).super()和this()都必须出现在构造方法的第一行;

      c).this()可调用一个构造器,但不能调用两个;

      d).super()和this()不能出现在同一个构造函数里,因为this必然会调用其他的构造函数,其他的构造函数也会有super语句的存在,如果一个构造函数里出现了相同的语句就是去了意义;

      e)super()和this()都是对象,所以不能在static环境下使用,包括static方法,static变量,static语句块

    2. 作用域public,protected,private,以及不写时的区别?

    这四个作用域的可见范围如下表所示。

    说明:如果在修饰的元素上面没有写任何访问修饰符,则表示friendly。

    作用域    当前类     同一package        子孙类        其他package

    ---------------------------------------------------------------------------------------

    public         √                  √                       √                     √

    protected   √                  √                       √                     ×

    friendly      √                  √                       ×                     ×

    private       √                  ×                       ×                     ×

    3.错误和异常的区别,以及运行时异常和一般异常的区别:

    Throwable 是所有 Java 程序中错误处理的父类 ,有两种资类: Error 和 Exception 。
    Error :表示由 JVM 所侦测到的无法预期的错误,由于这是属于 JVM 层次的严重错误 ,导致 JVM 无法继续执行,因此,这是不可捕捉到的,无法采取任何恢复的操作,顶多只能显示错误信息。
    Exception :表示可恢复的例外,这是可捕捉到的。
    Java 提供了两类主要的异常 :runtime exception 和 checked exception 。 checked 异常也就是我们经常遇到的 IO 异常,以及 SQL 异常都是这种异常。 对于这种异常, JAVA 编译器强制要求我们必需对出现的这些异常进行
    catch 。所以,面对这种异常不管我们是否愿意,只能自己去写一大堆 catch 块去处理可能的异常。

    但是另外一种异常: runtime exception ,也称运行时异常,我们可以不处理。当出现这样的异常时,总是由虚拟机接管。比如:我们从来没有人去处理过 NullPointerException 异常,它就是运行时异常,并且这种异常还是最常见的异常之一。
    出现运行时异常后,系统会把异常一直往上层抛,一直遇到处理代码。如果没有处理块,到最上层,如果是多线程就由 Thread.run() 抛出 ,如果是单线程就被 main() 抛出 。抛出之后,如果是线程,这个线程也就退出了。如果是主程序抛出的异常,那么这整个程序也就退出了。运行时异常是
    Exception 的子类,也有一般异常的特点,是可以被 Catch
    块处理的。只不过往往我们不对他处理罢了。也就是说,你如果不对运行时异常进行处理,那么出现运行时异常之后,要么是线程中止,要么是主程序终止。

    如果不想终止,则必须扑捉所有的运行时异常,决不让这个处理线程退出。队列里面出现异常数据了,正常的处理应该是把异常数据舍弃,然后记录日志。不应该由于异常数据而影响下面对正常数据的处理。
    在这个场景这样处理可能是一个比较好的应用,但并不代表在所有的场景你都应该如此。如果在其它场景,遇到了一些错误,如果退出程序比较好,这时你就可以不太理会运行时异常
    ,或者是通过对异常的处理显式的控制程序退出。

    4. Overload和Override的区别?

    Overload是重载的意思,Override是覆盖的意思,也就是重写。

    重载Overload表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数或类型不同)。

    重写Override表示子类中的方法可以与父类中的某个方法的名称和参数完全相同,通过子类创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于把父类中定义的那个完全相同的方法给覆盖了,这也是面向对象编程的多态性的一种表现。子类覆盖父类的方法时,只能比父类抛出更少的异常,或者是抛出父类抛出的异常的子异常,因为子类可以解决父类的一些问题,不能比父类有更多的问题。子类方法的访问权限只能比父类的更大,不能更小。如果父类的方法是private类型,那么,子类则不存在覆盖的限制,相当于子类中增加了一个全新的方法。

    构造器Constructor不能被继承,因此不能重写Override,但可以被重载Overload。

    5. Final类有什么特点?

    不可被继承,例如String。

    Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类、非抽象类成员方法和变量。

    final类不能被继承,没有子类,final类中的方法默认是final的。

    final方法不能被子类的方法覆盖,但可以被继承。

    final成员变量表示常量,只能被赋值一次,赋值后值不再改变。

    final不能用于修饰构造方法。

    注意:父类的private成员方法是不能被子类方法覆盖的,因此private类型的方法默认是final类型的。 1、final类 final类不能被继承,因此final类的成员方法没有机会被覆盖,默认都是final的。在设计类时候,如果这个类不需要有子类,类的实现细节不允许改变,并且确信这个类不会再被扩展,那么就设计为final类。

    2、final方法 如果一个类不允许其子类覆盖某个方法,则可以把这个方法声明为final方法。使用final方法的原因有二:①把方法锁定,防止任何继承类修改它的意义和实现。 ②高效,编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率。

    6. String ,StringBuilder,StringBuffer的区别?

    String是字符串常量,一般用在单线程处理少量数据时使用。

    StringBuilder是线程不安全的,一般用在单线程处理大量数据时使用,效率较高。

    StringBuffer是线程安全的,一般用在多线程处理大量数据时使用。

    7.list、set和map的区别?

    list是有序可重复的,set是无序不可重复的,map是以key-value键值对的形式存在的。

    List接口主要实现类包括:

    • ArrayList() : 代表长度可以改变得数组。可以对元素进行随机的访问,向ArrayList()中插入与删除元素的速度慢,但查询快。 
    • LinkedList(): 在实现中采用链表数据结构。插入和删除速度快,查询慢。

     Set接口主要实现了两个实现类:

    • HashSet: HashSet类按照哈希算法来存取集合中的对象,存取速度比较快 
    • TreeSet :TreeSet类实现了SortedSet接口,能够对集合中的对象进行排序。 

    map:添加数据put(),putAll(),删除数据remove(),clear(),其实现类有:

    • HashMap:HashMap就是使用对象的hashCode()进行快速查询的。此方法能够显着提高性能。
    • TreeMap :TreeMap 基于红黑树数据结构的实现。查看“键”或“键值对”时,它们会被排序(次序由Comparabel或Comparator决定)。TreeMap的特点在于,你得到的结果是经过排序的。TreeMap是唯一的带有subMap()方法的Map,它可以返回一个子树。  
    总结

    1. 如果涉及到堆栈,队列等操作,应该考虑用List,对于需要快速插入,删除元素,应该使用LinkedList,如果需要快速随机访问元素,应该使用ArrayList。
    2. 如果程序在单线程环境中,或者访问仅仅在一个线程中进行,考虑非同步的类,其效率较高,如果多个线程可能同时操作一个类,应该使用同步的类。
    3. 在除需要排序时使用TreeSet,TreeMap外,都应使用HashSet,HashMap,因为他们 的效率更高。
    4. 要特别注意对哈希表的操作,作为key的对象要正确复写equals和hashCode方法。
    5. 容器类仅能持有对象引用(指向对象的指针),而不是将对象信息copy一份至数列某位置。一旦将对象置入容器内,便损失了该对象的型别信息。
    6. 尽量返回接口而非实际的类型,如返回List而非ArrayList,这样如果以后需要将ArrayList换成LinkedList时,客户端代码不用改变。这就是针对抽象编程。

    注意:
    1、Collection没有get()方法来取得某个元素。只能通过iterator()遍历元素。
    2、Set和Collection拥有一模一样的接口。
    3、List,可以通过get()方法来一次取出一个元素。使用数字来选择一堆对象中的一个,get(0)...。(add/get)
    4、一般使用ArrayList。用LinkedList构造堆栈stack、队列queue。
    5、Map用 put(k,v) / get(k),还可以使用containsKey()/containsValue()来检查其中是否含有某个key/value。
          HashMap会利用对象的hashCode来快速找到key。
    6、Map中元素,可以将key序列、value序列单独抽取出来。
    使用keySet()抽取key序列,将map中的所有keys生成一个Set。
    使用values()抽取value序列,将map中的所有values生成一个Collection。
    为什么一个生成Set,一个生成Collection?那是因为,key总是独一无二的,value允许重复。
     

    8.线程的五大状态:

    1)新建(new Thread)
    当创建Thread类的一个实例(对象)时,此线程进入新建状态(未被启动)。
    例如:Thread  t1=new Thread();

    2)就绪(runnable)
    线程已经被启动,正在等待被分配给CPU时间片,也就是说此时线程正在就绪队列中排队等候得到CPU资源。例如:t1.start();

    3)运行(running)
    线程获得CPU资源正在执行任务(run()方法),此时除非此线程自动放弃CPU资源或者有优先级更高的线程进入,线程将一直运行到结束。

    4)死亡(dead)
    当线程执行完毕或被其它线程杀死,线程就进入死亡状态,这时线程不可能再进入就绪状态等待执行。

    自然终止:正常运行run()方法后终止

    异常终止:调用stop()方法让一个线程终止运行

    5)堵塞(blocked)
    由于某种原因导致正在运行的线程让出CPU并暂停自己的执行,即进入堵塞状态。

    正在睡眠:用sleep(long t) 方法可使线程进入睡眠方式。一个睡眠着的线程在指定的时间过去可进入就绪状态。

    正在等待:调用wait()方法。(调用motify()方法回到就绪状态)

    被另一个线程所阻塞:调用suspend()方法。(调用resume()方法恢复)


    启动一个线程是调用start()方法,使线程就绪状态,以后可以被调度为运行状态,一个线程必须关联一些具体的执行代码,run()方法是该线程所关联的执行代码。

    Sleep()可以设置时间,wait需要唤醒方法:

    (网上的答案:sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。 wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。)

    sleep就是正在执行的线程主动让出cpu,cpu去执行其他线程,在sleep指定的时间过后,cpu才会回到这个线程上继续往下执行,如果当前线程进入了同步锁,sleep方法并不会释放锁,即使当前线程使用sleep方法让出了cpu,但其他被同步锁挡住了的线程也无法得到执行。wait是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线程调用了notify方法(notify并不释放锁,只是告诉调用过wait方法的线程可以去参与获得锁的竞争了,但不是马上得到锁,因为锁还在别人手里,别人还没释放。如果notify方法后面的代码还有很多,需要这些代码执行完后才会释放锁,可以在notfiy方法后增加一个等待和一些代码,看看效果),调用wait方法的线程就会解除wait状态和程序可以再次得到锁后继续向下运行。

    9."=="和equals的区别:

    ==操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用==操作符。

    如果一个变量指向的数据是对象类型的,那么,这时候涉及了两块内存,对象本身占用一块内存(堆内存),变量也占用一块内存,例如Objet obj = new Object();变量obj是一个内存,new Object()是另一个内存,此时,变量obj所对应的内存中存储的数值就是对象占用的那块内存的首地址。对于指向对象类型的变量,如果要比较两个变量是否指向同一个对象,即要看这两个变量所对应的内存中的数值是否相等,这时候就需要用==操作符进行比较。

    equals方法是用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象是独立的。例如,对于下面的代码:

    String a=new String("foo");

    String b=new String("foo");

    两条new语句创建了两个对象,然后用a,b这两个变量分别指向了其中一个对象,这是两个不同的对象,它们的首地址是不同的,即a和b中存储的数值是不相同的,所以,表达式a==b将返回false,而这两个对象中的内容是相同的,所以,表达式a.equals(b)将返回true。

    在实际开发中,我们经常要比较传递进行来的字符串内容是否等,例如,String input = …;input.equals(“quit”),许多人稍不注意就使用==进行比较了,这是错误的,随便从网上找几个项目实战的教学视频看看,里面就有大量这样的错误。记住,字符串的比较基本上都是使用equals方法。

    10.Integer与int的区别:

    int是java提供的8种原始数据类型之一。Java为每个原始类型提供了封装类,Integer是java为int提供的封装类。int的默认值为0,而Integer的默认值为null,即Integer可以区分出未赋值和值为0的区别,int则无法表达出未赋值的情况,例如,要想表达出没有参加考试和考试成绩为0的区别,则只能使用Integer。在JSP开发中,Integer的默认为null,所以用el表达式在文本框中显示时,值为空白字符串,而int默认的默认值为0,所以用el表达式在文本框中显示时,结果为0,所以,int不适合作为web层的表单数据的类型。

    在Hibernate中,如果将OID定义为Integer类型,那么Hibernate就可以根据其值是否为null而判断一个对象是否是临时的,如果将OID定义为了int类型,还需要在hbm映射文件中设置其unsaved-value属性为0。

    另外,Integer提供了多个与整数相关的操作方法,例如,将一个字符串转换成整数,Integer中还定义了表示整数的最大值和最小值的常量。

    11.抽象类与接口的区别:

    1、概念不一样。接口是对动作的抽象,抽象类是对本质的抽象。
    抽象类表示的是,这个对象是什么。接口表示的是,这个对象能做什么。比如,男人,女人,这两个类(如果是类的话……),他们的抽象类是人。说明,他们都是人。人可以吃东西,狗也可以吃东西,你可以把“吃东西”定义成一个接口,然后让这些类去实现它。
    所以,在高级语言上,一个类只能继承一个类(抽象类)(正如人不可能同时是生物和非生物),但是可以实现多个接口(吃饭接口、走路接口)。

    2、使用不一样:

     a.抽象类 和 接口 都是用来抽象具体对象的. 但是接口的抽象级别最高
    b.抽象类可以有具体的方法 和属性,  接口只能有抽象方法和不可变常量
    c.抽象类主要用来抽象类别,接口主要用来抽象功能.
    d.抽象类中,且不包含任何实现,派生类必须覆盖它们。接口中所有方法都必须是未实现的。

     e.接口是设计的结果 ,抽象类是重构的结果

    3、使用方向:当你关注一个事物的本质的时候,用抽象类;当你关注一个操作的时候,用接口。
    注意:抽象类的功能要远超过接口,但是,定义抽象类的代价高。因为高级语言来说(从实际设计上来说也是)每个类只能继承一个类。在这个类中,你必须继承或编写出其所有子类的所有共性。虽然接口在功能上会弱化许多,但是它只是针对一个动作的描述。而且你可以在一个类中同时实现多个接口。在设计阶段会降低难度的。

  • 相关阅读:
    Python开篇——Python的哲学
    python在CentOS 7中的安装
    TortoiseSVN_1.9.1.267_x64版本控制系统(针对Visual SVN Server)使用简单介绍
    win10+eclipse+hadoop2.7.2+maven+local模式直接通过Run as Java Application运行wordcount
    存储器的保护(三)——《x86汇编语言:从实模式到保护模式》读书笔记20
    存储器的保护(一)——《x86汇编语言:从实模式到保护模式》读书笔记18
    存储器的保护(二)——《x86汇编语言:从实模式到保护模式》读书笔记19
    进入保护模式(三)——《x86汇编语言:从实模式到保护模式》读书笔记17
    16位模式/32位模式下PUSH指令探究——《x86汇编语言:从实模式到保护模式》读书笔记16
    关于80286——《x86汇编语言:从实模式到保护模式》读书笔记15
  • 原文地址:https://www.cnblogs.com/69-year-old-comrade/p/14983705.html
Copyright © 2011-2022 走看看