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

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

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

    posts - 8, comments - 13, trackbacks - 0, articles - 43
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    2011年5月22日

    先簡單回顧下sql語言的幾種語言:ddl,dml,dcl,它們分別是:

    ddl即data definition language,例如常用的:create,alter,drop,truncate,grant,revoke,comment;

    dml即data manipulation language,我們經常使用的:select,insert,update,delete等都是數據操作語言。

    dcl即data control language,數據控制語言,平時基本用不到,如commit,savepoint,rollback,set transaction。

     

    所以區別主要在:

    • delete是dml語句,這個操作使用放在rollback segement里,事務提交后才生效,是可以回滾的;truncate是ddl語句,它不在rollback segement里的,事務自動提交,操作立即生效,沒有回滾一說,除非自身失敗;
    • 還有一個關鍵,雖然truncate是數據定義語言,但是truncate和delete操作一樣,都只刪除數據不刪除表結構,兩者的主要區別在于,truncate操作是沒有備份的,所以它執行速度比delete快;而另一個ddl語句drop,將刪除的是結構包括被依賴的觸發器,索引,約束,依賴該表的存儲過程會被保留。剛才又搜索了下truncate和drop操作之后數據也還是可以找回來的:http://dbsnake.com/2010/06/truncate-drop-recovery.html

    posted @ 2011-05-22 12:12 kangaroo 閱讀(294) | 評論 (0)編輯 收藏

    1。xml背景

    格式良好的(web-fromed)xml可以不需要文檔類型定義(DTD),只要滿足基本的xml格式規范就可以認為是格式良好的xml文檔。但是格式標準,只能說明元素、標簽、格式是合法的,并不能說明元素是有意義的,或者說規范的。

    有效的xml文檔,首先要求是格式良好的文檔,同時遵守相應的DTD文件約束。

    2。xml解析

    xml文檔解析的大致使用過程如下圖:

     

     

     

    由xml解析器解析和操作指定的xml文檔,然后提供接口供應用程序使用。如果解析器不同,那么提供的接口就有可能不同。慶幸的是,目前所有的xml解析器對兩套標準的api提供了支持,這兩套標準api就是dom和sax。

    dom:即document object model,文檔對象模型,它是w3c組織推薦的處理xml的標準接口。dom是基于xml文檔結構樹的解析。

    sax:即simple api for xml,它是非官方的、xml社區事實上的標準。sax是基于事件流的解析。

    dom和sax只是定義了一些接口以及某些接口的缺省實現,應用程序要想利用dom或sax訪問xml文檔,還需要真正實現dom或sax接口的xml解析器。apache的xerces是一個使用非常廣泛的解析器,它實現了dom和sax的調用接口,并提供了多種語言的實現版本。

    3。java語言對xml文檔的解析

    首先介紹jaxp:

    基于dom或sax提供的api接口,使用相應的解析器實現類我們已經可以對xml進行解析處理了。如下所示:

    org.xml.sax.XMLReader sp=new org.apache.xerces.parser.SAXParser();

    FileInputStream fis=new FileInputStream(“hello.xml”);

    InputSource is=new InputSource(fis);

    sp.setContentHandler(new MyConentHandler());

    sp.parse(is);

    為了屏蔽xml解析器的變化對代碼的影響,java提供了一套標準的處理xml文件的接口(實際上是一些抽象的工廠類),使得java開發人員以一種標準的方式對xml進行編程,即jaxp(java api for xml processing)。jaxp沒有提供解析xml的新方法,只是在解析器之上封裝一個抽象層。在jdk1.6的文檔中,我們可以看到javax.xml,org.w3c.dom,org.xml.sax包及其子包都屬于jaxp的部分。jaxp由接口、抽象類和一些輔助類組成,符合jaxp規范的解析器實現其中的接口和抽象類,開發時只需要使用jaxp的api編程,底層的解析器對開發者時透明的,可以隨意的切換。

    那么jaxp出現后,java應用程序處理xml文檔的過程就如下圖:

     

    那實際采用哪種解析器的jaxp實現,可以通過系統屬性、properties文件等方式來配置。

    下面具體介紹幾種java解析xml的方法:

    3.1 DOM方式(jaxp)

    在javax.xml.parsers包中,定義了dom的抽象工廠類DocumentBuilderFactory,在這個類中有一個靜態的方法newInstance(),通過它產生一個DocumentBuilderFactory的實例。前面提到過jaxp編程,解析器提供商必須繼承該抽象類產生一個具體的解析器工廠,然后由這個工廠類實例出一個解析器對象,再通過該解析器對象處理xml文檔。那么這個newInstance方法就是用來產生一個具體的解析器工廠類實例,查找生成解析器工廠類實例的方式可參考jdk文檔。

    在獲取到解析器工廠類實例類之后,就可以調用newDocumentBuilder()方法創建一個dom解析器實例;dom解析器實例就可以調用parser()方法獲取整個xml問答的Document對象。

    3 .2 SAX方式(jaxp)

    sax是基于事件驅動的api,sax解析xml文檔時會向事件處理器發送不同的事件。sax解析器接口和事件處理器接口都在org.xml.sax包中定義。XMLReader即為sax定義的解析器接口,由解析器提供商實現該借口,應用程序需要做的是編寫一個事件處理器。可以通過XMLReader的setContentHandler()方法來設置一個事件處理器的實例。

    與dom類似,jaxp也為sax解析器提供了抽象工廠類SAXParserFactory類,sax解析器工廠類的實例與dom解析器工廠類的實例類似,都是通過newInstance()方法來創建,不同的是SAXParserFactory的newInstance()方法查找的工廠類屬性是:javax.xml.parsers.SAXParserFactory。同樣,獲取sax解析器實例的方法,可以通過調用newSAXParser()。

    使用SAXParser和XMLReader都可以用來對xml文檔進行解析,前者只是對后者又一次的包裝。

    3.3 JDOM

    dom被設計用于完成幾乎所有的xml操作任務,同時又是與語言無關的,這就導致dom的api龐大而且復雜。為了使java程序員更方便地處理xml文檔,兩位國外的java技術專家創建了jdom。用developerworks上的一句話,“延續開源社群有需要就創建工具的歷史傳統,Java 技術專家 Jason Hunter 和 Brett McLaughlin 締造了 JDOM”。所以可以認為,jdom是一種專門用于java語言解析xml文檔的開放源代碼框架。

    jdom也使用對象樹來表示xml文檔,底層使用sax解析器分析xml文檔,形成jdom樹。

    3.4 DOM4J

    同jdom一樣,dom4j也是應用于java平臺,提供簡單、靈活的處理xml文檔的開發源代碼庫。很有意思的是,dom4j是由早期開發jdom的人分離出來而后獨立開發的,(利益或意見不和?呵呵)與jdom相比,dom4j提供了更好的靈活性。從網上的評論可以看出,dom4j從性能、功能、易用性上都優于jdom,可以作為解析xml文件的首選。(看來后來分離出的那撥人選擇還是正確的!)流行的hibernate,jaxm都采用了dom4j處理xml文件。

    dom4j也使用sax解析器來分析xml文檔,形成dom4j樹;它也提供了用于大文檔的基于事件的處理模型。

    所以可以看出,jdom和dom4j只是開源社區產生出來的方便地解析xml的框架或工具,并沒有創造新的xml解析方式。如果拿

    拿以上四種解析xml的方法比較,用孫鑫老師的話,如果你需要頻繁更換解析器就是jaxp方式,否則推薦使用dom4j。

    posted @ 2011-05-22 11:25 kangaroo 閱讀(744) | 評論 (0)編輯 收藏

    2011年4月24日

    netstat -an 查詢所有連接和監聽端口

    lsof -i :port,使用lsof -i :port就能看見所指定端口運行的程序,同時還有當前連接。 


    posted @ 2011-04-24 15:10 kangaroo 閱讀(256) | 評論 (0)編輯 收藏

    2011年4月23日

    OAuth通過應用和微博授權頁面之間的跳轉來進行授權. 其步驟為

    1. 應用向微博平臺發起請求,獲得一個臨時的oauth_token,和oauth_token_secret(A),這套key被稱為request token.
    2. 應用將用戶轉向到微博授權頁面,同時帶上這個token和一個回調頁面地址
    3. 用戶在微博上同意授權后,會生成oauth_verifier(B),并在轉向到回調頁面是帶上這個值.
    4. 應用通過$_REQUEST得到oauth_verifier,再加上之前(A)處的oauth_token和oauth_token_secret,向微博發起最后一次請求.
    5. 微博平臺驗證無誤后,發給應用另外一套oauth_token和oauth_token_secret(C),這套key被成為access token.
    6. 拿到access token意味著應用已經獲得了授權.之后應用就可以通過access token獲取和發送微博了.

    access token不用每次都去取,可以把它保存下來,供下次使用.這樣性能更高.

    posted @ 2011-04-23 19:57 kangaroo 閱讀(613) | 評論 (0)編輯 收藏

    2011年4月20日

    pwd

    posted @ 2011-04-20 21:08 kangaroo 閱讀(430) | 評論 (0)編輯 收藏

    2011年4月18日

    sudo mysqld_safe 
    sudo mysqladmin shutdown

    posted @ 2011-04-18 22:24 kangaroo 閱讀(1245) | 評論 (0)編輯 收藏

    2011年3月31日

    ll 命令查詢出來的文件大小 單位是byte,
    要想方便的查看出大小,使用“ll -h”

    posted @ 2011-03-31 19:05 kangaroo 閱讀(341) | 評論 (0)編輯 收藏

    2011年3月29日

    ctrl+shift+j:類似firebug的功能,開發時很實用
    如果覺得太過復雜,可以使用firebug for chrome的插件,快捷F12,相當方便!

    posted @ 2011-03-29 22:31 kangaroo 閱讀(287) | 評論 (0)編輯 收藏

    2011年2月17日

    自動換行:ctrl+shift+w

    posted @ 2011-02-17 11:47 kangaroo 閱讀(233) | 評論 (0)編輯 收藏

    2011年1月10日

    XMind 快捷鍵

    快捷鍵(Windows)

    快捷鍵(Mac)

    描述

    Ctrl+N Command+N 建立新工作簿
    Ctrl+O Command+O 開啟工作簿
    Ctrl+S Command+S 儲存目前工作簿
    Ctrl+Shift+S Command+Shift+S 儲存全部工作簿
    Ctrl+W Command+W 關閉目前工作簿
    Ctrl+Shift+W Command+Shift+W 關閉全部工作簿
    Ctrl+P Command+P 列印
    Ctrl+Z Command+Z 復原
    Ctrl+Y Command+Y 重做
    Ctrl+X Command+X 剪切
    Ctrl+C Command+C 複製
    Ctrl+V Command+V 貼上
    Delete Delete 刪除
    Ctrl+Home Command+Home 返回中心主題
    Ctrl+A Command+A 選擇全部主題
    Ctrl+Shift+A Command+Shift+A 選擇同層級主題
    Ctrl+Alt+A Command+Alt+A 選擇子主題
    Ctrl+F Command+F 尋找/取代
    Ctrl++ Command++ 放大
    Ctrl+- Command+- 縮小
    Ctrl+= Command+= 正常大小
    Ctrl+] Command+] 插入摘要
    Alt+Enter Alt+Enter 屬性內容
    Enter Enter 插入主題
    Tab Tab 插入子主題
    Shift+Enter Shift+Enter 在目前主題前插入主題
    Ctrl+Enter Command+Enter 插入目前主題父主題
    Ctrl+Shift+L Command+Shift+L 快捷鍵助手
    Ctrl+I Ctrl+I 插入圖片
    Ctrl+Shift+H Command+Shift+H 插入超連結
    Ctrl+B Command+B 添加外框
    Ctrl+L Command+L 添加關連
    F2 F2 編輯主題
    F3 F3 添加/編輯標籤
    F4 F4 添加/編輯備註
    F5 F5 簡報演示
    F6 F6 下鑽
    Shift+F6 Shift+F6 上鑽
    F7 F7 智慧擷取圖面
    + + 展開目前分支
    - - 收縮目前分支
    * * 展開所有分支
    / / 收縮所有分支
    Alt+Up Alt+Up 向前移動
    Alt+Down Alt+Down 向後移動
    Ctrl+T Command+T 建立新心智圖
    Ctrl+1,2,3,4,5,6 Command+1,2,3,4,5,6 快速添加優先等級圖標
    Esc Esc 關閉跳出的備註對話框 / 取消擷圖
    Ctrl+滑鼠滾輪 Command+滑鼠滾輪 放大縮小目前的圖面

    posted @ 2011-01-10 09:55 kangaroo 閱讀(5622) | 評論 (0)編輯 收藏

    2010年12月17日

    ASCII是最初的計算機指定的一套符號編碼,使用一個字節其中的7位,128個數值代表不同字符,對于英語這個已經是足夠,
    但是對于其他國家的語言,卻遠遠不夠,如漢語,日語,韓語,所以就出現了非ASCII的字符編碼,如gbk2312,gbk的漢字編碼。這些非ascii的編碼都是兼容ascii128個符號編碼的。

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

    UNICODE首先只是一個字符集,它的出現就是因為各個國家出臺自己的語言編碼,為了統一這些所有語言,可以理解unicode是涵蓋各個國家字符的集合,現在的規模可以容納100多萬個符號。需要說明的是,定長編碼便于計算機處理(注意GB2312/GBK不是定長編碼),而unicode又可以用來表示所有字符,所以在很多軟件內部是使用unicode編碼來處理的,比如java。
    unicode只是一個符號集,只規定了符號的二進制代碼,卻沒有規定這個二進制代碼應該如何存儲,即編碼方式,常見的有utf-8和utf-16。
    (如果unicode規定,每個符號用三個字節表示,那么英文字母只占用一個字節,就浪費很多存儲空間。)
    UTF-8就是一種變長的編碼方式,它使用1~4個字節表示一個符號,根據不同的符號而變化字節長度。


    我們常用的記事本功能,在"save as"的時候,可以選擇不同的編碼方式,里面有四個選擇:ansi,unicode,unicode big endian,utf-8:
    1.ANSI是默認的編碼方式。對于英文文件是ASCII編碼,對于簡體中文文件是GB2312編碼(只針對Windows簡體中文版,如果是繁體中文版會采用Big5碼)。
    2.Unicode編碼指的是UCS-2編碼方式,即直接用兩個字節存入字符的Unicode碼。這個選項用的little endian格式。

    3.Unicode big endian編碼與上一個選項相對應。我在下一節會解釋little endian和big endian的涵義。

    4.UTF-8編碼,也就是上一節談到的編碼方法。



    參考:

    http://www.cnblogs.com/pony/archive/2009/02/05/1384323.html
    http://blog.chinaunix.net/u1/56156/showart_2245355.html
    http://liaoshaoyao.javaeye.com/blog/667056

    posted @ 2010-12-17 10:50 kangaroo 閱讀(1235) | 評論 (0)編輯 收藏

    2010年12月16日

    MD5是一種摘要生成算法,本來不能用于簽名,但是在待簽名數據之后加上一串私密內容,即散列碼,就可以用于簽名了。但是md5只能做到防篡改的功能,不能做到防抵賴,因為這串私密內容雙方是都知道的。

    DSA和RSA是一種非對稱加密算發,簽名密鑰分為公鑰和私鑰。私鑰用于加密,公鑰用于驗證簽名。使用這種算法的簽名即起到防篡改的功能,又起到防抵賴的作用。因為私鑰只有簽名者自己獨有。

    posted @ 2010-12-16 11:43 kangaroo 閱讀(4971) | 評論 (1)編輯 收藏

    2010年12月14日

    /*給創建bitmap index分配的內存空間參數,以加速建索引*/

    show parameter create_bit;

    /*改變索引的存儲參數*/

    alter index index_name pctfree 30 storage(initial 200k next 200k);

    /*給索引手工分配一個分區*/

    alter index index_name allocate extent (size 200k datafile '$ORACLE/oradata/..');

    /*釋放索引中沒用的空間*/

    alter index index_name deallocate unused;

    /*索引重建*/

    alter index index_name rebuild tablespace tablespace_name;

    /*普通索引和反轉索引的互換*/

    alter index index_name rebuild tablespace tablespace_name reverse;

    /*重建索引時,不鎖表*/

    alter index index_name rebuild online;

    /*給索引整理碎片*/

    alter index index_name COALESCE;

    /*分析索引,事實上是更新統計的過程*/

    analyze index index_name validate structure;

    desc index_state;

    drop index index_name;

    alter index index_name monitoring usage;-----監視索引是否被用到

    alter index index_name nomonitoring usage;----取消監視

    /*有關索引信息的視圖*/

    select * from dba_indexes/dba_ind_columns/dbs_ind_eXPressions/v$object_usage;

    ########## 數據完整性的治理(Maintaining data integrity) ##########

    alter table table_name drop constraint constraint_name;----drop 約束

    alter table table_name add constraint constraint_name primary key(column_name1,column_name2);-----創建主鍵

    alter table table_name add constraint constraint_name unique(column_name1,column_name2);---創建唯一約束

    /*創建外鍵約束*/

    alter table table_name add constraint constraint_name foreign key(column_name1) references table_name(column_name1);

    /*不效驗老數據,只約束新的數據[enable/disable:約束/不約束新數據;novalidate/validate:不對/對老數據進行驗證]*/

    alter table table_name add constraint constraint_name check(column_name like 'B%') enable/disable novalidate/validate;

    /*修改約束條件,延時驗證,commit時驗證*/

    alter table table_name modify constraint constraint_name initially deferred;

    /*修改約束條件,立即驗證*/

    alter table table_name modify constraint constraint_name initially immediate;

    alter session set constraints=deferred/immediate;

    /*drop一個有外鍵的主鍵表,帶cascade constraints參數級聯刪除*/

    drop table table_name cascade constraints;

    /*當truncate外鍵表時,先將外鍵設為無效,再truncate;*/

    truncate table table_name;

    /*設約束條件無效*/

    alter table table_name disable constraint constraint_name;

    alter table table_name enable novalidate constraint constraint_name;


    簡潔實用,謝謝http://wfly2004.blog.163.com/blog/static/11764272010629114155174/

    http://hi.baidu.com/zhangcheng1/blog/item/54deb0cc9ab69d1701e9281e.html

    posted @ 2010-12-14 17:45 kangaroo 閱讀(10052) | 評論 (0)編輯 收藏

    2010年12月12日


    找到一份比較清楚的文章:
    同事寫過的記錄數組的用法,很棒!
    |grep ","|awk -F ","  '{print $10}'| awk -F ":" '{hist[$1]++} END{for(i in hist) printf "%s %d\n", i, hist[i]}'

    posted @ 2010-12-12 20:44 kangaroo 閱讀(985) | 評論 (0)編輯 收藏

    早上去博庫看了一會PHP+Mysql核心開發的書,研一的時候就是這本書搞定的課程設計。
    php,服務器端腳本語言。每次請求之后,先由web服務器解釋執行后,在以html輸出到客戶端。
    相對于java sverlet容器的tomcat,php的編譯引擎可以嵌入到apache或iis這類web服務器中。

    posted @ 2010-12-12 15:57 kangaroo 閱讀(279) | 評論 (0)編輯 收藏

    2010年10月12日

    今天在使用淘寶openapi做試驗,通過nick查詢用戶的其他公開信息,在eclipse中java application運行測試類沒有問題,但是放在web工程中就不行了,jetty啟動工程后報錯:一些taobao.api中的類如DefaultTaobaoClient,UserGetRequest不存在。

     
    研究一下發現,因為在eclipse里面,淘寶api的jar包是以第三方jar的形式導入進來的,所以在eclipse中訪問是沒有問題的,但是如果是web工程打包時,是不包括第三方jar包的,所以結果是,不論是jetty還是tomcat中啟動都會出現第三方jar的類無法找到的錯誤。

    解決的辦法是,將這些第三方jar包install到本地maven庫,命令如:
    mvn install:install-file -Dfile=E:/08_library/taobao_sdk/taobao-sdk-java/taobao-sdk-java.jar -DgroupId=tanlun.taobao.openapi -DartifactId=taobaosdk -Dversion=0.2 -Dpackaging=jar
    之后在web工程的pom.xml文件中加入對該jar的依賴,這樣重新mvn eclipse:eclipse,之后再mvn jetty:run就沒有問題了。

    posted @ 2010-10-12 16:09 kangaroo 閱讀(1653) | 評論 (0)編輯 收藏

    2010年10月9日

    簡單的說,jvm的堆是存放對象的地方,棧存放的是基本數據類型和對象的引用。jvm棧是運行時的單位,jvm堆是存儲的單位。java中每個線程都有一個棧與之對應,這個很容易理解,每一個線程都有其特殊的執行流程邏輯,因此需要一個獨立的線程棧與之對應。jvm棧因為是運行時單位,所以里面存儲的信息都是跟當前線程相關的東西,如局部變量、運行時狀態,返回值等。而jvm堆是真正存放數據的地方,多個jvm棧可以共享堆中的數據。
    jvm堆和棧分離的好處,從軟件設計的角度看,棧代表處理邏輯,堆代表數據,分而治之,邏輯更加清楚。因為堆中的內容可以被共享,節省了空間。從面向對象的角度,對象的屬性,即數據,被存放在堆中,而對象中的方法,則是運行邏輯,存放在棧中。
    平時我們在eclipse啟動程序,我們可以通過-Xms,-Xmx來設置大小,其實是在設置初始堆空間,和最大堆空間的大小。

    posted @ 2010-10-09 17:19 kangaroo 閱讀(552) | 評論 (0)編輯 收藏

    2010年9月25日

    本想就OAUTH進行一下流程分析,看到原網站的內容已經足夠簡明,請訪問:
    然后看下中文的:

    明白了OAUTH的工作原理之后,我就在想,現在原有的webservice的方式,不是也可以實現不同網站之間通過api的形式來資源共享嗎,那OAUTH又有什么好處了。
    看了一些文章之后,我的認識可能是,在跨語言的webservice調用時,實現細節上還是有很多差異,特別是復雜的對象類型。
    轉換成REST方式的服務之后,對服務的發布者和使用者來說都是輕量級的。
    那OAUTH正是在REST基礎上api的安全校驗和授權的一種方式。

    posted @ 2010-09-25 16:00 kangaroo 閱讀(1178) | 評論 (0)編輯 收藏

    spring給我們提供了非常簡便的線程池管理的包裝類ThreadPoolTaskExecutor,本地啟動一個為異步任務創建線程池的方法:
     
    1<bean id="threadPoolTaskExecutor"
    2        class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
    3        <property name="corePoolSize" value="5" />
    4        <property name="maxPoolSize" value="10" />
    5        <property name="queueCapacity" value="25" />
    6    </bean>
    corePoolSize:默認開啟線程數;maxPoolSize:最大線程數;queueCapacity:緩沖任務隊列的長度;
    創建線程的方式:
    1threadPoolTaskExecutor.execute(new Runnable() {
    2                public void run() {
    3                   //異步任務
    4                }
    5            });

    posted @ 2010-09-25 11:29 kangaroo 閱讀(7956) | 評論 (0)編輯 收藏

    2010年9月9日

    本地起tomcat之后,配置服務器也可以使用https協議訪問的方式是方便:

    1. 創建證書
        進入到你的jre/bin文件夾下,鍵入“keytool -genkey -alias tomcat -keyalg RSA -keystore c:/.keystore”,默認將把證書保存在你的C盤根目錄下。在申請的過程中密碼請填寫“changeit”,這是tomcat的默認密碼。
    2. 修改server.xml
        進入到你的$CATALINA_HOME/conf/server.xml,打開后尋找:
    <!-- Define a SSL HTTP/1.1 Connector on port 8443 -->
        
    <!--
        <Connector port="8443" maxHttpHeaderSize="8192"
                   maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
                   enableLookups="false" disableUploadTimeout="true"
                   acceptCount="100" scheme="https" secure="true"
                   clientAuth="false" sslProtocol="TLS" />
    -->
        修改如下:
    <!-- Define a SSL HTTP/1.1 Connector on port 8443 -->
        
        
    <Connector port="8443" maxHttpHeaderSize="8192"
                   maxThreads
    ="150" minSpareThreads="25" maxSpareThreads="75"
                   enableLookups
    ="false" disableUploadTimeout="true"
                   acceptCount
    ="100" scheme="https" secure="true"
                   clientAuth
    ="false" sslProtocol="TLS" keystoreFile="c:\.keystore"/>
    3. 重啟你的tomcat,使用端口8443訪問即可。

    posted @ 2010-09-09 10:45 kangaroo 閱讀(686) | 評論 (0)編輯 收藏

    2010年9月5日

    剛開始的時候經常會把這兩類的方法搞混了,慢慢接觸多了,一定要弄清楚了。
    (1)管理線程的方法
    start:不用多說,啟動一個線程的方法。調用該方法后,線程即進入可運行狀態,也就是進入可運行的線程池了。
    sleep:線程休眠,將一個運行時的線程,將其狀態變為可運行狀態,然后加入到和其他處于可運行狀態下的線程搶奪運行機會。換句話說,sleep的時間是該線程不執行的最短時間。
    yield:使得當前線程進入可運行狀態,以允許具有相同狀態優先級的其他線程獲得運行機會。但是不保證,剛進入可運行狀態,又被選中進入運行狀態。
    join:非靜態方法join,有點搶線程的意思。一旦某個線程實例t調用join方法,則當前線程變為可運行狀態,直到線程t運行完畢為止。
    (2)線程間協作的方法

    posted @ 2010-09-05 23:06 kangaroo 閱讀(530) | 評論 (0)編輯 收藏

    在平時開發中,我們經常采用HashMap來作為本地緩存的一種實現方式,將一些如系統變量等數據量比較少的參數保存在HashMap中,并將其作為單例類的一個屬性。在系統運行中,使用到這些緩存數據,都可以直接從該單例中獲取該屬性集合。但是,最近發現,HashMap并不是線程安全的,如果你的單例類沒有做代碼同步或對象鎖的控制,就可能出現異常。

    首先看下在多線程的訪問下,非現場安全的HashMap的表現如何,在網上看了一些資料,自己也做了一下測試:

     1public class MainClass {
     2    
     3    public static final HashMap<String, String> firstHashMap=new HashMap<String, String>();
     4    
     5    public static void main(String[] args) throws InterruptedException {
     6        
     7        //線程一
     8        Thread t1=new Thread(){
     9            public void run() {
    10                for(int i=0;i<25;i++){
    11                    firstHashMap.put(String.valueOf(i), String.valueOf(i));
    12                }

    13            }

    14        }
    ;
    15        
    16        //線程二
    17        Thread t2=new Thread(){
    18            public void run() {
    19                for(int j=25;j<50;j++){
    20                    firstHashMap.put(String.valueOf(j), String.valueOf(j));
    21                }

    22            }

    23        }
    ;
    24        
    25        t1.start();
    26        t2.start();
    27        
    28        //主線程休眠1秒鐘,以便t1和t2兩個線程將firstHashMap填裝完畢。
    29        Thread.currentThread().sleep(1000);
    30        
    31        for(int l=0;l<50;l++){
    32            //如果key和value不同,說明在兩個線程put的過程中出現異常。
    33            if(!String.valueOf(l).equals(firstHashMap.get(String.valueOf(l)))){
    34                System.err.println(String.valueOf(l)+":"+firstHashMap.get(String.valueOf(l)));
    35            }

    36        }

    37        
    38    }

    39
    40}

    上面的代碼在多次執行后,發現表現很不穩定,有時沒有異常文案打出,有時則有個異常出現:


    為什么會出現這種情況,主要看下HashMap的實現:
     1public V put(K key, V value) {
     2    if (key == null)
     3        return putForNullKey(value);
     4        int hash = hash(key.hashCode());
     5        int i = indexFor(hash, table.length);
     6        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
     7            Object k;
     8            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
     9                V oldValue = e.value;
    10                e.value = value;
    11                e.recordAccess(this);
    12                return oldValue;
    13            }

    14        }

    15
    16        modCount++;
    17        addEntry(hash, key, value, i);
    18        return null;
    19    }

    我覺得問題主要出現在方法addEntry,繼續看:
    1void addEntry(int hash, K key, V value, int bucketIndex) {
    2    Entry<K,V> e = table[bucketIndex];
    3        table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
    4        if (size++ >= threshold)
    5            resize(2 * table.length);
    6    }

    從代碼中,可以看到,如果發現哈希表的大小超過閥值threshold,就會調用resize方法,擴大容量為原來的兩倍,而擴大容量的做法是新建一個Entry[]:
     1void resize(int newCapacity) {
     2        Entry[] oldTable = table;
     3        int oldCapacity = oldTable.length;
     4        if (oldCapacity == MAXIMUM_CAPACITY) {
     5            threshold = Integer.MAX_VALUE;
     6            return;
     7        }

     8
     9        Entry[] newTable = new Entry[newCapacity];
    10        transfer(newTable);
    11        table = newTable;
    12        threshold = (int)(newCapacity * loadFactor);
    13    }

    一般我們聲明HashMap時,使用的都是默認的構造方法:HashMap<K,V>,看了代碼你會發現,它還有其它的構造方法:HashMap(int initialCapacity, float loadFactor),其中參數initialCapacity為初始容量,loadFactor為加載因子,而之前我們看到的threshold = (int)(capacity * loadFactor); 如果在默認情況下,一個HashMap的容量為16,加載因子為0.75,那么閥值就是12,所以在往HashMap中put的值到達12時,它將自動擴容兩倍,如果兩個線程同時遇到HashMap的大小達到12的倍數時,就很有可能會出現在將oldTable轉移到newTable的過程中遇到問題,從而導致最終的HashMap的值存儲異常。

    JDK1.0引入了第一個關聯的集合類HashTable,它是線程安全的。HashTable的所有方法都是同步的。
    JDK2.0引入了HashMap,它提供了一個不同步的基類和一個同步的包裝器synchronizedMap。synchronizedMap被稱為有條件的線程安全類。
    JDK5.0util.concurrent包中引入對Map線程安全的實現ConcurrentHashMap,比起synchronizedMap,它提供了更高的靈活性。同時進行的讀和寫操作都可以并發地執行。

    所以在開始的測試中,如果我們采用ConcurrentHashMap,它的表現就很穩定,所以以后如果使用Map實現本地緩存,為了提高并發時的穩定性,還是建議使用ConcurrentHashMap。


    ====================================================================

    另外,還有一個我們經常使用的ArrayList也是非線程安全的,網上看到的有一個解釋是這樣:
    一個 ArrayList 類,在添加一個元素的時候,它可能會有兩步來完成:1. 在 Items[Size] 的位置存放此元素;2. 增大 Size 的值。
    在單線程運行的情況下,如果 Size = 0,添加一個元素后,此元素在位置 0,而且 Size=1;
    而如果是在多線程情況下,比如有兩個線程,線程 A 先將元素存放在位置 0。但是此時 CPU 調度線程A暫停,線程 B 得到運行的機會。線程B也將元素放在位置0,(因為size還未增長),完了之后,兩個線程都是size++,結果size變成2,而只有items[0]有元素。
    util.concurrent包也提供了一個線程安全的ArrayList替代者CopyOnWriteArrayList。
    
    

    posted @ 2010-09-05 17:12 kangaroo 閱讀(12198) | 評論 (5)編輯 收藏

    2010年8月17日

    基本:
    1. find -name #filename#:按文件名在本目錄下的所有文件里查找指定名字的文件,可用正則。
    2. more #filename#:更方面的查看文件的命令。進入后命令,"d":向下滾動;"b":向上滾動。
    3. vi #filename#:一般的文件編輯命令。進入后命令
        "/abc":查找"abc",所有匹配"abc"的地方都會高亮顯示。

    4. vi替換文件中所有“abc”為“def”命令:

       %s/abc/def/g 其中%表示替換所有行,g表示替換每一行所有匹配的字符串

    技巧:
    1. ll -t:按修改時間的先后排序文件。

    posted @ 2010-08-17 13:53 kangaroo 閱讀(582) | 評論 (0)編輯 收藏

    2010年8月6日

    持續記錄下自己遇到的java編碼技巧:

    1. java.util.List.addAll(Collection<? extends String> c)

    public static void main(String[] args) {

            List
    <String> firstList = new ArrayList<String>();
            firstList.add(
    "a");
            firstList.add(
    "b");
            firstList.add(
    "c");

            List
    <String> secondList = new ArrayList<String>();
            secondList.addAll(firstList);

            
    for (String s : secondList) {
                System.out.println(s);
            }

        }

    posted @ 2010-08-06 19:15 kangaroo 閱讀(341) | 評論 (0)編輯 收藏

    2010年8月3日

    1. 前言
    2. webservice的由來
    3. java領域可用于實現遠程通訊的開源框架或library
    4. 基于XFire的webservice的本地實現


    附件下載:
    (1)http://www.tkk7.com/Files/lukangping/webservice.pdf
    (2)......

    posted @ 2010-08-03 19:22 kangaroo 閱讀(252) | 評論 (0)編輯 收藏

    2010年8月1日

    記得在當時學習uml總是不好分清聚合與組合的關系,找工作時特地復習了這塊的內容,結果正巧被面試官問道,這兩天又在搞這塊的內容,對聚合與組合有了更清楚的了解:

    聚合:表示兩個對象之間是整體和部分的關系,部分的生命周期可以超越整體。如電腦和鼠標,就可以用一下圖形表示:



    組合:表示兩個對象之間是整體和部分的關系,部分的生命周期不能超越整體,或者說不能脫離整體而存在。組合關系的“部分”,是不能在整體之間進行共享的。如人和眼睛的關系:

    不過,如果你要說,眼睛可以移植,是不是說可以脫離人而存在,它們就不是組合關系了?其實,UML中對象的關系都是在相應的軟件環境或實際場景下定義的,這里區別聚合和組合的關系,關鍵還是在于它們之中整體和部分的關系強、弱,以及它們之間的依附關系。如果剛才說眼睛可以移植給別人,那你也可以把它認為是聚合,這都要結合實際場景來說明。

    另外兩個比較重要的關系是關聯和依賴:
    關聯:簡單的可以認為,如果一個類作為了另外一個類的屬性,那一定是關聯關系。但你要知道,聚合是一種特殊的關聯,而組合又是一種特殊的聚合。一般的關聯我們認為是平級的、無整體部分關系的,如朋友關系。

    依賴:對象之間的臨時關系,臨時性體現在不超越方法的周期。簡單的說,在方法使用到的,如參數類,就一定是依賴關系。

    最后想說一句,實際工作中,我并沒有發現區分這四種關系有多么大的用處,也許自己還沒有碰到,只是覺得可能每個學習它的同學總想把它搞清楚,但實際工作中作用并不明顯。

    posted @ 2010-08-01 14:17 kangaroo 閱讀(27101) | 評論 (5)編輯 收藏

    打開visio想創建一個類圖,卻發現沒有找到UML Model Diagram,從網上看到可以在UML Static Structure里找到“Class”,但是發現使用起來很不方便,甚至不好增加類名,就在網上搜索一下,中文的沒有提到,就搜索了一下“uml model diagram  template download”,在
    http://softwarestencils.com/uml/index.html#Visio2007
    找到了需要的template,然后解壓到"C:\Documents and Settings\<user name>\My Documents\My Shapes",重新啟動Visio,默認的快速創建頁面就有UML Model Diagram。That is it!

    posted @ 2010-08-01 13:41 kangaroo 閱讀(2247) | 評論 (1)編輯 收藏

    2010年7月29日

    同標題,持續記錄一些eclipse的高級快捷鍵,提高你的“專業性”,成為快捷鍵達人:

    慢慢發現很多軟件的快捷鍵都是相似的,用得多了,你就不用費腦子記了,這個很不錯。

    1. ctrl+滾輪:加快瀏覽速度;
    2. ctrl+w:關閉當前的Editor;
    3. ctrl+e:顯示隱藏的Editor;
    4. ctrl+f6:切換editor;
    5. ctrl+f7:切換view;
    6. ctrl+f8:切換perspectives;
    7. ctrl+shift+x:小寫變大寫;ctrl+shift+y:大寫變小寫
    8. ctrl+1:出現紅叉時,鼠標放置在該行,使用這個快捷鍵迅速彈出錯誤提示

    9. ctrl+shift+c:注釋xml里配置

    SecureCRT中常用的快捷鍵:

    1. ctrl+tab:標簽直接的切換;
    2. alt+1/2/3..:切換至第n個標簽;


    Chrome必會快捷鍵 bravo chrome! i like so much!
    1. ctrl+t:新建標簽;ctrl+n:新開窗口
    2. ctrl+w:關閉當前標簽頁
    3. ctrl+tab:切換到下個標簽;ctrl+shift+tab:切換到上一個標簽
    4. ctrl+1/2/../8:切換至指定標簽
    5. f6:聚焦鼠標至地址欄,這個各個瀏覽器都一樣。

    more:http://news.xinhuanet.com/internet/2008-09/07/content_9822978.htm
    existing: 新建標簽打開后,你會看到8個最近訪問的網站,首先,可以用tab切換,另外,它們的位置可以拖拽、可以刪改,還不讓你興奮嗎?


    posted @ 2010-07-29 14:09 kangaroo 閱讀(2124) | 評論 (0)編輯 收藏

    2010年7月28日

    Exception in thread “main” org.codehaus.xfire.XFireRuntimeException: Could not  invoke service.. Nested exception is org.codehaus.xfire.fault.XFireFault: There must be a method name element.

    解決辦法還是很簡單:將wsdlURL后面的”?wsdl”去掉即可:

    Service serviceModel = new ObjectServiceFactory().create(MyService.class);
    MyService service = (MyService) new XFireProxyFactory().create(serviceModel,
                “http://localhost:8080/ninthDemo/services/myService“);

    posted @ 2010-07-28 13:25 kangaroo 閱讀(860) | 評論 (0)編輯 收藏

    2010-07-19 16:17:42.670::WARN:  failed HandlerCollection@7f8922
    java.lang.UnsupportedClassVersionError: Bad version number in .class file

    使用mvn clean情況一下編譯好的文件,重新mvn jetty:run就好了。

    posted @ 2010-07-28 13:24 kangaroo 閱讀(421) | 評論 (0)編輯 收藏

    通常我們聽到的代理大致有三類:http/s proxy, socks proxy and VPN (實際上不是代理)。

    其中http/s proxy, socks proxy屬一類,作為代理服務器,它們類似一種網絡訪問的中介,每次我們訪問一個web網站時,實際上時先去訪問代理服務器,再由代理服務器訪問目標網站。而且這樣是匿名,也就是說被請求的網站并不知道你的原始的訪問地點在哪里。網上流傳的gappproxy翻墻就是一個典型的例子,在gae上建立一個代理服務器fetchserver后,然后在本機開啟gappproxy的代理程序,每次訪問任何網站時,其實是把請求發給代理服務器,然后由代理服務器去請求目標網站,因為gae都是在美國的服務器,同時目前訪問gae還是ok的,所以整個過程都是沒問題的。(我們知道GFW是通過黑名單來過濾訪問指定網站的數據包,如果把gae服務器也納入黑名單,那就杯具了。)

    如果只是網上沖浪或者通過瀏覽器使用的活動,那樣的話http/s proxy就可以了,像GAE中的gappproxy就是其中的一個例子。如果你需要做更多的事情,而不僅僅是websurf,那樣就需要使用socks proxy,它能更靈活地為你提供除了網頁瀏覽其他的一些功能。那VPN又是什么呢?VPN,Virtual private Network,中文名是“虛擬專用網絡”。一個簡單的解釋就是,在公共網絡中建立的兩點之間的專用的虛擬隧道。也可以理解為虛擬出來的企業內部專線。安全通信是通過加密來保證的,加密算法運用運用于你的實時通信中,保證在公用的網絡中兩點之間的數據通信不被其他人截取或訪問,也就是說,在兩點之間建立了一個專用的“隧道”。

    相比較來看,proxy server有很多的免費的解決方案,它也能提供匿名的web browsing。但是,安全性就差很多,你和代理服務器之間的通訊是完全透明的。(SSL proxy可以進行適當的保護),與VPN相比,代理的速率也比較低。VPN比http/s proxy和socks proxy的安全性就高很多了。VPN需要更多的硬件和軟件來支持,所以它是需要付費的。當然它的速率也是最高。除此之外,VPN加密本臺機器上的所有網絡通信,包括你的browsing,email,voip,chat等所有網絡傳輸。而不像http/s proxy只對你的瀏覽器訪問web網站做代理。

    以上文字參考:

    《Proxy vs VPN… Who wins?》

    《what is a VPN service?》

    posted @ 2010-07-28 13:23 kangaroo 閱讀(2649) | 評論 (0)編輯 收藏

    2010年7月27日

    blogjava的博客半年前玩的,后來忙了就忘了,發現有些內容之前寫下的,現在都不認識,學到的知識沒有延續,所以今天特意整理一下文章分類,慢慢使得自己在技術方面的積累不斷的形成體系。

    posted @ 2010-07-27 22:53 kangaroo 閱讀(225) | 評論 (0)編輯 收藏

    2009年11月1日

    Pure Pleasure - Reborn © 2008 - 轉載本文時請保留此鏈接。

    1. 培養耐心

    自信確實需要培養,所謂的“培養”,即是說并非朝夕可達。所以,培養自信的最重要前提就是要具備耐心,如若缺乏耐心就要培養耐心。沒有耐心的話就什么都做不成,更別提什么“自信了”。有所成就,就會伴隨著自信的增長,而一事無成的人穿得再整齊也只不過草包一個。

    2. 習得并精通一種技能

    具備學習能力的人通常都很自信,反過來也一樣,真正自信的人通常是因為相信自己的學習能力。所以面對挑戰的時候他們不會怕,不會心虛,因為他們知道“大不了去學么”。自學能力的基礎是耐心,而習得任何一種技能都會讓人更加懂得耐心的重要,并且同時因為具備耐心與學習能力而更加自信。只要花時間真正精通了一種技能,那么學會其他一種技能的時候就會變得更輕松——這是良性循環。

    --遇到枯燥,不好玩的東西,能夠靜下心來,耐心地去學習、去體會,這個應該是學習能力強和弱的差別之處吧。
    --久而久之,學習快的人,會將這種經驗不斷推廣,一門通,樣樣通。而在一方面沒有成就的人,會慢慢產生了厭煩的情緒,在拒絕學習的同時,也就表現出在這個方面的自卑了。

    3. 相信積累的力量
    再大的石頭也無法阻擋種子發芽,只因為種子一旦開始發芽,那細胞的分裂盡管速度不快但卻不見天日永不終止。滴水可以穿石的道理誰都懂但又好像誰都不相信—— 處于起點的人就好像是一粒細胞或者一滴水,但大多數人卻誤以為或者希望自己在起點上就強大鋒利猶如一束激光,但這不現實。要通過學習培養耐心,運用耐心去等待長期積累之后可以獲得的難以想象的好處與力量。


    --如果在某一方面學習的時候,就是不順利,或者就是理解不好的時候,這個時候,就是需要堅持的時候了。
    --記得自己學游泳,換氣總是不好,曾一度覺得我這輩子都學不會游泳了。但是總覺得好玩,雖然每次游都被會游的伙伴笑話,還不敢去深水呀?但也是當個玩笑聽了。后來,終于有一次,自己突然地發現,換氣換得很自然了,鼓足了勇氣去深水區游了一趟,那一天自己感覺到很開心,自信得很多。
    --任何事物的學習應該都有個“竅”,當一次,兩次,三次不理解時候,不需要急躁,明白看來這個東西不是那么簡單的,需要以后更多的閱讀或實踐才來理解透徹。

    4. 了解自己的局限

    沒有人無所不能。就算擁有真正強大學習能力的人也無法做到無所不能——因為時間不夠。有些領域確實必需天分。在自己確實不擅長的地方該自卑就要自卑——這沒有什么不好意思的。該自卑的時候不自卑,就多了一個心理負擔——并且還是永遠擺脫不掉的負擔,最終,肯定會拖累自信。凡事兒做得好必然容易自信,做得不好就很難自信,但是還沒上陣呢,就背著一個又一個的包袱,能走多遠?能做多好?

    --哎呀,這個東西實在跟我不投緣,這樣的話會讓自己輕松很多。(當然,這樣的話要在你堅持努力嘗試多次之后說了才有用)

    5. 凡事兒都要提前做足功課

    大聲說話也好,穿著正式也罷,最多只能讓一個人“顯得”自信,而非真正自信。“坐在第一排”可能是因為近視,“快速走路”往往是因為時間觀念不強——這些都與自信沒關系。做任何事情,提前做足了功課,想不自信都難。自信不等于自以為是,自以為是的人最終都會被現實砸爛。中國人說“成事在天,謀事在人”,西方人說“上帝的歸上帝,凱撒的歸凱撒”,某個層面上都是一回事兒:不要理會運氣(該來的時候它自然會來),重要的是專心做好功課。

    --查看線上錯誤日志的方法,會了嗎?還不趕緊去找?

    posted @ 2009-11-01 12:17 kangaroo 閱讀(459) | 評論 (0)編輯 收藏

    iBatis是一個中層的框架,它比jdbc的層次高一些(可以說,iBatis就是以XML的形式描述的jdbc代碼,它擁有許多jdbc所沒有的架構級的優點),但是對于對象/關系映射工具,層次又要低一些。

    1. 釋放數據庫資源
    使用jdbc時,很容易犯的錯誤就是獲取資源之后忘記正確地釋放它們。雖然垃圾收集進程最終可以釋放掉這些資源,但是這種做法非常耗時,并且無法得到保證。如果對象沒有別真正釋放,那應用程序最終將會因為耗盡了資源而崩潰。iBATIS框架能幫助管理這些資源,從而減輕應用程序對開發人員們的負擔

    2. SQL注入
    如果某個應用程序使用字符串拼接的方式來創建SQL語句,但是沒有正確地對參數進行轉義,那么惡意的用戶就可以通過傳遞一些特殊的參數來改變查詢原本的意圖。
    例如:select * from product where id = 5.
    如果5是用戶傳遞過來的參數,拼接到 id = 之后的。那么用戶就可以輸入"5 or 1 = 1",從而改變了整個SQL語句的意圖。如果用戶更壞一些,輸入"5;delete from orders",結果就是你的訂單表被清空了。
    由于ibatis使用了preparedStatement,而PreparedStatement是不會受到此類攻擊影響的,所以使用ibatis可以使得你對應用程序的保護變得更加容易。

    3. 降低復雜度

    posted @ 2009-11-01 11:28 kangaroo 閱讀(537) | 評論 (1)編輯 收藏

    2009年8月26日

    1. 發現你上司的性格和脾氣,向他的性格和行為方式靠攏。
    2. 如果上司對下面的人有什么小小的要求和幫助,作為下屬你一定要非常非常重視,這個很重要!

    posted @ 2009-08-26 09:21 kangaroo 閱讀(276) | 評論 (0)編輯 收藏

    2009年8月15日

    這篇文章寫在我研究J2SE、J2EE近三年后。前3年我研究了J2SE的Swing、Applet、Net、RMI、Collections、IO、JNI……研究了J2EE的JDBC、Sevlet、JSP、JNDI…..不久我發現這些好像太浮淺了:首先,我發現自己知道的僅僅是java提供的大量的API,根本不能很好地使用它; 其次,我根本就沒有學到任何有助于寫程序的知識,此時我也只不過能寫個幾頁的小程序。出于這個幼稚的想法我研究了JDK中Collections、Logger、IO…..的源代碼,發現這個世界真的很神奇,竟然有如此的高手――利用java語言最最基本的語法,創造了這些優秀的Framework。

    從此一發不可收拾,我繼續研究了J2EE的部分,又發現這是一個我根本不能理解的方向(曾經有半年停滯不前),為什么只有接口沒有實現啊!后來由于一直使用Tomcat、Derby等軟件突然發現:哦!原來J2EE僅僅是一個標準,只是一個架構。真正的實現是不同提供商提供的。

    接著我研究了MOM4J、OpenJMS、Mocki、HSQLD……發現這些就是J2EE的實現啊!原來軟件竟會如此復雜,竟會如此做….規范和實現又是如何成為一體的呢?通過上面的研究發現:原來J2EE后面竟然有太多太多理念、太多太多的相似!這些相似就是其背后的理念――設計模式!(很幸運,在我學java的時候,我一般學java的一個方向就會讀一些關于設計模式的書!很幸運,到能領略一點的時候能真正知道這是為什么!)其實模式就是一種思維方式、就是一種理念……模式是要運用到程序中的,只有從真正的項目中才能領會模式的含義……
    學得越多,發現懂得越少!在學習過程中發現一些很有用,很值得學習的開源項目,今天在此推薦給大家。

    一、JavaServlet和JSP方向

    很多人都是從Servlet和JSP步入J2EE的。它就是J2EE的表現層,用于向客戶呈現服務器上的內容。J2EE很重要的方面。不羅嗦了!大家都知道的!下面就開始推薦吧!

    1. Jakarta Tomcat

    Apache基金會提供的免費的開源的Serlvet容器,它是的Jakarta項目中的一個核心項目,由Apache、Sun和其它一些公司(都是IT界的大鱷哦)及個人共同開發而成,全世界絕大部分Servlet和Jsp的容器都是使用它哦!由于Sun的參與和支持,最新的Servlet和Jsp規范總能在Tomcat中得到體現。

    不過它是一個非常非常全的Serlvet容器,全部源碼可能有4000頁,對于初學者或者一般的老手可能還是比較大了!在你有能力時推薦研究!下載地址:http://jakarta.apache.org/tomcat/index.html

    下面推薦兩個小一點的吧!

    2. Jetty

    Jetty是一個開放源碼的HTTP服務器和Java serverlet容器。源代碼只有1000頁左右,很值得研究。有興趣可以去http://jetty.mortbay.com/下載看看。我曾經翻了一下,只是目前沒有時間。(都化在博客上了,等博客基本定型,且內容完整了,再干我熱衷的事件吧!)

    3. Jigsaw

    Jigsaw是W3C開發的HTTP,基于Java 的服務器,提供了未來 Web 技術發展的藍圖。W3C知道吧!(太有名氣了,很多標準都是它制訂的!有空經常去看看吧!)下載網址:http://www.w3.org/Jigsaw代碼僅僅1000頁左右。

    4. Jo!

    Jo!是一個純Java的實現了Servlet API 2.2, JSP 1.1, 和HTTP/1.1的Web服務器。它的特性包括支持servlet tag,支持SSI,高級線程管理,虛擬主機,數據緩存,自動壓縮text或HTML文件進行傳輸,國際化支持,自動重新加載Servlet、Jsp,自動重新加載web工程文件(WARs),支持WAR熱部署和一個Swing控制臺。jo!可以被用做jboss和jakarta avalon-phoenix的web容器。下載地址http://www.tagtraum.com/ 。我極力推薦大家在研究Tomcat之前研究該軟件,主要是其比Tomcat小多了,且開發者提供比較全的手冊。該方向研究這兩個也就可以了!

    二、JDBC方向

    很多人都喜歡JDBC,數據庫嗎!很深奧的東西,一聽就可以糊弄人。其實等你真正研究了數據庫的實現后發現,接口其實真的太簡單,太完美了!要想設計如此優秀的框架還是需要學習的。下面就推薦幾個數據庫的實現吧!

    1. Hypersonic SQL

    Hypersonic SQL開源數據庫方向比較流行的純Java開發的關系型數據庫。好像不是JDBC兼容的,JDBC的很多高級的特性都沒有支持,不過幸好支持ANSI-92 標準 SQL語法。我推薦它主要是它的代碼比較少1600頁左右,如此小的數據庫值得研究,而且他占的空間很小,大約只有160K,擁有快速的數據庫引擎。推薦你的第一個開源數據庫。下載地址:http://hsqldb.sourceforge.net/。

    2. Mckoi DataBase

    McKoiDB 和Hypersonic SQL差不多,它是GPL 的license的純Java開發的數據庫。他的 JDBC Driver 是使用 JDBC version 3 的 Specifaction。 他也是遵循 SQL-92 的標準,也盡量支持新的 SQL 特色, 并且支持 Transaction 的功能。兩個可以選一個吧!下載地址:http://mckoi.com/database/。

    3. Apache Derby

    學Java的數據庫我建議使用Apache Derby ,研究數據庫想成為一個數據庫的高手我建議你先研究Apache Derby。Apache Derby是一個高質量的、純 Java開發的嵌入式關系數據庫引擎,IBM® 將其捐獻給Apache開放源碼社區,同時IBM的產品CloudSpace是它對應的產品。Derby是基于文件系統,具有高度的可移植性,并且是輕量級的,這使得它非常便于發布。主要是沒有商業用戶的很好的界面,沒有其太多的功能。不過對于我們使用數據庫、研究數據庫還是極其有用的。對于中小型的企業說老實話你也不要用什么Oracle、SqlServer了,用Derby就可以了,何況是開源的呢!只要能發揮其長處也不容易啊!下載地址:http://incubator.apache.org/derby。

    不過在沒有足夠的能力前,不要試圖讀懂它!注釋和源代碼15000頁左右,我一年的閱讀量!能讀下來并且能真正領會它,絕對高手!你能讀完Derby的源代碼只有兩種可能:1.你成為頂尖的高手――至少是數據庫這部分; 2.你瘋了。選擇吧!!!!作為我自己我先選擇Hypersonic SQL這樣的數據庫先研究,能過這一關,再繼續研究Derby!不就是一年的閱讀量嗎!我可以化3年去研究如何做一個數據庫其實還是很值得的!有的人搞IT一輩子自己什么都沒有做,也根本沒有研究別人的東西!

    作為一個IT落后于別國若干年的、從事IT的下游產業“外包”的國家的IT從業人員,我認為還是先研究別人的優秀的東西比較好!可以先研究別人的,然后消化,學為己用!一心閉門造車實在遺憾!

    三、JMS方向

    JMS可能對大家來說是一個比較陌生的方向!其實JMS是一個比較容易理解,容易上手的方向。主要是Java消息服務,API也是相當簡單的。不過在企業應用中相當廣泛。下面就介紹幾個吧!

    1. MOM4J

    MOM4J是一個完全實現JMS1.1規范的消息中間件并且向下兼容JMS1.0與1.02。它提供了自己的消息處理存儲使它獨立于關系數據與語言,它的客戶端可以用任何語言開發。它可以算是一個小麻雀,很全實現也比較簡單!它包含一個命名服務器,一個消息服務器,同時提供自己的持續層。設計也相當的巧妙,完全利用操作系統中文件系統設計的觀念。代碼也很少,250頁左右,最近我在寫該實現的源代碼閱讀方面的書,希望明年年中能與大家見面!下載地址:http://mom4j.sourceforge.net/index.html。

    2. OpenJMS

    OpenJMS是一個開源的Java Message Service API 1.0.2 規范的實現,它包含有以下特性:
    1. 它既支持點到點(point-to-point)(PTP)模型和發布/訂閱(Pub/Sub)模型。

    2. 支持同步與異步消息發送 。

    3. JDBC持久性管理使用數據庫表來存儲消息 。

    4. 可視化管理界面。

    5. Applet支持。

    6. 能夠與Jakarta Tomcat這樣的Servlet容器結合。

    7. 支持RMI, TCP, HTTP 與SSL協議。

    8. 客戶端驗證 。

    9. 提供可靠消息傳輸、事務和消息過濾。

    很好的JMS方向的開源項目!我目前也在研究它的源代碼!學習它可以順便研究JNDI的實現、以及網絡通信的細節。這是我JMS方向研究的第二個開源項目。代碼量1600頁左右吧!下載地址:http://openjms.sourceforge.net/index.html

    3. ActiveMQ

    ActiveMQ是一個開放源碼基于Apache 2.0 licenced 發布并實現了JMS 1.1。它能夠與Geronimo,輕量級容器和任Java應用程序無縫的給合。主要是Apache的可以任意的使用和發布哦!個人比較喜歡Apache的源代碼!下載地址:http://activemq.codehaus.org/

    4. JORAM

    JORAM一個類似于openJMS分布在ObjectWeb之下的JMS消息中間件。ObjectWeb的產品也是非常值得研究的!下面我還會給大家另外一個ObjectWeb的產品。下載地址:http://joram.objectweb.org/

    我個人推薦:OpenJMS和ActiveMQ!

    四、EJB方向

    EJB一個比較“高級”的方向。Sun公司曾經以此在分布式計算領域重拳出擊。不過自從出現了Spring、Hibernation……后似乎沒落了!這個方向單獨開源的也比較少,主要EJB是和JNDI、JDBC、JMS、JTS、JTA結合在一起的是以很少有單獨的。下面推薦兩個不過好像也要下載其它類庫。

    1. EasyBeans

    ObjectWeb的一個新的項目,一個輕量級的EJB3容器,雖然還沒有正式發布,但是已經可以從它們的subversion倉庫中檢出代碼。代碼量比較小600頁左右,熟讀它可以對網絡編程、架構、RMI、容器的狀態設計比較了解了!即學會EJB又能學習其它設計方法何樂而不為哦!下載地址:http://easybeans.objectweb.org/
    2. OpenEJB

    OpenEJB是一個預生成的、自包含的、可移植的EJB容器系統,可以被插入到任意的服務器環境,包括應用程序服務器,Web服務器,J2EE平臺, CORBA ORB和數據庫等等。OpenEJB 被用于 Apple的WebObjects。聽起來很好,我目前沒有研究過。不知道我就不推薦了。下載地址:http://www.openejb.org/

    五、J2EE容器

    上面談了這么多,都是J2EE的各個方向的。其實J2EE是一個規范,J2EE的產品一般要求專業提供商必須提供它們的實現。這些實現本身就是J2EE容器。市場上流行的J2EE容器很多,在開源領域流行的只有很少,很少。其中最著名的是JBoss。

    1. JBoss

    在J2EE應用服務器領域,Jboss是發展最為迅速的應用服務器。由于Jboss遵循商業友好的LGPL授權分發,并且由開源社區開發,這使得Jboss廣為流行。另外,Jboss應用服務器還具有許多優秀的特質。

    其一,它將具有革命性的JMX微內核服務作為其總線結構;

    其二,它本身就是面向服務的架構(Service-Oriented Architecture,SOA);

    其三,它還具有統一的類裝載器,從而能夠實現應用的熱部署和熱卸載能力。因此,它是高度模塊化的和松耦合的。Jboss用戶的積極反饋告訴我們,Jboss應用服務器是健壯的、高質量的,而且還具有良好的性能。為滿足企業級市場日益增長的需求,Jboss公司從2003年開始就推出了24*7、專業級產品支持服務。同時,為拓展Jboss的企業級市場,Jboss公司還簽訂了許多渠道合作伙伴。比如,Jboss公司同HP、Novell、Computer Associates、Unisys等都是合作伙伴。

    在2004年6月,Jboss公司宣布,Jboss應用服務器通過了Sun公司的J2EE認證。這是Jboss應用服務器發展史上至今為止最重要的里程碑。與此同時,Jboss一直在緊跟最新的J2EE規范,而且在某些技術領域引領J2EE規范的開發。因此,無論在商業領域,還是在開源社區,Jboss成為了第一個通過J2EE 1.4認證的主流應用服務器。現在,Jboss應用服務器已經真正發展成具有企業強度(即,支持關鍵級任務的應用)的應用服務器。

    Jboss 4.0作為J2EE認證的重要成果之一,已經于2004年9月順利發布了。同時,Jboss 4.0還提供了Jboss AOP(Aspect-Oriented Programming,面向方面編程)組件。近來,AOP吸引了大量開發者的關注。它提供的新的編程模式使得用戶能夠將方面(比如,事務)從底層業務邏輯中分離出來,從而能夠縮短軟件開發周期。用戶能夠單獨使用Jboss AOP,即能夠在Jboss應用服務器外部使用它。或者,用戶也可以在應用服務器環境中使用它。Jboss AOP 1.0已經在2004年10月發布了。 很有名吧!可以下載一個用一下,下載地址:http://www.jboss.org/

    關于JBoss的使用資料也非常多,甚至比商業軟件的還多。有機會研究吧!

    2. JOnAS

    JOnAS是一個開放源代碼的J2EE實現,在ObjectWeb協會中開發。整合了Tomcat或Jetty成為它的Web容器,以確保符合Servlet 2.3和JSP 1.2規范。JOnAS服務器依賴或實現以下的Java API:JCA、JDBC、JTA 、JMS、JMX、JNDI、JAAS、JavaMail 。下載地址:http://jonas.objectweb.org/
    3.Apache Geronimo

    Apache Geronimo 是 Apache 軟件基金會的開放源碼J2EE服務器,它集成了眾多先進技術和設計理念。 這些技術和理念大多源自獨立的項目,配置和部署模型也各不相同。 Geronimo能將這些項目和方法的配置及部署完全整合到一個統一、易用的模型中。作為符合J2EE標準的服務器,Geronimo提供了豐富的功能集和無責任 Apache 許可,具備“立即部署”式J2EE 1.4容器的各種優點,其中包括:

    1. 符合J2EE1.4標準的服務器 。

    2. 預集成的開放源碼項目 。

    3. 統一的集成模型 。

    4. 可伸縮性、可管理性和配置管理功能。

    我一直比較推薦Apache的產品。主要是可以任意自由地使用。下載地址:http://incubator.apache.org/projects/geronimo/

    六、其它

    講了這么多大家可能很厭煩了!是不是很多很多啊!其實不然,我們不會的太多太多了!不會的太多太多了。不管你是不是J2EE高手,還是J2SE高手,有些東西你要絕對很精明的。例如:1.Java的Collections Framework就是java的數據結構了,不僅要吃透它,還要能按照需要擴展它,利用其思想創建一個自己的數據結構。2.網絡編程肯定要會吧,現在以及以后很多程序都是不在同一臺機器上的,不會網絡怎么行哦!3.IO肯定要會的吧!你的程序難道不用輸入輸出數據啊!整個IO包加NIO也有600多頁的源代碼哦!4.JDBC你要會吧!數據庫都不會,在你的企業應用中你的數據又保存到哪里啊!文件中――太落后了吧!典型的沒有學過J2EE。盡管數據庫背后也是采用文件保存的。5.Serverlet、JSp你要是做網頁做網站,肯定要做到。問你一個簡單的問題,網頁中如何實現分頁啊!有具體方法的就在本文章后發言吧!6. Ant要會吧!java語言中發布的工具,類似與c中的make工具。7.JUnit用過吧!單元測試軟件。你不要啊!你的軟件就沒有bug!你牛!(建議大家研究研究其源代碼,很有用的框架,包含大量的設計模式,源代碼不到100頁!看了只能感嘆――高手就是高手)細心的朋友可以看到在你使用的很多IDE工具中都有JUnit哦!就是它。

    一切的一切才剛剛開始!有興趣,有需要你可以研究數據庫連接池的框架,如:C3P0、Jakarta DBCP、 DBPool….可以研究J2EE框架Spring……. Web框架Struts……持久層框架Hibernate…..甚至開發工具Eclipse…..Sun領導的點對點通信的JXTA…..報表工具JFreeChart、JasperReports…..分布式網絡編程的CORBA、網絡通信的JGROUPS、XML解析的xerces…..(在不經意間開源已經步入你的電腦,不信啊!你JDK的安裝目錄jdk1.6.0 src com sun org apache就是Xerces,一個XML解析的著名的開源 項目)

    不管怎么樣我還是建議從基本的做起,學精J2SE,熟讀它的源碼,準確了解其設計理念,然后分頭擊破J2EE――一口吃不成一個胖子!不要貪多貪廣!腳踏實地就可以了!

    摘自CSDN:《J2EE值得學習的開源項目》

    posted @ 2009-08-15 21:49 kangaroo 閱讀(287) | 評論 (0)編輯 收藏

    1、語法:必須比較熟悉,在寫代碼的時候IDE的編輯器對某一行報錯應該能夠根據報錯信息知道是什么樣的語法錯誤并且知道任何修正。

    2、命令:必須熟悉JDK帶的一些常用命令及其常用選項,命令至少需要熟悉:appletviewer、 HtmlConverter、jar、 java、javac、javadoc、javap、javaw、native2ascii、serialver,如果這些命令你沒有全部使用過,那么你對java實際上還很不了解。

    3、工具:必須至少熟練使用一種IDE的開發工具,例如Eclipse、Netbeans、JBuilder、Jdeveloper、IDEA、JCreator或者Workshop,包括進行工程管理、常用選項的設置、插件的安裝配置以及進行調試。

    4、API:Java的核心API是非常龐大的,但是有一些內容筆者認為是必須熟悉的,否則不可能熟練的運用Java,包括:
    ◆java.lang包下的80%以上的類的功能的靈活運用。

    ◆java.util包下的80%以上的類的靈活運用,特別是集合類體系、規則表達式、zip、以及時間、隨機數、屬性、資源和Timer.

    ◆java.io包下的60%以上的類的使用,理解IO體系的基于管道模型的設計思路以及常用IO類的特性和使用場合。

    ◆java.math包下的100%的內容。

    ◆java.net包下的60%以上的內容,對各個類的功能比較熟悉。

    ◆java.text包下的60%以上的內容,特別是各種格式化類。

    ◆熟練運用JDBC. 8)、java.security包下40%以上的內容,如果對于安全沒有接觸的話根本就不可能掌握java.

    ◆AWT的基本內容,包括各種組件事件、監聽器、布局管理器、常用組件、打印。

    ◆Swing的基本內容,和AWT的要求類似。

    ◆XML處理,熟悉SAX、DOM以及JDOM的優缺點并且能夠使用其中的一種完成XML的解析及內容處理。

    5、測試:必須熟悉使用junit編寫測試用例完成代碼的自動測試。

    6、管理:必須熟悉使用ant完成工程管理的常用任務,例如工程編譯、生成javadoc、生成jar、版本控制、自動測試。

    7、排錯:應該可以根據異常信息比較快速的定位問題的原因和大致位置。

    8、思想:必須掌握OOP的主要要求,這樣使用Java開發的系統才能是真正的Java系統。

    9、規范:編寫的代碼必須符合流行的編碼規范,例如類名首字母大寫,成員和方法名首字母小寫,方法名的第一個單詞一般是動詞,包名全部小寫等,這樣程序的可讀性才比較好。

    10、博學:掌握J2EE 、Oracle 、WebLogic、Jboss、Spring、Struts、Hibernate 等流行技術,掌握軟件架構設計思想、搜索引擎優化、緩存系統設計、網站負載均衡、系統性能調優等實用技術。

    摘錄自CSDN:
    《一個java程序員的10項技能》

    posted @ 2009-08-15 21:40 kangaroo 閱讀(291) | 評論 (0)編輯 收藏

    2009年8月9日

    • 關注點concern:一個關注點可以是一個特定的問題、概念、或是應用程序的興趣區間。這是一個概念上的名詞,就是應用程序必須達到的一個目標。比如前面提到的安全性檢查,事務管理,性能檢測都是系統常見的關注點。
    • 橫切關注點crosscutting concern:如果一個關注點的實現代碼(哪怕就一句)散落在很多類或方法之中,我們就稱其為橫切關注點。
    • 方面aspect :一個方面是對一個橫切關注點的模塊化,它將原本散落在各處的用于實現這個關注點的代碼規整在一起。如果“關注點”是個概念上的名詞,“方面”就是實在的代碼。
    • 連接點join point:程序執行過程中的一點,例如:方法調用method invocation(對方法的調用)、字段訪問field access(讀或寫字段)、異常拋出throws(特定的異常被拋出)
    • 增強advice:在特定連接點執行的動作。很多AOP框架都以攔截器interceptor的形式來表現增強。攔截器是一種增強,還有別的形式的增強。所謂攔截器是這樣一個對象,當連接點被調用時,它會收到一個回調消息。增強的例子包括:在方法調用之前,進行安全性的檢查;在執行某個方法的連接點之前開啟事務,在方法執行完畢之后提交或回滾事務。
    • 切入點:一組連接點的總稱,用于指定某個增強應該在何時被調用。切入點常用正則表達式或別的通配符來描述。
    • 前增強:在連接點調用之前,首先調用增強。
    • 后增強:在連接點調用之后,再調用增強。
    • 環繞增強:   
    • 攔截器:很多AOP框架(如Spring和JBoss4,但不包括AspectJ)用它來實現字段和方法的攔截。隨之而來就是在連接點處掛一個攔截器鏈。攔截只是一種AOP的實現策略,不是AOP的核心概念。
    • 目標對象:位于攔截器鏈末端的對象實例。顯然這個概念只存在使用攔截器的AOP框架中。
    • AOP代理:被增強的對象引用。也就是,AOP增強將在其上執行的這樣一個對象引用。和“攔截器”一樣,“AOP代理”只是對于使用攔截機制的AOP框架,而且是其立身之本。

    講了這么多概念,舉個例子,把它們串起來,還是以“AOP學習筆記一”里面的“安全性檢查”為例:
    我們把“安全性檢查”作為一個方面
    那么實現安全性檢查的攔截器就是一種增強
    方法businessMethod1,businessMethod2,businessMethod3就是連接點,
    但是只有businessMethod1和businessMethod2需要增強,所以需要一個切入點,使其只匹配前兩個方法。
    當我們的業務對象和攔截器都配置到spring之后,spring會在運行時織入,并且生成一個AOP代理
    這個AOP代理將是一個JDK動態代理,將在完成安全性檢查之后,調用目標對象

    posted @ 2009-08-09 00:35 kangaroo 閱讀(310) | 評論 (0)編輯 收藏

    2009年8月8日

    用于實現AOP技術的主要策略,按照功能由弱到強排列:
    -J2SE動態代理
    -動態字節碼生成
    -java代碼生成
    -使用定制的類加載期
    -語言擴展

    1.J2SE動態代理
    動態代理是一種強大的語言結構,它使我們可以為一個或多個接口“憑空”地創建實現對象,而不需要預先有一個實現類。
    動態代理最大的好處在于:這是一種標準的Java語言特性。除了AOP框架之外不需要第三方庫,也不回受到應用程序的任何影響。
    動態代理的最大局限性在于:它只能針對接口進行代理,不能針對類。一般情況下,這種限制不是壞事,因為AOP主要針對業務對象,而業務對象通常是放在業務接口之后。
    動態代理在java1.4和更高的版本性能表現地相對好,不過,一旦使用動態代理的實習策略,便不可避免地招致反射調用的開銷。

    2.動態字節碼生成
    為了針對Java類提供代理,我們需要動態代理之外的工具,就是動態字節碼生成。應該慶幸,Java的反射和類裝載機制都非常開發,因此實現動態字節碼生成庫并不復雜。
    在這方面,最流行的工具就是CGLIB(Code Generation Library)。在spring中,如果需要針對類(而不是接口)提供代理,就會用到CGLIB。它可以針對制定的類動態生成一個子類,并覆蓋其中的方法,從而實現方法的攔截。CGLIB風格的字節碼增強并應用在Hibernate2.X版本中,并被證明是一種成熟的技術。Hibernate的成功表明,在應用服務器環境下CGLIB沒有給最終用戶帶來任何困擾。
    不過CGLIB有個小問題就是,因為它是通過生成類的子類來實現代理的,所以無法為final方法提供代理。

    3.java代碼生成
    逐漸退出流行。

    4.使用定制的類加載器

    5.語言擴展
    AspectJ就對java進行了擴展,將AOP概念作為一等公民來對待。

    posted @ 2009-08-08 22:01 kangaroo 閱讀(284) | 評論 (0)編輯 收藏

    AOP,全稱Aspect Oriented Programming,面向方面的編程。那么就要問了,什么是方面,為什么引入AOP?
    一般情況下,OOP能夠很好的避免代碼重復。具體繼承可以幫助我們在不同類型之間共享相同的行為;多態讓我們可以用同樣的方式處理不同類型的對象,將注意力集中在它們的共同之處。但是,有些時候,OOP也避免不了代碼的重復,比如下面的例子:

    public class MyBusinessObject extends BusinessObject {
     
        
    public void businessMethod1() throws UnanthorizedException {
            doSecurityCheck();
        }


        
    public void businessMethod2() throws UnanthorizedException {
            doSecurityCheck();
        }

           
        
    public void businessMethod3(){
            
    //do not need check security.
        }



        
    protected void doSecurityCheck() throws UnanthorizedException {
            
    //implement the security check.
        }

    }


    上面是安全性檢查的例子,我們希望檢查用戶是否有權限執行某個方法,如果沒有就拋出異常。我們把安全檢查的工作放在一個方法中實現,但是這個仍無法避免一行重復代碼的編寫。另外,當開發者添加一個新的業務方法時,它完全有可能忘記調用安全檢查的方法,從而破壞了應用程序的安全性。為了在方法執行的過程中識別出“應該調用安全性檢查”的那一點,我們需要用一種高全新的方式來看待程序結構,而OO的層次模型無法提供這種新的視角。對于這個問題,繼承愛莫能助,“安全性檢查”在這里是一個具有橫切性的問題,需要進行安全性檢查的方法都是彼此獨立的,無法從某個通用的方法繼承下去。
    AOP的目標就是將橫切型crosscutting的問題以一種更加通用的方式模塊化,從而提升程序的模塊化程度。在AOP中,我們可以單獨編寫“安全性檢查”的代碼,并將其包裝為一個方面aspect。(方面的概念出現嘍!)然后,我們可以告訴AOP實現產品如何在運行時將方面織入到程序流程之中,具體的實現策略,請看下篇AOP的實現策略。


     

    posted @ 2009-08-08 21:55 kangaroo 閱讀(239) | 評論 (0)編輯 收藏

    主站蜘蛛池模板: 涩涩色中文综合亚洲| 最新欧洲大片免费在线| 久久精品国产亚洲AV电影网| 亚洲av无码成人黄网站在线观看| 国产精品免费看久久久久| 最近中文字幕大全中文字幕免费 | 国产国产人免费视频成69堂| 人成免费在线视频| 成人婷婷网色偷偷亚洲男人的天堂| 亚洲第一成年人网站| 国产精品亚洲A∨天堂不卡| 亚洲国产婷婷香蕉久久久久久| 午夜两性色视频免费网站| 亚洲免费中文字幕| 免费无码又爽又刺激高潮视频 | 久久精品国产亚洲AV麻豆不卡 | 一本久久免费视频| 亚洲成在人线在线播放无码 | 午夜一级免费视频| 91在线品视觉盛宴免费| **俄罗斯毛片免费| 777爽死你无码免费看一二区| 视频免费在线观看| 国产精品美女免费视频观看| 国产一区二区三区亚洲综合 | 国产无遮挡吃胸膜奶免费看| 成人毛片免费在线观看| 青青久在线视频免费观看| 麻豆一区二区免费播放网站 | 91亚洲精品自在在线观看| 亚洲一区免费观看| 精品亚洲成a人片在线观看| 久久久国产精品亚洲一区| 久久精品国产亚洲精品2020| 99亚洲精品高清一二区| 亚洲第一精品电影网| 亚洲一区二区三区深夜天堂| 亚洲国产精品久久丫| 亚洲色欲啪啪久久WWW综合网| 亚洲日韩精品国产一区二区三区 | 国产jizzjizz视频全部免费|