`
yonlist
  • 浏览: 85688 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java性能优化

阅读更多

分为三个部分:J2SE、J2EE、GUI,多少有些帮助

 

一、通用篇

  通用篇讨论的问题适合于大多数Java应用。

  1.1 不用new关键词创建类的实例

  用new关键词创建类的实例时,构造函数链中的所有构造函数都会被自动调用。但如果一个对象实现了Cloneable接口,我们可以调用它的clone()方法。clone()方法不会调用任何类构造函数。

  在使用设计模式(Design Pattern)的场合,如果用Factory模式创建对象,则改用clone()方法创建新的对象实例非常简单。例如,下面是Factory模式的一个典型实现:

public static Credit getNewCredit() {
return new Credit();
}

  改进后的代码使用clone()方法,如下所示:

private static Credit BaseCredit = new Credit();
public static Credit getNewCredit() {
return (Credit) BaseCredit.clone();
}

  上面的思路对于数组处理同样很有用。

  1.2 使用非阻塞I/O

  版本较低的JDK不支持非阻塞I/O API。为避免I/O阻塞,一些应用采用了创建大量线程的办法(在较好的情况下,会使用一个缓冲池)。这种技术可以在许多必须支持并发I/O流的应用中见到,如Web服务器、报价和拍卖应用等。然而,创建Java线程需要相当可观的开销。

  JDK 1.4引入了非阻塞的I/O库(java.nio)。如果应用要求使用版本较早的JDK,在这里有一个支持非阻塞I/O的软件包。

  请参见Sun中国网站的《调整JavaI/O性能》。

  1.3 慎用异常

  异常对性能不利。抛出异常首先要创建一个新的对象。Throwable接口的构造函数调用名为fillInStackTrace()的本地(Native)方法,fillInStackTrace()方法检查堆栈,收集调用跟踪信息。只要有异常被抛出,VM就必须调整调用堆栈,因为在处理过程中创建了一个新的对象。

  异常只能用于错误处理,不应该用来控制程序流程。

  1.4 不要重复初始化变量

  默认情况下,调用类的构造函数时, Java会把变量初始化成确定的值:所有的对象被设置成null,整数变量(byteshortintlong)设置成0float double变量设置成0.0,逻辑值设置成false。当一个类从另一个类派生时,这一点尤其应该注意,因为用new关键词创建一个对象时,构造函数链中的所有构造函数都会被自动调用。

  1.5 尽量指定类的final修饰符

  带有final修饰符的类是不可派生的。在Java核心API中,有许多应用final的例子,例如java.lang.String。为String类指定final防止了人们覆盖length()方法。

  另外,如果指定一个类为final,则该类所有的方法都是finalJava编译器会寻找机会内联(inline)所有的final方法(这和具体的编译器实现有关)。此举能够使性能平均提高50%

  1.6 尽量使用局部变量

  调用方法时传递的参数以及在调用中创建的临时变量都保存在栈(Stack)中,速度较快。其他变量,如静态变量、实例变量等,都在堆(Heap)中创建,速度较慢。另外,依赖于具体的编译器/JVM,局部变量还可能得到进一步优化。请参见《尽可能使用堆栈变量》。

  1.7 乘法和除法

  考虑下面的代码:

for (val = 0; val < 100000; val +=5) { alterX = val * 8; myResult = val * 2; }

  用移位操作替代乘法操作可以极大地提高性能。下面是修改后的代码:

for (val = 0; val < 100000; val += 5) { alterX = val << 3; myResult = val << 1; }

  修改后的代码不再做乘以8的操作,而是改用等价的左移3位操作,每左移1位相当于乘以2。相应地,右移1位操作相当于除以2。值得一提的是,虽然移位操作速度快,但可能使代码比较难于理解,所以最好加上一些注释。

 

 

二、J2EE

  前面介绍的改善性能技巧适合于大多数Java应用,接下来要讨论的问题适合于使用JSPEJBJDBC的应用。

  2.1 使用缓冲标记

  一些应用服务器加入了面向JSP的缓冲标记功能。例如,BEAWebLogic Server6.0版本开始支持这个功能,Open Symphony工程也同样支持这个功能。JSP缓冲标记既能够缓冲页面片断,也能够缓冲整个页面。当JSP页面执行时,如果目标片断已经在缓冲之中,则生成该片断的代码就不用再执行。页面级缓冲捕获对指定URL的请求,并缓冲整个结果页面。对于购物篮、目录以及门户网站的主页来说,这个功能极其有用。对于这类应用,页面级缓冲能够保存页面执行的结果,供后继请求使用。

  对于代码逻辑复杂的页面,利用缓冲标记提高性能的效果比较明显;反之,效果可能略逊一筹。

  请参见《用缓冲技术提高JSP应用的性能和稳定性》。

  2.2 始终通过会话Bean访问实体Bean

  直接访问实体Bean不利于性能。当客户程序远程访问实体Bean时,每一个get方法都是一个远程调用。访问实体Bean的会话Bean是本地的,能够把所有数据组织成一个结构,然后返回它的值。

  用会话Bean封装对实体Bean的访问能够改进事务管理,因为会话Bean只有在到达事务边界时才会提交。每一个对get方法的直接调用产生一个事务,容器将在每一个实体Bean的事务之后执行一个装入-读取操作。

  一些时候,使用实体Bean会导致程序性能不佳。如果实体Bean的唯一用途就是提取和更新数据,改成在会话Bean之内利用JDBC访问数据库可以得到更好的性能。

  2.3 选择合适的引用机制

  在典型的JSP应用系统中,页头、页脚部分往往被抽取出来,然后根据需要引入页头、页脚。当前,在JSP页面中引入外部资源的方法主要有两种:include指令,以及include动作。

  include指令:例如<%@ include file="copyright.html" %>。该指令在编译时引入指定的资源。在编译之前,带有include指令的页面和指定的资源被合并成一个文件。被引用的外部资源在编译时就确定,比运行时才确定资源更高效。
include
动作:例如<jsp:include page="copyright.jsp" />。该动作引入指定页面执行后生成的结果。由于它在运行时完成,因此对输出结果的控制更加灵活。但时,只有当被引用的内容频繁地改变时,或者在对主页面的请求没有出现之前,被引用的页面无法确定时,使用include动作才合算。

  2.4 在部署描述器中设置只读属性

  实体Bean的部署描述器允许把所有get方法设置成只读。当某个事务单元的工作只包含执行读取操作的方法时,设置只读属性有利于提高性能,因为容器不必再执行存储操作。

  2.5 缓冲对EJB Home的访问

  EJB Home接口通过JNDI名称查找获得。这个操作需要相当可观的开销。JNDI查找最好放入Servletinit()方法里面。如果应用中多处频繁地出现EJB访问,最好创建一个EJBHomeCache类。EJBHomeCache类一般应该作为singleton实现。

  2.6 EJB实现本地接口

  本地接口是EJB 2.0规范新增的内容,它使得Bean能够避免远程调用的开销。请考虑下面的代码。

PayBeanHome home = (PayBeanHome)
javax.rmi.PortableRemoteObject.narrow
(ctx.lookup ("PayBeanHome"), PayBeanHome.class);
PayBean bean = (PayBean)
javax.rmi.PortableRemoteObject.narrow
(home.create(), PayBean.class);

  第一个语句表示我们要寻找BeanHome接口。这个查找通过JNDI进行,它是一个RMI调用。然后,我们定位远程对象,返回代理引用,这也是一个 RMI调用。第二个语句示范了如何创建一个实例,涉及了创建IIOP请求并在网络上传输请求的stub程序,它也是一个RMI调用。

  要实现本地接口,我们必须作如下修改:

  方法不能再抛出java.rmi.RemoteException异常,包括从RemoteException派生的异常,比如 TransactionRequiredExceptionTransactionRolledBackException NoSuchObjectExceptionEJB提供了等价的本地异常,如TransactionRequiredLocalException TransactionRolledBackLocalExceptionNoSuchObjectLocalException

  所有数据和返回值都通过引用的方式传递,而不是传递值。
  本地接口必须在EJB部署的机器上使用。简而言之,客户程序和提供服务的组件必须在同一个JVM上运行。

  如果Bean实现了本地接口,则其引用不可串行化。

  请参见《用本地引用提高EJB访问效率》。

 

2.7 生成主键

  在EJB之内生成主键有许多途径,下面分析了几种常见的办法以及它们的特点。

  利用数据库内建的标识机制(SQL ServerIDENTITYOracleSEQUENCE)。这种方法的缺点是EJB可移植性差。

  由实体Bean自己计算主键值(比如做增量操作)。它的缺点是要求事务可串行化,而且速度也较慢。

  利用NTP之类的时钟服务。这要求有面向特定平台的本地代码,从而把Bean固定到了特定的OS之上。另外,它还导致了这样一种可能,即在多CPU的服务器上,同一个毫秒之内生成了两个主键。

  借鉴Microsoft的思路,在Bean中创建一个GUID。然而,如果不求助于JNIJava不能确定网卡的MAC地址;如果使用JNI,则程序就要依赖于特定的OS

  还有其他几种办法,但这些办法同样都有各自的局限。似乎只有一个答案比较理想:结合运用RMIJNDI。先通过RMI注册把RMI远程对象绑定到JNDI树。客户程序通过JNDI进行查找。下面是一个例子:

public class keyGenerator extends UnicastRemoteObject implements Remote {
private static long KeyValue = System.currentTimeMillis();
public static synchronized long getKey() throws RemoteException { return KeyValue++; }

  2.8 及时清除不再需要的会话

  为了清除不再活动的会话,许多应用服务器都有默认的会话超时时间,一般为30分钟。当应用服务器需要保存更多会话时,如果内存容量不足,操作系统会把部分内存数据转移到磁盘,应用服务器也可能根据最近最频繁使用Most Recently Used)算法把部分不活跃的会话转储到磁盘,甚至可能抛出内存不足异常。在大规模系统中,串行化会话的代价是很昂贵的。当会话不再需要时,应当及时调用HttpSession.invalidate()方法清除会话。HttpSession.invalidate()方法通常可以在应用的退出页面调用。

  2.9 JSP页面中关闭无用的会话

  对于那些无需跟踪会话状态的页面,关闭自动创建的会话可以节省一些资源。使用如下page指令:

<%@ page session="false"%>

  2.10 Servlet与内存使用

  许多开发者随意地把大量信息保存到用户会话之中。一些时候,保存在会话中的对象没有及时地被垃圾回收机制回收。从性能上看,典型的症状是用户感到系统周期性地变慢,却又不能把原因归于任何一个具体的组件。如果监视JVM的堆空间,它的表现是内存占用不正常地大起大落。

  解决这类内存问题主要有二种办法。第一种办法是,在所有作用范围为会话的Bean中实现HttpSessionBindingListener接口。这样,只要实现valueUnbound()方法,就可以显式地释放Bean使用的资源。

  另外一种办法就是尽快地把会话作废。大多数应用服务器都有设置会话作废间隔时间的选项。另外,也可以用编程的方式调用会话的 setMaxInactiveInterval()方法,该方法用来设定在作废会话之前,Servlet容器允许的客户请求的最大间隔时间,以秒计。

  2.11 HTTP Keep-Alive

  Keep-Alive功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了建立或者重新建立连接。市场上的大部分Web服务器,包括iPlanetIISApache,都支持HTTP Keep-Alive。对于提供静态内容的网站来说,这个功能通常很有用。但是,对于负担较重的网站来说,这里存在另外一个问题:虽然为客户保留打开的连接有一定的好处,但它同样影响了性能,因为在处理暂停期间,本来可以释放的资源仍旧被占用。当Web服务器和应用服务器在同一台机器上运行时,Keep- Alive功能对资源利用的影响尤其突出。

  2.12 JDBCUnicode

  想必你已经了解一些使用JDBC时提高性能的措施,比如利用连接池、正确地选择存储过程和直接执行的SQL、从结果集删除多余的列、预先编译SQL语句,等等。

  除了这些显而易见的选择之外,另一个提高性能的好选择可能就是把所有的字符数据都保存为Unicode(代码页13488)。JavaUnicode形式处理所有数据,因此,数据库驱动程序不必再执行转换过程。但应该记住:如果采用这种方式,数据库会变得更大,因为每个Unicode字符需要2个字节存储空间。另外,如果有其他非Unicode的程序访问数据库,性能问题仍旧会出现,因为这时数据库驱动程序仍旧必须执行转换过程。

  2.13 JDBCI/O

  如果应用程序需要访问一个规模很大的数据集,则应当考虑使用块提取方式。默认情况下,JDBC每次提取32行数据。举例来说,假设我们要遍历一个5000 行的记录集,JDBC必须调用数据库157次才能提取到全部数据。如果把块大小改成512,则调用数据库的次数将减少到10次。

  在一些情形下这种技术无效。例如,如果使用可滚动的记录集,或者在查询中指定了FOR UPDATE,则块操作方式不再有效。

  2.14 内存数据库

  许多应用需要以用户为单位在会话对象中保存相当数量的数据,典型的应用如购物篮和目录等。由于这类数据可以按照行/列的形式组织,因此,许多应用创建了庞大的VectorHashMap。在会话中保存这类数据极大地限制了应用的可伸缩性,因为服务器拥有的内存至少必须达到每个会话占用的内存数量乘以并发用户最大数量,它不仅使服务器价格昂贵,而且垃圾收集的时间间隔也可能延长到难以忍受的程度。

  一些人把购物篮/目录功能转移到数据库层,在一定程度上提高了可伸缩性。然而,把这部分功能放到数据库层也存在问题,且问题的根源与大多数关系数据库系统的体系结构有关。对于关系数据库来说,运行时的重要原则之一是确保所有的写入操作稳定、可靠,因而,所有的性能问题都与物理上把数据写入磁盘的能力有关。关系数据库力图减少I/O操作,特别是对于读操作,但实现该目标的主要途径只是执行一套实现缓冲机制的复杂算法,而这正是数据库层第一号性能瓶颈通常总是 CPU的主要原因。

  一种替代传统关系数据库的方案是,使用在内存中运行的数据库(In-memory Database),例如TimesTen。内存数据库的出发点是允许数据临时地写入,但这些数据不必永久地保存到磁盘上,所有的操作都在内存中进行。这样,内存数据库不需要复杂的算法来减少I/O操作,而且可以采用比较简单的加锁机制,因而速度很快。

 

三、GUI

  这一部分介绍的内容适合于图形用户界面的应用(Applet和普通应用),要用到AWTSwing

  3.1 JAR压缩类文件

  Java档案文件(JAR文件)是根据JavaBean标准压缩的文件,是发布JavaBean组件的主要方式和推荐方式。JAR档案有助于减少文件体积,缩短下载时间。例如,它有助于Applet提高启动速度。一个JAR文件可以包含一个或者多个相关的Bean以及支持文件,比如图形、声音、HTML 和其他资源。

  要在HTML/JSP文件中指定JAR文件,只需在Applet标记中加入ARCHIVE = "name.jar"声明。

  请参见《使用档案文件提高 applet 的加载速度》。

  3.2 提示Applet装入进程

  你是否看到过使用Applet的网站,注意到在应该运行Applet的地方出现了一个占位符?当Applet的下载时间较长时,会发生什么事情?最大的可能就是用户掉头离去。在这种情况下,显示一个Applet正在下载的信息无疑有助于鼓励用户继续等待。

  下面我们来看看一种具体的实现方法。首先创建一个很小的Applet,该Applet负责在后台下载正式的Applet

import java.applet.Applet;
import java.applet.AppletStub;
import java.awt.Label;
import java.awt.Graphics;
import java.awt.GridLayout;
public class PreLoader extends Applet implements Runnable, AppletStub {
String largeAppletName;
Label label;
public void init() {
//
要求装载的正式Applet
largeAppletName = getParameter("applet");
// “
请稍等提示信息

label = new Label("
请稍等..." + largeAppletName);
add(label);
}
public void run(){
try {
//
获得待装载Applet的类

Class largeAppletClass = Class.forName(largeAppletName);
//
创建待装载Applet的实例
Applet largeApplet = (Applet)largeAppletClass.newInstance();
//
设置该AppletStub程序
largeApplet.setStub(this);
//
取消请稍等信息
remove(label);
//
设置布局
setLayout(new GridLayout(1, 0));
add(largeApplet);
//
显示正式的Applet
largeApplet.init();
largeApplet.start();
}
catch (Exception ex) {
//
显示错误信息

label.setText("
不能装入指定的Applet");
}
//
刷新屏幕

validate();
}
public void appletResize(int width, int height) {
//
appletResize调用从stub程序传递到Applet
resize(width, height);
}
}

  编译后的代码小于2K,下载速度很快。代码中有几个地方值得注意。首先,PreLoader实现了AppletStub接口。一般地,Applet从调用者判断自己的codebase。在本例中,我们必须调用setStub()告诉Applet到哪里提取这个信息。另一个值得注意的地方是, AppletStub接口包含许多和Applet类一样的方法,但appletResize()方法除外。这里我们把对appletResize()方法的调用传递给了resize()方法。

 

3.3 在画出图形之前预先装入它

  ImageObserver接口可用来接收图形装入的提示信息。ImageObserver接口只有一个方法imageUpdate(),能够用一次repaint()操作在屏幕上画出图形。下面提供了一个例子。

public boolean imageUpdate(Image img, int flags, int x, int y, int w, int h) {
if ((flags & ALLBITS) !=0 {
repaint();
}
else if (flags & (ERROR |ABORT )) != 0) {
error = true;
//
文件没有找到,考虑显示一个占位符
repaint();
}
return (flags & (ALLBITS | ERROR| ABORT)) == 0;
}

  当图形信息可用时,imageUpdate()方法被调用。如果需要进一步更新,该方法返回true;如果所需信息已经得到,该方法返回false

  3.4 覆盖update方法

  update()方法的默认动作是清除屏幕,然后调用paint()方法。如果使用默认的update()方法,频繁使用图形的应用可能出现显示闪烁现象。要避免在paint()调用之前的屏幕清除操作,只需按照如下方式覆盖update()方法:

public void update(Graphics g) {
paint(g);
}

  更理想的方案是:覆盖update(),只重画屏幕上发生变化的区域,如下所示:

public void update(Graphics g) {
g.clipRect(x, y, w, h);
paint(g);
}

  3.5 延迟重画操作

  对于图形用户界面的应用来说,性能低下的主要原因往往可以归结为重画屏幕的效率低下。当用户改变窗口大小或者滚动一个窗口时,这一点通常可以很明显地观察到。改变窗口大小或者滚动屏幕之类的操作导致重画屏幕事件大量地、快速地生成,甚至超过了相关代码的执行速度。对付这个问题最好的办法是忽略所有迟到的事件。

  建议在这里引入一个数毫秒的时差,即如果我们立即接收到了另一个重画事件,可以停止处理当前事件转而处理最后一个收到的重画事件;否则,我们继续进行当前的重画过程。

  如果事件要启动一项耗时的工作,分离出一个工作线程是一种较好的处理方式;否则,一些部件可能被冻结,因为每次只能处理一个事件。下面提供了一个事件处理的简单例子,但经过扩展后它可以用来控制工作线程。

public static void runOnce(String id, final long milliseconds) {
synchronized(e_queue) { // e_queue:
所有事件的集合
if (!e_queue.containsKey(id)) {
e_queue.put(token, new LastOne());
}
}
final LastOne lastOne = (LastOne) e_queue.get(token);
final long time = System.currentTimeMillis(); //
获得当前时间
lastOne.time = time;
(new Thread() {public void run() {
if (milliseconds > 0) {
try {Thread.sleep(milliseconds);} //
暂停线程
catch (Exception ex) {}
}
synchronized(lastOne.running) { //
等待上一事件结束
if (lastOne.time != time) //
只处理最后一个事件
return;
}
}}).start();
}
private static Hashtable e_queue = new Hashtable();
private static class LastOne {
public long time=0;
public Object running = new Object();
}

 

3.6 使用双缓冲区

  在屏幕之外的缓冲区绘图,完成后立即把整个图形显示出来。由于有两个缓冲区,所以程序可以来回切换。这样,我们可以用一个低优先级的线程负责画图,使得程序能够利用空闲的CPU时间执行其他任务。下面的伪代码片断示范了这种技术。

Graphics myGraphics;
Image myOffscreenImage = createImage(size().width, size().height);
Graphics offscreenGraphics = myOffscreenImage.getGraphics();
offscreenGraphics.drawImage(img, 50, 50, this);
myGraphics.drawImage(myOffscreenImage, 0, 0, this);

  3.7 使用BufferedImage

  Java JDK 1.2使用了一个软显示设备,使得文本在不同的平台上看起来相似。为实现这个功能,Java必须直接处理构成文字的像素。由于这种技术要在内存中大量地进行位复制操作,早期的JDK在使用这种技术时性能不佳。为解决这个问题而提出的Java标准实现了一种新的图形类型,即BufferedImage

  BufferedImage子类描述的图形带有一个可访问的图形数据缓冲区。一个BufferedImage包含一个ColorModel和一组光栅图形数据。这个类一般使用RGB(红、绿、蓝)颜色模型,但也可以处理灰度级图形。它的构造函数很简单,如下所示:
public BufferedImage (int width, int height, int imageType)

  ImageType允许我们指定要缓冲的是什么类型的图形,比如5-RGB8-RGB、灰度级等。

  3.8 使用VolatileImage

  许多硬件平台和它们的操作系统都提供基本的硬件加速支持。例如,硬件加速一般提供矩形填充功能,和利用CPU完成同一任务相比,硬件加速的效率更高。由于硬件加速分离了一部分工作,允许多个工作流并发进行,从而缓解了对CPU和系统总线的压力,使得应用能够运行得更快。利用VolatileImage可以创建硬件加速的图形以及管理图形的内容。由于它直接利用低层平台的能力,性能的改善程度主要取决于系统使用的图形适配器。VolatileImage的内容随时可能丢失,也即它是不稳定的(volatile。因此,在使用图形之前,最好检查一下它的内容是否丢失。VolatileImage有两个能够检查内容是否丢失的方法:

public abstract int validate(GraphicsConfiguration gc);
public abstract Boolean contentsLost();

  每次从VolatileImage对象复制内容或者写入VolatileImage时,应该调用validate()方法。contentsLost()方法告诉我们,自从最后一次validate()调用之后,图形的内容是否丢失。

  虽然VolatileImage是一个抽象类,但不要从它这里派生子类。VolatileImage应该通过 Component.createVolatileImage()或者 GraphicsConfiguration.createCompatibleVolatileImage()方法创建。

  3.9 使用Window Blitting

  进行滚动操作时,所有可见的内容一般都要重画,从而导致大量不必要的重画工作。许多操作系统的图形子系统,包括WIN32 GDIMacOSX/Windows,都支持Window Blitting技术。Window Blitting技术直接在屏幕缓冲区中把图形移到新的位置,只重画新出现的区域。要在Swing应用中使用Window Blitting技术,设置方法如下:

setScrollMode(int mode);

  在大多数应用中,使用这种技术能够提高滚动速度。只有在一种情形下,Window Blitting会导致性能降低,即应用在后台进行滚动操作。如果是用户在滚动一个应用,那么它总是在前台,无需担心任何负面影响。

分享到:
评论

相关推荐

    SPD-Conv-main.zip

    SPD-Conv-main.zip

    Docker从零走向实战视频(上).zip

    目录: 1-1 虚拟化技术发展史 1-2 虚拟化技术是什么 1-3 虚拟化技术的分类 1-4 虚拟化技术的优缺点(1) 1-4 虚拟化技术的优缺点 1-5 容器技术的发展 1-6 Docker的发展历史 1-7 Docker是什么 1-8 容器和虚拟机的区别(1) 1-9 容器和虚拟机的区别(2) 1-10 为什么要使用Docker 2-1 Docker的版本 2-2 Docker的安装 2-3 Docker服务启动 2-4 Docker服务信息 2-5 Docker使用初体验-Docker的运行机制 2-6 Docker使用初体验-Docker镜像仓库 2-7 Docker使用初体验-Docker镜像下载 2-8 Docker使用初体验-Docker镜像启动运行 2-9 Docker使用初体验-访问容器中的Tomcat服务 2-10 Docker使用初体验-Docker的网络访问机制 2-11 Docker使用初体验-进入Docker容器内部 2-12 Docker使用初体验-补充说明 3-1 Docker的体系架构(1) 3-2 Docker的体系架构(2)r ..........

    《狼》教学设计.docx

    《狼》教学设计

    房屋租赁平台:提升租赁交易透明度的数字化路径

    对于在外工作或生活的人来说,寻找合适的住房是首要解决的问题。传统的租房方式包括直接联系房东、通过房屋租赁公司或在线搜索房源。直接找房东可能耗时且不便,尤其是需要提前看房的情况;通过中介虽然方便,但需支付额外费用;而在线租房则提供了随时随地的便利性,因此越来越受到青睐。 本房屋租赁平台使用Java语言配合Idea开发环境进行构建,后端数据库选用了Mysql。平台提供了在线预约看房的功能,包括浏览出租房源、在线预约看房、收藏心仪房屋以及留言咨询等。该系统不仅方便了租房者在线预订和管理看房计划,也为房东提供了房屋信息发布和预订管理的便利。

    四轮独立驱动横摆角速度控制,LQR 基于LQR算法的 基于二自由度动力学方程,通过主动转向afs和直接横摆力矩dyc实现的横摆角速度跟踪 ,模型包括期望横摆角速度,质心侧偏角,稳定性因素,lqr模块等

    四轮独立驱动横摆角速度控制,LQR 基于LQR算法的 基于二自由度动力学方程,通过主动转向afs和直接横摆力矩dyc实现的横摆角速度跟踪 ,模型包括期望横摆角速度,质心侧偏角,稳定性因素,lqr模块等模块,作为lqr入门强烈推荐。 还有详细的lqr资料说明,可以作为基本模板,和其他算法(mpc smc)做对比等

    ESP8266、ESP32网页配网 支持中文SSID

    ESP8266、ESP32平台支持AIRKISS自动配网,但是实际使用中,发现失败的次数挺高的,影响体验,因此另辟他法,偶然发现EPS 支持webserver,通过webserver进行配网可大大提高成功率。 webserver.c实现网页的显示,及获取用户配置的wifi名称和密码; wifi_config.c根据是否已经配过网,决定是否开启ap配网模式还是st连接wifi模式; data_persistence.c实现保存用户设置的wifi名称和密码,防止断电后丢失;

    Python圣诞节倒计时与节日活动管理系统

    圣诞节倒计时与节日活动管理系统是一个基于Python的桌面应用程序,旨在帮助用户庆祝和管理圣诞节期间的活动。随着圣诞节的临近,许多人希望能够清晰地了解距离节日还有多少时间,同时也希望能够有效地组织和安排各类活动,如家庭聚会、朋友聚会、圣诞晚会等。这个应用程序通过直观的用户界面和实用的功能,满足了这些需求。 该系统的核心功能包括一个实时更新的倒计时器,用户可以看到距离圣诞节还有多少天、小时、分钟和秒。倒计时器通过Python的datetime模块实现,确保准确性和实时性。用户可以自定义圣诞节的日期,以适应不同的庆祝习惯。 除了倒计时功能,用户还可以添加、编辑和删除节日活动。通过简单的输入框,用户可以记录活动的名称、时间和地点等信息。所有活动将以列表的形式展示,用户可以轻松查看即将到来的活动,并进行相应的管理。 在技术实现方面,该应用程序使用了Python的Tkinter库来构建图形用户界面。界面设计简洁明了,用户可以轻松地进行操作。程序还使用了matplotlib库来绘制活动的统计图表,帮助用户直观地了解活动安排情况。

    双目立体匹配三维重建点云C++ 本工程基于网上开源代码进行修改,内容如下: 1.修改为 VS2015 Debug win32 版本,支持利用特征点和 OpenCV 立体匹配算法进行进行三维重建及显示

    双目立体匹配三维重建点云C++ 本工程基于网上开源代码进行修改,内容如下: 1.修改为 VS2015 Debug win32 版本,支持利用特征点和 OpenCV 立体匹配算法进行进行三维重建及显示,相关代码需要自行修改,代码中添加了修改注释。 2.工程依赖库为 OpenCV2.4.8,内部已完成 OpenCV 相关配置。 无论电脑中是否配置Opencv 都可以运行。 并且增加了点云保存,可以用MATLAB 显示点云。 一、操作步骤 1.解压后将 Reconstuction3d bin 中的所有 dll 拷贝到C: windows sysWOW64 或者system32 根据电脑版本决定,64 位为 sysWOW64。 2.双击 Reconstuction3d.sln 打开工程,运行后出现结果。 二、程序详解 Reconstuction3d.cpp 为程序主函数 cvFuncs.cpp 为特征点三维重建。 包含SIFT、SURF、FAST 等算法。 cvFuncs2.cpp 为视差图三维重建.包含 BM、SGBM 等算法可以选择两者中的一个进行重建,推荐特征点。 特征点三维重建流程:

    course_s5_linux应用程序开发篇.pdf

    course_s5_linux应用程序开发篇.pdf

    ESP32+DS1302芯片【简单DIY制作时钟】

    ESP32+DS1302芯片【简单DIY制作时钟】

    扑克牌数字检测48-CreateML、Darknet、Paligemma数据集合集.rar

    扑克牌数字检测48-CreateML、Darknet、Paligemma数据集合集.rarPCC3.0 Yolov8-V1 2023-12-04 5:04 PM ============================= *与您的团队在计算机视觉项目上合作 *收集和组织图像 *了解和搜索非结构化图像数据 *注释,创建数据集 *导出,训练和部署计算机视觉模型 *使用主动学习随着时间的推移改善数据集 对于最先进的计算机视觉培训笔记本,您可以与此数据集一起使用 该数据集包括4471张图像。 播放卡分类以创建格式注释。 将以下预处理应用于每个图像: *像素数据的自动取向(带有Exif-Arientation剥离) *调整大小为640x640(拉伸) 应用以下扩展用于创建每个源图像的2个版本: * 0到6像素之间的随机高斯模糊

    政务大数据资源平台设计方案

    政务大数据资源平台设计方案

    基于SSM框架一个比赛裁判管理系统校园赛事管理系统,主要技术(SpringMVC + Spring + Mybatis+Hui+Jquery+Ueditor)全部资料+详细文档+高分项目.zip

    【资源说明】 基于SSM框架一个比赛裁判管理系统校园赛事管理系统,主要技术(SpringMVC + Spring + Mybatis+Hui+Jquery+Ueditor)全部资料+详细文档+高分项目.zip 【备注】 1、该项目是个人高分项目源码,已获导师指导认可通过,答辩评审分达到95分 2、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 3、本项目适合计算机相关专业(人工智能、通信工程、自动化、电子信息、物联网等)的在校学生、老师或者企业员工下载使用,也可作为毕业设计、课程设计、作业、项目初期立项演示等,当然也适合小白学习进阶。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!

    (174549194)ANSYS Fluent Tutorial Guide

    ANSYS Fluent Tutorial Guide ANSYS Fluent是一种基于 Finite Element Method(有限元方法)的计算流体力学(CFD)软件,广泛应用于航空航天、汽车、能源、医药等领域。下面是ANSYS Fluent Tutorial Guide的知识点总结: 1. ANSYS Fluent简介 ANSYS Fluent是一个功能强大且灵活的CFD软件,能够模拟复杂的流体力学、热传导、质量传递等物理过程。该软件广泛应用于航空航天、汽车、能源、医药等领域,用于模拟、设计和优化各种流体力学系统。 2. ANSYS Fluent的主要特点 * 基于Finite Element Method(有限元方法),能够模拟复杂的几何形状和边界条件 * 支持多种物理模型,包括流体力学、热传导、质量传递、化学反应等 * 具有强大的后处理功能,能够输出丰富的结果数据 * 可以与其他ANSYS产品集成,实现多物理场耦合分析 3. ANSYS Fluent在航空航天领域的应用 * 飞机和导弹的气动设计 * 飞机发动机的热传导和燃烧模拟 * 航天器的热保护和气动设计 4. AN

    (173083656)河西学院网络工程javaweb期末大作业.zip

    JavaWeb教务系统是基于Java技术构建的网络应用程序,用于管理高校的教学事务。这个期末大作业可能涵盖了多个关键知识点,包括但不限于以下内容: 1. **Servlet与JSP**:JavaWeb开发的基础,Servlet用于处理服务器端逻辑,而JSP则用于生成动态网页。学生可能需要了解如何创建Servlet类,实现doGet或doPost方法,以及如何在JSP页面上使用EL(Expression Language)和JSTL(JavaServer Pages Standard Tag Library)标签。 2. **MVC模式**:Model-View-Controller模式是JavaWeb开发中常见的设计模式,用于分离业务逻辑、数据模型和用户界面。学生可能需要设计并实现一个MVC架构的教务系统,如Controller负责接收请求并调用Service,Service层处理业务逻辑,而Model层则封装数据。 3. **数据库操作**:项目可能涉及到MySQL或其他关系型数据库的使用,包括数据表的设计、SQL查询语句的编写以及JDBC(Java Database Connect

    Python之正则表达式基础知识

    Python之正则表达式基础知识

    《我的白鸽》教学设计.docx

    《我的白鸽》教学设计

    基于Spring、SpringMVC、Mybatis的校园二手交易平台全部资料+详细文档+高分项目.zip

    【资源说明】 基于Spring、SpringMVC、Mybatis的校园二手交易平台全部资料+详细文档+高分项目.zip 【备注】 1、该项目是个人高分项目源码,已获导师指导认可通过,答辩评审分达到95分 2、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 3、本项目适合计算机相关专业(人工智能、通信工程、自动化、电子信息、物联网等)的在校学生、老师或者企业员工下载使用,也可作为毕业设计、课程设计、作业、项目初期立项演示等,当然也适合小白学习进阶。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!

    非常好的音视频会议系统项目全套技术资料.zip

    非常好的音视频会议系统项目全套技术资料.zip

    UR5 3D模型 urdf模型

    UR5 3D模型

Global site tag (gtag.js) - Google Analytics