您的位置:首页 > 职场人生

面试小结

2015-03-16 21:41 141 查看
基础内容总结:

java抽象类和接口有什么区别?

       first: 方法中是否有实现? 抽象类里面的方法可以有实现,但是接口里面的方法只能声明。

       second:接口是设计的结果,抽象类是重构的结果。在设计时,怎么选择用抽象类还是用接口呢???

       (对于这句话的理解,面向接口编程更符合开闭原则,而抽象类编程不完全符合开闭原则,因为当抽象类中有方法的时候时候,修改就要繁琐了,我们就以hibernate中的DAO来说,为什么hibernate的设计人员把对DAO的操作封装成抽象类呢,而不是接口呢,我们看HibernateDaoSupport源码,

public abstract class HibernateDaoSupport extends DaoSupport
 
       我们在使用的时候是继承这个类,然后再调用的是静态方法。至于为什么hibernate不使用接口,因为人家的产品,就想是封装好一个工具类你来用,不需要你去修改,但是在DaoSupport上,追根到源头,我想一定是接口。但是在你自己设计项目的时候,就要根据项目的需求是选择使用抽象类还是接口了)。

       third: 接口是核心,定义了要做的事情,但是没有怎么去做这件事情。实现了接口的就要实现接口中的所有方法。如果某一些类的实现有共同之处,我们则可以在接口下抽象出一个抽象类来,让抽象类实现接口的共用代码,而那些自己个性化的方法则由各个子类去实现。(这是因为抽象类中必须至少有一个抽象方法,但是也可以有非抽象方法

       所以抽象类是简化了接口的实现,不仅提供了公共方法的实现,让我们快速开发,允许你的类完全可以自己实现所有的方法,降低耦合。

有这样的一个场景,台球厅中,不同的台球案根据尺寸大小等有不同的,分小时计算有不同的价格,并且根据小时累计,超过5小时的赠送一小时,你如何用程序来解决呢?

       最简单的办法是直接在客户端写代码,根据不同的案板有不同的价格计算,不过这样在计算中会出现大量重复的代码,在修改和扩展时都需要改动客户端代码,每次都要写一些重复的代码,每次都要重新编译,显然这是一个最不好的办法。

用简单工厂模式

       我们要把重复的东西提取出来,提取相同属性或功能的,封装成抽象类或者接口。我们可以把计算的算法抽象出一个抽象类(为什么是抽象类而不是接口,是根据需求而定的),然后不同的计算方法继承这个收费抽象类,然后通过一个简单工厂通过if语句对子类进行判断,这样是可以实现的。

但是如果再增加积分等计算的时候,会改动增加一个现金计算的子类,同时在工厂中增加一个分支条件语句,这样就需要变动两个类了。工厂模式只是隐藏了创建过程,但是如果需要经常改动收费方式,就有些麻烦了。

用策略模式

       那怎样让算法的增加,不会影响到算法的客户,而是用的客户端呢?

我们可以使用策略模式,这样做,把判断使用哪个算法放到了客户端,在客户端判断使用哪种现金计算方式,这样如果在修改和扩展的角度来看,需要改动计算现金的子类和客户端,那能不能使用简单工厂和策略模式相结合呢?

用简单工厂+策略模式

       简单工厂中客户端需要识别两个类,现金算法抽象类和工厂类。用简单工厂和策略模式结合,客户端需要识别现金算法配置类,这样在修改和扩展中把对程序的影响降低到最小。

ArrayList和LinkList的区别?

       从数据结构方面来看,ArrayList采用的是数组形式来保存对象的,这种方式将对象放在连续的位置,所以最大的缺点就是插入和删除的时候非常麻烦。而LinkList采用的是将对象放在独立的空间中,而且在每一个空间中还保存下一个连接的索引,缺点是在查找的时候非常的麻烦,要从第一个索引开始查起。

       最根本的内部机制,ArrayList采用的是线性表的顺序结构,而LinkList采用的是线性表的链式结构。





PrepareStatement和Statement区别?

       我们知道Preparestatement是预编译的,而Statement则不是。这同ibatis中的#和$符号的区别类似,$符号的作用实际上就是字符串拼接和statement类似,而#作用就类似与Preparestatement,使用Preparestatement和#有效的防止了sql注入,而且是预编译,这样对效率也有定义的提升,而$和Statement是简单的字符串拼接,会引发sql注入等安全问题。

       而什么是PrepareStatement的预编译呢?是当我们使用Preparestatement对象时就会把sql语句编译,除了动态指定的参数“?”,“?”是在运行期进行编译的。并且当你第一次被编译的时候,被放到缓存区,第二次重复调用就直接直接编译好的部分,需要动态编译的就是“?”参数传递的部分。

给定你一个数组,里面有不同的数字,数字可能会出现重复的,最后输出的是 所有的数字和对应数组中包含这个数字的个数

       方法一:

       首先我想到的最原始的办法,是从数组的头开始,把第一个数字作为比较的基数,分别和后面的比较,有相同的就count+1,同时改变数组的下标,就这样,再以第二个数为基数和后面的比较,相同就count,这样类推,直到最后一个数。这种方法如果实在c语言中,用指针可能效率高些。

       方法二

       先排序再利用二分查找法查找,再count。

       方法三:

       显然上述两种方法效率是极低的,面试官给我提示利用Map的特性。

Map有什么特性呢?

       Map中的key是不会重复的,利用Map的特性来解决问题,下篇文章,会详细把代码贴出来。

说说分页?怎么用的?sql代码是?

       hibernate的分页:传递两个参数返回List,显示到界面即可。

       传统分页:分为真分页和假分页,假分页就是把数据库中的数据全部取出来,然后再再界面上分页显示。真分页,在数据中把第几条,每页多少条都查出来,提高效率,只有当点击下一页的时候才查询,在oracle中使用的是oracle数据库语句,参考http://blog.csdn.net/lovesummerforever/article/details/9920849,还有其他一些封装好的分页框架,下篇将会把分页各种方法进行总结。

笔试基础:

       写一个函数,传入整型变量,输入数字,打印相应的金字塔样式,如下所示。



       很简单的一个程序,利用等差数列来找到规律,代码如下所示,完全正确,小女子亲测。

[java]
view plaincopyprint?





<span style="font-family:Microsoft YaHei;font-size:18px;">package print_xing;  
  
/** 
 *  
 * @author lovesummerforever  
 * 
 */  
public class print_Xing {  
    //用静态方法,方便测试.  
    public static void printXing(int num)  
    {  
        //一共是几行.  
        for(int i=0;i<=num-1;i++)  
        {  
            //打印空格.  
            for(int j=i;j<num;j++)  
            {  
                System.out.print(" ");  
            }  
            //打印口*号.  
            for(int k=1;k<=2*i+1;k++)  
            {  
                System.out.print("*");  
            }  
            //打印一行完毕后,一定要注意打印回车.  
            System.out.println();  
        }  
    }  
  
    public static void  main(String[] args)  
    {  
        //调用,传递参数,例如传递4,打印四行.  
        printXing(4);  
    }  
      
}</span>  

递归思想的应用:

二分查找法,写一个函数。

       二分查找算法,是对一个有序数进行分半查找,其原理属于减治算法的思想。我们可以用递归方式和非递归方式完成算法。

       代码见:http://blog.csdn.net/lovesummerforever/article/details/24588989

       总结的有些仓促和凌乱,望见谅额
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: