byterat

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            54 隨筆 :: 0 文章 :: 15 評論 :: 0 Trackbacks

          2007年5月19日 #

          Eclipse及其插件介紹和下載

          0.Eclipse下載
          EMF,GEF - Graphical Editor Framework,UML2,VE - Visual Editor都在這里下載
          http://www.eclipse.org/downloads/index.php

          0.5.lomboz J2EE插件,開發JSP,EJB
          http://forge.objectweb.org/projects/lomboz
          1.MyEclipse J2EE開發插件,支持SERVLET/JSP/EJB/數據庫操縱等
          http://www.myeclipseide.com

          2.Properties Editor 編輯java的屬性文件,并可以自動存盤為Unicode格式
          http://propedit.sourceforge.jp/index_en.html

          3.Colorer Take 為上百種類型的文件按語法著色
          http://colorer.sourceforge.net/

          4.XMLBuddy 編輯xml文件
          http://www.xmlbuddy.com

          5.Code Folding 加入多種代碼折疊功能(比eclipse自帶的更多)
          http://www.coffee-bytes.com/servlet/PlatformSupport

          6.Easy Explorer 從eclipse中訪問選定文件、目錄所在的文件夾
          http://easystruts.sourceforge.net/

          7.Fat Jar 打包插件,可以方便的完成各種打包任務,可以包含外部的包等
          http://fjep.sourceforge.net/

          8.RegEx Test 測試正則表達式
          http://brosinski.com/stephan/archives/000028.php

          9.JasperAssistant 報表插件(強,要錢的)
          http://www.jasperassistant.com/

          10.Jigloo GUI Builder JAVA的GUI編輯插件
          http://cloudgarden.com/jigloo/

          11.Profiler 性能跟蹤、測量工具,能跟蹤、測量BS程序
          http://sourceforge.net/projects/eclipsecolorer/

          12.AdvanQas 提供對if/else等條件語句的提示和快捷幫助(自動更改結構等)
          http://eclipsecolorer.sourceforge.net/advanqas/index.html

          13.Log4E Log4j插件,提供各種和Log4j相關的任務,如為方法、類添加一個logger等
          http://log4e.jayefem.de/index.php/Main_Page

          14.VSSPlugin VSS插件
          http://sourceforge.net/projects/vssplugin

          15.Implementors 提供跳轉到一個方法的實現類,而不是接中的功能(實用!)
          http://eclipse-tools.sourceforge.net/implementors/
          16.Call Hierarchy 顯示一個方法的調用層次(被哪些方法調,調了哪些方法)
          http://eclipse-tools.sourceforge.net/call-hierarchy/index.html

          17.EclipseTidy 檢查和格式化HTML/XML文件
          http://eclipsetidy.sourceforge.net/

          18.Checkclipse 檢查代碼的風格、寫法是否符合規范
          http://www.mvmsoft.de/content/plugins/checkclipse/checkclipse.htm

          19.Hibernate Synchronizer Hibernate插件,自動映射等
          http://www.binamics.com/hibernatesync/

          20.VeloEclipse Velocity插件
          http://propsorter.sourceforge.net/

          21.EditorList 方便的列出所有打開的Editor
          http://editorlist.sourceforge.net/

          22.MemoryManager 內存占用率的監視
          http://cloudgarden.com/memorymanager/

          23.swt-designer java的GUI插件
          http://www.swt-designer.com/

          24.TomcatPlugin 支持Tomcat插件
          http://www.eclipsetotale.com/tomcatPlugin.html

          25.XML Viewer
          http://tabaquismo.freehosting.net/ignacio/eclipse/xmlview/index.html

          26.quantum 數據庫插件
          http://quantum.sourceforge.net/

          27.Dbedit 數據庫插件
          http://sourceforge.net/projects/dbedit

          28.clay.core 可視化的數據庫插件
          http://www.azzurri.jp/en/software/index.jsp
          http://www.azzurri.jp/eclipse/plugins

          29.hiberclipse hibernate插件
          http://hiberclipse.sourceforge.net
          http://www.binamics.com/hibernatesync

          30.struts-console Struts插件
          http://www.jamesholmes.com/struts/console/

          31.easystruts Struts插件
          http://easystruts.sourceforge.net

          32.veloedit Velocity插件
          http://veloedit.sourceforge.net/

          33.jalopy 代碼整理插件
          http://jalopy.sourceforge.net/

          34.JDepend 包關系分析
          http://andrei.gmxhome.de/jdepend4eclipse/links.html

          35.Spring IDE Spring插件
          http://springide-eclip.sourceforge.net/updatesite/

          36.doclipse 可以產生xdoclet 的代碼提示
          http://beust.com/doclipse/
          posted @ 2008-06-05 15:44 比特鼠| 編輯 收藏

               摘要: 有這樣一個函數, 它接受一個函數(或者說閉包)作為參數  閱讀全文
          posted @ 2008-05-30 15:19 比特鼠| 編輯 收藏

          當談到表格數據的設計時,沒有太多的網頁設計師會有太大的興趣。今天我們已經收集了20多個功能超大且看上去挺漂亮的Ajax/CSS表格設計,并且教你一些表格設計中所運用的技巧,例如表格數據的排序和過濾等。

          OK,讓我們來看一下這些表格:

          1. Tablecloth

          Tablecloth 由CSS Globe 開發,是一個輕巧易于使用的表格,簡潔的將表格樣式添加到你的HTML 表格元素中。

          21個新奇漂亮的Ajax/CSS表格設計-Tablecloth

          2. Ask the CSS Guy Table

          Ask the CSS Guy Table教給我們要如何去創建能夠清晰顯出去資料之間的相關聯系的表格,例如:點擊一個表格元素時,將突了顯示這個元素,并且在縱列和橫列都顯示出相關的類別關系。

          21個新奇漂亮的Ajax/CSS表格設計-Ask the CSS Guy Table

          #3. A CSS styled table version 2

          Veerle Duoh 為我們展示了一個漂亮的表格設計,并教我們如何使用CSS來吸引用戶的眼球。

          21個新奇漂亮的Ajax/CSS表格設計-A CSS styled table version 2

          #4. Sortable Table

          Sortable Table 演示了如何按升序或降序排列以及如何過濾表格中的數據。

          21個新奇漂亮的Ajax/CSS表格設計-Sortable Table

          5. Row Locking with CSS and JavaScript

          Css Guy再次對表格使用了聚焦高亮的效果,除非用戶再次點擊,否則表單數據將一直保持亮高。

          21個新奇漂亮的Ajax/CSS表格設計-Row Locking with CSS and JavaScript

          他還給了我們另一個示例:another example to Lock rows with radios .

          #6. Vertical scrolling tables

          如果您有大量的表格數據,但卻沒有太大的空間來展示它,這可能是個比較好的方法:一個純CSS的表格與固定的標題和頁腳,以及滾動顯示的內容。

          21個新奇漂亮的Ajax/CSS表格設計-Vertical scrolling tables

          7. Replicating a Tree table

          這是一個使用HTML 和CSS 設計的樹形狀表格。

          21個新奇漂亮的Ajax/CSS表格設計-Replicating a Tree table

          8 ) Paginate, sort and search a table with Ajax and Rails

          這個表格提供了一個動態的界面,而不需要重新刷新整個頁面。

          21個新奇漂亮的Ajax/CSS表格設計-ajax tables

          9. Collapsible tables with DOM and CSS

          此表格加上箭頭形象的腳本提示,用來控制表格的伸展和收縮。

          21個新奇漂亮的Ajax/CSS表格設計-Collapsible tables with DOM and CSS

          10. TableSorter plug-in for jQuery

          它的主要特性包括多列排序,支持<TH>的rowspan和colspan屬性以及許多其他功能。

          21個新奇漂亮的Ajax/CSS表格設計-TableSorter plug-in for jQuery

          11. Stripe your tables the OO way

          使用了Javascript 為表格中的行進行顏色交替,并且添加了onmouseoveronmouseout 事件,當鼠標點擊時,切換背景顏色。

          21個新奇漂亮的Ajax/CSS表格設計-Stripe your tables the OO way

          12. MooTools Table Row & Column highlighting

          基于MooTools 框架,高亮顯示鼠標懸停時的單元格所在的行和列。

          21個新奇漂亮的Ajax/CSS表格設計-MooTools Table Row & Column highlighting

          13. CSS Table Gallery

          93 styled tables是一個專門收集表格樣式的站點,下面是來自一個表格樣式的截圖:

          21個新奇漂亮的Ajax/CSS表格設計-CSS Table Gallery

          14. jQuery Table Filter

          可以對數據進行各種不同的排序、過濾。

          21個新奇漂亮的Ajax/CSS表格設計-jQuery Table Filter

          15. Sortable/Resizable/Editable TableKit

          TableKit基于Prototype框架,專門收集各種HTML表格,可以利用Ajax實時的進行表格欄目大小、排序等編輯。

          21個新奇漂亮的Ajax/CSS表格設計-sortable, resizable, editable

          16. Make all your tables sortable

          21個新奇漂亮的Ajax/CSS表格設計-sortable table

          17. Zebra Tables

          alistapart為我們提供了一個極好的例子,如何使用JavaScript和DOM的改變背景色風格,以突出顯示單元格。

          21個新奇漂亮的Ajax/CSS表格設計-Zebra Tables

          18. Standardista Table Sorting

          Standardista Table Sorting 是一個Javascript模塊,讓您可以對HTML數據表的任何欄目進行排序。

          21個新奇漂亮的Ajax/CSS表格設計-Standardista Table Sorting

          19. GridView3 Example

          21個新奇漂亮的Ajax/CSS表格設計-GridView3 Example

          20. Mootable

          21個新奇漂亮的Ajax/CSS表格設計-Mootable

          21. Drag & Drop Sortable Lists with JavaScript and CSS

          21個新奇漂亮的Ajax/CSS表格設計-Drag & Drop Sortable Lists with JavaScript and CSS

          可能還會有一些你更想尋找的詳細資料,下面是一些相關的資源鏈接:

          如果你知道其它更強大的Ajax/CSS表格,歡迎在此留言。

          posted @ 2008-01-23 17:46 比特鼠 閱讀(3202) | 評論 (0)編輯 收藏

          一個在線調色工具
          posted @ 2008-01-23 17:44 比特鼠 閱讀(393) | 評論 (1)編輯 收藏

          /**
           * 加碼解碼工具
           * @author lwm
           *
           */

          public class Encode {
           
           /*
            * 對應javascript的escape()函數, 加碼后的串可直接使用javascript的unescape()進行解碼
            */
           public static String escape(String src) {
            int i;
            char j;
            StringBuffer tmp = new StringBuffer();
            tmp.ensureCapacity(src.length() * 6);
            for (i = 0; i < src.length(); i++) {
             j = src.charAt(i);
             if (Character.isDigit(j) || Character.isLowerCase(j)
               || Character.isUpperCase(j))
              tmp.append(j);
             else if (j < 256) {
              tmp.append("%");
              if (j < 16)
               tmp.append("0");
              tmp.append(Integer.toString(j, 16));
             } else {
              tmp.append("%u");
              tmp.append(Integer.toString(j, 16));
             }
            }
            return tmp.toString();
           }

           /*
            * 對應javascript的unescape()函數, 可對javascript的escape()進行解碼
            */
           public static String unescape(String src) {
            StringBuffer tmp = new StringBuffer();
            tmp.ensureCapacity(src.length());
            int lastPos = 0, pos = 0;
            char ch;
            while (lastPos < src.length()) {
             pos = src.indexOf("%", lastPos);
             if (pos == lastPos) {
              if (src.charAt(pos + 1) == 'u') {
               ch = (char) Integer.parseInt(src
                 .substring(pos + 2, pos + 6), 16);
               tmp.append(ch);
               lastPos = pos + 6;
              } else {
               ch = (char) Integer.parseInt(src
                 .substring(pos + 1, pos + 3), 16);
               tmp.append(ch);
               lastPos = pos + 3;
              }
             } else {
              if (pos == -1) {
               tmp.append(src.substring(lastPos));
               lastPos = src.length();
              } else {
               tmp.append(src.substring(lastPos, pos));
               lastPos = pos;
              }
             }
            }
            return tmp.toString();
           }

          }

          posted @ 2008-01-11 17:08 比特鼠 閱讀(1837) | 評論 (0)編輯 收藏

          讀 YUI ,EXT等源碼的時候看JS天旋地轉,那可不是51JS上那種挪挪位置就能理解的,此刻如果沒有JavaScrip的基礎,更是像沒有星光的黑夜…….

          自以為覺得Js對象是很好理解的東東,然而真實踐起來卻一片糊涂。
          通過查閱經典書籍《Professional JavaScript For Web Developers》稍微有些理解了

          JavaScript的基本類型
          原始類型如: Undefined Null Boolean Number String 等 用 typeof方法能辨別之
          引用類型如: Object Function Array Boolean Number String Date等,用insanceof方法辨別之

          嚴格來講,JavaScript沒有對象(Object),但是由于和OO術語對應,所以也稱之為對象。所以Array,Function,基本類型,引用類型,函數,以及函數的屬性 等等這些都是對象。

          而對象分類,則可以分為內置對象(Built-in Object) 和宿主對象(host object)。
          內置對象如 Math,Data啊。
          宿主對象則如 BOM,DOM之類.

          重新回顧了下這些基本概念之后,在做簡單實踐就有些理解了。
          因此對象的使用,創建方式不盡相同,最簡單的歸類如下:

          1 基本創建方式

          function Class() {
          window.alert("Hello Class!");
          }
          var clz= new Class();

          2 訪問對象成員

          function Class(){
          this.x = " this is x";
          this.y = "this is y";
          this.z = viewXY;
          function viewXY(){
          alert("x+","+y);
          }
          }
          var clz= new Class();
          clz.viewXY();

          3 對象繼承

          function Parent() {
          this.type= "human!";
          }
          function Child(){
          this.age = "26";
          this.sex ="male";
          this.say= myInfo;
          function myInfo(msg){
          alert(msg+this.type+ ","+this.age+","+this.sex);
          }
          }
          Child.prototype = new Parent();
          var clild = new Child();
          clild.say("I'm ");

          4.重用原對象 (書上的例子太好了,搬來了)

          Funcion.prototype.toString() = function(){
          return "Function code hidden";
          }
          function sayHi(){
          alert("hi");
          }
          alert(sayHi.toString());
          posted @ 2008-01-02 11:06 比特鼠 閱讀(273) | 評論 (0)編輯 收藏

          希望能做到以下幾點:

          1. 在Java服務端架構的設計, 選型, 方案等方面有所突破! -- 這是最主要的!
          2. 也想玩一玩Web前端的AJAX編程, RIA(富互聯網應用)等等
          3. 熟悉Linux/Unix系統的命令行操作
          4. 在Java中跑腳本語言Python, JRuby等等
          5. 項目管理

          暫時就這么多吧!

          posted @ 2007-12-28 09:41 比特鼠 閱讀(210) | 評論 (0)編輯 收藏

          為 Ajax 安全性所提出的經驗法則:
          1. 如果你使用身份驗證, 確定你在請求頁上檢查!
          2. 為 SQL 注入檢查。
          3. 為 JavaScript 注入檢查。
          4. 保留商務邏輯在服務器上!
          5. 不要假設每個請求是真正的!
          6. 確認檢查數據!
          7. 審查請求的數據而且確定它是正確的。
          posted @ 2007-12-19 17:10 比特鼠 閱讀(281) | 評論 (0)編輯 收藏

          1. jvm內部分為主工作區和線程工作區。主工作區是實例的所有線程共有,線程工作區是實例的每個線程專有的工作區,其中包括一些主工作區的一些實例字段數據的拷貝。

          2. 服務器一般都有線程池,線程資源是可以重復利用的。你2000個用戶在線,不見得能又200個用戶同時(或者說并發)訪問。再說,只要對象不是太大,我寧愿用200個拷貝,也不想讓用戶在這個200個任務的隊列里等待。

          3. 兩個DB之間的復制數據,每個DB各自使用自己的Sequane來生成id。復制數據時,如果DB中的外鍵是由DB維護的,則不會產生id沖突,如果外鍵是由外部程序維護的,則可能會產生錯誤!

          4. 對于非static的類的數據成員來說,在該類產生的實例中都有一份,并且相互獨立(修改后并不影響其他實例), 但static的數據成員則變成了每個類只有一份,即在該類產生的所有實例共享這一個數據成員, 該數據成員的改變會影響到其他的實例. 而static的方法則是讓你不用創建對象及能調用這個方法.

          5. ThreadLocal的作用就是將經常要用到的對象的引用放到屬于線程自己的一個存儲空間中,在該線程的執行過程中,可以通過類的靜態的ThreadLocal來方便的獲取到這個對象,而不用通過參數的形式傳來傳去。
          posted @ 2007-12-19 14:54 比特鼠 閱讀(257) | 評論 (0)編輯 收藏

          很多高分辨率的圖像真的能夠扮靚一個Web網站。但是它們也可能會降低網站的(響應)速度——圖像都是文件,文件就要占用帶寬,而帶寬與等待時間直接相關。現在是你進行自我學習,了解如何利用一種叫做圖像預加載的小技巧給網站提速的時候了。

          圖像的預加載

                 瀏覽器通常的工作方式是:只有當要求加載圖像的HTTP請求被發送的時候,圖像才會被加載,而不論它是被動地通過<img>標記加載,還是主動地通過方法調用加載。所以,如果你有一段JavaScript,需要在鼠標懸停的時候切換圖像,或者在超時之后自動地更換圖像,那么你就可能會在從服務器取回圖像的時候隨時碰到等待,時間會從數秒鐘到幾分鐘不等。當你以較慢的速度連接到Internet上的時候,或者被取回的圖像非常巨大的時候,這種狀況尤其顯著,而這種數據延遲通常都會毀掉你所期望的效果。

                  有些瀏覽器會試圖轉嫁這一問題,比如把圖像保存在本地緩沖區里,這樣以后對它的調用就能夠很快進行了,但是需要第一次調用圖像的時候仍然會產生延遲。預加載是一項在需要圖像之前就把它下載到緩沖區里的技術。通過這種方式,當真的需要圖像的時候,它可以被從緩沖區里取出來,并立即顯示出來。

          Image()對象
                  預加載圖像最簡單的方法用JavaScript將一個新的Image()對象實例化,并把你想要預加載的圖像的URL傳遞給它。假設我們有一個叫做
          http://www.host01.com/Get/jsp/00040004/heavyimagefile.jpg的圖像,我們希望,當用戶把鼠標放在一個已經顯示過的圖像上的時,系統能夠顯示出這個圖像。為了預加載這個圖像,以便實現更快的響應時間,我們只用創建一個新的Image()對象,將其命名為heavyImage,并使用onLoad()事件處理程序把它同時加載到頁面上。

          1 < html >< head >< script  language  = "JavaScript" > function  preloader()  {heavyImage  =   new  Image(); heavyImage.src = " http://www.host01.com/Get/jsp/00040004/heavyimagefile.jpg " ;} </ script ></ head >< body  onLoad ="javascript:preloader()" >< href ="#"  onMouseOver ="javascript:document.img01.src='http://www.host01.com/Get/jsp/00040004/heavyimagefile.jpg'" >< img  name ="img01"  src =http://www.host01.com/Get/jsp/00040004/"justanotherfile.jpg" ></ a ></ body ></ html >
          2

           

                    要注意的是,圖像標記自身并不會處理onMouseOver()和onMouseOut()事件,這就是為什么上面例子里的<img>標記被放在一個<a>標記里,后者的確加入了對這些事件類型的支持。
          用數組加載多個圖像


                     在實際操作中,你可能需要預加載一幅以上的圖像;例如,在包含有多個圖像翻滾(rollover)的菜單條里,或者如果你正在嘗試創建平滑的動態效果。這并不困難;你所需要做的就是使用JavaScript的數組,就像下面例子里的一樣:

           

          1 < script language = " JavaScript " > function  preloader()  //  counter var i = 0; // create object imageObj = new Image(); // set image list images = new Array(); images[0]="image1.jpg" images[1]="image2.jpg" images[2]="image3.jpg" images[3]="image4.jpg" // start preloading for(i=0; i<=3; i++) { imageObj.src=images[i]; }
          2 }
            </ script >


                   在上面的例子里,你先定義變量i和叫做imageObj的Image()對象。然后定義一個叫做images[]的新數組,在這個數組里,每個數組元素都保存著需要預加載的圖像來源。最后,創建一個for()循環,讓它在數組里循環,并將它們中的每一個都指派給Image()對象,這樣就能夠把它預加載到緩沖區里。
          onLoad()事件處理程序
                  就和JavaScript里的其它很多對象一樣,Image()對象也帶有多個事件處理程序。這其中最有用的毫無疑問的就是onLoad()處理程序了,它會在完成圖像加載的時候被調用。這個處理程序可以與自定義的函數一起使用,以便在完成圖像加載之后進行特定的任務。下面的例子通過在圖像加載的時候顯示“請等待(please wait)”提示信息來說明這個問題,然后在圖像完成加載之后就向瀏覽器發送一個新的URL。

           

          < html >< head >< script  language ="JavaScript" > //  create an image objectobjImage = new Image(); // set what happens once the image has loaded objImage.onLoad=imagesLoaded(); // preload the image fileobjImage.src='http://www.host01.com/Get/jsp/00040004/images/image1n.gif';// function invoked on image loadfunction imagesLoaded(){ document.location.href='index2.html';}</script></head><body>Please wait, loading images</body></html>

           


                 當然,你還可以創建一個圖像數組,對它進行循環,預加載每個圖像,并在每個階段對已加載圖像的數量保持跟蹤。一旦加載了所有的圖像,事件處理程序就能夠按照設定把瀏覽器帶到下一個頁面(或者進行其他的任務)。

          預加載與多狀態菜單

                    現在,把你剛剛學到的理論付諸真正的實踐怎么樣?下面一部分內容就是我碰巧編寫的一段代碼——一個由多個按鈕(圖像鏈接)組成的菜單條——其中每個按鈕都可能處于三種狀態中的一種:正常(normal)、hover(懸停)和點擊(click)。由于所有的按鈕都有多個狀態,所以就有必要使用圖像預加載來確保菜單能夠根據其切換到的狀態進行快速的響應。列表A里的代碼就說了這一點。

                     列表A里的HTML代碼會建立一個由四個按鈕組成的菜單條,每個按鈕都有三種狀態:正常、懸停和點擊。其要求如下:

                    但鼠標移動到處于正常狀態的按鈕上時,按鈕會變為懸停狀態。當鼠標移開的時候,按鈕又會恢復到正常狀態。當鼠標點擊按鈕的時候,按鈕就會變為點擊狀態。它會一直保持這個狀態,直到另外一個按鈕被點擊。如果有一個按鈕被點擊,那么其他的按鈕就都不能處于點擊狀態。其他的按鈕只能夠處于懸停或者正常狀態。一次只能有一個按鈕可以被點擊。一次只能有一個按鈕處于懸停狀態。
                  第一項任務是建立保存有菜單每個狀態的圖像的數組。與這些數組元素相對應的<img>元素也都在HTML文檔的主體里被創建,并按順序命名。要注意的是,對數組值的索引是從0開始的,而相應的<img>元素是從1開始命名的——這就需要在腳本后面的一段里進行某種計算上的調整。

                  PreloadImages()函數會負責把所有的圖像都加載到緩沖區里,這樣的話對鼠標移動的響應時間會被減到最小。一個for()循環被用在第一步里創建的圖像里進行迭代,并預加載每一個圖像。

                      ResetAll()函數是把所有圖像恢復都到它們正常狀態的方便方法。這是有必要的,因為當菜單的項目被點擊的時候,菜單里其他所有的項目都必須在被點擊項目能夠切換到點擊狀態之前恢復到正常狀態。

                  SetNormal()、setHover()和setClick()函數負責把特定圖像(圖像的編號被作為函數的自變量進行傳遞)的來源分別改為正常、懸停或者點擊狀態。由于被點擊的圖像必須一直保持點擊狀態,直到另外一個圖像被點擊(見第二項要求),所以它們暫時不會對鼠標移動作出反應;這樣的話,如果按鈕還不是處在點擊狀態,那么setNormal()和setHover()函數所包括的代碼就只能用來改變按鈕的狀態。

                   上面所提到的預加載只是提高你JavaScript效果響應時間的多種方法之一。就在你的網站上使用上面列出的技巧,并根據你的要求在需要的地方更改它們吧。祝你好運!

          posted @ 2007-12-19 10:40 比特鼠 閱讀(257) | 評論 (0)編輯 收藏

          這些東西都是Java Script大部分都是由老外寫的,并且封裝得很好,在運用上也很方便,而且也都兼容FF與OPERA,檔案中少部分是由中國的高手寫的。

           

            一、多樣化摺疊菜單:下載

            一個由老外寫的折疊式垂直菜單,多樣化,多功能,可自訂,使用容易,支持FF。

          國內外 Java Script 經典封裝
          圖1

            二、CSS圓角邊框:下載

            以CSS為主要,用Java Script封裝的相當完整,也是老外寫的,支持多瀏覽器,可以自訂樣式,目前有十多種可以運用。

          國內外 Java Script 經典封裝
          圖2

          國內外 Java Script 經典封裝
          圖3

            三、模擬視窗:下載

            用層模擬的視窗,是一個中國高手寫的,Java Script封裝的相當好,使用上也很容易

          國內外 Java Script 經典封裝
          圖4
            

            四、支持FF的省略符:下載

            說到省略符,那非CSS莫屬,有個老外用Java Script來實現,并且是批量處理的,重點是支持FF。

          國內外 Java Script 經典封裝
          圖5

            五、TAB選項卡:下載

            用Java Script模仿各種作業系統的選項卡,老外就是牛,不僅支援多樣式的即時切換,同時也支援每個選項卡是否附帶圖示的切換選項,選項卡也可以上下切換。

          國內外 Java Script 經典封裝
          圖6
            

            六、最佳化多樣式Windows:下載

            用層模擬視窗的最佳代表作,這是我看過功能最多的模擬式窗,內附多達74項功能與樣式,你完完全全可以把它當成是一個真正的視窗來應用,可以根據你的需求來應用,快丟掉你那認為好用的層視窗,這套封裝非常完整的視窗絕對可以滿足你的各種需求。

          國內外 Java Script 經典封裝
          圖7

          國內外 Java Script 經典封裝
          圖8

            七、多樣化的垂直菜單:附件

            別具風格的方塊式垂直折疊菜單,目前有8種風格可以運用,如果你已經厭煩WEB上平凡的菜單,這套在國外頗受歡迎的菜單肯定是你的最佳首選。

          國內外 Java Script 經典封裝
          圖9
            

            八、多樣化的連結提示效果:下載

            這個連結提示樣式允許你直接寫入css與html,共有14項功能可以讓你自訂。

          國內外 Java Script 經典封裝
          圖10

            九、側欄式折疊菜單:下載

            這是一個側欄式的折疊菜單,它允許你設置它是否有過渡效果、側欄菜單是否自動伸縮、菜單項切換是否允許動畫過渡、是否輪替切換等多項設置,并且也有多種樣式可以運用。

            這個腳本有個很好玩的東東,下載并且解壓後,請進入samples的目錄并打show.html看看效果,我不知道這效果容不容易實現,但是這效果很牛,菜單全自動運行的~

          國內外 Java Script 經典封裝
          圖11
            

            十、圖形滾動條:下載

            老外寫的圖形滾動條,有多種樣式,在ie里頭還支持滾輪滾動。

          國內外 Java Script 經典封裝
          圖12

            十一、圖片倒影效果:下載
            說到圖片倒影,不外乎就是直接作成圖片跟css濾鏡來實現,但是這個是用Java Script實現的,值得借鏡。

          國內外 Java Script 經典封裝
          圖13

            十二、代碼自動高亮:下載

            雖說這不是什麼新東西,但總是會有人需要吧,而且想學正則表達的人,這肯定是最佳借鏡的作品。

          國內外 Java Script 經典封裝
          圖14
            
            

            十三、酷似flash效果的圖片展示:下載

            這個老外牛到有點變態,這圖片展示效果已經跟FLASH沒什麼兩樣,用Java Script寫的耶。

          國內外 Java Script 經典封裝
          圖15

            十四、讓ie6支援png圖檔:下載

          國內外 Java Script 經典封裝
          圖16

            這個問題之前被很多人討論過,我就不多說什麼了,有需要下吧。

          posted @ 2007-12-13 17:29 比特鼠 閱讀(5343) | 評論 (5)編輯 收藏

          在一個老外的Blog上看到了這個網站,發現原來是一個以C語言為基準的性能比較網站!

          Java還算不錯,Ruby就不怎么樣了, 在腳本語言中居然排在了最后!

          看來,解析性的語言玩起來是簡單方便了,可是卻是以損失性能為代價的!
          posted @ 2007-12-13 16:34 比特鼠 閱讀(468) | 評論 (0)編輯 收藏

          BIG-ENDIAN(大字節序、高字節序)
          LITTLE-ENDIAN(小字節序、低字節序)
          主機字節序
          網絡字節順序
          JAVA字節序

          1.BIG-ENDIAN、LITTLE-ENDIAN跟多字節類型的數據有關的比如int,short,long型,而對單字節數據byte卻沒有影響。BIG-ENDIAN就是低位字節排放在內存的低端,高位字節排放在內存的高端。而LITTLE-ENDIAN正好相反。
          比如 int a = 0x05060708
          在BIG-ENDIAN的情況下存放為:
          字節號 0 1 2 3
          數據 05 06 07 08
          在LITTLE-ENDIAN的情況下存放為:
          字節號 0 1 2 3
          數據 08 07 06 05

          2.BIG-ENDIAN、LITTLE-ENDIAN、跟CPU有關的,每一種CPU不是BIG-ENDIAN就是LITTLE-ENDIAN、。IA架構的CPU中是Little-Endian,而PowerPC 、SPARC和Motorola處理器。這其實就是所謂的主機字節序。而網絡字節序是指數據在網絡上傳輸時是大頭還是小頭的,在Internet的網絡字節序是BIG-ENDIAN。所謂的JAVA字節序指的是在JAVA虛擬機中多字節類型數據的存放順序,JAVA字節序也是BIG-ENDIAN。

          3.所以在用C/C++寫通信程序時,在發送數據前務必用htonl和htons去把整型和短整型的數據進行從主機字節序到網絡字節序的轉換,而接收數據后對于整型和短整型數據則必須調用ntohl和ntohs實現從網絡字節序到主機字節序的轉換。如果通信的一方是JAVA程序、一方是C/C++程序時,則需要在C/C++一側使用以上幾個方法進行字節序的轉換,而JAVA一側,則不需要做任何處理,因為JAVA字節序與網絡字節序都是BIG-ENDIAN,只要C/C++一側能正確進行轉換即可(發送前從主機序到網絡序,接收時反變換)。如果通信的雙方都是JAVA,則根本不用考慮字節序的問題了。

          4.如果網絡上全部是PowerPC,SPARC和Motorola CPU的主機那么不會出現任何問題,但由于實際存在大量的IA架構的CPU,所以經常出現數據傳輸錯誤。

          5.文章開頭所提出的問題,就是因為程序運行在X86架構的PC SERVER上,發送數據的一端用C實現的,接收一端是用JAVA實現的,而發送端在發送數據前未進行從主機字節序到網絡字節序的轉換,這樣接收端接收到的是LITTLE-ENDIAN的數據,數據解釋自然出錯。
          具體數據如下,實際發送的數據為23578
          發送端發送數據: 1A 5C
          接收端接收到數據后,按BIG-ENDIAN進行解釋具體數據是多少?你們自己去計算并比較吧!


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

          Big Endian and Little Endian

              談到字節序的問題,必然牽涉到兩大CPU派系。那就是Motorola的PowerPC系列CPU和Intel的x86系列CPU。PowerPC系列采用big endian方式存儲數據,而x86系列則采用little endian方式存儲數據。那么究竟什么是big endian,什么又是little endian呢?

              其實big endian是指低地址存放最高有效字節(MSB),而little endian則是低地址存放最低有效字節(LSB),即常說的低位在先,高位在后。
              用文字說明可能比較抽象,下面用圖像加以說明。比如數字0x12345678在兩種不同字節序CPU中的存儲順序如下所示:

          Big Endian

            低地址                           高地址
            ----------------------------------------->
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |     12     |      34    |     56      |     78    |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          Little Endian

            低地址                           高地址
            ----------------------------------------->
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |     78     |      56    |     34      |     12    |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

              從上面兩圖可以看出,采用big endian方式存儲數據是符合我們人類的思維習慣的。而little endian,!@#$%^&*,見鬼去吧 -_-|||

              為什么要注意字節序的問題呢?你可能這么問。當然,如果你寫的程序只在單機環境下面運行,并且不和別人的程序打交道,那么你完全可以忽略字節序的存在。但是,如果你的程序要跟別人的程序產生交互呢?尤其是當你把你在微機上運算的結果運用到計算機群上去的話。在這里我想說說兩種語言。C/C++語言編寫的程序里數據存儲順序是跟編譯平臺所在的CPU相關的,而JAVA編寫的程序則唯一采用big endian方式來存儲數據。試想,如果你用C/C++語言在x86平臺下編寫的程序跟別人的JAVA程序互通時會產生什么結果?就拿上面的 0x12345678來說,你的程序傳遞給別人的一個數據,將指向0x12345678的指針傳給了JAVA程序,由于JAVA采取big endian方式存儲數據,很自然的它會將你的數據翻譯為0x78563412。什么?竟然變成另外一個數字了?是的,就是這種后果。因此,在你的C程序傳給JAVA程序之前有必要進行字節序的轉換工作。

              無獨有偶,所有網絡協議也都是采用big endian的方式來傳輸數據的。所以有時我們也會把big endian方式稱之為網絡字節序。當兩臺采用不同字節序的主機通信時,在發送數據之前都必須經過字節序的轉換成為網絡字節序后再進行傳輸。ANSI C中提供了四個轉換字節序的宏。


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

          /**
          * 通信格式轉換
          *
          * Java和一些windows編程語言如c、c++、delphi所寫的網絡程序進行通訊時,需要進行相應的轉換
          * 高、低字節之間的轉換
          * windows的字節序為低字節開頭
          * linux,unix的字節序為高字節開頭
          * java則無論平臺變化,都是高字節開頭
          */

          public class FormatTransfer {
          /**
            * 將int轉為低字節在前,高字節在后的byte數組
            * @param n int
            * @return byte[]
            */
          public static byte[] toLH(int n) {
            byte[] b = new byte[4];
            b[0] = (byte) (n & 0xff);
            b[1] = (byte) (n >> 8 & 0xff);
            b[2] = (byte) (n >> 16 & 0xff);
            b[3] = (byte) (n >> 24 & 0xff);
            return b;
          }

          /**
            * 將int轉為高字節在前,低字節在后的byte數組
            * @param n int
            * @return byte[]
            */
          public static byte[] toHH(int n) {
            byte[] b = new byte[4];
            b[3] = (byte) (n & 0xff);
            b[2] = (byte) (n >> 8 & 0xff);
            b[1] = (byte) (n >> 16 & 0xff);
            b[0] = (byte) (n >> 24 & 0xff);
            return b;
          }

          /**
            * 將short轉為低字節在前,高字節在后的byte數組
            * @param n short
            * @return byte[]
            */
          public static byte[] toLH(short n) {
            byte[] b = new byte[2];
            b[0] = (byte) (n & 0xff);
            b[1] = (byte) (n >> 8 & 0xff);
            return b;
          }

          /**
            * 將short轉為高字節在前,低字節在后的byte數組
            * @param n short
            * @return byte[]
            */
          public static byte[] toHH(short n) {
            byte[] b = new byte[2];
            b[1] = (byte) (n & 0xff);
            b[0] = (byte) (n >> 8 & 0xff);
            return b;
          }

           

          /**
            * 將將int轉為高字節在前,低字節在后的byte數組

          public static byte[] toHH(int number) {
            int temp = number;
            byte[] b = new byte[4];
            for (int i = b.length - 1; i > -1; i--) {
              b = new Integer(temp & 0xff).byteValue();
              temp = temp >> 8;
            }
            return b;
          }

          public static byte[] IntToByteArray(int i) {
              byte[] abyte0 = new byte[4];
              abyte0[3] = (byte) (0xff & i);
              abyte0[2] = (byte) ((0xff00 & i) >> 8);
              abyte0[1] = (byte) ((0xff0000 & i) >> 16);
              abyte0[0] = (byte) ((0xff000000 & i) >> 24);
              return abyte0;
          }


          */

          /**
            * 將float轉為低字節在前,高字節在后的byte數組
            */
          public static byte[] toLH(float f) {
            return toLH(Float.floatToRawIntBits(f));
          }

          /**
            * 將float轉為高字節在前,低字節在后的byte數組
            */
          public static byte[] toHH(float f) {
            return toHH(Float.floatToRawIntBits(f));
          }

          /**
            * 將String轉為byte數組
            */
          public static byte[] stringToBytes(String s, int length) {
            while (s.getBytes().length < length) {
              s += " ";
            }
            return s.getBytes();
          }


          /**
            * 將字節數組轉換為String
            * @param b byte[]
            * @return String
            */
          public static String bytesToString(byte[] b) {
            StringBuffer result = new StringBuffer("");
            int length = b.length;
            for (int i=0; i<length; i++) {
              result.append((char)(b & 0xff));
            }
            return result.toString();
          }

          /**
            * 將字符串轉換為byte數組
            * @param s String
            * @return byte[]
            */
          public static byte[] stringToBytes(String s) {
            return s.getBytes();
          }

          /**
            * 將高字節數組轉換為int
            * @param b byte[]
            * @return int
            */
          public static int hBytesToInt(byte[] b) {
            int s = 0;
            for (int i = 0; i < 3; i++) {
              if (b >= 0) {
              s = s + b;
              } else {
              s = s + 256 + b;
              }
              s = s * 256;
            }
            if (b[3] >= 0) {
              s = s + b[3];
            } else {
              s = s + 256 + b[3];
            }
            return s;
          }

          /**
            * 將低字節數組轉換為int
            * @param b byte[]
            * @return int
            */
          public static int lBytesToInt(byte[] b) {
            int s = 0;
            for (int i = 0; i < 3; i++) {
              if (b[3-i] >= 0) {
              s = s + b[3-i];
              } else {
              s = s + 256 + b[3-i];
              }
              s = s * 256;
            }
            if (b[0] >= 0) {
              s = s + b[0];
            } else {
              s = s + 256 + b[0];
            }
            return s;
          }


          /**
            * 高字節數組到short的轉換
            * @param b byte[]
            * @return short
            */
          public static short hBytesToShort(byte[] b) {
            int s = 0;
            if (b[0] >= 0) {
              s = s + b[0];
              } else {
              s = s + 256 + b[0];
              }
              s = s * 256;
            if (b[1] >= 0) {
              s = s + b[1];
            } else {
              s = s + 256 + b[1];
            }
            short result = (short)s;
            return result;
          }

          /**
            * 低字節數組到short的轉換
            * @param b byte[]
            * @return short
            */
          public static short lBytesToShort(byte[] b) {
            int s = 0;
            if (b[1] >= 0) {
              s = s + b[1];
              } else {
              s = s + 256 + b[1];
              }
              s = s * 256;
            if (b[0] >= 0) {
              s = s + b[0];
            } else {
              s = s + 256 + b[0];
            }
            short result = (short)s;
            return result;
          }

          /**
            * 高字節數組轉換為float
            * @param b byte[]
            * @return float
            */
          public static float hBytesToFloat(byte[] b) {
            int i = 0;
            Float F = new Float(0.0);
            i = ((((b[0]&0xff)<<8 | (b[1]&0xff))<<8) | (b[2]&0xff))<<8 | (b[3]&0xff);
            return F.intBitsToFloat(i);
          }

          /**
            * 低字節數組轉換為float
            * @param b byte[]
            * @return float
            */
          public static float lBytesToFloat(byte[] b) {
            int i = 0;
            Float F = new Float(0.0);
            i = ((((b[3]&0xff)<<8 | (b[2]&0xff))<<8) | (b[1]&0xff))<<8 | (b[0]&0xff);
            return F.intBitsToFloat(i);
          }

          /**
            * 將byte數組中的元素倒序排列
            */
          public static byte[] bytesReverseOrder(byte[] b) {
            int length = b.length;
            byte[] result = new byte[length];
            for(int i=0; i<length; i++) {
              result[length-i-1] = b;
            }
            return result;
          }

          /**
            * 打印byte數組
            */
          public static void printBytes(byte[] bb) {
            int length = bb.length;
            for (int i=0; i<length; i++) {
              System.out.print(bb + " ");
            }
            System.out.println("");
          }

          public static void logBytes(byte[] bb) {
            int length = bb.length;
            String ut = "";
            for (int i=0; i<length; i++) {
              ut = out + bb + " ";
            }

          }

          /**
            * 將int類型的值轉換為字節序顛倒過來對應的int值
            * @param i int
            * @return int
            */
          public static int reverseInt(int i) {
            int result = FormatTransfer.hBytesToInt(FormatTransfer.toLH(i));
            return result;
          }

          /**
            * 將short類型的值轉換為字節序顛倒過來對應的short值
            * @param s short
            * @return short
            */
          public static short reverseShort(short s) {
            short result = FormatTransfer.hBytesToShort(FormatTransfer.toLH(s));
            return result;
          }

          /**
            * 將float類型的值轉換為字節序顛倒過來對應的float值
            * @param f float
            * @return float
            */
          public static float reverseFloat(float f) {
            float result = FormatTransfer.hBytesToFloat(FormatTransfer.toLH(f));
            return result;
          }

          }

          posted @ 2007-10-24 09:57 比特鼠 閱讀(3407) | 評論 (0)編輯 收藏

          實現Leader/Fellows模式的項目--CAJ, 地址是:http://caj.cosylab.com/
          posted @ 2007-10-23 14:57 比特鼠 閱讀(198) | 評論 (0)編輯 收藏

          網址:http://httpd.apache.org/docs/2.0/programs/ab.html
          posted @ 2007-10-23 14:53 比特鼠 閱讀(273) | 評論 (0)編輯 收藏

          緩沖區基礎

          抽象類Buffer是java.nio包支持緩沖區的基礎。 Buffer 的工作方式就象內存中用于讀寫基本數據類型的 RandomAccessFile 。象 RandomAccessFile 一樣,使用 Buffer ,所執行的下一個操作(讀/寫)在當前某個位置發生。執行讀/寫操作中的任一個都會改變那個位置,所以在寫操作之后進行讀操作不會讀到剛才所寫的內容,而會讀到剛才所寫內容之后的數據。 Buffer 提供了四個指示方法,用于訪問線性結構(從最高值到最低值):

          capacity() :表明緩沖區的容量大小, 一旦確定了大小, 將不能再改變;
          limit() :告訴您到目前為止已經往緩沖區填了多少字節,或者讓您用 :limit(int newLimit) 來改變這個限制
          position() :告訴您當前的位置,以執行下一個讀/寫操作
          mark() :為了稍后用 reset() 進行重新設置而記住某個位置
          flip() :交換限制指針和位置指針,然后將位置置為 0,并廢棄已經做的mark標記

          緩沖區的基本操作是讀 get() 和寫 put() ;然而,這些方法在子類中都是針對每種數據類型的特定方法。為了說明這一情況,讓我們研究一個簡單示例,該示例演示了從同一個緩沖區讀和寫一個字符。在清單 1 中, flip() 方法交換限制和位置,然后將位置置為 0,并廢棄標記,讓您讀剛才所寫的數據:


          清單 1. 讀/寫示例
          import java.nio.*;
          ...
          CharBuffer buff = ...;
          buff.put('A');
          buff.flip();
          char c = buff.get();
          System.out.println("An A: " + c);
           


          現在讓我們研究一些具體的 Buffer 子類。

           

          緩沖區類型

          Merlin 具有 7 種特定的 Buffer 類型,每種類型對應著一個基本數據類型(不包括 boolean):

          ByteBuffer       //存放任何除boolean類型外的其他基本類型
          CharBuffer       //存放char
          DoubleBuffer     //存放double
          FloatBuffer      //存放float
          IntBuffer        //存放int
          LongBuffer       //存放long
          ShortBuffer      //存放short

          在本文后面,我將討論第 8 種類型 MappedByteBuffer ,它用于內存映射文件。如果您必須使用的類型不是這些基本類型,則可以先從 ByteBuffer 獲得字節類型,然后將其轉換成 Object 或其它任何類型。


          創建緩沖區
          一共有兩種類型的緩沖區,直接緩沖區和非直接緩沖區。

          在創建緩沖區時,可以要求創建直接緩沖區,創建直接緩沖區的成本要比創建間接緩沖區高,但這可以使運行時環境直接在該緩沖區上進行較快的本機 I/O 操作。因為創建直接緩沖區所增加的成本,所以直接緩沖區只用于長生存期的緩沖區,而不用于短生存期、一次性且用完就丟棄的緩沖區。而且,只能在 ByteBuffer 這個級別上創建直接緩沖區,如果希望使用其它類型,則必須將 Buffer 轉換成更具體的類型。

          判斷一個緩沖區是否是直接緩沖區,可以調用isDirect()方法。

          有三種方式來獲取一個緩沖區的對象:
          a. 調用allocate()或者allocateDirect()方法直接分配,其中allocateDirect()返回的是直接緩沖區。
          b. 包裝一個數組,如:
                byte[] b = new byte[1024];
                ByteBuffer bb = ByteBuffer.wrap(b);
          c. 內存映射,即調用FileChannel的map()方法。

          緩沖區基本屬性
          這幾個屬性是每個緩沖區都有的并且是常用的操作。
          a. 容量(capacity),緩沖區大小
          b. 限制(limit),第一個不應被讀取或寫入的字節的索引,總是小于容量。
          c. 位置(position),下一個被讀取或寫入的字節的索引,總是小于限制。
          d. clear()方法:設置limit為capacity,position為0。
          e. filp()方法:設置limit為當前position,然后設置position為0。
          f. rewind()方法:保持limit不變,設置position為0。

          緩沖區數據操作
          操作包括了讀取和寫入數據兩種。
          讀取數據使用get()及其系列方法,除boolean外,每一種類型包括了對應的get()方法,如getInt(),getChar()等,get()方法用來讀取字節,支持相對和絕對索引兩種方式。
          寫入數據使用put()及其系列方法,和get()方法是對應的。

          package nio;

          import java.io.FileInputStream;
          import java.io.FileOutputStream;
          import java.nio.ByteBuffer;
          import java.nio.channels.FileChannel;

          public class BufferDemo ...{

              
              public static void main(String[] args) throws Exception...{
                  //分配一個非直接緩沖區
                  ByteBuffer bb = ByteBuffer.allocate(100);
                  //向緩沖區寫入0到100的字節制
                  for(int i = 0; i <100; i++)...{
                      byte b = (byte) (Math.random() * 100);
                      bb.put(b);
                  }
                  
                  System.out.println("寫入文件前的緩沖區數據");
                  bb.flip();
                  while(bb.hasRemaining())
                      System.out.print(bb.get() + " ");
                  System.out.println();
                  
                  //獲取一個關聯到文件buffer.txt的信道
                  FileChannel fc = new FileOutputStream("buffer.txt").getChannel();
                  //將緩沖區數據寫到文件中
                  bb.flip();
                  fc.write(bb);
                  //防止緩存
                  fc.force(true);
                  //關閉信道
                  fc.close();
                  bb = null;
                  fc = null;
                  
                  //下面從文件中讀取數據
                  fc = new FileInputStream("buffer.txt").getChannel();
                  ByteBuffer bb2 = ByteBuffer.allocate((int) fc.size());
                  fc.read(bb2);
                  System.out.println("從文件讀取的緩沖區數據");
                  bb2.flip();
                  while(bb2.hasRemaining())
                      System.out.print(bb2.get() + " ");
                  System.out.println();
                  fc.close();
                  bb2 = null;
                  fc = null;
                  

              }

          }

          內存映射文件

          第 8 種 Buffer 類型 MappedByteBuffer 只是一種特殊的 ByteBuffer 。 MappedByteBuffer 將文件所在區域直接映射到內存。通常,該區域包含整個文件,但也可以只映射部分文件。所以,必須指定要映射文件的哪部分。而且,與其它 Buffer 對象一樣,這里沒有構造函數;必須讓 java.nio.channels.FileChannel 的 map() 方法來獲取 MappedByteBuffer 。此外,無需過多涉及通道就可以用 getChannel() 方法從 FileInputStream 或 FileOutputStream 獲取 FileChannel 。通過從命令行傳入文件名來讀取文本文件的內容,清單 4 顯示了 MappedByteBuffer :


          清單 4. 讀取內存映射文本文件
          import java.io.*;
          import java.nio.*;
          import java.nio.channels.*;
          import java.nio.charset.*;
          public class ReadFileBuff {
            public static void main(String args[]) throws IOException {
               if (args.length != 0) {
                String filename = args[0];
                FileInputStream fis = new FileInputStream(filename);
                FileChannel channel = fis.getChannel();
                int length = (int)channel.size();
                MappedByteBuffer byteBuffer =
                  channel.map(FileChannel.MapMode.READ_ONLY, 0, length);
                Charset charset = Charset.forName("ISO-8859-1");
                CharsetDecoder decoder = charset.newDecoder();
                CharBuffer charBuffer = decoder.decode(byteBuffer);
                for (int i=0, n=charBuffer.length(); i<n; i++) {
                  System.out.print(charBuffer.get());
                }
              }
            }
          }

          posted @ 2007-08-01 11:13 比特鼠 閱讀(3826) | 評論 (0)編輯 收藏

          1. 左移操作: x << n
            x可以是byte, short, char, int, long基本類型, n(位移量)只能是int型

            編譯器的執行步驟:
            1) 如果x是byte, short, char類型, 則將x提升為int;
            2) 如果x是byte, short, char, int類型, 則n被重新賦值(過程是:取n的補碼的低5位再轉成十進制的int值,相當對n取32模: n=n%32);
               如果x是long型, 則n被重新賦值(過程是:取n的補碼的低6位再轉成十進制的int值,相當對n取64模: n=n%64);
               (因為int類型為4個字節,即32位,移動32位將沒有任何意義.對于long則是模64)
            3) 對x左移n個位數, 整個表達式產生一個新值(x的值不變);
          2. <<是左移符號,列x<<1,就是x的內容左移一位(x的內容并不改變)
          3. >>是帶符號位的右移符號,x>>1就是x的內容右移一位,如果開頭是1則補1,是0責補0,(x的內容并不改變).
          4. >>>是不帶符號位的右移,x>>>1就是x的內容右移一位,開頭補0(x的內容并不改變)
          posted @ 2007-08-01 10:12 比特鼠 閱讀(2807) | 評論 (0)編輯 收藏

          原文地址 http://www.programbbs.com/doc/2433.htm
          為什么會排隊等待?

          下面的這個簡單的 Java 程序完成四項不相關的任務。這樣的程序有單個控制線程,控制在這四個任務之間線性地移動。此外,因為所需的資源 — 打印機、磁盤、數據庫和顯示屏 -- 由于硬件和軟件的限制都有內在的潛伏時間,所以每項任務都包含明顯的等待時間。因此,程序在訪問數據庫之前必須等待打印機完成打印文件的任務,等等。如果您正在等待程序的完成,則這是對計算資源和您的時間的一種拙劣使用。改進此程序的一種方法是使它成為多線程的。
           
          四項不相關的任務
           

          class myclass {
              static public void main(String args[]) {
                  print_a_file();
                  manipulate_another_file();
                  access_database();
                  draw_picture_on_screen();
              }
          }

          在本例中,每項任務在開始之前必須等待前一項任務完成,即使所涉及的任務毫不相關也是這樣。但是,在現實生活中,我們經常使用多線程模型。我們在處理某些任務的同時也可以讓孩子、配偶和父母完成別的任務。例如,我在寫信的同時可能打發我的兒子去郵局買郵票。用軟件術語來說,這稱為多個控制(或執行)線程。

          可以用兩種不同的方法來獲得多個控制線程:

          多個進程
          在大多數操作系統中都可以創建多個進程。當一個程序啟動時,它可以為即將開始的每項任務創建一個進程,并允許它們同時運行。當一個程序因等待網絡訪問或用戶輸入而被阻塞時,另一個程序還可以運行,這樣就增加了資源利用率。但是,按照這種方式創建每個進程要付出一定的代價:設置一個進程要占用相當一部分處理器時間和內存資源。而且,大多數操作系統不允許進程訪問其他進程的內存空間。因此,進程間的通信很不方便,并且也不會將它自己提供給容易的編程模型。


          線程
          線程也稱為輕型進程 (LWP)。因為線程只能在單個進程的作用域內活動,所以創建線程比創建進程要廉價得多。這樣,因為線程允許協作和數據交換,并且在計算資源方面非常廉價,所以線程比進程更可取。線程需要操作系統的支持,因此不是所有的機器都提供線程。Java 編程語言,作為相當新的一種語言,已將線程支持與語言本身合為一體,這樣就對線程提供了強健的支持。


          使用 Java 編程語言實現線程
          Java 編程語言使多線程如此簡單有效,以致于某些程序員說它實際上是自然的。盡管在 Java 中使用線程比在其他語言中要容易得多,仍然有一些概念需要掌握。要記住的一件重要的事情是 main() 函數也是一個線程,并可用來做有用的工作。程序員只有在需要多個線程時才需要創建新的線程。

          Thread 類
          Thread 類是一個具體的類,即不是抽象類,該類封裝了線程的行為。要創建一個線程,程序員必須創建一個從 Thread 類導出的新類。程序員必須覆蓋 Thread 的 run() 函數來完成有用的工作。用戶并不直接調用此函數;而是必須調用 Thread 的 start() 函數,該函數再調用 run()。下面的代碼說明了它的用法:

          創建兩個新線程

          import java.util.*;

          class TimePrinter extends Thread {
              int pauseTime;

              String name;

              public TimePrinter(int x, String n) {
                  pauseTime = x;
                  name = n;
              }

              public void run() {
                  while (true) {
                      try {
                          System.out.println(name + ":"
                                  + new Date(System.currentTimeMillis()));
                          Thread.sleep(pauseTime);
                      } catch (Exception e) {
                          System.out.println(e);
                      }
                  }
              }

              static public void main(String args[]) {
                  TimePrinter tp1 = new TimePrinter(1000, "Fast Guy");
                  tp1.start();
                  TimePrinter tp2 = new TimePrinter(3000, "Slow Guy");
                  tp2.start();

              }
          }

          在本例中,我們可以看到一個簡單的程序,它按兩個不同的時間間隔(1 秒和 3 秒)在屏幕上顯示當前時間。這是通過創建兩個新線程來完成的,包括 main() 共三個線程。但是,因為有時要作為線程運行的類可能已經是某個類層次的一部分,所以就不能再按這種機制創建線程。雖然在同一個類中可以實現任意數量的接口,但 Java 編程語言只允許一個類有一個父類。同時,某些程序員避免從 Thread 類導出,因為它強加了類層次。對于這種情況,就要 runnable 接口。

          Runnable 接口
          此接口只有一個函數,run(),此函數必須由實現了此接口的類實現。但是,就運行這個類而論,其語義與前一個示例稍有不同。我們可以用 runnable 接口改寫前一個示例。(不同的部分用黑體表示。)

          創建兩個新線程而不強加類層次

          import java.util.*;

          class TimePrinter implements Runnable {
              int pauseTime;

              String name;

              public TimePrinter(int x, String n) {
                  pauseTime = x;
                  name = n;
              }

              public void run() {
                  while (true) {
                      try {
                          System.out.println(name + ":"
                                  + new Date(System.currentTimeMillis()));
                          Thread.sleep(pauseTime);
                      } catch (Exception e) {
                          System.out.println(e);
                      }
                  }
              }

              static public void main(String args[]) {
                  Thread t1 = new Thread(new TimePrinter(1000, "Fast Guy"));
                  t1.start();
                  Thread t2 = new Thread(new TimePrinter(3000, "Slow Guy"));
                  t2.start();

              }
          }

          請注意,當使用 runnable 接口時,您不能直接創建所需類的對象并運行它;必須從 Thread 類的一個實例內部運行它。許多程序員更喜歡 runnable 接口,因為從 Thread 類繼承會強加類層次。

          synchronized 關鍵字
          到目前為止,我們看到的示例都只是以非常簡單的方式來利用線程。只有最小的數據流,而且不會出現兩個線程訪問同一個對象的情況。但是,在大多數有用的程序中,線程之間通常有信息流。試考慮一個金融應用程序,它有一個 Account 對象,如下例中所示:

          一個銀行中的多項活動

          public class Account {
              String holderName;

              float amount;

              public Account(String name, float amt) {
                  holderName = name;
                  amount = amt;
              }

              public void deposit(float amt) {
                  amount += amt;
              }

              public void withdraw(float amt) {
                  amount -= amt;
              }

              public float checkBalance() {
                  return amount;
              }
          }

          在此代碼樣例中潛伏著一個錯誤。如果此類用于單線程應用程序,不會有任何問題。但是,在多線程應用程序的情況中,不同的線程就有可能同時訪問同一個 Account 對象,比如說一個聯合帳戶的所有者在不同的 ATM 上同時進行訪問。在這種情況下,存入和支出就可能以這樣的方式發生:一個事務被另一個事務覆蓋。這種情況將是災難性的。但是,Java 編程語言提供了一種簡單的機制來防止發生這種覆蓋。每個對象在運行時都有一個關聯的鎖。這個鎖可通過為方法添加關鍵字 synchronized 來獲得。這樣,修訂過的 Account 對象(如下所示)將不會遭受像數據損壞這樣的錯誤:

          對一個銀行中的多項活動進行同步處理

          public class Account {
              String holderName;

              float amount;

              public Account(String name, float amt) {
                  holderName = name;
                  amount = amt;
              }

              public synchronized void deposit(float amt) {
                  amount += amt;
              }

              public synchronized void withdraw(float amt) {
                  amount -= amt;
              }

              public float checkBalance() {
                  return amount;
              }
          }

          deposit() 和 withdraw() 函數都需要這個鎖來進行操作,所以當一個函數運行時,另一個函數就被阻塞。請注意,checkBalance() 未作更改,它嚴格是一個讀函數。因為 checkBalance() 未作同步處理,所以任何其他方法都不會阻塞它,它也不會阻塞任何其他方法,不管那些方法是否進行了同步處理。

          Java 編程語言中的高級多線程支持

          線程組
          線程是被個別創建的,但可以將它們歸類到線程組中,以便于調試和監視。只能在創建線程的同時將它與一個線程組相關聯。在使用大量線程的程序中,使用線程組組織線程可能很有幫助。可以將它們看作是計算機上的目錄和文件結構。

          線程間發信
          當線程在繼續執行前需要等待一個條件時,僅有 synchronized 關鍵字是不夠的。雖然 synchronized 關鍵字阻止并發更新一個對象,但它沒有實現線程間發信。Object 類為此提供了三個函數:wait()、notify() 和 notifyAll()。以全球氣候預測程序為例。這些程序通過將地球分為許多單元,在每個循環中,每個單元的計算都是隔離進行的,直到這些值趨于穩定,然后相鄰單元之間就會交換一些數據。所以,從本質上講,在每個循環中各個線程都必須等待所有線程完成各自的任務以后才能進入下一個循環。這個模型稱為屏蔽同步,下例說明了這個模型:

          屏蔽同步

          public class BSync {
              int totalThreads;

              int currentThreads;

              public BSync(int x) {
                  totalThreads = x;
                  currentThreads = 0;
              }

              public synchronized void waitForAll() {
                  currentThreads++;
                  if (currentThreads < totalThreads) {
                      try {
                          wait();
                      } catch (Exception e) {
                      }
                  } else {
                      currentThreads = 0;
                      notifyAll();
                  }
              }
          }

          當對一個線程調用 wait() 時,該線程就被有效阻塞,只到另一個線程對同一個對象調用 notify() 或 notifyAll() 為止。因此,在前一個示例中,不同的線程在完成它們的工作以后將調用 waitForAll() 函數,最后一個線程將觸發 notifyAll() 函數,該函數將釋放所有的線程。第三個函數 notify() 只通知一個正在等待的線程,當對每次只能由一個線程使用的資源進行訪問限制時,這個函數很有用。但是,不可能預知哪個線程會獲得這個通知,因為這取決于 Java 虛擬機 (JVM) 調度算法。

          將 CPU 讓給另一個線程
          當線程放棄某個稀有的資源(如數據庫連接或網絡端口)時,它可能調用 yield() 函數臨時降低自己的優先級,以便某個其他線程能夠運行。

          守護線程
          有兩類線程:用戶線程和守護線程。用戶線程是那些完成有用工作的線程。守護線程是那些僅提供輔助功能的線程。Thread 類提供了 setDaemon() 函數。Java 程序將運行到所有用戶線程終止,然后它將破壞所有的守護線程。在 Java 虛擬機 (JVM) 中,即使在 main 結束以后,如果另一個用戶線程仍在運行,則程序仍然可以繼續運行。

          避免不提倡使用的方法
          不提倡使用的方法是為支持向后兼容性而保留的那些方法,它們在以后的版本中可能出現,也可能不出現。Java 多線程支持在版本 1.1 和版本 1.2 中做了重大修訂,stop()、suspend() 和 resume() 函數已不提倡使用。這些函數在 JVM 中可能引入微妙的錯誤。雖然函數名可能聽起來很誘人,但請抵制誘惑不要使用它們。

          調試線程化的程序
          在線程化的程序中,可能發生的某些常見而討厭的情況是死鎖、活鎖、內存損壞和資源耗盡。

          死鎖
          死鎖可能是多線程程序最常見的問題。當一個線程需要一個資源而另一個線程持有該資源的鎖時,就會發生死鎖。這種情況通常很難檢測。但是,解決方案卻相當好:在所有的線程中按相同的次序獲取所有資源鎖。例如,如果有四個資源 —A、B、C 和 D — 并且一個線程可能要獲取四個資源中任何一個資源的鎖,則請確保在獲取對 B 的鎖之前首先獲取對 A 的鎖,依此類推。如果“線程 1”希望獲取對 B 和 C 的鎖,而“線程 2”獲取了 A、C 和 D 的鎖,則這一技術可能導致阻塞,但它永遠不會在這四個鎖上造成死鎖。

          活鎖
          當一個線程忙于接受新任務以致它永遠沒有機會完成任何任務時,就會發生活鎖。這個線程最終將超出緩沖區并導致程序崩潰。試想一個秘書需要錄入一封信,但她一直在忙于接電話,所以這封信永遠不會被錄入。

          內存損壞
          如果明智地使用 synchronized 關鍵字,則完全可以避免內存錯誤這種氣死人的問題。

          資源耗盡
          某些系統資源是有限的,如文件描述符。多線程程序可能耗盡資源,因為每個線程都可能希望有一個這樣的資源。如果線程數相當大,或者某個資源的侯選線程數遠遠超過了可用的資源數,則最好使用資源池。一個最好的示例是數據庫連接池。只要線程需要使用一個數據庫連接,它就從池中取出一個,使用以后再將它返回池中。資源池也稱為資源庫。

          調試大量的線程
          有時一個程序因為有大量的線程在運行而極難調試。在這種情況下,下面的這個類可能會派上用場:

          public class Probe extends Thread {
              public Probe() {
              }

              public void run() {

                  while (true) {
                      Thread[] x = new Thread[100];
                      Thread.enumerate(x);

                      for (int i = 0; i < 100; i++) {
                          Thread t = x[i];
                          if (t == null)
                              break;
                          else
                              System.out.println(t.getName() + "\t" + t.getPriority()
                                      + "\t" + t.isAlive() + "\t" + t.isDaemon());
                      }
                  }
              }
          }

          限制線程優先級和調度
          Java 線程模型涉及可以動態更改的線程優先級。本質上,線程的優先級是從 1 到 10 之間的一個數字,數字越大表明任務越緊急。JVM 標準首先調用優先級較高的線程,然后才調用優先級較低的線程。但是,該標準對具有相同優先級的線程的處理是隨機的。如何處理這些線程取決于基層的操作系統策略。在某些情況下,優先級相同的線程分時運行;在另一些情況下,線程將一直運行到結束。請記住,Java 支持 10 個優先級,基層操作系統支持的優先級可能要少得多,這樣會造成一些混亂。因此,只能將優先級作為一種很粗略的工具使用。最后的控制可以通過明智地使用 yield() 函數來完成。通常情況下,請不要依靠線程優先級來控制線程的狀態。

          小結
          本文說明了在 Java 程序中如何使用線程。像是否應該使用線程這樣的更重要的問題在很大程序上取決于手頭的應用程序。決定是否在應用程序中使用多線程的一種方法是,估計可以并行運行的代碼量。并記住以下幾點:

          使用多線程不會增加 CPU 的能力。但是如果使用 JVM 的本地線程實現,則不同的線程可以在不同的處理器上同時運行(在多 CPU 的機器中),從而使多 CPU 機器得到充分利用。
          如果應用程序是計算密集型的,并受 CPU 功能的制約,則只有多 CPU 機器能夠從更多的線程中受益。
          當應用程序必須等待緩慢的資源(如網絡連接或數據庫連接)時,或者當應用程序是非交互式的時,多線程通常是有利的。
          基于 Internet 的軟件有必要是多線程的;否則,用戶將感覺應用程序反映遲鈍。例如,當開發要支持大量客戶機的服務器時,多線程可以使編程較為容易。在這種情況下,每個線程可以為不同的客戶或客戶組服務,從而縮短了響應時間。

          某些程序員可能在 C 和其他語言中使用過線程,在那些語言中對線程沒有語言支持。這些程序員可能通常都被搞得對線程失去了信心。

          posted @ 2007-07-30 09:36 比特鼠 閱讀(214) | 評論 (0)編輯 收藏

          眾所周知, Java在從XML文件中裝載內容到內存過程中,不論用何種方式,IO操作的開銷都無可避免。本文嘗試比較dom4j中的XPP3和SAX兩種方式裝載XML文件的性能,以便將IO操作的開銷降到最小!

          package gz.lwm;

          import java.io.File;
          import org.apache.log4j.Logger;
          import org.dom4j.Document;
          import org.dom4j.DocumentHelper;
          import org.dom4j.io.SAXReader;
          import org.dom4j.io.XPP3Reader;

          public class TestDom4j {
           private static final Logger log = Logger.getLogger(TestDom4j.class);
           private static long bt; 
           
           public static void main(String[] args) {
            Document doc = DocumentHelper.createDocument();   
            //先運行getXmlSAX()
            bt = System.currentTimeMillis();
            String strXml = getXmlSAX("xml/test.xml");
            if(log.isDebugEnabled()){
             log.debug("\ngetXmlSAX() use time: " + (System.currentTimeMillis() - bt) + " millis\n");
            }

            //再運行getXmlXPP3()
            bt = System.currentTimeMillis();
            String s1 =getXmlXPP3("xml/test.xml");
            if(log.isDebugEnabled()){
             log.debug("\ngetXmlXPP3() use time: " + (System.currentTimeMillis() - bt) + " millis\n");
            }
            
            
           }
           
           public static String getXmlSAX(String xmlFile){
            String result = "";
            try {
             SAXReader reader = new SAXReader();
             Document document = reader.read(new File(xmlFile));
             result = document.asXML();
            } catch (Exception e) {
             e.printStackTrace();
            }
            return result;
           }
           
           public static String getXmlXPP3(String xmlFile){
            String result = "";
            try {
             XPP3Reader reader = new XPP3Reader();
             Document document = reader.read(new File(xmlFile));
             result = document.asXML();
            } catch (Exception e) {
             e.printStackTrace();
            }
            return result;
           }


           
          }

          有沒有這一句"Document doc = DocumentHelper.createDocument()",對性能的影響很大,特別是對大xml文件(盡管并沒有使用doc)

          另外, getXmlXSAX()和getXmlXPP3()運行的先后次序對性能的影響也很大!

          測試:
              在我的機器上,對一個100k左右的XML文件進行多次測試后的均值結果為:

              getXmlXPP3() use time: 265 millis
              ...
              getXmlXSAX() use time: 359 millis
              ...

          結論:
              通過比較,在讀取XML文件上,XPP3略為優于SAX!


          注意:

          要運行例子,classpath需包含:
          dom4j-1.6.1.jar
          jaxen-1.1-beta-10.jar
          log4j-1.2.9.jar
          pull-parser-2.1.10.jar
          xpp3-1.1.4c.jar


          參考:
          dom4j :  http://www.dom4j.org/
          XPP   :  http://www.extreme.indiana.edu/xgws/xsoap/xpp/

          posted @ 2007-05-19 00:39 比特鼠 閱讀(2511) | 評論 (0)編輯 收藏

          主站蜘蛛池模板: 陕西省| 潜山县| 宁海县| 锡林郭勒盟| 梁河县| 临沂市| 西华县| 枣强县| 诸暨市| 苍山县| 历史| 普兰店市| 荣昌县| 舟曲县| 邵阳县| 苏州市| 新乡市| 若羌县| 登封市| 寻乌县| 上饶县| 吉水县| 灯塔市| 山东| 睢宁县| 阿拉善左旗| 隆昌县| 会宁县| 色达县| 石棉县| 宜州市| 太原市| 云南省| 宝坻区| 驻马店市| 黄龙县| 浦东新区| 临清市| 曲松县| 三都| 稷山县|