Java面试题

1.Servlet执行流程

    客户端发出http请求,web服务器将请求转发到servlet容器,servlet容器解析url并根据web.xml找到相对应的servlet,并将requestresponse对象传递给找到的servletservlet根据request就可以知道是谁发出的请求,请求信息及其他信息,当servlet处理完业务逻辑后会将信息放入到response并响应到客户端。

2.SpringMVC的执行流程

 springMVC是由dispatchservlet为核心的分层控制框架。首先客户端发出一个请求web服务器解析请求url并去匹配dispatchservlet的映射url,如果匹配上就将这个请求放入到dispatchservletdispatchservlet根据mapping映射配置去寻找相对应的handel,然后把处理权交给找到的handelhandel封装了处理业务逻辑的代码,当handel处理完后会返回一个逻辑视图modelandviewdispatchservlet,此时的modelandview是一个逻辑视图不是一个正式视图,所以dispatchservlet会通过viewresource视图资源去解析modelandview,然后将解析后的参数放到view中返回到客户端并展现。

 3.struts2的执行流程

    a)请求经过一系列的过滤器,FilterDispatcher被调用

    b)ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy

    c)ActionProxy通过ConfigurationManager询问框架配置文件找到需要调用的Action类

    d)ActionProxy创建一个ActionInvocation实例

e)ActionInvocation调用、回调Action的execute方法

f) Action执行完毕ActionInvocation根据struts.xml配置找到对应的返回结果

3、给定一个txt文件,如何得到某字符串出现的次数

File file = new File("E://test.txt");

InputStream is = new FileInputStream(file);

byte b[] = new byte[1024];

int a = is.read(b);

String str[] = new String(b,0,a).split("");

int count = 0;

for(int i = 0;i<str.length;i++){

if("a".equals(str[i]))count++;

}

System.out.println(count);

4、Java设计模式思想(单列模式,工厂模式,策略模式,代理模式,共23种设计模式)

a)单例模式:单例模式的核心是只需要new一个实例对象的模式,比如数据库的连接,在线人数等,一些网站上看到的在线人数统计就是单例模式实现的,把一个计时器存放在数据库或者是内存中,当有人登入的时候取出来加一再放回去,有人退出的时候取出来减一再放回去,但当有两个人同时登入的时候,会同时取出计时器,同时加一,这样的话数据就会出差错,所以需要一个全局变量的对象给全部人使用,只需要new出一个实例对象,这就是单例对象的应用,并且单例模式节省资源,因为他控制了实例对象的个数,并有利于gc

单例模式的核心设计代码:

public class Singleton{
     private Singleton(){
     }
     public Singleton getInstance(){
          Singleton single = new Singleton();
          return single;
     }
}

b)策略模式:策略模式的核心就是将几个类中公共的方法抽取到一个新的类之中,从而扩展更容易,保证代码的可移植性,可维护性强。比如有个需求是写鸭子对象,鸭子有叫、飞、外形这三个方法,如果每个鸭子类都写这三个方法会出现代码的冗余,这个时候我们可以把这三个方法抽取出来,放到鸭子的父类中,让每个鸭子都继承这个父类,重写这三个方法,这样封装的代码可移植性强,当用户提出新的需求,比如鸭子游泳的方法,只需要在父类中添加游泳的方法,这样鸭子就具备了游泳这个能力,重写父类的方法就好了

策略模式的详细讲解:https://www.cnblogs.com/java2016/p/5386615.html

c)工厂设计模式:简单的工厂模式主要是统一提供实例对象的引用,通过工厂模式接口获取实例对象的引用。比如一个登陆功能,后端有三个类,controller类,interface类,实现接口的实现类。当客户端发出一个请求,当请求传到controller类中时,controller获取接口的引用对象,而实现接口的实现类中封装好了登陆的业务逻辑代码。当你需要加一个注册需求的时候只需要在接口类中加一个注册方法,实现类中实现方法,controller获取接口的引用对象即可,不需要改动原来的代码,这种做法是的可拓展性强。

工厂模式的扩展:

  1)简单的工厂设计模式

  

interface Fruit {
    public void eat() ;
}
class Apple implements Fruit {
    public void eat() {
        System.out.println("吃苹果。");
    };
}
class Factory {
    public static Fruit getInstance(String className) {
        if ("apple".equals(className)){
            return new Apple() ;
        }
        return null ;
    }
}
public class FactoryDemo {
    public static void main(String[] args) {
        Fruit f = Factory.getInstance("apple") ;
        f.eat() ;
    }
}

  2)基于java反射机制的工厂设计模式

  

interface Fruit {
    public void eat() ;
}
class Apple implements Fruit {
    public void eat() {
        System.out.println("吃苹果。");
    };
}
class Orange implements Fruit {
    public void eat() {
        System.out.println("吃橘子。");
    };
}
class Factory {
    public static Fruit getInstance(String className) {
        Fruit f = null ;
        try {
            f = (Fruit) Class.forName(className).newInstance() ;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return f ;
    }
}
public class FactoryDemo {
    public static void main(String[] args) {
        Fruit f = Factory.getInstance("cn.mldn.demo.Orange") ;
        f.eat() ;
    }
}

d)静态代理模式与动态代理模式(AOP就是基于JDK和CGLIB动态代理技术实现的,在这不详细说明)

 5、冒泡排序、二分查找

a)冒泡

   

public static void mp(int a[]) {

 

int swap = 0;

for (int i = 0; i < a.length; i++) {

 

for (int j = i; j < a.length; j++) {

if (a[j] > a[i]) {

swap = a[i];

a[i] = a[j];

a[j] = swap;

}

}

}

 

System.out.println(Arrays.toString(a));

}
b)二分查找
public static int ef(int a[], int tag) {

 

int first = 0;

int end = a.length;

for (int i = 0; i < a.length; i++) {

int middle = (first + end) / 2;

 

if (tag == a[middle]) {

return middle;

}

if (tag > a[middle]) {

first = middle + 1;

}

if (tag < a[middle]) {

end = middle - 1;

}

 

}

return 0;

}

6、ajax的理解

a) Ajax为异步请求,即局部刷新技术,在传统的页面中,用户需要点击按钮或者事件触发请求,到刷新页面,而异步技术为不需要点击即可触发事件,这样使得用户体验感增强,比如商城购物车的异步加载,当你点击商品时无需请求后台而直接动态修改参数。

9、父类与子类之间的调用顺序(打印结果)

a) 父类静态代码块

b) 子类静态代码块

c) 父类构造方法

d) 子类构造方法

e) 子类普通方法

f) 重写父类的方法,则打印重写后的方法

10、内部类与外部类的调用

a) 内部类可以直接调用外部类包括private的成员变量,使用外部类引用的this.关键字调用即可

b) 而外部类调用内部类需要建立内部类对象

11、多线程

a)一个进程是一个独立的运行环境,可以看做是一个程序,而线程可以看做是进程的一个任务,比如QQ是一个进程,而一个QQ窗口是一个线程。

b)在多线程程序中,多线程并发可以提高程序的效率,cpu不会因为某个线程等待资源而进入空闲状态,它会把资源让给其他的线程。

c)用户线程就是我们开发程序是创建的线程,而守护线程为系统线程,如JVM虚拟中的GC

d)线程的优先级别:每一个线程都有优先级别,有限级别高的可以先获取CPU资源使该线程从就绪状态转为运行状态。也可以自定义线程的有限级别

e)死锁:至少两个以上线程争取两个以上cpu资源,避免死锁就避免使用嵌套锁,只需要在他们需要同步的地方加锁和避免无限等待

12、AOPIOC的概念(即spring的核心)

a) IOCSpring是开源框架,使用框架可以使我们减少工作量,提高工作效率并且它是分层结构,即相对应的层处理对应的业务逻辑,减少代码的耦合度。而spring的核心是IOC控制反转和AOP面向切面编程。IOC控制反转主要强调的是程序之间的关系是由容器控制的,容器控制对象,控制了对外部资源的获取。而反转即为,在传统的编程中都是由我们创建对象获取依赖对象,而在IOC中是容器帮我们创建对象并注入依赖对象,正是容器帮我们查找和注入对象,对象是被获取,所以叫反转。

b) AOP:面向切面编程,主要是管理系统层的业务,比如日志,权限,事物等。AOP是将封装好的对象剖开,找出其中对多个对象产生影响的公共行为,并将其封装为一个可重用的模块,这个模块被命名为切面(aspect),切面将那些与业务逻辑无关,却被业务模块共同调用的逻辑提取并封装起来,减少了系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。

13、hibernate的核心思想

a) Hibernate的核心思想是ROM对象关系映射机制。它是将表与表之间的操作映射成对象与对象之间的操作。也就是从数据库中提取的信息会自动按照你设置的映射要求封装成特定的对象。所以hibernate就是通过将数据表实体类的映射,使得对对象的修改对应数据行的修改。

16、Arraylistlinkedlist的区别

a) 都是实现list接口的列表,arraylist是基于数组的数据结构,linkedlist是基于链表的数据结构,当获取特定元素时,ArrayList效率比较快,它通过数组下标即可获取,而linkedlist则需要移动指针。当存储元素与删除元素时linkedlist效率较快,只需要将指针移动指定位置增加或者删除即可,而arraylist需要移动数据。

20、HTTP协议

a) 常用的请求方法有getpost

b) Getpost的区别:传送数据,get携带参数与访问地址传送,用户可以看见,这的话信息会不安全,导致信息泄露。而post则将字段与对应值封装在实体中传送,这个过程用户是不可见的。Get传递参数有限制,而post无限制。

27、事物的理解

a) 事物具有原子性,一致性,持久性,隔离性

b) 原子性:是指在一个事物中,要么全部执行成功,要么全部失败回滚。

c) 一致性:事物执行之前和执行之后都处于一致性状态

d) 持久性:事物多数据的操作是永久性

e) 隔离性:当一个事物正在对数据进行操作时,另一个事物不可以对数据进行操作,也就是多个并发事物之间相互隔离。

28、Hibernate对象的三种状态

     Hibernate中对象有三种状态: 临时状态(Transient)、持久状态(Persistent)、游离状态(Detached)。

  临时状态:刚刚使用new语句创建,还没有被持久化,不处于Session的缓存中。处于临时状态的状态的Java对象被称为临时对象。

  持久化状态:已经被持久化,加入到Session的缓存中。处于持久化状态的Java对象被称为持久化对象。

  游离状态:已经被持久化,但不处于session的缓存中。处于游离状态的Java对象被称为游离对象。

29.hibernate中get方法和load方法的区别

   a)如果数据库中没有相关的oid,使用get方法返回的是null,而使用load方法返回的是代理对象,使用代理对象调用对象的方法会抛出异常

   b)get方法不支持延迟加载,而get方法支持延迟加载

30.Hibernate的优缺点

  优点:

    a)对jdbc访问数据库提供了方便,简化了数据访问层繁琐的重复性代码

    b)对象关系映射非常的灵活,降低了编写sql的难度

    c)非侵入性,移植性好

    d) 提供了一级缓存和二级缓存

  缺点:

    a)对sql进行优化困难

    b)框架中使用ORM规则,配置复杂

    c)执行效率较比原生sql效率低,特别是在批量处理数据的时候

    d)不支持批量修改、删除

 31.Hibernate中opensessionview的问题

   ①. 用于解决懒加载异常, 主要功能就是把 Hibernate Session 和一个请求的线程绑定在一起, 直到页面完整输          出, 这样就可以保证页面读取数据的时候 Session 一直是开启的状态, 如果去获取延迟加载对象也不会报错。
   ②. 问题: 如果在业务处理阶段大批量处理数据, 有可能导致一级缓存里的对象占用内存过多导致内存溢出, 另外一        个是连接问题: Session 和数据库Connection 是绑定在一起的, 如果业务处理缓慢也会导致数据库连接得不到        及时的释放, 造成连接池连接不够. 所以在并发量较大的项目中不建议使用此种方式, 可以考虑使用迫切左外连        接 (LEFT OUTER JOIN FETCH) 或手工对关联的对象进行初始化.
   ③. 配置 Filter 的时候要放在 Struts2 过滤器的前面, 因为它要页面完全显示完后再退出.

32. Hibernate  中 getCurrentSession()  和 openSession ()  的区别 ?
   ①. getCurrentSession() 它会先查看当前线程中是否绑定了 Session,如果有则直接返回, 如果没有再创建. 而                                openSession() 则是直接 new 一个新的 Session 并返回。
   ②. 使用 ThreadLocal 来实现线程 Session 的隔离。

   ③. getCurrentSession() 在事务提交的时候会自动关闭 Session, 而openSession() 需要手动关闭.

33.说说Hibernate的缓存机制

   Hibernate  缓存包括两大类 :

   Hibernate  一级缓存和 Hibernate  二级缓存: :

    1). Hibernate 一级缓存又称为“Session 的缓存”,它是内置的,不能被卸载。由于 Session 对象的生命周期通常对应一           个数据库事务或者一个应用事务,因此它的缓存是事务范围的缓存。在第一级缓存中,持久化类的每个实例都具有唯一的           OID

   2)Hibernate 二级缓存又称为“SessionFactory 的缓存”,由于SessionFactory 对象的生命周期和应用程序的整个过程           对应,因此 Hibernate二级缓存是进程范围或者集群范围的缓存,有可能出现并发问题,因此需要采用适当的并发访问策         略,该策略为被缓存的数据提供了事务隔离级别。第二级缓存是可选的,是一个可配置的插件。


     当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中      查;如果都查不到,再查询数据库,把结果按照 ID 放入到缓存删除、更新、增加数据的时候,同时更新缓存。

 34.说说spring中bean的生命周期

(1).首先实例化一个bean

(2).按照spring的上下文对实例化的bean进行配置,也就是IOC

(3).如果该bean实现了BeanNameAware接口,则会调用其setBeanName(String beanId)方法

(4).如果该bean实现了BeanFactoryAware接口,则会调用其setBeanFactory()方法,可以用于获取其它的bean

(5).如果该bean实现了ApplicationContextAware接口,则会调用其setApplicationContext()方法,用于获取spring的上下文对象

(6).如果该bean实现了BeanPostProgressor接口,则会调用其PostProgressorBeforeInitiaized方法,执行该方法时bean已经实例化好了,但是属性还没有注入,因此通常用于对bean的修改

(7).如果在spring文件中该bean中定义了init-method方法,则会调用其定义的初始化方法

(8).如果该bean实现了BeanPostProgressor接口,则会调用其PostProgressorAfterInitaized方法

(9).当该bean不再使用的时候,如果bean实现了DisposableBean接口,则会其destory方法

(10).如果该bean在spring配置文件中定义了destory-method方法,则会调用其定义的销毁方法



    




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值