java常见面试题

本文详细介绍了Java面试中常见的知识点,包括Servlet的生命周期、Tomcat与Servlet的工作原理、JSP的生命周期、Java对象的创建方式、线程同步、JDBC流程、事务特性、设计模式(尤其是单例模式)以及并发控制、数据库操作和框架对比等。通过阅读,读者可以全面了解Java面试的重要知识点,为面试做好充分准备。
摘要由CSDN通过智能技术生成

生命周期

一个对象从产生到死亡的过程

Servlet的生命周期

Servlet是运行在Servlet容器中的, 其生命周期是由容器管理的

 

Servlet的生命周期有四个阶段:

加载并实例化

初始化

请求处理

销毁

 

加载并实例化:

Servlet容器负责加载和实例化Servlet

当Servlet容器启动后, Servelt通过类加载器来加载Servlet类, 加载完成之后再new一个Servlet对象来完成实例化

 

初始化:

在Servlet实例化后, 容器将调用init()方法

在Servlet的整个生命周期中, init()方法只被调用一次

 

请求处理:

当Servlet初始化后, 容器就可以准备处理请求了

当容器收到对Servlet的请求, 就调用Servlet的service()方法,并把请求和响应对象作为参数传递

 

销毁:

一旦Servlet容器检测到一个Servlet要被卸载, 这可能就是因为要回收资源或者因为它正在被关闭, 容器会在所有Servlet的servlce()线程之后, 调用destory()方法, Servlet对象就被销毁了

 

Tomcat 与 Servlet 是如何工作的

步骤:

Web Client 向Servlet容器(Tomcat)发出Http请求

Servlet容器接收Web Client的请求

Servlet容器创建一个HttpRequest对象,将Web Client请求的信息封装到这个对象中。

Servlet容器创建一个HttpResponse对象

Servlet容器调用HttpServlet对象的service方法,把HttpRequest对象与HttpResponse对象作为参数传给HttpServlet 对象。

HttpServlet调用HttpRequest对象的有关方法,获取Http请求信息。

HttpServlet调用HttpResponse对象的有关方法,生成响应数据。

Servlet容器把HttpServlet的响应结果传给Web Client。

jsp 的生命周期

转换,编译,加载并实例化,初始化(_jspInit),请求处理(_jspService()调用),销毁(_jspDestory())。

    转换:就是web容器将JSP文件转换成一个包含了Servlet类定义的java源文件。

    编译:把在转换阶段创建的java源文件编译成类文件。

    JSP 生命周期其他的四个阶段跟Servlet生命周期相同

==与equals的区别

==号比较基本数据类型时比较的是值, 而比较引用类型是话, 比较的是它们的地址值

 

equals()方法是存在于Object类中的, 因为Object类是所有类的直接或间接父类, 也就是说所有类的equals方法都是继承自Object类的, 而Object类中的equals()方法底层依赖的是==号, 所以, 在没有重写equals()方法的类中, 调用equals方法和==的效果是一样的, 是比较地址值, 重写equals方法之后, 一般比较的是两个对象里面的内容, 比如String Date等类

 

String和StringBuilder,StringBuffer的区别

 

1 运行速度上:

     按快慢顺序为: StringBuilder> StringBuffer > String

     String慢的原因:

String是字符串常量, 而StringBuilder和StringBuffer均为字符串变量

     即String对象一旦创建之后, 对象是不可更改的, 后两者的对象是变量, 是可以更改的

 

2 本质上:

String是字符常量, Stirng的值是不可改变的, 这就导致每次对String的操作都会产生新的String对象, 效率低, 而且大量浪费内存空间

StringBuilder是jdk1.5提出的, StringBuilder和StringBuffer最大的区别是线程安全, StringBuilder是线程安全的

 

    StringBuffer的扩容机制, 初始容量是16个字符, 扩容的话是增加原来的一倍加2

 

Cookie和session的区别

Cook:

 在网站中, http请求是无状态的, 也就是说即使第一次和服务器连接后并且登录成功后, 第二次请求服务器依然不能知道当前请求是哪个用户, cookie的出现就是为了解决这个问题, 第一次登录后服务器返回一些数据(cookie)给浏览器, 然后浏览器保存在本地, 当该用户发送第二次请求的时候, 会自动携带上次存储的cookie数据给服务器, 服务器通过, 浏览器携带的cookie数据就能判断是哪个用, Cookie的存储数量是有限的, 一般不超过4kb, 因此使用cookie只能存储一些小量的数据

Session:

Session的作用和cookie有点类似, 都是为了存储用户信息, 不同的是: cookie存储在本地浏览器, 而session存储在服务器, 存储在服务器的数据更加安全, 不容易被窃取, 但是存储在服务器也有弊端, 就是会占用服务器资源

 

 

Jsp中的四个作用域

PageContext, request, session, application

PageContext:

把变量放在pageContext里, 就说明它的作用域是page, 有效范围只在当前jsp页面里面,  从把变量放到pageContext开始, 到jsp页面结束都可以使用这个变量

Request:

如果把变量放到request里, 说明它的作用域是request, 它的有效范围是当前请求周期, 所谓的周期就是从http请求发起, 到服务器处理结束, 返回响应响应的整个过程, 在这个过程可能使用forward的方式跳转了多个jsp页面, 在这些页面你都可以使用这个变量

Session:

如果把便变量放到session里, 说明它的作用域是session, 它的有效范围是当前会话, 所谓当前会话, 就是指用户打开浏览器开始, 到用户关闭浏览器这中间的过程, 这个过程可能包含多个请求, 也就是说, 只用用户不关闭浏览器, 服务器就有办法知道这些请求是一个人发起的, 整个过程就被称为一个会话

Appilication:

  如果把变量放到application里, 就说明它的作用域是application, 它的有效范围是整个应用, 整个应用就是指从应用开始到应用结束

Application作用域的变量, 它们存活时间是最长的, 如果不手工进行删除, 它们就一直可以使用, 而且application里面的变量可以被其他用户共享 , 假如a用户修改了变量, 那么b用户得到的就是a用户修改后的值

九个内置对象

1. 输出输入对象:request对象、response对象、out对象

2. 通信控制对象:pageContext对象、session对象、application对象

3. Servlet对象:page对象、config对象

4. 错误处理对象:exception对象

 

Jsp内置对象

功能

主要方法

out

向客户端输出数据

print() println() flush() clear() isAutoFlush() getBufferSize() close() …………

request

向客户端请求数据

getAttributeNames() getCookies() getParameter() getParameterValues() setAttribute() getServletPath() …………..

response

封装了jsp产生的响应,然后被发送到客户端以响应客户的请求

addCookie() sendRedirect() setContentType()

flushBuffer() getBufferSize() getOutputStream()

sendError() containsHeader()……………

application

 

 

config

表示Servlet的配置,当一个Servlet初始化时,容器把某些信息通过此对象传递给这个Servlet

getServletContext() getServletName() getInitParameter() getInitParameterNames()……………

page

Jsp实现类的实例,它是jsp本身,通过这个可以对它进行访问

flush()………

pagecontext

为JSP页面包装页面的上下文。管理对属于JSP中特殊可见部分中己经命名对象的该问

forward() getAttribute() getException() getRequest() getResponse() getServletConfig()

getSession() getServletContext() setAttribute()

removeAttribute() findAttribute() ……………

session

用来保存每个用户的信息,以便跟踪每个用户的操作状态

getAttribute() getId() getAttributeNames() getCreateTime() getMaxInactiveInterval()

invalidate() isNew()

exception

反映运行的异常

getMessage()…………

 

 

ArrayList和LinkedList的区别

1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 
2.对于随机访问get和set,

ArrayList觉得优于LinkedList,因为LinkedList要移动指针。 
3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。 

Java常用的设计模式有哪些

单例模式

什么是单例

所谓单例就是所有的请求都是用一个对象来处理

比如说我们常用的servlce dao

 

对于struts2来说,action必须用多例,因为action本身含有请求参数的值,即可改变的状态;

 

核心就是三私一公;

1、私有化的构造方法

2、私有化的克隆方法

3、私有化的静态变量

4、公共的静态方法

  为什么要设置这三私一公呢?

1、私有化的构造方法是为了避免在类外使用 new class  来创建对象实体,我们只允许使用我们设定好的公共方法来建立实例。

2、私有化的克隆方法是为了避免在使用公共方法获取实例后,再通过clone的方法将对象实体克隆出新的对象(这就不再是单一对象了)

3、私有化的静态变量,用于存储类的实例化对象  

4、公共的静态方法,用于存储实例化的对象,供外界获取

 

单例模式的优点

在内存中只有一个对象,节省内存空间;

避免频繁的创建销毁对象,可以提高性能;

避免对共享资源的多重占用,简化访问;

为整个系统提供一个全局访问点。

 

单例模式的实现

 

懒汉式

延迟加载, 也就是需要的时候才去创建实例, 不用的时候不创建

饿汉式

立即加载, 类加载初始化的时候就主动创建实例

 

比较的话, 从速度和反应时间角度来看, 立即加载好一些, 从资源内存方面的话, 延迟加载好一些

 

单例是如何保证系统中实例只有一份

单例是为了保证系统中只有一个实例,其关键点有5

一.私有构造函数

二.声明静态单例对象

三.构造单例对象之前要加锁(lock一个静态的object对象)

四.需要两次检测单例实例是否已经被构造,分别在锁之前和锁之后

0.为何要检测两次?

如上面所述,有可能延迟加载或者缓存原因,造成构造多个实例,违反了单例的初衷。

1.构造函数能否公有化?

不行,单例类的构造函数必须私有化,单例类不能被实例化,单例实例只能静态调用

2.lock住的对象为什么要是object对象,可以是int吗?

不行,锁住的必须是个引用类型。如果锁值类型,每个不同的线程在声明的时候值类型变量的地址都不一样,那么上个线程锁住的东西下个线程进来会认为根本没锁,相当于每次都锁了不同的门,没有任何卵用。而引用类型的变量地址是相同的,每个线程进来判断锁多想是否被锁 的时候都是判断同一个地址,相当于是锁在通一扇门,起到了锁的作用。

 

线程的创建方式有几种

1. 继承Thread类, 重写run方法, 将线程要完成的任务写在run方法里面, 调用线程对象的start()方法启动该线程2. 通过Runnable接口创建线程类, 实现runnable接口的实现类, 重写该接口的run方法创建Runnable实现类的实例, 并依此实例作为Thread的 target来创建Thread对象调用线程对象的start()方法来启动线程3. 通过Callable和Future创建线程

创建Callable接口的实现类, 并重写call方法, 该方法有返回值

创建实现类的实例, 使用FutureTask类来包装Callable对象, 该FutureTask对象封装了Callable对象的call()方法的返回值

使用FutureTask对象作为Thread对象的target创建并启动线程

调用FutureTask对象的get()方法获得子线程执行结束后的返回值

怎么保证线程的顺序执行

Join方法

线程池

为数据库连接建立缓存池,

从连接池获取可有连接, 使用完毕之后, 把连接返回给连接池

在系统关闭之前,断开所有连接并释放连接占用的系统资源

好处:

减少频繁创建数据库连接, 降低资源消耗, 线程复用

提高了相应速度

提高了线程可管理性

 

线程同步

1 同步方法

2 同步代码块

3 ThreadLocal局部变量

JDBC的开发流程是什么

1 加载驱动

2 创建连接对象

3 创建sql语句语句对象

4 执行语句对象, 获得结果集

5 处理结果集

6 关闭资源

事务

什么是事务

一组逻辑性的操作, 在一个业务中, 多个sql语句执行, 要么全部都成功, 要么全部都失败

就是说, 把一对事情绑在一起做, 同享福同患难的样子

事务有四大特性

原子性  

每个事务都是不可分割的, 就是不可以只执行其中的一部分, 要么全部成功要么全部失败

一致性  

事务执行前和执行后, 数据库的状态应该是一致的

就比如说: 转账操作, 转账前和转账后两个的总金额应该是一样的

隔离性

同时有多个事务在执行的话, 每个事务都是独立的, 相互之间不会有影响和依赖

持久性

事务的一旦提交, 对数据库影响是持久的, 就算关闭服务器, 数据也是持久存在的

事务的隔离级别

脏读

一个事务读取了另一个事务未提交的的数据

不可重复读

一个事务中两次读取的数据内容不一致

这是update时引发的问题

幻读

一个事务中两次读取的数据的数量不一致

这是insert或delete时引发的问题

什么是存储过程? 有什么优点

存储过程是一组为完成特定功能功能的SQL语句集, 经编译后存储在数据库, 用户通过指定存储过程的名字执行

优点:

1 存储过程因为SQL语句已经进行了编译,运行速度比较快

2 运行比较稳定, 只要一次成功, 以后都会按这个程序运行

3 对数据库进行多表的复杂操作时, 可以将操作用存储过程封装起来, 与事务处理结合在一起使用

4 存储过程可以重复使用, 减少了数据库开发人员的工作量

5 安全性高, 可设定只有此用户才具有对指定存储过程的使用权

6 存储过程是运行在服务器的, 减少了客户机的压力

MyBaits,Jdbc, Hibernate区别是什么

Jdbc的缺点:

1 工作量比较大,

Mybaits:

1 相对轻量级的持久层框架, 封装了jdbc, 不支持事务无关性,

MyBatis的优缺点是什么

优点:

1 是最简单的持久化框架, 小巧并且容易学

2 sql写在xml里面, 从程序代码中彻底分离, 降低耦合度, 便于管理优化

3 提供xml标签, 支持编写动态sq语句

4 提供映射标签, 支持对象与数据库的ORM字段关系映射

缺点:

MyBatis的缓存机制是什么值传递和应用传递的区别

值传递传递的是基本类型, 调用方法时, 实际值复制一份给方法的形参, 由于是复制, 所以

JavaScript的数据类型都有什么

Boolean

Object

Number

String

Undefined

Servlet的开发流程是什么转发和重定向的区别

1.转发在服务器端完成的;重定向是在客户端完成的

2.转发的速度快;重定向速度慢

3.转发的是同一次请求;重定向是两次不同请求

4.转发不会执行转发后的代码;重定向会执行重定向之后的代码

5.转发地址栏没有变化;重定向地址栏有变化

6.转发必须是在同一台服务器下完成;重定向可以在不同的服务器下完成

 

 

转发过程:客户浏览器发送http请求,web服务器接受此请求,调用内部的一个方法在容器内部完成请求处理和转发动作,将目标资源发送给客户;在这里,转发的路径必须是同一个web容器下的url,其不能转向到其他的web路径上去,中间传递的是自己的容器内的request。在客户浏览器路径栏显示的仍然是其第一次访问的路径,也就是说客户是感觉不到服务器做了转发的。转发行为是浏览器只做了一次访问请求。

重定向过程:客户浏览器发送http请求,web服务器接受后发送302状态码响应及对应新的location给客户浏览器,客户浏览器发现是302响应,则自动再发送一个新的http请求,请求url是新的location地址,服务器根据此请求寻找资源并发送给客户。在这里location可以重定向到任意URL,既然是浏览器重新发出了请求,则就没有什么request传递的概念了。在客户浏览器路径栏显示的是其重定向的路径,客户可以观察到地址的变化的。重定向行为是浏览器做了至少两次的访问请求的。

重定向,其实是两次request

第一次,客户端request
A,服务器响应,并response回来,告诉浏览器,你应该去B。这个时候IE可以看到地址变了,而且历史的回退按钮也亮了。重定向可以访问自己web应用以外的资源。在重定向的过程中,传输的信息会被丢失。

 

HashMap与HashTable的区别

1 作者不同

HashMap比HashTable多了一位并发大神Doug Lea

 

2 产生时间不同

HashTable是java发布产生的

HashMap是JDK1.2出来的

虽然HashTable比HashMap出来的时间比较早, 但是基本已经被弃用

原因:HashTable是线程安全的, 效率比较低 没有驼峰命名法

 

3继承的父类不同

HashMap和Hashtable不仅作者不同,而且连父类也是不一样的。HashMap是继承自AbstractMap类,而HashTable是继承自Dictionary类。不过它们都实现了同时实现了map、Cloneable(可复制)、Serializable(可序列化)这三个接口

Dictionary类是一个已经被废弃的类(见其源码中的注释)。父类都被废弃,自然而然也没人用它的子类Hashtable了。

 

4 对外提供的接口不同 
Hashtable比HashMap多提供了elments() 和contains() 两个方法。

elments() 方法继承自Hashtable的父类Dictionnary。elements() 方法用于返回此Hashtable中的value的枚举。

contains()方法判断该Hashtable是否包含传入的value。它的作用与containsValue()一致。事实上,contansValue() 就只是调用了一下contains() 方法。

5 对Null key 和Null value的支持不同 
Hashtable既不支持Null key也不支持Null value。Hashtable的put()方法的注释中有说明。 
当key为Null时,调用put() 方法,运行到下面这一步就会抛出空指针异常。因为拿一个Null值去调用方法了。 

当value为null值时,Hashtable对其做了限制,运行到下面这步也会抛出空指针异常。 

HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,可能是 HashMap中没有该键,也可能使该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键, 而应该用containsKey()方法来判断。

6 线程安全性不同 
Hashtable是线程安全的,它的每个方法中都加入了Synchronize方法。在多线程并发的环境下,可以直接使用Hashtable,不需要自己为它的方法实现同步

HashMap不是线程安全的,在多线程并发的环境下,可能会产生死锁等问题。具体的原因

 

虽然HashMap不是线程安全的,但是它的效率会比Hashtable要好很多。这样设计是合理的。在我们的日常使用当中,大部分时间是单线程操作的。HashMap把这部分操作解放出来了。当需要多线程操作的时候可以使用线程安全的ConcurrentHashMap。ConcurrentHashMap虽然也是线程安全的,但是它的效率比Hashtable要高好多倍。因为ConcurrentHashMap使用了分段锁,并不对整个数据进行锁定。

7 遍历方式的内部实现上不同 
Hashtable、HashMap都使用了 Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式 。

HashMap的Iterator是fail-fast迭代器。当有其它线程改变了HashMap的结构(增加,删除,修改元素),将会抛出ConcurrentModificationException。不过,通过Iterator的remove()方法移除元素则不会抛出ConcurrentModificationException异常。但这并不是一个一定发生的行为,要看JVM。

JDK8之前的版本中,Hashtable是没有fast-fail机制的。在JDK8及以后的版本中 ,HashTable也是使用fast-fail的, 源码如下: 

modCount的使用类似于并发编程中的CAS(Compare and Swap)技术。我们可以看到这个方法中,每次在发生增删改的时候都会出现modCount++的动作。而modcount可以理解为是当前hashtable的状态。每发生一次操作,状态就向前走一步。设置这个状态,主要是由于hashtable等容器类在迭代时,判断数据是否过时时使用的。尽管hashtable采用了原生的同步锁来保护数据安全。但是在出现迭代数据的时候,则无法保证边迭代,边正确操作。于是使用这个值来标记状态。一旦在迭代的过程中状态发生了改变,则会快速抛出一个异常,终止迭代行为。

8 初始容量大小和每次扩充容量大小的不同 
Hashtable默认的初始大小为11,之后每次扩充,容量变为原来的2n+1。HashMap默认的初始化大小为16。之后每次扩充,容量变为原来的2倍。

创建时,如果给定了容量初始值,那么Hashtable会直接使用你给定的大小,而HashMap会将其扩充为2的幂次方大小。也就是说Hashtable会尽量使用素数、奇数。而HashMap则总是使用2的幂作为哈希表的大小。

之所以会有这样的不同,是因为Hashtable和HashMap设计时的侧重点不同。Hashtable的侧重点是哈希的结果更加均匀,使得哈希冲突减少。当哈希表的大小为素数时,简单的取模哈希的结果会更加均匀。而HashMap则更加关注hash的计算效率问题。在取模计算时,如果模数是2的幂,那么我们可以直接使用位运算来得到结果,效率要大大高于做除法。HashMap为了加快hash的速度,将哈希表的大小固定为了2的幂。当然这引入了哈希分布不均匀的问题,所以HashMap为解决这问题,又对hash算法做了一些改动。这从而导致了Hashtable和HashMap的计算hash值的方法不同 
9 计算hash值的方法不同 

Servlet和filter的区别


1.概念。
2.生命周期。
3.职责。

4.执行过程。

    一、概念:
         1、servlet:servlet是一种运行服务器端的java应用程序,具有独立于平台和协议的特性,并且可以动态的生成web页面,它工作在客户端请求与服务器响应的中间层。
 
         2、filter:filter是一个可以复用的代码片段,可以用来转换HTTP请求、响应和头信息。Filter不像Servlet,它不能产生一个请求或者响应,它只是修改对某一资源的请求,或者修改从某一的响应。
       二、生命周期:
        1、servlet:servlet的生命周期始于它被装入web服务器的内存时,并在web服务器终止或重新装入servlet时结束。servlet一旦被装入web服务器,一般不会从web服务器内存中删除,直至web服务器关闭或重新结束。
        (1)、装入:启动服务器时加载Servlet的实例;
        (2)、初始化:web服务器启动时或web服务器接收到请求时,或者两者之间的某个时刻启动。初始化工作有init()方法负责执行完成;
        (3)、调用:从第一次到以后的多次访问,都是只调用doGet()或doPost()方法;
        (4)、销毁:停止服务器时调用destroy()方法,销毁实例。 
 
        2、filter:(一定要实现javax.servlet包的Filter接口的三个方法init()、doFilter()、destroy(),空实现也行)
        (1)、启动服务器时加载过滤器的实例,并调用init()方法来初始化实例;
        (2)、每一次请求时都只调用方法doFilter()进行处理;

        (3)、停止服务器时调用destroy()方法,销毁实例。

  三、职责
       1、servlet:
 
        创建并返回一个包含基于客户请求性质的动态内容的完整的html页面;
        创建可嵌入到现有的html页面中的一部分html页面(html片段);
        读取客户端发来的隐藏数据;
        读取客户端发来的显示数据;
        与其他服务器资源(包括数据库和java的应用程序)进行通信;
        通过状态代码和响应头向客户端发送隐藏数据。
 
       2、filter:
 
        filter能够在一个请求到达servlet之前预处理用户请求,也可以在离开servlet时处理http响应:
        在执行servlet之前,首先执行filter程序,并为之做一些预处理工作;
        根据程序需要修改请求和响应;
        在servlet被调用之后截获servlet的执行

        四、区别:

      1,servlet 流程是短的,url传来之后,就对其进行处理,之后返回或转向到某一自己指定的页面。它主要用来在 业务处理之前进行控制.
        2,filter 流程是线性的, url传来之后,检查之后,可保持原来的流程继续向下执行,被下一个filter, servlet接收等,而servlet 处理之后,不会继续向下传递。filter功能可用来保持流程继续按照原来的方式进行下去,或者主导流程,而servlet的功能主要用来主导流程。
         filter可用来进行字符编码的过滤,检测用户是否登陆的过滤,禁止页面缓存等

 

Post和get请求

比较明显的就是

GET请求在URL中传送的参数是有长度限制的,而POST么有。

对参数的数据类型,GET只接受ASCII字符,而POST没有限制。

GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。

GET参数通过URL传递,POST放在Request body中。

GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留

HTTP的底层是TCP/IP。所以GET和POST的底层也是TCP/IP,也就是说,GET/POST都是TCP链接。GET和POST能做的事情是一样一样的。你要给GET加上request body,给POST带上url参数,技术上是完全行的通的

HTTP只是个行为准则,而TCP才是GET和POST怎么实现的基本

GET产生一个TCP数据包;POST产生两个TCP数据包。

长的说:

对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);

而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。

 

也就是说,GET只需要汽车跑一趟就把货送到了,而POST得跑两趟,第一趟,先去和服务器打个招呼“嗨,我等下要送一批货来,你们打开门迎接我”,然后再回头把货送过去。

 

因为POST需要两步,时间上消耗的要多一点,看起来GET比POST更有效

 

因此Yahoo团队有推荐用GET替换POST来优化网站性能。但这是一个坑!跳入需谨慎。为什么?

1. GET与POST都有自己的语义,不能随便混用。

2. 据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。

3. 并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。

Java中方法增强的方式

 * 一种方式:继承的方式.

        * 能够控制这个类的构造的时候,才可以使用继承.

Connection是一个接口,实现类不确定(由各厂商提供),无法使用此方法

    * 二种方式:装饰者模式方式.

        * 包装对象和被包装的对象都要实现相同的接口.

        * 包装的对象中需要获得到被包装对象的引用.

        ***** 缺点:如果接口的方法比较多,增强其中的某个方法.其他的功能的方法需要原有调用.

    * 三种方式:动态代理的方式.

        * 被增强的对象实现接口就可以.

Servlet和jsp的区别

Jsp的本质就是一个servlet

主要有两个方面的不同

第一: 编译: jsp修改后可以立即看到结果, 不需要编译, 而servlet需要编译

第二: 也是最大的区别: jsp是动态网页开发技术, 是运行在服务器端的脚本语言, 主要侧重于视图, jsp运行时需要转化为servlet,而servelt是web服务器端编程技术,  主要用于逻辑控制

 

Servelt是线程安全的吗

Servlet 默认是单例模式,在web 容器中只创建一个实例,所以多个线程同时访问servlet的时候,Servlet是线程不安全的。 
那么 web 容器能为每个请求创建一个Servlet的实例吗?当然是可以的,只要Servlet实现SingleThreadModel接口,就可以了。

 

什么情况下调用doGet方法和doPost方法?

主要是表单的提交方式, 假如表单是get提交就调用doGet方法

假如是post提交, 就调用doPost方法

还有就是浏览器输入url访问的话也是走doGet方法

 

Spring的理解?

Spring是apachec旗下一个开源的轻量级框架,

Spring的两个核心是ioc和aop

Ioc 控制反转  是一种设计思想 控制的是对象, 反转的是对象创建的权利

控制反转就是把创建对象的权利交给工厂

以前传统java开发模式中, 当需要一个对象, 会自己new或getinstance等直接或者间接的调用构造方法创建一个对象, 在spring开发模式中, spring容器使用了工厂模式为我们创建所需要的对象, 使用时不需要自己创建, 直接调用spring提供的对象即可, 这就是控制反转的思想

说到控制反转的话还得说一下 DI 依赖注入  就是容器动态的将某个依赖关系注入到某个组件

谁依赖谁   应用程序依赖ioc容器

为什么要依赖  应用程序需要ioc容器提供对象需要的外部资源

谁注入谁  ioc容器注入应用程序需要的某个对象, 应用程序依赖的某个对象

其实ioc和di是同一个概念不同角度的描述

 

Aop面向切面编程, 是oop的一个补充和完善

简单的说它就是把我们程序重复的代码抽取出来,在需要执行的时候,使用动态代理的技术,在不修改源码的基础上,对我们的已有方法进行增强。

实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。

 

Ioc和aop的作用和与原理?

Ioc 控制反转, 是一种设计模式 看名字就知道控制反转的意思

Aop 是一个思想  面向切面编程  一段代码可以原封不动的

增强这段代码 比如可以事务管理日志或者测试一段代码的运行效率

Mvc的理解?

是一个表现层的设计模型

m是model--模型

V是view--视图

c是controller--控制器

主要用于实现前端页面的展现和后端业务数据处理逻辑的分离

优点是:

1 分层架构设计, 实现业务系统各个组件之间的解耦

2 有利于系统的可扩展性和可维护性

3 有利于实现系统的并行开发, 提高开发效率

 

Struts2的标签和jstl的标签的优缺点?过滤器Filter和Struts1拦截器的区别?

1 拦截器是基于java反射机制

过滤器是基于函数回调的

2 拦截器依赖于servlet容器的

过滤器不依赖

3 拦截器只能对action请求起作用

过滤器则几乎可以对所有的请求起作用

4 filter的范围要比拦截器范围大,Filter除了过滤请求外通过通配符可以保护页面,图片,文件等, 拦截器只能过滤请求

5 拦截器可以访问action的上下文, 值栈里的对象, 而过滤器不能

6在action的生命周期, 拦截器可以多次调用, 而过滤器只在容器初始化的时候调用一次

 

HIbernate的一级缓存

1 使用一级缓存的目的是为了减少数据库的访问次数, 从而提升hibernate的执行效率

2 hibernate中的一级缓存, 也叫作session的缓存, 可以在session范围内减少数据库的访问次数, 只在session范围内有效

3 缓存是由hibernate维护的, 用户不能操作缓存内容, 如果想操作缓存内容, 必须通过hibernate提供的evict/clear方法

HIbernate的一级缓存有几种状态?

三种

第一种:

瞬时态, 也就是ne出来的, 没有OID, 未与session关联

第二种:

持久态, 也就是调用了save,update等方法, 有OID, 与session关联

第三种:

 也就是关闭了session或者清除一级缓存, 有OID, 与session失联

Hibernate的一级缓存和二级缓存有什么区别?

一级缓存保存在session的

二级缓存是保存在硬盘的

一级缓存是默认开启的

二级缓存手动开启

SpringMVC的执行流程

1 用户发送请求, 请求到前端控制器

2 控制器请求处理器映射器

3 处理器映射器根据请求的url找到处理器, 返回处理器到控制器\

4 控制器请求处理器适配器, 适配器执行处理器的方法, 返回模型与视图

5 控制器请求视图解析器, 解析视图然后返回物理视图

Springmvc五个常用的注解?

@Controller

定义一个controller控制器的注解, 用于类上

@RequestBoby

@RequestMapping

用来处理请求地址映射的注解, 用在类上, 就类似于命名空间的作用, 表示所有方法请求地址都用它来作为父路径,用在方法上,就是请求地址的映射

@Resource和@Autowired

Bean注入的注解

@ModelAttribute和 @SessionAttributes

@PathVariable

Springmvc拦截器三个方法执行时机?

preHandle方法:

在处理器方法执行前执行,在响应jsp页面前执行。执行预处理。返回布尔类型的值。返回true继续执行;返回false终止执行。在企业项目中,通常在这个方法中可以实现判断用户是否登录,是否有权限操作资源业务逻辑。

postHandle方法:

在处理器方法执行后,在响应jsp页面前执行。执行后处理。在企业项目中通常可以在这个方法实现给页面设置公共的模型数据。比如页面的头部公共信息,和页面的尾部公共信息。

afterCompletion方法:

在处理器方法执行后,在响应jsp页面后执行。执行后处理。在企业项目中可以在这个方法实现记录用户操作的日志。

MyBatis和Hibernate的优缺点?

相同点:

都是持久层框架

都对JDBC进行了封装

不同点:

1. Hibernate封装了sql语句,支持事务的无关性, 在项目需要支持多种数据库的情况下, 代码开发量少, sql语句优化困难,MyBatis是直接使用sql语句操作数据库, 不支持数据库无关性, 在项目需要支持多中数据库的情况下, 代码开发量较多, sql语句优化容易

2.  Hibernate是配置java对象与数据库表的关系, 多表关系配置复杂, MyBatis直接配置Java对象与sql语句对应的关系, 多表关联关系配置容易

3. HIbernate是一个相对重量级的框架, 学习使用门槛高, 适合于需求相对稳定, 中小型的项目, 比如OA CRM

 MyBatis是一个轻量级的框架, 学习使用门槛低, 适合于大型的项目, 比如互联网的项目

MyBatis的$和#取值的区别?

#{}是占位符, 相当于jdbc中的问号, 当参数传递的是java简单类型, 花括号中可以是任意字符串

${}字符串拼接符, 当参数传递的是java简单类型, 花括号中只能是value

他们参数传递的是pojo的时候, 花括号中都是pojo的属性

Jquery选择器有哪些?

基本选择器

层次选择器

过滤选择器

表单选择器

同步请求和异步请求有什么区别?

同步就类似java程序 一步一步有顺序的执行, 上一步未执行完, 下一步就不会执行

异步的话就好像在java的主线程分出一个子线程, 他们互补影响各自做自己的事情

你只知道哪些设计模式?

单例模式

懒汉式

Public class lazySingleton{

//比较懒, 在类加载时, 不创建实例, 因此类加载的速度快, 但获取对象的速度慢

 

Private static LazySingleton intance = null; //静态私有成员

    Private LazySingleton(){}    //私有构造方法

Public static synchroized LazySingleton getInstance(){  //静态\ 同步\ 公开

   If( intance == null){

  intance = new LazySingleton();

}

return intance;

}

}

饿汉式

Public class LazySingleton{

    

 

}

 

哪些集合是线程安全的?`

Vector hashtable

JDK1.8新特性了解吗?

Lambda 表达式

函数式接口

Stream流

常见的SQL函数有哪些?

 

使用Spring有哪些好处?

 1 轻量级框架

Spring是轻量级框架, 基本的版本大约是2M

2 控制反转

Spring通过控制反转实现松散耦合, 对象给他们的依赖的, 而不是创建或者查找依赖的对象们, 方便解耦, 简化开发

3  面向切面编程AOP

Spring支持面向切面的编程, 并且把应用业务逻辑和系统分开

4 容器

Spring包含并管理应用中对象的生命周期和配置

5 MVC框架

Spring的WEB框架是个精心设计的框架, 是WEB框架的一个很好的替代品

6 事务管理

Spring提供一个持续的事务管理接口, 可以扩展到上至本地事务下至全局事务(JTA)

7 异常处理

Spring提供方便的API把具体技术的相关异常一致转换为unchecked异常

 

如何优化数据库?

从两个方面下手

1 sql语句方面的优化

>避免使用select * from, 用具体的字段列表代替

>应尽量避免在where子句对字段进行null值判断

>应尽量避免在where子句中使用!=或<>操作符, 否则引擎将放弃使用索引而进行全表扫描....

2 数据库设计方面的优化

>索引优化

建立适当的索引, 提高查询的效率

>分库分表

分表------横切  纵切

分库: 主从数据库

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值