• Java基础笔试面试题整理


    计算机软件系统是现实生活中的业务在计算机中的映射,而现实生活中的业务其实就是一个个对象协作的过程。面向对象编程就是按现实业务一样的方式将程序代码按一个个对象进行组织和编写,让计算机系统能够识别和理解用对象方式组织和编写的程序代码,这样就可以把现实生活中的业务对象映射到计算机系统中。

    1、说说&&&的区别。 

    &&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都为true时,整个运算结果才为true,否则,只要有一方为false,则结果为false

    &&还具有短路的功能,即如果第一个表达式为false,则不再计算第二个表达式,例如,对于if(str != null && !str.equals(“”))表达式,当strnull时,后面的表达式不会执行,所以不会出现NullPointerException如果将&&改为&,则会抛出NullPointerException异常。If(x==33 & ++y>0) y会增长,If(x==33 && ++y>0)不会增长

    &还可以用作位运算符,当&操作符两边的表达式不是boolean类型时,&表示按位与操作,我们通常使用0x0f来与一个整数进行&运算,来获取该整数的最低4bit位,例如,0x31 & 0x0f的结果为0x01

    备注:这道题先说两者的共同点,再说出&&&的特殊之处,并列举一些经典的例子来表明自己理解透彻深入、实际经验丰富。

    2char型变量中能不能存贮一个中文汉字?为什么?

    char型变量是用来存储Unicode编码的字符的,unicode编码字符集中包含了汉字,所以,char型变量中当然可以存储汉字啦。不过,如果某个特殊的汉字没有被包含在unicode编码字符集中,那么,这个char型变量中就不能存储这个特殊汉字。补充说明:unicode编码占用两个字节,所以,char类型的变量也是占用两个字节。

    备注:后面一部分回答虽然不是在正面回答题目,但是,为了展现自己的学识和表现自己对问题理解的透彻深入,可以回答一些相关的知识,做到知无不言,言无不尽。

    3使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变 

    使用final关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的。例如,对于如下语句:

     final StringBuffer a=new StringBuffer("immutable");
    执行如下语句将报告编译期错误

    a=new StringBuffer("");
    但是,执行如下语句则可以通过编译:

    a.append(" broken!"); 

    有人在定义方法的参数时,可能想采用如下形式来阻止方法内部修改传进来的参数对象:

    public void method(final  StringBuffer  param){

    }

    实际上,这是办不到的,在该方法内部仍然可以增加如下代码来修改参数对象:

    param.append("a");

    4"=="equals方法究竟有什么区别?

    ==比较两个变量的引用(内存地址)是否相等。equals比较两个变量的实际值是否相等。

    例如,对于下面的代码:

    String a=new String("foo");

    String b=new String("foo");

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

    例如,以下代码:

    String a="hello";

    String b=new String("hello");

    System.out.println(a.equals(b));//true

    System.out.println(a==b);//false

    String c=new String("hello");

    System.out.println(b==c);//false

    上述代码中,当程序执行第一行时,会首先去字符串池中检查是否存在“hello”,若不存在,则在字符串池中创建“hello”对象。

    当程序执行第二行时,首先去字符串池中检查是否存在“hello”,若不存在,则在字符串池中创建“hello”对象,然后在堆内存中继续创建一个“hello”对象。变量b则指向堆内存中的“hello”对象。

    当执行到倒数第二行时,仍然会先去字符串池中检查是否存在“hello”,若不存在,则在字符串池中创建“hello”对象,然后在堆内存中继续创建一个“hello”对象。变量c则指向堆内存中的“hello”对象。

    只要通过关键字new创建的对象,不管堆内存中是否存在相同的值,一定会在堆内存中创建一个对象,然后将变量指向这个对象。

    5Integerint的区别

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

    6Math.round(11.5)等於多少? Math.round(-11.5)等於多少?

    Math类中提供了三个与取整有关的方法:ceilfloorround,这些方法的作用与它们的英文名称的含义相对应,例如,ceil的英文意义是天花板,该方法就表示向上取整,Math.ceil(11.3)的结果为12,Math.ceil(-11.3)的结果是-11floor的英文意义是地板,该方法就表示向下取整,Math.ceil(11.6)的结果为11,Math.ceil(-11.6)的结果是-12;最难掌握的是round方法,它表示“四舍五入”,算法为Math.floor(x+0.5),即将原来的数字加上0.5后再向下取整,所以,Math.round(11.5)的结果为12Math.round(-11.5)的结果为-11

    7、请说出作用域publicprivateprotected,以及不写时的区别

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

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

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

    public    √     √          √       √

    protected  √     √          √      ×

    friendly   √     √          ×      ×

    private    √     ×          ×      ×

    备注:只要记住了有4种访问权限,4个访问范围,然后将全选和范围在水平和垂直方向上分别按排从小到大或从大到小的顺序排列,就很容易画出上面的图了。

    8String s = new String("xyz");创建了几个String 对象?

    两个或一个,”xyz”对应一个对象,这个对象放在字符串常量缓冲区,常量”xyz”不管出现多少遍,都是缓冲区中的那一个。new String每写一遍,就在堆内存中创建一个新的对象。

    9String StringBuffer的区别

    JAVA平台提供了两个类:StringStringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据。这个String类提供了数值不可改变的字符串。而这个StringBuffer类提供的字符串进行修改。当你知道字符数据要改变的时候你就可以使用StringBuffer。典型地,你可以使用StringBuffers来动态构造字符数据。另外,String实现了equals方法,new String(“abc”).equals(new String(“abc”)的结果为true,StringBuffer没有实现equals方法,所以,new StringBuffer(“abc”).equals(new StringBuffer(“abc”)的结果为false

    接着要举一个具体的例子来说明,我们要把1100的所有数字拼起来,组成一个串。

    StringBuffer sbf = new StringBuffer();  

    for(int i=0;i<100;i++)

    {

    sbf.append(i);

    }

    上面的代码效率很高,因为只创建了一个StringBuffer对象,而下面的代码效率很低,因为创建了101个对象。

    String str = new String();  

    for(int i=0;i<100;i++)

    {

    str = str + i;

    }

    在讲两者区别时,应把循环的次数搞成10000,然后用endTime-beginTime来比较两者执行的时间差异,最后还要讲讲StringBuilderStringBuffer的区别。

    String覆盖了equals方法和hashCode方法,而StringBuffer没有覆盖equals方法和hashCode方法,所以,将StringBuffer对象存储进Java集合类中时会出现问题。

    10数组有没有length()这个方法? String有没有length()这个方法?

    数组没有length()这个方法,有length的属性。Stringlength()这个方法。

    11、下面这条语句一共创建了多少个对象:String s="a"+"b"+"c"+"d";

    答:对于如下代码:

    String s1 = "a";

    String s2 = s1 + "b";

    String s3 = "a" + "b";

    System.out.println(s2 == "ab");

    System.out.println(s3 == "ab");

    第一条语句打印的结果为false,第二条语句打印的结果为true,这说明javac编译可以对字符串常量直接相加的表达式进行优化,不必要等到运行期去进行加法运算处理,而是在编译时去掉其中的加号,直接将其编译成一个这些常量相连的结果。

    题目中的第一行代码被编译器在编译时优化后,相当于直接定义了一个”abcd”的字符串,所以,上面的代码应该只创建了一个String对象。写如下两行代码,

    String s = "a" + "b" + "c" + "d";

    System.out.println(s == "abcd");

    最终打印的结果应该为true

    12、掌握Java的常用排序算法

    冒泡排序、选择排序、插入排序、快速排序。

    13ListMapSet三个接口,存取元素时,各有什么特点? 

    这样的题属于随意发挥题:这样的题比较考水平,两个方面的水平:一是要真正明白这些内容,二是要有较强的总结和表述能力。如果你明白,但表述不清楚,在别人那里则等同于不明白。

    首先,ListSet具有相似性,它们都是单列元素的集合,所以,它们有一个功共同的父接口,叫CollectionSet里面不允许有重复的元素,所谓重复,即不能有两个相等(注意,不是仅仅是相同)的对象 ,即假设Set集合中有了一个A对象,现在我要向Set集合再存入一个B对象,但B对象与A对象equals相等,则B对象存储不进去,所以,Set集合的add方法有一个boolean的返回值,当集合中没有某个元素,此时add方法可成功加入该元素时,则返回true,当集合含有与某个元素equals相等的元素时,此时add方法无法加入该元素,返回结果为falseSet取元素时,没法说取第几个,只能以Iterator接口取得所有的元素,再逐一遍历各个元素。

    List表示有先后顺序的集合, 注意,不是那种按年龄、按大小、按价格之类的排序。当我们多次调用add(Obj e)方法时,每次加入的对象就像火车站买票有排队顺序一样,按先来后到的顺序排序。有时候,也可以插队,即调用add(int index,Obj e)方法,就可以指定当前对象在集合中的存放位置。一个对象可以被反复存储进List中,每调用一次add方法,这个对象就被插入进集合中一次,其实,并不是把这个对象本身存储进了集合中,而是在集合中用一个索引变量指向这个对象,当这个对象被add多次时,即相当于集合中有多个索引指向了这个对象,如图x所示。List除了可以以Iterator接口取得所有的元素,再逐一遍历各个元素之外,还可以调用get(index i)来明确说明取第几个。

    MapListSet不同,它是双列的集合,其中有put方法,定义如下:put(obj key,obj value),每次存储时,要存储一对key/value,不能存储重复的key,这个重复的规则也是按equals比较相等。取则可以根据key获得相应的value,即get(Object key)返回值为key 所对应的value。另外,也可以获得所有的key的结合,还可以获得所有的value的结合,还可以获得keyvalue组合成的Map.Entry对象的集合。

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

    HashSet按照hashcode值的某种运算方式进行存储,而不是直接按hashCode值的大小进行存储。例如,"abc" ---> 78"def" ---> 62"xyz" ---> 65hashSet中的存储顺序不是62,65,78,这些问题感谢以前一个叫崔健的学员提出,最后通过查看源代码给他解释清楚,看本次培训学员当中有多少能看懂源码。LinkedHashSet按插入的顺序存储,那被存储对象的hashcode方法还有什么作用呢?学员想想!hashset集合比较两个对象是否相等,首先看hashcode方法是否相等,然后看equals方法是否相等。new 两个Student插入到HashSet中,看HashSetsize,实现hashcodeequals方法后再看size

    同一个对象可以在Vector中加入多次。往集合里面加元素,相当于集合里用一根绳子连接到了目标对象。往HashSet中却加不了多次的。

    14、说出ArrayList,Vector, LinkedList的存储性能和特性 

    ArrayListVector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。

    LinkedList也是线程不安全的,LinkedList提供了一些方法,使得LinkedList可以被当作堆栈和队列来使用。

    15Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别? 

    Set里的元素是不能重复的,元素重复与否是使用equals()方法进行判断的。

       equals()==方法决定引用值是否指向同一对象equals()在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值。

    16、你所知道的集合类都有哪些?主要方法? 

    最常用的集合类是 List MapList 的具体实现包括 ArrayList Vector,它们是可变大小的列表,比较适合构建、存储和操作任何类型对象的元素列表。 List 适用于按数值索引访问元素的情形。

    Map 提供了一个更通用的元素存储方法。 Map 集合类用于存储元素对(称作""""),其中每个键映射到一个值。

    ArrayList/VectoràList

                        àCollection

    HashSet/TreeSetàSet

    PropetiesàHashTable

    àMap

    Treemap/HashMap

    我记的不是方法名,而是思想,我知道它们都有增删改查的方法,但这些方法的具体名称,我记得不是很清楚,对于set,大概的方法是add,remove, contains;对于map,大概的方法就是put,removecontains等,因为,我只要在eclispe下按点操作符,很自然的这些方法就出来了。我记住的一些思想就是List类会有get(int index)这样的方法,因为它可以按顺序取元素,而set类中没有get(int index)这样的方法。Listset都可以迭代出所有元素,迭代时先要得到一个iterator对象,所以,setlist类都有一个iterator方法,用于返回那个iterator对象。map可以返回三个集合,一个是返回所有的key的集合,另外一个返回的是所有value的集合,再一个返回的keyvalue组合成的EntrySet对象的集合,map也有get方法,参数是key,返回值是key对应的value

    17、说出一些常用的类,包,接口,请各举5 

    要让人家感觉你对java ee开发很熟,所以,不能仅仅只列core java中的那些东西,要多列你在做ssh项目中涉及的那些东西。就写你最近写的那些程序中涉及的那些类。

    常用的类:BufferedReader  BufferedWriter  FileReader  FileWirter  String  Integer

    java.util.DateSystemClassList,HashMap

    常用的包:java.lang   java.io  java.util  java.sql ,javax.servlet,org.apache.strtuts.action,org.hibernate

    常用的接口:Remote  List  Map  Document  NodeList ,Servlet,HttpServletRequest,HttpServletResponse,Transaction(Hibernate)Session(Hibernate),HttpSession

    18heap(堆)stack(栈)有什么区别。 

    java的内存分为两类,一类是栈内存,一类是堆内存。栈内存是指程序进入一个方法时,会为这个方法单独分配一块私属存储空间,用于存储这个方法内部的局部变量,当这个方法结束时,分配给这个方法的栈会释放,这个栈中的变量也将随之释放。

    堆是与栈作用不同的内存,一般用于存放不放在当前方法栈中的那些数据,例如,使用new创建的对象都放在堆里,所以,它不会随方法的结束而消失。方法中的局部变量使用final修饰后,放在堆中,而不是栈中。

    19GC是什么? 为什么要有GC?   

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

    20、垃圾回收的优点和原理。并考虑2种回收机制。 

    Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制,Java中的对象不再有"作用域"的概念,只有对象的引用才有"作用域"。垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清楚和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。回收机制有分代复制垃圾回收和标记垃圾回收,增量垃圾回收。

    21、垃圾回收器的基本原理是什么?垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收? 

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

    22、用Java写出一个单例(Singleton)模式。

    Singleton模式主要作用是保证在Java应用程序中,一个类只有一个实例存在。

    示例代码:

    public class Singleton {

    private Singleton(){}

          //在自己内部定义自己的一个实例,注意这是private,只供内部调用

          private static Singleton instance = new Singleton();

          //这里提供了一个供外部访问本的静态方法,可以直接访问  

          public static Singleton getInstance() {

            return instance;   

          }

     }

     调用Singleton. getInstance()获取本类的实例,而没法使用关键字new

    23数据库三范式是什么?

    第一范式(1NF):字段具有原子性,不可再分。所有关系型数据库系统都满足第一范式)

    数据库表中的字段都是单一属性的,不可再分。例如,姓名字段,其中的姓和名必须作为一个整体,无法区分哪部分是姓,哪部分是名,如果要区分出姓和名,必须设计成两个独立的字段。

    第二范式(2NF):

    第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。

    要求数据库表中的每个实例或行必须可以被惟一地区分。通常需要为表加上一个列,以存储各个实例的惟一标识。这个惟一属性列被称为主关键字或主键。

    第二范式(2NF)要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。简而言之,第二范式就是非主属性非部分依赖于主关键字。

      

     第三范式的要求如下:

    满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。

    所以第三范式具有如下特征:
             1,每一列只有一个值
             2,每一行都能区分。
             3,每一个表都不包含其他表已经包含的非主关键字信息。

    例如,帖子表中只能出现发帖人的id,而不能出现发帖人的id,还同时出现发帖人姓名,否则,只要出现同一发帖人id的所有记录,它们中的姓名部分都必须严格保持一致,这就是数据冗余。

    24用一条SQL语句 查询出每门课都大于80分的学生姓名 

    表名:score

    name   kecheng   fenshu
    张三     语文       81
    张三     数学       75
    李四     语文       76
    李四     数学       90
    王五     语文       81
    王五     数学       100
    王五     英语       90

    提示:当百思不得其解时,尝试从反方向思考。

    答案:
    A: select distinct name from score  where  name not in (select distinct name from score where score<=80)

    25、你对Spring理解

    1.Spring实现了工厂模式的工厂类(在这里有必要解释清楚什么是工厂模式),这个类名为BeanFactory(实际上是一个接口),在程序中通常BeanFactory的子类ApplicationContextSpring相当于一个大的工厂类,在其配置文件中通过<bean>元素配置用于创建实例对象的类名和实例对象的属性。

    2. Spring提供了对IOC良好支持,IOC是一种编程思想,是一种架构艺术,利用这种思想可以很好地实现模块之间的解耦。IOC也称为DIDepency Injection),什么叫依赖注入呢?

    譬如,Class Programmer

    {

    Computer computer = null;

    public void code()

    {

    //Computer computer = new IBMComputer();

    //Computer computer = beanfacotry.getComputer();

    computer.write();

    }

    public void setComputer(Computer computer)

    {

    this.computer = computer;

    }

    }
    另外两种方式都由依赖,第一个直接依赖于目标类,第二个把依赖转移到工厂上,第三个彻底与目标和工厂解耦了。在spring的配置文件中配置片段如下:

    <bean id=”computer” class=”cn.itcast.interview.Computer”>

    </bean>

    <bean id=”programmer” class=”cn.itcast.interview.Programmer”>

    <property name=”computer”  ref=”computer”></property>

    </bean>

    3. Spring提供了对AOP技术的良好封装, AOP称为面向切面编程,就是系统中有很多各不相干的类的方法,在这些众多方法中要加入某种系统功能的代码,例如,加入日志,加入权限判断,加入异常处理,这种应用称为AOP。实现AOP功能采用的是代理技术,客户端程序不再调用目标,而调用代理类,代理类与目标类对外具有相同的方法声明,有两种方式可以实现相同的方法声明,一是实现相同的接口,二是作为目标的子类在,JDK中采用Proxy类产生动态代理的方式为某个接口生成实现类,如果要为某个类生成子类,则可以用CGLI B。在生成的代理类的方法中加入系统功能和调用目标类的相应方法,系统功能的代理以Advice对象进行提供,显然要创建出代理对象,至少需要目标类和Advice类。spring提供了这种支持,只需要在spring配置文件中配置这两个元素即可实现代理和aop功能,例如,

    <bean id=”proxy” type=”org.spring.framework.aop.ProxyBeanFactory”>

    <property name=”target” ref=””></property>

    <property name=”advisor” ref=””></property>

    </bean>

    26j2ee常用的设计模式?说明工厂模式。 

    总共23种,分为三大类:创建型,结构型,行为型

    我只记得其中常用的67种,分别是:

    创建型(工厂、工厂方法、抽象工厂、单例)

    结构型(包装、适配器,组合,代理)

    行为(观察者,模版,策略)

    然后再针对你熟悉的模式谈谈你的理解即可。   

    Java中的23种设计模式:

    Factory(工厂模式),      Builder(建造模式),       Factory Method(工厂方法模式),

    Prototype(原始模型模式),Singleton(单例模式)    Facade(门面模式),

    Adapter(适配器模式),    Bridge(桥梁模式),        Composite(合成模式),

    Decorator(装饰模式),    Flyweight(享元模式),     Proxy(代理模式),

    Command(命令模式),      Interpreter(解释器模式), Visitor(访问者模式),

    Iterator(迭代子模式),   Mediator(调停者模式),    Memento(备忘录模式),

    Observer(观察者模式),   State(状态模式),         Strategy(策略模式),

    Template Method(模板方法模式), Chain Of Responsibleity(责任链模式)

    工厂模式:工厂模式是一种经常被使用到的模式,根据工厂模式实现的类可以根据提供的数据生成一组类中某一个类的实例,通常这一组类有一个公共的抽象父类并且实现了相同的方法,但是这些方法针对不同的数据进行了不同的操作。首先需要定义一个基类,该类的子类通过不同的方法实现了基类中的方法。然后需要定义一个工厂类,工厂类可以根据条件生成不同的子类实例。当得到子类的实例后,开发人员可以调用基类中的方法而不必考虑到底返回的是哪一个子类的实例。

    27、开发中都用到了哪些设计模式?用在什么场合? 

    每个模式都描述了一个在我们的环境中不断出现的问题,然后描述了该问题的解决方案的核心。通过这种方式,你可以无数次地使用那些已有的解决方案,无需在重复相同的工作。主要用到了MVC的设计模式。用来开发JSP/Servlet或者J2EE的相关应用。简单工厂模式、单例模式等。

  • 相关阅读:
    【MySQL】(三)文件
    【MySQL】(二)InnoDB存储引擎
    Linux Shell脚本编程-信号捕获
    Linux Shell脚本编程-数组和字符串处理
    Linux Shell脚本编程-函数
    Linux Shell脚本编程-语句控制
    Linux Shell脚本编程-基础2
    Linux Shell脚本编程-基础1
    Awk
    Sed
  • 原文地址:https://www.cnblogs.com/dreamboy/p/11752752.html
Copyright © 2020-2023  润新知