Summarizing Java Collection Class operation optimization Experience _java

Source: Internet
Author: User
Tags addall class definition comparable int size static class concurrentmodificationexception stringbuffer

In the actual project development, there will be many objects, how to manage objects efficiently and conveniently, and become an important link that affects program performance and maintainability. Java provides a collection framework to solve such problems, linear tables, lists, hash tables, etc. are commonly used data structures, in the Java development, the JDK has provided us with a series of corresponding classes to implement the basic data structure, all classes in Java.util this package, listing 1 describes the relationship of the collection class.

Listing 1. Relationship between collection classes

Collection
├list
│├linkedlist
│├arraylist
│└vector
│└stack
└set
Map
├hashtable
├hashmap
└weakhashmap

Collection interface
Collection interface

Collection is the most basic set interface, and a Collection represents a set of Object, the Collection element (Elements). Some Collection allow the same elements, support the ordering of elements, and others. JDK does not provide classes that directly inherit from Collection, and the JDK provides classes that inherit from Collection, such as List and Set. All classes that implement the Collection interface must provide two standard constructors, parameterless constructors are used to create an empty Collection, and a constructor for a Collection parameter is used to create a new Collection, the new The Collection has the same element as the incoming Collection, and the latter constructor allows the user to replicate a Collection.

How do I traverse every element in the Collection?

Regardless of the actual type of Collection, it supports a iterator () method that returns an iteration that can be used to access each element of the Collection one at a time. Typical usage is as follows:

Iterator it = Collection.iterator (); Gets an iterative child while
 
(It.hasnext ()) {
 
Object obj = It.next ();//Get the next element
 
}

The two interfaces derived from the Collection interface are List and Set.

The main methods provided by the Collection interface are:

1, the Boolean Add (Object o) adds objects to the collection;
2, the Boolean remove (object o) deletes the specified object;
3, int size () returns the number of elements in the current collection;
4. Boolean contains (object O) looks for the specified object in the collection;
5, Boolean IsEmpty () to determine whether the collection is empty;
6, iterator iterator () returns an iterator;
7. Boolean containsall (Collection C) finds whether the collection has elements in set C;
8. Boolean AddAll (Collection c) adds all the elements in the set C to the set;
9. Void Clear () deletes all elements in the collection;
10. void RemoveAll (Collection c) removes the elements in the C set from the set;
11. void Retainall (Collection c) Removes elements that are not contained in collection C from the collection.
List Interface

The List is an ordered Collection, using this interface to precisely control where each element is inserted. The user can access the elements in the list, similar to the Java array, by using the index (the position of the element in the list, similar to the array subscript). Unlike the Set to be mentioned below, the List allows the same elements.

In addition to the iterator () method with the Collection interface prerequisites, the List provides a listiterator () method that returns a Listiterator interface. Compared with the standard iterator interface, Listiterator has a number of add () methods such as Add, delete, set elements, forward or backward traversal functions. The common classes that implement the List interface are Linkedlist,arraylist,vector and Stack.

The main methods provided by the List interface are:

1, void Add (int index,object Element) Adds an object at the specified location;
2. Boolean AddAll (int index,collection c) adds the elements of the set C to the specified location;
3, Object get (int index) returns the element of the specified position in the list;
4, int indexOf (Object o) returns the position of the first occurrence of element o;
5, Object removeint (int index) deletes the element at the specified position;
6. Object set (int index,object element) replaces elements on position index with element elements, and returns the substituted elements.
Map Interface

The MAP does not inherit the Collection interface. Map provides a mapping of key to Value, a map cannot contain the same key, and each key can map only one value. The map interface provides a view of 3 collections, which can be treated as a set of Key sets, a set of Value sets, or a set of key-value mappings.

The main methods provided by MAP are:

1, Boolean equals (object o) Comparison object;
2, the Boolean remove (object o) deletes an object;
3, put (Object key,object value) add key and value.
Randomaccess Interface

The Randomaccess interface is a flag interface that does not provide any method in itself, and the task is generally considered to be an object that supports fast random access by invoking the object of the Randomaccess interface. The primary purpose of this interface is to identify the List implementations that can support fast random access. Any array-based list implementation implements the Raodomaccess interface, while the implementation based on the linked list is not. Because only the array can carry on the fast random access, but the random access to the linked list needs to carry on the link list the traversal. Therefore, the advantage of this interface is that you know in your application that the list object being processed can be accessed quickly and randomly to perform different operations on different lists to improve the performance of the program.

Collection Class Introduction
LinkedList class

LinkedList implements the List interface, allowing Null elements. In addition LinkedList provides additional get, Remove, Insert, and other methods to manipulate data at LinkedList's header or tail. These operations enable LinkedList to be used as stacks (stack), queues (queue), or bidirectional queues (Deque). Note that LinkedList does not have a synchronized method, which is not thread-synchronized, that is, if multiple threads access a List at the same time, they must implement access synchronization themselves. One workaround is to construct a synchronized list when the list is created, such as

List List = Collections.synchronizedlist (new LinkedList (...)) ;

ArrayList class

ArrayList implements a variable sized array. It allows all elements, including Null. The runtime of a method such as Size, IsEmpty, GET, Set, and so on is constant, but the Add method cost is the allocated constant, and the time for n (N) is added to the nth element, and the other methods run at a linear time.

Each ArrayList instance has a capacity (Capacity) that is used to store the size of an array of elements that can be automatically incremented as new elements are added continuously. When you need to insert a large number of elements, you can call the Ensurecapacity method before inserting to increase the capacity of the ArrayList to increase the insertion efficiency. Like LinkedList, ArrayList is also a thread-out-of-sync (unsynchronized).

The main methods provided by ArrayList are:

1. The Boolean Add (Object o) adds the specified element to the end of the list;
2. The Boolean Add (int index,object Element) adds the specified element at the specified position in the list;
3. Boolean AddAll (Collection c) adds the specified collection to the end of the list;
4. Boolean AddAll (int index,collection c) joins the specified set at the specified position in the list;
5. Boolean Clear () deletes all elements in the list;
6. Boolean Clone () returns a copy of the list instance;
7, Boolean contains (Object O) to determine whether the list contains elements;
8. Boolean ensurecapacity (int m) increases the capacity of the list, and if necessary, the list can hold m elements;
9, Object get (int index) returns the element of the specified position in the list;
10, Int indexOf (Object elem) finds the subscript of the specified element in the list;
11, Int size () returns the number of elements in the current list.
Vector class

Vectors are very similar to ArrayList, the difference being that vectors are thread-synchronized. Iterator created by Vector, although the same interface was created with ArrayList, but because vectors are synchronized, when one iterator is created and is being used, another thread changes the state of the vector (for example, adding Or some elements are removed), the concurrentmodificationexception is thrown when the iterator method is invoked, so the exception must be caught.

Stack class

Stack inherits from the Vector and implements a LIFO stack. Stack provides 5 additional methods that allow vectors to be used as stacks. In addition to the basic Push and Pop methods, and Peek method to get the top of the stack elements, Empty method test stack is empty, the Search method detects an element in the stack position. Notice that stack is just created with an empty stack.

Set class

A Set is a Collection that contains no duplicate elements, that is, any two elements E1 and E2 have E1.equals (E2) =false. Set has a maximum of one null element. Obviously, the constructor of the Set has a constraint, and the incoming Collection parameter cannot contain duplicate elements. Note that you must be careful to manipulate variable objects (Mutable object), which can cause problems if the variable elements in a Set change their state.

Hashtable class

Hashtable inherits the map interface and implements a hash table based on the Key-value map. Any object that is Non-null (non-null) can be a Key or Value. Adding data using put (Key,value), fetching data using Get (Key), the time cost of these two basic operations is constant.

Hashtable adjusts performance by Initial Capacity and Load Factor two parameters. Typically, the default Load Factor 0.75 achieves a better balance of time and space. Increasing the Load Factor can save space but the corresponding lookup time will increase, affecting operations like get and put. Using the simple example of Hashtable, the three digits of 1, 2, 3 are placed inside the Hashtable, their Key is "one", "two", "three", and the code is shown in Listing 2.

Listing 2. Hashtable sample

Hashtable numbers = new Hashtable ();
Numbers.put ("One", New Integer (1));
Numbers.put ("Two", New Integer (2));
Numbers.put ("Three", New Integer (3));

If we need to take out a number, such as 2, we can use the key to remove the code, as shown in Listing 3.

Listing 3. Reading data from hastable

Integer n = (integer) numbers.get ("two");
System.out.println ("two =" + N);

Because an object that is a key will determine the location of its corresponding Value by calculating its hash function, any object that is a key must implement the Hashcode and Equals methods. The Hashcode and Equals methods inherit from the root class object, and if you use a custom class as a Key, be very careful, as defined by the hash function, if two objects are the same, i.e. obj1.equals (OBJ2) =true, their hashcode Must be the same, but if two objects are different, their hashcode is not necessarily different, if two different objects hashcode the same, this phenomenon is called a conflict, the conflict will lead to the operation of the hash table time overhead, so try to define a good hashcode () method, can speed up the operation of the hash table.

If the same objects have different hashcode, the operation of the hash table will have unexpected results (the expected Get method returns Null), to avoid this problem, it is best to copy the Equals method and the Hashcode method, rather than just write one.

HashMap class

HashMap is similar to Hashtable, except that HashMap is thread-Out-of-sync and allows NULL, that is, null Value and null Key. However, when HASHMAP is treated as a Collection (the values () method returns Collection), its iterative child operation time cost is proportional to the capacity of the HashMap. Therefore, if the performance of an iterative operation is significant, do not set the HASHMAP initialization capacity too high, or the Load Factor parameter setting is too low.

Weakhashmap class

Weakhashmap is an improved HASHMAP, which implements a "weak reference" to key, and if a key is no longer referenced externally, the key can be reclaimed by GC.


Collection Class Practice
ArrayList, Vector, LinkedList are all from the abstractlist implementation, and abstractlist directly implement the List interface, and expand from Abstarctcollection. ArrayList and vectors use an array implementation, ArrayList does not provide thread synchronization for either method, so it is not thread-safe, and most of the vectors are thread-safe implementations. LinkedList uses a cyclic bidirectional linked list data structure, which is connected by a series of table items, and a table entry always contains 3 parts, element content, the precursor table item, and the back-drive table entry.

Expansion is required when the ArrayList demand for capacity exceeds the size of the current array. During the expansion process, a large number of array copying operations will be performed, and the System.arraycopy () method will eventually be invoked when the array is replicated. LinkedList because of the use of the structure of the linked list, so do not need to maintain the size of the capacity, but each increase in the elements need to create a new Entry object, and more assignment operations, in the frequent system calls, the performance will have a certain impact, Generating new objects without interruption is still taking up a certain amount of resources. Because of the continuity of the array, we always increase the elements at the end, and only when there is not enough space can we generate the array expansion and the replication.

The ArrayList is based on an array, and the array is a contiguous memory space, and if you insert an element at any point in the array, all elements in that position will need to be rearranged, so it is less efficient and can insert data to the tail as much as possible. LinkedList does not cause performance degradation because of the insertion of data.

After each effective element deletion of the ArrayList, the array is reorganized, and the more the deleted element position is, the greater the overhead of the array reorganization, the less the cost of the element to be deleted. LinkedList to remove the middle of the data needs to facilitate the completion of half a List.

Listing 4. ArrayList and LinkedList use code

Import java.util.ArrayList;
 
Import java.util.LinkedList;
 public class Arraylistandlinkedlist {public static void main (string[] args) {Long start = System.currenttimemillis ();
 ArrayList list = new ArrayList ();
 Object obj = new Object ();
 for (int i=0;i<5000000;i++) {list.add (obj);
 Long end = System.currenttimemillis ();
 
 System.out.println (End-start);
 Start = System.currenttimemillis ();
 LinkedList list1 = new LinkedList ();
 Object obj1 = new Object ();
 for (int i=0;i<5000000;i++) {list1.add (obj1);
 End = System.currenttimemillis ();
 
 System.out.println (End-start);
 Start = System.currenttimemillis ();
 Object obj2 = new Object ();
 for (int i=0;i<1000;i++) {list.add (0,OBJ2);
 End = System.currenttimemillis ();
 
 System.out.println (End-start);
 Start = System.currenttimemillis ();
 Object obj3 = new Object ();
 for (int i=0;i<1000;i++) {list1.add (obj1);
 End = System.currenttimemillis ();
 
 System.out.println (End-start); Start = System.currenttimemillis ();
 List.remove (0);
 End = System.currenttimemillis ();
 
 System.out.println (End-start);
 Start = System.currenttimemillis ();
 List1.remove (250000);
 End = System.currenttimemillis ();
 
 
 System.out.println (End-start);
 }
}

Listing 5. Run output

639
1296
6969
0
0
15

HashMap is the key to do the hash algorithm, and then map the hash value to the memory address, directly to obtain the key of the corresponding data. In HashMap, the underlying data structure uses an array, called a memory address, which is the subscript index of an array. HashMap's high performance needs to guarantee the following points:

1, the Hash algorithm must be efficient;
2, the Hash value to the memory address (array index) algorithm is fast;
3, according to the memory address (array index) can directly obtain the corresponding value.
HashMap is actually an array of linked lists. As already introduced, based on the HashMap linked list method implementation mechanism, as long as the hashcode () and the Hash () method is good enough to reduce conflict as far as possible, then the operation of HashMap is almost equivalent to the random access operation of the array, with good performance. However, if the hashcode () or Hash () method is poor, in the case of a large number of conflicts, HashMap in fact degenerate into several linked lists, the HASHMAP operation is equivalent to traversing the list, at this time performance is poor.

A functional disadvantage of HASHMAP is its disorder, the elements that are deposited into the HashMap, and the output is unordered when traversing HashMap. If you want the elements to remain in the order in which they are entered, you can use linkedhashmap substitution.

Linkedhashmap inherits from HashMap, has the high efficiency, simultaneously on the HashMap Foundation, also has added a linked list in the interior, uses in the element order.

HashMap can perform the put () and get () operations most quickly through the hash algorithm. TREEMAP provides a completely different MAP implementation. Functionally, TREEMAP has a more powerful function than HashMap, which implements the SortedMap interface, which means it can sort the elements. TREEMAP performance is slightly lower than HashMap. If elements need to be sorted in development, this functionality is not possible with HASHMAP, and iterative output using TREEMAP will be in the order of elements. Linkedhashmap are sorted based on the order in which the elements enter the collection or in the order in which they are accessed, TreeMap is based on the intrinsic order of the elements (determined by Comparator or comparable).

Linkedhashmap are sorted according to the order in which the elements are added or accessed, and TreeMap is sorted according to the Key of the element.

The code shown in Listing 6 illustrates the sort of business logic that is implemented using TREEMAP.

Listing 6. TreeMap Implementation Sort

Import Java.util.Iterator;
Import Java.util.Map;
 
 
Import Java.util.TreeMap; public class Student implements comparable<student>{public string name, public int score, public Student (string n
 
Ame,int score) {this.name = name; This.score = score;} @Override//Tell TreeMap how to sort public int compareTo (Student o) {//TODO auto-generated Method stub if (O.score<this.score) {return 1;}
else if (o.score>this.score) {return-1;} return 0;
@Override public String toString () {stringbuffer sb = new StringBuffer (); Sb.append ("Name:");
Sb.append (name);
Sb.append ("");
Sb.append ("Score:");
Sb.append (score);
return sb.tostring ();
public static void Main (string[] args) {TreeMap map = new TreeMap ();
Student S1 = new Student ("1", 100);
Student s2 = new Student ("2", 99);
Student s3 = new Student ("3", 97);
Student S4 = new Student ("4", 91);
Map.put (S1, New Studentdetailinfo (S1));
Map.put (S2, new Studentdetailinfo (S2));
Map.put (S3, New Studentdetailinfo (S3)); Map.put (S4, New StudentdetaiLinfo (S4));
Prints the People Map map1= ((TREEMAP) map) between S4 and S2. SubMap (S4, S2);
For (iterator Iterator=map1.keyset (). iterator (); Iterator.hasnext ();) {Student key = (Student) iterator.next ();
System.out.println (key+ "->" +map.get (key));
 
} System.out.println ("SubMap end");
Print scores are lower than S1 map1= (TREEMAP) map). Headmap (S1);
For (iterator Iterator=map1.keyset (). iterator (); Iterator.hasnext ();) {Student key = (Student) iterator.next ();
System.out.println (key+ "->" +map.get (key));
 
} System.out.println ("SubMap end");
Print scores are higher than S1 map1= (TREEMAP) map). Tailmap (S1);
For (iterator Iterator=map1.keyset (). iterator (); Iterator.hasnext ();) {Student key = (Student) iterator.next ();
System.out.println (key+ "->" +map.get (key));
} System.out.println ("SubMap end"); Class studentdetailinfo{Student S; public studentdetailinfo (Student s) {THIS.S = s;} @Override public String ToS Tring () {return s.name + "' s detail Information";}}

Listing 7. Running output

Name:4 score:91->4 ' s detail information
name:3 score:97->3 ' s detail information subMap end
name:4 Score:91->4 ' s detail information
name:3 score:97->3 ' s detail information name:2 score:99->2
' s detail Information
SubMap end
name:1 score:100->1 ' s detail information-end

The Weakhashmap feature is that if there is no other reference to this key except for its own reference to key, then this Map will automatically discard the value. The code shown in Listing 8 declares two Map objects, one is HashMap, one is Weakhashmap, and puts a, B two objects into two maps, when HashMap deletes a, and a and B point to Null, Weakhashmap A will automatically be recycled. The reason for this is that, for a object, when HashMap deletes and points A to Null, there is no pointer to a in addition to the Weakhashmap, so weakhashmap automatically discards a, while the B object points to NULL, but there is also a pointer to B in the HashMap, so Weakhashmap will retain the B object.

Listing 8.WeakHashMap Sample Code

Import Java.util.HashMap;
Import Java.util.Iterator;
Import Java.util.Map;
Import Java.util.WeakHashMap;
 
public class Weakhashmaptest {public
 static void Main (string[] args) throws Exception {
 String a = new String ("a" );
 String b = new String ("B");
 Map Weakmap = new Weakhashmap ();
 Map map = new HashMap ();
 Map.put (A, "AAA");
 Map.put (b, "BBB");
 Weakmap.put (A, "AAA");
 Weakmap.put (b, "BBB");
 Map.Remove (a);
 A=null;
 B=null;
 System.GC ();
 Iterator i = Map.entryset (). iterator ();
 while (I.hasnext ()) {
 map.entry en = (map.entry) i.next ();
 SYSTEM.OUT.PRINTLN ("Map:" +en.getkey () + ":" +en.getvalue ());
 }
 Iterator J = Weakmap.entryset (). iterator ();
 while (J.hasnext ()) {
 map.entry en = (map.entry) j.next ();
 System.out.println ("Weakmap:" +en.getkey () + ":" +en.getvalue ());}}}

Listing 9. Running output

MAP:B:BBB
WEAKMAP:B:BBB

Weakhashmap mainly by expungestaleentries this function to remove its internal unused entries, so as to achieve the purpose of automatically freeing memory. This function is called essentially as long as the content of the weakhashmap is accessed, thereby eliminating entries that are no longer internal to external references. But if the weakhashmap is generated beforehand and the GC has not accessed the weakhashmap before, isn't it possible to free up memory?

Listing 10. WeakHashMapTest1

Import java.util.ArrayList;
Import java.util.List;
Import Java.util.WeakHashMap;
 
public class WeakHashMapTest1 {public
 static void Main (string[] args) throws Exception {
 List<weakhashmap <byte[][], byte[][]>> maps = new arraylist<weakhashmap<byte[][], byte[][]>> ();
 for (int i = 0; i < 1000 i++) {
 weakhashmap<byte[][], byte[][]> d = new weakhashmap<byte[][], Byte[][]> ;();
 D.put (New byte[1000][1000], new byte[1000][1000]);
 Maps.add (d);
 System.GC ();
 System.err.println (i);
 }}}

Run the code shown in listing 10 without changing any JVM parameters, because the Java default memory is 64M, the throw memory overflowed the error.

Listing 11. Run output

241

242

243

Exception in thread "main" Java.lang.OutOfMemoryError:Java heap spaces
at Weakhashmaptest1.main (WEAKHASHMAPTEST1.JAVA:10)

Sure enough, weakhashmap this time does not automatically help us release unused memory. The code in Listing 12 shows no memory overflow problems.

Listing 12. WeakHashMapTest2

Import java.util.ArrayList;
Import java.util.List;
Import Java.util.WeakHashMap;
 
public class WeakHashMapTest2 {public
 static void Main (string[] args) throws Exception {
 List<weakhashmap <byte[][], byte[][]>> maps = new arraylist<weakhashmap<byte[][], byte[][]>> ();
 for (int i = 0; i < 1000 i++) {
 weakhashmap<byte[][], byte[][]> d = new weakhashmap<byte[][], Byte[][]> ;();
 D.put (New byte[1000][1000], new byte[1000][1000]);
 Maps.add (d);
 System.GC ();
 System.err.println (i);
 for (int j = 0; J < i; J +) {
 System.err.println (j + "size" + Maps.get (j). Size ());}}}

The run results found that the test output was normal and no memory overflow problem occurred.

In general, Weakhashmap is not what you do, it automatically frees objects that are not used internally, but releases objects that are not in use when you access its content.

Weakhashmap implements a weak reference because its entry<k,v> is inherited from Weakreference<k>,

The class definition and constructor of weakhashmap$entry<k,v> are shown in Listing 13.

Listing 13. Weakhashmap class definition

private static class Entry<k,v> extends Weakreference<k>
implements map.entry<k,v> Entry (K key, V Value, referencequeue<k> queue,int hash, entry<k,v> next) {
super (key, queue);
This.value = value;
This.hash = hash;
This.next = Next;

Note that it constructs the statement of the parent class: "Super (key, queue);", the key is passed in, so the key is weakly referenced, and Value is a direct strong reference association in the This.value. At System.GC (), the Byte array in the Key is reclaimed, and value remains (value is strongly associated to Entry, Entry is associated with the map, and the map is associated with the ArrayList).

In the For Loop, a new Weakhashmap is added each time, and after the put operation, although the GC reclaims the Byte array in the WeakReference Key and notifies the event to the Referencequeue, there is no corresponding action to trigger the Weakhashmap to deal with Referencequeue, so weakreference packaging Key still exists in Weakhashmap, its corresponding value of course exists.

When was the value cleared? For an analysis of listing 10 and listing 112 sample programs, the Maps.get (j) of listing 11 triggers the recovery of Value. View Weakhashmap source code It is known that the Size method calls the Expungestaleentries method, which iterates through the Entry (Quene) to be reclaimed by the JVM, and the Entry Value is empty and the memory is reclaimed. So the effect is that the key is cleared at the GC, and the Value is cleared after the key clears the access Weakhashmap.

The Weakhashmap class is thread-less, and you can use the Collections.synchronizedmap method to construct a synchronized weakhashmap that is indirectly stored as an indication object for a weak reference. Therefore, the key is automatically removed only after the garbage collector clears a weak reference to a key, whether inside or outside the map. It should be noted that the value objects in the Weakhashmap are persisted by the normal strong reference. It is therefore prudent to make sure that the value object does not strongly reference its own key directly or indirectly because it prevents the key from being discarded. Note that a value object can indirectly refer to its corresponding key by Weakhashmap itself, which means that a value object may be strong references to some other key object, whereas a value object associated with that key object will instead strongly reference the key of the first value object.

One way to handle this problem is to wrap the value itself in weakreferences before inserting, such as: M.put (Key, new WeakReference (value)), and then unpack with Get, which all "collection View Methods" The returned iterators are fast failures, and after the iterator is created, if you modify the mappings from the structure, except through the Remove or Add method of the iterator itself, any other time any way, the iterator throws Concurrentmodificationexception. Therefore, in the face of concurrent modifications, the iterator quickly fails completely, rather than risking any uncertain behavior at any future uncertain time.

Note that we cannot ensure that the iterator does not fail, and that in general, there is no guarantee of a complete certainty when there are concurrent modifications to the different steps.
Summarize
Combined with the previous introduction and example code, we can know that, if it involves stacks, queues and other operations, you should consider using List. You should use LinkedList for actions such as quick inserts, deletion of elements, and so on. If you need a quick random access element, you should use ArrayList. If the program is in a single-threaded environment, or if access is only done in one thread, it is more efficient to consider a class that is not synchronized. If more than one thread can manipulate a class at the same time, you should use a synchronized class. Special attention should be paid to the operation of the hash table, where the object of the Key is correctly hashcode the Equals and the method. Try to return the interface instead of the actual type, such as return List instead of ArrayList, so if you need to replace ArrayList with LinkedList, the client code does not have to change, this is to abstract programming ideas.

This article is only for the application level of sharing, I hope to optimize the Java Collection class operations to help.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.