Java面试题03

Java面试题(03

一、一个“.java”源文件中是否能够包含多个类(不是内部类)?有什么限制?

能够包含多个类。只容许有一个公共类,且公共类名与Java源文件名相同。java

二、switch可否做用在byte上,可否做用在long上,可否做用在String上?

基本类型的包装类(如:Character、Byte、Short、Integer)linux

switch可做用于char byte short int
switch可做用于char byte short int对应的包装类
switch不可做用于long double float boolean,包括他们的包装类
switch中能够是字符串类型,String(jdk1.7以后才能够做用在string上)
switch中能够是枚举类型程序员

三、说说final、finally、finalize三者的区别?

答:面试

1.final:若是一个类被final修饰,意味着该类不能派生出新的子类,不能做为父类被继承。所以一个类不能被声明为abstract,又被声明为final。将变量或方法声明为final。能够保证他们在使用的时候不被改变。其初始化能够在两个地方:一是其定义的地方,也就是在final变量在定义的时候就对其赋值;二是在构造函数中。这两个地方只能选其中的一个,要么在定义的时候给值,要么在构造函数中给值。被声明为final的方法也只能使用,不能重写。算法

2.finally:在异常处理的时候,提供finally块来执行任何的清除操做。若是抛出一个异常,那么相匹配的catch字句就会执行,而后控制就会进入finally块,前提是有finally块。sql

3.finalize:finalize是方法名,java技术容许使用finalize()方法在垃圾收集器将对象从内存中清除出去以前作必要的清理工做。这个方法是在垃圾收集器确认一个对象没有被引用时对这个对象调用的。它是在Object类中定义的,所以,全部的类都继承了它。子类覆盖finalize()方法已整理系统资源或者执行其余清理工做。finalize()方法是在垃圾收集器删除对象以前对这个对象调用的。数组

 

四、Math.round(11.5)和Math.round(-11.5)分别等于多少?

答案:12    和    -11浏览器

0一、round()方法能够这样理解:缓存

将括号内的数+0.5以后,向下取值,安全

好比:round(3.4)就是3.4+0.5=3.9,向下取值是3,因此round(3.4)=3; 

round(-10.5)就是-10.5+0.5=-10,向下取值就是-10,因此round(-10.5)=-10

因此,Math.round(11.5)=12; Math.round(-11.5)=-11;

 

0二、扩展

00一、Math.ceil求最小的整数,但不小于自己.  

ceil的英文意义是天花板,该方法就表示向上取整,

例子:

因此,Math.ceil(11.3)的结果为12,Math.ceil(-11.3)的结果是-11;

 

00二、Math.floor求最大的整数,但不大于自己.

floor的英文意义是地板,该方法就表示向下取整,

例子:

floor的英文意义是地板,该方法就表示向下取整,

因此,Math.floor(11.6)的结果为11,Math.floor(-11.6)的结果是-12;

 

五、说说String、StringBuffer、StringBuilder的区别。

区别:String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象,所以在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,而后将指针指向新的 String 对象,因此常常改变内容的字符串最好不要用 String ,由于每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了之后, JVM 的 GC 就会开始工做,那速度是必定会至关慢的,

 

执行速度:三者在执行速度方面的比较:

StringBuilder >  StringBuffer  >  String

 

使用场景:

01.若是要操做少许的数据用 = String  

02.单线程操做字符串缓冲区 下操做大量数据 = StringBuilder

03.多线程操做字符串缓冲区 下操做大量数据 = StringBuffe

 

六、为何不建议记录日志时使用System.out.println()。

1.  Log4j就是帮助开发人员进行日志输出管理的API类库。它最重要的特色就能够配置文件灵活的设置日志信息的优先级、日志信息的输出目的地以及日志信息的输出格式。

2.  Log4j除了能够记录程序运行日志信息外还有一重要的功能就是用来显示调试信息。

3.  程序员常常会遇到脱离java ide环境调试程序的状况,这时大多数人会选择使用System.out.println语句输出某个变量值的方法进行调试。这样会带来一个很是麻烦的问题:一旦哪天程序员决定不要显示这些System.out.println的东西了就只能一行行的把这些垃圾语句注释掉。若哪天又需调试变量值,则只能再一行行去掉这些注释恢复System.out.println语句。

使用log4j能够很好的处理相似状况。

 

七、运行时异常和普通异常有什么区别?

Java提供了两种错误的异常类,分别为Error和Exception,他们拥有共同的父类—Throwable。   

    Error表示程序在运行期间出了很是严重的错误,而且错误不可恢复,如OutOfMemoryError、ThreadDeath等

    Exception表示能够恢复的异常,是编译器能够捕捉到的。包含两种类型:

    检查异常和运行时异常。

    1)检查异常。Java编译器强制程序去捕获此类异常,如IO异常和SQL异常。

    2)运行时异常。编译器不会对其强制进行捕获并处理。若是不进行处理,出现异常时,JVM会来处理。

          出现运行时异常,系统会把异常一直往上抛,知道遇处处理代码为止。若没有处理代码,则抛到最上层。

          多线程又Thread.run()方法抛出,单线程用main()方法抛出。若是不处理异常,一旦发生,要么线程终止,要么主程序终止。

          运行时异常包括:NullPointException(空指针异常)

            ClassCastException(类型转换异常)

      ArrayIndexOutOfBoundsException(数组越界异常)

      ArrayStoreException(数组存储异常)

      BufferOverflowException(缓冲区溢出异常)

      ArithmeticException(算输异常)

 

八、Thread.Sleep和Object.wait()有什么区别?

一、这两个方法来自不一样的类分别是,sleep来自Thread类,和wait来自Object类。

sleep是Thread的静态类方法,谁调用的谁去睡觉,即便在a线程里调用了b的sleep方法,实际上仍是a去睡觉,要让b线程睡觉要在b的代码中调用sleep。


二、最主要sleep方法没有释放锁,而wait方法释放了锁,使得其余线程可使用同步控制块或者方法。

sleep不出让系统资源;wait是进入线程等待池等待,出让系统资源,其余线程能够占用CPU。通常wait不会加时间限制,由于若是wait线程的运行资源不够,再出来也没用,要等待其余线程调用notify/notifyAll唤醒等待池中的全部线程,才会进入就绪队列等待OS分配系统资源。sleep(milliseconds)能够用时间指定使它自动唤醒过来,若是时间不到只能调用interrupt()强行打断。

Thread.Sleep(0)的做用是“触发操做系统马上从新进行一次CPU竞争”。


三、使用范围:wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep能够在任何地方使用 
   synchronized(x){ 
      x.notify() 
     //或者wait() 
   }


四、sleep必须捕获异常,而wait,notify和notifyAll不须要捕获异常

 

九、当一个线程进入一个对象的一个synchronized方法后,其它线程是否能够进入此对象的其余synchronized方法和普通方法?

1.其余方法前是否加了synchronized关键字,若是没加,则能。
2.若是这个方法内部调用了wait,则能够进入其余synchronized方法。
3.若是其余个方法都加了synchronized关键字,而且内部没有调用wait,则不能。
4.若是其余方法是static,它用的同步锁是当前类的字节码,与非静态的方法不能同步,由于非静态的方法用的是this。

 

十、如何遍历HashMap。

public static void main(String[] args) {

  Map<String,String> map=new HashMap<String,String>();
        map.put("1", "value1");
        map.put("2", "value2");
        map.put("3", "value3");
        map.put("4", "value4");
       
        //第一种:普通使用,二次取值
        System.out.println("\n经过Map.keySet遍历keyvalue"); 
        for(String key:map.keySet())
        {
         System.out.println("Key: "+key+" Value: "+map.get(key));
        }
       
        //第二种
        System.out.println("\n经过Map.entrySet使用iterator遍历keyvalue: "); 
        Iterator map1it=map.entrySet().iterator();
        while(map1it.hasNext())
        {
         Map.Entry<String, String> entry=(Entry<String, String>) map1it.next();
         System.out.println("Key: "+entry.getKey()+" Value: "+entry.getValue());
        }
       
        //第三种:推荐,尤为是容量大时 
        System.out.println("\n经过Map.entrySet遍历keyvalue"); 
        for(Map.Entry<String, String> entry: map.entrySet())
        {
         System.out.println("Key: "+ entry.getKey()+ " Value: "+entry.getValue());
        }
       
        //第四种 
        System.out.println("\n经过Map.values()遍历全部的value,但不能遍历key"); 
        for(String v:map.values())
        {
         System.out.println("The value is "+v);
        }
 }

 

输出结果:

 

经过Map.keySet遍历keyvalue

Key: 1 Value: value1

Key: 2 Value: value2

Key: 3 Value: value3

Key: 4 Value: value4

 

经过Map.entrySet使用iterator遍历keyvalue:

Key: 1 Value: value1

Key: 2 Value: value2

Key: 3 Value: value3

Key: 4 Value: value4

 

经过Map.entrySet遍历keyvalue

Key: 1 Value: value1

Key: 2 Value: value2

Key: 3 Value: value3

Key: 4 Value: value4

 

经过Map.values()遍历全部的value,但不能遍历key

The value is value1

The value is value2

The value is value3

The value is value4

 

十一、Set中和的元素不能重复,用什么方法来区分是否重复呢?使用==仍是用equals?他们有什么区别?

Set是Collection容器的一个子接口,它不容许出现重复元素,固然也只容许有一个null对象。

如何来区分重复与否呢?

     “ 用 iterator() 方法来区分重复与否 ”,这是在网上流传的答案,我的认为这是个错误的答案。API中写的很明白:“set 不包含知足

e1.equals(e2) 的元素对 e1 和 e2 ”,因而可知回答使用equals()区分更合适。

 

为何用equals()而不用==来区分?

     应该从它俩的区别谈起,==是用来判断二者是不是同一对象(同一事物),而equals是用来判断是否引用同一个对象。再看一下Set里面存的是

对象,仍是对象的引用。根据java的存储机制可知,set里面存放的是对象的引用,因此当两个元素只要知足了equals()时就已经指向同一个对象,

也就出现了重复元素。因此应该用equals()来判断。

 

 

十二、写一个方法,计算菲波那切数列(1,1,2,3,5,8,...)第100项的值,方法  参数为第N项,返回值为第N项的值(考虑程序运行效率、异常处理)。

 

第一百项的值:354224848179261915075

public static BigDecimal getNum(Integer n){

      boolean flag=true;//声明一个标识符

      List<BigDecimal> lists = new ArrayList<BigDecimal>();//声明一个集合存储斐波那契数列的值

      try {

        for(int i=1;i<=n;i++){

           if (i<=2) {//斐波那契数列前两项值

              lists.add(new BigDecimal(1));

           }else{//大于两项后的值计算

              lists.add((lists.get(i-3).add(lists.get(i-2))));

           }

        }

        for (BigDecimal bigDecimal : lists) {//便利斐波那契数列

           System.out.println(bigDecimal);

        }

       

      } catch (Exception e) {

        flag=false;

        System.err.print("出错了");

        e.printStackTrace();

      }

      if (flag) {

        return lists.get(n-1);//返回第n象的值

      }else{

        return new BigDecimal(0);

      }

 

1三、谈谈你对java.math.BigDecimal类的认识。

java.math.BigDecimal 类提供用于算术,刻度操做,舍入,比较,哈希算法和格式转换操做。

对于不须要任何准确计算精度的数字能够直接使用float或double,可是若是须要精确计算的结果,则必须使用BigDecimal类,并且使用BigDecimal类也能够进行大数的操做。

BigDecimal是Java中用来表示任意精确浮点数运算的类,在BigDecimal中,使用unscaledValue × 10-scale来表示一个浮点数。其中,unscaledValue是一个BigInteger,scale是一个int。从这个表示方法来看,BigDecimal只能标识有限小数,不过能够表示的数据范围远远大于double,在实际应用中基本足够了。

toString()方法提供BigDecimal的规范表示。它使用户能够彻底控制舍入行为。

提供用于操做BigDecimal规模两种类型的操做:

缩放/舍入操做

小数点移动操做。

此类及其迭代器实现Comparable接口的全部可选方法。

 

1四、Java进程间通讯的方式有哪些。

1)管道(Pipe):管道可用于具备亲缘关系进程间的通讯,容许一个进程和另外一个与它有共同祖先的进程之间进行通讯。

2)命名管道(named pipe):命名管道克服了管道没有名字的限制,所以,除具备管道所具备的功能外,它还容许无亲缘关 系 进程间的通讯。命名管道在文件系统中有对应的文件名。命名管道经过命令mkfifo或系统调用mkfifo来建立。

3)信号(Signal):信号是比较复杂的通讯方式,用于通知接受进程有某种事件发生,除了用于进程间通讯外,进程还能够发送 信号给进程自己;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又可以统一对外接口,用sigaction函数从新实现了signal函数)。

4)消息(Message)队列:消息队列是消息的连接表,包括Posix消息队列system V消息队列。有足够权限的进程能够向队列中添加消息,被赋予读权限的进程则能够读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺

5)共享内存:使得多个进程能够访问同一块内存空间,是最快的可用IPC形式。是针对其余通讯机制运行效率较低而设计的。每每与其它通讯机制,如信号量结合使用,来达到进程间的同步及互斥。

6)内存映射(mapped memory):内存映射容许任何多个进程间通讯,每个使用该机制的进程经过把一个共享的文件映射到本身的进程地址空间来实现它。

7)信号量(semaphore):主要做为进程间以及同一进程不一样线程之间的同步手段。

8)套接口(Socket):更为通常的进程间通讯机制,可用于不一样机器之间的进程间通讯。起初是由Unix系统的BSD分支开发出来的,但如今通常能够移植到其它类Unix系统上:Linux和System V的变种都支持套接字。

 

 

1五、CSS规则style=”padding:0 0 3px 3px”设置的元素内边距分别是多少。

上:0px 右:0px 下:3px 左3px

 

1六、说出HTTP请求的GET和POST方式的区别。

(一)、原理区别

通常咱们在浏览器输入一个网址访问网站都是GET请求;再FORM表单中,能够经过设置Method指定提交方式为GET或者POST提交方式,默认为GET提交方式。

 

HTTP定义了与服务器交互的不一样方法,其中最基本的四种:GET,POST,PUT,DELETE,HEAD,其中GET和HEAD被称为安全方法,由于使用GET和HEAD的HTTP请求不会产生什么动做。不会产生动做意味着GET和HEAD的HTTP请求不会在服务器上产生任何结果。可是安全方法并非什么动做都不产生,这里的安全方法仅仅指不会修改信息。

 

根据HTTP规范,POST可能会修改服务器上的资源的请求。好比CSDN的博客,用户提交一篇文章或者一个读者提交评论是经过POST请求来实现的,由于再提交文章或者评论提交后资源(即某个页面)不一样了,或者说资源被修改了,这些即是“不安全方法”。

 

(二)、表现形式区别

HTTP请求中,奇异行必须是一个请求行,包括请求方法,请求URL,报文所用HTTP版本信息。紧接着是一个herders小节,能够有零个或一个首部,用来讲明服务器要使用的附加信息。在首部以后就是一个空行,最后就是报文实体的主体部分,包含一个由任意数据组成的数据块。可是并非全部的报文都包含实体的主体部分。

 

请求方式的区别:

1)、GET请求,请求的数据会附加在URL以后,以?分割URL和传输数据,多个参数用&链接。URL的编码格式采用的是ASCII编码,而不是uniclde,便是说全部的非ASCII字符都要编码以后再传输。

 

POST请求:POST请求会把请求的数据放置在HTTP请求包的包体中。上面的item=bandsaw就是实际的传输数据。

 

所以,GET请求的数据会暴露在地址栏中,而POST请求则不会。

 

2)、传输数据的大小

 

HTTP规范中,没有对URL的长度和传输的数据大小进行限制。可是在实际开发过程当中,对于GET,特定的浏览器和服务器对URL的长度有限制。所以,在使用GET请求时,传输数据会受到URL长度的限制。

 

对于POST,因为不是URL传值,理论上是不会受限制的,可是实际上各个服务器会规定对POST提交数据大小进行限制,Apache、IIS都有各自的配置。

 

3)、安全性

 

POST的安全性比GET的高。这里的安全是指真正的安全,而不一样于上面GET提到的安全方法中的安全,上面提到的安全仅仅是不修改服务器的数据。好比,在进行登陆操做,经过GET请求,用户名和密码都会暴露再URL上,由于登陆页面有可能被浏览器缓存以及其余人查看浏览器的历史记录的缘由,此时的用户名和密码就很容易被他人拿到了。除此以外,GET请求提交的数据还可能会形成Cross-site request frogery攻击

 

4)、HTTP中的GET,POST,SOAP协议都是在HTTP上运行的

 

1七、Servlet的forword和redirect的区别。

使用forward的时候浏览器不知道它所请求的具体资源来源,因此地址栏不会变;  

使用redirect,服务端根据逻辑,发送一个状态码,告诉浏览器从新去请求那个地址。因此地址栏显示的是新的URL。  

forward,转发页面和转发到的页面能够共享request里面的数据.redirect,不能共享数据。

 

1八、写一段JDBC查询oracle数据的代码。

package test;

 import java.sql.Connection;

 import java.sql.DriverManager;

 import java.sql.ResultSet;

 import java.sql.SQLException;

 import java.sql.Statement;

 public class JDBCDemo {

     public static void main(String[] args){

         Connection conn = null;

         ResultSet rs = null;

         try {

             //加载驱动

             Clas敏感词orName("oracle.jdbc.OracleDriver");

             //得到链接

             conn = DriverManager.getConnection(

                 "jdbc:oracle:thin:@localhost:1521:orcl",

                 "scott",

                 "tiger");

             Statement stat = conn.createStatement();

             //sql语句

             String sql = "SELECT * FROM emp";

             //执行语句得到结果集

             rs = stat.executeQuery(sql);

             //遍历结果集

             while(rs.next()){

                 String name = rs.getString("name");

                 System.out.println(name);

             }

         } catch (Exception e) {

             e.printStackTrace();

         } finally {

             //关闭链接

             try {

                 conn.close();

             } catch (SQLException e) {

                 // TODO Auto-generated catch block

                 e.printStackTrace();

             }

         }

     }

 }

 

1九、JDBC中PreparedStatement相比Statement的好处。

1)极大提升了安全性能,能够防止sql注入

 

2)代码的可读性和可维护性相比Statement要好.

 

3)有预编译功能,相同操做批量数据效率较高

 

由于预编译语句有可能被重复调用.因此语句在被DB的编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不须要编译,只要将参数直接传入编译过的语句执行代码中就会获得执行

相关文章
相关标签/搜索