Java面试题一

1.    Java实现一个高逼格的冒泡排序

把这个数组从小到大的排列

import java.util.Comparator;

/**
 *
排序器接口(策略模式: 将算法封装到具有共同接口的独立的类中使得它们可以相互替换)
 */
public interfaceSorter {
   
/**
     *
排序
    
*
     * @param
list 待排序的数组
    
*/
   
public <T extends Comparable<T>> void sort(T[] list);

   
/**
     *
排序
    
*
     * @param
list 待排序的数组
    
* @param comp 比较两个对象的比较器
    
*/
   
public <T> void sort(T[] list, Comparator<T> comp);
}

 

import java.util.Comparator;

public class BubbleSorter implements Sorter {

    @Override
    public <T extends Comparable<T>> void sort(T[] list) {
        boolean swapped = true;
        for (int i = 1, len = list.length; i < len && swapped; ++i) {
            swapped = false;
            for (int j = 0; j < len - i; ++j) {
                if (list[j].compareTo(list[j + 1]) > 0) {
                    T temp = list[j];
                    list[j] = list[j + 1];
                    list[j + 1] = temp;
                    swapped = true;
                }
            }
        }
    }
    @Override
    public <T> void sort(T[] list, Comparator<T> comp) {
        boolean swapped = true;
        for (int i = 1, len = list.length; i < len && swapped; ++i) {
            swapped = false;
            for (int j = 0; j < len - i; ++j) {
                if (comp.compare(list[j], list[j + 1]) > 0) {
                    T temp = list[j];
                    list[j] = list[j + 1];
                    list[j + 1] = temp;
                    swapped = true;
                }
            }
        }
    }
}
  }
}

2.    Java实现一个高逼格的二分法查找

折半查找,也称二分查找、二分搜索,是一种在有序数组中查找某一特定元素的搜索算法。搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组已经为空,则表示找不到指定的元素。这种搜索算法每一次比较都使搜索范围缩小一半,其时间复杂度是O(logN)

说明:下面的代码中给出了折半查找的两个版本,一个用递归实现,一个用循环实现。需要注意的是计算中间位置时不应该使用(high+ low) / 2的方式,因为加法运算可能导致整数越界,这里应该使用以下三种方式之一:low + (high - low) / 2或low + (high – low) >> 1或(low + high) >>> 1(>>>是逻辑右移,是不带符号位的右移

import java.util.Comparator;
public class BinarySearch {

    public static <T extends Comparable<T>> int binarySearch(T[] x, T key) {
        return binarySearch(x, 0, x.length - 1, key);
    }

    // 使用循环实现的二分查找
    public static <T> int binarySearch(T[] x, T key, Comparator<T> comp) {
        int low = 0;
        int high = x.length - 1;
        while (low <= high) {
            int mid = (low + high) >>> 1;
            int cmp = comp.compare(x[mid], key);
            if (cmp < 0) {
                low = mid + 1;
            } else if (cmp > 0) {
                high = mid - 1;
            } else {
                return mid;
            }
        }
        return -1;
    }

    // 使用递归实现的二分查找
    private static <T extends Comparable<T>> int binarySearch(T[] x, int low, int high, T key) {
        if (low <= high) {
            int mid = low + ((high - low) >> 1);
            if (key.compareTo(x[mid]) == 0) {
                return mid;
            } else if (key.compareTo(x[mid]) < 0) {
                return binarySearch(x, low, mid - 1, key);
            } else {
                return binarySearch(x, mid + 1, high, key);
            }
        }
        return -1;
    }
}

 

3.死锁

/*
    死锁
*/
public class DeadLock {
    public static void main(String[] args) {

        Object o1 = new Object();
        Object o2 = new Object();

        Thread t1 = new Thread(new T1(o1, o2));
        Thread t2 = new Thread(new T2(o1, o2));

        t1.start();
        t2.start();

    }
}

class T1 implements Runnable {
    Object o1;
    Object o2;

    T1(Object o1, Object o2) {
        this.o1 = o1;
        this.o2 = o2;
    }
    @Override
    public void run() {
        synchronized (o1) {
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
            }
            synchronized (o2) {

            }
        }
    }
}

class T2 implements Runnable {
    Object o1;
    Object o2;

    T2(Object o1, Object o2) {
        this.o1 = o1;
        this.o2 = o2;
    }

    @Override
    public void run() {
        synchronized (o2) {
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
            }
            synchronized (o1) {

            }
        }
    }
}

3. 阐述Spring框架中Bean的生命周期? 

1.  Spring IoC容器找到关于Bean定义,调用无参构造器,创建实例对象。

2.  调用参数setter方法,为属性注入值。

3.  如果Bean实现了BeanNameAware接口,则会执行此接口的setBeanName(String beanId)将获取容器中改bean的id名称。

4.  如果实现了BeanFactoryAware接口,则会执行setBeanFactory(BeanFactory factory),使bean类获取到BeanFactory对象。

5.  如果定义并注册了BeanPostProcessor,则调用其postProcessorBeforeInitialization()方法.

6.  如果Bean实现了InitializaingBean接口,则执行接口方法afterPropertiesSet()。该方法在Bean所有属性set方法执行完毕之后执行,是Bean初始化结束标志,即Bean实例化结束。

7.  如果设置了init-method方法,则执行。

8.  如果定义注册了Bean后处理器BeanPostProcessor,则执行postProcessAfterInitialization()方法。

9.  执行业务方法。

10.当销毁Bean实例时,如果Bean实现了DisposableBean接口,则调用destroy()方法。

11.如果设置destroy-method方法,则执行。

 

4. 依赖注入是如何注入集合属性?

可以在定义Bean属性时,通过<list> / <set> /<map> / <props>分别为其注入列表、集合、映射和键值都是字符串的映射属性。

5、如何在web项目中配置Spring的IoC容器?

如果需要在Web项目中使用Spring的IoC容器,可以在Web项目配置文件web.xml中做出如下配置:

<context-param>
    <param-name>contextConfigLocation</param-name>
   <param-value>classpath:applicationContext.xml</param-value>
</context-param>

<listener>
    <listener-class>
       org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

5. 如何在Web项目中配置Spring MVC?

要使用SpringMVC需要在Web项目配置文件中配置其前端控制器DispaterServlet,如下所示:

<web-app>

   <servlet>
       <servlet-name>example</servlet-name>
        <servlet-class>
           org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
       <load-on-startup>1</load-on-startup>
    </servlet>

   <servlet-mapping>
       <servlet-name>example</servlet-name>
       <url-pattern>*.html</url-pattern>
    </servlet-mapping>

</web-app>

6、如何在Spring IoC中配置数据源?

DBCP配置:

<beanid="dataSource"
       class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
    <property name="driverClassName"value="${jdbc.driverClassName}"/>
    <property name="url"value="${jdbc.url}"/>
    <property name="username"value="${jdbc.username}"/>
    <property name="password"value="${jdbc.password}"/>
</bean>
<context:property-placeholder location="jdbc.properties"/>

 

C3P0配置:

<beanid="dataSource"
       class="com.mchange.v2.c3p0.ComboPooledDataSource"
 destroy-method="close">
    <property name="driverClass"value="${jdbc.driverClassName}"/>
    <property name="jdbcUrl"value="${jdbc.url}"/>
    <property name="user"value="${jdbc.username}"/>
    <property name="password"value="${jdbc.password}"/>
</bean>

<context:property-placeholderlocation="jdbc.properties"/>

7、Spring中如何使用注解来配置Bean?有哪些相关的注解?

   首先需要在Spring配置文件中增加如下配置:

<context:component-scan base-package="org.example"/>

然后可以用@Component、@Controller、@Service、@Repository注解来标注需要由Spring IoC容器进行对象托管的类。这几个注解没有本质区别,只不过@Controller通常用于控制器,@Service通常用于业务逻辑类,@Repository通常用于仓库类(例如DAO实现类),普通类用@Component来标注。

8、Spring IoC容器配置Bean的方式?

- 基于XML文件进行配置。

- 基于注解进行配置。

- 基于Java程序进行配置(Spring 3+)

9、选择使用Spring框架的原因(Spring框架为企业级开发带来的好处有哪些)?

可以从以下几个方面作答: 
- 非侵入式:支持基于POJO的编程模式,不强制性的要求实现Spring框架中的接口或继承Spring框架中的类。 
- IoC容器:IoC容器帮助应用程序管理对象以及对象之间的依赖关系,对象之间的依赖关系如果发生了改变只需要修改配置文件而不是修改代码,因为代码的修改可能意味着项目的重新构建和完整的回归测试。有了IoC容器,程序员再也不需要自己编写工厂、单例,这一点特别符合Spring的精神"不要重复的发明轮子"。 
- AOP(面向切面编程):将所有的横切关注功能封装到切面(aspect)中,通过配置的方式将横切关注功能动态添加到目标代码上,进一步实现了业务逻辑和系统服务之间的分离。另一方面,有了AOP程序员可以省去很多自己写代理类的工作。 
- MVC:Spring的MVC框架是非常优秀的,从各个方面都可以甩Struts 2几条街,为Web表示层提供了更好的解决方案。 
- 事务管理:Spring以宽广的胸怀接纳多种持久层技术,并且为其提供了声明式的事务管理,在不需要任何一行代码的情况下就能够完成事务管理。 
- 其他:选择Spring框架的原因还远不止于此,Spring为Java企业级开发提供了一站式选择,你可以在需要的时候使用它的部分和全部,更重要的是,你甚至可以在感觉不到Spring存在的情况下,在你的项目中使用Spring提供的各种优秀的功能。 

10、如何配置配置事务增强? 

<?xmlversion="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
     xsi:schemaLocation="
     http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
     http://www.springframework.org/schema/tx
     http://www.springframework.org/schema/tx/spring-tx.xsd
     http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd">

 <!-- this is the service object that we want to make transactional -->
  <bean id="fooService"class="x.y.service.DefaultFooService"/>

 <!-- the transactional advice -->
  <tx:advice id="txAdvice"transaction-manager="txManager">
  <!-- the transactional semantics... -->
  <tx:attributes>
    <!-- all methods starting with 'get' are read-only -->
    <tx:method name="get*"read-only="true"/>
    <!-- other methods use the default transaction settings(see below) -->
    <tx:method name="*"/>
  </tx:attributes>
  </tx:advice>
  <!-- ensure that the above transactional
     advice runs for any execution
    of an operation defined by the
    FooService interface -->
  <aop:config>
  <aop:pointcut id="fooServiceOperation" 
    expression="execution(*x.y.service.FooService.*(..))"/>
  <aop:advisor advice-ref="txAdvice"
     pointcut-ref="fooServiceOperation"/>
  </aop:config>

 <!-- don't forget the DataSource -->
  <bean id="dataSource"
    class="org.apache.commons.dbcp.BasicDataSource" 
    destroy-method="close">
  <property name="driverClassName"
     value="oracle.jdbc.driver.OracleDriver"/>
  <property name="url"
    value="jdbc:oracle:thin:@localhost:1521:orcl"/>
  <property name="username" value="scott"/>
  <property name="password" value="tiger"/>
  </bean>

 <!-- similarly, don't forget the PlatformTransactionManager -->
  <bean id="txManager"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource" ref="dataSource"/>
  </bean>

 <!-- other <bean/> definitions here -->

</beans>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值