<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    2009年12月3日

    例子下載在此

    最近搞了個(gè)小實(shí)驗(yàn),發(fā)現(xiàn)Eclipse 插件的類(lèi)加載的一個(gè)問(wèn)題。Eclipse使用Equinox實(shí)現(xiàn)OSGi的框架,可以在插件的配置中確定哪些類(lèi)expose出去,哪些類(lèi)不能為外部所見(jiàn)。我發(fā)現(xiàn)的問(wèn)題是,可以通過(guò)ClassLoader繞過(guò)這個(gè)限制,在外部插件中加載到插件里那些不為外部所見(jiàn)的類(lèi),并且能夠創(chuàng)建類(lèi)的實(shí)例,可以通過(guò)反射調(diào)用其方法(當(dāng)然,如果被加載的類(lèi)實(shí)現(xiàn)了某些接口,也可以通過(guò)接口的引用直接調(diào)用相應(yīng)的方法)。

    為了演示這個(gè)問(wèn)題,先在eclipse中創(chuàng)建一個(gè)插件UtilityLibrary

    其中utilitylibrary.expose包中的類(lèi)會(huì)暴露給外部,而utilitylibrary.hide包中的類(lèi)不會(huì)暴露給外部。在MANIFEST.MF中增加這個(gè)設(shè)置:


    VisiableClassVisiableClass類(lèi)的內(nèi)容很簡(jiǎn)單:
    package utilitylibrary.expose;

    public class VisiableClass {
        
    public VisiableClass() {
            System.out.println(
    "This is VisiableClass");
        }

        
    public String getMessage() {
            
    return "From VisiableClass:\r\n"
                    
    + this.getClass().getClassLoader().toString() + "\t";
        }
    }

    package utilitylibrary.hide;

    public class InvisiableClass {
        
    public InvisiableClass() {
            System.out.println(
    "InvisiableClass");
        }

        
    public String getMessage() {
            
    return "From InvisiableClass:\r\n"
                    
    + this.getClass().getClassLoader().toString() + "\t";
        }
    }


    其實(shí)主要就是打印出相應(yīng)的信息。類(lèi)代碼幾乎是一樣的。

    下面創(chuàng)建另一個(gè)插件UsePlugin,依賴(lài)并使用UtilityLibrary中的類(lèi)。插件其實(shí)就是Eclipse自帶的Hello World程序,它會(huì)在eclipse 的toolbar上增加一個(gè)按鈕,點(diǎn)擊后會(huì)彈出一個(gè)MessageBox。好,MessageBox上顯示的就是從UtilityLibrary中類(lèi)的方法的返回值。首先增加插件依賴(lài)關(guān)系:


    在SampleAction中的Run方法里,如果直接使用InvisiableClass,插件完全找不到這個(gè)類(lèi),修改建議里面建議expose這個(gè)類(lèi):


    當(dāng)然,使用VisiableClass是沒(méi)問(wèn)題的。下面通過(guò)VisiableClass來(lái)將InvisiableClass拽出來(lái),SampleAction類(lèi)的源代碼如下,只要關(guān)心run方法就可以了:

    package useplugin.actions;

    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;

    import org.eclipse.jface.action.IAction;
    import org.eclipse.jface.dialogs.MessageDialog;
    import org.eclipse.jface.viewers.ISelection;
    import org.eclipse.ui.IWorkbenchWindow;
    import org.eclipse.ui.IWorkbenchWindowActionDelegate;

    import utilitylibrary.expose.VisiableClass;

    /**
     * Our sample action implements workbench action delegate. The action proxy will
     * be created by the workbench and shown in the UI. When the user tries to use
     * the action, this delegate will be created and execution will be delegated to
     * it.
     * 
     * 
    @see IWorkbenchWindowActionDelegate
     
    */
    public class SampleAction implements IWorkbenchWindowActionDelegate {
        
    private IWorkbenchWindow window;

        
    /**
         * The constructor.
         
    */
        
    public SampleAction() {
        }

        
    /**
         * The action has been activated. The argument of the method represents the
         * 'real' action sitting in the workbench UI.
         * 
         * 
    @see IWorkbenchWindowActionDelegate#run
         
    */
        
    public void run(IAction action) {
            
    try {
                Class
    <?> clazz = VisiableClass.class.getClassLoader().loadClass(
                        
    "utilitylibrary.hide.InvisiableClass");
                Object obj 
    = clazz.newInstance();
                Method method 
    = clazz.getMethod("getMessage");
                Object ret 
    = method.invoke(obj, new Object[] {});
                System.out.println(ret);
                MessageDialog.openInformation(window.getShell(), 
    "UsePlugin", ret
                        .toString());
            } 
    catch (ClassNotFoundException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            } 
    catch (InstantiationException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            } 
    catch (IllegalAccessException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            } 
    catch (SecurityException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            } 
    catch (NoSuchMethodException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            } 
    catch (IllegalArgumentException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            } 
    catch (InvocationTargetException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

        
    /**
         * Selection in the workbench has been changed. We can change the state of
         * the 'real' action here if we want, but this can only happen after the
         * delegate has been created.
         * 
         * 
    @see IWorkbenchWindowActionDelegate#selectionChanged
         
    */
        
    public void selectionChanged(IAction action, ISelection selection) {
        }

        
    /**
         * We can use this method to dispose of any system resources we previously
         * allocated.
         * 
         * 
    @see IWorkbenchWindowActionDelegate#dispose
         
    */
        
    public void dispose() {
        }

        
    /**
         * We will cache window object in order to be able to provide parent shell
         * for the message dialog.
         * 
         * 
    @see IWorkbenchWindowActionDelegate#init
         
    */
        
    public void init(IWorkbenchWindow window) {
            
    this.window = window;
        }
    }


    在run方法里面,直接使用VisiableClass.class.getClassLoader().loadClass("utilitylibrary.hide.InvisiableClass");來(lái)加載本不應(yīng)該被外部所見(jiàn)的Invisiable類(lèi)。因?yàn)樵贓clipse中,每個(gè)插件使用一個(gè)ClassLoader,所以用來(lái)加載VisiableClass類(lèi)的ClassLoader也同樣負(fù)責(zé)加載在同一個(gè)插件中的InvisiableClass類(lèi)。這樣InvisiableClass就在插件外部被加載成功了。類(lèi)加載成功后,剩下的事情就是順?biāo)浦哿耍瑒?chuàng)建個(gè)實(shí)例然后使用反射調(diào)用相應(yīng)的方法。
    程序運(yùn)行的時(shí)候,點(diǎn)擊toolbar上那個(gè)button,會(huì)彈出如下對(duì)話(huà)框:


    程序運(yùn)行也沒(méi)啥錯(cuò)誤。


    問(wèn)題分析:
    其實(shí)我覺(jué)得這個(gè)問(wèn)題是很難繞過(guò)去的。對(duì)于同一個(gè)插件,因?yàn)閮?nèi)部的類(lèi)需要互相引用和互相使用,所以必須使用同一個(gè)類(lèi)加載器來(lái)加載。所以,這個(gè)插件只要expose出來(lái)一個(gè)包,那么外部的插件就可以通過(guò)包中的任何一個(gè)類(lèi)來(lái)得到加載這個(gè)插件中的類(lèi)的類(lèi)加載器,然后就可以通過(guò)reflect愛(ài)做啥做啥了。

    換一個(gè)角度可能更好理解這個(gè)問(wèn)題為什么難以繞過(guò)去。假設(shè)VisiableClass需要用到InvisiableClass,雖然InvisiableClass沒(méi)有暴露出來(lái),但是在正常的使用VisiableClass的時(shí)候,需要先加載VisiableClass類(lèi),而加載VisiableClass的時(shí)候JVM就會(huì)隱式的加載InvisiableClass。這個(gè)過(guò)程和例子里現(xiàn)式的加載InvisiableClass沒(méi)啥本質(zhì)不同。也就是說(shuō),從ClassLoader的角度,很難判斷一個(gè)類(lèi)的加載是正常的代碼還是為了突破bundle的訪(fǎng)問(wèn)限制——它們都是在執(zhí)行run方法時(shí)發(fā)生的類(lèi)加載行為。

    或者是我有什么地方?jīng)]設(shè)置好?求解答。例子下載在此

    posted @ 2010-05-17 12:09 深夜兩點(diǎn) 閱讀(4806) | 評(píng)論 (8)編輯 收藏

    宅能量終于爆發(fā)了,書(shū)終于出版了。China Pub有售http://www.china-pub.com/196571

    posted @ 2010-04-27 20:47 深夜兩點(diǎn) 閱讀(1668) | 評(píng)論 (1)編輯 收藏

    在設(shè)計(jì)一個(gè)多線(xiàn)程程序的時(shí)候,首先要考慮好線(xiàn)程模型是怎樣的。設(shè)計(jì)線(xiàn)程模型的時(shí)候可以有多個(gè)考慮,比如使用線(xiàn)程池,使用多個(gè)線(xiàn)程處理任務(wù),或者使用類(lèi)似AWT/Swing中事件處理機(jī)制那樣,使用單個(gè)線(xiàn)程處理同一類(lèi)的任務(wù)。

    posted @ 2010-04-26 16:33 深夜兩點(diǎn) 閱讀(244) | 評(píng)論 (0)編輯 收藏

    rt

    posted @ 2010-04-11 11:21 深夜兩點(diǎn) 閱讀(238) | 評(píng)論 (0)編輯 收藏

    自己寫(xiě)的一個(gè)小程序,做個(gè)視頻冒充一下技術(shù)宅……


    程序經(jīng)多次優(yōu)化,終于能夠達(dá)到一個(gè)可以接受的性能了……莫言Java無(wú)效率,其實(shí)重要的還是要精雕細(xì)琢。至 少就繪制Julia Set而言,我這個(gè)程序比我見(jiàn)過(guò)的幾個(gè)cpp版本的要快的多。
    項(xiàng)目主頁(yè)地址:http://code.google.com/p/juliasetcreator/
    程序下載地址:http://code.google.com/p/juliasetcreator/downloads/list

    posted @ 2010-03-20 17:25 深夜兩點(diǎn) 閱讀(2625) | 評(píng)論 (2)編輯 收藏

    轉(zhuǎn)自http://static.icybear.net/%5BCN%5DProgrammer%20competency%20matrix.htm

    [譯文]程序員能力矩陣 Programmer Competency Matrix

    注意:每個(gè)層次的知識(shí)都是漸增的,位于層次n,也蘊(yùn)涵了你需了解所有低于層次n的 知識(shí)。
    計(jì)算機(jī)科學(xué) Computer Science
      2n (Level 0) n2 (Level 1) n (Level 2) log(n) (Level 3) Comments
    數(shù)據(jù)結(jié)構(gòu) 不知道數(shù)組和鏈表的差異 能夠解釋和使用數(shù)組, 鏈表,字典等,并且能夠用于實(shí)際的編程任務(wù)。 了解基本數(shù)據(jù)結(jié)構(gòu)時(shí)間和空間的折中,比如數(shù)組vs 鏈表,能夠解釋如何實(shí)現(xiàn)哈希表和處理沖突,了解優(yōu)先隊(duì)列及其實(shí)現(xiàn)。 高等的數(shù)據(jù)結(jié)構(gòu)的知識(shí),比如B-樹(shù)、二項(xiàng)堆、斐波那契堆、AVL 樹(shù)、紅黑樹(shù)、伸展樹(shù)、跳躍表以及前綴樹(shù)等。
    算法 不能夠找出一個(gè)數(shù)組各數(shù)的平均值(這令人難以置信,但是我的確在應(yīng)聘者 中遇到過(guò)) 基本的排序,搜索和數(shù)據(jù)的遍歷和檢索算法。 樹(shù),圖,簡(jiǎn)單的貪婪算法和分而治之算法,能夠適度了解矩陣該 層的含義。 能夠辨識(shí)和編寫(xiě)動(dòng)態(tài)規(guī)劃方案,良好的圖算法知識(shí),良好的數(shù)值估算的知識(shí),能夠辨別NP問(wèn)題等。 Working with someone who has a good topcoder ranking would be an unbelievable piece of luck!
    編程體系 不知道何為編譯器、鏈接器和解釋器。 對(duì)編譯 器、鏈接器、解釋器有基本的了解。知道什么是匯編代碼以及在硬件層如何工作。有一些虛擬內(nèi)存和分頁(yè)知識(shí)。 了解內(nèi)核模式vs用戶(hù)模式, 多線(xiàn)程,同步原語(yǔ)以及它們?nèi)绾螌?shí)現(xiàn),能夠閱讀匯編代碼。了解網(wǎng)絡(luò)如何工作,了解網(wǎng)絡(luò)協(xié)議和socket級(jí)別編程。 了解整個(gè)程序堆棧、 硬件(CPU+內(nèi)存+中斷+微碼)、二進(jìn)制代碼、匯編、靜態(tài)和動(dòng)態(tài)鏈接、編碼、解釋、JIT(just-in-time)編譯、內(nèi)存碎片回收、堆、棧、存 儲(chǔ)器編址…
    軟件工程 Software Engineering
      2n (Level 0) n2 (Level 1) n (Level 2) log(n) (Level 3) Comments
    源碼版本控制 通過(guò)日期備份文件夾 VSS和初級(jí)的 CVS/SVN用戶(hù) 熟練地使用CVS和SVN特性。知道如何分支和歸并,使用程序庫(kù)補(bǔ)丁安裝特性等 有分布式VCS 系統(tǒng)的知識(shí)。嘗試過(guò)Bzr/Mercurial/Darcs/Git
    自動(dòng)化編譯 只知道在IDE下編譯 知道如何編譯在命令行 下編譯系統(tǒng) 能夠安裝一個(gè)腳本構(gòu)建基本的系統(tǒng) 能夠安裝一個(gè)腳本來(lái)構(gòu)建系統(tǒng)并且歸檔,安裝程序,生成發(fā)布記錄和給源 碼控制中的代碼分配標(biāo)簽。
    自動(dòng)化測(cè)試 認(rèn)為所有的測(cè)試都是測(cè)試員的工作。 能夠編寫(xiě) 自動(dòng)化的單元測(cè)試,能夠?yàn)檎诰帉?xiě)的代碼提出良好的測(cè)試用例。 按照TDD (Test Driven Development)方式編寫(xiě)代碼。 了解并且能夠有效自動(dòng)化安裝,載入/性能和UI測(cè)試
    程序設(shè)計(jì) Programming
      2n (Level 0) n2 (Level 1) n (Level 2) log(n) (Level 3) Comments
    問(wèn)題分解 只有直線(xiàn)式的代碼,通過(guò)復(fù)制粘貼來(lái)復(fù)用 能夠把 問(wèn)題分散到多個(gè)函數(shù)中 能夠想出可復(fù)用的函數(shù)/對(duì)象來(lái)解決大題的問(wèn)題 使用適宜的數(shù)據(jù)結(jié)構(gòu)和算法,寫(xiě)出通用的/面向 對(duì)象的代碼來(lái)封裝問(wèn)題的易改變的層面。
    系統(tǒng)分解 N想不出比單一的文件/類(lèi)更好的層面 如果不在 同一平臺(tái)或沒(méi)采用相同的技術(shù),能夠把問(wèn)題空間和設(shè)計(jì)方案分解。 能夠設(shè)計(jì)跨技術(shù)/平臺(tái)的系統(tǒng)。 能夠在多個(gè)產(chǎn)品線(xiàn)和 與外部體系一體化中虛擬化和設(shè)計(jì)復(fù)制的系統(tǒng)。同時(shí)也能夠設(shè)計(jì)支持系統(tǒng)監(jiān)視、報(bào)告、故障恢復(fù)等。
    交流 不能向同伴表達(dá)想法/主意。匱乏拼寫(xiě)和語(yǔ)法的能力。 同 伴能了解你在說(shuō)什么。有良好的拼寫(xiě)和語(yǔ)法能力。 能夠和同伴進(jìn)行高效的交流 能夠使用清晰的方式了解和交流想法/設(shè)計(jì) /主意/細(xì)則,能適應(yīng)每種環(huán)境的交流 This is an often under rated but very critical criteria for judging a programmer. With the increase in outsourcing of programming tasks to places where English is not the native tongue this issue has become more prominent. I know of several projects that failed because the programmers could not understand what the intent of the communication was.
    同一文件中代碼組織 同一文件中組織沒(méi)有依據(jù) 按照邏輯 性或者易接近的方法 代碼分塊和對(duì)于其他源文件來(lái)說(shuō)是易于是釋,引用其他源文件時(shí)有良好的注釋 文檔頭部有許可聲 明,總結(jié),良好的注釋?zhuān)恢碌目崭窨s進(jìn)。文檔外觀美觀。
      2n (Level 0) n2 (Level 1) n (Level 2) log(n) (Level 3) Comments
    跨文件代碼組織 沒(méi)夠想過(guò)給代碼跨文件組織 相關(guān)文件按文件 夾分組 每個(gè)物理文件都有獨(dú)立的目的,比如一個(gè)類(lèi)的定義,一個(gè)特性的實(shí)現(xiàn)等。 代碼在物理層組織緊密,在文件名上與 設(shè)計(jì)和外觀相匹配,可以通過(guò)文件分布方式洞察設(shè)計(jì)理念。
    源碼樹(shù)組織 一切都放在一個(gè)文件夾內(nèi) 初步地將代碼分散進(jìn) 對(duì)應(yīng)邏輯的文件夾。 沒(méi)有循環(huán)依賴(lài),二進(jìn)制文件,庫(kù),文檔,構(gòu)建,第三方的代碼都組織進(jìn)合適的文件夾內(nèi)。 源碼樹(shù)的 物理布局與邏輯層次、組織方式相匹配。可以通過(guò)目錄名稱(chēng)和組織方式洞察設(shè)計(jì)理念。 The difference between this and the previous item is in the scale of organization, source tree organization relates to the entire set of artifacts that define the system.
    代碼可讀性 單音節(jié)的名稱(chēng) (在國(guó)內(nèi)應(yīng)該是那些類(lèi)似用漢語(yǔ)拼音命名的習(xí)慣) 對(duì)文件、變量、類(lèi)、方法等,有良好的命名。 沒(méi)有長(zhǎng)函數(shù)、注釋解釋不常規(guī)的代碼,bug修復(fù),代碼假設(shè)。 代 碼假設(shè)驗(yàn)證使用斷言,自然的代碼流,沒(méi)有深層嵌套的條件和方法
    防御性編碼 不知道這個(gè)概念 檢查代碼中所有的參數(shù),對(duì)關(guān)鍵 的假設(shè)進(jìn)行斷言 確保檢查了返回值和使代碼失敗的異常。 有自己的庫(kù)來(lái)幫助防御性編程、編寫(xiě)單元測(cè)試模擬故障
      2n (Level 0) n2 (Level 1) n (Level 2) log(n) (Level 3) Comments
    錯(cuò)誤處理 只給樂(lè)觀的情形編碼 基本的代碼錯(cuò)誤處理,拋出 異常/生成錯(cuò)誤 確保錯(cuò)誤/異常留在程序中有良好的狀態(tài),資源,連接,內(nèi)存都有被合適的清理。 在編碼之前察覺(jué)可能 出現(xiàn)的異常,在代碼的所有層次中維持一致性的異常處理策略,提出整個(gè)系統(tǒng)的錯(cuò)誤處理準(zhǔn)則。
    IDE IDE大部分用來(lái)進(jìn)行文本編輯 了解其周?chē)慕? 口,能夠高效地通過(guò)菜單來(lái)使用IDE 了解最常操作的鍵盤(pán)快捷鍵 編寫(xiě)自定義宏
    API 需要頻繁地查閱文檔 把最頻繁使用的API記在腦 子里 廣闊且深入的API知識(shí)。 為了使實(shí)際任務(wù)中常用API使用更加便捷,編寫(xiě)過(guò)API的上層庫(kù),填補(bǔ)API之間 的缺口。 E.g. of API can be Java library, .net framework or the custom API for the application
    框架 沒(méi)有使用過(guò)主平臺(tái)外的任何框架 聽(tīng)過(guò)但沒(méi)用過(guò)平臺(tái)下 流行的可用框架 在專(zhuān)業(yè)的職位中使用過(guò)一個(gè)以上的框架,通曉各框架的特色。 某框架的作者
      2n (Level 0) n2 (Level 1) n (Level 2) log(n) (Level 3) Comments
    需求分析 接受給定的需求和代碼規(guī)格 能對(duì)規(guī)格的遺漏提出 疑問(wèn) 了解全面情況,提出需要被規(guī)格化的整體范圍。 能夠提出更好的可選方案,根據(jù)經(jīng)驗(yàn)的浮現(xiàn)給出需求
    腳本 不具備腳本工具的知識(shí) 批處理文件/shell腳本 Perl/Python/Ruby/VBScript/Powershell 寫(xiě)過(guò)并且發(fā)表過(guò)可重用的代碼
    數(shù)據(jù)庫(kù) 認(rèn)為Excel就是數(shù)據(jù)庫(kù) 知道基本的數(shù)據(jù)庫(kù)概 念,規(guī)范化、ACID(原子性Atomicity、一致性Consistency、隔離性Isolation、持久性Durability)、事務(wù)化,能 夠?qū)懞?jiǎn)單的select語(yǔ)句 能夠牢記在運(yùn)行時(shí)必要查詢(xún)中設(shè)計(jì)良好的規(guī)范化數(shù)據(jù)庫(kù)模式, 精通用戶(hù)視圖,存儲(chǔ)過(guò)程,觸發(fā)器和用戶(hù)定義類(lèi)型。知道聚集與非聚集索引之間的差異。精通使用ORM(Object Relational Mapping對(duì)象關(guān)系映射)工具 能做基本的數(shù)據(jù)庫(kù)管理,性能優(yōu)化,索引優(yōu)化,編寫(xiě)高級(jí)的select查詢(xún),能夠使用相關(guān)sql來(lái)替 換游標(biāo),理解數(shù)據(jù)內(nèi)部的存儲(chǔ),了解如何鏡像、復(fù)制數(shù)據(jù)庫(kù)。知道兩段數(shù)據(jù)提交如何工作
    經(jīng)驗(yàn) Experience
      2n (Level 0) n2 (Level 1) n (Level 2) log(n) (Level 3) Comments
    專(zhuān)業(yè)語(yǔ)言經(jīng)驗(yàn) 命令式語(yǔ)言和面向?qū)ο笳Z(yǔ)言 命令式語(yǔ)言,面向?qū)ο笳Z(yǔ)言和說(shuō)明型語(yǔ)言(SQL),如果了解靜態(tài)類(lèi)型vs動(dòng)態(tài)類(lèi)型,弱類(lèi)型vs強(qiáng)類(lèi)型則有加分 函數(shù)式語(yǔ)言,如果了解延 緩求值,局部套用函數(shù),延續(xù)則有加分 并發(fā)語(yǔ)言(Erlang, Oz) 邏輯語(yǔ)言(Prolog)
    專(zhuān)業(yè)平臺(tái)經(jīng)驗(yàn) 1 2-3 4-5 6+
    專(zhuān)業(yè)經(jīng)驗(yàn)?zāi)挲g 1 2-5 6-9 10+
    領(lǐng)域知識(shí) 沒(méi)有該領(lǐng)域的知識(shí) 在該領(lǐng)域中曾經(jīng)至少為一個(gè) 產(chǎn)品工作過(guò) 在同一領(lǐng)域中為多個(gè)產(chǎn)品工作過(guò) 領(lǐng)域?qū)<摇T谠擃I(lǐng)域設(shè)計(jì)和實(shí)現(xiàn)數(shù)種產(chǎn)品/方案。精通該領(lǐng)域使用的標(biāo)準(zhǔn)條款 和協(xié)議
    學(xué)識(shí) Knowledge
      2n (Level 0) n2 (Level 1) n (Level 2) log(n) (Level 3) Comments
    工具知識(shí) 僅限于主要的IDE(VS.Net, Eclipse等) 知 道一些流行和標(biāo)準(zhǔn)工具的備選方案 對(duì)編輯器、調(diào)試器、IDE、開(kāi)源的備選方案有很好的了解。比如某人了解大多數(shù)Scott Hanselman的威力工具列表中的工具,使用過(guò)ORM工具。 實(shí)際地編寫(xiě)過(guò)工具和腳本,如果這些被發(fā)布則有加分
    語(yǔ)言接觸 命令式語(yǔ)言和面向?qū)ο笳Z(yǔ)言 命令式語(yǔ)言、面向?qū)ο? 語(yǔ)言和說(shuō)明型語(yǔ)言(SQL),如果了解靜態(tài)類(lèi)型vs動(dòng)態(tài)類(lèi)型、弱類(lèi)型vs強(qiáng)類(lèi)型則有加分 函數(shù)式語(yǔ)言,如果了解延緩求值、局部套用函 數(shù)、continuations (源于scheme中的一種高級(jí)控制結(jié)構(gòu))則有加分 并發(fā)語(yǔ)言(Erlang, Oz) 邏輯語(yǔ)言(Prolog)
    代碼庫(kù)知識(shí) 從來(lái)沒(méi)有查詢(xún)過(guò)代碼庫(kù) 基本的代碼層知識(shí),了 解如果構(gòu)建系統(tǒng) 良好的代碼庫(kù)工作知識(shí),實(shí)現(xiàn)過(guò)幾次bug修復(fù)或者完成了一些細(xì)小的特性 實(shí)現(xiàn)了代碼庫(kù)中多個(gè)大型特 性,能夠輕松地將多數(shù)特性的需求變更具體化,從容地處理bug修復(fù)。
    下一代技術(shù)知識(shí) 從來(lái)沒(méi)聽(tīng)說(shuō)過(guò)即將到來(lái)的技術(shù) 聽(tīng)說(shuō)過(guò)某領(lǐng) 域即將到來(lái)的技術(shù) 下載過(guò)alpha preview/CTP/beta版本,并且讀過(guò)一些文章和手冊(cè) 試用過(guò)預(yù)覽 版而且實(shí)際地構(gòu)建過(guò)某物,如果共享給其他人的話(huà)則有加分
      2n (Level 0) n2 (Level 1) n (Level 2) log(n) (Level 3) Comments
    平臺(tái)內(nèi)部 對(duì)平臺(tái)內(nèi)部毫無(wú)所知 有平臺(tái)基本的內(nèi)部工作的 知識(shí) 深度的平臺(tái)內(nèi)部知識(shí),能夠設(shè)想平臺(tái)如何將程序轉(zhuǎn)換成可執(zhí)行代碼。 編寫(xiě)過(guò)增強(qiáng)平臺(tái)或者為其平臺(tái)內(nèi)部提供信息的 工具。比如,反匯編工具,反編譯工具,調(diào)試工具等。
    書(shū)籍 菜鳥(niǎo)系列,21天系列,24小時(shí)系列,蠢貨系列... 《代 碼大全》,《別讓我思考》, 《精通正則表達(dá)式》 《設(shè)計(jì)模式》,《人件》,《代碼珠璣》,《算法設(shè)計(jì)手冊(cè)》,《程序員修煉之道》, 《人月神話(huà)》 《計(jì)算機(jī)程序設(shè)計(jì)與解釋》,《事務(wù)處理:概念與技術(shù)》,《計(jì)算機(jī)程序設(shè)計(jì)模型》,《計(jì)算機(jī)程序設(shè)計(jì)藝術(shù)》,《數(shù)據(jù)庫(kù)系統(tǒng) 導(dǎo)論》 C.J Date版,《Thinking Forth》 ,《Little Schemer》(沒(méi)找到其中譯本)
    博客 聽(tīng)過(guò)但是從來(lái)抽不出空去接觸 閱讀一些科技/編程 /軟件工程的博客,并且經(jīng)常的收聽(tīng)一些播客 維護(hù)一些博客的鏈接,收集博主分享的有用的文章和工具 維護(hù)一個(gè)在編程方 面,分享有個(gè)人見(jiàn)解和思考的博客
    Creative Commons License
    程序員能力矩陣 by XGuru is licensed under a Creative Commons 署名-非商業(yè)性使用-相同方式共享 2.5 中國(guó)大陸 License. 原文請(qǐng)看 這 里
    Thanks to bearice for debugging.
    Thanks to John Haugeland for a reformatting of it that works much more nicely on the web.

    posted @ 2010-03-14 23:35 深夜兩點(diǎn) 閱讀(239) | 評(píng)論 (0)編輯 收藏

    (轉(zhuǎn)自http://coolshell.cn/?p=1903

    問(wèn)答

    Q:你是怎么區(qū)分一個(gè)內(nèi)向的程序員和一個(gè)外向的程序員的?
    A:外向的程序員會(huì)看著你的鞋和你說(shuō)話(huà)時(shí)。

    Q:為什么程序員不能區(qū)分萬(wàn)圣節(jié)和圣誕節(jié)?
    A:這是因?yàn)镺ct 31 == Dec 25!(八進(jìn)制的31==十進(jìn)制的25)

    剎車(chē)失靈

    有一個(gè)物理學(xué)家,工程師和一個(gè)程序員駕駛著一輛汽車(chē)行駛在阿爾卑斯山脈上,在下山的時(shí)候,忽然,汽車(chē)的剎車(chē)失靈了,汽車(chē)無(wú)法控制地向下沖去,眼看前 面就是一個(gè)懸崖峭壁,但是很幸運(yùn)的是在這個(gè)懸崖的前面有一些小樹(shù)讓他們的汽車(chē)停了下來(lái),而沒(méi)有掉下山去。三個(gè)驚魂未定地從車(chē)?yán)锱懒顺鰜?lái)。

    物理學(xué)家說(shuō),“我覺(jué)得我們應(yīng)該建立一個(gè)模型來(lái)模擬在下車(chē)過(guò)程中剎車(chē)片在高溫情況下失靈的情形”。

    工程師說(shuō),“我在車(chē)的后備廂來(lái)有個(gè)扳手,要不我們把車(chē)拆開(kāi)看看到底是什么原因”。

    程序員說(shuō),“為什么我們不再找相同的車(chē)再來(lái)一次以重現(xiàn)這個(gè)問(wèn)題呢?”

    關(guān)于編程語(yǔ)言

    如果C++是一把錘子的話(huà),那么編程就會(huì)變成大手指頭。

    如果你找了一百萬(wàn)只猴子來(lái)敲打一百萬(wàn)個(gè)鍵盤(pán),那么會(huì)有一只猴子會(huì)敲出一段Java程序,而其余的只會(huì)敲出Perl程序。

    一陣急促的敲門(mén)聲,“誰(shuí)啊!”,過(guò)了5分鐘,門(mén)外傳來(lái)“Java”。

    如果說(shuō)Java很不錯(cuò)是因?yàn)樗梢赃\(yùn)行在所有的操作系統(tǒng)上,那么就可以說(shuō)肛交很不錯(cuò),因?yàn)槠淇梢允褂糜谒械男詣e上。

    自行車(chē)

    一個(gè)程序員騎著一個(gè)很漂亮的自行車(chē)到了公司,另一個(gè)程序員看到了他,問(wèn)到,“你是從哪搞到的這么漂亮的車(chē)的?”

    騎車(chē)的那個(gè)程序員說(shuō),“我剛從那邊過(guò)來(lái),有一個(gè)漂亮的姑娘騎著這個(gè)車(chē)過(guò)來(lái),并停在我跟前,把衣服全脫了,然后對(duì)我說(shuō),‘你想要什么都可以’”。

    另一個(gè)程序員馬上說(shuō)到,“你絕對(duì)做了一個(gè)正確的選擇,因?yàn)槟枪媚锏囊路悴⒉灰欢ù┑昧?#8221;。

    火車(chē)

    一個(gè)年輕的程序員和一個(gè)項(xiàng)目經(jīng)理登上了一列在山里行駛的火車(chē),他們發(fā)現(xiàn)列車(chē)上幾乎都坐滿(mǎn)了,只有兩個(gè)在一起的空位,這個(gè)空位的對(duì)面是一個(gè)老奶奶和一 個(gè)年輕漂亮的姑娘。兩個(gè)上前坐了下來(lái)。程序員和那個(gè)姑娘他們比較曖昧地相互看對(duì)方。這時(shí),火車(chē)進(jìn)入山洞,車(chē)廂里一片漆黑。此時(shí),只聽(tīng)見(jiàn)一個(gè)親嘴的聲音,隨 后就聽(tīng)到一個(gè)響亮的巴掌聲。很快火車(chē)出了山洞,他們四個(gè)人都不說(shuō)話(huà)。

    那個(gè)老奶奶在喃喃道,“這個(gè)年輕小伙怎么這么無(wú)禮,不過(guò)我很高興我的孫女扇了一個(gè)巴掌”。

    項(xiàng)目經(jīng)理在想,“沒(méi)想到這個(gè)程序員居然這么大膽,敢去親那姑娘,只可惜那姑娘打錯(cuò)了人,居然給打了我。”

    漂亮的姑娘想,“他親了我真好,希望我的祖母沒(méi)有打疼他”。

    程序員坐在那里露出了笑容,“生活真好啊。這一輩子能有幾次機(jī)會(huì)可以在親一個(gè)美女的同時(shí)打項(xiàng)目經(jīng)理一巴掌啊”

    問(wèn)路

    有一個(gè)駕駛熱氣球的人發(fā)現(xiàn)他迷路了。他降低了飛行的高度,并認(rèn)出了地面上的一個(gè)人。他繼續(xù)下降高度并對(duì)著那個(gè)人大叫,“打擾一下,你能告訴我我在哪嗎?”

    下面那個(gè)人說(shuō):“是的。你在熱氣球里啊,盤(pán)旋在30英尺的空中”。

    熱氣球上的人說(shuō):“你一定是在IT部門(mén)做技術(shù)工作”。

    “沒(méi)錯(cuò)”,地面上的人說(shuō)到,“你是怎么知道的?”

    “呵呵”,熱氣球上的人說(shuō),“你告訴我的每件事在技術(shù)上都是對(duì)的,但對(duì)都沒(méi)有用”。

    地面上的人說(shuō),“你一定是管理層的人”。

    “沒(méi)錯(cuò)”,熱氣球上的人說(shuō),“可是你是怎么知道的?”

    “呵呵”,地面上的那人說(shuō)到,“你不知道你在哪里,你也不知道你要去哪,你總希望我能幫你。你現(xiàn)在和我們剛見(jiàn)面時(shí)還在原來(lái)那個(gè)地方,但現(xiàn)在卻是我錯(cuò)了”。

    警告

    有一個(gè)小伙子在一個(gè)辦公大樓的門(mén)口抽著煙,一個(gè)婦女路過(guò)他身邊,并對(duì)他說(shuō),“你知道不知道這個(gè)東西會(huì)危害你的健康?我是說(shuō),你有沒(méi)有注意到香煙盒上的那個(gè)警告(Warning)?”

    小伙子說(shuō),“沒(méi)事兒,我是一個(gè)程序員”。

    那婦女說(shuō),“這又怎樣?”

    程序員說(shuō),“我們從來(lái)不關(guān)心Warning,只關(guān)心Error”

    posted @ 2009-12-07 10:24 深夜兩點(diǎn) 閱讀(315) | 評(píng)論 (0)編輯 收藏

    (http://www.yeeyan.com/articles/view/115732/71484)

    閱讀軟件開(kāi)發(fā)相關(guān)書(shū)籍,是程序員在技能和職業(yè)上為自己投資的好辦法。但是,需要閱讀那些書(shū)?應(yīng)該按照什么順序來(lái)進(jìn)行?這份書(shū)單適合那些剛剛開(kāi)始,一心想要提高自己的編程能力,想要以程序員為職業(yè)的人。

    我之前曾說(shuō),閱讀軟件開(kāi)發(fā)有關(guān)的書(shū)籍,是在你技能和事業(yè)上投資的好辦法。 但是哪些應(yīng)該閱讀呢?而且該按照什么順序閱讀呢? 我已經(jīng)編制了一份書(shū)單,我認(rèn)為它能真正大幅提高你的能力。 我已經(jīng)安排好它們的順序,分為3個(gè)階段,我相信這種順序是最有成效的。這份書(shū)單主要是為那些剛剛起步的開(kāi)發(fā)人員編寫(xiě)的,當(dāng)然專(zhuān)業(yè)的開(kāi)發(fā)者也可參照,它對(duì)周?chē)切┫氆@得提高的人來(lái)說(shuō)都是相當(dāng)有用的。

    首先,你應(yīng)該關(guān)注的是提高書(shū)寫(xiě)干凈,毫不含糊的,可維護(hù)代碼的能力。 下列書(shū)籍應(yīng)該大大有助于您:

    1. 測(cè)試驅(qū)動(dòng)開(kāi)發(fā)(肯特·貝克)
    2. 重構(gòu)(馬丁·福勒)
    3. 實(shí)現(xiàn)模式(肯特·貝克)
    4. 代碼大全:第二版(史蒂夫·麥康奈爾)
    5. Working Effectively With Legacy CodeMichael Feathers
    6. Clean Code (Robert C. Martin)

    上述的讀書(shū)順序可能使有些人感到驚訝,但我敢打賭,這是最有效的閱讀順序。

    當(dāng)你學(xué)會(huì)了如何書(shū)寫(xiě)偉大的代碼,你應(yīng)該開(kāi)始以簡(jiǎn)潔的設(shè)計(jì)和架構(gòu)為重點(diǎn)。 這并不是說(shuō),你應(yīng)該只集中于設(shè)計(jì)和架構(gòu),但你越了解它,你會(huì)變得越好:

    1. 設(shè)計(jì)模式(Gang Of Four 
    2. 企業(yè)應(yīng)用架構(gòu)模式(馬丁·福勒)
    3. 領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)(埃里克·埃文斯)
    4. 企業(yè)集成模式(格里高·Hohpe,鮑比·沃爾夫)
    5. Release It! Design and deploy production-ready software(Michael T. Nygard)
    6. 97 Things Every Software Architect Should Know (edited by Richard Monson-Haefel)

    這一階段可能值得說(shuō)明的是在這部分列出的一些圖書(shū)中可能是有點(diǎn)'爭(zhēng)議'的。 如果您已經(jīng)閱讀了第一階段的書(shū)籍,那么你應(yīng)該有能力用你自身的觀點(diǎn)看待第二階段的這些書(shū)籍。 你會(huì)了解到,你不應(yīng)該僅僅仿照那些模式,但了解它們的存在肯定是一件好事。

    最后,您需要了解如何在團(tuán)隊(duì)環(huán)境下工作并理解團(tuán)隊(duì)的動(dòng)力。 下面的書(shū)籍不是具體介紹團(tuán)隊(duì)中的工作,但包含了眾多的智慧和洞察力,這一定會(huì)幫助您在專(zhuān)業(yè)的團(tuán)隊(duì)環(huán)境中工作:

    1. 極限編程,第二版(肯特·貝克)
    2. The Art Of Agile Development (James Shore & Shane Warden)
    3. 人月神話(huà),20周年紀(jì)念版(弗雷德里克·布魯克斯)

    這本書(shū)可能也需要一點(diǎn)說(shuō)明。 我并不是說(shuō)你應(yīng)該做極限編程。 但你了解它肯定不會(huì)有害處,至少你應(yīng)該在你認(rèn)為有意義的時(shí)候去嘗試采用這種做法。 你并不會(huì)真的需要去采用所有的做法(雖然你這樣做會(huì)獲得額外的好處,或者至少假裝這樣做),但它們中的一些,每個(gè)人都應(yīng)該至少了解一下。

    所以就是這樣了...嘗試用上述方式閱讀這些書(shū),不要忘了以后感謝我 

    A Reading Guide To Becoming A Better Developer

    I’ve stated previously that reading software development books is a good way of investing in your skills and your career. But which ones should you read? And in what order should they be read? I’ve compiled a list of books that i think can truly increase your skills substantially. I’ve put them in the order in which i believe they will have the most effect, and grouped them in 3 ’stages’. I primarily have young developers who are just getting started as professional developers in mind with this list, but it should be just as useful to developers who’ve been around for a while and simply want to improve.

    The first thing that you should focus on is improving your ability to write clean, unambiguous, maintainable code. The following books should greatly help you with that:

    1. Test-Driven Development (Kent Beck)
    2. Refactoring (Martin Fowler)
    3. Implementation Patterns (Kent Beck)
    4. Code Complete: 2nd Edition (Steve McConnell)
    5. Working Effectively With Legacy Code (Michael Feathers)
    6. Clean Code (Robert C. Martin)

    The order of this stage might surprise some people, but i’m willing to bet that this is the most efficient order to reading those books.

    After you’ve learned how to write great code, you should really start focusing on clean design and architecture. That’s not to say that you should focus solely on design and architecture, but the more you know about it, the better off you will be:

    1. Design Patterns (Gang Of Four)
    2. Patterns Of Enterprise Application Architecture (Martin Fowler)
    3. Domain-Driven Design (Eric Evans)
    4. Enterprise Integration Patterns (Gregor Hohpe, Bobby Woolf)
    5. Release It! Design and deploy production-ready software (Michael T. Nygard)
    6. 97 Things Every Software Architect Should Know (edited by Richard Monson-Haefel)

    This stage probably deserves a bit of clarification as some of the books listed in this part might be somewhat ‘controversial’. If you read and learned from the books in the first stage, then you should be capable of putting everything you read in the second stage in perspective. You will have learned that you shouldn’t just apply as many patterns as possible, but it’s certainly a good thing to know about their existence.

    Finally, you need to learn about working in a team environment and understanding team dynamics. The following books aren’t about working in teams specifically, but contain a tremendous amount of wisdom and insight that will definitely help you when it comes to working in a professional team environment:

    1. Extreme Programming Explained, Second Edition (Kent Beck)
    2. The Art Of Agile Development (James Shore & Shane Warden)
    3. The Mythical Man-Month, 20th Anniversary Edition (Frederick P. Brooks)

    This one probably needs a bit of clarification as well. I’m not saying that you should do Extreme Programming. But it certainly won’t hurt you to learn about it, and at least try to apply the practices that you believe in when it makes sense to do so. You don’t really need to apply them all (though you will get bonus points from the cool kids if you do so, or at least pretend to), but there are a few of them that everyone really should do regardless of which agile variant you subscribe to.

    So there you have it… try those books out in that order, and don’t forget to thank me later



    posted @ 2009-12-05 21:48 深夜兩點(diǎn) 閱讀(277) | 評(píng)論 (0)編輯 收藏

    (上一篇:計(jì)算機(jī)中的加密和認(rèn)證http://www.tkk7.com/deepnighttwo/archive/2009/12/03 /304631.html
    A公司開(kāi)發(fā)了一個(gè)軟件,打成了一個(gè)jar包,然后發(fā)布出去liao。作為一個(gè)用戶(hù),如何來(lái)確認(rèn)這個(gè)jar包確實(shí)是A公司發(fā)布的哪個(gè)?而且,如何確定這個(gè)jar包沒(méi)有被別有用心的一小撮篡改過(guò)?這就需要Java中的簽名來(lái)保證。

    Java中的可執(zhí)行代碼就是class文件。直接使用class文件是很naive的。通常的做法是是對(duì)一個(gè)jar包中的所有class文件進(jìn)行簽名。過(guò)程可以分為如下步驟。
    1. 首先使用JDK自帶的keytool工具生成一個(gè)keystore,命令如下: keytool -genkey -keystore keystore文件 -alias 別名。回車(chē)后還有一些信息需要填寫(xiě)。keystore里面包含了很多信息,包括公鑰和私鑰信息。當(dāng)然可以使用keytool命令從keystore文件里面導(dǎo)出公鑰和私鑰。keytool命令還有很多參數(shù),比如你可以指定使用的摘要算法等。(具體用法可以Google之)。
    2. 然后,第二步當(dāng)然是找個(gè)CA給公鑰簽名。自?shī)首詷?lè)的用途就可以不用這一步了。
    3. 第三步是給jar包簽名。JDK中提供了給jar包簽名的工具,叫做jarsinger。命令各式如下:jarsigner -keystore keystore文件 jar文件 別名(就是生成keystore時(shí)用的那個(gè)別名)。回車(chē)后要輸入密碼,也跟生成keystore時(shí)候的密碼一樣就行了。
    好,到這里就算簽名結(jié)束了。命令執(zhí)行完畢后,jar包會(huì)陡然多出幾k來(lái)。這幾k就是簽名的內(nèi)容。


    Java(或者說(shuō)是Java Runtime)是支持簽名和認(rèn)證的。也就是說(shuō)一個(gè)jar包一旦被簽名了,Java Runtime會(huì)對(duì)這個(gè)jar包進(jìn)行驗(yàn)證。下面是驗(yàn)證簽名的過(guò)程。
    首先需要知道簽名后jar包里面多出了什么。簽名并不會(huì)改變jar包中已經(jīng)有的內(nèi)容,而是添加了一個(gè).DSA(說(shuō)明使用的是DSA算法)文件和一個(gè).SF(signed file)文件,然后在.MF文件里面增加一些內(nèi)容。驗(yàn)證的過(guò)程是這樣的(我猜的。。。覺(jué)得不對(duì)可以去http://java.sun.com/javase/6/docs/technotes/guides/jar /jar.html,Sun公司的jar包規(guī)范,自己看自己猜),首先是DSA文件,它里面存儲(chǔ)了公鑰內(nèi)容和對(duì)SF文件摘要的加密內(nèi)容,所以,首先驗(yàn)證公鑰(跟https里面的那個(gè)驗(yàn)證是一樣的過(guò)程),驗(yàn)證完畢證書(shū)后,用公鑰解密加密的內(nèi)容,然后得到SF文件的摘要值,把這個(gè)值和實(shí)際 SF文件的摘要值比較,這樣就可以保證SF文件沒(méi)問(wèn)題了。SF文件里面的內(nèi)容包含了很多條目的簽名值。首先是對(duì)MF文件的簽名值,這就是驗(yàn)證MF文件了。而MF文件里面對(duì)每個(gè)class文件都有一段描述的內(nèi)容,比如:
    Name: common/class2.class

    MD5-Digest: (base64 representation of MD5 digest)

    SHA-Digest: (base64 representation of SHA digest
    它代表這個(gè)class文件對(duì)應(yīng)摘要算法的摘要值。這個(gè)條目在SF里面有一個(gè)對(duì)應(yīng)的條目:
    Name: common/class2.class
    MD5-Digest: (base64 representation of MD5 digest)


    注意,SF文件中的這個(gè)摘要值不是class文件的,而是MF文件里面對(duì)應(yīng)條目的。也就是說(shuō),SF里面的簽名值統(tǒng)統(tǒng)是用來(lái)驗(yàn)證MF文件或者M(jìn)F文件中的條目的,而MF文件中的摘要值才是用來(lái)驗(yàn)證class文件的。真繞。。。

    總之,最后一層層的驗(yàn)證后,整個(gè)jar包中的內(nèi)容都被驗(yàn)證了。過(guò)程:CA的證書(shū)->自己的公鑰->SF文件簽名 ->MF文件簽名和MF文件每個(gè)條目的簽名->jar包中的每個(gè)文件(當(dāng)然主要是clas文件。別的文件應(yīng)該也會(huì)被驗(yàn)證的,至少properties文件會(huì)被簽名認(rèn)證)

    驗(yàn)證完了之后,就可以保證jar包確實(shí)出自某公司之手,也確實(shí)沒(méi)有被別有用心的一小撮人篡改過(guò)。如果你信任某公司,那就可以用這個(gè)jar包了。

    同樣,如果一個(gè)applet的jar包是簽名了的,而且在啟動(dòng)applet的時(shí)候用戶(hù)選擇信任這個(gè)簽名,那么這個(gè)applet就擁有了訪(fǎng)問(wèn)本機(jī)資源的權(quán)限,如果選擇不信任,那么applet就不會(huì)被啟動(dòng)。如果一個(gè)applet沒(méi)有被簽名,那么applet可以啟動(dòng),但是不會(huì)被允許訪(fǎng)問(wèn)本機(jī)資源(文件等)。

    如果一個(gè)證書(shū)沒(méi)有被CA的證書(shū)認(rèn)證,比如說(shuō),對(duì)于我寫(xiě)的這個(gè)applet,它就是用我自己搞出來(lái)的沒(méi)認(rèn)證過(guò)的證書(shū)簽了名的:http://appletfarm.appspot.com/juliaappletsigned.html
    這時(shí)候Java會(huì)提示說(shuō):

    “該應(yīng)用程序的數(shù)字簽名無(wú)法驗(yàn)證”,因?yàn)槲覜](méi)給過(guò)VeriSign年費(fèi)。如果證書(shū)是驗(yàn)證過(guò)的,對(duì)話(huà)框就會(huì)是詢(xún)問(wèn)你是否信任“某公司”,這個(gè)意思就是說(shuō),此jar包確實(shí)是“某公司”搞出來(lái)的,信任那個(gè)公司就可以運(yùn)行它了。

    posted @ 2009-12-03 23:17 深夜兩點(diǎn) 閱讀(1116) | 評(píng)論 (0)編輯 收藏

    大學(xué)時(shí)候?qū)W網(wǎng)絡(luò)安全,不知道是老師太脫離實(shí)際,還是當(dāng)時(shí)我上課睡太多了,反正學(xué)了個(gè)糊里糊涂。上機(jī)實(shí)驗(yàn)比著葫蘆畫(huà)瓢在JBoss上搞了個(gè)EJBCA的什么東西,就覺(jué)得已經(jīng)混過(guò)去了。不過(guò)該學(xué)的還是得學(xué),躲不過(guò)。現(xiàn)在開(kāi)始還大學(xué)睡覺(jué)的債。。。。前段時(shí)間看了一陣子的Java安全編程,回過(guò)頭來(lái)總結(jié)總結(jié)。

    首先是跟Java沒(méi)關(guān)系的,是加密和認(rèn)證。加密的算法可以分為三類(lèi):
    • 摘要算法(指紋算法,哈希算法等):摘要算法其實(shí)不算加密。算法以數(shù)據(jù)為輸入,生成一串等長(zhǎng)的輸出。這個(gè)輸出就是這段輸入的指紋,或者說(shuō)是摘要。算法不管輸入有多長(zhǎng),1G或者一個(gè)byte,輸出都是一樣長(zhǎng)的。指紋算法比較形象。我們可以認(rèn)為,只要數(shù)據(jù)不同,生成的摘要就是不同的(或者說(shuō),想根據(jù)一個(gè)摘要來(lái)生成特定的數(shù)據(jù)是很難的,所以這個(gè)摘要可以唯一的確定數(shù)據(jù)的身份)。當(dāng)然是無(wú)法從這個(gè)簡(jiǎn)短的摘要還原原始數(shù)據(jù)的。比較常用的摘要算法有MD5,SHA-1,DSA之類(lèi)的。摘要算法是公開(kāi)的,任何人都可以通過(guò)摘要算法來(lái)計(jì)算一段數(shù)據(jù)的摘要。所以,如果一個(gè)文件傳輸給你,同時(shí)也給你一個(gè)這個(gè)文件的MD5摘要,那么你收到文件后,計(jì)算一下文件的MD5,然后和別人給你的MD5摘要比較一下,就知道文件在到你手上之前是不是被人改動(dòng)過(guò)了。
    • 對(duì)稱(chēng)加密算法:對(duì)稱(chēng)加密算法是使用相同密鑰加密和解密數(shù)據(jù)的一種加密算法。密鑰可以認(rèn)為就是一段數(shù)據(jù)。使用相同的密鑰這點(diǎn)很重要。對(duì)稱(chēng)加密算法很多,加密解密也很快。最入門(mén)的對(duì)稱(chēng)加密算法就使凱撒密碼。工業(yè)中使用的加密算法很多,比如用于流加密的RC4,還有AES,DES等。只有有密鑰,那么就可以對(duì)加密后的數(shù)據(jù)進(jìn)行解密,得到原始的數(shù)據(jù)。從這里可以看出,密鑰是對(duì)稱(chēng)加密的關(guān)鍵,如果密鑰的傳輸無(wú)法保證安全,對(duì)稱(chēng)加密就是形同虛設(shè)的。
    • 非對(duì)稱(chēng)加密算法:非對(duì)稱(chēng)加密算法是計(jì)算機(jī)加密和認(rèn)證中最關(guān)鍵的一環(huán)。非對(duì)稱(chēng)加密的特點(diǎn)是,它有倆密鑰,用密鑰1加密的數(shù)據(jù)需要使用密鑰2解密,同樣,用密鑰2加密的數(shù)據(jù)需要用密鑰1解密。如果公開(kāi)密鑰1,那么密鑰1就成為公鑰,即公開(kāi)的密鑰,同時(shí),密鑰2就使私鑰,必須好好保存不能讓別人得到。非對(duì)稱(chēng)加密算法有數(shù)學(xué)證明來(lái)保證它幾乎不可能在一個(gè)有意義的時(shí)間段內(nèi)被破解。但是非對(duì)稱(chēng)加密也有致命的弱點(diǎn)——加密解密計(jì)算量大,不適合用來(lái)處理大量的數(shù)據(jù)。非對(duì)稱(chēng)加密算法有RSA,DSA等。
    計(jì)算機(jī)加密體系需要保證——保密性、完整性、認(rèn)證性和不可抵賴(lài)性。保密性就是說(shuō),數(shù)據(jù)是使用加密算法加密過(guò)的(一般是使用對(duì)稱(chēng)加密算法加密)。完整性可以用摘要算法保證,因?yàn)橐欢螖?shù)據(jù)一旦被人改動(dòng)過(guò)了,那么摘要就肯定不同了。但是,這兩者如果沒(méi)有非對(duì)稱(chēng)加密算法保護(hù),一切就都是空談。因?yàn)椋荑€總歸要通過(guò) internet傳輸?shù)模绻蝗烁`取了咋辦?摘要?大不了黑客篡改了數(shù)據(jù)之后,生成一個(gè)新的摘要。好,非對(duì)稱(chēng)加密上場(chǎng)了,認(rèn)證性和不可抵賴(lài)性這兩點(diǎn)也是非對(duì)稱(chēng)加密來(lái)保證的。它如何來(lái)保證前面這些呢?

    先看看什么是證書(shū)。有了這些算法之后,就有了證書(shū)這個(gè)概念。啥叫做證書(shū)呢?證書(shū)其實(shí)就是一個(gè)文件。文件內(nèi)容挺多,需要關(guān)心的有:
    • 非對(duì)稱(chēng)加密的公鑰。它可以用來(lái)解密那個(gè)秘密的私鑰加密過(guò)的數(shù)據(jù)。
    • 用別的私鑰加密過(guò)的非對(duì)稱(chēng)加密的公鑰的簽名。上面說(shuō)的非對(duì)稱(chēng)加密的公鑰也是一段數(shù)據(jù)呀,用摘要算法計(jì)算一下它的摘要。然后用別的私鑰加密一下這個(gè)摘要。注意,這里說(shuō)的是用別的私鑰加密。
    • 所謂的別的私鑰的標(biāo)識(shí)。有了這個(gè)標(biāo)識(shí),才知道是誰(shuí)加密了公鑰的簽名。
    問(wèn)題越來(lái)越多了。什么叫做別的私鑰?哪兒來(lái)的私鑰?對(duì)于一個(gè)有效的證書(shū)來(lái)說(shuō),這里說(shuō)的別的私鑰,就是那些專(zhuān)門(mén)來(lái)提供證書(shū)加密服務(wù)的公司(比如 VeriSign)的私鑰。這些公司會(huì)全副武裝的保護(hù)好自己的私鑰(公司的命根子呀)。下面來(lái)敘述一下這個(gè)過(guò)程:
    1. 首先,A公司想要一個(gè)證書(shū),用來(lái)在internet上證明自己確確實(shí)實(shí)是A公司。于是公司通過(guò)工具生成了一對(duì)密鑰(這個(gè)很簡(jiǎn)單,誰(shuí)都可以輕松的生成一對(duì)密鑰)。
    2. 然后他拿著公鑰去找VeriSign,計(jì)算了公鑰的MD5值,請(qǐng)求VeriSign拿出自己的寶貝私鑰,來(lái)對(duì)這個(gè)公鑰的MD5值進(jìn)行加密。
    3. VeriSign很專(zhuān)業(yè),他們會(huì)要求A公司出具相應(yīng)的證明,核實(shí)無(wú)誤后,VeriSign此才會(huì)拿出私鑰,把A公司公鑰的MD5值進(jìn)行加密。這個(gè)就叫做簽發(fā)證書(shū)。
    4. 這不是一錘子買(mǎi)賣(mài),A公司為了這個(gè)事兒,須要按年給VeriSign付錢(qián)。
    5. 好,A公司的公鑰的MD5值被VeriSign的私鑰加密過(guò)了,得到了一段加密后的數(shù)據(jù),只有VeriSign的公鑰才能解密這段數(shù)據(jù),得出正確的值。
    6. A公司屁顛屁顛的可以生成自己的證書(shū)了,證書(shū)的內(nèi)容包括:
    • A公司的公鑰。
    • VeriSign的私鑰對(duì)A公司的公鑰的MD5值加密后,所得到的數(shù)據(jù)。再次提醒一下,這個(gè)密鑰只有VeriSign的公鑰才能解密。
    • 一段文字,說(shuō)明證書(shū)是VeriSign驗(yàn)證的,公鑰的指紋算法是MD5。這段文字不用加密,誰(shuí)愛(ài)看誰(shuí)看。
    終于A公司有了自己的證書(shū),但是,VeriSign的私鑰加密過(guò)的東西,須要使用VeriSign的公鑰來(lái)解密,咋辦?不用急,VeriSign這種提供證書(shū)服務(wù)的公司早就和各種操作系統(tǒng)提供商協(xié)商好了,他們的公鑰早就一經(jīng)包含在了每一個(gè)操作系統(tǒng)中,在我們安裝操作系統(tǒng)的時(shí)候,VeriSign這些公司的公鑰就已經(jīng)包含在計(jì)算機(jī)里了。

    下面以https來(lái)解釋一下計(jì)算機(jī)中的安全體系(保密性、完整性、認(rèn)證性和不可抵賴(lài)性)是如何工作的。
    A公司有了一個(gè)站點(diǎn),瀏覽器使用https來(lái)訪(fǎng)問(wèn)這個(gè)站點(diǎn)的時(shí)候,大概的過(guò)程就是這樣的(下面的過(guò)程基本是Https協(xié)議的運(yùn)作過(guò)程):
    1. A公司站點(diǎn)首先給客戶(hù)端發(fā)送自己的寶貝證書(shū)。(數(shù)據(jù)傳輸?shù)臅r(shí)候被人從中間截獲了?不怕,想聽(tīng)就聽(tīng)吧)
    2. 認(rèn)證性:客戶(hù)端得到證書(shū)之后,開(kāi)始驗(yàn)證這個(gè)證書(shū):
      • 首先,客戶(hù)端從證書(shū)中知道,這個(gè)證書(shū)是被VeriSign公司簽發(fā)的。所以客戶(hù)端從操作系統(tǒng)中拿出來(lái)VeriSign公司的公鑰,待用。
      • 客戶(hù)端還知道,A公司公鑰是使用MD5算法計(jì)算的簽名,OK,客戶(hù)端讀取出來(lái)證書(shū)中A公司的公鑰,使用MD5值,待用。
      • 下面是重要的一步了,客戶(hù)端從A公司的證書(shū)中抽取出那段加密后的數(shù)據(jù)(也就是A公司公鑰的MD5值VeriSign公司的私鑰加密過(guò)的那段數(shù)據(jù)),然后再拿過(guò)來(lái)第一步中找到的VeriSign公司的公鑰,非對(duì)稱(chēng)加密的特點(diǎn)就是私鑰加密,公鑰解密之。所以,當(dāng)當(dāng)當(dāng)當(dāng)當(dāng),解密之,得到的值就應(yīng)該是A公司的公鑰的MD5值。< /li>
      • 那到底是不是呢?跟第二步中客戶(hù)端自己計(jì)算出來(lái)的MD5值比對(duì)一下就知道了。
      • 如果通過(guò)比較,發(fā)現(xiàn)確實(shí)是,那么安全體系中的認(rèn)證性就得到保證了,也就是說(shuō),客戶(hù)端可以完全相信對(duì)方就是A公司,訪(fǎng)問(wèn)的站點(diǎn)也就是A公司的站點(diǎn)。(等等,A公司的公鑰不是公開(kāi)的嗎?那豈不是任何站點(diǎn)都可以偽裝成A公司?不急,這不是個(gè)事兒,在下面不可抵賴(lài)性會(huì)說(shuō)到)當(dāng)然,如果驗(yàn)證不通過(guò),說(shuō)明對(duì)方是個(gè)“李鬼”。瀏覽器會(huì)有提示,說(shuō)這個(gè)站點(diǎn)提供的證書(shū)沒(méi)有通過(guò)驗(yàn)證思密達(dá)(還有一種情況就是,證書(shū)過(guò)期了,還記得前面說(shuō)的每年給VeriSign的年費(fèi)嗎)。
    3. 好,客戶(hù)端驗(yàn)證通過(guò)了,下面就是開(kāi)始傳輸數(shù)據(jù)了。傳輸數(shù)據(jù)的過(guò)程有保密性、完整性和不可抵賴(lài)性三點(diǎn)需要保證。
    4. 首先,客戶(hù)端瀏覽器悄悄地生成一個(gè)隨機(jī)數(shù)。然后使用A公司的公鑰加密這個(gè)隨機(jī)數(shù),發(fā)送給A公司的站點(diǎn)。因?yàn)槭茿公司公鑰加密的,所以不怕被人竊聽(tīng)。為啥不怕被竊聽(tīng),因?yàn)楦`聽(tīng)了也沒(méi)用,因?yàn)楦`聽(tīng)者肯定沒(méi)有A公司的私鑰,沒(méi)有私鑰也就沒(méi)法對(duì)竊聽(tīng)到的數(shù)據(jù)解密。
    5. A公司站點(diǎn)收到這個(gè)數(shù)據(jù)后,開(kāi)始使用自己的私鑰解密數(shù)據(jù)。到了這個(gè)時(shí)候,肯定是只有客戶(hù)端和A公司的站點(diǎn)服務(wù)器知道這個(gè)隨機(jī)數(shù)的。
    6. 接下來(lái),客戶(hù)端瀏覽器和A公司站點(diǎn)根據(jù)相同的算法,生成對(duì)稱(chēng)加密使用的密鑰(實(shí)際上是一組密鑰,當(dāng)然在這里不用深究這個(gè))。以后的數(shù)據(jù)傳輸就全使用這個(gè)對(duì)稱(chēng)加密密鑰進(jìn)行了。這就是保密性
    7. 保密性得到了保證,完整性如何保證呢?如果攻擊者雖然不能夠獲得數(shù)據(jù),但是他想搗蛋,偷偷篡改數(shù)據(jù)來(lái)破壞數(shù)據(jù)的完整性。這個(gè)時(shí)候也沒(méi)啥問(wèn)題,在https 協(xié)議中,每條消息在加密之前都包含了消息內(nèi)容和消息的hash值(比如,消息的MD5值),這樣在消息的接收端,就可以對(duì)這條消息進(jìn)行驗(yàn)證了。通過(guò)驗(yàn)證就可以知道消息是不是被篡改過(guò)。當(dāng)然,如果被篡改過(guò),也使沒(méi)辦法回復(fù)的,不過(guò)知道消息被篡改過(guò),那么就可以要求對(duì)方重新發(fā)送消息了,總之攻擊者是沒(méi)法辦得逞的。這就是消息的完整性
    8. 好的,在這里我們來(lái)看一下不可抵賴(lài)性。因?yàn)橹挥蠥公司有私鑰,這也就是說(shuō),只有A公司可以把這個(gè)數(shù)據(jù)成功解密,來(lái)得到這個(gè)隨機(jī)數(shù),從而來(lái)計(jì)算對(duì)稱(chēng)加密使用的密鑰。所以,如果A公司想抵賴(lài)說(shuō)那個(gè)站點(diǎn)不是自己,是不可能的事情。因?yàn)橹挥蠥公司有這個(gè)用于解密的私鑰,不是A公司是誰(shuí)。同樣,就好像在前面說(shuō)的,如果有人用A公司的公鑰冒充A公司,那么這個(gè)李鬼其實(shí)沒(méi)有A公司的公鑰,也就沒(méi)有辦法解密數(shù)據(jù)(注意,客戶(hù)端產(chǎn)生的隨機(jī)數(shù)是使用A公司的公鑰加密的,須要使用A公司的私鑰解密),所以這個(gè)是徒勞的。
    好,保密性、完整性、認(rèn)證性和不可抵賴(lài)性都在上面的過(guò)程中都得到保證了。這個(gè)過(guò)程的核心就是非對(duì)稱(chēng)加密的特性:公鑰加密私鑰解密,私鑰加密公鑰解密。本篇到此結(jié)束,下一篇中將涉及Java中的認(rèn)證和加密。

    關(guān)于https的具體內(nèi)容可以參考這篇文章:http://www.infoq.com/cn/articles/HTTPS-Connection-Jeff-Moser





    posted @ 2009-12-03 17:55 深夜兩點(diǎn) 閱讀(788) | 評(píng)論 (0)編輯 收藏

    (轉(zhuǎn)自http://weblogs.java.net/blog/2007/09/27/why-i-dont-use-swing-hacks-production-code)

    Why I don't use Swing hacks (in production code)

    Posted by alexfromsun on September 27, 2007 at 7:03 AM PDT

    One of the big part of my work is fixing bugs in Swing but not all of them are to be fixed, some of them are closed because they describe the situations when someone uses Swing in undocumented way or trying to make Swing do something which it doesn't support.

    My favourite example is so-called "Blocking GlassPane". If you file a bug with a description that you implemented a GlassPane to block your frame and it doesn't work, most likely it will immediately be closed as "not a bug". The reason is simple - glassPane is an internal feature of Swing and the library may use wherever it is necessary, for example currently we make it visible during resizing of internal frames to show a correct mouse cursor above any existing components.

    Swing does it well if you just paint something on a GlassPane but when your GlassPane affects the processing of events it becomes what I call a "hack". There are many definitions what a "hack" is, either positive or negative, but I want to give a definition what I mean by this word


    Hack is an approach when you use something in an unexpected way

    Hacks don't have to be alway good or bad. Some of them are creative and effective, some of them are just creative, but they are always different from recommended or well-known solutions.

    Going back to Swing I want to mention the main feature of a code which uses hacks:


    If you use recommended techniques and something doesn't work as it should 
    Swing team is to be blame.

    If you use a hack and something doesn't work - it is you to be blame.

    Hacks usually work well for a presentation or a blog entry, but very few of them work as good and stable as the core library code. When you think it is good enough, someone else finds a problem whith your code and when you fix it, another issue appears so when you fix the "last" problem you know enough to write another valid test case which will be broken with your code.

    Even if you are pretty sure that your hack works well on your computer, there usually no guarantee that it doesn't fail for another OS or with some custom components which use similar hack.

    The "Blocking GlassPane" is an interesting example because it is a well-known hack which has never worked well. It is easy to put a fancy animation to a GlassPane and add an empty MouseListener to block the MouseEvents but people tend to forget about KeyBoard events and it is usually possible to type something in a TextField under a Blocking GlassPane.

    I already blogged about this issue and offered some solutions to make this hack more robust however a month ago I got a message from one of my readers, he told me that my improved Blocking Glasspane fails to block the menu accelerators, so if you use Alt+MenuShortCut the menu will appear.

    Problems like that is a usual thing when you use hacks. The most straightforward fix for this particular problem would be to disable frame's JMenuBar before showing GlassPane and enabling it again when the GlassPane is gone, but don't ask me how give user a chance to interrupt the time-consuming operation which blocks his frame or how to ignore keyboards actions for other components.


    Modal dialog is the only recommended solution to block a top level frame

    During my work on JXTransformer I used any kind of hacks to make transformed components work as well as usual ones. I managed to make it work for unsigned applet however I used some fishy techniques which I can hardly recommend. And again I realized that it might work for the most usual cases but there will always be some cases when transformed components behave incorrectly and the only right fix is to change the Swing itself to support AffineTransform for JComponents.

    After that I added a special note that JXTransformer has several known limitations and decided that my next project will use only recommended techniques which always work well.

    That's the reason why I don't use any hacks in JXLayer component. When I started this project it was tempting to add some creative hacks to implement some unique features but I keep following the "no hacks rule" because I don't want to be blame if JXLayer wouldn't work for your project.

    When hacks are welcome

    If you think that I don't use hacks at all, it's not true. There are some situations where hacks (even the dirty ones) are welcome, I am talking about testing and debugging. Let's say you need to find a cause of a bug, and in this case all means which may help are good (until they are not a part of production code).

    On SwingHelper project you can find a CheckThreadViolationRepaintManager which helps finding a Event Dispatch Thread violation in Swing applications as well asEventDispatchThreadHangMonitor to catch time-consuming tasks on Event Dispatch Thread. 
    I would hardly use custom RepaintManager or EventQueue for my components, but they work very well when it comes to debugging.

    Testing is a similar story, when I have a choice between a manual regression test with no hacks and automated one with hacks, I always choose the last one, just because manual tests don't have much sense

    Conclusion

    I am a realist and I know that unfortunately it is almost impossible to make a big project without any hacks. The only recommendation I can give for this matter is do not use hacks just because you know them, try to follow the documented patterns as often as possible and you code will be more reliable

    To be continued...



    posted @ 2009-12-03 14:35 深夜兩點(diǎn) 閱讀(270) | 評(píng)論 (0)編輯 收藏

    主站蜘蛛池模板: 亚洲精品视频专区| 亚洲中文字幕无码mv| 国产.亚洲.欧洲在线| 免费一级全黄少妇性色生活片| 99久久成人国产精品免费| 性xxxxx免费视频播放| 亚洲国产精品碰碰| 91亚洲国产在人线播放午夜| 亚洲av综合日韩| 97公开免费视频| 亚洲欧洲精品成人久久奇米网| 亚洲精品视频在线观看视频| 国产综合成人亚洲区| 91精品手机国产免费| 亚洲国产成人久久一区久久| 亚洲国产成人在线视频 | 亚洲成人网在线观看| 国产AV日韩A∨亚洲AV电影| 88xx成人永久免费观看| 亚洲国产精品国产自在在线| 亚洲一区无码中文字幕乱码| 人妻在线日韩免费视频| 日韩a级毛片免费观看| 亚洲精品91在线| 三上悠亚在线观看免费| 日韩人妻无码免费视频一区二区三区 | 好紧我太爽了视频免费国产| 日本v片免费一区二区三区| 亚洲伊人久久大香线蕉苏妲己| 日韩大片免费观看视频播放| 久久久久久国产精品免费免费| 久久亚洲国产午夜精品理论片| MM1313亚洲精品无码久久| 亚洲免费网站在线观看| 亚洲理论电影在线观看| 猫咪免费观看人成网站在线| 97无码免费人妻超级碰碰夜夜| 亚洲精品网站在线观看你懂的| 久久九九久精品国产免费直播| 国产色爽女小说免费看| ww亚洲ww在线观看国产|