2012年4月19日

          perf4j使用四(log4j集成圖表查看)

           

          在使用二這編文章中提到,可以以匯總形式查看日志,也可以通過圖表來查看。Perf4jlog4j集成后,其實也可以以圖表的形式來查看性能狀況。

           

          我們這篇文章還是使用前一篇文章中提到log4j.xml的配置,其他都一樣,只是在配置中加入了圖表的配置:

          <!-- 生成firstBlock,secondBlock的平均值的圖表 -->

              <appender name="graphExecutionTimes"

                        class="org.perf4j.log4j.GraphingStatisticsAppender">

                  <!-- GraphType:Mean(平均值), Min(最小值), Max(最大值), TPS(每秒事務數) -->

                  <param name="GraphType" value="Mean"/>

                  <param name="TagNamesToGraph" value="firstBlock,secondBlock"/>

                  <appender-ref ref="graphsFileAppender"/>

              </appender>

           

              <!-- 生成firstBlock,secondBlocktps的圖表 -->

              <appender name="graphExecutionTPS"

                        class="org.perf4j.log4j.GraphingStatisticsAppender">

                  <param name="GraphType" value="TPS"/>

                  <param name="TagNamesToGraph" value="firstBlock,secondBlock"/>

                  <appender-ref ref="graphsFileAppender"/>

              </appender>

             

              <!-- 記錄圖表生成urllog文件 -->

              <appender name="graphsFileAppender" class="org.apache.log4j.FileAppender">

                  <param name="File" value="/home/perfGraphs.log"/>

                  <layout class="org.apache.log4j.PatternLayout">

                      <param name="ConversionPattern" value="%m%n"/>

                  </layout>

          </appender>

          另外還需要改一個地方,就是CoalescingStatistics的配置:

          <appender name="CoalescingStatistics"

                        class="org.perf4j.log4j.AsyncCoalescingStatisticsAppender">

                  <!--

                       TimeSlice配置多少時間間隔去做一次匯總寫入文件中

                       默認值是 30000 ms

                  -->

                  <param name="TimeSlice" value="10000"/>

                  <appender-ref ref="fileAppender"/>

                 

                  <appender-ref ref="graphExecutionTimes"/>

                  <appender-ref ref="graphExecutionTPS"/>

              </appender>

          黃色那段配置的意思就是把日志寫入到圖表日志去。

          運行代碼Perf4JAppenderExample,我們在perfGraphs.log文件中生成了圖表的url

          http://chart.apis.google.com/chart?cht=lxy&chtt=Mean&chs=750x400&chxt=x,x,y&chd=t:0.0,100.0|45.2,78.1|0.0,100.0|98.1,100.0&chco=ff0000,00ff00&chm=d,ff0000,0,-1,5.0|d,00ff00,1,-1,5.0&chdl=firstBlock|secondBlock&chxr=2,0,828.6&chxl=0:|13:23:50|13:24:00|1:|Time&chxp=0,0.0,100.0|1,50&chg=50.0,10

           

          http://chart.apis.google.com/chart?cht=lxy&chtt=TPS&chs=750x400&chxt=x,x,y&chd=t:0.0,100.0|100.0,100.0|0.0,100.0|100.0,100.0&chco=ff0000,00ff00&chm=d,ff0000,0,-1,5.0|d,00ff00,1,-1,5.0&chdl=firstBlock|secondBlock&chxr=2,0,0.5&chxl=0:|13:23:50|13:24:00|1:|Time&chxp=0,0.0,100.0|1,50&chg=50.0,10

          大家可以把url放到瀏覽器訪問下。

           

          上面這種方式呢,需要自己登錄到服務器上,找到log文件,在放到瀏覽器中查看,總的過程還是比較麻煩。如果大家需要監控的工程是一個web工程的話,那就更方便了,直接配置一個servlet來查看。Web.xml的配置如下:

          <!DOCTYPE web-app PUBLIC

           "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"

           "http://java.sun.com/dtd/web-app_2_3.dtd" >

           

          <web-app>

              <display-name>Archetype Created Web Application</display-name>

           

              <servlet>

                 <servlet-name>perf4j</servlet-name>

                 <servlet-class>org.perf4j.log4j.servlet.GraphingServlet</servlet-class>

                 <!-- graphExecutionTimesgraphExecutionTPS就是我們在log4j中配置的名稱 -->

                 <init-param>

                     <param-name>graphNames</param-name>

                     <param-value>graphExecutionTimes,graphExecutionTPS</param-value>

                 </init-param>

              </servlet>

           

              <servlet-mapping>

                 <servlet-name>perf4j</servlet-name>

                 <url-pattern>/perf4j</url-pattern>

              </servlet-mapping>

          </web-app>

          大家可以打包工程,并放到web服務器下啟動,然后訪問下/perf4j這個uri

          Maven有一個jetty插件,可以方便啟動web工程,只要大家在pom.xml文件中加入如下配置:

          <plugins>

                     <!-- jetty插件, 設定端口與context path-->

                     <plugin>

                        <groupId>org.mortbay.jetty</groupId>

                        <artifactId>jetty-maven-plugin</artifactId>

                     </plugin>    

          </plugins>

          在控制臺中輸入:mvn jetty:run,即可。省去了打包發布,很省心喔。

          第一次用http://localhost:8080/perf4j訪問查看圖表的時候沒有生成任何東西,那是因為內存中沒有收集到最新的性能數據。所以我在index.jsp里調用下以便產生性能數據。然后重新訪問,這個時候就有圖表生成了。


          下載工程

          posted @ 2012-04-19 14:12 yangpingyu 閱讀(1747) | 評論 (1)編輯 收藏

          2012年4月16日

          perf4j使用三(log4j集成)

          Perf4j最主要的一個好處就是可以跟log4j或者logback來性能分析和監控線上運行的程序。集成的方式主要是:自定義log4j的appenders通過標準的配置加入到log4j中去(后面會有配置的例子)。有一個要注意的地方就是需要使用log4j的1.2.14版本或者更高版本。由于我一般都是使用log4j,所以對于logback的集成我就不描述了,我覺得應該差不多的。

           

          Perf4j最重要的appender就是AsyncCoalescingStatisticsAppender,它會把一段時間內StopWatch的信息匯總到一個獨立的GroupedTimingStatistics日志信息,然后把這個獨立的信息傳給下游的appenders,比如fileappenders,這樣就可以寫到文件中去了。也可以傳給per4j的其他自定義appenders。

           

          接下來我們看一個log4j.xml的例子,有一個限制,如果要使用AsyncCoalescingStatisticsAppender就只能使用xml文件而不能使用properties文件。

           

          <?xml version="1.0" encoding="UTF-8" ?>

          <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

           

          <log4j:configuration debug="false" xmlns:log4j="http://jakarta.apache.org/log4j/">

              <!--

                   配置控制臺輸出

              -->

              <appender name="console" class="org.apache.log4j.ConsoleAppender">

                  <layout class="org.apache.log4j.PatternLayout">

                      <param name="ConversionPattern" value="%-5p %c{1} - %m%n"/>

                  </layout>

              </appender>

           

              <!-- Perf4J appenders -->

              <!--

                 AsyncCoalescingStatisticsAppender收集StopWatch的日志信息并傳送到下游的文件appenders

              -->

              <appender name="CoalescingStatistics"

                        class="org.perf4j.log4j.AsyncCoalescingStatisticsAppender">

                  <!--

                       TimeSlice配置多少時間間隔去做一次匯總寫入文件中

                       默認值是 30000 ms

                  -->

                  <param name="TimeSlice" value="10000"/>

                  <appender-ref ref="fileAppender"/>

              </appender>

           

              <!-- 把匯總的perf4j的日志信息寫到perfStats.log文件中去 -->

              <appender name="fileAppender" class="org.apache.log4j.FileAppender">

                  <param name="File" value="/home/perfStats.log"/>

                  <layout class="org.apache.log4j.PatternLayout">

                      <param name="ConversionPattern" value="%m%n"/>

                  </layout>

              </appender>

           

              <!-- Loggers -->

              <!-- 

                 配置perf4j logger

                 Additivity設置成false主要因為是不想讓代碼運行時間的日志輸出給上游appenders,即不要在控制臺輸出。

              -->

              <logger name="org.perf4j.TimingLogger" additivity="false">

                  <level value="INFO"/>

                  <appender-ref ref="CoalescingStatistics"/>

              </logger>

           

              <!-- 

                 Root logger打印所有日志,但不包含perf4j的信息。原因是在TimingLogger配置中設置了additivityfalse

              -->

              <root>

                  <level value="INFO"/>

                  <appender-ref ref="console"/>

              </root>

          </log4j:configuration>

           

           

          黃色背景是perf4j的配置信息。其他都是log4j的基本配置。下面是測試perf4j與log4j集成的代碼。

          package com.baowu.perf4j;

           

          import org.apache.log4j.Logger;

          import org.perf4j.StopWatch;

          import org.perf4j.log4j.Log4JStopWatch;

           

          public class Perf4JAppenderExample {

              public static void main (String[] args) throws Exception {

                  Logger rootLogger = Logger.getRootLogger();

                  for (int i = 0; i < 10; i++) {

                      // Log4JStopWatch默認使用org.perf4j.TimingLogger這個類

                      StopWatch stopWatch = new Log4JStopWatch();

                      //模擬代碼運行時間

                      Thread.sleep((long) (Math.random() * 1000L));

                      //打印到控制臺

                      rootLogger.info("Normal logging messages only go to the console");

                      stopWatch.lap("firstBlock");

                      Thread.sleep((long) (Math.random() * 2000L));

                      stopWatch.stop("secondBlock");

                  }

              }

          }

           

          運行代碼。

          控制臺輸出:

          INFO root - Normal logging messages only go to the console

          INFO root - Normal logging messages only go to the console

          INFO root - Normal logging messages only go to the console

          INFO root - Normal logging messages only go to the console

          INFO root - Normal logging messages only go to the console

          INFO root - Normal logging messages only go to the console

          INFO root - Normal logging messages only go to the console

          INFO root - Normal logging messages only go to the console

          INFO root - Normal logging messages only go to the console

          INFO root - Normal logging messages only go to the console

           

          文件輸出:


           

          輸出格式也可以改成CSV格式。配置:

          <appender name="fileAppender" class="org.apache.log4j.FileAppender">

                  <param name="File" value="/home/perfStats.log"/>

                  <layout class="org.apache.log4j.PatternLayout">

                      <param name="ConversionPattern" value="%m%n"/>

                  </layout>

          </appender>

          org.apache.log4j.PatternLayout改成org.perf4j.log4j.StatisticsCsvLayout即可。

          具體的參數請查看api
          下載工程


          posted @ 2012-04-16 13:59 yangpingyu 閱讀(4631) | 評論 (0)編輯 收藏

          2012年4月15日

          perf4j使用二

          Perf4j使用一主要演示了性能監控的日志直接打印在標準輸出流。那么使用二呢則主要來演示怎么來分析打印出來的日志文件。

           

          由于我們還沒有跟log4j集成,日志文件打印在標準輸出流,我們需要把標準輸出流重定向到times.log文件中。重定向有兩種方式:直接copy到文件中,或者在eclipse里指定下輸出文件。我主要是用eclipse指定輸出文件。

           

           

          然后運行代碼(Perf4j使用一Example.java),控制臺會在第一句話中打出[Console output redirected to file:E:\yangpingyu\work\times.log],這樣運行的結果會同時打印在文件中和標準輸出中。

           

          有了times.log,我們就可以對日志文件進行分析,以找出有問題的代碼。

           

          分析日志命令:

          E:\yangpingyu\work>java -jar perf4j-0.9.16.jar times.log

           

          csv的格式來查看結果,命令如下:

          java -jar perf4j-0.9.16.jar -f csv times.log

           

          以上都是以文本的格式進行輸出,但文本沒有圖表更具有表達力。所以把結果以圖表形式輸出是必不可少,幸好perf4j也支持,命令如下:

          java -jar perf4j-0.9.16.jar --graph perfGraphs.html times.log

          執行命令后,在控制臺輸出相應的統計信息,相應的在磁盤上也生成了一個htmlhtml里包含平均值圖表和tps圖表。

          <html>

          <head><title>Perf4J Performance Graphs</title></head>

          <body>

          <br/><br/><img src="http://chart.apis.google.com/chart?cht=lxy&chtt=Mean&chs=750x400&chxt=x,x,y&chd=t:0.0,50.0,100.0|56.3,60.1,6.0|0.0,50.0|88.5,94.5|50.0,100.0|43.2,7.2|0.0,50.0,100.0|71.8,57.4,8.0|0.0,50.0,100.0|100.0,61.2,59.6|0.0,50.0,100.0|63.9,62.0,18.7|0.0,50.0,100.0|34.4,72.1,30.1&chco=ff0000,00ff00,0000ff,00ffff,ff00ff,ffff00,000000&chm=d,ff0000,0,-1,5.0|d,00ff00,1,-1,5.0|d,0000ff,2,-1,5.0|d,00ffff,3,-1,5.0|d,ff00ff,4,-1,5.0|d,ffff00,5,-1,5.0|d,000000,6,-1,5.0&chdl=codeBlock1|codeBlock2.failure|codeBlock2.success|codeBlock3|codeBlock4|codeBlock5|codeBlock6&chxr=2,0,748.5&chxl=0:|18:12:00|18:12:30|18:13:00|1:|Time&chxp=0,0.0,50.0,100.0|1,50&chg=50.0,10"/>

          <br/><br/><img src="http://chart.apis.google.com/chart?cht=lxy&chtt=TPS&chs=750x400&chxt=x,x,y&chd=t:0.0,50.0,100.0|36.4,90.9,9.1|0.0,50.0|27.3,63.6|50.0,100.0|36.4,9.1|0.0,50.0,100.0|36.4,90.9,9.1|0.0,50.0,100.0|36.4,90.9,9.1|0.0,50.0,100.0|36.4,90.9,9.1|0.0,50.0,100.0|27.3,100.0,9.1&chco=ff0000,00ff00,0000ff,00ffff,ff00ff,ffff00,000000&chm=d,ff0000,0,-1,5.0|d,00ff00,1,-1,5.0|d,0000ff,2,-1,5.0|d,00ffff,3,-1,5.0|d,ff00ff,4,-1,5.0|d,ffff00,5,-1,5.0|d,000000,6,-1,5.0&chdl=codeBlock1|codeBlock2.failure|codeBlock2.success|codeBlock3|codeBlock4|codeBlock5|codeBlock6&chxr=2,0,0.4&chxl=0:|18:12:00|18:12:30|18:13:00|1:|Time&chxp=0,0.0,50.0,100.0|1,50&chg=50.0,10"/>

          </body></html>

          以上是html的內容,里面最重要的信息就是兩個img標簽,里面具體的圖片是google chart api生成。可以打開html直接查看圖表。

          如果想要看更詳細的參數,可以使用—help來查看。java -jar perf4j-0.9.16.jar –help

          posted @ 2012-04-15 19:35 yangpingyu 閱讀(1788) | 評論 (0)編輯 收藏

          小工具

          本文主要記錄下自己在日常工作中感覺比較好用的一些小工具。目前只有幾個,不過遇到好的會不斷更新上來。

          EmEditor:文本編輯器。
          onenote:主要用來記錄工作列表和一些計劃等。
          google chart api:可以用來制作圖表,很方便。性能測試的結果數據做對比圖。
          smartArt:也是圖表制作工具,已經集成到2007office中了。
          awk:linux文本處理工具。類似于腳本。牛逼的程序員應該要掌握的一個工具。

          add by 2012-06-19
          http://cn.edrawsoft.com/download.php :畫圖很漂亮的工具。


          待更新。。。

          posted @ 2012-04-15 16:46 yangpingyu 閱讀(273) | 評論 (0)編輯 收藏

          perf4j使用一

          如果大家使用的是maven工程,那么現在pom文件中加入perf4j的依賴。

          <dependency>

          <groupId>org.perf4j</groupId>

          <artifactId>perf4j</artifactId>

          <version>0.9.16</version>

          <scope>compile</scope>

          </dependency>

          如果用的是普通工程,那么直接下載jar包放入lib目錄下即可。

           

           

          例子:

          package com.baowu.per4j;

           

          import org.perf4j.LoggingStopWatch;

          import org.perf4j.StopWatch;

           

          public class Example1 {

           

              public static void main(String[] args) throws InterruptedException{

                 method1();

                 method2();

                 method3();

              }

             

              /**

               * 監控一處代碼示例

               * @throws InterruptedException

               */

              private static void method1() throws InterruptedException{

                 //創建一個監控對象,這里使用LoggingStopWatch,它是把結果直接輸出到控制臺。我們也可以

                 //使用StopWatch的其他子類,比如:Log4JStopWatchCommonsLogStopWatch。不過這些子類需

                 //要工程使用日志框架

                 StopWatch stopWatch = new LoggingStopWatch("codeBlock1");

           

                 //這里就是一些需要監控的代碼,我們命名為codeBlock1

                 //使用線程休眠是為了模擬代碼執行時間

                 Thread.sleep((long)(Math.random() * 1000L));

           

                 //停止計算代碼性能

                 stopWatch.stop();

              }

             

              /**

               * 一個方法多出代碼監控

               * @throws InterruptedException

               */

              private static void method2() throws InterruptedException{

                 StopWatch stopWatch = new LoggingStopWatch();

                 Thread.sleep((long)(Math.random() * 1000L));

                 stopWatch.lap("codeBlock3");

                 Thread.sleep((long)(Math.random() * 1000L));

                 stopWatch.lap("codeBlock4");

                 Thread.sleep((long)(Math.random() * 1000L));

                 stopWatch.lap("codeBlock5");

                 Thread.sleep((long)(Math.random() * 1000L));

                 stopWatch.stop("codeBlock6");

              }

             

              /**

               * stop方法可以加入一些說明信息

               */

              private static void method3(){

                 StopWatch stopWatch = new LoggingStopWatch();

                 try {

                     // the code block being timed - this is just a dummy example

                     long sleepTime = (long)(Math.random() * 1000L);

                     Thread.sleep(sleepTime);

                     if (sleepTime > 500L) {

                         throw new Exception("Throwing exception");

                     }

                     stopWatch.stop("codeBlock2.success", "Sleep time was < 500 ms");

                 } catch (Exception e) {

                     stopWatch.stop("codeBlock2.failure", "Exception was: " + e);

                 }

              }

          }

           

          運行結果:

          start[1334457619937] time[355] tag[codeBlock1]

          start[1334457620296] time[152] tag[codeBlock3]

          start[1334457620453] time[138] tag[codeBlock4]

          start[1334457620593] time[598] tag[codeBlock5]

          start[1334457621187] time[700] tag[codeBlock6]

          start[1334457621890] time[619] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception]

          posted @ 2012-04-15 10:44 yangpingyu 閱讀(2989) | 評論 (0)編輯 收藏

          Perf4j簡介

          Perf4j主要的用途是計量代碼性能和分析性能數據。

           

          為什么要使用這個工具呢?我們可以聯想下最早期java開發者調試代碼使用的方式,以前沒有日志框架,那java開發就使用System.out.println()來輸出自己想查看的變量。但是這樣項目上線的話,就要去掉這些打印語句以減少性能影響。那萬一在線上出問題了,調試哪里出問題就很麻煩,因為沒有輸出的日志可查。所以后來有人開發了日志框架,通過日志級別控制日志的輸出。

           

          類似的,如果沒有perf4j,我們在查看代碼運行時間的話可以用以下代碼來實現:

          long start = System.currentTimeMillis();

          // execute the block of code to be timed

          System.out.println("ms for block n was: " + (System.currentTimeMillis() - start));

          這種方式有幾個缺點:

          1、 這種方式輸出內容比較單一,就是代碼總的運行時間。但是我們代碼需要查看的性能指標有更多,比如總的平均值,最小值,最大值,tps等等。

          2、 也許我們的代碼在線上運行,我們想把這些值通過圖表的形式展示出來。或者把這些內容通過jmx輸出。

          3、 另外,我們可能把perf4jlog4jslf4j等日志框架和日志門面系統整合起來。

           

          基于以上這些問題,所以開源社區就出現了perf4j(人多力量大,社區的力量就是強大)。

          Perf4j一些特性:

          簡單的停止查看機制來計算語句時間消耗輸出。

          命令行解析log文件產生匯總數據和圖表。

          簡單的集成日志框架和門面框架。

          自定義log4jlogbackappenders來產生數據和圖表。

          通過jmx查看性能指標,并根據閾值發送消息。

          Web工程可以通過servlet來輸出性能指標。

          Perf4j可以和aop等切面框架整合起來輸出性能指標。

          Perf4j是一個可擴展的架構。

          posted @ 2012-04-15 10:15 yangpingyu 閱讀(760) | 評論 (0)編輯 收藏

          2012年4月14日

          Maven與findbugs

          公司最近嚴抓軟件質量問題,我抽空了解了下提高代碼質量的一些開源工具。其中一個就是findbugs。使用findbugs有很多方式,比如:安裝eclipse findbugs插件,通過maven調用生成報告。今天主要演示下mavenfindbugs集成。

           

          第一步:下載maven,我使用的是maven3。把maven的命令加入PATH環境變量。

          第二步:創建一個普通的maven java工程。命令如下:mvn archetype:maven-archetyp-quickstart –DgroupId=com.tianya –DartifactId=baowu。如果正常執行的話會生成如下結構的一個工程。

          第三步:我們看下pom文件

          <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

              xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

              <modelVersion>4.0.0</modelVersion>

              <groupId>com.tianya</groupId>

              <artifactId>baowu</artifactId>

              <version>0.0.1-SNAPSHOT</version>

              <packaging>war</packaging>

           

              <!--配置插件來源 -->

              <pluginRepositories>

                 <pluginRepository>

                     <id>Codehaus repository</id>

                     <url>http://repository.codehaus.org/</url>

                 </pluginRepository>

              </pluginRepositories>

             

              <build>

                 <plugins>

                     <plugin>

                        <groupId>org.codehaus.mojo</groupId>

                        <artifactId>findbugs-maven-plugin</artifactId>

                        <version>2.3.2</version>

                        <configuration>

                            <!-- <configLocation>${basedir}/springside-findbugs.xml</configLocation> -->

                            <threshold>High</threshold>

                            <effort>Default</effort>

                            <findbugsXmlOutput>true</findbugsXmlOutput>

                             <!-- findbugs xml輸出路徑-->         <findbugsXmlOutputDirectory>target/site</findbugsXmlOutputDirectory>

                        </configuration>

                     </plugin>

                 </plugins>

              </build>

          </project>

           

          我來解釋下xml配置:

          配置插件下載地址

          <!--配置插件來源 -->

              <pluginRepositories>

                 <pluginRepository>

                     <id>Codehaus repository</id>

                     <url>http://repository.codehaus.org/</url>

                 </pluginRepository>

              </pluginRepositories>

           

          由于maven核心做的事情都是抽象的構建過程,很多實際的工作都是具體的插件來實現。所以很顯然,maven以插件的方式集成findbugs

          <plugin>

                        <groupId>org.codehaus.mojo</groupId>

                        <artifactId>findbugs-maven-plugin</artifactId>

                        <version>2.3.2</version>

                        <configuration>

                            <!-- <configLocation>${basedir}/springside-findbugs.xml</configLocation> -->

                            <!-- findbugs xml輸出-->                   <findbugsXmlOutput>true</findbugsXmlOutput>

                             <!-- findbugs xml輸出路徑-->         <findbugsXmlOutputDirectory>target/site</findbugsXmlOutputDirectory>

                        </configuration>

                     </plugin>

           

          大家注意到了findbugs插件里,我注釋掉了一句話,其實這句話就是可以使用自己的fingbugs配置來做檢查。我用的是springside的一個xml文件。

           

          第四步:配置好相關文件之后,接下來就是執行相關命令了。

          mvn compile findbugs:findbugs生成報告。報告生成的地址就是${項目根目錄}/target/site。也可以通過mvn findbugs:gui gui界面查看findbugsreport

          posted @ 2012-04-14 18:55 yangpingyu 閱讀(7208) | 評論 (0)編輯 收藏

          2012年2月7日

          學習書單和資料

          從學校畢業到工作已經2年半時間了,在豆瓣、當當、京東和亞瑪遜上關注了很多書籍,也比較喜歡逛書店。當然買了很多和看了部分,自己家里很多書還沒看(人類的惰性,借口)。在這兩年半時間內,走了一些彎路,所以想總結下自己的學習生涯。

           

          畢業的時候去了一家創業型的互聯網公司,在這家公司沒有任何培訓機制,任何東西都需要靠自己來捉摸。根據工作需要看了struts2springhibernatejstljspservlet等一些J2EE相關組件的書和資料。僅靠這些技術也能搭建出一個符合產品的網站。接觸到infoq網站之后,了解了一些大型網站的架構變遷等技術,在一年的時間內不斷追尋這些不符合自己目前需要的技術,充其量就是開闊了自己技術的眼界。由于互聯網公司的一些劣勢,導致我有了跳槽的想法,但是出去面試之后,才知道自己是井底之蛙。自己也算熱愛技術,也算努力學習和研究的,自己反思和總結了一下:不注重基礎。

           

          那么學習什么才算基礎呢?我主要列舉下我的學習書單:

                  

          ü 計算機基礎:任何軟件運行的基礎。

          深入理解計算機系統(修訂版)

          計算機組成原

           

          ü 操作系統:硬件管理的軟件,我們的應用軟件主要依賴于操作系統。

          鳥哥的Linux私房菜 基礎學習篇

          操作系統原理

          Linux內核設計與實現

           

          ü 數據結構:軟件=數據結構+算法。其實操作系統軟件和應用軟件都在大量應用數據結構。

          大話數據結構

           

          ü 網絡:系統一定需要與外部交互,那就需要網絡。

          計算機網絡

          TCP/IP詳解 1

          TCP/IP詳解 2

          TCP/IP詳解 3

          ü 數據庫:存儲數據。

          數據庫系統概論

          MySQL 5 權威指南-(3)

          MySQL性能調優與架構設計

           

          ü 軟件工程:開發軟件是一個大工程,需要有一套理論來管理軟件開發。

          軟件工程

          敏捷軟件開發

           

          ü 算法:尚未接觸。

           

          ü Java基礎:具體的高級語言,最好的學習地方就是java的官方網站和開源代碼。

          Java JDK6學習筆記

          Effective Java中文版

          Java編程思想 (第4版)

          Java網絡編程(中文版 第三版)

          JAVA并發編程實踐

          深入理解Java虛擬機

          Spring in Action中文版

          深入淺出Hibernate

          Struts2權威指南

           

          ü Java進階:面向對象思想、設計模式和J2EE深入。

          Java與模式

          企業應用架構模式

          POJOs IN ACTION中文版

          J2EE設計開發編程指南Expert One-on-One J2EE Design and Development

          Expert One-on-One J2EE Development without EJB

           

          學習了這些基礎之后,我們在來說分布式,nosql,云計算,企業集成等等。只有掌握了基礎我們才能更好的創新。

          posted @ 2012-02-07 13:45 yangpingyu 閱讀(397) | 評論 (0)編輯 收藏

          jvm運行時數據區域

          Java語言與c語言有一個非常重要的區別就是:內存管理方式的不同,java語言內存管理不需要程序開發人員關注,而c語言的內存的請求和釋放都是開發人員來處理。辯證的思維來看,不同內存管理實現方式有優點和缺點,所以語言應用的場景,效率會有很大不同。

           

          Jvm運行時的數據區域主要有:程序計數器、虛擬機棧、本地方法棧、方法區和堆。其中程序計數器、虛擬機棧和本地方法棧是線程獨享,而方法區和堆是所有線程共享。

          ü 程序計數器:jvm每個線程都有一個程序計數器。在任一時刻都有一個線程的方法在運行,如果這個方法不是本地方法,那么程序計數器存放的就是正在執行的指令地址;如果是本地方法,那么程序計數器中存放的指定地址為undefined

          ü 虛擬機棧:當jvm創建一個線程的時候就會為線程分配一個虛擬機棧。主要用于存放方法的一些本地變量和部分結果,一般這里的大小都是固定,但不是絕對。一個方法的執行到完成就是棧的入棧和出棧。假設在某方法中定義了一個對象Object obj=new Object();其中obj是存放在棧上,而new Object()是在堆上分配。-Xss可以控制jvm虛擬機棧的大小。

          ü 本地方法棧:大體跟虛擬機棧類似,不過是給本地方法使用的。虛擬機棧和本地方法棧在hotspot是沒有分開實現的,而是統稱為棧。

          ü 方法區:主要存放靜態變量,常量,類加載器加載的類等一些信息。

          ü 堆:jvm絕大部分的對象分配都在堆上分配。-Xmn –Xmx是控制堆最小值和最大值,一般堆的大小在使用了超過mx設定的70%的時候,就會自動擴大到最大值,所以防止這種擴大和縮小我們設置成一樣的值。

          posted @ 2012-02-07 10:27 yangpingyu 閱讀(293) | 評論 (0)編輯 收藏

          2012年1月10日

          ClassCastException

          ClassCastException類型轉換異常,是一個運行時異常。

           

          非常常見就是不同類型之間的強制類型轉換就會拋出ClassCastException異常。還有一種就是不同ClassLoader加載的相同的類型轉換也會拋出ClassCastException。接下來我用代碼來詳細解釋下。

           

          1、 強制類型轉換

          public class ClassCastExceptionTest {

           

              /**

               * @param args

               */

              public static void main(String[] args) {

                 Animal a1 = new Dog(); //1

                 Animal a2 = new Cat(); //2

                 Dog d1 = (Dog)a1;       //3

                 Dog d2 = (Dog)a2;       //4

              }

          }

          把貓轉換成狗,是不對的。后面注釋為4的代碼是無法正常賦值的。

          Exception in thread "main" java.lang.ClassCastException: Cat cannot be cast to Dog

              at ClassCastExceptionTest.main(ClassCastExceptionTest.java:13)

           

           

          2、 不同classloader加載相同類型類之間的轉換

          import java.io.File;

          import java.net.URL;

          import java.net.URLClassLoader;

           

           

          public class ClassCastExceptionTest {

              /**

               * @param args

               */

              public static void main(String[] args) throws Exception {

                 File file = new File(Thread.currentThread().getContextClassLoader().getResource("").getPath());

                 URL[] urls = {file.toURL()};

                 URLClassLoader classloader1 = new URLClassLoader(urls, ClassLoader.getSystemClassLoader().getParent());

                 Class classloader1Animal1 = classloader1.loadClass("Dog");

                 Dog dog1 = (Dog)classloader1Animal1.newInstance();

                

                 URLClassLoader classloader2 = new URLClassLoader(urls, ClassLoader.getSystemClassLoader().getParent());

                 Class classloader1Animal2 = classloader1.loadClass("Dog");

                 Dog dog2 = (Dog)classloader1Animal1.newInstance();

                

                 dog1 = dog2;

              }

           

          }

           

          代碼中我們看到dog1=dog2,這樣賦值是會拋異常的。

          Exception in thread "main" java.lang.ClassCastException: Dog cannot be cast to Dog

              at ClassCastExceptionTest.main(ClassCastExceptionTest.java:17)

           

          以后大家遇到classCastException的時候要注意了,不一定是強制類型轉換導致的,也有可能不同的classloader加載了相同的類,然后這個類不同的實例進行賦值。

          posted @ 2012-01-10 16:07 yangpingyu 閱讀(585) | 評論 (0)編輯 收藏

          僅列出標題  下一頁
          <2025年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          導航

          統計

          常用鏈接

          留言簿

          隨筆分類

          隨筆檔案

          收藏夾

          linux

          產品交互

          分析,設計,架構

          安全

          技術牛人

          數據庫

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 同德县| 水城县| 勃利县| 淮南市| 集贤县| 丹阳市| 天全县| 北安市| 金平| 崇文区| 安陆市| 泸溪县| 同仁县| 雷山县| 宜都市| 湟中县| 裕民县| 营山县| 淳安县| 山阳县| 资阳市| 开原市| 西贡区| 麻江县| 邛崃市| 临桂县| 永济市| 县级市| 贵州省| 卢湾区| 巴塘县| 桓仁| 金华市| 十堰市| 宾阳县| 西宁市| 尖扎县| 萨迦县| 班戈县| 甘洛县| 安仁县|