JAVA数据结构存储剖析

时间:2019-05-13 12:12:45下载本文作者:会员上传
简介:写写帮文库小编为你整理了多篇相关的《JAVA数据结构存储剖析》,但愿对你工作学习有帮助,当然你在写写帮文库还可以找到更多《JAVA数据结构存储剖析》。

第一篇:JAVA数据结构存储剖析

JAVA数据结构存储剖析

实用举例:

1:堆栈(stack)

方法的参数值

public void sun(int a , int b)

//调用方法是在栈内存中为参数分配存储空间,方法结束自动释放。

局部变量

public static void main(String[] args){int a = 5;}

//在方法中的局部变量,存储在栈内存中,方法结束时候,释放内存

引用变量

Person p = new Person(“zhaoyue”, 22);

//调用构造方法的时候,“形参”先在堆栈中开辟内存,存放“实参”,再把“实参”的//一份拷贝传入对象之中。此时,“实参”的拷贝存放在堆(heap)中,构造方法结束,//堆栈中的内存释放。

堆栈的存储要领:压栈,出栈,自动清除!

2:堆(heap)

成员变量

public class Person{ String name;int age;}

// New 的时候存储在堆中。

new得到的对象

Person p = new Person(“zhaoyue”, 22);

// New 的时候存储在堆中。

3:数据区(Data segment)

3.1:静态存储(static storage)

静态变量

public static int a = 5;

//JVM运行时首先为其开辟空间,位置不变,程序运行结束时空间释放。并且在运行时只加载一次。

静态方法

public static void run(){print(“hello”);}

//JVM运行时首先为其开辟空间,位置不变,程序运行结束时空间释放。并且在运行时只加载一次。

3.2地址池(address pool)

非new的字符串

String s = “hello world”;

3.3常量存储(constant storage)

常量

public final int a = 5;

4:Code segment(代码区)

4.1:Code segment

存放代码

4.2:方法区(method area)

成员方法

Public void run(){System.out.println(“I’m run!”);}

//类装载的时候存储在方法区,初始时被隐藏,实例化对象时被激活。

具体解释:

在java中有6中存取机制:

1: 寄存器(register)

2: 堆栈(stack)

3: 堆(heap)

4: 静态存储(static storage)

5: 常量存储(constant storage)

6: 非RAM存储寄存器(register):这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部。但是寄存器的数量极其有限,所以寄存器由编译器根据需求进行分配。你不能直接控制,也不能在程序中感觉到寄存器存在的任何迹象。堆栈(stack):位于通用RAM中,但通过它的“堆栈指针”可以从处理器哪里获得支持。堆栈指针若向下移动,则分配新的内存;若向上移动,则释放那些内存。这是一种快速有效的分配存储方法,仅次于寄存器。创建程序时候,JAVA编译器必须知道存储在堆栈内所有数据的确切大小和生命周期,因为它必须生成相应的代码,以便上下移动堆栈指针。这一约束限制了程序的灵活性,所以虽然某些JAVA数据存储在堆栈中——特别是对象引用,但是JAVA对象不存储其中。堆(heap):一种通用性的内存池(也存在于RAM中),用于存放所有的JAVA对象。堆不同于堆栈的好处是:编译器不需要知道要从堆里分配多少存储区域,也不必知道存储的数据在堆里存活多长时间。因此,在堆里分配存储有很大的灵活性。当你需要创建一个对象的时候,只需要new写一行简单的代码,当执行这行代码时,会自动在堆里进行存储分配。当然,为这种灵活性必须要付出相应的代码。用堆进行存储分配比用堆栈进行存储存储需要更多的时

间。

4: 静态存储(static storage):这里的“静态”是指“在固定的位置”。静态存储里存放程序运行时一直存在的数据。你可用关键字static来标识一个对象的特定元素是静态的,但JAVA对象本身从来不会存放在静态存储空间里。

5: 常量存储(constant storage):常量值通常直接存放在程序代码内部,这样做是安全的,因为它们永远不会被改变。有时,在嵌入式系统中,常量本身会和其他部分分割离开,所以在这种情况下,可以选择将其放在ROM中

6: 非RAM存储:如果数据完全存活于程序之外,那么它可以不受程序的任何控制,在程序没有运行时也可以存在。

速度:

就速度来说,有如下关系:

寄存器 > 堆栈 > 堆 > 其他

关系:

然后我主要要说下堆与堆栈的关系:

堆:堆是heap,是所谓的动态内存,其中的内存在不需要时可以回收,以分配给新的内存请求,其内存中的数据是无序的,即先分配的和随后分配的内存并没有什么必然的位置关系,释放时也可以没有先后顺序。一般由使用者自由分配,在C语言中malloc分配的就是堆,需要手动释放。

堆栈:就是stack。实际上是只有一个出入口的队列,即后进先出(frist in , last out),先分配的内存必定后释放。一般由,由系统自动分配,存放函数的参数值,局部变量等,自动清除。

还有,堆是全局的,堆栈是每个函数进入的时候分一小块,函数返回的时候就释放了,静态和全局变量,new得到的变量,都放在堆中,局部变量放在堆栈中,所以函数返回,局部变量就全没了。

JAVA中的基本类型,其实需要特殊对待。因为,在JAVA中,通过new创建的对象存储在“堆”中,所以用new 创建一个小的、简单的变量,如基本类型等,往往不是很有效。因此,在JAVA中,对于这些类型,采用了与C、C++相同的方法。也就是说,不用new 来创建,而是创建一个并非是“引用”的“自动”变量。这个变量拥有它的“值”,并置于堆栈中,因此更高效。

再说一说类的实例方法!

类的实例方法在内存中是只有一份,不过肯定不会是第一个对象中,如果是第一个对象的话,那么当第一个对象被销毁的时候,那么后面的对象就永远无法调用了。

类的实例方法存在一个专门的区叫方法区(method area),事实上类刚装载的时候就被装载好了,不过它们在“睡眠”,只是这些方法必须当有对象产生的时候才会“苏醒”.(比如,一个输出类的成员变量的方法,如果连对象都没有,何来的输出成员变量).所以,方法在装载的时候就有了,但是不可用,因为它没有指象任何一个对象。

而静态的又不一样了,静态的东西存在静态存储(static storage)区,他们和类是一个等级的,就是说只要类被装载,它们就可以直接用.(用类名来调用).他们不依赖与任何对象,所以也不能输出任何对象的成员属性.(除非成员属性也是静态的).每个对象在new的时候都会在堆区中开辟内存,用来保存对象的属性和方法.(实际上方法保存的只是方法区的引用,如果保存的是方法本身,那么试想一下,有多少个对象就得有多少个方法,那么又和第一点中“实例方法在内存中只有一份拷贝”相矛盾了。另外我补充一点,在父类的引用指向子类对象的时候,父类可以调用子类从父类继承的属性和方法,子类覆写父类的属性和方法,在动态绑定(也就是多态)时,子类对象有一个方法区得引用,动态new的时候这个引用指向子类的方法,从而实现了父类可以调用子类覆写父类的方法。这也是动态绑定得名的原因。)

如果您认真看完这篇文章,估计java中内存方面肯定会有所帮助,这篇文章是我总结归纳出来的,并非完全自己写的。有什么不对的地方,欢迎批评指正。

第二篇:java部分数据结构总结

package datastructtest;

import java.io.File;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

import java.util.LinkedList;

import java.util.Scanner;

import javax.swing.JFrame;

public class Testbase {

public static void main(String[] args)throws IOException{

//100之内被3或7整除的数的个数

//int m=0,n=0;

//for(int i=0;i<100;i++){

//if(i%3==0){

//m++;

//}

//if(i%7==0){

//n++;

//}

//}

//System.out.println(“m=”+m+“ ;”);

//System.out.println(“n=”+n+“ ;”);

//1~100之间的整数累加和,并显示每个整数和当前累加和的对应关系 //int sum=0;

//for(int i=1;i<=100;i++){

//

//System.out.print(“i=”+i+“,sum=”+sum);

//sum+=i;

//System.out.println(“;i+sum=”+sum);

//}

//计算30的阶乘

//int m=jiecheng(30);

//System.out.println(m);

//直接插入排序

//int[] test={64,5,7,89,6,24};

//int n=test.length;

//insertSort(test);

//for(int i=0;i

//System.out.print(test[i]+“,”);

//}

//希尔排序

//int[] test={65,34,25,87,12,38,56,46,14,77,92,33};//int n=test.length;

//int d[]={6,3,1};//每次循环用到的增量值

//int numOfD=d.length;//共进行几次循环

//shellSort(test,d,numOfD);

//for(int i=0;i

//System.out.print(test[i]+“,”);

// }

//直接选择排序

//int[] test={65,34,25,87,12,38,56,46,14,77,92,33};

//int n=test.length;

//

//selectSort(test);

//for(int i=0;i

//System.out.print(test[i]+“,”);

// }

////字符串逆转

//char[]a={'a','f','g','h','j'};

//char[]b=reverse1(a);

//for(int i=0;i

//System.out.print(b[i]+“,”);

//}

//Scanner类的应用和split的使用

//System.out.println(“请输入带逗号的字符:”);

//Scanner sc=new Scanner(System.in);

//

//while(sc.hasNext()){

//StringBuffer str=new StringBuffer();

//str=str.append(sc.next());

////System.out.println(str);

//String st=str.toString();

//String[] a=st.split(“,”);

//System.out.println(“字符串被逗号分割之后:”);

//for(int i=0;i

//System.out.println(a[i]);

//}

//}

//写文件和读文件复制文件aa到bb

//FileReader filein=new FileReader(new File(“d://aa.txt”));//此句会产生异常

//FileWriter fileout=new FileWriter(new File(“d://bb.txt”));//int c;

//while((c=filein.read())!=-1){

//fileout.write(c);

//}

//filein.close();

//fileout.close();

//

}

private static int jiecheng(int n){

if(n==1)

return 1;

else

return n*jiecheng(n-1);

}

//栈

private LinkedList list=new LinkedList();

public void push(Object v){

list.addFirst(v);

}

public Object top(){

return list.getFirst();

}

public Object pop(){

return list.removeFirst();

}

//直接插入排序

public static void insertSort(int[] a){

int i,j,temp;

int n=a.length;

for(i=0;i

temp=a[i+1];

j=i;

while(j>-1&&temp<=a[j]){

a[j+1]=a[j];

j--;

}

a[j+1]=temp;

}

//for(i=0;i

//temp=a[i+1];

//// j=i;

//while(i>-1&&temp<=a[i]){

//a[i+1]=a[i];

//i--;

//}

//a[i+1]=temp;

//}

}

//希尔排序

public static void shellSort(int[]a,int[]d,int numOfD){

int i,j,k,m,span;

int temp;

int n=a.length;

for(m=0;m

span=d[m];//取本次的增量值

for(k=0;k

for(i=k;i

temp=a[i+span];

j=i;

while(j>-1&&temp<=a[j]){

a[j+span]=a[j];

j=j-span;

}

a[j+span]=temp;

}

}

}

}

//直接选择排序

public static void selectSort(int[]a){

int i,j,small;

int temp;

int n=a.length;

for(i=0;i

small=i;//设第i个数据元素最小

for(j=i+1;j

if(a[j]

if(small!=i){

temp=a[small];

for(j=small;j>i;j--)//把该区段尚未排序元素依次后移

a[j]=a[j-1];

a[i]=temp;//插入找出的最小元素

}

}

}

public static char[] reverse1(char[]a){

int n=a.length;

char[]b=new char[n];

for(int i=0;i

b[n-i-1]=a[i];

}

return b;

}

}

第三篇:java数据结构测试题及答案解析

Java数据结构试题及解析 下列数据结构中,能用二分法进行查找的是__A____。

A、顺序存储的有序线性表 B、线性链表 C、二叉链表 D、有序线性链表

解析:二分法查找只适用于顺序存储的有序表。在此所说的有序表是指线性表中的元素按值非递减排列(即从小到大,但允许相邻元素值相等)。

在软件设计中,不属于过程设计工具的是__D____。

A、PDL(过程设计语言)B、PAD图 C、N-S图 D、DFD图

解析:软件设计工具包括:程序流程图、N-S、PAD、HIPO,判定表,PDL(伪码)。而DFD(数据流图)属于结构化分析工具。在switch(expression)语句中,expression的数据类型不能是__A____。

A、double B、char C、byte D、short

解析:表达式expression只能返回这个几种类型的值:int、byte、short和char。多分支语句把表达式返回的值依次与每个case子句中的值相比较,如果遇到匹配的值,则执行该case子句后的语句序列。下列叙述中,错误的是__D____。

A、父类不能替代子类 B、子类能够替代父类 C、子类继承父类 D、父类包含子类

通过继承实现代码复用:

Java中所有的类都是通过直接或间接地继承java.lang.Object类得到的。继承而得到的类称为子类,被继承的类称为父类。子类不能继承父类中访问权限为private的成员变量和方法,子类可以重写父类的方法,及命名与父类同名的成员变量。

子类通过隐藏父类的成员变量和重写父类的方法,把父类的状态和行为改变为自身的状态和行为。注意:子类中重写的方法和父类中被重写的方法要具有相同的名字,相同的参数表和相同的返回类型,只是函数体不同。

由于子类继承了父类所有的属性(私有的除外),所以子类对象可以作为父类对象使用。程序中凡是使用父类对象的地方,都可以用子类对象来代替。一个对象可以通过引用子类的实例来调用子类的方法。

java运行时系统根据调用该方法的实例,来决定调用哪个方法。对子类的一个实例,如果子类重写了父类的方法,则运行时系统调用子类的方法;如果子类继承了父类的方法(未重写),则运行时系统调用父类的方法。自定义表格类中的model部分应实现的接口是___A___。

A、AbstractTableModel B、JTable C、TableModel D、TableModelable 下列代码中,将引起编译错误的行是__B____。

1)public class Exercise{

2)public static void main(String args[]){

3)float f=0.0;

4)f+=1.0;

5)}

6)}

A、第2行 B、第3行 C、第4行 D、第6行

解析:float定义变量赋值时,需要在数值后面加f以标识它为浮点型,让系统知道该给它精确到多少位。下列关于Java多线程并发控制机制的叙述中,错误的是___B___。

A、Java中对共享数据操作的并发控制是采用加锁技术

B、线程之间的交互,提倡采用suspend()/resume()方法

C、共享数据的访问权限都必须定义为private

D、Java中没有提供检测与避免死锁的专门机制,但应用程序员可以采用某些策略防止死锁的发生 解析:

1)Java中对共享数据操作的并发控制是采用传统的封锁技术。一个程序中单独的、并发的线程对同一个对象进行访问的代码段,称为临界区。在Java语言中,临界区可以是一个语句块或是一个方法,并且用“synchronized”关键字标识。Java平台将每个由synchronized(Object)语句指定的对象设置一个锁,称为对象锁。

2)共享数据的所有访问都必须作为临界区,使用“synchronized”进行加锁控制。用“synchronized”保护的数据也必须是私有的,使线程不能直接访问这些数据,必须通过对象的方法。

3)Java中没有检测与避免死锁的专门机制,因此完全由程序进行控制,防止死锁的发生。

4)有时,某个线程进入“synchronized”块后,共享数据的状态并不一定满足线程的需要,它要等待其他线程将共享数据改变为它需要的状态后才能继续执行,但由于此时它占有了该对象的锁,其他线程无法对共享数据进行操作,为此Java引入wait()和notify(),这两个方法使java.lang.object类的方法,使实现线程通信的两个方法。

下列操作中,不属于Applet安全限制的是___D___。

A、加载本 B、读写本地文件系统 C、运行本地可执行程序 D、与同一个页面中的Applet通信 在进行模块测试时,要为每个被测试的模块另外设计两类模块:驱动模块和承接模块(桩模块)。其中,驱动模块相当于被测试模块的主程序,它接收测试数据,并传给被测试模块,输出实际测试结果。承接模块通常用于代替被测试模块调用的其他模块,其作用仅做少量的数据操作,是一个模拟子程序,不必将子模块的所有功能带入。

Java语言具有可移植性、高性能、健壮性、安全性和独立于体系结构的__跨平台____特点。

解析:Java语言是一种跨平台,适合于分布式计算环境的面向对象的编程语言。具体来说,它具有如下特性:简单性、面向对象、分布式、解释型、可靠、安全、平台无关、可移植、高性能、多线程、动态性等。在运行时,由Java解释器自动导入,而不用import语句引入的包是__java.lang____。

解析:因为包java.lang所包含的类和接口对所有实际的Java程序都是必要的,所以,它被自动导入所有的程序且它是Java最广泛使用的包。下列程序的功能是创建了一个显示5个“Hello!”的线程并启动运行,请将程序补充完整。

public class ThreadTest extends Thread{

public static void main(String args[]){

ThreadTest t=new __ThreadTest()____;

t.start();}

public void run(){int i=0;

while(true){System.out.println(“Hello!”);

if(i++==4)break;

}

}

解析:ThreadTest继承java.lang.Thread类,重写了run()方法,实现了Java中的线程。ThreadTest t定义了空的线程对象,下面t.start()启动了这个线程,因此ThreadTest t=new ______;就应该是实例化该线程对象,所以空格中应填ThreadTest()。

Swing的顶层容器有:JApplet、JWindow、JDialog和__JFrame____。

顶层容器:JFrame、JApplet、JDialog和JWindow共4个。

中间容器:JPanel、JScrollPane、JSplitPane、JToolBar。

特殊容器:JInternalFrame、JLayeredPane、JRootPane。

基本控件:JButton、JComboBox、JList、JMenu、JSlider、JTextField。

不可编辑信息的构件:JLabel、JProgressBar、ToolTip、可编辑信息的构件:JColorChooser、JFileChooser、JFileChooser、JTable、JTextArea 所有的这些构件的分类都是按功能来划分的。14 下列叙述中正确的是___D___。

A、一个逻辑数据结构只能有一种存储结构

B、数据的逻辑结构属于线性结构,存储结构属于非线性结构

C、一个逻辑数据结构可以有多种存储结构,且各种存储结构不影响数据处理的效率

D、一个逻辑数据结构可以有多种存储结构,且各种存储结构影响数据处理的效率

解析:一般来说,一种数据的逻辑结构根据需要可以表示成多种存储结构,常用的存储结构有顺序、链接、索引等存储结构。而采用不同的存储结构,其数据处理的效率是不同的。

Java的图形用户界面的最基本的组成部分就是构件(Component),构件是一个可以以图形化的方式显示在屏幕上并能与用户交互的对象,但构件不能独立地显示出来,必须将构件放在一定的容器中才可以显示出来。解析:容器Container是一个类,因为容器本身也是一个构件,具有构件的所有性质,因此继承之Component类。

下列叙述中,错误的是__A____。

A、File类能够存储文件 B、File类能够读写文件C、File类能够建立文件D、File类能够获取文件目录信息

解析:文件类File是java.io包中的一个重要的非流类,它以一种与系统无关的方式表示一个文件对象的属性。而目录在Java中作为一种特殊文件,即文件名的列表,通过类File所提供的方法,可得到文件或目录的描述信息(包括名字、路径、长度、可读、可写等),也可以生成新文件、目录、修改文件和目录,查询文件属性,重命名文件或者删除文件。

下列叙述中,正确的是___C___。

A、Reader是一个读取字符文件的接口 B、Reader是一个读取数据文件的抽象类

C、Reader是一个读取字符文件的抽象类 D、Reader是一个读取字节文件的一般类

解析:Java中的流分为两种,一种是字节流,另一种是字符流,分别由四个抽象类来表示(每种流包括输入和输出两种,所以一共四个):InputStream,OutputStream,Reader,Writer。Java中其他多种多样变化的流均是由它们派生出来的。

在这其中InputStream和OutputStream在早期的Java版本中就已经存在了,它们是基于字节流的,而基于字符流的Reader和Writer是后来加入作为补充的。在这四个抽象类中,InputStream和Reader定义了完全相同的接口:

int read()

int read(char cbuf[])

int read(char cbuf[], int offset, int length)

而OutputStream和Writer也是如此:

int write(int c)

int write(char cbuf[])

int write(char cbuf[], int offset, int length)用于输入压缩文件格式的ZipInputStream类所属包是___D___。

A、java.util B、java.io C、java.nio D、java.util.zip

解析:ZipInputStream该对象用于从ZIP压缩文件中创建输入流对象。

对象定义结构:java.util.zip.ZipInputStream

静态成员变量:CENATT、CENATX、CENCRC……,这些静态成员变量用于定义在压缩过程中采用的压缩算法。

构造方法:ZipInputStream(InputStream in)应用输入流对象创建从ZIP文件中读取数据的输入流对象。

成员方法:

int available()判断当前入口指定的压缩原始文件中是否还有未读数据。

void close()关闭ZIP输入流对象。

void closeEntry()关闭被读取的ZIP入口,并移动到下一压缩原始文件入口。

protectedZipEntry createZipEntry(String name)利用指定的名称创建ZipEntry对象实例。

ZipEntry getNextEntry()将输入流对象移动到下一入口对象。

int read(byte[] b, int off, int len)从当前ZipEntry中读取字节数组。

long skip(long n)将输入流指定的读取数据位置移动n个字节。

在Swing中用轻量级的构件替代了AWT中的重量级的构件,而且Swing的替代构件中都包含有一些其他的特性。与AWT构件不同,Swing构件不能直接添加到顶层容器中,它必须添加到一个与Swing顶层容器相关联的内容面板(contentPane)上。

查找随机文件的记录时,应使用的方法是___C___。

A、readInt()B、readBytes(int n)C、seek(long l)D、readDouble()

文件操作中经常需要的是随机访问,Java中的RandomAccessFile类提供随机访问文件的功能,其中的seek方法实现了查找随机文件记录的功能,格式如下:

void seek(long pos);//用于移动文件指针到指定的位置 20 下列关于栈的描述中错误的是___B___。

A、栈是先进后出的线性表 B、栈只能顺序存储 C、栈具有记忆作用

D、对栈的插入与删除操作中,不需要改变栈底指针 21 对于长度为n的线性表,在最坏情况下,下列各排序法所对应的比较次数中正确的是___D___。

A、冒泡排序为n/2 B、冒泡排序为n C、快速排序为n D、快速排序为n(n-1)22 对长度为n的线性表进行顺序查找,在最坏情况下所需要的比较次数为__C____。

A、B、n/2 C、n D、n+1 23 在进行顺序查找过程中,如果线性表中的第一个元素就是被查找元素,则只需做一次比较就查找成功,查找效率最高;但如果被查找的元素是线性表中的最后一个元素,或者被查找的元素根本就不在线性表中,则为了查找这个元素需要与线性表中所有的元素进行比较,这是顺序查找的最坏情况。所以对长度为n的线性表进行顺序查找,在最坏情况下需要比较n次。模块独立性是指每个模块只完成系统要求的独立的子功能,并且与其他模块的联系最少且接口简单。耦合性与内聚性是模块独立性的两个定性标准,耦合与内聚是相互关联的。在程序结构中,各模块的内聚性越强,则耦合性越弱。一般较优秀的软件设计,应尽量做到高内聚,低耦合,即减弱模块之间的耦合性和提高模块内的内聚性,有利于提高模块的独立性。

计算机软件是计算机系统中与硬件相互依存的另一部分,是包括程序、数据及相关文档的完整集合。软件具有以下特点:①软件是一种逻辑实体,而不是物理实体,具有抽象性;②软件的生产过程与硬件不同,它没有明显的制作过程;③软件在运行、使用期间不存在磨损、老化问题;④软件的开发、运行对计算机系统具有依赖性,受计算机系统的限制,这导致软件移植的问题;⑤软件复杂性高,成本昂贵;⑥软件开发涉及诸多的社会因素。

数据独立性是数据库技术的重要特点之一。所谓数据独立性是指__D____。

A、数据与程序独立存放 B、不同的数据被存放在不同的文件中

C、不同的数据只能被对应的应用程序所使用 D、以上三种说法都不对

在读字符文件Employee.dat时,使用该文件作为参数的类是___D___。

A、BufferedReader B、DataInputStream C、DataOutputStream D、FileInputStream 下列不是InputStream子类的是__C____。

A、文件输入流FileInputStream B、对象输入流ObjectInputStream

C、字符输入流CharInputStream D、压缩文件输入流ZipInputStream 28 Java中没有CharInputStream流。

下列方法中可以用来创建一个新线程的是___C___。

A、实现java.lang.Runnable接口并重写start()方法

B、实现java.lang.Runnable接口并重写run()方法

C、继承java.lang.Thread类并重写run()方法

D、继承java.lang.Thread类并重写start()方法 下列关于线程优先级的说法中,正确的是__C____。

A、线程的优先级是不能改变的 B、线程的优先级是在创建线程时设置的 C、在创建线程后的任何时候都可以设置 D、B和C 下列代码中,将引起一个编译错误的行是__D____。

1)public class Test{

2)int m,n;

3)public Test(){}

4)public Test(int a){m=a;}

5)public static void main(String args[]){

6)Test t1,t2;

7)int j,k;

8)j=0;k=0;

9)t1=new Test();

10)t2=new Test(j,k);

11)}

12)}

A、第3行 B、第5行 C、第6行 D、第10行

阅读下列代码后

public class Person{

int arr[]=new int[10];

public static void main(String args[]){

System.out.println(arr[1]);

}

}

正确的说法是__A____。

A、编译时将产生错误 B、编译时正确,运行时将产生错误 C、输出为零 D、输出为空

32请阅读下列程序代码,然后将程序的执行结果补充完整。

程序代码:

class throwsException

{

static void Proc(int sel)throws ArithmeticException,ArrayIndexOutOfBoundsException

{

System.out.println(“In Situation”+sel);

if(sel==0){

System.out.println(“no Exception caught”);

return;

}

else if(sel==1){

int iArray[]=new int[4];

iArray[1]=3;

}

}

public static void main(String[] args)

{

try{

Proc(0);

Proc(1);

}catch(ArrayIndexOutOfBoundsException e){

System.out.println(“Catch”+e);

}finally{

System.out.println(“in Proc finally”);

}

}

} 执行结果:

In Situation0

no Exception caught

__In Situation1____

in Proc finally

解析:调用Proc(1)时,执行语句System.out.println(“In Situation”+sel);控制台输出In Situation1。然后在if语句中执行sel==1分支,该分支中无任何输出语句。

当使用Thread t=new Thread(r)创建一个线程时,表达式:r instanceof Thread的值是___false___。

表达式:r instanceof Thread的语义即“r是否为Thread的实例(instance)”。再看Thread的构造方法(Thread有许多构造方法,以下是最典型的构造方法,其它构造方法都是从下面的构造方法中“减掉”一些参数形成的):

Thread(ThreadGroup group, Runnable target, String name)

可见,Thread构造方法中没有类型为Thread的参数,故r不可能是Thread的实例

第四篇:数据结构实验报告二线性表的顺序存储

实验报告二 线性表的顺序存储

班级: 2010XXX 姓名: HoogLe 学号: 2010XXXX 专业: XXXX

2858505197@qq.com

一、实验目的:

(1)掌握顺序表的基本操作的实现方法。

(2)应用顺序表的基本算法实现集合A=AUB算法。

(3)应用顺序表的基本算法实现两有序顺序表的归并算法。

二、实验内容:

1、线性表顺序存储结构的基本操作算法实现(要求采用类模板实现)

[实现提示](同时可参见教材p5822-p60页算法、ppt)函数、类名称等可自定义,部分变量请加上学号后3位。库函数载和常量定义:(代码)#include using namespace std;const int MaxSize=100;

(1)顺序表存储结构的定义(类的声明):(代码)

template //定义模板类SeqList class SeqList { public: SeqList();//无参构造函数

SeqList(datatype a[ ], int n);//有参构造函数 ~SeqList(){};//析构函数为空 int Length();//求线性表的长度

datatype Get(int i);//按位查找,取线性表的第i个元素 int Locate(datatype item);//查找元素item void Insert(int i, datatype item);//在第i个位置插入元素item datatype Delete(int i);//删除线性表的第i个元素 void display();//遍历线性表,按序号依次输出各元素 private: datatype data[MaxSize];//存放数据元素的数组 int length;//线性表的长度 };

(2)初始化顺序表算法实现(不带参数的构造函数)/* *输 入:无

*前置条件:顺序表不存在 *功 能:构建一个顺序表 *输 出:无

*后置条件:表长为0 */ 实现代码:

template SeqList:: SeqList(){ length=0;}

(3)顺序表的建立算法(带参数的构造函数)

/* *输 入:顺序表信息的数组形式a[],顺序表长度n *前置条件:顺序表不存在

*功 能:将数组a[]中元素建为长度为n的顺序表 *输 出:无

*后置条件:构建一个顺序表 */ 实现代码:

template SeqList:: SeqList(datatype a[], int n){ if(n>MaxSize){

cout<<“数组元素个数不合法”<

data[i]=a[i];length=n;}(4)在顺序表的第i个位置前插入元素e算法 /* *输 入:插入元素e,插入位置i *前置条件:顺序表存在,i要合法

*功 能:将元素e插入到顺序表中位置i处 *输 出:无

*后置条件:顺序表插入新元素,表长加1 */ 实现代码:

template void SeqList::Insert(int i, datatype item){ int j;if(length>=MaxSize){

cout<<“溢出”<length+1){

cout<<“i不合法!”<=i;j--)

data[j]=data[j-1];data[i-1]=item;length++;}(5)删除线性表中第i个元素算法 /* *输 入:要删除元素位置i *前置条件:顺序表存在,i要合法

*功 能:删除顺序表中位置为i的元素 *输 出:无

*后置条件: 顺序表册除了一个元素,表长减1 */ 实现代码:

template datatype SeqList::Delete(int i){ int item,j;if(length==0){

cout<<“表为空,无法删除元素!”<length){

cout<<“i不合法!”<

for(j=i;j

data[j-1]=data[j];//注意数组下标从0记

length--;return item;}(6)遍历线性表元素算法 /* *输 入:无

*前置条件:顺序表存在 *功 能:顺序表遍历 *输 出:输出所有元素 *后置条件:无 */ 实现代码:

template void SeqList::display(){ if(length==0){

cout<<“表为空,无法输出!”<

cout<

(7)获得线性表长度算法 /* *输 入:无

*前置条件:顺序表存在 *功 能:输出顺序表长度 *输 出:顺序表长度 *后置条件:无 */ 实现代码:

template int SeqList::Length(){ return Length;}

(8)在顺序线性表中查找e值,返回该元素的位序算法 /* *输 入:查询元素值e *前置条件:顺序表存在

*功 能:按值查找值的元素并输出位置 *输 出:查询元素的位置 *后置条件:无 */ 实现代码:

template int SeqList::Locate(datatype item){ for(int i=0;i

//下标为i的元素等于item,返回其序号i+1

return 0;//查找失败 }

(9)获得顺序线性表第i个元素的值 /* *输 入:查询元素位置i *前置条件:顺序表存在,i要合法

*功 能:按位查找位置为i的元素并输出值 *输 出:查询元素的值 *后置条件:无 */ 实现代码:

template datatype SeqList::Get(int i){ if(i<0||i>length){

cout<<“i不合法!”<

(10)判表空算法 /* *输 入:无 *前置条件:无

*功 能:判表是否为空

*输 出:为空返回1,不为空返回0 *后置条件:无 */ 实现代码:

template bool SeqList::Empty(){ if(length==0){

return 1;} else {

return 0;} }

(11)求直接前驱结点算法 /* *输 入:要查找的元素e,待存放前驱结点值e1

*前置条件:无

*功 能:查找该元素的所在位置,获得其前驱所在位置。*输 出:返回其前驱结点的位序。*后置条件:e1值为前驱结点的值 */ 实现代码:

template int SeqList::Pre(datatype item){ int k=Locate(item)-1;if(k>0)

return k;else {

cout<<“无前驱结点!”<

return 0;} }(12)求直接后继结点算法 /* *输 入:要查找的元素e,待存放后继结点值e1 *前置条件:无

*功 能:查找该元素的所在位置,获得其后继所在位置。*输 出:返回其后继结点的位序。*后置条件:e1值为后继结点的值 */ 实现代码:

template int SeqList::Suc(datatype item){ int k=Locate(item)+1;if(k>length){

cout<<“无后继结点!”<

return k;} }

上机实现以上基本操作,写出main()程序: void main(){ SeqList Seq;//创建

if(Seq.Empty()){

cout<<“线性表为空!”<

} Seq.Insert(1,1);Seq.Insert(2,2);Seq.Insert(3,3);Seq.Insert(4,4);Seq.Insert(5,5);//插入元素操作

cout<<“输出插入的五个元素:”<

cout<

cout<<“2是第”<

cout<<“第五个元素是:”<

cout<<“线性表的长度为:”<

Seq.Delete(3);//删除元素

cout<<“删除第三个元素后的线性表为:”<

cout<

cout<<“元素2前驱结点的数值为:”<

cout<<“元素4后继结点的位置为:”<

cout<<“元素4后继结点的数值为:”<

要求对每个算法都加以测试,判断是否正确;并测试不同类型数据的操作。粘贴测试数据及运行结果:

2、用以上基本操作算法,实现A=AUB算法。(利用函数模板实现)/* *输 入:集合A,集合B *前置条件:无

*功 能:实现A=AUB *输 出:无

*后置条件:A中添加了B中的元素。*/

实现代码:

template SeqList SeqList::Add(SeqList& item){ if(item.Empty())

return *this;else {

int k=item.Length();

int num=this->Length();

for(int i=1;i<=k;i++)

{

for(int j=0;j

if(data[j]==item.Get(i))

{

break;

}

else if(num-1==j&&data[num-1]!=item.Get(i))

{

this->Insert(++num,item.Get(i));

}

}

return *this;} } void main(){ SeqList A,B;cout<<“A∪B的结果是:”<

B.Insert(1,2);B.Insert(2,6);B.Insert(3,1);B.Insert(4,8);B.Insert(5,9);//插入集合B中元素

A.Add(B);A.display();cout<

3、对以上顺序表类中的基本操作算法适当加以补充,实现向一个有序的(非递减)的顺序表中插入数据元素e算法。/* *输 入:插入元素e *前置条件:顺序表已有序

*功 能:将元素e插入到顺序表中适当的位置,使顺序表依然有序 *输 出: 无

*后置条件:有序顺序表插入了新元素,且表长加1。*/ 实现代码:

template void SeqList::orderInsert(datatype item){ int num=this->Length();for(int i=0;i

if((data[i]item))

{

for(int k=num;k>i;k--)

data[k]=data[k-1];

data[i+1]=item;

length++;

break;

}

if(data[i]>item)

{

for(int k=num;k>i;k--)

data[k]=data[k-1];

data[i]=item;

length++;

break;

} } } void main(){ SeqList A,B;A.Insert(1,3);A.Insert(2,5);A.Insert(3,6);A.Insert(4,8);A.Insert(5,10);//插入顺序表

cout<<“原顺序表为:”<

cout<

cout<<“插入新元素后的顺序表为:”<

4、算法实现:La,Lb为非递减的有序线性表,将其归并为Lc,该线性表仍有序(未考虑相同时删除一重复值)(利用函数类板实现)MergeList: /* *输 入:有序线性表La,有序线性表Lb *前置条件:顺序表已有序

*功 能:将两线性表归并,不去掉相同元素 *输 出: 返回一个新的有序线性表Lc *后置条件:无 */ 实现代码:

template SeqList SeqList::ElseAdd(SeqList Seq1,SeqList Seq2){ int num=Seq2.Length();for(int i=0;i<=num;i++){

Seq1.orderInsert(Seq2.Get(i));} return Seq1;} void main(){ SeqList La,Lb,Lc;La.Insert(1,2);La.Insert(2,4);La.Insert(3,6);La.Insert(4,8);//插入La cout<<“La中元素为:”<

cout<<“合并后的Lc为:”<

cout<

粘贴测试数据及运行结果:

三、心得体会:(含上机中所遇问题的解决办法,所使用到的编程技巧、创新点及编程的心得)

第五篇:数据结构课程设计—java通讯录管理系统

import java.io.*;import java.util.*;public class LittleProgram {

static boolean isDelete = true;

static boolean isFind = true;

public static void main(String [] args)//主方法,程序从这里开始运行

throws IOException,NumberNotFoundException

{

int choice=-1;

do{

LittleProgram lp = new LittleProgram();

System.out.println();

System.out.println(“t

#”);

System.out.println();

System.out.println(“tt通訊錄管理系统”);

System.out.println(“t

请用号码插入,查找,修改,删除数据”);

System.out.println();

System.out.println(“t

#n”);

System.out.print(“1.增加号码:n”+

“2.查找号码:n”+

“3.删除号码:n”+ “4.清除所有号码:n”+ “5.把号码全部打印到屏幕n”+ “6.把通讯录按号码排序n”+

“7.修改号码n”+

“8.统计通码讯录的总人数n”+

“9.关于作者n”+

“0.退出程序.n” +

“输入:”);

BufferedReader in =

//从终

new BufferedReader(//端接

new InputStreamReader(System.in));//收数

String inputLine = in.readLine();

//字选

choice= Integer.valueOf(inputLine).intValue();//项;

switch(choice)

{

case 1: {//1.增加号码

String str = lp.inputData();

lp.addData(str);

System.out.println(“增加号码成功.”);

timeOut(1);

}break;

case 2: {//2.查找号码

long find = 0;

System.out.print(“请输入你要查找的号码:”);

BufferedReader inn =

new BufferedReader(new InputStreamReader(System.in));

String inputLi = inn.readLine();

find = Integer.valueOf(inputLi).longValue();

lp.findData(find);

timeOut(2);

}break;

case 3: {//3.删除号码

long deleteNumber = 0;

System.out.print(“请输入你想删除号码:”);

BufferedReader bf =

new BufferedReader(new InputStreamReader(System.in));

String inputL = bf.readLine();

deleteNumber = Integer.valueOf(inputL).longValue();

lp.deleteData(deleteNumber);

if(isDelete)

System.out.println(“删除号码成功!”);

timeOut(1);

}break;

case 4: {

lp.clearData();//4.清除所有号码

timeOut(1);

}break;

case 5: {

print();//5.把号码全部打印到屏幕

timeOut(2);

}break;

case 6: {

lp.numSort();//6.把号码按号码排序

System.out.println(“按照号码从小到大排序成功!n”+

“排序后:n”);

print();

timeOut(2);

}break;

case 7: {

lp.rewrite();//7.修改号码

timeOut(2);

}break;

case 8: {

int count = lp.count();

System.out.println(“共有”+count+“个号码记录.”);

timeOut(2);

}break;

case 9: {

System.out.print(“tt李雪萍n”+

“tt安徽理工大學理學院n”+

“ttQQ:1154646392n”);

timeOut(4);

}break;

}}while(choice!= 0);

System.out.println(“Bye!^-^”);

System.exit(0);

}

public String inputData()//从终端接收数据的方法,返回字符串

throws IOException,NumberFormatException

{

System.out.print(“请依次输入 :号码 姓名 地址 生日n” +

“每项数据请用空格隔开:”);

String all = “";

try{

BufferedReader in =

//从终

new BufferedReader(//端接

new InputStreamReader(System.in));

//收数

String inputLine = in.readLine();

//据

StringTokenizer str =

new StringTokenizer(inputLine,” “);//接收的数据用空格隔开,这个类用来提取每个字符串

long num = Integer.valueOf(str.nextToken()).longValue();//号码

String name =(String)str.nextToken();

//姓名

String add =(String)str.nextToken();

// 地址

String birth =(String)str.nextToken();//出生年月

all = String.valueOf(num)+” , “+

name +” , “+

add +” , “+

String.valueOf(birth);//把所有的数据用” , “隔开然后在连起来放进字符串all

}catch(IOException e){}

catch(NumberFormatException e){}

return all;//返回字符串all

}

public void addData(String str)//增加号码的方法

throws IOException

{

String s1 =”“,s2=”“ ,s3= ”“;

File file = new File(”c:data.txt“);

if(file.exists())//如果文件data.txt存在 {

try{

BufferedReader in =

new BufferedReader(new FileReader(file));

while((s1=in.readLine())!=null)

s2+=s1+”n“;//把文件中的每行数据全部放进一个字符串s2

s2+=str+”n“;

//再把s2于形参str相连放进s2

BufferedReader in2 =

//把字符

new BufferedReader(//串s2也

new StringReader(s2));

//就是原

PrintWriter out =

//文件+

new PrintWriter(//形参str(新输入的一行数据)

new BufferedWriter(//重新写进data.txt

new FileWriter(file)));

//覆盖原来的数据

while((s3=in2.readLine())!= null)

{

out.println(s3);

}

out.close();

//System.out.println(”write data true.“);

}catch(IOException e){}

}else{

System.err.println(”File “data” Missing!“);

}

}

public void clearData()//清除data.txt的所有数据的方法

throws IOException

{

File file = new File(”c:data.txt“);

if(file.exists())//如果文件在{

try{

PrintWriter out =

new PrintWriter(new BufferedWriter(new FileWriter(file)));

out.print(”“);//在文件data.txt里写进一个空字符,所以清除了原来的内容

out.close();//关闭文件

System.out.println(”clear data true!“);

}catch(IOException e){}

}else{

System.err.println(”File “data” Missing!“);

}

}

public void deleteData(long deleteNumber)//删除某条号码数据

throws IOException,FileNotFoundException

{

isDelete = true;

try{

DataMap mp = new DataMap();//生成一个自己编写的容器

long j=0;

String s1=”“,s2=”“,s3=”“;

BufferedReader in =

new BufferedReader(new FileReader(”c:data.txt“));

while((s1=in.readLine())!=null)

{

j=numberTokenizer(s1);

mp.put(j,s1);

}

try{

if(mp.containsKey(String.valueOf(deleteNumber).toString()))

{

mp.remove(deleteNumber);

}else

throw new NumberNotFoundException();

Collection c = mp.values();

Iterator iter = c.iterator();

while(iter.hasNext())

{

s1 =(String)iter.next();

s3 +=s1+”n“;

}

BufferedReader in2 =

new BufferedReader(new StringReader(s3));

PrintWriter out =

new PrintWriter(new BufferedWriter(new FileWriter(”c:data.txt“)));

//System.out.println(”delete No“+deleteNumber);

while((s1 = in2.readLine())!=null)

{

out.println(s1);

} out.close();}catch(NumberNotFoundException e){

isDelete = false;

System.out.println(deleteNumber+” no found :(“);

}

}catch(IOException e){}

}

public long numberTokenizer(String s)

throws IOException

{

StringTokenizer st =

new StringTokenizer(s,” “);

return Integer.valueOf((st.nextToken())).longValue();

}

public void findData(long find)//查找数据

throws IOException,NumberNotFoundException

{

isFind = true;

String s = ”“,findString =”“;long i;DataMap dm = new DataMap();BufferedReader in =

new BufferedReader(new FileReader(”c:data.txt“));

while((s=in.readLine())!=null)

{

i=numberTokenizer(s);

dm.put(i,s);

}

//in.close();

try{

if(dm.containsKey(String.valueOf(find).toString()))

{

findString = dm.get(find);

System.out.println(”学号“+find+”学生的资料是:“);

System.out.println(findString);

}else

throw new NumberNotFoundException();

}catch(NumberNotFoundException e){

System.out.println(find+” no found :(“);

isFind = false;

}

}

public static void print()//读取文本文件把数据打印到终端的方法

throws IOException

{

try{

BufferedReader in =

new BufferedReader(new FileReader(”c:data.txt“));

String read = ”“;

while((read = in.readLine())!=null)

System.out.println(read);

}catch(IOException e){}

}

public static void timeOut(double sec)//停顿短暂时间的一个方法完全可以不要这个功能

{

double seconds = sec;

long t = System.currentTimeMillis()+(int)(seconds*1000);

while((System.currentTimeMillis())

;

}

public void numSort()//按学号排序

throws IOException

{

long i = 0;

String s = ”“;

try{

DataArrayList dal = new DataArrayList();

BufferedReader in =

new BufferedReader(new FileReader(”c:data.txt“));

while((s=in.readLine())!=null)

{

i=numberTokenizer(s);

dal.add(i);

}

Collections.sort(dal);

DataMap dm = new DataMap();

BufferedReader in2 =

new BufferedReader(new FileReader(”c:data.txt“));

while((s=in2.readLine())!=null)

{

i=numberTokenizer(s);

dm.put(i,s);

}

PrintWriter out =

new PrintWriter(new BufferedWriter(new FileWriter(”c:data.txt“)));

Iterator it = dal.iterator();

long temp = 0;

String tempStr = ”“;

while(it.hasNext())

{

temp = Integer.valueOf((String)it.next()).longValue();

tempStr = dm.get(temp);

out.println(tempStr);

}

out.close();

}catch(IOException e){}

}

public void rewrite()

throws IOException,NumberNotFoundException

{

try{

System.out.print(”请输入你要修改的学生号码:“);

BufferedReader in =

new BufferedReader(new InputStreamReader(System.in));

String inputLine = in.readLine();

long num = Integer.valueOf(inputLine).longValue();

findData(num);

if(isFind)

{ deleteData(num);System.out.print(”请重新输入该号码:“);String str = inputData();

addData(str);

System.out.println(”rewrite true!“);

}

}catch(IOException e){}

catch(NumberNotFoundException e){}

}

public int count()

throws IOException

{

DataArrayList dal = new DataArrayList();

try{

String s = ”“;

long i =0;

BufferedReader in =

new BufferedReader(new FileReader(”c:data.txt“));

while((s=in.readLine())!=null)

{

i=numberTokenizer(s);

dal.add(i);

}

}catch(IOException e){}

return dal.size();

} } /* *

* @author RangWei * TODO 这是个写的一个容器,继承公共类HashMap * 大概的功能就相当一个数组

*

*/ class DataMap extends HashMap//一个存储数据的Map

{

public void put(long i,String str)//把学号和数据放进这个Map

{

//以后一个学号(key)对应的是一个人的数据(value)

put(String.valueOf(i).toString(),str);

}

public void remove(long i)//接收学号,然后删除学号(key)和它对应的数据(value)

{

remove(String.valueOf(i).toString().toString());

}

public String get(long i)//接收一个学号,然后返回这个key对应的value

{

String s = String.valueOf(i).toString();

if(!containsKey(s))

{

System.err.println(”Not found Key: "+s);

}

return(String)get(s);

} } /*

*

* @author RangWei * * TODO 这个类继承ArrayList * 用来按数字排序,在用号码排序时要用到它

*

*/ class DataArrayList extends ArrayList {

public void add(long num)

{

String numToString = String.valueOf(num).toString();

add(numToString);

} } /* *

* @author RangWei * * TODO 增加的一个Exception,主要是在文件里没有要找

* 的号码就抛出

*

*/ class NumberNotFoundException extends Exception {

public NumberNotFoundException()

{} }

下载JAVA数据结构存储剖析word格式文档
下载JAVA数据结构存储剖析.doc
将本文档下载到自己电脑,方便修改和收藏,请勿使用迅雷等下载。
点此处下载文档

文档为doc格式


声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:645879355@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。

相关范文推荐

    数据结构(Java)复习题及答案 1绪论

    一、单项选择题 ( B )1. 计算机算法必须具备输入、输出和 等5个特性。 A) 可行性、可移植性和可扩充性 B) 可行性、确定性和有穷性 C) 确定性、有穷性和稳定性 D) 易读性、稳......

    2012广西壮族自治区JAVA版数据结构试题及答案

    1、下列序列中,执行第一趟快速排序后得到的序列是( A )。 A)[d,a,e,d,b]f[h,g] B) [c,e,a,d]f[h,g,b] C) [g,a,e,c,b]f[d,h] D) [a,b,c,d,]f[e,g,h] 2、设给定问题的规模为变量......

    用java调用oracle存储过程总结

    用java调用oracle存储过程总结 分类: PL/SQL系列 2009-09-24 15:08 253人阅读 评论(0) 收藏 举报 声明: 以下的例子不一定正确,只是为了演示大概的流程。 一:无返回值的存储......

    数据结构实验报告三线性表的链式存储(5篇范文)

    实验报告三 线性表的链式存储 班级: 2010XXX 姓名: HoogLe 学号: 2010XXXX 专业: XXXX 2858505197@qq.com 一、 实验目的: (1) 掌握单链表的基本操作的实现方法。 (2) 掌握循环单链表......

    企业财务数据存储及备份解决方案剖析

    企业财务数据存储及备份解决方案 一、需求分析 财务部门是企业开展信息化较早的部门,很多企业在实施会计电算化取得成功后,逐步将企业的信息化推向供应链、人力资源等系统。......

    数据结构参考材料[范文大全]

    数据结构参考题目 一、选择 1.如果在数据结构中每个数据元素只可能有一个直接前驱,但可以有多个直接后继,则该结构是( ) A.栈 B.队列 C. 树 D.图 2.下面程序段的时间复杂度为( ) f......

    BMP图像存储格式

    维基百科的BMP定义 BMP取自位图BitMaP的缩写,也称为DIB(与设备无关的位图),是微软视窗图形子系统(Graphics Device Interface)内部使用的一种位图图形格式,它是微软视窗平台上的一......

    存储方案选择

    第三章 存储方案选择 3.1 存储架构选择 目前主流的存储架构包括DAS、 NAS、 SAN,下面针对3种主流应用系统做架构分析。 直连方式存储(Direct Attached StorageSAN)。存储设备组......