隨筆-204  評論-90  文章-8  trackbacks-0
           
          2003-02-17· ·板橋里人 ··j-道

          開始之初的架構設計決定著軟件產品的生死存亡。“好的開始相當于成功一半”。

            開始的架構設計也是最難的,需要調研同類產品的情況以及技術特征,了解當前世界上對這種產品所能提供的理論支持和技術平臺支持。再結合自己項目的特點(需要透徹的系統分析),才能逐步形成自己項目的架構藍圖。

            比如要開發網站引擎系統,就從Yahoo的個人主頁生成工具 到虛擬主機商提供的網站自動生成系統,以及IBM Webphere Portal的特點和局限 從而從架構設計角度定立自己產品的位置。

            好的設計肯定需要經過反復修改,從簡單到復雜的循環測試是保證設計正確的一個好辦法

            由于在開始選擇了正確的方向,后來項目的實現過程也驗證了這種選擇,但在一些架構設計的細部方面,還需要對方案進行修改,屬于那種螺旋上升的方式,顯然這是通過測試第一的思想和XP工程方法來實現的。

            如果我們開始的架構設計在技術平臺定位具有一定的世界先進水平,那么,項目開發實際有一半相當于做實驗,是研發,存在相當的技術風險。

            因此,一開始我們不可能將每個需求都實現,而是采取一種簡單完成架構流程的辦法,使用最簡單的需求將整個架構都簡單的完成一遍(加入人工干 預),以檢驗各個技術環節是否能協調配合工作(非常優秀先進的兩種技術有時無法在一起工作),同時也可以探知技術的深淺,掌握項目中的技術難易點。這個過 程完成后,我們就對設計方案做出上面的重大修改,豐富完善了設計方案。

            設計模式是支撐架構的重要組件

            架構設計也類似一種工作流,它是動態的,這點不象建筑設計那樣,一開始就能完全確定,架構設計伴隨著整個項目的進行過程之中,有兩種具體操作保證架構設計的正確完成,那就是設計模式(靜態)和工程項目方法(RUP或XP 動態的)。

            設計模式是支撐架構的一種重要組件,這與建筑有很相象的地方,一個建筑物建立設計需要建筑架構設計,在具體施工中,有很多建筑方面的規則和模式。

            我們從J2EE藍圖模式分類http://java.sun.com/blueprints/patterns/catalog.html中就可以很清楚的看到J2EE這樣一個框架軟件的架構與設計模式的關系。

            架構設計是骨架,設計模式就是肉

            這樣,一個比較豐富的設計方案可以交由程序員進一步完成了,載輔助以適當的工程方法,這樣就可保證項目的架構設計能正確快速的完成。

            時刻牢記架構設計的目標

            由于架構設計是在動態中完成的,因此在把握架構設計的目標上就很重要,因此在整個項目過程中,甚至每一步我們都必須牢記我們架構設計的總體目標,可以概括下面幾點:

            1. 最大化的重用:這個重用包括組件重用 和設計模式使用等多個方面。

            比如,我們項目中有用戶注冊和用戶權限系統驗證,這其實是個通用課題,每個項目只是有其內容和一些細微的差別,如果我們之前有這方面成功研發經 驗,可以直接重用,如果沒有,那么我們就要進行這個子項目的研發,在研發過程中,不能僅僅看到這個項目的需求,也要以架構的概念去完成這個可以稱為組件的 子項目。

            2. 盡可能的簡單明了:我們解決問題的總方向是將復雜問題簡單化,其實這也是中間件或多層體系技術的根本目標。但是在具體實施設計過程中,我們可能會將簡單問題復雜化,特別是設計模式的運用上很容易范這個錯誤,因此如何盡可能的做到設計的簡單明了是不容易的。

            我認為落實到每個類的具體實現上要真正能體現系統事物的本質特征,因為事物的本質特征只有一個,你的代碼越接近它,表示你的設計就是簡單明了, 越簡單明了,你的系統就越可靠。更多情況是,一個類并不能反應事物本質,需要多個類的組合協調,那么能夠正確使用合適的設計模式就稱為重中之重。

            我們看一個具備好的架構設計的系統代碼時,基本看到的都是設計模式,寵物店(pet store)就是這樣的例子。或者可以這樣說,一個好的架構設計基本是由簡單明了的多個設計模式完成的。

            3. 最靈活的拓展性:架構設計要具備靈活性 拓展性,這樣,用戶可以在你的架構上進行二次開發或更加具體的開發。

            要具備靈活的拓展性,就要站在理論的高度去進行架構設計,比如現在工作流概念逐步流行,因為我們具體很多實踐項目中都有工作流的影子,工作流中有一個樹形結構權限設定的概念就對很多領域比較通用。

            樹形結構是組織信息的基本形式,我們現在看到的網站或者ERP前臺都是以樹形菜單來組織功能的,那么我們在進行架構設計時,就可以將樹形結構和 功能分開設計,他們之間聯系可以通過樹形結構的節點link在一起,就象我們可以在圣誕樹的樹枝上掛各種小禮品一樣,這些小禮品就是我們要實現的各種功 能。

            有了這個概念,通常比較難實現的用戶級別權限控制也有了思路,將具體用戶或組也是和樹形結構的節點link在一起,這樣就間接實現了用戶對相應功能的權限控制,有了這樣的基本設計方案的架構無疑具備很靈活的拓展性。


          posted @ 2007-11-26 11:56 一凡 閱讀(264) | 評論 (0)編輯 收藏
          在使用二分法查找注意事項時,容器(ArrayList)的排序規則和查找時使用的比較規則必須一致,否則有查不到的情況發生。例:
           排序方法:(JVM自動調用)
           public int compare(Object o1, Object o2)和
           比較方法:(我們的程序調用)
           public int compare(int co, int oprId, int provId,int prodId)必須一致
          posted @ 2007-11-21 11:22 一凡 閱讀(310) | 評論 (0)編輯 收藏
          第一,談談final, finally, finalize的區別。 
             final?修飾符(關鍵字)如果一個類被聲明為final,意
           味著它不能再派生出新的子類,不能作為父類被繼承。因此
           一個類不能既被聲明為 abstract的,又被聲明為final的。將
           變量或方法聲明為final, 可以保證它們在使用中不被改變。
           被聲明為final的變量必須在聲明時給定初值,而在以后的引
           用中只能 讀取,不可修改。被聲明為final的方法也同樣只能
           使用,不能重載。finally?再異常處理時提供 finally 塊來執行
           任何清除操作。如果拋出一個異常,那么相匹配的 catch 子
           句就會執行,然后控制就會進入 finally 塊(如果有的話)。 
           finalize?方法名。Java 技術允許使用 finalize() 方法在垃
           圾收集器將對象從內存中清除出去 之前做必要的清理工作。
           這個方法是由垃圾收集器在確定這個對象沒有被引用時對這
           個對象調用的。它是 在 Object 類中定義的,因此所有的類
           都繼承了它。子類覆蓋 finalize() 方法以整理系統資源或
           者執 行其他清理工作。finalize() 方法是在垃圾收集器刪
           除對象之前對這個對象調用的。 
             第二,Anonymous Inner Class (匿名內部類) 是否可
           以extends(繼承)其它類,是否可以 
           implements(實現)interface(接口)? 
             匿名的內部類是沒有名字的內部類。不能extends(繼承
           ) 其它類,但一個內部類可以作為一個接口 
           ,由另一個內部類實現。 
             第三,Static Nested Class 和 Inner Class的不同,說得
           越多越好(面試題有的很籠統)。 
             Nested Class (一般是C++的說法),Inner Class (一
           般是JAVA的說法)。Java內部類與C++嵌套 
           類最大的不同就在于是否有指向外部的引用上。具體可
           見http: 
           //www.frontfree.net/articles/services/view.asp?id=704&page
           =1 
             注: 靜態內部類(Inner Class)意味著1創建一個static
           內部類的對象,不需要一個外部類對象,2 
           不能從一個static內部類的一個對象訪問一個外部類對象 
             第四,&和&&的區別。 
             &是位運算符。&&是布爾邏輯運算符。 
             第五,HashMap和Hashtable的區別。 
             都屬于Map接口的類,實現了將惟一鍵映射到特定的值
           上。 
             HashMap 類沒有分類或者排序。它允許一個 null 鍵和多
           個 null 值。 
             Hashtable 類似于 HashMap,但是不允許 null 鍵和 null 
           值。它也比 HashMap 慢,因為它是同步 
           的。 
             第六,Collection 和 Collections的區別。 
             Collections是個java.util下的類,它包含有各種有關集合
           操作的靜態方法。 
             Collection是個java.util下的接口,它是各種集合結構的父
           接口。 
           第七,什么時候用assert。 
           斷言是一個包含布爾表達式的語句,在執行這個語句時假定
           該表達式為 true。如果表達式計算為 false,那么系統會報告
           一個 AssertionError。它用于調試目的: 
           assert(a > 0); // throws an AssertionError if a <= 0 
           斷言可以有兩種形式: 
           assert Expression1 ; 
           assert Expression1 : Expression2 ; 
           Expression1 應該總是產生一個布爾值。 
           Expression2 可以是得出一個值的任意表達式。這個值用于
           生成顯示更多調試信息的 String 消息。 
           斷言在默認情況下是禁用的。要在編譯時啟用斷言,需要使
           用 source 1.4 標記: 
           javac -source 1.4 Test.java 
           要在運行時啟用斷言,可使用 -enableassertions 或者 -ea 標
           記。 
           要在運行時選擇禁用斷言,可使用 -da 或者 
           -disableassertions 標記。 
           要系統類中啟用斷言,可使用 -esa 或者 -dsa 標記。還可以
           在包的基礎上啟用或者禁用斷言。 可以在預計正常情況下不
           會到達的任何位置上放置斷言。斷言可以用于驗證傳遞給私
           有方法的參數。不過,斷言不應該用于驗證傳遞給公有方法
           的參數,因為不管是否啟用了斷言,公有方法都必須檢查其
           參數。不過,既可以在公有方法中,也可以在非公有方法中
           利用斷言測試后置條件。另外,斷言不應該以任何方式改變
           程序的狀態。 
           第八,GC是什么? 為什么要有GC? (基礎)。 
           GC是垃圾收集器。Java 程序員不用擔心內存管理,因為垃
           圾收集器會自動進行管理。要請求垃圾收 
           集,可以調用下面的方法之一: 
           System.gc() 
           Runtime.getRuntime().gc() 
           第九,String s = new String("xyz");創建了幾個String Object? 
           兩個對象,一個是"xyx",一個是指向"xyx"的引用對象s。 
           第十,Math.round(11.5)等於多少? Math.round(-11.5)等於多
           少? 
           Math.round(11.5)返回(long)12,Math.round(-11.5)返
           回(long)-11; 
           第十一,short s1 = 1; s1 = s1 + 1;有什么錯? short s1 = 1; s1 
           += 1;有什么錯? 
           short s1 = 1; s1 = s1 + 1;有錯,s1是short型,s1+1是int型,不
           能顯式轉化為short型。可修改為 s1 =(short)(s1 + 1) 。short 
           s1 = 1; s1 += 1正確。 
           第十二,sleep() 和 wait() 有什么區別? 搞線程的最愛 
           sleep()方法是使線程停止一段時間的方法。在sleep 時間間
           隔期滿后,線程不一定立即恢復執行。 這是因為在那個時刻
           ,其它線程可能正在運行而且沒有被調度為放棄執行,除
           非(a)"醒來"的線程具有更高的優先級,(b)正在運行的線程因
           為其它原因而阻塞。 
           wait()是線程交互時,如果線程對一個同步對象x 發出一
           個wait()調用,該線程會暫停執行,被調對象進入等待狀態,
           直到被喚醒或等待時間到。 
           第十三,Java有沒有goto? 
           Goto?java中的保留字,現在沒有在java中使用。 
           第十四,數組有沒有length()這個方法? String有沒有length()
           這個方法? 
           數組沒有length()這個方法,有length的屬性。 
           String有有length()這個方法。
            
           第十五,Overload和Override的區別。Overloaded的方法是
           否可以改變返回值的類型? 
           方法的重寫Overriding和重載Overloading是Java多態性的不
           同表現。重寫Overriding是父類與子類 之間多態性的一種表
           現,重載Overloading是一個類中多態性的一種表現。如果在
           子類中定義某方法與其父類有相同的名稱和參數,我們說該
           方法被重寫 (Overriding)。子類的對象使用這個方法時,將調
           用子類中的定義,對它而言,父類中的定義如同被"屏蔽"了
           。如果在一個類中定義了多個同名的方法,它們或有不同的
           參數個數或有不同的參數類型,則稱為方法的重
           載(Overloading)。Overloaded的方法是可以改變返回值的類
           型。 
           第十六,Set里的元素是不能重復的,那么用什么方法來區
           分重復與否呢? 是用==還是equals()? 它們有何區別? 
           Set里的元素是不能重復的,那么用iterator()方法來區分重復
           與否。equals()是判讀兩個Set是否相 等。 
           equals()和==方法決定引用值是否指向同一對象equals()在類
           中被覆蓋,為的是當兩個分離的對象的內容和類型相配的話
           ,返回真值。 
           第十七,給我一個你最常見到的runtime exception。 
           ArithmeticException, ArrayStoreException, 
           BufferOverflowException, 
           BufferUnderflowException, CannotRedoException, 
           CannotUndoException, ClassCastException, 
           CMMException, ConcurrentModificationException, 
           DOMException, EmptyStackException, 
           IllegalArgumentException, IllegalMonitorStateException, 
           IllegalPathStateException, 
           IllegalStateException, ImagingOpException, 
           IndexOutOfBoundsException, 
           MissingResourceException, NegativeArraySizeException, 
           NoSuchElementException, 
           NullPointerException, ProfileDataException, 
           ProviderException, RasterFormatException, 
           SecurityException, SystemException, 
           UndeclaredThrowableException, UnmodifiableSetException, 
           UnsupportedOperationException 
           第十八,error和exception有什么區別? 
           error 表示恢復不是不可能但很困難的情況下的一種嚴重問題
           。比如說內存溢出。不可能指望程序能處理這樣的情況。 
           exception 表示一種設計或實現問題。也就是說,它表示如果
           程序運行正常,從不會發生的情況。 
           第十九,List, Set, Map是否繼承自Collection接口? 
           List,Set是 
           Map不是 
           第二十,abstract class和interface有什么區別? 
           聲明方法的存在而不去實現它的類被叫做抽象類(abstract 
           class),它用于要創建一個體現某些基本行為的類,并為該
           類聲明方法,但不能在該類中實現該類的情況。不能創
           建abstract 類的實例。然而可以創建一個變量,其類型是一
           個抽象類,并讓它指向具體子類的一個實例。不能有抽象構
           造函數或抽象靜態方法。Abstract 類的子類為它們父類中的
           所有抽象方法提供實現,否則它們也是抽象類為。取而代之
           ,在子類中實現該方法。知道其行為的其它類可以在類中實
           現這些方法。 
           接口(interface)是抽象類的變體。在接口中,所有方法都
           是抽象的。多繼承性可通過實現這樣的接口而獲得。接口中
           的所有方法都是抽象的,沒有一個有程序體。接口只可以定
           義static final成員變量。接口的實現與子類相似,除了該實現
           類不能從接口定義中繼承行為。當類實現特殊接口時,它定
           義(即將程序體給予)所有這種接口的方法。然后,它可以
           在實現了該接口的類的任何對象上調用接口的方法.由于有抽
           象類,它允許使用接口名作為引用變量的類型。通常的動態
           聯編將生效。引用可以轉換到接口類型或從接口類型轉
           換,instanceof 運算符可以用來決定某對象的類是否實現了
           接口。 
           第二十一,abstract的method是否可同時是static,是否可同時
           是native,是否可同時是 
           synchronized? 
           都不能 
           第二十二,接口是否可繼承接口? 抽象類是否可實
           現(implements)接口? 抽象類是否可繼承實體類 
           (concrete class)? 
           接口可以繼承接口。抽象類可以實現(implements)接口,抽象
           類是否可繼承實體類,但前提是實體類必須有明確的構造函
           數。 
           第二十三,啟動一個線程是用run()還是start()? 
           啟動一個線程是調用start()方法,使線程所代表的虛擬處理
           機處于可運行狀態,這意味著它可以由JVM調度并執行。這
           并不意味著線程就會立即運行。run()方法可以產生必須退出
           的標志來停止一個線程。 
            
           第二十四,構造器Constructor是否可被override? 
           構造器Constructor不能被繼承,因此不能重寫Overriding,但
           可以被重載Overloading。 
           第二十五,是否可以繼承String類? 
           String類是final類故不可以繼承。 
           第二十六,當一個線程進入一個對象的一個synchronized方
           法后,其它線程是否可進入此對象的其它方法? 
           不能,一個對象的一個synchronized方法只能由一個線程訪
           問。 
           第二十七,try {}里有一個return語句,那么緊跟在這個try后
           的finally {}里的code會不會被執行,什么時候被執
           行,在return前還是后? 
           會執行,在return前執行。 
           第二十八,編程題: 用最有效率的方法算出2乘以8等於幾? 
           有C背景的程序員特別喜歡問這種問題。 
           2 << 3 
           第二十九,兩個對象值相同(x.equals(y) == true),但卻可有
           不同的hash code,這句話對不對? 
           不對,有相同的hash code。 
           第三十,當一個對象被當作參數傳遞到一個方法后,此方法
           可改變這個對象的屬性,并可返回變化后的結果,那么這里
           到底是值傳遞還是引用傳遞? 
           是值傳遞。Java 編程語言只由值傳遞參數。當一個對象實例
           作為一個參數被傳遞到方法中時,參數的值就是對該對象的
           引用。對象的內容可以在被調用的方法中改變,但對象的引
           用是永遠不會改變的。 
           第三十一,swtich是否能作用在byte上,是否能作用在long上
           ,是否能作用在String上? 
           switch(expr1)中,expr1是一個整數表達式。因此傳遞給 
           switch 和 case 語句的參數應該是 int、 short、 char 或者 
           byte。long,string 都不能作用于swtich。 
           第三十二,編程題: 寫一個Singleton出來。 
           Singleton模式主要作用是保證在Java應用程序中,一個
           類Class只有一個實例存在。 
           一般Singleton模式通常有幾種種形式: 
           第一種形式:   定義一個類,它的構造函數為private的,
           它有一個static的private的該類變量, 在類初始化時實例話
           ,通過一個public的getInstance方法獲取對它的引用,繼而調
           用其中的方法。 
           public class Singleton { 
           private Singleton(){} 
           //在自己內部定義自己一個實例,是不是很奇怪? 
           //注意這是private 只供內部調用 
           private static Singleton instance = new Singleton(); 
           //這里提供了一個供外部訪問本class的靜態方法,可以直接
           訪問 
           public static Singleton getInstance() { 
           return instance; 
           } 
           } 
           第二種形式: 
           public class Singleton { 
           private static Singleton instance = null; 
           public static synchronized Singleton getInstance() { 
           //這個方法比上面有所改進,不用每次都進行生成對象,只
           是第一次 
           //使用時生成實例,提高了效率! 
           if (instance==null) 
           instance=new Singleton(); 
           return instance; } 
           } 
           其他形式: 
           定義一個類,它的構造函數為private的,所有方法為static的
           。 
           一般認為第一種形式要更加安全些 
           第三十三 Hashtable和HashMap 
           Hashtable繼承自Dictionary類,而HashMap是Java1.2引進的
           Map interface的一個實現 
           HashMap允許將null作為一個entry的key或
           者value,而Hashtable不允許 
           還有就是,HashMap把Hashtable的contains方法去掉了,改
           成containsvalue和containsKey。因為 contains方法容易讓人
           引起誤解。 
           最大的不同是,Hashtable的方法
           是Synchronize的,而HashMap不是,在多個線程訪
           問Hashtable時,不需要自己為它的方法實現同
           步,而HashMap就必須為之提供外同步。 
           Hashtable和HashMap采用的hash/rehash算法都大概一樣,
           所以性能不會有很大的差異 
          posted @ 2007-11-14 16:27 一凡 閱讀(294) | 評論 (0)編輯 收藏
          一:需要包含的包

             

             import java.security.*;

             import java.io.*;

             import java.util.*;

             import java.security.*;

             import java.security.cert.*;

             import sun.security.x509.*

             import java.security.cert.Certificate;

             import java.security.cert.CertificateFactory;

             二:從文件中讀取證書

             用keytool將.keystore中的證書寫入文件中,然后從該文件中讀取證書信息

             CertificateFactory cf=CertificateFactory.getInstance("X.509");

             FileInputStream in=new FileInputStream("out.csr");

             Certificate c=cf.generateCertificate(in);

             String s=c.toString();

             三:從密鑰庫中直接讀取證書

             String pass="123456";

             FileInputStream in=new FileInputStream(".keystore");

             KeyStore ks=KeyStore.getInstance("JKS");

             ks.load(in,pass.toCharArray());

             java.security.cert.Certificate c=ks.getCertificate(alias);//alias為條目的別名

             四:JAVA程序中顯示證書指定信息

             System.out.println("輸出證書信息:\n"+c.toString());

             System.out.println("版本號:"+t.getVersion());

             System.out.println("序列號:"+t.getSerialNumber().toString(16));

             System.out.println("主體名:"+t.getSubjectDN());

             System.out.println("簽發者:"+t.getIssuerDN());

             System.out.println("有效期:"+t.getNotBefore());

             System.out.println("簽名算法:"+t.getSigAlgName());

             byte [] sig=t.getSignature();//簽名值

             PublicKey pk=t.getPublicKey();

             byte [] pkenc=pk.getEncoded();

             System.out.println("公鑰");

             for(int i=0;i<pkenc.length;i++)System.out.print(pkenc[i]+",");

             五:JAVA程序列出密鑰庫所有條目
           String pass="123456";

             FileInputStream in=new FileInputStream(".keystore");

             KeyStore ks=KeyStore.getInstance("JKS");

             ks.load(in,pass.toCharArray());

             Enumeration e=ks.aliases();

             while(e.hasMoreElements())

             java.security.cert.Certificate c=ks.getCertificate((String)e.nextElement());

             六:JAVA程序修改密鑰庫口令

             String oldpass="123456";

             String newpass="654321";

             FileInputStream in=new FileInputStream(".keystore");

             KeyStore ks=KeyStore.getInstance("JKS");

             ks.load(in,oldpass.toCharArray());

             in.close();

             FileOutputStream output=new FileOutputStream(".keystore");

             ks.store(output,newpass.toCharArray());

             output.close();

             七:JAVA程序修改密鑰庫條目的口令及添加條目

             FileInputStream in=new FileInputStream(".keystore");

             KeyStore ks=KeyStore.getInstance("JKS");

             ks.load(in,storepass.toCharArray());

             Certificate [] cchain=ks.getCertificate(alias);獲取別名對應條目的證書鏈

             PrivateKey pk=(PrivateKey)ks.getKey(alias,oldkeypass.toCharArray());獲取別名對應條目的私鑰

             ks.setKeyEntry(alias,pk,newkeypass.toCharArray(),cchain);向密鑰庫中添加條目

             第一個參數指定所添加條目的別名,假如使用已存在別名將覆蓋已存在條目,使用新別名將增加一個新條目,第二個參數為條目的私鑰,第三個為設置的新口令,第四個為該私鑰的公鑰的證書鏈

             FileOutputStream output=new FileOutputStream("another");

             ks.store(output,storepass.toCharArray())將keystore對象內容寫入新文件

             八:JAVA程序檢驗別名和刪除條目

             FileInputStream in=new FileInputStream(".keystore");

             KeyStore ks=KeyStore.getInstance("JKS");

             ks.load(in,storepass.toCharArray());
           ks.containsAlias("sage");檢驗條目是否在密鑰庫中,存在返回true

             ks.deleteEntry("sage");刪除別名對應的條目

             FileOutputStream output=new FileOutputStream(".keystore");

             ks.store(output,storepass.toCharArray())將keystore對象內容寫入文件,條目刪除成功

           九:JAVA程序簽發數字證書

             

             (1)從密鑰庫中讀取CA的證書

             FileInputStream in=new FileInputStream(".keystore");

             KeyStore ks=KeyStore.getInstance("JKS");

             ks.load(in,storepass.toCharArray());

             java.security.cert.Certificate c1=ks.getCertificate("caroot");

             (2)從密鑰庫中讀取CA的私鑰

             PrivateKey caprk=(PrivateKey)ks.getKey(alias,cakeypass.toCharArray());

             (3)從CA的證書中提取簽發者的信息

             byte[] encod1=c1.getEncoded();  提取CA證書的編碼

             X509CertImpl cimp1=new X509CertImpl(encod1); 用該編碼創建X509CertImpl類型對象

             X509CertInfo cinfo1=(X509CertInfo)cimp1.get(X509CertImpl.NAME+"."+X509CertImpl.INFO); 獲取X509CertInfo對象

             X500Name issuer=(X500Name)cinfo1.get(X509CertInfo.SUBJECT+"."+CertificateIssuerName.DN_NAME); 獲取X509Name類型的簽發者信息

             (4)獲取待簽發的證書

             CertificateFactory cf=CertificateFactory.getInstance("X.509");

             FileInputStream in2=new FileInputStream("user.csr");

             java.security.cert.Certificate c2=cf.generateCertificate(in);

             (5)從待簽發的證書中提取證書信息

             byte [] encod2=c2.getEncoded();

             X509CertImpl cimp2=new X509CertImpl(encod2); 用該編碼創建X509CertImpl類型對象

             X509CertInfo cinfo2=(X509CertInfo)cimp2.get(X509CertImpl.NAME+"."+X509CertImpl.INFO); 獲取X509CertInfo對象

             (6)設置新證書有效期

             Date begindate=new Date(); 獲取當前時間

             Date enddate=new Date(begindate.getTime()+3000*24*60*60*1000L); 有效期為3000天
           CertificateValidity cv=new CertificateValidity(begindate,enddate); 創建對象

             cinfo2.set(X509CertInfo.VALIDITY,cv); 設置有效期

             (7)設置新證書序列號

             int sn=(int)(begindate.getTime()/1000);  以當前時間為序列號

             CertificateSerialNumber csn=new CertificateSerialNumber(sn);

             cinfo2.set(X509CertInfo.SERIAL_NUMBER,csn);

             (8)設置新證書簽發者

             cinfo2.set(X509CertInfo.ISSUER+"."+CertificateIssuerName.DN_NAME,issuer);應用第三步的結果

             (9)設置新證書簽名算法信息

             AlgorithmId algorithm=new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);

             cinfo2.set(CertificateAlgorithmId.NAME+"."+CertificateAlgorithmId.ALGORITHM,algorithm);

             (10)創建證書并使用CA的私鑰對其簽名

             X509CertImpl newcert=new X509CertImpl(cinfo2);

             newcert.sign(caprk,"MD5WithRSA"); 使用CA私鑰對其簽名

             (11)將新證書寫入密鑰庫

             ks.setCertificateEntry("lf_signed",newcert);

             FileOutputStream out=new FileOutputStream("newstore");

             ks.store(out,"newpass".toCharArray()); 這里是寫入了新的密鑰庫,也可以使用第七條來增加條目

             十:數字證書的檢驗

             (1)驗證證書的有效期

             (a)獲取X509Certificate類型對象

             CertificateFactory cf=CertificateFactory.getInstance("X.509");

             FileInputStream in1=new FileInputStream("aa.crt");

             java.security.cert.Certificate c1=cf.generateCertificate(in1);

             X509Certificate t=(X509Certificate)c1;

             in2.close();

             (b)獲取日期

             Date TimeNow=new Date();

             (c)檢驗有效性

             try{

             t.checkValidity(TimeNow);

             System.out.println("OK");

             }catch(CertificateExpiredException e){ //過期

             System.out.println("Expired");
           System.out.println(e.getMessage());

             }catch((CertificateNotYetValidException e){ //尚未生效

             System.out.println("Too early");

             System.out.println(e.getMessage());}

             (2)驗證證書簽名的有效性

             (a)獲取CA證書

             CertificateFactory cf=CertificateFactory.getInstance("X.509");

             FileInputStream in2=new FileInputStream("caroot.crt");

             java.security.cert.Certificate cac=cf.generateCertificate(in2);

             in2.close();

             (c)獲取CA的公鑰

             PublicKey pbk=cac.getPublicKey();

             (b)獲取待檢驗的證書(上步已經獲取了,就是C1)

             (c)檢驗證書

             boolean pass=false;

             try{

             c1.verify(pbk);

             pass=true;

             }catch(Exception e){

             pass=false;

             System.out.println(e);

             } 
          posted @ 2007-11-14 16:08 一凡 閱讀(313) | 評論 (0)編輯 收藏

          一、功能:使用crontab命令裝載cron進程所需要的crontab文件。

          格式:

          格式1:crontab [-u user] [-l|-r|-e]

          格式2:crontab [-u user] filename

          其中:

          -u user: 修改指定用戶的crontab文件。如果不指定該選項,crontab將默認為是操作者本人的crontab。

          -l:在標準輸出上顯示當前的crontab任務。

          -r:刪除當前的crontab任務。

          -e:使用環境變量指定的編輯器編輯crontab文件。當結束編輯離開時,編輯后的文件將自動安裝。

          filename:是一個crontab文件的來源文件
          crontab文件的來源文件
          crontab文件的來源文件存在的形式

          一個符合語法規則的純文本文件,使用第2種格式的crontab命令裝載

          使用第2種格式的crontab命令時,它是一個文本編輯器(如vi)的臨時文件,編輯結束自動裝載

          crontab文件的來源文件的格式
          每一行格式為:

          分< >時< >日< >月< >星期< >要運行的命令

          minute hour day-of-month month-of-year day-of-week [username] commands

          其中:

          minute:一小時中的哪一分鐘(0~59)

          hour:一天中的哪個小時(0~23)

          day-of-month:一月中的哪一天(1~31)

          month-of-year:一年中的哪一月(1~12)

          day-of-week:一周中的哪一天(0~6)

          username:以指定的用戶身份執行commands

          commands:執行的命令(可以是多行命令或者是腳本調用)

          五個時間字段的語法說明

          不能為空,可以使用統配符*表示任何時間。

          可以指定多個值,它們之間用逗號間隔。例如:1,3,7。

          可以指定時間段,用減號間隔。例如:0-6。

          可以用/n表示步長。例如:8-18/2表示時間序列8,10,12,14,16,18



          二、示例
          ● 0 */2 * * * /sbin/service httpd restart  意思是每兩個小時重啟一次apache
          ● 50 7 * * * /sbin/service sshd start  意思是每天7:50開啟ssh服務
          ● 50 22 * * * /sbin/service sshd stop  意思是每天22:50關閉ssh服務
          ● 0 0 1,15 * * fsck /home  每月1號和15號檢查/home 磁盤
          ● 1 * * * * /home/bruce/backup  每小時的第一分執行 /home/bruce/backup這個文件
          ● 00 03 * * 1-5 find /home "*.xxx" -mtime +4 -exec rm {} \;  每周一至周五3點鐘,在目錄/home中,查找文件名為*.xxx的文件,并刪除4天前的文件。
          ● 30 6 */10 * * ls  意思是每月的1、11、21、31日(每隔10天)是的6:30執行一次ls命令
          posted @ 2007-11-02 17:43 一凡 閱讀(1049) | 評論 (0)編輯 收藏
               makefile文件里的命令行部分一定要以一個TAB開頭,否則會報錯“makefile:2: *** 遺漏分隔符”如下:
          OBJS = main.o add.o
          CC 
          = gcc
          CFLAGS 
          = -Wall --g

          test : $(OBJS)
                  $(CC) $(OBJS) 
          -o test

          main.o : main.c add.h
                  $(CC) $(CFLAGS) 
          -c main.c -o main.o

          add.o : add.c add.h
                  $(CC) $(CFLAGS) 
          -c add.c -o add.o

          clear:
                  rm 
          -*.o


          posted @ 2007-10-22 13:34 一凡 閱讀(391) | 評論 (0)編輯 收藏
          此JOB每小時執行一次:
          begin
            sys.dbms_job.submit(job => :job,
                                what => 'Cancel_36_37;',
                                next_date => to_date('22-10-2007 11:00:00', 'dd-mm-yyyy hh24:mi:ss'),
                                interval => 'trunc(sysdate +1/24,''hh'')');
            commit;
          end;
          /
          posted @ 2007-10-22 10:35 一凡 閱讀(2204) | 評論 (0)編輯 收藏
          http://www.aka.org.cn/Lectures/002/Lecture-2.1.8/Lecture-2.1.8/index.htm
          posted @ 2007-10-19 11:14 一凡 閱讀(376) | 評論 (0)編輯 收藏

          中國移動、中國聯通推行的GPRS網絡、CDMA網絡已覆蓋大量的區域,通過無線網絡實現數據傳輸成為可能。無線Modem采用GPRS、CDMA 模塊通過中國移動、中國聯通的GPRS、CDMA網絡進行數據傳輸,并通TCP/IP協議進行數據封包,可靈活地實現多種設備接入,工程安裝簡單,在工業 現場數據傳輸的應用中,能很好的解決偏遠無網絡無電話線路地區的數據傳輸的難題。同傳統的數傳電臺想比較,更具有簡便性、靈活性、易操作性,同時還降低了 成本,無線Modem傳輸方案是現代化工業現場數據傳輸最好的選擇方案。
               目前中國移動、中國聯通提供的GPRS網絡、CDMA網絡的數據傳輸帶寬在40Kbps左右,且受帶寬的限制,數據采集方案最好采用于主動告警、數據輪巡 采集、告警主動回叫等對傳輸帶寬占用較少的采集方式。同時考慮對前置機實時采集方案的支持,無線Modem傳輸方案只能作為目前傳輸方案的補充。
              隨著無線通訊技術的不斷發展,無線傳輸數據帶寬將不斷提高,采用3G無線網絡,數據傳輸帶寬將達到2M,無線傳輸方案將逐漸成為監控傳輸組網的主要應用方案。
               目前,由于GPRS和CDMA固有的特性,在各個領域中GPRS和CDMA的應用也越來越廣泛,但是關于傳輸中使用TCP/IP協議還是UDP協議,卻爭論很多。

          這里先簡單的說一下TCP與UDP的區別:
            1。基于連接與無連接
            2。對系統資源的要求(TCP較多,UDP少)
            3。UDP程序結構較簡單
            4。流模式與數據報模式
            5。TCP保證數據正確性,UDP可能丟包,TCP保證數據順序,UDP不保證

          另外結合GPRS網絡的情況具體的談一下他們的區別:
           1。TCP傳輸存在一定的延時,大概是1600MS(移動提供),UDP響應速度稍微快一些。
           2。TCP包頭結構
          源端口16位
          目標端口 16位
          序列號 32位
          回應序號 32位
          TCP頭長度 4位
          reserved 6位
          控制代碼6位
          窗口大小16位
          偏移量16位
          校驗和16位
          選項 32位(可選)
          這樣我們得出了TCP包頭的最小大小.就是20字節.

            UDP包頭結構
          源端口16位
          目的端口16位
          長度 16位
          校驗和 16位
          UDP的包小很多.確實如此.因為UDP是非可靠連接.設計初衷就是盡可能快的將數據包發送出去.所以UDP協

          議顯得非常精簡.

           3。GPRS網絡端口資源,UDP十分緊缺,變化很快;而TCP采用可靠鏈路傳輸,不存在端口變化的問題工業場合的應用一般都有以下特點,

           1。要求時時傳輸,但也有一些場合是定時傳輸,總的來說在整個傳輸過程中要求服務器中心端和GPRS終端設備能相互的、時時的傳輸數據。
          TCP 本身就是可靠鏈路傳輸,提供一個時時的雙向的傳輸通道,能很好的滿足工業現場傳輸的要求。但是GPRS網絡對TCP鏈路也存在一個限制:此條鏈路在長時間 (大概20分鐘左右,視具體情況而定)沒有數據流量,會自動降低此鏈路的優先級直至強制斷開此鏈路。所以在實際使用中也會采用心跳包(一般是一個字節的數 據)來維持此鏈路。
          UDP由于自身特點,以及GPRS網絡UDP端口資源的有限性,在一段時間沒有數據流量后,端口容易改變,產生的影響就是從服 務器中心端向GPRS終端發送數據,GPRS終端接收不到。具體的原因就是移動網關從中作了中轉,需要隔一定時間給主機發UDP包來維持這個IP和端口 號,這樣主機就能主動給GPRS發UDP包了并且我在測試中發現,這個間隔時間很短,我在1多分鐘發一次UDP包才能夠維持,但是再長可能移動網關那邊就 要丟失這個端口了,此時如果主機想主動發數據給GPRS,那肯定是不行的了,只有GPRS終端設備再發一個UDP包過去,移動重新給你分配一個中轉IP和 端口,才能夠進行雙向通訊。

           2。要求數據的丟包率較小。有些工業場合,例如電力、水務抄表,環保監測等等,不容許傳輸過程中的數據丟失或者最大限度的要求數據的可靠性。從這 一點來看,很顯然在無線數據傳輸過程中,TCP比UDP更能保證數據的完整性、可靠性,存在更小的丟包率。在實際測試中也是如此。以廈門桑榮科技有限公司 提供的GPRS終端設備為例:TCP的在千分之9,UDP的在千分之17左右。

          3。要求降低費用。目前有很大部分GPRS設備的應用都是取代前期無線數傳電臺,除了使用范圍外,其考慮的主要問題就是費用。能降低費用當然都是大 家最愿意接受的。和費用直接相關的就是流量了,流量低,費用就低了。雖然TCP本身的包頭要比UDP多,但是UDP在實際應用中往往需要維護雙向通道,就 必須要通過大量的心跳包數據來維護端口資源。總的比較起來,UDP的實際流量要比TCP還要大。很多使用者在初期的時候并不了解UDP需要大量心跳包來維 持端口資源這個問題,往往都認為UDP要比TCP更節省流量,實際上這里存在著一個誤區。

          4。在某些特定的應用場合,例如一些銀行的時時交互系統,對響應速度要求很高,此時數據傳輸頻率較快,不需要大量心跳包維持UDP端口資源,采用UDP就比較有利了。

          5。在目前的1:N的傳輸模式中,既有多個GPRS終端設備往一個服務器中心傳輸數據,此時采用UDP會比TCP要好的多,因為UDP耗用更少的系 統資源。但是在實際應用中卻發現,很多用戶還是采用TCP的傳輸方式,建立二級中心1:A(1:N),即每一個分中心對應N/A臺設備,獨立處理數據,再 統一將數據傳送到主中心。這樣既能保證了傳輸過程中采用了TCP的傳輸協議,又能很好處理了中心服務器的多鏈路的系統耗用的問題。
             
               總的來說,我認為TCP/IP協議更能滿足目前各行業對遠程數據傳輸的要求,它提供更穩定更便利的傳輸通道,很好的滿足了遠程數據傳輸的要求。
          posted @ 2007-10-19 11:02 一凡 閱讀(517) | 評論 (0)編輯 收藏

          Siege(英文意思是圍攻)是一個壓力測試和評測工具,設計用于WEB開發這評估應用在壓力下的承受能力:可以根據配置對一個WEB站點進行多用戶的并發訪問,記錄每個用戶所有請求過程的相應時間,并在一定數量的并發訪問下重復進行。


          最早使用的壓力測試工具是apache的ab(apache benchmark),apache ab做重復壓力測試不錯,但是每次只能測試一個鏈接,如何測試一組鏈接(比如從日志中導出的1個小時的日志,做真實壓力測試),后來找到了這個:
          Siege是一個壓力測試和評測工具,設計用于WEB開發這評估應用在壓力下的承受能力:可以根據配置對一個WEB站點進行多用戶的并發訪問,記錄每個用戶所有請求過程的相應時間,并在一定數量的并發訪問下重復進行。
          SIEGE is an http regressive testing and benchmarking utility. It was designed to let web developers measure the performance of their code under duress, to see how it will stand up to load on the internet. It lets the user hit a webserver with a configurable number of concurrent simulated users. Those users place the webserver "under siege." The duration of the siege is measured in transactions, the sum of simulated users and the number of times each simulated user repeats the process of hitting the server. Thus 20 concurrent users 50 times is 1000 transactions, the length of the test.

          下載/安裝
          Siege時一個開放源代碼項目:http://www.joedog.org

          下載:
          wget ftp://sid.joedog.org/pub/siege/siege-latest.tar.gz

          安裝:
          %./configure ; make
          #make install

          siege包含了一組壓力測試工具:
          SIEGE (1) Siege是一個HTTP壓力測試和評測工具.
          使用樣例:
          任務列表:www.chedong.com.url文件
          http://www.chedong.com/tech/
          http://www.chedong.com/tech/acdsee.html
          http://www.chedong.com/tech/ant.html
          http://www.chedong.com/tech/apache_install.html
          http://www.chedong.com/tech/awstats.html
          http://www.chedong.com/tech/cache.html
          http://www.chedong.com/tech/click.html
          http://www.chedong.com/tech/cms.html
          http://www.chedong.com/tech/compress.html
          http://www.chedong.com/tech/cvs_card.html
          http://www.chedong.com/tech/default.html
          http://www.chedong.com/tech/dev.html
          http://www.chedong.com/tech/gnu.html
          ....

          siege -c 20 -r 2 -f www.chedong.com.url
          參數說明:
          -c 20 并發20個用戶
          -r 2 重復循環2次
          -f www.chedong.com.url 任務列表:URL列表

          輸出樣例:

          ** Siege 2.59
          ** Preparing 20 concurrent users for battle. 這次“戰斗”準備了20個并發用戶
          The server is now under siege.. done. 服務在“圍攻”測試中:
          Transactions: 40 hits 完成40次處理
          Availability: 100.00 % 成功率
          Elapsed time: 7.67 secs 總共用時
          Data transferred: 877340 bytes 共數據傳輸:877340字節
          Response time: 1.65 secs 相應用時1.65秒:顯示網絡連接的速度
          Transaction rate: 5.22 trans/sec 平均每秒完成5.22次處理:表示服務器后臺處理的速度
          Throughput: 114385.92 bytes/sec 平均每秒傳送數據:114385.92字節
          Concurrency: 8.59 最高并發數 8.59
          Successful transactions: 40 成功處理次數
          Failed transactions: 0 失敗處理次數

          注意:由于速度很快,可能會達不到并發速度很高就已經完成。Response time顯示的是測試機器和被測試服務器之間網絡鏈接狀況。Transaction rate則表示服務器端任務處理的完成速度。

          輔助工具:
          增量壓力測試:


          為了方便增量壓力測試,siege還包含了一些輔助工具:
          bombardment (1)
          是一個輔助工具:用于按照增量用戶壓力測試:
          使用樣例:
          bombardment urlfile.txt 5 3 4 1
          初始化URL列表:urlfile.txt
          初始化為:5個用戶
          每次增加:3個用戶
          運行:4次
          每個客戶端之間的延遲為:1秒

          輸出成CSV格式:
          siege2csv.pl (1)
          siege2csv.pl將bombardment的輸出變成CSV格式:
          Time Data Transferred Response Time Transaction Rate Throughput Concurrency Code 200 (note that this is horribly broken.)
          242 60.22 603064 0.02 4.02 10014.35 0.08
          605 59.98 1507660 0.01 10.09 25136.05 0.12
          938 59.98 2337496 0.02 15.64 38971.26 0.26
          1157 60 2883244 0.04 19.28 48054.07 0.78

          參考:
          開源測試工具:http://www.opensourcetesting.org/performance.php

          壓力測試工具:HammerHead 正在試用中

          posted @ 2007-09-20 17:56 一凡 閱讀(364) | 評論 (0)編輯 收藏
          僅列出標題
          共21頁: First 上一頁 11 12 13 14 15 16 17 18 19 下一頁 Last 
          主站蜘蛛池模板: 梧州市| 桃源县| 武清区| 邓州市| 集安市| 岗巴县| 绥中县| 开远市| 田东县| 高淳县| 岑溪市| 德格县| 白玉县| 台江县| 宣恩县| 永城市| 星子县| 清丰县| 图们市| 博兴县| 满洲里市| 崇义县| 永嘉县| 南木林县| 佛冈县| 监利县| 宜兴市| 独山县| 舟山市| 罗江县| 隆尧县| 新田县| 托克逊县| 东台市| 东阿县| 翁源县| 吴堡县| 五峰| 深州市| 满洲里市| 新乡市|