1. 程式人生 > 實用技巧 >keepalived 高可用方案

keepalived 高可用方案

  • Collection介面

Collection 介面是在整個 Java 類集中儲存單值的最大操作父介面,裡面每次操作的時候都只能儲存一個物件的資料。

部分方法

方法名稱 描述
public boolean add(E e) 向集合中插入一個元素
public Iterator<E> iterator() 為Iterator介面例項化
public int size() 求出集合中元素的個數

子介面:List、Set

  • LIst介面

List 是 Collection 的子介面,裡面的所有內容都是允許重複的。

部分方法

方法名稱 描述
public void add(intindex,Eelement) 在指定位置處增加元素
boolean addAll(intindex,Collection<?extendsE>c) 在指定位置處增加一組元素
public E get(intindex) 根據索引位置取出每一個元素
public int indexOf(Objecto) 根據物件查詢指定的位置,找不到返回-1
public int lastIndexOf(Objecto) 從後面向前查詢位置,找不到返回-1
public ListIterator<E> listIterator() 返回 ListIterator 介面的例項
public ListIterator<E> listIterator(intindex) 返回從指定位置的 ListIterator 介面的例項
public E remove(intindex) 刪除指定位置的內容
public E set(intindex,Eelement) 修改指定位置的內容
List<E> subList(intfromIndex,inttoIndex) 返回子集合


實現類有如下幾個: ArrayList、Vector、LinkedList

  • ArrayList

ArraryList繼承了 AbstractList 類。AbstractList 是 List 介面的子類。AbstractList 是個抽象類,介面卡設計模式。

ArraryList有3個構造方法

ArraryList() 構造一個初始容量為10的空列表。
ArraryList(int initialCapacity) 構造具有指定初始容量的空列表。
ArraryList(Collection<? extends E> c) 按照集合的迭代器返回的順序構造一個包含指定集合元素的列表。

原始碼中的內容

成員變數原始碼

 1     /**
 2      * Default initial capacity.
 3      */
 4     private static final int DEFAULT_CAPACITY = 10;
 5 
 6     /**
 7      * Shared empty array instance used for empty instances.
 8      */
 9     private static final Object[] EMPTY_ELEMENTDATA = {};
10 
11     /**
12      * Shared empty array instance used for default sized empty instances. We
13      * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
14      * first element is added.
15      */
16     private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
17 
18     /**
19      * The array buffer into which the elements of the ArrayList are stored.
20      * The capacity of the ArrayList is the length of this array buffer. Any
21      * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
22      * will be expanded to DEFAULT_CAPACITY when the first element is added.
23      */
24     transient Object[] elementData; // non-private to simplify nested class access
25 
26     /**
27      * The size of the ArrayList (the number of elements it contains).
28      *
29      * @serial
30      */
31     private int size;

建構函式原始碼

 1    /**
 2      * Constructs an empty list with the specified initial capacity.
 3      *
 4      * @param  initialCapacity  the initial capacity of the list
 5      * @throws IllegalArgumentException if the specified initial capacity
 6      *         is negative
 7      */
 8     public ArrayList(int initialCapacity) {
 9         if (initialCapacity > 0) {
10             this.elementData = new Object[initialCapacity];
11         } else if (initialCapacity == 0) {
12             this.elementData = EMPTY_ELEMENTDATA;
13         } else {
14             throw new IllegalArgumentException("Illegal Capacity: "+
15                                                initialCapacity);
16         }
17     }
18 
19     /**
20      * Constructs an empty list with an initial capacity of ten.
21      */
22     public ArrayList() {
23         this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
24     }
25 
26     /**
27      * Constructs a list containing the elements of the specified
28      * collection, in the order they are returned by the collection's
29      * iterator.
30      *
31      * @param c the collection whose elements are to be placed into this list
32      * @throws NullPointerException if the specified collection is null
33      */
34     public ArrayList(Collection<? extends E> c) {
35         elementData = c.toArray();
36         if ((size = elementData.length) != 0) {
37             // defend against c.toArray (incorrectly) not returning Object[]
38             // (see e.g. https://bugs.openjdk.java.net/browse/JDK-6260652)
39             if (elementData.getClass() != Object[].class)
40                 elementData = Arrays.copyOf(elementData, size, Object[].class);
41         } else {
42             // replace with empty array.
43             this.elementData = EMPTY_ELEMENTDATA;
44         }
45     }

從原始碼中可以看出,無論是用哪一個構造方法,ArraryList中的資料都是存放在elementData陣列中的。

在無參建構函式中,elementData被賦值為DEFAULTCAPACITY_EMPTY_ELEMENTDATA(長度為0的空陣列)。

在引數為int initialCapacity的建構函式中,若引數大於0,則將elementData賦值為指定長度陣列,當引數為0時,elementData被賦值為EMPTY_ELEMENTDATA(長度為0的空陣列)。

且慢,在api中,ArraryList的無參建構函式是構造一個長度為10的空列表,為什麼原始碼中的無參建構函式是構造一個長度為0的列表呢?

我們先來看看ArraryList的add方法:

 1     /**
 2      * This helper method split out from add(E) to keep method
 3      * bytecode size under 35 (the -XX:MaxInlineSize default value),
 4      * which helps when add(E) is called in a C1-compiled loop.
 5      */
 6     private void add(E e, Object[] elementData, int s) {
 7         if (s == elementData.length)
 8             elementData = grow();
 9         elementData[s] = e;
10         size = s + 1;
11     }
12 
13     /**
14      * Appends the specified element to the end of this list.
15      *
16      * @param e element to be appended to this list
17      * @return {@code true} (as specified by {@link Collection#add})
18      */
19     public boolean add(E e) {
20         modCount++;
21         add(e, elementData, size);
22         return true;
23     }

我們使用的add方法是第19行的add方法,這個方法的返回值只有true,並且在這個方法中會呼叫第6行的add方法。19行的add方法會把我們需要add的物件還有this.elementData、this.size傳給第6行的add方法。

第6行的add方法會先判斷當前size是否等於當前elementData的長度,如果是則在第8行使用grow()方法對elementData進行陣列擴容。

我們再來看看grow()方法:

 1     /**
 2      * Increases the capacity to ensure that it can hold at least the
 3      * number of elements specified by the minimum capacity argument.
 4      *
 5      * @param minCapacity the desired minimum capacity
 6      * @throws OutOfMemoryError if minCapacity is less than zero
 7      */
 8     private Object[] grow(int minCapacity) {
 9         return elementData = Arrays.copyOf(elementData,
10                                            newCapacity(minCapacity));
11     }
12 
13     private Object[] grow() {
14         return grow(size + 1);
15     }
16 
17     /**
18      * Returns a capacity at least as large as the given minimum capacity.
19      * Returns the current capacity increased by 50% if that suffices.
20      * Will not return a capacity greater than MAX_ARRAY_SIZE unless
21      * the given minimum capacity is greater than MAX_ARRAY_SIZE.
22      *
23      * @param minCapacity the desired minimum capacity
24      * @throws OutOfMemoryError if minCapacity is less than zero
25      */
26     private int newCapacity(int minCapacity) {
27         // overflow-conscious code
28         int oldCapacity = elementData.length;
29         int newCapacity = oldCapacity + (oldCapacity >> 1);
30         if (newCapacity - minCapacity <= 0) {
31             if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
32                 return Math.max(DEFAULT_CAPACITY, minCapacity);
33             if (minCapacity < 0) // overflow
34                 throw new OutOfMemoryError();
35             return minCapacity;
36         }
37         return (newCapacity - MAX_ARRAY_SIZE <= 0)
38             ? newCapacity
39             : hugeCapacity(minCapacity);
40     }

我們在add中呼叫的grow()方法是第13行的grow()方法,該方法會呼叫第8行的grow方法,並把this.size+1(擴容後的長度)傳遞給它。

第8行的grow方法會使用Arrays.copyOf(需要操作的陣列,新陣列的長度)進行擴容操作,其中第二個引數由第26行的newCapacity方法得出。

在26行的newCapacity可以看到,引數名為minCapacity(我們需要的長度),有兩個內部變數oldCapacity和newCapacity。oldCapacity為elementData的長度,而newCapacity為oldCapacity的1.5倍。

如果我們使用無參建構函式new物件,則進入第31行if語句,此時會比較DEFAULT_CAPACITY與minCapacity,找出最大值,由於DEFAULT_CAPACITY=10,minCapacity=1,此時minCapacity則會return DEFAULT_CAPACITY。

在newCapacity方法returnDEFAULT_CAPACITY後,Arrays.copyOf的第二個引數則為10,陣列被擴容到長度為10。

也就是說,當我們使用無參建構函式new一個ArraryList物件,在第一次使用add方法的時候,該ArraryList的長度會由0變為10。

  • Vector

Vector與ArraryList一樣,屬於List介面的子類。在增刪操作上與ArraryList無區別。

  • Vector與ArraryList的區別

區別點 ArraryList Vector
時間 JDK1.2之後推出 JKD1.0推出
效能 效能較高,採用非同步處理 效能較低,採用同步處理
輸出

支援 Iterator、ListIterator 輸出

除了支援 Iterator、ListIterator 輸出,還支援 Enumeration 輸出

  • LinkedList

方法名稱 描述
public booleanadd(Ee)

增加元素,如果有容量限制,並且已滿,則丟擲異

public Eelement()

取得,但是不刪除當前元素,如果對列為空則丟擲
異常

boolean offer(E e)

新增,如果有容量限制,並且已滿,只是無法新增, 但不丟擲異常,返回 false

E peek() 取得頭元素,但是不刪除,如果佇列為空,則返回 null
E poll() 取得頭元素,但是刪除, 如果佇列為空,則返回 null
E remove() 刪除當前元素, 如果對列為空則丟擲異常

  • Set 介面

Set 介面也是 Collection 的子介面,與 List 介面最大的不同在於,Set 接口裡面的內容是不允許重複的。

在此介面中有兩個常用的子類:HashSet、TreeSet

  • 雜湊存放:HashSet

java.util.HashSet 是 Set 介面的一個實現類,它所儲存的元素是不可重複的,並且元素都是無序的 (即存取順序不一致)。

HashSet 是根據物件的雜湊值來確定元素在集合中的儲存位置,因此具有良好的存取和查詢效能。保證 元素唯一性的方式依賴於: hashCode 與 equals 方法。

構造方法

HashSet() 構造一個新的空集; 支援HashMap例項具有預設初始容量(16)和載入因子(0.75)。
HashSet(intinitialCapacity) 構造一個新的空集; 支援HashMap例項具有指定的初始容量和預設載入因子(0.75)。
HashSet(intinitialCapacity, floatloadFactor) 構造一個新的空集; 支援HashMap例項具有指定的初始容量和指定的載入因子。
HashSet(intinitialCapacity, floatloadFactor) 構造一個包含指定集合中元素的新集合。

原始碼

 1     static final long serialVersionUID = -5024744406713321676L;
 2 
 3     private transient HashMap<E,Object> map;
 4 
 5     // Dummy value to associate with an Object in the backing Map
 6     private static final Object PRESENT = new Object();
 7 
 8     /**
 9      * Constructs a new, empty set; the backing {@code HashMap} instance has
10      * default initial capacity (16) and load factor (0.75).
11      */
12     public HashSet() {
13         map = new HashMap<>();
14     }
15 
16     /**
17      * Constructs a new set containing the elements in the specified
18      * collection.  The {@code HashMap} is created with default load factor
19      * (0.75) and an initial capacity sufficient to contain the elements in
20      * the specified collection.
21      *
22      * @param c the collection whose elements are to be placed into this set
23      * @throws NullPointerException if the specified collection is null
24      */
25     public HashSet(Collection<? extends E> c) {
26         map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
27         addAll(c);
28     }
29 
30     /**
31      * Constructs a new, empty set; the backing {@code HashMap} instance has
32      * the specified initial capacity and the specified load factor.
33      *
34      * @param      initialCapacity   the initial capacity of the hash map
35      * @param      loadFactor        the load factor of the hash map
36      * @throws     IllegalArgumentException if the initial capacity is less
37      *             than zero, or if the load factor is nonpositive
38      */
39     public HashSet(int initialCapacity, float loadFactor) {
40         map = new HashMap<>(initialCapacity, loadFactor);
41     }
42 
43     /**
44      * Constructs a new, empty set; the backing {@code HashMap} instance has
45      * the specified initial capacity and default load factor (0.75).
46      *
47      * @param      initialCapacity   the initial capacity of the hash table
48      * @throws     IllegalArgumentException if the initial capacity is less
49      *             than zero
50      */
51     public HashSet(int initialCapacity) {
52         map = new HashMap<>(initialCapacity);
53     }

由原始碼和構造方法可以看出HashSet是利用HashMap實現的。

  • 排序的子類:TreeSet

與 HashSet 不同的是,TreeSet 本身屬於排序的子類。

雖然在增加元素的時候屬於無序的操作,但是增加之後卻可以為使用者進行排序功能的實現。

  • 排序的說明

既然 Set 介面的 TreeSet 類本身是允許排序,但自定義類需要實現Comparable<T>介面,通過compareTo(Object o)實現排序操作。

  • Map 介面

以上的 Collection 中,每次操作的都是一個物件,如果現在假設要操作一對物件,則就必須使用 Map 了,類似於以 下一種情況:

張三 1班
李四 1班
王五 2班

那麼儲存以上資訊的時候使用 Collection 就不那麼方便,所以要使用 Map 介面。裡面的所有內容都按照 key->value 的形式儲存,也稱為二元偶物件

常用方法

方法名稱 描述
void clear() 清空 Map 集合中的內容
boolean containsKey(Objectkey) 判斷集合中是否存在指定的 key
boolean containsValue(Objectvalue) 判斷集合中是否存在指定的 value
Set<Map.Entry<K,V>> entrySet() 將 Map 介面變為 Set 集合
V get(Objectkey) 根據 key 找到其對應的 value
boolean isEmpty() 判斷是否為空
Set<K> keySet() 將全部的 key 變為 Set 集合
Collection<V> values() 將全部的 value 變為 Collection 集合
V put(Kkey,Vvalue) 向集合中增加內容
void putAll(Map<?extendsK,?extendsV>m) 增加一組集合
V remove(Objectkey) 根據 key 刪除內容

Map 本身是一個介面,所以一般會使用以下的幾個子類:HashMap、TreeMap、Hashtable

  • HashMap

HashMap是Map的一個具體體現類,是以雜湊表實現的對映集合,內部由一個儲存Entry型別元素的陣列組成。HashMap的資料是無序存放的。

構造方法

HashMap() 使用預設初始容量(16)和預設載入因子(0.75)構造一個空 HashMap
HashMap(int initialCapacity) 使用指定的初始容量和預設載入因子(0.75)構造一個空 HashMap
HashMap(intinitialCapacity, floatloadFactor) 使用指定的初始容量和載入因子構造一個空 HashMap
HashMap(Map<? extends K,​? extends V>m) 構造一個新的 HashMap ,其對映與指定的 Map相同。

HashMap是陣列+連結串列+紅黑樹(JDK1.8增加了紅黑樹部分)實現的

當連結串列節點大於等於8時,連結串列轉化為紅黑樹

當紅黑樹節點小於等於6時,紅黑樹轉化為連結串列

  • Hashtable

Hashtable 是一個最早的 key->value 的操作類,本身是在 JDK1.0的時候推出的。其基本操作與 HashMap 是類似的。Hashtable 中是不能向集合中插入 null 值的。

  • HashMap 與 Hashtable 的區別

區別點 HashMap Hashtable
推出時間 JKD1.2之後推出 JDK1.0時推出
效能 非同步處理,效能較高 同步處理,效能較低
null 允許設定為null 不允許設定,否則將會丟擲空指標異常