学习过程总结

本文详细介绍了Java编程的基础知识,包括面向对象特性、异常处理、集合框架、多线程以及内存管理。特别强调了Java中的构造器、抽象类与接口的区别、异常的处理机制、String与StringBuffer的区别、线程同步与异步的概念,以及HashMap与Hashtable的差异。此外,还探讨了内部类、匿名内部类和线程安全问题。通过对各种面试题的解答,揭示了Java编程的核心概念和最佳实践。
摘要由CSDN通过智能技术生成

我所学习的

java

Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程。
Java具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点 [2] 。Java可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等

面试题

  1. Java基础部分
      基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语法,集合的语法,io 的语法,虚拟机方面的语法。
    1、一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制?
      可以有多个类,但只能有一个public的类,并且public的类名必须与文件名相一致。
    2、Java有没有goto?
    java中的保留字,现在没有在java中使用。
    3、说说&和&&的区别。
      &和&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都为true时,整个运算结果才为true,否则,只要有一方为false,则结果为false。
      &&还具有短路的功能,即如果第一个表达式为false,则不再计算第二个表达式,例如,对于if(str != null && !str.equals(“”))表达式,当str为null时,后面的表达式不会执行,所以不会出现NullPointerException如果将&&改为&,则会抛出NullPointerException异常。If(x33 & ++y>0) y会增长,If(x33 && ++y>0)不会增长
      &还可以用作位运算符,当&操作符两边的表达式不是boolean类型时,&表示按位与操作,我们通常使用0x0f来与一个整数进行&运算,来获取该整数的最低4个bit位,例如,0x31 & 0x0f的结果为0x01。
      备注:这道题先说两者的共同点,再说出&&和&的特殊之处,并列举一些经典的例子来表明自己理解透彻深入、实际经验丰富。
    4、在JAVA中如何跳出当前的多重嵌套循环?   
    5、switch语句能否作用在byte上,能否作用在long上,能否作用在String上?
      在switch(expr1)中,expr1只能是一个整数表达式或者枚举常量(更大字体),整数表达式可以是int基本类型或Integer包装类型,由于,byte,short,char都可以隐含转换为int,所以,这些类型以及这些类型的包装类型也是可以的。显然,long和String类型都不符合switch的语法规定,并且不能被隐式转换成int类型,所以,它们不能作用于swtich语句中。
    6、short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?
      对于short s1 = 1; s1 = s1 + 1; 由于s1+1运算时会自动提升表达式的类型,所以结果是int型,再赋值给short类型s1时,编译器将报告需要强制转换类型的错误。
      对于short s1 = 1; s1 += 1;由于 += 是java语言规定的运算符,java编译器会对它进行特殊处理,因此可以正确编译。
    7、char型变量中能不能存贮一个中文汉字?为什么?
      char型变量是用来存储Unicode编码的字符的,unicode编码字符集中包含了汉字,所以,char型变量中当然可以存储汉字啦。不过,如果某个特殊的汉字没有被包含在unicode编码字符集中,那么,这个char型变量中就不能存储这个特殊汉字。补充说明:unicode编码占用两个字节,所以,char类型的变量也是占用两个字节。
      备注:后面一部分回答虽然不是在正面回答题目,但是,为了展现自己的学识和表现自己对问题理解的透彻深入,可以回答一些相关的知识,做到知无不言,言无不尽。
    8、用最有效率的方法算出2乘以8等於几?
      2 << 3,
      因为将一个数左移n位,就相当于乘以了2的n次方,那么,一个数乘以8只要将其左移3位即可,而位运算cpu直接支持的,效率最高,所以,2乘以8等於几的最效率的方法是2 << 3。
     
    10、使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?
      只是引用不能变,但是引用所指向的对象是可以变化的。
      使用final关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的。例如,对于如下语句:
       final?StringBuffer?a=new?StringBuffer(“immutable”);执行如下语句将报告编译期错误:
      a=new?StringBuffer("");但是,执行如下语句则可以通过编译:
      a.append("?broken!"); 
      有人在定义方法的参数时,可能想采用如下形式来阻止方法内部修改传进来的参数对象:
       public void method(final StringBuffer param){

}
  实际上,这是办不到的,在该方法内部仍然可以增加如下代码来修改参数对象:
   param.append(“a”);
11、"=="和equals方法究竟有什么区别?
   ==是比较运算符
equals是Object的方法

 相同之处:
    如果不重写equals方法:equals方法和==都可以判断两个引用是否执行同一个对象
 不同之处:
    不同之处1:(是否可以被重写)
		== 如果判断引用数据类型  只能判断两个引用是否为同一个对象
		equals方法  可以被重写 
   	不同之处2:(是否可以操作基本数据类型)
  		==  可以操作基本数据类型   用于判断基本数据类型的值是否相同

12、静态变量和实例变量的区别?
  静态变量:被static修饰的成员变量
实例变量:没有被static修饰的成员变量
相同之处:都是成员变量 都有被对象来调用
不同之处:
1 修饰符不同
是否被static修饰
2 调用不同
静态变量 是属于类的:不但可以被对象调用 还可以被类直接调用
实例变量 是属于对象的: 只能被对象调用
3
静态变量 是共享数据 所有的对象公用一个
实例变量 每个对象都拥有属于自己的实例变量
4 加载的时间不同
静态变量在类加载时加载
实例变量 在对象创建时才加载
13、是否可以从一个static方法内部发出对非static方法的调用?
不能:加载的时间不同
14、Integer与int的区别
  可以通过自动装箱和自动拆箱 互相转换

1  类型不同
   int是基本数据类型   
   integer是引用数据类型  
2  默认值不同
   integer类型的成员变量默认值时null
   int默认值是0
3  占内存不同
   int固定占4个字节
   integer因为有方法和属性  所占内存要大

15、Math.round(11.5)等於多少? Math.round(-11.5)等於多少?
  Math中几个容易混淆取近似值的方法
floor(double) 取小于等于参数的最大整数
ceil(double) 取大于等于参数的最小整数
round(double) 正宗的四舍五入
rint(double) 四舍六入 五取偶
16、下面的代码有什么不妥之处?

  1. if(username.equals(“zxx”){}
    1. int x = 1;
      return x==1?true:false;
      17、请说出作用域public,private,protected,以及不写时的区别
        private: 私有的 当前类
      不写 默认的 本包
      protected 受保护的 本包和其他包的子类
      public 公共的 整个项目
      18、Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?
        Overload是重载的意思,Override是覆盖的意思,也就是重写。
        重载Overload表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数或类型不同)。
        重写Override表示子类中的方法可以与父类中的某个方法的名称和参数完全相同,通过子类创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于把父类中定义的那个完全相同的方法给覆盖了,这也是面向对象编程的多态性的一种表现。子类覆盖父类的方法时,只能比父类抛出更少的异常,或者是抛出父类抛出的异常的子异常,因为子类可以解决父类的一些问题,不能比父类有更多的问题。子类方法的访问权限只能比父类的更大,不能更小。如果父类的方法是private类型,那么,子类则不存在覆盖的限制,相当于子类中增加了一个全新的方法。
        至于Overloaded的方法是否可以改变返回值的类型这个问题,要看你倒底想问什么呢?这个题目很模糊。如果几个Overloaded的方法的参数列表不一样,它们的返回者类型当然也可以不一样。但我估计你想问的问题是:如果两个方法的参数列表完全一样,是否可以让它们的返回值不同来实现重载Overload。这是不行的,我们可以用反证法来说明这个问题,因为我们有时候调用一个方法时也可以不定义返回结果变量,即不要关心其返回结果,例如,我们调用map.remove(key)方法时,虽然remove方法有返回值,但是我们通常都不会定义接收返回结果的变量,这时候假设该类中有两个名称和参数列表完全相同的方法,仅仅是返回类型不同,java就无法确定编程者倒底是想调用哪个方法了,因为它无法通过返回结果类型来判断。
      override可以翻译为覆盖,从字面就可以知道,它是覆盖了一个方法并且对其重写,以求达到不同的作用。对我们来说最熟悉的覆盖就是对接口方法的实现,在接口中一般只是对方法进行了声明,而我们在实现时,就需要实现接口声明的所有方法。除了这个典型的用法以外,我们在继承中也可能会在子类覆盖父类中的方法。在覆盖要注意以下的几点:
      1、覆盖的方法的标志必须要和被覆盖的方法的标志完全匹配,才能达到覆盖的效果;
      2、覆盖的方法的返回值必须和被覆盖的方法的返回一致;
      3、覆盖的方法所抛出的异常必须和被覆盖方法的所抛出的异常一致,或者是其子类;
      4、被覆盖的方法不能为private,否则在其子类中只是新定义了一个方法,并没有对其进行覆盖。
      overload对我们来说可能比较熟悉,可以翻译为重载,它是指我们可以定义一些名称相同的方法,通过定义不同的输入参数来区分这些方法,然后再调用时,VM就会根据不同的参数样式,来选择合适的方法执行。在使用重载要注意以下的几点:
      1、在使用重载时只能通过不同的参数样式。例如,不同的参数类型,不同的参数个数,不同的参数顺序(当然,同一方法内的几个参数类型必须不一样,例如可以是fun(int,float),但是不能为fun(int,int));
      2、不能通过访问权限、返回类型、抛出的异常进行重载;
      3、方法的异常类型和数目不会对重载造成影响;
      4、对于继承来说,如果某一方法在父类中是访问权限是priavte,那么就不能在子类对其进行重载,如果定义的话,也只是定义了一个新方法,而不会达到重载的效果。
      19、构造器Constructor是否可被override?
        构造器Constructor不能被继承,因此不能重写Override,但可以被重载Overload。
      20、接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承具体类(concrete class)? 抽象类中是否可以有静态的main方法?
        接口可以继承接口。抽象类可以实现(implements)接口,抽象类是否可继承具体类。抽象类中可以有静态的main方法。
        备注:只要明白了接口和抽象类的本质和作用,这些问题都很好回答,你想想,如果你是java语言的设计者,你是否会提供这样的支持,如果不提供的话,有什么理由吗?如果你没有道理不提供,那答案就是肯定的了。
        只有记住抽象类与普通类的唯一区别就是不能创建实例对象和允许有abstract方法。
      java只支持类与类的单继承 但支持接口与接口的多继承
      java支持一个类继承父类时 同时实现多个接口
      抽象类中可以有抽象方法 但一个类一旦有抽象方法就必须是抽象类
      21、写clone()方法时,通常都有一行代码,是什么?
        clone 有缺省行为,super.clone();
      因为首先要把父类中的成员复制到位,
      然后才是复制自己的成员。
      Zi zi=new Zi();
      zi.a=1;
      Zi zi2=zi.clone();
      22、面向对象的特征有哪些方面
        计算机软件系统是现实生活中的业务在计算机中的映射,而现实生活中的业务其实就是一个个对象协作的过程。面向对象编程就是按现实业务一样的方式将程序代码按一个个对象进行组织和编写,让计算机系统能够识别和理解用对象方式组织和编写的程序代码,这样就可以把现实生活中的业务对象映射到计算机系统中。
        面向对象的编程语言有,吗 等4个主要的特征。
        1封装:方法:对象:类:
        封装是保证软件部件具有优良的模块性的基础,
      封装的目标就是要实现软件部件的“高内聚、低耦合”,
      防止程序相互依赖性而带来的变动影响。在面向对象的编程语言中,对象是封装的最基本单位,面向对象的封装比传统语言的封装更为清晰、更为有力。面向对象的封装就是把描述一个对象的属性和行为的代码封装在一个“模块”中,也就是一个类中,属性用变量定义,行为用方法进行定义,方法可以直接访问同一个对象中的属性。通常情况下,只要记住让变量和访问这个变量的方法放在一起,将一个类中的成员变量全部定义成私有的,只有这个类自己的方法才可以访问到这些成员变量,这就基本上实现对象的封装,就很容易找出要分配到这个类上的方法了,就基本上算是会面向对象的编程了。把握一个原则:把对同一事物进行操作的方法和相关的方法放在同一个类中,把方法和它操作的数据放在同一个类中。
        例如,人要在黑板上画圆,这一共涉及三个对象:人、黑板、圆,画圆的方法要分配给哪个对象呢?由于画圆需要使用到圆心和半径,圆心和半径显然是圆的属性,如果将它们在类中定义成了私有的成员变量,那么,画圆的方法必须分配给圆,它才能访问到圆心和半径这两个属性,人以后只是调用圆的画圆方法、表示给圆发给消息而已,画圆这个方法不应该分配在人这个对象上,这就是面向对象的封装性,即将对象封装成一个高度自治和相对封闭的个体,对象状态(属性)由这个对象自己的行为(方法)来读取和改变。一个更便于理解的例子就是,司机将火车刹住了,刹车的动作是分配给司机,还是分配给火车,显然,应该分配给火车,因为司机自身是不可能有那么大的力气将一个火车给停下来的,只有火车自己才能完成这一动作,火车需要调用内部的离合器和刹车片等多个器件协作才能完成刹车这个动作,司机刹车的过程只是给火车发了一个消息,通知火车要执行刹车动作而已。
        
        抽象:
        抽象就是找出一些事物的相似和共性之处,
      然后将这些事物归为一个类,这个类只考虑这些事物的相似和共性之处,
      并且会忽略与当前主题和目标无关的那些方面,
      将注意力集中在与当前目标有关的方面。
      例如,看到一只蚂蚁和大象,你能够想象出它们的相同之处,
      那就是抽象。抽象包括行为抽象和状态抽象两个方面。
      例如,定义一个Person类,如下:
        class Person{
         String name;
         int age;
        }
        人本来是很复杂的事物,有很多方面,但因为当前系统只需要了解人的姓名和年龄,所以上面定义的类中只包含姓名和年龄这两个属性,这就是一种抽像,使用抽象可以避免考虑一些与目标无关的细节。我对抽象的理解就是不要用显微镜去看一个事物的所有方面,这样涉及的内容就太多了,而是要善于划分问题的边界,当前系统需要什么,就只考虑什么。
        
        继承:
        在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,
      把这个已经存在的类所定义的内容作为自己的内容,并可以加入若干新的内容,
      或修改原来的方法使之更适合特殊的需要,这就是继承。
      继承是子类自动共享父类数据和方法的机制,这是类之间的一种关系,
      提高了软件的可重用性和可扩展性。
        
        多态:
        多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。多态性增强了软件的灵活性和扩展性。例如,下面代码中的UserDao是一个接口,它定义引用变量userDao指向的实例对象由daofactory.getDao()在执行的时候返回,有时候指向的是UserJdbcDao这个实现,有时候指向的是UserHibernateDao这个实现,这样,不用修改源代码,就可以改变userDao指向的具体类实现,从而导致userDao.insertUser()方法调用的具体代码也随之改变,即有时候调用的是UserJdbcDao的insertUser方法,有时候调用的是UserHibernateDao的insertUser方法:
        UserDao userDao = daofactory.getDao();
        userDao.insertUser(user);
        比喻:人吃饭,你看到的是左手,还是右手?

23、java中实现多态的机制是什么?
  靠的是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象,
而程序调用的方法在运行期才动态绑定,就
是引用变量所指向的具体实例对象的方法,
也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。
public static void hehe(Fu fu){
fu.hai();
}

24、abstract class和interface有什么区别?
  含有abstract修饰符的class即为抽象类,abstract 类不能创建的实例对象。
含有abstract方法的类必须定义为abstract class,
abstract class类中的方法不必是抽象的。
abstract class类中定义抽象方法必须在具体(Concrete)子类中实现,所以,
不能有抽象构造方法或抽象静态方法。
如果的子类没有实现抽象父类中的所有抽象方法,
那么子类也必须定义为abstract类型。
  接口(interface)可以说成是抽象类的一种特例,
接口中的所有方法都必须是抽象的。接口中的方法定义默认为public abstract类型,
接口中的成员变量类型默认为public static final。
  下面比较一下两者的语法区别:
1.抽象类可以有构造方法,接口中不能有构造方法。
abstract class Fu{
int c=11;
public void ehhe(){}
public abstract hai();
Fu(){}
}
class Zi extends Fu{
public hai(){}
}
new Zi(); super();//抽象父类中定义构造方法 不是为了创建父类对象 而是为了创建子类对象
2.抽象类中可以有普通成员变量 ,接口中没有普通成员变量
3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。
4. 抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。
5. 抽象类中可以包含静态方法,接口中不能包含静态方法
6. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。
7. 一个类可以实现多个接口,但只能继承一个抽象类。
public abstract hehe();

25、abstract的method是否可同时是static,
是否可同时是native,
是否可同时是synchronized?
  abstract的method 不可以是static的,因为抽象的方法是要被子类实现的,
而static与子类扯不上关系!
  native方法表示该方法要用另外一种依赖平台的编程语言实现的,
不存在着被子类实现的问题,所以,它也不能是抽象的,
不能与abstract混用。例如,FileOutputSteam类要硬件打交道,
底层的实现用的是操作系统相关的api实现,例如,在windows用c语言实现的,
所以,查看jdk 的源代码,可以发现FileOutputStream的open方法的定义如下:
  private native void open(String name) throws FileNotFoundException;
  如果我们要用java调用别人写的c语言函数,
我们是无法直接调用的,我们需要按照java的要求写一个c语言的函数,又我们的这个c语言函数去调用别人的c语言函数。由于我们的c语言函数是按java的要求来写的,我们这个c语言函数就可以与java对接上,java那边的对接方式就是定义出与我们这个c函数相对应的方法,java中对应的方法不需要写具体的代码,但需要在前面声明native。
  关于synchronized与abstract合用的问题,我觉得也不行,
因为在我几年的学习和开发中,从来没见到过这种情况,
并且我觉得synchronized应该是作用在一个具体的方法上才有意义。
而且,方法上的synchronized同步所使用的同步锁对象是this,而抽象方法上无法确定this是什么。
26、什么是内部类?Static Nested Class 和 Inner Class的不同。
27、内部类可以引用它的包含类的成员吗?有没有什么限制?   
28、Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)?
  可以继承其他类或实现其他接口。不仅是可以,而是必须!
29、super.getClass()方法调用
下面程序的输出结果是多少?
import java.util.Date;
public class Test extends Date{
public static void main(String[] args) {
new Test().test();
}
public void test(){
System.out.println(super.getClass().getName());
}
}

30、String是最基本的数据类型吗?
基本数据类型包括byte、int、char、long、float、double、boolean和short。
java.lang.String类是final类型的,因此不可以继承这个类、
不能修改这个类。为了提高效率节省空间,我们应该用StringBuffer类
String s=new String(“1111”);//创建字符串对象有两种方式:"" new
1 通过“”在字符串常量池中创建一个字符串1111
2 在内存中通过new 创建一个第一步的字符串的副本对象
31、String s=“Hello”;s=s+“world!”;
这两行代码执行后,原始的String对象中的内容到底变了没有?
String:字符串常量:字符串不可变序列:字符串对象一旦创建 字符序列是无法更改的
32、是否可以继承String类?
String类是final类故不可以继承。
33、String s = new String(“xyz”);创建了几个String Object?
2 个 通过“”在字符串常量池中创建一个xyz
通过new创建一个"xyz"的副本字符串对象
34、String 和StringBuffer的区别StringBuilder
String是字符串常量
StringBuffer和StringBuilder是字符串缓冲区
相同之处:都可以来表示字符串序列
都是final类 不能被继承
String与StringBuilder和StringBuffer不同之处:
String是字符串常量:对象一旦创建 字符序列不能更改
StringBuilder和StringBuffer是字符串缓冲区:字符序列可以更改
StringBuilder与StringBuffer相同之处:
1 api兼容(两个类的方法属性完全相同)
2 都是字符串缓冲区 字符串可变序列
StringBuilder与StringBuffer不同之处:
1 版本不同:
StringBuffer是1.0版本 StringBuffer是1.5
2 StringBuffer线程安全效率低
StringBuilder线程不安全效率高
35、如何把一段逗号分割的字符串转换成一个数组?
String s=“119191,111,2,3,3,4,5,389849”
1:split方法
2:indexof和substring方法组合
ArrayList list=new ArrayList<>();
int index1=0;
int index2;
while(true){
index2=s.indexOf(’,’,index1);//从index1处开始 获取第一次出现,的位置
if(index2==-1){
list.add(s.substring(index1));
break;
}
list.add(s.substring(index1,index2));
index1=index2+1;
}
  
36、数组有没有length()这个方法? String有没有length()这个方法?
数组没有length()这个方法,有length的属性。String有有length()这个方法。
37、下面这条语句一共创建了多少个对象:String s=“a”+“b”+“c”+“d”;
7个对象
38、try {}里有一个return语句,那么紧跟在这个try后的finally
{}里的code会不会被执行,什么时候被执行,在return前还是后?
40、final, finally, finalize的区别。
  final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
内部类要访问局部变量,局部变量必须定义成final类型,例如,一段代码……
finally是异常处理语句结构的一部分,表示总是执行。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。JVM不保证此方法总被调用

41、运行时异常与编译时异常?
相同之处:都是throwable和exception的子类
运行时异常:如果是RuntimeException的子类的exception
编译时异常:不是RuntimeException的子类的exception
不同之处:1 是否继承了RuntimeException
2 编译时异常 如果不捕获 必须在方法声明上显式抛出
运行时异常 如果不捕获 默认抛出
3 编译时异常只有在特定情况下出现 出现频率低
运行时异常 出现频率高

 public  void hehe(String s)throws  parseexception{
     int leng=s.length();
	 //try{
	   new simpledateformat().parse(str);
	 //}
	 //catch(){} 
 }

42、error和exception有什么区别?
error和exception都是throwable的子类
error表示严重的异常情况,一般是虚拟机出现异常情况,
如内存溢出 文件找不到 语法错误…
exception是可以处理的异常情况
1 异常程度不同
2 是否可以通过代码逻辑来处理
error不能通过代码逻辑来处理 只能修改代码
exception 可以通过trycatch进行捕获处理 程序可以继续执行

43、Java中的异常处理机制的简单原理和应用。
虚拟机会把与异常有关的所有内容(异常类型,异常原因,异常位置) 封装成对象
处理异常情况 可以通过捕获机制或者抛出机制
捕获机制:通过try catch来处理异常 一但出现异常就走对应的catch代码块
如果产生的异常被捕获 程序会继续执行
抛出机制:在方法声明上通过throws 来抛出指定类型的异常
如果产生异常对象 就把异常对象抛给当前方法的调用者去处理

44、请写出你最常见到的5个runtime exception。
NullPointerException
indexoutofboundsexception
classnotfoundexception
ArithmeticException
classcaseexception
numberformatexception

编译时异常  
 parseexception:  simpledateformat.parse  
 UnsupportedEncodingException: new String(new byte[]{},"ehhee");
 ioexception: new fileinputtsream("xxxx")
 EOFException: bufferedinputstream.read()
 sqlexception:connection.preparedstatement(sql)
 IllegalAccessException:field.get(obj)

45、JAVA语言如何进行异常处理,
关键字:throws,throw,try,catch,finally分别代表什么意义?
在try块中可以抛出异常吗?
throws和throw的区别
相同之处:都是用于处理异常
不同之处:1 位置不同:throws用于方法声明上 throw 方法体中
2 后面跟的内容不同:throws后面跟的是多个异常类型
throw后面跟一个异常对象
3 作用不同:throws用于在方法声明上声明当前方法可能产生
的异常情况,一旦产生异常情况 把异常对象抛给调用者
throw表示程序出现了指定的异常情况
if(){
throw new MyException();
}

46、java中有几种方法可以实现一个线程?
synchronized用什么关键字修饰同步方法?
非静态的同步方法的锁对象是this
静态的同步方法的锁对象是当前类的字节码文件对象
47、sleep() 和 wait() 有什么区别?
相同之处:用在多线程中的两个方法 可以让线程停止
1 所属对象不同:Thread类sleep() 线程对象的方法
Object类wait()是锁对象的方法
2 是否释放锁对象:sleep方法不释放锁对象
wait是否锁对象
3 使用的位置不同:
sleep方法可以在线程任意位置使用
wait只能在同步代码块或者同步方法中使用
4 结束停止或者休眠的方式不同:
sleep只有当线程休眠时间到期 就自动停止休眠
wait时 当前线程会一直处于等待状态,
除非别的线程调用了锁对象的notify或者notifyall方法

48、同步和异步有何异同,在什么情况下分别使用他们?举例说明。
如果数据将在线程间共享。
例如正在写的数据以后可能被另一个线程读到,
或者正在读的数据可能已经被另一个线程写过了,
那么这些数据就是共享数据,必须进行同步存取。

当应用程序在对象上调用了一个需要花费很长时间来执行的方法,
并且不希望让程序等待方法的返回时,就应该使用异步编程,
在很多情况下采用异步途径往往更有效率。 

多个线程操作共享数据时  出现前后数据不一致的现象----线程安全问题
解决线程安全问题---通过同步代码块/同步方法

50、多线程有几种实现方法?同步有几种实现方法?
多线程有两种实现方法,分别是继承Thread类与实现Runnable接口
同步的实现方面有两种,分别是synchronized,wait与notify
wait():使一个线程处于等待状态,并且释放所持有的对象的lock。
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常。
notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
Allnotity():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。

-----  怎么实现:三个线程打印大写 小写  数字  
			   按顺序执行:wait与notify 

51、启动一个线程是用run()还是start()? .
只有当线程的statrt方法被调用 虚拟机才会为此线程对象开辟执行空间
虚拟机会自动调用此线程的run方法

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

52、当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
分几种情况:
1.其他方法前是否加了synchronized关键字,如果没加,则能。
2.如果这个方法内部调用了wait,则可以进入其他synchronized方法。
3.如果其他个方法都加了synchronized关键字,并且内部没有调用wait,则不能。
4.如果其他方法是static,它用的同步锁是当前类的字节码,与非静态的方法不能同步,因为非静态的方法用的是this。

53、线程的基本概念、线程的基本状态以及状态之间的关系

54、简述synchronized和java.util.concurrent.locks.Lock的异同 ?
参考:http://blog.sina.com.cn/s/blog_613531810102x1wd.html
55、设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。
写出程序。
57、介绍Collection框架的结构
一个图:即下边这个图
一个类:Collections类
六个接口:
Collection接口
Set接口
List接口
Map接口
Iterator接口(统一的遍历 容器内的值)
Comparable接口

Student具有可比较性:
1 Student类实现接口Comparable接口
2 为Student类写一个比较器:比较器实现接口Comparator

答:随意发挥题,天南海北谁便谈,只要让别觉得你知识渊博,理解透彻即可。

58、Collection框架中实现比较要实现什么接口 comparable/comparator

59、ArrayList和Vector的区别
答:
这两个类都实现了List接口(List接口继承了Collection接口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当于一种动态的数组,我们以后可以按位置索引号取出某个元素,,并且其中的数据是允许重复的,这是HashSet之类的集合的最大不同处,HashSet之类的集合不可以按索引号去检索其中的元素,也不允许有重复的元素(本来题目问的与hashset没有任何关系,但为了说清楚ArrayList与Vector的功能,我们使用对比方式,更有利于说明问题)。

接着才说ArrayList与Vector的区别,这主要包括两个方面:. (1)同步性:
Vector是线程安全的,也就是说是它的方法之间是线程同步的,而ArrayList是线程序不安全的,它的方法之间是线程不同步的。如果只有一个线程会访问到集合,那最好是使用ArrayList,因为它不考虑线程安全,效率会高些;如果有多个线程会访问到集合,那最好是使用Vector,因为不需要我们自己再去考虑和编写线程安全的代码。

备注:对于Vector&ArrayList、Hashtable&HashMap,要记住线程安全的问题,记住Vector与Hashtable是旧的,是java一诞生就提供了的,它们是线程安全的,ArrayList与HashMap是java2时才提供的,它们是线程不安全的。所以,我们讲课时先讲老的。(2)数据增长:
ArrayList与Vector都有一个初始的容量大小,当存储进它们里面的元素的个数超过了容量时,就需要增加ArrayList与Vector的存储空间,每次要增加存储空间时,不是只增加一个存储单元,而是增加多个存储单元,每次增加的存储单元的个数在内存空间利用与程序效率之间要取得一定的平衡。Vector默认增长为原来两倍,而ArrayList的增长策略在文档中没有明确规定(从源代码看到的是增长为原来的1.5倍)。ArrayList与Vector都可以设置初始的空间大小,Vector还可以设置增长的空间大小,而ArrayList没有提供设置增长空间的方法。
总结:即Vector增长原来的一倍,ArrayList增加原来的0.5倍。
60、HashMap和Hashtable的区别
(条理上还需要整理,也是先说相同点,再说不同点)
HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,在只有一个线程访问的情况下,效率要高于Hashtable。
HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。
HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。
Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。
最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步。
Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。

就HashMap与HashTable主要从三方面来说。 一
.历史原因:Hashtable是基于陈旧的Dictionary类的,
HashMap是Java 1.2引进的Map接口的一个实现 二.同步性:Hashtable是线程安全的,
也就是说是同步的,而HashMap是线程序不安全的,不是同步的 
三.值:只有HashMap可以让你将空值作为一个表的条目的key或value 

61、List 和 Map 区别?
一个是存储单列数据的集合,另一个是存储键和值这样的双列数据的集合,
List中存储的数据是有顺序,并且允许重复;Map中存储的数据是没有顺序的,
其键是不能重复的,它的值是可以有重复的。
62、List, Set, Map是否继承自Collection接口?
List,Set是,Map不是

63、List、Map、Set三个接口,存取元素时,各有什么特点?
首先,List与Set具有相似性,它们都是单列元素的集合,
所以,它们有一个功共同的父接口,叫Collection。
Set里面不允许有重复的元素,所谓重复,即不能有两个相等(注意,不是仅仅是相同)的对象 ,即假设Set集合中有了一个A对象,现在我要向Set集合再存入一个B对象,但B对象与A对象equals相等,则B对象存储不进去,所以,Set集合的add方法有一个boolean的返回值,当集合中没有某个元素,此时add方法可成功加入该元素时,则返回true,当集合含有与某个元素equals相等的元素时,此时add方法无法加入该元素,返回结果为false。Set取元素时,没法说取第几个,只能以Iterator接口取得所有的元素,再逐一遍历各个元素。
List表示有先后顺序的集合, 注意,不是那种按年龄、按大小、按价格之类的排序。当我们多次调用add(Obj e)方法时,每次加入的对象就像火车站买票有排队顺序一样,按先来后到的顺序排序。有时候,也可以插队,即调用add(int index,Obj e)方法,就可以指定当前对象在集合中的存放位置。一个对象可以被反复存储进List中,每调用一次add方法,这个对象就被插入进集合中一次,其实,并不是把这个对象本身存储进了集合中,而是在集合中用一个索引变量指向这个对象,当这个对象被add多次时,即相当于集合中有多个索引指向了这个对象,如图x所示。List除了可以以Iterator接口取得所有的元素,再逐一遍历各个元素之外,还可以调用get(index i)来明确说明取第几个。
Map与List和Set不同,它是双列的集合,其中有put方法,定义如下:put(obj key,obj value),每次存储时,要存储一对key/value,不能存储重复的key,这个重复的规则也是按equals比较相等。取则可以根据key获得相应的value,即get(Object key)返回值为key 所对应的value。另外,也可以获得所有的key的结合,还可以获得所有的value的结合,还可以获得key和value组合成的Map.Entry对象的集合。

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

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

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

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

LinkedList也是线程不安全的,LinkedList提供了一些方法,使得LinkedList可以被当作堆栈和队列来使用。
65、去掉一个Vector集合中重复的元素
Vector newVector = new Vector();
For (int i=0;i<vector.size();i++)
{
  Object obj = vector.get(i);
if(!newVector.contains(obj);
newVector.add(obj);
}
还有一种简单的方式,HashSet set = new HashSet(vector);
66、Collection 和 Collections的区别。

67、Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用还是equals()? 它们有何区别?
Set里的元素是不能重复的,元素重复与否是使用equals()方法进行判断的。
equals()和
方法决定引用值是否指向同一对象equals()在类中被覆盖,
为的是当两个分离的对象的内容和类型相配的话,返回真值。

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

69、两个对象值相同(x.equals(y) == true),
但却可有不同的hash code,这句话对不对?
对。
如果对象要保存在HashSet或HashMap中,它们的equals相等,那么,它们的hashcode值就必须相等。
如果不是要保存在HashSet或HashMap,则与hashcode没有什么关系了,这时候hashcode不等是可以的,例如arrayList存储的对象就不用实现hashcode,当然,我们没有理由不实现,通常都会去实现的。
70、TreeSet里面放对象,如果同时放入了父类和子类的实例对象,
那比较时使用的是父类的compareTo方法,还是使用的子类的compareTo方法,
还是抛异常!
(应该是没有针对问题的确切的答案,当前的add方法放入的是哪个对象,
就调用哪个对象的compareTo方法,至于这个compareTo方法怎么做,
就看当前这个对象的类中是如何编写这个方法的)
-----集合框架 类层次结构
----Collection 单列集合的顶层父类
—list
—ArrayList
—Vector
—LinkedList
—set
—hashset
—treeset

 ----Map         双列集合的顶层父类
      ---hashmap
	  ---hashtable

-----集合框架 类的特点
----
-----集合框架 遍历方式
—list:4个
—set :3个
—map : 2个

71、说出一些常用的类,包,接口,请各举5个
要让人家感觉你对java ee开发很熟,
所以,不能仅仅只列core java中的那些东西,
要多列你在做ssh项目中涉及的那些东西。
就写你最近写的那些程序中涉及的那些类。

常用的类:BufferedReader  BufferedWriter  FileReader  FileWirter  String  Integer 
java.util.Date,System,Class,List,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

72、java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?
字节流,字符流。字节流继承于InputStream OutputStream,字符流继承于InputStreamReader OutputStreamWriter。在java.io包中还有许多其他的流,主要是为了提高性能和使用方便。
73、字节流与字符流的区别

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

例如,在web开发中,如果对象被保存在了Session中,tomcat在重启时要把Session对象序列化到硬盘,这个对象就必须实现Serializable接口。如果对象要经过分布式系统进行网络传输或通过rmi等远程调用,这就需要在网络上传输对象,被传输的对象就必须实现Serializable接口。

75、描述一下JVM加载class文件的原理机制?
JVM中类的装载是由ClassLoader和它的子类来实现的,Java ClassLoader
是一个重要的Java运行时系统组件。它负责在运行时查找和装入类文件的类。

76、heap和stack有什么区别。
java的内存分为两类,一类是栈内存,一类是堆内存。
栈内存是指程序进入一个方法时,会为这个方法单独分配一块私属存储空间,
用于存储这个方法内部的局部变量,当这个方法结束时,
分配给这个方法的栈会释放,这个栈中的变量也将随之释放。
堆是与栈作用不同的内存,一般用于存放不放在当前方法栈中的那些数据,
例如,使用new创建的对象都放在堆里,所以,它不会随方法的结束而消失。
方法中的局部变量使用final修饰后,放在堆中,而不是栈中。

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

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

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

81、java中会存在内存泄漏吗,请简单描述。
存在
描述
82 线程面试题:线程线程面试题Java多线程面试题及答案
83 集合必会14问集合常见面试题
84:sql面试题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值