- 浏览: 17574 次
- 性别:
- 来自: 福州
最新评论
一、序列化是什么?
序列化支持对象编码为字节流和并从中获得对象。序列化支持对象图像从流中重构。用于轻量级的持久化和通过Socket和RMI的通信。默认的对象编码方法保护私有和临时数据,支持类的演变。一个类可以实现自己的外部编码方法,然后唯一地负责外部格式。
Object Serialization supports the encoding of objects and the objects reachable from them, into a stream of bytes. Serialization also supports the complementary reconstruction of the object graph from a stream. Serialization is used for lightweight persistence and for communication via sockets or Java Remote Method Invocation (Java RMI). The default encoding of objects protects private and transient data, and supports the evolution of the classes. A class may implement its own external encoding and is then solely responsible for the external format.
序列化现在包含一个API,允许对象的序列化数据的指定独立于类的字段,并允许序列化数据从流中读或写,使用现有的协议(协商、商议)保证与默认的读写机制的兼容。
Serialization now includes an API that allows the serialized data of an object to be specified independently of the fields of the class and allows those serialized data fields to be written to and read from the stream using the existing protocol to ensure compatiblity with the default writing and reading mechanisms.
序列化的应用场景:
1) 对数据传输的处理;
2) 对数据加密的处理;
3) 对数据压缩的处理
4) 对版本更新的处理
5) 对继承关系的处理
序列化的实现手段:
1) 默认序列化技术:继承Serializable接口,可重写writeObject/readObject方法。
2) 外部序列化技术:继承Externalizable接口,实现writeExternal/readExternal方法。
3) 替换技术:继承Serializable接口, 实现writeReplace/readResolve进行预编码与解析,读与写不需要平衡,也可以使用代理技术。
4) 使用序列化字段API: 使用ObjectStreamField指定序列化字段,使用对象流中内部类PutField和GetField的putFields/getFieldsf方法,批量将对象的字段写入流或从流中读出。
二、序列化技术的应用
1)序列化技术中对象的传输
在客户端将对象序列化写入流中,在服务器将从流中反序列化读取对象。客户端代码示例,序列化。
服务器代码示例,反序列化。
2)序列化技术对数据的加密
3)序列化技术对数据的压缩
这个例子展示了如何使用writeObject和readObject对自定义数据格式进行编码。当持久化的数据是笨重的,应当采用更轻捷、紧凑的格式来存储它。该例子中的涉及到一个三角形矩阵,一个三角形矩阵是一个二维对称的矩阵,所以序列化时,仅需要存储一半的数据,而不是全部。
4)序列化技术对版本更新的处理
序列化机制仅保存对象的类型信息,属性的类型信息和属性值,与方法无关。序列化允许重构:将新字段添加到类中,将字段从 static 改为非 static,将字段从 transient 改为非 transient。如果采用默认的内部序列化机制,对象中字段去掉修饰符private, static, transient或增加字段,不需要去改写read/write Object方法。
5)序列化技术对继承关系的处理
父类是否实现了序列化,一个是无,一个是有;有的话,序列化的方式是采用默认的内部实现,还是外部的实现?于是,根据父类的序列化的不同情况,子类的序列化需要采取不同的策略。
a)父类实现默认内部序列化接口(子类使用默认化的序列实现就可以了,即实现序列化接口)。
b)父类没有实现内部序列化接口(子类必须实现read/writeObject,显式序列化父类的状态,自身的状态可以采用默认的实现)。
c)父类实现外部序列化接口(子类必须重写read/writeExternal,显式序列化父类与子类的状态,可复用父类的实现)。
d)父类没有实现外部序列化接口(子类必须实现read/writeExternal,显式序列化父类与子类的状态)。
三、序列化技术的实现手段
1)默认序列化技术:继承Serializable接口,可重写writeObject/readObject方法。
2)外部序列化技术:继承Externalizable接口,实现writeExternal/readExternal方法。
3)替换技术:继承Serializable接口, 实现writeReplace/readResolve进行预编码与解析,读与写不需要平衡,也可以应用代理技术。
4)使用序列化字段API: 使用ObjectStreamField指定序列化字段,使用putFields/getFieldsf方法,批量将对象的字段写入流或从流中读出。
序列化支持对象编码为字节流和并从中获得对象。序列化支持对象图像从流中重构。用于轻量级的持久化和通过Socket和RMI的通信。默认的对象编码方法保护私有和临时数据,支持类的演变。一个类可以实现自己的外部编码方法,然后唯一地负责外部格式。
Object Serialization supports the encoding of objects and the objects reachable from them, into a stream of bytes. Serialization also supports the complementary reconstruction of the object graph from a stream. Serialization is used for lightweight persistence and for communication via sockets or Java Remote Method Invocation (Java RMI). The default encoding of objects protects private and transient data, and supports the evolution of the classes. A class may implement its own external encoding and is then solely responsible for the external format.
序列化现在包含一个API,允许对象的序列化数据的指定独立于类的字段,并允许序列化数据从流中读或写,使用现有的协议(协商、商议)保证与默认的读写机制的兼容。
Serialization now includes an API that allows the serialized data of an object to be specified independently of the fields of the class and allows those serialized data fields to be written to and read from the stream using the existing protocol to ensure compatiblity with the default writing and reading mechanisms.
序列化的应用场景:
1) 对数据传输的处理;
2) 对数据加密的处理;
3) 对数据压缩的处理
4) 对版本更新的处理
5) 对继承关系的处理
序列化的实现手段:
1) 默认序列化技术:继承Serializable接口,可重写writeObject/readObject方法。
2) 外部序列化技术:继承Externalizable接口,实现writeExternal/readExternal方法。
3) 替换技术:继承Serializable接口, 实现writeReplace/readResolve进行预编码与解析,读与写不需要平衡,也可以使用代理技术。
4) 使用序列化字段API: 使用ObjectStreamField指定序列化字段,使用对象流中内部类PutField和GetField的putFields/getFieldsf方法,批量将对象的字段写入流或从流中读出。
二、序列化技术的应用
1)序列化技术中对象的传输
在客户端将对象序列化写入流中,在服务器将从流中反序列化读取对象。客户端代码示例,序列化。
import java.io.*; import java.net.*; import java.util.*; public class Client { public static void main(String args[]) { try { // Create a socket Socket soc = new Socket(InetAddress.getLocalHost(), 8020); // Serialize today's date to a outputstream associated to the socket OutputStream o = soc.getOutputStream(); ObjectOutput s = new ObjectOutputStream(o); s.writeObject("Today's date"); s.writeObject(new Date()); s.flush(); s.close(); } catch (Exception e) { System.out.println(e.getMessage()); System.out.println("Error during serialization"); System.exit(1); } } }
服务器代码示例,反序列化。
import java.io.*; import java.net.*; import java.util.*; public class Server { /** * Create the serversocket and use its stream to receive serialized objects */ public static void main(String args[]) { ServerSocket ser = null; Socket soc = null; String str = null; Date d = null; try { ser = new ServerSocket(8020); /* * This will wait for a connection to be made to this socket. */ soc = ser.accept(); InputStream o = soc.getInputStream(); ObjectInput s = new ObjectInputStream(o); str = (String) s.readObject(); d = (Date) s.readObject(); s.close(); // print out what we just received System.out.println(str); System.out.println(d); } catch (Exception e) { System.out.println(e.getMessage()); System.out.println("Error during serialization"); System.exit(1); } } }
2)序列化技术对数据的加密
package serializable; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; class Person implements Serializable { private static final long serialVersionUID = 1L; private String name; private int age; public String getName() { return name;} public int getAge() { return age; } public void setAge(int age) { this.age = age;} public void setName(String name) { this.name = name;} private void writeObject(ObjectOutputStream oos) throws IOException { // Encrypt this.age <<= 3; oos.defaultWriteObject(); } private void readObject(ObjectInputStream ios) throws IOException, ClassNotFoundException { // Decrypt ios.defaultReadObject(); this.age >>= 3; } } class SerializableMain { public static void main(String[] args) throws Exception { Person object = new Person(); object.setName("Lily"); object.setAge(18); // Serializing FileOutputStream fos = new FileOutputStream("Person"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(object); oos.close(); fos.close(); // Deserializing FileInputStream fis = new FileInputStream("Person"); ObjectInputStream ios = new ObjectInputStream(fis); object = (Person) ios.readObject(); fis.close(); ios.close(); System.out.println(object.getAge()); System.out.println(object.getName()); System.out.println(object.getClass()); } }
3)序列化技术对数据的压缩
这个例子展示了如何使用writeObject和readObject对自定义数据格式进行编码。当持久化的数据是笨重的,应当采用更轻捷、紧凑的格式来存储它。该例子中的涉及到一个三角形矩阵,一个三角形矩阵是一个二维对称的矩阵,所以序列化时,仅需要存储一半的数据,而不是全部。
import java.io.*; /* * This will print out two arrays: one from before serialization and the other * from after deserialization. */ public class CustomDataExample implements Serializable { private static final long serialVersionUID = 1L; transient int dimension; transient int thearray[][]; /** * Create the triangular array of dimension dim and initialize it */ CustomDataExample(int dim) { dimension = dim; thearray = new int[dim][dim]; arrayInit(); } /** * Create an CustomDataExample object, serialize it, deserialize it and see * that they are the same. So, basically test that this custom data * example's serialization works. */ public static void main(String args[]) { CustomDataExample corg = new CustomDataExample(4); CustomDataExample cnew = null; // Serialize the original class object try { FileOutputStream fo = new FileOutputStream("cde.tmp"); ObjectOutputStream so = new ObjectOutputStream(fo); so.writeObject(corg); so.flush(); so.close(); } catch (Exception e) { e.printStackTrace(); System.exit(1); } // Deserialize in to new class object try { FileInputStream fi = new FileInputStream("cde.tmp"); ObjectInputStream si = new ObjectInputStream(fi); cnew = (CustomDataExample) si.readObject(); si.close(); } catch (Exception e) { e.printStackTrace(); System.exit(1); } // Print out to check the correctness System.out.println(); System.out.println("Printing the original array..."); System.out.println(corg); System.out.println(); System.out.println("Printing the new array..."); System.out.println(cnew); System.out.println(); System.out.println("The original and new arrays should be the same!"); System.out.println(); } /** * Write out the dimension and 1/2 of the 2-dimensional array to the * ObjectOutputStream s. readObject depends on this data format. * * @serialData Write serializable fields, if any exist. Write out the * integer Dimension of the symetrical, two-dimensional array. * Write out the integers composing 1/2 of the 2-dimensional * array. * */ private void writeObject(ObjectOutputStream s) throws IOException { // Call even if there is no default serializable fields. s.defaultWriteObject(); // save the dimension s.writeInt(dimension); // write out only 1/2 of the 2-dimensional array for (int i = 0; i < dimension; i++) { for (int j = 0; j <= i; j++) { s.writeInt(thearray[i][j]); } } } /** * Read in the dimension and 1/2 of the 2-dimensional array from the * ObjectInputStream s. Was written to by writeObject. Also, copy the 1/2 * array to the other half to completely fill the symmetric array. * * @serialData Read serializable fields, if any exist. Read optional data * consisting of an integer indicating both dimensions of the * 2-dimensional array. Read in 1/2 of the 2-dimensional array. */ private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { /* * Call even if there is no default serializable fields. Enables default * serializable fields to be added in future versions and skipped by * this version which has no default serializable fields. */ s.defaultReadObject(); // restore the dimension dimension = s.readInt(); // allocate space for the array thearray = new int[dimension][dimension]; // first restore 1/2 the 2-dimensional array for (int i = 0; i < dimension; i++) { for (int j = 0; j <= i; j++) { thearray[i][j] = s.readInt(); } } // copy over to the other side for (int i = 0; i < dimension; i++) { for (int j = dimension - 1; j > i; j--) { thearray[i][j] = thearray[j][i]; } } } /** * Initialize the array to some numbers starting from 0 - make it * symmetrical */ void arrayInit() { int x = 0; for (int i = 0; i < dimension; i++) { for (int j = 0; j <= i; j++) { thearray[i][j] = x; thearray[j][i] = x; x++; } } } /** * Print the 2-dimensional array. Useful for testing. */ public String toString() { StringBuffer sb = new StringBuffer(); for (int i = 0; i < dimension; i++) { for (int j = 0; j < dimension; j++) { sb.append(Integer.toString(thearray[i][j]) + " "); } sb.append("\n"); } return (sb.toString()); } }
4)序列化技术对版本更新的处理
序列化机制仅保存对象的类型信息,属性的类型信息和属性值,与方法无关。序列化允许重构:将新字段添加到类中,将字段从 static 改为非 static,将字段从 transient 改为非 transient。如果采用默认的内部序列化机制,对象中字段去掉修饰符private, static, transient或增加字段,不需要去改写read/write Object方法。
5)序列化技术对继承关系的处理
父类是否实现了序列化,一个是无,一个是有;有的话,序列化的方式是采用默认的内部实现,还是外部的实现?于是,根据父类的序列化的不同情况,子类的序列化需要采取不同的策略。
a)父类实现默认内部序列化接口(子类使用默认化的序列实现就可以了,即实现序列化接口)。
b)父类没有实现内部序列化接口(子类必须实现read/writeObject,显式序列化父类的状态,自身的状态可以采用默认的实现)。
c)父类实现外部序列化接口(子类必须重写read/writeExternal,显式序列化父类与子类的状态,可复用父类的实现)。
d)父类没有实现外部序列化接口(子类必须实现read/writeExternal,显式序列化父类与子类的状态)。
三、序列化技术的实现手段
1)默认序列化技术:继承Serializable接口,可重写writeObject/readObject方法。
2)外部序列化技术:继承Externalizable接口,实现writeExternal/readExternal方法。
public class ReadingMaterial implements Externalizable { /* * In order for us to be able to serialize this data, these must be either * serializable/externalizable objects or primitive data types. */ private String author; private String subject; private int yearwritten; /* * Must have a public no-arg constructor when implementing Externalizable */ public ReadingMaterial() { } public ReadingMaterial(String auth, String sub, int year) { author = auth; subject = sub; yearwritten = year; } public String getAuthor() { return author; } public String getSubject() { return subject; } public int getYearwritten() { return yearwritten; } public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(author); out.writeObject(subject); out.writeInt(yearwritten); } public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { author = (String) in.readObject(); subject = (String) in.readObject(); yearwritten = in.readInt(); } }
import java.io.*; public class Book extends ReadingMaterial implements Externalizable { private int numpages; private String name; private boolean ishardcover; /** * mandatory public no-arg constructor */ public Book() { super(); } public Book(int pages, String n, boolean hardcover, String author, String subject, int yearwritten) { super(author, subject, yearwritten); numpages = pages; name = n; ishardcover = hardcover; } public void writeExternal(ObjectOutput out) throws IOException { // first we call the writeExternal of the superclass as to write // all the superclass data fields super.writeExternal(out); // now we take care of this class's fields out.writeInt(numpages); out.writeObject(name); out.writeBoolean(ishardcover); } public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { // first call the superclass external method super.readExternal(in); // now take care of this subclass's fields numpages = in.readInt(); name = (String)in.readObject(); ishardcover= in.readBoolean(); } /** * Prints out the fields. used for testing! */ public String toString() { return("Name: " + name + "\n" + "Author: " + super.getAuthor() + "\n" + "Pages: " + numpages + "\n" + "Subject: " + super.getSubject() + "\n" + "Year: " + super.getYearwritten() + "\n" ); } }
import java.io.*; public class Savesuper { /** * Create an Book (subclass of reading material) object, serialize it, * deserialize it and see that they are the same. So, basically test that * this Externalizable example's works */ public static void main(String args[]) { // create a Book object Book bookorg = new Book(100, "How to Serialize", true, "R.R", "Serialization", 97); Book booknew = null; //serialize the book try { FileOutputStream fo = new FileOutputStream("tmp"); ObjectOutputStream so = new ObjectOutputStream(fo); so.writeObject(bookorg); so.flush(); } catch (Exception e) { System.out.println(e); System.exit(1); } // de-serialize the Book try { FileInputStream fi = new FileInputStream("tmp"); ObjectInputStream si = new ObjectInputStream(fi); booknew = (Book) si.readObject(); } catch (Exception e) { System.out.println(e); System.exit(1); } /* * Print out the original and new book information * It should be the same if we did everything correctly! */ System.out.println(); System.out.println("Printing original book..."); System.out.println(bookorg); System.out.println("Printing new book... "); System.out.println(booknew); System.out.println("Both original and new should be the same!"); System.out.println(); } }
3)替换技术:继承Serializable接口, 实现writeReplace/readResolve进行预编码与解析,读与写不需要平衡,也可以应用代理技术。
public class Substitute { /** * Basically, serialize and deserialize two symbols with the same * name and show that they are actually the same symbol. */ public static void main(String args[]) { // create a few symbols to be serialized Symbol s1 = Symbol.symbolLookup("blue"); Symbol s2 = Symbol.symbolLookup("pink"); Symbol s3 = Symbol.symbolLookup("blue"); // use these to deserialize the symbols Symbol obj1 = null, obj2 = null, obj3 = null; // serialize the symbols try { FileOutputStream fo = new FileOutputStream("symbol.tmp"); ObjectOutputStream so = new ObjectOutputStream(fo); so.writeObject(s1); so.writeObject(s2); so.writeObject(s3); so.flush(); } catch (Exception e) { System.out.println(e); System.exit(1); } // deserialize the symbols try { FileInputStream fi = new FileInputStream("symbol.tmp"); ObjectInputStream si = new ObjectInputStream(fi); obj1 = (Symbol) si.readObject(); obj2 = (Symbol) si.readObject(); obj3 = (Symbol) si.readObject(); } catch (Exception e) { System.out.println(e); System.exit(1); } // show the uniqueness if (obj1 == obj3) { System.out.println("Symbol1 and Symbol3 are the same!"); } System.out.println(obj1.symbolname); System.out.println(obj2.symbolname); System.out.println(obj3.symbolname); } } /** * The class implementing the readResolve method. */ class Symbol implements Serializable { private static final long serialVersionUID = 1L; /** * @serial */ String symbolname; /* * Hashtable is **static** because we need to use the same one for * all symbol objects. */ static Hashtable<String, Symbol> ht = new Hashtable<String, Symbol>(); /** * This method serves as the constructor. It looks in the hashtable and * if that symbol exists, will return that symbol... otherwise, will * create a symbol with that name and will add it to the hashtable. This * will assure that the symbols are always unique. */ static Symbol symbolLookup(String symname) { if (!ht.containsKey(symname)) { ht.put(symname, new Symbol(symname)); } return (ht.get(symname)); } /** * Private constructor because we want "outsiders" to use * symbolLookup instead to force uniqueness. */ private Symbol (String name) { symbolname = name; } /** * Deals with the issue of uniqueness when we are dealing with more * than one VM by adding the read symbol to the hash table, if it * isn't already there. */ public Object readResolve() throws ObjectStreamException { if (!ht.containsKey(symbolname)) { ht.put(symbolname, this); } return (ht.get(symbolname)); } }
class PersonProxy implements java.io.Serializable { private static final long serialVersionUID = 1L; public PersonProxy(Person orig) { data = orig.getFirstName() + "," + orig.getLastName() + "," + orig.getAge(); if (orig.getSpouse() != null) { Person spouse = orig.getSpouse(); data = data + "," + spouse.getFirstName() + "," + spouse.getLastName() + "," + spouse.getAge(); } } public String data; private Object readResolve() throws java.io.ObjectStreamException { String[] pieces = data.split(","); Person result = new Person(pieces[0], pieces[1], Integer .parseInt(pieces[2])); if (pieces.length > 3) { result.setSpouse(new Person(pieces[3], pieces[4], Integer .parseInt(pieces[5]))); result.getSpouse().setSpouse(result); } return result; } } class Person implements java.io.Serializable { public Person(String fn, String ln, int a) { this.firstName = fn; this.lastName = ln; this.age = a; } private Object writeReplace() throws java.io.ObjectStreamException { return new PersonProxy(this); } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public int getAge() { return age; } public Person getSpouse() { return spouse; } public void setFirstName(String value) { firstName = value; } public void setLastName(String value) { lastName = value; } public void setAge(int value) { age = value; } public void setSpouse(Person value) { spouse = value; } public String toString() { return "[Person: firstName=" + firstName + " lastName=" + lastName + " age=" + age + " spouse=" + spouse.getFirstName() + "]"; } private String firstName; private String lastName; private int age; private Person spouse; }
4)使用序列化字段API: 使用ObjectStreamField指定序列化字段,使用putFields/getFieldsf方法,批量将对象的字段写入流或从流中读出。
public class EvolvedClass { public static void main(String args[]) { ARectangle orgClass = new ARectangle(100, 100, 102, 102); ARectangle newClass = null; boolean serialize = false; boolean deserialize = false; if (args.length == 1) { if (args[0].equals("-d")) { deserialize = true; } else if (args[0].equals("-s")) { serialize = true; } else { usage(); System.exit(0); } } else { usage(); System.exit(0); } /* * Serialize the original class if that's the option chosen */ if (serialize) { try { FileOutputStream fo = new FileOutputStream("evolve.tmp"); ObjectOutputStream so = new ObjectOutputStream(fo); so.writeObject(orgClass); so.flush(); } catch (Exception e) { System.out.println(e); System.exit(1); } } if (deserialize) { try { FileInputStream fi = new FileInputStream("evolve.tmp"); ObjectInputStream si = new ObjectInputStream(fi); newClass = (ARectangle) si.readObject(); } catch (Exception e) { System.out.println(e); System.exit(1); } System.out.println("Now printing deserialized object: "); System.out.println(); System.out.println(newClass); } } static void usage() { System.out.println("Usage:"); System.out.println(" -s (in order to serialize)"); System.out.println(" -d (in order to deserialize)"); } } class ARectangle implements java.io.Serializable { Point point1; Point point2; static final long serialVersionUID = 9030593813711490592L; private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField("x1", Integer.TYPE), new ObjectStreamField("y1", Integer.TYPE), new ObjectStreamField("x2", Integer.TYPE), new ObjectStreamField("y2", Integer.TYPE) }; ARectangle(int x1, int y1, int x2, int y2) { point1 = new Point(x1, y1); point2 = new Point(x2, y2); } /** * writeObject - Writes out the serializable fields * (the 4 integers, x1, y1, x2, y2) using the * Serializable Field API. (the methods putFields and * writeFields of the ObjectOutputStream Class and the method put * of the ObjectOutputStream.PutField inner class) * * @serialData Only the serializable fields of the class are written. * No optional data written. */ private void writeObject(ObjectOutputStream s) throws IOException { // set the values of the Serializable fields ObjectOutputStream.PutField fields = s.putFields(); fields.put("x1", point1.x); fields.put("y1", point1.y); fields.put("x2", point2.x); fields.put("y2", point2.y); // save them s.writeFields(); } /** * readsObject - Reads in the serializable fields * (the 4 integers, x1, y1, x2, y2) using the * Serializable Field API. (the methods getFields and * readFields of the ObjectInputStream Class and the method get * of the ObjectOutputStream.GetField inner class) * * @serialData No optional data is read. */ private void readObject(ObjectInputStream s) throws IOException { // prepare to read the alternate persistent fields ObjectInputStream.GetField fields = null; try { fields = s.readFields(); } catch (Exception ClassNotFoundException) { throw new IOException(); } // read the alternate persistent fields int x1 = (int)fields.get("x1", 0); int y1 = (int)fields.get("y1", 0); int x2 = (int)fields.get("x2", 0); int y2 = (int)fields.get("y2", 0); // save them back as Points. point1 = new Point(x1, y1); point2 = new Point(x2, y2); } public String toString() { return("point1.x: " + point1.x + "\npoint1.y: " + point1.y + "\npoint2.x: " + point2.x + "\npoint2.y: " + point2.y); } }
- serial-spec.pdf (341.7 KB)
- 下载次数: 6
发表评论
-
Lisp
2011-09-30 14:28 7811) John McCarthy's Home Page ht ... -
同步与异步(Synchronous and Asynchronous in Concurrency)
2011-03-08 14:59 988The Concurrency Utilities packa ... -
集合与映射(Collection and Map in Data Structure)
2011-03-08 14:55 803The collections framework is a ... -
流与通道(Stream and Channel in I/O)
2011-03-08 14:52 8971) File and device I/O 文件与设备的I/ ... -
递归(Recursion)
2011-03-04 14:09 1191递归,常出现在声明式范式的语言中,用来实现过程迭代的语 ... -
反射(Reflection)
2011-03-02 17:20 714class A { public void metho ... -
泛型(Generics)
2011-03-02 16:14 919重温了一下泛型,心得记录如下。 1)什么是泛型? 泛 ... -
OOP in C Language
2011-02-25 09:26 704// cool.h 头文件,定义父类和子类。 typed ... -
Map-Reduce in C Language
2011-02-22 08:57 695#include <stdio.h> #in ...
相关推荐
电子商务之价格优化算法:梯度下降:机器学习在价格优化中的角色.docx
ToadforOracle与Oracle数据库版本兼容性教程.docx
360浏览器银河麒麟版 for X86 适配兆芯 / 海光 / intel / AMD CPU
使用React.js构建,提供多种主题可供选择,并且易于定制。该项目旨在帮助开发者和自由职业者创建自己的个性化投资组合。 主要功能点 多种主题可供选择,包括绿色、黑白、蓝色、红色、橙色、紫色、粉色和黄色 易于定制,可以在src/data文件夹中更新个人信息 包含主页、关于、简历、教育、技能、经验、项目、成就、服务、推荐信、博客和联系等多个部分 支持通过Google表单收集联系信息 提供SEO优化建议 支持多种部署方式,如Netlify、Firebase、Heroku和GitHub Pages 技术栈主要 React.js Material-UI Axios React-fast-marquee React-helmet React-icons React-reveal React-router-dom React-router-hash-link React-slick Slick-carousel Validator
中小型企业财务管理系统 SSM毕业设计 附带论文 启动教程:https://www.bilibili.com/video/BV1GK1iYyE2B
python whl离线安装包 pip安装失败可以尝试使用whl离线安装包安装 第一步 下载whl文件,注意需要与python版本配套 python版本号、32位64位、arm或amd64均有区别 第二步 使用pip install XXXXX.whl 命令安装,如果whl路径不在cmd窗口当前目录下,需要带上路径 WHL文件是以Wheel格式保存的Python安装包, Wheel是Python发行版的标准内置包格式。 在本质上是一个压缩包,WHL文件中包含了Python安装的py文件和元数据,以及经过编译的pyd文件, 这样就使得它可以在不具备编译环境的条件下,安装适合自己python版本的库文件。 如果要查看WHL文件的内容,可以把.whl后缀名改成.zip,使用解压软件(如WinRAR、WinZIP)解压打开即可查看。 为什么会用到whl文件来安装python库文件呢? 在python的使用过程中,我们免不了要经常通过pip来安装自己所需要的包, 大部分的包基本都能正常安装,但是总会遇到有那么一些包因为各种各样的问题导致安装不了的。 这时我们就可以通过尝试去Python安装包大全中(whl包下载)下载whl包来安装解决问题。
电子商务之价格优化算法:线性回归:价格优化策略实施.docx
内容概要:报告详细介绍了企业数字化转型的驱动因素、数字化转型方案分类及其应用场景,重点关注了云计算、超连接、数字孪生、人工智能、分布式账本、增材制造、人机接口、数据共享、工业物联网等关键技术。这些技术不仅支持了企业的运营效率提升和业务模式创新,也为实现更快、更开放、更高效的数字化转型提供了支撑。报告最后提出了企业实施数字化转型的六个步骤。 适合人群:企业高级管理人员、技术人员、咨询顾问,以及对工业数字化转型感兴趣的读者。 使用场景及目标:帮助企业制定和实施数字化转型策略,优化运营模式,提升业务效率,增强市场竞争力。同时,也可作为政府部门、研究机构和行业协会的参考文献。 其他说明:报告中提到的关键技术及其应用场景对企业数字化转型具有重要的指导意义,特别是对于那些希望通过数字化转型实现业务创新和升级的企业。
基于java的线上选课系统的设计与实现答辩PPT.pptx
安装前的准备 1、安装Python:确保你的计算机上已经安装了Python。你可以在命令行中输入python --version或python3 --version来检查是否已安装以及安装的版本。 个人建议:在anaconda中自建不同python版本的环境,方法如下(其他版本照葫芦画瓢): 比如创建python3.8环境,anaconda命令终端输入:conda create -n py38 python==3.8 2、安装pip:pip是Python的包管理工具,用于安装和管理Python包。你可以通过输入pip --version或pip3 --version来检查pip是否已安装。 安装WHL安装包 1、打开命令行(或打开anaconda命令行终端): 在Windows上,你可以搜索“cmd”或“命令提示符”并打开它。 在macOS或Linux上,你可以打开“终端”。 2、cd到whl文件所在目录安装: 使用cd命令导航到你下载的whl文件所在的文件夹。 终端输入:pip install xxx.whl安装即可(xxx.whl指的是csdn下载解压出来的whl) 3、等待安装完成: 命令行会显示安装进度,并在安装完成后返回提示符。 以上是简单安装介绍,小白也能会,简单好用,从此再也不怕下载安装超时问题。 使用过程遇到问题可以私信,我可以帮你解决! 收起
电子商务之价格优化算法:贝叶斯定价:贝叶斯网络在电子商务定价中的应用.docx
IMG_20241105_235746.jpg
基于java的毕业设计选题系统答辩PPT.pptx
专升本考试资料全套.7z
Trustwave DbProtect:数据库活动监控策略制定.docx
基于VB的程序实例,可供参考学习使用
本压缩包资源说明,你现在往下拉可以看到压缩包内容目录 我是批量上传的基于SpringBoot+Vue的项目,所以描述都一样;有源码有数据库脚本,系统都是测试过可运行的,看文件名即可区分项目~ |Java|SpringBoot|Vue|前后端分离| 开发语言:Java 框架:SpringBoot,Vue JDK版本:JDK1.8 数据库:MySQL 5.7+(推荐5.7,8.0也可以) 数据库工具:Navicat 开发软件: idea/eclipse(推荐idea) Maven包:Maven3.3.9+ 系统环境:Windows/Mac
该源码项目是一款基于Thinkphp5框架的Java插件设计,包含114个文件,其中Java源文件60个,PNG图片32个,XML配置文件7个,GIF图片7个,Git忽略文件1个,LICENSE文件1个,Markdown文件1个,Xmind文件1个,Idea项目文件1个,以及JAR文件1个。
数据库开发和管理最佳实践.pdf
本压缩包资源说明,你现在往下拉可以看到压缩包内容目录 我是批量上传的基于SpringBoot+Vue的项目,所以描述都一样;有源码有数据库脚本,系统都是测试过可运行的,看文件名即可区分项目~ |Java|SpringBoot|Vue|前后端分离| 开发语言:Java 框架:SpringBoot,Vue JDK版本:JDK1.8 数据库:MySQL 5.7+(推荐5.7,8.0也可以) 数据库工具:Navicat 开发软件: idea/eclipse(推荐idea) Maven包:Maven3.3.9+ 系统环境:Windows/Mac