面试题汇总

* 用java写出n!(n的阶乘)*

public class MyTest {    
    /**
     *
     * 阶乘指从 1 乘以 2 乘以 3 乘以 4 一直乘到所要求的数。
     * @param n
     * @return
     */
      //第一种方法:while循环
    public static int whileTest(int n) {

        if(n==0){
            return 0;
        }
        if(n==1){
            return 1;
        }
        int i=1;
        int result=1;  //声明变量result---阶乘的结果
        while(i<=n){
            result=i*result;
            i++;
        }
        return result;
    }

     //第二种方法:do...while循环
    public static int doWhileTest(int n) {

        if(n==0){
            return 0;
        }
        if(n==1){
            return 1;
        }
       int i=1;
        int result=1;  //声明变量result---阶乘的结果
        do{
            result=result*i;
            i++;
        }while(i<=n);
        return result;
    }

     //第三种方法:for循环
    public static int forTest(int n) {

        if(n==0){
            return 0;
        }
        if(n==1){
            return 1;
        }
        int result=1;  //声明变量result---阶乘的结果
        for(int i=1; i<=n;i++){
            result=result*i;
        }
     return result;
    }

     //第四种方法:递归方式
    public static int recursionTest(int n) {
        int result=1;
        if(n==0){
            return 0;
        }else if(n==1){
            return 1;
        }else{            
            result =n*recursionTest(n-1);            
        }
        return result;
    }    
}
public class MyTest {
    /**
     * 结果是3
     */
    @Test
    public void test1(){
        int x=1;
        int y=2;
        int z=3;
        int result=y+=z--/++x;
        System.out.print("结果是:"+result);
    }

    /**
     * 实现的是1+1/2+1/3+1/4+...+1/99+1/100的和
     */
    @Test
    public void test2(){
            double   sum = 0.0;
            for(int  i = 1;   i <= 100;  i++){
                sum += 1.0/(double) i;
                System.out.println( "sum="+sum );

            }

        }

    /**
     * 给int类型数组中---的元素进行反转
     */
    @Test
    public void test3(){
        int i=10;
        int n =10 ;
        int  a[ ] = new int[10];

        for  ( i = 0;  i < n;  i++ ){

            try {
                BufferedReader br = new BufferedReader( new InputStreamReader(System.in));
                // 输入一个整数
                a[i] = Integer.parseInt(br.readLine( ));  

            } catch ( IOException e ) {

            }
        }

        for  ( i = n-1;  i >= 0;  i--){
            System.out.print(a[i]+"  ");
            System.out.println();
        }
    }

}
/**
*结果为20
*/
public class Test2 {
    public static void main(String args[]) {
        SubClass sb = new SubClass();
        System.out.println(sb.max());
    }
}

class SuperClass {
    int  a = 10 , b = 20;
}

class SubClass extends SuperClass {
    int max() {
        return ((a > b) ? a : b);
    }
}
/**
 * 结果是:“Hello!I love JAVA.”
 * @author Administrator
 *
 */
public class Test2 {
    public static void main(String args[]) {
        AB s = new AB("Hello!", "I love JAVA.");
        System.out.println(s.toString());
    }
}

class AB {
    String s1;
    String s2;

    AB(String str1, String str2) {
        s1 = str1;
        s2 = str2;
    }

    public String toString() {
        return s1 + s2;
    }
}

j2ee(javaEE)的分为几层?

java enterprise edition(java企业应用)一共分为三层:
(1) 表示逻辑层(显示数据)。
(2)业务逻辑层(处理数据)。
(3) 数据访问逻辑层(存取数据)。

什么是存贮过程?是用来做什么?使用sql语句写出存贮过程?

存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。
存储过程的优点:

1.存储过程只在创造时进行编译,以后每次执行存储过程都不需再重新编译,而一般SQL语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度。
2.当对数据库进行复杂操作时(如对多个表进行Update,Insert,Query,Delete时),可将此复杂操作用存储过程封装起来与数据库提供的事务处理结合一起使用。
3.存储过程可以重复使用,可减少数据库开发人员的工作量 。
4.安全性高,可设定只有某此用户才具有对指定存储过程的使用权 。

缺点:

1.如果更改范围大到需要对输入存储过程的参数进行更改,或者要更改由其返回的数据,则您仍需要更新程序集中的代码以添加参数、更新 GetValue() 调用,等等,这时候估计比较繁琐了。
2.可移植性差 由于存储过程将应用程序绑定到 SQL Server,因此使用存储过程封装业务逻辑将限制应用程序的可移植性。

什么是触发器?有什么作用?

触发器(trigger)是个特殊的存储过程,它的执行不是由程序调用,也不是手工启动,而是由事件来触发,比如当对一个表进行操作( insert,delete, update)时就会激活它执行。触发器经常用于加强数据的完整性约束和业务规则等。 触发器可以从 var cpro_psid =”u2572954”; var cpro_pswidth =966; var cpro_psheight =120; DBA_TRIGGERS ,USER_TRIGGERS 数据字典中查到。 触发器可以查询其他表,而且可以包含复杂的 SQL语句。它们主要用于强制服从复杂的业务规则或要求。

例如:您可以根据客户当前的帐户状态,控制是否允许插入新订单。
触发器也可用于强制引用完整性,以便在多个表中添加、更新或删除行时,保留在这些表之间所定义的关系。然而,强制引用完整性的最好方法是在相关表中定义主键和外键约束。如果使用数据库关系图,则可以在表之间创建关系以自动创建外键约束。

优点:

触发器可通过数据库中的相关表实现级联更改,不过,通过级联引用完整性约束可以更有效地执行这些更改。触发器可以强制比用CHECK约束定义的约束更为复杂的约束。与CHECK 约束不同,触发器可以引用其它表中的列。
例如,触发器可以使用另一个表中的 SELECT比较插入或更新的数据,以及执行其它操作,如修改数据或显示用户定义错误信息。触发器也可以评估数据修改前后的表状态,并根据其差异采取对策。一个表中的多个同类触发器(INSERT、UPDATE 或 DELETE)允许采取多个不同的对策以响应同一个修改语句。

Overload和Override的区别:
重载Overload表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数或类型不同)。
重写Override表示子类中的方法可以与父类中的某个方法的名称和参数完全相同,通过子类创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于把父类中定义的那个完全相同的方法给覆盖了,这也是面向对象编程的多态性的一种表现。

HashMap和Hashtable的区别;

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

给我十个你最常见到的runtime exception;
—->运行时异常<—–
ArithmeticException (算术异常)最常见的就是0作为了除数
ArrayIndexOutOfBoundsException、(数组越界异常)
ArrayStoreException (数组存储异常)
ClassCastException、(类转换异常)
EmptyStackException (空栈异常)
IllegalPathStateException (不合法路径异常)
IllegalStateException (不合法状态异常)
NullPointerException、(空指针异常)
NoSuchElementException、 (没有此元素异常)
SystemException(系统异常)

什么是线程同步?
当使用多个线程来访问同一个数据时,非常容易出现线程安全问题(比如多个线程都在操作同一数据导致数据不一致),所以我们用同步机制来解决这些问题。

多线程有几种实现方法,都是什么?
多线程有两种实现方法,分别是继承Thread类与实现Runnable接口

实现同步机制有两个方法:
1。同步代码块:
synchronized(同一个数据){}
同一个数据:就是N条线程同时访问一个数据。
2。 同步方法:
public synchronized 数据返回类型 方法名(){}
就是使用 synchronized 来修饰某个方法,则该方法称为同步方法。
对于同步方法而言,无需显示指定同步监视器,同步方法的同步监视器是 this 也就是该对象的本身(这里指的对象本身有点含糊,其实就是调用该同步方法的对象)通过使用同步方法,可非常方便的将某类变成线程安全的类,具有如下特征:
1,该类的对象可以被多个线程安全的访问。
2,每个线程调用该对象的任意方法之后,都将得到正确的结果。
3,每个线程调用该对象的任意方法之后,该对象状态依然保持合理状态。
注:synchronized关键字可以修饰方法,也可以修饰代码块,但不能修饰构造器,属性等。
实现同步机制注意以下几点: 安全性高,性能低,在多线程用。性能高,安全性低,在单线程用。
1,不要对线程安全类的所有方法都进行同步,只对那些会改变共享资源方法的进行同步。
2,如果可变类有两种运行环境,当线程环境和多线程环境则应该为该可变类提供两种版本:线程安全版本和线程不安全版本(没有同步方法和同步块)。在单线程中环境中,使用线程不安全版本以保证性能,在多线程中使用线程安全版本.

为什么要使用线程通讯?

当使用synchronized来修饰某个共享资源时(分同步代码块和同步方法两种情况),当某个线程获得共享资源的锁后就可以执行相应的代码段,直到该线程运行完该代码段后才释放对该共享资源的锁,让其他线程有机会执行对该共享资源的修改。当某个线程占有某个共享资源的锁时,如果另外一个线程也想获得这把锁运行就需要使用wait()和notify()/notifyAll()方法来进行线程通讯了。

wait():使一个线程处于等待状态,并且释放所持有的对象的lock。
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉
notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
Allnotity():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。

使用数据库连接池连接mysql数据库,并添加查询相应数据;

//连接先建立一些连接,并且这些连接允许共享,因此这样就节省了每次连接的时间开销。
//Mysql数据库为例,连接池在Tomcat中的配置与使用。
1、创建数据库Student,表student
2、配置server.xml文件。Tomcat安装目录下conf中server.xml文件。                
    <name="jdbc/DBPool"
    type="javax.sql.DataSource"
    password=""
    driverClassName="com.mysql.jdbc.Driver"
    maxIdle="2"
    maxWait="5000"
    username="root"
    url="jdbc:mysql://localhost:3306/student"
    maxActive="3"
        />

name:指定连接池的名称
type:指定连接池的类,他负责连接池的事务处理
url:指定要连接的数据库
driverClassName:指定连接数据库使用的驱动程序
username:数据库用户名
password:数据库密码
maxWait:指定最大建立连接等待时间,如果超过此时间将接到异常
maxIdle:指定连接池中连接的最大空闲数
maxActive:指定连接池最大连接数


3、配置web.xml文件。
     mysql数据库连接池配置
     jdbc/DBPool
     javax.sql.DataSource
     Container
     Shareable


4、配置context.xml文件
    与server.xml文件所在的位置相同。
    name="jdbc/DBPool"
    type="javax.sql.DataSource"
    global="jdbc/DBPool"
    />

5、测试
DataSource pool = null;
Context env = null;
Connection conn = null;
Statement st = null;
ResultSet rs  = null;
try{
    env = (Context)new InitialContext().lookup("java:comp/env");
    //检索指定的对象,返回此上下文的一个新实例
    pool = (DataSource)env.lookup("jdbc/DBPool");
    //获得数据库连接池
    if(pool==null){out.printl("找不到指定的连接池!");}
    con = pool.getConnection();
    st = con.createStatement();
    rs = st.executeQuery("select * from student");
}catch(Exception ex){out.printl(ne.toString());}

猜你喜欢

转载自blog.csdn.net/yuki5233/article/details/70157631