1. 程式人生 > >槓槓的筆記

槓槓的筆記

---------------------------------------------------------------------------------------  StringBuffer、ArrayList、HashMap的初始容量、已經如何擴充的總結(適用範圍:JDK1.7)  StringBuffer:內部實現是一個字元陣列。初始預設大小為16,當然也可以在其構造方法中進行設定。當新新增字元或字串時,發現數組容量不夠。這個時候就需要使用Array.copyOf()方法進行擴充。擴充的新的陣列大小等於,(原始容量*2+2)和(陣列實際字元個數+新增的字元長度)之間的較大值。

ArrayList:內部實現是一個Object的陣列。初始預設大小為0,當然也可以在其構造方法中設定。當新增一個Object時,預設擴充陣列容量為10。然後每次擴充的新的陣列大小等於,(原始容量*3/2)和(陣列的長度+1)之間的較大值。根據每次增加一個Object,可得該情況每次擴充的固定大小為3/2。當初始大小為手動設定的時候,每次擴充的新的陣列大小等於,(原始容量*3/2)和(陣列的長度+1)之間的較大值。

HashMap:內部實現是一個Entry的陣列,預設大小是空的陣列。初始化的容量是16,載入因子是3/4(當陣列元素數量大於總容量的載入因子的時候,擴充陣列)。當預設不是空的陣列時,當達到載入因子的比例的時候,每次擴充初始容量的2倍。

---------------------------------------------------------------------------------------    ----------------------------------------------------------------------------------------  ArrayList         import java.util.ArrayList;     import java.util.List;     提供了三種方式的構造器,可以構造一個預設初始容量為10的空列表、     從上面介紹的向ArrayList中儲存元素的程式碼中,我們看到,每當向陣列中新增元素時,都要去檢查新增後元素的個數是否會超出當前陣列的長度,如果超出,陣列將會進行擴容,以滿足新增資料的需求。陣列擴容通過一個公開的方法ensureCapacity(intminCapacity)來實現。在實際新增大量元素前,我也可以使用ensureCapacity來手動增加ArrayList例項的容量,以減少遞增式再分配的數量。          ARRAYLIST VECTOR LINKEDLIST 區別與用法     1. Vector & ArrayList     1)  Vector的方法都是同步的(Synchronized),是執行緒安全的(thread-safe),而ArrayList的方法不是,由於執行緒的同步必然要影響效能,因此,ArrayList的效能比Vector好。     2) 當Vector或ArrayList中的元素超過它的初始大小時,Vector會將它的容量翻倍,而ArrayList只增加50%的大小,這樣,ArrayList就有利於節約記憶體空間。 ----------------------------------------------------------------------------------------    

----------------------------------------------------------------------------------------     HashMap

    陣列:陣列儲存區間是連續的,佔用記憶體嚴重,故空間複雜的很大。但陣列的二分查詢時間複雜度小,為O(1);陣列的特點是:定址容易,插入和刪除困難;          連結串列:連結串列儲存區間離散,佔用記憶體比較寬鬆,故空間複雜度很小,但時間複雜度很大,達O(N)。連結串列的特點是:定址困難,插入和刪除容易。          雜湊表:那麼我們能不能綜合兩者的特性,做出一種定址容易,插入刪除也容易的資料結構?答案是肯定的,這就是我們要提起的雜湊表。雜湊表((Hash table)既滿足了資料的查詢方便,同時不佔用太多的內容空間,使用也十分方便。          以Entry[]陣列實現的雜湊桶陣列,用Key的雜湊值取模桶陣列的大小可得到陣列下標. 插入元素時,如果兩條Key落在同一個桶(比如雜湊值1和17取模16後都屬於第一個雜湊桶),Entry用一個next屬性實現多個Entry以單向連結串列存放,後入桶的Entry將next指向桶當前的Entry。   查詢雜湊值為17的key時,先定位到第一個雜湊桶,然後以連結串列遍歷桶裡所有元素,逐個比較其key值。     當Entry數量達到桶數量的75%時(很多文章說使用的桶數量達到了75%,但看程式碼不是),會成倍擴容桶陣列,並重新分配所有原來的Entry,所以這裡也最好有個預估值。

    取模用位運算(hash & (arrayLength-1))會比較快,所以陣列的大小永遠是2的N次方, 你隨便給一個初始值比如17會轉為32。預設第一次放入元素時的初始值是16。

    iterator()時順著雜湊桶陣列來遍歷,看起來是個亂序。     在JDK8裡,新增預設為8的閥值,當一個桶裡的Entry超過閥值,就不以單向連結串列而以紅黑樹來存放以加快Key的查詢速度。          1、HashMap是非執行緒安全的,HashTable是執行緒安全的。     2、HashMap的鍵和值都允許有null值存在,而HashTable則不行。     3、因為執行緒安全的問題,HashMap效率比HashTable的要高。 ----------------------------------------------------------------------------------------                     ---------------------------------------------------------------------------------------- JAVA深複製(深克隆)與淺複製(淺克隆)  (Cloneable介面實現 clone方法)

    ⑴淺複製(淺克隆)     被複制物件的所有變數都含有與原來的物件相同的值,而所有的對其他物件的引用仍然指向原來的物件。換言之,淺複製僅僅複製所考慮的物件,而不復制它所引用的物件。

    ⑵深複製(深克隆)     被複制物件的所有變數都含有與原來的物件相同的值,除去那些引用其他物件的變數。那些引用其他物件的變數將指向被複制過的新物件,而不再是原     ⑴clone方法將物件複製了一份並返回給呼叫者。一般而言,clone()方法滿足:     ①對任何的物件x,都有x.clone() !=x//克隆物件與原物件不是同一個物件     ②對任何的物件x,都有x.clone().getClass()= =x.getClass()//克隆物件與原物件的型別一樣     ③如果物件x的equals()方法定義恰當,那麼x.clone().equals(x)應該成立。

    ⑵Java中物件的克隆     ①為了獲取物件的一份拷貝,我們可以利用Object類的clone()方法。     ②在派生類中覆蓋基類的clone()方法,並宣告為public。     ③在派生類的clone()方法中,呼叫super.clone()。     ④在派生類中實現Cloneable介面。 ----------------------------------------------------------------------------------------                          ----------------------------------------------------------------------------------------     垃圾回收用到的方法

    (1)finalize()    該方法是用來回收“特殊”的記憶體,而這記憶體不是new出來的,所以垃圾回收器無法回收。這種情況主要發生在使用“本地方法”的情況下,本地方法是一種在Java中使用的非Java程式碼,可以呼叫任何程式碼,但只能被C和C++呼叫。所以我們使用finalize()來釋放本地方法產生的記憶體。

    (2)System.gc()     該方法不推薦,嚴重消耗效能,除非萬不得已,一般不用。 ----------------------------------------------------------------------------------------       ---------------------------------------------------------------------------------------- 關於棧和堆記憶體

    Java把記憶體分成兩種,一種叫做棧記憶體,一種叫做堆記憶體

    在函式中定義的一些基本型別的變數和物件的引用變數都是在函式的棧記憶體中分配。當在一段程式碼塊中定義一個變數時,java就在棧中為這個變數分配記憶體空間,當超過變數的作用域後,java會自動釋放掉為該變數分配的記憶體空間,該記憶體空間可以立刻被另作他用。

    堆記憶體用於存放由new建立的物件和陣列。在堆中分配的記憶體,由java虛擬機器自動垃圾回收器來管理。在堆中產生了一個數組或者物件後,還可以在棧中定義一個特殊的變數,這個變數的取值等於陣列或者物件在堆記憶體中的首地址,在棧中的這個特殊的變數就變成了陣列或者物件的引用變數,以後就可以在程式中使用棧記憶體中的引用變數來訪問堆中的陣列或者物件,引用變數相當於為陣列或者物件起的一個別名,或者代號。

    引用變數是普通變數,定義時在棧中分配記憶體,引用變數在程式執行到作用域外釋放。而陣列&物件本身在堆中分配,即使程式執行到使用new產生陣列和物件的語句所在地程式碼塊之外,陣列和物件本身佔用的堆記憶體也不會被釋放,陣列和物件在沒有引用變數指向它的時候,才變成垃圾,不能再被使用,但是仍然佔著記憶體,在隨後的一個不確定的時間被垃圾回收器釋放掉。這個也是java比較佔記憶體的主要原因,實際上,棧中的變數指向堆記憶體中的變數,這就是 Java 中的指標!  ----------------------------------------------------------------------------------------                    ---------------------------------------------------------------------------------------- 自動裝箱&自動拆箱

    基本資料型別的自動裝箱(autoboxing)、拆箱(unboxing)是自J2SE 5.0開始提供的功能。      Integer i = 10; //裝箱     int t = i; //拆箱,實際上執行了 int t = i.intValue();          Integer i = 100;     Integer i = Integer.valueOf(100);     //在-128~127 之外的數      Integer i1 =200;        Integer i2 =200;                System.out.println("i1==i2: "+(i1==i2));                         // 在-128~127 之內的數      Integer i3 =100;        Integer i4 =100;        System.out.println("i3==i4: "+(i3==i4));           String str1 ="abc";     String str2 ="abc";     System.out.println(str2==str1);  //輸出為 true      System.out.println(str2.equals(str1));  //輸出為 true                   String str3 =new String("abc");     String str4 =new String("abc");      System.out.println(str3==str4);  //輸出為 false      System.out.println(str3.equals(str4));  //輸出為 true ----------------------------------------------------------------------------------------           ---------------------------------------------------------------------------------------- 四種執行緒池      Java通過Executors提供四種執行緒池,分別為:     newCachedThreadPool:建立一個可快取執行緒池,如果執行緒池長度超過處理需要,可靈活回收空閒執行緒,若無可回收,則新建執行緒     newFixedThreadPool:建立一個定長執行緒池,可控制執行緒最大併發數,超出的執行緒會在佇列中等待。     newScheduledThreadPool:建立一個定長執行緒池,支援定時及週期性任務執行。    newSingleThreadExecutor:建立一個單執行緒化的執行緒池,它只會用唯一的工作執行緒來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先順序)執行。          public static void main(String[] args) {           jervice cachedThreadPool = Executors.newCachedThreadPool();           for (int i = 0; i < 10; i++) {               final int index = i;               try {                   Thread.sleep(10);               } catch (InterruptedException e) {                   e.printStackTrace();               }               cachedThreadPool.execute(new Runnable() {                   public void run() {                       System.out.println(index);                   }               });           }       }             public static void main(String[] args) {           ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);           for (int i = 0; i < 10; i++) {               final int index = i;               fixedThreadPool.execute(new Runnable() {                   public void run() {                       try {                           System.out.println(index);                           Thread.sleep(10);                       } catch (InterruptedException e) {                           e.printStackTrace();                       }                   }               });           }       }            public static void main(String[] args) {           ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);           for (int i = 0; i < 10; i++) {               scheduledThreadPool.schedule(new Runnable() {                   public void run() {                       System.out.println("delay 3 seconds");                   }               }, 3, TimeUnit.SECONDS);           }          }            public static void main(String[] args) {           ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();           for (int i = 0; i < 10; i++) {               final int index = i;               singleThreadExecutor.execute(new Runnable() {                   public void run() {                       try {                           System.out.println(index);                           Thread.sleep(2000);                       } catch (InterruptedException e) {                           e.printStackTrace();                       }                   }               });           }       }             <!-- Spring執行緒池 -->       <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">           <!-- 核心執行緒數 -->           <property name="corePoolSize" value="5" />           <!-- 最大執行緒數 -->           <property name="maxPoolSize" value="10" />           <!-- 佇列最大長度 >=mainExecutor.maxSize -->           <property name="queueCapacity" value="25" />           <!-- 執行緒池維護執行緒所允許的空閒時間 -->           <property name="keepAliveSeconds" value="3000" />           <!-- 執行緒池對拒絕任務(無執行緒可用)的處理策略 ThreadPoolExecutor.CallerRunsPolicy策略 ,呼叫者的執行緒會執行該任務,如果執行器已關閉,則丟棄. -->           <property name="rejectedExecutionHandler">               <bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" />           </property>       </bean>   ----------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------- 關於如何停止一個執行緒的方法:

A:停止一個執行緒可以用Thread.stop()方法,但最好不要用它。雖然它確實可以停止一個正在執行的執行緒,但是這個方法是不安全, 而且是已被廢棄的方法。

B:System.exit();  在主執行緒呼叫則會,同時停止掉所含的子執行緒.如果在子執行緒中呼叫,則只會停掉該子執行緒.

C:異常停止

D:return 返回

E:interrupt()方法的使用效果並不像for+break語句那樣,馬上就停止迴圈。呼叫interrupt方法是在當前執行緒中打了一個停止標誌,並不是真的停止執行緒。

----------------------------------------------------------------------------------------

      ---------------------------------------------------------------------------------------- 建立執行緒的3種方法     A: 繼承Thread類建立執行緒類 run()方法 類物件.start()啟動     B: 通過Runnable介面建立執行緒類, run()方法 new Thread(該物件例項,"新執行緒1").start();       C: 通過Callable介面建立執行緒類, call()方法,啟動: FutureTask<Integer> ft = new FutureTask<>(該物件例項);   new Thread(ft,"有返回值的執行緒").start();  ----------------------------------------------------------------------------------------               ---------------------------------------------------------------------------------------- wait()、notify()、notifyAll()     如果物件呼叫了wait方法就會使持有該物件的執行緒把該物件的控制權交出去,然後處於等待狀態。     如果物件呼叫了notify方法就會通知某個正在等待這個物件的控制權的執行緒可以繼續執行。     如果物件呼叫了notifyAll方法就會通知所有等待這個物件控制權的執行緒繼續執行。 ----------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------- 關於異常的體系結構         Throwable         A:Error(硬體異常)           B:Exception(程式異常)又包含1:Checked(編譯異常,java特有) 2:RuntimeException(執行時異常) ----------------------------------------------------------------------------------------              java.util.Collection 是一個集合介面。它提供了對集合物件進行基本操作的通用介面方法。Collection介面在Java 類庫中有很多具體的實現。Collection介面的意義是為各種具體的集合提供了最大化的統一操作方式。  Collection   ├List   │├LinkedList   │├ArrayList   │└Vector   │ └Stack   └Set  

java.util.Collections 是一個包裝類。它包含有各種有關集合操作的靜態多型方法。此類不能例項化,就像一個工具類,服務於Java的Collection框架。                            ---------------------------------------------------------------------------------------- 索引生效規則     btree索引的常見誤區     在where條件常用的列上都加上索引     比如:where cat_id=3 and price>100 #查詢第3個欄目,100以上的商品     只能用上cat_id或price索引,因為獨立的索引同時只能用上1個。     組合索引的生效原則是  從前往後依次使用生效,如果中間某個索引沒有使用,那麼斷點前面的索引部分起作用,斷點後面的索引沒有起作用;          比如:     where a=3 and b=45 and c=5 .... 這種三個索引順序使用中間沒有斷點,全部發揮作用;     where a=3 and c=5... 這種情況下b就是斷點,a發揮了效果,c沒有效果     where b=3 and c=4... 這種情況下a就是斷點,在a後面的索引都沒有發揮作用,這種寫法聯合索引沒有發揮任何效果;     where b=45 and a=3 and c=5 .... 這個跟第一個一樣,全部發揮作用,abc只要用上了就行,跟寫的順序無關     (0)    select * from mytable where a=3 and b=5 and c=4;     abc三個索引都在where條件裡面用到了,而且都發揮了作用     (1)    select * from mytable where  c=4 and b=6 and a=3;     這條語句列出來只想說明 mysql沒有那麼笨,where裡面的條件順序在查詢之前會被mysql自動優化,效果跟上一句一樣     (2)    select * from mytable where a=3 and c=7;     a用到索引,b沒有用,所以c是沒有用到索引效果的     (3)    select * from mytable where a=3 and b>7 and c=3;     a用到了,b也用到了,c沒有用到,這個地方b是範圍值,也算斷點,只不過自身用到了索引     (4)    select * from mytable where b=3 and c=4;     因為a索引沒有使用,所以這裡 bc都沒有用上索引效果     (5)    select * from mytable where a>4 and b=7 and c=9;     a用到了  b沒有使用,c沒有使用     (6)    select * from mytable where a=3 order by b;     a用到了索引,b在結果排序中也用到了索引的效果,前面說了,a下面任意一段的b是排好序的     (7)    select * from mytable where a=3 order by c;     a用到了索引,但是這個地方c沒有發揮排序效果,因為中間斷點了,使用 explain 可以看到 filesort     (8)    select * from mytable where b=3 order by a;     b沒有用到索引,排序中a也沒有發揮索引效果 ----------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------- 一方庫、二方庫、三方庫說明: 一方庫:本工程中的各模組的相互依賴 二方庫:公司內部的依賴庫,一般指公司內部的其他專案釋出的jar包 三方庫:公司之外的開源庫, 比如apache、ibm、google等釋出的依賴 ----------------------------------------------------------------------------------------  

  ----------------------------------------------------------------------------------------  Synchronized 可以修飾:類,方法,靜態方法,語句塊.    synchronized 和 block區別:  synchronized:在需要同步的物件中加入此控制,synchronized可以加在方法上,也可以加在特定程式碼塊中,括號中表示需要鎖的物件。 lock:需要顯示指定起始位置和終止位置。一般使用ReentrantLock類做為鎖,多個執行緒中必須要使用一個ReentrantLock類做為物件才能保證鎖的生效。且在加鎖和解鎖處需要通過lock()和unlock()顯示指出。所以一般會在finally塊中寫unlock()以防死鎖。用法區別比較簡單,這裡不贅述了,如果不懂的可以看看Java基本語法。  synchronized是託管給JVM執行的,而lock是java寫的控制鎖的程式碼。在Java1.5中,synchronize是效能低效的。因為這是一個重量級操作,需要呼叫操作介面,導致有可能加鎖消耗的系統時間比加鎖以外的操作還多。相比之下使用Java提供的Lock物件,效能更高一些。但是到了Java1.6,發生了變化。synchronize在語義上很清晰,可以進行很多優化,有適應自旋,鎖消除,鎖粗化,輕量級鎖,偏向鎖等等。導致在Java1.6上synchronize的效能並不比Lock差。官方也表示,他們也更支援synchronize,在未來的版本中還有優化餘地。  ----------------------------------------------------------------------------------------    資料庫索引優化    threadlocal 執行緒間共享資料    安全的集合方式       設計模式:     1:單例模式     2:原型模式    ----即cloneable     3:觀察者模式     4:代理模式     5:策略模式---可以利用到註解來選擇不同的策略,主要解決if----else   策略模式針對不同物種的共有操作     6:模板模式    模板模式共有操作的不同物種

     javadoc 註釋     TODO     FIXME           38.volatile關鍵字

Spring mvc與Struts區別 :http://blog.csdn.net/chenleixing/article/details/44570681

  ---------------------------------------------------------------------------------------- Hadoop Hadoop的框架最核心的設計就是:HDFS和MapReduce。HDFS為海量的資料提供了儲存,則MapReduce為海量的資料提 ----------------------------------------------------------------------------------------       ---------------------------------------------------------------------------------------- zookeeper zookeeper: 統一配置管理(簡單) 名字服務(類似DNS) 分散式鎖(服務並行執行的協調) 叢集管理(節點的管理,與是否可用的監察)

 原理:zookeeper在配置檔案中並沒有指定master和slave,但是,zookeeper在工作時,只有一個節點為leader,其餘節點為follower,leader是通過內部的選舉機制臨時產生的。

   a:是為別的分散式程式服務的  b:本身就是一個分散式程式(只要半數以上節點存活,zookeeper就能正常服務。)  C:服務範圍:主從協調、伺服器節點動態上下線、統一配置管理、分散式共享鎖、統一名稱服務...  D:底層其實只提供了兩個功能:     1)管理(儲存、讀取)使用者程式提交的資料     2)為使用者程式提交資料節點監聽服務                    Zookeeper:一個leader,多個follower組成的叢集     全域性資料一致:每個server儲存一份相同的資料副本,client無論連線到哪個server,資料都是一致的     分散式讀寫,更新請求轉發,由leader實施     更新請求順序進行,來自同一個client的更新請求按其傳送順序依次執行     資料更新原子性,一次資料更新要麼成功,要麼失敗     實時性,在一定時間範圍內,client能讀到最新資料

     1、Znode有兩種型別:         短暫(ephemeral)(斷開連線自己刪除)         持久(persistent)(斷開連線不刪除)

4、zookeeper資料結構     層次化的目錄結構,命名符合常規檔案系統規範(見下圖)     每個節點在zookeeper中叫做Znode,並且其有一個唯一的路徑標識     節點Znode可以包含資料和子節點(但是EPHEMERAL型別的節點不能有子節點)     客戶端應用可以在節點上設定監視器

    ----------------------------------------------------------------------------------------     ----------------------------------------------------------------------------------------  子執行緒等待主執行緒的方法: join 或者 CountDownLatch  正如每個Java文件所描述的那樣,CountDownLatch是一個同步工具類,它允許一個或多個執行緒一直等待,直到其他執行緒的操作執行完後再執行。在Java併發中,countdownlatch的概念是一個常見的面試題,所以一定要確保你很好的理解了它。在這篇文章中,我將會涉及到在Java併發編 程中跟CountDownLatch相關的以下幾點: ----------------------------------------------------------------------------------------     ----------------------------------------子執行緒等待父執行緒結束----------------------------- 程序的 join 和 countdownlatch 

    join用於讓當前執行執行緒等待join執行緒執行結束。其實現原理是不停檢查join執行緒是否存活.     如上即是: 子執行緒在main方法中呼叫了join,則main該主執行緒一直等待該執行緒結束了在繼續執行.(非常好)       當我們呼叫一次CountDownLatch的countDown方法時,N就會減1,CountDownLatch的await會阻塞當前執行緒,直到N變成零。     由於countDown方法可以用在任何地方,所以這裡說的N個點,可以是N個執行緒,也可以是1個執行緒裡的N個執行步驟。用在多個執行緒時,你只需要把這個CountDownLatch的引用傳遞到執行緒裡。 ----------------------------------------子執行緒等待父執行緒結束-----------------------------    ----------------------------------------------------------------------------------------  final,finally,finalize:       final用於宣告屬性,方法和類,分別表示屬性不可交變,方法不可覆蓋,類不可繼承。     finally是異常處理語句結構的一部分,表示總是執行。     finalize是Object類的一個方法,在垃圾收集器執行的時候會呼叫被回收物件的此方法,供垃圾收集時的其他資源回收,例如關閉檔案等。      try catch finaly 中的return問題:       1, 如果catch塊中捕獲了異常, 並且在catch塊中將該異常throw給上級呼叫者進行處理, 但finally中return了, 那麼catch塊中的throw就失效了, 上級方法呼叫者是捕獲不到異常的. 見demo如下:     2, 如果在finally裡的return之前執行了其它return , 那麼最終的返回值是finally中的return:     3, try 和 catch中都有return, (只要try中的內容沒報錯).並且catch中可以存在return.    ----------------------------------------------------------------------------------------       ----------------------------------------------------------------------------------------     collection collections:     1.java.util.Collection 是一個集合介面。    它提供了對集合物件進行基本操作的通用介面方法。Collection介面在Java類庫中有很多具體的實現。Collection介面的意義是為各種具體的集合提供了最大化的統一操作方式。     以下介面實現了Collection介面:map,set,list,vector       java.util.Collections 是一個包裝類。     它包含有各種有關集合操作的靜態多型方法。此類不能例項化,就像一個工具類,服務於Java的Collection框架。 ----------------------------------------------------------------------------------------   ----------------------------------------------------------------------------------------  ThreadLocal  我們看到雖然 threadLocal 是靜態變數,但是每個執行緒都有自己的值,不會受到其他執行緒的影響。    ThreadLocal 的實現思想,我們在前面已經說了,每個執行緒維護一個 ThreadLocalMap 的對映表,對映表的 key 是 ThreadLocal 例項本身,value 是要儲存的副本變數。ThreadLocal 例項本身並不儲存值,它只是提供一個在當前執行緒中找到副本值的 key。 如下圖所示: ----------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------- collectons.sort    

A:要排序的類,實現介面Comparable的compareTo 方法 B: 如下做匿名內部類 Collections.sort(listA, new Comparator<TestA>() {             @Override             public int compare(TestA o1, TestA o2) {                 //升序                 return o1.getOrder().compareTo(o2.getOrder());             }         });

----------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------     redis 是單執行緒     並不是所有的KV資料庫或者記憶體資料庫都應該用單執行緒,比如ZooKeeper就是多執行緒的,最終還是看作者自己的意願和取捨。

     1、所有的redis節點彼此互聯(PING-PONG機制),內部使用二進位制協議優化傳輸速度和頻寬。      2、節點的fail是通過叢集中超過半數的節點檢測失效時才生效。      3、客戶端與redis節點直連,不需要中間proxy層.客戶端不需要連線叢集所有節點,連線叢集中任何一個可用節點即可。      4、redis-cluster把所有的物理節點對映到[0-16383]slot上(不一定是平均分配),cluster 負責維護node<->slot<->value。

     5、Redis叢集預分好16384個桶,當需要在 Redis 叢集中放置一個 key-value 時,根據 CRC16(key) mod 16384的值,決定將一個key放到哪個桶中。                  Redis Cluster主從模式      redis cluster 為了保證資料的高可用性,加入了主從模式,一個主節點對應一個或多個從節點,主節點提供資料存取,從節點則是從主節點拉取資料備份,當這個主節點掛掉後,就會有這個從節點選取一個來充當主節點,從而保證叢集不會掛掉。

     上面那個例子裡, 叢集有ABC三個主節點, 如果這3個節點都沒有加入從節點,如果B掛掉了,我們就無法訪問整個叢集了。A和C的slot也無法訪問。

     所以我們在叢集建立的時候,一定要為每個主節點都添加了從節點, 比如像這樣, 叢集包含主節點A、B、C, 以及從節點A1、B1、C1, 那麼即使B掛掉系統也可以繼續正確工作。

     B1節點替代了B節點,所以Redis叢集將會選擇B1節點作為新的主節點,叢集將會繼續正確地提供服務。 當B重新開啟後,它就會變成B1的從節點。

     不過需要注意,如果節點B和B1同時掛了,Redis叢集就無法繼續正確地提供服務了。

    redis:只能儲存, 字串和byte[] 型別的資料. 但是提供了方法可以存入  List 和 Set 格式的資料

----------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------- nginx 相對 apache 的優點:     輕量級,同樣起web 服務,比apache 佔用更少的記憶體及資源     抗併發,nginx 處理請求是非同步非阻塞的,而apache 則是阻塞型的,在高併發下nginx 能保持低資源低消耗高效能     高度模組化的設計,編寫模組相對簡單     社群活躍,各種高效能模組出品迅速啊

apache 相對nginx 的優點:     rewrite ,比nginx 的rewrite      強大模組超多,基本想到的都可以找到     少bug ,nginx 的bug 相對較多     超穩定      nginx輪詢策略

    1、輪詢(預設)     每個請求按時間順序逐一分配到不同的後端伺服器,如果後端伺服器down掉,能自動剔除。 

    2、指定權重     指定輪詢機率,weight和訪問比率成正比,用於後端伺服器效能不均的情況

    3、IP繫結 ip_hash     每個請求按訪問ip的hash結果分配,這樣每個訪客固定訪問一個後端伺服器,可以解決session的問題。 

    4、fair(第三方)     按後端伺服器的響應時間來分配請求,響應時間短的優先分配。

    5、url_hash(第三方)     按訪問url的hash結果來分配請求,使每個url定向到同一個後端伺服器,後端伺服器為快取時比較有效。

----------------------------------------------------------------------------------------

----------------------------------------fastDFS----------------------------------------------

FastDFS由跟蹤伺服器(Tracker Server)、儲存伺服器(Storage Server)和客戶端(Client)構成。

                                            跟蹤伺服器Tracker Server 主要做排程工作,起到均衡的作用;負責管理所有的 storage server和 group,每個 storage 在啟動後會連線 Tracker,告知自己所屬 group 等資訊,並保持週期性心跳。tracker根據storage的心跳資訊,建立group==>[storage serverlist]的對映表。 Tracker需要管理的元資訊很少,會全部儲存在記憶體中;另外tracker上的元資訊都是由storage彙報的資訊生成的,本身不需要持久化任何資料,這樣使得tracker非常容易擴充套件,直接增加tracker機器即可擴充套件為tracker cluster來服務,cluster裡每個tracker之間是完全對等的,所有的tracker都接受stroage的心跳資訊,生成元資料資訊來提供讀寫服務。

                                            儲存伺服器Storage Server 主要提供容量和備份服務;以 group 為單位,每個 group 內可以有多臺 storage server,資料互為備份。以group為單位組織儲存能方便的進行應用隔離、負載均衡、副本數定製(group內storage server數量即為該group的副本數),比如將不同應用資料存到不同的group就能隔離應用資料,同時還可根據應用的訪問特性來將應用分配到不同的group來做負載均衡;缺點是group的容量受單機儲存容量的限制,同時當group內有機器壞掉時,資料恢復只能依賴group內地其他機器,使得恢復時間會很長。

group內每個storage的儲存依賴於本地檔案系統,storage可配置多個數據儲存目錄,比如有10塊磁碟,分別掛載在/data/disk1-/data/disk10,則可將這10個目錄都配置為storage的資料儲存目錄。storage接受到寫檔案請求時,會根據配置好的規則選擇其中一個儲存目錄來儲存檔案。為了避免單個目錄下的檔案數太多,在storage第一次啟動時,會在每個資料儲存目錄裡建立2級子目錄,每級256個,總共65536個檔案,新寫的檔案會以hash的方式被路由到其中某個子目錄下,然後將檔案資料作為本地檔案儲存到該目錄中。                                                客戶端Client 主要是上傳下載資料的伺服器,也就是我們自己的專案所部署在的伺服器。每個客戶端伺服器都需要安裝Nginx

                                           檔案上傳的步驟: 檔案上傳分為選擇Tracker,選擇Group,選擇Storage,生成Field,選擇兩級目錄,生成檔名這麼幾個步驟.現在網際網路專案,為了保證服務可靠性,都會搭建叢集,所以按照這種方式來總結.

選擇Tracker: Tracker叢集中所有的Tracker地位都是對等的,客戶端上傳檔案時會任意選擇一個Tracker.

選擇Group: Tracker收到上傳請求之後,會分配一個Group來儲存檔案,提供的規則有:輪詢所有的Group,指定一個Group,負載均衡(剩餘空間多的優先)

選擇Storage: 分配好Group之後,Tracker會在Group中選擇一個Storage,提供的規則有:輪詢所有的Storage,根據ip排序,根據Storage優先順序排序. 在選定好了Storage之後客戶端向Storage傳送寫入檔案請求,Storage為檔案分配一個數據儲存目錄,提供的規則有:儲存目錄輪詢,負載均衡

生成Field: 選擇好儲存目錄之後,Storage為檔案分配一個Field,由Storage的ip + 檔案建立的時間戳 + 檔案大小 + 檔案crc32校驗後+一個隨機數拼接而成.再將這個二進位制串進行Base64編碼轉換成String.

選擇兩級目錄:生成field之後,每個儲存目錄下會有兩級256*256的子目錄,Storage會按照field進行第一次hash,路由到第一級子目錄,再進行第二次hash,儲存到對應的子目錄下.

                                            關於如何解決 檔案同步的問題 一個最簡單的解決辦法,和檔案更新一樣,優先選擇源Storage server下載檔案即可。這可以在Tracker server的配置檔案中設定,對應的引數名為download_server。

另外一種選擇Storage server的方法是輪流選擇(round-robin)。當Client詢問Tracker server有哪些Storage server可以下載指定檔案時,Tracker server返回滿足如下四個條件之一的Storage server:

  1、該檔案上傳到的源Storage server,檔案直接上傳到該伺服器上的;

2、檔案建立時間戳 < Storage server被同步到的檔案時間戳,這意味著當前檔案已經被同步過來了;

3、檔案建立時間戳=Storage server被同步到的檔案時間戳,且(當前時間—檔案建立時間戳) > 一個檔案同步完成需要的最大時間(如5分鐘);

4、(當前時間—檔案建立時間戳) > 檔案同步延遲閾值,比如我們把閾值設定為1天,表示檔案同步在一天內肯定可以完成。

----------------------------------------fastDFS----------------------------------------------

-----------------------------------------JVM垃圾回收機制-------------------------------------- 一.如何確定某個物件是“垃圾”?

引用計數: 在java中是通過引用來和物件進行關聯的,也就是說如果要操作物件,必須通過引用來進行。那麼很顯然一個簡單的辦法就是通過引用計數來判斷一個物件是否可以被回收。不失一般性,如果一個物件沒有任何引用與之關聯,則說明該物件基本不太可能在其他地方被使用到,那麼這個物件就成為可被回收的物件了。這種方式成為引用計數法。

這種方式的特點是實現簡單,而且效率較高,但是它無法解決迴圈引用的問題,因此在Java中並沒有採用這種方式(Python採用的是引用計數法)。

可達分析: 為了解決這個問題,在Java中採取了 可達性分析法。該方法的基本思想是通過一系列的“gc Roots”物件作為起點進行搜尋,如果在“GC Roots”和一個物件之間沒有可達路徑,則稱該物件是不可達的,不過要注意的是被判定為不可達的物件不一定就會成為可回收物件。被判定為不可達的物件要成為可回收物件必須至少經歷兩次標記過程,如果在這兩次標記過程中仍然沒有逃脫成為可回收物件的可能性,則基本上就真的成為可回收物件了。

二.典型的垃圾收集演算法

1.Mark-Sweep(標記-清除)演算法 這是最基礎的垃圾回收演算法,之所以說它是最基礎的是因為它最容易實現,思想也是最簡單的。標記-清除演算法分為兩個階段:標記階段和清除階段。標記階段的任務是標記出所有需要被回收的物件,清除階段就是回收被標記的物件所佔用的空間。具體過程如下圖所示: 這是最基礎的垃圾回收演算法,之所以說它是最基礎的是因為它最容易實現,思想也是最簡單的。標記-清除演算法分為兩個階段:標記階段和清除階段。標記階段的任務是標記出所有需要被回收的物件,清除階段就是回收被標記的物件所佔用的空間。具體過程如下圖所示:

從圖中可以很容易看出標記-清除演算法實現起來比較容易,但是有一個比較嚴重的問題就是容易產生記憶體碎片,碎片太多可能會導致後續過程中需要為大物件分配空間時無法找到足夠的空間而提前觸發新的一次垃圾收集動作。

2.Copying(複製)演算法 為了解決Mark-Sweep演算法的缺陷,Copying演算法就被提了出來。它將可用記憶體按容量劃分為大小相等的兩塊,每次只使用其中的一塊。當這一塊的記憶體用完了,就將還存活著的物件複製到另外一塊上面,然後再把已使用的記憶體空間一次清理掉,這樣一來就不容易出現記憶體碎片的問題。具體過程如下圖所示:

這種演算法雖然實現簡單,執行高效且不容易產生記憶體碎片,但是卻對記憶體空間的使用做出了高昂的代價,因為能夠使用的記憶體縮減到原來的一半。 很顯然,Copying演算法的效率跟存活物件的數目多少有很大的關係,如果存活物件很多,那麼Copying演算法的效率將會大大降低。

3.Mark-Compact(標記-整理)演算法 為了解決Copying演算法的缺陷,充分利用記憶體空間,提出了Mark-Compact演算法。該演算法標記階段和Mark-Sweep一樣,但是在完成標記之後,它不是直接清理可回收物件,而是將存活物件都向一端移動,然後清理掉端邊界以外的記憶體。具體過程如下圖所示:

4.Generational Collection(分代收集)演算法 分代收集演算法是目前大部分JVM的垃圾收集器採用的演算法。它的核心思想是根據物件存活的生命週期將記憶體劃分為若干個不同的區域。一般情況下將堆區劃分為老年代(Tenured Generation)和新生代(Young Generation),老年代的特點是每次垃圾收集時只有少量物件需要被回收,而新生代的特點是每次垃圾回收時都有大量的物件需要被回收,那麼就可以根據不同代的特點採取最適合的收集演算法。

三.典型的垃圾收集器 垃圾收集演算法是 記憶體回收的理論基礎,而垃圾收集器就是記憶體回收的具體實現。下面介紹一下HotSpot(JDK 7)虛擬機器提供的幾種垃圾收集器,使用者可以根據自己的需求組合出各個年代使用的收集器。

物件的記憶體分配,往大方向上講就是在堆上分配,物件主要分配在新生代的Eden Space和From Space,少數情況下會直接分配在老年代。如果新生代的Eden Space和From Space的空間不足,則會發起一次GC,如果進行了GC之後,Eden Space和From Space能夠容納該物件就放在Eden Space和From Space。在GC的過程中,會將Eden Space和From  Space中的存活物件移動到To Space,然後將Eden Space和From Space進行清理。如果在清理的過程中,To Space無法足夠來儲存某個物件,就會將該物件移動到老年代中。在進行了GC之後,使用的便是Eden space和To Space了,下次GC時會將存活物件複製到From Space,如此反覆迴圈。當物件在Survivor區躲過一次GC的話,其物件年齡便會加1,預設情況下,如果物件年齡達到15歲,就會移動到老年代中。

一般來說,大物件會被直接分配到老年代,所謂的大物件是指需要大量連續儲存空間的物件,最常見的一種大物件就是大陣列,比如:

byte[] data = new byte[4*1024*1024]

這種一般會直接在老年代分配儲存空間。

當然分配的規則並不是百分之百固定的,這要取決於當前使用的是哪種垃圾收集器組合和JVM的相關引數。

1.Serial/Serial Old

Serial/Serial Old收集器是最基本最古老的收集器,它是一個單執行緒收集器,並且在它進行垃圾收集時,必須暫停所有使用者執行緒。Serial收集器是針對新生代的收集器,採用的是Copying演算法,Serial Old收集器是針對老年代的收集器,採用的是Mark-Compact演算法。它的優點是實現簡單高效,但是缺點是會給使用者帶來停頓。

2.ParNew

ParNew收集器是Serial收集器的多執行緒版本,使用多個執行緒進行垃圾收集。

3.Parallel Scavenge

Parallel Scavenge收集器是一個新生代的多執行緒收集器(並行收集器),它在回收期間不需要暫停其他使用者執行緒,其採用的是Copying演算法,該收集器與前兩個收集器有所不同,它主要是為了達到一個可控的吞吐量。

4.Parallel Old

Parallel Old是Parallel Scavenge收集器的老年代版本(並行收集器),使用多執行緒和Mark-Compact演算法。

5.CMS

CMS(Current Mark Sweep)收集器是一種以獲取最短回收停頓時間為目標的收集器,它是一種併發收集器,採用的是Mark-Sweep演算法。

-----------------------------------------JVM垃圾回收機制--------------------------------------

---------------------------------------------System.gc()----------------------------------------

其實這個gc()函式的作用只是提醒虛擬機器:程式設計師希望進行一次垃圾回收。但是它不能保證垃圾回收一定會進行,而且具體什麼時候進行是取決於具體的虛擬機器的,不同的虛擬機器有不同的對策。

最後的箴言:不要頻繁使用gc函式。 我的建議是:保持程式碼健壯(記得將不用的變數置為null),讓虛擬機器去管理記憶體。 ---------------------------------------------System.gc()----------------------------------------

----------------------------------------hibernate 快取---------------------------------------  一級快取:指的是Session快取,基於執行緒的快取

 二級快取: 指的是SessionFactory的快取,是基於程序的快取(由於SessionFactory的宣告週期和程式的宣告週期是相同的,並且是單例的)

     二級快取又分為內建快取和外接快取         內建快取是hibernate中自己編寫的         外接快取是hibernate藉助第三方外掛的快取         外接快取又分為class快取和查詢快取             這兩種快取都採用的是map結構,前者的key儲存的是sql語句的字串,value儲存的是主鍵id的集合                                          後者的key儲存的是id,value儲存的是id所對應的某一條記錄封裝後的物件    三級快取:指的是外接快取中的查詢快取     由於查詢快取依賴於class快取,所以說三級快取是基於二級快取之上的.

  ----------------------------------------hibernate 快取---------------------------------------

----------------------------------------hibernate get load 的區別--------------------------------- 1. 對於get方法,hibernate會確認一下該id對應的資料是否存在,首先在session快取中查詢,然後在二級快取中查詢,還沒有就查詢資料庫,資料庫中沒有就返回null。這個相對比較簡單,也沒有太大的爭議。主要要說明的一點就是在這個版本中get方法也會查詢二級快取!

2.  load方法載入實體物件的時候,根據對映檔案上類級別的lazy屬性的配置(預設為true),分情況討論:

(1)若為true,則首先在Session快取中查詢,看看該id對應的物件是否存在,不存在則使用延遲載入,返回實體的代理類物件(該代理類為實體類的子類,由CGLIB動態生成)。等到具體使用該物件(除獲取OID以外)的時候,再查詢二級快取和資料庫,若仍沒發現符合條件的記錄,則會丟擲一個ObjectNotFoundException。

(2)若為false,就跟get方法查詢順序一樣,只是最終若沒發現符合條件的記錄,則會丟擲一個ObjectNotFoundException。

總之對於get和load的根本區別,一句話,hibernate對於load方法認為該資料在資料庫中一定存在,可以放心的使用代理來延遲載入,如果在使用過程中發現了問題,只能拋異常;而對於get方法,hibernate一定要獲取到真實的資料,否則返回null。

----------------------------------------hibernate get load 的區別---------------------------------

-------------------------------------spring 工作原理-------------------------------------

在spring ioc中有三種依賴注入,分別是: a、介面注入; b、setter方法注入; c、構造方法注入;

就是 ioc 和 aop

ioc 就是反射 aop 就是動態代理

-------------------------------------spring 工作原理-------------------------------------

------------------------------------------關於反射--------------------------------------- public Object invoke(Object obj,Object... args)

public Object invoke(Object obj,Object... args)

 Class<?> clazz = Class.forName("net.xsoftlab.baike.Person");   // 呼叫Person類中的run方法   Method method = clazz.getMethod("run");   method.invoke(clazz.newInstance());   // Java 反射機制 - 呼叫某個類的方法1.   // 呼叫Person的Speak方法   method = clazz.getMethod("Speak", int.class, String.class);   method.invoke(clazz.newInstance(), 22, "小明");   // Java 反射機制 - 呼叫某個類的方法2.   // age -> 22. name -> 小明  

                                           如何獲取私有屬性和私有方法(如果要呼叫私有屬性還需設定屬性可達.                         // 要設定屬性可達,不然會丟擲IllegalAccessException異常field.setAccessible(true);     //僅能獲取共有的屬性     Field[] fieldArray = clazz.getFields();         //能夠獲取共有和私有的所有屬性     Field[] declaredArray = clazz.getDeclaredFields();     for(int i = 0 ; i < fieldArray.length ; i++){         System.out.println( fieldArray[i].getName() );     }          for(int i = 0 ; i < declaredArray.length; i++){         System.out.println( declaredArray[i].getName() );     }          //僅能獲取共有的方法     Method[] methodArray = clazz.getMethods();     //能夠獲取公有和私有的方法     Method[] methodDeclaredArray = clazz.getDeclaredMethods();

                                      反射獲取所有的成員變數 // 要獲取類的資訊,首先要獲取類的類型別     Class<?> class1 = object.getClass();// 傳遞的是哪個子類的物件,class1就是該子類的類型別 /**  * 成員變數也是物件 java.lang.reflect.Field Field類封裝了關於成員變數的操作  * getFields()方法獲取的是所有的public的成員變數的資訊  * getDeclaredFields獲取的是該類自己宣告的成員變數的資訊  */     Field[] fs = class1.getFields();

                                      反射獲取所有的成員方法  // 要獲取類的資訊,首先要獲取類的類型別     Class<?> class1 = object.getClass();// 傳遞的是哪個子類的物件,class1就是該子類的類型別 // 獲取類的名稱     System.out.println("類的名稱是:" + class1.getName()); /** * Method類,方法物件 一個成員方法就是一個Method物件 getMehtod()方法 * 獲取的是所有得public的函式,包括父類繼承的 getDeclaredMethods()獲取的是所有該類宣告的方法,不同訪問許可權 */     Method[] ms = class1.getMethods();     for (int i = 0; i < ms.length; i++) { // 得到方法的返回值型別的類型別     Class<?> returnType = ms[i].getReturnType(); // 得到方法的名稱     System.out.print(ms[i].getName() + "("); // 獲取引數型別     Class[] paramTypes = ms[i].getParameterTypes();

------------------------------------------關於反射---------------------------------------

----------------------------------char varchar varchar2 的區別 ------------------------------------------ 區別: 1.CHAR的長度是固定的,而VARCHAR2的長度是可以變化的, 比如,儲存字串“abc",對於CHAR (20),表示你儲存的字元將佔20個位元組(包括17個空字元),而同樣的VARCHAR2 (20)則只佔用3個位元組的長度,20只是最大值,當你儲存的字元小於20時,按實際長度儲存。  2.CHAR的效率比VARCHAR2的效率稍高。  3.目前VARCHAR是VARCHAR2的同義詞。工業標準的VARCHAR型別可以儲存空字串,但是oracle不這樣做,儘管它保留以後這樣做的權利。Oracle自己開發了一個數據型別VARCHAR2,這個型別不是一個標準的VARCHAR,它將在資料庫中varchar列可以儲存空字串的特性改為儲存NULL值。如果你想有向後相容的能力,Oracle建議使用VARCHAR2而不是VARCHAR。

varchar       存放固定長度的字元資料,最長2000個字元。

varchar2    存放可變長字元資料,最大長度為4000字元。,最大長度為4000字元。

varchar     是標準sql提供的資料型別。

varchar2  是oracle提供的獨特的資料型別。

oracle保證在任何版本中該資料型別向上和向下相容,但不保證varchar。

總之,如果想新版本的資料庫相容就不要用varchar,如果想和其他資料庫相容就不要用varchar2。

何時該用CHAR,何時該用varchar2?  CHAR與VARCHAR2是一對矛盾的統一體,兩者是互補的關係.  VARCHAR2比CHAR節省空間,在效率上比CHAR會稍微差一些,即要想獲得效率,就必須犧牲一定的空間,這也就是我們在資料庫設計上常說的‘以空間換效率’。  VARCHAR2雖然比CHAR節省空間,但是如果一個VARCHAR2列經常被修改,而且每次被修改的資料的長度不同,這會引起‘行遷移’(Row Migration)現象,而這造成多餘的I/O,是資料庫設計和調整中要盡力避免的,在這種情況下用CHAR代替VARCHAR2會更好一些。

----------------------------------char varchar varchar2 的區別 ------------------------------------------

----------------------------------------代理的3種模式------------------------------------

1.1.靜態代理

代理類也需要實現 目標介面類

動態代理 JDK方式: 1.代理物件,不需要實現介面 2.代理物件的生成,是利用JDK的API,動態的在記憶體中構建代理物件(需要我們指定建立代理物件/目標物件實現的介面的型別) 3.動態代理也叫做:JDK代理,介面代理

cglib:(子類代理,同時也是需要 實現MethodInterceptor這個介面的.) 上面的靜態代理和動態代理模式都是要求目標物件是實現一個介面的目標物件,但是有時候目標物件只是一個單獨的物件,並沒有實現任何的介面,這個時候就可以使用以目標物件子類的方式類實現代理,這種方法就叫做:Cglib代理 Cglib代理,也叫作子類代理,它是在記憶體中構建一個子類物件從而實現對目標物件功能的擴充套件.

在Spring的AOP程式設計中: 如果加入容器的目標物件有實現介面,用JDK代理 如果目標物件沒有實現介面,用Cglib代理

----------------------------------------代理的3種模式------------------------------------

----------------------------------------runnabel callable/futuretask 區別----------------------------------

相同點:

    兩者都是介面;(廢話)     兩者都可用來編寫多執行緒程式;     兩者都需要呼叫Thread.start()啟動執行緒;

不同點:

    兩者最大的不同點是:實現Callable介面的任務執行緒能返回執行結果;而實現Runnable介面的任務執行緒不能返回結果;     Callable介面的call()方法允許丟擲異常;而Runnable介面的run()方法的異常只能在內部消化,不能繼續上拋;

----------------------------------------runnabel callable/futuretask 區別----------------------------------

-------------------------------------------分散式資料庫&大資料下的處理方法------------------------------------

二階段提交 三階段提交

在兩階段提交協議中,系統一般包含兩類機器(或節點):     一類為協調者(coordinator),通常一個系統中只有一個;      另一類為事務參與者(participants,cohorts或workers),一般包含多個,在資料儲存系統中可以理解為資料副本的個數。協議中假設每個節點都會記錄寫前日誌(write-ahead log)並永續性儲存,即使節點發生故障日誌也不會丟失。協議中同時假設節點不會發生永久性故障而且任意兩個節點都可以互相通訊。

                 一張表大資料下的解決方案:  分表,分庫(垂直分庫,水平分庫)   分割槽

-------------------------------------------分散式資料庫&大資料下的處理方法------------------------------------

-------------------------------------------hdfs試用場景與不適用場景-------------------------------

使用場景:大檔案訪問,流失資料訪問 不適用場景:儲存大量小檔案,隨機讀取低延遲讀取

-------------------------------------------hdfs試用場景與不適用場景-------------------------------

-------------------------------------------軟體設計中的一些圖示---------------------------------- ER圖是實體-關係圖,包括一些物件和物件的聯絡,還有物件的屬性 用例圖是指由參與者(Actor)、用例(Use Case)以及它們之間的關係構成的用於描述系統功能的檢視

泳道圖,一種UML活動圖,能夠清晰體現出某個動作發生在哪個部門,常見工具有StarUML、Rose、Visio等。泳道圖在縱向上是部門職能,橫向是崗位(有時候橫向上不區分崗位)。繪圖元素與傳統流程圖類似,但在業務流程主體上,通過泳道(縱向條)區分出執行主體,即部門和崗位來。 -------------------------------------------軟體設計中的一些圖示----------------------------------

-----------------------------執行緒的幾種狀態--------------------- 新建  就緒  執行  阻塞 -----------------------------執行緒的幾種狀態----------------------

-------------------------------String 執行時常量池-------------------------

幾個關鍵詞: jvm 執行時常量池(符號引用,字面量) String的一些方法  intern(1:如果字串在 常量池中,則直接返回引用. 2:如果常量池中沒有該字串,則將該字串放到常量池中)

直接使用new 出來的字串如果沒有intern則不會放入到常量池

關於什麼時候會把字串放入到常量池中 1:頁面初始化編譯的時候.且是明確的字串賦值.如果使用s=s1+s2則不會把該字串放入到常量池中.s="123"會放入     次方法叫靜態編譯時放入常量池 2:使用intern()方法.此方法交 執行時常量放入

-------------------------------String 執行時常量池-------------------------

---------------------------------------mongodb事務解決方案-------------------

A:作業佇列  B:欄位同步

---------------------------------------mongodb事務解決方案-------------------

--------------------------------------事務問題-----------------------------------

資料庫支援資料塊間的事務是有原因的。典型的場景是應用需要修改幾個獨立的位元時,如果只有一些而不是全部改變儲存到了資料庫,那麼這就會出現不一致問題。因此ACID的概念是:

原子性:所有的改變要麼都做了,要麼都沒做 一致性:資料保持一致性狀態 隔離性:其它使用者看不到部分改變 永續性:一旦向用戶確認了事務,資料就處於安全的狀態(通常存在硬碟上)

原子性:實際上你希望所有的改變都完成 一致性:系統短時間不一致沒關係,只要最終一致就行 隔離性:缺乏隔離性導致暫時的不一致,這並不理想,但是當今線上服務時代,很多使用者對此都習慣了(如使用者支援:“它要花幾秒傳輸”)。 永續性:很重要,要支援。 --------------------------------------事務問題-----------------------------------

---------------------------------------mongodb oracle 效能對比----------------------------------------------

資料插入上的對比: 相同表結構,相同數量級的記錄  mongodb 始終比 oracle 插入的效率要要快.效率從數量級的增加越來越明顯從10萬條開始 mondogb就是 一個數量級的差距. 比如 mongodb 是10萬毫秒 oracle 就是100萬毫秒(在有索引和無索引的下相同)

資料查詢上的對比: mongodb 和oracle 在檢索上的效率:在有索引和無索引的情況下 以1000萬為臨界點 mongodb在檢索的效率上是 oracle的數值的一半 比如 mongodb 是9000ms oracle 就是 4000ms左右(在1萬資料 10萬資料 100萬資料的檢索下效率是差不多的)

---------------------------------------mongodb oracle 效能對比----------------------------------------------

---------------------------------------資料庫的橫向設計  縱向設計-------------------------------------------

橫向設計的利與弊

利:1、預選設定好了所需要的列,對資料庫操作方便 弊:1、不易拓展,易冗餘

縱向設計的利與弊 利:1、容易拓展,彈性好,遵循資料庫設計的XX正規化(至於第幾條,我真心記不得) 弊:1、失去了對資料的控制權,也就是說很難維持資料的規範化,如果我的程式不規範隨意在選修課列中加入‘烹飪技巧