杭州面试总结

我所据说过的技术名词总结:java

1.熟悉的:Java、SVN、Maven、Agile、Scrum、Spring、mysql

2.正在了解的:Jetty、MongoDB、redis、Lucene、程序员

3.不熟悉的:Autonomy、Quova、面试

4.工具:Eclipse、MyEclipse、Navicat、Plsql、springsourcetoolsuite、redis

 

须要巩固的知识:Spring、SpringMVC、Mybatis;Java、Mysql、Oracle、HTML、CSS、JS算法

须要了解的东西:HTTP协议、单元测试技术、J2EE体系结构、高并发大数据量的项目了解spring

第一部分:Mysql和Oracle面试问题总结sql

  varchar与char的区别,char是一种固定长度的类型,varchar则是一种可变长度的类型。数据库

  varchar(50)中50的涵义,最多存放50个字节。服务器

  事务是如何经过日志来实现的。隔离性: 经过 锁 实现。原子性、一致性和持久性是经过 redo和undo来完成的。

// 你如何肯定 MySQL 是否处于运行状态?
命令:service mysql status

//如何开启或中止 MySQL 服务?
命令:service mysqld start  ||  service mysqld stop

//如何经过 Shell 登入 MySQL?
命令:mysql -u root -p

//如何列出全部数据库?
命令:show databases;

//如何切换到某个数据库并在上面工做?
命令:use database_name;

//如何列出某个数据库内全部表?
命令:show tables;

//删除数据库、删除表
命令:drop database database_name;   drop table table_name;

//建立数据库
命令:creat database database_name;

//建立新表
命令:creat table_name(col1_name varchar [not null] [primary key], col2_name varchar [not null]...);

//增长一个列
命令:Alter table table_name add column col_name type;

//添加主键
命令:Alter table table_name add primary key(col);

//选择语句
select * from table_name where...
select sum(uid) from table_name where...

什么是存储过程?用什么来调用?
答:存储过程是一个预编译的SQL语句,优势是容许模块化的设计,就是说只需建立一次,之后在该程序中就能够调用屡次。若是某次操做须要执行屡次SQL,使用存储过程比单纯SQL语句执行要快。能够用一个命令对象来调用存储过程。

索引的做用?和它的优势缺点是什么?
答:索引就一种特殊的查询表,数据库的搜索引擎能够利用它加速对数据的检索。它很相似与现实生活中书的目录,不须要查询整本书内容就能够找到想要的数据。索引能够是惟一的,建立索引容许指定单个列或者是多个列。缺点是它减慢了数据录入的速度,同时也增长了数据库的尺寸大小。

什么是内存泄漏?
答:通常咱们所说的内存泄漏指的是堆内存的泄漏。堆内存是程序从堆中为其分配的,大小任意的,使用完后要显示释放内存。当应用程序用关键字new等建立对象时,就从堆中为它分配一块内存,使用完后程序调用free或者delete释放该内存,不然就说该内存就不能被使用,咱们就说该内存被泄漏了。

第二部分:J2EE体系结构图

第三部分,单元测试技术

  Junit单元测试,一个bug被隐藏的时间越长,修复这个bug的代价就越大。Junit是一个回归测试框架(regression testing framework),供Java开发人员编写单元测试。Junit测试是程序员测试,即所谓白盒测试。

 黑盒测试:是经过使用整个软件或某种软件功能来严格地测试, 而并无经过检查程序的源代码或者很清楚地了解该软件的源代码程序具体是怎样设计的。测试人员经过输入他们的数据而后看输出的结果从而了解软件怎样工做。在测试时,把程序看做一个不能打开的黑盆子,在彻底不考虑程序内部结构和内部特性的状况下,测试者在程序接口进行测试,它只检查程序功能是否按照需求规格说明书的规定正常使用,程序是否能适当地接收和正确的输出。
  白盒测试:是经过程序的源代码进行测试而不使用用户界面。这种类型的测试须要从代码句法发现内部代码在算法,溢出,路径,条件等等中的缺点或者错误,进而加以修正。
接下来咱们讲讲Junit的使用:
正常的规范的代码开发步骤:天天早上,先检索SVN,而后单元测试,若是没问题了。而后作本身的开发任务,作完以后,执行单元测试,若是没有问题,则提交服务器。测试中用到了Java中的一个关键字assert断言。
// 先下载junit.jar包放到eclipse的项目中

// 好比新建了一个类,以下:
package com.sunrun;
public class Calculate{
    public int add(int a , int b){
        return a+b;
    }  
    public int min(int a, int b){
        return a-b;
    }
}

//定义测试类的时候,常有以下规范:package包名与被测试类结构一致,这样的好处是不须要导入类的包,并且被编译后的.class文件是放在一块儿的。类名经常是TestXxx
package com.sunrun;  //不须要导入类哦!!!
import org.junit.Test;
import org.junit.Before;
import org.junit.Assert; //Junit4才会有
public class TestCalculate{
  Calculate cal;

  @Before //执行任意一个方法以前,都会执行这段代码
  public void setUp(){
    
  }
  @Test
  public int testAdd(){
    int rel = cal.add(2, 7);
    Assert.assertEquals("加法有问题", rel, 9); //(出错提示信息, 预期值, 实际值)
  } }
//Junit3和Junit4的差异很大 1.在Junit3中,测试类必须继承TestCase; 测试方法必须以testXxx开头,若是但愿在执行某个方法执行,都必须执行某个初始化方法,则该初始化方法必须命名为setUp;若是但愿在某个方法运行以后,都必须运行某个方法(如释放资源),则必须使用tear down.
2.在Junit4中,一个POJO类就是一个测试类,测试方法军用@Test来标识。初始化方法用@Before来标石,释放资源的方法用@After来标识。
3.Junit4总提供了一个类叫作Assert,它提供了大量的方法进行断言处理。Junit3中继承了TestCase类,类中提供了大量的assert方法。
总结:可是为了Junit4中的测试类在Junit3中也可使用,习惯于把初始化方法命名为setUp,释放资源的方法命名为tearDown;测试方法也一样以test开头(保持兼容)
 根据上面讲的,咱们引出了两个问题:第一,单元测试其中某一个方法的失败,并不会影响其余方法的测试(最致命的优势).第二,若是测试除法,是否能考虑到全部的测试用例。我想这就是从单元测试像自动化测试的转变。
//插播一下异常测试和性能测试

//若是抛出异常,则测试经过;不抛异常则测试不经过。适用于用户名和密码校验的应用场景
@Test(expected=ArithmetricException.class)
public void testDivided(int a, int b){
    int real = cal.divided(20, 0);              
}

//300毫秒执行完毕,才算正常。用于简单的性能测试。
@Test(timeout=300)
public void testTime(){
    try{
       Thread.sleep(500);
    } catch(Exception e){
        e.printStackTrace();
    } 
}
回顾一下Spring的事务(原子、一致、隔离、持久)
小回顾Spring事务管理的API,它提供了三个接口:
platformTransactionManager(平台事务管理器)
TransactionDefinition(事务定义信息:隔离、传播、超时、只读)
TransactionStatus(事务具体运行状态)
/*
*platformTransactionManager(平台事务管理器)
*TransactionDefinition(事务定义信息:隔离、传播、超时、只读)
*TransactionStatus(事务具体运行状态)
*/

//事务管理器
platformTransactionManager是一个接口,它有好多个实现类,咱们要掌握的就两个,一个是支持Hibernate的,另一个是支持JDBC和Mybatis的。
Hibernate:  HibernateTransactionManager  (org.springframework.orm.hibernate2.HibernateTransactionManager)
JDBC/Mybatis:  DataSourceTransactionManager (org.springframework.jdbc.datasource.DataSourceTransactionManager)

//事务定义信息
TransactionDefinition,它提供了事务的隔离级别和传播特性。

 模式篇--代理模式:(基本概念及其应用场景、几种实现方式)

  代理模式定义,为其余对象提供代理,以控制对这个对象的访问。代理对象起到中介的做用,能够新增额外服务,取消部分功能服务。(如:火车站代售处是火车站的代理;至关于一个中介的做用,它提供了电话订票服务(这是火车站没有的)同时取消了退票服务(火车站有的))。

  常见的集中代理模式:远程代理,为不一样地理的对象提供局域网的表明对象。(相似于客户端和服务器)。虚拟代理,根据须要将资源消耗很大的对象进行延迟,真正须要的时候再去建立。(相似于新闻页中的图片,新闻页的图片是真是图片的一个缩影,真正须要专门去看图片的时候才会去加载真正图片,你看一下两个图片大小就知道了。)保护代理,用于提供权限控制

 

/*
*  代理的两种实现方式:
*       1.静态代理
*       2.动态代理
*/

静态代理:代理和被代理对象在代理以前是肯定的。它们都实现相同的接口或者继承相同的抽象类。(继承方式和聚合方式)
动态打理:

 1 // 首先定义接口
 2 public interface Moveable {
 3     void run();
 4 }
 5 
 6 //定义了被代理类
 7 public class Car implements MOveable {
 8     
 9     @Overide
10     public void run() {
11         try{
12             Thread.sleep(new Random().nextInt(1000));
13         }catch (InterruptException e){
14              e.printStackTrace();
15         }
16     }
17 
18 }
19 
20 //在好久好久之前,咱们若是要记录汽车的行驶时间
21 public class Car implements MOveable {
22     long startTime = System.currentTimeMills();
23     @Override
24     public void run() {
25         try{
26             Thread.sleep(new Random().nextInt(1000));
27         }catch (InterruptException e){
28              e.printStackTrace();
29         }
30     }
31     long endTime= System.currentTimeMills();
32     System.out.println("汽车行驶时间:"+(endTime - startTime) +"毫秒!");
33 }
34 
35 //接下来演示一下使用继承方式和聚合方式来实现静态代理:
36 
37 //?Demo1,使用继承方式实现静态代理
38 public class Car2 extends Car {
39     @Override
40     public void move(){
41         long startTime = System.currentTimeMills();
42         super.move();
43         long endTime= System.currentTimeMills();
44         System.out.println("汽车行驶时间:"+(endTime - startTime) +"毫秒!");
45     }
46 }
47 
48 //?Demo2,使用聚合方式实现静态代理(聚合:一个类中调用另外一个对象)
49 public class Car3 implements Moveable {
50     private Car car;
51     public Car3(Car car){
52         super();
53         this.car = car;
54     }
55     @Override
56     public void move(){
57         long startTime = System.currentTimeMills();
58         car.move();
59          long endTime= System.currentTimeMills();
60         System.out.println("汽车行驶时间:"+(endTime - startTime) +"毫秒!");
61     }
62 }

 聚合方式比继承方式更适合代理模式

  分析以下:好比我如今有以下功能的叠加:时间处理;增长权限管理;增长日志处理。

/*
* 咱们先来看若是使用继承方式
*/

// 需求1:先记录日志,再记录汽车行驶的时间
/*
*  日志记录开始
*       汽车行驶开始
*       汽车行驶中
*       汽车行驶结束
*   日志记录结束
*/

// 需求2:先记录汽车行驶的时间,再记录日志
/*
*  汽车行驶开始
*       日志记录开始
*            汽车行驶中
*       日志记录结束
*  汽车行驶结束
*/

像上面这样,随着应用场景的叠加,代理类膨胀的函数达到n的阶乘(N!)

/*
* 咱们再来看若是使用聚合方式
* 聚合方式,代理类和被代理类实现相同的接口
* 使用聚合方式,会很是灵活
*/
// 公共接口
public interface Moveable {
    void run(){

    }
}
// 被代理类
public class Car implements Moveable{
    @Override
    public void run () {
        try{
            Thread.sleep();
        } catch (InterruptException e){
            e.printStackTrace();
        }
    }
}
//代理类一,实现时间处理
public class CarTimeProxy implements Moveable {
    private Moveable m;
    public CarTimeProxy (Moveable m){
        super();
        this.m = m;
    }
    @Override
    public void run(Moveable m) {
        long startTime = System.currentTimeMills();
        m.move();
        long endTime = System.currentTimeMills();
        System.out.println("运行时间:" + (endTime - startTime) + "毫秒!");
    }
}
//代理类二,实现日志的代理  (注意这里实现代理类的叠加)
public class CarLogProxy implements Moveable {
    private Moveable m;
    public CarLogProxy (Moveable m){
        super();
        this.m = m;
    }
    @Override
    public void run(Moveable m) {
        System.out.println("日志开始");
        m.move();
        System.out.println("日志结束");
    }
}

//接下来,咱们使用测试类看看聚合代理的灵活性
public class TestCar extends TestCase {
    public static void main(String args[]){
        Car car = new Car();
        
        /*
        * 功能叠加Demo 1
        * 先时间处理,后日志叠加
        */
        CarTimeProxy ctp = new CarTimeProxy(car);
        CarLogProxy clp = new CarLogProxy(ctp);
        clp.move();
        /*
        * 功能叠加Demo 2
        * 先记录日志,后时间处理功能叠加
        */
        CarLogProxy clp = new CarLogProxy(car);
        CarTimeProxy ctp = new CarTimeProxy(clp);
        ctp.move();
    }
}

总结一下上面的问题,解决了静态代理功能扩展的灵活性。那么若是咱们写火车、飞机、坦克的相应继承了Moveable的类,能不能复用上面的那些代理类呢?就是说一个TimeProxy同时实现了对火车、汽车、自行车的代理呢?接下来就引伸出来了动态代理。咱们来分析一下:

1 /*
2 * 动态代理但是一个高逼格的东西,包括JDK和Spring框架都是以它为基础构建的,咱们先来分析一下JDK中的动态代理。
3 *  动态的产生代理,实现对不一样类,不一样方法的代理。
4 */

 


如上图所示,ProxySubject是代理类,RealSubject是被代理类;ProxyHandler是实现了InvocationHandler接口的一个类(JDK提供),Proxy是动态产生的代理类。奉上代码:
// Demo展现
import java.lang.reflect.InvocationHandler;

public class TimeHandler implements InvocationHandler {
    private Object target;
    public TimeHandler(Object target){
        super();//调用父类构造方法
        this.target = target;
    }
    
    /*
    * 参数说明
    * Proxy 被代理对象
    * Method 被代理对象的方法
    * args[] 方法的参数
    *
    * 返回值
    * Object 方法的返回值
    **/
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) 
        throws Throwable{
        long startTime = System.currentTimeMills();
        method.invoke(target);
        long endTime = System.currentTimeMills();
        System.out.println("运行时间:" + (startTime - endTime));
        return null;
    }
}

// 来一个测试用例,生成动态代理类
public class Test {
    Car car = new Car(); //这部分省略了,固然Car是继承了Moveable接口的
    InvocationHandler h = new TimeHandler();
    Class<?> cls = car.getClass();

    /*
    * 参数说明(loader, interface, innovationHandler)
    * loader 类加载器
    * interface 实现接口
    * innovationHandler 
    **/
    Moveable m = (Moveable)Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterface(), h);
    m.move();
}
总结,所谓动态代理是这样一种类,它在运行的时候产生了一个class对象。该class须要实现一组interface,使用动态代理时,必须实现InvocationHandler接口。



说一下Lucene的搜索引擎机制:
//如搜索“数据结构 清华大学”
(content like '%数据结构%') or (content like '%清华大学%')
使用上面的like的方法,检索起来超级慢的,把用户都吓跑了 
Java基础回顾
 1 1.Java为何要单继承?既然单继承为何又要实现多个接口?
 2  一个类只能继承一个其余的类:
 3      在Java语言中禁止多重继承:一个类能够具备多个直接父类。多重继承不合法的缘由是容易引起意义不明确。例如,有一个类C,若是容许它同时继承A类与B类(class C extends A,B{}),假如A、B两个类都有同一种方法fun(),若是定义:
 4      C c = new C();
 5      那么c.fun()应该调用哪个父类的fun()方法?没法给出答案,所以Java语言禁止多重继承。 但C++倒是能够的,因此C++比起java在语法上却难了些。
 6 
 7      但一个类能够实现多个接口,这又是为何?
 8      这一特性和上一特性结合使用,能够得到和多重继承类似的效果。
 9      现假如类C实现了A与B两个接口(class c implements A,c{}),且这两个接口都有一个抽象fun()方法,如今调用方法时没有任务不明确的地方,由于接口中的全部方法都是抽象,而且超类的任何方法都需在子类中地覆盖实现,因此调用时实际上是调用本身自己的实现方法,没有什么调用不明确的说法。
10 2.Static、final迅速作出区分?
11 三个维度来看:基本类型变量,引用类型变量,方法、类。
12 final,修饰基本类型变量,变量不可变;修饰引用类型变量,内容能够变,不能再指向其余内容;修饰方法,指方法不可被继承;修饰类,类不能被继承。
13 static,修饰基本类型变量,就是全局变量;修饰引用类型变量,也是全局的;修饰方法;初始化一次;修饰类,通常内部类才申明为静态的,静态内部类。静态的不能调用非静态的。
View Code
相关文章
相关标签/搜索