2012年8月23日
本文簡(jiǎn)單介紹一下在寫代碼過程中用到的一些讓JAVA代碼更高效的技巧。
1,將一些系統(tǒng)資源放在池中,如數(shù)據(jù)庫(kù)連接,線程等.在standalone的應(yīng)用中,數(shù)據(jù)庫(kù)連接池可以使用一些開源的連接池實(shí)現(xiàn),如C3P0,proxool和DBCP等,在運(yùn)行在容器中的應(yīng)用這可以使用服務(wù)器提供的DataSource.線程池可以使用JDK本身就提供的java.util.concurrent.ExecutorService.
- import java.util.concurrent.Executors;
- import java.util.concurrent.ExecutorService;
- public class JavaThreadPool {
- public static void main(String[] args) {
- ExecutorService pool = Executors.newFixedThreadPool(2);
-
- Thread t1 = new MyThread();
- Thread t2 = new MyThread();
- Thread t3 = new MyThread();
- Thread t4 = new MyThread();
- Thread t5 = new MyThread();
-
- pool.execute(t1);
- pool.execute(t2);
- pool.execute(t3);
- pool.execute(t4);
-
- pool.shutdown();
- }
- }
-
- class MyThread extends Thread {
- public void run() {
- System.out.println(Thread.currentThread().getName() + "running....");
- }
- }
2,減少網(wǎng)絡(luò)開銷,在和數(shù)據(jù)庫(kù)或者遠(yuǎn)程服務(wù)交互的時(shí)候,盡量將多次調(diào)用合并到一次調(diào)用中。
3,將經(jīng)常訪問的外部資源cache到內(nèi)存中,簡(jiǎn)單的可以使用static的hashmap在應(yīng)用啟動(dòng)的時(shí)候加載,也可以使用一些開源的cache框架,如OSCache和Ehcache等.和資源的同步可以考慮定期輪詢和外部資源更新時(shí)候主動(dòng)通知.或者在自己寫的代碼中留出接口(命令方式或者界面方式)共手動(dòng)同步。
4,優(yōu)化IO操作,JAVA操作文件的時(shí)候分InputStream and OutputStream,Reader and Writer兩類,stream的方式要快,后者主要是為了操作字符而用的,在字符僅僅是ASCII的時(shí)候可以用stream的方式提高效率.JDK1.4之后的nio比io的效率更好。java教程下載
- OutputStream out = new BufferedOutputStream(new FileOutputStream(new File("d:/temp/test.txt")));
- out.write("abcde".getBytes());
- out.flush();
- out.close();
利用BufferedInputStream,BufferedOutputStream,BufferedReader,BufferedWriter減少對(duì)磁盤的直接訪問次數(shù)。
- FileReader fr = new FileReader(f);
- BufferedReader br = new BufferedReader(fr);
- while (br.readLine() != null) count++;
5不要頻繁的new對(duì)象,對(duì)于在整個(gè)應(yīng)用中只需要存在一個(gè)實(shí)例的類使用單例模式.對(duì)于String的連接操作,使用StringBuffer或者StringBuilder.對(duì)于utility類型的類通過靜態(tài)方法來訪問。
6,避免使用錯(cuò)誤的方式,如Exception可以控制方法推出,但是Exception要保留stacktrace消耗性能,除非必要不要使用instanceof做條件判斷,盡量使用比的條件判斷方式.使用JAVA中效率高的類,比如ArrayList比Vector性能好。
7,對(duì)性能的考慮要在系統(tǒng)分析和設(shè)計(jì)之初就要考慮。
總之,一個(gè)系統(tǒng)運(yùn)行時(shí)的性能,無非是從CPU,Memory和IO這三個(gè)主要方面來考慮優(yōu)化.減少不必要的CPU消耗,減少不必要的IO操作,增加Memory利用效率。
提升網(wǎng)站性能的方式有很多,例如有效的使用緩存,生成靜態(tài)頁(yè)面等等。今天要說的就是生成靜態(tài)頁(yè)面的方式。這個(gè)也是我近期一直在搞的一個(gè)問題,近期在做使用html + servlet做個(gè)人網(wǎng)站,為什么是這2個(gè)東西呢?
1、直接用servlet是為了保證網(wǎng)站能以最快的速度執(zhí)行命令個(gè)人總感覺像Struts hibernate spring之類的雖然方便但是效能帶來的損耗不太能接收
2、使用html同樣是為了保證最快的反應(yīng)速度,畢竟html 比jsp少了一層服務(wù)器執(zhí)行。速度上要快的多
一、在這里要先說一下什么是頁(yè)面靜態(tài)化:
簡(jiǎn)單的說,我們?nèi)绻L問一個(gè)鏈接 ,服務(wù)器對(duì)應(yīng)的模塊會(huì)處理這個(gè)請(qǐng)求,轉(zhuǎn)到對(duì)應(yīng)的jsp界面,最后生成我們想要看到的數(shù)據(jù)。這其中的缺點(diǎn)是顯而易見的:因?yàn)槊看握?qǐng)求服務(wù)器都會(huì)進(jìn)行處理,如果有太多的高并發(fā)請(qǐng)求,那么就會(huì)加重應(yīng)用服務(wù)器的壓力,弄不好就把服務(wù)器 搞down 掉了。那么如何去避免呢?如果我們把對(duì) test.do 請(qǐng)求后的結(jié)果保存成一個(gè) html 文件,然后每次用戶都去訪問 ,這樣應(yīng)用服務(wù)器的壓力不就減少了?
那么靜態(tài)頁(yè)面從哪里來呢?總不能讓我們每個(gè)頁(yè)面都手動(dòng)處理吧?這里就牽涉到我們要講解的內(nèi)容了,靜態(tài)頁(yè)面生成方案… 我們需要的是自動(dòng)的生成靜態(tài)頁(yè)面,當(dāng)用戶訪問 ,會(huì)自動(dòng)生成 test.html ,然后顯示給用戶。
二、下面我們?cè)诤?jiǎn)單介紹一下要想掌握頁(yè)面靜態(tài)化方案應(yīng)該掌握的知識(shí)點(diǎn)
1、 基礎(chǔ)- URL Rewrite
什么是 URL Rewrite 呢 ? URL 重寫。用一個(gè)簡(jiǎn)單的例子來說明問題:輸入網(wǎng)址 ,但是實(shí)際上訪問的卻是 abc.com/test.action,那我們就可以說 URL 被重寫了。這項(xiàng)技術(shù)應(yīng)用廣泛,有許多開源的工具可以實(shí)現(xiàn)這個(gè)功能。java電子書免費(fèi)下載2、 基礎(chǔ)- Servlet web.xml
如果你還不知道 web.xml 中一個(gè)請(qǐng)求和一個(gè) servlet 是如何匹配到一起的,那么請(qǐng)搜索一下 servlet 的文檔。這可不是亂說呀,有很多人就認(rèn)為 /xyz/*.do 這樣的匹配方式能有效。
如果你還不知道怎么編寫一個(gè) servlet ,那么請(qǐng)搜索一下如何編寫 servlet.這可不是說笑呀,在各種集成工具漫天飛舞的今天,很多人都不會(huì)去從零編寫一個(gè) servlet了。
三、基本的方案介紹

其中,對(duì)于 URL Rewriter的部分,可以使用收費(fèi)或者開源的工具來實(shí)現(xiàn),如果 url不是特別的復(fù)雜,可以考慮在 servlet 中實(shí)現(xiàn),那么就是下面這個(gè)樣子:

以前在學(xué)校的時(shí)候自己以為是不是每個(gè)做JAVA開發(fā)的公司每次做項(xiàng)目的時(shí)候都要搭建一個(gè)SSH框架呢,工作之后才發(fā)現(xiàn)每個(gè)公司都有自己的一套框架,要不是在SSH基礎(chǔ)上,要不是在SSI基礎(chǔ)上進(jìn)行了符合自己公司需求的封裝,并且隨著自己公司的框架被應(yīng)用到各個(gè)實(shí)際系統(tǒng)的過程中,這個(gè)框架會(huì)越來越成熟,會(huì)使該公司的開發(fā)效率越來越高。
根據(jù)筆者接觸過的幾個(gè)公司的框架,筆者發(fā)現(xiàn)要想實(shí)現(xiàn)高效的開發(fā),每個(gè)公司的框架應(yīng)該具備如下的特點(diǎn):
1.具有靈活的分頁(yè)功能。
分頁(yè)功能是每個(gè)項(xiàng)目中必須要實(shí)現(xiàn)的功能,而恰恰這個(gè)功能是比較費(fèi)時(shí)費(fèi)力的,如果在框架中實(shí)現(xiàn)這一功能,將在每個(gè)項(xiàng)目中大大減少分頁(yè)的重復(fù)性工作。
2.可以方便的實(shí)現(xiàn)文件的上傳與下載、數(shù)據(jù)的導(dǎo)入和導(dǎo)出的功能。
文件的上傳于下載、數(shù)據(jù)的導(dǎo)入和導(dǎo)出在大部門項(xiàng)目中也會(huì)遇到,但是這兩個(gè)功能可能會(huì)因?yàn)轫?xiàng)目的不同導(dǎo)致實(shí)現(xiàn)上有一點(diǎn)區(qū)別,我們框架中要做的就是應(yīng)該抽出其中共有的東西,定義為抽象的東西,以便不同的項(xiàng)目、不同的需求都能很容易的實(shí)現(xiàn)該功能。成都java培訓(xùn)機(jī)構(gòu)
3.方便的事務(wù)管理功能。
事務(wù)管理一般來說都定義在業(yè)務(wù)邏輯層。我們框架中應(yīng)該實(shí)現(xiàn)對(duì)業(yè)務(wù)邏輯對(duì)象事務(wù)的簡(jiǎn)單配置甚至是零配置。筆者接觸過的兩個(gè)框架中,一個(gè)需要在配置完一個(gè)業(yè)務(wù)邏輯對(duì)象時(shí),在事務(wù)管理的配置文件中加上一句簡(jiǎn)單的配置即可,另一個(gè)是框架中實(shí)現(xiàn)了幾個(gè)基本的業(yè)務(wù)邏輯對(duì)象,并對(duì)這幾個(gè)對(duì)象實(shí)現(xiàn)了事務(wù)管理的配置,開發(fā)的時(shí)候定義的業(yè)務(wù)邏輯對(duì)象都是繼承自這幾個(gè)基本對(duì)象,也就省去了事務(wù)管理的配置。
4.具有異常處理框架。
基本上每個(gè)項(xiàng)目的異常處理都應(yīng)該可以使用公司的框架定義的異常處理框架,并不會(huì)因?yàn)轫?xiàng)目的不同而要求的異常處理也不一樣。
5.具有自己的一套頁(yè)面組件。
項(xiàng)目開發(fā)都是團(tuán)隊(duì)的開發(fā),要想保證每個(gè)開發(fā)人員的界面風(fēng)格統(tǒng)一,最好的辦法就是定義一套公司自己的頁(yè)面組建。這樣既能保證開發(fā)效率,也能做到界面的統(tǒng)一。freemark就是不錯(cuò)的選擇,其支持自定義宏,公司框架中可以定義一套自己的頁(yè)面組建宏,供開發(fā)人員調(diào)用即可。
6.具有數(shù)據(jù)校驗(yàn)框架。
每個(gè)項(xiàng)目在數(shù)據(jù)校驗(yàn)時(shí)都可能會(huì)用到大量的正則表達(dá)式,那么在公司的框架中將這些正則表達(dá)式封裝起來,提供統(tǒng)一的調(diào)用接口將是不錯(cuò)的選擇。
7.簡(jiǎn)單的實(shí)現(xiàn)菜單的配置。
一個(gè)好的框架應(yīng)該提供對(duì)菜單、二級(jí)菜單等的簡(jiǎn)單配置、管理。還是上文提到的兩個(gè)框架,一個(gè)是通過XML配置文件實(shí)現(xiàn)了對(duì)系統(tǒng)中一級(jí)菜單、二級(jí)菜單、三級(jí)菜單的管理,而另個(gè)框架要實(shí)現(xiàn)相同的需求卻要在數(shù)據(jù)庫(kù)中進(jìn)行繁瑣的配置,顯然第一個(gè)框架的實(shí)現(xiàn)方案更可取、更高效。
2012年8月22日
摘要:眾所周知,隨機(jī)數(shù)是任何一種編程語(yǔ)言最基本的特征之一。而生成隨機(jī)數(shù)的基本方式也是相同的:產(chǎn)生一個(gè)0到1之間的隨機(jī)數(shù)。看似簡(jiǎn)單,但有時(shí)我們也會(huì)忽略了一些有趣的功能。
眾所周知,隨機(jī)數(shù)是任何一種編程語(yǔ)言最基本的特征之一。而生成隨機(jī)數(shù)的基本方式也是相同的:產(chǎn)生一個(gè)0到1之間的隨機(jī)數(shù)。看似簡(jiǎn)單,但有時(shí)我們也會(huì)忽略了一些有趣的功能。
我們從書本上學(xué)到什么?
最明顯的,也是直觀的方式,在Java中生成隨機(jī)數(shù)只要簡(jiǎn)單的調(diào)用:
- java.lang.Math.random()
在所有其他語(yǔ)言中,生成隨機(jī)數(shù)就像是使用Math工具類,如abs, pow, floor, sqrt和其他數(shù)學(xué)函數(shù)。大多數(shù)人通過書籍、教程和課程來了解這個(gè)類。一個(gè)簡(jiǎn)單的例子:從0.0到1.0之間可以生成一個(gè)雙精度浮點(diǎn)數(shù)。那么通過上面的信息,開發(fā)人員要產(chǎn)生0.0和10.0之間的雙精度浮點(diǎn)數(shù)會(huì)這樣來寫:
- Math.random() * 10
而產(chǎn)生0和10之間的整數(shù),則會(huì)寫成:
- Math.round(Math.random() * 10)
進(jìn)階
通過閱讀Math.random()的源碼,或者干脆利用IDE的自動(dòng)完成功能,開發(fā)人員可以很容易發(fā)現(xiàn),java.lang.Math.random()使用一個(gè)內(nèi)部的隨機(jī)生成對(duì)象 - 一個(gè)很強(qiáng)大的對(duì)象可以靈活的隨機(jī)產(chǎn)生:布爾值、所有數(shù)字類型,甚至是高斯分布。例如:
- new java.util.Random().nextInt(10)
它有一個(gè)缺點(diǎn),就是它是一個(gè)對(duì)象。它的方法必須是通過一個(gè)實(shí)例來調(diào)用,這意味著必須先調(diào)用它的構(gòu)造函數(shù)。如果在內(nèi)存充足的情況下,像上面的表達(dá)式是可以接受的;但內(nèi)存不足時(shí),就會(huì)帶來問題。java教程下載一個(gè)簡(jiǎn)單的解決方案,可以避免每次需要生成一個(gè)隨機(jī)數(shù)時(shí)創(chuàng)建一個(gè)新實(shí)例,那就是使用一個(gè)靜態(tài)類。猜你可能想到了java.lang.Math,很好,我們就是改良java.lang.Math的初始化。雖然這個(gè)工程量低,但你也要做一些簡(jiǎn)單的單元測(cè)試來確保其不會(huì)出錯(cuò)。
假設(shè)程序需要生成一個(gè)隨機(jī)數(shù)來存儲(chǔ),問題就又來了。比如有時(shí)需要操作或保護(hù)種子(seed),一個(gè)內(nèi)部數(shù)用來存儲(chǔ)狀態(tài)和計(jì)算下一個(gè)隨機(jī)數(shù)。在這些特殊情況下,共用隨機(jī)生成對(duì)象是不合適的。
并發(fā)
在Java EE多線程應(yīng)用程序的環(huán)境中,隨機(jī)生成實(shí)例對(duì)象仍然可以被存儲(chǔ)在類或其他實(shí)現(xiàn)類,作為一個(gè)靜態(tài)屬性。幸運(yùn)的是,java.util.Random是線程安全的,所以不存在多個(gè)線程調(diào)用會(huì)破壞種子(seed)的風(fēng)險(xiǎn)。
另一個(gè)值得考慮的是多線程java.lang.ThreadLocal的實(shí)例。偷懶的做法是通過Java本身API實(shí)現(xiàn)單一實(shí)例,當(dāng)然你也可以確保每一個(gè)線程都有自己的一個(gè)實(shí)例對(duì)象。
雖然Java沒有提供一個(gè)很好的方法來管理java.util.Random的單一實(shí)例。但是,期待已久的Java 7提供了一種新的方式來產(chǎn)生隨機(jī)數(shù):
- java.util.concurrent.ThreadLocalRandom.current().nextInt(10)
這個(gè)新的API綜合了其他兩種方法的優(yōu)點(diǎn):?jiǎn)我粚?shí)例/靜態(tài)訪問,就像Math.random()一樣靈活。ThreadLocalRandom也比其他任何處理高并發(fā)的方法要更快。
經(jīng)驗(yàn)
Chris Marasti-Georg 指出:
- Math.round(Math.random() * 10)
使分布不平衡,例如:0.0 - 0.499999將四舍五入為0,而0.5至1.499999將四舍五入為1。那么如何使用舊式語(yǔ)法來實(shí)現(xiàn)正確的均衡分布,如下:
- Math.floor(Math.random() * 11)
幸運(yùn)的是,如果我們使用java.util.Random或java.util.concurrent.ThreadLocalRandom就不用擔(dān)心上述問題了。
Java實(shí)戰(zhàn)項(xiàng)目里面介紹了一些不正確使用java.util.Random API的危害。這個(gè)教訓(xùn)告訴我們不要使用:
- Math.abs(rnd.nextInt())%n
而使用:
- rnd.nextInt(n)
摘要:我們一直在期待著Java 8的新功能,雖然很大一部分是對(duì)Java 7的擴(kuò)展,發(fā)布時(shí)間也一推再推。但如今甲骨文終于承諾:新版本將是徹底的變革而不僅僅是Java 7的擴(kuò)展。那Java 8到底是什么樣的呢?
我們一直在期待著Java 8的新功能,雖然很大一部分是對(duì)Java 7的擴(kuò)展,發(fā)布時(shí)間也一推再推。但如今甲骨文終于承諾:新版本將是徹底的變革而不僅僅是Java 7的擴(kuò)展。那Java 8到底是什么樣的呢?
甲骨文的Java總架構(gòu)師馬克•雷納德在2011年JavaOne大會(huì)上為大家透露了Java 8的新功能,同時(shí)也談到了一些關(guān)于Java 9的計(jì)劃。他說,Java 7未能實(shí)現(xiàn)五個(gè)關(guān)鍵的功能是非常遺憾的一件事,而且另外兩個(gè)功能為了配合發(fā)布日期也只好作罷。馬克認(rèn)為,Java 7的更新是非常重要的,他還暗示,Java 8將從根本上改變編程語(yǔ)言的功能。看完下面的介紹你也許會(huì)明白馬克的說法不是天方夜譚。
Java 8包含兩個(gè)主要項(xiàng)目:
1. Lambda
在Lambda項(xiàng)目中,多核處理器下的Java編程將更高效,Lambda表達(dá)式可以幫助開發(fā)人員提高效率,更好地利用多核處理器。Lambda項(xiàng)目還包括一個(gè)新的處理系統(tǒng),該系統(tǒng)允許要求代碼建模的編程模式作為數(shù)據(jù)。新功能一覽:
- Lambda表達(dá)式的運(yùn)用
- 擴(kuò)展目標(biāo)類型化
- 方法和構(gòu)造函數(shù)參考
- 默認(rèn)方法
2. Jigsaw
Jigsaw項(xiàng)目的目標(biāo)是創(chuàng)建一個(gè)實(shí)用的方式來在JDK上設(shè)計(jì)和實(shí)施一個(gè)模塊系統(tǒng),然后將該系統(tǒng)應(yīng)用于JDK本身。其關(guān)鍵是令大塊的代碼更易于管理,并促進(jìn)應(yīng)用和大型運(yùn)算的代碼重用。Jigsaw項(xiàng)目還帶來了許多新的表單功能,涉及封裝、重構(gòu)、版本和模塊集成。
此外,除了這兩個(gè)項(xiàng)目,Java 8 還增加改進(jìn)了一些其他語(yǔ)言功能,如升級(jí)核心Java庫(kù)使并行運(yùn)算的表達(dá)更容易;虛擬擴(kuò)展方法允許對(duì)接口增加方法,為默認(rèn)實(shí)現(xiàn)指定參考;增加新的日期/時(shí)間API,同時(shí)支持傳感器,增加代碼的部署選項(xiàng)。
Java 9、10的發(fā)展規(guī)劃
甲骨文對(duì)Java 8 的前景很是看好,并已經(jīng)開始討論Java 9發(fā)展的關(guān)鍵領(lǐng)域。比如加入一個(gè)self-tuning JVM,提高本地集成和大規(guī)模多核的可擴(kuò)展性;通過新的元對(duì)象協(xié)議和資源管理器為云應(yīng)用添加跨語(yǔ)言支持。java電子書免費(fèi)下載
甲骨文也表示,Java9和10將加入大數(shù)據(jù)、多語(yǔ)言的互操作性、云計(jì)算和移動(dòng),預(yù)期分別于2015年和2017年發(fā)布。而關(guān)于Java開發(fā)工具包(JDK)10以及之后的版本也正在討論中,比如使Java語(yǔ)言面向?qū)ο螅纬梢粋€(gè)統(tǒng)一的類型系統(tǒng),所有原語(yǔ)都將轉(zhuǎn)換為對(duì)象和方法。
隨著使用人數(shù)的增加,Java正逐漸成為最常用的編程語(yǔ)言,令每個(gè)使用者都滿意成了它的目標(biāo)。甲骨文認(rèn)為Java在將來會(huì)成為開發(fā)者們首選的編程語(yǔ)言,因?yàn)樗梢詫?shí)現(xiàn)的東西正好符合了開發(fā)者們的期望。
選擇排序:讓第一個(gè)跟后面的每個(gè)元素比較,如果大于則交換量元素的位置,第二次則讓第二個(gè)元素跟后面的元素一次比較(因?yàn)榈谝粋€(gè)元素的位置已經(jīng)定了),一次類推直到最后一個(gè)元素.
代碼:
public class TestChoose {
public static void main(String[] args) {
int[] arr = {8,3,67,43,21,56,78};
choose(arr);
printArray(arr);
}
public static void choose(int[] arr){
int temp = 0;
for(int i = 0;i < arr.length;i ++){
for(int j = i+1;j < arr.length;j ++){
if(arr[i]>arr[j]){
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
}
public static void printArray(int[] arr){
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
System.out.println();
}
}
當(dāng)if(arr[i]>arr[j])時(shí):為升序排列
if(arr[i]<arr[j])時(shí):為降序排列
代碼:
public static void bubbleSort(int[] arr){
int temp = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length -i -1; j++) {
if(arr[j]>arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
對(duì)上面中arr.length-x-1說明
-x 是為了每次少比一次,每次比完以后最后的那個(gè)元素位值就確定了,所以沒有必要再比
成都java培訓(xùn)機(jī)構(gòu)-1 是防止數(shù)組越界,當(dāng)我i=0的事,j最后一次就是arr.length,如果不減1,則會(huì)出現(xiàn)數(shù)組訪問越界
把上面的代碼中的choose(arr)改成bubbleSort(arr)可以測(cè)試冒泡排序的算法