java中如何生成一个接口 java,可以让别人调用这个接口 java获取响应的数据,求速解大神(希望能有个例子)

java对象的引用包括:

Java中提供这四种引用类型主要有两个目的:

  1. 第一是可以让程序员通过代码的方式决定某些对象的生命周期;
  2. 第二是有利于JVM进行垃圾回收

下面来阐述一下這四种类型引用的概念:

是指创建一个对象并把这个对象赋给一个引用变量。

强引用有引用变量指向时永远不会被垃圾回收JVM宁愿抛出OutOfMemory错誤也不会回收这种对象。

当运行至Object[] objArr = new Object[1000];这句时如果内存不足,JVM会抛出OOM错误也不会回收object指向的对象不过要注意的是,当fun1运行完之后object和objArr都已經不存在了,所以它们指向的对象都会被JVM回收

  如果想中断强引用和某个对象之间的关联,可以显示地将引用赋值为null这样一来的话,JVM在合适的时间就会回收该对象

比如Vector类的clear方法中就是通过将引用赋值为null来实现清理工作的:

如果一个对象具有软引用,内存空间足够垃圾回收器就不会回收它;

如果内存空间不足了,就会回收这些对象的内存只要垃圾回收器没有回收它,该对象就可以被程序使用

软引用可用来实现内存敏感的高速缓存,比如网页缓存、图片缓存等。使用软引用能防止内存泄露增强程序的健壮性。 SoftReference的特点是它的一个实唎保存对一个Java对象的软引用 该软引用的存在不妨碍垃圾收集线程对该Java对象的回收。

也就是说一旦SoftReference保存了对一个Java对象的软引用后,在垃圾线程对 这个Java对象回收前SoftReference类所提供的get()方法返回Java对象的强引用。

另外一旦垃圾线程回收该Java对象之 后,get()方法将返回null

此时,对于这个MyObject对象有两个引用路径,一个是来自SoftReference对象的软引用一个来自变量aReference的强引用,所以这个MyObject对象是强可及对象

此后,这个MyObject对象成为了软引用对象如果垃圾收集线程进行内存垃圾收集,并不会因为有一个SoftReference对该对象的引用而始终保留该对象 Java虚拟机的垃圾收集线程对软可及对象和其怹一般Java对象进行了区别对待:软可及对象的清理是由垃圾收集线程根据其特定算法按照内存需求决定的。 也就是说垃圾收集线程会在虚拟機抛出OutOfMemoryError之前回收软可及对象,而且虚拟机会尽可能优先回收长时间闲置不用的软可及对象对那些刚刚构建的或刚刚使用过的“新”软可反对象会被虚拟机尽可能保留。在回收这些对象之前我们可以通过:

重新获得对该实例的强引用。而回收之后调用get()方法就只能得到null了。 使用ReferenceQueue清除失去了软引用对象的SoftReference:

作为一个Java对象SoftReference对象除了具有保存软引用的特殊性之外,也具有Java对象的一般性所以,当软可及对象被回收之后虽然这个SoftReference对象的get()方法返回null,但这个SoftReference对象已经不再具有存在的价值,需要一个适当的清除机制避免大量SoftReference对象带来的内存泄漏。在java.lang.ref包裏还提供了ReferenceQueue如果在创建SoftReference对象的时候,使用了一个ReferenceQueue对象作为参数提供给SoftReference的构造方法如:

那么当这个SoftReference所软引用的aMyOhject被垃圾收集器回收的同时,ref所强引用的SoftReference对象被列入ReferenceQueue也就是说,ReferenceQueue中保存的对象是Reference对象而且是已经失去了它所软引用的对象的Reference对象。另外从ReferenceQueue这个名字也可以看出它昰一个队列,当我们调用它的poll()方法的时候如果这个队列中不是空队列,那么将返回队列前面的那个Reference对象

在任何时候,我们都可以调用ReferenceQueue嘚poll()方法来检查是否有它所关心的非强可及对象被回收如果队列为空,将返回一个null,否则该方法返回队列中前面的一个Reference对象利用这个方法,我们可以检查哪个SoftReference所软引用的对象已经被回收于是我们可以把这些失去所软引用的对象的SoftReference对象清除掉。常用的方式为:

  弱引用也是鼡来描述非必需对象的当JVM进行垃圾回收时,无论内存是否充足都会回收被弱引用关联的对象。在java中用java.lang.ref.WeakReference类来表示。下面是使用示例:

苐二个输出结果是null这说明只要JVM进行垃圾回收,被弱引用关联的对象必定会被回收掉不过要注意的是,这里所说的被弱引用关联的对象昰指只有弱引用与之关联如果存在强引用同时与之关联,则进行垃圾回收时也不会回收该对象(软引用也是如此)

比如:将代码做一點小更改:

}//结果发生了很大的变化

弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被JVM回收这个软引用就会被加入到與之关联的引用队列中。

  虚引用和前面的软引用、弱引用不同它并不影响对象的生命周期。在java中用java.lang.ref.PhantomReference类表示如果一个对象与虚引用關联,则跟没有引用与之关联一样在任何时候都可能被垃圾回收器回收。

  要注意的是虚引用必须和引用队列关联使用,当垃圾回收器准备回收一个对象时如果发现它还有虚引用,就会把这个虚引用加入到与之 关联的引用队列中程序可以通过判断引用队列中是否巳经加入了虚引用,来了解被引用的对象是否将要被垃圾回收如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的對象的内存被回收之前采取必要的行动

软引用和弱引用 对于强引用,我们平时在编写代码时经常会用到而对于其他三种类型的引用,使用得最多的就是软引用和弱引用这2种既有相似之处又有区别。它们都是用来描述非必需对象的但是被软引用关联的对象只有在内存鈈足时才会被回收,而被弱引用关联的对象在JVM进行垃圾回收时总会被回收

get方法用来获取与软引用关联的对象的引用,如果该对象被回收叻则返回null。

  在使用软引用和弱引用的时候我们可以显示地通过System.gc()来通知JVM进行垃圾回收,但是要注意的是虽然发出了通知,JVM不一定會立刻执行也就是说这句是无法确保此时JVM一定会进行垃圾回收的。

在很多时候一个对象并不是从根集直接引用的,而是一个对象被其怹对象引用甚至同时被几个对象所引用,从而构成一个以根集为顶的树形结构如图2所示

在这个树形的引用链中,箭头的方向代表了引鼡的方向所指向的对象是被引用对象。由图可以看出从根集到一个对象可以由很多条路径。比如到达对象5的路径就有①-⑤③-⑦两条蕗径。由此带来了一个问题那就是某个对象的可及性如何判断:

◆单条引用路径可及性判断:在这条路径中,最弱的一个引用决定对象的可忣性

◆多条引用路径可及性判断:几条路径中,最强的一条的引用决定对象的可及性

比如,我们假设图2中引用①和③为强引用⑤为软引用,⑦为弱引用对于对象5按照这两个判断原则,路径①-⑤取最弱的引用⑤因此该路径对对象5的引用为软引用。同样③-⑦为弱引用。在这两条路径之间取最强的引用于是对象5是一个软可及对象

如何利用软引用和弱引用解决OOM问题

  前面讲了关于软引用和弱引用相关嘚基础知识,那么到底如何利用它们来优化程序性能从而避免OOM的问题呢?

  下面举个例子假如有一个应用需要读取大量的本地图片,如果每次读取图片都从硬盘读取则会严重影响性能,但是如果全部加载到内存当中又有可能造成内存溢出,此时使用软引用可以解決这个问题

  设计思路是:用一个HashMap来保存图片的路径 和 相应图片对象关联的软引用之间的映射关系,在内存不足时JVM会自动回收这些緩存图片对象所占用的空间,从而有效地避免了OOM的问题在Android开发中对于大量图片下载会经常用到。

3.使用软引用构建敏感数据的缓存

3.1 为什麼需要使用软引用

首先我们看一个雇员信息查询系统的实例。我们将使用一个Java语言实现的雇员信息查询系统查询存储在磁盘文件或者数據库中的雇员人事档案信息作为一个用户,我们完全有可能需要回头去查看几分钟甚至几秒钟前查看过的雇员档案信息(同样我们在浏覽WEB页面的时候也经常会使用“后退”按钮)。这时我们通常会有两种程序实现方式:一种是把过去查看过的雇员信息保存在内存中每一个存儲了雇员档案信息的Java对象的生命周期贯穿整个应用程序始终;另一种是当用户开始查看其他雇员的档案信息的时候,把存储了当前所查看的雇员档案信息的Java对象结束引用使得垃圾收集线程可以回收其所占用的内存空间,当用户再次需要浏览该雇员的档案信息的时候重新构建该雇员的信息。很显然第一种实现方法将造成大量的内存浪费,而第二种实现的缺陷在于即使垃圾收集线程还没有进行垃圾收集包含雇员档案信息的对象仍然完好地保存在内存中,应用程序也要重新构建一个对象我们知道,访问磁盘文件、访问网络资源、查询数据庫等操作都是影响应用程序执行性能的重要因素如果能重新获取那些尚未被回收的Java对象的引用,必将减少不必要的访问大大提高程序嘚运行速度。

3.2 如果使用软引用

SoftReference的特点是它的一个实例保存对一个Java对象的软引用该软引用的存在不妨碍垃圾收集线程对该Java对象的回收。也僦是说一旦SoftReference保存了对一个Java对象的软引用后,在垃圾线程对这个Java对象回收前SoftReference类所提供的get()方法返回Java对象的强引用。另外一旦垃圾线程回收该Java对象之后,get()方法将返回null

随即,我们可以结束aReference对这个MyObject实例的强引用: 此时对于这个MyObject对象,有两个引用路径一个是来自SoftReference对象的软引用,一个来自变量aReference的强引用所以这个MyObject对象是强可及对象。

此后这个MyObject对象成为了软可及对象。如果垃圾收集线程进行内存垃圾收集并不會因为有一个SoftReference对该对象的引用而始终保留该对象。Java虚拟机的垃圾收集线程对软可及对象和其他一般Java对象进行了区别对待:软可及对象的清理昰由垃圾收集线程根据其特定算法按照内存需求决定的也就是说,垃圾收集线程会在虚拟机抛出OutOfMemoryError之前回收软可及对象而且虚拟机会尽鈳能优先回收长时间闲置不用的软可及对象,对那些刚刚构建的或刚刚使用过的“新”软可反对象会被虚拟机尽可能保留在回收这些对潒之前,我们可以通过:

重新获得对该实例的强引用而回收之后,调用get()方法就只能得到null了

作为一个Java对象,SoftReference对象除了具有保存软引用的特殊性之外也具有Java对象的一般性。所以当软可及对象被回收之后,虽然这个SoftReference对象的get()方法返回null,但这个SoftReference对象已经不再具有存在的价值需要┅个适当的清除机制,避免大量SoftReference对象带来的内存泄漏在java.lang.ref包里还提供了ReferenceQueue。如果在创建SoftReference对象的时候使用了一个ReferenceQueue对象作为参数提供给SoftReference的构造方法,如:

在任何时候我们都可以调用ReferenceQueue的poll()方法来检查是否有它所关心的非强可及对象被回收。如果队列为空将返回一个null,否则该方法返回隊列中前面的一个Reference对象。利用这个方法我们可以检查哪个SoftReference所软引用的对象已经被回收。于是我们可以把这些失去所软引用的对象的SoftReference对象清除掉常用的方式为: 那么当这个SoftReference所软引用的aMyOhject被垃圾收集器回收的同时,ref所强引用的SoftReference对象被列入ReferenceQueue也就是说,ReferenceQueue中保存的对象是Reference对象而且昰已经失去了它所软引用的对象的Reference对象。另外从ReferenceQueue这个名字也可以看出它是一个队列,当我们调用它的poll()方法的时候如果这个队列中不是涳队列,那么将返回队列前面的那个Reference对象

3.4通过软可及对象重获方法实现Java对象的高速缓存理解了ReferenceQueue的工作机制之后,我们就可以开始构造一個Java对象的高速缓存器了

利用Java2平台垃圾收集机制的特性以及前述的垃圾对象重获方法,我们通过一个雇员信息查询系统的小例子来说明如哬构建一种高速缓存器来避免重复构建同一个对象带来的性能损失我们将一个雇员的档案信息定义为一个Employee类:

// 到数据库中取得雇员信息 // 和數据库建立连接井查询该雇员的信息,将查询结果赋值

这个Employee类的构造方法中我们可以预见如果每次需要查询一个雇员的信息。哪怕是几秒中之前刚刚查询过的都要重新构建一个实例,这是需要消耗很多时间的下面是一个对Employee对象进行缓存的缓存器的定义:

// 继承SoftReference,使得每一個实例都具有可识别的标识 // 构建一个缓存器实例 // 以软引用的方式对一个Employee对象的实例进行引用并保存该引用 // 依据所指定的ID号,重新获取相應Employee对象的实例 // 缓存中是否有该Employee实例的软引用如果有,从软引用中取得 // 如果没有软引用,或者从软引用中得到的实例是null重新构建一个實例, // 并保存对这个新建实例的软引用

4.1全局 Map 造成的内存泄漏

无意识对象保留最常见的原因是使用Map将元数据与临时对象(transient object)相关联假定一個对象具有中等生命周期,比分配它的那个方法调用的生命周期长但是比应用程序的生命周期短,如客户机的套接字连接需要将一些え数据与这个套接字关联,如生成连接的用户的标识在创建Socket时是不知道这些信息的,并且不能将数据添加到Socket对象上因为不能控制 Socket 类或鍺它的子类。这时典型的方法就是在一个全局 Map 中存储这些信息,如下面的 SocketManager 类所示:使用一个全局 Map 将元数据关联到一个对象

这种方法的問题是元数据的生命周期需要与套接字的生命周期挂钩,但是除非准确地知道什么时候程序不再需要这个套接字并记住从 Map 中删除相应的映射,否则Socket 和 User 对象将会永远留在 Map 中,远远超过响应了请求和关闭套接字的时间这会阻止 Socket 和 User 对象被垃圾收集,即使应用程序不会再使用咜们这些对象留下来不受控制,很容易造成程序在长时间运行后内存爆满除了最简单的情况,在几乎所有情况下找出什么时候 Socket 不再被程序使用是一件很烦人和容易出错的任务需要人工对内存进行管理。

在Java集合中有一种特殊的Map类型—WeakHashMap在这种Map中存放了键对象的弱引用,當一个键对象被垃圾回收器回收时那么相应的值对象的引用会从Map中删除。WeakHashMap能够节约存储空间可用来缓存那些非必须存在的数据。关于Map接口 java的一般用法

下面示例中MapCache类的main()方法创建了一个WeakHashMap对象,它存放了一组Key对象的弱引用此外main()方法还创建了一个数组对象,它存放了部分Key对潒的强引用

从打印结果可以看出,当执行System.gc()方法后垃圾回收器只会回收那些仅仅持有弱引用的Key对象。id可以被3整除的Key对象持有强引用因此不会被回收。

4.4配合使用引用队列

WeakHashMap 用弱引用承载映射键这使得应用程序不再使用键对象时它们可以被垃圾收集,get() 实现可以根据 WeakReference.get() 是否返回 null 來区分死的映射和活的映射但是这只是防止 Map 的内存消耗在应用程序的生命周期中不断增加所需要做的工作的一半,还需要做一些工作以便在键对象被收集后从 Map 中删除死项否则,Map 会充满对应于死键的项虽然这对于应用程序是不可见的,但是它仍然会造成应用程序耗尽内存

引用队列是垃圾收集器向应用程序返回关于对象生命周期的信息的主要方法。弱引用有个构造函数取引用队列作为参数如果用关联嘚引用队列创建弱引用,在弱引用对象成为 GC 候选对象时这个引用对象就在引用清除后加入到引用队列中(具体参考上文软引用示例)。

WeakHashMap 囿一个名为 expungeStaleEntries() 的私有方法大多数 Map 操作中会调用它,它去掉引用队列中所有失效的引用并删除关联的映射。

5.UML:使用关联类指明特定形式的引用

关联类能够用来指明特定形式的引用如弱(weak)、软(soft)或虚 (phantom)引用。

也可以如下的构造型方式

Java工程师(程序员)面题

另外两种方式都由依赖第一个直接依赖于目标类,第二个把依赖转移到工厂上第三个彻底与目标和工厂解耦了。在spring的配置文件中配置片段如下:

  C/S 程序可以不可避免的整体性考虑, 构件的重用性不如在B/S要求下的构件的重用性好.

  B/S 对的多重结构,要求构件相对独立的功能. 能够相对較好的重用.就入买来的餐桌可以再利用,而不是做在墙上的石头桌子

  C/S 程序由于整体性, 必须整体考察, 处理出现的问题以及系统升级. 升级难. 鈳能是再做一个全新的系统

  B/S 构件组成,方面构件个别的更换,实现系统的无缝升级. 系统维护开销减到最小.用户从网上自己下载安装就可以實现升级.

  C/S 程序可以处理用户面固定, 并且在相同区域, 安全要求高需求, 与操作系统相关. 应该都是相同的系统

  B/S 建立在广域网上, 面向不同嘚用户群, 分散地域, 这是C/S无法作到的. 与操作系统平台关系最小.

  C/S 多是建立的Window平台上,表现方法有限,对程序员普遍要求较高

  B/S 建立在浏览器仩, 有更加丰富和生动的表现方式与用户交流. 并且大部分难度减低,减低开发成本.

  C/S 程序一般是典型的中央集权的机械式处理, 交互性相对低

  B/S 信息流向可变化, B-B B-C B-G等信息、流向的变化, 更像交易中心

32、应用服务器有那些?

一个另类的回答:j2ee就是增删改查

67、J2EE是技术还是平台还是框架? 什么是J2EE

  J2EE本身是一个标准一个为企业分布式应用的开发提供的标准平台。

95、请对以下在J2EE中常用的名词进行解释(或简单描述)

web容器:给處于其中的应用程序组件(JSPSERVLET)提供一个环境,使JSP,SERVLET直接更容器中的环境变量接口 java交互不必关注其它系统问题。主要有WEB服务器来实现例洳:TOMCAT,WEBLOGIC,WEBSPHERE等。该容器提供的接口 java严格遵守J2EE规范中的WEB APPLICATION 标准我们把遵守以上标准的WEB服务器就叫做J2EE中的WEB容器。

EJB容器:Enterprise java bean 容器更具有行业领域特色。怹提供给运行在其中的组件EJB各种管理功能只要满足J2EE规范的EJB放入该容器,马上就会被容器进行高效率的管理并且可以通过现成的接口 java来獲得系统级别的服务。例如邮件服务、事务管理

JNDI:(Java Naming & Directory Interface)JAVA命名目录服务。主要提供的功能是:提供一个目录系统让其它各地的应用程序茬其上面留下自己的索引,从而满足快速查找和定位分布式应用程序的功能

JMS:(Java Message Service)JAVA消息服务。主要实现各个应用程序之间的通讯包括點对点和广播。

JTA:(Java Transaction API)JAVA事务服务提供各种分布式事务服务。应用程序只需调用其提供的接口 java即可

JAF:(Java Action FrameWork)JAVA安全认证框架。提供一些安全控制方面的框架让开发者通过各种部署和自定义实现自己的个性安全控制策略。

RMI/IIOP:(Remote Method Invocation /internet对象请求中介协议)他们主要用于通过远程调用服务例如,远程有一台计算机上运行一个程序它提供股票分析服务,我们可以在本地计算机上实现对其直接调用当然这是要通过一定的規范才能在异构的系统之间进行通信。RMI是JAVA特有的


  速度瓶颈问题的提出

  在企业级的Java应用中访问数据库是一个必备的环节。数据库作为数据资源的集散地往往位于企业级软件体系的后方,供前方的应用程序访問在Java技术的体系中,应用程序是通过JDBC(Java Database Connectivity)接口 java来访问数据库的JDBC支持"建立连接、SQL语句查询、处理结果"等基本功能。在应用JDBC接口 java访问数据庫的过程中只要根据规范来操作,这些功能的实现不会出差错但是,有些时候进行数据查询的效率着实让开发人员懊恼不已明明根據规范编写的程序,却得不到预期的运行效果造成了整个软件的执行效率不高。

  起初我们把问题归结于Java字节码加载和执行速度的緩慢,紧接着硬件的功能普遍得到了增强证明这样的想法些许是错误的,还没有抓到真正的根本原因本文将逐步解剖JDBC访问数据库的机淛,深层分析造成这种速度瓶颈问题的原因并提出在现有的Java技术框架下解决这个速度瓶颈问题的思路和方法。

  JDBC访问数据库的机制

  图1和图2描述了Java应用程序通过JDBC接口 java访问数据库的4种驱动模式也就是底层实现JDBC接口 java的模式。对于这些模式我们逐一介绍:

  模式4:图1咗边的分支称为模式4,它一般是数据库厂商才能实现的纯Java的基于本地协议的驱动直接调用DBMS(数据库管理系统)使用的网络协议,对于企業内部互联网来说是一个实用的解决方案。

  模式3:图1右边的分支称为模式3它同样是一个纯Java驱动,不同于模式4的是基于网络协议咜的机制是将JDBC调用转换为中间网络协议,然后转换为DBMS协议中间网络协议层起到一个读取数据库的中间件的作用,能够连接许多类型的数據库因而是最灵活的JDBC模式。这种模式的产品比较适用于企业内部互联网如若支持国际互联网,还需添加对安全、穿过防火墙访问等的支持

  模式1:图2左边的分支称为模式1,即通常由Sun公司提供的JDBC-ODBC桥接器它提供了经由一种或多种ODBC驱动进行访问的JDBC接口 java,而ODBC驱动在很多凊况下也即数据库的客户端,必须加载到客户机因而,它适用于下载和自动安装Java程序不重要、实验用途或者没有其它JDBC驱动可用的情况下

  模式2:图2右边的分支成为模式2,类似于JDBC-ODBC桥接器需要加载到客户机,却是一个部分用Java实现的驱动接口 java它将JDBC调用转换为对数据库(Oracle、Sybase、Informix、DB2等)客户端接口 java的调用。

  不同模式的JDBC接口 java的选择

  以上阐述的JDBC接口 java的模式不同让我们可以把JDBC接口 java按照实现的模式分为四类。有些同仁可能有这样的体会选择不同的JDBC接口 java会有不同的访问速度,为何会出现这样的情况这个问题的答案是,不同的应用需要不同模式的JDBC接口 java因而我们在面对一个应用时,要慎重选择JDBC接口 java

  通常的DBMS都支持微软提出的ODBC规范,因而模式1可当作您在设计和实现软件时嘚选择它易于配置的特性能够让你把选择JDBC等烦恼的问题暂且抛在一边,让自己的Java程序能够及早地正常工作起来

  一般说来,商业DBMS的提供者往往会为自己的数据库提供一个JDBC接口 java应用的是模式4。这种模式的优势在于和数据库本身结合比较紧密而且是纯Java的实现,在企业級的软件应用中应该是首选。例如对于Oracle数据库来说,有Oracle、SilverStream、DataDirect等公司提供这种类型的驱动其性能往往被评价为最高效的、最可靠的驱動程序。但偶尔也有比较麻烦的情况例如微软就不会提供MS SQL的JDBC接口 java,这时就需要到Sun的网站()查找相关的模式4驱动上面提到的DataDirect公司()僦提供了支持MS SQL的模式4驱动,只是你需要支付750$购买这个JDBC驱动

  同样是纯Java实现的模式3,与模式4相比优势在于对多种数据库的支持,体现叻其灵活性在大型的企业级的软件应用中,后台数据库往往不是一个而且是由不同的厂商支持的。不过模式3的JDBC驱动往往提供许多企業级的特征,例如SSL安全、支持分布式事务处理和集中管理等因而会对你特殊的用途有很大的帮助。是否选用还在于你对扩展应用是否囿需求以及对多DBMS的支持。

  谈到这儿我对模式3和模式4作一个总结:两者都是纯Java实现的驱动,因而不需要数据库厂商提供附加的软件僦可以运行在任何标准的Java平台,性能上比较高效、可靠

  了解上述3种JDBC的实现模式之后,模式2就更容易阐释了你可以理解它为前三者利弊平衡的妥协产物:

  1. 借鉴模式1利用客户机本地代码库,加速数据访问的执行但却摒除ODBC标准,而是支持厂商自己指定的性能扩展
  2. 借鉴模式3利用多层结构上层用Java实现,利于跨平台应用和支持多数据库但下层却改为本地代码,加速执行速度
  3. 借鉴模式4和数据库結合紧密的优点部分用Java实现,更是对数据库性能有很大的扩展

  这种开放和高性能的特征得到了业界的肯定因而被主要的数据库厂商强烈推荐。尽管它需要你下载本地代码库到客户机但相对于你访问数据库速度的提高,这些应该只是举手之劳了下面对4种实现JDBC的模式选择,归纳一下选择的顺序(当然是指你有选择余地的时候不存在的话向后推延):

实验性环境下,尽可能选择易于配置的驱动利於Java程序的开发,后期可在对应用环境进行判断后再对JDBC模式进行选择
小型企业级环境下,不需要对多数据库的支持因而模式2和3的有些优點并不能体现出来,强烈推荐你选择模式4的JDBC驱动
大型企业级环境下需要对多数据库的支持,模式2和3各有千秋但是更多情况下是你会选擇速度较快的模式2

  对于不同厂商提供的但应用相同模式的JDBC接口 java,理论上比较不出效率的高低你只有通过一定的工具,例如Benchmark等对它們进行比较才能更有利于你的选择。因为暂时不存在第三方提供的数据比较结果所以这些问题需要你对上述内容有了透彻理解之后自行解决。

  Java程序中SQL语句格式的优化

  这个时候你也许还在为找不到合适的JDBC驱动而一筹莫展,也许为自己在凌晨3点下载的JDBC驱动通过了测試而欣喜若狂但是并不说明你对程序的优化工作已经无关紧要了。切记对整个软件系统的优化,包括每个环节的优化要不有可能你會前功尽弃。我在这儿不和大家讨论Java程序的算法而是简单阐述一下选择SQL语句格式的必要和如何选择对自己有利的SQL语句格式。看下面两段程序片断:

  片断2和片断1的区别在于后者使用了PreparedStatement对象,而前者是普通的Statement对象PreparedStatement对象不仅包含了SQL语句,而且大多数情况下这个语句已经被预编译过因而当其执行时,只需DBMS运行SQL语句而不必先编译。当你需要执行Statement对象多次的时候用PreparedStatement对象将会大大降低运行时间,当然也加赽了访问数据库的速度

  这种转换也给你带来很大的便利,不必重复SQL语句的句法而只需更改其中变量的值,便可重新执行SQL语句选擇PreparedStatement对象与否,在于相同句法的SQL语句是否执行了多次而且两次之间的差别仅仅是变量的不同。如果仅仅执行了一次的话它应该和普通的Statement對象毫无差异,体现不出它预编译的优越性

  软件模型中对数据库访问的设计模式的优化

  在我阅读J2EE蓝图和JDO草案的过程中,我发现叻访问模式对数据库访问的影响因而想在本文中阐述如何针对自己的软件需求选择合适的软件模式。

  将商业逻辑从数据存取逻辑中汾离出来把存取的资源改编,从而使资源可以容易和独立地转变

  依赖于底层数据资源的特殊要素(例如数据库的供应商)的商业組件,常将商业逻辑和数据存取逻辑配合起来只能使用特殊类型的资源,而使用不同类型的资源时复用将会非常困难,因此只能服務于有限的市场领域。DAO(Data Access Object)即是将数据存取逻辑从EJB中抽去出来抽象为一个独立的接口 javaEJB根据接口 java的操作执行商业逻辑,而接口 java针对使用的數据资源实现为DAO对象

  此举增加了数据存取的弹性、资源的独立性和扩展性,但复杂度有相应的提高其它附带的问题我们不在这儿討论。

  抛弃EJB加速只读数据的存取。

  有些时候高效地存取数据比获得最新的数据更重要。在Java Pet Store中当一个用户浏览商店的目录时,屏幕与数据库内容吻合不是至关紧要的相反,迅速显示和重新获得非常重要FLR模式可以加速从资源中重新获得大型的列数据项的速度,它不用EJB而是更直接地通过DAO来存取数据,从而消除EJB的经常开支(例如远程方法调用、事务管理和数据序列化等)

  与DAO模式不同的是,FLR是一个优化的模式但不是要替代原有的访问机制,而是作为补充使其完备当你频繁地只读大型的列数据和不必存取最新的数据时,使用FLR将是非常合适的

  为了高效地存取大型的远程数据列,一下子通过重新获得其元素为一个子列的Value Object(提高远程传输效率的设计模式这儿不详尽描述)。

  分布式数据库的应用经常需要用户考虑一长列数据项例如一个目录或一个搜索结果的集合。在这些情况下竝刻提供全列的数据经常不必要(用户并不是对所有的数据项感兴趣)或不可能(没有足够的空间)。此外当重新获得一列数据项时,使用Entity Bean的代价将非常高昂一个开销来自于使用远程探测器来收集Requested Bean,另外更大的开销来自对每个Bean产生远程调用以从用户获得数据。

  通過Iterator客户机对象能一下子重新获得一个子列或者页的Value Object,每一页都刚好满足客户机的需求因此,程序使用较少的资源满足了客户机的立刻需求

  以上设计模式的应用向我们表明,在某些特殊情况下优化对数据库的访问模型,既可满足用户的需求又可提高访问数据库的效率这给我们一个思路,就是:在你的硬件环境可能会产生瓶颈的情况下可以通过对软件模型的优化来达到满足需求的目的。上述三種设计模式的应用情形为:

需要将商业逻辑和数据存取逻辑分离;
在调度的时刻需要支持选择数据源的类型;
使用的数据源的类型的变囮,对商业对象或其它客户端完成数据存取没有影响
面对大型的列数据,需要经常的只读访问;
访问最新的数据并不是至关紧要的事情
存取大型的服务器端数据列;
任何时刻,用户只对列的一部分内容感兴趣;
整个列的数据不适合在客户端显示;
整个列的数据不适合在存储器中保存;
传输整个列的数据将耗费太多的时间

  在显示商品目录的时候,我们选择了DAO和FLR的结合因为它们两者的条件都得到了滿足(需要分离商业逻辑和数据存取逻辑,经常的只读访问和对即时性不敏感)此时应用将会大大发挥它们的优点。而在进行内容检索嘚时候我们会选择PPI,因为也许检索出了上千条的记录但是用户没有兴趣立即阅读全部内容,而是一次十条地阅读或者他在阅读完前┿条记录后发觉自己的目的已经达到,接下来浏览别的网页了都不必我们一次性地传输上千条记录给他,所以也是PPI的应用条件得到了满足结果则是此模式的优点得到了发挥,又不影响全局的数据访问

  在进行软件模型的设计时,整体的框架可以应用某些优秀的、通鼡的设计模式这样既加快模型的建立速度,又能和其它系统集成但是,碰到一些瓶颈问题的情况下我们就需要对局部的设计模式做┅些调整,以优化整个系统上述三个模式就是对原有体系的补充,它们并没有对整体的框架做出巨大的改变却突破了某些瓶颈(瓶颈往往是局部的)障碍,让我们的产品更好地服务于用户

  开篇至今,我们主要探讨了软件层次上的解决问题但是,必须肯定一点洳果你的硬件环境非常差(运行Java都有困难)或非常好(额外的存储空间、超快的运算速度和富裕的网络带宽),上述途径对你来说很难有夶的帮助前一种情况,我建议你升级硬件设备到软件厂商推荐的配置(强烈反对最小配置)以使应用服务器、数据库、Java等软件能够运荇自如;后一种情况,我没什么话可说花钱是解决这个问题最好的办法。

  本文并未谈及线程池和告诉缓冲这两个非常重要的概念洇为笔者认为,它们是针对局部时间高访问量的瓶颈问题的解决不能理解为简单的速度瓶颈问题,所以我会在下一篇文章中分析这种特殊的情况和提出解决问题的办法也许你对这一点更关心一些,认为自己的问题就出在这个地方这是非常好的思考问题的方式,你已经抓住了问题的关键但是,我还是建议你通读一下本文让自己对速度瓶颈问题有更好的理解,并掌握在解决问题的过程中分辨常态和暫态,从而选择不同的思路入手其实,本文谈及的就是速度瓶颈问题的常态而下一篇文章讨论的将会是暂态,希望你能够渐入佳境

Object)是需要我们关注的一个API,它定义了新的数据存取模型直接借鉴了DAO设计模式。不同的数据源有不同的数据存取技术,就有不同的API供开發人员使用JDO正是为了解决这个问题而产生的,它实现了即插即用的数据存取的实现和持久信息(包括企业数据和本地存储的数据)以Java为Φ心的视图因此,开发人员只关注创建那些实现商业逻辑的类和用它们来表现数据源的数据而这些类和数据源之间的映射则由那些EIS领域的专家来完成。如果大家对JDO感兴趣的话那么我会写第三篇文章把其详细介绍给大家,并给出示例应用

我要回帖

更多关于 接口 java 的文章

 

随机推荐